Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CERT-22 - Add CSR feature #53

Merged
merged 10 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 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
}
}

func retrieveCSREndpoint(svc certs.Service) endpoint.Endpoint {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switch the order of retrieve and list endpoints.

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