92 lines
2.6 KiB
Go
92 lines
2.6 KiB
Go
package crt
|
|
|
|
import (
|
|
"crypto/ecdsa"
|
|
"crypto/elliptic"
|
|
"crypto/rand"
|
|
"crypto/x509"
|
|
"crypto/x509/pkix"
|
|
"database/sql"
|
|
"fmt"
|
|
"log"
|
|
"math/big"
|
|
"time"
|
|
|
|
"github.com/jasinco/crtman/internal/cli"
|
|
"github.com/jasinco/crtman/internal/store"
|
|
)
|
|
|
|
func IssueRoot(config cli.CA_CFG) {
|
|
log.Printf("CA: Org: %s, FQDN: %s\n", config.Org, config.FQDN)
|
|
rootca := x509.Certificate{
|
|
IsCA: true,
|
|
Version: 1,
|
|
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign | x509.KeyUsageDigitalSignature,
|
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageOCSPSigning},
|
|
Subject: pkix.Name{
|
|
Country: []string{"Taiwan"},
|
|
Organization: []string{config.Org},
|
|
CommonName: config.FQDN,
|
|
},
|
|
NotBefore: time.Now(),
|
|
BasicConstraintsValid: true,
|
|
SerialNumber: big.NewInt(0),
|
|
}
|
|
privkey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
crt, err := x509.CreateCertificate(rand.Reader, &rootca, &rootca, &privkey.PublicKey, privkey)
|
|
if err != nil {
|
|
log.Fatal("can't create x509 ca, ", err)
|
|
}
|
|
// privkey_bytes, err := x509.MarshalECPrivateKey(privkey)
|
|
// if err != nil {
|
|
// log.Fatal("can't create ecdsa key encoded, ", err)
|
|
// }
|
|
store.RootCA = crt
|
|
store.RootCAKey = privkey
|
|
}
|
|
|
|
// csr is a DER csr
|
|
func IssueCert(csr []byte) sql.Null[[]byte] {
|
|
req, err := x509.ParseCertificateRequest(csr)
|
|
if err != nil {
|
|
return sql.Null[[]byte]{Valid: false}
|
|
}
|
|
if req.CheckSignature() != nil {
|
|
return sql.Null[[]byte]{Valid: false}
|
|
}
|
|
|
|
store.SerialLock.Lock()
|
|
defer store.SerialLock.Unlock()
|
|
cert := x509.Certificate{
|
|
Subject: req.Subject,
|
|
PublicKey: req.PublicKey,
|
|
PublicKeyAlgorithm: req.PublicKeyAlgorithm,
|
|
NotBefore: time.Now(),
|
|
NotAfter: time.Now().Add(time.Hour * 24 * 720),
|
|
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
|
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
|
IsCA: false,
|
|
BasicConstraintsValid: true,
|
|
DNSNames: req.DNSNames,
|
|
IPAddresses: req.IPAddresses,
|
|
SerialNumber: &store.Serial,
|
|
OCSPServer: []string{fmt.Sprintf("https://%s/api/ocsp", cli.Outbound)},
|
|
}
|
|
ca, err := x509.ParseCertificate(store.RootCA)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return sql.Null[[]byte]{Valid: false}
|
|
}
|
|
signed, err := x509.CreateCertificate(rand.Reader, &cert, ca, req.PublicKey, store.RootCAKey)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return sql.Null[[]byte]{Valid: false}
|
|
}
|
|
store.Serial.Add(&store.Serial, big.NewInt(1))
|
|
|
|
return sql.Null[[]byte]{Valid: true, V: signed}
|
|
}
|