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.
This commit is contained in:
parent
3ed8c619b1
commit
68e5c4cd2b
@ -1,11 +1,12 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/rand"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"time"
|
"time"
|
||||||
@ -87,10 +88,19 @@ func getTeamP12File(cert fic.Certificate, _ []byte) (interface{}, error) {
|
|||||||
|
|
||||||
func generateClientCert(_ httprouter.Params, _ []byte) (interface{}, error) {
|
func generateClientCert(_ httprouter.Params, _ []byte) (interface{}, error) {
|
||||||
// First, generate a new, unique, serial
|
// First, generate a new, unique, serial
|
||||||
serial := rand.Int63()
|
var serial_gen [8]byte
|
||||||
for fic.ExistingCertSerial(serial) {
|
if _, err := rand.Read(serial_gen[:]); err != nil {
|
||||||
serial = rand.Int63()
|
return nil, err
|
||||||
}
|
}
|
||||||
|
for fic.ExistingCertSerial(serial_gen) {
|
||||||
|
if _, err := rand.Read(serial_gen[:]); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var serial_b big.Int
|
||||||
|
serial_b.SetBytes(serial_gen[:])
|
||||||
|
serial := serial_b.Uint64()
|
||||||
|
|
||||||
// Let's pick a random password
|
// Let's pick a random password
|
||||||
password, err := pki.GeneratePassword()
|
password, err := pki.GeneratePassword()
|
||||||
@ -148,7 +158,10 @@ func updateCertificateAssociation(cert fic.Certificate, body []byte) (interface{
|
|||||||
// moreover, backend doesn't update the DB at registration, it only creates a symlink
|
// moreover, backend doesn't update the DB at registration, it only creates a symlink
|
||||||
cert.IdTeam = uc.Team
|
cert.IdTeam = uc.Team
|
||||||
|
|
||||||
dstLinkPath := path.Join(TeamsDir, fmt.Sprintf("_AUTH_ID_%X", cert.Id))
|
var serial big.Int
|
||||||
|
serial.SetUint64(cert.Id)
|
||||||
|
|
||||||
|
dstLinkPath := path.Join(TeamsDir, fmt.Sprintf("_AUTH_ID_%0X", serial.Bytes()))
|
||||||
|
|
||||||
if uc.Team != nil {
|
if uc.Team != nil {
|
||||||
srcLinkPath := fmt.Sprintf("%d", *uc.Team)
|
srcLinkPath := fmt.Sprintf("%d", *uc.Team)
|
||||||
|
@ -282,7 +282,7 @@ func fileHandler(f func(fic.EFile,[]byte) (interface{}, error)) func (httprouter
|
|||||||
|
|
||||||
func certificateHandler(f func(fic.Certificate,[]byte) (interface{}, error)) func (httprouter.Params,[]byte) (interface{}, error) {
|
func certificateHandler(f func(fic.Certificate,[]byte) (interface{}, error)) func (httprouter.Params,[]byte) (interface{}, error) {
|
||||||
return func (ps httprouter.Params, body []byte) (interface{}, error) {
|
return func (ps httprouter.Params, body []byte) (interface{}, error) {
|
||||||
if certid, err := strconv.ParseInt(string(ps.ByName("certid")), 10, 64); err != nil {
|
if certid, err := strconv.ParseUint(string(ps.ByName("certid")), 10, 64); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if cert, err := fic.GetCertificate(certid); err != nil {
|
} else if cert, err := fic.GetCertificate(certid); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -13,21 +13,23 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ClientCertificatePath(serial int64) string {
|
func ClientCertificatePath(serial uint64) string {
|
||||||
return path.Join(PKIDir, fmt.Sprintf("%d", serial), "cert.pem")
|
return path.Join(PKIDir, fmt.Sprintf("%d", serial), "cert.pem")
|
||||||
}
|
}
|
||||||
|
|
||||||
func ClientPrivkeyPath(serial int64) string {
|
func ClientPrivkeyPath(serial uint64) string {
|
||||||
return path.Join(PKIDir, fmt.Sprintf("%d", serial), "privkey.pem")
|
return path.Join(PKIDir, fmt.Sprintf("%d", serial), "privkey.pem")
|
||||||
}
|
}
|
||||||
|
|
||||||
func ClientP12Path(serial int64) string {
|
func ClientP12Path(serial uint64) string {
|
||||||
return path.Join(PKIDir, fmt.Sprintf("%d", serial), "team.p12")
|
return path.Join(PKIDir, fmt.Sprintf("%d", serial), "team.p12")
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateClient(serial int64, notBefore time.Time, notAfter time.Time, parent_cert *x509.Certificate, parent_priv *ecdsa.PrivateKey) error {
|
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{
|
client := &x509.Certificate{
|
||||||
SerialNumber: big.NewInt(serial),
|
SerialNumber: &certid,
|
||||||
Subject: pkix.Name{
|
Subject: pkix.Name{
|
||||||
Organization: []string{"EPITA"},
|
Organization: []string{"EPITA"},
|
||||||
OrganizationalUnit: []string{"SRS laboratory"},
|
OrganizationalUnit: []string{"SRS laboratory"},
|
||||||
@ -69,7 +71,7 @@ func GenerateClient(serial int64, notBefore time.Time, notAfter time.Time, paren
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func WriteP12(serial int64, password string) error {
|
func WriteP12(serial uint64, password string) error {
|
||||||
cmd := exec.Command("/usr/bin/openssl", "pkcs12", "-export",
|
cmd := exec.Command("/usr/bin/openssl", "pkcs12", "-export",
|
||||||
"-inkey", ClientPrivkeyPath(serial),
|
"-inkey", ClientPrivkeyPath(serial),
|
||||||
"-in", ClientCertificatePath(serial),
|
"-in", ClientCertificatePath(serial),
|
||||||
|
@ -2,11 +2,12 @@ package fic
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"math/big"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Certificate struct {
|
type Certificate struct {
|
||||||
Id int64 `json:"id,string"`
|
Id uint64 `json:"id,string"`
|
||||||
Creation time.Time `json:"creation"`
|
Creation time.Time `json:"creation"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
IdTeam *int64 `json:"id_team"`
|
IdTeam *int64 `json:"id_team"`
|
||||||
@ -49,17 +50,20 @@ func GetTeamCertificates(team Team) (certificates []Certificate, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetCertificate(serial int64) (c Certificate, err error) {
|
func GetCertificate(serial uint64) (c Certificate, err error) {
|
||||||
err = DBQueryRow("SELECT id_cert, creation, password, id_team, revoked FROM certificates WHERE id_cert = ?", serial).Scan(&c.Id, &c.Creation, &c.Password, &c.IdTeam, &c.Revoked)
|
err = DBQueryRow("SELECT id_cert, creation, password, id_team, revoked FROM certificates WHERE id_cert = ?", serial).Scan(&c.Id, &c.Creation, &c.Password, &c.IdTeam, &c.Revoked)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExistingCertSerial(serial int64) (bool) {
|
func ExistingCertSerial(serial [8]byte) (bool) {
|
||||||
c, _ := GetCertificate(serial)
|
var m big.Int
|
||||||
|
m.SetBytes(serial[:])
|
||||||
|
|
||||||
|
c, _ := GetCertificate(m.Uint64())
|
||||||
return c.Id > 0
|
return c.Id > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func RegisterCertificate(serial int64, password string) (Certificate, error) {
|
func RegisterCertificate(serial uint64, password string) (Certificate, error) {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
if _, err := DBExec("INSERT INTO certificates (id_cert, creation, password) VALUES (?, ?, ?)", serial, now, password); err != nil {
|
if _, err := DBExec("INSERT INTO certificates (id_cert, creation, password) VALUES (?, ?, ?)", serial, now, password); err != nil {
|
||||||
return Certificate{}, err
|
return Certificate{}, err
|
||||||
|
@ -84,7 +84,7 @@ CREATE TABLE IF NOT EXISTS teams(
|
|||||||
}
|
}
|
||||||
if _, err := db.Exec(`
|
if _, err := db.Exec(`
|
||||||
CREATE TABLE IF NOT EXISTS certificates(
|
CREATE TABLE IF NOT EXISTS certificates(
|
||||||
id_cert BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
id_cert BIGINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||||
creation TIMESTAMP NOT NULL,
|
creation TIMESTAMP NOT NULL,
|
||||||
password VARCHAR(255) NOT NULL,
|
password VARCHAR(255) NOT NULL,
|
||||||
id_team INTEGER NULL,
|
id_team INTEGER NULL,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user