diff options
author | inoguchi <> | 2019-11-18 11:34:41 +0000 |
---|---|---|
committer | inoguchi <> | 2019-11-18 11:34:41 +0000 |
commit | 20b2f29ba1a080176623746a32406f58e54313b4 (patch) | |
tree | cc66851e8367d79ca557a0f6c04ea3989cdd70a4 | |
parent | d29c2aa42ff08eae9d602f68ded7137c5fc198b7 (diff) | |
download | openbsd-20b2f29ba1a080176623746a32406f58e54313b4.tar.gz openbsd-20b2f29ba1a080176623746a32406f58e54313b4.tar.bz2 openbsd-20b2f29ba1a080176623746a32406f58e54313b4.zip |
Add -keyopt opiton to openssl(1) cms subcommand
This provides rsa_padding_mode:oaep for cms -encrypt,
and rsa_padding_mode:pss for cms -sign.
ok jsing@
-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 |