Skip to content

Commit

Permalink
feat: add support for certificates removal
Browse files Browse the repository at this point in the history
  • Loading branch information
streambinder committed Jul 15, 2022
1 parent 624ff6d commit c6fb40c
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 81 deletions.
4 changes: 4 additions & 0 deletions pki/crt.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,7 @@ func New(req Request) (*x509.Certificate, *Key, error) {
key, err := newKey(req.Algo)
return &crt, key, err
}

func IsValidCN(name string) bool {
return len(name) > 3
}
24 changes: 24 additions & 0 deletions server/ca.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package server

import (
"bytes"

"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog/log"
"gitlab.rete.farm/sistemi/inca/provider"
)

func (inca *Inca) handlerCA(c *fiber.Ctx) error {
p := provider.Get(c.Params("provider"), inca.Cfg.Providers)
if p == nil {
return c.SendStatus(fiber.StatusNotFound)
}

caCrt, err := (*p).CA()
if err != nil {
log.Error().Err(err).Msg("unable to retrieve CA certificate")
return c.SendStatus(fiber.StatusBadRequest)
}

return c.SendStream(bytes.NewReader(caCrt.Bytes), len(caCrt.Bytes))
}
58 changes: 58 additions & 0 deletions server/crt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package server

import (
"bytes"
"fmt"

"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog/log"
"gitlab.rete.farm/sistemi/inca/provider"
"gitlab.rete.farm/sistemi/inca/util"
)

func (inca *Inca) handlerCRT(c *fiber.Ctx) error {
var (
name = c.Params("name")
crtFname = crtFilename(name)
keyFname = keyFilename(name)
queryStrings = util.ParseQueryString(c.Request().URI().QueryString())
)
if len(name) <= 3 {
log.Error().Str("name", name).Msg("name too short")
return c.SendStatus(fiber.StatusBadRequest)
}

data, err := (*inca.Cfg.Storage).Get(crtFname)
if err == nil {
log.Info().Str("fname", crtFname).Err(err).Msg("returning cached certificate")
return c.SendStream(bytes.NewReader(data), len(data))
}

p := provider.GetFor(name, queryStrings, (*inca.Cfg).Providers)
if p == nil {
log.Error().Str("name", name).Msg("no provider found")
return c.SendStatus(fiber.StatusBadRequest)
}

crt, key, err := (*p).Get(name, queryStrings)
if err != nil {
log.Error().Err(err).Msg("unable to generate")
return c.SendStatus(fiber.StatusBadRequest)
}

if err := (*inca.Cfg.Storage).Put(crtFname, crt); err != nil {
log.Error().Err(err).Msg("unable to persist certificate")
return c.SendStatus(fiber.StatusBadRequest)
}

if err := (*inca.Cfg.Storage).Put(keyFname, key); err != nil {
log.Error().Err(err).Msg("unable to persist certificate")
return c.SendStatus(fiber.StatusBadRequest)
}

return c.SendStream(bytes.NewReader(crt.Bytes), len(crt.Bytes))
}

func crtFilename(name string) string {
return fmt.Sprintf("%s.pem", name)
}
86 changes: 5 additions & 81 deletions server/inca.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
package server

import (
"bytes"
"fmt"
"os"

"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"gitlab.rete.farm/sistemi/inca/provider"
"gitlab.rete.farm/sistemi/inca/server/config"
"gitlab.rete.farm/sistemi/inca/server/middleware"
"gitlab.rete.farm/sistemi/inca/util"
)

