608a026494
RFC 3447, section 8.2.2, steps 3 and 4 states that verifiers must encode the DigestInfo struct and then compare the result against the public key operation result. This implies that one and only one encoding is legal. OpenSSL instead parses with crypto/asn1, then checks that the encoding round-trips, and allows some variations for the parameter. Sufficient laxness in this area can allow signature forgeries, as described in https://www.imperialviolet.org/2014/09/26/pkcs1.html Although there aren't known attacks against OpenSSL's current scheme, this change makes OpenSSL implement the algorithm as specified. This avoids the uncertainty and, more importantly, helps grow a healthy ecosystem. Laxness beyond the spec, particularly in implementations which enjoy wide use, risks harm to the ecosystem for all. A signature producer which only tests against OpenSSL may not notice bugs and accidentally become widely deployed. Thus implementations have a responsibility to honor the specification as tightly as is practical. In some cases, the damage is permanent and the spec deviation and security risk becomes a tax all implementors must forever pay, but not here. Both BoringSSL and Go successfully implemented and deployed RSASSA-PKCS1-v1_5 as specified since their respective beginnings, so this change should be compatible enough to pin down in future OpenSSL releases. See also https://tools.ietf.org/html/draft-thomson-postel-was-wrong-00 As a bonus, by not having to deal with sign/verify differences, this version is also somewhat clearer. It also more consistently enforces digest lengths in the verify_recover codepath. The NID_md5_sha1 codepath wasn't quite doing this right. Reviewed-by: Kurt Roeckx <kurt@roeckx.be> Reviewed-by: Rich Salz <rsalz@openssl.org> GH: #1474 |
||
---|---|---|
.. | ||
certs | ||
ct | ||
d2i-tests | ||
ocsp-tests | ||
ossl_shim | ||
recipes | ||
smime-certs | ||
ssl-tests | ||
testlib/OpenSSL | ||
aborttest.c | ||
afalgtest.c | ||
asn1_internal_test.c | ||
asynciotest.c | ||
asynctest.c | ||
bad_dtls_test.c | ||
bftest.c | ||
bio_enc_test.c | ||
bioprinttest.c | ||
bntest.c | ||
build.info | ||
CAss.cnf | ||
CAssdh.cnf | ||
CAssdsa.cnf | ||
CAssrsa.cnf | ||
casttest.c | ||
CAtsa.cnf | ||
cipher_overhead_test.c | ||
cipherlist_test.c | ||
clienthellotest.c | ||
cms-examples.pl | ||
constant_time_test.c | ||
ct_test.c | ||
d2i_test.c | ||
danetest.c | ||
danetest.in | ||
danetest.pem | ||
destest.c | ||
dhtest.c | ||
dsatest.c | ||
dtls_mtu_test.c | ||
dtlstest.c | ||
dtlsv1listentest.c | ||
ecdhtest.c | ||
ecdhtest_cavs.h | ||
ecdsatest.c | ||
ectest.c | ||
enginetest.c | ||
evp_extra_test.c | ||
evp_test.c | ||
evptests.txt | ||
exdatatest.c | ||
exptest.c | ||
generate_buildtest.pl | ||
generate_ssl_tests.pl | ||
gmdifftest.c | ||
handshake_helper.c | ||
handshake_helper.h | ||
heartbeat_test.c | ||
hmactest.c | ||
ideatest.c | ||
igetest.c | ||
md2test.c | ||
md4test.c | ||
md5test.c | ||
mdc2_internal_test.c | ||
mdc2test.c | ||
memleaktest.c | ||
methtest.c | ||
modes_internal_test.c | ||
P1ss.cnf | ||
P2ss.cnf | ||
p5_crpt2_test.c | ||
packettest.c | ||
pbelutest.c | ||
pkcs7-1.pem | ||
pkcs7.pem | ||
pkits-test.pl | ||
poly1305_internal_test.c | ||
r160test.c | ||
randtest.c | ||
rc2test.c | ||
rc4test.c | ||
rc5test.c | ||
README | ||
README.external | ||
README.ssltest.md | ||
rmdtest.c | ||
rsa_test.c | ||
run_tests.pl | ||
sanitytest.c | ||
secmemtest.c | ||
serverinfo.pem | ||
sha1test.c | ||
sha256t.c | ||
sha512t.c | ||
shibboleth.pfx | ||
shlibloadtest.c | ||
smcont.txt | ||
srptest.c | ||
ssl_test.c | ||
ssl_test.tmpl | ||
ssl_test_ctx.c | ||
ssl_test_ctx.h | ||
ssl_test_ctx_test.c | ||
ssl_test_ctx_test.conf | ||
sslapitest.c | ||
ssltest_old.c | ||
ssltestlib.c | ||
ssltestlib.h | ||
Sssdsa.cnf | ||
Sssrsa.cnf | ||
test.cnf | ||
testcrl.pem | ||
testdsa.pem | ||
testdsapub.pem | ||
testec-p256.pem | ||
testecpub-p256.pem | ||
testp7.pem | ||
testreq2.pem | ||
testrsa.pem | ||
testrsapub.pem | ||
testsid.pem | ||
testutil.c | ||
testutil.h | ||
testx509.pem | ||
threadstest.c | ||
Uss.cnf | ||
v3-cert1.pem | ||
v3-cert2.pem | ||
v3ext.c | ||
v3nametest.c | ||
verify_extra_test.c | ||
wp_test.c | ||
wpackettest.c | ||
x509_internal_test.c | ||
x509aux.c |
How to add recipes ================== For any test that you want to perform, you write a script located in test/recipes/, named {nn}-test_{name}.t, where {nn} is a two digit number and {name} is a unique name of your choice. Please note that if a test involves a new testing executable, you will need to do some additions in test/Makefile. More on this later. Naming conventions ================= A test executable is named test/{name}test.c A test recipe is named test/recipes/{nn}-test_{name}.t, where {nn} is a two digit number and {name} is a unique name of your choice. The number {nn} is (somewhat loosely) grouped as follows: 05 individual symmetric cipher algorithms 10 math (bignum) 15 individual asymmetric cipher algorithms 20 openssl commands (some otherwise not tested) 25 certificate forms, generation and verification 30 engine and evp 70 PACKET layer 80 "larger" protocols (CA, CMS, OCSP, SSL, TSA) 90 misc A recipe that just runs a test executable ========================================= A script that just runs a program looks like this: #! /usr/bin/perl use OpenSSL::Test::Simple; simple_test("test_{name}", "{name}test", "{name}"); {name} is the unique name you have chosen for your test. The second argument to `simple_test' is the test executable, and `simple_test' expects it to be located in test/ For documentation on OpenSSL::Test::Simple, do `perldoc test/testlib/OpenSSL/Test/Simple.pm'. A recipe that runs a more complex test ====================================== For more complex tests, you will need to read up on Test::More and OpenSSL::Test. Test::More is normally preinstalled, do `man Test::More' for documentation. For OpenSSL::Test, do `perldoc test/testlib/OpenSSL/Test.pm'. A script to start from could be this: #! /usr/bin/perl use strict; use warnings; use OpenSSL::Test; setup("test_{name}"); plan tests => 2; # The number of tests being performed ok(test1, "test1"); ok(test2, "test1"); sub test1 { # test feature 1 } sub test2 { # test feature 2 } Changes to test/Makefile ======================== Whenever a new test involves a new test executable you need to do the following (at all times, replace {NAME} and {name} with the name of your test): * among the variables for test executables at the beginning, add a line like this: {NAME}TEST= {name}test * add `$({NAME}TEST)$(EXE_EXT)' to the assignment of EXE: * add `$({NAME}TEST).o' to the assignment of OBJ: * add `$({NAME}TEST).c' to the assignment of SRC: * add the following lines for building the executable: $({NAME}TEST)$(EXE_EXT): $({NAME}TEST).o $(DLIBCRYPTO) @target=$({NAME}TEST); $(BUILD_CMD)