server/admin/pki/client.go
nemunaire 68e5c4cd2b pki: improve serial number generation + fix team association
Replace math/rand by crypto/rand.

Fix big when associating certificate with leading zero: nginx prepend 0 wherehas we don't.
2018-05-11 05:27:51 +02:00

84 lines
2.1 KiB
Go

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()
}