diff options
Diffstat (limited to 'src/lib/libcrypto/cms/cms_pwri.c')
| -rw-r--r-- | src/lib/libcrypto/cms/cms_pwri.c | 231 |
1 files changed, 104 insertions, 127 deletions
diff --git a/src/lib/libcrypto/cms/cms_pwri.c b/src/lib/libcrypto/cms/cms_pwri.c index 36d50f1797..1399cbd606 100644 --- a/src/lib/libcrypto/cms/cms_pwri.c +++ b/src/lib/libcrypto/cms/cms_pwri.c | |||
| @@ -10,7 +10,7 @@ | |||
| 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 |
| @@ -62,15 +62,16 @@ | |||
| 62 | #include "cms_lcl.h" | 62 | #include "cms_lcl.h" |
| 63 | #include "asn1_locl.h" | 63 | #include "asn1_locl.h" |
| 64 | 64 | ||
| 65 | int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, | 65 | int |
| 66 | unsigned char *pass, ssize_t passlen) | 66 | CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, unsigned char *pass, |
| 67 | { | 67 | ssize_t passlen) |
| 68 | { | ||
| 68 | CMS_PasswordRecipientInfo *pwri; | 69 | CMS_PasswordRecipientInfo *pwri; |
| 69 | if (ri->type != CMS_RECIPINFO_PASS) | 70 | |
| 70 | { | 71 | if (ri->type != CMS_RECIPINFO_PASS) { |
| 71 | CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, CMS_R_NOT_PWRI); | 72 | CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, CMS_R_NOT_PWRI); |
| 72 | return 0; | 73 | return 0; |
| 73 | } | 74 | } |
| 74 | 75 | ||
| 75 | pwri = ri->d.pwri; | 76 | pwri = ri->d.pwri; |
| 76 | pwri->pass = pass; | 77 | pwri->pass = pass; |
| @@ -78,14 +79,13 @@ int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, | |||
| 78 | passlen = strlen((char *)pass); | 79 | passlen = strlen((char *)pass); |
| 79 | pwri->passlen = passlen; | 80 | pwri->passlen = passlen; |
| 80 | return 1; | 81 | return 1; |
| 81 | } | 82 | } |
| 82 | 83 | ||
| 83 | CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, | 84 | CMS_RecipientInfo * |
| 84 | int iter, int wrap_nid, int pbe_nid, | 85 | CMS_add0_recipient_password(CMS_ContentInfo *cms, int iter, int wrap_nid, |
| 85 | unsigned char *pass, | 86 | int pbe_nid, unsigned char *pass, ssize_t passlen, |
| 86 | ssize_t passlen, | 87 | const EVP_CIPHER *kekciph) |
| 87 | const EVP_CIPHER *kekciph) | 88 | { |
| 88 | { | ||
| 89 | CMS_RecipientInfo *ri = NULL; | 89 | CMS_RecipientInfo *ri = NULL; |
| 90 | CMS_EnvelopedData *env; | 90 | CMS_EnvelopedData *env; |
| 91 | CMS_PasswordRecipientInfo *pwri; | 91 | CMS_PasswordRecipientInfo *pwri; |
| @@ -93,6 +93,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, | |||
| 93 | X509_ALGOR *encalg = NULL; | 93 | X509_ALGOR *encalg = NULL; |
| 94 | unsigned char iv[EVP_MAX_IV_LENGTH]; | 94 | unsigned char iv[EVP_MAX_IV_LENGTH]; |
| 95 | int ivlen; | 95 | int ivlen; |
| 96 | |||
| 96 | env = cms_get0_enveloped(cms); | 97 | env = cms_get0_enveloped(cms); |
| 97 | if (!env) | 98 | if (!env) |
| 98 | goto err; | 99 | goto err; |
| @@ -107,54 +108,47 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, | |||
| 107 | if (kekciph == NULL) | 108 | if (kekciph == NULL) |
| 108 | kekciph = env->encryptedContentInfo->cipher; | 109 | kekciph = env->encryptedContentInfo->cipher; |
| 109 | 110 | ||
| 110 | if (kekciph == NULL) | 111 | if (kekciph == NULL) { |
| 111 | { | ||
| 112 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER); | 112 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER); |
| 113 | return NULL; | 113 | return NULL; |
| 114 | } | 114 | } |
| 115 | if (wrap_nid != NID_id_alg_PWRI_KEK) | 115 | if (wrap_nid != NID_id_alg_PWRI_KEK) { |
| 116 | { | ||
| 117 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, | 116 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, |
| 118 | CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); | 117 | CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); |
| 119 | return NULL; | 118 | return NULL; |
| 120 | } | 119 | } |
| 121 | 120 | ||
| 122 | /* Setup algorithm identifier for cipher */ | 121 | /* Setup algorithm identifier for cipher */ |
| 123 | encalg = X509_ALGOR_new(); | 122 | encalg = X509_ALGOR_new(); |
| 124 | EVP_CIPHER_CTX_init(&ctx); | 123 | EVP_CIPHER_CTX_init(&ctx); |
| 125 | 124 | ||
| 126 | if (EVP_EncryptInit_ex(&ctx, kekciph, NULL, NULL, NULL) <= 0) | 125 | if (EVP_EncryptInit_ex(&ctx, kekciph, NULL, NULL, NULL) <= 0) { |
| 127 | { | ||
| 128 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB); | 126 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB); |
| 129 | goto err; | 127 | goto err; |
| 130 | } | 128 | } |
| 131 | 129 | ||
| 132 | ivlen = EVP_CIPHER_CTX_iv_length(&ctx); | 130 | ivlen = EVP_CIPHER_CTX_iv_length(&ctx); |
| 133 | 131 | ||
| 134 | if (ivlen > 0) | 132 | if (ivlen > 0) { |
| 135 | { | ||
| 136 | if (RAND_pseudo_bytes(iv, ivlen) <= 0) | 133 | if (RAND_pseudo_bytes(iv, ivlen) <= 0) |
| 137 | goto err; | 134 | goto err; |
| 138 | if (EVP_EncryptInit_ex(&ctx, NULL, NULL, NULL, iv) <= 0) | 135 | if (EVP_EncryptInit_ex(&ctx, NULL, NULL, NULL, iv) <= 0) { |
| 139 | { | ||
| 140 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, | 136 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, |
| 141 | ERR_R_EVP_LIB); | 137 | ERR_R_EVP_LIB); |
| 142 | goto err; | 138 | goto err; |
| 143 | } | 139 | } |
| 144 | encalg->parameter = ASN1_TYPE_new(); | 140 | encalg->parameter = ASN1_TYPE_new(); |
| 145 | if (!encalg->parameter) | 141 | if (!encalg->parameter) { |
| 146 | { | ||
| 147 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, | 142 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, |
| 148 | ERR_R_MALLOC_FAILURE); | 143 | ERR_R_MALLOC_FAILURE); |
| 149 | goto err; | 144 | goto err; |
| 150 | } | 145 | } |
| 151 | if (EVP_CIPHER_param_to_asn1(&ctx, encalg->parameter) <= 0) | 146 | if (EVP_CIPHER_param_to_asn1(&ctx, encalg->parameter) <= 0) { |
| 152 | { | ||
| 153 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, | 147 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, |
| 154 | CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); | 148 | CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); |
| 155 | goto err; | 149 | goto err; |
| 156 | } | ||
| 157 | } | 150 | } |
| 151 | } | ||
| 158 | 152 | ||
| 159 | 153 | ||
| 160 | encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(&ctx)); | 154 | encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(&ctx)); |
| @@ -182,10 +176,10 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, | |||
| 182 | if (!pwri->keyEncryptionAlgorithm->parameter) | 176 | if (!pwri->keyEncryptionAlgorithm->parameter) |
| 183 | goto merr; | 177 | goto merr; |
| 184 | 178 | ||
| 185 | if(!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR), | 179 | if (!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR), |
| 186 | &pwri->keyEncryptionAlgorithm->parameter->value.sequence)) | 180 | &pwri->keyEncryptionAlgorithm->parameter->value.sequence)) |
| 187 | goto merr; | 181 | goto merr; |
| 188 | pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE; | 182 | pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE; |
| 189 | 183 | ||
| 190 | X509_ALGOR_free(encalg); | 184 | X509_ALGOR_free(encalg); |
| 191 | encalg = NULL; | 185 | encalg = NULL; |
| @@ -205,48 +199,47 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, | |||
| 205 | 199 | ||
| 206 | return ri; | 200 | return ri; |
| 207 | 201 | ||
| 208 | merr: | 202 | merr: |
| 209 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE); | 203 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE); |
| 210 | err: | 204 | err: |
| 211 | EVP_CIPHER_CTX_cleanup(&ctx); | 205 | EVP_CIPHER_CTX_cleanup(&ctx); |
| 212 | if (ri) | 206 | if (ri) |
| 213 | M_ASN1_free_of(ri, CMS_RecipientInfo); | 207 | M_ASN1_free_of(ri, CMS_RecipientInfo); |
| 214 | if (encalg) | 208 | if (encalg) |
| 215 | X509_ALGOR_free(encalg); | 209 | X509_ALGOR_free(encalg); |
| 216 | return NULL; | 210 | return NULL; |
| 217 | 211 | } | |
| 218 | } | ||
| 219 | 212 | ||
| 220 | /* This is an implementation of the key wrapping mechanism in RFC3211, | 213 | /* This is an implementation of the key wrapping mechanism in RFC3211, |
| 221 | * at some point this should go into EVP. | 214 | * at some point this should go into EVP. |
| 222 | */ | 215 | */ |
| 223 | 216 | ||
| 224 | static int kek_unwrap_key(unsigned char *out, size_t *outlen, | 217 | static int |
| 225 | const unsigned char *in, size_t inlen, EVP_CIPHER_CTX *ctx) | 218 | kek_unwrap_key(unsigned char *out, size_t *outlen, const unsigned char *in, |
| 226 | { | 219 | size_t inlen, EVP_CIPHER_CTX *ctx) |
| 220 | { | ||
| 227 | size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); | 221 | size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); |
| 228 | unsigned char *tmp; | 222 | unsigned char *tmp; |
| 229 | int outl, rv = 0; | 223 | int outl, rv = 0; |
| 230 | if (inlen < 2 * blocklen) | 224 | |
| 231 | { | 225 | if (inlen < 2 * blocklen) { |
| 232 | /* too small */ | 226 | /* too small */ |
| 233 | return 0; | 227 | return 0; |
| 234 | } | 228 | } |
| 235 | if (inlen % blocklen) | 229 | if (inlen % blocklen) { |
| 236 | { | ||
| 237 | /* Invalid size */ | 230 | /* Invalid size */ |
| 238 | return 0; | 231 | return 0; |
| 239 | } | 232 | } |
| 240 | tmp = malloc(inlen); | 233 | tmp = malloc(inlen); |
| 241 | /* setup IV by decrypting last two blocks */ | 234 | /* setup IV by decrypting last two blocks */ |
| 242 | EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl, | 235 | EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl, |
| 243 | in + inlen - 2 * blocklen, blocklen * 2); | 236 | in + inlen - 2 * blocklen, blocklen * 2); |
| 244 | /* Do a decrypt of last decrypted block to set IV to correct value | 237 | /* Do a decrypt of last decrypted block to set IV to correct value |
| 245 | * output it to start of buffer so we don't corrupt decrypted block | 238 | * output it to start of buffer so we don't corrupt decrypted block |
| 246 | * this works because buffer is at least two block lengths long. | 239 | * this works because buffer is at least two block lengths long. |
| 247 | */ | 240 | */ |
| 248 | EVP_DecryptUpdate(ctx, tmp, &outl, | 241 | EVP_DecryptUpdate(ctx, tmp, &outl, |
| 249 | tmp + inlen - blocklen, blocklen); | 242 | tmp + inlen - blocklen, blocklen); |
| 250 | /* Can now decrypt first n - 1 blocks */ | 243 | /* Can now decrypt first n - 1 blocks */ |
| 251 | EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen); | 244 | EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen); |
| 252 | 245 | ||
| @@ -255,49 +248,47 @@ static int kek_unwrap_key(unsigned char *out, size_t *outlen, | |||
| 255 | /* Decrypt again */ | 248 | /* Decrypt again */ |
| 256 | EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen); | 249 | EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen); |
| 257 | /* Check check bytes */ | 250 | /* Check check bytes */ |
| 258 | if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & (tmp[3] ^ tmp[6])) != 0xff) | 251 | if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & |
| 259 | { | 252 | (tmp[3] ^ tmp[6])) != 0xff) { |
| 260 | /* Check byte failure */ | 253 | /* Check byte failure */ |
| 261 | goto err; | 254 | goto err; |
| 262 | } | 255 | } |
| 263 | if (inlen < (size_t)(tmp[0] - 4 )) | 256 | if (inlen < (size_t)(tmp[0] - 4 )) { |
| 264 | { | ||
| 265 | /* Invalid length value */ | 257 | /* Invalid length value */ |
| 266 | goto err; | 258 | goto err; |
| 267 | } | 259 | } |
| 268 | *outlen = (size_t)tmp[0]; | 260 | *outlen = (size_t)tmp[0]; |
| 269 | memcpy(out, tmp + 4, *outlen); | 261 | memcpy(out, tmp + 4, *outlen); |
| 270 | rv = 1; | 262 | rv = 1; |
| 271 | err: | 263 | |
| 264 | err: | ||
| 272 | OPENSSL_cleanse(tmp, inlen); | 265 | OPENSSL_cleanse(tmp, inlen); |
| 273 | free(tmp); | 266 | free(tmp); |
| 274 | return rv; | 267 | return rv; |
| 268 | } | ||
| 275 | 269 | ||
| 276 | } | 270 | static int |
| 277 | 271 | kek_wrap_key(unsigned char *out, size_t *outlen, const unsigned char *in, | |
| 278 | static int kek_wrap_key(unsigned char *out, size_t *outlen, | 272 | size_t inlen, EVP_CIPHER_CTX *ctx) |
| 279 | const unsigned char *in, size_t inlen, EVP_CIPHER_CTX *ctx) | 273 | { |
| 280 | { | ||
| 281 | size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); | 274 | size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); |
| 282 | size_t olen; | 275 | size_t olen; |
| 283 | int dummy; | 276 | int dummy; |
| 277 | |||
| 284 | /* First decide length of output buffer: need header and round up to | 278 | /* First decide length of output buffer: need header and round up to |
| 285 | * multiple of block length. | 279 | * multiple of block length. |
| 286 | */ | 280 | */ |
| 287 | olen = (inlen + 4 + blocklen - 1)/blocklen; | 281 | olen = (inlen + 4 + blocklen - 1)/blocklen; |
| 288 | olen *= blocklen; | 282 | olen *= blocklen; |
| 289 | if (olen < 2 * blocklen) | 283 | if (olen < 2 * blocklen) { |
| 290 | { | ||
| 291 | /* Key too small */ | 284 | /* Key too small */ |
| 292 | return 0; | 285 | return 0; |
| 293 | } | 286 | } |
| 294 | if (inlen > 0xFF) | 287 | if (inlen > 0xFF) { |
| 295 | { | ||
| 296 | /* Key too large */ | 288 | /* Key too large */ |
| 297 | return 0; | 289 | return 0; |
| 298 | } | 290 | } |
| 299 | if (out) | 291 | if (out) { |
| 300 | { | ||
| 301 | /* Set header */ | 292 | /* Set header */ |
| 302 | out[0] = (unsigned char)inlen; | 293 | out[0] = (unsigned char)inlen; |
| 303 | out[1] = in[0] ^ 0xFF; | 294 | out[1] = in[0] ^ 0xFF; |
| @@ -310,18 +301,19 @@ static int kek_wrap_key(unsigned char *out, size_t *outlen, | |||
| 310 | /* Encrypt twice */ | 301 | /* Encrypt twice */ |
| 311 | EVP_EncryptUpdate(ctx, out, &dummy, out, olen); | 302 | EVP_EncryptUpdate(ctx, out, &dummy, out, olen); |
| 312 | EVP_EncryptUpdate(ctx, out, &dummy, out, olen); | 303 | EVP_EncryptUpdate(ctx, out, &dummy, out, olen); |
| 313 | } | 304 | } |
| 314 | 305 | ||
| 315 | *outlen = olen; | 306 | *outlen = olen; |
| 316 | 307 | ||
| 317 | return 1; | 308 | return 1; |
| 318 | } | 309 | } |
| 319 | 310 | ||
| 320 | /* Encrypt/Decrypt content key in PWRI recipient info */ | 311 | /* Encrypt/Decrypt content key in PWRI recipient info */ |
| 321 | 312 | ||
| 322 | int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, | 313 | int |
| 323 | int en_de) | 314 | cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, |
| 324 | { | 315 | int en_de) |
| 316 | { | ||
| 325 | CMS_EncryptedContentInfo *ec; | 317 | CMS_EncryptedContentInfo *ec; |
| 326 | CMS_PasswordRecipientInfo *pwri; | 318 | CMS_PasswordRecipientInfo *pwri; |
| 327 | const unsigned char *p = NULL; | 319 | const unsigned char *p = NULL; |
| @@ -338,69 +330,61 @@ int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, | |||
| 338 | pwri = ri->d.pwri; | 330 | pwri = ri->d.pwri; |
| 339 | EVP_CIPHER_CTX_init(&kekctx); | 331 | EVP_CIPHER_CTX_init(&kekctx); |
| 340 | 332 | ||
| 341 | if (!pwri->pass) | 333 | if (!pwri->pass) { |
| 342 | { | ||
| 343 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD); | 334 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD); |
| 344 | return 0; | 335 | return 0; |
| 345 | } | 336 | } |
| 346 | algtmp = pwri->keyEncryptionAlgorithm; | 337 | algtmp = pwri->keyEncryptionAlgorithm; |
| 347 | 338 | ||
| 348 | if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) | 339 | if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) { |
| 349 | { | ||
| 350 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, | 340 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, |
| 351 | CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); | 341 | CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); |
| 352 | return 0; | 342 | return 0; |
| 353 | } | 343 | } |
| 354 | 344 | ||
| 355 | if (algtmp->parameter->type == V_ASN1_SEQUENCE) | 345 | if (algtmp->parameter->type == V_ASN1_SEQUENCE) { |
| 356 | { | ||
| 357 | p = algtmp->parameter->value.sequence->data; | 346 | p = algtmp->parameter->value.sequence->data; |
| 358 | plen = algtmp->parameter->value.sequence->length; | 347 | plen = algtmp->parameter->value.sequence->length; |
| 359 | kekalg = d2i_X509_ALGOR(NULL, &p, plen); | 348 | kekalg = d2i_X509_ALGOR(NULL, &p, plen); |
| 360 | } | 349 | } |
| 361 | if (kekalg == NULL) | 350 | if (kekalg == NULL) { |
| 362 | { | ||
| 363 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, | 351 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, |
| 364 | CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER); | 352 | CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER); |
| 365 | return 0; | 353 | return 0; |
| 366 | } | 354 | } |
| 367 | 355 | ||
| 368 | kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); | 356 | kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); |
| 369 | 357 | ||
| 370 | if(!kekcipher) | 358 | if (!kekcipher) { |
| 371 | { | ||
| 372 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, | 359 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, |
| 373 | CMS_R_UNKNOWN_CIPHER); | 360 | CMS_R_UNKNOWN_CIPHER); |
| 374 | goto err; | 361 | goto err; |
| 375 | } | 362 | } |
| 376 | 363 | ||
| 377 | /* Fixup cipher based on AlgorithmIdentifier to set IV etc */ | 364 | /* Fixup cipher based on AlgorithmIdentifier to set IV etc */ |
| 378 | if (!EVP_CipherInit_ex(&kekctx, kekcipher, NULL, NULL, NULL, en_de)) | 365 | if (!EVP_CipherInit_ex(&kekctx, kekcipher, NULL, NULL, NULL, en_de)) |
| 379 | goto err; | 366 | goto err; |
| 380 | EVP_CIPHER_CTX_set_padding(&kekctx, 0); | 367 | EVP_CIPHER_CTX_set_padding(&kekctx, 0); |
| 381 | if(EVP_CIPHER_asn1_to_param(&kekctx, kekalg->parameter) < 0) | 368 | if (EVP_CIPHER_asn1_to_param(&kekctx, kekalg->parameter) < 0) { |
| 382 | { | ||
| 383 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, | 369 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, |
| 384 | CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); | 370 | CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); |
| 385 | goto err; | 371 | goto err; |
| 386 | } | 372 | } |
| 387 | 373 | ||
| 388 | algtmp = pwri->keyDerivationAlgorithm; | 374 | algtmp = pwri->keyDerivationAlgorithm; |
| 389 | 375 | ||
| 390 | /* Finish password based key derivation to setup key in "ctx" */ | 376 | /* Finish password based key derivation to setup key in "ctx" */ |
| 391 | 377 | ||
| 392 | if (EVP_PBE_CipherInit(algtmp->algorithm, | 378 | if (EVP_PBE_CipherInit(algtmp->algorithm, |
| 393 | (char *)pwri->pass, pwri->passlen, | 379 | (char *)pwri->pass, pwri->passlen, |
| 394 | algtmp->parameter, &kekctx, en_de) < 0) | 380 | algtmp->parameter, &kekctx, en_de) < 0) { |
| 395 | { | ||
| 396 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB); | 381 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB); |
| 397 | goto err; | 382 | goto err; |
| 398 | } | 383 | } |
| 399 | 384 | ||
| 400 | /* Finally wrap/unwrap the key */ | 385 | /* Finally wrap/unwrap the key */ |
| 401 | 386 | ||
| 402 | if (en_de) | 387 | if (en_de) { |
| 403 | { | ||
| 404 | 388 | ||
| 405 | if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, &kekctx)) | 389 | if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, &kekctx)) |
| 406 | goto err; | 390 | goto err; |
| @@ -414,41 +398,34 @@ int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, | |||
| 414 | goto err; | 398 | goto err; |
| 415 | pwri->encryptedKey->data = key; | 399 | pwri->encryptedKey->data = key; |
| 416 | pwri->encryptedKey->length = keylen; | 400 | pwri->encryptedKey->length = keylen; |
| 417 | } | 401 | } else { |
| 418 | else | ||
| 419 | { | ||
| 420 | key = malloc(pwri->encryptedKey->length); | 402 | key = malloc(pwri->encryptedKey->length); |
| 421 | 403 | ||
| 422 | if (!key) | 404 | if (!key) { |
| 423 | { | ||
| 424 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, | 405 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, |
| 425 | ERR_R_MALLOC_FAILURE); | 406 | ERR_R_MALLOC_FAILURE); |
| 426 | goto err; | 407 | goto err; |
| 427 | } | 408 | } |
| 428 | if (!kek_unwrap_key(key, &keylen, | 409 | if (!kek_unwrap_key(key, &keylen, |
| 429 | pwri->encryptedKey->data, | 410 | pwri->encryptedKey->data, |
| 430 | pwri->encryptedKey->length, &kekctx)) | 411 | pwri->encryptedKey->length, &kekctx)) { |
| 431 | { | ||
| 432 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, | 412 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, |
| 433 | CMS_R_UNWRAP_FAILURE); | 413 | CMS_R_UNWRAP_FAILURE); |
| 434 | goto err; | 414 | goto err; |
| 435 | } | 415 | } |
| 436 | 416 | ||
| 437 | ec->key = key; | 417 | ec->key = key; |
| 438 | ec->keylen = keylen; | 418 | ec->keylen = keylen; |
| 439 | 419 | ||
| 440 | } | 420 | } |
| 441 | 421 | ||
| 442 | r = 1; | 422 | r = 1; |
| 443 | 423 | ||
| 444 | err: | 424 | err: |
| 445 | |||
| 446 | EVP_CIPHER_CTX_cleanup(&kekctx); | 425 | EVP_CIPHER_CTX_cleanup(&kekctx); |
| 447 | |||
| 448 | if (!r && key) | 426 | if (!r && key) |
| 449 | free(key); | 427 | free(key); |
| 450 | X509_ALGOR_free(kekalg); | 428 | X509_ALGOR_free(kekalg); |
| 451 | 429 | ||
| 452 | return r; | 430 | return r; |
| 453 | 431 | } | |
| 454 | } | ||
