github.com/erriapo/terraform@v0.6.12-0.20160203182612-0340ea72354f/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  					got := s.RootModule().Outputs["cert_pem"]
    51  					if !strings.HasPrefix(got, "-----BEGIN CERTIFICATE----") {
    52  						return fmt.Errorf("key is missing cert PEM preamble")
    53  					}
    54  					block, _ := pem.Decode([]byte(got))
    55  					cert, err := x509.ParseCertificate(block.Bytes)
    56  					if err != nil {
    57  						return fmt.Errorf("error parsing cert: %s", err)
    58  					}
    59  					if expected, got := "2", cert.Subject.SerialNumber; got != expected {
    60  						return fmt.Errorf("incorrect subject serial number: expected %v, got %v", expected, got)
    61  					}
    62  					if expected, got := "example.com", cert.Subject.CommonName; got != expected {
    63  						return fmt.Errorf("incorrect subject common name: expected %v, got %v", expected, got)
    64  					}
    65  					if expected, got := "Example, Inc", cert.Subject.Organization[0]; got != expected {
    66  						return fmt.Errorf("incorrect subject organization: expected %v, got %v", expected, got)
    67  					}
    68  					if expected, got := "Department of Terraform Testing", cert.Subject.OrganizationalUnit[0]; got != expected {
    69  						return fmt.Errorf("incorrect subject organizational unit: expected %v, got %v", expected, got)
    70  					}
    71  					if expected, got := "5879 Cotton Link", cert.Subject.StreetAddress[0]; got != expected {
    72  						return fmt.Errorf("incorrect subject street address: expected %v, got %v", expected, got)
    73  					}
    74  					if expected, got := "Pirate Harbor", cert.Subject.Locality[0]; got != expected {
    75  						return fmt.Errorf("incorrect subject locality: expected %v, got %v", expected, got)
    76  					}
    77  					if expected, got := "CA", cert.Subject.Province[0]; got != expected {
    78  						return fmt.Errorf("incorrect subject province: expected %v, got %v", expected, got)
    79  					}
    80  					if expected, got := "US", cert.Subject.Country[0]; got != expected {
    81  						return fmt.Errorf("incorrect subject country: expected %v, got %v", expected, got)
    82  					}
    83  					if expected, got := "95559-1227", cert.Subject.PostalCode[0]; got != expected {
    84  						return fmt.Errorf("incorrect subject postal code: expected %v, got %v", expected, got)
    85  					}
    86  
    87  					if expected, got := 2, len(cert.DNSNames); got != expected {
    88  						return fmt.Errorf("incorrect number of DNS names: expected %v, got %v", expected, got)
    89  					}
    90  					if expected, got := "example.com", cert.DNSNames[0]; got != expected {
    91  						return fmt.Errorf("incorrect DNS name 0: expected %v, got %v", expected, got)
    92  					}
    93  					if expected, got := "example.net", cert.DNSNames[1]; got != expected {
    94  						return fmt.Errorf("incorrect DNS name 0: expected %v, got %v", expected, got)
    95  					}
    96  
    97  					if expected, got := 2, len(cert.IPAddresses); got != expected {
    98  						return fmt.Errorf("incorrect number of IP addresses: expected %v, got %v", expected, got)
    99  					}
   100  					if expected, got := "127.0.0.1", cert.IPAddresses[0].String(); got != expected {
   101  						return fmt.Errorf("incorrect IP address 0: expected %v, got %v", expected, got)
   102  					}
   103  					if expected, got := "127.0.0.2", cert.IPAddresses[1].String(); got != expected {
   104  						return fmt.Errorf("incorrect IP address 0: expected %v, got %v", expected, got)
   105  					}
   106  
   107  					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) {
   108  						return fmt.Errorf("incorrect AuthorityKeyId: expected %v, got %v", expected, got)
   109  					}
   110  
   111  					if expected, got := 2, len(cert.ExtKeyUsage); got != expected {
   112  						return fmt.Errorf("incorrect number of ExtKeyUsage: expected %v, got %v", expected, got)
   113  					}
   114  					if expected, got := x509.ExtKeyUsageServerAuth, cert.ExtKeyUsage[0]; got != expected {
   115  						return fmt.Errorf("incorrect ExtKeyUsage[0]: expected %v, got %v", expected, got)
   116  					}
   117  					if expected, got := x509.ExtKeyUsageClientAuth, cert.ExtKeyUsage[1]; got != expected {
   118  						return fmt.Errorf("incorrect ExtKeyUsage[1]: expected %v, got %v", expected, got)
   119  					}
   120  
   121  					if expected, got := x509.KeyUsageKeyEncipherment|x509.KeyUsageDigitalSignature, cert.KeyUsage; got != expected {
   122  						return fmt.Errorf("incorrect KeyUsage: expected %v, got %v", expected, got)
   123  					}
   124  
   125  					// This time checking is a bit sloppy to avoid inconsistent test results
   126  					// depending on the power of the machine running the tests.
   127  					now := time.Now()
   128  					if cert.NotBefore.After(now) {
   129  						return fmt.Errorf("certificate validity begins in the future")
   130  					}
   131  					if now.Sub(cert.NotBefore) > (2 * time.Minute) {
   132  						return fmt.Errorf("certificate validity begins more than two minutes in the past")
   133  					}
   134  					if cert.NotAfter.Sub(cert.NotBefore) != time.Hour {
   135  						return fmt.Errorf("certificate validity is not one hour")
   136  					}
   137  
   138  					caBlock, _ := pem.Decode([]byte(testCACert))
   139  					caCert, err := x509.ParseCertificate(caBlock.Bytes)
   140  					if err != nil {
   141  						return fmt.Errorf("error parsing ca cert: %s", err)
   142  					}
   143  					certPool := x509.NewCertPool()
   144  
   145  					// Verify certificate
   146  					_, err = cert.Verify(x509.VerifyOptions{Roots: certPool})
   147  					if err == nil {
   148  						return errors.New("incorrectly verified certificate")
   149  					} else if _, ok := err.(x509.UnknownAuthorityError); !ok {
   150  						return fmt.Errorf("incorrect verify error: expected UnknownAuthorityError, got %v", err)
   151  					}
   152  					certPool.AddCert(caCert)
   153  					if _, err = cert.Verify(x509.VerifyOptions{Roots: certPool}); err != nil {
   154  						return fmt.Errorf("verify failed: %s", err)
   155  					}
   156  
   157  					return nil
   158  				},
   159  			},
   160  		},
   161  	})
   162  }