diff options
Diffstat (limited to '')
| -rw-r--r-- | src/usr.bin/openssl/cms.c | 136 |
1 files changed, 128 insertions, 8 deletions
diff --git a/src/usr.bin/openssl/cms.c b/src/usr.bin/openssl/cms.c index b36c08b209..71e52fe52c 100644 --- a/src/usr.bin/openssl/cms.c +++ b/src/usr.bin/openssl/cms.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: cms.c,v 1.13 2019/11/04 15:34:27 jsing Exp $ */ | 1 | /* $OpenBSD: cms.c,v 1.14 2019/11/18 11:34:41 inoguchi Exp $ */ |
| 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 | */ |
| @@ -74,6 +74,8 @@ static void receipt_request_print(BIO *out, CMS_ContentInfo *cms); | |||
| 74 | static CMS_ReceiptRequest *make_receipt_request( | 74 | static CMS_ReceiptRequest *make_receipt_request( |
| 75 | STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst, | 75 | STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst, |
| 76 | STACK_OF(OPENSSL_STRING) *rr_from); | 76 | STACK_OF(OPENSSL_STRING) *rr_from); |
| 77 | static int cms_set_pkey_param(EVP_PKEY_CTX *pctx, | ||
| 78 | STACK_OF(OPENSSL_STRING) *param); | ||
| 77 | 79 | ||
| 78 | #define SMIME_OP 0x10 | 80 | #define SMIME_OP 0x10 |
| 79 | #define SMIME_IP 0x20 | 81 | #define SMIME_IP 0x20 |
| @@ -97,6 +99,14 @@ static CMS_ReceiptRequest *make_receipt_request( | |||
| 97 | 99 | ||
| 98 | int verify_err = 0; | 100 | int verify_err = 0; |
| 99 | 101 | ||
| 102 | typedef struct cms_key_param_st cms_key_param; | ||
| 103 | |||
| 104 | struct cms_key_param_st { | ||
| 105 | int idx; | ||
| 106 | STACK_OF(OPENSSL_STRING) *param; | ||
| 107 | cms_key_param *next; | ||
| 108 | }; | ||
| 109 | |||
| 100 | int | 110 | int |
| 101 | cms_main(int argc, char **argv) | 111 | cms_main(int argc, char **argv) |
| 102 | { | 112 | { |
| @@ -132,6 +142,8 @@ cms_main(int argc, char **argv) | |||
| 132 | unsigned char *pwri_pass = NULL, *pwri_tmp = NULL; | 142 | unsigned char *pwri_pass = NULL, *pwri_tmp = NULL; |
| 133 | size_t secret_keylen = 0, secret_keyidlen = 0; | 143 | size_t secret_keylen = 0, secret_keyidlen = 0; |
| 134 | 144 | ||
| 145 | cms_key_param *key_first = NULL, *key_param = NULL; | ||
| 146 | |||
| 135 | ASN1_OBJECT *econtent_type = NULL; | 147 | ASN1_OBJECT *econtent_type = NULL; |
| 136 | 148 | ||
| 137 | X509_VERIFY_PARAM *vpm = NULL; | 149 | X509_VERIFY_PARAM *vpm = NULL; |
| @@ -351,7 +363,19 @@ cms_main(int argc, char **argv) | |||
| 351 | } else if (!strcmp(*args, "-recip")) { | 363 | } else if (!strcmp(*args, "-recip")) { |
| 352 | if (!args[1]) | 364 | if (!args[1]) |
| 353 | goto argerr; | 365 | goto argerr; |
| 354 | recipfile = *++args; | 366 | if (operation == SMIME_ENCRYPT) { |
| 367 | if (encerts == NULL && | ||
| 368 | (encerts = sk_X509_new_null()) == NULL) | ||
| 369 | goto end; | ||
| 370 | cert = load_cert(bio_err, *++args, FORMAT_PEM, | ||
| 371 | NULL, "recipient certificate file"); | ||
| 372 | if (cert == NULL) | ||
| 373 | goto end; | ||
| 374 | sk_X509_push(encerts, cert); | ||
| 375 | cert = NULL; | ||
| 376 | } else { | ||
| 377 | recipfile = *++args; | ||
| 378 | } | ||
| 355 | } else if (!strcmp(*args, "-certsout")) { | 379 | } else if (!strcmp(*args, "-certsout")) { |
| 356 | if (!args[1]) | 380 | if (!args[1]) |
| 357 | goto argerr; | 381 | goto argerr; |
| @@ -389,6 +413,38 @@ cms_main(int argc, char **argv) | |||
| 389 | if (!args[1]) | 413 | if (!args[1]) |
| 390 | goto argerr; | 414 | goto argerr; |
| 391 | keyform = str2fmt(*++args); | 415 | keyform = str2fmt(*++args); |
| 416 | } else if (!strcmp (*args, "-keyopt")) { | ||
| 417 | int keyidx = -1; | ||
| 418 | if (!args[1]) | ||
| 419 | goto argerr; | ||
| 420 | if (operation == SMIME_ENCRYPT) { | ||
| 421 | if (encerts != NULL) | ||
| 422 | keyidx += sk_X509_num(encerts); | ||
| 423 | } else { | ||
| 424 | if (keyfile != NULL || signerfile != NULL) | ||
| 425 | keyidx++; | ||
| 426 | if (skkeys != NULL) | ||
| 427 | keyidx += sk_OPENSSL_STRING_num(skkeys); | ||
| 428 | } | ||
| 429 | if (keyidx < 0) { | ||
| 430 | BIO_printf(bio_err, "No key specified\n"); | ||
| 431 | goto argerr; | ||
| 432 | } | ||
| 433 | if (key_param == NULL || key_param->idx != keyidx) { | ||
| 434 | cms_key_param *nparam; | ||
| 435 | if ((nparam = malloc(sizeof(cms_key_param))) == NULL) | ||
| 436 | goto end; | ||
| 437 | nparam->idx = keyidx; | ||
| 438 | if ((nparam->param = sk_OPENSSL_STRING_new_null()) == NULL) | ||
| 439 | goto end; | ||
| 440 | nparam->next = NULL; | ||
| 441 | if (key_first == NULL) | ||
| 442 | key_first = nparam; | ||
| 443 | else | ||
| 444 | key_param->next = nparam; | ||
| 445 | key_param = nparam; | ||
| 446 | } | ||
| 447 | sk_OPENSSL_STRING_push(key_param->param, *++args); | ||
| 392 | } else if (!strcmp(*args, "-rctform")) { | 448 | } else if (!strcmp(*args, "-rctform")) { |
| 393 | if (!args[1]) | 449 | if (!args[1]) |
| 394 | goto argerr; | 450 | goto argerr; |
| @@ -474,7 +530,7 @@ cms_main(int argc, char **argv) | |||
| 474 | badarg = 1; | 530 | badarg = 1; |
| 475 | } | 531 | } |
| 476 | } else if (operation == SMIME_ENCRYPT) { | 532 | } else if (operation == SMIME_ENCRYPT) { |
| 477 | if (!*args && !secret_key && !pwri_pass) { | 533 | if (!*args && !secret_key && !pwri_pass && !encerts) { |
| 478 | BIO_printf(bio_err, | 534 | BIO_printf(bio_err, |
| 479 | "No recipient(s) certificate(s) specified\n"); | 535 | "No recipient(s) certificate(s) specified\n"); |
| 480 | badarg = 1; | 536 | badarg = 1; |
| @@ -524,6 +580,7 @@ cms_main(int argc, char **argv) | |||
| 524 | BIO_printf(bio_err, "-inform arg input format SMIME (default), PEM or DER\n"); | 580 | BIO_printf(bio_err, "-inform arg input format SMIME (default), PEM or DER\n"); |
| 525 | BIO_printf(bio_err, "-inkey file input private key (if not signer or recipient)\n"); | 581 | BIO_printf(bio_err, "-inkey file input private key (if not signer or recipient)\n"); |
| 526 | BIO_printf(bio_err, "-keyform arg input private key format (PEM)\n"); | 582 | BIO_printf(bio_err, "-keyform arg input private key format (PEM)\n"); |
| 583 | BIO_printf (bio_err, "-keyopt nm:v set public key parameters\n"); | ||
| 527 | BIO_printf(bio_err, "-out file output file\n"); | 584 | BIO_printf(bio_err, "-out file output file\n"); |
| 528 | BIO_printf(bio_err, "-outform arg output format SMIME (default), PEM or DER\n"); | 585 | BIO_printf(bio_err, "-outform arg output format SMIME (default), PEM or DER\n"); |
| 529 | BIO_printf(bio_err, "-content file supply or override content for detached signature\n"); | 586 | BIO_printf(bio_err, "-content file supply or override content for detached signature\n"); |
| @@ -578,7 +635,7 @@ cms_main(int argc, char **argv) | |||
| 578 | BIO_printf(bio_err, "No secret key id\n"); | 635 | BIO_printf(bio_err, "No secret key id\n"); |
| 579 | goto end; | 636 | goto end; |
| 580 | } | 637 | } |
| 581 | if (*args) | 638 | if (*args && !encerts) |
| 582 | encerts = sk_X509_new_null(); | 639 | encerts = sk_X509_new_null(); |
| 583 | while (*args) { | 640 | while (*args) { |
| 584 | if (!(cert = load_cert(bio_err, *args, FORMAT_PEM, | 641 | if (!(cert = load_cert(bio_err, *args, FORMAT_PEM, |
| @@ -722,10 +779,33 @@ cms_main(int argc, char **argv) | |||
| 722 | } else if (operation == SMIME_COMPRESS) { | 779 | } else if (operation == SMIME_COMPRESS) { |
| 723 | cms = CMS_compress(in, -1, flags); | 780 | cms = CMS_compress(in, -1, flags); |
| 724 | } else if (operation == SMIME_ENCRYPT) { | 781 | } else if (operation == SMIME_ENCRYPT) { |
| 782 | int i; | ||
| 725 | flags |= CMS_PARTIAL; | 783 | flags |= CMS_PARTIAL; |
| 726 | cms = CMS_encrypt(encerts, in, cipher, flags); | 784 | cms = CMS_encrypt(NULL, in, cipher, flags); |
| 727 | if (!cms) | 785 | if (cms == NULL) |
| 728 | goto end; | 786 | goto end; |
| 787 | for (i = 0; i < sk_X509_num(encerts); i++) { | ||
| 788 | CMS_RecipientInfo *ri; | ||
| 789 | cms_key_param *kparam; | ||
| 790 | int tflags = flags; | ||
| 791 | X509 *x = sk_X509_value(encerts, i); | ||
| 792 | for (kparam = key_first; kparam; kparam = kparam->next) { | ||
| 793 | if (kparam->idx == i) { | ||
| 794 | tflags |= CMS_KEY_PARAM; | ||
| 795 | break; | ||
| 796 | } | ||
| 797 | } | ||
| 798 | ri = CMS_add1_recipient_cert(cms, x, tflags); | ||
| 799 | if (ri == NULL) | ||
| 800 | goto end; | ||
| 801 | if (kparam != NULL) { | ||
| 802 | EVP_PKEY_CTX *pctx; | ||
| 803 | pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); | ||
| 804 | if (!cms_set_pkey_param(pctx, kparam->param)) | ||
| 805 | goto end; | ||
| 806 | } | ||
| 807 | } | ||
| 808 | |||
| 729 | if (secret_key) { | 809 | if (secret_key) { |
| 730 | if (!CMS_add0_recipient_key(cms, NID_undef, secret_key, | 810 | if (!CMS_add0_recipient_key(cms, NID_undef, secret_key, |
| 731 | secret_keylen, secret_keyid, secret_keyidlen, | 811 | secret_keylen, secret_keyid, secret_keyidlen, |
| @@ -797,8 +877,11 @@ cms_main(int argc, char **argv) | |||
| 797 | flags |= CMS_REUSE_DIGEST; | 877 | flags |= CMS_REUSE_DIGEST; |
| 798 | for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) { | 878 | for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) { |
| 799 | CMS_SignerInfo *si; | 879 | CMS_SignerInfo *si; |
| 880 | cms_key_param *kparam; | ||
| 881 | int tflags = flags; | ||
| 800 | signerfile = sk_OPENSSL_STRING_value(sksigners, i); | 882 | signerfile = sk_OPENSSL_STRING_value(sksigners, i); |
| 801 | keyfile = sk_OPENSSL_STRING_value(skkeys, i); | 883 | keyfile = sk_OPENSSL_STRING_value(skkeys, i); |
| 884 | |||
| 802 | signer = load_cert(bio_err, signerfile, FORMAT_PEM, | 885 | signer = load_cert(bio_err, signerfile, FORMAT_PEM, |
| 803 | NULL, "signer certificate"); | 886 | NULL, "signer certificate"); |
| 804 | if (!signer) | 887 | if (!signer) |
| @@ -807,9 +890,21 @@ cms_main(int argc, char **argv) | |||
| 807 | "signing key file"); | 890 | "signing key file"); |
| 808 | if (!key) | 891 | if (!key) |
| 809 | goto end; | 892 | goto end; |
| 810 | si = CMS_add1_signer(cms, signer, key, sign_md, flags); | 893 | for (kparam = key_first; kparam; kparam = kparam->next) { |
| 811 | if (!si) | 894 | if (kparam->idx == i) { |
| 895 | tflags |= CMS_KEY_PARAM; | ||
| 896 | break; | ||
| 897 | } | ||
| 898 | } | ||
| 899 | si = CMS_add1_signer(cms, signer, key, sign_md, tflags); | ||
| 900 | if (si == NULL) | ||
| 812 | goto end; | 901 | goto end; |
| 902 | if (kparam != NULL) { | ||
| 903 | EVP_PKEY_CTX *pctx; | ||
| 904 | pctx = CMS_SignerInfo_get0_pkey_ctx(si); | ||
| 905 | if (!cms_set_pkey_param(pctx, kparam->param)) | ||
| 906 | goto end; | ||
| 907 | } | ||
| 813 | if (rr && !CMS_add1_ReceiptRequest(si, rr)) | 908 | if (rr && !CMS_add1_ReceiptRequest(si, rr)) |
| 814 | goto end; | 909 | goto end; |
| 815 | X509_free(signer); | 910 | X509_free(signer); |
| @@ -952,6 +1047,13 @@ cms_main(int argc, char **argv) | |||
| 952 | CMS_ReceiptRequest_free(rr); | 1047 | CMS_ReceiptRequest_free(rr); |
| 953 | sk_OPENSSL_STRING_free(rr_to); | 1048 | sk_OPENSSL_STRING_free(rr_to); |
| 954 | sk_OPENSSL_STRING_free(rr_from); | 1049 | sk_OPENSSL_STRING_free(rr_from); |
| 1050 | for (key_param = key_first; key_param;) { | ||
| 1051 | cms_key_param *tparam; | ||
| 1052 | sk_OPENSSL_STRING_free(key_param->param); | ||
| 1053 | tparam = key_param->next; | ||
| 1054 | free(key_param); | ||
| 1055 | key_param = tparam; | ||
| 1056 | } | ||
| 955 | X509_STORE_free(store); | 1057 | X509_STORE_free(store); |
| 956 | X509_free(cert); | 1058 | X509_free(cert); |
| 957 | X509_free(recip); | 1059 | X509_free(recip); |
| @@ -1133,4 +1235,22 @@ make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst, | |||
| 1133 | return NULL; | 1235 | return NULL; |
| 1134 | } | 1236 | } |
| 1135 | 1237 | ||
| 1238 | static int | ||
| 1239 | cms_set_pkey_param(EVP_PKEY_CTX *pctx, STACK_OF(OPENSSL_STRING) *param) | ||
| 1240 | { | ||
| 1241 | char *keyopt; | ||
| 1242 | int i; | ||
| 1243 | if (sk_OPENSSL_STRING_num(param) <= 0) | ||
| 1244 | return 1; | ||
| 1245 | for (i = 0; i < sk_OPENSSL_STRING_num(param); i++) { | ||
| 1246 | keyopt = sk_OPENSSL_STRING_value(param, i); | ||
| 1247 | if (pkey_ctrl_string(pctx, keyopt) <= 0) { | ||
| 1248 | BIO_printf(bio_err, "parameter error \"%s\"\n", keyopt); | ||
| 1249 | ERR_print_errors(bio_err); | ||
| 1250 | return 0; | ||
| 1251 | } | ||
| 1252 | } | ||
| 1253 | return 1; | ||
| 1254 | } | ||
| 1255 | |||
| 1136 | #endif | 1256 | #endif |
