~ubuntu-branches/ubuntu/precise/nss/precise-security

« back to all changes in this revision

Viewing changes to .pc/85_security_load.patch/nss/cmd/shlibsign/shlibsign.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2013-11-14 14:58:07 UTC
  • mfrom: (1.1.19)
  • Revision ID: package-import@ubuntu.com-20131114145807-ay302kimn72ovt88
Tags: 3.15.3-0ubuntu0.12.04.1
* SECURITY UPDATE: New upstream release to fix multiple security issues
  and add TLSv1.2 support.
  - CVE-2013-1739
  - CVE-2013-1741
  - CVE-2013-5605
  - CVE-2013-5606
* Adjusted packaging for 3.15.3:
  - debian/patches/*: refreshed.
  - debian/patches/lower-dhe-priority.patch: removed, no longer needed,
    was a workaround for an old version of firefox.
  - debian/libnss3.symbols: added new symbols.
  - debian/rules: updated for new source layout.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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_file = NULL;
 
710
#endif
 
711
 
 
712
    char *pwd = NULL;
 
713
    char *configDir = NULL;
 
714
    char *dbPrefix = NULL;
 
715
    char *disableUnload = NULL;
 
716
 
 
717
    CK_C_GetFunctionList pC_GetFunctionList;
 
718
    CK_TOKEN_INFO tokenInfo;
 
719
    CK_FUNCTION_LIST_PTR pFunctionList = NULL;
 
720
    CK_RV crv = CKR_OK;
 
721
    CK_SESSION_HANDLE hRwSession;
 
722
    CK_SLOT_ID *pSlotList = NULL;
 
723
    CK_ULONG slotIndex = 0; 
 
724
    CK_MECHANISM digestmech;
 
725
    CK_ULONG digestLen = 0;
 
726
    CK_BYTE digest[32]; /* SHA256_LENGTH */
 
727
    CK_BYTE sign[64];   /* DSA SIGNATURE LENGTH */
 
728
    CK_ULONG signLen = 0 ;
 
729
    CK_MECHANISM signMech = {
 
730
        CKM_DSA, NULL, 0
 
731
    };
 
732
 
 
733
    /*** DSA Key ***/
 
734
 
 
735
    CK_MECHANISM dsaKeyPairGenMech;
 
736
    CK_ATTRIBUTE dsaPubKeyTemplate[5];
 
737
    CK_ATTRIBUTE dsaPrivKeyTemplate[5];
 
738
    CK_OBJECT_HANDLE hDSApubKey = CK_INVALID_HANDLE;
 
739
    CK_OBJECT_HANDLE hDSAprivKey = CK_INVALID_HANDLE;
 
740
 
 
741
    CK_BYTE dsaPubKey[384];
 
742
    CK_ATTRIBUTE dsaPubKeyValue;
 
743
 
 
744
 
 
745
    program_name = strrchr(argv[0], '/');
 
746
    program_name = program_name ? (program_name + 1) : argv[0];
 
747
    optstate = PL_CreateOptState (argc, argv, "i:o:f:Fd:hH?k:p:P:vVs:");
 
748
    if (optstate == NULL) {
 
749
        lperror("PL_CreateOptState failed");
 
750
        return 1;
 
751
    }
 
