- }
- else
- {
- if (BIO_write_filename(out,outf) <= 0)
- {
- perror(outf);
- goto end;
- }
- }
-
- rbio=in;
- wbio=out;
-
- if (base64)
- {
- if ((b64=BIO_new(BIO_f_base64())) == NULL)
- goto end;
- if (debug)
- {
- BIO_set_callback(b64,BIO_debug_callback);
- BIO_set_callback_arg(b64,bio_err);
- }
- if (olb64)
- BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL);
- if (enc)
- wbio=BIO_push(b64,wbio);
- else
- rbio=BIO_push(b64,rbio);
- }
-
- if (cipher != NULL)
- {
- /* Note that str is NULL if a key was passed on the command
- * line, so we get no salt in that case. Is this a bug?
- */
- if (str != NULL)
- {
- /* Salt handling: if encrypting generate a salt and
- * write to output BIO. If decrypting read salt from
- * input BIO.
- */
- unsigned char *sptr;
- if(nosalt) sptr = NULL;
- else {
- if(enc) {
- if(hsalt) {
- if(!set_hex(hsalt,salt,sizeof salt)) {
- BIO_printf(bio_err,
- "invalid hex salt value\n");
- goto end;
- }
- } else if (RAND_pseudo_bytes(salt, sizeof salt) < 0)
- goto end;
- /* If -P option then don't bother writing */
- if((printkey != 2)
- && (BIO_write(wbio,magic,
- sizeof magic-1) != sizeof magic-1
- || BIO_write(wbio,
- (char *)salt,
- sizeof salt) != sizeof salt)) {
- BIO_printf(bio_err,"error writing output file\n");
- goto end;
- }
- } else if(BIO_read(rbio,mbuf,sizeof mbuf) != sizeof mbuf
- || BIO_read(rbio,
- (unsigned char *)salt,
- sizeof salt) != sizeof salt) {
- BIO_printf(bio_err,"error reading input file\n");
- goto end;
- } else if(memcmp(mbuf,magic,sizeof magic-1)) {
- BIO_printf(bio_err,"bad magic number\n");
- goto end;
- }
-
- sptr = salt;
- }
-
- EVP_BytesToKey(cipher,dgst,sptr,
- (unsigned char *)str,
- strlen(str),1,key,iv);
- /* zero the complete buffer or the string
- * passed from the command line
- * bug picked up by
- * Larry J. Hughes Jr. <hughes@indiana.edu> */
- if (str == strbuf)
- OPENSSL_cleanse(str,SIZE);
- else
- OPENSSL_cleanse(str,strlen(str));
- }
- if ((hiv != NULL) && !set_hex(hiv,iv,sizeof iv))
- {
- BIO_printf(bio_err,"invalid hex iv value\n");
- goto end;
- }
- if ((hiv == NULL) && (str == NULL))
- {
- /* No IV was explicitly set and no IV was generated
- * during EVP_BytesToKey. Hence the IV is undefined,
- * making correct decryption impossible. */
- BIO_printf(bio_err, "iv undefined\n");
- goto end;
- }
- if ((hkey != NULL) && !set_hex(hkey,key,sizeof key))
- {
- BIO_printf(bio_err,"invalid hex key value\n");
- goto end;
- }
-
- if ((benc=BIO_new(BIO_f_cipher())) == NULL)
- goto end;
-
- /* Since we may be changing parameters work on the encryption
- * context rather than calling BIO_set_cipher().
- */
-
- BIO_get_cipher_ctx(benc, &ctx);
- if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc))
- {
- BIO_printf(bio_err, "Error setting cipher %s\n",
- EVP_CIPHER_name(cipher));
- ERR_print_errors(bio_err);
- goto end;
- }
-
- if (nopad)
- EVP_CIPHER_CTX_set_padding(ctx, 0);
-
- if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc))
- {
- BIO_printf(bio_err, "Error setting cipher %s\n",
- EVP_CIPHER_name(cipher));
- ERR_print_errors(bio_err);
- goto end;
- }
-
- if (debug)
- {
- BIO_set_callback(benc,BIO_debug_callback);
- BIO_set_callback_arg(benc,bio_err);
- }
-
- if (printkey)
- {
- if (!nosalt)
- {
- printf("salt=");
- for (i=0; i<(int)sizeof(salt); i++)
- printf("%02X",salt[i]);
- printf("\n");
- }
- if (cipher->key_len > 0)
- {
- printf("key=");
- for (i=0; i<cipher->key_len; i++)
- printf("%02X",key[i]);
- printf("\n");
- }
- if (cipher->iv_len > 0)
- {
- printf("iv =");
- for (i=0; i<cipher->iv_len; i++)
- printf("%02X",iv[i]);
- printf("\n");
- }
- if (printkey == 2)
- {
- ret=0;
- goto end;
- }
- }
- }
-
- /* Only encrypt/decrypt as we write the file */
- if (benc != NULL)
- wbio=BIO_push(benc,wbio);
-
- for (;;)
- {
- inl=BIO_read(rbio,(char *)buff,bsize);
- if (inl <= 0) break;
- if (BIO_write(wbio,(char *)buff,inl) != inl)
- {
- BIO_printf(bio_err,"error writing output file\n");
- goto end;
- }
- }
- if (!BIO_flush(wbio))
- {
- BIO_printf(bio_err,"bad decrypt\n");
- goto end;
- }
-
- ret=0;
- if (verbose)
- {
- BIO_printf(bio_err,"bytes read :%8ld\n",BIO_number_read(in));
- BIO_printf(bio_err,"bytes written:%8ld\n",BIO_number_written(out));
- }
-end:
- ERR_print_errors(bio_err);
- if (strbuf != NULL) OPENSSL_free(strbuf);
- if (buff != NULL) OPENSSL_free(buff);
- if (in != NULL) BIO_free(in);
- if (out != NULL) BIO_free_all(out);
- if (benc != NULL) BIO_free(benc);
- if (b64 != NULL) BIO_free(b64);
- if(pass) OPENSSL_free(pass);
- apps_shutdown();
- OPENSSL_EXIT(ret);
- }
-
-int set_hex(char *in, unsigned char *out, int size)
- {
- int i,n;
- unsigned char j;
-
- n=strlen(in);
- if (n > (size*2))
- {
- BIO_printf(bio_err,"hex string is too long\n");
- return(0);
- }
- memset(out,0,size);
- for (i=0; i<n; i++)
- {
- j=(unsigned char)*in;
- *(in++)='\0';
- if (j == 0) break;
- if ((j >= '0') && (j <= '9'))
- j-='0';
- else if ((j >= 'A') && (j <= 'F'))
- j=j-'A'+10;
- else if ((j >= 'a') && (j <= 'f'))
- j=j-'a'+10;
- else
- {
- BIO_printf(bio_err,"non-hex digit\n");
- return(0);
- }
- if (i&1)
- out[i/2]|=j;
- else
- out[i/2]=(j<<4);
- }
- return(1);
- }