Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

bdcat.cc

Go to the documentation of this file.
00001 // $Id: bdcat.cc,v 1.1.1.1 2004/04/30 00:31:27 jason Exp $
00002 //
00003 // Decrypts Bro's log files.
00004 //
00005 // Usage: bdcat [-k file-with-secret-rsa-key] [files...]
00006 //
00007 // The key file may be alternatively set via the env variable BDCAT_KEY.
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         // Read file header.
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         // Decrypt data.
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         // Read options.
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         // Init crypto.
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         // Depending on the OpenSSL version, EVP_*_cbc()
00153         // returns a const or a non-const.
00154         CipherType = (EVP_CIPHER*) EVP_bf_cbc();
00155 
00156         // Decrypt the files.
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         }

Generated on Wed Sep 14 02:55:57 2005 for bro_docs by doxygen 1.3.5