Skip to content

Commit

Permalink
CERT-22 - Add CSR feature (#53)
Browse files Browse the repository at this point in the history
* Intial implementation of CSR

Signed-off-by: nyagamunene <[email protected]>

* Add repository for CSR

Signed-off-by: nyagamunene <[email protected]>

* Add endpoints

Signed-off-by: nyagamunene <[email protected]>

* add sdk support

Signed-off-by: nyagamunene <[email protected]>

* fix tests

Signed-off-by: nyagamunene <[email protected]>

* fix postgres varibles

Signed-off-by: nyagamunene <[email protected]>

* fix sdk url paths

Signed-off-by: nyagamunene <[email protected]>

* fix failing linter

Signed-off-by: nyagamunene <[email protected]>

* address comments

Signed-off-by: nyagamunene <[email protected]>

* Fix sign conflict

Signed-off-by: nyagamunene <[email protected]>

---------

Signed-off-by: nyagamunene <[email protected]>
  • Loading branch information
nyagamunene authored Nov 28, 2024
1 parent 0dab8cc commit f2b8a9a
Show file tree
Hide file tree
Showing 28 changed files with 2,154 additions and 137 deletions.
73 changes: 73 additions & 0 deletions api/http/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,3 +309,76 @@ func viewCAEndpoint(svc certs.Service) endpoint.Endpoint {
}, nil
}
}

func createCSREndpoint(svc certs.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
req := request.(createCSRReq)
if err := req.validate(); err != nil {
return createCSRRes{created: false}, err
}

csr, err := svc.CreateCSR(ctx, req.Metadata, req.Metadata.EntityID, req.privKey)
if err != nil {
return createCSRRes{created: false}, err
}

return createCSRRes{
created: true,
CSR: csr,
}, nil
}
}

func signCSREndpoint(svc certs.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
req := request.(SignCSRReq)
if err := req.validate(); err != nil {
return signCSRRes{signed: false}, err
}

err = svc.SignCSR(ctx, req.csrID, req.approve)
if err != nil {
return signCSRRes{signed: false}, err
}

return signCSRRes{
signed: true,
}, nil
}
}

func retrieveCSREndpoint(svc certs.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
req := request.(retrieveCSRReq)
if err := req.validate(); err != nil {
return retrieveCSRRes{}, err
}

csr, err := svc.RetrieveCSR(ctx, req.csrID)
if err != nil {
return retrieveCSRRes{}, err
}

return retrieveCSRRes{
CSR: csr,
}, nil
}
}

func listCSRsEndpoint(svc certs.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
req := request.(listCSRsReq)
if err := req.validate(); err != nil {
return listCSRsRes{}, err
}

cp, err := svc.ListCSRs(ctx, req.pm)
if err != nil {
return listCSRsRes{}, err
}

return listCSRsRes{
cp,
}, nil
}
}
4 changes: 2 additions & 2 deletions api/http/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ var (
// ErrMissingCN indicates missing common name.
ErrMissingCN = errors.New("missing common name")

// ErrEmptyEntityID indicates that the entity id is empty.
ErrEmptyEntityID = errors.New("missing entity id")
// ErrMissingStatus indicates missing status.
ErrMissingStatus = errors.New("missing status")
)
52 changes: 51 additions & 1 deletion api/http/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
package http

import (
"crypto/rsa"

"github.com/absmach/certs"
"github.com/absmach/certs/errors"
"golang.org/x/crypto/ocsp"
Expand Down Expand Up @@ -38,7 +40,7 @@ type deleteReq struct {

func (req deleteReq) validate() error {
if req.entityID == "" {
return errors.Wrap(certs.ErrMalformedEntity, ErrEmptyEntityID)
return errors.Wrap(certs.ErrMalformedEntity, ErrMissingEntityID)
}
return nil
}
Expand Down Expand Up @@ -87,3 +89,51 @@ func (req ocspReq) validate() error {
}
return nil
}

type createCSRReq struct {
Metadata certs.CSRMetadata `json:"metadata"`
PrivateKey []byte `json:"private_Key"`
privKey *rsa.PrivateKey
}

func (req createCSRReq) validate() error {
if req.Metadata.EntityID == "" {
return errors.Wrap(certs.ErrMalformedEntity, ErrMissingEntityID)
}
return nil
}

type SignCSRReq struct {
csrID string
approve bool
}

func (req SignCSRReq) validate() error {
if req.csrID == "" {
return errors.Wrap(certs.ErrMalformedEntity, ErrMissingEntityID)
}

return nil
}

type listCSRsReq struct {
pm certs.PageMetadata
}

func (req listCSRsReq) validate() error {
if req.pm.Status.String() == "" {
return errors.Wrap(certs.ErrMalformedEntity, ErrMissingStatus)
}
return nil
}

type retrieveCSRReq struct {
csrID string
}

func (req retrieveCSRReq) validate() error {
if req.csrID == "" {
return errors.Wrap(certs.ErrMalformedEntity, ErrMissingEntityID)
}
return nil
}
72 changes: 71 additions & 1 deletion api/http/responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"net/http"
"time"

"github.com/absmach/certs"
"golang.org/x/crypto/ocsp"
)

Expand Down Expand Up @@ -142,7 +143,7 @@ func (res listCertsRes) Empty() bool {
type viewCertRes struct {
SerialNumber string `json:"serial_number,omitempty"`
Certificate string `json:"certificate,omitempty"`
Key string `json:"key,omitempty,omitempty"`
Key string `json:"key,omitempty"`
Revoked bool `json:"revoked,omitempty"`
ExpiryTime time.Time `json:"expiry_time,omitempty"`
EntityID string `json:"entity_id,omitempty"`
Expand Down Expand Up @@ -201,3 +202,72 @@ type fileDownloadRes struct {
Filename string
ContentType string
}

type createCSRRes struct {
certs.CSR
created bool
}

func (res createCSRRes) Code() int {
if res.created {
return http.StatusCreated
}

return http.StatusNoContent
}

func (res createCSRRes) Headers() map[string]string {
return map[string]string{}
}

func (res createCSRRes) Empty() bool {
return false
}

type signCSRRes struct {
signed bool
}

func (res signCSRRes) Code() int {
return http.StatusOK
}

func (res signCSRRes) Headers() map[string]string {
return map[string]string{}
}

func (res signCSRRes) Empty() bool {
return true
}

type listCSRsRes struct {
certs.CSRPage
}

func (res listCSRsRes) Code() int {
return http.StatusOK
}

func (res listCSRsRes) Headers() map[string]string {
return map[string]string{}
}

func (res listCSRsRes) Empty() bool {
return false
}

type retrieveCSRRes struct {
certs.CSR
}

func (res retrieveCSRRes) Code() int {
return http.StatusOK
}

func (res retrieveCSRRes) Headers() map[string]string {
return map[string]string{}
}

func (res retrieveCSRRes) Empty() bool {
return false
}
Loading

0 comments on commit f2b8a9a

Please sign in to comment.