752
 
 
753
    while (PL_GetNextOpt (optstate) == PL_OPT_OK) {
 
754
        switch (optstate->option) {
 
755
 
 
756
            case 'd':
 
757
                if (!optstate->value) {
 
758
                    PL_DestroyOptState(optstate);
 
759
                    usage(program_name);
 
760
                }
 
761
                configDir = PL_strdup(optstate->value);
 
762
                checkPath(configDir);
 
763
                break;
 
764
 
 
765
                case 'i':
 
766
                if (!optstate->value) {
 
767
                    PL_DestroyOptState(optstate);
 
768
                    usage(program_name);
 
769
                }
 
770
                input_file = optstate->value;
 
771
                break;
 
772
 
 
773
                case 'o':
 
774
                if (!optstate->value) {
 
775
                    PL_DestroyOptState(optstate);
 
776
                    usage(program_name);
 
777
                }
 
778
                output_file = PL_strdup(optstate->value);
 
779
                break;
 
780
 
 
781
                case 'k':
 
782
                if (!optstate->value) {
 
783
                    PL_DestroyOptState(optstate);
 
784
                    usage(program_name);
 
785
                }
 
786
                keySize = atoi(optstate->value);
 
787
                break;
 
788
 
 
789
                case 'f':
 
790
                if (!optstate->value) {
 
791
                    PL_DestroyOptState(optstate);
 
792
                    usage(program_name);
 
793
                }
 
794
                pwd = filePasswd((char *)optstate->value);
 
795
                if (!pwd) usage(program_name);
 
796
                break;
 
797
 
 
798
                case 'F':
 
799
                FIPSMODE = PR_TRUE;
 
800
                break;
 
801
 
 
802
                case 'p':
 
803
                if (!optstate->value) {
 
804
                    PL_DestroyOptState(optstate);
 
805
                    usage(program_name);
 
806
                }
 
807
                pwd =  PL_strdup(optstate->value);
 
808
                break;
 
809
 
 
810
                case 'P':
 
811
                if (!optstate->value) {
 
812
                    PL_DestroyOptState(optstate);
 
813
                    usage(program_name);
 
814
                }
 
815
                dbPrefix = PL_strdup(optstate->value);
 
816
                break;
 
817
 
 
818
                case 'v':
 
819
                verbose = PR_TRUE;
 
820
                break;
 
821
 
 
822
                case 'V':
 
823
                verify = PR_TRUE;
 
824
                break;
 
825
 
 
826
                case 'H':
 
827
                PL_DestroyOptState(optstate);
 
828
                long_usage (program_name);
 
829
                return 1;
 
830
                break;
 
831
 
 
832
                case 'h':
 
833
                case '?':
 
834
                default:
 
835
                PL_DestroyOptState(optstate);
 
836
                usage(program_name);
 
837
                return 1;
 
838
                break;
 
839
        }
 
840
    }
 
841
    PL_DestroyOptState(optstate);
 
842
 
 
843
    if (!input_file) {
 
844
        usage(program_name);
 
845
        return 1;
 
846
    }
 
847
 
 
848
    /* Get the platform-dependent library name of the
 
849
     * NSS cryptographic module.
 
850
     */
 
851
    libname = PR_GetLibraryName(NULL, "softokn3");
 
852
    assert(libname != NULL);
 
853
    lib = PR_LoadLibrary(libname);
 
854
    assert(lib != NULL);
 
855
    PR_FreeLibraryName(libname);
 
856
 
 
857
 
 
858
    if (FIPSMODE) {
 
859
        /* FIPSMODE == FC_GetFunctionList */
 
860
        /* library path must be set to an already signed softokn3/freebl */
 
861
        pC_GetFunctionList = (CK_C_GetFunctionList)
 
862
                             PR_FindFunctionSymbol(lib, "FC_GetFunctionList");
 
863
    } else {
 
864
        /* NON FIPS mode  == C_GetFunctionList */
 
865
        pC_GetFunctionList = (CK_C_GetFunctionList)
 
866
                             PR_FindFunctionSymbol(lib, "C_GetFunctionList");
 
867
     }
 
868
    assert(pC_GetFunctionList != NULL);
 
869
 
 
870
    crv = (*pC_GetFunctionList)(&pFunctionList);
 
871
    assert(crv == CKR_OK);
 
872
 
 
873
    if (configDir) {
 
874
    if (!dbPrefix) {
 
875
            dbPrefix = PL_strdup("");
 
876
        }
 
877
        crv = softokn_Init(pFunctionList, configDir, dbPrefix);
 
878
        if (crv != CKR_OK) {
 
879
            logIt("Failed to use provided database directory "
 
880
                  "will just initialize the volatile certdb.\n");
 
881
            crv = softokn_Init(pFunctionList, NULL, NULL); /* NoDB Init */
 
882
        }
 
883
    } else {
 
884
        crv = softokn_Init(pFunctionList, NULL, NULL); /* NoDB Init */
 
885
    }
 
886
 
 
887
    if (crv != CKR_OK) {
 
888
        pk11error( "Initiailzing softoken failed", crv);
 
889
        goto cleanup;
 
890
    }
 
891
 
 
892
    pSlotList = getSlotList(pFunctionList, slotIndex);
 
893
    if (pSlotList == NULL) {
 
894
        PR_fprintf(PR_STDERR, "getSlotList failed");
 
895
        goto cleanup;
 
896
    }
 
