Add SSL_set_signing_algorithm_prefs.
This gives us a sigalg-based API for configuring signing algorithms.
Change-Id: Ib746a56ebd1061eadd2620cdb140d5171b59bc02
Reviewed-on: https://boringssl-review.googlesource.com/8784
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index 02af8f2..3cfbeb3 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -315,6 +315,14 @@
}
}
+ if (!config->signing_prefs.empty()) {
+ std::vector<uint16_t> u16s(config->signing_prefs.begin(),
+ config->signing_prefs.end());
+ if (!SSL_set_signing_algorithm_prefs(ssl, u16s.data(), u16s.size())) {
+ return false;
+ }
+ }
+
if (!config->key_file.empty()) {
*out_pkey = LoadPrivateKey(config->key_file.c_str());
if (!*out_pkey) {
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 5bbf57d..5a3256c 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -259,8 +259,6 @@
messageLen int
// messageCount is the number of test messages that will be sent.
messageCount int
- // digestPrefs is the list of digest preferences from the client.
- digestPrefs string
// certFile is the path to the certificate to use for the server.
certFile string
// keyFile is the path to the private key to use for the server.
@@ -744,11 +742,6 @@
}
}
- if test.digestPrefs != "" {
- flags = append(flags, "-digest-prefs")
- flags = append(flags, test.digestPrefs)
- }
-
if test.protocol == dtls {
flags = append(flags, "-dtls")
}
@@ -4736,6 +4729,13 @@
TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
}
+ var allAlgorithms []signatureAlgorithm
+ for _, alg := range testSignatureAlgorithms {
+ if alg.id != 0 {
+ allAlgorithms = append(allAlgorithms, alg.id)
+ }
+ }
+
// Make sure each signature algorithm works. Include some fake values in
// the list and ensure they're ignored.
for _, alg := range testSignatureAlgorithms {
@@ -4899,6 +4899,41 @@
expectedError: ":BAD_SIGNATURE:",
})
}
+
+ if ver.version >= VersionTLS12 && !shouldFail {
+ testCases = append(testCases, testCase{
+ name: "ClientAuth-Sign-Negotiate" + suffix,
+ config: Config{
+ MaxVersion: ver.version,
+ ClientAuth: RequireAnyClientCert,
+ VerifySignatureAlgorithms: allAlgorithms,
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)),
+ "-key-file", path.Join(*resourceDir, getShimKey(alg.cert)),
+ "-enable-all-curves",
+ "-signing-prefs", strconv.Itoa(int(alg.id)),
+ },
+ expectedPeerSignatureAlgorithm: alg.id,
+ })
+
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "ServerAuth-Sign-Negotiate" + suffix,
+ config: Config{
+ MaxVersion: ver.version,
+ CipherSuites: signingCiphers,
+ VerifySignatureAlgorithms: allAlgorithms,
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)),
+ "-key-file", path.Join(*resourceDir, getShimKey(alg.cert)),
+ "-enable-all-curves",
+ "-signing-prefs", strconv.Itoa(int(alg.id)),
+ },
+ expectedPeerSignatureAlgorithm: alg.id,
+ })
+ }
}
}
@@ -5095,6 +5130,24 @@
//
// TODO(davidben): Add TLS 1.3 versions of these.
testCases = append(testCases, testCase{
+ name: "NoCommonAlgorithms-Digests",
+ config: Config{
+ MaxVersion: VersionTLS12,
+ ClientAuth: RequireAnyClientCert,
+ VerifySignatureAlgorithms: []signatureAlgorithm{
+ signatureRSAPKCS1WithSHA512,
+ signatureRSAPKCS1WithSHA1,
+ },
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
+ "-digest-prefs", "SHA256",
+ },
+ shouldFail: true,
+ expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
+ })
+ testCases = append(testCases, testCase{
name: "NoCommonAlgorithms",
config: Config{
MaxVersion: VersionTLS12,
@@ -5107,8 +5160,26 @@
flags: []string{
"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
"-key-file", path.Join(*resourceDir, rsaKeyFile),
+ "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)),
},
- digestPrefs: "SHA256",
+ shouldFail: true,
+ expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
+ })
+ testCases = append(testCases, testCase{
+ name: "NoCommonAlgorithms-TLS13",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ ClientAuth: RequireAnyClientCert,
+ VerifySignatureAlgorithms: []signatureAlgorithm{
+ signatureRSAPSSWithSHA512,
+ signatureRSAPSSWithSHA384,
+ },
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
+ "-signing-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA256)),
+ },
shouldFail: true,
expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
})
@@ -5125,8 +5196,8 @@
flags: []string{
"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
"-key-file", path.Join(*resourceDir, rsaKeyFile),
+ "-digest-prefs", "SHA256,SHA1",
},
- digestPrefs: "SHA256,SHA1",
expectedPeerSignatureAlgorithm: signatureRSAPKCS1WithSHA256,
})
testCases = append(testCases, testCase{
@@ -5141,8 +5212,8 @@
flags: []string{
"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
"-key-file", path.Join(*resourceDir, rsaKeyFile),
+ "-digest-prefs", "SHA512,SHA256,SHA1",
},
- digestPrefs: "SHA512,SHA256,SHA1",
expectedPeerSignatureAlgorithm: signatureRSAPKCS1WithSHA1,
})
testCases = append(testCases, testCase{
@@ -5164,6 +5235,28 @@
expectedPeerSignatureAlgorithm: signatureRSAPKCS1WithSHA256,
})
+ // Test that the signing preference list may include extra algorithms
+ // without negotiation problems.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "FilterExtraAlgorithms",
+ config: Config{
+ MaxVersion: VersionTLS12,
+ VerifySignatureAlgorithms: []signatureAlgorithm{
+ signatureRSAPKCS1WithSHA256,
+ },
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
+ "-signing-prefs", strconv.Itoa(int(fakeSigAlg1)),
+ "-signing-prefs", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)),
+ "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)),
+ "-signing-prefs", strconv.Itoa(int(fakeSigAlg2)),
+ },
+ expectedPeerSignatureAlgorithm: signatureRSAPKCS1WithSHA256,
+ })
+
// In TLS 1.2 and below, ECDSA uses the curve list rather than the
// signature algorithms.
testCases = append(testCases, testCase{
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index 1c3302e..24a4646 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -153,6 +153,10 @@
{ "-initial-timeout-duration-ms", &TestConfig::initial_timeout_duration_ms },
};
+const Flag<std::vector<int>> kIntVectorFlags[] = {
+ { "-signing-prefs", &TestConfig::signing_prefs },
+};
+
} // namespace
bool ParseConfig(int argc, char **argv, TestConfig *out_config) {
@@ -208,6 +212,20 @@
continue;
}
+ std::vector<int> *int_vector_field =
+ FindField(out_config, kIntVectorFlags, argv[i]);
+ if (int_vector_field) {
+ i++;
+ if (i >= argc) {
+ fprintf(stderr, "Missing parameter\n");
+ return false;
+ }
+
+ // Each instance of the flag adds to the list.
+ int_vector_field->push_back(atoi(argv[i]));
+ continue;
+ }
+
fprintf(stderr, "Unknown argument: %s\n", argv[i]);
return false;
}
diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h
index b3c858d..4ee717e 100644
--- a/ssl/test/test_config.h
+++ b/ssl/test/test_config.h
@@ -16,6 +16,7 @@
#define HEADER_TEST_CONFIG
#include <string>
+#include <vector>
struct TestConfig {
@@ -25,6 +26,7 @@
bool resume = false;
bool fallback_scsv = false;
std::string digest_prefs;
+ std::vector<int> signing_prefs;
std::string key_file;
std::string cert_file;
std::string expected_server_name;