Bug Summary

File:s/cmd/shlibsign/shlibsign.c
Warning:line 1123, column 26
Access to field 'hmac' results in a dereference of a null pointer (loaded from variable 'hash')

Annotated Source Code

Press '?' to see keyboard shortcuts

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/* 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_UNIX1
19#define USES_LINKS1 1
20#endif
21
22#define COMPAT_MAJOR0x01 0x01
23#define COMPAT_MINOR0x02 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_LINKS1
32#include <unistd.h>
33#include <sys/param.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#endif
37
38/* nspr headers */
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/* softoken headers */
49#include "pkcs11.h"
50#include "pkcs11t.h"
51
52/* freebl headers */
53#include "shsign.h"
54
55/* nss headers for definition of HASH_HashType */
56#include "hasht.h"
57
58CK_BBOOL cktrue = CK_TRUE1;
59CK_BBOOL ckfalse = CK_FALSE0;
60static PRBool verbose = PR_FALSE0;
61static PRBool verify = PR_FALSE0;
62static PRBool compat = PR_FALSE0;
63
64typedef 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_FAILURE0x80111111 0x80111111
74#define CKR_INTERNAL_IN_FAILURE0x80222222 0x80222222
75#define CKM_SHA10x00000220UL CKM_SHA_10x00000220UL
76#define CKM_SHA1_HMAC0x00000221UL CKM_SHA_1_HMAC0x00000221UL
77#define CKK_SHA1_HMAC0x00000028UL CKK_SHA_1_HMAC0x00000028UL
78#define MKHASH(name, mech){ name, CKM_mech, CKM_mech_HMAC, CKK_mech_HMAC, HASH_Algmech,
mech_LENGTH }
\
79 { \
80 name, CKM_##mech, CKM_##mech##_HMAC, \
81 CKK_##mech##_HMAC, HASH_Alg##mech, mech##_LENGTH \
82 }
83static HashTable hashTable[] = {
84 MKHASH("sha-1", SHA1){ "sha-1", 0x00000220UL, 0x00000221UL, 0x00000028UL, HASH_AlgSHA1
, 20 }
, MKHASH("sha1", SHA1){ "sha1", 0x00000220UL, 0x00000221UL, 0x00000028UL, HASH_AlgSHA1
, 20 }
, MKHASH("sha224", SHA224){ "sha224", 0x00000255UL, 0x00000256UL, 0x0000002EUL, HASH_AlgSHA224
, 28 }
,
85 MKHASH("sha256", SHA256){ "sha256", 0x00000250UL, 0x00000251UL, 0x0000002BUL, HASH_AlgSHA256
, 32 }
, MKHASH("sha384", SHA384){ "sha384", 0x00000260UL, 0x00000261UL, 0x0000002CUL, HASH_AlgSHA384
, 48 }
,
86 MKHASH("sha512", SHA512){ "sha512", 0x00000270UL, 0x00000271UL, 0x0000002DUL, HASH_AlgSHA512
, 64 }
87};
88static size_t hashTableSize = PR_ARRAY_SIZE(hashTable)(sizeof(hashTable)/sizeof((hashTable)[0]));
89
90const HashTable *
91findHash(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((void*)0);
101}
102
103static void
104usage(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
126static void
127long_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
163static char *
164mkoutput(const char *input)
165{
166 int in_len = strlen(input);
167 char *output = PR_Malloc(in_len + sizeof(SGN_SUFFIX".chk"));
168 int index = in_len + 1 - sizeof("." SHLIB_SUFFIX"so");
169
170 if ((index > 0) &&
171 (PL_strncmp(&input[index],
172 "." SHLIB_SUFFIX"so", sizeof("." SHLIB_SUFFIX"so")) == 0)) {
173 in_len = index;
174 }
175 memcpy(output, input, in_len);
176 memcpy(&output[in_len], SGN_SUFFIX".chk", sizeof(SGN_SUFFIX".chk"));
177 return output;
178}
179
180static void
181lperror(const char *string)
182{
183 PRErrorCode errorcode;
184
185 errorcode = PR_GetError();
186 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "%s: %d: %s\n", string, errorcode,
187 PR_ErrorToString(errorcode, PR_LANGUAGE_I_DEFAULT0));
188}
189
190static void
191encodeInt(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
200static PRStatus
201writeItem(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_STDERRPR_GetSpecialFD(PR_StandardError), "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
222static 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
240static 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
245static 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 * The constants h, seed, & counter aren't used in the code; they're provided
266 * here (commented-out) so that human readers can verify that our our PQG
267 * parameters were generated properly.
268static const unsigned char h[] = {
269 0x41, 0x87, 0x47, 0x79, 0xd8, 0xba, 0x4e, 0xac,
270 0x44, 0x4f, 0x6b, 0xd2, 0x16, 0x5e, 0x04, 0xc6,
271 0xc2, 0x29, 0x93, 0x5e, 0xbd, 0xc7, 0xa9, 0x8f,
272 0x23, 0xa1, 0xc8, 0xee, 0x80, 0x64, 0xd5, 0x67,
273 0x3c, 0xba, 0x59, 0x9a, 0x06, 0x0c, 0xcc, 0x29,
274 0x56, 0xc0, 0xb2, 0x21, 0xe0, 0x5b, 0x52, 0xcd,
275 0x84, 0x73, 0x57, 0xfd, 0xd8, 0xc3, 0x5b, 0x13,
276 0x54, 0xd7, 0x4a, 0x06, 0x86, 0x63, 0x09, 0xa5,
277 0xb0, 0x59, 0xe2, 0x32, 0x9e, 0x09, 0xa3, 0x9f,
278 0x49, 0x62, 0xcc, 0xa6, 0xf9, 0x54, 0xd5, 0xb2,
279 0xc3, 0x08, 0x71, 0x7e, 0xe3, 0x37, 0x50, 0xd6,
280 0x7b, 0xa7, 0xc2, 0x60, 0xc1, 0xeb, 0x51, 0x32,
281 0xfa, 0xad, 0x35, 0x25, 0x17, 0xf0, 0x7f, 0x23,
282 0xe5, 0xa8, 0x01, 0x52, 0xcf, 0x2f, 0xd9, 0xa9,
283 0xf6, 0x00, 0x21, 0x15, 0xf1, 0xf7, 0x70, 0xb7,
284 0x57, 0x8a, 0xd0, 0x59, 0x6a, 0x82, 0xdc, 0x9c };
285
286static const unsigned char seed[] = { 0x00,
287 0xcc, 0x4c, 0x69, 0x74, 0xf6, 0x72, 0x24, 0x68,
288 0x24, 0x4f, 0xd7, 0x50, 0x11, 0x40, 0x81, 0xed,
289 0x19, 0x3c, 0x8a, 0x25, 0xbc, 0x78, 0x0a, 0x85,
290 0x82, 0x53, 0x70, 0x20, 0xf6, 0x54, 0xa5, 0x1b,
291 0xf4, 0x15, 0xcd, 0xff, 0xc4, 0x88, 0xa7, 0x9d,
292 0xf3, 0x47, 0x1c, 0x0a, 0xbe, 0x10, 0x29, 0x83,
293 0xb9, 0x0f, 0x4c, 0xdf, 0x90, 0x16, 0x83, 0xa2,
294 0xb3, 0xe3, 0x2e, 0xc1, 0xc2, 0x24, 0x6a, 0xc4,
295 0x9d, 0x57, 0xba, 0xcb, 0x0f, 0x18, 0x75, 0x00,
296 0x33, 0x46, 0x82, 0xec, 0xd6, 0x94, 0x77, 0xc3,
297 0x4f, 0x4c, 0x58, 0x1c, 0x7f, 0x61, 0x3c, 0x36,
298 0xd5, 0x2f, 0xa5, 0x66, 0xd8, 0x2f, 0xce, 0x6e,
299 0x8e, 0x20, 0x48, 0x4a, 0xbb, 0xe3, 0xe0, 0xb2,
300 0x50, 0x33, 0x63, 0x8a, 0x5b, 0x2d, 0x6a, 0xbe,
301 0x4c, 0x28, 0x81, 0x53, 0x5b, 0xe4, 0xf6, 0xfc,
302 0x64, 0x06, 0x13, 0x51, 0xeb, 0x4a, 0x91, 0x9c };
303
304static const unsigned int counter=1496;
305 */
306
307static 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
341static 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
347static 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 * The constants h2, seed2, & counter2 aren't used in the code; they're provided
383 * here (commented-out) so that human readers can verify that our our PQG
384 * parameters were generated properly.
385static const unsigned char h2[] = {
386 0x30, 0x91, 0xa1, 0x2e, 0x40, 0xa5, 0x7d, 0xf7,
387 0xdc, 0xed, 0xee, 0x05, 0xc2, 0x31, 0x91, 0x37,
388 0xda, 0xc5, 0xe3, 0x47, 0xb5, 0x35, 0x4b, 0xfd,
389 0x18, 0xb2, 0x7e, 0x67, 0x1e, 0x92, 0x22, 0xe7,
390 0xf5, 0x00, 0x71, 0xc0, 0x86, 0x8d, 0x90, 0x31,
391 0x36, 0x3e, 0xd0, 0x94, 0x5d, 0x2f, 0x9a, 0x68,
392 0xd2, 0xf8, 0x3d, 0x5e, 0x84, 0x42, 0x35, 0xda,
393 0x75, 0xdd, 0x05, 0xf0, 0x03, 0x31, 0x39, 0xe5,
394 0xfd, 0x2f, 0x5a, 0x7d, 0x56, 0xd8, 0x26, 0xa0,
395 0x51, 0x5e, 0x32, 0xb4, 0xad, 0xee, 0xd4, 0x89,
396 0xae, 0x01, 0x7f, 0xac, 0x86, 0x98, 0x77, 0x26,
397 0x5c, 0x31, 0xd2, 0x5e, 0xbb, 0x7f, 0xf5, 0x4c,
398 0x9b, 0xf0, 0xa6, 0x37, 0x34, 0x08, 0x86, 0x6b,
399 0xce, 0xeb, 0x85, 0x66, 0x0a, 0x26, 0x8a, 0x14,
400 0x92, 0x12, 0x74, 0xf4, 0xf0, 0xcb, 0xb5, 0xfc,
401 0x38, 0xd5, 0x1e, 0xa1, 0x2f, 0x4a, 0x1a, 0xca,
402 0x66, 0xde, 0x6e, 0xe6, 0x6e, 0x1c, 0xef, 0x50,
403 0x41, 0x31, 0x09, 0xe7, 0x4a, 0xb8, 0xa3, 0xaa,
404 0x5a, 0x22, 0xbd, 0x63, 0x0f, 0xe9, 0x0e, 0xdb,
405 0xb3, 0xca, 0x7e, 0x8d, 0x40, 0xb3, 0x3e, 0x0b,
406 0x12, 0x8b, 0xb0, 0x80, 0x4d, 0x6d, 0xb0, 0x54,
407 0xbb, 0x4c, 0x1d, 0x6c, 0xa0, 0x5c, 0x9d, 0x91,
408 0xb3, 0xbb, 0xd9, 0xfc, 0x60, 0xec, 0xc1, 0xbc,
409 0xae, 0x72, 0x3f, 0xa5, 0x4f, 0x36, 0x2d, 0x2c,
410 0x81, 0x03, 0x86, 0xa2, 0x03, 0x38, 0x36, 0x8e,
411 0xad, 0x1d, 0x53, 0xc6, 0xc5, 0x9e, 0xda, 0x08,
412 0x35, 0x4f, 0xb2, 0x78, 0xba, 0xd1, 0x22, 0xde,
413 0xc4, 0x6b, 0xbe, 0x83, 0x71, 0x0f, 0xee, 0x38,
414 0x4a, 0x9f, 0xda, 0x90, 0x93, 0x6b, 0x9a, 0xf2,
415 0xeb, 0x23, 0xfe, 0x41, 0x3f, 0xf1, 0xfc, 0xee,
416 0x7f, 0x67, 0xa7, 0xb8, 0xab, 0x29, 0xf4, 0x75,
417 0x1c, 0xe9, 0xd1, 0x47, 0x7d, 0x86, 0x44, 0xe2 };
418
419static const unsigned char seed2[] = { 0x00,
420 0xbc, 0xae, 0xc4, 0xea, 0x4e, 0xd2, 0xed, 0x1c,
421 0x8d, 0x48, 0xed, 0xf2, 0xa5, 0xb4, 0x18, 0xba,
422 0x00, 0xcb, 0x9c, 0x75, 0x8a, 0x39, 0x94, 0x3b,
423 0xd0, 0xd6, 0x01, 0xf7, 0xc1, 0xf5, 0x9d, 0xe5,
424 0xe3, 0xb4, 0x1d, 0xf5, 0x30, 0xfe, 0x99, 0xe4,
425 0x01, 0xab, 0xc0, 0x88, 0x4e, 0x67, 0x8f, 0xc6,
426 0x72, 0x39, 0x2e, 0xac, 0x51, 0xec, 0x91, 0x41,
427 0x47, 0x71, 0x14, 0x8a, 0x1d, 0xca, 0x88, 0x15,
428 0xea, 0xc9, 0x48, 0x9a, 0x71, 0x50, 0x19, 0x38,
429 0xdb, 0x4e, 0x65, 0xd5, 0x13, 0xd8, 0x2a, 0xc4,
430 0xcd, 0xfd, 0x0c, 0xe3, 0xc3, 0x60, 0xae, 0x6d,
431 0x88, 0xf2, 0x3a, 0xd0, 0x64, 0x73, 0x32, 0x89,
432 0xcd, 0x0b, 0xb8, 0xc7, 0xa5, 0x27, 0x84, 0xd5,
433 0x83, 0x3f, 0x0e, 0x10, 0x63, 0x10, 0x78, 0xac,
434 0x6b, 0x56, 0xb2, 0x62, 0x3a, 0x44, 0x56, 0xc0,
435 0xe4, 0x33, 0xd7, 0x63, 0x4c, 0xc9, 0x6b, 0xae,
436 0xfb, 0xe2, 0x9b, 0xf4, 0x96, 0xc7, 0xf0, 0x2a,
437 0x50, 0xde, 0x86, 0x69, 0x4f, 0x42, 0x4b, 0x1c,
438 0x7c, 0xa8, 0x6a, 0xfb, 0x54, 0x47, 0x1b, 0x41,
439 0x31, 0x9e, 0x0a, 0xc6, 0xc0, 0xbc, 0x88, 0x7f,
440 0x5a, 0x42, 0xa9, 0x82, 0x58, 0x32, 0xb3, 0xeb,
441 0x54, 0x83, 0x84, 0x26, 0x92, 0xa6, 0xc0, 0x6e,
442 0x2b, 0xa6, 0x82, 0x82, 0x43, 0x58, 0x84, 0x53,
443 0x31, 0xcf, 0xd0, 0x0a, 0x11, 0x09, 0x44, 0xc8,
444 0x11, 0x36, 0xe0, 0x04, 0x85, 0x2e, 0xd1, 0x29,
445 0x6b, 0x7b, 0x00, 0x71, 0x5f, 0xef, 0x7b, 0x7a,
446 0x2d, 0x91, 0xf9, 0x84, 0x45, 0x4d, 0xc7, 0xe1,
447 0xee, 0xd4, 0xb8, 0x61, 0x3b, 0x13, 0xb7, 0xba,
448 0x95, 0x39, 0xf6, 0x3d, 0x89, 0xbd, 0xa5, 0x80,
449 0x93, 0xf7, 0xe5, 0x17, 0x05, 0xc5, 0x65, 0xb7,
450 0xde, 0xc9, 0x9f, 0x04, 0x87, 0xcf, 0x4f, 0x86,
451 0xc3, 0x29, 0x7d, 0xb7, 0x89, 0xbf, 0xe3, 0xde };
452
453static const unsigned int counter2=210;
454 */
455
456struct tuple_str {
457 CK_RV errNum;
458 const char *errString;
459};
460
461typedef struct tuple_str tuple_str;
462
463static const tuple_str errStrings[] = {
464 { CKR_OK0x00000000UL, "CKR_OK " },
465 { CKR_CANCEL0x00000001UL, "CKR_CANCEL " },
466 { CKR_HOST_MEMORY0x00000002UL, "CKR_HOST_MEMORY " },
467 { CKR_SLOT_ID_INVALID0x00000003UL, "CKR_SLOT_ID_INVALID " },
468 { CKR_GENERAL_ERROR0x00000005UL, "CKR_GENERAL_ERROR " },
469 { CKR_FUNCTION_FAILED0x00000006UL, "CKR_FUNCTION_FAILED " },
470 { CKR_ARGUMENTS_BAD0x00000007UL, "CKR_ARGUMENTS_BAD " },
471 { CKR_NO_EVENT0x00000008UL, "CKR_NO_EVENT " },
472 { CKR_NEED_TO_CREATE_THREADS0x00000009UL, "CKR_NEED_TO_CREATE_THREADS " },
473 { CKR_CANT_LOCK0x0000000AUL, "CKR_CANT_LOCK " },
474 { CKR_ATTRIBUTE_READ_ONLY0x00000010UL, "CKR_ATTRIBUTE_READ_ONLY " },
475 { CKR_ATTRIBUTE_SENSITIVE0x00000011UL, "CKR_ATTRIBUTE_SENSITIVE " },
476 { CKR_ATTRIBUTE_TYPE_INVALID0x00000012UL, "CKR_ATTRIBUTE_TYPE_INVALID " },
477 { CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL, "CKR_ATTRIBUTE_VALUE_INVALID " },
478 { CKR_DATA_INVALID0x00000020UL, "CKR_DATA_INVALID " },
479 { CKR_DATA_LEN_RANGE0x00000021UL, "CKR_DATA_LEN_RANGE " },
480 { CKR_DEVICE_ERROR0x00000030UL, "CKR_DEVICE_ERROR " },
481 { CKR_DEVICE_MEMORY0x00000031UL, "CKR_DEVICE_MEMORY " },
482 { CKR_DEVICE_REMOVED0x00000032UL, "CKR_DEVICE_REMOVED " },
483 { CKR_ENCRYPTED_DATA_INVALID0x00000040UL, "CKR_ENCRYPTED_DATA_INVALID " },
484 { CKR_ENCRYPTED_DATA_LEN_RANGE0x00000041UL, "CKR_ENCRYPTED_DATA_LEN_RANGE " },
485 { CKR_FUNCTION_CANCELED0x00000050UL, "CKR_FUNCTION_CANCELED " },
486 { CKR_FUNCTION_NOT_PARALLEL0x00000051UL, "CKR_FUNCTION_NOT_PARALLEL " },
487 { CKR_FUNCTION_NOT_SUPPORTED0x00000054UL, "CKR_FUNCTION_NOT_SUPPORTED " },
488 { CKR_KEY_HANDLE_INVALID0x00000060UL, "CKR_KEY_HANDLE_INVALID " },
489 { CKR_KEY_SIZE_RANGE0x00000062UL, "CKR_KEY_SIZE_RANGE " },
490 { CKR_KEY_TYPE_INCONSISTENT0x00000063UL, "CKR_KEY_TYPE_INCONSISTENT " },
491 { CKR_KEY_NOT_NEEDED0x00000064UL, "CKR_KEY_NOT_NEEDED " },
492 { CKR_KEY_CHANGED0x00000065UL, "CKR_KEY_CHANGED " },
493 { CKR_KEY_NEEDED0x00000066UL, "CKR_KEY_NEEDED " },
494 { CKR_KEY_INDIGESTIBLE0x00000067UL, "CKR_KEY_INDIGESTIBLE " },
495 { CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL, "CKR_KEY_FUNCTION_NOT_PERMITTED " },
496 { CKR_KEY_NOT_WRAPPABLE0x00000069UL, "CKR_KEY_NOT_WRAPPABLE " },
497 { CKR_KEY_UNEXTRACTABLE0x0000006AUL, "CKR_KEY_UNEXTRACTABLE " },
498 { CKR_MECHANISM_INVALID0x00000070UL, "CKR_MECHANISM_INVALID " },
499 { CKR_MECHANISM_PARAM_INVALID0x00000071UL, "CKR_MECHANISM_PARAM_INVALID " },
500 { CKR_OBJECT_HANDLE_INVALID0x00000082UL, "CKR_OBJECT_HANDLE_INVALID " },
501 { CKR_OPERATION_ACTIVE0x00000090UL, "CKR_OPERATION_ACTIVE " },
502 { CKR_OPERATION_NOT_INITIALIZED0x00000091UL, "CKR_OPERATION_NOT_INITIALIZED " },
503 { CKR_PIN_INCORRECT0x000000A0UL, "CKR_PIN_INCORRECT " },
504 { CKR_PIN_INVALID0x000000A1UL, "CKR_PIN_INVALID " },
505 { CKR_PIN_LEN_RANGE0x000000A2UL, "CKR_PIN_LEN_RANGE " },
506 { CKR_PIN_EXPIRED0x000000A3UL, "CKR_PIN_EXPIRED " },
507 { CKR_PIN_LOCKED0x000000A4UL, "CKR_PIN_LOCKED " },
508 { CKR_SESSION_CLOSED0x000000B0UL, "CKR_SESSION_CLOSED " },
509 { CKR_SESSION_COUNT0x000000B1UL, "CKR_SESSION_COUNT " },
510 { CKR_SESSION_HANDLE_INVALID0x000000B3UL, "CKR_SESSION_HANDLE_INVALID " },
511 { CKR_SESSION_PARALLEL_NOT_SUPPORTED0x000000B4UL, "CKR_SESSION_PARALLEL_NOT_SUPPORTED " },
512 { CKR_SESSION_READ_ONLY0x000000B5UL, "CKR_SESSION_READ_ONLY " },
513 { CKR_SESSION_EXISTS0x000000B6UL, "CKR_SESSION_EXISTS " },
514 { CKR_SESSION_READ_ONLY_EXISTS0x000000B7UL, "CKR_SESSION_READ_ONLY_EXISTS " },
515 { CKR_SESSION_READ_WRITE_SO_EXISTS0x000000B8UL, "CKR_SESSION_READ_WRITE_SO_EXISTS " },
516 { CKR_SIGNATURE_INVALID0x000000C0UL, "CKR_SIGNATURE_INVALID " },
517 { CKR_SIGNATURE_LEN_RANGE0x000000C1UL, "CKR_SIGNATURE_LEN_RANGE " },
518 { CKR_TEMPLATE_INCOMPLETE0x000000D0UL, "CKR_TEMPLATE_INCOMPLETE " },
519 { CKR_TEMPLATE_INCONSISTENT0x000000D1UL, "CKR_TEMPLATE_INCONSISTENT " },
520 { CKR_TOKEN_NOT_PRESENT0x000000E0UL, "CKR_TOKEN_NOT_PRESENT " },
521 { CKR_TOKEN_NOT_RECOGNIZED0x000000E1UL, "CKR_TOKEN_NOT_RECOGNIZED " },
522 { CKR_TOKEN_WRITE_PROTECTED0x000000E2UL, "CKR_TOKEN_WRITE_PROTECTED " },
523 { CKR_UNWRAPPING_KEY_HANDLE_INVALID0x000000F0UL, "CKR_UNWRAPPING_KEY_HANDLE_INVALID " },
524 { CKR_UNWRAPPING_KEY_SIZE_RANGE0x000000F1UL, "CKR_UNWRAPPING_KEY_SIZE_RANGE " },
525 { CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT0x000000F2UL, "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT" },
526 { CKR_USER_ALREADY_LOGGED_IN0x00000100UL, "CKR_USER_ALREADY_LOGGED_IN " },
527 { CKR_USER_NOT_LOGGED_IN0x00000101UL, "CKR_USER_NOT_LOGGED_IN " },
528 { CKR_USER_PIN_NOT_INITIALIZED0x00000102UL, "CKR_USER_PIN_NOT_INITIALIZED " },
529 { CKR_USER_TYPE_INVALID0x00000103UL, "CKR_USER_TYPE_INVALID " },
530 { CKR_USER_ANOTHER_ALREADY_LOGGED_IN0x00000104UL, "CKR_USER_ANOTHER_ALREADY_LOGGED_IN " },
531 { CKR_USER_TOO_MANY_TYPES0x00000105UL, "CKR_USER_TOO_MANY_TYPES " },
532 { CKR_WRAPPED_KEY_INVALID0x00000110UL, "CKR_WRAPPED_KEY_INVALID " },
533 { CKR_WRAPPED_KEY_LEN_RANGE0x00000112UL, "CKR_WRAPPED_KEY_LEN_RANGE " },
534 { CKR_WRAPPING_KEY_HANDLE_INVALID0x00000113UL, "CKR_WRAPPING_KEY_HANDLE_INVALID " },
535 { CKR_WRAPPING_KEY_SIZE_RANGE0x00000114UL, "CKR_WRAPPING_KEY_SIZE_RANGE " },
536 { CKR_WRAPPING_KEY_TYPE_INCONSISTENT0x00000115UL, "CKR_WRAPPING_KEY_TYPE_INCONSISTENT " },
537 { CKR_RANDOM_SEED_NOT_SUPPORTED0x00000120UL, "CKR_RANDOM_SEED_NOT_SUPPORTED " },
538 { CKR_RANDOM_NO_RNG0x00000121UL, "CKR_RANDOM_NO_RNG " },
539 { CKR_DOMAIN_PARAMS_INVALID0x00000130UL, "CKR_DOMAIN_PARAMS_INVALID " },
540 { CKR_BUFFER_TOO_SMALL0x00000150UL, "CKR_BUFFER_TOO_SMALL " },
541 { CKR_SAVED_STATE_INVALID0x00000160UL, "CKR_SAVED_STATE_INVALID " },
542 { CKR_INFORMATION_SENSITIVE0x00000170UL, "CKR_INFORMATION_SENSITIVE " },
543 { CKR_STATE_UNSAVEABLE0x00000180UL, "CKR_STATE_UNSAVEABLE " },
544 { CKR_CRYPTOKI_NOT_INITIALIZED0x00000190UL, "CKR_CRYPTOKI_NOT_INITIALIZED " },
545 { CKR_CRYPTOKI_ALREADY_INITIALIZED0x00000191UL, "CKR_CRYPTOKI_ALREADY_INITIALIZED " },
546 { CKR_MUTEX_BAD0x000001A0UL, "CKR_MUTEX_BAD " },
547 { CKR_MUTEX_NOT_LOCKED0x000001A1UL, "CKR_MUTEX_NOT_LOCKED " },
548 { CKR_FUNCTION_REJECTED0x00000200UL, "CKR_FUNCTION_REJECTED " },
549 { CKR_VENDOR_DEFINED0x80000000UL, "CKR_VENDOR_DEFINED " },
550 { 0xCE534351, "CKR_NSS_CERTDB_FAILED " },
551 { 0xCE534352, "CKR_NSS_KEYDB_FAILED " }
552
553};
554
555static const CK_ULONG numStrings = sizeof(errStrings) / sizeof(tuple_str);
556
557/* Returns constant error string for "CRV".
558 * Returns "unknown error" if errNum is unknown.
559 */
560static const char *
561CK_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 /* make sure table is in ascending order.
570 * binary search depends on it.
571 */
572 if (!initDone) {
573 CK_RV lastNum = CKR_OK0x00000000UL;
574 for (i = low; i <= high; ++i) {
575 num = errStrings[i].errNum;
576 if (num <= lastNum) {
577 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError),
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 /* Do binary search of table. */
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
608static void
609pk11error(const char *string, CK_RV crv)
610{
611 PRErrorCode errorcode;
612
613 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "%s: 0x%08lX, %-26s\n", string, crv, CK_RVtoStr(crv));
614
615 errorcode = PR_GetError();
616 if (errorcode) {
617 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "NSPR error code: %d: %s\n", errorcode,
618 PR_ErrorToString(errorcode, PR_LANGUAGE_I_DEFAULT0));
619 }
620}
621
622static void
623logIt(const char *fmt, ...)
624{
625 va_list args;
626
627 if (verbose) {
628 va_start(args, fmt)__builtin_va_start(args, fmt);
629 vprintf(fmt, args);
630 va_end(args)__builtin_va_end(args);
631 }
632}
633
634static CK_RV
635softokn_Init(CK_FUNCTION_LIST_PTR pFunctionList, const char *configDir,
636 const char *dbPrefix)
637{
638
639 CK_RV crv = CKR_OK0x00000000UL;
640 CK_C_INITIALIZE_ARGS initArgs;
641 char *moduleSpec = NULL((void*)0);
642
643 initArgs.CreateMutex = NULL((void*)0);
644 initArgs.DestroyMutex = NULL((void*)0);
645 initArgs.LockMutex = NULL((void*)0);
646 initArgs.UnlockMutex = NULL((void*)0);
647 initArgs.flags = CKF_OS_LOCKING_OK0x00000002UL;
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_STDERRPR_GetSpecialFD(PR_StandardError), "softokn_Init: out of memory error\n");
658 return CKR_HOST_MEMORY0x00000002UL;
659 }
660 logIt("moduleSpec %s\n", moduleSpec);
661 initArgs.LibraryParameters = (CK_CHAR_PTR *)moduleSpec;
662 initArgs.pReserved = NULL((void*)0);
663
664 crv = pFunctionList->C_Initialize(&initArgs);
665 if (crv != CKR_OK0x00000000UL) {
666 pk11error("C_Initialize failed", crv);
667 goto cleanup;
668 }
669
670cleanup:
671 if (moduleSpec) {
672 PR_smprintf_free(moduleSpec);
673 }
674
675 return crv;
676}
677
678static char *
679filePasswd(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_RDONLY0x01, 0);
690 if (!fd) {
691 lperror(pwFile);
692 return NULL((void*)0);
693 }
694
695 nb = PR_Read(fd, phrase, sizeof(phrase));
696
697 PR_Close(fd);
698 /* handle the Windows EOL case */
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_STDERRPR_GetSpecialFD(PR_StandardError), "password file contains no data\n");
705 return NULL((void*)0);
706 }
707 return (char *)PL_strdup((char *)phrase);
708}
709
710static void
711checkPath(char *string)
712{
713 char *src;
714 char *dest;
715
716 /*
717 * windows support convert any back slashes to
718 * forward slashes.
719 */
720 for (src = string, dest = string; *src; src++, dest++) {
721 if (*src == '\\') {
722 *dest = '/';
723 }
724 }
725 dest--;
726 /* if the last char is a / set it to 0 */
727 if (*dest == '/')
728 *dest = 0;
729}
730
731static CK_SLOT_ID *
732getSlotList(CK_FUNCTION_LIST_PTR pFunctionList,
733 CK_ULONG slotIndex)
734{
735 CK_RV crv = CKR_OK0x00000000UL;
736 CK_SLOT_ID *pSlotList = NULL((void*)0);
737 CK_ULONG slotCount;
738
739 /* Get slot list */
740 crv = pFunctionList->C_GetSlotList(CK_FALSE0 /* all slots */,
741 NULL((void*)0), &slotCount);
742 if (crv != CKR_OK0x00000000UL) {
743 pk11error("C_GetSlotList failed", crv);
744 return NULL((void*)0);
745 }
746
747 if (slotIndex >= slotCount) {
748 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "provided slotIndex is greater than the slot count.");
749 return NULL((void*)0);
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((void*)0);
756 }
757 crv = pFunctionList->C_GetSlotList(CK_FALSE0 /* all slots */,
758 pSlotList, &slotCount);
759 if (crv != CKR_OK0x00000000UL) {
760 pk11error("C_GetSlotList failed", crv);
761 if (pSlotList)
762 PR_Free(pSlotList);
763 return NULL((void*)0);
764 }
765 return pSlotList;
766}
767
768CK_RV
769shlibSignDSA(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_MAX64];
776 CK_BYTE sign[64]; /* DSA2 SIGNATURE LENGTH */
777 CK_ULONG signLen = 0;
778 CK_ULONG expectedSigLen = sizeof(sign);
779 CK_MECHANISM signMech = {
780 CKM_DSA0x00000011UL, NULL((void*)0), 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_ERROR0x00000005UL;
788 PRStatus rv = PR_SUCCESS;
789 const char *hashName = "sha256"; /* default hash value */
790 int i;
791
792 /*** DSA Key ***/
793 CK_MECHANISM dsaKeyPairGenMech;
794 CK_ATTRIBUTE dsaPubKeyTemplate[5];
795 CK_ATTRIBUTE dsaPrivKeyTemplate[5];
796 CK_OBJECT_HANDLE hDSApubKey = CK_INVALID_HANDLE0;
797 CK_OBJECT_HANDLE hDSAprivKey = CK_INVALID_HANDLE0;
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_DSA0x00000011UL, &mechInfo);
805 if (crv != CKR_OK0x00000000UL) {
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_STDERRPR_GetSpecialFD(PR_StandardError),
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 /* DSA key init */
825 if (keySize == 1024) {
826 dsaPubKeyTemplate[0].type = CKA_PRIME0x00000130UL;
827 dsaPubKeyTemplate[0].pValue = (CK_VOID_PTR)&prime;
828 dsaPubKeyTemplate[0].ulValueLen = sizeof(prime);
829 dsaPubKeyTemplate[1].type = CKA_SUBPRIME0x00000131UL;
830 dsaPubKeyTemplate[1].pValue = (CK_VOID_PTR)&subprime;
831 dsaPubKeyTemplate[1].ulValueLen = sizeof(subprime);
832 dsaPubKeyTemplate[2].type = CKA_BASE0x00000132UL;
833 dsaPubKeyTemplate[2].pValue = (CK_VOID_PTR)&base;
834 dsaPubKeyTemplate[2].ulValueLen = sizeof(base);
835 hashName = "sha-1"; /* use sha-1 for old dsa keys */
836 expectedSigLen = 32;
837 } else if (keySize == 2048) {
838 dsaPubKeyTemplate[0].type = CKA_PRIME0x00000130UL;
839 dsaPubKeyTemplate[0].pValue = (CK_VOID_PTR)&prime2;
840 dsaPubKeyTemplate[0].ulValueLen = sizeof(prime2);
841 dsaPubKeyTemplate[1].type = CKA_SUBPRIME0x00000131UL;
842 dsaPubKeyTemplate[1].pValue = (CK_VOID_PTR)&subprime2;
843 dsaPubKeyTemplate[1].ulValueLen = sizeof(subprime2);
844 dsaPubKeyTemplate[2].type = CKA_BASE0x00000132UL;
845 dsaPubKeyTemplate[2].pValue = (CK_VOID_PTR)&base2;
846 dsaPubKeyTemplate[2].ulValueLen = sizeof(base2);
847 digestmech.mechanism = hash ? hash->hash : CKM_SHA2560x00000250UL;
848 digestmech.pParameter = NULL((void*)0);
849 digestmech.ulParameterLen = 0;
850 } else {
851 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "Only keysizes 1024 and 2048 are supported");
852 return CKR_GENERAL_ERROR0x00000005UL;
853 }
854 if (hash == NULL((void*)0)) {
855 hash = findHash(hashName);
856 }
857 if (hash == NULL((void*)0)) {
858 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError),
859 "Internal error, couldn't find hash '%s' in table.\n",
860 hashName);
861 return CKR_GENERAL_ERROR0x00000005UL;
862 }
863 digestmech.mechanism = hash->hash;
864 digestmech.pParameter = NULL((void*)0);
865 digestmech.ulParameterLen = 0;
866 dsaPubKeyTemplate[3].type = CKA_TOKEN0x00000001UL;
867 dsaPubKeyTemplate[3].pValue = &ckfalse; /* session object */
868 dsaPubKeyTemplate[3].ulValueLen = sizeof(ckfalse);
869 dsaPubKeyTemplate[4].type = CKA_VERIFY0x0000010AUL;
870 dsaPubKeyTemplate[4].pValue = &cktrue;
871 dsaPubKeyTemplate[4].ulValueLen = sizeof(cktrue);
872 dsaKeyPairGenMech.mechanism = CKM_DSA_KEY_PAIR_GEN0x00000010UL;
873 dsaKeyPairGenMech.pParameter = NULL((void*)0);
874 dsaKeyPairGenMech.ulParameterLen = 0;
875 dsaPrivKeyTemplate[0].type = CKA_TOKEN0x00000001UL;
876 dsaPrivKeyTemplate[0].pValue = &ckfalse; /* session object */
877 dsaPrivKeyTemplate[0].ulValueLen = sizeof(ckfalse);
878 dsaPrivKeyTemplate[1].type = CKA_PRIVATE0x00000002UL;
879 dsaPrivKeyTemplate[1].pValue = &cktrue;
880 dsaPrivKeyTemplate[1].ulValueLen = sizeof(cktrue);
881 dsaPrivKeyTemplate[2].type = CKA_SENSITIVE0x00000103UL;
882 dsaPrivKeyTemplate[2].pValue = &cktrue;
883 dsaPrivKeyTemplate[2].ulValueLen = sizeof(cktrue);
884 dsaPrivKeyTemplate[3].type = CKA_SIGN0x00000108UL,
885 dsaPrivKeyTemplate[3].pValue = &cktrue;
886 dsaPrivKeyTemplate[3].ulValueLen = sizeof(cktrue);
887 dsaPrivKeyTemplate[4].type = CKA_EXTRACTABLE0x00000162UL;
888 dsaPrivKeyTemplate[4].pValue = &ckfalse;
889 dsaPrivKeyTemplate[4].ulValueLen = sizeof(ckfalse);
890
891 /* Generate a DSA key pair */
892 logIt("Generate a DSA key pair ... \n");
893 crv = pFunctionList->C_GenerateKeyPair(hRwSession, &dsaKeyPairGenMech,
894 dsaPubKeyTemplate,
895 PR_ARRAY_SIZE(dsaPubKeyTemplate)(sizeof(dsaPubKeyTemplate)/sizeof((dsaPubKeyTemplate)[0])),
896 dsaPrivKeyTemplate,
897 PR_ARRAY_SIZE(dsaPrivKeyTemplate)(sizeof(dsaPrivKeyTemplate)/sizeof((dsaPrivKeyTemplate)[0])),
898 &hDSApubKey, &hDSAprivKey);
899 if (crv != CKR_OK0x00000000UL) {
900 pk11error("DSA key pair generation failed", crv);
901 return crv;
902 }
903
904 /* compute the digest */
905 memset(digest, 0, sizeof(digest));
906 crv = pFunctionList->C_DigestInit(hRwSession, &digestmech);
907 if (crv != CKR_OK0x00000000UL) {
908 pk11error("C_DigestInit failed", crv);
909 return crv;
910 }
911
912 /* Digest the file */
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_OK0x00000000UL) {
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_FAILURE0x80222222;
926 }
927
928 digestLen = sizeof(digest);
929 crv = pFunctionList->C_DigestFinal(hRwSession, (CK_BYTE_PTR)digest,
930 &digestLen);
931 if (crv != CKR_OK0x00000000UL) {
932 pk11error("C_DigestFinal failed", crv);
933 return crv;
934 }
935
936 if (digestLen != hash->hashLength) {
937 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "digestLen has incorrect length %lu "
938 "it should be %lu \n",
939 digestLen, sizeof(digest));
940 return crv;
941 }
942
943 /* sign the hash */
944 memset(sign, 0, sizeof(sign));
945 /* SignUpdate */
946 crv = pFunctionList->C_SignInit(hRwSession, &signMech, hDSAprivKey);
947 if (crv != CKR_OK0x00000000UL) {
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_OK0x00000000UL) {
956 pk11error("C_Sign failed", crv);
957 return crv;
958 }
959
960 if (signLen != expectedSigLen) {
961 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "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_OK0x00000000UL) {
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_OK0x00000000UL) {
976 pk11error("C_Verify failed", crv);
977 return crv;
978 }
979 }
980
981 if (verbose) {
982 int j;
983 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "Library File Size: %d bytes\n", count);
984 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), " hash: %lu bytes\n", digestLen);
985#define STEP10 10
986 for (i = 0; i < (int)digestLen; i += STEP10) {
987 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), " ");
988 for (j = 0; j < STEP10 && (i + j) < (int)digestLen; j++) {
989 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), " %02x", digest[i + j]);
990 }
991 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "\n");
992 }
993 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), " signature: %lu bytes\n", signLen);
994 for (i = 0; i < (int)signLen; i += STEP10) {
995 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), " ");
996 for (j = 0; j < STEP10 && (i + j) < (int)signLen; j++) {
997 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), " %02x", sign[i + j]);
998 }
999 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "\n");
1000 }
1001 }
1002
1003 /*
1004 * we write the key out in a straight binary format because very
1005 * low level libraries need to read an parse this file. Ideally we should
1006 * just derEncode the public key (which would be pretty simple, and be
1007 * more general), but then we'd need to link the ASN.1 decoder with the
1008 * freebl libraries.
1009 */
1010
1011 header.magic1 = NSS_SIGN_CHK_MAGIC10xf1;
1012 header.magic2 = NSS_SIGN_CHK_MAGIC20xc5;
1013 header.majorVersion = compat ? COMPAT_MAJOR0x01 : NSS_SIGN_CHK_MAJOR_VERSION0x02;
1014 header.minorVersion = compat ? COMPAT_MINOR0x02 : NSS_SIGN_CHK_MINOR_VERSION0x01;
1015 encodeInt(header.offset, sizeof(header)); /* offset to data start */
1016 encodeInt(header.type, CKK_DSA0x00000001UL);
1017 bytesWritten = PR_Write(ofd, &header, sizeof(header));
1018 if (bytesWritten != sizeof(header)) {
1019 return CKR_INTERNAL_OUT_FAILURE0x80111111;
1020 }
1021
1022 /* get DSA Public KeyValue */
1023 memset(dsaPubKey, 0, sizeof(dsaPubKey));
1024 dsaPubKeyValue.type = CKA_VALUE0x00000011UL;
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_OK0x00000000UL && crv != CKR_ATTRIBUTE_TYPE_INVALID0x00000012UL) {
1031 pk11error("C_GetAttributeValue failed", crv);
1032 return crv;
1033 }
1034
1035 /* CKA_PRIME */
1036 rv = writeItem(ofd, dsaPubKeyTemplate[0].pValue,
1037 dsaPubKeyTemplate[0].ulValueLen);
1038 if (rv != PR_SUCCESS) {
1039 return CKR_INTERNAL_OUT_FAILURE0x80111111;
1040 }
1041 /* CKA_SUBPRIME */
1042 rv = writeItem(ofd, dsaPubKeyTemplate[1].pValue,
1043 dsaPubKeyTemplate[1].ulValueLen);
1044 if (rv != PR_SUCCESS) {
1045 return CKR_INTERNAL_OUT_FAILURE0x80111111;
1046 }
1047 /* CKA_BASE */
1048 rv = writeItem(ofd, dsaPubKeyTemplate[2].pValue,
1049 dsaPubKeyTemplate[2].ulValueLen);
1050 if (rv != PR_SUCCESS) {
1051 return CKR_INTERNAL_OUT_FAILURE0x80111111;
1052 }
1053 /* DSA Public Key value */
1054 rv = writeItem(ofd, dsaPubKeyValue.pValue,
1055 dsaPubKeyValue.ulValueLen);
1056 if (rv != PR_SUCCESS) {
1057 return CKR_INTERNAL_OUT_FAILURE0x80111111;
1058 }
1059 /* DSA SIGNATURE */
1060 rv = writeItem(ofd, &sign, signLen);
1061 if (rv != PR_SUCCESS) {
1062 return CKR_INTERNAL_OUT_FAILURE0x80111111;
1063 }
1064
1065 return CKR_OK0x00000000UL;
1066}
1067
1068CK_RV
1069shlibSignHMAC(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((void*)0), 0 };
1074 CK_MECHANISM hmacKeyGenMech = { 0, NULL((void*)0), 0 };
1075 CK_BYTE keyBuf[HASH_LENGTH_MAX64];
1076 CK_ULONG keyLen = 0;
1077 CK_BYTE sign[HASH_LENGTH_MAX64];
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_ERROR0x00000005UL;
1085 PRStatus rv = PR_SUCCESS;
1086 int i;
1087
1088 /*** HMAC Key ***/
1089 CK_ATTRIBUTE hmacKeyTemplate[7];
1090 CK_ATTRIBUTE hmacKeyValue;
1091 CK_OBJECT_HANDLE hHMACKey = CK_INVALID_HANDLE0;
1092
1093 if (hash
48.1
'hash' is equal to NULL
== NULL((void*)0)) {
49
Taking true branch
1094 hash = findHash("sha256");
50
Value assigned to 'hash'
1095 }
1096 if (hash == NULL((void*)0)) {
51
Assuming 'hash' is equal to NULL
52
Taking true branch
1097 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError),
1098 "Internal error:Could find sha256 entry in table.\n");
1099 }
1100
1101 hmacKeyTemplate[0].type = CKA_TOKEN0x00000001UL;
1102 hmacKeyTemplate[0].pValue = &ckfalse; /* session object */
1103 hmacKeyTemplate[0].ulValueLen = sizeof(ckfalse);
1104 hmacKeyTemplate[1].type = CKA_PRIVATE0x00000002UL;
1105 hmacKeyTemplate[1].pValue = &cktrue;
1106 hmacKeyTemplate[1].ulValueLen = sizeof(cktrue);
1107 hmacKeyTemplate[2].type = CKA_SENSITIVE0x00000103UL;
1108 hmacKeyTemplate[2].pValue = &ckfalse;
1109 hmacKeyTemplate[2].ulValueLen = sizeof(cktrue);
1110 hmacKeyTemplate[3].type = CKA_SIGN0x00000108UL;
1111 hmacKeyTemplate[3].pValue = &cktrue;
1112 hmacKeyTemplate[3].ulValueLen = sizeof(cktrue);
1113 hmacKeyTemplate[4].type = CKA_EXTRACTABLE0x00000162UL;
1114 hmacKeyTemplate[4].pValue = &ckfalse;
1115 hmacKeyTemplate[4].ulValueLen = sizeof(ckfalse);
1116 hmacKeyTemplate[5].type = CKA_VALUE_LEN0x00000161UL;
1117 hmacKeyTemplate[5].pValue = (void *)&hash->hashLength;
1118 hmacKeyTemplate[5].ulValueLen = sizeof(hash->hashLength);
1119 hmacKeyTemplate[6].type = CKA_KEY_TYPE0x00000100UL;
1120 hmacKeyTemplate[6].pValue = (void *)&hash->keyType;
1121 hmacKeyTemplate[6].ulValueLen = sizeof(hash->keyType);
1122 hmacKeyGenMech.mechanism = CKM_GENERIC_SECRET_KEY_GEN0x00000350UL;
1123 hmacMech.mechanism = hash->hmac;
53
Access to field 'hmac' results in a dereference of a null pointer (loaded from variable 'hash')
1124
1125 /* Generate a DSA key pair */
1126 logIt("Generate an HMAC key ... \n");
1127 crv = pFunctionList->C_GenerateKey(hRwSession, &hmacKeyGenMech,
1128 hmacKeyTemplate,
1129 PR_ARRAY_SIZE(hmacKeyTemplate)(sizeof(hmacKeyTemplate)/sizeof((hmacKeyTemplate)[0])),
1130 &hHMACKey);
1131 if (crv != CKR_OK0x00000000UL) {
1132 pk11error("HMAC key generation failed", crv);
1133 return crv;
1134 }
1135
1136 /* compute the digest */
1137 memset(sign, 0, sizeof(sign));
1138 crv = pFunctionList->C_SignInit(hRwSession, &hmacMech, hHMACKey);
1139 if (crv != CKR_OK0x00000000UL) {
1140 pk11error("C_SignInit failed", crv);
1141 return crv;
1142 }
1143
1144 /* Digest the file */
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_OK0x00000000UL) {
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_FAILURE0x80222222;
1158 }
1159
1160 signLen = sizeof(sign);
1161 crv = pFunctionList->C_SignFinal(hRwSession, (CK_BYTE_PTR)sign,
1162 &signLen);
1163 if (crv != CKR_OK0x00000000UL) {
1164 pk11error("C_SignFinal failed", crv);
1165 return crv;
1166 }
1167
1168 if (signLen != hash->hashLength) {
1169 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "digestLen has incorrect length %lu "
1170 "it should be %lu \n",
1171 signLen, hash->hashLength);
1172 return crv;
1173 }
1174 /* get HMAC KeyValue */
1175 memset(keyBuf, 0, sizeof(keyBuf));
1176 hmacKeyValue.type = CKA_VALUE0x00000011UL;
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_OK0x00000000UL && crv != CKR_ATTRIBUTE_TYPE_INVALID0x00000012UL) {
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_STDERRPR_GetSpecialFD(PR_StandardError), "Library File Size: %d bytes\n", count);
1191 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), " key: %lu bytes\n", keyLen);
1192#define STEP10 10
1193 for (i = 0; i < (int)keyLen; i += STEP10) {
1194 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), " ");
1195 for (j = 0; j < STEP10 && (i + j) < (int)keyLen; j++) {
1196 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), " %02x", keyBuf[i + j]);
1197 }
1198 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "\n");
1199 }
1200 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), " signature: %lu bytes\n", signLen);
1201 for (i = 0; i < (int)signLen; i += STEP10) {
1202 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), " ");
1203 for (j = 0; j < STEP10 && (i + j) < (int)signLen; j++) {
1204 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), " %02x", sign[i + j]);
1205 }
1206 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "\n");
1207 }
1208 }
1209
1210 /*
1211 * we write the key out in a straight binary format because very
1212 * low level libraries need to read an parse this file. Ideally we should
1213 * just derEncode the public key (which would be pretty simple, and be
1214 * more general), but then we'd need to link the ASN.1 decoder with the
1215 * freebl libraries.
1216 */
1217
1218 header.magic1 = NSS_SIGN_CHK_MAGIC10xf1;
1219 header.magic2 = NSS_SIGN_CHK_MAGIC20xc5;
1220 header.majorVersion = NSS_SIGN_CHK_MAJOR_VERSION0x02;
1221 header.minorVersion = NSS_SIGN_CHK_MINOR_VERSION0x01;
1222 encodeInt(header.offset, sizeof(header)); /* offset to data start */
1223 encodeInt(header.type, NSS_SIGN_CHK_FLAG_HMAC0x80000000 | hash->hashType);
1224 bytesWritten = PR_Write(ofd, &header, sizeof(header));
1225 if (bytesWritten != sizeof(header)) {
1226 return CKR_INTERNAL_OUT_FAILURE0x80111111;
1227 }
1228
1229 /* HMACKey */
1230 rv = writeItem(ofd, keyBuf, keyLen);
1231 if (rv != PR_SUCCESS) {
1232 return CKR_INTERNAL_OUT_FAILURE0x80111111;
1233 }
1234 /* HMAC SIGNATURE */
1235 rv = writeItem(ofd, &sign, signLen);
1236 if (rv != PR_SUCCESS) {
1237 return CKR_INTERNAL_OUT_FAILURE0x80111111;
1238 }
1239
1240 return CKR_OK0x00000000UL;
1241}
1242
1243int
1244main(int argc, char **argv)
1245{
1246 PLOptState *optstate;
1247 char *program_name;
1248 char *libname = NULL((void*)0);
1249 PRLibrary *lib = NULL((void*)0);
1250 PRFileDesc *ifd = NULL((void*)0);
1251 PRFileDesc *ofd = NULL((void*)0);
1252 const char *input_file = NULL((void*)0); /* read/create encrypted data from here */
1253 char *output_file = NULL((void*)0); /* write new encrypted data here */
1254 unsigned int keySize = 0;
1255 static PRBool FIPSMODE = PR_FALSE0;
1256 static PRBool useDSA = PR_FALSE0;
1257 PRBool successful = PR_FALSE0;
1258 const HashTable *hash = NULL((void*)0);
1259
1260#ifdef USES_LINKS1
1261 int ret;
1262 struct stat stat_buf;
1263 char link_buf[MAXPATHLEN4096 + 1];
1264 char *link_file = NULL((void*)0);
1265#endif
1266
1267 char *pwd = NULL((void*)0);
1268 char *configDir = NULL((void*)0);
1269 char *dbPrefix = NULL((void*)0);
1270 char *disableUnload = NULL((void*)0);
1271
1272 CK_C_GetFunctionList pC_GetFunctionList;
1273 CK_TOKEN_INFO tokenInfo;
1274 CK_FUNCTION_LIST_PTR pFunctionList = NULL((void*)0);
1275 CK_RV crv = CKR_OK0x00000000UL;
1276 CK_SESSION_HANDLE hRwSession;
1277 CK_SLOT_ID *pSlotList = NULL((void*)0);
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
2
'?' condition is true
1282 optstate = PL_CreateOptState(argc, argv, "i:o:f:Fd:hH?k:p:P:vVs:t:Dc");
1283 if (optstate == NULL((void*)0)) {
3
Assuming 'optstate' is not equal to NULL
4
Taking false branch
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_TRUE1;
1302 break;
1303
1304 case 'c':
1305 compat = PR_TRUE1;
1306 break;
1307
1308 case 'i':
1309 if (!optstate->value) {
8
Assuming field 'value' is non-null
9
Taking false branch
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_TRUE1;
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((void*)0)) {
1369 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "Invalid hash '%s'\n",
1370 optstate->value);
1371 usage(program_name);
1372 }
1373 break;
1374 case 'v':
1375 verbose = PR_TRUE1;
1376 break;
1377
1378 case 'V':
1379 verify = PR_TRUE1;
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
12.1
'input_file' is non-null
) {
13
Taking false branch
1400 usage(program_name);
1401 return 1;
1402 }
1403
1404 /* Get the platform-dependent library name of the
1405 * NSS cryptographic module.
1406 */
1407 libname = PR_GetLibraryName(NULL((void*)0), "softokn3");
1408 assert(libname != NULL)((libname != ((void*)0)) ? (void) (0) : __assert_fail ("libname != NULL"
, "shlibsign.c", 1408, __extension__ __PRETTY_FUNCTION__))
;
14
Assuming 'libname' is not equal to null
15
'?' condition is true
1409 if (!libname
15.1
'libname' is non-null
) {
16
Taking false branch
1410 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "getting softokn3 failed");
1411 goto cleanup;
1412 }
1413 lib = PR_LoadLibrary(libname);
1414 assert(lib != NULL)((lib != ((void*)0)) ? (void) (0) : __assert_fail ("lib != NULL"
, "shlibsign.c", 1414, __extension__ __PRETTY_FUNCTION__))
;
17
Assuming 'lib' is not equal to null
18
'?' condition is true
1415 if (!lib
18.1
'lib' is non-null
) {
19
Taking false branch
1416 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "loading softokn3 failed");
1417 goto cleanup;
1418 }
1419 PR_FreeLibraryName(libname);
1420
1421 if (FIPSMODE
19.1
'FIPSMODE' is 0
) {
20
Taking false branch
1422 /* FIPSMODE == FC_GetFunctionList */
1423 /* library path must be set to an already signed softokn3/freebl */
1424 pC_GetFunctionList = (CK_C_GetFunctionList)
1425 PR_FindFunctionSymbol(lib, "FC_GetFunctionList");
1426 } else {
1427 /* NON FIPS mode == C_GetFunctionList */
1428 pC_GetFunctionList = (CK_C_GetFunctionList)
1429 PR_FindFunctionSymbol(lib, "C_GetFunctionList");
1430 }
1431 assert(pC_GetFunctionList != NULL)((pC_GetFunctionList != ((void*)0)) ? (void) (0) : __assert_fail
("pC_GetFunctionList != NULL", "shlibsign.c", 1431, __extension__
__PRETTY_FUNCTION__))
;
21
Assuming 'pC_GetFunctionList' is not equal to null
22
'?' condition is true
1432 if (!pC_GetFunctionList
22.1
'pC_GetFunctionList' is non-null
) {
23
Taking false branch
1433 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "getting function list failed");
1434 goto cleanup;
1435 }
1436
1437 crv = (*pC_GetFunctionList)(&pFunctionList);
1438 assert(crv == CKR_OK)((crv == 0x00000000UL) ? (void) (0) : __assert_fail ("crv == CKR_OK"
, "shlibsign.c", 1438, __extension__ __PRETTY_FUNCTION__))
;
24
Assuming 'crv' is equal to 0
25
'?' condition is true
1439 if (crv
25.1
'crv' is equal to CKR_OK
!= CKR_OK0x00000000UL) {
26
Taking false branch
1440 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "loading function list failed");
1441 goto cleanup;
1442 }
1443
1444 if (configDir
26.1
'configDir' is null
) {
27
Taking false branch
1445 if (!dbPrefix) {
1446 dbPrefix = PL_strdup("");
1447 }
1448 crv = softokn_Init(pFunctionList, configDir, dbPrefix);
1449 if (crv != CKR_OK0x00000000UL) {
1450 logIt("Failed to use provided database directory "
1451 "will just initialize the volatile certdb.\n");
1452 crv = softokn_Init(pFunctionList, NULL((void*)0), NULL((void*)0)); /* NoDB Init */
1453 }
1454 } else {
1455 crv = softokn_Init(pFunctionList, NULL((void*)0), NULL((void*)0)); /* NoDB Init */
1456 }
1457
1458 if (crv
27.1
'crv' is equal to CKR_OK
!= CKR_OK0x00000000UL) {
28
Taking false branch
1459 pk11error("Initiailzing softoken failed", crv);
1460 goto cleanup;
1461 }
1462
1463 pSlotList = getSlotList(pFunctionList, slotIndex);
1464 if (pSlotList
28.1
'pSlotList' is not equal to NULL
== NULL((void*)0)) {
29
Taking false branch
1465 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "getSlotList failed");
1466 goto cleanup;
1467 }
1468
1469 crv = pFunctionList->C_OpenSession(pSlotList[slotIndex],
1470 CKF_RW_SESSION0x00000002UL | CKF_SERIAL_SESSION0x00000004UL,
1471 NULL((void*)0), NULL((void*)0), &hRwSession);
1472 if (crv != CKR_OK0x00000000UL) {
30
Assuming 'crv' is equal to CKR_OK
31
Taking false branch
1473 pk11error("Opening a read/write session failed", crv);
1474 goto cleanup;
1475 }
1476
1477 /* check if a password is needed */
1478 crv = pFunctionList->C_GetTokenInfo(pSlotList[slotIndex], &tokenInfo);
1479 if (crv != CKR_OK0x00000000UL) {
32
Assuming 'crv' is equal to CKR_OK
33
Taking false branch
1480 pk11error("C_GetTokenInfo failed", crv);
1481 goto cleanup;
1482 }
1483 if (tokenInfo.flags & CKF_LOGIN_REQUIRED0x00000004UL) {
34
Assuming the condition is false
35
Taking false branch
1484 if (pwd) {
1485 int pwdLen = strlen((const char *)pwd);
1486 crv = pFunctionList->C_Login(hRwSession, CKU_USER1,
1487 (CK_UTF8CHAR_PTR)pwd, (CK_ULONG)pwdLen);
1488 if (crv != CKR_OK0x00000000UL) {
1489 pk11error("C_Login failed", crv);
1490 goto cleanup;
1491 }
1492 } else {
1493 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "Please provide the password for the token");
1494 goto cleanup;
1495 }
1496 } else if (pwd
35.1
'pwd' is null
) {
36
Taking false branch
1497 logIt("A password was provided but the password was not used.\n");
1498 }
1499
1500 /* open the shared library */
1501 ifd = PR_OpenFile(input_file, PR_RDONLY0x01, 0);
1502 if (ifd == NULL((void*)0)) {
37
Assuming 'ifd' is not equal to NULL
38
Taking false branch
1503 lperror(input_file);
1504 goto cleanup;
1505 }
1506#ifdef USES_LINKS1
1507 ret = lstat(input_file, &stat_buf);
1508 if (ret < 0) {
39
Assuming 'ret' is >= 0
40
Taking false branch
1509 perror(input_file);
1510 goto cleanup;
1511 }
1512 if (S_ISLNK(stat_buf.st_mode)((((stat_buf.st_mode)) & 0170000) == (0120000))) {
41
Assuming the condition is false
42
Taking false branch
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 /* get the dirname of input_file */
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 /* get the basename of link_file */
1535 dirend = strrchr(link_file, '/');
1536 if (dirend) {
1537 char *tmp_file = NULL((void*)0);
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
42.1
'output_file' is equal to NULL
== NULL((void*)0)) {
43
Taking true branch
1545 output_file = mkoutput(input_file);
1546 }
1547
1548 if (verbose
43.1
'verbose' is 0
) {
44
Taking false branch
1549 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "Library File: %s\n", input_file);
1550 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "Check File: %s\n", output_file);
1551#ifdef USES_LINKS1
1552 if (link_file) {
1553 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "Link: %s\n", link_file);
1554 }
1555#endif
1556 }
1557
1558 /* open the target signature file */
1559 ofd = PR_Open(output_file, PR_WRONLY0x02 | PR_CREATE_FILE0x08 | PR_TRUNCATE0x20, 0666);
1560 if (ofd == NULL((void*)0)) {
45
Assuming 'ofd' is not equal to NULL
46
Taking false branch
1561 lperror(output_file);
1562 goto cleanup;
1563 }
1564
1565 if (useDSA
46.1
'useDSA' is 0
) {
47
Taking false branch
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_FAILURE0x80111111) {
1573 lperror(output_file);
1574 }
1575 if (crv == CKR_INTERNAL_IN_FAILURE0x80222222) {
1576 lperror(input_file);
1577 }
1578
1579 PR_Close(ofd);
1580 ofd = NULL((void*)0);
1581 /* close the input_File */
1582 PR_Close(ifd);
1583 ifd = NULL((void*)0);
1584
1585#ifdef USES_LINKS1
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_TRUE1;
1596
1597cleanup:
1598 if (pFunctionList) {
1599 /* C_Finalize will automatically logout, close session, */
1600 /* and delete the temp objects on the token */
1601 crv = pFunctionList->C_Finalize(NULL((void*)0));
1602 if (crv != CKR_OK0x00000000UL) {
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) { /* allocated by mkoutput function */
1619 PL_strfree(output_file);
1620 }
1621#ifdef USES_LINKS1
1622 if (link_file) { /* allocated by mkoutput function */
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_OK0x00000000UL)
1640 return crv;
1641
1642 return (successful) ? 0 : 1;
1643}