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 |