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