897
 
 
898
    if ((keySize == 0) || (keySize > 1024)) {
 
899
        CK_MECHANISM_INFO mechInfo;
 
900
        crv = pFunctionList->C_GetMechanismInfo(pSlotList[slotIndex],
 
901
                        CKM_DSA, &mechInfo);
 
902
        if (crv != CKR_OK) {
 
903
            pk11error( "Couldn't get mechanism info for DSA", crv);
 
904
            goto cleanup;
 
905
        }
 
906
 
 
907
        if (keySize && (mechInfo.ulMaxKeySize < keySize)) {
 
908
            PR_fprintf(PR_STDERR, 
 
909
                "token doesn't support DSA2 (Max key size=%d)\n", 
 
910
                mechInfo.ulMaxKeySize);
 
911
            goto cleanup;
 
912
        }
 
913
 
 
914
        if ((keySize == 0) && mechInfo.ulMaxKeySize >=2048 ) {
 
915
            keySize = 2048;
 
916
        } else {
 
917
            keySize = 1024;
 
918
        }
 
919
    }
 
920
 
 
921
    /* DSA key init */
 
922
    if (keySize == 1024) {
 
923
        dsaPubKeyTemplate[0].type       = CKA_PRIME;
 
924
        dsaPubKeyTemplate[0].pValue     = (CK_VOID_PTR) &prime;
 
925
        dsaPubKeyTemplate[0].ulValueLen = sizeof(prime);
 
926
        dsaPubKeyTemplate[1].type = CKA_SUBPRIME;
 
927
        dsaPubKeyTemplate[1].pValue = (CK_VOID_PTR) &subprime;
 
928
        dsaPubKeyTemplate[1].ulValueLen = sizeof(subprime);
 
929
        dsaPubKeyTemplate[2].type = CKA_BASE;
 
930
        dsaPubKeyTemplate[2].pValue = (CK_VOID_PTR) &base;
 
931
        dsaPubKeyTemplate[2].ulValueLen = sizeof(base);
 
932
        digestmech.mechanism = CKM_SHA_1;
 
933
        digestmech.pParameter = NULL;
 
934
        digestmech.ulParameterLen = 0;
 
935
    } else if (keySize == 2048) {
 
936
        dsaPubKeyTemplate[0].type       = CKA_PRIME;
 
937
        dsaPubKeyTemplate[0].pValue     = (CK_VOID_PTR) &prime2;
 
938
        dsaPubKeyTemplate[0].ulValueLen = sizeof(prime2);
 
939
        dsaPubKeyTemplate[1].type = CKA_SUBPRIME;
 
940
        dsaPubKeyTemplate[1].pValue = (CK_VOID_PTR) &subprime2;
 
941
        dsaPubKeyTemplate[1].ulValueLen = sizeof(subprime2);
 
942
        dsaPubKeyTemplate[2].type = CKA_BASE;
 
943
        dsaPubKeyTemplate[2].pValue = (CK_VOID_PTR) &base2;
 
944
        dsaPubKeyTemplate[2].ulValueLen = sizeof(base2);
 
945
        digestmech.mechanism = CKM_SHA256;
 
946
        digestmech.pParameter = NULL;
 
947
        digestmech.ulParameterLen = 0;
 
948
    } else {
 
949
        /* future - generate pqg */
 
950
        PR_fprintf(PR_STDERR, "Only keysizes 1024 and 2048 are supported");
 
951
        goto cleanup;
 
952
    }
 
953
    dsaPubKeyTemplate[3].type = CKA_TOKEN;
 
954
    dsaPubKeyTemplate[3].pValue = &false; /* session object */
 
955
    dsaPubKeyTemplate[3].ulValueLen = sizeof(false);
 
956
    dsaPubKeyTemplate[4].type = CKA_VERIFY;
 
957
    dsaPubKeyTemplate[4].pValue = &true;
 
958
    dsaPubKeyTemplate[4].ulValueLen = sizeof(true);
 
959
    dsaKeyPairGenMech.mechanism      = CKM_DSA_KEY_PAIR_GEN;
 
960
    dsaKeyPairGenMech.pParameter = NULL;
 
961
    dsaKeyPairGenMech.ulParameterLen = 0;
 
