123 lines
2.7 KiB
Go
123 lines
2.7 KiB
Go
package store
|
|
|
|
import (
|
|
"context"
|
|
"crypto/ecdsa"
|
|
"crypto/x509"
|
|
"database/sql"
|
|
"log"
|
|
"math/big"
|
|
"sync"
|
|
|
|
_ "github.com/mattn/go-sqlite3"
|
|
)
|
|
|
|
var DB *sql.DB
|
|
var RootCA []byte
|
|
var RootCAKey *ecdsa.PrivateKey
|
|
var SerialLock sync.Mutex
|
|
var Serial big.Int
|
|
|
|
func InitStore(path string) {
|
|
var err error
|
|
DB, err = sql.Open("sqlite3", path)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
func CloseStore() {
|
|
DB.Close()
|
|
}
|
|
func ChekInit() bool {
|
|
result := DB.QueryRow("select id,cert,key,serial from syscfg order by id desc limit 1")
|
|
if result.Err() != nil {
|
|
log.Println(result.Err())
|
|
return false
|
|
}
|
|
var placeholder int
|
|
var temp_serial, temp_ca_key []byte
|
|
err := result.Scan(&placeholder, &RootCA, &temp_ca_key, &temp_serial)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return false
|
|
}
|
|
Serial.SetBytes(temp_serial)
|
|
RootCAKey, err = x509.ParseECPrivateKey(temp_ca_key)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
func initSchema(tx *sql.Tx) {
|
|
_, err := tx.Exec(`
|
|
create table syscfg (id integer not null primary key autoincrement, cert blob not null, key blob not null, serial blob not null);
|
|
delete from syscfg;
|
|
`)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
_, err = tx.Exec(`
|
|
create table leaf (id blob not null primary key, cert blob not null, owner text not null, revokeAt datetime, revokeReason integer);
|
|
delete from leaf;
|
|
`)
|
|
}
|
|
func InitStoreData() {
|
|
ctx := context.Background()
|
|
tx, err := DB.BeginTx(ctx, nil)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
initSchema(tx)
|
|
|
|
temp_ca_key, err := x509.MarshalECPrivateKey(RootCAKey)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
tx.Exec(`
|
|
insert into syscfg(cert,key,serial) values(?,?,?)
|
|
`, RootCA, temp_ca_key, Serial.Bytes())
|
|
err = tx.Commit()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
func InsertCert(cert []byte, applicant string) {
|
|
parse, err := x509.ParseCertificate(cert)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return
|
|
}
|
|
DB.Exec("insert into syscfg(id,cert,owner) values(?,?,?)", parse.SerialNumber.Bytes(), cert, applicant)
|
|
}
|
|
|
|
type LeafCert struct {
|
|
Cert_org []byte
|
|
Cert *x509.Certificate
|
|
RevokeAt sql.NullTime
|
|
RevokeReason sql.NullInt16
|
|
}
|
|
|
|
func GetLeafCert(serial_num *big.Int) sql.Null[LeafCert] {
|
|
var err error
|
|
result := DB.QueryRow("select cert,revokeAt, revokeReason from leaf where id = ?", serial_num.Bytes())
|
|
var leaf LeafCert
|
|
if result.Err() != nil {
|
|
log.Println(result.Err())
|
|
return sql.Null[LeafCert]{Valid: false}
|
|
}
|
|
|
|
err = result.Scan(&leaf.Cert_org, &leaf.RevokeAt, &leaf.RevokeReason)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return sql.Null[LeafCert]{Valid: false}
|
|
}
|
|
leaf.Cert, err = x509.ParseCertificate(leaf.Cert_org)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return sql.Null[LeafCert]{Valid: false}
|
|
}
|
|
return sql.Null[LeafCert]{V: leaf, Valid: true}
|
|
|
|
}
|