package mediaserver import ( "bytes" "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/x509" "crypto/x509/pkix" "encoding/pem" "math/big" "time" ) type ( tlsCert []byte tlsKey []byte ) // generateTLSCert generates a self-signed TLS certificate and private key. func generateTLSCert() (tlsCert, tlsKey, error) { privKey, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader) if err != nil { return nil, nil, err } serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128)) if err != nil { return nil, nil, err } now := time.Now() template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"octoplex.netflux.io"}, }, NotBefore: now, NotAfter: now.Add(5 * 365 * 24 * time.Hour), KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}, BasicConstraintsValid: true, DNSNames: []string{"localhost"}, } certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &privKey.PublicKey, privKey) if err != nil { return nil, nil, err } var certPEM, keyPEM bytes.Buffer if err = pem.Encode(&certPEM, &pem.Block{Type: "CERTIFICATE", Bytes: certDER}); err != nil { return nil, nil, err } privKeyDER, err := x509.MarshalECPrivateKey(privKey) if err != nil { return nil, nil, err } if err := pem.Encode(&keyPEM, &pem.Block{Type: "EC PRIVATE KEY", Bytes: privKeyDER}); err != nil { return nil, nil, err } return certPEM.Bytes(), keyPEM.Bytes(), nil }