package plugin import ( "bytes" "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/x509" "crypto/x509/pkix" "encoding/pem" "math/big" "time" ) // generateCert generates a temporary certificate for plugin authentication. The // certificate and private key are returns in PEM format. func generateCert() (cert []byte, privateKey []byte, err error) { key, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) if err != nil { return nil, nil, err } serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) sn, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { return nil, nil, err } host := "localhost" template := &x509.Certificate{ Subject: pkix.Name{ CommonName: host, Organization: []string{"HashiCorp"}, }, DNSNames: []string{host}, ExtKeyUsage: []x509.ExtKeyUsage{ x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth, }, KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment | x509.KeyUsageKeyAgreement | x509.KeyUsageCertSign, BasicConstraintsValid: true, SerialNumber: sn, NotBefore: time.Now().Add(-30 * time.Second), NotAfter: time.Now().Add(262980 * time.Hour), IsCA: true, } der, err := x509.CreateCertificate(rand.Reader, template, template, key.Public(), key) if err != nil { return nil, nil, err } var certOut bytes.Buffer if err := pem.Encode(&certOut, &pem.Block{Type: "CERTIFICATE", Bytes: der}); err != nil { return nil, nil, err } keyBytes, err := x509.MarshalECPrivateKey(key) if err != nil { return nil, nil, err } var keyOut bytes.Buffer if err := pem.Encode(&keyOut, &pem.Block{Type: "EC PRIVATE KEY", Bytes: keyBytes}); err != nil { return nil, nil, err } cert = certOut.Bytes() privateKey = keyOut.Bytes() return cert, privateKey, nil }