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:
hc-github-team-secure-vault-core 2023-05-31 14:42:44 -04:00 committed by GitHub
parent 6009fab706
commit 52835311b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 34 additions and 3 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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 {

View File

@ -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)

5
changelog/20864.txt Normal file
View File

@ -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.
```

View File

@ -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 {