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: sdrtest.c,v 1.14 2008/03/10 20:16:44 rrelyea%redhat.com Exp $
54 #define DEFAULT_VALUE "Test"
55 static const char default_value
[] = { DEFAULT_VALUE
};
57 PRFileDesc
*pr_stderr
;
58 PRBool verbose
= PR_FALSE
;
61 synopsis (char *program_name
)
63 PR_fprintf (pr_stderr
,
64 "Usage: %s [<common>] -i <input-file>\n"
65 " %s [<common>] -o <output-file>\n"
66 " <common> [-d dir] [-v] [-t text] [-a] [-f pwfile | -p pwd]\n",
67 program_name
, program_name
);
71 short_usage (char *program_name
)
73 PR_fprintf (pr_stderr
,
74 "Type %s -H for more detailed descriptions\n",
76 synopsis (program_name
);
81 long_usage (char *program_name
)
83 synopsis (program_name
);
84 PR_fprintf (pr_stderr
, "\nSecret Decoder Test:\n");
85 PR_fprintf (pr_stderr
,
86 " %-13s Read encrypted data from \"file\"\n",
88 PR_fprintf (pr_stderr
,
89 " %-13s Write newly generated encrypted data to \"file\"\n",
91 PR_fprintf (pr_stderr
,
92 " %-13s Use \"text\" as the plaintext for encryption and verification\n",
94 PR_fprintf (pr_stderr
,
95 " %-13s Find security databases in \"dbdir\"\n",
97 PR_fprintf (pr_stderr
,
98 " %-13s read the password from \"pwfile\"\n",
100 PR_fprintf (pr_stderr
,
101 " %-13s supply \"password\" on the command line\n",
106 readStdin(SECItem
* result
)
115 if (bufsize
< wanted
) {
116 unsigned char * tmpData
= (unsigned char *)realloc(result
->data
, wanted
);
118 if (verbose
) PR_fprintf(pr_stderr
, "Allocation of buffer failed\n");
121 result
->data
= tmpData
;
124 cc
= PR_Read(PR_STDIN
, result
->data
+ result
->len
, bufsize
- result
->len
);
126 result
->len
+= (unsigned)cc
;
127 if (result
->len
>= wanted
)
135 readInputFile(const char * filename
, SECItem
* result
)
137 PRFileDesc
*file
/* = PR_OpenFile(input_file, 0) */;
143 file
= PR_Open(filename
, PR_RDONLY
, 0);
145 if (verbose
) PR_fprintf(pr_stderr
, "Open of file %s failed\n", filename
);
149 s
= PR_GetOpenFileInfo(file
, &info
);
150 if (s
!= PR_SUCCESS
) {
151 if (verbose
) PR_fprintf(pr_stderr
, "File info operation failed\n");
155 result
->len
= info
.size
;
156 result
->data
= (unsigned char *)malloc(result
->len
);
158 if (verbose
) PR_fprintf(pr_stderr
, "Allocation of buffer failed\n");
162 count
= PR_Read(file
, result
->data
, result
->len
);
163 if (count
!= result
->len
) {
164 if (verbose
) PR_fprintf(pr_stderr
, "Read failed\n");
176 main (int argc
, char **argv
)
178 int retval
= 0; /* 0 - test succeeded. -1 - test failed */
180 PLOptState
*optstate
;
181 PLOptStatus optstatus
;
183 const char *input_file
= NULL
; /* read encrypted data from here (or create) */
184 const char *output_file
= NULL
; /* write new encrypted data here */
185 const char *value
= default_value
; /* Use this for plaintext */
187 SECItem result
= {0, 0, 0};
189 PRBool ascii
= PR_FALSE
;
190 secuPWData pwdata
= { PW_NONE
, 0 };
192 pr_stderr
= PR_STDERR
;
194 text
.data
= 0; text
.len
= 0;
196 program_name
= PL_strrchr(argv
[0], '/');
197 program_name
= program_name
? (program_name
+ 1) : argv
[0];
199 optstate
= PL_CreateOptState (argc
, argv
, "?Had:i:o:t:vf:p:");
200 if (optstate
== NULL
) {
201 SECU_PrintError (program_name
, "PL_CreateOptState failed");
205 while ((optstatus
= PL_GetNextOpt(optstate
)) == PL_OPT_OK
) {
206 switch (optstate
->option
) {
208 short_usage (program_name
);
212 long_usage (program_name
);
220 SECU_ConfigDirectory(optstate
->value
);
224 input_file
= optstate
->value
;
228 output_file
= optstate
->value
;
232 value
= optstate
->value
;
237 PORT_Free(pwdata
.data
);
238 short_usage(program_name
);
241 pwdata
.source
= PW_FROMFILE
;
242 pwdata
.data
= PORT_Strdup(optstate
->value
);
247 PORT_Free(pwdata
.data
);
248 short_usage(program_name
);
251 pwdata
.source
= PW_PLAINTEXT
;
252 pwdata
.data
= PORT_Strdup(optstate
->value
);
260 PL_DestroyOptState(optstate
);
261 if (optstatus
== PL_OPT_BAD
) {
262 short_usage (program_name
);
265 if (!output_file
&& !input_file
&& value
== default_value
) {
266 short_usage (program_name
);
267 PR_fprintf (pr_stderr
, "Must specify at least one of -t, -i or -o \n");
272 * Initialize the Security libraries.
274 PK11_SetPasswordFunc(SECU_GetModulePassword
);
277 rv
= NSS_InitReadWrite(SECU_ConfigDirectory(NULL
));
279 rv
= NSS_Init(SECU_ConfigDirectory(NULL
));
281 if (rv
!= SECSuccess
) {
282 SECU_PrintError(program_name
, "NSS_Init failed");
287 /* Convert value into an item */
288 data
.data
= (unsigned char *)value
;
289 data
.len
= strlen(value
);
291 /* Get the encrypted result, either from the input file
292 * or from encrypting the plaintext value
296 if (verbose
) printf("Reading data from %s\n", input_file
);
298 if (!strcmp(input_file
, "-")) {
299 retval
= readStdin(&result
);
302 retval
= readInputFile(input_file
, &result
);
307 /* input was base64 encoded. Decode it. */
308 SECItem newResult
= {0, 0, 0};
309 SECItem
*ok
= NSSBase64_DecodeBuffer(NULL
, &newResult
,
310 (const char *)result
.data
, result
.len
);
312 SECU_PrintError(program_name
, "Base 64 decode failed");
322 SECItem keyid
= { 0, 0, 0 };
323 SECItem outBuf
= { 0, 0, 0 };
324 PK11SlotInfo
*slot
= NULL
;
326 /* sigh, initialize the key database */
327 slot
= PK11_GetInternalKeySlot();
328 if (slot
&& PK11_NeedUserInit(slot
)) {
329 switch (pwdata
.source
) {
331 rv
= SECU_ChangePW(slot
, 0, pwdata
.data
);
334 rv
= SECU_ChangePW(slot
, pwdata
.data
, 0);
337 rv
= SECU_ChangePW(slot
, "", 0);
340 if (rv
!= SECSuccess
) {
341 SECU_PrintError(program_name
, "Failed to initialize slot \"%s\"",
342 PK11_GetSlotName(slot
));
350 rv
= PK11SDR_Encrypt(&keyid
, &data
, &result
, &pwdata
);
351 if (rv
!= SECSuccess
) {
353 SECU_PrintError(program_name
, "Encrypt operation failed\n");
358 if (verbose
) printf("Encrypted result is %d bytes long\n", result
.len
);
360 if (!strcmp(output_file
, "-")) {
365 /* base64 encode output. */
366 char * newResult
= NSSBase64_EncodeItem(NULL
, NULL
, 0, &result
);
368 SECU_PrintError(program_name
, "Base 64 encode failed\n");
372 outBuf
.data
= (unsigned char *)newResult
;
373 outBuf
.len
= strlen(newResult
);
375 printf("Base 64 encoded result is %d bytes long\n", outBuf
.len
);
380 /* -v printf("Result is %.*s\n", text.len, text.data); */
385 if (verbose
) printf("Writing result to %s\n", output_file
);
386 if (!strcmp(output_file
, "-")) {
390 file
= PR_Open(output_file
, PR_CREATE_FILE
|PR_WRONLY
, 0666);
394 SECU_PrintError(program_name
,
395 "Open of output file %s failed\n",
401 count
= PR_Write(file
, outBuf
.data
, outBuf
.len
);
403 if (file
== PR_STDOUT
) {
409 if (count
!= outBuf
.len
) {
410 if (verbose
) SECU_PrintError(program_name
, "Write failed\n");
420 /* Decrypt the value */
421 rv
= PK11SDR_Decrypt(&result
, &text
, &pwdata
);
422 if (rv
!= SECSuccess
) {
423 if (verbose
) SECU_PrintError(program_name
, "Decrypt operation failed\n");
428 if (verbose
) printf("Decrypted result is \"%.*s\"\n", text
.len
, text
.data
);
430 /* Compare to required value */
431 if (text
.len
!= data
.len
|| memcmp(data
.data
, text
.data
, text
.len
) != 0)
433 if (verbose
) PR_fprintf(pr_stderr
, "Comparison failed\n");
439 if (text
.data
) free(text
.data
);
440 if (result
.data
) free(result
.data
);
441 if (NSS_Shutdown() != SECSuccess
) {
448 PORT_Free(pwdata
.data
);