diff options
author | Dmitry Belyavskiy <beldmit@gmail.com> | 2020-01-20 18:17:44 +0300 |
---|---|---|
committer | Dmitry Belyavskiy <beldmit@gmail.com> | 2020-03-03 16:34:40 +0300 |
commit | 71434aed0de274abe8f10768c4dd11a5b3b387e4 (patch) | |
tree | 3603b2e31c1b29a09990d028b0d9390b7a5a9fa5 /apps/cms.c | |
parent | 88398d2a358fe41e33c61ac02f23ffaeacddcff0 (diff) |
Implementation of Russian GOST CMS
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/10904)
Diffstat (limited to 'apps/cms.c')
-rw-r--r-- | apps/cms.c | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/apps/cms.c b/apps/cms.c index d67116d3fc..9c92e79658 100644 --- a/apps/cms.c +++ b/apps/cms.c @@ -81,10 +81,11 @@ typedef enum OPTION_choice { OPT_PASSIN, OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP, OPT_CERTSOUT, OPT_MD, OPT_INKEY, OPT_KEYFORM, OPT_KEYOPT, OPT_RR_FROM, OPT_RR_TO, OPT_AES128_WRAP, OPT_AES192_WRAP, OPT_AES256_WRAP, - OPT_3DES_WRAP, OPT_ENGINE, + OPT_3DES_WRAP, OPT_WRAP, OPT_ENGINE, OPT_R_ENUM, OPT_V_ENUM, - OPT_CIPHER + OPT_CIPHER, + OPT_ORIGINATOR } OPTION_CHOICE; const OPTIONS cms_options[] = { @@ -197,6 +198,7 @@ const OPTIONS cms_options[] = { {"from", OPT_FROM, 's', "From address"}, {"subject", OPT_SUBJECT, 's', "Subject"}, {"signer", OPT_SIGNER, 's', "Signer certificate file"}, + {"originator", OPT_ORIGINATOR, 's', "Originator certificate file"}, {"recip", OPT_RECIP, '<', "Recipient cert file for decryption"}, {"receipt_request_from", OPT_RR_FROM, 's', "Create signed receipt request with specified email address"}, @@ -214,6 +216,7 @@ const OPTIONS cms_options[] = { # ifndef OPENSSL_NO_DES {"des3-wrap", OPT_3DES_WRAP, '-', "Use 3DES-EDE to wrap key"}, # endif + {"wrap", OPT_WRAP, 's', "Any wrap cipher to wrap key"}, OPT_R_OPTIONS, OPT_V_OPTIONS, @@ -236,7 +239,7 @@ int cms_main(int argc, char **argv) STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL; STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL; STACK_OF(X509) *encerts = NULL, *other = NULL; - X509 *cert = NULL, *recip = NULL, *signer = NULL; + X509 *cert = NULL, *recip = NULL, *signer = NULL, *originator = NULL; X509_STORE *store = NULL; X509_VERIFY_PARAM *vpm = NULL; char *certfile = NULL, *keyfile = NULL, *contfile = NULL; @@ -244,7 +247,7 @@ int cms_main(int argc, char **argv) char *certsoutfile = NULL; int noCAfile = 0, noCApath = 0, noCAstore = 0; char *infile = NULL, *outfile = NULL, *rctfile = NULL; - char *passinarg = NULL, *passin = NULL, *signerfile = NULL, *recipfile = NULL; + char *passinarg = NULL, *passin = NULL, *signerfile = NULL, *originatorfile = NULL, *recipfile = NULL; char *to = NULL, *from = NULL, *subject = NULL, *prog; cms_key_param *key_first = NULL, *key_param = NULL; int flags = CMS_DETACHED, noout = 0, print = 0, keyidx = -1, vpmtouched = 0; @@ -535,6 +538,9 @@ int cms_main(int argc, char **argv) } signerfile = opt_arg(); break; + case OPT_ORIGINATOR: + originatorfile = opt_arg(); + break; case OPT_INKEY: /* If previous -inkey argument add signer to list */ if (keyfile != NULL) { @@ -629,6 +635,10 @@ int cms_main(int argc, char **argv) case OPT_AES256_WRAP: wrap_cipher = EVP_aes_256_wrap(); break; + case OPT_WRAP: + if (!opt_cipher(opt_unknown(), &wrap_cipher)) + goto end; + break; } } argc = opt_num_rest(); @@ -759,6 +769,14 @@ int cms_main(int argc, char **argv) } } + if (originatorfile != NULL) { + if ((originator = load_cert(originatorfile, FORMAT_PEM, + "originator certificate file")) == NULL) { + ERR_print_errors(bio_err); + goto end; + } + } + if (operation == SMIME_SIGN_RECEIPT) { if ((signer = load_cert(signerfile, FORMAT_PEM, "receipt signer certificate file")) == NULL) { @@ -767,7 +785,7 @@ int cms_main(int argc, char **argv) } } - if (operation == SMIME_DECRYPT) { + if ((operation == SMIME_DECRYPT) || (operation == SMIME_ENCRYPT)) { if (keyfile == NULL) keyfile = recipfile; } else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT)) { @@ -877,23 +895,32 @@ int cms_main(int argc, char **argv) for (i = 0; i < sk_X509_num(encerts); i++) { CMS_RecipientInfo *ri; cms_key_param *kparam; - int tflags = flags; + int tflags = flags | CMS_KEY_PARAM; /* This flag enforces allocating the EVP_PKEY_CTX for the recipient here */ + EVP_PKEY_CTX *pctx; X509 *x = sk_X509_value(encerts, i); + int res; + for (kparam = key_first; kparam; kparam = kparam->next) { if (kparam->idx == i) { - tflags |= CMS_KEY_PARAM; break; } } - ri = CMS_add1_recipient_cert(cms, x, tflags); + ri = CMS_add1_recipient(cms, x, key, originator, tflags); if (ri == NULL) goto end; + + pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); if (kparam != NULL) { - EVP_PKEY_CTX *pctx; - pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); if (!cms_set_pkey_param(pctx, kparam->param)) goto end; } + + res = EVP_PKEY_CTX_ctrl(pctx, -1, -1, + EVP_PKEY_CTRL_CIPHER, + EVP_CIPHER_nid(cipher), NULL); + if (res <= 0 && res != -2) + goto end; + if (CMS_RecipientInfo_type(ri) == CMS_RECIPINFO_AGREE && wrap_cipher) { EVP_CIPHER_CTX *wctx; @@ -1039,7 +1066,7 @@ int cms_main(int argc, char **argv) } if (key != NULL) { - if (!CMS_decrypt_set1_pkey(cms, key, recip)) { + if (!CMS_decrypt_set1_pkey_and_peer(cms, key, recip, originator)) { BIO_puts(bio_err, "Error decrypting CMS using private key\n"); goto end; } |