85 lines
2.4 KiB
Go
85 lines
2.4 KiB
Go
package pki
|
|
|
|
import (
|
|
"crypto/ecdsa"
|
|
"crypto/rand"
|
|
"crypto/x509"
|
|
"crypto/x509/pkix"
|
|
"fmt"
|
|
"math"
|
|
"math/big"
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
"time"
|
|
)
|
|
|
|
func ClientCertificatePath(serial uint64) string {
|
|
return path.Join(PKIDir, fmt.Sprintf("%0[2]*[1]X", serial, int(math.Ceil(math.Log2(float64(serial))/8)*2)), "cert.pem")
|
|
}
|
|
|
|
func ClientPrivkeyPath(serial uint64) string {
|
|
return path.Join(PKIDir, fmt.Sprintf("%0[2]*[1]X", serial, int(math.Ceil(math.Log2(float64(serial))/8)*2)), "privkey.pem")
|
|
}
|
|
|
|
func ClientP12Path(serial uint64) string {
|
|
return path.Join(PKIDir, fmt.Sprintf("%0[2]*[1]X", serial, int(math.Ceil(math.Log2(float64(serial))/8)*2)), "team.p12")
|
|
}
|
|
|
|
func GenerateClient(serial uint64, notBefore time.Time, notAfter time.Time, parent_cert *x509.Certificate, parent_priv *ecdsa.PrivateKey) error {
|
|
var certid big.Int
|
|
certid.SetUint64(serial)
|
|
client := &x509.Certificate{
|
|
SerialNumber: &certid,
|
|
Subject: pkix.Name{
|
|
Organization: []string{"EPITA"},
|
|
OrganizationalUnit: []string{"SRS laboratory"},
|
|
Country: []string{"FR"},
|
|
Locality: []string{"Paris"},
|
|
CommonName: fmt.Sprintf("TEAM-%0[2]*[1]X", serial, int(math.Ceil(math.Log2(float64(serial))/8)*2)),
|
|
},
|
|
NotBefore: notBefore,
|
|
NotAfter: notAfter,
|
|
IsCA: false,
|
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
|
KeyUsage: x509.KeyUsageDigitalSignature,
|
|
BasicConstraintsValid: true,
|
|
}
|
|
|
|
pub, priv, err := GeneratePrivKey()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
client_b, err := x509.CreateCertificate(rand.Reader, client, parent_cert, pub, parent_priv)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Create intermediate directory
|
|
os.MkdirAll(path.Join(PKIDir, fmt.Sprintf("%0[2]*[1]X", serial, int(math.Ceil(math.Log2(float64(serial))/8)*2))), 0777)
|
|
|
|
// Save certificate to file
|
|
if err := saveCertificate(ClientCertificatePath(serial), client_b); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Save private key to file
|
|
if err := savePrivateKey(ClientPrivkeyPath(serial), priv); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func WriteP12(serial uint64, password string) error {
|
|
cmd := exec.Command("/usr/bin/openssl", "pkcs12", "-export",
|
|
"-inkey", ClientPrivkeyPath(serial),
|
|
"-in", ClientCertificatePath(serial),
|
|
"-name", fmt.Sprintf("TEAM-%0[2]*[1]X", serial, int(math.Ceil(math.Log2(float64(serial))/8)*2)),
|
|
"-passout", "pass:" + password,
|
|
"-out", ClientP12Path(serial))
|
|
|
|
return cmd.Run()
|
|
}
|