parent
8d9c1542dd
commit
ef2112534c
@ -1,6 +1,13 @@
|
||||
COVERAGE_DIR=coverage
|
||||
|
||||
lint:
|
||||
golangci-lint run ./...
|
||||
goreportcard:
|
||||
goreportcard-cli -v
|
||||
test:
|
||||
go test ./...
|
||||
go test ./...
|
||||
test-coverage:
|
||||
rm -rf ${COVERAGE_DIR}
|
||||
mkdir ${COVERAGE_DIR}
|
||||
go test -v -coverprofile ${COVERAGE_DIR}/cover.out ./...
|
||||
go tool cover -html ${COVERAGE_DIR}/cover.out -o ${COVERAGE_DIR}/cover.html
|
@ -0,0 +1,75 @@
|
||||
package cert
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"gitlab.com/urkob/go-cert-gen/pkg/client"
|
||||
)
|
||||
|
||||
type clientCert struct {
|
||||
certPEM []byte
|
||||
keyPEM []byte
|
||||
}
|
||||
|
||||
func (c *clientCert) Key() []byte {
|
||||
return c.keyPEM
|
||||
}
|
||||
|
||||
func (c *clientCert) PEM() []byte {
|
||||
return c.certPEM
|
||||
}
|
||||
|
||||
func newClientCert(config *client.ClientCertConfig, rootCA *x509.Certificate, rootKeyPEM []byte) ([]byte, []byte, error) {
|
||||
template := &x509.Certificate{
|
||||
SerialNumber: config.Serial,
|
||||
Subject: pkix.Name{
|
||||
Organization: []string{config.Subject.Organization},
|
||||
Country: []string{config.Subject.Country},
|
||||
Province: []string{config.Subject.Province},
|
||||
Locality: []string{config.Subject.Locality},
|
||||
StreetAddress: []string{config.Subject.StreetAddress},
|
||||
PostalCode: []string{config.Subject.PostalCode},
|
||||
},
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(config.Duration),
|
||||
SubjectKeyId: config.SubjectKeyId,
|
||||
ExtKeyUsage: config.ExtKeyUsage,
|
||||
KeyUsage: config.KeyUsage,
|
||||
}
|
||||
|
||||
block, _ := pem.Decode(rootKeyPEM)
|
||||
caPrivKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("x509.ParsePKCS8PrivateKey: %s", err)
|
||||
}
|
||||
|
||||
priv, err := newPrivateKey()
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("newPrivateKey: %s", err)
|
||||
}
|
||||
|
||||
der, err := x509.CreateCertificate(rand.Reader, template, rootCA, &priv.PublicKey, caPrivKey)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("x509.CreateCertificate: %s", err)
|
||||
}
|
||||
|
||||
out := &bytes.Buffer{}
|
||||
err = pem.Encode(out, &pem.Block{Type: CERTIFICATE, Bytes: der})
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("pem.Encode: %s", err)
|
||||
}
|
||||
|
||||
certPEM := out.Bytes()
|
||||
keyPEM, err := encodePrivateKey(priv)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("encodePrivateKey: %s", err)
|
||||
}
|
||||
|
||||
return certPEM, keyPEM, nil
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package cert
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"gitlab.com/urkob/go-cert-gen/pkg/client"
|
||||
)
|
||||
|
||||
func Test_newClientCert(t *testing.T) {
|
||||
var config *client.ClientCertConfig
|
||||
var rootCA *x509.Certificate
|
||||
var rootKeyPEM []byte
|
||||
|
||||
_, _, err := newClientCert(config, rootCA, rootKeyPEM)
|
||||
require.NoError(t, err)
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
package cert
|
||||
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"crypto/x509"
|
||||
"math/big"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"gitlab.com/urkob/go-cert-gen/pkg/ca"
|
||||
"gitlab.com/urkob/go-cert-gen/pkg/client"
|
||||
)
|
||||
|
||||
const year = time.Hour * 24 * 365
|
||||
|
||||
var rootTestConfig = ca.CaConfig{
|
||||
SerialNumber: big.NewInt(12321),
|
||||
Subject: ca.CaSubject{
|
||||
Organization: "test-organization",
|
||||
CommonName: "test-organization",
|
||||
},
|
||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{
|
||||
x509.ExtKeyUsageServerAuth,
|
||||
x509.ExtKeyUsageClientAuth,
|
||||
},
|
||||
Duration: year,
|
||||
}
|
||||
|
||||
var clientTestConfig = client.ClientCertConfig{
|
||||
Serial: big.NewInt(12321),
|
||||
Subject: client.Subject{
|
||||
Organization: rootTestConfig.Subject.Organization,
|
||||
Country: "REML",
|
||||
Province: "REML",
|
||||
Locality: "REML",
|
||||
StreetAddress: "c/o Sovereign 7 rural free delivery",
|
||||
PostalCode: "[Near 777]",
|
||||
},
|
||||
Duration: year,
|
||||
SubjectKeyId: []byte{1, 2, 3, 4, 6},
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{
|
||||
x509.ExtKeyUsageServerAuth,
|
||||
x509.ExtKeyUsageClientAuth,
|
||||
},
|
||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||
}
|
||||
|
||||
func Test_newPrivateKey(t *testing.T) {
|
||||
privKey, err := newPrivateKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotEmpty(t, privKey.PublicKey.Params().Name)
|
||||
require.Equal(t, elliptic.P256(), privKey.PublicKey.Params().Name)
|
||||
}
|
||||
|
||||
func Test_encodePrivateKey(t *testing.T) {
|
||||
privKey, err := newPrivateKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
bytes, err := encodePrivateKey(privKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotNil(t, bytes)
|
||||
require.Greater(t, len(bytes), 0)
|
||||
}
|
||||
|
||||
func Test_newRootCA(t *testing.T) {
|
||||
caPEM, keyPEM, err := newRootCA(&rootTestConfig)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, caPEM)
|
||||
require.Greater(t, len(caPEM), 0)
|
||||
require.NotNil(t, keyPEM)
|
||||
require.Greater(t, len(keyPEM), 0)
|
||||
}
|
||||
|
||||
func Test_parseCertificate(t *testing.T) {
|
||||
caPEM, _, err := newRootCA(&rootTestConfig)
|
||||
require.NoError(t, err)
|
||||
|
||||
rootCert, err := parseCertificate(caPEM)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, rootCert)
|
||||
require.Equal(t, rootCert.SignatureAlgorithm, x509.ECDSAWithSHA256)
|
||||
require.Equal(t, rootCert.Issuer.Organization, []string{rootTestConfig.Subject.Organization})
|
||||
require.Equal(t, rootCert.Issuer.CommonName, rootTestConfig.Subject.CommonName)
|
||||
}
|
||||
|
||||
func TestNewRootCA(t *testing.T) {
|
||||
rootCert, err := NewRootCA(&rootTestConfig)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, rootCert)
|
||||
}
|
||||
|
||||
func Test_rootCA_WithClientCert(t *testing.T) {
|
||||
rootCert, err := NewRootCA(&rootTestConfig)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, rootCert)
|
||||
|
||||
clientSrv, err := rootCert.WithClientCert(&clientTestConfig)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, clientSrv)
|
||||
|
||||
require.NotNil(t, clientSrv.Key())
|
||||
require.Greater(t, len(clientSrv.Key()), 0)
|
||||
|
||||
require.NotNil(t, clientSrv.PEM())
|
||||
require.Greater(t, len(clientSrv.PEM()), 0)
|
||||
}
|
Loading…
Reference in new issue