CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/CondCore/DBCommon/src/Cipher.cc

Go to the documentation of this file.
00001 #include "CondCore/DBCommon/interface/Cipher.h"
00002 #include "CondCore/DBCommon/interface/Exception.h"
00003 #include <string.h>
00004 // blowfish encryption
00005 #include "blowfish.h"
00006 // GNU base 64 encoding
00007 #include "base64.h"
00008 
00009 cond::Cipher::Cipher( const std::string& key ):
00010   m_ctx(new BLOWFISH_CTX){
00011   char* k = const_cast<char*>(key.c_str());
00012   Blowfish_Init( m_ctx, reinterpret_cast<unsigned char*>(k), key.size());  
00013 }
00014 
00015 cond::Cipher::~Cipher(){
00016   delete m_ctx;
00017 }
00018 
00019 size_t cond::Cipher::bf_process_alloc( const unsigned char* input, 
00020                                        size_t input_size, 
00021                                        unsigned char*& output,
00022                                        bool decrypt ){
00023   uInt32 L, R;
00024   unsigned int j = sizeof(uInt32);
00025 
00026   unsigned int output_size=0;
00027   for ( unsigned int i=0; i < input_size; i+=(j*2)){
00028     output_size = i+2*j;
00029   }
00030   output = (unsigned char*) malloc( output_size );
00031   memset(output, 0, output_size);
00032 
00033   for (unsigned int i=0; i < input_size; i+=(j*2)) {
00034     L = R = 0;
00035     unsigned int nl = 0;
00036     unsigned int nr = 0;
00037     if( input_size > i+j ){
00038       nl = j;
00039       if( input_size > i+2*j ){
00040         nr = j;
00041       } else { 
00042         nr = input_size-i-j;
00043       }
00044     } else {
00045       nl = input_size-i;
00046       nr = 0;
00047     }
00048     if(nl) memcpy(&L, input+i, nl);
00049     if(nr) memcpy(&R, input+i+j, nr);
00050     if( !decrypt ){
00051       Blowfish_Encrypt(m_ctx, &L, &R);
00052     } else {
00053       Blowfish_Decrypt(m_ctx, &L, &R);
00054     }
00055     memcpy(output+i, &L, j);
00056     memcpy(output+i+j, &R, j);
00057   }
00058   
00059   return output_size;
00060 }
00061     
00062 size_t cond::Cipher::encrypt( const std::string& input, unsigned char*& output ){
00063   return bf_process_alloc( reinterpret_cast<const unsigned char*>(input.c_str()), input.size(), output, false );;
00064 }
00065 
00066 std::string cond::Cipher::decrypt( const unsigned char* input, size_t inputSize ){
00067   unsigned char* out = 0;
00068   size_t outSize = bf_process_alloc( input, inputSize, out, true );
00069   char* sout = reinterpret_cast<char*>(out);
00070   // the output can still contain one or more \0 chars...
00071   size_t soutSize = strlen( sout ); 
00072   if( soutSize < outSize ){
00073     outSize = soutSize;
00074   }
00075   std::string ret( sout, outSize );
00076   free (out );
00077   return ret;
00078 }
00079 
00080 std::string cond::Cipher::b64encrypt( const std::string& input ){
00081   unsigned char* out = 0;
00082   size_t outSize = bf_process_alloc( reinterpret_cast<const unsigned char*>(input.c_str()), input.size(), out, false );
00083   char* b64out = 0;
00084   size_t b64size = base64_encode_alloc( reinterpret_cast<const char*>(out), outSize, &b64out );
00085   std::string ret( b64out, b64size );
00086   free (out);
00087   free (b64out);
00088   return ret;
00089 }
00090 
00091 std::string cond::Cipher::b64decrypt( const std::string& b64in ){
00092   char* input = 0;
00093   size_t inputSize = 0;
00094   if( !base64_decode_alloc( b64in.c_str(), b64in.size(), &input, &inputSize ) ){
00095     throwException("Input provided is not a valid base64 string.","Cipher::b64decrypt");
00096   }
00097   std::string ret = decrypt( reinterpret_cast<const unsigned char*>(input), inputSize );
00098   free (input);
00099   return ret;
00100 }
00101