PageRenderTime 29ms CodeModel.GetById 12ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 0ms

/security/nss/cmd/pwdecrypt/pwdecrypt.c

http://github.com/zpao/v8monkey
C | 368 lines | 274 code | 43 blank | 51 comment | 65 complexity | a28efdf91ddafd49940c6f1dc604a63f MD5 | raw file
  1/* ***** BEGIN LICENSE BLOCK *****
  2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3 *
  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/
  8 *
  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.
 13 *
 14 * The Original Code is the Netscape security libraries.
 15 *
 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.
 20 *
 21 * Contributor(s):
 22 *
 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.
 34 *
 35 * ***** END LICENSE BLOCK ***** */
 36
 37/*
 38 * Test program for SDR (Secret Decoder Ring) functions.
 39 *
 40 * $Id: pwdecrypt.c,v 1.7 2009/08/03 07:07:13 nelson%bolyard.com Exp $
 41 */
 42
 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"
 50
 51#include "plgetopt.h"
 52#include "pk11sdr.h"
 53
 54#define DEFAULT_VALUE "Test"
 55
 56static void
 57synopsis (char *program_name)
 58{
 59    PRFileDesc *pr_stderr;
 60
 61    pr_stderr = PR_STDERR;
 62    PR_fprintf (pr_stderr,
 63	"Usage:\t%s [-i <input-file>] [-o <output-file>] [-d <dir>]\n"
 64        "      \t[-l logfile] [-p pwd] [-f pwfile]\n", program_name);
 65}
 66
 67
 68static void
 69short_usage (char *program_name)
 70{
 71    PR_fprintf (PR_STDERR,
 72		"Type %s -H for more detailed descriptions\n",
 73		program_name);
 74    synopsis (program_name);
 75}
 76
 77
 78static void
 79long_usage (char *program_name)
 80{
 81    PRFileDesc *pr_stderr;
 82
 83    pr_stderr = PR_STDERR;
 84    synopsis (program_name);
 85    PR_fprintf (pr_stderr, "\nDecode encrypted passwords (and other data).\n");
 86    PR_fprintf (pr_stderr, 
 87	"This program reads in standard configuration files looking\n"
 88	"for base 64 encoded data. Data that looks like it's base 64 encode\n"
 89	"is decoded an passed to the NSS SDR code. If the decode and decrypt\n"
 90	"is successful, then decrypted data is outputted in place of the\n"
 91	"original base 64 data. If the decode or decrypt fails, the original\n"
 92	"data is written and the reason for failure is logged to the \n"
 93	"optional logfile.\n");
 94    PR_fprintf (pr_stderr,
 95		"  %-13s Read stream including encrypted data from "
 96	        "\"read_file\"\n",
 97		"-i read_file");
 98    PR_fprintf (pr_stderr,
 99		"  %-13s Write results to \"write_file\"\n",
100		"-o write_file");
101    PR_fprintf (pr_stderr,
102		"  %-13s Find security databases in \"dbdir\"\n",
103		"-d dbdir");
104    PR_fprintf (pr_stderr,
105		"  %-13s Log failed decrypt/decode attempts to \"log_file\"\n",
106		"-l log_file");
107    PR_fprintf (pr_stderr,
108		"  %-13s Token password\n",
109		"-p pwd");
110    PR_fprintf (pr_stderr,
111		"  %-13s Password file\n",
112		"-f pwfile");
113}
114
115/*
116 * base64 table only used to identify the end of a base64 string 
117 */
118static unsigned char b64[256] = {
119/*  00: */	0,	0,	0,	0,	0,	0,	0,	0,
120/*  08: */	0,	0,	0,	0,	0,	0,	0,	0,
121/*  10: */	0,	0,	0,	0,	0,	0,	0,	0,
122/*  18: */	0,	0,	0,	0,	0,	0,	0,	0,
123/*  20: */	0,	0,	0,	0,	0,	0,	0,	0,
124/*  28: */	0,	0,	0,	1,	0,	0,	0,	1,
125/*  30: */	1,	1,	1,	1,	1,	1,	1,	1,
126/*  38: */	1,	1,	0,	0,	0,	0,	0,	0,
127/*  40: */	0,	1,	1,	1,	1,	1,	1,	1,
128/*  48: */	1,	1,	1,	1,	1,	1,	1,	1,
129/*  50: */	1,	1,	1,	1,	1,	1,	1,	1,
130/*  58: */	1,	1,	1,	0,	0,	0,	0,	0,
131/*  60: */	0,	1,	1,	1,	1,	1,	1,	1,
132/*  68: */	1,	1,	1,	1,	1,	1,	1,	1,
133/*  70: */	1,	1,	1,	1,	1,	1,	1,	1,
134/*  78: */	1,	1,	1,	0,	0,	0,	0,	0,
135};
136
137enum {
138   false = 0,
139   true = 1
140} bool;
141
142#define isatobchar(c) (b64[c])
143
144#define MAX_STRING 8192
145
146int
147isBase64(char *inString) 
148{
149    unsigned int i;
150    unsigned char c;
151
152    for (i = 0; (c = inString[i]) != 0 && isatobchar(c); ++i) 
153	;
154    if (c == '=') {
155	while ((c = inString[++i]) == '=')
156	    ; /* skip trailing '=' characters */
157    }
158    if (c && c != '\n' && c != '\r')
159	return false;
160    if (i == 0 || i % 4)
161    	return false;
162    return true;
163}
164
165void
166doDecrypt(char * dataString, FILE *outFile, FILE *logFile, secuPWData *pwdata)
167{
168    int        strLen = strlen(dataString);
169    SECItem   *decoded = NSSBase64_DecodeBuffer(NULL, NULL, dataString, strLen);
170    SECStatus  rv;
171    int        err;
172    unsigned int i;
173    SECItem    result = { siBuffer, NULL, 0 };
174
175    if ((decoded == NULL) || (decoded->len == 0)) {
176	if (logFile) {
177	    err = PORT_GetError();
178	    fprintf(logFile,"Base 64 decode failed on <%s>\n", dataString);
179	    fprintf(logFile," Error %d: %s\n", err, SECU_Strerror(err));
180	}
181	fputs(dataString, outFile);
182	if (decoded)
183	    SECITEM_FreeItem(decoded, PR_TRUE);
184	return;
185    }
186
187    rv = PK11SDR_Decrypt(decoded, &result, pwdata);
188    SECITEM_ZfreeItem(decoded, PR_TRUE);
189    if (rv == SECSuccess) {
190	/* result buffer has no extra space for a NULL */
191	fprintf(outFile, "Decrypted: \"%.*s\"\n", result.len, result.data);
192	SECITEM_ZfreeItem(&result, PR_FALSE);
193	return;
194    }
195    /* Encryption failed. output raw input. */
196    if (logFile) {
197	err = PORT_GetError();
198	fprintf(logFile,"SDR decrypt failed on <%s>\n", dataString);
199	fprintf(logFile," Error %d: %s\n", err, SECU_Strerror(err));
200    }
201    fputs(dataString,outFile);
202}
203
204void
205doDecode(char * dataString, FILE *outFile, FILE *logFile)
206{
207    int        strLen = strlen(dataString + 1);
208    SECItem   *decoded;
209
210    decoded = NSSBase64_DecodeBuffer(NULL, NULL, dataString + 1, strLen);
211    if ((decoded == NULL) || (decoded->len == 0)) {
212	if (logFile) {
213	    int err = PORT_GetError();
214	    fprintf(logFile,"Base 64 decode failed on <%s>\n", dataString + 1);
215	    fprintf(logFile," Error %d: %s\n", err, SECU_Strerror(err));
216	}
217	fputs(dataString, outFile);
218	if (decoded)
219	    SECITEM_FreeItem(decoded, PR_TRUE);
220	return;
221    }
222    fprintf(outFile, "Decoded: \"%.*s\"\n", decoded->len, decoded->data);
223    SECITEM_ZfreeItem(decoded, PR_TRUE);
224}
225
226char dataString[MAX_STRING + 1];
227
228int
229main (int argc, char **argv)
230{
231    int		 retval = 0;  /* 0 - test succeeded.  -1 - test failed */
232    SECStatus	 rv;
233    PLOptState	*optstate;
234    char	*program_name;
235    char  *input_file = NULL; 	/* read encrypted data from here (or create) */
236    char  *output_file = NULL;	/* write new encrypted data here */
237    char  *log_file = NULL;	/* write new encrypted data here */
238    FILE	*inFile = stdin;
239    FILE	*outFile = stdout;
240    FILE	*logFile = NULL;
241    PLOptStatus optstatus;
242    secuPWData  pwdata = { PW_NONE, NULL };
243
244
245    program_name = PL_strrchr(argv[0], '/');
246    program_name = program_name ? (program_name + 1) : argv[0];
247
248    optstate = PL_CreateOptState (argc, argv, "Hd:f:i:o:l:p:?");
249    if (optstate == NULL) {
250	SECU_PrintError (program_name, "PL_CreateOptState failed");
251	return 1;
252    }
253
254    while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
255	switch (optstate->option) {
256	  case '?':
257	    short_usage (program_name);
258	    return 1;
259
260	  case 'H':
261	    long_usage (program_name);
262	    return 1;
263
264	  case 'd':
265	    SECU_ConfigDirectory(optstate->value);
266	    break;
267
268          case 'i':
269            input_file = PL_strdup(optstate->value);
270            break;
271
272          case 'o':
273            output_file = PL_strdup(optstate->value);
274            break;
275
276          case 'l':
277            log_file = PL_strdup(optstate->value);
278            break;
279
280          case 'f':
281            pwdata.source = PW_FROMFILE;
282            pwdata.data = PL_strdup(optstate->value);
283            break;
284
285          case 'p':
286            pwdata.source = PW_PLAINTEXT;
287            pwdata.data = PL_strdup(optstate->value);
288            break;
289
290	}
291    }
292    PL_DestroyOptState(optstate);
293    if (optstatus == PL_OPT_BAD) {
294	short_usage (program_name);
295	return 1;
296    }
297
298    if (input_file) {
299        inFile = fopen(input_file,"r");
300        if (inFile == NULL) {
301	    perror(input_file);
302	    return 1;
303        }
304        PR_Free(input_file);
305    }
306    if (output_file) {
307        outFile = fopen(output_file,"w+");
308        if (outFile == NULL) {
309	    perror(output_file);
310	    return 1;
311        }
312        PR_Free(output_file);
313    }
314    if (log_file) {
315	if (log_file[0] == '-')
316	    logFile = stderr;
317	else
318	    logFile = fopen(log_file,"w+");
319	if (logFile == NULL) {
320	    perror(log_file);
321	    return 1;
322	}
323        PR_Free(log_file);
324    }
325
326    /*
327     * Initialize the Security libraries.
328     */
329    PK11_SetPasswordFunc(SECU_GetModulePassword);
330    rv = NSS_Init(SECU_ConfigDirectory(NULL));
331    if (rv != SECSuccess) {
332	SECU_PrintError (program_name, "NSS_Init failed");
333	retval = 1;
334	goto prdone;
335    }
336
337    /* Get the encrypted result, either from the input file
338     * or from encrypting the plaintext value
339     */
340    while (fgets(dataString, sizeof dataString, inFile)) {
341	unsigned char c = dataString[0];
342
343	if (c == 'M' && isBase64(dataString)) {
344	    doDecrypt(dataString, outFile, logFile, &pwdata);
345        } else if (c == '~' && isBase64(dataString + 1)) {
346	    doDecode(dataString, outFile, logFile);
347	} else {
348	    fputs(dataString, outFile);
349	}
350    }
351    if (pwdata.data)
352    	PR_Free(pwdata.data);
353
354    fclose(outFile);
355    fclose(inFile);
356    if (logFile && logFile != stderr) {
357	fclose(logFile);
358    }
359
360    if (NSS_Shutdown() != SECSuccess) {
361	SECU_PrintError (program_name, "NSS_Shutdown failed");
362        exit(1);
363    }
364
365prdone:
366    PR_Cleanup ();
367    return retval;
368}