1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/cmd/shlibsign/shlibsign.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1291 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/* 1.9 + * shlibsign creates the checksum (.chk) files for the NSS libraries, 1.10 + * libsoftokn3/softokn3 and libfreebl/freebl (platforms can have 1.11 + * multiple freebl variants), that contain the NSS cryptograhic boundary. 1.12 + * 1.13 + * The generated .chk files must be put in the same directory as 1.14 + * the NSS libraries they were generated for. 1.15 + * 1.16 + * When in FIPS 140 mode, the NSS Internal FIPS PKCS #11 Module will 1.17 + * compute the checksum for the NSS cryptographic boundary libraries 1.18 + * and compare the checksum with the value in .chk file. 1.19 + */ 1.20 + 1.21 +#ifdef XP_UNIX 1.22 +#define USES_LINKS 1 1.23 +#endif 1.24 + 1.25 +#include <assert.h> 1.26 +#include <stdio.h> 1.27 +#include <stdlib.h> 1.28 +#include <string.h> 1.29 +#include <stdarg.h> 1.30 + 1.31 +#ifdef USES_LINKS 1.32 +#include <unistd.h> 1.33 +#include <sys/param.h> 1.34 +#include <sys/types.h> 1.35 +#include <sys/stat.h> 1.36 +#endif 1.37 + 1.38 +/* nspr headers */ 1.39 +#include "prlink.h" 1.40 +#include "prprf.h" 1.41 +#include "prenv.h" 1.42 +#include "plgetopt.h" 1.43 +#include "prinit.h" 1.44 +#include "prmem.h" 1.45 +#include "plstr.h" 1.46 +#include "prerror.h" 1.47 + 1.48 +/* softoken headers */ 1.49 +#include "pkcs11.h" 1.50 +#include "pkcs11t.h" 1.51 + 1.52 +/* freebl headers */ 1.53 +#include "shsign.h" 1.54 + 1.55 +#define NUM_ELEM(array) (sizeof(array)/sizeof(array[0])) 1.56 +CK_BBOOL true = CK_TRUE; 1.57 +CK_BBOOL false = CK_FALSE; 1.58 +static PRBool verbose = PR_FALSE; 1.59 + 1.60 +static void 1.61 +usage (const char *program_name) 1.62 +{ 1.63 + PRFileDesc *debug_out = PR_GetSpecialFD(PR_StandardError); 1.64 + PR_fprintf (debug_out, 1.65 + "type %s -H for more detail information.\n", program_name); 1.66 + PR_fprintf (debug_out, 1.67 + "Usage: %s [-v] [-V] [-o outfile] [-d dbdir] [-f pwfile]\n" 1.68 + " [-F] [-p pwd] -[P dbprefix ] " 1.69 + "-i shared_library_name\n", 1.70 + program_name); 1.71 + exit(1); 1.72 +} 1.73 + 1.74 +static void 1.75 +long_usage(const char *program_name) 1.76 +{ 1.77 + PRFileDesc *debug_out = PR_GetSpecialFD(PR_StandardError); 1.78 + PR_fprintf(debug_out, "%s test program usage:\n", program_name); 1.79 + PR_fprintf(debug_out, "\t-i <infile> shared_library_name to process\n"); 1.80 + PR_fprintf(debug_out, "\t-o <outfile> checksum outfile\n"); 1.81 + PR_fprintf(debug_out, "\t-d <path> database path location\n"); 1.82 + PR_fprintf(debug_out, "\t-P <prefix> database prefix\n"); 1.83 + PR_fprintf(debug_out, "\t-f <file> password File : echo pw > file \n"); 1.84 + PR_fprintf(debug_out, "\t-F FIPS mode\n"); 1.85 + PR_fprintf(debug_out, "\t-p <pwd> password\n"); 1.86 + PR_fprintf(debug_out, "\t-v verbose output\n"); 1.87 + PR_fprintf(debug_out, "\t-V perform Verify operations\n"); 1.88 + PR_fprintf(debug_out, "\t-? short help message\n"); 1.89 + PR_fprintf(debug_out, "\t-h short help message\n"); 1.90 + PR_fprintf(debug_out, "\t-H this help message\n"); 1.91 + PR_fprintf(debug_out, "\n\n\tNote: Use of FIPS mode requires your "); 1.92 + PR_fprintf(debug_out, "library path is using \n"); 1.93 + PR_fprintf(debug_out, "\t pre-existing libraries with generated "); 1.94 + PR_fprintf(debug_out, "checksum files\n"); 1.95 + PR_fprintf(debug_out, "\t and database in FIPS mode \n"); 1.96 + exit(1); 1.97 +} 1.98 + 1.99 +static char * 1.100 +mkoutput(const char *input) 1.101 +{ 1.102 + int in_len = strlen(input); 1.103 + char *output = PR_Malloc(in_len+sizeof(SGN_SUFFIX)); 1.104 + int index = in_len + 1 - sizeof("."SHLIB_SUFFIX); 1.105 + 1.106 + if ((index > 0) && 1.107 + (PL_strncmp(&input[index], 1.108 + "."SHLIB_SUFFIX,sizeof("."SHLIB_SUFFIX)) == 0)) { 1.109 + in_len = index; 1.110 + } 1.111 + memcpy(output,input,in_len); 1.112 + memcpy(&output[in_len],SGN_SUFFIX,sizeof(SGN_SUFFIX)); 1.113 + return output; 1.114 +} 1.115 + 1.116 +static void 1.117 +lperror(const char *string) { 1.118 + PRErrorCode errorcode; 1.119 + 1.120 + errorcode = PR_GetError(); 1.121 + PR_fprintf(PR_STDERR, "%s: %d: %s\n", string, errorcode, 1.122 + PR_ErrorToString(errorcode, PR_LANGUAGE_I_DEFAULT)); 1.123 +} 1.124 + 1.125 +static void 1.126 +encodeInt(unsigned char *buf, int val) 1.127 +{ 1.128 + buf[3] = (val >> 0) & 0xff; 1.129 + buf[2] = (val >> 8) & 0xff; 1.130 + buf[1] = (val >> 16) & 0xff; 1.131 + buf[0] = (val >> 24) & 0xff; 1.132 + return; 1.133 +} 1.134 + 1.135 +static PRStatus 1.136 +writeItem(PRFileDesc *fd, CK_VOID_PTR pValue, 1.137 + CK_ULONG ulValueLen, char *file) 1.138 +{ 1.139 + unsigned char buf[4]; 1.140 + int bytesWritten; 1.141 + if (ulValueLen == 0) { 1.142 + PR_fprintf(PR_STDERR, "call to writeItem with 0 bytes of data.\n"); 1.143 + return PR_FAILURE; 1.144 + } 1.145 + 1.146 + encodeInt(buf,ulValueLen); 1.147 + bytesWritten = PR_Write(fd,buf, 4); 1.148 + if (bytesWritten != 4) { 1.149 + lperror(file); 1.150 + return PR_FAILURE; 1.151 + } 1.152 + bytesWritten = PR_Write(fd, pValue, ulValueLen); 1.153 + if (bytesWritten != ulValueLen) { 1.154 + lperror(file); 1.155 + return PR_FAILURE; 1.156 + } 1.157 + return PR_SUCCESS; 1.158 +} 1.159 + 1.160 +static const unsigned char prime[] = { 0x00, 1.161 + 0x97, 0x44, 0x1d, 0xcc, 0x0d, 0x39, 0x0d, 0x8d, 1.162 + 0xcb, 0x75, 0xdc, 0x24, 0x25, 0x6f, 0x01, 0x92, 1.163 + 0xa1, 0x11, 0x07, 0x6b, 0x70, 0xac, 0x73, 0xd7, 1.164 + 0x82, 0x28, 0xdf, 0xab, 0x82, 0x0c, 0x41, 0x0c, 1.165 + 0x95, 0xb3, 0x3c, 0x3d, 0xea, 0x8a, 0xe6, 0x44, 1.166 + 0x0a, 0xb8, 0xab, 0x90, 0x15, 0x41, 0x11, 0xe8, 1.167 + 0x48, 0x7b, 0x8d, 0xb0, 0x9c, 0xd3, 0xf2, 0x69, 1.168 + 0x66, 0xff, 0x66, 0x4b, 0x70, 0x2b, 0xbf, 0xfb, 1.169 + 0xd6, 0x68, 0x85, 0x76, 0x1e, 0x34, 0xaa, 0xc5, 1.170 + 0x57, 0x6e, 0x23, 0x02, 0x08, 0x60, 0x6e, 0xfd, 1.171 + 0x67, 0x76, 0xe1, 0x7c, 0xc8, 0xcb, 0x51, 0x77, 1.172 + 0xcf, 0xb1, 0x3b, 0x00, 0x2e, 0xfa, 0x21, 0xcd, 1.173 + 0x34, 0x76, 0x75, 0x01, 0x19, 0xfe, 0xf8, 0x5d, 1.174 + 0x43, 0xc5, 0x34, 0xf3, 0x7a, 0x95, 0xdc, 0xc2, 1.175 + 0x58, 0x07, 0x19, 0x2f, 0x1d, 0x6f, 0x9a, 0x77, 1.176 + 0x7e, 0x55, 0xaa, 0xe7, 0x5a, 0x50, 0x43, 0xd3 }; 1.177 + 1.178 +static const unsigned char subprime[] = { 0x0, 1.179 + 0xd8, 0x16, 0x23, 0x34, 0x8a, 0x9e, 0x3a, 0xf5, 1.180 + 0xd9, 0x10, 0x13, 0x35, 0xaa, 0xf3, 0xf3, 0x54, 1.181 + 0x0b, 0x31, 0x24, 0xf1 }; 1.182 + 1.183 +static const unsigned char base[] = { 1.184 + 0x03, 0x3a, 0xad, 0xfa, 0x3a, 0x0c, 0xea, 0x0a, 1.185 + 0x4e, 0x43, 0x32, 0x92, 0xbb, 0x87, 0xf1, 0x11, 1.186 + 0xc0, 0xad, 0x39, 0x38, 0x56, 0x1a, 0xdb, 0x23, 1.187 + 0x66, 0xb1, 0x08, 0xda, 0xb6, 0x19, 0x51, 0x42, 1.188 + 0x93, 0x4f, 0xc3, 0x44, 0x43, 0xa8, 0x05, 0xc1, 1.189 + 0xf8, 0x71, 0x62, 0x6f, 0x3d, 0xe2, 0xab, 0x6f, 1.190 + 0xd7, 0x80, 0x22, 0x6f, 0xca, 0x0d, 0xf6, 0x9f, 1.191 + 0x45, 0x27, 0x83, 0xec, 0x86, 0x0c, 0xda, 0xaa, 1.192 + 0xd6, 0xe0, 0xd0, 0x84, 0xfd, 0xb1, 0x4f, 0xdc, 1.193 + 0x08, 0xcd, 0x68, 0x3a, 0x77, 0xc2, 0xc5, 0xf1, 1.194 + 0x99, 0x0f, 0x15, 0x1b, 0x6a, 0x8c, 0x3d, 0x18, 1.195 + 0x2b, 0x6f, 0xdc, 0x2b, 0xd8, 0xb5, 0x9b, 0xb8, 1.196 + 0x2d, 0x57, 0x92, 0x1c, 0x46, 0x27, 0xaf, 0x6d, 1.197 + 0xe1, 0x45, 0xcf, 0x0b, 0x3f, 0xfa, 0x07, 0xcc, 1.198 + 0x14, 0x8e, 0xe7, 0xb8, 0xaa, 0xd5, 0xd1, 0x36, 1.199 + 0x1d, 0x7e, 0x5e, 0x7d, 0xfa, 0x5b, 0x77, 0x1f }; 1.200 + 1.201 +static const unsigned char h[] = { 1.202 + 0x41, 0x87, 0x47, 0x79, 0xd8, 0xba, 0x4e, 0xac, 1.203 + 0x44, 0x4f, 0x6b, 0xd2, 0x16, 0x5e, 0x04, 0xc6, 1.204 + 0xc2, 0x29, 0x93, 0x5e, 0xbd, 0xc7, 0xa9, 0x8f, 1.205 + 0x23, 0xa1, 0xc8, 0xee, 0x80, 0x64, 0xd5, 0x67, 1.206 + 0x3c, 0xba, 0x59, 0x9a, 0x06, 0x0c, 0xcc, 0x29, 1.207 + 0x56, 0xc0, 0xb2, 0x21, 0xe0, 0x5b, 0x52, 0xcd, 1.208 + 0x84, 0x73, 0x57, 0xfd, 0xd8, 0xc3, 0x5b, 0x13, 1.209 + 0x54, 0xd7, 0x4a, 0x06, 0x86, 0x63, 0x09, 0xa5, 1.210 + 0xb0, 0x59, 0xe2, 0x32, 0x9e, 0x09, 0xa3, 0x9f, 1.211 + 0x49, 0x62, 0xcc, 0xa6, 0xf9, 0x54, 0xd5, 0xb2, 1.212 + 0xc3, 0x08, 0x71, 0x7e, 0xe3, 0x37, 0x50, 0xd6, 1.213 + 0x7b, 0xa7, 0xc2, 0x60, 0xc1, 0xeb, 0x51, 0x32, 1.214 + 0xfa, 0xad, 0x35, 0x25, 0x17, 0xf0, 0x7f, 0x23, 1.215 + 0xe5, 0xa8, 0x01, 0x52, 0xcf, 0x2f, 0xd9, 0xa9, 1.216 + 0xf6, 0x00, 0x21, 0x15, 0xf1, 0xf7, 0x70, 0xb7, 1.217 + 0x57, 0x8a, 0xd0, 0x59, 0x6a, 0x82, 0xdc, 0x9c }; 1.218 + 1.219 +static const unsigned char seed[] = { 0x00, 1.220 + 0xcc, 0x4c, 0x69, 0x74, 0xf6, 0x72, 0x24, 0x68, 1.221 + 0x24, 0x4f, 0xd7, 0x50, 0x11, 0x40, 0x81, 0xed, 1.222 + 0x19, 0x3c, 0x8a, 0x25, 0xbc, 0x78, 0x0a, 0x85, 1.223 + 0x82, 0x53, 0x70, 0x20, 0xf6, 0x54, 0xa5, 0x1b, 1.224 + 0xf4, 0x15, 0xcd, 0xff, 0xc4, 0x88, 0xa7, 0x9d, 1.225 + 0xf3, 0x47, 0x1c, 0x0a, 0xbe, 0x10, 0x29, 0x83, 1.226 + 0xb9, 0x0f, 0x4c, 0xdf, 0x90, 0x16, 0x83, 0xa2, 1.227 + 0xb3, 0xe3, 0x2e, 0xc1, 0xc2, 0x24, 0x6a, 0xc4, 1.228 + 0x9d, 0x57, 0xba, 0xcb, 0x0f, 0x18, 0x75, 0x00, 1.229 + 0x33, 0x46, 0x82, 0xec, 0xd6, 0x94, 0x77, 0xc3, 1.230 + 0x4f, 0x4c, 0x58, 0x1c, 0x7f, 0x61, 0x3c, 0x36, 1.231 + 0xd5, 0x2f, 0xa5, 0x66, 0xd8, 0x2f, 0xce, 0x6e, 1.232 + 0x8e, 0x20, 0x48, 0x4a, 0xbb, 0xe3, 0xe0, 0xb2, 1.233 + 0x50, 0x33, 0x63, 0x8a, 0x5b, 0x2d, 0x6a, 0xbe, 1.234 + 0x4c, 0x28, 0x81, 0x53, 0x5b, 0xe4, 0xf6, 0xfc, 1.235 + 0x64, 0x06, 0x13, 0x51, 0xeb, 0x4a, 0x91, 0x9c }; 1.236 + 1.237 +static const unsigned int counter=1496; 1.238 + 1.239 +static const unsigned char prime2[] = { 0x00, 1.240 + 0xa4, 0xc2, 0x83, 0x4f, 0x36, 0xd3, 0x4f, 0xae, 1.241 + 0xa0, 0xb1, 0x47, 0x43, 0xa8, 0x15, 0xee, 0xad, 1.242 + 0xa3, 0x98, 0xa3, 0x29, 0x45, 0xae, 0x5c, 0xd9, 1.243 + 0x12, 0x99, 0x09, 0xdc, 0xef, 0x05, 0xb4, 0x98, 1.244 + 0x05, 0xaa, 0x07, 0xaa, 0x83, 0x89, 0xd7, 0xba, 1.245 + 0xd1, 0x25, 0x56, 0x58, 0xd1, 0x73, 0x3c, 0xd0, 1.246 + 0x91, 0x65, 0xbe, 0x27, 0x92, 0x94, 0x86, 0x95, 1.247 + 0xdb, 0xcf, 0x07, 0x13, 0xa0, 0x85, 0xd6, 0xaa, 1.248 + 0x6c, 0x1d, 0x63, 0xbf, 0xdd, 0xdf, 0xbc, 0x30, 1.249 + 0xeb, 0x42, 0x2f, 0x52, 0x11, 0xec, 0x6e, 0x65, 1.250 + 0xdf, 0x50, 0xbe, 0x28, 0x3d, 0xa4, 0xec, 0x45, 1.251 + 0x19, 0x4c, 0x13, 0x0f, 0x59, 0x74, 0x57, 0x69, 1.252 + 0x99, 0x4f, 0x4a, 0x74, 0x7f, 0x8c, 0x9e, 0xa2, 1.253 + 0xe7, 0x94, 0xc9, 0x70, 0x70, 0xd0, 0xc4, 0xda, 1.254 + 0x49, 0x5b, 0x7a, 0x7d, 0xd9, 0x71, 0x7c, 0x3b, 1.255 + 0xdc, 0xd2, 0x8a, 0x74, 0x5f, 0xce, 0x09, 0xa2, 1.256 + 0xdb, 0xec, 0xa4, 0xba, 0x75, 0xaa, 0x0a, 0x97, 1.257 + 0xa6, 0x82, 0x25, 0x90, 0x90, 0x37, 0xe4, 0x40, 1.258 + 0x05, 0x28, 0x8f, 0x98, 0x8e, 0x68, 0x01, 0xaf, 1.259 + 0x9b, 0x08, 0x2a, 0x9b, 0xd5, 0xb9, 0x8c, 0x14, 1.260 + 0xbf, 0xba, 0xcb, 0x5b, 0xda, 0x4c, 0x95, 0xb8, 1.261 + 0xdf, 0x67, 0xa6, 0x6b, 0x76, 0x8c, 0xad, 0x4f, 1.262 + 0xfd, 0x6a, 0xd6, 0xcc, 0x62, 0x71, 0x30, 0x30, 1.263 + 0xc1, 0x29, 0x84, 0xe4, 0x8e, 0x32, 0x51, 0xb6, 1.264 + 0xea, 0xfa, 0xba, 0x00, 0x99, 0x76, 0xea, 0x86, 1.265 + 0x90, 0xab, 0x2d, 0xe9, 0xfd, 0x1e, 0x8c, 0xcc, 1.266 + 0x3c, 0x2b, 0x5d, 0x13, 0x1b, 0x47, 0xb4, 0xf5, 1.267 + 0x09, 0x74, 0x1d, 0xd4, 0x78, 0xb2, 0x42, 0x19, 1.268 + 0xd6, 0x24, 0xd1, 0x68, 0xbf, 0x11, 0xf1, 0x38, 1.269 + 0xa0, 0x44, 0x9c, 0xc6, 0x51, 0x33, 0xaa, 0x42, 1.270 + 0x93, 0x9e, 0x30, 0x58, 0x9e, 0xc0, 0x70, 0xdf, 1.271 + 0x7e, 0x64, 0xb1, 0xd8, 0x68, 0x75, 0x98, 0xa7 }; 1.272 + 1.273 +static const unsigned char subprime2[] = { 0x00, 1.274 + 0x8e, 0xab, 0xf4, 0xbe, 0x45, 0xeb, 0xa3, 0x58, 1.275 + 0x4e, 0x60, 0x15, 0x66, 0x5a, 0x4b, 0x25, 0xcf, 1.276 + 0x45, 0x77, 0x89, 0x3f, 0x73, 0x34, 0x4a, 0xe0, 1.277 + 0x9e, 0xac, 0xfd, 0xdc, 0xff, 0x9c, 0x8d, 0xe7 }; 1.278 + 1.279 +static const unsigned char base2[] = { 0x00, 1.280 + 0x8d, 0x72, 0x32, 0x46, 0xa6, 0x5c, 0x80, 0xe3, 1.281 + 0x43, 0x0a, 0x9e, 0x94, 0x35, 0x86, 0xd4, 0x58, 1.282 + 0xa1, 0xca, 0x22, 0xb9, 0x73, 0x46, 0x0b, 0xfb, 1.283 + 0x3e, 0x33, 0xf1, 0xd5, 0xd3, 0xb4, 0x26, 0xbf, 1.284 + 0x50, 0xd7, 0xf2, 0x09, 0x33, 0x6e, 0xc0, 0x31, 1.285 + 0x1b, 0x6d, 0x07, 0x70, 0x86, 0xca, 0x57, 0xf7, 1.286 + 0x0b, 0x4a, 0x63, 0xf0, 0x6f, 0xc8, 0x8a, 0xed, 1.287 + 0x50, 0x60, 0xf3, 0x11, 0xc7, 0x44, 0xf3, 0xce, 1.288 + 0x4e, 0x50, 0x42, 0x2d, 0x85, 0x33, 0x54, 0x57, 1.289 + 0x03, 0x8d, 0xdc, 0x66, 0x4d, 0x61, 0x83, 0x17, 1.290 + 0x1c, 0x7b, 0x0d, 0x65, 0xbc, 0x8f, 0x2c, 0x19, 1.291 + 0x86, 0xfc, 0xe2, 0x9f, 0x5d, 0x67, 0xfc, 0xd4, 1.292 + 0xa5, 0xf8, 0x23, 0xa1, 0x1a, 0xa2, 0xe1, 0x11, 1.293 + 0x15, 0x84, 0x32, 0x01, 0xee, 0x88, 0xf1, 0x55, 1.294 + 0x30, 0xe9, 0x74, 0x3c, 0x1a, 0x2b, 0x54, 0x45, 1.295 + 0x2e, 0x39, 0xb9, 0x77, 0xe1, 0x32, 0xaf, 0x2d, 1.296 + 0x97, 0xe0, 0x21, 0xec, 0xf5, 0x58, 0xe1, 0xc7, 1.297 + 0x2e, 0xe0, 0x71, 0x3d, 0x29, 0xa4, 0xd6, 0xe2, 1.298 + 0x5f, 0x85, 0x9c, 0x05, 0x04, 0x46, 0x41, 0x89, 1.299 + 0x03, 0x3c, 0xfa, 0xb2, 0xcf, 0xfa, 0xd5, 0x67, 1.300 + 0xcc, 0xec, 0x68, 0xfc, 0x83, 0xd9, 0x1f, 0x2e, 1.301 + 0x4e, 0x9a, 0x5e, 0x77, 0xa1, 0xff, 0xe6, 0x6f, 1.302 + 0x04, 0x8b, 0xf9, 0x6b, 0x47, 0xc6, 0x49, 0xd2, 1.303 + 0x88, 0x6e, 0x29, 0xa3, 0x1b, 0xae, 0xe0, 0x4f, 1.304 + 0x72, 0x8a, 0x28, 0x94, 0x0c, 0x1d, 0x8c, 0x99, 1.305 + 0xa2, 0x6f, 0xf8, 0xba, 0x99, 0x90, 0xc7, 0xe5, 1.306 + 0xb1, 0x3c, 0x10, 0x34, 0x86, 0x6a, 0x6a, 0x1f, 1.307 + 0x39, 0x63, 0x58, 0xe1, 0x5e, 0x97, 0x95, 0x45, 1.308 + 0x40, 0x38, 0x45, 0x6f, 0x02, 0xb5, 0x86, 0x6e, 1.309 + 0xae, 0x2f, 0x32, 0x7e, 0xa1, 0x3a, 0x34, 0x2c, 1.310 + 0x1c, 0xd3, 0xff, 0x4e, 0x2c, 0x38, 0x1c, 0xaa, 1.311 + 0x2e, 0x66, 0xbe, 0x32, 0x3e, 0x3c, 0x06, 0x5f }; 1.312 + 1.313 +static const unsigned char h2[] = { 1.314 + 0x30, 0x91, 0xa1, 0x2e, 0x40, 0xa5, 0x7d, 0xf7, 1.315 + 0xdc, 0xed, 0xee, 0x05, 0xc2, 0x31, 0x91, 0x37, 1.316 + 0xda, 0xc5, 0xe3, 0x47, 0xb5, 0x35, 0x4b, 0xfd, 1.317 + 0x18, 0xb2, 0x7e, 0x67, 0x1e, 0x92, 0x22, 0xe7, 1.318 + 0xf5, 0x00, 0x71, 0xc0, 0x86, 0x8d, 0x90, 0x31, 1.319 + 0x36, 0x3e, 0xd0, 0x94, 0x5d, 0x2f, 0x9a, 0x68, 1.320 + 0xd2, 0xf8, 0x3d, 0x5e, 0x84, 0x42, 0x35, 0xda, 1.321 + 0x75, 0xdd, 0x05, 0xf0, 0x03, 0x31, 0x39, 0xe5, 1.322 + 0xfd, 0x2f, 0x5a, 0x7d, 0x56, 0xd8, 0x26, 0xa0, 1.323 + 0x51, 0x5e, 0x32, 0xb4, 0xad, 0xee, 0xd4, 0x89, 1.324 + 0xae, 0x01, 0x7f, 0xac, 0x86, 0x98, 0x77, 0x26, 1.325 + 0x5c, 0x31, 0xd2, 0x5e, 0xbb, 0x7f, 0xf5, 0x4c, 1.326 + 0x9b, 0xf0, 0xa6, 0x37, 0x34, 0x08, 0x86, 0x6b, 1.327 + 0xce, 0xeb, 0x85, 0x66, 0x0a, 0x26, 0x8a, 0x14, 1.328 + 0x92, 0x12, 0x74, 0xf4, 0xf0, 0xcb, 0xb5, 0xfc, 1.329 + 0x38, 0xd5, 0x1e, 0xa1, 0x2f, 0x4a, 0x1a, 0xca, 1.330 + 0x66, 0xde, 0x6e, 0xe6, 0x6e, 0x1c, 0xef, 0x50, 1.331 + 0x41, 0x31, 0x09, 0xe7, 0x4a, 0xb8, 0xa3, 0xaa, 1.332 + 0x5a, 0x22, 0xbd, 0x63, 0x0f, 0xe9, 0x0e, 0xdb, 1.333 + 0xb3, 0xca, 0x7e, 0x8d, 0x40, 0xb3, 0x3e, 0x0b, 1.334 + 0x12, 0x8b, 0xb0, 0x80, 0x4d, 0x6d, 0xb0, 0x54, 1.335 + 0xbb, 0x4c, 0x1d, 0x6c, 0xa0, 0x5c, 0x9d, 0x91, 1.336 + 0xb3, 0xbb, 0xd9, 0xfc, 0x60, 0xec, 0xc1, 0xbc, 1.337 + 0xae, 0x72, 0x3f, 0xa5, 0x4f, 0x36, 0x2d, 0x2c, 1.338 + 0x81, 0x03, 0x86, 0xa2, 0x03, 0x38, 0x36, 0x8e, 1.339 + 0xad, 0x1d, 0x53, 0xc6, 0xc5, 0x9e, 0xda, 0x08, 1.340 + 0x35, 0x4f, 0xb2, 0x78, 0xba, 0xd1, 0x22, 0xde, 1.341 + 0xc4, 0x6b, 0xbe, 0x83, 0x71, 0x0f, 0xee, 0x38, 1.342 + 0x4a, 0x9f, 0xda, 0x90, 0x93, 0x6b, 0x9a, 0xf2, 1.343 + 0xeb, 0x23, 0xfe, 0x41, 0x3f, 0xf1, 0xfc, 0xee, 1.344 + 0x7f, 0x67, 0xa7, 0xb8, 0xab, 0x29, 0xf4, 0x75, 1.345 + 0x1c, 0xe9, 0xd1, 0x47, 0x7d, 0x86, 0x44, 0xe2 }; 1.346 + 1.347 +static const unsigned char seed2[] = { 0x00, 1.348 + 0xbc, 0xae, 0xc4, 0xea, 0x4e, 0xd2, 0xed, 0x1c, 1.349 + 0x8d, 0x48, 0xed, 0xf2, 0xa5, 0xb4, 0x18, 0xba, 1.350 + 0x00, 0xcb, 0x9c, 0x75, 0x8a, 0x39, 0x94, 0x3b, 1.351 + 0xd0, 0xd6, 0x01, 0xf7, 0xc1, 0xf5, 0x9d, 0xe5, 1.352 + 0xe3, 0xb4, 0x1d, 0xf5, 0x30, 0xfe, 0x99, 0xe4, 1.353 + 0x01, 0xab, 0xc0, 0x88, 0x4e, 0x67, 0x8f, 0xc6, 1.354 + 0x72, 0x39, 0x2e, 0xac, 0x51, 0xec, 0x91, 0x41, 1.355 + 0x47, 0x71, 0x14, 0x8a, 0x1d, 0xca, 0x88, 0x15, 1.356 + 0xea, 0xc9, 0x48, 0x9a, 0x71, 0x50, 0x19, 0x38, 1.357 + 0xdb, 0x4e, 0x65, 0xd5, 0x13, 0xd8, 0x2a, 0xc4, 1.358 + 0xcd, 0xfd, 0x0c, 0xe3, 0xc3, 0x60, 0xae, 0x6d, 1.359 + 0x88, 0xf2, 0x3a, 0xd0, 0x64, 0x73, 0x32, 0x89, 1.360 + 0xcd, 0x0b, 0xb8, 0xc7, 0xa5, 0x27, 0x84, 0xd5, 1.361 + 0x83, 0x3f, 0x0e, 0x10, 0x63, 0x10, 0x78, 0xac, 1.362 + 0x6b, 0x56, 0xb2, 0x62, 0x3a, 0x44, 0x56, 0xc0, 1.363 + 0xe4, 0x33, 0xd7, 0x63, 0x4c, 0xc9, 0x6b, 0xae, 1.364 + 0xfb, 0xe2, 0x9b, 0xf4, 0x96, 0xc7, 0xf0, 0x2a, 1.365 + 0x50, 0xde, 0x86, 0x69, 0x4f, 0x42, 0x4b, 0x1c, 1.366 + 0x7c, 0xa8, 0x6a, 0xfb, 0x54, 0x47, 0x1b, 0x41, 1.367 + 0x31, 0x9e, 0x0a, 0xc6, 0xc0, 0xbc, 0x88, 0x7f, 1.368 + 0x5a, 0x42, 0xa9, 0x82, 0x58, 0x32, 0xb3, 0xeb, 1.369 + 0x54, 0x83, 0x84, 0x26, 0x92, 0xa6, 0xc0, 0x6e, 1.370 + 0x2b, 0xa6, 0x82, 0x82, 0x43, 0x58, 0x84, 0x53, 1.371 + 0x31, 0xcf, 0xd0, 0x0a, 0x11, 0x09, 0x44, 0xc8, 1.372 + 0x11, 0x36, 0xe0, 0x04, 0x85, 0x2e, 0xd1, 0x29, 1.373 + 0x6b, 0x7b, 0x00, 0x71, 0x5f, 0xef, 0x7b, 0x7a, 1.374 + 0x2d, 0x91, 0xf9, 0x84, 0x45, 0x4d, 0xc7, 0xe1, 1.375 + 0xee, 0xd4, 0xb8, 0x61, 0x3b, 0x13, 0xb7, 0xba, 1.376 + 0x95, 0x39, 0xf6, 0x3d, 0x89, 0xbd, 0xa5, 0x80, 1.377 + 0x93, 0xf7, 0xe5, 0x17, 0x05, 0xc5, 0x65, 0xb7, 1.378 + 0xde, 0xc9, 0x9f, 0x04, 0x87, 0xcf, 0x4f, 0x86, 1.379 + 0xc3, 0x29, 0x7d, 0xb7, 0x89, 0xbf, 0xe3, 0xde }; 1.380 + 1.381 +static const unsigned int counter2=210; 1.382 + 1.383 +struct tuple_str { 1.384 + CK_RV errNum; 1.385 + const char * errString; 1.386 +}; 1.387 + 1.388 +typedef struct tuple_str tuple_str; 1.389 + 1.390 +static const tuple_str errStrings[] = { 1.391 +{CKR_OK , "CKR_OK "}, 1.392 +{CKR_CANCEL , "CKR_CANCEL "}, 1.393 +{CKR_HOST_MEMORY , "CKR_HOST_MEMORY "}, 1.394 +{CKR_SLOT_ID_INVALID , "CKR_SLOT_ID_INVALID "}, 1.395 +{CKR_GENERAL_ERROR , "CKR_GENERAL_ERROR "}, 1.396 +{CKR_FUNCTION_FAILED , "CKR_FUNCTION_FAILED "}, 1.397 +{CKR_ARGUMENTS_BAD , "CKR_ARGUMENTS_BAD "}, 1.398 +{CKR_NO_EVENT , "CKR_NO_EVENT "}, 1.399 +{CKR_NEED_TO_CREATE_THREADS , "CKR_NEED_TO_CREATE_THREADS "}, 1.400 +{CKR_CANT_LOCK , "CKR_CANT_LOCK "}, 1.401 +{CKR_ATTRIBUTE_READ_ONLY , "CKR_ATTRIBUTE_READ_ONLY "}, 1.402 +{CKR_ATTRIBUTE_SENSITIVE , "CKR_ATTRIBUTE_SENSITIVE "}, 1.403 +{CKR_ATTRIBUTE_TYPE_INVALID , "CKR_ATTRIBUTE_TYPE_INVALID "}, 1.404 +{CKR_ATTRIBUTE_VALUE_INVALID , "CKR_ATTRIBUTE_VALUE_INVALID "}, 1.405 +{CKR_DATA_INVALID , "CKR_DATA_INVALID "}, 1.406 +{CKR_DATA_LEN_RANGE , "CKR_DATA_LEN_RANGE "}, 1.407 +{CKR_DEVICE_ERROR , "CKR_DEVICE_ERROR "}, 1.408 +{CKR_DEVICE_MEMORY , "CKR_DEVICE_MEMORY "}, 1.409 +{CKR_DEVICE_REMOVED , "CKR_DEVICE_REMOVED "}, 1.410 +{CKR_ENCRYPTED_DATA_INVALID , "CKR_ENCRYPTED_DATA_INVALID "}, 1.411 +{CKR_ENCRYPTED_DATA_LEN_RANGE , "CKR_ENCRYPTED_DATA_LEN_RANGE "}, 1.412 +{CKR_FUNCTION_CANCELED , "CKR_FUNCTION_CANCELED "}, 1.413 +{CKR_FUNCTION_NOT_PARALLEL , "CKR_FUNCTION_NOT_PARALLEL "}, 1.414 +{CKR_FUNCTION_NOT_SUPPORTED , "CKR_FUNCTION_NOT_SUPPORTED "}, 1.415 +{CKR_KEY_HANDLE_INVALID , "CKR_KEY_HANDLE_INVALID "}, 1.416 +{CKR_KEY_SIZE_RANGE , "CKR_KEY_SIZE_RANGE "}, 1.417 +{CKR_KEY_TYPE_INCONSISTENT , "CKR_KEY_TYPE_INCONSISTENT "}, 1.418 +{CKR_KEY_NOT_NEEDED , "CKR_KEY_NOT_NEEDED "}, 1.419 +{CKR_KEY_CHANGED , "CKR_KEY_CHANGED "}, 1.420 +{CKR_KEY_NEEDED , "CKR_KEY_NEEDED "}, 1.421 +{CKR_KEY_INDIGESTIBLE , "CKR_KEY_INDIGESTIBLE "}, 1.422 +{CKR_KEY_FUNCTION_NOT_PERMITTED , "CKR_KEY_FUNCTION_NOT_PERMITTED "}, 1.423 +{CKR_KEY_NOT_WRAPPABLE , "CKR_KEY_NOT_WRAPPABLE "}, 1.424 +{CKR_KEY_UNEXTRACTABLE , "CKR_KEY_UNEXTRACTABLE "}, 1.425 +{CKR_MECHANISM_INVALID , "CKR_MECHANISM_INVALID "}, 1.426 +{CKR_MECHANISM_PARAM_INVALID , "CKR_MECHANISM_PARAM_INVALID "}, 1.427 +{CKR_OBJECT_HANDLE_INVALID , "CKR_OBJECT_HANDLE_INVALID "}, 1.428 +{CKR_OPERATION_ACTIVE , "CKR_OPERATION_ACTIVE "}, 1.429 +{CKR_OPERATION_NOT_INITIALIZED , "CKR_OPERATION_NOT_INITIALIZED "}, 1.430 +{CKR_PIN_INCORRECT , "CKR_PIN_INCORRECT "}, 1.431 +{CKR_PIN_INVALID , "CKR_PIN_INVALID "}, 1.432 +{CKR_PIN_LEN_RANGE , "CKR_PIN_LEN_RANGE "}, 1.433 +{CKR_PIN_EXPIRED , "CKR_PIN_EXPIRED "}, 1.434 +{CKR_PIN_LOCKED , "CKR_PIN_LOCKED "}, 1.435 +{CKR_SESSION_CLOSED , "CKR_SESSION_CLOSED "}, 1.436 +{CKR_SESSION_COUNT , "CKR_SESSION_COUNT "}, 1.437 +{CKR_SESSION_HANDLE_INVALID , "CKR_SESSION_HANDLE_INVALID "}, 1.438 +{CKR_SESSION_PARALLEL_NOT_SUPPORTED , "CKR_SESSION_PARALLEL_NOT_SUPPORTED "}, 1.439 +{CKR_SESSION_READ_ONLY , "CKR_SESSION_READ_ONLY "}, 1.440 +{CKR_SESSION_EXISTS , "CKR_SESSION_EXISTS "}, 1.441 +{CKR_SESSION_READ_ONLY_EXISTS , "CKR_SESSION_READ_ONLY_EXISTS "}, 1.442 +{CKR_SESSION_READ_WRITE_SO_EXISTS , "CKR_SESSION_READ_WRITE_SO_EXISTS "}, 1.443 +{CKR_SIGNATURE_INVALID , "CKR_SIGNATURE_INVALID "}, 1.444 +{CKR_SIGNATURE_LEN_RANGE , "CKR_SIGNATURE_LEN_RANGE "}, 1.445 +{CKR_TEMPLATE_INCOMPLETE , "CKR_TEMPLATE_INCOMPLETE "}, 1.446 +{CKR_TEMPLATE_INCONSISTENT , "CKR_TEMPLATE_INCONSISTENT "}, 1.447 +{CKR_TOKEN_NOT_PRESENT , "CKR_TOKEN_NOT_PRESENT "}, 1.448 +{CKR_TOKEN_NOT_RECOGNIZED , "CKR_TOKEN_NOT_RECOGNIZED "}, 1.449 +{CKR_TOKEN_WRITE_PROTECTED , "CKR_TOKEN_WRITE_PROTECTED "}, 1.450 +{CKR_UNWRAPPING_KEY_HANDLE_INVALID , "CKR_UNWRAPPING_KEY_HANDLE_INVALID "}, 1.451 +{CKR_UNWRAPPING_KEY_SIZE_RANGE , "CKR_UNWRAPPING_KEY_SIZE_RANGE "}, 1.452 +{CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT"}, 1.453 +{CKR_USER_ALREADY_LOGGED_IN , "CKR_USER_ALREADY_LOGGED_IN "}, 1.454 +{CKR_USER_NOT_LOGGED_IN , "CKR_USER_NOT_LOGGED_IN "}, 1.455 +{CKR_USER_PIN_NOT_INITIALIZED , "CKR_USER_PIN_NOT_INITIALIZED "}, 1.456 +{CKR_USER_TYPE_INVALID , "CKR_USER_TYPE_INVALID "}, 1.457 +{CKR_USER_ANOTHER_ALREADY_LOGGED_IN , "CKR_USER_ANOTHER_ALREADY_LOGGED_IN "}, 1.458 +{CKR_USER_TOO_MANY_TYPES , "CKR_USER_TOO_MANY_TYPES "}, 1.459 +{CKR_WRAPPED_KEY_INVALID , "CKR_WRAPPED_KEY_INVALID "}, 1.460 +{CKR_WRAPPED_KEY_LEN_RANGE , "CKR_WRAPPED_KEY_LEN_RANGE "}, 1.461 +{CKR_WRAPPING_KEY_HANDLE_INVALID , "CKR_WRAPPING_KEY_HANDLE_INVALID "}, 1.462 +{CKR_WRAPPING_KEY_SIZE_RANGE , "CKR_WRAPPING_KEY_SIZE_RANGE "}, 1.463 +{CKR_WRAPPING_KEY_TYPE_INCONSISTENT , "CKR_WRAPPING_KEY_TYPE_INCONSISTENT "}, 1.464 +{CKR_RANDOM_SEED_NOT_SUPPORTED , "CKR_RANDOM_SEED_NOT_SUPPORTED "}, 1.465 +{CKR_RANDOM_NO_RNG , "CKR_RANDOM_NO_RNG "}, 1.466 +{CKR_DOMAIN_PARAMS_INVALID , "CKR_DOMAIN_PARAMS_INVALID "}, 1.467 +{CKR_BUFFER_TOO_SMALL , "CKR_BUFFER_TOO_SMALL "}, 1.468 +{CKR_SAVED_STATE_INVALID , "CKR_SAVED_STATE_INVALID "}, 1.469 +{CKR_INFORMATION_SENSITIVE , "CKR_INFORMATION_SENSITIVE "}, 1.470 +{CKR_STATE_UNSAVEABLE , "CKR_STATE_UNSAVEABLE "}, 1.471 +{CKR_CRYPTOKI_NOT_INITIALIZED , "CKR_CRYPTOKI_NOT_INITIALIZED "}, 1.472 +{CKR_CRYPTOKI_ALREADY_INITIALIZED , "CKR_CRYPTOKI_ALREADY_INITIALIZED "}, 1.473 +{CKR_MUTEX_BAD , "CKR_MUTEX_BAD "}, 1.474 +{CKR_MUTEX_NOT_LOCKED , "CKR_MUTEX_NOT_LOCKED "}, 1.475 +{CKR_FUNCTION_REJECTED , "CKR_FUNCTION_REJECTED "}, 1.476 +{CKR_VENDOR_DEFINED , "CKR_VENDOR_DEFINED "}, 1.477 +{0xCE534351 , "CKR_NETSCAPE_CERTDB_FAILED "}, 1.478 +{0xCE534352 , "CKR_NETSCAPE_KEYDB_FAILED "} 1.479 + 1.480 +}; 1.481 + 1.482 +static const CK_ULONG numStrings = sizeof(errStrings) / sizeof(tuple_str); 1.483 + 1.484 +/* Returns constant error string for "CRV". 1.485 + * Returns "unknown error" if errNum is unknown. 1.486 + */ 1.487 +static const char * 1.488 +CK_RVtoStr(CK_RV errNum) { 1.489 + CK_ULONG low = 1; 1.490 + CK_ULONG high = numStrings - 1; 1.491 + CK_ULONG i; 1.492 + CK_RV num; 1.493 + static int initDone; 1.494 + 1.495 + /* make sure table is in ascending order. 1.496 + * binary search depends on it. 1.497 + */ 1.498 + if (!initDone) { 1.499 + CK_RV lastNum = CKR_OK; 1.500 + for (i = low; i <= high; ++i) { 1.501 + num = errStrings[i].errNum; 1.502 + if (num <= lastNum) { 1.503 + PR_fprintf(PR_STDERR, 1.504 + "sequence error in error strings at item %d\n" 1.505 + "error %d (%s)\n" 1.506 + "should come after \n" 1.507 + "error %d (%s)\n", 1.508 + (int) i, (int) lastNum, errStrings[i-1].errString, 1.509 + (int) num, errStrings[i].errString); 1.510 + } 1.511 + lastNum = num; 1.512 + } 1.513 + initDone = 1; 1.514 + } 1.515 + 1.516 + /* Do binary search of table. */ 1.517 + while (low + 1 < high) { 1.518 + i = (low + high) / 2; 1.519 + num = errStrings[i].errNum; 1.520 + if (errNum == num) 1.521 + return errStrings[i].errString; 1.522 + if (errNum < num) 1.523 + high = i; 1.524 + else 1.525 + low = i; 1.526 + } 1.527 + if (errNum == errStrings[low].errNum) 1.528 + return errStrings[low].errString; 1.529 + if (errNum == errStrings[high].errNum) 1.530 + return errStrings[high].errString; 1.531 + return "unknown error"; 1.532 +} 1.533 + 1.534 +static void 1.535 +pk11error(const char *string, CK_RV crv) { 1.536 + PRErrorCode errorcode; 1.537 + 1.538 + PR_fprintf(PR_STDERR, "%s: 0x%08lX, %-26s\n", string, crv, CK_RVtoStr(crv)); 1.539 + 1.540 + errorcode = PR_GetError(); 1.541 + if (errorcode) { 1.542 + PR_fprintf(PR_STDERR, "NSPR error code: %d: %s\n", errorcode, 1.543 + PR_ErrorToString(errorcode, PR_LANGUAGE_I_DEFAULT)); 1.544 + } 1.545 +} 1.546 + 1.547 +static void 1.548 +logIt(const char *fmt, ...) { 1.549 + va_list args; 1.550 + 1.551 + if (verbose) { 1.552 + va_start (args, fmt); 1.553 + vprintf(fmt, args); 1.554 + va_end(args); 1.555 + } 1.556 +} 1.557 + 1.558 +static CK_RV 1.559 +softokn_Init(CK_FUNCTION_LIST_PTR pFunctionList, const char * configDir, 1.560 + const char * dbPrefix) { 1.561 + 1.562 + CK_RV crv = CKR_OK; 1.563 + CK_C_INITIALIZE_ARGS initArgs; 1.564 + char *moduleSpec = NULL; 1.565 + 1.566 + initArgs.CreateMutex = NULL; 1.567 + initArgs.DestroyMutex = NULL; 1.568 + initArgs.LockMutex = NULL; 1.569 + initArgs.UnlockMutex = NULL; 1.570 + initArgs.flags = CKF_OS_LOCKING_OK; 1.571 + if (configDir) { 1.572 + moduleSpec = PR_smprintf("configdir='%s' certPrefix='%s' " 1.573 + "keyPrefix='%s' secmod='secmod.db' flags=ReadOnly ", 1.574 + configDir, dbPrefix, dbPrefix); 1.575 + } else { 1.576 + moduleSpec = PR_smprintf("configdir='' certPrefix='' keyPrefix='' " 1.577 + "secmod='' flags=noCertDB, noModDB"); 1.578 + } 1.579 + if (!moduleSpec) { 1.580 + PR_fprintf(PR_STDERR, "softokn_Init: out of memory error\n"); 1.581 + return CKR_HOST_MEMORY; 1.582 + } 1.583 + logIt("moduleSpec %s\n", moduleSpec); 1.584 + initArgs.LibraryParameters = (CK_CHAR_PTR *) moduleSpec; 1.585 + initArgs.pReserved = NULL; 1.586 + 1.587 + crv = pFunctionList->C_Initialize(&initArgs); 1.588 + if (crv != CKR_OK) { 1.589 + pk11error("C_Initialize failed", crv); 1.590 + goto cleanup; 1.591 + } 1.592 + 1.593 +cleanup: 1.594 + if (moduleSpec) { 1.595 + PR_smprintf_free(moduleSpec); 1.596 + } 1.597 + 1.598 + return crv; 1.599 +} 1.600 + 1.601 +static char * 1.602 +filePasswd(char *pwFile) 1.603 +{ 1.604 + unsigned char phrase[200]; 1.605 + PRFileDesc *fd; 1.606 + PRInt32 nb; 1.607 + int i; 1.608 + 1.609 + if (!pwFile) 1.610 + return 0; 1.611 + 1.612 + fd = PR_Open(pwFile, PR_RDONLY, 0); 1.613 + if (!fd) { 1.614 + lperror(pwFile); 1.615 + return NULL; 1.616 + } 1.617 + 1.618 + nb = PR_Read(fd, phrase, sizeof(phrase)); 1.619 + 1.620 + PR_Close(fd); 1.621 + /* handle the Windows EOL case */ 1.622 + i = 0; 1.623 + while (phrase[i] != '\r' && phrase[i] != '\n' && i < nb) i++; 1.624 + phrase[i] = '\0'; 1.625 + if (nb == 0) { 1.626 + PR_fprintf(PR_STDERR,"password file contains no data\n"); 1.627 + return NULL; 1.628 + } 1.629 + return (char*) PL_strdup((char*)phrase); 1.630 +} 1.631 + 1.632 +static void 1.633 +checkPath(char *string) 1.634 +{ 1.635 + char *src; 1.636 + char *dest; 1.637 + 1.638 + /* 1.639 + * windows support convert any back slashes to 1.640 + * forward slashes. 1.641 + */ 1.642 + for (src=string, dest=string; *src; src++,dest++) { 1.643 + if (*src == '\\') { 1.644 + *dest = '/'; 1.645 + } 1.646 + } 1.647 + dest--; 1.648 + /* if the last char is a / set it to 0 */ 1.649 + if (*dest == '/') 1.650 + *dest = 0; 1.651 + 1.652 +} 1.653 + 1.654 +static CK_SLOT_ID * 1.655 +getSlotList(CK_FUNCTION_LIST_PTR pFunctionList, 1.656 + CK_ULONG slotIndex) { 1.657 + CK_RV crv = CKR_OK; 1.658 + CK_SLOT_ID *pSlotList = NULL; 1.659 + CK_ULONG slotCount; 1.660 + 1.661 + /* Get slot list */ 1.662 + crv = pFunctionList->C_GetSlotList(CK_FALSE /* all slots */, 1.663 + NULL, &slotCount); 1.664 + if (crv != CKR_OK) { 1.665 + pk11error( "C_GetSlotList failed", crv); 1.666 + return NULL; 1.667 + } 1.668 + 1.669 + if (slotIndex >= slotCount) { 1.670 + PR_fprintf(PR_STDERR, "provided slotIndex is greater than the slot count."); 1.671 + return NULL; 1.672 + } 1.673 + 1.674 + pSlotList = (CK_SLOT_ID *)PR_Malloc(slotCount * sizeof(CK_SLOT_ID)); 1.675 + if (!pSlotList) { 1.676 + lperror("failed to allocate slot list"); 1.677 + return NULL; 1.678 + } 1.679 + crv = pFunctionList->C_GetSlotList(CK_FALSE /* all slots */, 1.680 + pSlotList, &slotCount); 1.681 + if (crv != CKR_OK) { 1.682 + pk11error( "C_GetSlotList failed", crv); 1.683 + if (pSlotList) PR_Free(pSlotList); 1.684 + return NULL; 1.685 + } 1.686 + return pSlotList; 1.687 +} 1.688 + 1.689 +int main(int argc, char **argv) 1.690 +{ 1.691 + PLOptState *optstate; 1.692 + char *program_name; 1.693 + char *libname = NULL; 1.694 + PRLibrary *lib; 1.695 + PRFileDesc *fd; 1.696 + PRStatus rv = PR_SUCCESS; 1.697 + const char *input_file = NULL; /* read/create encrypted data from here */ 1.698 + char *output_file = NULL; /* write new encrypted data here */ 1.699 + int bytesRead; 1.700 + int bytesWritten; 1.701 + unsigned char file_buf[512]; 1.702 + int count=0; 1.703 + int keySize = 0; 1.704 + int i; 1.705 + PRBool verify = PR_FALSE; 1.706 + static PRBool FIPSMODE = PR_FALSE; 1.707 + PRBool successful = PR_FALSE; 1.708 + 1.709 +#ifdef USES_LINKS 1.710 + int ret; 1.711 + struct stat stat_buf; 1.712 + char link_buf[MAXPATHLEN+1]; 1.713 + char *link_file = NULL; 1.714 +#endif 1.715 + 1.716 + char *pwd = NULL; 1.717 + char *configDir = NULL; 1.718 + char *dbPrefix = NULL; 1.719 + char *disableUnload = NULL; 1.720 + 1.721 + CK_C_GetFunctionList pC_GetFunctionList; 1.722 + CK_TOKEN_INFO tokenInfo; 1.723 + CK_FUNCTION_LIST_PTR pFunctionList = NULL; 1.724 + CK_RV crv = CKR_OK; 1.725 + CK_SESSION_HANDLE hRwSession; 1.726 + CK_SLOT_ID *pSlotList = NULL; 1.727 + CK_ULONG slotIndex = 0; 1.728 + CK_MECHANISM digestmech; 1.729 + CK_ULONG digestLen = 0; 1.730 + CK_BYTE digest[32]; /* SHA256_LENGTH */ 1.731 + CK_BYTE sign[64]; /* DSA SIGNATURE LENGTH */ 1.732 + CK_ULONG signLen = 0 ; 1.733 + CK_MECHANISM signMech = { 1.734 + CKM_DSA, NULL, 0 1.735 + }; 1.736 + 1.737 + /*** DSA Key ***/ 1.738 + 1.739 + CK_MECHANISM dsaKeyPairGenMech; 1.740 + CK_ATTRIBUTE dsaPubKeyTemplate[5]; 1.741 + CK_ATTRIBUTE dsaPrivKeyTemplate[5]; 1.742 + CK_OBJECT_HANDLE hDSApubKey = CK_INVALID_HANDLE; 1.743 + CK_OBJECT_HANDLE hDSAprivKey = CK_INVALID_HANDLE; 1.744 + 1.745 + CK_BYTE dsaPubKey[384]; 1.746 + CK_ATTRIBUTE dsaPubKeyValue; 1.747 + 1.748 + 1.749 + program_name = strrchr(argv[0], '/'); 1.750 + program_name = program_name ? (program_name + 1) : argv[0]; 1.751 + optstate = PL_CreateOptState (argc, argv, "i:o:f:Fd:hH?k:p:P:vVs:"); 1.752 + if (optstate == NULL) { 1.753 + lperror("PL_CreateOptState failed"); 1.754 + return 1; 1.755 + } 1.756 + 1.757 + while (PL_GetNextOpt (optstate) == PL_OPT_OK) { 1.758 + switch (optstate->option) { 1.759 + 1.760 + case 'd': 1.761 + if (!optstate->value) { 1.762 + PL_DestroyOptState(optstate); 1.763 + usage(program_name); 1.764 + } 1.765 + configDir = PL_strdup(optstate->value); 1.766 + checkPath(configDir); 1.767 + break; 1.768 + 1.769 + case 'i': 1.770 + if (!optstate->value) { 1.771 + PL_DestroyOptState(optstate); 1.772 + usage(program_name); 1.773 + } 1.774 + input_file = optstate->value; 1.775 + break; 1.776 + 1.777 + case 'o': 1.778 + if (!optstate->value) { 1.779 + PL_DestroyOptState(optstate); 1.780 + usage(program_name); 1.781 + } 1.782 + output_file = PL_strdup(optstate->value); 1.783 + break; 1.784 + 1.785 + case 'k': 1.786 + if (!optstate->value) { 1.787 + PL_DestroyOptState(optstate); 1.788 + usage(program_name); 1.789 + } 1.790 + keySize = atoi(optstate->value); 1.791 + break; 1.792 + 1.793 + case 'f': 1.794 + if (!optstate->value) { 1.795 + PL_DestroyOptState(optstate); 1.796 + usage(program_name); 1.797 + } 1.798 + pwd = filePasswd((char *)optstate->value); 1.799 + if (!pwd) usage(program_name); 1.800 + break; 1.801 + 1.802 + case 'F': 1.803 + FIPSMODE = PR_TRUE; 1.804 + break; 1.805 + 1.806 + case 'p': 1.807 + if (!optstate->value) { 1.808 + PL_DestroyOptState(optstate); 1.809 + usage(program_name); 1.810 + } 1.811 + pwd = PL_strdup(optstate->value); 1.812 + break; 1.813 + 1.814 + case 'P': 1.815 + if (!optstate->value) { 1.816 + PL_DestroyOptState(optstate); 1.817 + usage(program_name); 1.818 + } 1.819 + dbPrefix = PL_strdup(optstate->value); 1.820 + break; 1.821 + 1.822 + case 'v': 1.823 + verbose = PR_TRUE; 1.824 + break; 1.825 + 1.826 + case 'V': 1.827 + verify = PR_TRUE; 1.828 + break; 1.829 + 1.830 + case 'H': 1.831 + PL_DestroyOptState(optstate); 1.832 + long_usage (program_name); 1.833 + return 1; 1.834 + break; 1.835 + 1.836 + case 'h': 1.837 + case '?': 1.838 + default: 1.839 + PL_DestroyOptState(optstate); 1.840 + usage(program_name); 1.841 + return 1; 1.842 + break; 1.843 + } 1.844 + } 1.845 + PL_DestroyOptState(optstate); 1.846 + 1.847 + if (!input_file) { 1.848 + usage(program_name); 1.849 + return 1; 1.850 + } 1.851 + 1.852 + /* Get the platform-dependent library name of the 1.853 + * NSS cryptographic module. 1.854 + */ 1.855 + libname = PR_GetLibraryName(NULL, "softokn3"); 1.856 + assert(libname != NULL); 1.857 + lib = PR_LoadLibrary(libname); 1.858 + assert(lib != NULL); 1.859 + PR_FreeLibraryName(libname); 1.860 + 1.861 + 1.862 + if (FIPSMODE) { 1.863 + /* FIPSMODE == FC_GetFunctionList */ 1.864 + /* library path must be set to an already signed softokn3/freebl */ 1.865 + pC_GetFunctionList = (CK_C_GetFunctionList) 1.866 + PR_FindFunctionSymbol(lib, "FC_GetFunctionList"); 1.867 + } else { 1.868 + /* NON FIPS mode == C_GetFunctionList */ 1.869 + pC_GetFunctionList = (CK_C_GetFunctionList) 1.870 + PR_FindFunctionSymbol(lib, "C_GetFunctionList"); 1.871 + } 1.872 + assert(pC_GetFunctionList != NULL); 1.873 + 1.874 + crv = (*pC_GetFunctionList)(&pFunctionList); 1.875 + assert(crv == CKR_OK); 1.876 + 1.877 + if (configDir) { 1.878 + if (!dbPrefix) { 1.879 + dbPrefix = PL_strdup(""); 1.880 + } 1.881 + crv = softokn_Init(pFunctionList, configDir, dbPrefix); 1.882 + if (crv != CKR_OK) { 1.883 + logIt("Failed to use provided database directory " 1.884 + "will just initialize the volatile certdb.\n"); 1.885 + crv = softokn_Init(pFunctionList, NULL, NULL); /* NoDB Init */ 1.886 + } 1.887 + } else { 1.888 + crv = softokn_Init(pFunctionList, NULL, NULL); /* NoDB Init */ 1.889 + } 1.890 + 1.891 + if (crv != CKR_OK) { 1.892 + pk11error( "Initiailzing softoken failed", crv); 1.893 + goto cleanup; 1.894 + } 1.895 + 1.896 + pSlotList = getSlotList(pFunctionList, slotIndex); 1.897 + if (pSlotList == NULL) { 1.898 + PR_fprintf(PR_STDERR, "getSlotList failed"); 1.899 + goto cleanup; 1.900 + } 1.901 + 1.902 + if ((keySize == 0) || (keySize > 1024)) { 1.903 + CK_MECHANISM_INFO mechInfo; 1.904 + crv = pFunctionList->C_GetMechanismInfo(pSlotList[slotIndex], 1.905 + CKM_DSA, &mechInfo); 1.906 + if (crv != CKR_OK) { 1.907 + pk11error( "Couldn't get mechanism info for DSA", crv); 1.908 + goto cleanup; 1.909 + } 1.910 + 1.911 + if (keySize && (mechInfo.ulMaxKeySize < keySize)) { 1.912 + PR_fprintf(PR_STDERR, 1.913 + "token doesn't support DSA2 (Max key size=%d)\n", 1.914 + mechInfo.ulMaxKeySize); 1.915 + goto cleanup; 1.916 + } 1.917 + 1.918 + if ((keySize == 0) && mechInfo.ulMaxKeySize >=2048 ) { 1.919 + keySize = 2048; 1.920 + } else { 1.921 + keySize = 1024; 1.922 + } 1.923 + } 1.924 + 1.925 + /* DSA key init */ 1.926 + if (keySize == 1024) { 1.927 + dsaPubKeyTemplate[0].type = CKA_PRIME; 1.928 + dsaPubKeyTemplate[0].pValue = (CK_VOID_PTR) ′ 1.929 + dsaPubKeyTemplate[0].ulValueLen = sizeof(prime); 1.930 + dsaPubKeyTemplate[1].type = CKA_SUBPRIME; 1.931 + dsaPubKeyTemplate[1].pValue = (CK_VOID_PTR) &subprime; 1.932 + dsaPubKeyTemplate[1].ulValueLen = sizeof(subprime); 1.933 + dsaPubKeyTemplate[2].type = CKA_BASE; 1.934 + dsaPubKeyTemplate[2].pValue = (CK_VOID_PTR) &base; 1.935 + dsaPubKeyTemplate[2].ulValueLen = sizeof(base); 1.936 + digestmech.mechanism = CKM_SHA_1; 1.937 + digestmech.pParameter = NULL; 1.938 + digestmech.ulParameterLen = 0; 1.939 + } else if (keySize == 2048) { 1.940 + dsaPubKeyTemplate[0].type = CKA_PRIME; 1.941 + dsaPubKeyTemplate[0].pValue = (CK_VOID_PTR) &prime2; 1.942 + dsaPubKeyTemplate[0].ulValueLen = sizeof(prime2); 1.943 + dsaPubKeyTemplate[1].type = CKA_SUBPRIME; 1.944 + dsaPubKeyTemplate[1].pValue = (CK_VOID_PTR) &subprime2; 1.945 + dsaPubKeyTemplate[1].ulValueLen = sizeof(subprime2); 1.946 + dsaPubKeyTemplate[2].type = CKA_BASE; 1.947 + dsaPubKeyTemplate[2].pValue = (CK_VOID_PTR) &base2; 1.948 + dsaPubKeyTemplate[2].ulValueLen = sizeof(base2); 1.949 + digestmech.mechanism = CKM_SHA256; 1.950 + digestmech.pParameter = NULL; 1.951 + digestmech.ulParameterLen = 0; 1.952 + } else { 1.953 + /* future - generate pqg */ 1.954 + PR_fprintf(PR_STDERR, "Only keysizes 1024 and 2048 are supported"); 1.955 + goto cleanup; 1.956 + } 1.957 + dsaPubKeyTemplate[3].type = CKA_TOKEN; 1.958 + dsaPubKeyTemplate[3].pValue = &false; /* session object */ 1.959 + dsaPubKeyTemplate[3].ulValueLen = sizeof(false); 1.960 + dsaPubKeyTemplate[4].type = CKA_VERIFY; 1.961 + dsaPubKeyTemplate[4].pValue = &true; 1.962 + dsaPubKeyTemplate[4].ulValueLen = sizeof(true); 1.963 + dsaKeyPairGenMech.mechanism = CKM_DSA_KEY_PAIR_GEN; 1.964 + dsaKeyPairGenMech.pParameter = NULL; 1.965 + dsaKeyPairGenMech.ulParameterLen = 0; 1.966 + dsaPrivKeyTemplate[0].type = CKA_TOKEN; 1.967 + dsaPrivKeyTemplate[0].pValue = &false; /* session object */ 1.968 + dsaPrivKeyTemplate[0].ulValueLen = sizeof(false); 1.969 + dsaPrivKeyTemplate[1].type = CKA_PRIVATE; 1.970 + dsaPrivKeyTemplate[1].pValue = &true; 1.971 + dsaPrivKeyTemplate[1].ulValueLen = sizeof(true); 1.972 + dsaPrivKeyTemplate[2].type = CKA_SENSITIVE; 1.973 + dsaPrivKeyTemplate[2].pValue = &true; 1.974 + dsaPrivKeyTemplate[2].ulValueLen = sizeof(true); 1.975 + dsaPrivKeyTemplate[3].type = CKA_SIGN, 1.976 + dsaPrivKeyTemplate[3].pValue = &true; 1.977 + dsaPrivKeyTemplate[3].ulValueLen = sizeof(true); 1.978 + dsaPrivKeyTemplate[4].type = CKA_EXTRACTABLE; 1.979 + dsaPrivKeyTemplate[4].pValue = &false; 1.980 + dsaPrivKeyTemplate[4].ulValueLen = sizeof(false); 1.981 + 1.982 + crv = pFunctionList->C_OpenSession(pSlotList[slotIndex], 1.983 + CKF_RW_SESSION | CKF_SERIAL_SESSION, 1.984 + NULL, NULL, &hRwSession); 1.985 + if (crv != CKR_OK) { 1.986 + pk11error( "Opening a read/write session failed", crv); 1.987 + goto cleanup; 1.988 + } 1.989 + 1.990 + /* check if a password is needed */ 1.991 + crv = pFunctionList->C_GetTokenInfo(pSlotList[slotIndex], &tokenInfo); 1.992 + if (crv != CKR_OK) { 1.993 + pk11error( "C_GetTokenInfo failed", crv); 1.994 + goto cleanup; 1.995 + } 1.996 + if (tokenInfo.flags & CKF_LOGIN_REQUIRED) { 1.997 + if (pwd) { 1.998 + int pwdLen = strlen((const char*)pwd); 1.999 + crv = pFunctionList->C_Login(hRwSession, CKU_USER, 1.1000 + (CK_UTF8CHAR_PTR) pwd, (CK_ULONG)pwdLen); 1.1001 + if (crv != CKR_OK) { 1.1002 + pk11error("C_Login failed", crv); 1.1003 + goto cleanup; 1.1004 + } 1.1005 + } else { 1.1006 + PR_fprintf(PR_STDERR, "Please provide the password for the token"); 1.1007 + goto cleanup; 1.1008 + } 1.1009 + } else if (pwd) { 1.1010 + logIt("A password was provided but the password was not used.\n"); 1.1011 + } 1.1012 + 1.1013 + /* Generate a DSA key pair */ 1.1014 + logIt("Generate a DSA key pair ... \n"); 1.1015 + crv = pFunctionList->C_GenerateKeyPair(hRwSession, &dsaKeyPairGenMech, 1.1016 + dsaPubKeyTemplate, 1.1017 + NUM_ELEM(dsaPubKeyTemplate), 1.1018 + dsaPrivKeyTemplate, 1.1019 + NUM_ELEM(dsaPrivKeyTemplate), 1.1020 + &hDSApubKey, &hDSAprivKey); 1.1021 + if (crv != CKR_OK) { 1.1022 + pk11error("DSA key pair generation failed", crv); 1.1023 + goto cleanup; 1.1024 + } 1.1025 + 1.1026 + /* open the shared library */ 1.1027 + fd = PR_OpenFile(input_file,PR_RDONLY,0); 1.1028 + if (fd == NULL ) { 1.1029 + lperror(input_file); 1.1030 + goto cleanup; 1.1031 + } 1.1032 +#ifdef USES_LINKS 1.1033 + ret = lstat(input_file, &stat_buf); 1.1034 + if (ret < 0) { 1.1035 + perror(input_file); 1.1036 + goto cleanup; 1.1037 + } 1.1038 + if (S_ISLNK(stat_buf.st_mode)) { 1.1039 + char *dirpath,*dirend; 1.1040 + ret = readlink(input_file, link_buf, sizeof(link_buf) - 1); 1.1041 + if (ret < 0) { 1.1042 + perror(input_file); 1.1043 + goto cleanup; 1.1044 + } 1.1045 + link_buf[ret] = 0; 1.1046 + link_file = mkoutput(input_file); 1.1047 + /* get the dirname of input_file */ 1.1048 + dirpath = PL_strdup(input_file); 1.1049 + dirend = strrchr(dirpath, '/'); 1.1050 + if (dirend) { 1.1051 + *dirend = '\0'; 1.1052 + ret = chdir(dirpath); 1.1053 + if (ret < 0) { 1.1054 + perror(dirpath); 1.1055 + goto cleanup; 1.1056 + } 1.1057 + } 1.1058 + PL_strfree(dirpath); 1.1059 + input_file = link_buf; 1.1060 + /* get the basename of link_file */ 1.1061 + dirend = strrchr(link_file, '/'); 1.1062 + if (dirend) { 1.1063 + char * tmp_file = NULL; 1.1064 + tmp_file = PL_strdup(dirend +1 ); 1.1065 + PL_strfree(link_file); 1.1066 + link_file = tmp_file; 1.1067 + } 1.1068 + } 1.1069 +#endif 1.1070 + if (output_file == NULL) { 1.1071 + output_file = mkoutput(input_file); 1.1072 + } 1.1073 + 1.1074 + /* compute the digest */ 1.1075 + memset(digest, 0, sizeof(digest)); 1.1076 + crv = pFunctionList->C_DigestInit(hRwSession, &digestmech); 1.1077 + if (crv != CKR_OK) { 1.1078 + pk11error("C_DigestInit failed", crv); 1.1079 + goto cleanup; 1.1080 + } 1.1081 + 1.1082 + /* Digest the file */ 1.1083 + while ((bytesRead = PR_Read(fd,file_buf,sizeof(file_buf))) > 0) { 1.1084 + crv = pFunctionList->C_DigestUpdate(hRwSession, (CK_BYTE_PTR)file_buf, 1.1085 + bytesRead); 1.1086 + if (crv != CKR_OK) { 1.1087 + pk11error("C_DigestUpdate failed", crv); 1.1088 + goto cleanup; 1.1089 + } 1.1090 + count += bytesRead; 1.1091 + } 1.1092 + 1.1093 + /* close the input_File */ 1.1094 + PR_Close(fd); 1.1095 + fd = NULL; 1.1096 + if (bytesRead < 0) { 1.1097 + lperror("0 bytes read from input file"); 1.1098 + goto cleanup; 1.1099 + } 1.1100 + 1.1101 + digestLen = sizeof(digest); 1.1102 + crv = pFunctionList->C_DigestFinal(hRwSession, (CK_BYTE_PTR)digest, 1.1103 + &digestLen); 1.1104 + if (crv != CKR_OK) { 1.1105 + pk11error("C_DigestFinal failed", crv); 1.1106 + goto cleanup; 1.1107 + } 1.1108 + 1.1109 + if (digestLen != sizeof(digest)) { 1.1110 + PR_fprintf(PR_STDERR, "digestLen has incorrect length %lu " 1.1111 + "it should be %lu \n",digestLen, sizeof(digest)); 1.1112 + goto cleanup; 1.1113 + } 1.1114 + 1.1115 + /* sign the hash */ 1.1116 + memset(sign, 0, sizeof(sign)); 1.1117 + /* SignUpdate */ 1.1118 + crv = pFunctionList->C_SignInit(hRwSession, &signMech, hDSAprivKey); 1.1119 + if (crv != CKR_OK) { 1.1120 + pk11error("C_SignInit failed", crv); 1.1121 + goto cleanup; 1.1122 + } 1.1123 + 1.1124 + signLen = sizeof(sign); 1.1125 + crv = pFunctionList->C_Sign(hRwSession, (CK_BYTE * ) digest, digestLen, 1.1126 + sign, &signLen); 1.1127 + if (crv != CKR_OK) { 1.1128 + pk11error("C_Sign failed", crv); 1.1129 + goto cleanup; 1.1130 + } 1.1131 + 1.1132 + if (signLen != sizeof(sign)) { 1.1133 + PR_fprintf(PR_STDERR, "signLen has incorrect length %lu " 1.1134 + "it should be %lu \n", signLen, sizeof(sign)); 1.1135 + goto cleanup; 1.1136 + } 1.1137 + 1.1138 + if (verify) { 1.1139 + crv = pFunctionList->C_VerifyInit(hRwSession, &signMech, hDSApubKey); 1.1140 + if (crv != CKR_OK) { 1.1141 + pk11error("C_VerifyInit failed", crv); 1.1142 + goto cleanup; 1.1143 + } 1.1144 + crv = pFunctionList->C_Verify(hRwSession, digest, digestLen, 1.1145 + sign, signLen); 1.1146 + if (crv != CKR_OK) { 1.1147 + pk11error("C_Verify failed", crv); 1.1148 + goto cleanup; 1.1149 + } 1.1150 + } 1.1151 + 1.1152 + if (verbose) { 1.1153 + int j; 1.1154 + PR_fprintf(PR_STDERR,"Library File: %s %d bytes\n",input_file, count); 1.1155 + PR_fprintf(PR_STDERR,"Check File: %s\n",output_file); 1.1156 +#ifdef USES_LINKS 1.1157 + if (link_file) { 1.1158 + PR_fprintf(PR_STDERR,"Link: %s\n",link_file); 1.1159 + } 1.1160 +#endif 1.1161 + PR_fprintf(PR_STDERR," hash: %lu bytes\n", digestLen); 1.1162 +#define STEP 10 1.1163 + for (i=0; i < (int) digestLen; i += STEP) { 1.1164 + PR_fprintf(PR_STDERR," "); 1.1165 + for (j=0; j < STEP && (i+j) < (int) digestLen; j++) { 1.1166 + PR_fprintf(PR_STDERR," %02x", digest[i+j]); 1.1167 + } 1.1168 + PR_fprintf(PR_STDERR,"\n"); 1.1169 + } 1.1170 + PR_fprintf(PR_STDERR," signature: %lu bytes\n", signLen); 1.1171 + for (i=0; i < (int) signLen; i += STEP) { 1.1172 + PR_fprintf(PR_STDERR," "); 1.1173 + for (j=0; j < STEP && (i+j) < (int) signLen; j++) { 1.1174 + PR_fprintf(PR_STDERR," %02x", sign[i+j]); 1.1175 + } 1.1176 + PR_fprintf(PR_STDERR,"\n"); 1.1177 + } 1.1178 + } 1.1179 + 1.1180 + /* open the target signature file */ 1.1181 + fd = PR_Open(output_file,PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE,0666); 1.1182 + if (fd == NULL ) { 1.1183 + lperror(output_file); 1.1184 + goto cleanup; 1.1185 + } 1.1186 + 1.1187 + /* 1.1188 + * we write the key out in a straight binary format because very 1.1189 + * low level libraries need to read an parse this file. Ideally we should 1.1190 + * just derEncode the public key (which would be pretty simple, and be 1.1191 + * more general), but then we'd need to link the ASN.1 decoder with the 1.1192 + * freebl libraries. 1.1193 + */ 1.1194 + 1.1195 + file_buf[0] = NSS_SIGN_CHK_MAGIC1; 1.1196 + file_buf[1] = NSS_SIGN_CHK_MAGIC2; 1.1197 + file_buf[2] = NSS_SIGN_CHK_MAJOR_VERSION; 1.1198 + file_buf[3] = NSS_SIGN_CHK_MINOR_VERSION; 1.1199 + encodeInt(&file_buf[4],12); /* offset to data start */ 1.1200 + encodeInt(&file_buf[8],CKK_DSA); 1.1201 + bytesWritten = PR_Write(fd,file_buf, 12); 1.1202 + if (bytesWritten != 12) { 1.1203 + lperror(output_file); 1.1204 + goto cleanup; 1.1205 + } 1.1206 + 1.1207 + /* get DSA Public KeyValue */ 1.1208 + memset(dsaPubKey, 0, sizeof(dsaPubKey)); 1.1209 + dsaPubKeyValue.type =CKA_VALUE; 1.1210 + dsaPubKeyValue.pValue = (CK_VOID_PTR) &dsaPubKey; 1.1211 + dsaPubKeyValue.ulValueLen = sizeof(dsaPubKey); 1.1212 + 1.1213 + crv = pFunctionList->C_GetAttributeValue(hRwSession, hDSApubKey, 1.1214 + &dsaPubKeyValue, 1); 1.1215 + if (crv != CKR_OK && crv != CKR_ATTRIBUTE_TYPE_INVALID) { 1.1216 + pk11error("C_GetAttributeValue failed", crv); 1.1217 + goto cleanup; 1.1218 + } 1.1219 + 1.1220 + /* CKA_PRIME */ 1.1221 + rv = writeItem(fd,dsaPubKeyTemplate[0].pValue, 1.1222 + dsaPubKeyTemplate[0].ulValueLen, output_file); 1.1223 + if (rv != PR_SUCCESS) goto cleanup; 1.1224 + /* CKA_SUBPRIME */ 1.1225 + rv = writeItem(fd,dsaPubKeyTemplate[1].pValue, 1.1226 + dsaPubKeyTemplate[1].ulValueLen, output_file); 1.1227 + if (rv != PR_SUCCESS) goto cleanup; 1.1228 + /* CKA_BASE */ 1.1229 + rv = writeItem(fd,dsaPubKeyTemplate[2].pValue, 1.1230 + dsaPubKeyTemplate[2].ulValueLen, output_file); 1.1231 + if (rv != PR_SUCCESS) goto cleanup; 1.1232 + /* DSA Public Key value */ 1.1233 + rv = writeItem(fd,dsaPubKeyValue.pValue, 1.1234 + dsaPubKeyValue.ulValueLen, output_file); 1.1235 + if (rv != PR_SUCCESS) goto cleanup; 1.1236 + /* DSA SIGNATURE */ 1.1237 + rv = writeItem(fd,&sign, signLen, output_file); 1.1238 + if (rv != PR_SUCCESS) goto cleanup; 1.1239 + PR_Close(fd); 1.1240 + 1.1241 +#ifdef USES_LINKS 1.1242 + if (link_file) { 1.1243 + (void)unlink(link_file); 1.1244 + ret = symlink(output_file, link_file); 1.1245 + if (ret < 0) { 1.1246 + perror(link_file); 1.1247 + goto cleanup; 1.1248 + } 1.1249 + } 1.1250 +#endif 1.1251 + 1.1252 + successful = PR_TRUE; 1.1253 + 1.1254 +cleanup: 1.1255 + if (pFunctionList) { 1.1256 + /* C_Finalize will automatically logout, close session, */ 1.1257 + /* and delete the temp objects on the token */ 1.1258 + crv = pFunctionList->C_Finalize(NULL); 1.1259 + if (crv != CKR_OK) { 1.1260 + pk11error("C_Finalize failed", crv); 1.1261 + } 1.1262 + } 1.1263 + if (pSlotList) { 1.1264 + PR_Free(pSlotList); 1.1265 + } 1.1266 + if (pwd) { 1.1267 + PL_strfree(pwd); 1.1268 + } 1.1269 + if (configDir) { 1.1270 + PL_strfree(configDir); 1.1271 + } 1.1272 + if (dbPrefix) { 1.1273 + PL_strfree(dbPrefix); 1.1274 + } 1.1275 + if (output_file) { /* allocated by mkoutput function */ 1.1276 + PL_strfree(output_file); 1.1277 + } 1.1278 +#ifdef USES_LINKS 1.1279 + if (link_file) { /* allocated by mkoutput function */ 1.1280 + PL_strfree(link_file); 1.1281 + } 1.1282 +#endif 1.1283 + 1.1284 + disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD"); 1.1285 + if (!disableUnload) { 1.1286 + PR_UnloadLibrary(lib); 1.1287 + } 1.1288 + PR_Cleanup(); 1.1289 + 1.1290 + if (crv != CKR_OK) 1.1291 + return crv; 1.1292 + 1.1293 + return (successful) ? 0 : 1; 1.1294 +}