Transit: Allow ENT only arguments for sign/verify. Add docs for new Ed25519 signature types (#28821)

This commit is contained in:
Steven Clark
2024-11-01 12:57:52 -04:00
committed by GitHub
parent bad87541ed
commit e489631e87
5 changed files with 562 additions and 440 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,61 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
//go:build !enterprise
package transit
import (
"context"
"fmt"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/keysutil"
)
// addEntSignFieldArgs adds the enterprise only fields to the field schema definition
func addEntSignFieldArgs(_ map[string]*framework.FieldSchema) {
// Do nothing
}
// addEntVerifyFieldArgs adds the enterprise only fields to the field schema definition
func addEntVerifyFieldArgs(_ map[string]*framework.FieldSchema) {
// Do nothing
}
// validateSignApiArgsVersionSpecific will perform a validation of the Sign API parameters
// from the Enterprise or CE point of view.
func validateSignApiArgsVersionSpecific(p *keysutil.Policy, apiArgs commonSignVerifyApiArgs) error {
if err := _validateEntSpecificKeyType(p); err != nil {
return err
}
if apiArgs.hashAlgorithm == keysutil.HashTypeNone {
if !apiArgs.prehashed || apiArgs.sigAlgorithm != "pkcs1v15" {
return fmt.Errorf("hash_algorithm=none requires both prehashed=true and signature_algorithm=pkcs1v15")
}
}
return nil
}
// populateEntPolicySigning augments or tweaks the input parameters to the SDK policy.SignWithOptions for
// Enterprise usage.
func (b *backend) populateEntPolicySigningOptions(_ context.Context, _ *keysutil.Policy, _ signApiArgs, _ batchRequestSignItem, _ *policySignArgs) error {
return nil
}
// populateEntPolicyVerifyOptions augments or tweaks the input parameters to the SDK policy.VerifyWithOptions for
// Enterprise usage.
func (b *backend) populateEntPolicyVerifyOptions(ctx context.Context, p *keysutil.Policy, args verifyApiArgs, item batchRequestVerifyItem, vsa *policyVerifyArgs) error {
return nil
}
func _validateEntSpecificKeyType(p *keysutil.Policy) error {
switch p.Type {
case keysutil.KeyType_AES128_CMAC, keysutil.KeyType_AES256_CMAC, keysutil.KeyType_MANAGED_KEY:
return fmt.Errorf("enterprise specific key type %q can not be used on CE", p.Type)
default:
return nil
}
}

View File

@@ -10,6 +10,7 @@ import (
"crypto/aes"
"crypto/cipher"
"crypto/ecdsa"
stdlibEd25519 "crypto/ed25519"
"crypto/elliptic"
"crypto/hmac"
"crypto/rand"
@@ -133,6 +134,7 @@ type SigningOptions struct {
Marshaling MarshalingType
SaltLength int
SigAlgorithm string
SigContext string // Provide a context for Ed25519ctx signatures
ManagedKeyParams ManagedKeyParameters
}
@@ -1300,9 +1302,12 @@ func (p *Policy) SignWithOptions(ver int, context, input []byte, options *Signin
key = ed25519.PrivateKey(keyParams.Key)
}
opts := genEd25519Options(hashAlgorithm, options.SigContext)
// Per docs, do not pre-hash ed25519; it does two passes and performs
// its own hashing
sig, err = key.Sign(rand.Reader, input, crypto.Hash(0))
// its own hashing when we specify crypto.Hash(0). Ed25519Ph assumes
// pre-hashed with SHA512
sig, err = key.Sign(rand.Reader, input, opts)
if err != nil {
return nil, err
}
@@ -1498,7 +1503,13 @@ func (p *Policy) VerifySignatureWithOptions(context, input []byte, sig string, o
pub = ed25519.PublicKey(raw)
}
return ed25519.Verify(pub, input, sigBytes), nil
opts := genEd25519Options(hashAlgorithm, options.SigContext)
if err := stdlibEd25519.VerifyWithOptions(pub, input, sigBytes, opts); err != nil {
// We drop the error, just report back that we failed signature verification
return false, nil
}
return true, nil
case KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096:
keyEntry, err := p.safeGetKeyEntry(ver)
@@ -1550,6 +1561,20 @@ func (p *Policy) VerifySignatureWithOptions(context, input []byte, sig string, o
}
}
func genEd25519Options(hashAlgorithm HashType, sigContext string) *stdlibEd25519.Options {
opts := &stdlibEd25519.Options{
Hash: crypto.Hash(0),
}
if hashAlgorithm == HashTypeSHA2512 {
// activate ph mode, we assume input is prehashed
opts.Hash = crypto.SHA512
}
if len(sigContext) > 0 {
opts.Context = sigContext
}
return opts
}
func (p *Policy) Import(ctx context.Context, storage logical.Storage, key []byte, randReader io.Reader) error {
return p.ImportPublicOrPrivate(ctx, storage, key, true, randReader)
}

View File

@@ -1516,6 +1516,9 @@ supports signing.
Required if key derivation is enabled; currently only available with ed25519
keys.
- `signature_context` `(string: "")` <EnterpriseAlert inline="true" /> - Base64
encoded context for Ed25519ctx and Ed25519ph signatures.
- `prehashed` `(bool: false)` - Set to `true` when the input is already hashed.
If the key type is `rsa-2048`, `rsa-3072` or `rsa-4096`, then the algorithm used to hash
the input should be indicated by the `hash_algorithm` parameter. Just as the
@@ -1523,6 +1526,9 @@ supports signing.
data you want signed, when set, `input` is expected to be base64-encoded
binary hashed data, not hex-formatted. (As an example, on the command line,
you could generate a suitable input via `openssl dgst -sha256 -binary | base64`.)
On Enterprise <EnterpriseAlert inline="true" />, enabling this will activate
Ed25519ph signatures for Ed25519 keys along with hash_algorithm being either `none`
or `sha2-512`.
- `signature_algorithm` `(string: "pss")`  When using a RSA key, specifies the RSA
signature algorithm to use for signing. Supported signature types are:
@@ -1714,9 +1720,19 @@ or [generate CMAC](#generate-cmac) API calls.
Required if key derivation is enabled; currently only available with ed25519
keys.
- `prehashed` `(bool: false)` - Set to `true` when the input is already
hashed. If the key type is `rsa-2048`, `rsa-3072` or `rsa-4096`, then the algorithm used
to hash the input should be indicated by the `hash_algorithm` parameter.
- `signature_context` `(string: "")` <EnterpriseAlert inline="true" /> - Base64
encoded context for Ed25519ctx and Ed25519ph signatures.
- `prehashed` `(bool: false)` - Set to `true` when the input is already hashed.
If the key type is `rsa-2048`, `rsa-3072` or `rsa-4096`, then the algorithm used to hash
the input should be indicated by the `hash_algorithm` parameter. Just as the
value to sign should be the base64-encoded representation of the exact binary
data you want signed, when set, `input` is expected to be base64-encoded
binary hashed data, not hex-formatted. (As an example, on the command line,
you could generate a suitable input via `openssl dgst -sha256 -binary | base64`.)
On Enterprise <EnterpriseAlert inline="true" />, enabling this will activate
Ed25519ph signatures for Ed25519 keys along with hash_algorithm being either `none`
or `sha2-512`.
- `signature_algorithm` `(string: "pss")`  When using a RSA key, specifies the RSA
signature algorithm to use for signature verification. Supported signature types

View File

@@ -88,7 +88,7 @@ types also generate separate HMAC keys):
- `hmac`: HMAC; supporting HMAC generation and verification.
- `managed_key`: Managed key; supports a variety of operations depending on the
backing key management solution. See [Managed Keys](/vault/docs/enterprise/managed-keys)
for more information.
for more information. <EnterpriseAlert inline="true" />
- `aes128-cmac`: CMAC with a 128-bit AES key; supporting CMAC generation and verification. <EnterpriseAlert inline="true" />
- `aes256-cmac`: CMAC with a 256-bit AES key; supporting CMAC generation and verification. <EnterpriseAlert inline="true" />
@@ -262,7 +262,7 @@ have Transit generate and manage a key within Vault.
### Via the Command Line
The Vault command line tool [includes a helper](/vault/docs/commands/transit/) to perform the steps described
in Manual below.
in Manual below.
### Via the API