Skip to content

Commit

Permalink
libmycms: use keyopt as list as order is important
Browse files Browse the repository at this point in the history
  • Loading branch information
alonbl committed May 20, 2023
1 parent 39e161d commit 6be2f9b
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 80 deletions.
6 changes: 3 additions & 3 deletions include/mycms/mycms.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ mycms_sign(
const mycms mycms __attribute__((unused)),
const mycms_certificate certificate,
const mycms_list_str digests,
const mycms_dict keyopt,
const mycms_list_str keyopts,
const mycms_io cms_in,
const mycms_io cms_out,
const mycms_io data_in
Expand Down Expand Up @@ -88,7 +88,7 @@ mycms_encrypt(
const mycms mycms,
const char * const cipher_name,
const mycms_list_blob to,
const mycms_dict keyopt,
const mycms_list_str keyopts,
const mycms_io cms_out,
const mycms_io data_pt,
const mycms_io data_ct
Expand All @@ -99,7 +99,7 @@ mycms_encrypt_add(
const mycms mycms,
const mycms_certificate certificate,
const mycms_list_blob to,
const mycms_dict keyopt,
const mycms_list_str keyopts,
const mycms_io cms_in,
const mycms_io cms_out
);
Expand Down
34 changes: 26 additions & 8 deletions src/libmycms/mycms-core-encrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ __add_recipients(
const mycms mycms,
CMS_ContentInfo *cms,
const mycms_list_blob to,
const mycms_dict keyopt,
const mycms_list_str keyopts,
int flags
) {
STACK_OF(CMS_RecipientInfo) *ret = NULL;
Expand All @@ -41,7 +41,7 @@ __add_recipients(
for (t = to;t != NULL;t = t->next) {
CMS_RecipientInfo *ri;
EVP_PKEY_CTX *ctx;
mycms_list_dict_entry opt;
mycms_list_str keyopt;
unsigned const char * p;

p = t->blob.data;
Expand Down Expand Up @@ -81,8 +81,26 @@ __add_recipients(
goto cleanup;
}

for (opt = mycms_dict_entries(keyopt); opt != NULL; opt = opt->next) {
if (!EVP_PKEY_CTX_ctrl_str(ctx, opt->entry.k, opt->entry.v)) {
for (keyopt = keyopts; keyopt != NULL; keyopt = keyopt->next) {
char opt[1024];
char *p;
strncpy(opt, keyopt->str, sizeof(opt));
opt[sizeof(opt) - 1] = '\0';
if ((p = strchr(opt, ':')) == NULL) {
_mycms_error_entry_dispatch(_mycms_error_entry_base(
_mycms_error_capture(mycms_context_get_error(mycms_get_context(mycms))),
"core.sign.keyopt",
MYCMS_ERROR_CODE_ARGS,
true,
"Invalid keyopts '%s' no separator",
opt
));
goto cleanup;
}
*p = '\0';
p++;

if (!EVP_PKEY_CTX_ctrl_str(ctx, opt, p)) {
_mycms_error_entry_dispatch(_error_entry_openssl_status(_mycms_error_entry_base(
_mycms_error_capture(mycms_context_get_error(mycms_get_context(mycms))),
"core.encrypt.add.prms",
Expand Down Expand Up @@ -115,7 +133,7 @@ mycms_encrypt(
const mycms mycms,
const char * const cipher_name,
const mycms_list_blob to,
const mycms_dict keyopt,
const mycms_list_str keyopts,
const mycms_io cms_out,
const mycms_io data_pt,
const mycms_io data_ct
Expand Down Expand Up @@ -208,7 +226,7 @@ mycms_encrypt(
goto cleanup;
}

if ((added = __add_recipients(mycms, cms, to, keyopt, flags)) == NULL) {
if ((added = __add_recipients(mycms, cms, to, keyopts, flags)) == NULL) {
goto cleanup;
}

Expand Down Expand Up @@ -252,7 +270,7 @@ mycms_encrypt_add(
const mycms mycms,
const mycms_certificate certificate,
const mycms_list_blob to,
const mycms_dict keyopt,
const mycms_list_str keyopts,
const mycms_io cms_in,
const mycms_io cms_out
) {
Expand Down Expand Up @@ -332,7 +350,7 @@ mycms_encrypt_add(
goto cleanup;
}

if ((added = __add_recipients(mycms, cms, to, keyopt, flags)) == NULL) {
if ((added = __add_recipients(mycms, cms, to, keyopts, flags)) == NULL) {
goto cleanup;
}

Expand Down
33 changes: 26 additions & 7 deletions src/libmycms/mycms-core-sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ mycms_sign(
const mycms mycms,
const mycms_certificate certificate,
const mycms_list_str digests,
const mycms_dict keyopt,
const mycms_list_str keyopts,
const mycms_io cms_in,
const mycms_io cms_out,
const mycms_io data_in
Expand Down Expand Up @@ -75,7 +75,6 @@ mycms_sign(
for (digest = digests;digest != NULL; digest = digest->next) {
const EVP_MD *md = NULL;
CMS_SignerInfo *signer = NULL;
mycms_list_dict_entry opt;

if ((md = EVP_get_digestbyname(digest->str)) == NULL) {
_mycms_error_entry_dispatch(_mycms_error_entry_base(
Expand All @@ -94,7 +93,7 @@ mycms_sign(
_mycms_certificate_get_X509(certificate),
_mycms_certificate_get_EVP_PKEY(certificate),
md,
flags | (mycms_dict_entries(keyopt) == NULL ? 0 : CMS_KEY_PARAM) /* Does not work for 2nd sign, see https://github.com/openssl/openssl/issues/14257 */
flags | (keyopts == NULL ? 0 : CMS_KEY_PARAM) /* Does not work for 2nd sign, see https://github.com/openssl/openssl/issues/14257 */
)) == NULL) {
_mycms_error_entry_dispatch(_error_entry_openssl_status(_mycms_error_entry_base(
_mycms_error_capture(mycms_context_get_error(mycms_get_context(mycms))),
Expand All @@ -106,7 +105,9 @@ mycms_sign(
goto cleanup;
}

if (mycms_dict_entries(keyopt) != NULL) { /* TODO: remove when openssl bug fixed */
if (keyopts != NULL) { /* TODO: remove when openssl bug fixed */
mycms_list_str keyopt;

if ((ctx = CMS_SignerInfo_get0_pkey_ctx(signer)) == NULL) {
_mycms_error_entry_dispatch(_error_entry_openssl_status(_mycms_error_entry_base(
_mycms_error_capture(mycms_context_get_error(mycms_get_context(mycms))),
Expand All @@ -118,11 +119,29 @@ mycms_sign(
goto cleanup;
}

for (opt = mycms_dict_entries(keyopt); opt != NULL; opt = opt->next) {
if (!EVP_PKEY_CTX_ctrl_str(ctx, opt->entry.k, opt->entry.v)) {
for (keyopt = keyopts;keyopt != NULL; keyopt = keyopt->next) {
char opt[1024];
char *p;
strncpy(opt, keyopt->str, sizeof(opt));
opt[sizeof(opt) - 1] = '\0';
if ((p = strchr(opt, ':')) == NULL) {
_mycms_error_entry_dispatch(_mycms_error_entry_base(
_mycms_error_capture(mycms_context_get_error(mycms_get_context(mycms))),
"core.sign.keyopt",
MYCMS_ERROR_CODE_ARGS,
true,
"Invalid keyopts '%s' no separator",
opt
));
goto cleanup;
}
*p = '\0';
p++;

if (!EVP_PKEY_CTX_ctrl_str(ctx, opt, p)) {
_mycms_error_entry_dispatch(_error_entry_openssl_status(_mycms_error_entry_base(
_mycms_error_capture(mycms_context_get_error(mycms_get_context(mycms))),
"core.sign.add.prm",
"core.sign.add.keyopt",
MYCMS_ERROR_CODE_CRYPTO,
true,
"Failed to set signer key parameters"
Expand Down
54 changes: 15 additions & 39 deletions src/mycms-tool/cmd-encrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ _cmd_encrypt(
{"data-pt\0FILE|input plain text data", required_argument, NULL, OPT_DATA_PT},
{"data-ct\0FILE|output plain text data", required_argument, NULL, OPT_DATA_CT},
{"to\0FILE|target DER encoded certificate, may be specified several times", required_argument, NULL, OPT_TO},
{"keyopt\0KEYOPT_EXPRESSION|key options expression", required_argument, NULL, OPT_KEYOPT},
{"keyopt\0KEYOPT|key options opt:value, may be specified multiple times", required_argument, NULL, OPT_KEYOPT},
{NULL, 0, NULL, 0}
};

Expand All @@ -47,15 +47,13 @@ _cmd_encrypt(

const char *cipher = "AES-256-CBC";

const char * keyopt_exp = NULL;

mycms_system system = mycms_context_get_system(context);
mycms mycms = NULL;
mycms_io cms_out = NULL;
mycms_io data_pt = NULL;
mycms_io data_ct = NULL;
mycms_list_blob to = NULL;
mycms_dict keyopt_dict = NULL;
mycms_list_str keyopts = NULL;

if ((mycms = mycms_new(context)) == NULL) {
goto cleanup;
Expand Down Expand Up @@ -132,7 +130,9 @@ _cmd_encrypt(
}
break;
case OPT_KEYOPT:
keyopt_exp = optarg;
if (!mycms_list_str_add(system, &keyopts, optarg)) {
goto cleanup;
}
break;
default:
fprintf(stderr, "Invalid option\n");
Expand All @@ -157,19 +157,7 @@ _cmd_encrypt(
goto cleanup;
}

if ((keyopt_dict = mycms_dict_new(context)) == NULL) {
goto cleanup;
}

if (!mycms_dict_construct(keyopt_dict)) {
goto cleanup;
}

if (!util_split_string(keyopt_dict, keyopt_exp)) {
goto cleanup;
}

if (!mycms_encrypt(mycms, cipher, to, keyopt_dict, cms_out, data_pt, data_ct)) {
if (!mycms_encrypt(mycms, cipher, to, keyopts, cms_out, data_pt, data_ct)) {
goto cleanup;
}

Expand All @@ -186,8 +174,8 @@ _cmd_encrypt(
mycms_io_destruct(data_ct);
data_ct = NULL;

mycms_dict_destruct(keyopt_dict);
keyopt_dict = NULL;
mycms_list_str_free(system, keyopts);
keyopts = NULL;

while(to != NULL) {
mycms_list_blob t = to;
Expand Down Expand Up @@ -228,7 +216,7 @@ _cmd_encrypt_add(
{"recip-cert\0CERTIFICATE_EXPRESSION|recipient certificate to use", required_argument, NULL, OPT_RECIP_CERT},
{"recip-cert-pass\0PASSPHRASE_EXPRESSION|recipient certificate passphrase to use", required_argument, NULL, OPT_RECIP_CERT_PASS},
{"to\0FILE|target DER encoded certificate, may be specified several times", required_argument, NULL, OPT_TO},
{"keyopt\0KEYOPT_EXPRESSION|key options expression", required_argument, NULL, OPT_KEYOPT},
{"keyopt\0KEYOPT|key options opt:value, may be specified multiple times", required_argument, NULL, OPT_KEYOPT},
{NULL, 0, NULL, 0}
};

Expand All @@ -238,14 +226,13 @@ _cmd_encrypt_add(

const char * certificate_exp = NULL;
const char * pass_exp = NULL;
const char * keyopt_exp = NULL;

mycms_system system = mycms_context_get_system(context);
mycms mycms = NULL;
mycms_io cms_in = NULL;
mycms_io cms_out = NULL;
mycms_list_blob to = NULL;
mycms_dict keyopt_dict = NULL;
mycms_list_str keyopts = NULL;
mycms_dict certificate_dict = NULL;
mycms_dict pass_dict = NULL;
mycms_certificate certificate = NULL;
Expand Down Expand Up @@ -317,7 +304,9 @@ _cmd_encrypt_add(
}
break;
case OPT_KEYOPT:
keyopt_exp = optarg;
if (!mycms_list_str_add(system, &keyopts, optarg)) {
goto cleanup;
}
break;
default:
fprintf(stderr, "Invalid option\n");
Expand Down Expand Up @@ -382,18 +371,6 @@ _cmd_encrypt_add(
goto cleanup;
}

if ((keyopt_dict = mycms_dict_new(context)) == NULL) {
goto cleanup;
}

if (!mycms_dict_construct(keyopt_dict)) {
goto cleanup;
}

if (!util_split_string(keyopt_dict, keyopt_exp)) {
goto cleanup;
}

if (!mycms_certificate_set_passphrase_callback(certificate, _cmd_common_passphrase_callback)) {
goto cleanup;
}
Expand All @@ -414,7 +391,7 @@ _cmd_encrypt_add(
goto cleanup;
}

if (!mycms_encrypt_add(mycms, certificate, to, keyopt_dict, cms_in, cms_out)) {
if (!mycms_encrypt_add(mycms, certificate, to, keyopts, cms_in, cms_out)) {
goto cleanup;
}

Expand All @@ -437,8 +414,7 @@ _cmd_encrypt_add(
mycms_dict_destruct(pass_dict);
pass_dict = NULL;

mycms_dict_destruct(keyopt_dict);
keyopt_dict = NULL;
mycms_list_str_free(system, keyopts);

while(to != NULL) {
mycms_list_blob t = to;
Expand Down
Loading

0 comments on commit 6be2f9b

Please sign in to comment.