github.com/criteo-forks/consul@v1.4.5-criteonogrpc/command/tls/generate_test.go (about)

     1  package tls
     2  
     3  import (
     4  	"crypto"
     5  	"crypto/ecdsa"
     6  	"crypto/elliptic"
     7  	"crypto/rand"
     8  	"crypto/rsa"
     9  	"crypto/x509"
    10  	"encoding/pem"
    11  	"fmt"
    12  	"io"
    13  	"net"
    14  	"testing"
    15  	"time"
    16  
    17  	"github.com/stretchr/testify/require"
    18  )
    19  
    20  func TestSerialNumber(t *testing.T) {
    21  	n1, err := GenerateSerialNumber()
    22  	require.Nil(t, err)
    23  
    24  	n2, err := GenerateSerialNumber()
    25  	require.Nil(t, err)
    26  	require.NotEqual(t, n1, n2)
    27  
    28  	n3, err := GenerateSerialNumber()
    29  	require.Nil(t, err)
    30  	require.NotEqual(t, n1, n3)
    31  	require.NotEqual(t, n2, n3)
    32  
    33  }
    34  
    35  func TestGeneratePrivateKey(t *testing.T) {
    36  	t.Parallel()
    37  	_, p, err := GeneratePrivateKey()
    38  	require.Nil(t, err)
    39  	require.NotEmpty(t, p)
    40  	require.Contains(t, p, "BEGIN EC PRIVATE KEY")
    41  	require.Contains(t, p, "END EC PRIVATE KEY")
    42  
    43  	block, _ := pem.Decode([]byte(p))
    44  	pk, err := x509.ParseECPrivateKey(block.Bytes)
    45  
    46  	require.Nil(t, err)
    47  	require.NotNil(t, pk)
    48  	require.Equal(t, 256, pk.Params().BitSize)
    49  }
    50  
    51  type TestSigner struct {
    52  	public interface{}
    53  }
    54  
    55  func (s *TestSigner) Public() crypto.PublicKey {
    56  	return s.public
    57  }
    58  
    59  func (s *TestSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
    60  	return []byte{}, nil
    61  }
    62  
    63  func TestGenerateCA(t *testing.T) {
    64  	t.Parallel()
    65  	sn, err := GenerateSerialNumber()
    66  	require.Nil(t, err)
    67  	var s crypto.Signer
    68  
    69  	// test what happens without key
    70  	s = &TestSigner{}
    71  	ca, err := GenerateCA(s, sn, 0, nil)
    72  	require.Error(t, err)
    73  	require.Empty(t, ca)
    74  
    75  	// test what happens with wrong key
    76  	s = &TestSigner{public: &rsa.PublicKey{}}
    77  	ca, err = GenerateCA(s, sn, 0, nil)
    78  	require.Error(t, err)
    79  	require.Empty(t, ca)
    80  
    81  	// test what happens with correct key
    82  	s, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    83  	require.Nil(t, err)
    84  	ca, err = GenerateCA(s, sn, 365, nil)
    85  	require.Nil(t, err)
    86  	require.NotEmpty(t, ca)
    87  
    88  	cert, err := parseCert(ca)
    89  	require.Nil(t, err)
    90  	require.Equal(t, fmt.Sprintf("Consul Agent CA %d", sn), cert.Subject.CommonName)
    91  	require.Equal(t, true, cert.IsCA)
    92  	require.Equal(t, true, cert.BasicConstraintsValid)
    93  
    94  	// format so that we don't take anything smaller than second into account.
    95  	require.Equal(t, cert.NotBefore.Format(time.ANSIC), time.Now().UTC().Format(time.ANSIC))
    96  	require.Equal(t, cert.NotAfter.Format(time.ANSIC), time.Now().AddDate(0, 0, 365).UTC().Format(time.ANSIC))
    97  
    98  	require.Equal(t, x509.KeyUsageCertSign|x509.KeyUsageCRLSign|x509.KeyUsageDigitalSignature, cert.KeyUsage)
    99  }
   100  
   101  func TestGenerateCert(t *testing.T) {
   102  	t.Parallel()
   103  	sn, err := GenerateSerialNumber()
   104  	require.Nil(t, err)
   105  	signer, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   106  	require.Nil(t, err)
   107  	ca, err := GenerateCA(signer, sn, 365, nil)
   108  	require.Nil(t, err)
   109  
   110  	sn, err = GenerateSerialNumber()
   111  	require.Nil(t, err)
   112  	DNSNames := []string{"server.dc1.consul"}
   113  	IPAddresses := []net.IP{net.ParseIP("123.234.243.213")}
   114  	extKeyUsage := []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}
   115  	name := "Cert Name"
   116  	certificate, pk, err := GenerateCert(signer, ca, sn, name, 365, DNSNames, IPAddresses, extKeyUsage)
   117  	require.Nil(t, err)
   118  	require.NotEmpty(t, certificate)
   119  	require.NotEmpty(t, pk)
   120  
   121  	cert, err := parseCert(certificate)
   122  	require.Nil(t, err)
   123  	require.Equal(t, name, cert.Subject.CommonName)
   124  	require.Equal(t, true, cert.BasicConstraintsValid)
   125  	signee, err := ParseSigner(pk)
   126  	require.Nil(t, err)
   127  	certID, err := keyID(signee.Public())
   128  	require.Nil(t, err)
   129  	require.Equal(t, certID, cert.SubjectKeyId)
   130  	caID, err := keyID(signer.Public())
   131  	require.Nil(t, err)
   132  	require.Equal(t, caID, cert.AuthorityKeyId)
   133  	require.Contains(t, cert.Issuer.CommonName, "Consul Agent CA")
   134  	require.Equal(t, false, cert.IsCA)
   135  
   136  	// format so that we don't take anything smaller than second into account.
   137  	require.Equal(t, cert.NotBefore.Format(time.ANSIC), time.Now().UTC().Format(time.ANSIC))
   138  	require.Equal(t, cert.NotAfter.Format(time.ANSIC), time.Now().AddDate(0, 0, 365).UTC().Format(time.ANSIC))
   139  
   140  	require.Equal(t, x509.KeyUsageDigitalSignature|x509.KeyUsageKeyEncipherment, cert.KeyUsage)
   141  	require.Equal(t, extKeyUsage, cert.ExtKeyUsage)
   142  
   143  	// https://github.com/golang/go/blob/10538a8f9e2e718a47633ac5a6e90415a2c3f5f1/src/crypto/x509/verify.go#L414
   144  	require.Equal(t, DNSNames, cert.DNSNames)
   145  	require.True(t, IPAddresses[0].Equal(cert.IPAddresses[0]))
   146  }