package pki import ( "crypto/ecdsa" "crypto/rand" "crypto/x509" "crypto/x509/pkix" "fmt" "math/big" "os" "os/exec" "path" "time" ) func ClientCertificatePath(serial uint64) string { return path.Join(PKIDir, fmt.Sprintf("%d", serial), "cert.pem") } func ClientPrivkeyPath(serial uint64) string { return path.Join(PKIDir, fmt.Sprintf("%d", serial), "privkey.pem") } func ClientP12Path(serial uint64) string { return path.Join(PKIDir, fmt.Sprintf("%d", serial), "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-%o", serial), }, 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("%d", serial)), 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-%o", serial), "-passout", "pass:" + password, "-out", ClientP12Path(serial)) return cmd.Run() }