00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef _CRYPT_H
00034 #define _CRYPT_H
00035
00036 #ifdef HAVE_CONFIG_H
00037 # include <config.h>
00038 #endif
00039
00040 #ifdef HAVE_INTTYPES_H
00041 # include <inttypes.h>
00042 #endif
00043
00044 #include "../intl.h"
00045
00046
00047 #include <openssl/evp.h>
00048
00049 #include "yapetexception.h"
00050 #include "key.h"
00051 #include "bdbuffer.h"
00052 #include "record.h"
00053
00054 namespace YAPET {
00071 class Crypt {
00072 private:
00081 const EVP_CIPHER* cipher;
00088 uint32_t iv_length;
00095 uint32_t key_length;
00101 Key key;
00102
00103 public:
00105 Crypt(const Key& k) throw(YAPETException);
00106 Crypt(const Crypt& c);
00107 inline ~Crypt() {}
00108
00118 inline uint32_t getIVLength() const { return iv_length; }
00127 inline uint32_t getKeyLength() const { return key_length; }
00128
00152 template<class T>
00153 BDBuffer* encrypt(const Record<T>& data)
00154 throw(YAPETException, YAPETEncryptionException) {
00155 if (key.ivec_size() != iv_length)
00156 throw YAPETException(_("IVec length missmatch"));
00157
00158 EVP_CIPHER_CTX ctx;
00159 EVP_CIPHER_CTX_init(&ctx);
00160
00161 int retval = EVP_EncryptInit_ex(&ctx,
00162 cipher,
00163 NULL,
00164 key,
00165 key.getIVec());
00166 if (retval == 0) {
00167 EVP_CIPHER_CTX_cleanup(&ctx);
00168 throw YAPETEncryptionException(_("Error initializing encryption engine"));
00169 }
00170
00171 retval = EVP_CIPHER_CTX_set_key_length(&ctx, key.size());
00172 if (retval == 0) {
00173 EVP_CIPHER_CTX_cleanup(&ctx);
00174 throw YAPETException(_("Error setting the key length"));
00175 }
00176
00177 BDBuffer* encdata =
00178 new BDBuffer(data.size() + EVP_MAX_BLOCK_LENGTH);
00179 int outlen;
00180 retval = EVP_EncryptUpdate(&ctx,
00181 *encdata,
00182 &outlen,
00183 data,
00184 data.size());
00185 if (retval == 0) {
00186 EVP_CIPHER_CTX_cleanup(&ctx);
00187 delete encdata;
00188 throw YAPETEncryptionException(_("Error encrypting data"));
00189 }
00190
00191 int tmplen;
00192 retval = EVP_EncryptFinal_ex(&ctx,
00193 encdata->at(outlen),
00194 &tmplen);
00195 if (retval == 0) {
00196 EVP_CIPHER_CTX_cleanup(&ctx);
00197 delete encdata;
00198 throw YAPETEncryptionException(_("Error finalizing encryption"));
00199 }
00200
00201 encdata->resize(outlen+tmplen);
00202
00203 EVP_CIPHER_CTX_cleanup(&ctx);
00204
00205 return encdata;
00206 }
00207
00229 template<class T>
00230 Record<T>* decrypt(const BDBuffer& data)
00231 throw(YAPETException, YAPETEncryptionException) {
00232 if ( ((unsigned int)key.ivec_size()) != iv_length)
00233 throw YAPETException(_("IVec length missmatch"));
00234
00235 EVP_CIPHER_CTX ctx;
00236 EVP_CIPHER_CTX_init(&ctx);
00237
00238 int retval = EVP_DecryptInit_ex(&ctx,
00239 cipher,
00240 NULL,
00241 key,
00242 key.getIVec());
00243 if (retval == 0) {
00244 EVP_CIPHER_CTX_cleanup(&ctx);
00245 throw YAPETEncryptionException(_("Error initializing encryption engine"));
00246 }
00247
00248 retval = EVP_CIPHER_CTX_set_key_length(&ctx, key.size());
00249 if (retval == 0) {
00250 EVP_CIPHER_CTX_cleanup(&ctx);
00251 throw YAPETException(_("Error setting the key length"));
00252 }
00253
00254 BDBuffer* decdata = new BDBuffer(data.size());
00255 int outlen;
00256 retval = EVP_DecryptUpdate(&ctx,
00257 *decdata,
00258 &outlen,
00259 data,
00260 data.size());
00261 if (retval == 0) {
00262 EVP_CIPHER_CTX_cleanup(&ctx);
00263 delete decdata;
00264 throw YAPETEncryptionException(_("Error decrypting data"));
00265 }
00266
00267 int tmplen;
00268 retval = EVP_DecryptFinal_ex(&ctx,
00269 decdata->at(outlen),
00270 &tmplen);
00271 if (retval == 0) {
00272 EVP_CIPHER_CTX_cleanup(&ctx);
00273 delete decdata;
00274 throw YAPETEncryptionException(_("Error finalizing decryption"));
00275 }
00276
00277 decdata->resize(outlen+tmplen);
00278
00279 EVP_CIPHER_CTX_cleanup(&ctx);
00280
00281 Record<T>* r = new Record<T>;
00282 *r=*decdata;
00283
00284 delete decdata;
00285 return r;
00286 }
00287
00288 const Crypt& operator=(const Crypt& c);
00289 };
00290 }
00291
00292 #endif // _CRYPT_H