OLD | NEW |
1 /* evp_pbe.c */ | 1 /* evp_pbe.c */ |
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
3 * project 1999. | 3 * project 1999. |
4 */ | 4 */ |
5 /* ==================================================================== | 5 /* ==================================================================== |
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | 6 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. |
7 * | 7 * |
8 * Redistribution and use in source and binary forms, with or without | 8 * Redistribution and use in source and binary forms, with or without |
9 * modification, are permitted provided that the following conditions | 9 * modification, are permitted provided that the following conditions |
10 * are met: | 10 * are met: |
11 * | 11 * |
12 * 1. Redistributions of source code must retain the above copyright | 12 * 1. Redistributions of source code must retain the above copyright |
13 * notice, this list of conditions and the following disclaimer. | 13 * notice, this list of conditions and the following disclaimer. |
14 * | 14 * |
15 * 2. Redistributions in binary form must reproduce the above copyright | 15 * 2. Redistributions in binary form must reproduce the above copyright |
16 * notice, this list of conditions and the following disclaimer in | 16 * notice, this list of conditions and the following disclaimer in |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 * | 52 * |
53 * This product includes cryptographic software written by Eric Young | 53 * This product includes cryptographic software written by Eric Young |
54 * (eay@cryptsoft.com). This product includes software written by Tim | 54 * (eay@cryptsoft.com). This product includes software written by Tim |
55 * Hudson (tjh@cryptsoft.com). | 55 * Hudson (tjh@cryptsoft.com). |
56 * | 56 * |
57 */ | 57 */ |
58 | 58 |
59 #include <stdio.h> | 59 #include <stdio.h> |
60 #include "cryptlib.h" | 60 #include "cryptlib.h" |
61 #include <openssl/evp.h> | 61 #include <openssl/evp.h> |
| 62 #include <openssl/pkcs12.h> |
62 #include <openssl/x509.h> | 63 #include <openssl/x509.h> |
63 | 64 |
64 /* Password based encryption (PBE) functions */ | 65 /* Password based encryption (PBE) functions */ |
65 | 66 |
66 static STACK *pbe_algs; | 67 DECLARE_STACK_OF(EVP_PBE_CTL) |
| 68 static STACK_OF(EVP_PBE_CTL) *pbe_algs; |
67 | 69 |
68 /* Setup a cipher context from a PBE algorithm */ | 70 /* Setup a cipher context from a PBE algorithm */ |
69 | 71 |
70 typedef struct { | 72 typedef struct |
71 int pbe_nid; | 73 » { |
72 const EVP_CIPHER *cipher; | 74 » int pbe_type; |
73 const EVP_MD *md; | 75 » int pbe_nid; |
74 EVP_PBE_KEYGEN *keygen; | 76 » int cipher_nid; |
75 } EVP_PBE_CTL; | 77 » int md_nid; |
| 78 » EVP_PBE_KEYGEN *keygen; |
| 79 » } EVP_PBE_CTL; |
| 80 |
| 81 static const EVP_PBE_CTL builtin_pbe[] = |
| 82 » { |
| 83 » {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC, |
| 84 » » » NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen}, |
| 85 » {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC, |
| 86 » » » NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen}, |
| 87 » {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC, |
| 88 » » » NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen}, |
| 89 |
| 90 » {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4, |
| 91 » » » NID_rc4, NID_sha1, PKCS12_PBE_keyivgen}, |
| 92 » {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4, |
| 93 » » » NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen}, |
| 94 » {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC, |
| 95 » » » NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen}, |
| 96 » {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC, |
| 97 » » » NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen}, |
| 98 » {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC, |
| 99 » » » NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen}, |
| 100 » {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC, |
| 101 » » » NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen}, |
| 102 |
| 103 #ifndef OPENSSL_NO_HMAC |
| 104 » {EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen}, |
| 105 #endif |
| 106 » {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC, |
| 107 » » » NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen}, |
| 108 » {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC, |
| 109 » » » NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen}, |
| 110 » {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC, |
| 111 » » » NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen}, |
| 112 |
| 113 |
| 114 » {EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0}, |
| 115 » {EVP_PBE_TYPE_PRF, NID_hmacWithMD5, -1, NID_md5, 0}, |
| 116 » {EVP_PBE_TYPE_PRF, NID_hmacWithSHA224, -1, NID_sha224, 0}, |
| 117 » {EVP_PBE_TYPE_PRF, NID_hmacWithSHA256, -1, NID_sha256, 0}, |
| 118 » {EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0}, |
| 119 » {EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0}, |
| 120 » {EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0}, |
| 121 » }; |
| 122 |
| 123 #ifdef TEST |
| 124 int main(int argc, char **argv) |
| 125 » { |
| 126 » int i, nid_md, nid_cipher; |
| 127 » EVP_PBE_CTL *tpbe, *tpbe2; |
| 128 » /*OpenSSL_add_all_algorithms();*/ |
| 129 |
| 130 » for (i = 0; i < sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL); i++) |
| 131 » » { |
| 132 » » tpbe = builtin_pbe + i; |
| 133 » » fprintf(stderr, "%d %d %s ", tpbe->pbe_type, tpbe->pbe_nid, |
| 134 » » » » » » OBJ_nid2sn(tpbe->pbe_nid)); |
| 135 » » if (EVP_PBE_find(tpbe->pbe_type, tpbe->pbe_nid, |
| 136 » » » » » &nid_cipher ,&nid_md,0)) |
| 137 » » » fprintf(stderr, "Found %s %s\n", |
| 138 » » » » » OBJ_nid2sn(nid_cipher), |
| 139 » » » » » OBJ_nid2sn(nid_md)); |
| 140 » » else |
| 141 » » » fprintf(stderr, "Find ERROR!!\n"); |
| 142 » » } |
| 143 |
| 144 » return 0; |
| 145 » } |
| 146 #endif |
| 147 » » |
| 148 |
76 | 149 |
77 int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, | 150 int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, |
78 » ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de) | 151 » » ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de) |
79 { | 152 » { |
80 | 153 » const EVP_CIPHER *cipher; |
81 » EVP_PBE_CTL *pbetmp, pbelu; | 154 » const EVP_MD *md; |
82 » int i; | 155 » int cipher_nid, md_nid; |
83 » pbelu.pbe_nid = OBJ_obj2nid(pbe_obj); | 156 » EVP_PBE_KEYGEN *keygen; |
84 » if (pbelu.pbe_nid != NID_undef) i = sk_find(pbe_algs, (char *)&pbelu); | 157 |
85 » else i = -1; | 158 » if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj), |
86 | 159 » » » » » &cipher_nid, &md_nid, &keygen)) |
87 » if (i == -1) { | 160 » » { |
88 char obj_tmp[80]; | 161 char obj_tmp[80]; |
89 EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_PBE_ALGORITHM); | 162 EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_PBE_ALGORITHM); |
90 if (!pbe_obj) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp); | 163 if (!pbe_obj) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp); |
91 else i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj); | 164 else i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj); |
92 ERR_add_error_data(2, "TYPE=", obj_tmp); | 165 ERR_add_error_data(2, "TYPE=", obj_tmp); |
93 return 0; | 166 return 0; |
94 » } | 167 » » } |
95 » if(!pass) passlen = 0; | 168 |
96 » else if (passlen == -1) passlen = strlen(pass); | 169 » if(!pass) |
97 » pbetmp = (EVP_PBE_CTL *)sk_value (pbe_algs, i); | 170 » » passlen = 0; |
98 » i = (*pbetmp->keygen)(ctx, pass, passlen, param, pbetmp->cipher, | 171 » else if (passlen == -1) |
99 » » » » » » pbetmp->md, en_de); | 172 » » passlen = strlen(pass); |
100 » if (!i) { | 173 |
| 174 » if (cipher_nid == -1) |
| 175 » » cipher = NULL; |
| 176 » else |
| 177 » » { |
| 178 » » cipher = EVP_get_cipherbynid(cipher_nid); |
| 179 » » if (!cipher) |
| 180 » » » { |
| 181 » » » EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_CIPHER); |
| 182 » » » return 0; |
| 183 » » » } |
| 184 » » } |
| 185 |
| 186 » if (md_nid == -1) |
| 187 » » md = NULL; |
| 188 » else |
| 189 » » { |
| 190 » » md = EVP_get_digestbynid(md_nid); |
| 191 » » if (!md) |
| 192 » » » { |
| 193 » » » EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_DIGEST); |
| 194 » » » return 0; |
| 195 » » » } |
| 196 » » } |
| 197 |
| 198 » if (!keygen(ctx, pass, passlen, param, cipher, md, en_de)) |
| 199 » » { |
101 EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_KEYGEN_FAILURE); | 200 EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_KEYGEN_FAILURE); |
102 return 0; | 201 return 0; |
103 » } | 202 » » } |
104 return 1; | 203 return 1; |
105 } | 204 } |
106 | 205 |
107 static int pbe_cmp(const char * const *a, const char * const *b) | 206 DECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2); |
108 { | 207 |
109 » const EVP_PBE_CTL * const *pbe1 = (const EVP_PBE_CTL * const *) a, | 208 static int pbe2_cmp(const EVP_PBE_CTL *pbe1, const EVP_PBE_CTL *pbe2) |
110 » » » * const *pbe2 = (const EVP_PBE_CTL * const *)b; | 209 » { |
111 » return ((*pbe1)->pbe_nid - (*pbe2)->pbe_nid); | 210 » int ret = pbe1->pbe_type - pbe2->pbe_type; |
112 } | 211 » if (ret) |
| 212 » » return ret; |
| 213 » else |
| 214 » » return pbe1->pbe_nid - pbe2->pbe_nid; |
| 215 » } |
| 216 |
| 217 IMPLEMENT_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2); |
| 218 |
| 219 static int pbe_cmp(const EVP_PBE_CTL * const *a, const EVP_PBE_CTL * const *b) |
| 220 » { |
| 221 » int ret = (*a)->pbe_type - (*b)->pbe_type; |
| 222 » if (ret) |
| 223 » » return ret; |
| 224 » else |
| 225 » » return (*a)->pbe_nid - (*b)->pbe_nid; |
| 226 » } |
113 | 227 |
114 /* Add a PBE algorithm */ | 228 /* Add a PBE algorithm */ |
115 | 229 |
| 230 int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid, |
| 231 EVP_PBE_KEYGEN *keygen) |
| 232 { |
| 233 EVP_PBE_CTL *pbe_tmp; |
| 234 if (!pbe_algs) |
| 235 pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp); |
| 236 if (!(pbe_tmp = (EVP_PBE_CTL*) OPENSSL_malloc (sizeof(EVP_PBE_CTL)))) |
| 237 { |
| 238 EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE,ERR_R_MALLOC_FAILURE); |
| 239 return 0; |
| 240 } |
| 241 pbe_tmp->pbe_type = pbe_type; |
| 242 pbe_tmp->pbe_nid = pbe_nid; |
| 243 pbe_tmp->cipher_nid = cipher_nid; |
| 244 pbe_tmp->md_nid = md_nid; |
| 245 pbe_tmp->keygen = keygen; |
| 246 |
| 247 |
| 248 sk_EVP_PBE_CTL_push (pbe_algs, pbe_tmp); |
| 249 return 1; |
| 250 } |
| 251 |
116 int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, | 252 int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, |
117 » EVP_PBE_KEYGEN *keygen) | 253 » » EVP_PBE_KEYGEN *keygen) |
118 { | 254 » { |
119 » EVP_PBE_CTL *pbe_tmp; | 255 » int cipher_nid, md_nid; |
120 » if (!pbe_algs) pbe_algs = sk_new(pbe_cmp); | 256 » if (cipher) |
121 » if (!(pbe_tmp = (EVP_PBE_CTL*) OPENSSL_malloc (sizeof(EVP_PBE_CTL)))) { | 257 » » cipher_nid = EVP_CIPHER_type(cipher); |
122 » » EVPerr(EVP_F_EVP_PBE_ALG_ADD,ERR_R_MALLOC_FAILURE); | 258 » else |
123 » » return 0; | 259 » » cipher_nid = -1; |
124 » } | 260 » if (md) |
125 » pbe_tmp->pbe_nid = nid; | 261 » » md_nid = EVP_MD_type(md); |
126 » pbe_tmp->cipher = cipher; | 262 » else |
127 » pbe_tmp->md = md; | 263 » » md_nid = -1; |
128 » pbe_tmp->keygen = keygen; | 264 |
129 » sk_push (pbe_algs, (char *)pbe_tmp); | 265 » return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid, |
| 266 » » » » » cipher_nid, md_nid, keygen); |
| 267 » } |
| 268 |
| 269 int EVP_PBE_find(int type, int pbe_nid, |
| 270 » » int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen) |
| 271 » { |
| 272 » EVP_PBE_CTL *pbetmp = NULL, pbelu; |
| 273 » int i; |
| 274 » if (pbe_nid == NID_undef) |
| 275 » » return 0; |
| 276 |
| 277 » pbelu.pbe_type = type; |
| 278 » pbelu.pbe_nid = pbe_nid; |
| 279 |
| 280 » if (pbe_algs) |
| 281 » » { |
| 282 » » i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu); |
| 283 » » if (i != -1) |
| 284 » » » pbetmp = sk_EVP_PBE_CTL_value (pbe_algs, i); |
| 285 » » } |
| 286 » if (pbetmp == NULL) |
| 287 » » { |
| 288 » » pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe, |
| 289 » » » » sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL)); |
| 290 » » } |
| 291 » if (pbetmp == NULL) |
| 292 » » return 0; |
| 293 » if (pcnid) |
| 294 » » *pcnid = pbetmp->cipher_nid; |
| 295 » if (pmnid) |
| 296 » » *pmnid = pbetmp->md_nid; |
| 297 » if (pkeygen) |
| 298 » » *pkeygen = pbetmp->keygen; |
130 return 1; | 299 return 1; |
131 } | 300 » } |
| 301 |
| 302 static void free_evp_pbe_ctl(EVP_PBE_CTL *pbe) |
| 303 » { |
| 304 » OPENSSL_freeFunc(pbe); |
| 305 » } |
132 | 306 |
133 void EVP_PBE_cleanup(void) | 307 void EVP_PBE_cleanup(void) |
134 { | 308 » { |
135 » sk_pop_free(pbe_algs, OPENSSL_freeFunc); | 309 » sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl); |
136 pbe_algs = NULL; | 310 pbe_algs = NULL; |
137 } | 311 » } |
OLD | NEW |