| OLD | NEW |
| 1 /* crypto/cms/cms_env.c */ | 1 /* crypto/cms/cms_env.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. | 3 * project. |
| 4 */ | 4 */ |
| 5 /* ==================================================================== | 5 /* ==================================================================== |
| 6 * Copyright (c) 2008 The OpenSSL Project. All rights reserved. | 6 * Copyright (c) 2008 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: |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 | 53 |
| 54 #include "cryptlib.h" | 54 #include "cryptlib.h" |
| 55 #include <openssl/asn1t.h> | 55 #include <openssl/asn1t.h> |
| 56 #include <openssl/pem.h> | 56 #include <openssl/pem.h> |
| 57 #include <openssl/x509v3.h> | 57 #include <openssl/x509v3.h> |
| 58 #include <openssl/err.h> | 58 #include <openssl/err.h> |
| 59 #include <openssl/cms.h> | 59 #include <openssl/cms.h> |
| 60 #include <openssl/rand.h> | 60 #include <openssl/rand.h> |
| 61 #include <openssl/aes.h> | 61 #include <openssl/aes.h> |
| 62 #include "cms_lcl.h" | 62 #include "cms_lcl.h" |
| 63 #include "asn1_locl.h" |
| 63 | 64 |
| 64 /* CMS EnvelopedData Utilities */ | 65 /* CMS EnvelopedData Utilities */ |
| 65 | 66 |
| 66 DECLARE_ASN1_ITEM(CMS_EnvelopedData) | 67 DECLARE_ASN1_ITEM(CMS_EnvelopedData) |
| 67 DECLARE_ASN1_ITEM(CMS_RecipientInfo) | 68 DECLARE_ASN1_ITEM(CMS_RecipientInfo) |
| 68 DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo) | 69 DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo) |
| 69 DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo) | 70 DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo) |
| 70 DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute) | 71 DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute) |
| 71 | 72 |
| 72 DECLARE_STACK_OF(CMS_RecipientInfo) | 73 DECLARE_STACK_OF(CMS_RecipientInfo) |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 * If we ever handle key agreement will need updating. | 145 * If we ever handle key agreement will need updating. |
| 145 */ | 146 */ |
| 146 | 147 |
| 147 CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, | 148 CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, |
| 148 X509 *recip, unsigned int flags) | 149 X509 *recip, unsigned int flags) |
| 149 { | 150 { |
| 150 CMS_RecipientInfo *ri = NULL; | 151 CMS_RecipientInfo *ri = NULL; |
| 151 CMS_KeyTransRecipientInfo *ktri; | 152 CMS_KeyTransRecipientInfo *ktri; |
| 152 CMS_EnvelopedData *env; | 153 CMS_EnvelopedData *env; |
| 153 EVP_PKEY *pk = NULL; | 154 EVP_PKEY *pk = NULL; |
| 154 » int type; | 155 » int i, type; |
| 155 env = cms_get0_enveloped(cms); | 156 env = cms_get0_enveloped(cms); |
| 156 if (!env) | 157 if (!env) |
| 157 goto err; | 158 goto err; |
| 158 | 159 |
| 159 /* Initialize recipient info */ | 160 /* Initialize recipient info */ |
| 160 ri = M_ASN1_new_of(CMS_RecipientInfo); | 161 ri = M_ASN1_new_of(CMS_RecipientInfo); |
| 161 if (!ri) | 162 if (!ri) |
| 162 goto merr; | 163 goto merr; |
| 163 | 164 |
| 164 /* Initialize and add key transport recipient info */ | 165 /* Initialize and add key transport recipient info */ |
| (...skipping 28 matching lines...) Expand all Loading... |
| 193 type = CMS_RECIPINFO_ISSUER_SERIAL; | 194 type = CMS_RECIPINFO_ISSUER_SERIAL; |
| 194 } | 195 } |
| 195 | 196 |
| 196 /* Not a typo: RecipientIdentifier and SignerIdentifier are the | 197 /* Not a typo: RecipientIdentifier and SignerIdentifier are the |
| 197 * same structure. | 198 * same structure. |
| 198 */ | 199 */ |
| 199 | 200 |
| 200 if (!cms_set1_SignerIdentifier(ktri->rid, recip, type)) | 201 if (!cms_set1_SignerIdentifier(ktri->rid, recip, type)) |
| 201 goto err; | 202 goto err; |
| 202 | 203 |
| 203 » /* Since we have no EVP_PKEY_ASN1_METHOD in OpenSSL 0.9.8, | 204 » if (pk->ameth && pk->ameth->pkey_ctrl) |
| 204 » * hard code algorithm parameters. | |
| 205 » */ | |
| 206 | |
| 207 » if (pk->type == EVP_PKEY_RSA) | |
| 208 { | 205 { |
| 209 » » X509_ALGOR_set0(ktri->keyEncryptionAlgorithm, | 206 » » i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_ENVELOPE, |
| 210 » » » » » OBJ_nid2obj(NID_rsaEncryption), | 207 » » » » » » 0, ri); |
| 211 » » » » » V_ASN1_NULL, 0); | 208 » » if (i == -2) |
| 212 » » } | 209 » » » { |
| 213 » else | 210 » » » CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, |
| 214 » » { | |
| 215 » » CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, | |
| 216 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); | 211 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); |
| 217 » » goto err; | 212 » » » goto err; |
| 213 » » » } |
| 214 » » if (i <= 0) |
| 215 » » » { |
| 216 » » » CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, |
| 217 » » » » CMS_R_CTRL_FAILURE); |
| 218 » » » goto err; |
| 219 » » » } |
| 218 } | 220 } |
| 219 | 221 |
| 220 if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) | 222 if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) |
| 221 goto merr; | 223 goto merr; |
| 222 | 224 |
| 223 return ri; | 225 return ri; |
| 224 | 226 |
| 225 merr: | 227 merr: |
| 226 CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE); | 228 CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE); |
| 227 err: | 229 err: |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 return 1; | 296 return 1; |
| 295 } | 297 } |
| 296 | 298 |
| 297 /* Encrypt content key in key transport recipient info */ | 299 /* Encrypt content key in key transport recipient info */ |
| 298 | 300 |
| 299 static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, | 301 static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, |
| 300 CMS_RecipientInfo *ri) | 302 CMS_RecipientInfo *ri) |
| 301 { | 303 { |
| 302 CMS_KeyTransRecipientInfo *ktri; | 304 CMS_KeyTransRecipientInfo *ktri; |
| 303 CMS_EncryptedContentInfo *ec; | 305 CMS_EncryptedContentInfo *ec; |
| 306 EVP_PKEY_CTX *pctx = NULL; |
| 304 unsigned char *ek = NULL; | 307 unsigned char *ek = NULL; |
| 305 » int eklen; | 308 » size_t eklen; |
| 306 | 309 |
| 307 int ret = 0; | 310 int ret = 0; |
| 308 | 311 |
| 309 if (ri->type != CMS_RECIPINFO_TRANS) | 312 if (ri->type != CMS_RECIPINFO_TRANS) |
| 310 { | 313 { |
| 311 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, | 314 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, |
| 312 CMS_R_NOT_KEY_TRANSPORT); | 315 CMS_R_NOT_KEY_TRANSPORT); |
| 313 return 0; | 316 return 0; |
| 314 } | 317 } |
| 315 ktri = ri->d.ktri; | 318 ktri = ri->d.ktri; |
| 316 ec = cms->d.envelopedData->encryptedContentInfo; | 319 ec = cms->d.envelopedData->encryptedContentInfo; |
| 317 | 320 |
| 318 » eklen = EVP_PKEY_size(ktri->pkey); | 321 » pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); |
| 322 » if (!pctx) |
| 323 » » return 0; |
| 324 |
| 325 » if (EVP_PKEY_encrypt_init(pctx) <= 0) |
| 326 » » goto err; |
| 327 |
| 328 » if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, |
| 329 » » » » EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) |
| 330 » » { |
| 331 » » CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR); |
| 332 » » goto err; |
| 333 » » } |
| 334 |
| 335 » if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0) |
| 336 » » goto err; |
| 319 | 337 |
| 320 ek = OPENSSL_malloc(eklen); | 338 ek = OPENSSL_malloc(eklen); |
| 321 | 339 |
| 322 if (ek == NULL) | 340 if (ek == NULL) |
| 323 { | 341 { |
| 324 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, | 342 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, |
| 325 ERR_R_MALLOC_FAILURE); | 343 ERR_R_MALLOC_FAILURE); |
| 326 goto err; | 344 goto err; |
| 327 } | 345 } |
| 328 | 346 |
| 329 » eklen = EVP_PKEY_encrypt(ek, ec->key, ec->keylen, ktri->pkey); | 347 » if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0) |
| 330 | |
| 331 » if (eklen <= 0) | |
| 332 goto err; | 348 goto err; |
| 333 | 349 |
| 334 ASN1_STRING_set0(ktri->encryptedKey, ek, eklen); | 350 ASN1_STRING_set0(ktri->encryptedKey, ek, eklen); |
| 335 ek = NULL; | 351 ek = NULL; |
| 336 | 352 |
| 337 ret = 1; | 353 ret = 1; |
| 338 | 354 |
| 339 err: | 355 err: |
| 356 if (pctx) |
| 357 EVP_PKEY_CTX_free(pctx); |
| 340 if (ek) | 358 if (ek) |
| 341 OPENSSL_free(ek); | 359 OPENSSL_free(ek); |
| 342 return ret; | 360 return ret; |
| 343 | 361 |
| 344 } | 362 } |
| 345 | 363 |
| 346 /* Decrypt content key from KTRI */ | 364 /* Decrypt content key from KTRI */ |
| 347 | 365 |
| 348 static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, | 366 static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, |
| 349 CMS_RecipientInfo *ri) | 367 CMS_RecipientInfo *ri) |
| 350 { | 368 { |
| 351 CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; | 369 CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; |
| 370 EVP_PKEY_CTX *pctx = NULL; |
| 352 unsigned char *ek = NULL; | 371 unsigned char *ek = NULL; |
| 353 » int eklen; | 372 » size_t eklen; |
| 354 int ret = 0; | 373 int ret = 0; |
| 355 | 374 |
| 356 if (ktri->pkey == NULL) | 375 if (ktri->pkey == NULL) |
| 357 { | 376 { |
| 358 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, | 377 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, |
| 359 CMS_R_NO_PRIVATE_KEY); | 378 CMS_R_NO_PRIVATE_KEY); |
| 360 return 0; | 379 return 0; |
| 361 } | 380 } |
| 362 | 381 |
| 363 » eklen = EVP_PKEY_size(ktri->pkey); | 382 » pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); |
| 383 » if (!pctx) |
| 384 » » return 0; |
| 385 |
| 386 » if (EVP_PKEY_decrypt_init(pctx) <= 0) |
| 387 » » goto err; |
| 388 |
| 389 » if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT, |
| 390 » » » » EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) |
| 391 » » { |
| 392 » » CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR); |
| 393 » » goto err; |
| 394 » » } |
| 395 |
| 396 » if (EVP_PKEY_decrypt(pctx, NULL, &eklen, |
| 397 » » » » ktri->encryptedKey->data, |
| 398 » » » » ktri->encryptedKey->length) <= 0) |
| 399 » » goto err; |
| 364 | 400 |
| 365 ek = OPENSSL_malloc(eklen); | 401 ek = OPENSSL_malloc(eklen); |
| 366 | 402 |
| 367 if (ek == NULL) | 403 if (ek == NULL) |
| 368 { | 404 { |
| 369 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, | 405 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, |
| 370 ERR_R_MALLOC_FAILURE); | 406 ERR_R_MALLOC_FAILURE); |
| 371 goto err; | 407 goto err; |
| 372 } | 408 } |
| 373 | 409 |
| 374 » eklen = EVP_PKEY_decrypt(ek, | 410 » if (EVP_PKEY_decrypt(pctx, ek, &eklen, |
| 375 ktri->encryptedKey->data, | 411 ktri->encryptedKey->data, |
| 376 » » » » ktri->encryptedKey->length, ktri->pkey); | 412 » » » » ktri->encryptedKey->length) <= 0) |
| 377 » if (eklen <= 0) | |
| 378 { | 413 { |
| 379 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB); | 414 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB); |
| 380 goto err; | 415 goto err; |
| 381 } | 416 } |
| 382 | 417 |
| 383 ret = 1; | 418 ret = 1; |
| 384 | 419 |
| 385 cms->d.envelopedData->encryptedContentInfo->key = ek; | 420 cms->d.envelopedData->encryptedContentInfo->key = ek; |
| 386 cms->d.envelopedData->encryptedContentInfo->keylen = eklen; | 421 cms->d.envelopedData->encryptedContentInfo->keylen = eklen; |
| 387 | 422 |
| 388 err: | 423 err: |
| 424 if (pctx) |
| 425 EVP_PKEY_CTX_free(pctx); |
| 389 if (!ret && ek) | 426 if (!ret && ek) |
| 390 OPENSSL_free(ek); | 427 OPENSSL_free(ek); |
| 391 | 428 |
| 392 return ret; | 429 return ret; |
| 393 } | 430 } |
| 394 | 431 |
| 395 /* Key Encrypted Key (KEK) RecipientInfo routines */ | 432 /* Key Encrypted Key (KEK) RecipientInfo routines */ |
| 396 | 433 |
| 397 int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, | 434 int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, |
| 398 const unsigned char *id, size_t idlen) | 435 const unsigned char *id, size_t idlen) |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 816 OPENSSL_free(ec->key); | 853 OPENSSL_free(ec->key); |
| 817 ec->key = NULL; | 854 ec->key = NULL; |
| 818 ec->keylen = 0; | 855 ec->keylen = 0; |
| 819 } | 856 } |
| 820 if (ok) | 857 if (ok) |
| 821 return ret; | 858 return ret; |
| 822 BIO_free(ret); | 859 BIO_free(ret); |
| 823 return NULL; | 860 return NULL; |
| 824 | 861 |
| 825 } | 862 } |
| OLD | NEW |