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 "../intl.h"
00034
00035
00036 #include <openssl/evp.h>
00037
00038 #include "yapetexception.h"
00039 #include "key.h"
00040 #include "bdbuffer.h"
00041 #include "record.h"
00042
00043 namespace YAPET {
00060 class Crypt {
00061 private:
00070 const EVP_CIPHER* cipher;
00077 uint32_t iv_length;
00084 uint32_t key_length;
00090 Key key;
00091
00092 public:
00094 Crypt(const Key& k) throw(YAPETException);
00095 Crypt(const Crypt& c);
00096 inline ~Crypt() {}
00097
00107 inline uint32_t getIVLength() const { return iv_length; }
00116 inline uint32_t getKeyLength() const { return key_length; }
00117
00141 template<class T>
00142 BDBuffer* encrypt(const Record<T>& data)
00143 throw(YAPETException, YAPETEncryptionException) {
00144 if (key.ivec_size() != iv_length)
00145 throw YAPETException(_("IVec length missmatch"));
00146
00147 EVP_CIPHER_CTX ctx;
00148 EVP_CIPHER_CTX_init(&ctx);
00149
00150 int retval = EVP_EncryptInit_ex(&ctx,
00151 cipher,
00152 NULL,
00153 key,
00154 key.getIVec());
00155 if (retval == 0) {
00156 EVP_CIPHER_CTX_cleanup(&ctx);
00157 throw YAPETEncryptionException(_("Error initializing encryption engine"));
00158 }
00159
00160 retval = EVP_CIPHER_CTX_set_key_length(&ctx, key.size());
00161 if (retval == 0) {
00162 EVP_CIPHER_CTX_cleanup(&ctx);
00163 throw YAPETException(_("Error setting the key length"));
00164 }
00165
00166 BDBuffer* encdata =
00167 new BDBuffer(data.size() + EVP_MAX_BLOCK_LENGTH);
00168 int outlen;
00169 retval = EVP_EncryptUpdate(&ctx,
00170 *encdata,
00171 &outlen,
00172 data,
00173 data.size());
00174 if (retval == 0) {
00175 EVP_CIPHER_CTX_cleanup(&ctx);
00176 delete encdata;
00177 throw YAPETEncryptionException(_("Error encrypting data"));
00178 }
00179
00180 int tmplen;
00181 retval = EVP_EncryptFinal_ex(&ctx,
00182 encdata->at(outlen),
00183 &tmplen);
00184 if (retval == 0) {
00185 EVP_CIPHER_CTX_cleanup(&ctx);
00186 delete encdata;
00187 throw YAPETEncryptionException(_("Error finalizing encryption"));
00188 }
00189
00190 encdata->resize(outlen+tmplen);
00191
00192 EVP_CIPHER_CTX_cleanup(&ctx);
00193
00194 return encdata;
00195 }
00196
00218 template<class T>
00219 Record<T>* decrypt(const BDBuffer& data)
00220 throw(YAPETException, YAPETEncryptionException) {
00221 if ( ((unsigned int)key.ivec_size()) != iv_length)
00222 throw YAPETException(_("IVec length missmatch"));
00223
00224 EVP_CIPHER_CTX ctx;
00225 EVP_CIPHER_CTX_init(&ctx);
00226
00227 int retval = EVP_DecryptInit_ex(&ctx,
00228 cipher,
00229 NULL,
00230 key,
00231 key.getIVec());
00232 if (retval == 0) {
00233 EVP_CIPHER_CTX_cleanup(&ctx);
00234 throw YAPETEncryptionException(_("Error initializing encryption engine"));
00235 }
00236
00237 retval = EVP_CIPHER_CTX_set_key_length(&ctx, key.size());
00238 if (retval == 0) {
00239 EVP_CIPHER_CTX_cleanup(&ctx);
00240 throw YAPETException(_("Error setting the key length"));
00241 }
00242
00243 BDBuffer* decdata = new BDBuffer(data.size());
00244 int outlen;
00245 retval = EVP_DecryptUpdate(&ctx,
00246 *decdata,
00247 &outlen,
00248 data,
00249 data.size());
00250 if (retval == 0) {
00251 EVP_CIPHER_CTX_cleanup(&ctx);
00252 delete decdata;
00253 throw YAPETEncryptionException(_("Error decrypting data"));
00254 }
00255
00256 int tmplen;
00257 retval = EVP_DecryptFinal_ex(&ctx,
00258 decdata->at(outlen),
00259 &tmplen);
00260 if (retval == 0) {
00261 EVP_CIPHER_CTX_cleanup(&ctx);
00262 delete decdata;
00263 throw YAPETEncryptionException(_("Error finalizing decryption"));
00264 }
00265
00266 decdata->resize(outlen+tmplen);
00267
00268 EVP_CIPHER_CTX_cleanup(&ctx);
00269
00270 Record<T>* r = new Record<T>;
00271 *r=*decdata;
00272
00273 delete decdata;
00274 return r;
00275 }
00276
00277 const Crypt& operator=(const Crypt& c);
00278 };
00279 }
00280
00281 #endif // _CRYPT_H