Compare commits
5 Commits
99c2ebe055
...
72ffe8456d
Author | SHA1 | Date |
---|---|---|
Urko | 72ffe8456d | |
Urko | 8b1d063ffe | |
Urko | bb9df2fe8d | |
Urko | ef2112534c | |
Urko | 8d9c1542dd |
|
@ -1,3 +1,5 @@
|
||||||
.env
|
.env
|
||||||
viper.default.yaml
|
viper.default.yaml
|
||||||
.vscode
|
.vscode
|
||||||
|
certs
|
||||||
|
coverage
|
|
@ -0,0 +1,8 @@
|
||||||
|
---- Definitions ----
|
||||||
|
license means right to use
|
||||||
|
|
||||||
|
|
||||||
|
Everybody is invited to contribute to improve this project and the main idea.
|
||||||
|
This idea which is to help the community to develop more secure code.
|
||||||
|
|
||||||
|
By the grace of YAHWEH
|
7
Makefile
7
Makefile
|
@ -1,6 +1,13 @@
|
||||||
|
COVERAGE_DIR=coverage
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
golangci-lint run ./...
|
golangci-lint run ./...
|
||||||
goreportcard:
|
goreportcard:
|
||||||
goreportcard-cli -v
|
goreportcard-cli -v
|
||||||
test:
|
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
|
11
README.md
11
README.md
|
@ -65,15 +65,14 @@ make goreportcard
|
||||||
```
|
```
|
||||||
output:
|
output:
|
||||||
```bash
|
```bash
|
||||||
goreportcard-cli -v
|
➜ go-cert-gen git:(main) goreportcard-cli -v
|
||||||
Grade ........... A+ 94.1%
|
Grade .......... A+ 100.0%
|
||||||
Files .................. 9
|
Files ................. 12
|
||||||
Issues ................. 1
|
Issues ................. 0
|
||||||
gofmt ............... 100%
|
gofmt ............... 100%
|
||||||
go_vet .............. 100%
|
go_vet .............. 100%
|
||||||
gocyclo ............. 100%
|
gocyclo ............. 100%
|
||||||
ineffassign ......... 100%
|
ineffassign ......... 100%
|
||||||
license ............... 0%
|
license ............. 100%
|
||||||
|
|
||||||
misspell ............ 100%
|
misspell ............ 100%
|
||||||
```
|
```
|
3
go.mod
3
go.mod
|
@ -7,15 +7,18 @@ require (
|
||||||
github.com/kelseyhightower/envconfig v1.4.0
|
github.com/kelseyhightower/envconfig v1.4.0
|
||||||
github.com/spf13/cobra v1.6.1
|
github.com/spf13/cobra v1.6.1
|
||||||
github.com/spf13/viper v1.15.0
|
github.com/spf13/viper v1.15.0
|
||||||
|
github.com/stretchr/testify v1.8.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/magiconair/properties v1.8.7 // indirect
|
github.com/magiconair/properties v1.8.7 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/spf13/afero v1.9.3 // indirect
|
github.com/spf13/afero v1.9.3 // indirect
|
||||||
github.com/spf13/cast v1.5.0 // indirect
|
github.com/spf13/cast v1.5.0 // indirect
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
package cert
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/x509"
|
||||||
|
"crypto/x509/pkix"
|
||||||
|
"encoding/pem"
|
||||||
|
"errors"
|
||||||
|
"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)
|
||||||
|
if block == nil {
|
||||||
|
return nil, nil, errors.New("pem.Decode")
|
||||||
|
}
|
||||||
|
|
||||||
|
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,36 @@
|
||||||
|
package cert
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_newClientCert(t *testing.T) {
|
||||||
|
ca, err := NewRootCA(&rootTestConfig)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, ca)
|
||||||
|
|
||||||
|
require.NotNil(t, ca.Key())
|
||||||
|
require.Greater(t, len(ca.Key()), 0)
|
||||||
|
|
||||||
|
require.NotNil(t, ca.PEM())
|
||||||
|
require.Greater(t, len(ca.PEM()), 0)
|
||||||
|
|
||||||
|
x509RootCA, err := parseCertificate(ca.PEM())
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
pem, key, err := newClientCert(&clientTestConfig, x509RootCA, ca.Key())
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.NotNil(t, pem)
|
||||||
|
require.Greater(t, len(pem), 0)
|
||||||
|
|
||||||
|
require.NotNil(t, key)
|
||||||
|
require.Greater(t, len(key), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_newClientCertErrr(t *testing.T) {
|
||||||
|
_, _, err := newClientCert(&clientTestConfig, nil, []byte{})
|
||||||
|
require.Error(t, err)
|
||||||
|
}
|
|
@ -8,15 +8,104 @@ import (
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"crypto/x509/pkix"
|
"crypto/x509/pkix"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gitlab.com/urkob/go-cert-gen/pkg/ca"
|
"gitlab.com/urkob/go-cert-gen/pkg/ca"
|
||||||
|
|
||||||
"gitlab.com/urkob/go-cert-gen/pkg/client"
|
"gitlab.com/urkob/go-cert-gen/pkg/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CERTIFICATE = "CERTIFICATE"
|
||||||
|
PRIVATE_KEY = "PRIVATE KEY"
|
||||||
|
)
|
||||||
|
|
||||||
|
type rootCA struct {
|
||||||
|
caPEM []byte
|
||||||
|
keyPEM []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *rootCA) Key() []byte {
|
||||||
|
return r.keyPEM
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *rootCA) PEM() []byte {
|
||||||
|
return r.caPEM
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *rootCA) WithClientCert(config *client.ClientCertConfig) (client.ClientCertIface, error) {
|
||||||
|
x509RootCA, err := parseCertificate(r.caPEM)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("parseCertificate: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
clientCertPEM, clientKeyPEM, err := newClientCert(config, x509RootCA, r.keyPEM)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("newClientCert: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &clientCert{
|
||||||
|
certPEM: clientCertPEM,
|
||||||
|
keyPEM: clientKeyPEM,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a self-signed certificate.
|
||||||
|
func newRootCA(config *ca.CaConfig) ([]byte, []byte, error) {
|
||||||
|
if config == nil {
|
||||||
|
return nil, nil, errors.New("ca.CaConfig config is nil")
|
||||||
|
}
|
||||||
|
priv, err := newPrivateKey()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("newPrivateKey: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
template := x509.Certificate{
|
||||||
|
SerialNumber: config.SerialNumber,
|
||||||
|
Subject: pkix.Name{
|
||||||
|
Organization: []string{config.Subject.Organization},
|
||||||
|
CommonName: config.Subject.CommonName,
|
||||||
|
},
|
||||||
|
NotBefore: time.Now().Add(-time.Minute),
|
||||||
|
NotAfter: time.Now().Add(config.Duration),
|
||||||
|
IsCA: true,
|
||||||
|
KeyUsage: config.KeyUsage,
|
||||||
|
ExtKeyUsage: config.ExtKeyUsage,
|
||||||
|
BasicConstraintsValid: true,
|
||||||
|
}
|
||||||
|
der, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
caPEM := out.Bytes()
|
||||||
|
keyPEM, err := encodePrivateKey(priv)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("encodePrivateKey: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return caPEM, keyPEM, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRootCA(config *ca.CaConfig) (ca.RootCACertificateIface, error) {
|
||||||
|
caPEM, keyPEM, err := newRootCA(config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("newRootCA: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &rootCA{
|
||||||
|
caPEM: caPEM,
|
||||||
|
keyPEM: keyPEM,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Creates a new 512bit private key.
|
// Creates a new 512bit private key.
|
||||||
func newPrivateKey() (*ecdsa.PrivateKey, error) {
|
func newPrivateKey() (*ecdsa.PrivateKey, error) {
|
||||||
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
|
@ -45,155 +134,16 @@ func encodePrivateKey(priv *ecdsa.PrivateKey) ([]byte, error) {
|
||||||
out := &bytes.Buffer{}
|
out := &bytes.Buffer{}
|
||||||
privBytes, err := x509.MarshalPKCS8PrivateKey(priv)
|
privBytes, err := x509.MarshalPKCS8PrivateKey(priv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("marshal: %s", err)
|
return nil, fmt.Errorf("x509.MarshalPKCS8PrivateKey: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = pem.Encode(out, &pem.Block{
|
err = pem.Encode(out, &pem.Block{
|
||||||
Type: "PRIVATE KEY",
|
Type: PRIVATE_KEY,
|
||||||
Bytes: privBytes,
|
Bytes: privBytes,
|
||||||
})
|
})
|
||||||
return out.Bytes(), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a self-signed certificate.
|
|
||||||
func newRootCA(config *ca.CaConfig) ([]byte, []byte, error) {
|
|
||||||
priv, err := newPrivateKey()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("newPrivateKey: %s", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
template := x509.Certificate{
|
return out.Bytes(), nil
|
||||||
SerialNumber: config.SerialNumber,
|
|
||||||
Subject: pkix.Name{
|
|
||||||
Organization: []string{config.Subject.Organization},
|
|
||||||
CommonName: config.Subject.CommonName,
|
|
||||||
},
|
|
||||||
NotBefore: time.Now().Add(-time.Minute),
|
|
||||||
NotAfter: time.Now().Add(config.Duration),
|
|
||||||
IsCA: true,
|
|
||||||
KeyUsage: config.KeyUsage,
|
|
||||||
ExtKeyUsage: config.ExtKeyUsage,
|
|
||||||
BasicConstraintsValid: true,
|
|
||||||
}
|
|
||||||
der, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
caPEM := out.Bytes()
|
|
||||||
keyPEM, err := encodePrivateKey(priv)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("encodePrivateKey: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return caPEM, keyPEM, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
|
||||||
log.Fatalf("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
|
|
||||||
}
|
|
||||||
|
|
||||||
type rootCA struct {
|
|
||||||
caPEM []byte
|
|
||||||
keyPEM []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type clientCert struct {
|
|
||||||
certPEM []byte
|
|
||||||
keyPEM []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *clientCert) Key() []byte {
|
|
||||||
return c.keyPEM
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *clientCert) PEM() []byte {
|
|
||||||
return c.certPEM
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *rootCA) WithClientCert(config *client.ClientCertConfig) (client.ClientCertIface, error) {
|
|
||||||
x509RootCA, err := parseCertificate(r.caPEM)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("parseCertificate: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
clientCertPEM, clientKeyPEM, err := newClientCert(config, x509RootCA, r.keyPEM)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("newClientCert: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &clientCert{
|
|
||||||
certPEM: clientCertPEM,
|
|
||||||
keyPEM: clientKeyPEM,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *rootCA) Key() []byte {
|
|
||||||
return r.keyPEM
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *rootCA) PEM() []byte {
|
|
||||||
return r.caPEM
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewRootCA(config *ca.CaConfig) (ca.RootCACertificateIface, error) {
|
|
||||||
caPEM, keyPEM, err := newRootCA(config)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("newRootCA: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &rootCA{
|
|
||||||
caPEM: caPEM,
|
|
||||||
keyPEM: keyPEM,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
package cert
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"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().Params().Name, 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_encodePrivateKeyError(t *testing.T) {
|
||||||
|
key := ecdsa.PrivateKey{}
|
||||||
|
_, err := encodePrivateKey(&key)
|
||||||
|
require.Error(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
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 Test_parseCertificateError(t *testing.T) {
|
||||||
|
_, err := parseCertificate([]byte{})
|
||||||
|
require.Error(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewRootCA(t *testing.T) {
|
||||||
|
rootCert, err := NewRootCA(&rootTestConfig)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, rootCert)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewRootCAERror(t *testing.T) {
|
||||||
|
_, err := NewRootCA(nil)
|
||||||
|
require.Error(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
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