00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _CRYPT_H
00023 #define _CRYPT_H
00024
00025 #ifdef HAVE_CONFIG_H
00026 # include <config.h>
00027 #endif
00028
00029 #ifdef HAVE_INTTYPES_H
00030 # include <inttypes.h>
00031 #endif
00032
00033 #include <openssl/evp.h>
00034
00035 #include "yapetexception.h"
00036 #include "key.h"
00037 #include "bdbuffer.h"
00038 #include "record.h"
00039
00040 namespace YAPET {
00057 class Crypt {
00058 private:
00067 const EVP_CIPHER* cipher;
00074 uint32_t iv_length;
00081 uint32_t key_length;
00087 Key key;
00088
00089 public:
00091 Crypt(const Key& k) throw(YAPETException);
00092 Crypt(const Crypt& c);
00093 inline ~Crypt() {}
00094
00104 inline uint32_t getIVLength() const { return iv_length; }
00113 inline uint32_t getKeyLength() const { return key_length; }
00114
00138 template<class T>
00139 BDBuffer* encrypt(const Record<T>& data)
00140 throw(YAPETException, YAPETEncryptionException) {
00141 if (key.ivec_size() != iv_length)
00142 throw YAPETException("IVec length missmatch");
00143
00144 EVP_CIPHER_CTX ctx;
00145 EVP_CIPHER_CTX_init(&ctx);
00146
00147 int retval = EVP_EncryptInit_ex(&ctx,
00148 cipher,
00149 NULL,
00150 key,
00151 key.getIVec());
00152 if (retval == 0) {
00153 EVP_CIPHER_CTX_cleanup(&ctx);
00154 throw YAPETEncryptionException("Error initializing encryption engine");
00155 }
00156
00157 retval = EVP_CIPHER_CTX_set_key_length(&ctx, key.size());
00158 if (retval == 0) {
00159 EVP_CIPHER_CTX_cleanup(&ctx);
00160 throw YAPETException("Error setting the key length");
00161 }
00162
00163 BDBuffer* encdata =
00164 new BDBuffer(data.size() + EVP_MAX_BLOCK_LENGTH);
00165 int outlen;
00166 retval = EVP_EncryptUpdate(&ctx,
00167 *encdata,
00168 &outlen,
00169 data,
00170 data.size());
00171 if (retval == 0) {
00172 EVP_CIPHER_CTX_cleanup(&ctx);
00173 delete encdata;
00174 throw YAPETEncryptionException("Error encrypting data");
00175 }
00176
00177 int tmplen;
00178 retval = EVP_EncryptFinal_ex(&ctx,
00179 encdata->at(outlen),
00180 &tmplen);
00181 if (retval == 0) {
00182 EVP_CIPHER_CTX_cleanup(&ctx);
00183 delete encdata;
00184 throw YAPETEncryptionException("Error finalizing encryption");
00185 }
00186
00187 encdata->resize(outlen+tmplen);
00188
00189 EVP_CIPHER_CTX_cleanup(&ctx);
00190
00191 return encdata;
00192 }
00193
00215 template<class T>
00216 Record<T>* decrypt(const BDBuffer& data)
00217 throw(YAPETException, YAPETEncryptionException) {
00218 if ( ((unsigned int)key.ivec_size()) != iv_length)
00219 throw YAPETException("IVec length missmatch");
00220
00221 EVP_CIPHER_CTX ctx;
00222 EVP_CIPHER_CTX_init(&ctx);
00223
00224 int retval = EVP_DecryptInit_ex(&ctx,
00225 cipher,
00226 NULL,
00227 key,
00228 key.getIVec());
00229 if (retval == 0) {
00230 EVP_CIPHER_CTX_cleanup(&ctx);
00231 throw YAPETEncryptionException("Error initializing encryption engine");
00232 }
00233
00234 retval = EVP_CIPHER_CTX_set_key_length(&ctx, key.size());
00235 if (retval == 0) {
00236 EVP_CIPHER_CTX_cleanup(&ctx);
00237 throw YAPETException("Error setting the key length");
00238 }
00239
00240 BDBuffer* decdata = new BDBuffer(data.size());
00241 int outlen;
00242 retval = EVP_DecryptUpdate(&ctx,
00243 *decdata,
00244 &outlen,
00245 data,
00246 data.size());
00247 if (retval == 0) {
00248 EVP_CIPHER_CTX_cleanup(&ctx);
00249 delete decdata;
00250 throw YAPETEncryptionException("Error decrypting data");
00251 }
00252
00253 int tmplen;
00254 retval = EVP_DecryptFinal_ex(&ctx,
00255 decdata->at(outlen),
00256 &tmplen);
00257 if (retval == 0) {
00258 EVP_CIPHER_CTX_cleanup(&ctx);
00259 delete decdata;
00260 throw YAPETEncryptionException("Error finalizing decryption");
00261 }
00262
00263 decdata->resize(outlen+tmplen);
00264
00265 EVP_CIPHER_CTX_cleanup(&ctx);
00266
00267 Record<T>* r = new Record<T>;
00268 *r=*decdata;
00269
00270 delete decdata;
00271 return r;
00272 }
00273
00274 const Crypt& operator=(const Crypt& c);
00275 };
00276 }
00277
00278 #endif // _CRYPT_H