github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/tls/resource_locally_signed_cert_test.go (about) 1 package tls 2 3 import ( 4 "bytes" 5 "crypto/x509" 6 "encoding/pem" 7 "errors" 8 "fmt" 9 "strings" 10 "testing" 11 "time" 12 13 r "github.com/hashicorp/terraform/helper/resource" 14 "github.com/hashicorp/terraform/terraform" 15 ) 16 17 func TestLocallySignedCert(t *testing.T) { 18 r.Test(t, r.TestCase{ 19 Providers: testProviders, 20 Steps: []r.TestStep{ 21 r.TestStep{ 22 Config: fmt.Sprintf(` 23 resource "tls_locally_signed_cert" "test" { 24 cert_request_pem = <<EOT 25 %s 26 EOT 27 28 validity_period_hours = 1 29 30 allowed_uses = [ 31 "key_encipherment", 32 "digital_signature", 33 "server_auth", 34 "client_auth", 35 ] 36 37 ca_key_algorithm = "RSA" 38 ca_cert_pem = <<EOT 39 %s 40 EOT 41 ca_private_key_pem = <<EOT 42 %s 43 EOT 44 } 45 output "cert_pem" { 46 value = "${tls_locally_signed_cert.test.cert_pem}" 47 } 48 `, testCertRequest, testCACert, testCAPrivateKey), 49 Check: func(s *terraform.State) error { 50 gotUntyped := s.RootModule().Outputs["cert_pem"].Value 51 got, ok := gotUntyped.(string) 52 if !ok { 53 return fmt.Errorf("output for \"cert_pem\" is not a string") 54 } 55 if !strings.HasPrefix(got, "-----BEGIN CERTIFICATE----") { 56 return fmt.Errorf("key is missing cert PEM preamble") 57 } 58 block, _ := pem.Decode([]byte(got)) 59 cert, err := x509.ParseCertificate(block.Bytes) 60 if err != nil { 61 return fmt.Errorf("error parsing cert: %s", err) 62 } 63 if expected, got := "2", cert.Subject.SerialNumber; got != expected { 64 return fmt.Errorf("incorrect subject serial number: expected %v, got %v", expected, got) 65 } 66 if expected, got := "example.com", cert.Subject.CommonName; got != expected { 67 return fmt.Errorf("incorrect subject common name: expected %v, got %v", expected, got) 68 } 69 if expected, got := "Example, Inc", cert.Subject.Organization[0]; got != expected { 70 return fmt.Errorf("incorrect subject organization: expected %v, got %v", expected, got) 71 } 72 if expected, got := "Department of Terraform Testing", cert.Subject.OrganizationalUnit[0]; got != expected { 73 return fmt.Errorf("incorrect subject organizational unit: expected %v, got %v", expected, got) 74 } 75 if expected, got := "5879 Cotton Link", cert.Subject.StreetAddress[0]; got != expected { 76 return fmt.Errorf("incorrect subject street address: expected %v, got %v", expected, got) 77 } 78 if expected, got := "Pirate Harbor", cert.Subject.Locality[0]; got != expected { 79 return fmt.Errorf("incorrect subject locality: expected %v, got %v", expected, got) 80 } 81 if expected, got := "CA", cert.Subject.Province[0]; got != expected { 82 return fmt.Errorf("incorrect subject province: expected %v, got %v", expected, got) 83 } 84 if expected, got := "US", cert.Subject.Country[0]; got != expected { 85 return fmt.Errorf("incorrect subject country: expected %v, got %v", expected, got) 86 } 87 if expected, got := "95559-1227", cert.Subject.PostalCode[0]; got != expected { 88 return fmt.Errorf("incorrect subject postal code: expected %v, got %v", expected, got) 89 } 90 91 if expected, got := 2, len(cert.DNSNames); got != expected { 92 return fmt.Errorf("incorrect number of DNS names: expected %v, got %v", expected, got) 93 } 94 if expected, got := "example.com", cert.DNSNames[0]; got != expected { 95 return fmt.Errorf("incorrect DNS name 0: expected %v, got %v", expected, got) 96 } 97 if expected, got := "example.net", cert.DNSNames[1]; got != expected { 98 return fmt.Errorf("incorrect DNS name 0: expected %v, got %v", expected, got) 99 } 100 101 if expected, got := 2, len(cert.IPAddresses); got != expected { 102 return fmt.Errorf("incorrect number of IP addresses: expected %v, got %v", expected, got) 103 } 104 if expected, got := "127.0.0.1", cert.IPAddresses[0].String(); got != expected { 105 return fmt.Errorf("incorrect IP address 0: expected %v, got %v", expected, got) 106 } 107 if expected, got := "127.0.0.2", cert.IPAddresses[1].String(); got != expected { 108 return fmt.Errorf("incorrect IP address 0: expected %v, got %v", expected, got) 109 } 110 111 if expected, got := []byte{50, 174, 195, 33, 77, 223, 57, 1, 58, 166, 246, 243, 114, 109, 59, 64, 111, 9, 198, 144}, cert.AuthorityKeyId; !bytes.Equal(got, expected) { 112 return fmt.Errorf("incorrect AuthorityKeyId: expected %v, got %v", expected, got) 113 } 114 115 if expected, got := 2, len(cert.ExtKeyUsage); got != expected { 116 return fmt.Errorf("incorrect number of ExtKeyUsage: expected %v, got %v", expected, got) 117 } 118 if expected, got := x509.ExtKeyUsageServerAuth, cert.ExtKeyUsage[0]; got != expected { 119 return fmt.Errorf("incorrect ExtKeyUsage[0]: expected %v, got %v", expected, got) 120 } 121 if expected, got := x509.ExtKeyUsageClientAuth, cert.ExtKeyUsage[1]; got != expected { 122 return fmt.Errorf("incorrect ExtKeyUsage[1]: expected %v, got %v", expected, got) 123 } 124 125 if expected, got := x509.KeyUsageKeyEncipherment|x509.KeyUsageDigitalSignature, cert.KeyUsage; got != expected { 126 return fmt.Errorf("incorrect KeyUsage: expected %v, got %v", expected, got) 127 } 128 129 // This time checking is a bit sloppy to avoid inconsistent test results 130 // depending on the power of the machine running the tests. 131 now := time.Now() 132 if cert.NotBefore.After(now) { 133 return fmt.Errorf("certificate validity begins in the future") 134 } 135 if now.Sub(cert.NotBefore) > (2 * time.Minute) { 136 return fmt.Errorf("certificate validity begins more than two minutes in the past") 137 } 138 if cert.NotAfter.Sub(cert.NotBefore) != time.Hour { 139 return fmt.Errorf("certificate validity is not one hour") 140 } 141 142 caBlock, _ := pem.Decode([]byte(testCACert)) 143 caCert, err := x509.ParseCertificate(caBlock.Bytes) 144 if err != nil { 145 return fmt.Errorf("error parsing ca cert: %s", err) 146 } 147 certPool := x509.NewCertPool() 148 149 // Verify certificate 150 _, err = cert.Verify(x509.VerifyOptions{Roots: certPool}) 151 if err == nil { 152 return errors.New("incorrectly verified certificate") 153 } else if _, ok := err.(x509.UnknownAuthorityError); !ok { 154 return fmt.Errorf("incorrect verify error: expected UnknownAuthorityError, got %v", err) 155 } 156 certPool.AddCert(caCert) 157 if _, err = cert.Verify(x509.VerifyOptions{Roots: certPool}); err != nil { 158 return fmt.Errorf("verify failed: %s", err) 159 } 160 161 return nil 162 }, 163 }, 164 }, 165 }) 166 }