File indexing completed on 2024-04-06 12:01:25
0001 #include "CondCore/CondDB/interface/Cipher.h"
0002 #include "CondCore/CondDB/interface/Exception.h"
0003 #include <cstring>
0004
0005 #include "blowfish.h"
0006
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
0092
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 }