Skip to content

Commit

Permalink
Use signing algorithm matching public key algorithm (#1)
Browse files Browse the repository at this point in the history
* Use signing algorithm matching public key algorithm

* Add example certificates
  • Loading branch information
jniebuhr authored Jan 15, 2021
1 parent 31ee37e commit c780104
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 1 deletion.
22 changes: 22 additions & 0 deletions config/examples/certificates/ecdsa-256.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
kind: Certificate
apiVersion: cert-manager.io/v1
metadata:
name: ecdsa-cert-256
namespace: default
spec:
commonName: ecdsa-256.example.com
dnsNames:
- ecdsa-256.example.com
duration: 2160h0m0s
issuerRef:
group: awspca.cert-manager.io
kind: AWSPCAClusterIssuer
name: example
renewBefore: 360h0m0s
secretName: ecdsa-cert-256
usages:
- server auth
- client auth
privateKey:
algorithm: "ecdsa"
size: 256
22 changes: 22 additions & 0 deletions config/examples/certificates/ecdsa-521.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
kind: Certificate
apiVersion: cert-manager.io/v1
metadata:
name: ecdsa-cert-521
namespace: default
spec:
commonName: ecdsa-521.example.com
dnsNames:
- ecdsa-521.example.com
duration: 2160h0m0s
issuerRef:
group: awspca.cert-manager.io
kind: AWSPCAClusterIssuer
name: example
renewBefore: 360h0m0s
secretName: ecdsa-cert-521
usages:
- server auth
- client auth
privateKey:
algorithm: "ecdsa"
size: 521
22 changes: 22 additions & 0 deletions config/examples/certificates/rsa-2048.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
kind: Certificate
apiVersion: cert-manager.io/v1
metadata:
name: rsa-cert-2048
namespace: default
spec:
commonName: rsa-2048.example.com
dnsNames:
- rsa-2048.example.com
duration: 2160h0m0s
issuerRef:
group: awspca.cert-manager.io
kind: AWSPCAClusterIssuer
name: example
renewBefore: 360h0m0s
secretName: rsa-cert-2048
usages:
- server auth
- client auth
privateKey:
algorithm: "rsa"
size: 2048
22 changes: 22 additions & 0 deletions config/examples/certificates/rsa-4096.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
kind: Certificate
apiVersion: cert-manager.io/v1
metadata:
name: rsa-cert-4096
namespace: default
spec:
commonName: rsa-4096.example.com
dnsNames:
- rsa-4096.example.com
duration: 2160h0m0s
issuerRef:
group: awspca.cert-manager.io
kind: AWSPCAClusterIssuer
name: example
renewBefore: 360h0m0s
secretName: rsa-cert-4096
usages:
- server auth
- client auth
privateKey:
algorithm: "rsa"
size: 4096
66 changes: 65 additions & 1 deletion pkg/aws/pca.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ package aws

import (
"context"
"crypto/ecdsa"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/acmpca"
Expand Down Expand Up @@ -61,14 +66,29 @@ func NewProvisioner(session *session.Session, arn string) (p *PCAProvisioner) {
func (p *PCAProvisioner) Sign(ctx context.Context, cr *cmapi.CertificateRequest) ([]byte, []byte, error) {
svc := acmpca.New(p.session, &aws.Config{})

block, _ := pem.Decode(cr.Spec.Request)
if block == nil {
return nil, nil, fmt.Errorf("failed to decode CSR")
}

csr, err := x509.ParseCertificateRequest(block.Bytes)
if err != nil {
return nil, nil, err
}

sigAlgorithm, err := signatureAlgorithm(csr)
if err != nil {
return nil, nil, err
}

validityDays := int64(30)
if cr.Spec.Duration != nil {
validityDays = int64(cr.Spec.Duration.Hours() / 24)
}

issueParams := acmpca.IssueCertificateInput{
CertificateAuthorityArn: aws.String(p.arn),
SigningAlgorithm: aws.String(acmpca.SigningAlgorithmSha256withrsa),
SigningAlgorithm: aws.String(sigAlgorithm),
Csr: cr.Spec.Request,
Validity: &acmpca.Validity{
Type: aws.String(acmpca.ValidityPeriodTypeDays),
Expand Down Expand Up @@ -114,3 +134,47 @@ func (p *PCAProvisioner) Sign(ctx context.Context, cr *cmapi.CertificateRequest)

return certPem, caPem, nil
}

func signatureAlgorithm(cr *x509.CertificateRequest) (string, error) {
switch cr.PublicKeyAlgorithm {
case x509.RSA:
pubKey, ok := cr.PublicKey.(*rsa.PublicKey)
if !ok {
return "", fmt.Errorf("failed to read public key")
}

switch {
case pubKey.N.BitLen() >= 4096:
return acmpca.SigningAlgorithmSha512withrsa, nil
case pubKey.N.BitLen() >= 3072:
return acmpca.SigningAlgorithmSha384withrsa, nil
case pubKey.N.BitLen() >= 2048:
return acmpca.SigningAlgorithmSha256withrsa, nil
case pubKey.N.BitLen() == 0:
return acmpca.SigningAlgorithmSha256withrsa, nil
default:
return "", fmt.Errorf("unsupported rsa keysize specified: %d", pubKey.N.BitLen())
}
case x509.ECDSA:
pubKey, ok := cr.PublicKey.(*ecdsa.PublicKey)
if !ok {
return "", fmt.Errorf("failed to read public key")
}

switch pubKey.Curve.Params().BitSize {
case 521:
return acmpca.SigningAlgorithmSha512withecdsa, nil
case 384:
return acmpca.SigningAlgorithmSha384withecdsa, nil
case 256:
return acmpca.SigningAlgorithmSha256withecdsa, nil
case 0:
return acmpca.SigningAlgorithmSha256withecdsa, nil
default:
return "", fmt.Errorf("unsupported ecdsa keysize specified: %d", pubKey.Curve.Params().BitSize)
}

default:
return "", fmt.Errorf("unsupported public key algorithm: %v", cr.PublicKeyAlgorithm)
}
}

0 comments on commit c780104

Please sign in to comment.