mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-14 17:44:26 -06:00
As of this commit this provider has only logical resources that allow the creation of private keys, self-signed certs and certificate requests. These can be useful when creating other resources that use TLS certificates, such as AWS Elastic Load Balancers. Later it could grow to include support for real certificate provision from CAs using the LetsEncrypt ACME protocol, once it is stable.
153 lines
6.2 KiB
Go
153 lines
6.2 KiB
Go
package tls
|
|
|
|
import (
|
|
"crypto/x509"
|
|
"encoding/pem"
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
r "github.com/hashicorp/terraform/helper/resource"
|
|
"github.com/hashicorp/terraform/terraform"
|
|
)
|
|
|
|
func TestSelfSignedCert(t *testing.T) {
|
|
r.Test(t, r.TestCase{
|
|
Providers: testProviders,
|
|
Steps: []r.TestStep{
|
|
r.TestStep{
|
|
Config: fmt.Sprintf(`
|
|
resource "tls_self_signed_cert" "test" {
|
|
subject {
|
|
common_name = "example.com"
|
|
organization = "Example, Inc"
|
|
organizational_unit = "Department of Terraform Testing"
|
|
street_address = ["5879 Cotton Link"]
|
|
locality = "Pirate Harbor"
|
|
province = "CA"
|
|
country = "US"
|
|
postal_code = "95559-1227"
|
|
serial_number = "2"
|
|
}
|
|
|
|
dns_names = [
|
|
"example.com",
|
|
"example.net",
|
|
]
|
|
|
|
ip_addresses = [
|
|
"127.0.0.1",
|
|
"127.0.0.2",
|
|
]
|
|
|
|
validity_period_hours = 1
|
|
|
|
allowed_uses = [
|
|
"key_encipherment",
|
|
"digital_signature",
|
|
"server_auth",
|
|
"client_auth",
|
|
]
|
|
|
|
key_algorithm = "RSA"
|
|
private_key_pem = <<EOT
|
|
%s
|
|
EOT
|
|
}
|
|
output "key_pem" {
|
|
value = "${tls_self_signed_cert.test.cert_pem}"
|
|
}
|
|
`, testPrivateKey),
|
|
Check: func(s *terraform.State) error {
|
|
got := s.RootModule().Outputs["key_pem"]
|
|
if !strings.HasPrefix(got, "-----BEGIN CERTIFICATE----") {
|
|
return fmt.Errorf("key is missing cert PEM preamble")
|
|
}
|
|
block, _ := pem.Decode([]byte(got))
|
|
cert, err := x509.ParseCertificate(block.Bytes)
|
|
if err != nil {
|
|
return fmt.Errorf("error parsing cert: %s", err)
|
|
}
|
|
if expected, got := "2", cert.Subject.SerialNumber; got != expected {
|
|
return fmt.Errorf("incorrect subject serial number: expected %v, got %v", expected, got)
|
|
}
|
|
if expected, got := "example.com", cert.Subject.CommonName; got != expected {
|
|
return fmt.Errorf("incorrect subject common name: expected %v, got %v", expected, got)
|
|
}
|
|
if expected, got := "Example, Inc", cert.Subject.Organization[0]; got != expected {
|
|
return fmt.Errorf("incorrect subject organization: expected %v, got %v", expected, got)
|
|
}
|
|
if expected, got := "Department of Terraform Testing", cert.Subject.OrganizationalUnit[0]; got != expected {
|
|
return fmt.Errorf("incorrect subject organizational unit: expected %v, got %v", expected, got)
|
|
}
|
|
if expected, got := "5879 Cotton Link", cert.Subject.StreetAddress[0]; got != expected {
|
|
return fmt.Errorf("incorrect subject street address: expected %v, got %v", expected, got)
|
|
}
|
|
if expected, got := "Pirate Harbor", cert.Subject.Locality[0]; got != expected {
|
|
return fmt.Errorf("incorrect subject locality: expected %v, got %v", expected, got)
|
|
}
|
|
if expected, got := "CA", cert.Subject.Province[0]; got != expected {
|
|
return fmt.Errorf("incorrect subject province: expected %v, got %v", expected, got)
|
|
}
|
|
if expected, got := "US", cert.Subject.Country[0]; got != expected {
|
|
return fmt.Errorf("incorrect subject country: expected %v, got %v", expected, got)
|
|
}
|
|
if expected, got := "95559-1227", cert.Subject.PostalCode[0]; got != expected {
|
|
return fmt.Errorf("incorrect subject postal code: expected %v, got %v", expected, got)
|
|
}
|
|
|
|
if expected, got := 2, len(cert.DNSNames); got != expected {
|
|
return fmt.Errorf("incorrect number of DNS names: expected %v, got %v", expected, got)
|
|
}
|
|
if expected, got := "example.com", cert.DNSNames[0]; got != expected {
|
|
return fmt.Errorf("incorrect DNS name 0: expected %v, got %v", expected, got)
|
|
}
|
|
if expected, got := "example.net", cert.DNSNames[1]; got != expected {
|
|
return fmt.Errorf("incorrect DNS name 0: expected %v, got %v", expected, got)
|
|
}
|
|
|
|
if expected, got := 2, len(cert.IPAddresses); got != expected {
|
|
return fmt.Errorf("incorrect number of IP addresses: expected %v, got %v", expected, got)
|
|
}
|
|
if expected, got := "127.0.0.1", cert.IPAddresses[0].String(); got != expected {
|
|
return fmt.Errorf("incorrect IP address 0: expected %v, got %v", expected, got)
|
|
}
|
|
if expected, got := "127.0.0.2", cert.IPAddresses[1].String(); got != expected {
|
|
return fmt.Errorf("incorrect IP address 0: expected %v, got %v", expected, got)
|
|
}
|
|
|
|
if expected, got := 2, len(cert.ExtKeyUsage); got != expected {
|
|
return fmt.Errorf("incorrect number of ExtKeyUsage: expected %v, got %v", expected, got)
|
|
}
|
|
if expected, got := x509.ExtKeyUsageServerAuth, cert.ExtKeyUsage[0]; got != expected {
|
|
return fmt.Errorf("incorrect ExtKeyUsage[0]: expected %v, got %v", expected, got)
|
|
}
|
|
if expected, got := x509.ExtKeyUsageClientAuth, cert.ExtKeyUsage[1]; got != expected {
|
|
return fmt.Errorf("incorrect ExtKeyUsage[1]: expected %v, got %v", expected, got)
|
|
}
|
|
|
|
if expected, got := x509.KeyUsageKeyEncipherment|x509.KeyUsageDigitalSignature, cert.KeyUsage; got != expected {
|
|
return fmt.Errorf("incorrect KeyUsage: expected %v, got %v", expected, got)
|
|
}
|
|
|
|
// This time checking is a bit sloppy to avoid inconsistent test results
|
|
// depending on the power of the machine running the tests.
|
|
now := time.Now()
|
|
if cert.NotBefore.After(now) {
|
|
return fmt.Errorf("certificate validity begins in the future")
|
|
}
|
|
if now.Sub(cert.NotBefore) > (2 * time.Minute) {
|
|
return fmt.Errorf("certificate validity begins more than two minutes in the past")
|
|
}
|
|
if cert.NotAfter.Sub(cert.NotBefore) != time.Hour {
|
|
return fmt.Errorf("certificate validity is not one hour")
|
|
}
|
|
|
|
return nil
|
|
},
|
|
},
|
|
},
|
|
})
|
|
}
|