working changes
This commit is contained in:
14
Makefile.am
14
Makefile.am
@@ -12,12 +12,12 @@ GOFLAGS = -v -ldflags='-s -w -X helmet/certmanager/internal/config.buildVersion=
|
||||
|
||||
certmanagerd_SOURCES = cmd/certmanagerd/main.go
|
||||
certmanagerd$(EXEEXT): $(certmanagerd_SOURCES) $(EXTRA_certmanagerd_SOURCES)
|
||||
env CGO_ENABLED=0 $(GO) build $(GOFLAGS) -o certmanagerd$(EXEEXT) $(certmanagerd_SOURCES)
|
||||
env CGO_ENABLED=1 $(GO) build $(GOFLAGS) -o certmanagerd$(EXEEXT) $(certmanagerd_SOURCES)
|
||||
|
||||
|
||||
certmanagerctl_SOURCES = cmd/certmanagerctl/main.go
|
||||
certmanagerctl$(EXEEXT): $(certmanagerctl_SOURCES) $(EXTRA_certmanagerd_SOURCES)
|
||||
env CGO_ENABLED=0 $(GO) build $(GOFLAGS) -o certmanagerctl$(EXEEXT) $(certmanagerctl_SOURCES)
|
||||
env CGO_ENABLED=1 $(GO) build $(GOFLAGS) -o certmanagerctl$(EXEEXT) $(certmanagerctl_SOURCES)
|
||||
|
||||
|
||||
EXTRA_certmanagerd_SOURCES =
|
||||
@@ -29,8 +29,6 @@ grpc:
|
||||
mkdir -p $(GENDIR)
|
||||
protoc --proto_path=proto --go_out=$(GENDIR) --go-grpc_out=$(GENDIR) proto/certmanagercontrol.proto
|
||||
|
||||
|
||||
|
||||
SYSTEMD_LIBDIR = /lib/systemd/system
|
||||
|
||||
install-data-local:
|
||||
@@ -49,7 +47,10 @@ gformat:
|
||||
done
|
||||
|
||||
run:
|
||||
env CGO_ENABLED=0 $(GO) run $(GOFLAGS) ./cmd/certmanagerd/... --daemon=false
|
||||
test -z $(DESTDIR)$(SRV_LOGDIR) || $(MKDIR_P) $(DESTDIR)$(SRV_LOGDIR)
|
||||
test -z $(DESTDIR)$(SRV_RUNDIR) || $(MKDIR_P) $(DESTDIR)$(SRV_RUNDIR)
|
||||
test -z $(DESTDIR)$(SRV_DATADIR) || $(MKDIR_P) $(DESTDIR)$(SRV_DATADIR)
|
||||
env CGO_ENABLED=1 $(GO) run $(GOFLAGS) ./cmd/certmanagerd/... --daemon=false
|
||||
|
||||
distclean-local: clean
|
||||
rm -rf autom4te.cache
|
||||
@@ -58,4 +59,5 @@ clean-local:
|
||||
rm -rf autom4te.cache
|
||||
rm -f cmd/certmanagerd/certmanagerd
|
||||
rm -f cmd/certmanagerctl/certmanagerctl
|
||||
rm -rf tmp/
|
||||
rm -rf tmp.*/
|
||||
|
||||
|
||||
11
Makefile.in
11
Makefile.in
@@ -795,9 +795,9 @@ uninstall-am: uninstall-binPROGRAMS uninstall-sbinPROGRAMS
|
||||
.PRECIOUS: Makefile
|
||||
|
||||
certmanagerd$(EXEEXT): $(certmanagerd_SOURCES) $(EXTRA_certmanagerd_SOURCES)
|
||||
env CGO_ENABLED=0 $(GO) build $(GOFLAGS) -o certmanagerd$(EXEEXT) $(certmanagerd_SOURCES)
|
||||
env CGO_ENABLED=1 $(GO) build $(GOFLAGS) -o certmanagerd$(EXEEXT) $(certmanagerd_SOURCES)
|
||||
certmanagerctl$(EXEEXT): $(certmanagerctl_SOURCES) $(EXTRA_certmanagerd_SOURCES)
|
||||
env CGO_ENABLED=0 $(GO) build $(GOFLAGS) -o certmanagerctl$(EXEEXT) $(certmanagerctl_SOURCES)
|
||||
env CGO_ENABLED=1 $(GO) build $(GOFLAGS) -o certmanagerctl$(EXEEXT) $(certmanagerctl_SOURCES)
|
||||
grpc:
|
||||
mkdir -p $(GENDIR)
|
||||
protoc --proto_path=proto --go_out=$(GENDIR) --go-grpc_out=$(GENDIR) proto/certmanagercontrol.proto
|
||||
@@ -817,7 +817,10 @@ gformat:
|
||||
done
|
||||
|
||||
run:
|
||||
env CGO_ENABLED=0 $(GO) run $(GOFLAGS) ./cmd/certmanagerd/... --daemon=false
|
||||
test -z $(DESTDIR)$(SRV_LOGDIR) || $(MKDIR_P) $(DESTDIR)$(SRV_LOGDIR)
|
||||
test -z $(DESTDIR)$(SRV_RUNDIR) || $(MKDIR_P) $(DESTDIR)$(SRV_RUNDIR)
|
||||
test -z $(DESTDIR)$(SRV_DATADIR) || $(MKDIR_P) $(DESTDIR)$(SRV_DATADIR)
|
||||
env CGO_ENABLED=1 $(GO) run $(GOFLAGS) ./cmd/certmanagerd/... --daemon=false
|
||||
|
||||
distclean-local: clean
|
||||
rm -rf autom4te.cache
|
||||
@@ -826,7 +829,7 @@ clean-local:
|
||||
rm -rf autom4te.cache
|
||||
rm -f cmd/certmanagerd/certmanagerd
|
||||
rm -f cmd/certmanagerctl/certmanagerctl
|
||||
rm -rf tmp/
|
||||
rm -rf tmp.*/
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
|
||||
3
go.mod
3
go.mod
@@ -7,6 +7,7 @@ require (
|
||||
github.com/jmoiron/sqlx v1.4.0
|
||||
github.com/mattn/go-sqlite3 v1.14.22
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/stretchr/testify v1.9.0
|
||||
google.golang.org/grpc v1.65.0
|
||||
google.golang.org/protobuf v1.34.2
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
@@ -18,6 +19,7 @@ require (
|
||||
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
@@ -31,6 +33,7 @@ require (
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package config
|
||||
|
||||
const (
|
||||
confdirPath = "/home/ziggi/projects/certman/etc/certmanager"
|
||||
rundirPath = "/home/ziggi/projects/certman/tmp.run"
|
||||
logdirPath = "/home/ziggi/projects/certman/tmp.log"
|
||||
datadirPath = "/home/ziggi/projects/certman/tmp.data"
|
||||
confdirPath = "/home/ziggi/projects/certman/etc/certmanager"
|
||||
rundirPath = "/home/ziggi/projects/certman/tmp.run"
|
||||
logdirPath = "/home/ziggi/projects/certman/tmp.log"
|
||||
datadirPath = "/home/ziggi/projects/certman/tmp.data"
|
||||
)
|
||||
|
||||
|
||||
@@ -10,49 +10,51 @@ import (
|
||||
)
|
||||
|
||||
const schema = `
|
||||
--- DROP TABLE IF EXISTS manifests;
|
||||
CREATE TABLE IF NOT EXISTS manifests (
|
||||
id VARCHAR(255) NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
reference VARCHAR(255) NOT NULL,
|
||||
contentType VARCHAR(255) NOT NULL,
|
||||
payload VARCHAR(4096) NOT NULL
|
||||
DROP TABLE IF EXISTS issuer;
|
||||
CREATE TABLE IF NOT EXISTS issuer (
|
||||
id INT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
cert TEXT NOT NULL,
|
||||
key TEXT NOT NULL,
|
||||
revoked BOOL
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS manifest_index
|
||||
ON manifests(name, reference);
|
||||
CREATE INDEX IF NOT EXISTS issuer_index
|
||||
ON issuer(id, name);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS blobs (
|
||||
id VARCHAR(255) NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
digest VARCHAR(255) NOT NULL,
|
||||
used INTEGER
|
||||
DROP TABLE IF EXISTS service;
|
||||
CREATE TABLE IF NOT EXISTS service (
|
||||
id INT NOT NULL,
|
||||
issuer_id INT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
cert TEXT NOT NULL,
|
||||
key TEXT NOT NULL,
|
||||
revoked BOOL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS blobs_index
|
||||
ON blobs(name, digest);
|
||||
|
||||
|
||||
CREATE INDEX IF NOT EXISTS service_index
|
||||
ON issuer(id, name);
|
||||
`
|
||||
|
||||
type Database struct {
|
||||
datapath string
|
||||
db *sqlx.DB
|
||||
log *logger.Logger
|
||||
log *logger.Logger
|
||||
}
|
||||
|
||||
func NewDatabase(datapath string) (*Database, error) {
|
||||
var err error
|
||||
var err error
|
||||
db := &Database{
|
||||
datapath: datapath,
|
||||
}
|
||||
db.log = logger.NewLogger("database")
|
||||
return db, err
|
||||
db.log = logger.NewLogger("database")
|
||||
return db, err
|
||||
|
||||
}
|
||||
|
||||
func (db *Database) InitDatabase() error {
|
||||
var err error
|
||||
dbPath := filepath.Join(db.datapath, "certmanager.db")
|
||||
db.log.Infof("Initialize database %s", dbPath)
|
||||
|
||||
db.db, err = sqlx.Open("sqlite3", dbPath)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
101
internal/database/issuer.go
Normal file
101
internal/database/issuer.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"certmanager/internal/descriptor"
|
||||
"certmanager/pkg/auxid"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
func (db *Database) InsertIssuer(ctx context.Context, issuer *descriptor.Issuer) (int64, error) {
|
||||
var err error
|
||||
var res int64
|
||||
issuer.ID = auxid.GenID()
|
||||
request := `INSERT INTO issuer(id, name, cert, key, revoked)
|
||||
VALUES ($1, $2, $3, $4, $5)`
|
||||
_, err = db.db.Exec(request, issuer.ID, issuer.Name, issuer.Cert, issuer.Key, issuer.Revoked)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
res = issuer.ID
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (db *Database) UpdateIssuerByID(ctx context.Context, issuerID int64, issuer *descriptor.Issuer) error {
|
||||
var err error
|
||||
request := `UPDATE issuer SET revoked = $1 WHERE id = $2`
|
||||
_, err = db.db.Exec(request, issuer.Revoked, issuerID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (db *Database) ListIssuers(ctx context.Context) ([]descriptor.Issuer, error) {
|
||||
var err error
|
||||
request := `SELECT id, name, revoked FROM issuer`
|
||||
res := make([]descriptor.Issuer, 0)
|
||||
err = db.db.Select(&res, request)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (db *Database) GetIssuerByID(ctx context.Context, issuerID int64) (bool, *descriptor.Issuer, error) {
|
||||
var err error
|
||||
var res *descriptor.Issuer
|
||||
var exists bool
|
||||
request := `SELECT id, name, cert, key, revoked FROM issuer WHERE id = $1 LiMIT 1`
|
||||
dbRes := make([]descriptor.Issuer, 0)
|
||||
err = db.db.Select(&dbRes, request, issuerID)
|
||||
if err != nil {
|
||||
return exists, res, err
|
||||
}
|
||||
if len(dbRes) == 0 {
|
||||
return exists, res, err
|
||||
}
|
||||
exists = true
|
||||
res = &dbRes[0]
|
||||
return exists, res, err
|
||||
}
|
||||
|
||||
func (db *Database) GetIssuerByName(ctx context.Context, issuerName string) (bool, *descriptor.Issuer, error) {
|
||||
var err error
|
||||
var res *descriptor.Issuer
|
||||
var exists bool
|
||||
request := `SELECT id, name, cert, key, revoked FROM issuer WHERE name = $1 LIMIT 1`
|
||||
dbRes := make([]descriptor.Issuer, 0)
|
||||
err = db.db.Select(&dbRes, request, issuerName)
|
||||
if err != nil {
|
||||
return exists, res, err
|
||||
}
|
||||
if len(dbRes) == 0 {
|
||||
return exists, res, err
|
||||
}
|
||||
exists = true
|
||||
res = &dbRes[0]
|
||||
return exists, res, err
|
||||
}
|
||||
|
||||
func (db *Database) DeleteIssuerByID(ctx context.Context, issuerID int64) error {
|
||||
var err error
|
||||
request := `DELETE FROM issuer WHERE id = $1`
|
||||
_, err = db.db.Exec(request, issuerID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (db *Database) DeleteIssuerByName(ctx context.Context, issuerName string) error {
|
||||
var err error
|
||||
request := `DELETE FROM issuer WHERE name = $1`
|
||||
_, err = db.db.Exec(request, issuerName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
102
internal/database/service.go
Normal file
102
internal/database/service.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"certmanager/internal/descriptor"
|
||||
"certmanager/pkg/auxid"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
func (db *Database) InsertService(ctx context.Context, service *descriptor.Service) (int64, error) {
|
||||
var err error
|
||||
var res int64
|
||||
service.ID = auxid.GenID()
|
||||
request := `INSERT INTO service(id, issuer_id, name, cert, key, revoked)
|
||||
VALUES ($1, $2, $3, $4, $5, $6)`
|
||||
_, err = db.db.Exec(request, service.ID, service.IssuerID, service.Name, service.Cert,
|
||||
service.Key, service.Revoked)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
res = service.ID
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (db *Database) UpdateServiceByID(ctx context.Context, serviceID int64, service *descriptor.Service) error {
|
||||
var err error
|
||||
request := `UPDATE service SET revoked = $1 WHERE id = $2`
|
||||
_, err = db.db.Exec(request, service.Revoked, serviceID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (db *Database) ListServices(ctx context.Context) ([]descriptor.Service, error) {
|
||||
var err error
|
||||
request := `SELECT id, name, revoked FROM service`
|
||||
res := make([]descriptor.Service, 0)
|
||||
err = db.db.Select(&res, request)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (db *Database) GetServiceByID(ctx context.Context, serviceID int64) (bool, *descriptor.Service, error) {
|
||||
var err error
|
||||
var res *descriptor.Service
|
||||
var exists bool
|
||||
request := `SELECT id, name, cert, key, revoked FROM service WHERE id = $1 LiMIT 1`
|
||||
dbRes := make([]descriptor.Service, 0)
|
||||
err = db.db.Select(&dbRes, request, serviceID)
|
||||
if err != nil {
|
||||
return exists, res, err
|
||||
}
|
||||
if len(dbRes) == 0 {
|
||||
return exists, res, err
|
||||
}
|
||||
exists = true
|
||||
res = &dbRes[0]
|
||||
return exists, res, err
|
||||
}
|
||||
|
||||
func (db *Database) GetServiceByName(ctx context.Context, serviceName string) (bool, *descriptor.Service, error) {
|
||||
var err error
|
||||
var res *descriptor.Service
|
||||
var exists bool
|
||||
request := `SELECT id, name, cert, key, revoked FROM service WHERE name = $1 LIMIT 1`
|
||||
dbRes := make([]descriptor.Service, 0)
|
||||
err = db.db.Select(&dbRes, request, serviceName)
|
||||
if err != nil {
|
||||
return exists, res, err
|
||||
}
|
||||
if len(dbRes) == 0 {
|
||||
return exists, res, err
|
||||
}
|
||||
exists = true
|
||||
res = &dbRes[0]
|
||||
return exists, res, err
|
||||
}
|
||||
|
||||
func (db *Database) DeleteServiceByID(ctx context.Context, serviceID int64) error {
|
||||
var err error
|
||||
request := `DELETE FROM service WHERE id = $1`
|
||||
_, err = db.db.Exec(request, serviceID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (db *Database) DeleteServiceByName(ctx context.Context, serviceName string) error {
|
||||
var err error
|
||||
request := `DELETE FROM service WHERE name = $1`
|
||||
_, err = db.db.Exec(request, serviceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -1,3 +1,18 @@
|
||||
package descriptor
|
||||
|
||||
type Issuer struct {
|
||||
ID int64 `json:"id" yaml:"id" db:"id"`
|
||||
Name string `json:"name" yaml:"name" db:"name"`
|
||||
Cert string `json:"cert" yaml:"cert" db:"cert"`
|
||||
Key string `json:"key" yaml:"key" db:"key"`
|
||||
Revoked bool `json:"revoked" yaml:"revoked" db:"revoked"`
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
ID int64 `json:"id" yaml:"id" db:"id"`
|
||||
IssuerID int64 `json:"issuerId" yaml:"issuerId" db:"issuer_id"`
|
||||
Name string `json:"name" yaml:"name" db:"name"`
|
||||
Cert string `json:"cert" yaml:"cert" db:"cert"`
|
||||
Key string `json:"key" yaml:"key" db:"key"`
|
||||
Revoked bool `json:"revoked" yaml:"revoked" db:"revoked"`
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"certmanager/api/certmanagercontrol"
|
||||
)
|
||||
|
||||
|
||||
func (hand *Handler) CreateIssuerPair(ctx context.Context, req *certmanagercontrol.CreateIssuerPairParams) (*certmanagercontrol.CreateIssuerPairResult, error) {
|
||||
var err error
|
||||
hand.log.Debugf("Handle CreateIssuerPair request")
|
||||
|
||||
@@ -2,66 +2,90 @@ package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
|
||||
"certmanager/api/certmanagercontrol"
|
||||
cmapi "certmanager/api/certmanagercontrol"
|
||||
"certmanager/internal/descriptor"
|
||||
//yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func (lg *Logic) CreateIssuerPair(ctx context.Context, params *certmanagercontrol.CreateIssuerPairParams) (*certmanagercontrol.CreateIssuerPairResult, error) {
|
||||
func (lg *Logic) CreateIssuerPair(ctx context.Context, params *cmapi.CreateIssuerPairParams) (*cmapi.CreateIssuerPairResult, error) {
|
||||
var err error
|
||||
res := &certmanagercontrol.CreateIssuerPairResult{}
|
||||
res := &cmapi.CreateIssuerPairResult{}
|
||||
|
||||
paramsJson, err := json.Marshal(params)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
lg.log.Debugf("params: \n%s\n", string(paramsJson))
|
||||
|
||||
certBytes, keyBytes, err := CreateX509SelfSignedCert(params.IssuerName)
|
||||
certString := base64.StdEncoding.EncodeToString(certBytes)
|
||||
keyString := base64.StdEncoding.EncodeToString(keyBytes)
|
||||
issuer := &descriptor.Issuer{
|
||||
Name: params.IssuerName,
|
||||
Cert: certString,
|
||||
Key: keyString,
|
||||
}
|
||||
issuerID, err := lg.db.InsertIssuer(ctx, issuer)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
res.IssuerID = issuerID
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (lg *Logic) ImportIssuerPair(ctx context.Context, params *certmanagercontrol.ImportIssuerPairParams) (*certmanagercontrol.ImportIssuerPairResult, error) {
|
||||
func (lg *Logic) ImportIssuerPair(ctx context.Context, params *cmapi.ImportIssuerPairParams) (*cmapi.ImportIssuerPairResult, error) {
|
||||
var err error
|
||||
res := &certmanagercontrol.ImportIssuerPairResult{}
|
||||
res := &cmapi.ImportIssuerPairResult{}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (lg *Logic) RevokeIssuerPair(ctx context.Context, params *certmanagercontrol.RevokeIssuerPairParams) (*certmanagercontrol.RevokeIssuerPairResult, error) {
|
||||
func (lg *Logic) RevokeIssuerPair(ctx context.Context, params *cmapi.RevokeIssuerPairParams) (*cmapi.RevokeIssuerPairResult, error) {
|
||||
var err error
|
||||
res := &certmanagercontrol.RevokeIssuerPairResult{}
|
||||
res := &cmapi.RevokeIssuerPairResult{}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (lg *Logic) UnrevokeIssuerPair(ctx context.Context, params *certmanagercontrol.UnrevokeIssuerPairParams) (*certmanagercontrol.UnrevokeIssuerPairResult, error) {
|
||||
func (lg *Logic) UnrevokeIssuerPair(ctx context.Context, params *cmapi.UnrevokeIssuerPairParams) (*cmapi.UnrevokeIssuerPairResult, error) {
|
||||
var err error
|
||||
res := &certmanagercontrol.UnrevokeIssuerPairResult{}
|
||||
res := &cmapi.UnrevokeIssuerPairResult{}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (lg *Logic) ListIssuerPairs(ctx context.Context, params *certmanagercontrol.ListIssuerPairsParams) (*certmanagercontrol.ListIssuerPairsResult, error) {
|
||||
func (lg *Logic) ListIssuerPairs(ctx context.Context, params *cmapi.ListIssuerPairsParams) (*cmapi.ListIssuerPairsResult, error) {
|
||||
var err error
|
||||
res := &certmanagercontrol.ListIssuerPairsResult{}
|
||||
res := &cmapi.ListIssuerPairsResult{}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (lg *Logic) GetIssuerCertificate(ctx context.Context, params *certmanagercontrol.GetIssuerCertificateParams) (*certmanagercontrol.GetIssuerCertificateResult, error) {
|
||||
func (lg *Logic) GetIssuerCertificate(ctx context.Context, params *cmapi.GetIssuerCertificateParams) (*cmapi.GetIssuerCertificateResult, error) {
|
||||
var err error
|
||||
res := &certmanagercontrol.GetIssuerCertificateResult{}
|
||||
res := &cmapi.GetIssuerCertificateResult{}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (lg *Logic) CreateServicePair(ctx context.Context, params *certmanagercontrol.CreateServicePairParams) (*certmanagercontrol.CreateServicePairResult, error) {
|
||||
func (lg *Logic) CreateServicePair(ctx context.Context, params *cmapi.CreateServicePairParams) (*cmapi.CreateServicePairResult, error) {
|
||||
var err error
|
||||
res := &certmanagercontrol.CreateServicePairResult{}
|
||||
res := &cmapi.CreateServicePairResult{}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (lg *Logic) RevokeServicePair(ctx context.Context, params *certmanagercontrol.RevokeServicePairParams) (*certmanagercontrol.RevokeServicePairResult, error) {
|
||||
func (lg *Logic) RevokeServicePair(ctx context.Context, params *cmapi.RevokeServicePairParams) (*cmapi.RevokeServicePairResult, error) {
|
||||
var err error
|
||||
res := &certmanagercontrol.RevokeServicePairResult{}
|
||||
res := &cmapi.RevokeServicePairResult{}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (lg *Logic) ListServicePairs(ctx context.Context, params *certmanagercontrol.ListServicePairsParams) (*certmanagercontrol.ListServicePairsResult, error) {
|
||||
func (lg *Logic) ListServicePairs(ctx context.Context, params *cmapi.ListServicePairsParams) (*cmapi.ListServicePairsResult, error) {
|
||||
var err error
|
||||
res := &certmanagercontrol.ListServicePairsResult{}
|
||||
res := &cmapi.ListServicePairsResult{}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (lg *Logic) GetServicePair(ctx context.Context, params *certmanagercontrol.GetServicePairParams) (*certmanagercontrol.GetServicePairResult, error) {
|
||||
func (lg *Logic) GetServicePair(ctx context.Context, params *cmapi.GetServicePairParams) (*cmapi.GetServicePairResult, error) {
|
||||
var err error
|
||||
res := &certmanagercontrol.GetServicePairResult{}
|
||||
res := &cmapi.GetServicePairResult{}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -7,21 +7,21 @@ import (
|
||||
)
|
||||
|
||||
type LogicConfig struct {
|
||||
Database *database.Database
|
||||
Auths []config.AuthConfig
|
||||
Database *database.Database
|
||||
Auths []config.AuthConfig
|
||||
}
|
||||
|
||||
type Logic struct {
|
||||
auths []config.AuthConfig
|
||||
log *logger.Logger
|
||||
db *database.Database
|
||||
auths []config.AuthConfig
|
||||
log *logger.Logger
|
||||
db *database.Database
|
||||
}
|
||||
|
||||
func NewLogic(conf *LogicConfig) (*Logic, error) {
|
||||
var err error
|
||||
lg := &Logic{
|
||||
db: conf.Database,
|
||||
auths: conf.Auths,
|
||||
db: conf.Database,
|
||||
auths: conf.Auths,
|
||||
}
|
||||
lg.log = logger.NewLogger("logic")
|
||||
return lg, err
|
||||
|
||||
176
internal/logic/x509.go
Normal file
176
internal/logic/x509.go
Normal file
@@ -0,0 +1,176 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
func CreateX509SelfSignedCert(subject string, commonNames ...string) ([]byte, []byte, error) {
|
||||
var err error
|
||||
certPem := make([]byte, 0)
|
||||
keyPem := make([]byte, 0)
|
||||
|
||||
now := time.Now()
|
||||
|
||||
const yearsAfter int = 10
|
||||
const keySize int = 2048
|
||||
|
||||
key, err := rsa.GenerateKey(rand.Reader, keySize)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Can't create a private key: %v", err)
|
||||
return certPem, keyPem, err
|
||||
|
||||
}
|
||||
keyPemBlock := pem.Block{
|
||||
Type: "RSA PRIVATE KEY",
|
||||
Bytes: x509.MarshalPKCS1PrivateKey(key),
|
||||
}
|
||||
keyPem = pem.EncodeToMemory(&keyPemBlock)
|
||||
|
||||
dnsNames := make([]string, 0)
|
||||
dnsNames = append(dnsNames, subject)
|
||||
dnsNames = append(dnsNames, commonNames...)
|
||||
tml := x509.Certificate{
|
||||
SerialNumber: big.NewInt(now.Unix()),
|
||||
NotBefore: now,
|
||||
NotAfter: now.AddDate(yearsAfter, 0, 0),
|
||||
Subject: pkix.Name{
|
||||
CommonName: subject,
|
||||
},
|
||||
DNSNames: dnsNames,
|
||||
IPAddresses: []net.IP{net.ParseIP("192.168.57.1")},
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
certBytes, err := x509.CreateCertificate(rand.Reader, &tml, &tml, &key.PublicKey, key)
|
||||
if err != nil {
|
||||
return certPem, keyPem, fmt.Errorf("Can't create a certificate: %v", err)
|
||||
|
||||
}
|
||||
certPemBlock := pem.Block{
|
||||
Type: "CERTIFICATE",
|
||||
Bytes: certBytes,
|
||||
}
|
||||
certPem = pem.EncodeToMemory(&certPemBlock)
|
||||
if err != nil {
|
||||
return certPem, keyPem, err
|
||||
}
|
||||
return certPem, keyPem, err
|
||||
}
|
||||
|
||||
func CreateX509CACert(commonName string) ([]byte, []byte, error) {
|
||||
var err error
|
||||
certPem := make([]byte, 0)
|
||||
keyPem := make([]byte, 0)
|
||||
|
||||
now := time.Now()
|
||||
|
||||
const yearsAfter int = 10
|
||||
const keySize int = 2048
|
||||
|
||||
key, err := rsa.GenerateKey(rand.Reader, keySize)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Can't create a private key: %v", err)
|
||||
return certPem, keyPem, err
|
||||
|
||||
}
|
||||
keyPemBlock := pem.Block{
|
||||
Type: "RSA PRIVATE KEY",
|
||||
Bytes: x509.MarshalPKCS1PrivateKey(key),
|
||||
}
|
||||
keyPem = pem.EncodeToMemory(&keyPemBlock)
|
||||
|
||||
tml := x509.Certificate{
|
||||
SerialNumber: big.NewInt(now.Unix()),
|
||||
NotBefore: now,
|
||||
NotAfter: now.AddDate(yearsAfter, 0, 0),
|
||||
Subject: pkix.Name{
|
||||
CommonName: commonName,
|
||||
},
|
||||
IsCA: true,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
|
||||
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
certBytes, err := x509.CreateCertificate(rand.Reader, &tml, &tml, &key.PublicKey, key)
|
||||
if err != nil {
|
||||
return certPem, keyPem, fmt.Errorf("Can't create a certificate: %v", err)
|
||||
|
||||
}
|
||||
certPemBlock := pem.Block{
|
||||
Type: "CERTIFICATE",
|
||||
Bytes: certBytes,
|
||||
}
|
||||
certPem = pem.EncodeToMemory(&certPemBlock)
|
||||
|
||||
if err != nil {
|
||||
return certPem, keyPem, err
|
||||
}
|
||||
return certPem, keyPem, err
|
||||
}
|
||||
|
||||
func CreateX509Cert(commonName string, caKeyPem []byte, dnsNames ...string) ([]byte, []byte, error) {
|
||||
var err error
|
||||
certPem := make([]byte, 0)
|
||||
keyPem := make([]byte, 0)
|
||||
now := time.Now()
|
||||
|
||||
const yearsAfter int = 10
|
||||
const keySize int = 2048
|
||||
|
||||
key, err := rsa.GenerateKey(rand.Reader, keySize)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Can't create a private key: %v", err)
|
||||
return certPem, keyPem, err
|
||||
}
|
||||
keyPemBlock := pem.Block{
|
||||
Type: "RSA PRIVATE KEY",
|
||||
Bytes: x509.MarshalPKCS1PrivateKey(key),
|
||||
}
|
||||
keyPem = pem.EncodeToMemory(&keyPemBlock)
|
||||
|
||||
pemBlock, _ := pem.Decode(caKeyPem)
|
||||
if pemBlock == nil {
|
||||
err := fmt.Errorf("Can't parse a CA private key block")
|
||||
return certPem, keyPem, err
|
||||
}
|
||||
caKey, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Can't parse a CA private key")
|
||||
return certPem, keyPem, err
|
||||
}
|
||||
|
||||
tml := x509.Certificate{
|
||||
SerialNumber: big.NewInt(now.Unix()),
|
||||
NotBefore: now,
|
||||
NotAfter: now.AddDate(yearsAfter, 0, 0),
|
||||
Subject: pkix.Name{
|
||||
CommonName: commonName,
|
||||
},
|
||||
DNSNames: append([]string{commonName}, dnsNames...),
|
||||
IsCA: false,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
|
||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
certBytes, err := x509.CreateCertificate(rand.Reader, &tml, &tml, &key.PublicKey, caKey)
|
||||
if err != nil {
|
||||
return certPem, keyPem, fmt.Errorf("Can't create a certificate: %v", err)
|
||||
|
||||
}
|
||||
certPemBlock := pem.Block{
|
||||
Type: "CERTIFICATE",
|
||||
Bytes: certBytes,
|
||||
}
|
||||
certPem = pem.EncodeToMemory(&certPemBlock)
|
||||
if err != nil {
|
||||
return certPem, keyPem, err
|
||||
}
|
||||
return certPem, keyPem, err
|
||||
}
|
||||
@@ -85,8 +85,8 @@ func (srv *Server) Build() error {
|
||||
|
||||
// Create logic
|
||||
logicConfig := &logic.LogicConfig{
|
||||
Auths: srv.conf.Auths,
|
||||
Database: srv.db,
|
||||
Auths: srv.conf.Auths,
|
||||
Database: srv.db,
|
||||
}
|
||||
srv.lg, err = logic.NewLogic(logicConfig)
|
||||
if err != nil {
|
||||
@@ -149,13 +149,19 @@ func (srv *Server) Run() error {
|
||||
}
|
||||
srv.log.Debugf("Server configuration:\n%s\n", yamlConfig)
|
||||
|
||||
// Show current user
|
||||
// Show current user
|
||||
currUser, err := user.Current()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
srv.log.Infof("Running server as user %s", currUser.Username)
|
||||
|
||||
// Show current user
|
||||
err = srv.db.InitDatabase()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sigs := make(chan os.Signal, 1)
|
||||
gdone := make(chan error, 1)
|
||||
wdone := make(chan error, 1)
|
||||
|
||||
118
internal/test/database_test.go
Normal file
118
internal/test/database_test.go
Normal file
@@ -0,0 +1,118 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"certmanager/internal/config"
|
||||
"certmanager/internal/database"
|
||||
"certmanager/internal/descriptor"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func TestDatabaseIssuer(t *testing.T) {
|
||||
var err error
|
||||
conf := config.NewConfig()
|
||||
err = conf.ReadFile()
|
||||
require.NoError(t, err)
|
||||
|
||||
db, err := database.NewDatabase(conf.DataDir)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, db)
|
||||
|
||||
err = db.InitDatabase()
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx, _ := context.WithTimeout(context.Background(), 1*time.Second)
|
||||
|
||||
issuer := &descriptor.Issuer{
|
||||
Name: "foo.bar",
|
||||
Cert: "ASDFF",
|
||||
Key: "QWERT",
|
||||
Revoked: true,
|
||||
}
|
||||
issuerID, err := db.InsertIssuer(ctx, issuer)
|
||||
require.NoError(t, err)
|
||||
fmt.Printf("issuerId: %d\n", issuerID)
|
||||
|
||||
issuer.Revoked = true
|
||||
err = db.UpdateIssuerByID(ctx, issuerID, issuer)
|
||||
require.NoError(t, err)
|
||||
|
||||
issuerExists, issuer, err := db.GetIssuerByID(ctx, issuerID)
|
||||
require.NoError(t, err)
|
||||
require.True(t, issuerExists)
|
||||
require.NotNil(t, issuer)
|
||||
require.True(t, issuer.Revoked)
|
||||
|
||||
issuerYAML, err := yaml.Marshal(issuer)
|
||||
require.NoError(t, err)
|
||||
fmt.Printf("Issuer: \n%s\n---\n", string(issuerYAML))
|
||||
|
||||
listIssuers, err := db.ListIssuers(ctx)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, listIssuers)
|
||||
|
||||
listIssuersYAML, err := yaml.Marshal(listIssuers)
|
||||
require.NoError(t, err)
|
||||
fmt.Printf("listIssuers: \n%s\n", string(listIssuersYAML))
|
||||
|
||||
err = db.DeleteIssuerByID(ctx, issuerID)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestDatabaseService(t *testing.T) {
|
||||
var err error
|
||||
conf := config.NewConfig()
|
||||
err = conf.ReadFile()
|
||||
require.NoError(t, err)
|
||||
|
||||
db, err := database.NewDatabase(conf.DataDir)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, db)
|
||||
|
||||
err = db.InitDatabase()
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx, _ := context.WithTimeout(context.Background(), 1*time.Second)
|
||||
|
||||
service := &descriptor.Service{
|
||||
Name: "foo.bar",
|
||||
IssuerID: 123456,
|
||||
Cert: "ASDFF",
|
||||
Key: "QWERT",
|
||||
Revoked: true,
|
||||
}
|
||||
serviceID, err := db.InsertService(ctx, service)
|
||||
require.NoError(t, err)
|
||||
fmt.Printf("serviceId: %d\n", serviceID)
|
||||
|
||||
service.Revoked = true
|
||||
err = db.UpdateServiceByID(ctx, serviceID, service)
|
||||
require.NoError(t, err)
|
||||
|
||||
serviceExists, service, err := db.GetServiceByID(ctx, serviceID)
|
||||
require.NoError(t, err)
|
||||
require.True(t, serviceExists)
|
||||
require.NotNil(t, service)
|
||||
require.True(t, service.Revoked)
|
||||
|
||||
serviceYAML, err := yaml.Marshal(service)
|
||||
require.NoError(t, err)
|
||||
fmt.Printf("Service: \n%s\n---\n", string(serviceYAML))
|
||||
|
||||
listServices, err := db.ListServices(ctx)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, listServices)
|
||||
|
||||
listServicesYAML, err := yaml.Marshal(listServices)
|
||||
require.NoError(t, err)
|
||||
fmt.Printf("listServices: \n%s\n", string(listServicesYAML))
|
||||
|
||||
err = db.DeleteServiceByID(ctx, serviceID)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
50
internal/test/logic_test.go
Normal file
50
internal/test/logic_test.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
cmapi "certmanager/api/certmanagercontrol"
|
||||
"certmanager/internal/config"
|
||||
"certmanager/internal/database"
|
||||
"certmanager/internal/logic"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestLogicIssuer(t *testing.T) {
|
||||
var err error
|
||||
conf := config.NewConfig()
|
||||
err = conf.ReadFile()
|
||||
require.NoError(t, err)
|
||||
|
||||
db, err := database.NewDatabase(conf.DataDir)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, db)
|
||||
|
||||
err = db.InitDatabase()
|
||||
require.NoError(t, err)
|
||||
|
||||
logicConfig := &logic.LogicConfig{
|
||||
Auths: conf.Auths,
|
||||
Database: db,
|
||||
}
|
||||
lg, err := logic.NewLogic(logicConfig)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, lg)
|
||||
|
||||
ctx, _ := context.WithTimeout(context.Background(), 1*time.Second)
|
||||
|
||||
createIssuerPairParams := &cmapi.CreateIssuerPairParams{
|
||||
SelfSigned: true,
|
||||
IssuerName: "foo.bar",
|
||||
}
|
||||
createIssuerPairRes, err := lg.CreateIssuerPair(ctx, createIssuerPairParams)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, createIssuerPairRes)
|
||||
|
||||
fmt.Printf("issuerId: %d\n", createIssuerPairRes.IssuerID)
|
||||
|
||||
}
|
||||
32
pkg/auxid/genid.go
Normal file
32
pkg/auxid/genid.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package auxid
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
}
|
||||
|
||||
var (
|
||||
idMtx sync.Mutex
|
||||
lastID int64
|
||||
)
|
||||
|
||||
func GenID() int64 {
|
||||
// 53 bit limit for js
|
||||
// See https://stackoverflow.com/questions/1379934/large-numbers-erroneously-rounded-in-javascript
|
||||
idMtx.Lock()
|
||||
defer idMtx.Unlock()
|
||||
for {
|
||||
id := (time.Now().UnixNano() / 1000) // - 10000000000000
|
||||
if id != lastID {
|
||||
lastID = id
|
||||
return id
|
||||
}
|
||||
time.Sleep(1 * time.Microsecond)
|
||||
}
|
||||
//10467328383814
|
||||
}
|
||||
@@ -24,7 +24,6 @@ type Access struct {
|
||||
Password string
|
||||
}
|
||||
|
||||
|
||||
type Control struct {
|
||||
conn *grpc.ClientConn
|
||||
client cmapi.ControlClient
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
package common
|
||||
|
||||
|
||||
Reference in New Issue
Block a user