Fix HTTP binding unit test: generate certificates on-demand (#3308)

Signed-off-by: ItalyPaleAle <43508+ItalyPaleAle@users.noreply.github.com>
This commit is contained in:
Alessandro (Ale) Segala 2024-01-08 11:43:33 -08:00 committed by GitHub
parent 59858c49fb
commit e581f3c146
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 246 additions and 54 deletions

View File

@ -15,10 +15,17 @@ package http
import (
"context"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"io"
"math/big"
"net"
"net/http"
"net/http/httptest"
"os"
@ -51,6 +58,243 @@ func TestOperations(t *testing.T) {
}, opers)
}
//nolint:forbidigo
func TestMain(m *testing.M) {
err := generateCACertificate()
if err != nil {
fmt.Println("Failed to generate CA certificate:", err)
os.Exit(1)
}
err = generateMTLSCertificates()
if err != nil {
fmt.Println("Failed to generate mTLS certificates:", err)
os.Exit(1)
}
exitCode := m.Run()
err = deleteTestCerts()
if err != nil {
fmt.Println("Failed to delete test certificates:", err)
os.Exit(1)
}
os.Exit(exitCode)
}
func deleteTestCerts() error {
files, err := filepath.Glob(filepath.Join("testdata", "*.key"))
if err != nil {
return err
}
for _, file := range files {
err = os.Remove(file)
if err != nil {
return err
}
}
files, err = filepath.Glob(filepath.Join("testdata", "*.pem"))
if err != nil {
return err
}
for _, file := range files {
err = os.Remove(file)
if err != nil {
return err
}
}
return nil
}
func generateCACertificate() error {
// Generate a private key for the CA
caPrivateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
return err
}
// Create a self-signed CA certificate
caTemplate := &x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{CommonName: "CA"},
NotBefore: time.Now().Add(-1 * time.Hour),
NotAfter: time.Now().Add(24 * time.Hour),
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
IsCA: true,
}
caCertificate, err := x509.CreateCertificate(rand.Reader, caTemplate, caTemplate, caPrivateKey.Public(), caPrivateKey)
if err != nil {
return err
}
// Save the CA certificate to "ca.pem"
caCertFile, err := os.Create(filepath.Join("testdata", "ca.pem"))
if err != nil {
return err
}
defer caCertFile.Close()
err = pem.Encode(caCertFile, &pem.Block{Type: "CERTIFICATE", Bytes: caCertificate})
if err != nil {
return err
}
// Save the CA private key to "ca.key"
caKeyFile, err := os.Create(filepath.Join("testdata", "ca.key"))
if err != nil {
return err
}
defer caKeyFile.Close()
caPrivateKeyBytes, err := x509.MarshalPKCS8PrivateKey(caPrivateKey)
if err != nil {
return err
}
err = pem.Encode(caKeyFile, &pem.Block{Type: "PRIVATE KEY", Bytes: caPrivateKeyBytes})
if err != nil {
return err
}
return nil
}
func generateMTLSCertificates() error {
// Load the CA private key
caKeyFile, err := os.ReadFile(filepath.Join("testdata", "ca.key"))
if err != nil {
return err
}
caKeyBlock, _ := pem.Decode(caKeyFile)
caPrivateKey, err := x509.ParsePKCS8PrivateKey(caKeyBlock.Bytes)
if err != nil {
return err
}
// Load the CA certificate
caCertFile, err := os.ReadFile(filepath.Join("testdata", "ca.pem"))
if err != nil {
return err
}
caCertBlock, _ := pem.Decode(caCertFile)
caCertificate, err := x509.ParseCertificate(caCertBlock.Bytes)
if err != nil {
return err
}
// Generate a private key for the client
clientPrivateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
return err
}
// Create a certificate for the client
client := &x509.Certificate{
SerialNumber: big.NewInt(10),
Subject: pkix.Name{Organization: []string{"client"}},
NotBefore: time.Now().Add(-1 * time.Hour),
NotAfter: time.Now().Add(24 * time.Hour),
IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1), net.IPv6loopback},
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageDigitalSignature,
}
clientCertificate, err := x509.CreateCertificate(rand.Reader, client, caCertificate, clientPrivateKey.Public(), caPrivateKey)
if err != nil {
return err
}
// Save the client certificate to "client.pem"
clientCertFile, err := os.Create(filepath.Join("testdata", "client.pem"))
if err != nil {
return err
}
defer clientCertFile.Close()
err = pem.Encode(clientCertFile, &pem.Block{Type: "CERTIFICATE", Bytes: clientCertificate})
if err != nil {
return err
}
// Save the client private key to "client.key"
clientKeyFile, err := os.Create(filepath.Join("testdata", "client.key"))
if err != nil {
return err
}
defer clientKeyFile.Close()
clientPrivateKeyBytes, err := x509.MarshalPKCS8PrivateKey(clientPrivateKey)
if err != nil {
return err
}
err = pem.Encode(clientKeyFile, &pem.Block{Type: "PRIVATE KEY", Bytes: clientPrivateKeyBytes})
if err != nil {
return err
}
// Generate a private key for the server
serverPrivateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
return err
}
// Create a certificate for the server
server := &x509.Certificate{
SerialNumber: big.NewInt(11),
Subject: pkix.Name{Organization: []string{"server"}},
NotBefore: time.Now().Add(-1 * time.Hour),
NotAfter: time.Now().Add(24 * time.Hour),
IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1), net.IPv6loopback},
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageDigitalSignature,
}
serverCertificate, err := x509.CreateCertificate(rand.Reader, server, caCertificate, serverPrivateKey.Public(), caPrivateKey)
if err != nil {
return err
}
// Save the server certificate to "server.pem"
serverCertFile, err := os.Create(filepath.Join("testdata", "server.pem"))
if err != nil {
return err
}
defer serverCertFile.Close()
err = pem.Encode(serverCertFile, &pem.Block{Type: "CERTIFICATE", Bytes: serverCertificate})
if err != nil {
return err
}
// Save the server private key to "server.key"
serverKeyFile, err := os.Create(filepath.Join("testdata", "server.key"))
if err != nil {
return err
}
defer serverKeyFile.Close()
serverPrivateKeyBytes, err := x509.MarshalPKCS8PrivateKey(serverPrivateKey)
if err != nil {
return err
}
err = pem.Encode(serverKeyFile, &pem.Block{Type: "PRIVATE KEY", Bytes: serverPrivateKeyBytes})
if err != nil {
return err
}
return nil
}
type TestCase struct {
input string
operation string

2
bindings/http/testdata/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.pem
*.key

View File

@ -1,14 +0,0 @@
-----BEGIN CERTIFICATE-----
MIICHzCCAcWgAwIBAgIUVmulwhIO5Y2A8ACi3OcX94denFEwCgYIKoZIzj0EAwIw
UDELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAlRTMQswCQYDVQQHDAJIWTETMBEGA1UE
CgwKRGFwciBXb3JsZDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIzMDEwNjEwMDI0
NVoXDTI0MDEwNjEwMDI0NVowUDELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAlRTMQsw
CQYDVQQHDAJIWTETMBEGA1UECgwKRGFwciBXb3JsZDESMBAGA1UEAwwJbG9jYWxo
b3N0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE03ecfl+LFMzocftTCwpYrcJK
YwutP6My8ZNfELp0IUqvMyTCgG3o08niA4GrUGaP73wyUFhO6UaswvFccBI92aN9
MHswDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYI
KwYBBQUHAwEGCCsGAQUFBwMCMBoGA1UdEQQTMBGCCWxvY2FsaG9zdIcEfwAAATAd
BgNVHQ4EFgQUmYArK7rKcVh57kzZXYMze2RiNrMwCgYIKoZIzj0EAwIDSAAwRQIg
QtSMNNo+OWONVB4HfyV5UwjxyMxGmJwNt8qh99PWS2UCIQCyzZzBUOwNAHQv/T3D
IsCxyWZQ37yZpvS82Z/SnCIZuw==
-----END CERTIFICATE-----

View File

@ -1,5 +0,0 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIEobWR8PduGHOPY+T/Id/bNmjS8cjRQ+UID4NnCaROgmoAoGCCqGSM49
AwEHoUQDQgAEKx7xYU7DGNX+WDo5QzJGkIvrqhqbw1ZaNKe5h2QREJwwIB2X5TyT
DYaNfhqXc8IOB9si4GJ2x0JhyeoAvi/U8w==
-----END EC PRIVATE KEY-----

View File

@ -1,15 +0,0 @@
-----BEGIN CERTIFICATE-----
MIICRjCCAeugAwIBAgIUKCvur/fviGKJDitDggTtIkwQMxIwCgYIKoZIzj0EAwIw
UDELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAlRTMQswCQYDVQQHDAJIWTETMBEGA1UE
CgwKRGFwciBXb3JsZDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIzMDEwNjEwMDI0
NVoXDTI0MDEwNjEwMDI0NVowUDELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAlRTMQsw
CQYDVQQHDAJIWTETMBEGA1UECgwKRGFwciBXb3JsZDESMBAGA1UEAwwJbG9jYWxo
b3N0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEKx7xYU7DGNX+WDo5QzJGkIvr
qhqbw1ZaNKe5h2QREJwwIB2X5TyTDYaNfhqXc8IOB9si4GJ2x0JhyeoAvi/U86OB
ojCBnzASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUE
FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGgYDVR0RBBMwEYIJbG9jYWxob3N0hwR/
AAABMB0GA1UdDgQWBBRHcmSCVapIorD+/O1T+ySlkwEI+zAfBgNVHSMEGDAWgBSZ
gCsruspxWHnuTNldgzN7ZGI2szAKBggqhkjOPQQDAgNJADBGAiEAh+c11VmTeiv3
v4sRikMeiLkneDUl1wuLfffZbCLXsXkCIQC9bfk8RlH5aTTJ6Xrpz5oVyxU58v7E
2HVuTU281m67bw==
-----END CERTIFICATE-----

View File

@ -1,5 +0,0 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIBdj4qCqbLVvFqjcv14xthAm+YGghrMe6uHbE6nKg93EoAoGCCqGSM49
AwEHoUQDQgAEJup13iQfS72fRxN9JLJDLP0tel4F8bmxEfcHjvKMGJaupvvtHgZm
tlYlY6evzE6yIN5mUIcBqCWzpN+aCPBwqw==
-----END EC PRIVATE KEY-----

View File

@ -1,15 +0,0 @@
-----BEGIN CERTIFICATE-----
MIICRjCCAeugAwIBAgIUXpf5hT8jws5FV65ZFdVUITeldAYwCgYIKoZIzj0EAwIw
UDELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAlRTMQswCQYDVQQHDAJIWTETMBEGA1UE
CgwKRGFwciBXb3JsZDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIzMDEwNjEwMDI0
NVoXDTI0MDEwNjEwMDI0NVowUDELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAlRTMQsw
CQYDVQQHDAJIWTETMBEGA1UECgwKRGFwciBXb3JsZDESMBAGA1UEAwwJbG9jYWxo
b3N0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJup13iQfS72fRxN9JLJDLP0t
el4F8bmxEfcHjvKMGJaupvvtHgZmtlYlY6evzE6yIN5mUIcBqCWzpN+aCPBwq6OB
ojCBnzASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUE
FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGgYDVR0RBBMwEYIJbG9jYWxob3N0hwR/
AAABMB0GA1UdDgQWBBRkZKt5a3/g5ea0eVufjBT3QL5xkTAfBgNVHSMEGDAWgBSZ
gCsruspxWHnuTNldgzN7ZGI2szAKBggqhkjOPQQDAgNJADBGAiEAkO5nX2Eofa0k
R+u1zIiwJilwzgI9A2WnnvLWWmKiQkQCIQDtoS4x1bKaPyCTtLJ91fwSPxWdexhQ
CDsniMd431J38g==
-----END CERTIFICATE-----