9 #include <openssl/evp.h>
10 #include <openssl/rand.h>
32 Key *Key::CreateRandomly(
const unsigned size) {
35 result->
data_ =
reinterpret_cast<unsigned char *
>(smalloc(size));
37 int retval = RAND_bytes(result->
data_, result->
size_);
47 Key *Key::CreateFromFile(
const string &path) {
48 int fd = open(path.c_str(), O_RDONLY);
59 if ((info.st_size == 0) || (info.st_size > kMaxSize)) {
65 result->
size_ = info.st_size;
66 result->
data_ =
reinterpret_cast<unsigned char *
>(smalloc(result->
size_));
67 int nbytes = read(fd, result->
data_, result->
size_);
69 if ((nbytes < 0) || (static_cast<unsigned>(nbytes) != result->
size_)) {
77 Key *Key::CreateFromString(
const string &key) {
78 unsigned size = key.size();
79 if ((size == 0) || (size > kMaxSize))
83 result->data_ =
reinterpret_cast<unsigned char *
>(smalloc(size));
84 memcpy(result->data_, key.data(),
size);
91 memset(data_, 0, size_);
97 bool Key::SaveToFile(
const std::string &path) {
98 int fd = open(path.c_str(), O_WRONLY);
103 int nbytes = write(fd, data_, size_);
105 return (nbytes >= 0) && (
static_cast<unsigned>(nbytes) == size_);
109 string Key::ToBase64()
const {
110 return Base64(
string(reinterpret_cast<const char *>(data_), size_));
117 MemoryKeyDatabase::MemoryKeyDatabase() {
119 reinterpret_cast<pthread_mutex_t *
>(smalloc(
sizeof(pthread_mutex_t)));
120 int retval = pthread_mutex_init(lock_, NULL);
125 MemoryKeyDatabase::~MemoryKeyDatabase() {
126 pthread_mutex_destroy(lock_);
131 bool MemoryKeyDatabase::StoreNew(
const Key *key,
string *
id) {
137 map<string, const Key *>::const_iterator i = database_.find(*
id);
138 if (i != database_.end())
141 database_[*id] = key;
146 const Key *MemoryKeyDatabase::Find(
const string &
id) {
148 map<string, const Key *>::const_iterator i = database_.find(
id);
149 if (i != database_.end())
171 bool Cipher::Encrypt(
172 const string &plaintext,
177 if (key.
size() != key_size())
180 unsigned char envelope = 0 & 0x0F;
182 ciphertext->push_back(envelope);
184 *ciphertext += DoEncrypt(plaintext, key);
189 bool Cipher::Decrypt(
190 const string &ciphertext,
195 if (ciphertext.size() < 1)
197 unsigned char envelope = ciphertext[0];
198 unsigned char version = envelope & 0x0F;
201 unsigned char algorithm = (envelope & 0xF0) >> 4;
202 if (algorithm >
kNone)
206 if (key.
size() != cipher->key_size())
208 *plaintext += cipher->DoDecrypt(ciphertext.substr(1), key);
216 string CipherAes256Cbc::DoDecrypt(
const string &ciphertext,
const Key &key) {
219 if (ciphertext.size() < kIvSize)
222 const unsigned char *iv =
reinterpret_cast<const unsigned char *
>(
226 unsigned char *plaintext =
reinterpret_cast<unsigned char *
>(
227 smalloc(kBlockSize + ciphertext.size() - kIvSize));
230 #ifdef OPENSSL_API_INTERFACE_V11
231 EVP_CIPHER_CTX *ctx_ptr = EVP_CIPHER_CTX_new();
234 EVP_CIPHER_CTX_init(&ctx);
235 EVP_CIPHER_CTX *ctx_ptr = &
ctx;
237 retval = EVP_DecryptInit_ex(ctx_ptr, EVP_aes_256_cbc(), NULL, key.
data(), iv);
239 retval = EVP_DecryptUpdate(ctx_ptr,
240 plaintext, &plaintext_len,
241 reinterpret_cast<const unsigned char *>(
242 ciphertext.data() + kIvSize),
243 ciphertext.length() - kIvSize);
246 #ifdef OPENSSL_API_INTERFACE_V11
247 EVP_CIPHER_CTX_free(ctx_ptr);
249 retval = EVP_CIPHER_CTX_cleanup(&ctx);
254 retval = EVP_DecryptFinal_ex(ctx_ptr, plaintext + plaintext_len, &tail_len);
255 #ifdef OPENSSL_API_INTERFACE_V11
256 EVP_CIPHER_CTX_free(ctx_ptr);
258 int retval_2 = EVP_CIPHER_CTX_cleanup(&ctx);
266 plaintext_len += tail_len;
267 if (plaintext_len == 0) {
271 string result(reinterpret_cast<char *>(plaintext), plaintext_len);
277 string CipherAes256Cbc::DoEncrypt(
const string &plaintext,
const Key &key) {
283 unsigned char *iv = md5.
digest;
287 unsigned char *ciphertext =
reinterpret_cast<unsigned char *
>(
288 smalloc(kIvSize + 2 * kBlockSize + plaintext.size()));
289 memcpy(ciphertext, iv, kIvSize);
292 #ifdef OPENSSL_API_INTERFACE_V11
293 EVP_CIPHER_CTX *ctx_ptr = EVP_CIPHER_CTX_new();
296 EVP_CIPHER_CTX_init(&ctx);
297 EVP_CIPHER_CTX *ctx_ptr = &
ctx;
299 retval = EVP_EncryptInit_ex(ctx_ptr, EVP_aes_256_cbc(), NULL, key.
data(), iv);
302 if (!plaintext.empty()) {
303 retval = EVP_EncryptUpdate(ctx_ptr,
304 ciphertext + kIvSize, &cipher_len,
305 reinterpret_cast<const unsigned char *>(plaintext.data()),
309 retval = EVP_EncryptFinal_ex(ctx_ptr, ciphertext + kIvSize + cipher_len,
312 #ifdef OPENSSL_API_INTERFACE_V11
313 EVP_CIPHER_CTX_free(ctx_ptr);
315 retval = EVP_CIPHER_CTX_cleanup(&ctx);
319 cipher_len += tail_len;
321 string result(reinterpret_cast<char *>(ciphertext), kIvSize + cipher_len);
341 return hmac.CastToMd5();
348 string CipherNone::DoDecrypt(
const string &ciphertext,
const Key &key) {
353 string CipherNone::DoEncrypt(
const string &plaintext,
const Key &key) {
struct cvmcache_context * ctx
static Publisher * Create(const SettingsPublisher &settings)
std::string ToString(const bool with_suffix=false) const
void Hmac(const string &key, const unsigned char *buffer, const unsigned buffer_size, Any *any_digest)
assert((mem||(size==0))&&"Out Of Memory")
unsigned char digest[digest_size_]
static Uuid * Create(const std::string &store_path)
void HashMem(const unsigned char *buffer, const unsigned buffer_size, Any *any_digest)
string Base64(const string &data)
const unsigned char * data() const
const unsigned char * data() const