github.com/hashicorp/go-plugin@v1.6.0/mtls.go (about)

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