Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:50:22

0001 #include "CondCore/CondDB/interface/Cipher.h"
0002 #include "CondCore/CondDB/interface/Exception.h"
0003 #include <cstring>
0004 // blowfish encryption
0005 #include "blowfish.h"
0006 // GNU base 64 encoding
0007 #include "base64.h"
0008 #include <cassert>
0009 
0010 cond::auth::Cipher::Cipher(const std::string& key) : m_ctx(new BLOWFISH_CTX) {
0011   char* k = const_cast<char*>(key.c_str());
0012   Blowfish_Init(m_ctx, reinterpret_cast<unsigned char*>(k), key.size());
0013 }
0014 
0015 cond::auth::Cipher::~Cipher() { delete m_ctx; }
0016 
0017 size_t cond::auth::Cipher::bf_process_alloc(const unsigned char* input,
0018                                             size_t input_size,
0019                                             unsigned char*& output,
0020                                             bool decrypt) {
0021   assert(input_size != 0);
0022 
0023   uInt32 L, R;
0024   unsigned int j = sizeof(uInt32);
0025 
0026   unsigned int output_size = 0;
0027 
0028   if (!input_size) {
0029     output = nullptr;
0030     return 0;
0031   }
0032 
0033   for (unsigned int i = 0; i < input_size; i += (j * 2)) {
0034     output_size = i + 2 * j;
0035   }
0036   output = (unsigned char*)malloc(output_size);
0037   memset(output, 0, output_size);
0038 
0039   for (unsigned int i = 0; i < input_size; i += (j * 2)) {
0040     L = R = 0;
0041     unsigned int nl = 0;
0042     unsigned int nr = 0;
0043     if (input_size > i + j) {
0044       nl = j;
0045       if (input_size > i + 2 * j) {
0046         nr = j;
0047       } else {
0048         nr = input_size - i - j;
0049       }
0050     } else {
0051       nl = input_size - i;
0052       nr = 0;
0053     }
0054     if (nl)
0055       memcpy(&L, input + i, nl);
0056     if (nr)
0057       memcpy(&R, input + i + j, nr);
0058     if (!decrypt) {
0059       Blowfish_Encrypt(m_ctx, &L, &R);
0060     } else {
0061       Blowfish_Decrypt(m_ctx, &L, &R);
0062     }
0063     memcpy(output + i, &L, j);
0064     memcpy(output + i + j, &R, j);
0065   }
0066 
0067   return output_size;
0068 }
0069 
0070 size_t cond::auth::Cipher::encrypt(const std::string& input, unsigned char*& output) {
0071   if (input.empty()) {
0072     output = nullptr;
0073     return 0;
0074   }
0075   return bf_process_alloc(reinterpret_cast<const unsigned char*>(input.c_str()), input.size(), output, false);
0076   ;
0077 }
0078 
0079 std::string cond::auth::Cipher::decrypt(const unsigned char* input, size_t inputSize) {
0080   if (!inputSize)
0081     return "";
0082   unsigned char* out = nullptr;
0083   size_t outSize = bf_process_alloc(input, inputSize, out, true);
0084   size_t i = 0;
0085   for (i = 0; i < outSize; i++) {
0086     if (out[i] == 0)
0087       break;
0088   }
0089 
0090   char* sout = reinterpret_cast<char*>(out);
0091   // the output can still contain one or more \0 chars...
0092   //size_t soutSize = strlen( sout );
0093   size_t soutSize = 0;
0094   for (soutSize = 0; soutSize < outSize; soutSize++)
0095     if (out[soutSize] == 0)
0096       break;
0097 
0098   if (soutSize < outSize) {
0099     outSize = soutSize;
0100   }
0101 
0102   std::string ret("");
0103   if (outSize)
0104     ret = std::string(sout, outSize);
0105   free(out);
0106   return ret;
0107 }
0108 
0109 std::string cond::auth::Cipher::b64encrypt(const std::string& input) {
0110   if (input.empty())
0111     return "";
0112   unsigned char* out = nullptr;
0113   size_t outSize = bf_process_alloc(reinterpret_cast<const unsigned char*>(input.c_str()), input.size(), out, false);
0114   char* b64out = nullptr;
0115   size_t b64size = base64_encode_alloc(reinterpret_cast<const char*>(out), outSize, &b64out);
0116   std::string ret(b64out, b64size);
0117   free(out);
0118   free(b64out);
0119   return ret;
0120 }
0121 
0122 std::string cond::auth::Cipher::b64decrypt(const std::string& b64in) {
0123   if (b64in.empty())
0124     return "";
0125   char* input = nullptr;
0126   size_t inputSize = 0;
0127   if (!base64_decode_alloc(b64in.c_str(), b64in.size(), &input, &inputSize)) {
0128     throwException("Input provided is not a valid base64 string.", "Cipher::b64decrypt");
0129   }
0130   std::string ret = decrypt(reinterpret_cast<const unsigned char*>(input), inputSize);
0131   free(input);
0132   return ret;
0133 }