From 606d9a7e18c951bb64ea460597894558ff3808c1 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 3 Dec 2015 14:36:45 -0500 Subject: [PATCH] crypto/x509: introduce ErrInsecureAlgorithm for insecure algorithms Until now we've used ErrUnknownAlgorithm but that's a bit confusing when it is returned for obviously-known things like MD5. Fixes #10431. Change-Id: Ief8a8ef46e5b99bd4fd18e1acd7ae398a484bac3 Reviewed-on: https://go-review.googlesource.com/17380 Reviewed-by: Adam Langley --- src/crypto/x509/x509.go | 6 ++++++ src/crypto/x509/x509_test.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/crypto/x509/x509.go b/src/crypto/x509/x509.go index 126432d875..3fc7e0fdfb 100644 --- a/src/crypto/x509/x509.go +++ b/src/crypto/x509/x509.go @@ -541,6 +541,10 @@ type Certificate struct { // involves algorithms that are not currently implemented. var ErrUnsupportedAlgorithm = errors.New("x509: cannot verify signature: algorithm unimplemented") +// ErrInsecureAlgorithm results from attempting to perform an operation that +// involves algorithms that are deemed insecure, notably MD5. +var ErrInsecureAlgorithm = errors.New("x509: cannot verify signature: insecure algorithm") + // ConstraintViolationError results when a requested usage is not permitted by // a certificate. For example: checking a signature when the public key isn't a // certificate signing key. @@ -651,6 +655,8 @@ func checkSignature(algo SignatureAlgorithm, signed, signature []byte, publicKey hashType = crypto.SHA384 case SHA512WithRSA, ECDSAWithSHA512: hashType = crypto.SHA512 + case MD2WithRSA, MD5WithRSA: + return ErrInsecureAlgorithm default: return ErrUnsupportedAlgorithm } diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go index 2c01ec7bf1..4cb9fd8d07 100644 --- a/src/crypto/x509/x509_test.go +++ b/src/crypto/x509/x509_test.go @@ -1220,3 +1220,36 @@ var csrBase64Array = [...]string{ // Both [ v3_req ] and [ req_attributes ] "MIIDaTCCAlECAQAwfjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEUMBIGA1UEAwwLQ29tbW9uIE5hbWUxITAfBgkqhkiG9w0BCQEWEnRlc3RAZW1haWwuYWRkcmVzczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK1GY4YFx2ujlZEOJxQVYmsjUnLsd5nFVnNpLE4cV+77sgv9NPNlB8uhn3MXt5leD34rm/2BisCHOifPucYlSrszo2beuKhvwn4+2FxDmWtBEMu/QA16L5IvoOfYZm/gJTsPwKDqvaR0tTU67a9OtxwNTBMI56YKtmwd/o8d3hYv9cg+9ZGAZ/gKONcg/OWYx/XRh6bd0g8DMbCikpWgXKDsvvK1Nk+VtkDO1JxuBaj4Lz/p/MifTfnHoqHxWOWl4EaTs4Ychxsv34/rSj1KD1tJqorIv5Xv2aqv4sjxfbrYzX4kvS5SC1goIovLnhj5UjmQ3Qy8u65eow/LLWw+YFcCAwEAAaCBpTAgBgkqhkiG9w0BCQcxEwwRaWdub3JlZCBjaGFsbGVuZ2UwKAYJKoZIhvcNAQkCMRsMGWlnbm9yZWQgdW5zdHJ1Y3R1cmVkIG5hbWUwVwYJKoZIhvcNAQkOMUowSDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAuBgNVHREEJzAlgRFnb3BoZXJAZ29sYW5nLm9yZ4IQdGVzdC5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAgxe2N5O48EMsYE7o0rZBB0wi3Ov5/yYfnmmVI22Y3sP6VXbLDW0+UWIeSccOhzUCcZ/G4qcrfhhx6gTZTeA01nP7TdTJURvWAH5iFqj9sQ0qnLq6nEcVHij3sG6M5+BxAIVClQBk6lTCzgphc835Fjj6qSLuJ20XHdL5UfUbiJxx299CHgyBRL+hBUIPfz8p+ZgamyAuDLfnj54zzcRVyLlrmMLNPZNll1Q70RxoU6uWvLH8wB8vQe3Q/guSGubLyLRTUQVPh+dw1L4t8MKFWfX/48jwRM4gIRHFHPeAAE9D9YAoqdIvj/iFm/eQ++7DP8MDwOZWsXeB6jjwHuLmkQ==", } + +var md5cert = ` +-----BEGIN CERTIFICATE----- +MIIB4TCCAUoCCQCfmw3vMgPS5TANBgkqhkiG9w0BAQQFADA1MQswCQYDVQQGEwJB +VTETMBEGA1UECBMKU29tZS1TdGF0ZTERMA8GA1UEChMITUQ1IEluYy4wHhcNMTUx +MjAzMTkyOTMyWhcNMjkwODEyMTkyOTMyWjA1MQswCQYDVQQGEwJBVTETMBEGA1UE +CBMKU29tZS1TdGF0ZTERMA8GA1UEChMITUQ1IEluYy4wgZ8wDQYJKoZIhvcNAQEB +BQADgY0AMIGJAoGBANrq2nhLQj5mlXbpVX3QUPhfEm/vdEqPkoWtR/jRZIWm4WGf +Wpq/LKHJx2Pqwn+t117syN8l4U5unyAi1BJSXjBwPZNd7dXjcuJ+bRLV7FZ/iuvs +cfYyQQFTxan4TaJMd0x1HoNDbNbjHa02IyjjYE/r3mb/PIg+J2t5AZEh80lPAgMB +AAEwDQYJKoZIhvcNAQEEBQADgYEAjGzp3K3ey/YfKHohf33yHHWd695HQxDAP+wY +cs9/TAyLR+gJzJP7d18EcDDLJWVi7bhfa4EAD86di05azOh9kWSn4b3o9QYRGCSw +GNnI3Zk0cwNKA49hZntKKiy22DhRk7JAHF01d6Bu3KkHkmENrtJ+zj/+159WAnUa +qViorq4= +-----END CERTIFICATE----- +` + +func TestMD5(t *testing.T) { + pemBlock, _ := pem.Decode([]byte(md5cert)) + cert, err := ParseCertificate(pemBlock.Bytes) + if err != nil { + t.Fatalf("failed to parse certificate: %s", err) + } + if sa := cert.SignatureAlgorithm; sa != MD5WithRSA { + t.Errorf("signature algorithm is %v, want %v", sa, MD5WithRSA) + } + if err = cert.CheckSignatureFrom(cert); err == nil { + t.Fatalf("certificate verification succeeded incorrectly") + } + if err != ErrInsecureAlgorithm { + t.Fatalf("certificate verification returned %q, wanted %q", err, ErrInsecureAlgorithm) + } +} -- 2.48.1