1package plugin 2 3import ( 4 "bytes" 5 "crypto/ecdsa" 6 "crypto/elliptic" 7 "crypto/rand" 8 "crypto/x509" 9 "crypto/x509/pkix" 10 "encoding/pem" 11 "math/big" 12 "time" 13) 14 15// generateCert generates a temporary certificate for plugin authentication. The 16// certificate and private key are returns in PEM format. 17func generateCert() (cert []byte, privateKey []byte, err error) { 18 key, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) 19 if err != nil { 20 return nil, nil, err 21 } 22 23 serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) 24 sn, err := rand.Int(rand.Reader, serialNumberLimit) 25 if err != nil { 26 return nil, nil, err 27 } 28 29 host := "localhost" 30 31 template := &x509.Certificate{ 32 Subject: pkix.Name{ 33 CommonName: host, 34 Organization: []string{"HashiCorp"}, 35 }, 36 DNSNames: []string{host}, 37 ExtKeyUsage: []x509.ExtKeyUsage{ 38 x509.ExtKeyUsageClientAuth, 39 x509.ExtKeyUsageServerAuth, 40 }, 41 KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment | x509.KeyUsageKeyAgreement | x509.KeyUsageCertSign, 42 BasicConstraintsValid: true, 43 SerialNumber: sn, 44 NotBefore: time.Now().Add(-30 * time.Second), 45 NotAfter: time.Now().Add(262980 * time.Hour), 46 IsCA: true, 47 } 48 49 der, err := x509.CreateCertificate(rand.Reader, template, template, key.Public(), key) 50 if err != nil { 51 return nil, nil, err 52 } 53 54 var certOut bytes.Buffer 55 if err := pem.Encode(&certOut, &pem.Block{Type: "CERTIFICATE", Bytes: der}); err != nil { 56 return nil, nil, err 57 } 58 59 keyBytes, err := x509.MarshalECPrivateKey(key) 60 if err != nil { 61 return nil, nil, err 62 } 63 64 var keyOut bytes.Buffer 65 if err := pem.Encode(&keyOut, &pem.Block{Type: "EC PRIVATE KEY", Bytes: keyBytes}); err != nil { 66 return nil, nil, err 67 } 68 69 cert = certOut.Bytes() 70 privateKey = keyOut.Bytes() 71 72 return cert, privateKey, nil 73} 74