ezshare/certs/generate.go
2021-12-03 23:05:29 +01:00

172 lines
3.8 KiB
Go

package certs
import (
"bytes"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"math/big"
"os"
"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
}
func GenCerts() error {
// Create CA certs
caPriv, caPub, err := GenCACert()
if err != nil {
return err
}
if err := WriteKey(caPriv, "certs/ca.key"); err != nil {
return err
}
if err := WriteCert(caPub, "certs/ca.pem"); err != nil {
return err
}
// Create server certs
srvKey, srvCrt, err := GenCert(caPub, caPriv)
if err != nil {
return err
}
if err := WriteKey(srvKey, "certs/srv.key"); err != nil {
return err
}
if err := WriteCert(srvCrt, "certs/srv.pem"); err != nil {
return err
}
clientKey, clientCrt, err := GenCert(caPub, caPriv)
if err != nil {
return err
}
if err := WriteKey(clientKey, "certs/client.key"); err != nil {
return err
}
if err := WriteCert(clientCrt, "certs/client.pem"); err != nil {
return err
}
return nil
}
func GenCert(caPub, caPrivKey []byte) (priv, pub []byte, err error) {
// 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{
SerialNumber: big.NewInt(1658),
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},
DNSNames: []string{"*"},
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
}