aboutsummaryrefslogtreecommitdiff
path: root/apps/cms.c
diff options
context:
space:
mode:
authorDmitry Belyavskiy <beldmit@gmail.com>2020-01-20 18:17:44 +0300
committerDmitry Belyavskiy <beldmit@gmail.com>2020-03-03 16:34:40 +0300
commit71434aed0de274abe8f10768c4dd11a5b3b387e4 (patch)
tree3603b2e31c1b29a09990d028b0d9390b7a5a9fa5 /apps/cms.c
parent88398d2a358fe41e33c61ac02f23ffaeacddcff0 (diff)
downloadopenssl-71434aed0de274abe8f10768c4dd11a5b3b387e4.zip
openssl-71434aed0de274abe8f10768c4dd11a5b3b387e4.tar.gz
openssl-71434aed0de274abe8f10768c4dd11a5b3b387e4.tar.bz2
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.c49
1 files changed, 38 insertions, 11 deletions
diff --git a/apps/cms.c b/apps/cms.c
index d67116d..9c92e79 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;
}