Skip to content

Commit

Permalink
Fix CMS encryption with key agreement when originator set
Browse files Browse the repository at this point in the history
OpenSSL currently does not support encryption with originator flag so it
should fail nicely instead of segfaulting.

Reviewed-by: Hugo Landau <hlandau@devever.net>
Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from openssl#26014)
  • Loading branch information
bukka authored and t8m committed Jan 6, 2025
1 parent 24dd635 commit 894e69e
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 55 deletions.
9 changes: 8 additions & 1 deletion apps/cms.c
Original file line number Diff line number Diff line change
Expand Up @@ -1044,8 +1044,15 @@ int cms_main(int argc, char **argv)
pwri_tmp = NULL;
}
if (!(flags & CMS_STREAM)) {
if (!CMS_final(cms, in, NULL, flags))
if (!CMS_final(cms, in, NULL, flags)) {
if (originator != NULL
&& ERR_GET_REASON(ERR_peek_error())
== CMS_R_ERROR_UNSUPPORTED_STATIC_KEY_AGREEMENT) {
BIO_printf(bio_err, "Cannot use originator for encryption\n");
goto end;
}
goto end;
}
}
} else if (operation == SMIME_ENCRYPTED_ENCRYPT) {
cms = CMS_EncryptedData_encrypt_ex(in, cipher, secret_key,
Expand Down
104 changes: 53 additions & 51 deletions crypto/cms/cms_err.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
* Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
Expand All @@ -20,77 +20,79 @@ static const ERR_STRING_DATA CMS_str_reasons[] = {
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ADD_SIGNER_ERROR), "add signer error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ATTRIBUTE_ERROR), "attribute error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CERTIFICATE_ALREADY_PRESENT),
"certificate already present"},
"certificate already present"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CERTIFICATE_HAS_NO_KEYID),
"certificate has no keyid"},
"certificate has no keyid"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CERTIFICATE_VERIFY_ERROR),
"certificate verify error"},
"certificate verify error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_AEAD_SET_TAG_ERROR),
"cipher aead set tag error"},
"cipher aead set tag error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_GET_TAG), "cipher get tag"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_INITIALISATION_ERROR),
"cipher initialisation error"},
"cipher initialisation error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR),
"cipher parameter initialisation error"},
"cipher parameter initialisation error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CMS_DATAFINAL_ERROR),
"cms datafinal error"},
"cms datafinal error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CMS_LIB), "cms lib"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENTIDENTIFIER_MISMATCH),
"contentidentifier mismatch"},
"contentidentifier mismatch"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_NOT_FOUND), "content not found"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_TYPE_MISMATCH),
"content type mismatch"},
"content type mismatch"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA),
"content type not compressed data"},
"content type not compressed data"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA),
"content type not enveloped data"},
"content type not enveloped data"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA),
"content type not signed data"},
"content type not signed data"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_VERIFY_ERROR),
"content verify error"},
"content verify error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CTRL_ERROR), "ctrl error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CTRL_FAILURE), "ctrl failure"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_DECODE_ERROR), "decode error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_DECRYPT_ERROR), "decrypt error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_GETTING_PUBLIC_KEY),
"error getting public key"},
"error getting public key"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE),
"error reading messagedigest attribute"},
"error reading messagedigest attribute"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_SETTING_KEY), "error setting key"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_SETTING_RECIPIENTINFO),
"error setting recipientinfo"},
"error setting recipientinfo"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_UNSUPPORTED_STATIC_KEY_AGREEMENT),
"error unsupported static key agreement"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR),
"ess signing certid mismatch error"},
"ess signing certid mismatch error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_ENCRYPTED_KEY_LENGTH),
"invalid encrypted key length"},
"invalid encrypted key length"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER),
"invalid key encryption parameter"},
"invalid key encryption parameter"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_KEY_LENGTH), "invalid key length"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_LABEL), "invalid label"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_OAEP_PARAMETERS),
"invalid oaep parameters"},
"invalid oaep parameters"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_KDF_PARAMETER_ERROR),
"kdf parameter error"},
"kdf parameter error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MD_BIO_INIT_ERROR), "md bio init error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH),
"messagedigest attribute wrong length"},
"messagedigest attribute wrong length"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MESSAGEDIGEST_WRONG_LENGTH),
"messagedigest wrong length"},
"messagedigest wrong length"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MSGSIGDIGEST_ERROR), "msgsigdigest error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE),
"msgsigdigest verification failure"},
"msgsigdigest verification failure"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MSGSIGDIGEST_WRONG_LENGTH),
"msgsigdigest wrong length"},
"msgsigdigest wrong length"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NEED_ONE_SIGNER), "need one signer"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_A_SIGNED_RECEIPT),
"not a signed receipt"},
"not a signed receipt"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_ENCRYPTED_DATA), "not encrypted data"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_KEK), "not kek"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_KEY_AGREEMENT), "not key agreement"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_KEY_TRANSPORT), "not key transport"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_PWRI), "not pwri"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),
"not supported for this key type"},
"not supported for this key type"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_CIPHER), "no cipher"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_CONTENT), "no content"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_CONTENT_TYPE), "no content type"},
Expand All @@ -100,69 +102,69 @@ static const ERR_STRING_DATA CMS_str_reasons[] = {
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_KEY_OR_CERT), "no key or cert"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_MATCHING_DIGEST), "no matching digest"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_MATCHING_RECIPIENT),
"no matching recipient"},
"no matching recipient"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_MATCHING_SIGNATURE),
"no matching signature"},
"no matching signature"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_MSGSIGDIGEST), "no msgsigdigest"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_PASSWORD), "no password"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_PRIVATE_KEY), "no private key"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_PUBLIC_KEY), "no public key"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_RECEIPT_REQUEST), "no receipt request"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_SIGNERS), "no signers"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_OPERATION_UNSUPPORTED),
"operation unsupported"},
"operation unsupported"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_PEER_KEY_ERROR), "peer key error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),
"private key does not match certificate"},
"private key does not match certificate"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_RECEIPT_DECODE_ERROR),
"receipt decode error"},
"receipt decode error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_RECIPIENT_ERROR), "recipient error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SHARED_INFO_ERROR), "shared info error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND),
"signer certificate not found"},
"signer certificate not found"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SIGNFINAL_ERROR), "signfinal error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SMIME_TEXT_ERROR), "smime text error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_STORE_INIT_ERROR), "store init error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_TYPE_NOT_COMPRESSED_DATA),
"type not compressed data"},
"type not compressed data"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_TYPE_NOT_DATA), "type not data"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_TYPE_NOT_DIGESTED_DATA),
"type not digested data"},
"type not digested data"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_TYPE_NOT_ENCRYPTED_DATA),
"type not encrypted data"},
"type not encrypted data"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_TYPE_NOT_ENVELOPED_DATA),
"type not enveloped data"},
"type not enveloped data"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNABLE_TO_FINALIZE_CONTEXT),
"unable to finalize context"},
"unable to finalize context"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNKNOWN_CIPHER), "unknown cipher"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNKNOWN_DIGEST_ALGORITHM),
"unknown digest algorithm"},
"unknown digest algorithm"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNKNOWN_ID), "unknown id"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM),
"unsupported compression algorithm"},
"unsupported compression algorithm"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM),
"unsupported content encryption algorithm"},
"unsupported content encryption algorithm"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_CONTENT_TYPE),
"unsupported content type"},
"unsupported content type"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_ENCRYPTION_TYPE),
"unsupported encryption type"},
"unsupported encryption type"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_KEK_ALGORITHM),
"unsupported kek algorithm"},
"unsupported kek algorithm"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM),
"unsupported key encryption algorithm"},
"unsupported key encryption algorithm"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_LABEL_SOURCE),
"unsupported label source"},
"unsupported label source"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE),
"unsupported recipientinfo type"},
"unsupported recipientinfo type"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_RECIPIENT_TYPE),
"unsupported recipient type"},
"unsupported recipient type"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_SIGNATURE_ALGORITHM),
"unsupported signature algorithm"},
"unsupported signature algorithm"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_TYPE), "unsupported type"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNWRAP_ERROR), "unwrap error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNWRAP_FAILURE), "unwrap failure"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_VERIFICATION_FAILURE),
"verification failure"},
"verification failure"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_WRAP_ERROR), "wrap error"},
{0, NULL}
};
Expand Down
7 changes: 7 additions & 0 deletions crypto/cms/cms_kari.c
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,13 @@ int ossl_cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo *cms,
oik->d.originatorKey = M_ASN1_new_of(CMS_OriginatorPublicKey);
if (!oik->d.originatorKey)
return 0;
} else {
/*
* Currently it is not possible to get public key as it is not stored
* during kari initialization.
*/
ERR_raise(ERR_LIB_CMS, CMS_R_ERROR_UNSUPPORTED_STATIC_KEY_AGREEMENT);
return 0;
}
/* Initialise KDF algorithm */
if (!ossl_cms_env_asn1_ctrl(ri, 0))
Expand Down
2 changes: 2 additions & 0 deletions crypto/err/openssl.txt
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,8 @@ CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE:114:\
error reading messagedigest attribute
CMS_R_ERROR_SETTING_KEY:115:error setting key
CMS_R_ERROR_SETTING_RECIPIENTINFO:116:error setting recipientinfo
CMS_R_ERROR_UNSUPPORTED_STATIC_KEY_AGREEMENT:196:\
error unsupported static key agreement
CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR:183:ess signing certid mismatch error
CMS_R_INVALID_ENCRYPTED_KEY_LENGTH:117:invalid encrypted key length
CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER:176:invalid key encryption parameter
Expand Down
3 changes: 2 additions & 1 deletion doc/man1/openssl-cms.pod.in
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,8 @@ See L<openssl-format-options(1)> for details.
=item B<-originator> I<file>

