File
Blob: cmd/server/self_signed.go
| 1 | package server |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "crypto/ecdsa" |
| 6 | "crypto/elliptic" |
| 7 | "crypto/rand" |
| 8 | "crypto/tls" |
| 9 | "crypto/x509" |
| 10 | "crypto/x509/pkix" |
| 11 | "encoding/pem" |
| 12 | "math/big" |
| 13 | "time" |
| 14 | |
| 15 | "go.miragespace.co/specter/spec/cipher" |
| 16 | ) |
| 17 | |
| 18 | type SelfSignedProvider struct { |
| 19 | cert *tls.Certificate |
| 20 | RootDomain string |
| 21 | } |
| 22 | |
| 23 | var _ cipher.CertProvider = (*SelfSignedProvider)(nil) |
| 24 | |
| 25 | func (s *SelfSignedProvider) Initialize(_ context.Context) error { |
| 26 | priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) |
| 27 | if err != nil { |
| 28 | return err |
| 29 | } |
| 30 | keyDER, err := x509.MarshalECPrivateKey(priv) |
| 31 | if err != nil { |
| 32 | return err |
| 33 | } |
| 34 | serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) |
| 35 | serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) |
| 36 | if err != nil { |
| 37 | return err |
| 38 | } |
| 39 | template := x509.Certificate{ |
| 40 | SerialNumber: serialNumber, |
| 41 | Subject: pkix.Name{ |
| 42 | Organization: []string{"Dev"}, |
| 43 | }, |
| 44 | NotBefore: time.Now(), |
| 45 | NotAfter: time.Now().Add(time.Hour * 24 * 180), |
| 46 | |
| 47 | KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, |
| 48 | ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, |
| 49 | BasicConstraintsValid: true, |
| 50 | |
| 51 | DNSNames: []string{ |
| 52 | s.RootDomain, |
| 53 | "*." + s.RootDomain, |
| 54 | }, |
| 55 | } |
| 56 | certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) |
| 57 | if err != nil { |
| 58 | return err |
| 59 | } |
| 60 | keyPEM := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: keyDER}) |
| 61 | certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER}) |
| 62 | |
| 63 | tlsCert, err := tls.X509KeyPair(certPEM, keyPEM) |
| 64 | if err != nil { |
| 65 | return err |
| 66 | } |
| 67 | |
| 68 | s.cert = &tlsCert |
| 69 | |
| 70 | return nil |
| 71 | } |
| 72 | |
| 73 | func (s *SelfSignedProvider) GetCertificate(_ *tls.ClientHelloInfo) (*tls.Certificate, error) { |
| 74 | return s.cert, nil |
| 75 | } |
| 76 | |
| 77 | func (s *SelfSignedProvider) GetCertificateWithContext(context.Context, *tls.ClientHelloInfo) (*tls.Certificate, error) { |
| 78 | return s.cert, nil |
| 79 | } |
| 80 | |
| 81 | func (s *SelfSignedProvider) OnHandshake(_ cipher.OnHandshakeFunc) {} |