Skip to content
This repository was archived by the owner on Apr 6, 2026. It is now read-only.

NOISSUE - Refactor CSR generation#55

Merged
dborovcanin merged 22 commits into
absmach:mainfrom
nyagamunene:Remove-CSR-Repo
Dec 9, 2024
Merged

NOISSUE - Refactor CSR generation#55
dborovcanin merged 22 commits into
absmach:mainfrom
nyagamunene:Remove-CSR-Repo

Conversation

@nyagamunene

@nyagamunene nyagamunene commented Nov 28, 2024

Copy link
Copy Markdown
Contributor

What type of PR is this?

This is a refactor because it changes the following functionality: it removes CSR repository.

What does this do?

It removes CSR repository.

Which issue(s) does this PR fix/relate to?

N/A

Have you included tests for your changes?

Yes

Did you document any new/modified features?

No

Notes

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
@nyagamunene nyagamunene marked this pull request as ready for review December 2, 2024 08:31

@SammyOina SammyOina left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Method should be IssueFromCSR with csr as argument and the response should be the issued certificate

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
@nyagamunene nyagamunene self-assigned this Dec 2, 2024
Comment thread api/http/endpoint.go
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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

what is the purpose of create csr endpoint, users can create csrs using openssl

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Its an alternative if the user doesn't want to use openssl. The idea is to make certs more generic.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

move to cli tool, no need to call an online api to create a CSR

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Comment thread api/http/endpoint.go Outdated
}

csr, err := svc.CreateCSR(ctx, req.Metadata, req.Metadata.EntityID, req.privKey)
cert, err := svc.IssueFromCSR(ctx, req.entityID, req.ttl, certs.CSR{CSR: []byte(req.CSR), PrivateKey: []byte(req.PrivateKey)})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why is the private key uploaded,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

you don't need the private key when signing the certificate, you only need the public key. the point of this endpoint is for users who want to keep their private keys secure

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Let me make that change

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
SammyOina
SammyOina previously approved these changes Dec 3, 2024
Comment thread cli/certs.go Outdated
Comment on lines +392 to +397
case *rsa.PrivateKey:
signer = key
case *ecdsa.PrivateKey:
signer = key
case ed25519.PrivateKey:
signer = key

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Group cases:

case *rsa.PrivateKey, *ecdsa.PrivateKey, *ed25519.PrivateKey:

Comment thread cli/certs.go Outdated
}
return CreateCSR(metadata, parsedKey)
default:
return certs.CSR{}, errors.NewSDKError(errors.Wrap(ErrCreateEntity, errors.New("unsupported private key type")))

@dborovcanin dborovcanin Dec 6, 2024

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Extract errors.New("unsupported...") to a variable.

Comment thread cli/certs.go Outdated
privateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
case certs.ECPrivateKey:
privateKey, err = x509.ParseECPrivateKey(block.Bytes)
case certs.PrivateKey, "PKCS8 PRIVATE KEY":

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Extract string literal to constant. Please double-check to see if there is no such constant somewhere in imported packages.

Comment thread cli/certs.go Outdated
privateKey, err = x509.ParseECPrivateKey(block.Bytes)
case certs.PrivateKey, "PKCS8 PRIVATE KEY":
privateKey, err = x509.ParsePKCS8PrivateKey(block.Bytes)
case "ED25519 PRIVATE KEY":

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same.

Comment thread cli/certs.go Outdated
case "ED25519 PRIVATE KEY":
privateKey, err = x509.ParsePKCS8PrivateKey(block.Bytes)
default:
err = errors.New("unsupported private key type")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Use error var.

Comment thread cli/certs.go Outdated
err = errors.New("unsupported private key type")
}
if err != nil {
return nil, errors.New("failed to parse key")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Extract error to var.

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Comment thread service.go Outdated
// The certificate is then stored in the repository using the CreateCert method.
// If the root CA is not found, it returns an error.
func (s *service) IssueCert(ctx context.Context, entityID, ttl string, ipAddrs []string, options SubjectOptions, key ...any) (Certificate, error) {
var privKey any

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Use var privKey crypto.PrivateKey instead.

Comment thread certs.go Outdated

// IssueCert issues a certificate from the database.
IssueCert(ctx context.Context, entityID, ttl string, ipAddrs []string, option SubjectOptions, privKey ...*rsa.PrivateKey) (Certificate, error)
IssueCert(ctx context.Context, entityID, ttl string, ipAddrs []string, option SubjectOptions, privKey ...any) (Certificate, error)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Use privKey crypto.PrivateKey instead.

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Comment thread certs.go Outdated

// IssueCert issues a certificate from the database.
IssueCert(ctx context.Context, entityID, ttl string, ipAddrs []string, option SubjectOptions, privKey ...*rsa.PrivateKey) (Certificate, error)
IssueCert(ctx context.Context, entityID, ttl string, ipAddrs []string, option SubjectOptions, privKey ...crypto.PrivateKey) (Certificate, error)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is there a reason for this to be a variadic function? Can we just use have

	IssueCert(ctx context.Context, entityID, ttl string, ipAddrs []string, option SubjectOptions, privKey crypto.PrivateKey) (Certificate, error)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes there is a reason. It because its also been used by the issueCSR method to issue certificates since they user needs to provide their own private key

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Comment thread service.go Outdated
Comment on lines +96 to +100
// issueCert generates and issues a certificate for a given backendID.
// It uses the RSA algorithm to generate a private key, and then creates a certificate
// using the provided template and the generated private key.
// The certificate is then stored in the repository using the CreateCert method.
// If the root CA is not found, it returns an error.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Remove duplicate comments.

Comment thread service.go Outdated
// using the provided template and the generated private key.
// The certificate is then stored in the repository using the CreateCert method.
// If the root CA is not found, it returns an error.
func (s *service) IssueCert(ctx context.Context, entityID, ttl string, ipAddrs []string, options SubjectOptions, key crypto.PrivateKey) (Certificate, error) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Let's extract issuing certs to unexported method:

 (s *service) issue(ctx context.Context, entityID, ttl string, ipAddrs []string, options SubjectOptions, pubKey crypto.PublicKey, privKey crypto.PrivateKey) (Certificate, error)

you can call from both IssuseCert and IssueFromCSR so that you can make the interface cleaner:

IssueCert(ctx context.Context, entityID, ttl string, ipAddrs []string, option SubjectOptions) (Certificate, error)

So we do not have any key params when issuing certs (so you don't have to use nil as the indicator you want to create a key pair).

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Comment thread service.go Outdated

if s.intermediateCA.Certificate == nil || s.intermediateCA.PrivateKey == nil {
return Certificate{}, ErrIntermediateCANotFound
subject := s.getSubject(options)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Rename to subjectFromOpts. Also, no need to make it a service method, it's just an unexported function: func subjectFromOpts(opts SubjectOptions) pkix.Name.

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
@dborovcanin dborovcanin merged commit 04dbd2c into absmach:main Dec 9, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

3 participants