962
    dsaPrivKeyTemplate[0].type       = CKA_TOKEN;
 
963
    dsaPrivKeyTemplate[0].pValue     = &false; /* session object */
 
964
    dsaPrivKeyTemplate[0].ulValueLen = sizeof(false);
 
965
    dsaPrivKeyTemplate[1].type       = CKA_PRIVATE;
 
966
    dsaPrivKeyTemplate[1].pValue     = &true;
 
967
    dsaPrivKeyTemplate[1].ulValueLen = sizeof(true);
 
968
    dsaPrivKeyTemplate[2].type       = CKA_SENSITIVE;
 
969
    dsaPrivKeyTemplate[2].pValue     = &true; 
 
970
    dsaPrivKeyTemplate[2].ulValueLen = sizeof(true);
 
971
    dsaPrivKeyTemplate[3].type       = CKA_SIGN,
 
972
    dsaPrivKeyTemplate[3].pValue     = &true;
 
973
    dsaPrivKeyTemplate[3].ulValueLen = sizeof(true);
 
974
    dsaPrivKeyTemplate[4].type       = CKA_EXTRACTABLE;
 
975
    dsaPrivKeyTemplate[4].pValue     = &false;
 
976
    dsaPrivKeyTemplate[4].ulValueLen = sizeof(false);
 
977
 
 
978
    crv = pFunctionList->C_OpenSession(pSlotList[slotIndex],
 
979
                                       CKF_RW_SESSION | CKF_SERIAL_SESSION,
 
980
                                       NULL, NULL, &hRwSession);
 
981
    if (crv != CKR_OK) {
 
982
        pk11error( "Opening a read/write session failed", crv);
 
983
        goto cleanup;
 
984
    }
 
985
 
 
986
    /* check if a password is needed */
 
987
    crv = pFunctionList->C_GetTokenInfo(pSlotList[slotIndex], &tokenInfo);
 
988
    if (crv != CKR_OK) {
 
989
        pk11error( "C_GetTokenInfo failed", crv);
 
990
        goto cleanup;
 
991
    }
 
992
    if (tokenInfo.flags & CKF_LOGIN_REQUIRED) {
 
993
        if (pwd) {
 
994
            int pwdLen = strlen((const char*)pwd); 
 
995
            crv = pFunctionList->C_Login(hRwSession, CKU_USER, 
 
996
                                (CK_UTF8CHAR_PTR) pwd, (CK_ULONG)pwdLen);
 
997
            if (crv != CKR_OK) {
 
998
                pk11error("C_Login failed", crv);
 
999
                goto cleanup;
 
1000
            }
 
1001
        } else {
 
1002
            PR_fprintf(PR_STDERR, "Please provide the password for the token");
 
1003
            goto cleanup;
 
1004
        }
 
1005
    } else if (pwd) {
 
1006
        logIt("A password was provided but the password was not used.\n");
 
1007
    }
 
1008
 
 
1009
    /* Generate a DSA key pair */
 
1010
    logIt("Generate a DSA key pair ... \n");
 
1011
    crv = pFunctionList->C_GenerateKeyPair(hRwSession, &dsaKeyPairGenMech,
 
1012
                                           dsaPubKeyTemplate,
 
1013
                                           NUM_ELEM(dsaPubKeyTemplate),
 
1014
                                           dsaPrivKeyTemplate,
 
1015
                                           NUM_ELEM(dsaPrivKeyTemplate),
 
1016
                                           &hDSApubKey, &hDSAprivKey);
 
1017
    if (crv != CKR_OK) {
 
1018
        pk11error("DSA key pair generation failed", crv);
 
1019
        goto cleanup;
 
1020
    }
 
1021
 
 
1022
    /* open the shared library */
 
1023
    fd = PR_OpenFile(input_file,PR_RDONLY,0);
 
1024
    if (fd == NULL ) {
 
1025
        lperror(input_file);
 
1026
        goto cleanup;
 
1027
    }
 
1028
#ifdef USES_LINKS
 
1029
    ret = lstat(input_file, &stat_buf);
 
1030
    if (ret < 0) {
 
1031
        perror(input_file);
 
1032
        goto cleanup;
 
1033
    }
 
