Backport of Fix transit import/export of hmac-only keys into release/1.14.x (#20902)
* backport of commit daf72aa42790144c3a0ca9c17bb19b1c5bce66c6 * Fix formatting Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> --------- Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> Co-authored-by: Alexander Scheel <alex.scheel@hashicorp.com>
This commit is contained in:
parent
6009fab706
commit
52835311b2
|
@ -39,6 +39,7 @@ func TestTransit_BackupRestore(t *testing.T) {
|
|||
testBackupRestore(t, "rsa-2048", "hmac-verify")
|
||||
testBackupRestore(t, "rsa-3072", "hmac-verify")
|
||||
testBackupRestore(t, "rsa-4096", "hmac-verify")
|
||||
testBackupRestore(t, "hmac", "hmac-verify")
|
||||
}
|
||||
|
||||
func testBackupRestore(t *testing.T, keyType, feature string) {
|
||||
|
@ -57,6 +58,9 @@ func testBackupRestore(t *testing.T, keyType, feature string) {
|
|||
"exportable": true,
|
||||
},
|
||||
}
|
||||
if keyType == "hmac" {
|
||||
keyReq.Data["key_size"] = 32
|
||||
}
|
||||
resp, err = b.HandleRequest(context.Background(), keyReq)
|
||||
if err != nil || (resp != nil && resp.IsError()) {
|
||||
t.Fatalf("resp: %#v\nerr: %v", resp, err)
|
||||
|
|
|
@ -28,7 +28,8 @@ func TestTransit_BYOKExportImport(t *testing.T) {
|
|||
testBYOKExportImport(t, "rsa-3072", "sign-verify")
|
||||
testBYOKExportImport(t, "rsa-4096", "sign-verify")
|
||||
|
||||
// Unlike backup, we don't support importing HMAC keys here.
|
||||
// Test HMAC sign/verify after a restore for supported keys.
|
||||
testBYOKExportImport(t, "hmac", "hmac-verify")
|
||||
}
|
||||
|
||||
func testBYOKExportImport(t *testing.T, keyType, feature string) {
|
||||
|
@ -47,6 +48,9 @@ func testBYOKExportImport(t *testing.T, keyType, feature string) {
|
|||
"exportable": true,
|
||||
},
|
||||
}
|
||||
if keyType == "hmac" {
|
||||
keyReq.Data["key_size"] = 32
|
||||
}
|
||||
resp, err = b.HandleRequest(context.Background(), keyReq)
|
||||
if err != nil || (resp != nil && resp.IsError()) {
|
||||
t.Fatalf("resp: %#v\nerr: %v", resp, err)
|
||||
|
|
|
@ -162,7 +162,11 @@ func getExportKey(policy *keysutil.Policy, key *keysutil.KeyEntry, exportType st
|
|||
|
||||
switch exportType {
|
||||
case exportTypeHMACKey:
|
||||
return strings.TrimSpace(base64.StdEncoding.EncodeToString(key.HMACKey)), nil
|
||||
src := key.HMACKey
|
||||
if policy.Type == keysutil.KeyType_HMAC {
|
||||
src = key.Key
|
||||
}
|
||||
return strings.TrimSpace(base64.StdEncoding.EncodeToString(src)), nil
|
||||
|
||||
case exportTypeEncryptionKey:
|
||||
switch policy.Type {
|
||||
|
|
|
@ -28,6 +28,7 @@ func TestTransit_Export_KeyVersion_ExportsCorrectVersion(t *testing.T) {
|
|||
verifyExportsCorrectVersion(t, "hmac-key", "ecdsa-p384")
|
||||
verifyExportsCorrectVersion(t, "hmac-key", "ecdsa-p521")
|
||||
verifyExportsCorrectVersion(t, "hmac-key", "ed25519")
|
||||
verifyExportsCorrectVersion(t, "hmac-key", "hmac")
|
||||
}
|
||||
|
||||
func verifyExportsCorrectVersion(t *testing.T, exportType, keyType string) {
|
||||
|
@ -43,6 +44,9 @@ func verifyExportsCorrectVersion(t *testing.T, exportType, keyType string) {
|
|||
"exportable": true,
|
||||
"type": keyType,
|
||||
}
|
||||
if keyType == "hmac" {
|
||||
req.Data["key_size"] = 32
|
||||
}
|
||||
_, err := b.HandleRequest(context.Background(), req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
```release-note:bug
|
||||
secrets/transit: Fix export of HMAC-only key, correctly exporting the key used for sign operations. For consumers of the previously incorrect key, use the plaintext export to retrieve these incorrect keys and import them as new versions.
|
||||
secrets/transit: Fix bug related to shorter dedicated HMAC key sizing.
|
||||
sdk/helper/keysutil: New HMAC type policies will have HMACKey equal to Key and be copied over on import.
|
||||
```
|
|
@ -767,6 +767,10 @@ func (p *Policy) Upgrade(ctx context.Context, storage logical.Storage, randReade
|
|||
entry.HMACKey = hmacKey
|
||||
p.Keys[strconv.Itoa(p.LatestVersion)] = entry
|
||||
persistNeeded = true
|
||||
|
||||
if p.Type == KeyType_HMAC {
|
||||
entry.HMACKey = entry.Key
|
||||
}
|
||||
}
|
||||
|
||||
if persistNeeded {
|
||||
|
@ -1497,6 +1501,7 @@ func (p *Policy) ImportPublicOrPrivate(ctx context.Context, storage logical.Stor
|
|||
entry.Key = key
|
||||
if p.Type == KeyType_HMAC {
|
||||
p.KeySize = len(key)
|
||||
entry.HMACKey = key
|
||||
}
|
||||
} else {
|
||||
var parsedKey any
|
||||
|
@ -1613,7 +1618,7 @@ func (p *Policy) RotateInMemory(randReader io.Reader) (retErr error) {
|
|||
if p.Type == KeyType_AES128_GCM96 {
|
||||
numBytes = 16
|
||||
} else if p.Type == KeyType_HMAC {
|
||||
numBytes := p.KeySize
|
||||
numBytes = p.KeySize
|
||||
if numBytes < HmacMinKeySize || numBytes > HmacMaxKeySize {
|
||||
return fmt.Errorf("invalid key size for HMAC key, must be between %d and %d bytes", HmacMinKeySize, HmacMaxKeySize)
|
||||
}
|
||||
|
@ -1624,6 +1629,11 @@ func (p *Policy) RotateInMemory(randReader io.Reader) (retErr error) {
|
|||
}
|
||||
entry.Key = newKey
|
||||
|
||||
if p.Type == KeyType_HMAC {
|
||||
// To avoid causing problems, ensure HMACKey = Key.
|
||||
entry.HMACKey = newKey
|
||||
}
|
||||
|
||||
case KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521:
|
||||
var curve elliptic.Curve
|
||||
switch p.Type {
|
||||
|
|
Loading…
Reference in New Issue