2021-12-03 22:04:09 +00:00
|
|
|
package certs
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"crypto/ecdsa"
|
|
|
|
"crypto/elliptic"
|
|
|
|
"crypto/rand"
|
|
|
|
"crypto/x509"
|
|
|
|
"crypto/x509/pkix"
|
|
|
|
"encoding/pem"
|
|
|
|
"fmt"
|
|
|
|
"math/big"
|
|
|
|
"os"
|
2021-12-04 02:25:09 +00:00
|
|
|
"path/filepath"
|
2021-12-03 22:04:09 +00:00
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
func WriteCert(data []byte, filename string) error {
|
|
|
|
// Convert to PEM
|
|
|
|
certPEM := new(bytes.Buffer)
|
|
|
|
pem.Encode(certPEM, &pem.Block{
|
|
|
|
Type: "CERTIFICATE",
|
|
|
|
Bytes: data,
|
|
|
|
})
|
|
|
|
|
|
|
|
// Write file
|
|
|
|
f, err := os.Create(filename)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
|
|
|
|
if _, err := f.Write(certPEM.Bytes()); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
fmt.Printf("Wrote %s.\n", filename)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func WriteKey(data []byte, filename string) error {
|
|
|
|
// Convert to PEM
|
|
|
|
KeyPEM := new(bytes.Buffer)
|
|
|
|
pem.Encode(KeyPEM, &pem.Block{
|
|
|
|
Type: "EC PRIVATE KEY",
|
|
|
|
Bytes: data,
|
|
|
|
})
|
|
|
|
|
|
|
|
f, err := os.Create(filename)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
|
|
|
|
if _, err := f.Write(KeyPEM.Bytes()); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
fmt.Printf("Wrote %s.\n", filename)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func GenCACert() (priv []byte, pub []byte, err error) {
|
|
|
|
ca := &x509.Certificate{
|
|
|
|
SerialNumber: big.NewInt(time.Now().Unix()),
|
|
|
|
Subject: pkix.Name{
|
|
|
|
Organization: []string{"ezshare"},
|
|
|
|
Country: []string{"NO"},
|
|
|
|
Locality: []string{"Oslo"},
|
|
|
|
},
|
|
|
|
NotBefore: time.Now(),
|
|
|
|
NotAfter: time.Now().Add(time.Hour * 24 * 365 * 2),
|
|
|
|
IsCA: true,
|
|
|
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
|
|
|
|
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
|
|
|
BasicConstraintsValid: true,
|
|
|
|
}
|
|
|
|
caPrivKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
caBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, &caPrivKey.PublicKey, caPrivKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
caPrivKeyBytes, err := x509.MarshalECPrivateKey(caPrivKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return caPrivKeyBytes, caBytes, nil
|
|
|
|
}
|
|
|
|
|
2021-12-04 09:19:59 +00:00
|
|
|
func GenAllCerts(path, domain string) error {
|
2021-12-03 22:04:09 +00:00
|
|
|
// Create CA certs
|
|
|
|
caPriv, caPub, err := GenCACert()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-12-04 02:25:09 +00:00
|
|
|
if err := WriteKey(caPriv, filepath.Join(path, "ca.key")); err != nil {
|
2021-12-03 22:04:09 +00:00
|
|
|
return err
|
|
|
|
}
|
2021-12-04 02:25:09 +00:00
|
|
|
if err := WriteCert(caPub, filepath.Join(path, "ca.pem")); err != nil {
|
2021-12-03 22:04:09 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create server certs
|
2021-12-04 09:19:59 +00:00
|
|
|
dnsNames := []string{domain}
|
|
|
|
srvKey, srvCrt, err := GenCert(caPub, caPriv, dnsNames)
|
2021-12-03 22:04:09 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-12-04 02:25:09 +00:00
|
|
|
if err := WriteKey(srvKey, filepath.Join(path, "srv.key")); err != nil {
|
2021-12-03 22:04:09 +00:00
|
|
|
return err
|
|
|
|
}
|
2021-12-04 02:25:09 +00:00
|
|
|
if err := WriteCert(srvCrt, filepath.Join(path, "srv.pem")); err != nil {
|
2021-12-03 22:04:09 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-12-04 09:19:59 +00:00
|
|
|
clientKey, clientCrt, err := GenCert(caPub, caPriv, []string{})
|
2021-12-03 22:04:09 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-12-04 02:25:09 +00:00
|
|
|
if err := WriteKey(clientKey, filepath.Join(path, "client.key")); err != nil {
|
2021-12-03 22:04:09 +00:00
|
|
|
return err
|
|
|
|
}
|
2021-12-04 02:25:09 +00:00
|
|
|
if err := WriteCert(clientCrt, filepath.Join(path, "client.pem")); err != nil {
|
2021-12-03 22:04:09 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-12-04 09:19:59 +00:00
|
|
|
func GenCert(caPub, caPrivKey []byte, dnsNames []string) (priv, pub []byte, err error) {
|
2021-12-03 22:04:09 +00:00
|
|
|
// Parse ca
|
|
|
|
ca, err := x509.ParseCertificate(caPub)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
caPrivKeyParsed, err := x509.ParseECPrivateKey(caPrivKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
cert := &x509.Certificate{
|
2021-12-05 00:01:05 +00:00
|
|
|
SerialNumber: big.NewInt(time.Now().Unix()),
|
2021-12-03 22:04:09 +00:00
|
|
|
Subject: pkix.Name{
|
|
|
|
Organization: []string{"ezshare"},
|
|
|
|
Country: []string{"No"},
|
|
|
|
Locality: []string{"Oslo"},
|
|
|
|
},
|
|
|
|
NotBefore: time.Now(),
|
|
|
|
NotAfter: time.Now().AddDate(10, 0, 0),
|
|
|
|
SubjectKeyId: []byte{1, 2, 3, 4, 6},
|
2021-12-04 09:19:59 +00:00
|
|
|
DNSNames: dnsNames,
|
2021-12-03 22:04:09 +00:00
|
|
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
|
|
|
|
KeyUsage: x509.KeyUsageDigitalSignature,
|
|
|
|
}
|
|
|
|
|
|
|
|
certPrivKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
certPrivKeyBytes, err := x509.MarshalECPrivateKey(certPrivKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
certBytes, err := x509.CreateCertificate(rand.Reader, cert, ca, &certPrivKey.PublicKey, caPrivKeyParsed)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
return certPrivKeyBytes, certBytes, nil
|
|
|
|
}
|