A certificate of the originator of the encrypted message. Necessary for
decryption when Key Agreement is in use for a shared key.
decryption when Key Agreement is in use for a shared key. Currently, not
allowed for encryption.

=item B<-recip> I<file>

Expand Down
2 changes: 1 addition & 1 deletion include/crypto/cmserr.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
* Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
Expand Down
3 changes: 2 additions & 1 deletion include/openssl/cmserr.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
* Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
Expand Down Expand Up @@ -49,6 +49,7 @@
# define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 114
# define CMS_R_ERROR_SETTING_KEY 115
# define CMS_R_ERROR_SETTING_RECIPIENTINFO 116
# define CMS_R_ERROR_UNSUPPORTED_STATIC_KEY_AGREEMENT 196
# define CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR 183
# define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH 117
# define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER 176
Expand Down
16 changes: 16 additions & 0 deletions test/recipes/80-test_cms.t
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,22 @@ ok(!run(app(['openssl', 'cms', '-verify',
])),
"issue#19643");

# Check that kari encryption with originator does not segfault
with({ exit_checker => sub { return shift == 3; } },
sub {
SKIP: {
skip "EC is not supported in this build", 1 if $no_ec;

ok(run(app(['openssl', 'cms', '-encrypt',
'-in', srctop_file("test", "smcont.txt"), '-aes128',
'-recip', catfile($smdir, "smec1.pem"),
'-originator', catfile($smdir, "smec3.pem"),
'-inkey', catfile($smdir, "smec3.pem")
])),
"Check failure for currently not supported kari encryption with static originator");
}
});

# Check that we get the expected failure return code
with({ exit_checker => sub { return shift == 6; } },
sub {
Expand Down

0 comments on commit 894e69e

Please sign in to comment.