|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/x509"
|
|
|
|
"crypto/x509/pkix"
|
|
|
|
"encoding/pem"
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"git.sequentialread.com/forest/easypki.git/pkg/certificate"
|
|
|
|
"git.sequentialread.com/forest/easypki.git/pkg/easypki"
|
|
|
|
"git.sequentialread.com/forest/easypki.git/pkg/store"
|
|
|
|
errors "git.sequentialread.com/forest/pkg-errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
|
|
|
|
domain := os.Args[1]
|
|
|
|
outputLocation, err := os.Getwd()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
inMemoryStore := &store.InMemory{}
|
|
|
|
pki := &easypki.EasyPKI{Store: inMemoryStore}
|
|
|
|
|
|
|
|
domainCA := fmt.Sprintf("%s_CA", domain)
|
|
|
|
|
|
|
|
log.Println("make-fake-cert: creating server CA / key pair ")
|
|
|
|
|
|
|
|
// Create a CA for the server's key/cert
|
|
|
|
err = pki.Sign(
|
|
|
|
nil,
|
|
|
|
&easypki.Request{
|
|
|
|
Name: domainCA,
|
|
|
|
Template: &x509.Certificate{
|
|
|
|
NotAfter: time.Now().Add(time.Hour * 24 * 720),
|
|
|
|
IsCA: true,
|
|
|
|
MaxPathLen: -1,
|
|
|
|
Subject: getSubject(domainCA),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
panic(errors.Wrap(err, "make-fake-cert: failed creating CA"))
|
|
|
|
}
|
|
|
|
|
|
|
|
err = saveBundle(pki, domainCA, domainCA, false, outputLocation)
|
|
|
|
if err != nil {
|
|
|
|
panic(errors.Wrap(err, "make-fake-cert: saveBundle():"))
|
|
|
|
}
|
|
|
|
|
|
|
|
caSigner, err := pki.GetCA(domainCA)
|
|
|
|
if err != nil {
|
|
|
|
panic(errors.Wrap(err, "make-fake-cert: signer named \"CA\" was not found"))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create server certificate
|
|
|
|
err = pki.Sign(
|
|
|
|
caSigner,
|
|
|
|
&easypki.Request{
|
|
|
|
Name: domain,
|
|
|
|
Template: &x509.Certificate{
|
|
|
|
NotAfter: time.Now().Add(time.Hour * 24 * 720),
|
|
|
|
IsCA: false,
|
|
|
|
Subject: getSubject(domain),
|
|
|
|
DNSNames: []string{domain},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
panic(errors.Wrap(err, "make-fake-cert: failed creating Threshold server certificate"))
|
|
|
|
}
|
|
|
|
|
|
|
|
err = saveBundle(pki, domainCA, domain, true, outputLocation)
|
|
|
|
if err != nil {
|
|
|
|
panic(errors.Wrap(err, "make-fake-cert: saveBundle():"))
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(os.Args) == 3 {
|
|
|
|
user := fmt.Sprintf("%s@%s", os.Args[2], domain)
|
|
|
|
// Create client certificate
|
|
|
|
err = pki.Sign(
|
|
|
|
caSigner,
|
|
|
|
&easypki.Request{
|
|
|
|
Name: user,
|
|
|
|
Template: &x509.Certificate{
|
|
|
|
NotAfter: time.Now().Add(time.Hour * 24 * 720),
|
|
|
|
IsCA: false,
|
|
|
|
Subject: getSubject(user),
|
|
|
|
EmailAddresses: []string{user},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
panic(errors.Wrap(err, "make-fake-cert: failed creating Threshold server certificate"))
|
|
|
|
}
|
|
|
|
|
|
|
|
err = saveBundle(pki, domainCA, user, true, outputLocation)
|
|
|
|
if err != nil {
|
|
|
|
panic(errors.Wrap(err, "make-fake-cert: saveBundle():"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func saveBundle(pki *easypki.EasyPKI, caName, bundleName string, savePrivateKey bool, saveInDirectory string) error {
|
|
|
|
var bundle *certificate.Bundle
|
|
|
|
if caName == "" {
|
|
|
|
caName = bundleName
|
|
|
|
}
|
|
|
|
|
|
|
|
bundle, err := pki.GetBundle(caName, bundleName)
|
|
|
|
if err != nil {
|
|
|
|
panic(errors.Wrapf(err, "Failed getting bundle %v within CA %v: %v", bundleName, caName))
|
|
|
|
}
|
|
|
|
leaf := bundle
|
|
|
|
chain := []*certificate.Bundle{bundle}
|
|
|
|
//if fullChain {
|
|
|
|
for {
|
|
|
|
if leaf.Cert.Issuer.CommonName == leaf.Cert.Subject.CommonName {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
ca, err := pki.GetCA(leaf.Cert.Issuer.CommonName)
|
|
|
|
if err != nil {
|
|
|
|
panic(errors.Wrapf(err, "Failed getting signing CA %v: %v", leaf.Cert.Issuer.CommonName))
|
|
|
|
}
|
|
|
|
chain = append(chain, ca)
|
|
|
|
leaf = ca
|
|
|
|
}
|
|
|
|
//}
|
|
|
|
|
|
|
|
if savePrivateKey {
|
|
|
|
key, err := os.Create(filepath.Join(saveInDirectory, bundleName+".key"))
|
|
|
|
if err != nil {
|
|
|
|
panic(errors.Wrap(err, "Failed creating key output file"))
|
|
|
|
}
|
|
|
|
if err := pem.Encode(key, &pem.Block{
|
|
|
|
Bytes: x509.MarshalPKCS1PrivateKey(bundle.Key),
|
|
|
|
Type: "RSA PRIVATE KEY",
|
|
|
|
}); err != nil {
|
|
|
|
panic(errors.Wrap(err, "Failed ecoding private key"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
crtName := bundleName + ".crt"
|
|
|
|
cert, err := os.Create(filepath.Join(saveInDirectory, crtName))
|
|
|
|
if err != nil {
|
|
|
|
panic(errors.Wrap(err, "Failed creating chain output file"))
|
|
|
|
}
|
|
|
|
for _, c := range chain {
|
|
|
|
if err := pem.Encode(cert, &pem.Block{
|
|
|
|
Bytes: c.Cert.Raw,
|
|
|
|
Type: "CERTIFICATE",
|
|
|
|
}); err != nil {
|
|
|
|
panic(errors.Wrapf(err, "Failed ecoding %v certificate: %v", c.Name))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO add certificate metadata option to seedpacket?
|
|
|
|
func getSubject(commonName string) pkix.Name {
|
|
|
|
return pkix.Name{
|
|
|
|
Organization: []string{"aaaaa user left blank"},
|
|
|
|
OrganizationalUnit: []string{"aaaaa user left blank"},
|
|
|
|
Locality: []string{"aaaaa user left blank"},
|
|
|
|
Country: []string{"aaaaa user left blank"},
|
|
|
|
Province: []string{"aaaaa user left blank"},
|
|
|
|
CommonName: commonName,
|
|
|
|
}
|
|
|
|
}
|