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
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.
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 $
54 #define DEFAULT_VALUE "Test"
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",
70 short_usage (char *program_name
)
72 PR_fprintf (PR_STDERR
,
73 "Type %s -H for more detailed descriptions\n",
75 synopsis (program_name
);
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 "
99 PR_fprintf (pr_stderr
,
100 " %-13s Write results to \"write_file\"\n",
102 PR_fprintf (pr_stderr
,
103 " %-13s Find security databases in \"dbdir\"\n",
105 PR_fprintf (pr_stderr
,
106 " %-13s Log failed decrypt/decode attempts to \"log_file\"\n",
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
139 isatobchar(int c
) { return b64
[c
] != 0; }
142 #define MAX_STRING 256
144 getData(FILE *inFile
,char **inString
) {
146 int space
= MAX_STRING
;
147 int oneequal
= false;
149 char *string
= (char *) malloc(space
);
153 while ((c
= getc(inFile
)) != EOF
) {
158 newString
= (char *)realloc(string
,space
);
159 if (newString
== NULL
) {
166 if (!isatobchar(c
)) {
187 string
= (char *)realloc(string
,space
);
195 main (int argc
, char **argv
)
197 int retval
= 0; /* 0 - test succeeded. -1 - test failed */
199 PLOptState
*optstate
;
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
;
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");
222 while ((optstatus
= PL_GetNextOpt(optstate
)) == PL_OPT_OK
) {
223 switch (optstate
->option
) {
225 short_usage (program_name
);
229 long_usage (program_name
);
233 SECU_ConfigDirectory(optstate
->value
);
237 input_file
= PL_strdup(optstate
->value
);
241 output_file
= PL_strdup(optstate
->value
);
245 log_file
= PL_strdup(optstate
->value
);
250 PL_DestroyOptState(optstate
);
251 if (optstatus
== PL_OPT_BAD
) {
252 short_usage (program_name
);
257 inFile
= fopen(input_file
,"r");
258 if (inFile
== NULL
) {
265 outFile
= fopen(output_file
,"w+");
266 if (outFile
== NULL
) {
270 PR_Free(output_file
);
273 logFile
= fopen(log_file
,"w+");
274 if (logFile
== NULL
) {
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");
292 /* Get the encrypted result, either from the input file
293 * or from encrypting the plaintext value
296 while ((c
= getc(inFile
)) != EOF
) {
298 char *dataString
= NULL
;
301 rv
= getData(inFile
, &dataString
);
303 fputs(dataString
,outFile
);
307 inText
= NSSBase64_DecodeBuffer(NULL
, NULL
, dataString
,
309 if ((inText
== NULL
) || (inText
->len
== 0)) {
311 fprintf(logFile
,"Base 64 decode failed on <%s>\n",
313 fprintf(logFile
," Error %x: %s\n",PORT_GetError(),
314 SECU_Strerror(PORT_GetError()));
316 fputs(dataString
,outFile
);
322 rv
= PK11SDR_Decrypt(inText
, &result
, NULL
);
323 SECITEM_FreeItem(inText
, PR_TRUE
);
324 if (rv
!= SECSuccess
) {
326 fprintf(logFile
,"SDR decrypt failed on <%s>\n",
328 fprintf(logFile
," Error %x: %s\n",PORT_GetError(),
329 SECU_Strerror(PORT_GetError()));
331 fputs(dataString
,outFile
);
333 SECITEM_ZfreeItem(&result
, PR_FALSE
);
336 /* result buffer has no extra space for a NULL */
337 fprintf(outFile
, "%.*s", result
.len
, result
.data
);
338 SECITEM_ZfreeItem(&result
, PR_FALSE
);
350 if (NSS_Shutdown() != SECSuccess
) {
351 SECU_PrintError (program_name
, "NSS_Shutdown failed");