package presences import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/tls" "crypto/x509" "crypto/x509/pkix" "encoding/pem" "fmt" "math/big" "time" ) func newTLSPair() (tls.Certificate, error) { //TODO revise this code to make sure it is satisfying // Generate an ECDSA private key using P256. priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { return tls.Certificate{}, fmt.Errorf("Failed to generate private key: %v", err) } // Generate a random serial number. serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128)) if err != nil { return tls.Certificate{}, fmt.Errorf("Failed to generate serial number: %v", err) } // Create a certificate template. template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"AGECEM-bottin-presences"}, CommonName: "localhost", // common name localhost for local development }, NotBefore: time.Now().Add(-time.Hour), // valid from 1 hour ago NotAfter: time.Now().Add(365 * 24 * time.Hour), // valid for 1 year KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, IsCA: true, // self-signed, so we can mark it as CA (optional) } // Self-sign the certificate. derCert, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { return tls.Certificate{}, fmt.Errorf("Failed to create certificate: %v", err) } // Encode the certificate PEM block. certPEM := pem.EncodeToMemory(&pem.Block{ Type: "CERTIFICATE", Bytes: derCert, }) // Encode the private key PEM block. keyBytes, err := x509.MarshalECPrivateKey(priv) if err != nil { return tls.Certificate{}, fmt.Errorf("Unable to marshal ECDSA private key: %v", err) } keyPEM := pem.EncodeToMemory(&pem.Block{ Type: "EC PRIVATE KEY", Bytes: keyBytes, }) // Load the generated certificate into a tls.Certificate. tlsCert, err := tls.X509KeyPair(certPEM, keyPEM) if err != nil { return tls.Certificate{}, fmt.Errorf("failed to load X509 key pair: %v", err) } return tlsCert, nil }