|
1 /* apps/enc.c */ |
|
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
|
3 * All rights reserved. |
|
4 * |
|
5 * This package is an SSL implementation written |
|
6 * by Eric Young (eay@cryptsoft.com). |
|
7 * The implementation was written so as to conform with Netscapes SSL. |
|
8 * |
|
9 * This library is free for commercial and non-commercial use as long as |
|
10 * the following conditions are aheared to. The following conditions |
|
11 * apply to all code found in this distribution, be it the RC4, RSA, |
|
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation |
|
13 * included with this distribution is covered by the same copyright terms |
|
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). |
|
15 * |
|
16 * Copyright remains Eric Young's, and as such any Copyright notices in |
|
17 * the code are not to be removed. |
|
18 * If this package is used in a product, Eric Young should be given attribution |
|
19 * as the author of the parts of the library used. |
|
20 * This can be in the form of a textual message at program startup or |
|
21 * in documentation (online or textual) provided with the package. |
|
22 * |
|
23 * Redistribution and use in source and binary forms, with or without |
|
24 * modification, are permitted provided that the following conditions |
|
25 * are met: |
|
26 * 1. Redistributions of source code must retain the copyright |
|
27 * notice, this list of conditions and the following disclaimer. |
|
28 * 2. Redistributions in binary form must reproduce the above copyright |
|
29 * notice, this list of conditions and the following disclaimer in the |
|
30 * documentation and/or other materials provided with the distribution. |
|
31 * 3. All advertising materials mentioning features or use of this software |
|
32 * must display the following acknowledgement: |
|
33 * "This product includes cryptographic software written by |
|
34 * Eric Young (eay@cryptsoft.com)" |
|
35 * The word 'cryptographic' can be left out if the rouines from the library |
|
36 * being used are not cryptographic related :-). |
|
37 * 4. If you include any Windows specific code (or a derivative thereof) from |
|
38 * the apps directory (application code) you must include an acknowledgement: |
|
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" |
|
40 * |
|
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
|
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
|
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
51 * SUCH DAMAGE. |
|
52 * |
|
53 * The licence and distribution terms for any publically available version or |
|
54 * derivative of this code cannot be changed. i.e. this code cannot simply be |
|
55 * copied and put under another distribution licence |
|
56 * [including the GNU Public Licence.] |
|
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 |
|
82 |
|
83 static void show_ciphers(const OBJ_NAME *name,void *bio_) |
|
84 { |
|
85 BIO *bio=bio_; |
|
86 static int n; |
|
87 |
|
88 if(!islower((unsigned char)*name->name)) |
|
89 return; |
|
90 |
|
91 BIO_printf(bio,"-%-25s",name->name); |
|
92 if(++n == 3) |
|
93 { |
|
94 BIO_printf(bio,"\n"); |
|
95 n=0; |
|
96 } |
|
97 else |
|
98 BIO_printf(bio," "); |
|
99 } |
|
100 |
|
101 int MAIN(int, char **); |
|
102 |
|
103 int MAIN(int argc, char **argv) |
|
104 { |
|
105 #ifndef OPENSSL_NO_ENGINE |
|
106 ENGINE *e = NULL; |
|
107 #endif |
|
108 static const char magic[]="Salted__"; |
|
109 char mbuf[sizeof magic-1]; |
|
110 char *strbuf=NULL; |
|
111 unsigned char *buff=NULL,*bufsize=NULL; |
|
112 int bsize=BSIZE,verbose=0; |
|
113 int ret=1,inl; |
|
114 int nopad = 0; |
|
115 unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH]; |
|
116 unsigned char salt[PKCS5_SALT_LEN]; |
|
117 char *str=NULL, *passarg = NULL, *pass = NULL; |
|
118 char *hkey=NULL,*hiv=NULL,*hsalt = NULL; |
|
119 char *md=NULL; |
|
120 int enc=1,printkey=0,i,base64=0; |
|
121 int debug=0,olb64=0,nosalt=0; |
|
122 const EVP_CIPHER *cipher=NULL,*c; |
|
123 EVP_CIPHER_CTX *ctx = NULL; |
|
124 char *inf=NULL,*outf=NULL; |
|
125 BIO *in=NULL,*out=NULL,*b64=NULL,*benc=NULL,*rbio=NULL,*wbio=NULL; |
|
126 #define PROG_NAME_SIZE 39 |
|
127 char pname[PROG_NAME_SIZE+1]; |
|
128 #ifndef OPENSSL_NO_ENGINE |
|
129 char *engine = NULL; |
|
130 #endif |
|
131 const EVP_MD *dgst=NULL; |
|
132 |
|
133 apps_startup(); |
|
134 |
|
135 if (bio_err == NULL) |
|
136 if ((bio_err=BIO_new(BIO_s_file())) != NULL) |
|
137 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); |
|
138 |
|
139 |
|
140 if (!load_config(bio_err, NULL)) |
|
141 goto end; |
|
142 |
|
143 /* first check the program name */ |
|
144 program_name(argv[0],pname,sizeof pname); |
|
145 if (strcmp(pname,"base64") == 0) |
|
146 base64=1; |
|
147 |
|
148 cipher=EVP_get_cipherbyname(pname); |
|
149 if (!base64 && (cipher == NULL) && (strcmp(pname,"enc") != 0)) |
|
150 { |
|
151 BIO_printf(bio_err,"%s is an unknown cipher\n",pname); |
|
152 goto bad; |
|
153 } |
|
154 |
|
155 argc--; |
|
156 argv++; |
|
157 while (argc >= 1) |
|
158 { |
|
159 if (strcmp(*argv,"-e") == 0) |
|
160 enc=1; |
|
161 else if (strcmp(*argv,"-in") == 0) |
|
162 { |
|
163 if (--argc < 1) goto bad; |
|
164 inf= *(++argv); |
|
165 } |
|
166 else if (strcmp(*argv,"-out") == 0) |
|
167 { |
|
168 if (--argc < 1) goto bad; |
|
169 outf= *(++argv); |
|
170 } |
|
171 else if (strcmp(*argv,"-pass") == 0) |
|
172 { |
|
173 if (--argc < 1) goto bad; |
|
174 passarg= *(++argv); |
|
175 } |
|
176 #ifndef OPENSSL_NO_ENGINE |
|
177 else if (strcmp(*argv,"-engine") == 0) |
|
178 { |
|
179 if (--argc < 1) goto bad; |
|
180 engine= *(++argv); |
|
181 } |
|
182 #endif |
|
183 else if (strcmp(*argv,"-d") == 0) |
|
184 enc=0; |
|
185 else if (strcmp(*argv,"-p") == 0) |
|
186 printkey=1; |
|
187 else if (strcmp(*argv,"-v") == 0) |
|
188 verbose=1; |
|
189 else if (strcmp(*argv,"-nopad") == 0) |
|
190 nopad=1; |
|
191 else if (strcmp(*argv,"-salt") == 0) |
|
192 nosalt=0; |
|
193 else if (strcmp(*argv,"-nosalt") == 0) |
|
194 nosalt=1; |
|
195 else if (strcmp(*argv,"-debug") == 0) |
|
196 debug=1; |
|
197 else if (strcmp(*argv,"-P") == 0) |
|
198 printkey=2; |
|
199 else if (strcmp(*argv,"-A") == 0) |
|
200 olb64=1; |
|
201 else if (strcmp(*argv,"-a") == 0) |
|
202 base64=1; |
|
203 else if (strcmp(*argv,"-base64") == 0) |
|
204 base64=1; |
|
205 else if (strcmp(*argv,"-bufsize") == 0) |
|
206 { |
|
207 if (--argc < 1) goto bad; |
|
208 bufsize=(unsigned char *)*(++argv); |
|
209 } |
|
210 else if (strcmp(*argv,"-k") == 0) |
|
211 { |
|
212 if (--argc < 1) goto bad; |
|
213 str= *(++argv); |
|
214 } |
|
215 else if (strcmp(*argv,"-kfile") == 0) |
|
216 { |
|
217 static char buf[128]; |
|
218 FILE *infile; |
|
219 char *file; |
|
220 |
|
221 if (--argc < 1) goto bad; |
|
222 file= *(++argv); |
|
223 infile=fopen(file,"r"); |
|
224 if (infile == NULL) |
|
225 { |
|
226 BIO_printf(bio_err,"unable to read key from '%s'\n", |
|
227 file); |
|
228 goto bad; |
|
229 } |
|
230 buf[0]='\0'; |
|
231 fgets(buf,sizeof buf,infile); |
|
232 fclose(infile); |
|
233 i=strlen(buf); |
|
234 if ((i > 0) && |
|
235 ((buf[i-1] == '\n') || (buf[i-1] == '\r'))) |
|
236 buf[--i]='\0'; |
|
237 if ((i > 0) && |
|
238 ((buf[i-1] == '\n') || (buf[i-1] == '\r'))) |
|
239 buf[--i]='\0'; |
|
240 if (i < 1) |
|
241 { |
|
242 BIO_printf(bio_err,"zero length password\n"); |
|
243 goto bad; |
|
244 } |
|
245 str=buf; |
|
246 } |
|
247 else if (strcmp(*argv,"-K") == 0) |
|
248 { |
|
249 if (--argc < 1) goto bad; |
|
250 hkey= *(++argv); |
|
251 } |
|
252 else if (strcmp(*argv,"-S") == 0) |
|
253 { |
|
254 if (--argc < 1) goto bad; |
|
255 hsalt= *(++argv); |
|
256 } |
|
257 else if (strcmp(*argv,"-iv") == 0) |
|
258 { |
|
259 if (--argc < 1) goto bad; |
|
260 hiv= *(++argv); |
|
261 } |
|
262 else if (strcmp(*argv,"-md") == 0) |
|
263 { |
|
264 if (--argc < 1) goto bad; |
|
265 md= *(++argv); |
|
266 } |
|
267 else if ((argv[0][0] == '-') && |
|
268 ((c=EVP_get_cipherbyname(&(argv[0][1]))) != NULL)) |
|
269 { |
|
270 cipher=c; |
|
271 } |
|
272 else if (strcmp(*argv,"-none") == 0) |
|
273 cipher=NULL; |
|
274 else |
|
275 { |
|
276 BIO_printf(bio_err,"unknown option '%s'\n",*argv); |
|
277 bad: |
|
278 BIO_printf(bio_err,"options are\n"); |
|
279 BIO_printf(bio_err,"%-14s input file\n","-in <file>"); |
|
280 BIO_printf(bio_err,"%-14s output file\n","-out <file>"); |
|
281 BIO_printf(bio_err,"%-14s pass phrase source\n","-pass <arg>"); |
|
282 BIO_printf(bio_err,"%-14s encrypt\n","-e"); |
|
283 BIO_printf(bio_err,"%-14s decrypt\n","-d"); |
|
284 BIO_printf(bio_err,"%-14s base64 encode/decode, depending on encryption flag\n","-a/-base64"); |
|
285 BIO_printf(bio_err,"%-14s passphrase is the next argument\n","-k"); |
|
286 BIO_printf(bio_err,"%-14s passphrase is the first line of the file argument\n","-kfile"); |
|
287 BIO_printf(bio_err,"%-14s the next argument is the md to use to create a key\n","-md"); |
|
288 BIO_printf(bio_err,"%-14s from a passphrase. One of md2, md5, sha or sha1\n",""); |
|
289 BIO_printf(bio_err,"%-14s key/iv in hex is the next argument\n","-K/-iv"); |
|
290 BIO_printf(bio_err,"%-14s print the iv/key (then exit if -P)\n","-[pP]"); |
|
291 BIO_printf(bio_err,"%-14s buffer size\n","-bufsize <n>"); |
|
292 #ifndef OPENSSL_NO_ENGINE |
|
293 BIO_printf(bio_err,"%-14s use engine e, possibly a hardware device.\n","-engine e"); |
|
294 #endif |
|
295 |
|
296 BIO_printf(bio_err,"Cipher Types\n"); |
|
297 OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, |
|
298 show_ciphers, |
|
299 bio_err); |
|
300 BIO_printf(bio_err,"\n"); |
|
301 |
|
302 goto end; |
|
303 } |
|
304 argc--; |
|
305 argv++; |
|
306 } |
|
307 |
|
308 #ifndef OPENSSL_NO_ENGINE |
|
309 e = setup_engine(bio_err, engine, 0); |
|
310 #endif |
|
311 |
|
312 if (md && (dgst=EVP_get_digestbyname(md)) == NULL) |
|
313 { |
|
314 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md); |
|
315 goto end; |
|
316 } |
|
317 |
|
318 if (dgst == NULL) |
|
319 { |
|
320 dgst = EVP_md5(); |
|
321 } |
|
322 |
|
323 if (bufsize != NULL) |
|
324 { |
|
325 unsigned long n; |
|
326 |
|
327 for (n=0; *bufsize; bufsize++) |
|
328 { |
|
329 i= *bufsize; |
|
330 if ((i <= '9') && (i >= '0')) |
|
331 n=n*10+i-'0'; |
|
332 else if (i == 'k') |
|
333 { |
|
334 n*=1024; |
|
335 bufsize++; |
|
336 break; |
|
337 } |
|
338 } |
|
339 if (*bufsize != '\0') |
|
340 { |
|
341 BIO_printf(bio_err,"invalid 'bufsize' specified.\n"); |
|
342 goto end; |
|
343 } |
|
344 |
|
345 /* It must be large enough for a base64 encoded line */ |
|
346 if (base64 && n < 80) n=80; |
|
347 |
|
348 bsize=(int)n; |
|
349 if (verbose) BIO_printf(bio_err,"bufsize=%d\n",bsize); |
|
350 } |
|
351 |
|
352 strbuf=OPENSSL_malloc(SIZE); |
|
353 buff=(unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize)); |
|
354 if ((buff == NULL) || (strbuf == NULL)) |
|
355 { |
|
356 BIO_printf(bio_err,"OPENSSL_malloc failure %ld\n",(long)EVP_ENCODE_LENGTH(bsize)); |
|
357 goto end; |
|
358 } |
|
359 |
|
360 in=BIO_new(BIO_s_file()); |
|
361 out=BIO_new(BIO_s_file()); |
|
362 if ((in == NULL) || (out == NULL)) |
|
363 { |
|
364 ERR_print_errors(bio_err); |
|
365 goto end; |
|
366 } |
|
367 if (debug) |
|
368 { |
|
369 BIO_set_callback(in,BIO_debug_callback); |
|
370 BIO_set_callback(out,BIO_debug_callback); |
|
371 BIO_set_callback_arg(in,(char *)bio_err); |
|
372 BIO_set_callback_arg(out,(char *)bio_err); |
|
373 } |
|
374 |
|
375 if (inf == NULL) |
|
376 { |
|
377 if (bufsize != NULL) |
|
378 setvbuf(stdin, (char *)NULL, _IONBF, 0); |
|
379 BIO_set_fp(in,stdin,BIO_NOCLOSE); |
|
380 } |
|
381 else |
|
382 { |
|
383 if (BIO_read_filename(in,inf) <= 0) |
|
384 { |
|
385 perror(inf); |
|
386 goto end; |
|
387 } |
|
388 } |
|
389 |
|
390 if(!str && passarg) { |
|
391 if(!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { |
|
392 BIO_printf(bio_err, "Error getting password\n"); |
|
393 goto end; |
|
394 } |
|
395 str = pass; |
|
396 } |
|
397 |
|
398 if ((str == NULL) && (cipher != NULL) && (hkey == NULL)) |
|
399 { |
|
400 for (;;) |
|
401 { |
|
402 char buf[200]; |
|
403 |
|
404 BIO_snprintf(buf,sizeof buf,"enter %s %s password:", |
|
405 OBJ_nid2ln(EVP_CIPHER_nid(cipher)), |
|
406 (enc)?"encryption":"decryption"); |
|
407 strbuf[0]='\0'; |
|
408 i=EVP_read_pw_string((char *)strbuf,SIZE,buf,enc); |
|
409 if (i == 0) |
|
410 { |
|
411 if (strbuf[0] == '\0') |
|
412 { |
|
413 ret=1; |
|
414 goto end; |
|
415 } |
|
416 str=strbuf; |
|
417 break; |
|
418 } |
|
419 if (i < 0) |
|
420 { |
|
421 BIO_printf(bio_err,"bad password read\n"); |
|
422 goto end; |
|
423 } |
|
424 } |
|
425 } |
|
426 |
|
427 |
|
428 if (outf == NULL) |
|
429 { |
|
430 BIO_set_fp(out,stdout,BIO_NOCLOSE); |
|
431 if (bufsize != NULL) |
|
432 setvbuf(stdout, (char *)NULL, _IONBF, 0); |
|
433 #ifdef OPENSSL_SYS_VMS |
|
434 { |
|
435 BIO *tmpbio = BIO_new(BIO_f_linebuffer()); |
|
436 out = BIO_push(tmpbio, out); |
|
437 } |
|
438 #endif |
|
439 } |
|
440 else |
|
441 { |
|
442 if (BIO_write_filename(out,outf) <= 0) |
|
443 { |
|
444 perror(outf); |
|
445 goto end; |
|
446 } |
|
447 } |
|
448 |
|
449 rbio=in; |
|
450 wbio=out; |
|
451 |
|
452 if (base64) |
|
453 { |
|
454 if ((b64=BIO_new(BIO_f_base64())) == NULL) |
|
455 goto end; |
|
456 if (debug) |
|
457 { |
|
458 BIO_set_callback(b64,BIO_debug_callback); |
|
459 BIO_set_callback_arg(b64,(char *)bio_err); |
|
460 } |
|
461 if (olb64) |
|
462 BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL); |
|
463 if (enc) |
|
464 wbio=BIO_push(b64,wbio); |
|
465 else |
|
466 rbio=BIO_push(b64,rbio); |
|
467 } |
|
468 |
|
469 if (cipher != NULL) |
|
470 { |
|
471 /* Note that str is NULL if a key was passed on the command |
|
472 * line, so we get no salt in that case. Is this a bug? |
|
473 */ |
|
474 if (str != NULL) |
|
475 { |
|
476 /* Salt handling: if encrypting generate a salt and |
|
477 * write to output BIO. If decrypting read salt from |
|
478 * input BIO. |
|
479 */ |
|
480 unsigned char *sptr; |
|
481 if(nosalt) sptr = NULL; |
|
482 else { |
|
483 if(enc) { |
|
484 if(hsalt) { |
|
485 if(!set_hex(hsalt,salt,sizeof salt)) { |
|
486 BIO_printf(bio_err, |
|
487 "invalid hex salt value\n"); |
|
488 goto end; |
|
489 } |
|
490 } else if (RAND_pseudo_bytes(salt, sizeof salt) < 0) |
|
491 goto end; |
|
492 /* If -P option then don't bother writing */ |
|
493 if((printkey != 2) |
|
494 && (BIO_write(wbio,magic, |
|
495 sizeof magic-1) != sizeof magic-1 |
|
496 || BIO_write(wbio, |
|
497 (char *)salt, |
|
498 sizeof salt) != sizeof salt)) { |
|
499 BIO_printf(bio_err,"error writing output file\n"); |
|
500 goto end; |
|
501 } |
|
502 } else if(BIO_read(rbio,mbuf,sizeof mbuf) != sizeof mbuf |
|
503 || BIO_read(rbio, |
|
504 (unsigned char *)salt, |
|
505 sizeof salt) != sizeof salt) { |
|
506 BIO_printf(bio_err,"error reading input file\n"); |
|
507 goto end; |
|
508 } else if(memcmp(mbuf,magic,sizeof magic-1)) { |
|
509 BIO_printf(bio_err,"bad magic number\n"); |
|
510 goto end; |
|
511 } |
|
512 |
|
513 sptr = salt; |
|
514 } |
|
515 |
|
516 EVP_BytesToKey(cipher,dgst,sptr, |
|
517 (unsigned char *)str, |
|
518 strlen(str),1,key,iv); |
|
519 /* zero the complete buffer or the string |
|
520 * passed from the command line |
|
521 * bug picked up by |
|
522 * Larry J. Hughes Jr. <hughes@indiana.edu> */ |
|
523 if (str == strbuf) |
|
524 OPENSSL_cleanse(str,SIZE); |
|
525 else |
|
526 OPENSSL_cleanse(str,strlen(str)); |
|
527 } |
|
528 if ((hiv != NULL) && !set_hex(hiv,iv,sizeof iv)) |
|
529 { |
|
530 BIO_printf(bio_err,"invalid hex iv value\n"); |
|
531 goto end; |
|
532 } |
|
533 if ((hiv == NULL) && (str == NULL)) |
|
534 { |
|
535 /* No IV was explicitly set and no IV was generated |
|
536 * during EVP_BytesToKey. Hence the IV is undefined, |
|
537 * making correct decryption impossible. */ |
|
538 BIO_printf(bio_err, "iv undefined\n"); |
|
539 goto end; |
|
540 } |
|
541 if ((hkey != NULL) && !set_hex(hkey,key,sizeof key)) |
|
542 { |
|
543 BIO_printf(bio_err,"invalid hex key value\n"); |
|
544 goto end; |
|
545 } |
|
546 |
|
547 if ((benc=BIO_new(BIO_f_cipher())) == NULL) |
|
548 goto end; |
|
549 |
|
550 /* Since we may be changing parameters work on the encryption |
|
551 * context rather than calling BIO_set_cipher(). |
|
552 */ |
|
553 |
|
554 BIO_get_cipher_ctx(benc, &ctx); |
|
555 if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)) |
|
556 { |
|
557 BIO_printf(bio_err, "Error setting cipher %s\n", |
|
558 EVP_CIPHER_name(cipher)); |
|
559 ERR_print_errors(bio_err); |
|
560 goto end; |
|
561 } |
|
562 |
|
563 if (nopad) |
|
564 EVP_CIPHER_CTX_set_padding(ctx, 0); |
|
565 |
|
566 if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc)) |
|
567 { |
|
568 BIO_printf(bio_err, "Error setting cipher %s\n", |
|
569 EVP_CIPHER_name(cipher)); |
|
570 ERR_print_errors(bio_err); |
|
571 goto end; |
|
572 } |
|
573 |
|
574 if (debug) |
|
575 { |
|
576 BIO_set_callback(benc,BIO_debug_callback); |
|
577 BIO_set_callback_arg(benc,(char *)bio_err); |
|
578 } |
|
579 |
|
580 if (printkey) |
|
581 { |
|
582 if (!nosalt) |
|
583 { |
|
584 printf("salt="); |
|
585 for (i=0; i<(int)sizeof(salt); i++) |
|
586 printf("%02X",salt[i]); |
|
587 printf("\n"); |
|
588 } |
|
589 if (cipher->key_len > 0) |
|
590 { |
|
591 printf("key="); |
|
592 for (i=0; i<cipher->key_len; i++) |
|
593 printf("%02X",key[i]); |
|
594 printf("\n"); |
|
595 } |
|
596 if (cipher->iv_len > 0) |
|
597 { |
|
598 printf("iv ="); |
|
599 for (i=0; i<cipher->iv_len; i++) |
|
600 printf("%02X",iv[i]); |
|
601 printf("\n"); |
|
602 } |
|
603 if (printkey == 2) |
|
604 { |
|
605 ret=0; |
|
606 goto end; |
|
607 } |
|
608 |
|
609 |
|
610 } |
|
611 } |
|
612 |
|
613 /* Only encrypt/decrypt as we write the file */ |
|
614 if (benc != NULL) |
|
615 wbio=BIO_push(benc,wbio); |
|
616 |
|
617 for (;;) |
|
618 { |
|
619 inl=BIO_read(rbio,(char *)buff,bsize); |
|
620 if (inl <= 0) break; |
|
621 if (BIO_write(wbio,(char *)buff,inl) != inl) |
|
622 { |
|
623 BIO_printf(bio_err,"error writing output file\n"); |
|
624 goto end; |
|
625 } |
|
626 } |
|
627 if (!BIO_flush(wbio)) |
|
628 { |
|
629 BIO_printf(bio_err,"bad decrypt\n"); |
|
630 goto end; |
|
631 } |
|
632 |
|
633 ret=0; |
|
634 if (verbose) |
|
635 { |
|
636 BIO_printf(bio_err,"bytes read :%8ld\n",BIO_number_read(in)); |
|
637 BIO_printf(bio_err,"bytes written:%8ld\n",BIO_number_written(out)); |
|
638 } |
|
639 end: |
|
640 ERR_print_errors(bio_err); |
|
641 if (strbuf != NULL) OPENSSL_free(strbuf); |
|
642 if (buff != NULL) OPENSSL_free(buff); |
|
643 if (in != NULL) BIO_free(in); |
|
644 if (out != NULL) BIO_free_all(out); |
|
645 if (benc != NULL) BIO_free(benc); |
|
646 if (b64 != NULL) BIO_free(b64); |
|
647 if(pass) OPENSSL_free(pass); |
|
648 apps_shutdown(); |
|
649 OPENSSL_EXIT(ret); |
|
650 } |
|
651 |
|
652 int set_hex(char *in, unsigned char *out, int size) |
|
653 { |
|
654 int i,n; |
|
655 unsigned char j; |
|
656 |
|
657 n=strlen(in); |
|
658 if (n > (size*2)) |
|
659 { |
|
660 BIO_printf(bio_err,"hex string is too long\n"); |
|
661 return(0); |
|
662 } |
|
663 memset(out,0,size); |
|
664 for (i=0; i<n; i++) |
|
665 { |
|
666 j=(unsigned char)*in; |
|
667 *(in++)='\0'; |
|
668 if (j == 0) break; |
|
669 if ((j >= '0') && (j <= '9')) |
|
670 j-='0'; |
|
671 else if ((j >= 'A') && (j <= 'F')) |
|
672 j=j-'A'+10; |
|
673 else if ((j >= 'a') && (j <= 'f')) |
|
674 j=j-'a'+10; |
|
675 else |
|
676 { |
|
677 BIO_printf(bio_err,"non-hex digit\n"); |
|
678 return(0); |
|
679 } |
|
680 if (i&1) |
|
681 out[i/2]|=j; |
|
682 else |
|
683 out[i/2]=(j<<4); |
|
684 } |
|
685 return(1); |
|
686 } |