type Inca struct {
Expand All @@ -25,82 +20,11 @@ func Spinup(path string) (*Inca, error) {
return nil, err
}

inca := &Inca{
fiber.New(
fiber.Config{DisableStartupMessage: true},
),
cfg,
}
inca := &Inca{fiber.New(fiber.Config{DisableStartupMessage: true}), cfg}
inca.Use(middleware.Logger(zerolog.New(os.Stdout), func(c *fiber.Ctx) bool { return false }))
inca.Get("/:name", func(c *fiber.Ctx) error {
var (
name = c.Params("name")
crtFname = fmt.Sprintf("%s.pem", name)
keyFname = fmt.Sprintf("%s.key", name)
queryStrings = util.ParseQueryString(c.Request().URI().QueryString())
)
if len(name) <= 3 {
log.Error().Str("name", name).Msg("name too short")
return c.SendStatus(fiber.StatusBadRequest)
}

data, err := (*cfg.Storage).Get(crtFname)
if err == nil {
log.Info().Str("fname", crtFname).Err(err).Msg("returning cached certificate")
return c.SendStream(bytes.NewReader(data), len(data))
}

p := provider.GetFor(name, queryStrings, cfg.Providers)
if p == nil {
log.Error().Str("name", name).Msg("no provider found")
return c.SendStatus(fiber.StatusBadRequest)
}

crt, key, err := (*p).Get(name, queryStrings)
if err != nil {
log.Error().Err(err).Msg("unable to generate")
return c.SendStatus(fiber.StatusBadRequest)
}

if err := (*cfg.Storage).Put(crtFname, crt); err != nil {
log.Error().Err(err).Msg("unable to persist certificate")
return c.SendStatus(fiber.StatusBadRequest)
}

if err := (*cfg.Storage).Put(keyFname, key); err != nil {
log.Error().Err(err).Msg("unable to persist certificate")
return c.SendStatus(fiber.StatusBadRequest)
}

return c.SendStream(bytes.NewReader(crt.Bytes), len(crt.Bytes))
})
inca.Get("/:name/key", func(c *fiber.Ctx) error {
var keyFname = fmt.Sprintf("%s.key", c.Params("name"))
data, err := (*cfg.Storage).Get(keyFname)
if err == nil {
return c.SendStream(bytes.NewReader(data), len(data))
}

log.Info().Str("fname", keyFname).Err(err).Msg("cached key not found")
return c.SendStatus(fiber.StatusNotFound)
})
inca.Get("/ca/:provider", func(c *fiber.Ctx) error {
p := provider.Get(c.Params("provider"), inca.Cfg.Providers)
if p == nil {
return c.SendStatus(fiber.StatusNotFound)
}

caCrt, err := (*p).CA()
if err != nil {
log.Error().Err(err).Msg("unable to retrieve CA certificate")
return c.SendStatus(fiber.StatusBadRequest)
}

return c.SendStream(bytes.NewReader(caCrt.Bytes), len(caCrt.Bytes))
})
inca.Get("/revoke/:name", func(c *fiber.Ctx) error {
return c.SendString(fmt.Sprintf("revoke %s", c.Params("name")))
})

inca.Get("/:name", inca.handlerCRT)
inca.Get("/:name/key", inca.handlerKey)
inca.Put("/:name/revoke", inca.handlerRevoke)
inca.Get("/ca/:provider", inca.handlerCA)
return inca, nil
}
24 changes: 24 additions & 0 deletions server/key.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package server

import (
"bytes"
"fmt"

"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog/log"
)

func (inca *Inca) handlerKey(c *fiber.Ctx) error {
keyFname := keyFilename(c.Params("name"))
data, err := (*inca.Cfg.Storage).Get(keyFname)
if err == nil {
return c.SendStream(bytes.NewReader(data), len(data))
}

log.Info().Str("fname", keyFname).Err(err).Msg("cached key not found")
return c.SendStatus(fiber.StatusNotFound)
}

func keyFilename(name string) string {
return fmt.Sprintf("%s.key", name)
}
19 changes: 19 additions & 0 deletions server/revoke.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package server

import (
"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog/log"
)

func (inca *Inca) handlerRevoke(c *fiber.Ctx) error {
for _, asset := range []string{
crtFilename(c.Params("name")),
keyFilename(c.Params("name")),
} {
if err := (*inca.Cfg.Storage).Del(asset); err != nil {
log.Error().Err(err).Msg("unable to remove")
return c.SendStatus(fiber.StatusBadRequest)
}
}
return c.SendStatus(fiber.StatusOK)
}
1 change: 1 addition & 0 deletions storage/abstract.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type Storage interface {
Tune(options ...string) error
Put(name string, data *pem.Block) error
Get(name string) ([]byte, error)
Del(name string) error
}

func Get(id string, options ...string) (*Storage, error) {
Expand Down
5 changes: 5 additions & 0 deletions storage/filesystem.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/pem"
"fmt"
"io/ioutil"
"os"
"path/filepath"

"gitlab.rete.farm/sistemi/inca/pki"
Expand Down Expand Up @@ -47,3 +48,7 @@ func (s *FileSystem) Put(name string, data *pem.Block) error {
}
return nil
}

func (s *FileSystem) Del(name string) error {
return os.Remove(filepath.Join(s.path, name))
}

0 comments on commit c6fb40c

Please sign in to comment.