00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "key.h"
00021
00022 #ifdef HAVE_STRING_H
00023 # include <string.h>
00024 #endif
00025
00026 using namespace YAPET;
00027
00032 void
00033 Key::cleanup() {
00034 memset(key, 0, KEYLENGTH);
00035 memset(IVec, 0, IVECLENGTH);
00036 }
00037
00045 Key::Key(const char* password) throw(YAPETException) {
00046
00047 uint8_t eff_keylength;
00048
00049
00050
00051
00052 const EVP_MD* md = EVP_sha1();
00053 if (md == NULL)
00054 throw YAPETException("Run 1: Unable to initialize the EVP_MD structure");
00055
00056 EVP_MD_CTX mdctx;
00057 EVP_MD_CTX_init(&mdctx);
00058
00059 int retval = EVP_DigestInit_ex(&mdctx, md, NULL);
00060 if (retval == 0) {
00061 EVP_MD_CTX_cleanup(&mdctx);
00062 throw YAPETException("Run 1: Unable to initialize the digest");
00063 }
00064
00065 retval = EVP_DigestUpdate(&mdctx, password, strlen(password));
00066 if (retval == 0) {
00067 EVP_MD_CTX_cleanup(&mdctx);
00068 throw YAPETException("Run 1: Unable to update the digest");
00069 }
00070
00071 unsigned int tmplen;
00072 retval = EVP_DigestFinal_ex(&mdctx, key, &tmplen);
00073 if (retval == 0) {
00074 EVP_MD_CTX_cleanup(&mdctx);
00075 cleanup();
00076 throw YAPETException("Run 1: Unable to finalize the digest");
00077 }
00078
00079 if (tmplen != SHA1_LEN) {
00080 EVP_MD_CTX_cleanup(&mdctx);
00081 cleanup();
00082 throw YAPETException("Run 1: Digest does not have expected length");
00083 }
00084
00085 eff_keylength = tmplen;
00086 EVP_MD_CTX_cleanup(&mdctx);
00087
00088
00089
00090
00091 md = EVP_md5();
00092 if (md == NULL) {
00093 cleanup();
00094 throw YAPETException("Run 2: Unable to initialize the EVP_MD structure");
00095 }
00096
00097 EVP_MD_CTX_init(&mdctx);
00098 retval = EVP_DigestInit_ex(&mdctx, md, NULL);
00099 if (retval == 0) {
00100 EVP_MD_CTX_cleanup(&mdctx);
00101 cleanup();
00102 throw YAPETException("Run 2: Unable to initialize the digest");
00103 }
00104
00105 retval = EVP_DigestUpdate(&mdctx, key, SHA1_LEN);
00106 if (retval == 0) {
00107 EVP_MD_CTX_cleanup(&mdctx);
00108 cleanup();
00109 throw YAPETException("Run 2: Unable to update the digest");
00110 }
00111
00112 retval = EVP_DigestFinal_ex(&mdctx, key + SHA1_LEN, &tmplen);
00113 if (retval == 0) {
00114 EVP_MD_CTX_cleanup(&mdctx);
00115 cleanup();
00116 throw YAPETException("Run 2: Unable to finalize the digest");
00117 }
00118
00119 if (tmplen != MD5_LEN) {
00120 EVP_MD_CTX_cleanup(&mdctx);
00121 cleanup();
00122 throw YAPETException("Run 2: Digest does not have expected length");
00123 }
00124
00125 eff_keylength += tmplen;
00126 EVP_MD_CTX_cleanup(&mdctx);
00127
00128
00129
00130
00131 md = EVP_ripemd160();
00132 if (md == NULL) {
00133 cleanup();
00134 throw YAPETException("Run 3: Unable to initialize the EVP_MD structure");
00135 }
00136
00137 EVP_MD_CTX_init(&mdctx);
00138 retval = EVP_DigestInit_ex(&mdctx, md, NULL);
00139 if (retval == 0) {
00140 EVP_MD_CTX_cleanup(&mdctx);
00141 cleanup();
00142 throw YAPETException("Run 3: Unable to initialize the digest");
00143 }
00144
00145 retval = EVP_DigestUpdate(&mdctx, key, SHA1_LEN + MD5_LEN);
00146 if (retval == 0) {
00147 EVP_MD_CTX_cleanup(&mdctx);
00148 cleanup();
00149 throw YAPETException("Run 3: Unable to update the digest");
00150 }
00151
00152 retval = EVP_DigestFinal_ex(&mdctx, key + SHA1_LEN + MD5_LEN, &tmplen);
00153 if (retval == 0) {
00154 EVP_MD_CTX_cleanup(&mdctx);
00155 cleanup();
00156 throw YAPETException("Run 3: Unable to finalize the digest");
00157 }
00158
00159 if (tmplen != RIPEMD160_LEN) {
00160 EVP_MD_CTX_cleanup(&mdctx);
00161 cleanup();
00162 throw YAPETException("Run 3: Digest does not have expected length");
00163 }
00164
00165 eff_keylength += tmplen;
00166 EVP_MD_CTX_cleanup(&mdctx);
00167
00168 if (eff_keylength != KEYLENGTH) {
00169 cleanup();
00170 char tmp[100];
00171 snprintf(tmp,
00172 100,
00173 "Effective key length of %d does not match expected key length %d",
00174 eff_keylength,
00175 KEYLENGTH);
00176 throw YAPETException(tmp);
00177 }
00178
00179
00180
00181
00182 uint8_t ivec_hash_buf[MD5_LEN];
00183 md = EVP_md5();
00184 if (md == NULL) {
00185 cleanup();
00186 throw YAPETException("IVec: Unable to initialize the EVP_MD structure");
00187 }
00188
00189 EVP_MD_CTX_init(&mdctx);
00190 retval = EVP_DigestInit_ex(&mdctx, md, NULL);
00191 if (retval == 0) {
00192 EVP_MD_CTX_cleanup(&mdctx);
00193 cleanup();
00194 throw YAPETException("IVec: Unable to initialize the digest");
00195 }
00196
00197 retval = EVP_DigestUpdate(&mdctx, key, SHA1_LEN + MD5_LEN + RIPEMD160_LEN);
00198 if (retval == 0) {
00199 EVP_MD_CTX_cleanup(&mdctx);
00200 cleanup();
00201 throw YAPETException("IVec: Unable to update the digest");
00202 }
00203
00204 retval = EVP_DigestFinal_ex(&mdctx, ivec_hash_buf, &tmplen);
00205 if (retval == 0) {
00206 EVP_MD_CTX_cleanup(&mdctx);
00207 cleanup();
00208 throw YAPETException("IVec: Unable to finalize the digest");
00209 }
00210
00211 if (tmplen != MD5_LEN) {
00212 EVP_MD_CTX_cleanup(&mdctx);
00213 cleanup();
00214 throw YAPETException("IVec: Digest does not have expected length");
00215 }
00216
00217 EVP_MD_CTX_cleanup(&mdctx);
00218
00219 memcpy(IVec, ivec_hash_buf, IVECLENGTH);
00220 memset(ivec_hash_buf, 0, MD5_LEN);
00221 }
00222
00223 Key::Key(const Key& k) {
00224 memcpy(key, k.key, KEYLENGTH);
00225 memcpy(IVec, k.IVec, IVECLENGTH);
00226 }
00227
00228 Key::~Key() {
00229 cleanup();
00230 }
00231
00232 const Key&
00233 Key::operator=(const Key& k) {
00234 if (this == &k) return *this;
00235
00236 cleanup();
00237
00238 memcpy(key, k.key, KEYLENGTH);
00239 memcpy(IVec, k.IVec, IVECLENGTH);
00240
00241 return *this;
00242 }
00243
00254 bool
00255 Key::operator==(const Key& k) const {
00256 if (k.size() != size()) return false;
00257 if (k.ivec_size() != ivec_size()) return false;
00258
00259 int retval = memcmp(k.key, key, size());
00260 if (retval != 0)
00261 return false;
00262
00263 retval = memcmp(k.IVec, IVec, ivec_size());
00264 if (retval != 0)
00265 return false;
00266
00267 return true;
00268 }