package server import ( "context" "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/tls" "crypto/x509" "crypto/x509/pkix" "encoding/pem" "math/big" "time" "go.miragespace.co/specter/spec/cipher" ) type SelfSignedProvider struct { cert *tls.Certificate RootDomain string } var _ cipher.CertProvider = (*SelfSignedProvider)(nil) func (s *SelfSignedProvider) Initialize(_ context.Context) error { priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { return err } keyDER, err := x509.MarshalECPrivateKey(priv) if err != nil { return err } serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { return err } template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"Dev"}, }, NotBefore: time.Now(), NotAfter: time.Now().Add(time.Hour * 24 * 180), KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, DNSNames: []string{ s.RootDomain, "*." + s.RootDomain, }, } certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { return err } keyPEM := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: keyDER}) certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER}) tlsCert, err := tls.X509KeyPair(certPEM, keyPEM) if err != nil { return err } s.cert = &tlsCert return nil } func (s *SelfSignedProvider) GetCertificate(_ *tls.ClientHelloInfo) (*tls.Certificate, error) { return s.cert, nil } func (s *SelfSignedProvider) GetCertificateWithContext(context.Context, *tls.ClientHelloInfo) (*tls.Certificate, error) { return s.cert, nil } func (s *SelfSignedProvider) OnHandshake(_ cipher.OnHandshakeFunc) {}