summaryrefslogtreecommitdiffstats
path: root/test/recipes/80-test_cms.t
diff options
context:
space:
mode:
authorClemens Lang <cllang@redhat.com>2022-11-21 14:33:57 +0100
committerTomas Mraz <tomas@openssl.org>2022-12-08 11:02:52 +0100
commit5a3bbe1712435d577bbc5ec046906979e8471d8b (patch)
tree0baeafcfd65f2db8dc64c27689f3b63d51421ef2 /test/recipes/80-test_cms.t
parentcae72eefc3fbdd2f7a1a065f237bf3943619bca2 (diff)
Obtain PSS salt length from provider
Rather than computing the PSS salt length again in core using ossl_rsa_ctx_to_pss_string, which calls rsa_ctx_to_pss and computes the salt length, obtain it from the provider using the OSSL_SIGNATURE_PARAM_ALGORITHM_ID param to handle the case where the interpretation of the magic constants in the provider differs from that of OpenSSL core. Add tests that verify that the rsa_pss_saltlen:max, rsa_pss_saltlen:<integer> and rsa_pss_saltlen:digest options work and put the computed digest length into the CMS_ContentInfo struct when using CMS. Do not add a test for the salt length generated by a provider when no specific rsa_pss_saltlen option is defined, since that number could change between providers and provider versions, and we want to preserve compatibility with older providers. Signed-off-by: Clemens Lang <cllang@redhat.com> Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/19724)
Diffstat (limited to 'test/recipes/80-test_cms.t')
-rw-r--r--test/recipes/80-test_cms.t76
1 files changed, 76 insertions, 0 deletions
diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t
index f9d19df6b9..f6794be891 100644
--- a/test/recipes/80-test_cms.t
+++ b/test/recipes/80-test_cms.t
@@ -64,6 +64,7 @@ my @prov = ("-provider-path", $provpath,
@config,
"-provider", $provname);
+my $smrsa1024 = catfile($smdir, "smrsa1024.pem");
my $smrsa1 = catfile($smdir, "smrsa1.pem");
my $smroot = catfile($smdir, "smroot.pem");
@@ -498,6 +499,7 @@ my @smime_cms_param_tests = (
"-signer", $smrsa1,
"-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_pss_saltlen:max",
"-out", "{output}.cms" ],
+ sub { my %opts = @_; rsapssSaltlen("$opts{output}.cms") == 222; },
[ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
"-CAfile", $smroot, "-out", "{output}.txt" ],
\&final_compare
@@ -523,6 +525,29 @@ my @smime_cms_param_tests = (
\&final_compare
],
+ [ "signed content test streaming PEM format, RSA keys, PSS signature, saltlen=16",
+ [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
+ "-signer", $smrsa1, "-md", "sha256",
+ "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_pss_saltlen:16",
+ "-out", "{output}.cms" ],
+ sub { my %opts = @_; rsapssSaltlen("$opts{output}.cms") == 16; },
+ [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
+ "-CAfile", $smroot, "-out", "{output}.txt" ],
+ \&final_compare
+ ],
+
+ [ "signed content test streaming PEM format, RSA keys, PSS signature, saltlen=digest",
+ [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
+ "-signer", $smrsa1, "-md", "sha256",
+ "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_pss_saltlen:digest",
+ "-out", "{output}.cms" ],
+ # digest is SHA-256, which produces 32 bytes of output
+ sub { my %opts = @_; rsapssSaltlen("$opts{output}.cms") == 32; },
+ [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
+ "-CAfile", $smroot, "-out", "{output}.txt" ],
+ \&final_compare
+ ],
+
[ "enveloped content test streaming S/MIME format, DES, OAEP default parameters",
[ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
"-stream", "-out", "{output}.cms",
@@ -738,6 +763,57 @@ sub contentType_matches {
return scalar(@c);
}
+sub rsapssSaltlen {
+ my ($in) = @_;
+ my $exit = 0;
+
+ my @asn1parse = run(app(["openssl", "asn1parse", "-in", $in, "-dump"]),
+ capture => 1,
+ statusvar => $exit);
+ return -1 if $exit != 0;
+
+ my $pssparam_offset = -1;
+ while ($_ = shift @asn1parse) {
+ chomp;
+ next unless /:rsassaPss$/;
+ # This line contains :rsassaPss, the next line contains a raw dump of the
+ # RSA_PSS_PARAMS sequence; obtain its offset
+ $_ = shift @asn1parse;
+ if (/^\s*(\d+):/) {
+ $pssparam_offset = int($1);
+ }
+ }
+
+ if ($pssparam_offset == -1) {
+ note "Failed to determine RSA_PSS_PARAM offset in CMS. " +
+ "Was the file correctly signed with RSASSA-PSS?";
+ return -1;
+ }
+
+ my @pssparam = run(app(["openssl", "asn1parse", "-in", $in,
+ "-strparse", $pssparam_offset]),
+ capture => 1,
+ statusvar => $exit);
+ return -1 if $exit != 0;
+
+ my $saltlen = -1;
+ # Can't use asn1parse -item RSA_PSS_PARAMS here, because that's deprecated.
+ # This assumes the salt length is the last field, which may possibly be
+ # incorrect if there is a non-standard trailer field, but there almost never
+ # is in PSS.
+ if ($pssparam[-1] =~ /prim:\s+INTEGER\s+:([A-Fa-f0-9]+)$/) {
+ $saltlen = hex($1);
+ }
+
+ if ($saltlen == -1) {
+ note "Failed to determine salt length from RSA_PSS_PARAM struct. " +
+ "Was the file correctly signed with RSASSA-PSS?";
+ return -1;
+ }
+
+ return $saltlen;
+}
+
subtest "CMS Check the content type attribute is added for additional signers\n" => sub {
plan tests => (scalar @contenttype_cms_test);