1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
package testhelpers
import (
"crypto"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/pem"
"math/big"
"net"
"os"
"path/filepath"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func GenerateCACert(t *testing.T) (string /* caCertFile */, string /* caKeyFile */, *x509.Certificate /* caCert */, crypto.PrivateKey /* caKey */) {
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
require.NoError(t, err)
publicKey := privateKey.Public()
spkiASN1, err := x509.MarshalPKIXPublicKey(publicKey)
require.NoError(t, err)
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(spkiASN1, &spki)
require.NoError(t, err)
skid := sha256.Sum256(spki.SubjectPublicKey.Bytes)
tpl := &x509.Certificate{
SerialNumber: randomSerialNumber(t),
Subject: pkix.Name{
Organization: []string{"GitLab test CA"},
OrganizationalUnit: []string{"group::environments"},
CommonName: "test CA cert",
},
SubjectKeyId: skid[:],
NotAfter: time.Now().Add(time.Hour),
NotBefore: time.Now(),
KeyUsage: x509.KeyUsageCertSign,
BasicConstraintsValid: true,
IsCA: true,
MaxPathLenZero: true,
}
tmp := t.TempDir()
cert, err := x509.CreateCertificate(rand.Reader, tpl, tpl, publicKey, privateKey)
require.NoError(t, err)
certTyped, err := x509.ParseCertificate(cert)
require.NoError(t, err)
caCertFile := filepath.Join(tmp, "ca-cert.pem")
err = os.WriteFile(caCertFile, pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert}), 0600)
require.NoError(t, err)
privateDER, err := x509.MarshalPKCS8PrivateKey(privateKey)
require.NoError(t, err)
caKeyFile := filepath.Join(tmp, "ca-key.pem")
err = os.WriteFile(caKeyFile, pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privateDER}), 0400)
require.NoError(t, err)
return caCertFile, caKeyFile, certTyped, privateKey
}
func GenerateCert(t *testing.T, name string, caCert *x509.Certificate, caKey crypto.PrivateKey) (string /* certFile */, string /* keyFile */) {
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
require.NoError(t, err)
publicKey := privateKey.Public()
tpl := &x509.Certificate{
SerialNumber: randomSerialNumber(t),
Subject: pkix.Name{
Organization: []string{"GitLab test certificate - " + name},
OrganizationalUnit: []string{"group::environments"},
},
NotBefore: time.Now(),
NotAfter: time.Now().Add(time.Hour),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
IPAddresses: []net.IP{{127, 0, 0, 1}},
}
cert, err := x509.CreateCertificate(rand.Reader, tpl, caCert, publicKey, caKey)
require.NoError(t, err)
tmp := t.TempDir()
certFile := filepath.Join(tmp, name+"-cert.pem")
err = os.WriteFile(certFile, pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert}), 0600)
require.NoError(t, err)
privateDER, err := x509.MarshalPKCS8PrivateKey(privateKey)
require.NoError(t, err)
keyFile := filepath.Join(tmp, name+"-key.pem")
err = os.WriteFile(keyFile, pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privateDER}), 0400)
require.NoError(t, err)
return certFile, keyFile
}
func randomSerialNumber(t *testing.T) *big.Int {
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
require.NoError(t, err)
return serialNumber
}
|