@ -102,6 +102,10 @@ type ShimConfiguration struct {
// This is currently used to control tests that enable all curves but may
// automatically disable tests in the future.
AllCurves [ ] int
// AllSignatureAlgorithms is the list of all signature algorithm code points
// supported by the shim.
AllSignatureAlgorithms [ ] int
}
// Setup shimConfig defaults aligning with BoringSSL.
@ -390,12 +394,7 @@ func createDelegatedCredential(config delegatedCredentialConfig, parentDER []byt
dc = append ( dc , pubBytes ... )
var dummyConfig Config
parentSigner , err := getSigner ( tlsVersion , parentPriv , & dummyConfig , config . algo , false /* not for verification */ )
if err != nil {
return nil , nil , err
}
parentSignature , err := parentSigner . signMessage ( parentPriv , & dummyConfig , delegatedCredentialSignedMessage ( dc , config . algo , parentDER ) )
parentSignature , err := signMessage ( false /* server */ , tlsVersion , parentPriv , & dummyConfig , config . algo , delegatedCredentialSignedMessage ( dc , config . algo , parentDER ) )
if err != nil {
return nil , nil , err
}
@ -1645,16 +1644,16 @@ func runTest(statusChan chan statusMsg, test *testCase, shimPath string, mallocN
case failed && ! test . shouldFail :
msg = "unexpected failure"
case ! failed && test . shouldFail :
msg = "unexpected success"
msg = fmt . Sprintf ( "unexpected success (wanted failure with %q / %q) " , expectedError , test . expectedLocalError )
case failed && ! correctFailure :
msg = "bad error (wanted '" + expectedError + "' / '" + test . expectedLocalError + "' )"
msg = fmt . Sprintf ( "bad error (wanted %q / %q)" , expectedError , test . expectedLocalError )
case mustFail :
msg = "test failure"
default :
panic ( "internal error" )
}
return fmt . Errorf ( "%s: local error '%s', child error '%s' , stdout:\n%s\nstderr:\n%s\n%s" , msg , localError , childError , stdout , stderr , extraStderr )
return fmt . Errorf ( "%s: local error %q, child error %q , stdout:\n%s\nstderr:\n%s\n%s" , msg , localError , childError , stdout , stderr , extraStderr )
}
if len ( extraStderr ) > 0 || ( ! failed && len ( stderr ) > 0 ) {
@ -9894,6 +9893,7 @@ var testSignatureAlgorithms = []struct {
} {
{ "RSA_PKCS1_SHA1" , signatureRSAPKCS1WithSHA1 , testCertRSA } ,
{ "RSA_PKCS1_SHA256" , signatureRSAPKCS1WithSHA256 , testCertRSA } ,
{ "RSA_PKCS1_SHA256_LEGACY" , signatureRSAPKCS1WithSHA256Legacy , testCertRSA } ,
{ "RSA_PKCS1_SHA384" , signatureRSAPKCS1WithSHA384 , testCertRSA } ,
{ "RSA_PKCS1_SHA512" , signatureRSAPKCS1WithSHA512 , testCertRSA } ,
{ "ECDSA_SHA1" , signatureECDSAWithSHA1 , testCertECDSAP256 } ,
@ -9942,51 +9942,94 @@ func addSignatureAlgorithmTests() {
continue
}
var shouldFail , rejectByDefault bool
// ecdsa_sha1 does not exist in TLS 1.3.
if ver . version >= VersionTLS13 && alg . id == signatureECDSAWithSHA1 {
shouldFail = true
suffix := "-" + alg . name + "-" + ver . name
for _ , signTestType := range [ ] testType { clientTest , serverTest } {
signPrefix := "Client-"
verifyPrefix := "Server-"
verifyTestType := serverTest
if signTestType == serverTest {
verifyTestType = clientTest
signPrefix , verifyPrefix = verifyPrefix , signPrefix
}
// RSA-PKCS1 does not exist in TLS 1.3.
if ver . version >= VersionTLS13 && hasComponent ( alg . name , "PKCS1" ) {
var shouldFail bool
isTLS12PKCS1 := hasComponent ( alg . name , "PKCS1" ) && ! hasComponent ( alg . name , "LEGACY" )
isTLS13PKCS1 := hasComponent ( alg . name , "PKCS1" ) && hasComponent ( alg . name , "LEGACY" )
// TLS 1.3 removes a number of signature algorithms.
if ver . version >= VersionTLS13 && ( alg . cert == testCertECDSAP224 || alg . id == signatureECDSAWithSHA1 || isTLS12PKCS1 ) {
shouldFail = true
}
// SHA-224 has been removed from TLS 1.3 and, in 1.3,
// the curve has to match the hash size.
if ver . version >= VersionTLS13 && alg . cert == testCertECDSAP224 {
// The backported RSA-PKCS1 code points only exist for TLS 1.3
// client certificates.
if ( ver . version < VersionTLS13 || signTestType == serverTest ) && isTLS13PKCS1 {
shouldFail = true
}
// By default, BoringSSL does not enable ecdsa_sha1, ecdsa_secp521_sha512, and ed25519.
if alg . id == signatureECDSAWithSHA1 || alg . id == signatureECDSAWithP521AndSHA512 || alg . id == signatureEd25519 {
rejectByDefault = true
// By default, BoringSSL does not sign with these algorithms.
signDefault := true
if isTLS13PKCS1 {
signDefault = false
}
var signError , signLocalError , verifyError , verifyLocalError , defaultError , defaultLocalError string
// By default, BoringSSL does not accept these algorithms.
verifyDefault := true
if alg . id == signatureECDSAWithSHA1 || alg . id == signatureECDSAWithP521AndSHA512 || alg . id == signatureEd25519 || isTLS13PKCS1 {
verifyDefault = false
}
var signError , signLocalError , verifyError , verifyLocalError string
if shouldFail {
signError = ":NO_COMMON_SIGNATURE_ALGORITHMS:"
signLocalError = "remote error: handshake failure"
verifyError = ":WRONG_SIGNATURE_TYPE:"
verifyLocalError = "remote error"
rejectByDefault = true
signDefault = false
verifyDefault = false
}
if rejectByDefault {
defaultError = ":WRONG_SIGNATURE_TYPE:"
defaultLocalError = "remote error"
var signDefaultError , signDefaultLocalError string
if ! signDefault {
signDefaultError = ":NO_COMMON_SIGNATURE_ALGORITHMS:"
signDefaultLocalError = "remote error: handshake failure"
}
suffix := "-" + alg . name + "-" + ver . name
for _ , testType := range [ ] testType { clientTest , serverTest } {
prefix := "Client-"
if testType == serverTest {
prefix = "Server-"
var verifyDefaultError , verifyDefaultLocalError string
if ! verifyDefault {
verifyDefaultError = ":WRONG_SIGNATURE_TYPE:"
verifyDefaultLocalError = "remote error"
}
// Test the shim using the algorithm for signing.
signTestFlags := [ ] string {
"-cert-file" , path . Join ( * resourceDir , getShimCertificate ( alg . cert ) ) ,
"-key-file" , path . Join ( * resourceDir , getShimKey ( alg . cert ) ) ,
}
signTestFlags = append ( signTestFlags , flagInts ( "-curves" , shimConfig . AllCurves ) ... )
signTestFlags = append ( signTestFlags , flagInts ( "-signing-prefs" , shimConfig . AllSignatureAlgorithms ) ... )
signTest := testCase {
testType : testType ,
name : prefix + "Sign" + suffix ,
testType : signTestType ,
name : signPrefix + "Sign" + suffix ,
config : Config {
MaxVersion : ver . version ,
VerifySignatureAlgorithms : [ ] signatureAlgorithm {
fakeSigAlg1 ,
alg . id ,
fakeSigAlg2 ,
} ,
} ,
flags : signTestFlags ,
shouldFail : shouldFail ,
expectedError : signError ,
expectedLocalError : signLocalError ,
expectations : connectionExpectations {
peerSignatureAlgorithm : alg . id ,
} ,
}
// Test whether the shim enables the algorithm by default.
signDefaultTest := testCase {
testType : signTestType ,
name : signPrefix + "SignDefault" + suffix ,
config : Config {
MaxVersion : ver . version ,
VerifySignatureAlgorithms : [ ] signatureAlgorithm {
@ -10002,9 +10045,9 @@ func addSignatureAlgorithmTests() {
} ,
flagInts ( "-curves" , shimConfig . AllCurves ) ... ,
) ,
shouldFail : shouldFail ,
expectedError : signError ,
expectedLocalError : signLocalError ,
shouldFail : ! signDefault ,
expectedError : signDefault Error ,
expectedLocalError : signDefault LocalError ,
expectations : connectionExpectations {
peerSignatureAlgorithm : alg . id ,
} ,
@ -10013,8 +10056,8 @@ func addSignatureAlgorithmTests() {
// Test that the shim will select the algorithm when configured to only
// support it.
negotiateTest := testCase {
testType : t estType,
name : p refix + "Sign-Negotiate" + suffix ,
testType : signT estType,
name : signP refix + "Sign-Negotiate" + suffix ,
config : Config {
MaxVersion : ver . version ,
VerifySignatureAlgorithms : allAlgorithms ,
@ -10032,24 +10075,26 @@ func addSignatureAlgorithmTests() {
} ,
}
if t estType == serverTest {
if signT estType == serverTest {
// TLS 1.2 servers only sign on some cipher suites.
signTest . config . CipherSuites = signingCiphers
signDefaultTest . config . CipherSuites = signingCiphers
negotiateTest . config . CipherSuites = signingCiphers
} else {
// TLS 1.2 clients only sign when the server requests certificates.
signTest . config . ClientAuth = RequireAnyClientCert
signDefaultTest . config . ClientAuth = RequireAnyClientCert
negotiateTest . config . ClientAuth = RequireAnyClientCert
}
testCases = append ( testCases , signTest )
testCases = append ( testCases , signTest , signDefaultTest )
if ver . version >= VersionTLS12 && ! shouldFail {
testCases = append ( testCases , negotiateTest )
}
// Test the shim using the algorithm for verifying.
verifyTest := testCase {
testType : t estType,
name : p refix + "Verify" + suffix ,
testType : verifyT estType,
name : verifyP refix + "Verify" + suffix ,
config : Config {
MaxVersion : ver . version ,
Certificates : [ ] Certificate { getRunnerCertificate ( alg . cert ) } ,
@ -10081,8 +10126,8 @@ func addSignatureAlgorithmTests() {
// Test whether the shim expects the algorithm enabled by default.
defaultTest := testCase {
testType : t estType,
name : p refix + "VerifyDefault" + suffix ,
testType : verifyT estType,
name : verifyP refix + "VerifyDefault" + suffix ,
config : Config {
MaxVersion : ver . version ,
Certificates : [ ] Certificate { getRunnerCertificate ( alg . cert ) } ,
@ -10090,10 +10135,10 @@ func addSignatureAlgorithmTests() {
alg . id ,
} ,
Bugs : ProtocolBugs {
SkipECDSACurveCheck : rejectB yDefault,
IgnoreSignatureVersionChecks : rejectB yDefault,
SkipECDSACurveCheck : ! verif yDefault,
IgnoreSignatureVersionChecks : ! verif yDefault,
// Some signature algorithms may not be advertised.
IgnorePeerSignatureAlgorithmPreferences : rejectB yDefault,
IgnorePeerSignatureAlgorithmPreferences : ! verif yDefault,
} ,
} ,
flags : append (
@ -10102,16 +10147,16 @@ func addSignatureAlgorithmTests() {
) ,
// Resume the session to assert the peer signature
// algorithm is reported on both handshakes.
resumeSession : ! rejectB yDefault,
shouldFail : rejectB yDefault,
expectedError : d efaultError,
expectedLocalError : d efaultLocalError,
resumeSession : verif yDefault,
shouldFail : ! verif yDefault,
expectedError : verifyD efaultError,
expectedLocalError : verifyD efaultLocalError,
}
// Test whether the shim handles invalid signatures for this algorithm.
invalidTest := testCase {
testType : t estType,
name : p refix + "InvalidSignature" + suffix ,
testType : verifyT estType,
name : verifyP refix + "InvalidSignature" + suffix ,
config : Config {
MaxVersion : ver . version ,
Certificates : [ ] Certificate { getRunnerCertificate ( alg . cert ) } ,
@ -10131,7 +10176,7 @@ func addSignatureAlgorithmTests() {
expectedError : ":BAD_SIGNATURE:" ,
}
if t estType == serverTest {
if verifyT estType == serverTest {
// TLS 1.2 servers only verify when they request client certificates.
verifyTest . flags = append ( verifyTest . flags , "-require-any-client-certificate" )
defaultTest . flags = append ( defaultTest . flags , "-require-any-client-certificate" )
@ -16798,6 +16843,14 @@ func main() {
}
}
if shimConfig . AllSignatureAlgorithms == nil {
for _ , alg := range testSignatureAlgorithms {
if alg . id != 0 {
shimConfig . AllSignatureAlgorithms = append ( shimConfig . AllSignatureAlgorithms , int ( alg . id ) )
}
}
}
addBasicTests ( )
addCipherSuiteTests ( )
addBadECDSASignatureTests ( )