mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-09-19 09:40:12 +00:00
111 lines
3.2 KiB
Go
111 lines
3.2 KiB
Go
package fixture
|
|
|
|
import (
|
|
"crypto/ecdsa"
|
|
"crypto/elliptic"
|
|
"crypto/rand"
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"crypto/x509/pkix"
|
|
"encoding/pem"
|
|
"errors"
|
|
"math/big"
|
|
"net"
|
|
"time"
|
|
)
|
|
|
|
type LocalTLSFixture struct {
|
|
certificate tls.Certificate
|
|
rootCAs *x509.CertPool
|
|
caPEM []byte
|
|
certificatePEM []byte
|
|
privateKeyPEM []byte
|
|
}
|
|
|
|
func NewLocalTLSFixture(now time.Time) (LocalTLSFixture, error) {
|
|
caKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
if err != nil {
|
|
return LocalTLSFixture{}, err
|
|
}
|
|
caTemplate := &x509.Certificate{
|
|
SerialNumber: big.NewInt(1),
|
|
Subject: pkix.Name{CommonName: "agentcompat local CA"},
|
|
NotBefore: now.Add(-time.Hour),
|
|
NotAfter: now.Add(24 * time.Hour),
|
|
IsCA: true,
|
|
BasicConstraintsValid: true,
|
|
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageDigitalSignature,
|
|
}
|
|
caDER, err := x509.CreateCertificate(rand.Reader, caTemplate, caTemplate, &caKey.PublicKey, caKey)
|
|
if err != nil {
|
|
return LocalTLSFixture{}, err
|
|
}
|
|
leafKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
if err != nil {
|
|
return LocalTLSFixture{}, err
|
|
}
|
|
leafTemplate := &x509.Certificate{
|
|
SerialNumber: big.NewInt(2),
|
|
Subject: pkix.Name{CommonName: "localhost"},
|
|
NotBefore: now.Add(-time.Hour),
|
|
NotAfter: now.Add(24 * time.Hour),
|
|
KeyUsage: x509.KeyUsageDigitalSignature,
|
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
|
DNSNames: []string{"localhost"},
|
|
IPAddresses: []net.IP{net.ParseIP("127.0.0.1"), net.ParseIP("::1")},
|
|
}
|
|
leafDER, err := x509.CreateCertificate(rand.Reader, leafTemplate, caTemplate, &leafKey.PublicKey, caKey)
|
|
if err != nil {
|
|
return LocalTLSFixture{}, err
|
|
}
|
|
leafKeyDER, err := x509.MarshalPKCS8PrivateKey(leafKey)
|
|
if err != nil {
|
|
return LocalTLSFixture{}, err
|
|
}
|
|
caPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: caDER})
|
|
certificatePEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: leafDER})
|
|
privateKeyPEM := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: leafKeyDER})
|
|
certificate, err := tls.X509KeyPair(certificatePEM, privateKeyPEM)
|
|
if err != nil {
|
|
return LocalTLSFixture{}, err
|
|
}
|
|
rootCAs := x509.NewCertPool()
|
|
if !rootCAs.AppendCertsFromPEM(caPEM) {
|
|
return LocalTLSFixture{}, errors.New("append local CA certificate")
|
|
}
|
|
return LocalTLSFixture{
|
|
certificate: certificate,
|
|
rootCAs: rootCAs,
|
|
caPEM: caPEM,
|
|
certificatePEM: certificatePEM,
|
|
privateKeyPEM: privateKeyPEM,
|
|
}, nil
|
|
}
|
|
|
|
func (fixture LocalTLSFixture) ClientConfig(serverName string) *tls.Config {
|
|
return &tls.Config{
|
|
MinVersion: tls.VersionTLS13,
|
|
RootCAs: fixture.rootCAs.Clone(),
|
|
ServerName: serverName,
|
|
}
|
|
}
|
|
|
|
func (fixture LocalTLSFixture) Listener(listener net.Listener) net.Listener {
|
|
return tls.NewListener(listener, &tls.Config{
|
|
MinVersion: tls.VersionTLS13,
|
|
Certificates: []tls.Certificate{fixture.certificate},
|
|
})
|
|
}
|
|
|
|
func (fixture LocalTLSFixture) CAPEM() []byte {
|
|
return append([]byte(nil), fixture.caPEM...)
|
|
}
|
|
|
|
func (fixture LocalTLSFixture) CertificatePEM() []byte {
|
|
return append([]byte(nil), fixture.certificatePEM...)
|
|
}
|
|
|
|
func (fixture LocalTLSFixture) PrivateKeyPEM() []byte {
|
|
return append([]byte(nil), fixture.privateKeyPEM...)
|
|
}
|