From 84978d88d8078db9583c3611a507e291501d1352 Mon Sep 17 00:00:00 2001 From: James Munnelly Date: Sat, 13 Oct 2018 18:07:12 +0100 Subject: [PATCH] Add extra comments to acme and pki package Signed-off-by: James Munnelly --- pkg/issuer/acme/setup.go | 12 ++++++++++++ pkg/util/pki/generate.go | 23 +++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/pkg/issuer/acme/setup.go b/pkg/issuer/acme/setup.go index 7014ff8f3..f2cd84559 100644 --- a/pkg/issuer/acme/setup.go +++ b/pkg/issuer/acme/setup.go @@ -52,6 +52,7 @@ const ( // Setup will verify an existing ACME registration, or create one if not // already registered. func (a *Acme) Setup(ctx context.Context) (issuer.SetupResponse, error) { + // check if user has specified a v1 account URL, and set a status condition if so. if newURL, ok := acmev1ToV2Mappings[a.issuer.GetSpec().ACME.Server]; ok { a.issuer.UpdateStatusCondition(v1alpha1.IssuerConditionReady, v1alpha1.ConditionFalse, "InvalidConfig", fmt.Sprintf("Your ACME server URL is set to a v1 endpoint (%s). "+ @@ -60,11 +61,17 @@ func (a *Acme) Setup(ctx context.Context) (issuer.SetupResponse, error) { return issuer.SetupResponse{Requeue: false}, nil } + // if the namespace field is not set, we are working on a ClusterIssuer resource + // therefore we should check for the ACME private key in the 'cluster resource namespace'. ns := a.issuer.GetObjectMeta().Namespace if ns == "" { ns = a.IssuerOptions.ClusterResourceNamespace } + // attempt to obtain the ACME client for this issuer using the 'acme helper'. + // This will will attempt to retrieve the ACME private key from the apiserver. + // If retrieving the private key fails, we catch this case and generate a + // new key. cl, err := a.helper.ClientForIssuer(a.issuer) if k8sErrors.IsNotFound(err) || errors.IsInvalidData(err) { glog.Infof("%s: generating acme account private key %q", a.issuer.GetObjectMeta().Name, a.issuer.GetSpec().ACME.PrivateKey.Name) @@ -111,6 +118,7 @@ func (a *Acme) registerAccount(ctx context.Context, cl client.Interface) (*acmea if err == nil { return acc, nil } + // return all errors except for 404 errors (which indicate the account // is not yet registered) acmeErr, ok := err.(*acmeapi.Error) @@ -122,6 +130,7 @@ func (a *Acme) registerAccount(ctx context.Context, cl client.Interface) (*acmea Contact: []string{fmt.Sprintf("mailto:%s", strings.ToLower(a.issuer.GetSpec().ACME.Email))}, TermsAgreed: true, } + acc, err = cl.CreateAccount(ctx, acc) if err != nil { return nil, err @@ -130,9 +139,12 @@ func (a *Acme) registerAccount(ctx context.Context, cl client.Interface) (*acmea // if acc.Status != acme.StatusValid { // return nil, fmt.Errorf("acme account is not valid") // } + return acc, nil } +// createAccountPrivateKey will generate a new RSA private key, and create it +// as a secret resource in the apiserver. func (a *Acme) createAccountPrivateKey(sel v1alpha1.SecretKeySelector, ns string) (*rsa.PrivateKey, error) { sel = acme.PrivateKeySelector(sel) accountPrivKey, err := pki.GenerateRSAPrivateKey(pki.MinRSAKeySize) diff --git a/pkg/util/pki/generate.go b/pkg/util/pki/generate.go index b831d2db6..d19a1f747 100644 --- a/pkg/util/pki/generate.go +++ b/pkg/util/pki/generate.go @@ -30,14 +30,26 @@ import ( ) const ( + // MinRSAKeySize is the minimum RSA keysize allowed to be generated by the + // generator functions in this package. MinRSAKeySize = 2048 + + // MaxRSAKeySize is the maximum RSA keysize allowed to be generated by the + // generator functions in this package. MaxRSAKeySize = 8192 + // ECCurve256 represents a 256bit ECDSA key. ECCurve256 = 256 + // ECCurve384 represents a 384bit ECDSA key. ECCurve384 = 384 + // ECCurve521 represents a 521bit ECDSA key. ECCurve521 = 521 ) +// GeneratePrivateKeyForCertificate will generate a private key suitable for +// the provided cert-manager Certificate resource, taking into account the +// parameters on the provided resource. +// The returned key will either be RSA or ECDSA. func GeneratePrivateKeyForCertificate(crt *v1alpha1.Certificate) (crypto.Signer, error) { switch crt.Spec.KeyAlgorithm { case v1alpha1.KeyAlgorithm(""), v1alpha1.RSAKeyAlgorithm: @@ -61,6 +73,8 @@ func GeneratePrivateKeyForCertificate(crt *v1alpha1.Certificate) (crypto.Signer, } } +// GenerateRSAPrivateKey will generate a RSA private key of the given size. +// It places restrictions on the minimum and maximum RSA keysize. func GenerateRSAPrivateKey(keySize int) (*rsa.PrivateKey, error) { // Do not allow keySize < 2048 // https://en.wikipedia.org/wiki/Key_size#cite_note-twirl-14 @@ -74,6 +88,8 @@ func GenerateRSAPrivateKey(keySize int) (*rsa.PrivateKey, error) { return rsa.GenerateKey(rand.Reader, keySize) } +// GenerateECPrivateKey will generate an ECDSA private key of the given size. +// It can be used to generate 256, 384 and 521 sized keys. func GenerateECPrivateKey(keySize int) (*ecdsa.PrivateKey, error) { var ecCurve elliptic.Curve @@ -91,6 +107,9 @@ func GenerateECPrivateKey(keySize int) (*ecdsa.PrivateKey, error) { return ecdsa.GenerateKey(ecCurve, rand.Reader) } +// EncodePrivateKey will encode a given crypto.PrivateKey by first inspecting +// the type of key provided. +// It only supports encoding RSA or ECDSA keys. func EncodePrivateKey(pk crypto.PrivateKey) ([]byte, error) { switch k := pk.(type) { case *rsa.PrivateKey: @@ -102,12 +121,14 @@ func EncodePrivateKey(pk crypto.PrivateKey) ([]byte, error) { } } +// EncodePKCS1PrivateKey will marshal a RSA private key into x509 PEM format. func EncodePKCS1PrivateKey(pk *rsa.PrivateKey) []byte { block := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(pk)} return pem.EncodeToMemory(block) } +// EncodeECPrivateKey will marshal an ECDSA private key into x509 PEM format. func EncodeECPrivateKey(pk *ecdsa.PrivateKey) ([]byte, error) { asnBytes, err := x509.MarshalECPrivateKey(pk) if err != nil { @@ -118,6 +139,8 @@ func EncodeECPrivateKey(pk *ecdsa.PrivateKey) ([]byte, error) { return pem.EncodeToMemory(block), nil } +// PublicKeyForPrivateKey will return the crypto.PublicKey for the given +// crypto.PrivateKey. It only supports RSA and ECDSA keys. func PublicKeyForPrivateKey(pk crypto.PrivateKey) (crypto.PublicKey, error) { switch k := pk.(type) { case *rsa.PrivateKey: