1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59: #include <stdio.h>
60: #include <stdlib.h>
61: #include <string.h>
62: #include "apps.h"
63: #include <openssl/bio.h>
64: #include <openssl/err.h>
65: #include <openssl/evp.h>
66: #include <openssl/objects.h>
67: #include <openssl/x509.h>
68: #include <openssl/rand.h>
69: #include <openssl/pem.h>
70: #include <ctype.h>
71:
72: int set_hex(char *in,unsigned char *out,int size);
73: #undef SIZE
74: #undef BSIZE
75: #undef PROG
76:
77: #define SIZE (512)
78: #define BSIZE (8*1024)
79: #define PROG enc_main
80:
81: static void show_ciphers(const OBJ_NAME *name,void *bio_)
82: {
83: BIO *bio=bio_;
84: static int n;
85:
86: if(!islower((unsigned char)*name->name))
87: return;
88:
89: BIO_printf(bio,"-%-25s",name->name);
90: if(++n == 3)
91: {
92: BIO_printf(bio,"\n");
93: n=0;
94: }
95: else
96: BIO_printf(bio," ");
97: }
98:
99: int MAIN(int, char **);
100:
101: int MAIN(int argc, char **argv)
102: {
103: #ifndef OPENSSL_NO_ENGINE
104: ENGINE *e = NULL;
105: #endif
106: static const char magic[]="Salted__";
107: char mbuf[sizeof magic-1];
108: char *strbuf=NULL;
109: unsigned char *buff=NULL,*bufsize=NULL;
110: int bsize=BSIZE,verbose=0;
111: int ret=1,inl;
112: int nopad = 0;
113: unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH];
114: unsigned char salt[PKCS5_SALT_LEN];
115: char *str=NULL, *passarg = NULL, *pass = NULL;
116: char *hkey=NULL,*hiv=NULL,*hsalt = NULL;
117: char *md=NULL;
118: int enc=1,printkey=0,i,base64=0;
119: int debug=0,olb64=0,nosalt=0;
120: const EVP_CIPHER *cipher=NULL,*c;
121: EVP_CIPHER_CTX *ctx = NULL;
122: char *inf=NULL,*outf=NULL;
123: BIO *in=NULL,*out=NULL,*b64=NULL,*benc=NULL,*rbio=NULL,*wbio=NULL;
124: #define PROG_NAME_SIZE 39
125: char pname[PROG_NAME_SIZE+1];
126: #ifndef OPENSSL_NO_ENGINE
127: char *engine = NULL;
128: #endif
129: const EVP_MD *dgst=NULL;
130:
131: apps_startup();
132:
133: if (bio_err == NULL)
134: if ((bio_err=BIO_new(BIO_s_file())) != NULL)
135: BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
136:
137: if (!load_config(bio_err, NULL))
138: goto end;
139:
140:
141: program_name(argv[0],pname,sizeof pname);
142: if (strcmp(pname,"base64") == 0)
143: base64=1;
144:
145: cipher=EVP_get_cipherbyname(pname);
146: if (!base64 && (cipher == NULL) && (strcmp(pname,"enc") != 0))
147: {
148: BIO_printf(bio_err,"%s is an unknown cipher\n",pname);
149: goto bad;
150: }
151:
152: argc--;
153: argv++;
154: while (argc >= 1)
155: {
156: if (strcmp(*argv,"-e") == 0)
157: enc=1;
158: else if (strcmp(*argv,"-in") == 0)
159: {
160: if (--argc < 1) goto bad;
161: inf= *(++argv);
162: }
163: else if (strcmp(*argv,"-out") == 0)
164: {
165: if (--argc < 1) goto bad;
166: outf= *(++argv);
167: }
168: else if (strcmp(*argv,"-pass") == 0)
169: {
170: if (--argc < 1) goto bad;
171: passarg= *(++argv);
172: }
173: #ifndef OPENSSL_NO_ENGINE
174: else if (strcmp(*argv,"-engine") == 0)
175: {
176: if (--argc < 1) goto bad;
177: engine= *(++argv);
178: }
179: #endif
180: else if (strcmp(*argv,"-d") == 0)
181: enc=0;
182: else if (strcmp(*argv,"-p") == 0)
183: printkey=1;
184: else if (strcmp(*argv,"-v") == 0)
185: verbose=1;
186: else if (strcmp(*argv,"-nopad") == 0)
187: nopad=1;
188: else if (strcmp(*argv,"-salt") == 0)
189: nosalt=0;
190: else if (strcmp(*argv,"-nosalt") == 0)
191: nosalt=1;
192: else if (strcmp(*argv,"-debug") == 0)
193: debug=1;
194: else if (strcmp(*argv,"-P") == 0)
195: printkey=2;
196: else if (strcmp(*argv,"-A") == 0)
197: olb64=1;
198: else if (strcmp(*argv,"-a") == 0)
199: base64=1;
200: else if (strcmp(*argv,"-base64") == 0)
201: base64=1;
202: else if (strcmp(*argv,"-bufsize") == 0)
203: {
204: if (--argc < 1) goto bad;
205: bufsize=(unsigned char *)*(++argv);
206: }
207: else if (strcmp(*argv,"-k") == 0)
208: {
209: if (--argc < 1) goto bad;
210: str= *(++argv);
211: }
212: else if (strcmp(*argv,"-kfile") == 0)
213: {
214: static char buf[128];
215: FILE *infile;
216: char *file;
217:
218: if (--argc < 1) goto bad;
219: file= *(++argv);
220: infile=fopen(file,"r");
221: if (infile == NULL)
222: {
223: BIO_printf(bio_err,"unable to read key from '%s'\n",
224: file);
225: goto bad;
226: }
227: buf[0]='\0';
228: fgets(buf,sizeof buf,infile);
229: fclose(infile);
230: i=strlen(buf);
231: if ((i > 0) &&
232: ((buf[i-1] == '\n') || (buf[i-1] == '\r')))
233: buf[--i]='\0';
234: if ((i > 0) &&
235: ((buf[i-1] == '\n') || (buf[i-1] == '\r')))
236: buf[--i]='\0';
237: if (i < 1)
238: {
239: BIO_printf(bio_err,"zero length password\n");
240: goto bad;
241: }
242: str=buf;
243: }
244: else if (strcmp(*argv,"-K") == 0)
245: {
246: if (--argc < 1) goto bad;
247: hkey= *(++argv);
248: }
249: else if (strcmp(*argv,"-S") == 0)
250: {
251: if (--argc < 1) goto bad;
252: hsalt= *(++argv);
253: }
254: else if (strcmp(*argv,"-iv") == 0)
255: {
256: if (--argc < 1) goto bad;
257: hiv= *(++argv);
258: }
259: else if (strcmp(*argv,"-md") == 0)
260: {
261: if (--argc < 1) goto bad;
262: md= *(++argv);
263: }
264: else if ((argv[0][0] == '-') &&
265: ((c=EVP_get_cipherbyname(&(argv[0][1]))) != NULL))
266: {
267: cipher=c;
268: }
269: else if (strcmp(*argv,"-none") == 0)
270: cipher=NULL;
271: else
272: {
273: BIO_printf(bio_err,"unknown option '%s'\n",*argv);
274: bad:
275: BIO_printf(bio_err,"options are\n");
276: BIO_printf(bio_err,"%-14s input file\n","-in <file>");
277: BIO_printf(bio_err,"%-14s output file\n","-out <file>");
278: BIO_printf(bio_err,"%-14s pass phrase source\n","-pass <arg>");
279: BIO_printf(bio_err,"%-14s encrypt\n","-e");
280: BIO_printf(bio_err,"%-14s decrypt\n","-d");
281: BIO_printf(bio_err,"%-14s base64 encode/decode, depending on encryption flag\n","-a/-base64");
282: BIO_printf(bio_err,"%-14s passphrase is the next argument\n","-k");
283: BIO_printf(bio_err,"%-14s passphrase is the first line of the file argument\n","-kfile");
284: BIO_printf(bio_err,"%-14s the next argument is the md to use to create a key\n","-md");
285: BIO_printf(bio_err,"%-14s from a passphrase. One of md2, md5, sha or sha1\n","");
286: BIO_printf(bio_err,"%-14s key/iv in hex is the next argument\n","-K/-iv");
287: BIO_printf(bio_err,"%-14s print the iv/key (then exit if -P)\n","-[pP]");
288: BIO_printf(bio_err,"%-14s buffer size\n","-bufsize <n>");
289: #ifndef OPENSSL_NO_ENGINE
290: BIO_printf(bio_err,"%-14s use engine e, possibly a hardware device.\n","-engine e");
291: #endif
292:
293: BIO_printf(bio_err,"Cipher Types\n");
294: OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
295: show_ciphers,
296: bio_err);
297: BIO_printf(bio_err,"\n");
298:
299: goto end;
300: }
301: argc--;
302: argv++;
303: }
304:
305: #ifndef OPENSSL_NO_ENGINE
306: e = setup_engine(bio_err, engine, 0);
307: #endif
308:
309: if (md && (dgst=EVP_get_digestbyname(md)) == NULL)
310: {
311: BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
312: goto end;
313: }
314:
315: if (dgst == NULL)
316: {
317: dgst = EVP_md5();
318: }
319:
320: if (bufsize != NULL)
321: {
322: unsigned long n;
323:
324: for (n=0; *bufsize; bufsize++)
325: {
326: i= *bufsize;
327: if ((i <= '9') && (i >= '0'))
328: n=n*10+i-'0';
329: else if (i == 'k')
330: {
331: n*=1024;
332: bufsize++;
333: break;
334: }
335: }
336: if (*bufsize != '\0')
337: {
338: BIO_printf(bio_err,"invalid 'bufsize' specified.\n");
339: goto end;
340: }
341:
342:
343: if (base64 && n < 80) n=80;
344:
345: bsize=(int)n;
346: if (verbose) BIO_printf(bio_err,"bufsize=%d\n",bsize);
347: }
348:
349: strbuf=OPENSSL_malloc(SIZE);
350: buff=(unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize));
351: if ((buff == NULL) || (strbuf == NULL))
352: {
353: BIO_printf(bio_err,"OPENSSL_malloc failure %ld\n",(long)EVP_ENCODE_LENGTH(bsize));
354: goto end;
355: }
356:
357: in=BIO_new(BIO_s_file());
358: out=BIO_new(BIO_s_file());
359: if ((in == NULL) || (out == NULL))
360: {
361: ERR_print_errors(bio_err);
362: goto end;
363: }
364: if (debug)
365: {
366: BIO_set_callback(in,BIO_debug_callback);
367: BIO_set_callback(out,BIO_debug_callback);
368: BIO_set_callback_arg(in,(char *)bio_err);
369: BIO_set_callback_arg(out,(char *)bio_err);
370: }
371:
372: if (inf == NULL)
373: {
374: if (bufsize != NULL)
375: setvbuf(stdin, (char *)NULL, _IONBF, 0);
376: BIO_set_fp(in,stdin,BIO_NOCLOSE);
377: }
378: else
379: {
380: if (BIO_read_filename(in,inf) <= 0)
381: {
382: perror(inf);
383: goto end;
384: }
385: }
386:
387: if(!str && passarg) {
388: if(!app_passwd(bio_err, passarg, NULL, &pass, NULL)) {
389: BIO_printf(bio_err, "Error getting password\n");
390: goto end;
391: }
392: str = pass;
393: }
394:
395: if ((str == NULL) && (cipher != NULL) && (hkey == NULL))
396: {
397: for (;;)
398: {
399: char buf[200];
400:
401: BIO_snprintf(buf,sizeof buf,"enter %s %s password:",
402: OBJ_nid2ln(EVP_CIPHER_nid(cipher)),
403: (enc)?"encryption":"decryption");
404: strbuf[0]='\0';
405: i=EVP_read_pw_string((char *)strbuf,SIZE,buf,enc);
406: if (i == 0)
407: {
408: if (strbuf[0] == '\0')
409: {
410: ret=1;
411: goto end;
412: }
413: str=strbuf;
414: break;
415: }
416: if (i < 0)
417: {
418: BIO_printf(bio_err,"bad password read\n");
419: goto end;
420: }
421: }
422: }
423:
424:
425: if (outf == NULL)
426: {
427: BIO_set_fp(out,stdout,BIO_NOCLOSE);
428: if (bufsize != NULL)
429: setvbuf(stdout, (char *)NULL, _IONBF, 0);
430: #ifdef OPENSSL_SYS_VMS
431: {
432: BIO *tmpbio = BIO_new(BIO_f_linebuffer());
433: out = BIO_push(tmpbio, out);
434: }
435: #endif
436: }
437: else
438: {
439: if (BIO_write_filename(out,outf) <= 0)
440: {
441: perror(outf);
442: goto end;
443: }
444: }
445:
446: rbio=in;
447: wbio=out;
448:
449: if (base64)
450: {
451: if ((b64=BIO_new(BIO_f_base64())) == NULL)
452: goto end;
453: if (debug)
454: {
455: BIO_set_callback(b64,BIO_debug_callback);
456: BIO_set_callback_arg(b64,(char *)bio_err);
457: }
458: if (olb64)
459: BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL);
460: if (enc)
461: wbio=BIO_push(b64,wbio);
462: else
463: rbio=BIO_push(b64,rbio);
464: }
465:
466: if (cipher != NULL)
467: {
468:
469:
470:
471: if (str != NULL)
472: {
473:
474:
475:
476:
477: unsigned char *sptr;
478: if(nosalt) sptr = NULL;
479: else {
480: if(enc) {
481: if(hsalt) {
482: if(!set_hex(hsalt,salt,sizeof salt)) {
483: BIO_printf(bio_err,
484: "invalid hex salt value\n");
485: goto end;
486: }
487: } else if (RAND_pseudo_bytes(salt, sizeof salt) < 0)
488: goto end;
489:
490: if((printkey != 2)
491: && (BIO_write(wbio,magic,
492: sizeof magic-1) != sizeof magic-1
493: || BIO_write(wbio,
494: (char *)salt,
495: sizeof salt) != sizeof salt)) {
496: BIO_printf(bio_err,"error writing output file\n");
497: goto end;
498: }
499: } else if(BIO_read(rbio,mbuf,sizeof mbuf) != sizeof mbuf
500: || BIO_read(rbio,
501: (unsigned char *)salt,
502: sizeof salt) != sizeof salt) {
503: BIO_printf(bio_err,"error reading input file\n");
504: goto end;
505: } else if(memcmp(mbuf,magic,sizeof magic-1)) {
506: BIO_printf(bio_err,"bad magic number\n");
507: goto end;
508: }
509:
510: sptr = salt;
511: }
512:
513: EVP_BytesToKey(cipher,dgst,sptr,
514: (unsigned char *)str,
515: strlen(str),1,key,iv);
516:
517:
518:
519:
520: if (str == strbuf)
521: OPENSSL_cleanse(str,SIZE);
522: else
523: OPENSSL_cleanse(str,strlen(str));
524: }
525: if ((hiv != NULL) && !set_hex(hiv,iv,sizeof iv))
526: {
527: BIO_printf(bio_err,"invalid hex iv value\n");
528: goto end;
529: }
530: if ((hiv == NULL) && (str == NULL))
531: {
532:
533:
534:
535: BIO_printf(bio_err, "iv undefined\n");
536: goto end;
537: }
538: if ((hkey != NULL) && !set_hex(hkey,key,sizeof key))
539: {
540: