summaryrefslogtreecommitdiff
path: root/src/pkg/crypto/x509/x509_test.go
diff options
context:
space:
mode:
authorMichael Stapelberg <stapelberg@debian.org>2013-03-04 21:27:36 +0100
committerMichael Stapelberg <michael@stapelberg.de>2013-03-04 21:27:36 +0100
commit04b08da9af0c450d645ab7389d1467308cfc2db8 (patch)
treedb247935fa4f2f94408edc3acd5d0d4f997aa0d8 /src/pkg/crypto/x509/x509_test.go
parent917c5fb8ec48e22459d77e3849e6d388f93d3260 (diff)
downloadgolang-upstream/1.1_hg20130304.tar.gz
Imported Upstream version 1.1~hg20130304upstream/1.1_hg20130304
Diffstat (limited to 'src/pkg/crypto/x509/x509_test.go')
-rw-r--r--src/pkg/crypto/x509/x509_test.go296
1 files changed, 250 insertions, 46 deletions
diff --git a/src/pkg/crypto/x509/x509_test.go b/src/pkg/crypto/x509/x509_test.go
index f0327b012..abd4fe84d 100644
--- a/src/pkg/crypto/x509/x509_test.go
+++ b/src/pkg/crypto/x509/x509_test.go
@@ -7,14 +7,20 @@ package x509
import (
"bytes"
"crypto/dsa"
+ "crypto/ecdsa"
+ "crypto/elliptic"
"crypto/rand"
"crypto/rsa"
+ _ "crypto/sha256"
+ _ "crypto/sha512"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/base64"
"encoding/hex"
"encoding/pem"
"math/big"
+ "net"
+ "reflect"
"testing"
"time"
)
@@ -169,6 +175,49 @@ func TestMatchHostnames(t *testing.T) {
}
}
+func TestMatchIP(t *testing.T) {
+ // Check that pattern matching is working.
+ c := &Certificate{
+ DNSNames: []string{"*.foo.bar.baz"},
+ Subject: pkix.Name{
+ CommonName: "*.foo.bar.baz",
+ },
+ }
+ err := c.VerifyHostname("quux.foo.bar.baz")
+ if err != nil {
+ t.Fatalf("VerifyHostname(quux.foo.bar.baz): %v", err)
+ }
+
+ // But check that if we change it to be matching against an IP address,
+ // it is rejected.
+ c = &Certificate{
+ DNSNames: []string{"*.2.3.4"},
+ Subject: pkix.Name{
+ CommonName: "*.2.3.4",
+ },
+ }
+ err = c.VerifyHostname("1.2.3.4")
+ if err == nil {
+ t.Fatalf("VerifyHostname(1.2.3.4) should have failed, did not")
+ }
+
+ c = &Certificate{
+ IPAddresses: []net.IP{net.ParseIP("127.0.0.1"), net.ParseIP("::1")},
+ }
+ err = c.VerifyHostname("127.0.0.1")
+ if err != nil {
+ t.Fatalf("VerifyHostname(127.0.0.1): %v", err)
+ }
+ err = c.VerifyHostname("::1")
+ if err != nil {
+ t.Fatalf("VerifyHostname(::1): %v", err)
+ }
+ err = c.VerifyHostname("[::1]")
+ if err != nil {
+ t.Fatalf("VerifyHostname([::1]): %v", err)
+ }
+}
+
func TestCertificateParse(t *testing.T) {
s, _ := hex.DecodeString(certBytes)
certs, err := ParseCertificates(s)
@@ -237,65 +286,220 @@ func TestCreateSelfSignedCertificate(t *testing.T) {
random := rand.Reader
block, _ := pem.Decode([]byte(pemPrivateKey))
- priv, err := ParsePKCS1PrivateKey(block.Bytes)
+ rsaPriv, err := ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
- t.Errorf("Failed to parse private key: %s", err)
- return
+ t.Fatalf("Failed to parse private key: %s", err)
}
- commonName := "test.example.com"
- template := Certificate{
- SerialNumber: big.NewInt(1),
- Subject: pkix.Name{
- CommonName: commonName,
- Organization: []string{"Acme Co"},
- },
- NotBefore: time.Unix(1000, 0),
- NotAfter: time.Unix(100000, 0),
+ ecdsaPriv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+ if err != nil {
+ t.Fatalf("Failed to generate ECDSA key: %s", err)
+ }
- SubjectKeyId: []byte{1, 2, 3, 4},
- KeyUsage: KeyUsageCertSign,
+ tests := []struct {
+ name string
+ pub, priv interface{}
+ checkSig bool
+ }{
+ {"RSA/RSA", &rsaPriv.PublicKey, rsaPriv, true},
+ {"RSA/ECDSA", &rsaPriv.PublicKey, ecdsaPriv, false},
+ {"ECDSA/RSA", &ecdsaPriv.PublicKey, rsaPriv, false},
+ {"ECDSA/ECDSA", &ecdsaPriv.PublicKey, ecdsaPriv, true},
+ }
- BasicConstraintsValid: true,
- IsCA: true,
- DNSNames: []string{"test.example.com"},
+ testExtKeyUsage := []ExtKeyUsage{ExtKeyUsageClientAuth, ExtKeyUsageServerAuth}
+ testUnknownExtKeyUsage := []asn1.ObjectIdentifier{[]int{1, 2, 3}, []int{3, 2, 1}}
- PolicyIdentifiers: []asn1.ObjectIdentifier{[]int{1, 2, 3}},
- PermittedDNSDomains: []string{".example.com", "example.com"},
- }
+ for _, test := range tests {
+ commonName := "test.example.com"
+ template := Certificate{
+ SerialNumber: big.NewInt(1),
+ Subject: pkix.Name{
+ CommonName: commonName,
+ Organization: []string{"Σ Acme Co"},
+ },
+ NotBefore: time.Unix(1000, 0),
+ NotAfter: time.Unix(100000, 0),
- derBytes, err := CreateCertificate(random, &template, &template, &priv.PublicKey, priv)
- if err != nil {
- t.Errorf("Failed to create certificate: %s", err)
- return
- }
+ SubjectKeyId: []byte{1, 2, 3, 4},
+ KeyUsage: KeyUsageCertSign,
- cert, err := ParseCertificate(derBytes)
- if err != nil {
- t.Errorf("Failed to parse certificate: %s", err)
- return
- }
+ ExtKeyUsage: testExtKeyUsage,
+ UnknownExtKeyUsage: testUnknownExtKeyUsage,
- if len(cert.PolicyIdentifiers) != 1 || !cert.PolicyIdentifiers[0].Equal(template.PolicyIdentifiers[0]) {
- t.Errorf("Failed to parse policy identifiers: got:%#v want:%#v", cert.PolicyIdentifiers, template.PolicyIdentifiers)
- }
+ BasicConstraintsValid: true,
+ IsCA: true,
- if len(cert.PermittedDNSDomains) != 2 || cert.PermittedDNSDomains[0] != ".example.com" || cert.PermittedDNSDomains[1] != "example.com" {
- t.Errorf("Failed to parse name constraints: %#v", cert.PermittedDNSDomains)
- }
+ DNSNames: []string{"test.example.com"},
+ EmailAddresses: []string{"gopher@golang.org"},
+ IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")},
- if cert.Subject.CommonName != commonName {
- t.Errorf("Subject wasn't correctly copied from the template. Got %s, want %s", cert.Subject.CommonName, commonName)
- }
+ PolicyIdentifiers: []asn1.ObjectIdentifier{[]int{1, 2, 3}},
+ PermittedDNSDomains: []string{".example.com", "example.com"},
+ }
+
+ derBytes, err := CreateCertificate(random, &template, &template, test.pub, test.priv)
+ if err != nil {
+ t.Errorf("%s: failed to create certificate: %s", test.name, err)
+ continue
+ }
+
+ cert, err := ParseCertificate(derBytes)
+ if err != nil {
+ t.Errorf("%s: failed to parse certificate: %s", test.name, err)
+ continue
+ }
+
+ if len(cert.PolicyIdentifiers) != 1 || !cert.PolicyIdentifiers[0].Equal(template.PolicyIdentifiers[0]) {
+ t.Errorf("%s: failed to parse policy identifiers: got:%#v want:%#v", test.name, cert.PolicyIdentifiers, template.PolicyIdentifiers)
+ }
+
+ if len(cert.PermittedDNSDomains) != 2 || cert.PermittedDNSDomains[0] != ".example.com" || cert.PermittedDNSDomains[1] != "example.com" {
+ t.Errorf("%s: failed to parse name constraints: %#v", test.name, cert.PermittedDNSDomains)
+ }
+
+ if cert.Subject.CommonName != commonName {
+ t.Errorf("%s: subject wasn't correctly copied from the template. Got %s, want %s", test.name, cert.Subject.CommonName, commonName)
+ }
+
+ if cert.Issuer.CommonName != commonName {
+ t.Errorf("%s: issuer wasn't correctly copied from the template. Got %s, want %s", test.name, cert.Issuer.CommonName, commonName)
+ }
+
+ if !reflect.DeepEqual(cert.ExtKeyUsage, testExtKeyUsage) {
+ t.Errorf("%s: extkeyusage wasn't correctly copied from the template. Got %v, want %v", test.name, cert.ExtKeyUsage, testExtKeyUsage)
+ }
- if cert.Issuer.CommonName != commonName {
- t.Errorf("Issuer wasn't correctly copied from the template. Got %s, want %s", cert.Issuer.CommonName, commonName)
+ if !reflect.DeepEqual(cert.UnknownExtKeyUsage, testUnknownExtKeyUsage) {
+ t.Errorf("%s: unknown extkeyusage wasn't correctly copied from the template. Got %v, want %v", test.name, cert.UnknownExtKeyUsage, testUnknownExtKeyUsage)
+ }
+
+ if !reflect.DeepEqual(cert.DNSNames, template.DNSNames) {
+ t.Errorf("%s: SAN DNS names differ from template. Got %v, want %v", test.name, cert.DNSNames, template.DNSNames)
+ }
+
+ if !reflect.DeepEqual(cert.EmailAddresses, template.EmailAddresses) {
+ t.Errorf("%s: SAN emails differ from template. Got %v, want %v", test.name, cert.EmailAddresses, template.EmailAddresses)
+ }
+
+ if !reflect.DeepEqual(cert.IPAddresses, template.IPAddresses) {
+ t.Errorf("%s: SAN IPs differ from template. Got %v, want %v", test.name, cert.IPAddresses, template.IPAddresses)
+ }
+
+ if test.checkSig {
+ err = cert.CheckSignatureFrom(cert)
+ if err != nil {
+ t.Errorf("%s: signature verification failed: %s", test.name, err)
+ }
+ }
}
+}
- err = cert.CheckSignatureFrom(cert)
- if err != nil {
- t.Errorf("Signature verification failed: %s", err)
- return
+// Self-signed certificate using ECDSA with SHA1 & secp256r1
+var ecdsaSHA1CertPem = `
+-----BEGIN CERTIFICATE-----
+MIICDjCCAbUCCQDF6SfN0nsnrjAJBgcqhkjOPQQBMIGPMQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEVMBMG
+A1UECgwMR29vZ2xlLCBJbmMuMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEG
+CSqGSIb3DQEJARYUZ29sYW5nLWRldkBnbWFpbC5jb20wHhcNMTIwNTIwMjAyMDUw
+WhcNMjIwNTE4MjAyMDUwWjCBjzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm
+b3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFTATBgNVBAoMDEdvb2dsZSwg
+SW5jLjEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20xIzAhBgkqhkiG9w0BCQEWFGdv
+bGFuZy1kZXZAZ21haWwuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE/Wgn
+WQDo5+bz71T0327ERgd5SDDXFbXLpzIZDXTkjpe8QTEbsF+ezsQfrekrpDPC4Cd3
+P9LY0tG+aI8IyVKdUjAJBgcqhkjOPQQBA0gAMEUCIGlsqMcRqWVIWTD6wXwe6Jk2
+DKxL46r/FLgJYnzBEH99AiEA3fBouObsvV1R3oVkb4BQYnD4/4LeId6lAT43YvyV
+a/A=
+-----END CERTIFICATE-----
+`
+
+// Self-signed certificate using ECDSA with SHA256 & secp256r1
+var ecdsaSHA256p256CertPem = `
+-----BEGIN CERTIFICATE-----
+MIICDzCCAbYCCQDlsuMWvgQzhTAKBggqhkjOPQQDAjCBjzELMAkGA1UEBhMCVVMx
+EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFTAT
+BgNVBAoMDEdvb2dsZSwgSW5jLjEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20xIzAh
+BgkqhkiG9w0BCQEWFGdvbGFuZy1kZXZAZ21haWwuY29tMB4XDTEyMDUyMTAwMTkx
+NloXDTIyMDUxOTAwMTkxNlowgY8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
+Zm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRUwEwYDVQQKDAxHb29nbGUs
+IEluYy4xFzAVBgNVBAMMDnd3dy5nb29nbGUuY29tMSMwIQYJKoZIhvcNAQkBFhRn
+b2xhbmctZGV2QGdtYWlsLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPMt
+2ErhxAty5EJRu9yM+MTy+hUXm3pdW1ensAv382KoGExSXAFWP7pjJnNtHO+XSwVm
+YNtqjcAGFKpweoN//kQwCgYIKoZIzj0EAwIDRwAwRAIgIYSaUA/IB81gjbIw/hUV
+70twxJr5EcgOo0hLp3Jm+EYCIFDO3NNcgmURbJ1kfoS3N/0O+irUtoPw38YoNkqJ
+h5wi
+-----END CERTIFICATE-----
+`
+
+// Self-signed certificate using ECDSA with SHA256 & secp384r1
+var ecdsaSHA256p384CertPem = `
+-----BEGIN CERTIFICATE-----
+MIICSjCCAdECCQDje/no7mXkVzAKBggqhkjOPQQDAjCBjjELMAkGA1UEBhMCVVMx
+EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDAS
+BgNVBAoMC0dvb2dsZSwgSW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEG
+CSqGSIb3DQEJARYUZ29sYW5nLWRldkBnbWFpbC5jb20wHhcNMTIwNTIxMDYxMDM0
+WhcNMjIwNTE5MDYxMDM0WjCBjjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm
+b3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDASBgNVBAoMC0dvb2dsZSwg
+SW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEGCSqGSIb3DQEJARYUZ29s
+YW5nLWRldkBnbWFpbC5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARRuzRNIKRK
+jIktEmXanNmrTR/q/FaHXLhWRZ6nHWe26Fw7Rsrbk+VjGy4vfWtNn7xSFKrOu5ze
+qxKnmE0h5E480MNgrUiRkaGO2GMJJVmxx20aqkXOk59U8yGA4CghE6MwCgYIKoZI
+zj0EAwIDZwAwZAIwBZEN8gvmRmfeP/9C1PRLzODIY4JqWub2PLRT4mv9GU+yw3Gr
+PU9A3CHMdEcdw/MEAjBBO1lId8KOCh9UZunsSMfqXiVurpzmhWd6VYZ/32G+M+Mh
+3yILeYQzllt/g0rKVRk=
+-----END CERTIFICATE-----
+`
+
+// Self-signed certificate using ECDSA with SHA384 & secp521r1
+var ecdsaSHA384p521CertPem = `
+-----BEGIN CERTIFICATE-----
+MIICljCCAfcCCQDhp1AFD/ahKjAKBggqhkjOPQQDAzCBjjELMAkGA1UEBhMCVVMx
+EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDAS
+BgNVBAoMC0dvb2dsZSwgSW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEG
+CSqGSIb3DQEJARYUZ29sYW5nLWRldkBnbWFpbC5jb20wHhcNMTIwNTIxMTUwNDI5
+WhcNMjIwNTE5MTUwNDI5WjCBjjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm
+b3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDASBgNVBAoMC0dvb2dsZSwg
+SW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEGCSqGSIb3DQEJARYUZ29s
+YW5nLWRldkBnbWFpbC5jb20wgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABACqx9Rv
+IssRs1LWYcNN+WffwlHw4Tv3y8/LIAA9MF1ZScIonU9nRMxt4a2uGJVCPDw6JHpz
+PaYc0E9puLoE9AfKpwFr59Jkot7dBg55SKPEFkddoip/rvmN7NPAWjMBirOwjOkm
+8FPthvPhGPqsu9AvgVuHu3PosWiHGNrhh379pva8MzAKBggqhkjOPQQDAwOBjAAw
+gYgCQgEHNmswkUdPpHqrVxp9PvLVl+xxPuHBkT+75z9JizyxtqykHQo9Uh6SWCYH
+BF9KLolo01wMt8DjoYP5Fb3j5MH7xwJCAbWZzTOp4l4DPkIvAh4LeC4VWbwPPyqh
+kBg71w/iEcSY3wUKgHGcJJrObZw7wys91I5kENljqw/Samdr3ka+jBJa
+-----END CERTIFICATE-----
+`
+
+var ecdsaTests = []struct {
+ sigAlgo SignatureAlgorithm
+ pemCert string
+}{
+ {ECDSAWithSHA1, ecdsaSHA1CertPem},
+ {ECDSAWithSHA256, ecdsaSHA256p256CertPem},
+ {ECDSAWithSHA256, ecdsaSHA256p384CertPem},
+ {ECDSAWithSHA384, ecdsaSHA384p521CertPem},
+}
+
+func TestECDSA(t *testing.T) {
+ for i, test := range ecdsaTests {
+ pemBlock, _ := pem.Decode([]byte(test.pemCert))
+ cert, err := ParseCertificate(pemBlock.Bytes)
+ if err != nil {
+ t.Errorf("%d: failed to parse certificate: %s", i, err)
+ continue
+ }
+ if sa := cert.SignatureAlgorithm; sa != test.sigAlgo {
+ t.Errorf("%d: signature algorithm is %v, want %v", i, sa, test.sigAlgo)
+ }
+ if parsedKey, ok := cert.PublicKey.(*ecdsa.PublicKey); !ok {
+ t.Errorf("%d: wanted an ECDSA public key but found: %#v", i, parsedKey)
+ }
+ if pka := cert.PublicKeyAlgorithm; pka != ECDSA {
+ t.Errorf("%d: public key algorithm is %v, want ECDSA", i, pka)
+ }
+ if err = cert.CheckSignatureFrom(cert); err != nil {
+ t.Errorf("%d: certificate verification failed: %s", i, err)
+ }
}
}
@@ -374,7 +578,7 @@ func TestVerifyCertificateWithDSASignature(t *testing.T) {
}
// test cert is self-signed
if err = cert.CheckSignatureFrom(cert); err != nil {
- t.Fatalf("DSA Certificate verfication failed: %s", err)
+ t.Fatalf("DSA Certificate verification failed: %s", err)
}
}