mirror of
https://github.com/openssl/openssl.git
synced 2025-02-17 14:32:04 +08:00
apps/cms.c: Make -sign and -verify handle binary input
Fixes #8940 Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/12959)
This commit is contained in:
parent
7c701c590d
commit
6b83d032a6
55
apps/cms.c
55
apps/cms.c
@ -159,7 +159,7 @@ const OPTIONS cms_options[] = {
|
|||||||
{"nodetach", OPT_NODETACH, '-', "Use opaque signing"},
|
{"nodetach", OPT_NODETACH, '-', "Use opaque signing"},
|
||||||
{"nosmimecap", OPT_NOSMIMECAP, '-', "Omit the SMIMECapabilities attribute"},
|
{"nosmimecap", OPT_NOSMIMECAP, '-', "Omit the SMIMECapabilities attribute"},
|
||||||
{"noattr", OPT_NOATTR, '-', "Don't include any signed attributes"},
|
{"noattr", OPT_NOATTR, '-', "Don't include any signed attributes"},
|
||||||
{"binary", OPT_BINARY, '-', "Don't translate message to text"},
|
{"binary", OPT_BINARY, '-', "Treat input as binary: do not translate to canonical form"},
|
||||||
{"keyid", OPT_KEYID, '-', "Use subject key identifier"},
|
{"keyid", OPT_KEYID, '-', "Use subject key identifier"},
|
||||||
{"nosigs", OPT_NOSIGS, '-', "Don't verify message signature"},
|
{"nosigs", OPT_NOSIGS, '-', "Don't verify message signature"},
|
||||||
{"nocerts", OPT_NOCERTS, '-',
|
{"nocerts", OPT_NOCERTS, '-',
|
||||||
@ -227,7 +227,7 @@ const OPTIONS cms_options[] = {
|
|||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
static CMS_ContentInfo *load_content_info(int informat, BIO *in, BIO **indata,
|
static CMS_ContentInfo *load_content_info(int informat, BIO *in, int flags, BIO **indata,
|
||||||
const char *name,
|
const char *name,
|
||||||
OSSL_LIB_CTX *libctx,
|
OSSL_LIB_CTX *libctx,
|
||||||
const char *propq)
|
const char *propq)
|
||||||
@ -241,7 +241,7 @@ static CMS_ContentInfo *load_content_info(int informat, BIO *in, BIO **indata,
|
|||||||
}
|
}
|
||||||
switch (informat) {
|
switch (informat) {
|
||||||
case FORMAT_SMIME:
|
case FORMAT_SMIME:
|
||||||
ci = SMIME_read_CMS_ex(in, indata, &ret);
|
ci = SMIME_read_CMS_ex(in, flags, indata, &ret);
|
||||||
break;
|
break;
|
||||||
case FORMAT_PEM:
|
case FORMAT_PEM:
|
||||||
ci = PEM_read_bio_CMS(in, &ret, NULL, NULL);
|
ci = PEM_read_bio_CMS(in, &ret, NULL, NULL);
|
||||||
@ -263,6 +263,29 @@ err:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void warn_binary(const char *file)
|
||||||
|
{
|
||||||
|
BIO *bio;
|
||||||
|
unsigned char linebuf[1024], *cur, *end;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if ((bio = bio_open_default(file, 'r', FORMAT_BINARY)) == NULL)
|
||||||
|
return; /* cannot give a proper warning since there is an error */
|
||||||
|
while ((len = BIO_read(bio, linebuf, sizeof(linebuf))) > 0) {
|
||||||
|
end = linebuf + len;
|
||||||
|
for (cur = linebuf; cur < end; cur++) {
|
||||||
|
if (*cur == '\0' || *cur >= 0x80) {
|
||||||
|
BIO_printf(bio_err, "Warning: input file '%s' contains %s"
|
||||||
|
" character; better use -binary option\n",
|
||||||
|
file, *cur == '\0' ? "NUL" : "8-bit");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BIO_free(bio);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int cms_main(int argc, char **argv)
|
int cms_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
CONF *conf = NULL;
|
CONF *conf = NULL;
|
||||||
@ -452,7 +475,7 @@ int cms_main(int argc, char **argv)
|
|||||||
OPT_FMT_PEMDER | OPT_FMT_SMIME, &rctformat))
|
OPT_FMT_PEMDER | OPT_FMT_SMIME, &rctformat))
|
||||||
goto opthelp;
|
goto opthelp;
|
||||||
} else {
|
} else {
|
||||||
rcms = load_content_info(rctformat, rctin, NULL, "recipient",
|
rcms = load_content_info(rctformat, rctin, 0, NULL, "recipient",
|
||||||
libctx, app_get0_propq());
|
libctx, app_get0_propq());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -784,13 +807,12 @@ int cms_main(int argc, char **argv)
|
|||||||
if (!(operation & SMIME_SIGNERS))
|
if (!(operation & SMIME_SIGNERS))
|
||||||
flags &= ~CMS_DETACHED;
|
flags &= ~CMS_DETACHED;
|
||||||
|
|
||||||
if (!(operation & SMIME_OP))
|
if ((flags & CMS_BINARY) != 0) {
|
||||||
if (flags & CMS_BINARY)
|
if (!(operation & SMIME_OP))
|
||||||
outformat = FORMAT_BINARY;
|
outformat = FORMAT_BINARY;
|
||||||
|
if (!(operation & SMIME_IP))
|
||||||
if (!(operation & SMIME_IP))
|
|
||||||
if (flags & CMS_BINARY)
|
|
||||||
informat = FORMAT_BINARY;
|
informat = FORMAT_BINARY;
|
||||||
|
}
|
||||||
|
|
||||||
if (operation == SMIME_ENCRYPT) {
|
if (operation == SMIME_ENCRYPT) {
|
||||||
if (!cipher) {
|
if (!cipher) {
|
||||||
@ -867,16 +889,22 @@ int cms_main(int argc, char **argv)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
in = bio_open_default(infile, 'r', informat);
|
if ((flags & CMS_BINARY) == 0)
|
||||||
|
warn_binary(infile);
|
||||||
|
in = bio_open_default(infile, 'r',
|
||||||
|
(flags & CMS_BINARY) != 0 ? FORMAT_BINARY : informat);
|
||||||
if (in == NULL)
|
if (in == NULL)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
if (operation & SMIME_IP) {
|
if (operation & SMIME_IP) {
|
||||||
cms = load_content_info(informat, in, &indata, "SMIME", libctx, app_get0_propq());
|
cms = load_content_info(informat, in, flags, &indata, "SMIME",
|
||||||
|
libctx, app_get0_propq());
|
||||||
if (cms == NULL)
|
if (cms == NULL)
|
||||||
goto end;
|
goto end;
|
||||||
if (contfile != NULL) {
|
if (contfile != NULL) {
|
||||||
BIO_free(indata);
|
BIO_free(indata);
|
||||||
|
if ((flags & CMS_BINARY) == 0)
|
||||||
|
warn_binary(contfile);
|
||||||
if ((indata = BIO_new_file(contfile, "rb")) == NULL) {
|
if ((indata = BIO_new_file(contfile, "rb")) == NULL) {
|
||||||
BIO_printf(bio_err, "Can't read content file %s\n", contfile);
|
BIO_printf(bio_err, "Can't read content file %s\n", contfile);
|
||||||
goto end;
|
goto end;
|
||||||
@ -897,13 +925,14 @@ int cms_main(int argc, char **argv)
|
|||||||
|
|
||||||
if (rctfile != NULL) {
|
if (rctfile != NULL) {
|
||||||
char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r";
|
char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r";
|
||||||
|
|
||||||
if ((rctin = BIO_new_file(rctfile, rctmode)) == NULL) {
|
if ((rctin = BIO_new_file(rctfile, rctmode)) == NULL) {
|
||||||
BIO_printf(bio_err, "Can't open receipt file %s\n", rctfile);
|
BIO_printf(bio_err, "Can't open receipt file %s\n", rctfile);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
rcms = load_content_info(rctformat, rctin, NULL, "recipient", libctx,
|
rcms = load_content_info(rctformat, rctin, 0, NULL, "recipient", libctx,
|
||||||
app_get0_propq());
|
app_get0_propq);
|
||||||
if (rcms == NULL)
|
if (rcms == NULL)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ use warnings;
|
|||||||
|
|
||||||
use POSIX;
|
use POSIX;
|
||||||
use File::Spec::Functions qw/catfile/;
|
use File::Spec::Functions qw/catfile/;
|
||||||
use File::Compare qw/compare_text/;
|
use File::Compare qw/compare_text compare/;
|
||||||
use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file bldtop_dir bldtop_file/;
|
use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file bldtop_dir bldtop_file/;
|
||||||
|
|
||||||
use OpenSSL::Test::Utils;
|
use OpenSSL::Test::Utils;
|
||||||
@ -50,8 +50,7 @@ my ($no_des, $no_dh, $no_dsa, $no_ec, $no_ec2m, $no_rc2, $no_zlib)
|
|||||||
|
|
||||||
$no_rc2 = 1 if disabled("legacy");
|
$no_rc2 = 1 if disabled("legacy");
|
||||||
|
|
||||||
plan tests =>
|
plan tests => 11;
|
||||||
+ 10;
|
|
||||||
|
|
||||||
unless ($no_fips) {
|
unless ($no_fips) {
|
||||||
@config = ( "-config", srctop_file("test", "fips-and-base.cnf") );
|
@config = ( "-config", srctop_file("test", "fips-and-base.cnf") );
|
||||||
@ -812,6 +811,48 @@ subtest "CAdES ko tests\n" => sub {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
subtest "CMS binary input tests\n" => sub {
|
||||||
|
my $input = srctop_file("test", "smcont.bin");
|
||||||
|
my $signed = "smcont.signed";
|
||||||
|
my $verified = "smcont.verified";
|
||||||
|
my $cert = srctop_file("test", "certs", "ee-self-signed.pem");
|
||||||
|
my $key = srctop_file("test", "certs", "ee-key.pem");
|
||||||
|
|
||||||
|
plan tests => 11;
|
||||||
|
|
||||||
|
ok(run(app(["openssl", "cms", "-sign", "-md", "sha256",
|
||||||
|
"-signer", $cert, "-inkey", $key,
|
||||||
|
"-binary", "-in", $input, "-out", $signed])),
|
||||||
|
"sign binary input with -binary");
|
||||||
|
ok(run(app(["openssl", "cms", "-verify", "-CAfile", $cert,
|
||||||
|
"-binary", "-in", $signed, "-out", $verified])),
|
||||||
|
"verify binary input with -binary");
|
||||||
|
is(compare($input, $verified), 0, "binary input retained with -binary");
|
||||||
|
ok(run(app(["openssl", "cms", "-sign", "-md", "sha256",
|
||||||
|
"-signer", $cert, "-inkey", $key,
|
||||||
|
"-in", $input, "-out", $signed])),
|
||||||
|
"sign binary input without -binary");
|
||||||
|
ok(run(app(["openssl", "cms", "-verify", "-CAfile", $cert,
|
||||||
|
"-in", $signed, "-out", $verified])),
|
||||||
|
"verify binary input without -binary");
|
||||||
|
is(compare($input, $verified), 1, "binary input not retained without -binary");
|
||||||
|
ok(!run(app(["openssl", "cms", "-verify", "-CAfile", $cert, "-crlfeol",
|
||||||
|
"-binary", "-in", $signed, "-out", $verified])),
|
||||||
|
"verify binary input wrong crlfeol");
|
||||||
|
|
||||||
|
ok(run(app(["openssl", "cms", "-sign", "-md", "sha256", "-crlfeol",
|
||||||
|
"-signer", $cert, "-inkey", $key,
|
||||||
|
"-binary", "-in", $input, "-out", $signed.".crlf"])),
|
||||||
|
"sign binary input crlfeol");
|
||||||
|
ok(run(app(["openssl", "cms", "-verify", "-CAfile", $cert, "-crlfeol",
|
||||||
|
"-binary", "-in", $signed.".crlf", "-out", $verified.".crlf"])),
|
||||||
|
"verify binary input crlfeol");
|
||||||
|
is(compare($input, $verified.".crlf"), 0);
|
||||||
|
ok(!run(app(["openssl", "cms", "-verify", "-CAfile", $cert,
|
||||||
|
"-binary", "-in", $signed.".crlf", "-out", $verified.".crlf"])),
|
||||||
|
"verify binary input missing crlfeol");
|
||||||
|
};
|
||||||
|
|
||||||
sub check_availability {
|
sub check_availability {
|
||||||
my $tnam = shift;
|
my $tnam = shift;
|
||||||
|
|
||||||
|
BIN
test/smcont.bin
Normal file
BIN
test/smcont.bin
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user