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 }