1034
    if (S_ISLNK(stat_buf.st_mode)) {
 
1035
        char *dirpath,*dirend;
 
1036
        char *link_buf = NULL;
 
1037
        size_t size = 64;
 
1038
        while (1) {
 
1039
            link_buf = realloc(link_buf, size);
 
1040
            if (!link_buf) {
 
1041
                perror(input_file);
 
1042
                goto cleanup;
 
1043
            }
 
1044
            ret = readlink(input_file, link_buf, size - 1);
 
1045
            if (ret < 0) {
 
1046
                perror(input_file);
 
1047
                goto cleanup;
 
1048
            }
 
1049
            if (ret < size - 1)
 
1050
                break;
 
1051
            size *= 2;
 
1052
        }
 
1053
        link_buf[ret] = 0;
 
1054
        link_file = mkoutput(input_file);
 
1055
        /* get the dirname of input_file */
 
1056
        dirpath = PL_strdup(input_file);
 
1057
        dirend = strrchr(dirpath, '/');
 
1058
        if (dirend) {
 
1059
            *dirend = '\0';
 
1060
            ret = chdir(dirpath);
 
1061
            if (ret < 0) {
 
1062
                perror(dirpath);
 
1063
                goto cleanup;
 
1064
            }
 
1065
        }
 
1066
        PL_strfree(dirpath);
 
1067
        input_file = link_buf;
 
1068
        /* get the basename of link_file */
 
1069
        dirend = strrchr(link_file, '/');
 
1070
        if (dirend) {
 
1071
            char * tmp_file = NULL;
 
1072
            tmp_file = PL_strdup(dirend +1 );
 
1073
            PL_strfree(link_file);
 
1074
            link_file = tmp_file;
 
1075
        }
 
1076
    }
 
1077
#endif
 
1078
    if (output_file == NULL) {
 
1079
        output_file = mkoutput(input_file);
 
1080
    }
 
1081
 
 
1082
    /* compute the digest */
 
1083
    memset(digest, 0, sizeof(digest));
 
1084
    crv = pFunctionList->C_DigestInit(hRwSession, &digestmech);
 
1085
    if (crv != CKR_OK) {
 
1086
        pk11error("C_DigestInit failed", crv);
 
1087
        goto cleanup;
 
1088
    }
 
1089
 
 
1090
    /* Digest the file */
 
1091
    while ((bytesRead = PR_Read(fd,file_buf,sizeof(file_buf))) > 0) {
 
1092
        crv = pFunctionList->C_DigestUpdate(hRwSession, (CK_BYTE_PTR)file_buf,
 
1093
                                            bytesRead);
 
1094
        if (crv != CKR_OK) {
 
1095
            pk11error("C_DigestUpdate failed", crv);
 
1096
            goto cleanup;
 
1097
        }
 
1098
        count += bytesRead;
 
1099
    }
 
1100
 
 
1101
    /* close the input_File */
 
1102
    PR_Close(fd);
 
1103
    fd = NULL;
 
1104
    if (bytesRead < 0) {
 
1105
        lperror("0 bytes read from input file");
 
1106
        goto cleanup;
 
1107
    }
 
1108
 
 
1109
    digestLen = sizeof(digest);
 
1110
    crv = pFunctionList->C_DigestFinal(hRwSession, (CK_BYTE_PTR)digest,
 
1111
                                       &digestLen);
 
1112
    if (crv != CKR_OK) {
 
1113
        pk11error("C_DigestFinal failed", crv);
 
1114
        goto cleanup;
 
1115
    }
 
1116
 
 
1117
    if (digestLen != sizeof(digest)) {
 
1118
        PR_fprintf(PR_STDERR, "digestLen has incorrect length %lu "
 
1119
                "it should be %lu \n",digestLen, sizeof(digest));
 
1120
        goto cleanup;
 
1121
    }
 
1122
 
 
1123
    /* sign the hash */
 
1124
    memset(sign, 0, sizeof(sign));
 
1125
    /* SignUpdate  */
 
1126
    crv = pFunctionList->C_SignInit(hRwSession, &signMech, hDSAprivKey);
 
1127
    if (crv != CKR_OK) {
 
1128
        pk11error("C_SignInit failed", crv);
 
1129
        goto cleanup;
 
1130
    }
 
1131
 
 
1132
    signLen = sizeof(sign);
 
