00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <string.h>
00012 #include <unistd.h>
00013 #include <netinet/in.h>
00014
00015 #include "openssl/evp.h"
00016 #include "openssl/pem.h"
00017 #include "openssl/err.h"
00018
00019 EVP_PKEY* SecKey = 0;
00020 EVP_CIPHER* CipherType = 0;
00021
00022 void cryptcat(FILE* f)
00023 {
00024 unsigned char magic[7];
00025 unsigned long secret_len;
00026
00027
00028 if ( ! (fread(&magic, 7, 1, f) &&
00029 fread(&secret_len, sizeof(secret_len), 1, f)) )
00030 {
00031 fprintf(stderr, "can't read file header: %s\n", strerror(errno));
00032 exit(1);
00033 }
00034
00035 if ( memcmp("BROENC1", (const char*) magic, 7) != 0 )
00036 {
00037 fputs("not a Bro encrypted file\n", stderr);
00038 exit(1);
00039 }
00040
00041 secret_len = ntohl(secret_len);
00042 int iv_len = EVP_CIPHER_iv_length(CipherType);
00043 unsigned char secret[secret_len];
00044 unsigned char iv[iv_len];
00045
00046 if ( ! (fread(&secret, secret_len, 1, f) &&
00047 fread(&iv, iv_len, 1, f)) )
00048 {
00049 fprintf(stderr, "can't read file header: %s\n", strerror(errno));
00050 exit(1);
00051 }
00052
00053
00054 EVP_CIPHER_CTX cipher_ctx;
00055 if ( ! EVP_OpenInit(&cipher_ctx, CipherType,
00056 secret, secret_len, iv, SecKey) )
00057 {
00058 fprintf( stderr, "can't init decryption: %s\n",
00059 ERR_error_string(ERR_get_error(), 0));
00060 exit(1);
00061 return;
00062 }
00063
00064 int block_size = EVP_CIPHER_block_size(CipherType);
00065 unsigned char buffer_in[block_size];
00066 unsigned char buffer_out[block_size];
00067
00068 int inl, outl;
00069 while ( (inl = fread(buffer_in, 1, block_size, f)) )
00070 {
00071 if ( ! EVP_OpenUpdate(&cipher_ctx, buffer_out,
00072 &outl, buffer_in, inl) )
00073 {
00074 fprintf( stderr, "can't decrypt: %s\n",
00075 ERR_error_string(ERR_get_error(), 0));
00076 exit(1);
00077 }
00078
00079 if ( outl && ! fwrite(buffer_out, outl, 1, stdout) )
00080 {
00081 fprintf(stderr, "can't write to stdout: %s\n",
00082 strerror(errno));
00083 exit(1);
00084 }
00085 }
00086
00087 if ( ! EVP_OpenFinal(&cipher_ctx, buffer_out, &outl) )
00088 {
00089 fprintf( stderr, "can't decrypt: %s\n",
00090 ERR_error_string(ERR_get_error(), 0));
00091 exit(1);
00092 }
00093
00094 if ( outl && ! fwrite(buffer_out, outl, 1, stdout) )
00095 {
00096 fprintf(stderr, "can't write to stdout: %s\n", strerror(errno));
00097 exit(1);
00098 }
00099
00100 fclose(f);
00101 }
00102
00103 void Usage()
00104 {
00105 fprintf(stderr, "bdcat [-k <sec-key-file>] [files]\n");
00106 exit(1);
00107 }
00108
00109 int main(int argc, char** argv)
00110 {
00111 char* keyfile = getenv("BDCAT_KEY");
00112
00113
00114 char op;
00115 while ( (op = getopt(argc, argv, "k:")) >= 0 )
00116 {
00117 if ( op == 'k' )
00118 keyfile = optarg;
00119 else
00120 Usage();
00121 }
00122
00123 if ( ! keyfile )
00124 {
00125 fputs("no keyfile given\n", stderr);
00126 exit(1);
00127 }
00128
00129
00130
00131 ERR_load_crypto_strings();
00132 OpenSSL_add_all_algorithms();
00133
00134 FILE* f = fopen(keyfile, "r");
00135 if ( ! f )
00136 {
00137 fprintf(stderr, "can't open key file %s: %s\n",
00138 keyfile, strerror(errno));
00139 exit(1);
00140 }
00141
00142 SecKey = PEM_read_PrivateKey(f, 0, 0, 0);
00143 if ( ! SecKey )
00144 {
00145 fprintf(stderr, "can't read key from %s: %s\n", keyfile,
00146 ERR_error_string(ERR_get_error(), 0));
00147 exit(1);
00148 }
00149
00150 fclose(f);
00151
00152
00153
00154 CipherType = (EVP_CIPHER*) EVP_bf_cbc();
00155
00156
00157 if ( optind == argc )
00158 cryptcat(stdin);
00159 else
00160 {
00161 while ( optind < argc )
00162 {
00163 FILE* f = fopen(argv[optind], "r");
00164 if ( ! f )
00165 {
00166 fprintf(stderr, "can't open %s: %s\n",
00167 argv[optind], strerror(errno));
00168 exit(1);
00169 }
00170
00171 cryptcat(f);
00172 ++optind;
00173 }
00174 }
00175 }