From 80e40fe2bc28f67d1daefd83888bf07bc01554f1 Mon Sep 17 00:00:00 2001 From: Dominik Roos Date: Thu, 4 Nov 2021 21:33:01 +0100 Subject: [PATCH] certutil: select appropriate hash algorithm for ECDSA signature (#11216) * certutil: select appropriate hash algorithm for ECDSA signature Select the appropriate signature algorithm for certificates signed with an ECDSA private key. The algorithm is selected based on the curve: - P-256 -> x509.ECDSAWithSHA256 - P-384 -> x509.ECDSAWithSHA384 - P-521 -> x509.ECDSAWithSHA512 - Other -> x509.ECDSAWithSHA256 fixes #11006 --- changelog/11216.txt | 3 +++ sdk/helper/certutil/helpers.go | 45 ++++++++++++++++++++++------------ 2 files changed, 32 insertions(+), 16 deletions(-) create mode 100644 changelog/11216.txt diff --git a/changelog/11216.txt b/changelog/11216.txt new file mode 100644 index 0000000000000..beef5c5d44dc1 --- /dev/null +++ b/changelog/11216.txt @@ -0,0 +1,3 @@ +```release-note:improvement +secrets/pki: select appropriate signature algorithm for ECDSA signature on certificates. +``` diff --git a/sdk/helper/certutil/helpers.go b/sdk/helper/certutil/helpers.go index e8edcfd2913f7..4ce36b6d6dc7d 100644 --- a/sdk/helper/certutil/helpers.go +++ b/sdk/helper/certutil/helpers.go @@ -655,14 +655,7 @@ func createCertificate(data *CreationBundle, randReader io.Reader) (*ParsedCertB case Ed25519PrivateKey: certTemplate.SignatureAlgorithm = x509.PureEd25519 case ECPrivateKey: - switch data.Params.SignatureBits { - case 256: - certTemplate.SignatureAlgorithm = x509.ECDSAWithSHA256 - case 384: - certTemplate.SignatureAlgorithm = x509.ECDSAWithSHA384 - case 512: - certTemplate.SignatureAlgorithm = x509.ECDSAWithSHA512 - } + certTemplate.SignatureAlgorithm = selectSignatureAlgorithmForECDSA(data.SigningBundle.PrivateKey.Public(), data.Params.SignatureBits) } caCert := data.SigningBundle.Certificate @@ -691,14 +684,7 @@ func createCertificate(data *CreationBundle, randReader io.Reader) (*ParsedCertB case "ed25519": certTemplate.SignatureAlgorithm = x509.PureEd25519 case "ec": - switch data.Params.SignatureBits { - case 256: - certTemplate.SignatureAlgorithm = x509.ECDSAWithSHA256 - case 384: - certTemplate.SignatureAlgorithm = x509.ECDSAWithSHA384 - case 512: - certTemplate.SignatureAlgorithm = x509.ECDSAWithSHA512 - } + certTemplate.SignatureAlgorithm = selectSignatureAlgorithmForECDSA(result.PrivateKey.Public(), data.Params.SignatureBits) } certTemplate.AuthorityKeyId = subjKeyID @@ -733,6 +719,33 @@ func createCertificate(data *CreationBundle, randReader io.Reader) (*ParsedCertB return result, nil } +func selectSignatureAlgorithmForECDSA(pub crypto.PublicKey, signatureBits int) x509.SignatureAlgorithm { + // If signature bits are configured, prefer them to the default choice. + switch signatureBits { + case 256: + return x509.ECDSAWithSHA256 + case 384: + return x509.ECDSAWithSHA384 + case 512: + return x509.ECDSAWithSHA512 + } + + key, ok := pub.(*ecdsa.PublicKey) + if !ok { + return x509.ECDSAWithSHA256 + } + switch key.Curve { + case elliptic.P224(), elliptic.P256(): + return x509.ECDSAWithSHA256 + case elliptic.P384(): + return x509.ECDSAWithSHA384 + case elliptic.P521(): + return x509.ECDSAWithSHA512 + default: + return x509.ECDSAWithSHA256 + } +} + var oidExtensionBasicConstraints = []int{2, 5, 29, 19} // CreateCSR creates a CSR with the default rand.Reader to