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