Fix handling of default zero SignatureBits value with Any key type in PKI Secrets Engine (#14875)
* Correctly handle minimums, default SignatureBits When using KeyType = "any" on a role (whether explicitly or implicitly via a sign-verbatim like operation), we need to update the value of SignatureBits from its new value 0 to a per-key-type default value. This will allow sign operations on these paths to function correctly, having the correctly inferred default signature bit length. Additionally, this allows the computed default value for key type to be used for minimum size validation in the RSA/ECDSA paths. We additionally enforce the 2048-minimum in this case as well. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Fix defaults and validation of "any" KeyType When certutil is given the placeholder any keytype, it attempts to validate and update the default zero value. However, in lacking a default value for SignatureBits, it cannot update the value from the zero value, thus causing validation to fail. Add more awareness to the placeholder "any" value to certutil. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add role-based regression tests for key bits This adds regression tests for Key Type, Key Bits, and Signature Bits parameters on the role. We test several values, including the "any" value to ensure it correctly restricts key sizes. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add sign-verbatim test for key type This ensures that we test sign-verbatim against a variety of key types. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add changelog entry Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> Co-authored-by: Steven Clark <steven.clark@hashicorp.com>
This commit is contained in:
parent
1b62e17f89
commit
8904f2a55a
|
@ -702,6 +702,46 @@ func generateURLSteps(t *testing.T, caCert, caKey string, intdata, reqdata map[s
|
|||
return ret
|
||||
}
|
||||
|
||||
func generateCSR(t *testing.T, csrTemplate *x509.CertificateRequest, keyType string, keyBits int) (interface{}, []byte, string) {
|
||||
var priv interface{}
|
||||
var err error
|
||||
switch keyType {
|
||||
case "rsa":
|
||||
priv, err = rsa.GenerateKey(rand.Reader, keyBits)
|
||||
case "ec":
|
||||
switch keyBits {
|
||||
case 224:
|
||||
priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
|
||||
case 256:
|
||||
priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
case 384:
|
||||
priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
|
||||
case 521:
|
||||
priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
|
||||
default:
|
||||
t.Fatalf("Got unknown ec< key bits: %v", keyBits)
|
||||
}
|
||||
case "ed25519":
|
||||
_, priv, err = ed25519.GenerateKey(rand.Reader)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Got error generating private key for CSR: %v", err)
|
||||
}
|
||||
|
||||
csr, err := x509.CreateCertificateRequest(rand.Reader, csrTemplate, priv)
|
||||
if err != nil {
|
||||
t.Fatalf("Got error generating CSR: %v", err)
|
||||
}
|
||||
|
||||
csrPem := strings.TrimSpace(string(pem.EncodeToMemory(&pem.Block{
|
||||
Type: "CERTIFICATE REQUEST",
|
||||
Bytes: csr,
|
||||
})))
|
||||
|
||||
return priv, csr, csrPem
|
||||
}
|
||||
|
||||
func generateCSRSteps(t *testing.T, caCert, caKey string, intdata, reqdata map[string]interface{}) []logicaltest.TestStep {
|
||||
csrTemplate := x509.CertificateRequest{
|
||||
Subject: pkix.Name{
|
||||
|
@ -726,12 +766,7 @@ func generateCSRSteps(t *testing.T, caCert, caKey string, intdata, reqdata map[s
|
|||
},
|
||||
}
|
||||
|
||||
priv, _ := rsa.GenerateKey(rand.Reader, 2048)
|
||||
csr, _ := x509.CreateCertificateRequest(rand.Reader, &csrTemplate, priv)
|
||||
csrPem := strings.TrimSpace(string(pem.EncodeToMemory(&pem.Block{
|
||||
Type: "CERTIFICATE REQUEST",
|
||||
Bytes: csr,
|
||||
})))
|
||||
_, _, csrPem := generateCSR(t, &csrTemplate, "rsa", 2048)
|
||||
|
||||
ret := []logicaltest.TestStep{
|
||||
{
|
||||
|
@ -1260,7 +1295,7 @@ func generateRoleSteps(t *testing.T, useCSRs bool) []logicaltest.TestStep {
|
|||
for name, allowedInt := range cnMap {
|
||||
roleVals.KeyType = "rsa"
|
||||
roleVals.KeyBits = 2048
|
||||
if mathRand.Int()%2 == 1 {
|
||||
if mathRand.Int()%3 == 1 {
|
||||
roleVals.KeyType = "ec"
|
||||
roleVals.KeyBits = 224
|
||||
}
|
||||
|
@ -1918,6 +1953,23 @@ func TestBackend_PathFetchCertList(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBackend_SignVerbatim(t *testing.T) {
|
||||
testCases := []struct {
|
||||
testName string
|
||||
keyType string
|
||||
}{
|
||||
{testName: "RSA", keyType: "rsa"},
|
||||
{testName: "ED25519", keyType: "ed25519"},
|
||||
{testName: "EC", keyType: "ec"},
|
||||
{testName: "Any", keyType: "any"},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.testName, func(t *testing.T) {
|
||||
runTestSignVerbatim(t, tc.keyType)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func runTestSignVerbatim(t *testing.T, keyType string) {
|
||||
// create the backend
|
||||
config := logical.TestBackendConfig()
|
||||
storage := &logical.InmemStorage{}
|
||||
|
@ -1995,8 +2047,9 @@ func TestBackend_SignVerbatim(t *testing.T) {
|
|||
|
||||
// create a role entry; we use this to check that sign-verbatim when used with a role is still honoring TTLs
|
||||
roleData := map[string]interface{}{
|
||||
"ttl": "4h",
|
||||
"max_ttl": "8h",
|
||||
"ttl": "4h",
|
||||
"max_ttl": "8h",
|
||||
"key_type": keyType,
|
||||
}
|
||||
resp, err = b.HandleRequest(context.Background(), &logical.Request{
|
||||
Operation: logical.UpdateOperation,
|
||||
|
@ -2109,6 +2162,7 @@ func TestBackend_SignVerbatim(t *testing.T) {
|
|||
"ttl": "4h",
|
||||
"max_ttl": "8h",
|
||||
"generate_lease": true,
|
||||
"key_type": keyType,
|
||||
}
|
||||
resp, err = b.HandleRequest(context.Background(), &logical.Request{
|
||||
Operation: logical.UpdateOperation,
|
||||
|
@ -4216,6 +4270,145 @@ func TestBackend_Roles_IssuanceRegression(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// We need a RSA key so all signature sizes are valid with it.
|
||||
resp, err := client.Logical().WriteWithContext(context.Background(), "pki/root/generate/exported", map[string]interface{}{
|
||||
"common_name": "myvault.com",
|
||||
"ttl": "128h",
|
||||
"key_type": "rsa",
|
||||
"key_bits": 2048,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if resp == nil {
|
||||
t.Fatal("expected ca info")
|
||||
}
|
||||
|
||||
tested := 0
|
||||
for index, test := range testCases {
|
||||
tested += RoleIssuanceRegressionHelper(t, client, index, test)
|
||||
}
|
||||
|
||||
t.Log(fmt.Sprintf("Issuance regression expanded matrix test scenarios: %d", tested))
|
||||
}
|
||||
|
||||
type KeySizeRegression struct {
|
||||
RoleKeyType string
|
||||
RoleKeyBits []int
|
||||
RoleSignatureBits []int
|
||||
|
||||
// These are tuples; must be of the same length.
|
||||
TestKeyTypes []string
|
||||
TestKeyBits []int
|
||||
|
||||
// All of the above key types/sizes must pass or fail together.
|
||||
ExpectError bool
|
||||
}
|
||||
|
||||
func RoleKeySizeRegressionHelper(t *testing.T, client *api.Client, index int, test KeySizeRegression) int {
|
||||
tested := 0
|
||||
|
||||
for _, roleKeyBits := range test.RoleKeyBits {
|
||||
for _, roleSignatureBits := range test.RoleSignatureBits {
|
||||
role := fmt.Sprintf("key-size-regression-%d-keytype-%v-keybits-%d-signature-bits-%d", index, test.RoleKeyType, roleKeyBits, roleSignatureBits)
|
||||
resp, err := client.Logical().WriteWithContext(context.Background(), "pki/roles/"+role, map[string]interface{}{
|
||||
"key_type": test.RoleKeyType,
|
||||
"key_bits": roleKeyBits,
|
||||
"signature_bits": roleSignatureBits,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for index, keyType := range test.TestKeyTypes {
|
||||
keyBits := test.TestKeyBits[index]
|
||||
|
||||
_, _, csrPem := generateCSR(t, &x509.CertificateRequest{
|
||||
Subject: pkix.Name{
|
||||
CommonName: "localhost",
|
||||
},
|
||||
}, keyType, keyBits)
|
||||
|
||||
resp, err = client.Logical().WriteWithContext(context.Background(), "pki/sign/"+role, map[string]interface{}{
|
||||
"common_name": "localhost",
|
||||
"csr": csrPem,
|
||||
})
|
||||
|
||||
haveErr := err != nil || resp == nil
|
||||
|
||||
if haveErr != test.ExpectError {
|
||||
t.Fatalf("key size regression test [%d] failed: haveErr: %v, expectErr: %v, err: %v, resp: %v, test case: %v, role: %v, keyType: %v, keyBits: %v", index, haveErr, test.ExpectError, err, resp, test, role, keyType, keyBits)
|
||||
}
|
||||
|
||||
tested += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tested
|
||||
}
|
||||
|
||||
func TestBackend_Roles_KeySizeRegression(t *testing.T) {
|
||||
// Regression testing of role's issuance policy.
|
||||
testCases := []KeySizeRegression{
|
||||
// RSA with default parameters should fail to issue smaller RSA keys
|
||||
// and any size ECDSA/Ed25519 keys.
|
||||
/* 0 */ {"rsa", []int{0, 2048}, []int{0, 256, 384, 512}, []string{"rsa", "rsa", "ec", "ec", "ec", "ec", "ed25519"}, []int{512, 1024, 224, 256, 384, 521, 0}, true},
|
||||
// But it should work to issue larger RSA keys.
|
||||
/* 1 */ {"rsa", []int{0, 2048}, []int{0, 256, 384, 512}, []string{"rsa", "rsa", "rsa"}, []int{2048, 3072, 4906}, false},
|
||||
|
||||
// EC with default parameters should fail to issue smaller EC keys
|
||||
// and any size RSA/Ed25519 keys.
|
||||
/* 2 */ {"ec", []int{0}, []int{0}, []string{"rsa", "rsa", "rsa", "ec", "ed25519"}, []int{1024, 2048, 4096, 224, 0}, true},
|
||||
// But it should work to issue larger EC keys.
|
||||
/* 3 */ {"ec", []int{0, 256}, []int{0, 256}, []string{"ec"}, []int{256}, false},
|
||||
/* 4 */ {"ec", []int{384}, []int{0, 384}, []string{"ec"}, []int{384}, false},
|
||||
/* 5 */ {"ec", []int{521}, []int{0, 512}, []string{"ec"}, []int{521}, false},
|
||||
|
||||
// Ed25519 should reject RSA and EC keys.
|
||||
/* 6 */ {"ed25519", []int{0}, []int{0}, []string{"rsa", "rsa", "rsa", "ec", "ec"}, []int{1024, 2048, 4096, 256, 521}, true},
|
||||
// But it should work to issue Ed25519 keys.
|
||||
/* 7 */ {"ed25519", []int{0}, []int{0}, []string{"ed25519"}, []int{0}, false},
|
||||
|
||||
// Any key type should reject insecure RSA key sizes.
|
||||
/* 8 */ {"any", []int{0}, []int{0, 256, 384, 512}, []string{"rsa", "rsa"}, []int{512, 1024}, true},
|
||||
// But work for everything else.
|
||||
/* 9 */ {"any", []int{0}, []int{0, 256, 384, 512}, []string{"rsa", "rsa", "rsa", "ec", "ec", "ec", "ec", "ed25519"}, []int{2048, 3072, 4906, 224, 256, 384, 521, 0}, false},
|
||||
|
||||
// RSA with larger than default key size should reject smaller ones.
|
||||
/* 10 */ {"rsa", []int{3072}, []int{0, 256, 384, 512}, []string{"rsa", "rsa", "rsa"}, []int{512, 1024, 2048}, true},
|
||||
}
|
||||
|
||||
if len(testCases) != 11 {
|
||||
t.Fatalf("misnumbered test case entries will make it hard to find bugs: %v", len(testCases))
|
||||
}
|
||||
|
||||
coreConfig := &vault.CoreConfig{
|
||||
LogicalBackends: map[string]logical.Factory{
|
||||
"pki": Factory,
|
||||
},
|
||||
}
|
||||
cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{
|
||||
HandlerFunc: vaulthttp.Handler,
|
||||
})
|
||||
cluster.Start()
|
||||
defer cluster.Cleanup()
|
||||
|
||||
client := cluster.Cores[0].Client
|
||||
var err error
|
||||
|
||||
// Generate a root CA at /pki to use for our tests
|
||||
err = client.Sys().MountWithContext(context.Background(), "pki", &api.MountInput{
|
||||
Type: "pki",
|
||||
Config: api.MountConfigInput{
|
||||
DefaultLeaseTTL: "12h",
|
||||
MaxLeaseTTL: "128h",
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
resp, err := client.Logical().WriteWithContext(context.Background(), "pki/root/generate/exported", map[string]interface{}{
|
||||
"common_name": "myvault.com",
|
||||
"ttl": "128h",
|
||||
|
@ -4231,10 +4424,10 @@ func TestBackend_Roles_IssuanceRegression(t *testing.T) {
|
|||
|
||||
tested := 0
|
||||
for index, test := range testCases {
|
||||
tested += RoleIssuanceRegressionHelper(t, client, index, test)
|
||||
tested += RoleKeySizeRegressionHelper(t, client, index, test)
|
||||
}
|
||||
|
||||
t.Log(fmt.Sprintf("Issuance regression expanded matrix test scenarios: %d", tested))
|
||||
t.Log(fmt.Sprintf("Key size regression expanded matrix test scenarios: %d", tested))
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
|
@ -673,6 +673,11 @@ func signCert(b *backend,
|
|||
return nil, errutil.UserError{Err: fmt.Sprintf("certificate request could not be parsed: %v", err)}
|
||||
}
|
||||
|
||||
// This switch validates that the CSR key type matches the role and sets
|
||||
// the value in the actualKeyType/actualKeyBits values.
|
||||
actualKeyType := ""
|
||||
actualKeyBits := 0
|
||||
|
||||
switch data.role.KeyType {
|
||||
case "rsa":
|
||||
// Verify that the key matches the role type
|
||||
|
@ -681,24 +686,14 @@ func signCert(b *backend,
|
|||
"role requires keys of type %s",
|
||||
data.role.KeyType)}
|
||||
}
|
||||
|
||||
pubKey, ok := csr.PublicKey.(*rsa.PublicKey)
|
||||
if !ok {
|
||||
return nil, errutil.UserError{Err: "could not parse CSR's public key"}
|
||||
}
|
||||
|
||||
// Verify that the key is at least 2048 bits
|
||||
if pubKey.N.BitLen() < 2048 {
|
||||
return nil, errutil.UserError{Err: "RSA keys < 2048 bits are unsafe and not supported"}
|
||||
}
|
||||
|
||||
// Verify that the bit size is at least the size specified in the role
|
||||
if pubKey.N.BitLen() < data.role.KeyBits {
|
||||
return nil, errutil.UserError{Err: fmt.Sprintf(
|
||||
"role requires a minimum of a %d-bit key, but CSR's key is %d bits",
|
||||
data.role.KeyBits,
|
||||
pubKey.N.BitLen())}
|
||||
}
|
||||
|
||||
actualKeyType = "rsa"
|
||||
actualKeyBits = pubKey.N.BitLen()
|
||||
case "ec":
|
||||
// Verify that the key matches the role type
|
||||
if csr.PublicKeyAlgorithm != x509.ECDSA {
|
||||
|
@ -711,14 +706,8 @@ func signCert(b *backend,
|
|||
return nil, errutil.UserError{Err: "could not parse CSR's public key"}
|
||||
}
|
||||
|
||||
// Verify that the bit size is at least the size specified in the role
|
||||
if pubKey.Params().BitSize < data.role.KeyBits {
|
||||
return nil, errutil.UserError{Err: fmt.Sprintf(
|
||||
"role requires a minimum of a %d-bit key, but CSR's key is %d bits",
|
||||
data.role.KeyBits,
|
||||
pubKey.Params().BitSize)}
|
||||
}
|
||||
|
||||
actualKeyType = "ec"
|
||||
actualKeyBits = pubKey.Params().BitSize
|
||||
case "ed25519":
|
||||
// Verify that the key matches the role type
|
||||
if csr.PublicKeyAlgorithm != x509.Ed25519 {
|
||||
|
@ -726,31 +715,107 @@ func signCert(b *backend,
|
|||
"role requires keys of type %s",
|
||||
data.role.KeyType)}
|
||||
}
|
||||
|
||||
_, ok := csr.PublicKey.(ed25519.PublicKey)
|
||||
if !ok {
|
||||
return nil, errutil.UserError{Err: "could not parse CSR's public key"}
|
||||
}
|
||||
|
||||
actualKeyType = "ed25519"
|
||||
actualKeyBits = 0
|
||||
case "any":
|
||||
// We only care about running RSA < 2048 bit checks, so if not RSA
|
||||
// break out
|
||||
if csr.PublicKeyAlgorithm != x509.RSA {
|
||||
break
|
||||
}
|
||||
// We need to compute the actual key type and key bits, to correctly
|
||||
// validate minimums and SignatureBits below.
|
||||
switch csr.PublicKeyAlgorithm {
|
||||
case x509.RSA:
|
||||
pubKey, ok := csr.PublicKey.(*rsa.PublicKey)
|
||||
if !ok {
|
||||
return nil, errutil.UserError{Err: "could not parse CSR's public key"}
|
||||
}
|
||||
if pubKey.N.BitLen() < 2048 {
|
||||
return nil, errutil.UserError{Err: "RSA keys < 2048 bits are unsafe and not supported"}
|
||||
}
|
||||
|
||||
// Run RSA < 2048 bit checks
|
||||
pubKey, ok := csr.PublicKey.(*rsa.PublicKey)
|
||||
if !ok {
|
||||
return nil, errutil.UserError{Err: "could not parse CSR's public key"}
|
||||
}
|
||||
if pubKey.N.BitLen() < 2048 {
|
||||
return nil, errutil.UserError{Err: "RSA keys < 2048 bits are unsafe and not supported"}
|
||||
}
|
||||
actualKeyType = "rsa"
|
||||
actualKeyBits = pubKey.N.BitLen()
|
||||
case x509.ECDSA:
|
||||
pubKey, ok := csr.PublicKey.(*ecdsa.PublicKey)
|
||||
if !ok {
|
||||
return nil, errutil.UserError{Err: "could not parse CSR's public key"}
|
||||
}
|
||||
|
||||
actualKeyType = "ec"
|
||||
actualKeyBits = pubKey.Params().BitSize
|
||||
case x509.Ed25519:
|
||||
_, ok := csr.PublicKey.(ed25519.PublicKey)
|
||||
if !ok {
|
||||
return nil, errutil.UserError{Err: "could not parse CSR's public key"}
|
||||
}
|
||||
|
||||
actualKeyType = "ed25519"
|
||||
actualKeyBits = 0
|
||||
default:
|
||||
return nil, errutil.UserError{Err: "Unknown key type in CSR: " + csr.PublicKeyAlgorithm.String()}
|
||||
}
|
||||
default:
|
||||
return nil, errutil.InternalError{Err: fmt.Sprintf("unsupported key type value: %s", data.role.KeyType)}
|
||||
}
|
||||
|
||||
// Before validating key lengths, update our KeyBits/SignatureBits based
|
||||
// on the actual CSR key type.
|
||||
if data.role.KeyType == "any" {
|
||||
// We update the value of KeyBits and SignatureBits here (from the
|
||||
// role), using the specified key type. This allows us to convert
|
||||
// the default value (0) for SignatureBits and KeyBits to a
|
||||
// meaningful value. In the event KeyBits takes a zero value, we also
|
||||
// update that to a new value.
|
||||
//
|
||||
// This is mandatory because on some roles, with KeyType any, we'll
|
||||
// set a default SignatureBits to 0, but this will need to be updated
|
||||
// in order to behave correctly during signing.
|
||||
roleBitsWasZero := data.role.KeyBits == 0
|
||||
if data.role.KeyBits, data.role.SignatureBits, err = certutil.ValidateDefaultOrValueKeyTypeSignatureLength(actualKeyType, data.role.KeyBits, data.role.SignatureBits); err != nil {
|
||||
return nil, errutil.InternalError{Err: fmt.Sprintf("unknown internal error updating default values: %v", err)}
|
||||
}
|
||||
|
||||
// We're using the KeyBits field as a minimum value, and P-224 is safe
|
||||
// and a previously allowed value. However, the above call defaults
|
||||
// to P-256 as that's a saner default than P-224 (w.r.t. generation).
|
||||
// So, override our fake Role value if it was previously zero.
|
||||
if actualKeyType == "ec" && roleBitsWasZero {
|
||||
data.role.KeyBits = 224
|
||||
}
|
||||
}
|
||||
|
||||
// At this point, data.role.KeyBits and data.role.SignatureBits should both
|
||||
// be non-zero, for RSA and ECDSA keys. Validate the actualKeyBits based on
|
||||
// the role's values. If the KeyType was any, and KeyBits was set to 0,
|
||||
// KeyBits should be updated to 2048 unless some other value was chosen
|
||||
// explicitly.
|
||||
//
|
||||
// This validation needs to occur regardless of the role's key type, so
|
||||
// that we always validate both RSA and ECDSA key sizes.
|
||||
if actualKeyType == "rsa" {
|
||||
if actualKeyBits < data.role.KeyBits {
|
||||
return nil, errutil.UserError{Err: fmt.Sprintf(
|
||||
"role requires a minimum of a %d-bit key, but CSR's key is %d bits",
|
||||
data.role.KeyBits, actualKeyBits)}
|
||||
}
|
||||
|
||||
if actualKeyBits < 2048 {
|
||||
return nil, errutil.UserError{Err: fmt.Sprintf(
|
||||
"Vault requires a minimum of a 2048-bit key, but CSR's key is %d bits",
|
||||
actualKeyBits)}
|
||||
}
|
||||
} else if actualKeyType == "ec" {
|
||||
if actualKeyBits < data.role.KeyBits {
|
||||
return nil, errutil.UserError{Err: fmt.Sprintf(
|
||||
"role requires a minimum of a %d-bit key, but CSR's key is %d bits",
|
||||
data.role.KeyBits,
|
||||
actualKeyBits)}
|
||||
}
|
||||
}
|
||||
|
||||
creation, err := generateCreationBundle(b, data, caSign, csr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
```release-note:bug
|
||||
secrets/pki: Fix handling of "any" key type with default zero signature bits value.
|
||||
```
|
|
@ -600,10 +600,11 @@ func DefaultOrValueHashBits(keyType string, keyBits int, hashBits int) (int, err
|
|||
// To match previous behavior (and ignoring NIST's recommendations for
|
||||
// hash size to align with RSA key sizes), default to SHA-2-256.
|
||||
hashBits = 256
|
||||
} else if keyType == "ed25519" || keyType == "ed448" {
|
||||
} else if keyType == "ed25519" || keyType == "ed448" || keyType == "any" {
|
||||
// No-op; ed25519 and ed448 internally specify their own hash and
|
||||
// we do not need to select one. Double hashing isn't supported in
|
||||
// certificate signing and we must
|
||||
// certificate signing. Additionally, the any key type can't know
|
||||
// what hash algorithm to use yet, so default to zero.
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
|
@ -642,7 +643,7 @@ func ValidateDefaultOrValueKeyTypeSignatureLength(keyType string, keyBits int, h
|
|||
// Validates that the length of the hash (in bits) used in the signature
|
||||
// calculation is a known, approved value.
|
||||
func ValidateSignatureLength(keyType string, hashBits int) error {
|
||||
if keyType == "ed25519" || keyType == "ed448" {
|
||||
if keyType == "any" || keyType == "ed25519" || keyType == "ed448" {
|
||||
// ed25519 and ed448 include built-in hashing and is not externally
|
||||
// configurable. There are three modes for each of these schemes:
|
||||
//
|
||||
|
@ -654,6 +655,9 @@ func ValidateSignatureLength(keyType string, hashBits int) error {
|
|||
//
|
||||
// In all cases, we won't have a hash algorithm to validate here, so
|
||||
// return nil.
|
||||
//
|
||||
// Additionally, when KeyType is any, we can't yet validate the
|
||||
// signature algorithm size, so it takes the default zero value.
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue