Import from 1.9a8 tarball
[mozilla-nss.git] / security / nss / cmd / pwdecrypt / pwdecrypt.c
blob541dbdb3fcbfedf6fa855367bd922294f95bd151
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
38 * Test program for SDR (Secret Decoder Ring) functions.
40 * $Id: pwdecrypt.c,v 1.4 2005/11/15 23:40:18 nelsonb%netscape.com Exp $
43 #include "nspr.h"
44 #include "string.h"
45 #include "nss.h"
46 #include "secutil.h"
47 #include "cert.h"
48 #include "pk11func.h"
49 #include "nssb64.h"
51 #include "plgetopt.h"
52 #include "pk11sdr.h"
54 #define DEFAULT_VALUE "Test"
56 static void
57 synopsis (char *program_name)
59 PRFileDesc *pr_stderr;
61 pr_stderr = PR_STDERR;
62 PR_fprintf (pr_stderr, "Usage:");
63 PR_fprintf (pr_stderr,
64 "\t%s [-i <input-file>] [-o <output-file>] [-d <dir>] [-l logfile]\n",
65 program_name);
69 static void
70 short_usage (char *program_name)
72 PR_fprintf (PR_STDERR,
73 "Type %s -H for more detailed descriptions\n",
74 program_name);
75 synopsis (program_name);
79 static void
80 long_usage (char *program_name)
82 PRFileDesc *pr_stderr;
84 pr_stderr = PR_STDERR;
85 synopsis (program_name);
86 PR_fprintf (pr_stderr, "\nDecode encrypted passwords (and other data).\n");
87 PR_fprintf (pr_stderr,
88 "This program reads in standard configuration files looking\n"
89 "for base 64 encoded data. Data that looks like it's base 64 encode\n"
90 "is decoded an passed to the NSS SDR code. If the decode and decrypt\n"
91 "is successful, then decrypted data is outputted in place of the\n"
92 "original base 64 data. If the decode or decrypt fails, the original\n"
93 "data is written and the reason for failure is logged to the \n"
94 "optional logfile.\n");
95 PR_fprintf (pr_stderr,
96 " %-13s Read stream including encrypted data from "
97 "\"read_file\"\n",
98 "-i read_file");
99 PR_fprintf (pr_stderr,
100 " %-13s Write results to \"write_file\"\n",
101 "-o write_file");
102 PR_fprintf (pr_stderr,
103 " %-13s Find security databases in \"dbdir\"\n",
104 "-d dbdir");
105 PR_fprintf (pr_stderr,
106 " %-13s Log failed decrypt/decode attempts to \"log_file\"\n",
107 "-l log_file");
111 * base64 table only used to identify the end of a base64 string
113 static unsigned char b64[256] = {
114 /* 0: */ 0, 0, 0, 0, 0, 0, 0, 0,
115 /* 8: */ 0, 0, 0, 0, 0, 0, 0, 0,
116 /* 16: */ 0, 0, 0, 0, 0, 0, 0, 0,
117 /* 24: */ 0, 0, 0, 0, 0, 0, 0, 0,
118 /* 32: */ 0, 0, 0, 0, 0, 0, 0, 0,
119 /* 40: */ 0, 0, 0, 1, 0, 0, 0, 1,
120 /* 48: */ 1, 1, 1, 1, 1, 1, 1, 1,
121 /* 56: */ 1, 1, 0, 0, 0, 0, 0, 0,
122 /* 64: */ 0, 1, 1, 1, 1, 1, 1, 1,
123 /* 72: */ 1, 1, 1, 1, 1, 1, 1, 1,
124 /* 80: */ 1, 1, 1, 1, 1, 1, 1, 1,
125 /* 88: */ 1, 1, 1, 0, 0, 0, 0, 0,
126 /* 96: */ 0, 1, 1, 1, 1, 1, 1, 1,
127 /* 104: */ 1, 1, 1, 1, 1, 1, 1, 1,
128 /* 112: */ 1, 1, 1, 1, 1, 1, 1, 1,
129 /* 120: */ 1, 1, 1, 0, 0, 0, 0, 0,
130 /* 128: */ 0, 0, 0, 0, 0, 0, 0, 0
133 enum {
134 false = 0,
135 true = 1
136 } bool;
139 isatobchar(int c) { return b64[c] != 0; }
142 #define MAX_STRING 256
144 getData(FILE *inFile,char **inString) {
145 int len = 0;
146 int space = MAX_STRING;
147 int oneequal = false;
148 int c;
149 char *string = (char *) malloc(space);
151 string[len++]='M';
153 while ((c = getc(inFile)) != EOF) {
154 if (len >= space) {
155 char *newString;
157 space *= 2;
158 newString = (char *)realloc(string,space);
159 if (newString == NULL) {
160 ungetc(c,inFile);
161 break;
163 string = newString;
165 string[len++] = c;
166 if (!isatobchar(c)) {
167 if (c == '=') {
168 if (oneequal) {
169 break;
171 oneequal = true;
172 continue;
173 } else {
174 ungetc(c,inFile);
175 len--;
176 break;
179 if (oneequal) {
180 ungetc(c,inFile);
181 len--;
182 break;
185 if (len >= space) {
186 space += 2;
187 string = (char *)realloc(string,space);
189 string[len++] = 0;
190 *inString = string;
191 return true;
195 main (int argc, char **argv)
197 int retval = 0; /* 0 - test succeeded. -1 - test failed */
198 SECStatus rv;
199 PLOptState *optstate;
200 char *program_name;
201 char *input_file = NULL; /* read encrypted data from here (or create) */
202 char *output_file = NULL; /* write new encrypted data here */
203 char *log_file = NULL; /* write new encrypted data here */
204 FILE *inFile = stdin;
205 FILE *outFile = stdout;
206 FILE *logFile = NULL;
207 PLOptStatus optstatus;
208 SECItem result;
209 int c;
211 result.data = 0;
213 program_name = PL_strrchr(argv[0], '/');
214 program_name = program_name ? (program_name + 1) : argv[0];
216 optstate = PL_CreateOptState (argc, argv, "Hd:i:o:l:?");
217 if (optstate == NULL) {
218 SECU_PrintError (program_name, "PL_CreateOptState failed");
219 return 1;
222 while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
223 switch (optstate->option) {
224 case '?':
225 short_usage (program_name);
226 return 1;
228 case 'H':
229 long_usage (program_name);
230 return 1;
232 case 'd':
233 SECU_ConfigDirectory(optstate->value);
234 break;
236 case 'i':
237 input_file = PL_strdup(optstate->value);
238 break;
240 case 'o':
241 output_file = PL_strdup(optstate->value);
242 break;
244 case 'l':
245 log_file = PL_strdup(optstate->value);
246 break;
250 PL_DestroyOptState(optstate);
251 if (optstatus == PL_OPT_BAD) {
252 short_usage (program_name);
253 return 1;
256 if (input_file) {
257 inFile = fopen(input_file,"r");
258 if (inFile == NULL) {
259 perror(input_file);
260 return 1;
262 PR_Free(input_file);
264 if (output_file) {
265 outFile = fopen(output_file,"w+");
266 if (outFile == NULL) {
267 perror(output_file);
268 return 1;
270 PR_Free(output_file);
272 if (log_file) {
273 logFile = fopen(log_file,"w+");
274 if (logFile == NULL) {
275 perror(log_file);
276 return 1;
278 PR_Free(log_file);
282 * Initialize the Security libraries.
284 PK11_SetPasswordFunc(SECU_GetModulePassword);
285 rv = NSS_Init(SECU_ConfigDirectory(NULL));
286 if (rv != SECSuccess) {
287 SECU_PrintError (program_name, "NSS_Init failed");
288 retval = 1;
289 goto prdone;
292 /* Get the encrypted result, either from the input file
293 * or from encrypting the plaintext value
296 while ((c = getc(inFile)) != EOF) {
297 if (c == 'M') {
298 char *dataString = NULL;
299 SECItem *inText;
301 rv = getData(inFile, &dataString);
302 if (!rv) {
303 fputs(dataString,outFile);
304 free(dataString);
305 continue;
307 inText = NSSBase64_DecodeBuffer(NULL, NULL, dataString,
308 strlen(dataString));
309 if ((inText == NULL) || (inText->len == 0)) {
310 if (logFile) {
311 fprintf(logFile,"Base 64 decode failed on <%s>\n",
312 dataString);
313 fprintf(logFile," Error %x: %s\n",PORT_GetError(),
314 SECU_Strerror(PORT_GetError()));
316 fputs(dataString,outFile);
317 free(dataString);
318 continue;
320 result.data = NULL;
321 result.len = 0;
322 rv = PK11SDR_Decrypt(inText, &result, NULL);
323 SECITEM_FreeItem(inText, PR_TRUE);
324 if (rv != SECSuccess) {
325 if (logFile) {
326 fprintf(logFile,"SDR decrypt failed on <%s>\n",
327 dataString);
328 fprintf(logFile," Error %x: %s\n",PORT_GetError(),
329 SECU_Strerror(PORT_GetError()));
331 fputs(dataString,outFile);
332 free(dataString);
333 SECITEM_ZfreeItem(&result, PR_FALSE);
334 continue;
336 /* result buffer has no extra space for a NULL */
337 fprintf(outFile, "%.*s", result.len, result.data);
338 SECITEM_ZfreeItem(&result, PR_FALSE);
339 } else {
340 putc(c,outFile);
344 fclose(outFile);
345 fclose(inFile);
346 if (logFile) {
347 fclose(logFile);
350 if (NSS_Shutdown() != SECSuccess) {
351 SECU_PrintError (program_name, "NSS_Shutdown failed");
352 exit(1);
355 prdone:
356 PR_Cleanup ();
357 return retval;