1133
    crv = pFunctionList->C_Sign(hRwSession, (CK_BYTE * ) digest, digestLen,
 
1134
                                sign, &signLen);
 
1135
    if (crv != CKR_OK) {
 
1136
        pk11error("C_Sign failed", crv);
 
1137
        goto cleanup;
 
1138
    }
 
1139
 
 
1140
    if (signLen != sizeof(sign)) {
 
1141
        PR_fprintf(PR_STDERR, "signLen has incorrect length %lu "
 
1142
                    "it should be %lu \n", signLen, sizeof(sign));
 
1143
        goto cleanup;
 
1144
    }
 
1145
 
 
1146
    if (verify) {
 
1147
        crv = pFunctionList->C_VerifyInit(hRwSession, &signMech, hDSApubKey);
 
1148
        if (crv != CKR_OK) {
 
1149
            pk11error("C_VerifyInit failed", crv);
 
1150
            goto cleanup;
 
1151
        }
 
1152
        crv = pFunctionList->C_Verify(hRwSession, digest, digestLen,
 
1153
                                      sign, signLen);
 
1154
        if (crv != CKR_OK) {
 
1155
            pk11error("C_Verify failed", crv);
 
1156
            goto cleanup;
 
1157
        }
 
1158
    }
 
1159
 
 
1160
    if (verbose) {
 
1161
        int j;
 
1162
        PR_fprintf(PR_STDERR,"Library File: %s %d bytes\n",input_file, count);
 
1163
        PR_fprintf(PR_STDERR,"Check File: %s\n",output_file);
 
1164
#ifdef USES_LINKS
 
1165
        if (link_file) {
 
1166
            PR_fprintf(PR_STDERR,"Link: %s\n",link_file);
 
1167
        }
 
1168
#endif
 
1169
        PR_fprintf(PR_STDERR,"  hash: %lu bytes\n", digestLen);
 
1170
#define STEP 10
 
1171
        for (i=0; i < (int) digestLen; i += STEP) {
 
1172
            PR_fprintf(PR_STDERR,"   ");
 
1173
            for (j=0; j < STEP && (i+j) < (int) digestLen; j++) {
 
1174
                PR_fprintf(PR_STDERR," %02x", digest[i+j]);
 
1175
            }
 
1176
            PR_fprintf(PR_STDERR,"\n");
 
1177
        }
 
1178
        PR_fprintf(PR_STDERR,"  signature: %lu bytes\n", signLen);
 
1179
        for (i=0; i < (int) signLen; i += STEP) {
 
1180
            PR_fprintf(PR_STDERR,"   ");
 
1181
            for (j=0; j < STEP && (i+j) < (int) signLen; j++) {
 
1182
                PR_fprintf(PR_STDERR," %02x", sign[i+j]);
 
1183
            }
 
1184
            PR_fprintf(PR_STDERR,"\n");
 
1185
        }
 
1186
    }
 
1187
 
 
1188
    /* open the target signature file */
 
1189
    fd = PR_Open(output_file,PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE,0666);
 
1190
    if (fd == NULL ) {
 
1191
        lperror(output_file);
 
1192
        goto cleanup;
 
1193
    }
 
1194
 
 
1195
    /*
 
1196
     * we write the key out in a straight binary format because very
 
1197
     * low level libraries need to read an parse this file. Ideally we should
 
1198
     * just derEncode the public key (which would be pretty simple, and be
 
1199
     * more general), but then we'd need to link the ASN.1 decoder with the
 
1200
     * freebl libraries.
 
1201
     */
 
1202
 
 
1203
    file_buf[0] = NSS_SIGN_CHK_MAGIC1;
 
1204
    file_buf[1] = NSS_SIGN_CHK_MAGIC2;
 
1205
    file_buf[2] = NSS_SIGN_CHK_MAJOR_VERSION;
 
1206
    file_buf[3] = NSS_SIGN_CHK_MINOR_VERSION;
 
1207
    encodeInt(&file_buf[4],12);  /* offset to data start */
 
1208
    encodeInt(&file_buf[8],CKK_DSA);
 
1209
    bytesWritten = PR_Write(fd,file_buf, 12);
 
1210
    if (bytesWritten != 12) {
 
1211
        lperror(output_file);
 
1212
        goto cleanup;
 
1213
    }
 
