Update transit public keys for Ed25519 support (#20727)
* Refine documentation for public_key Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Support additional key types in importing version This originally left off the custom support for Ed25519 and RSA-PSS formatted keys that we've added manually. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add support for Ed25519 keys Here, we prevent importing public-key only keys with derived Ed25519 keys. Notably, we still allow import of derived Ed25519 keys via private key method, though this is a touch weird: this private key must have been packaged in an Ed25519 format (and parseable through Go as such), even though it is (strictly) an HKDF key and isn't ever used for Ed25519. Outside of this, importing non-derived Ed25519 keys works as expected. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add public-key only export method to Transit This allows the existing endpoints to retain private-key only, including empty strings for versions which lack private keys. On the public-key endpoint, all versions will have key material returned. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Update tests for exporting via public-key interface Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add public-key export option to docs Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> --------- Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
This commit is contained in:
parent
8698650394
commit
04bb7eef15
|
@ -6,6 +6,7 @@ package transit
|
|||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/ed25519"
|
||||
cryptoRand "crypto/rand"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
|
@ -2018,6 +2019,7 @@ func TestTransitPKICSR(t *testing.T) {
|
|||
func TestTransit_ReadPublicKeyImported(t *testing.T) {
|
||||
testTransit_ReadPublicKeyImported(t, "rsa-2048")
|
||||
testTransit_ReadPublicKeyImported(t, "ecdsa-p256")
|
||||
testTransit_ReadPublicKeyImported(t, "ed25519")
|
||||
}
|
||||
|
||||
func testTransit_ReadPublicKeyImported(t *testing.T, keyType string) {
|
||||
|
@ -2066,6 +2068,7 @@ func testTransit_ReadPublicKeyImported(t *testing.T, keyType string) {
|
|||
func TestTransit_SignWithImportedPublicKey(t *testing.T) {
|
||||
testTransit_SignWithImportedPublicKey(t, "rsa-2048")
|
||||
testTransit_SignWithImportedPublicKey(t, "ecdsa-p256")
|
||||
testTransit_SignWithImportedPublicKey(t, "ed25519")
|
||||
}
|
||||
|
||||
func testTransit_SignWithImportedPublicKey(t *testing.T, keyType string) {
|
||||
|
@ -2210,6 +2213,7 @@ func TestTransit_VerifyWithImportedPublicKey(t *testing.T) {
|
|||
func TestTransit_ExportPublicKeyImported(t *testing.T) {
|
||||
testTransit_ExportPublicKeyImported(t, "rsa-2048")
|
||||
testTransit_ExportPublicKeyImported(t, "ecdsa-p256")
|
||||
testTransit_ExportPublicKeyImported(t, "ed25519")
|
||||
}
|
||||
|
||||
func testTransit_ExportPublicKeyImported(t *testing.T, keyType string) {
|
||||
|
@ -2227,6 +2231,8 @@ func testTransit_ExportPublicKeyImported(t *testing.T, keyType string) {
|
|||
t.Fatalf("failed to extract the public key: %s", err)
|
||||
}
|
||||
|
||||
t.Logf("generated key: %v", string(publicKeyBytes))
|
||||
|
||||
// Import key
|
||||
importReq := &logical.Request{
|
||||
Storage: s,
|
||||
|
@ -2243,10 +2249,12 @@ func testTransit_ExportPublicKeyImported(t *testing.T, keyType string) {
|
|||
t.Fatalf("failed to import public key. err: %s\nresp: %#v", err, importResp)
|
||||
}
|
||||
|
||||
t.Logf("importing key: %v", importResp)
|
||||
|
||||
// Export key
|
||||
exportReq := &logical.Request{
|
||||
Operation: logical.ReadOperation,
|
||||
Path: fmt.Sprintf("export/signing-key/%s/latest", keyID),
|
||||
Path: fmt.Sprintf("export/public-key/%s/latest", keyID),
|
||||
Storage: s,
|
||||
}
|
||||
|
||||
|
@ -2255,16 +2263,36 @@ func testTransit_ExportPublicKeyImported(t *testing.T, keyType string) {
|
|||
t.Fatalf("failed to export key. err: %v\nresp: %#v", err, exportResp)
|
||||
}
|
||||
|
||||
t.Logf("exporting key: %v", exportResp)
|
||||
|
||||
responseKeys, exist := exportResp.Data["keys"]
|
||||
if !exist {
|
||||
t.Fatal("expected response data to hold a 'keys' field")
|
||||
}
|
||||
|
||||
exportedKeyBytes := responseKeys.(map[string]string)["1"]
|
||||
|
||||
if keyType != "ed25519" {
|
||||
exportedKeyBlock, _ := pem.Decode([]byte(exportedKeyBytes))
|
||||
publicKeyBlock, _ := pem.Decode(publicKeyBytes)
|
||||
|
||||
if !reflect.DeepEqual(publicKeyBlock.Bytes, exportedKeyBlock.Bytes) {
|
||||
t.Fatal("exported key bytes should have matched with imported key")
|
||||
t.Fatalf("exported key bytes should have matched with imported key for key type: %v\nexported: %v\nimported: %v", keyType, exportedKeyBlock.Bytes, publicKeyBlock.Bytes)
|
||||
}
|
||||
} else {
|
||||
exportedKey, err := base64.StdEncoding.DecodeString(exportedKeyBytes)
|
||||
if err != nil {
|
||||
t.Fatalf("error decoding exported key bytes (%v) to base64 for key type %v: %v", exportedKeyBytes, keyType, err)
|
||||
}
|
||||
|
||||
publicKeyBlock, _ := pem.Decode(publicKeyBytes)
|
||||
publicKeyParsed, err := x509.ParsePKIXPublicKey(publicKeyBlock.Bytes)
|
||||
if err != nil {
|
||||
t.Fatalf("error decoding source key bytes (%v) from PKIX marshaling for key type %v: %v", publicKeyBlock.Bytes, keyType, err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual([]byte(publicKeyParsed.(ed25519.PublicKey)), exportedKey) {
|
||||
t.Fatalf("exported key bytes should have matched with imported key for key type: %v\nexported: %v\nimported: %v", keyType, exportedKey, publicKeyParsed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ const (
|
|||
exportTypeEncryptionKey = "encryption-key"
|
||||
exportTypeSigningKey = "signing-key"
|
||||
exportTypeHMACKey = "hmac-key"
|
||||
exportTypePublicKey = "public-key"
|
||||
)
|
||||
|
||||
func (b *backend) pathExportKeys() *framework.Path {
|
||||
|
@ -39,7 +40,7 @@ func (b *backend) pathExportKeys() *framework.Path {
|
|||
Fields: map[string]*framework.FieldSchema{
|
||||
"type": {
|
||||
Type: framework.TypeString,
|
||||
Description: "Type of key to export (encryption-key, signing-key, hmac-key)",
|
||||
Description: "Type of key to export (encryption-key, signing-key, hmac-key, public-key)",
|
||||
},
|
||||
"name": {
|
||||
Type: framework.TypeString,
|
||||
|
@ -69,6 +70,7 @@ func (b *backend) pathPolicyExportRead(ctx context.Context, req *logical.Request
|
|||
case exportTypeEncryptionKey:
|
||||
case exportTypeSigningKey:
|
||||
case exportTypeHMACKey:
|
||||
case exportTypePublicKey:
|
||||
default:
|
||||
return logical.ErrorResponse(fmt.Sprintf("invalid export type: %s", exportType)), logical.ErrInvalidRequest
|
||||
}
|
||||
|
@ -194,6 +196,10 @@ func getExportKey(policy *keysutil.Policy, key *keysutil.KeyEntry, exportType st
|
|||
return ecKey, nil
|
||||
|
||||
case keysutil.KeyType_ED25519:
|
||||
if len(key.Key) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return strings.TrimSpace(base64.StdEncoding.EncodeToString(key.Key)), nil
|
||||
|
||||
case keysutil.KeyType_RSA2048, keysutil.KeyType_RSA3072, keysutil.KeyType_RSA4096:
|
||||
|
@ -203,26 +209,70 @@ func getExportKey(policy *keysutil.Policy, key *keysutil.KeyEntry, exportType st
|
|||
}
|
||||
return rsaKey, nil
|
||||
}
|
||||
case exportTypePublicKey:
|
||||
switch policy.Type {
|
||||
case keysutil.KeyType_ECDSA_P256, keysutil.KeyType_ECDSA_P384, keysutil.KeyType_ECDSA_P521:
|
||||
var curve elliptic.Curve
|
||||
switch policy.Type {
|
||||
case keysutil.KeyType_ECDSA_P384:
|
||||
curve = elliptic.P384()
|
||||
case keysutil.KeyType_ECDSA_P521:
|
||||
curve = elliptic.P521()
|
||||
default:
|
||||
curve = elliptic.P256()
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("unknown key type %v", policy.Type)
|
||||
}
|
||||
|
||||
func encodeRSAPrivateKey(key *keysutil.KeyEntry) (string, error) {
|
||||
// When encoding PKCS1, the PEM header should be `RSA PRIVATE KEY`. When Go
|
||||
// has PKCS8 encoding support, we may want to change this.
|
||||
var blockType string
|
||||
var derBytes []byte
|
||||
var err error
|
||||
if !key.IsPrivateKeyMissing() {
|
||||
blockType = "RSA PRIVATE KEY"
|
||||
derBytes = x509.MarshalPKCS1PrivateKey(key.RSAKey)
|
||||
} else {
|
||||
blockType = "PUBLIC KEY"
|
||||
derBytes, err = x509.MarshalPKIXPublicKey(key.RSAPublicKey)
|
||||
ecKey, err := keyEntryToECPublicKey(key, curve)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return ecKey, nil
|
||||
|
||||
case keysutil.KeyType_ED25519:
|
||||
return strings.TrimSpace(key.FormattedPublicKey), nil
|
||||
|
||||
case keysutil.KeyType_RSA2048, keysutil.KeyType_RSA3072, keysutil.KeyType_RSA4096:
|
||||
rsaKey, err := encodeRSAPublicKey(key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return rsaKey, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("unknown key type %v for export type %v", policy.Type, exportType)
|
||||
}
|
||||
|
||||
func encodeRSAPrivateKey(key *keysutil.KeyEntry) (string, error) {
|
||||
if key == nil {
|
||||
return "", errors.New("nil KeyEntry provided")
|
||||
}
|
||||
|
||||
if key.IsPrivateKeyMissing() {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// When encoding PKCS1, the PEM header should be `RSA PRIVATE KEY`. When Go
|
||||
// has PKCS8 encoding support, we may want to change this.
|
||||
blockType := "RSA PRIVATE KEY"
|
||||
derBytes := x509.MarshalPKCS1PrivateKey(key.RSAKey)
|
||||
pemBlock := pem.Block{
|
||||
Type: blockType,
|
||||
Bytes: derBytes,
|
||||
}
|
||||
|
||||
pemBytes := pem.EncodeToMemory(&pemBlock)
|
||||
return string(pemBytes), nil
|
||||
}
|
||||
|
||||
func encodeRSAPublicKey(key *keysutil.KeyEntry) (string, error) {
|
||||
if key == nil {
|
||||
return "", errors.New("nil KeyEntry provided")
|
||||
}
|
||||
|
||||
blockType := "RSA PUBLIC KEY"
|
||||
derBytes, err := x509.MarshalPKIXPublicKey(key.RSAPublicKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
pemBlock := pem.Block{
|
||||
|
@ -239,38 +289,49 @@ func keyEntryToECPrivateKey(k *keysutil.KeyEntry, curve elliptic.Curve) (string,
|
|||
return "", errors.New("nil KeyEntry provided")
|
||||
}
|
||||
|
||||
if k.IsPrivateKeyMissing() {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
pubKey := ecdsa.PublicKey{
|
||||
Curve: curve,
|
||||
X: k.EC_X,
|
||||
Y: k.EC_Y,
|
||||
}
|
||||
|
||||
var blockType string
|
||||
var derBytes []byte
|
||||
var err error
|
||||
if !k.IsPrivateKeyMissing() {
|
||||
blockType = "EC PRIVATE KEY"
|
||||
blockType := "EC PRIVATE KEY"
|
||||
privKey := &ecdsa.PrivateKey{
|
||||
PublicKey: pubKey,
|
||||
D: k.EC_D,
|
||||
}
|
||||
derBytes, err = x509.MarshalECPrivateKey(privKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if derBytes == nil {
|
||||
return "", errors.New("no data returned when marshalling to private key")
|
||||
}
|
||||
} else {
|
||||
blockType = "PUBLIC KEY"
|
||||
derBytes, err = x509.MarshalPKIXPublicKey(&pubKey)
|
||||
derBytes, err := x509.MarshalECPrivateKey(privKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if derBytes == nil {
|
||||
return "", errors.New("no data returned when marshalling to public key")
|
||||
pemBlock := pem.Block{
|
||||
Type: blockType,
|
||||
Bytes: derBytes,
|
||||
}
|
||||
|
||||
return strings.TrimSpace(string(pem.EncodeToMemory(&pemBlock))), nil
|
||||
}
|
||||
|
||||
func keyEntryToECPublicKey(k *keysutil.KeyEntry, curve elliptic.Curve) (string, error) {
|
||||
if k == nil {
|
||||
return "", errors.New("nil KeyEntry provided")
|
||||
}
|
||||
|
||||
pubKey := ecdsa.PublicKey{
|
||||
Curve: curve,
|
||||
X: k.EC_X,
|
||||
Y: k.EC_Y,
|
||||
}
|
||||
|
||||
blockType := "PUBLIC KEY"
|
||||
derBytes, err := x509.MarshalPKIXPublicKey(&pubKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
pemBlock := pem.Block{
|
||||
|
|
|
@ -457,8 +457,8 @@ func TestTransit_Import(t *testing.T) {
|
|||
},
|
||||
}
|
||||
_, err = b.HandleRequest(context.Background(), req)
|
||||
if err == nil {
|
||||
t.Fatalf("invalid public_key import incorrectly succeeeded")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to import ed25519 key: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ func (kt KeyType) AssociatedDataSupported() bool {
|
|||
|
||||
func (kt KeyType) ImportPublicKeySupported() bool {
|
||||
switch kt {
|
||||
case KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096, KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521:
|
||||
case KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096, KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521, KeyType_ED25519:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
@ -1361,20 +1361,30 @@ func (p *Policy) VerifySignatureWithOptions(context, input []byte, sig string, o
|
|||
return ecdsa.Verify(key, input, ecdsaSig.R, ecdsaSig.S), nil
|
||||
|
||||
case KeyType_ED25519:
|
||||
var key ed25519.PrivateKey
|
||||
var pub ed25519.PublicKey
|
||||
|
||||
if p.Derived {
|
||||
// Derive the key that should be used
|
||||
var err error
|
||||
key, err = p.GetKey(context, ver, 32)
|
||||
key, err := p.GetKey(context, ver, 32)
|
||||
if err != nil {
|
||||
return false, errutil.InternalError{Err: fmt.Sprintf("error deriving key: %v", err)}
|
||||
}
|
||||
pub = ed25519.PrivateKey(key).Public().(ed25519.PublicKey)
|
||||
} else {
|
||||
key = ed25519.PrivateKey(p.Keys[strconv.Itoa(ver)].Key)
|
||||
keyEntry, err := p.safeGetKeyEntry(ver)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return ed25519.Verify(key.Public().(ed25519.PublicKey), input, sigBytes), nil
|
||||
raw, err := base64.StdEncoding.DecodeString(keyEntry.FormattedPublicKey)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
pub = ed25519.PublicKey(raw)
|
||||
}
|
||||
|
||||
return ed25519.Verify(pub, input, sigBytes), nil
|
||||
|
||||
case KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096:
|
||||
keyEntry, err := p.safeGetKeyEntry(ver)
|
||||
|
@ -1445,6 +1455,10 @@ func (p *Policy) ImportPublicOrPrivate(ctx context.Context, storage logical.Stor
|
|||
entry.HMACKey = hmacKey
|
||||
}
|
||||
|
||||
if p.Type == KeyType_ED25519 && p.Derived && !isPrivateKey {
|
||||
return fmt.Errorf("unable to import only public key for derived Ed25519 key: imported key should not be an Ed25519 key pair but is instead an HKDF key")
|
||||
}
|
||||
|
||||
if (p.Type == KeyType_AES128_GCM96 && len(key) != 16) ||
|
||||
((p.Type == KeyType_AES256_GCM96 || p.Type == KeyType_ChaCha20_Poly1305) && len(key) != 32) ||
|
||||
(p.Type == KeyType_HMAC && (len(key) < HmacMinKeySize || len(key) > HmacMaxKeySize)) {
|
||||
|
@ -1615,13 +1629,19 @@ func (p *Policy) RotateInMemory(randReader io.Reader) (retErr error) {
|
|||
entry.FormattedPublicKey = string(pemBytes)
|
||||
|
||||
case KeyType_ED25519:
|
||||
// Go uses a 64-byte private key for Ed25519 keys (private+public, each
|
||||
// 32-bytes long). When we do Key derivation, we still generate a 32-byte
|
||||
// random value (and compute the corresponding Ed25519 public key), but
|
||||
// use this entire 64-byte key as if it was an HKDF key. The corresponding
|
||||
// underlying public key is never returned (which is probably good, because
|
||||
// doing so would leak half of our HKDF key...), but means we cannot import
|
||||
// derived-enabled Ed25519 public key components.
|
||||
pub, pri, err := ed25519.GenerateKey(randReader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
entry.Key = pri
|
||||
entry.FormattedPublicKey = base64.StdEncoding.EncodeToString(pub)
|
||||
|
||||
case KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096:
|
||||
bitSize := 2048
|
||||
if p.Type == KeyType_RSA3072 {
|
||||
|
@ -2090,8 +2110,26 @@ func (p *Policy) ImportPrivateKeyForVersion(ctx context.Context, storage logical
|
|||
// Parse key
|
||||
parsedPrivateKey, err := x509.ParsePKCS8PrivateKey(key)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "unknown elliptic curve") {
|
||||
var edErr error
|
||||
parsedPrivateKey, edErr = ParsePKCS8Ed25519PrivateKey(key)
|
||||
if edErr != nil {
|
||||
return fmt.Errorf("error parsing asymmetric key:\n - assuming contents are an ed25519 private key: %s\n - original error: %v", edErr, err)
|
||||
}
|
||||
|
||||
// Parsing as Ed25519-in-PKCS8-ECPrivateKey succeeded!
|
||||
} else if strings.Contains(err.Error(), oidSignatureRSAPSS.String()) {
|
||||
var rsaErr error
|
||||
parsedPrivateKey, rsaErr = ParsePKCS8RSAPSSPrivateKey(key)
|
||||
if rsaErr != nil {
|
||||
return fmt.Errorf("error parsing asymmetric key:\n - assuming contents are an RSA/PSS private key: %v\n - original error: %w", rsaErr, err)
|
||||
}
|
||||
|
||||
// Parsing as RSA-PSS in PKCS8 succeeded!
|
||||
} else {
|
||||
return fmt.Errorf("error parsing asymmetric key: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
switch parsedPrivateKey.(type) {
|
||||
case *ecdsa.PrivateKey:
|
||||
|
@ -2177,15 +2215,20 @@ func (ke *KeyEntry) parseFromKey(PolKeyType KeyType, parsedKey any) error {
|
|||
return fmt.Errorf("error PEM-encoding public key")
|
||||
}
|
||||
ke.FormattedPublicKey = string(pemBytes)
|
||||
case ed25519.PrivateKey:
|
||||
case ed25519.PrivateKey, ed25519.PublicKey:
|
||||
if PolKeyType != KeyType_ED25519 {
|
||||
return fmt.Errorf("invalid key type: expected %s, got %T", PolKeyType, parsedKey)
|
||||
}
|
||||
privateKey := parsedKey.(ed25519.PrivateKey)
|
||||
|
||||
privateKey, ok := parsedKey.(ed25519.PrivateKey)
|
||||
if ok {
|
||||
ke.Key = privateKey
|
||||
publicKey := privateKey.Public().(ed25519.PublicKey)
|
||||
ke.FormattedPublicKey = base64.StdEncoding.EncodeToString(publicKey)
|
||||
} else {
|
||||
publicKey := parsedKey.(ed25519.PublicKey)
|
||||
ke.FormattedPublicKey = base64.StdEncoding.EncodeToString(publicKey)
|
||||
}
|
||||
case *rsa.PrivateKey, *rsa.PublicKey:
|
||||
if PolKeyType != KeyType_RSA2048 && PolKeyType != KeyType_RSA3072 && PolKeyType != KeyType_RSA4096 {
|
||||
return fmt.Errorf("invalid key type: expected %s, got %T", PolKeyType, parsedKey)
|
||||
|
|
|
@ -109,7 +109,17 @@ $ curl \
|
|||
|
||||
This endpoint imports existing key material into a new transit-managed encryption key.
|
||||
To import key material into an existing key, see the `import_version/` endpoint.
|
||||
// TODO: Has to be updated.
|
||||
|
||||
This supports one of two forms:
|
||||
|
||||
1. Private/Symmetric Key import, requiring the `ciphertext`, `hash_function`
|
||||
parameters be set (and automatically deriving the public key), or
|
||||
2. Public Key-only import, restricting the operations that can be done with
|
||||
this key, and requiring only the `public_key` parameter.
|
||||
|
||||
The remaining parameters (including `name`, `type`, `allow_rotation`,
|
||||
`derived`, `context`, `exportable`, `allow_plaintext_backup`, and
|
||||
`auto_rotate_period`) remain the same across both versions of this call.
|
||||
|
||||
| Method | Path |
|
||||
| :----- | :--------------------------- |
|
||||
|
@ -153,8 +163,10 @@ the hash function defaults to SHA256.
|
|||
- `rsa-3072` - RSA with bit size of 3072 (asymmetric)
|
||||
- `rsa-4096` - RSA with bit size of 4096 (asymmetric)
|
||||
|
||||
- `public_key` `(string: "", optional)` - A plaintext PEM public key to be imported.
|
||||
If `ciphertext` is set, this field is ignored.
|
||||
- `public_key` `(string: "", optional)` - A plaintext PEM public key to be
|
||||
imported. This limits the operations available under this key to verification
|
||||
and encryption, depending on the key type and algorithm, as no private key
|
||||
is available.
|
||||
|
||||
- `allow_rotation` `(bool: false)` - If set, the imported key can be rotated
|
||||
within Vault by using the `rotate` endpoint.
|
||||
|
@ -203,7 +215,12 @@ $ curl \
|
|||
## Import Key Version
|
||||
|
||||
This endpoint imports new key material into an existing imported key.
|
||||
// TODO: Has to be updated.
|
||||
|
||||
See description and note in [Import Key](#import-key) above about importing
|
||||
public and private keys.
|
||||
|
||||
Notably, using this method, a private key matching a public key can be
|
||||
imported at a later date.
|
||||
|
||||
| Method | Path |
|
||||
| :----- | :----------------------------------- |
|
||||
|
@ -225,15 +242,16 @@ provided AES key. The wrapped AES key should be the first 512 bytes of the
|
|||
ciphertext, and the encrypted key material should be the remaining bytes.
|
||||
See the BYOK section of the [Transit secrets engine documentation](/vault/docs/secrets/transit#bring-your-own-key-byok)
|
||||
for more information on constructing the ciphertext.
|
||||
// TODO: Update text
|
||||
|
||||
- `hash_function` `(string: "SHA256")` - The hash function used for the
|
||||
RSA-OAEP step of creating the ciphertext. Supported hash functions are:
|
||||
`SHA1`, `SHA224`, `SHA256`, `SHA384`, and `SHA512`. If not specified,
|
||||
the hash function defaults to SHA256.
|
||||
|
||||
- `public_key` `(string: "", optional)` - A plaintext PEM public key to be imported.
|
||||
If `ciphertext` is set, this field is ignored.
|
||||
- `public_key` `(string: "", optional)` - A plaintext PEM public key to be
|
||||
imported. This limits the operations available under this key to verification
|
||||
and encryption, depending on the key type and algorithm, as no private key
|
||||
is available.
|
||||
|
||||
- `bump_version` - By default, each operator will create a new key version.
|
||||
If set to "false", will try to update the latest version of the key,
|
||||
|
@ -513,6 +531,8 @@ be valid.
|
|||
- `encryption-key`
|
||||
- `signing-key`
|
||||
- `hmac-key`
|
||||
- `public-key`, to return the corresponding public keys of private key
|
||||
asymmetric keys (EC with NIST P-curves or Ed25519 and RSA).
|
||||
|
||||
- `name` `(string: <required>)` – Specifies the name of the key to read
|
||||
information about. This is specified as part of the URL.
|
||||
|
|
Loading…
Reference in New Issue