github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/common/crypto/tlsgen/ca.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package tlsgen
     8  
     9  import (
    10  	"crypto"
    11  	"crypto/x509"
    12  )
    13  
    14  // CertKeyPair denotes a TLS certificate and corresponding key,
    15  // both PEM encoded
    16  type CertKeyPair struct {
    17  	// Cert is the certificate, PEM encoded
    18  	Cert []byte
    19  	// Key is the key corresponding to the certificate, PEM encoded
    20  	Key []byte
    21  
    22  	crypto.Signer
    23  	TLSCert *x509.Certificate
    24  }
    25  
    26  // CA defines a certificate authority that can generate
    27  // certificates signed by it
    28  type CA interface {
    29  	// CertBytes returns the certificate of the CA in PEM encoding
    30  	CertBytes() []byte
    31  
    32  	NewIntermediateCA() (CA, error)
    33  
    34  	// newCertKeyPair returns a certificate and private key pair and nil,
    35  	// or nil, error in case of failure
    36  	// The certificate is signed by the CA and is used for TLS client authentication
    37  	NewClientCertKeyPair() (*CertKeyPair, error)
    38  
    39  	// NewServerCertKeyPair returns a CertKeyPair and nil,
    40  	// with a given custom SAN.
    41  	// The certificate is signed by the CA.
    42  	// Returns nil, error in case of failure
    43  	NewServerCertKeyPair(hosts ...string) (*CertKeyPair, error)
    44  
    45  	// Signer returns a crypto.Signer that signs with the CA's private key.
    46  	Signer() crypto.Signer
    47  }
    48  
    49  type ca struct {
    50  	caCert *CertKeyPair
    51  }
    52  
    53  func NewCA() (CA, error) {
    54  	c := &ca{}
    55  	var err error
    56  	c.caCert, err = newCertKeyPair(true, false, nil, nil)
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  	return c, nil
    61  }
    62  
    63  func (c *ca) NewIntermediateCA() (CA, error) {
    64  	intermediateCA := &ca{}
    65  	var err error
    66  	intermediateCA.caCert, err = newCertKeyPair(true, false, c.caCert.Signer, c.caCert.TLSCert)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  	return intermediateCA, nil
    71  }
    72  
    73  // CertBytes returns the certificate of the CA in PEM encoding
    74  func (c *ca) CertBytes() []byte {
    75  	return c.caCert.Cert
    76  }
    77  
    78  // newClientCertKeyPair returns a certificate and private key pair and nil,
    79  // or nil, error in case of failure
    80  // The certificate is signed by the CA and is used as a client TLS certificate
    81  func (c *ca) NewClientCertKeyPair() (*CertKeyPair, error) {
    82  	return newCertKeyPair(false, false, c.caCert.Signer, c.caCert.TLSCert)
    83  }
    84  
    85  // newServerCertKeyPair returns a certificate and private key pair and nil,
    86  // or nil, error in case of failure
    87  // The certificate is signed by the CA and is used as a server TLS certificate
    88  func (c *ca) NewServerCertKeyPair(hosts ...string) (*CertKeyPair, error) {
    89  	keypair, err := newCertKeyPair(false, true, c.caCert.Signer, c.caCert.TLSCert, hosts...)
    90  	if err != nil {
    91  		return nil, err
    92  	}
    93  	return keypair, nil
    94  }
    95  
    96  // Signer returns a crypto.Signer that signs with the CA's private key.
    97  func (c *ca) Signer() crypto.Signer {
    98  	return c.caCert.Signer
    99  }