1214
 
 
1215
    /* get DSA Public KeyValue */
 
1216
    memset(dsaPubKey, 0, sizeof(dsaPubKey));
 
1217
    dsaPubKeyValue.type =CKA_VALUE;
 
1218
    dsaPubKeyValue.pValue = (CK_VOID_PTR) &dsaPubKey;
 
1219
    dsaPubKeyValue.ulValueLen = sizeof(dsaPubKey);
 
1220
 
 
1221
    crv = pFunctionList->C_GetAttributeValue(hRwSession, hDSApubKey,
 
1222
                                             &dsaPubKeyValue, 1);
 
1223
    if (crv != CKR_OK && crv != CKR_ATTRIBUTE_TYPE_INVALID) {
 
1224
        pk11error("C_GetAttributeValue failed", crv);
 
1225
        goto cleanup;
 
1226
    }
 
1227
 
 
1228
    /* CKA_PRIME */
 
1229
    rv = writeItem(fd,dsaPubKeyTemplate[0].pValue,
 
1230
                   dsaPubKeyTemplate[0].ulValueLen, output_file);
 
1231
    if (rv != PR_SUCCESS) goto cleanup;
 
1232
    /* CKA_SUBPRIME */
 
1233
    rv = writeItem(fd,dsaPubKeyTemplate[1].pValue,
 
1234
                   dsaPubKeyTemplate[1].ulValueLen, output_file);
 
1235
    if (rv != PR_SUCCESS) goto cleanup;
 
1236
    /* CKA_BASE */ 
 
1237
    rv = writeItem(fd,dsaPubKeyTemplate[2].pValue,
 
1238
                   dsaPubKeyTemplate[2].ulValueLen, output_file);
 
1239
    if (rv != PR_SUCCESS) goto cleanup;
 
1240
    /* DSA Public Key value */
 
1241
    rv = writeItem(fd,dsaPubKeyValue.pValue,
 
1242
                   dsaPubKeyValue.ulValueLen, output_file);
 
1243
    if (rv != PR_SUCCESS) goto cleanup;
 
1244
    /* DSA SIGNATURE */
 
1245
    rv = writeItem(fd,&sign, signLen, output_file);
 
1246
    if (rv != PR_SUCCESS) goto cleanup;
 
1247
    PR_Close(fd);
 
1248
 
 
1249
#ifdef USES_LINKS
 
1250
    if (link_file) {
 
1251
        (void)unlink(link_file);
 
1252
        ret = symlink(output_file, link_file);
 
1253
        if (ret < 0) {
 
1254
            perror(link_file);
 
1255
            goto cleanup;
 
1256
        }
 
1257
    }
 
1258
#endif
 
1259
 
 
1260
    successful = PR_TRUE;
 
1261
 
 
1262
cleanup:
 
1263
    if (pFunctionList) {
 
1264
        /* C_Finalize will automatically logout, close session, */
 
1265
        /* and delete the temp objects on the token */
 
1266
        crv = pFunctionList->C_Finalize(NULL);
 
1267
        if (crv != CKR_OK) {
 
1268
            pk11error("C_Finalize failed", crv);
 
1269
        }
 
1270
    }
 
1271
    if (pSlotList) {
 
1272
        PR_Free(pSlotList);
 
1273
    }
 
1274
    if (pwd) {
 
1275
        PL_strfree(pwd);
 
1276
    }
 
1277
    if (configDir) {
 
1278
        PL_strfree(configDir);
 
1279
    }
 
1280
    if (dbPrefix) {
 
1281
        PL_strfree(dbPrefix);
 
1282
    }
 
1283
    if (output_file) { /* allocated by mkoutput function */
 
1284
        PL_strfree(output_file); 
 
1285
    }
 
1286
#ifdef USES_LINKS
 
1287
    if (link_file) { /* allocated by mkoutput function */
 
1288
        PL_strfree(link_file); 
 
1289
    }
 
1290
#endif
 
1291
 
 
1292
    disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
 
1293
    if (!disableUnload) {
 
1294
        PR_UnloadLibrary(lib);
 
1295
    }
 
1296
    PR_Cleanup();
 
1297
 
 
1298
    if (crv != CKR_OK)
 
1299
        return crv;
 
1300
    
 
1301
    return (successful) ? 0 : 1;
 
1302
}