github.com/grailbio/base@v0.0.11/security/tls/certificateauthority/tls_test.go (about) 1 // Copyright 2018 GRAIL, Inc. All rights reserved. 2 // Use of this source code is governed by the Apache-2.0 3 // license that can be found in the LICENSE file. 4 5 package certificateauthority 6 7 import ( 8 "crypto/x509" 9 "io/ioutil" 10 "net" 11 "reflect" 12 "testing" 13 "time" 14 15 "github.com/grailbio/base/security/keycrypt" 16 ) 17 18 func TestAuthority(t *testing.T) { 19 margin := 60 * time.Second 20 certPEM, err := ioutil.ReadFile("testdata/cert.pem") 21 if err != nil { 22 panic(err) 23 } 24 ca := CertificateAuthority{DriftMargin: margin, Signer: keycrypt.Static(certPEM)} 25 if err := ca.Init(); err != nil { 26 t.Fatal(err) 27 } 28 ips := []net.IP{net.IPv4(1, 2, 3, 4)} 29 dnses := []string{"test.grail.com"} 30 certBytes, priv, err := ca.Issue("test", 10*time.Minute, ips, dnses) 31 if err != nil { 32 t.Fatal(err) 33 } 34 cert, err := x509.ParseCertificate(certBytes) 35 if err != nil { 36 t.Fatal(err) 37 } 38 39 now := time.Now() 40 opts := x509.VerifyOptions{} 41 opts.Roots = x509.NewCertPool() 42 opts.Roots.AddCert(ca.Cert) 43 if _, err := cert.Verify(opts); err != nil { 44 t.Fatal(err) 45 } 46 if err := priv.Validate(); err != nil { 47 t.Fatal(err) 48 } 49 if got, want := priv.Public(), cert.PublicKey; !reflect.DeepEqual(got, want) { 50 t.Errorf("got %v, want %v", got, want) 51 } 52 if got, want := cert.Subject.CommonName, "test"; got != want { 53 t.Errorf("got %q, want %q", got, want) 54 } 55 if got, want := cert.NotBefore, now.Add(-margin); want.Before(got) { 56 t.Errorf("wanted %s <= %s", got, want) 57 } 58 if got, want := cert.NotAfter.Sub(cert.NotBefore), 10*time.Minute+margin; got != want { 59 t.Errorf("got %s, want %s", got, want) 60 } 61 if cert.IsCA { 62 t.Error("cert is CA") 63 } 64 if got, want := cert.IPAddresses, ips; !ipsEqual(got, want) { 65 t.Errorf("got %v, want %v", got, want) 66 } 67 if got, want := cert.DNSNames, dnses; !reflect.DeepEqual(got, want) { 68 t.Errorf("got %v, want %v", got, want) 69 } 70 keyUsage := []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth} 71 if got, want := cert.ExtKeyUsage, keyUsage; !reflect.DeepEqual(got, want) { 72 t.Errorf("got %v, want %v", got, want) 73 } 74 } 75 76 func TestAuthorityServerExtKeyUsage(t *testing.T) { 77 margin := 60 * time.Second 78 certPEM, err := ioutil.ReadFile("testdata/cert.pem") 79 if err != nil { 80 panic(err) 81 } 82 ca := CertificateAuthority{DriftMargin: margin, Signer: keycrypt.Static(certPEM)} 83 if err := ca.Init(); err != nil { 84 t.Fatal(err) 85 } 86 ips := []net.IP{net.IPv4(1, 2, 3, 4)} 87 dnses := []string{"test.grail.com"} 88 keyUsage := []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth} 89 certBytes, priv, err := ca.IssueWithKeyUsage("test", 10*time.Minute, ips, dnses, keyUsage) 90 if err != nil { 91 t.Fatal(err) 92 } 93 cert, err := x509.ParseCertificate(certBytes) 94 if err != nil { 95 t.Fatal(err) 96 } 97 opts := x509.VerifyOptions{} 98 opts.Roots = x509.NewCertPool() 99 opts.Roots.AddCert(ca.Cert) 100 if _, err := cert.Verify(opts); err != nil { 101 t.Fatal(err) 102 } 103 if err := priv.Validate(); err != nil { 104 t.Fatal(err) 105 } 106 if got, want := cert.ExtKeyUsage, keyUsage; !reflect.DeepEqual(got, want) { 107 t.Errorf("got %v, want %v", got, want) 108 } 109 } 110 111 func TestAuthorityClientExtKeyUsage(t *testing.T) { 112 margin := 60 * time.Second 113 certPEM, err := ioutil.ReadFile("testdata/cert.pem") 114 if err != nil { 115 panic(err) 116 } 117 ca := CertificateAuthority{DriftMargin: margin, Signer: keycrypt.Static(certPEM)} 118 if err := ca.Init(); err != nil { 119 t.Fatal(err) 120 } 121 ips := []net.IP{net.IPv4(1, 2, 3, 4)} 122 dnses := []string{"test.grail.com"} 123 keyUsage := []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth} 124 certBytes, priv, err := ca.IssueWithKeyUsage("test", 10*time.Minute, ips, dnses, keyUsage) 125 if err != nil { 126 t.Fatal(err) 127 } 128 cert, err := x509.ParseCertificate(certBytes) 129 if err != nil { 130 t.Fatal(err) 131 } 132 opts := x509.VerifyOptions{} 133 opts.Roots = x509.NewCertPool() 134 opts.Roots.AddCert(ca.Cert) 135 // Client certs can not be verified as a server, expect verification fail. 136 if _, err := cert.Verify(opts); err == nil { 137 t.Fatal("unexpected valid X509 certificate.") 138 } 139 if err := priv.Validate(); err != nil { 140 t.Fatal(err) 141 } 142 if got, want := cert.ExtKeyUsage, keyUsage; !reflect.DeepEqual(got, want) { 143 t.Errorf("got %v, want %v", got, want) 144 } 145 } 146 147 func ipsEqual(x, y []net.IP) bool { 148 if len(x) != len(y) { 149 return false 150 } 151 for i := range x { 152 if !x[i].Equal(y[i]) { 153 return false 154 } 155 } 156 return true 157 }