Skip to content

Commit

Permalink
RSA3072 implementation in transit secrets engine (hashicorp#8151)
Browse files Browse the repository at this point in the history
* RSA3072 implementation in transit secrets engine

* moved new KeyType at the end of the list
So already stored keys still work properly

Co-authored-by: Jim Kalafut <[email protected]>
  • Loading branch information
JulesRenz and kalafut authored Feb 15, 2020
1 parent 5350e67 commit f6547fa
Show file tree
Hide file tree
Showing 15 changed files with 67 additions and 33 deletions.
1 change: 1 addition & 0 deletions builtin/logical/transit/backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ func createBackendWithForceNoCacheWithSysViewWithStorage(t *testing.T, s logical

func TestTransit_RSA(t *testing.T) {
testTransit_RSA(t, "rsa-2048")
testTransit_RSA(t, "rsa-3072")
testTransit_RSA(t, "rsa-4096")
}

Expand Down
3 changes: 3 additions & 0 deletions builtin/logical/transit/path_backup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ func TestTransit_BackupRestore(t *testing.T) {
testBackupRestore(t, "aes256-gcm96", "encrypt-decrypt")
testBackupRestore(t, "chacha20-poly1305", "encrypt-decrypt")
testBackupRestore(t, "rsa-2048", "encrypt-decrypt")
testBackupRestore(t, "rsa-3072", "encrypt-decrypt")
testBackupRestore(t, "rsa-4096", "encrypt-decrypt")

// Test signing/verification after a restore for supported keys
Expand All @@ -21,6 +22,7 @@ func TestTransit_BackupRestore(t *testing.T) {
testBackupRestore(t, "ecdsa-p521", "sign-verify")
testBackupRestore(t, "ed25519", "sign-verify")
testBackupRestore(t, "rsa-2048", "sign-verify")
testBackupRestore(t, "rsa-3072", "sign-verify")
testBackupRestore(t, "rsa-4096", "sign-verify")

// Test HMAC/verification after a restore for all key types
Expand All @@ -32,6 +34,7 @@ func TestTransit_BackupRestore(t *testing.T) {
testBackupRestore(t, "ecdsa-p521", "hmac-verify")
testBackupRestore(t, "ed25519", "hmac-verify")
testBackupRestore(t, "rsa-2048", "hmac-verify")
testBackupRestore(t, "rsa-3072", "hmac-verify")
testBackupRestore(t, "rsa-4096", "hmac-verify")
}

Expand Down
4 changes: 2 additions & 2 deletions builtin/logical/transit/path_export.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ func getExportKey(policy *keysutil.Policy, key *keysutil.KeyEntry, exportType st
case keysutil.KeyType_AES128_GCM96, keysutil.KeyType_AES256_GCM96, keysutil.KeyType_ChaCha20_Poly1305:
return strings.TrimSpace(base64.StdEncoding.EncodeToString(key.Key)), nil

case keysutil.KeyType_RSA2048, keysutil.KeyType_RSA4096:
case keysutil.KeyType_RSA2048, keysutil.KeyType_RSA3072, keysutil.KeyType_RSA4096:
return encodeRSAPrivateKey(key.RSAKey), nil
}

Expand All @@ -183,7 +183,7 @@ func getExportKey(policy *keysutil.Policy, key *keysutil.KeyEntry, exportType st
case keysutil.KeyType_ED25519:
return strings.TrimSpace(base64.StdEncoding.EncodeToString(key.Key)), nil

case keysutil.KeyType_RSA2048, keysutil.KeyType_RSA4096:
case keysutil.KeyType_RSA2048, keysutil.KeyType_RSA3072, keysutil.KeyType_RSA4096:
return encodeRSAPrivateKey(key.RSAKey), nil
}
}
Expand Down
14 changes: 10 additions & 4 deletions builtin/logical/transit/path_keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ func (b *backend) pathKeys() *framework.Path {
Default: "aes256-gcm96",
Description: `
The type of key to create. Currently, "aes128-gcm96" (symmetric), "aes256-gcm96" (symmetric), "ecdsa-p256"
(asymmetric), "ecdsa-p384" (asymmetric), "ecdsa-p521" (asymmetric), "ed25519" (asymmetric), "rsa-2048" (asymmetric), "rsa-4096"
(asymmetric) are supported. Defaults to "aes256-gcm96".
(asymmetric), "ecdsa-p384" (asymmetric), "ecdsa-p521" (asymmetric), "ed25519" (asymmetric), "rsa-2048" (asymmetric), "rsa-3072"
(asymmetric), "rsa-4096" (asymmetric) are supported. Defaults to "aes256-gcm96".
`,
},

Expand Down Expand Up @@ -155,6 +155,8 @@ func (b *backend) pathPolicyWrite(ctx context.Context, req *logical.Request, d *
polReq.KeyType = keysutil.KeyType_ED25519
case "rsa-2048":
polReq.KeyType = keysutil.KeyType_RSA2048
case "rsa-3072":
polReq.KeyType = keysutil.KeyType_RSA3072
case "rsa-4096":
polReq.KeyType = keysutil.KeyType_RSA4096
default:
Expand Down Expand Up @@ -269,7 +271,7 @@ func (b *backend) pathPolicyRead(ctx context.Context, req *logical.Request, d *f
}
resp.Data["keys"] = retKeys

case keysutil.KeyType_ECDSA_P256, keysutil.KeyType_ECDSA_P384, keysutil.KeyType_ECDSA_P521, keysutil.KeyType_ED25519, keysutil.KeyType_RSA2048, keysutil.KeyType_RSA4096:
case keysutil.KeyType_ECDSA_P256, keysutil.KeyType_ECDSA_P384, keysutil.KeyType_ECDSA_P521, keysutil.KeyType_ED25519, keysutil.KeyType_RSA2048, keysutil.KeyType_RSA3072, keysutil.KeyType_RSA4096:
retKeys := map[string]map[string]interface{}{}
for k, v := range p.Keys {
key := asymKey{
Expand Down Expand Up @@ -305,8 +307,12 @@ func (b *backend) pathPolicyRead(ctx context.Context, req *logical.Request, d *f
}
}
key.Name = "ed25519"
case keysutil.KeyType_RSA2048, keysutil.KeyType_RSA4096:
case keysutil.KeyType_RSA2048, keysutil.KeyType_RSA3072, keysutil.KeyType_RSA4096:
key.Name = "rsa-2048"
if p.Type == keysutil.KeyType_RSA3072 {
key.Name = "rsa-3072"
}

if p.Type == keysutil.KeyType_RSA4096 {
key.Name = "rsa-4096"
}
Expand Down
4 changes: 2 additions & 2 deletions builtin/logical/transit/path_sign_verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ to the min_encryption_version configured on the key.`,

"prehashed": {
Type: framework.TypeBool,
Description: `Set to 'true' when the input is already hashed. If the key type is 'rsa-2048' or 'rsa-4096', then the algorithm used to hash the input should be indicated by the 'algorithm' parameter.`,
Description: `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 'algorithm' parameter.`,
},

"signature_algorithm": {
Expand Down Expand Up @@ -193,7 +193,7 @@ Defaults to "sha2-256". Not valid for all key types.`,

"prehashed": {
Type: framework.TypeBool,
Description: `Set to 'true' when the input is already hashed. If the key type is 'rsa-2048' or 'rsa-4096', then the algorithm used to hash the input should be indicated by the 'algorithm' parameter.`,
Description: `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 'algorithm' parameter.`,
},

"signature_algorithm": {
Expand Down
2 changes: 1 addition & 1 deletion sdk/helper/keysutil/lock_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ func (lm *LockManager) GetPolicy(ctx context.Context, req PolicyRequest, rand io
return nil, false, fmt.Errorf("convergent encryption not supported for keys of type %v", req.KeyType)
}

case KeyType_RSA2048, KeyType_RSA4096:
case KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096:
if req.Derived || req.Convergent {
cleanup()
return nil, false, fmt.Errorf("key derivation and convergent encryption not supported for keys of type %v", req.KeyType)
Expand Down
24 changes: 15 additions & 9 deletions sdk/helper/keysutil/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const (
KeyType_ECDSA_P384
KeyType_ECDSA_P521
KeyType_AES128_GCM96
KeyType_RSA3072
)

const (
Expand Down Expand Up @@ -92,31 +93,31 @@ type KeyType int

func (kt KeyType) EncryptionSupported() bool {
switch kt {
case KeyType_AES128_GCM96, KeyType_AES256_GCM96, KeyType_ChaCha20_Poly1305, KeyType_RSA2048, KeyType_RSA4096:
case KeyType_AES128_GCM96, KeyType_AES256_GCM96, KeyType_ChaCha20_Poly1305, KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096:
return true
}
return false
}

func (kt KeyType) DecryptionSupported() bool {
switch kt {
case KeyType_AES128_GCM96, KeyType_AES256_GCM96, KeyType_ChaCha20_Poly1305, KeyType_RSA2048, KeyType_RSA4096:
case KeyType_AES128_GCM96, KeyType_AES256_GCM96, KeyType_ChaCha20_Poly1305, KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096:
return true
}
return false
}

func (kt KeyType) SigningSupported() bool {
switch kt {
case KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521, KeyType_ED25519, KeyType_RSA2048, KeyType_RSA4096:
case KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521, KeyType_ED25519, KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096:
return true
}
return false
}

func (kt KeyType) HashSignatureInput() bool {
switch kt {
case KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521, KeyType_RSA2048, KeyType_RSA4096:
case KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521, KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096:
return true
}
return false
Expand Down Expand Up @@ -148,6 +149,8 @@ func (kt KeyType) String() string {
return "ed25519"
case KeyType_RSA2048:
return "rsa-2048"
case KeyType_RSA3072:
return "rsa-3072"
case KeyType_RSA4096:
return "rsa-4096"
}
Expand Down Expand Up @@ -899,7 +902,7 @@ func (p *Policy) Encrypt(ver int, context, nonce []byte, value string) (string,
ciphertext = append(nonce, ciphertext...)
}

case KeyType_RSA2048, KeyType_RSA4096:
case KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096:
key := p.Keys[strconv.Itoa(ver)].RSAKey
ciphertext, err = rsa.EncryptOAEP(sha256.New(), rand.Reader, &key.PublicKey, plaintext, nil)
if err != nil {
Expand Down Expand Up @@ -1033,7 +1036,7 @@ func (p *Policy) Decrypt(context, nonce []byte, value string) (string, error) {
return "", errutil.UserError{Err: "invalid ciphertext: unable to decrypt"}
}

case KeyType_RSA2048, KeyType_RSA4096:
case KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096:
key := p.Keys[strconv.Itoa(ver)].RSAKey
plain, err = rsa.DecryptOAEP(sha256.New(), rand.Reader, key, decoded, nil)
if err != nil {
Expand Down Expand Up @@ -1169,7 +1172,7 @@ func (p *Policy) Sign(ver int, context, input []byte, hashAlgorithm HashType, si
return nil, err
}

case KeyType_RSA2048, KeyType_RSA4096:
case KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096:
key := p.Keys[strconv.Itoa(ver)].RSAKey

var algo crypto.Hash
Expand Down Expand Up @@ -1332,7 +1335,7 @@ func (p *Policy) VerifySignature(context, input []byte, hashAlgorithm HashType,

return ed25519.Verify(key.Public().(ed25519.PublicKey), input, sigBytes), nil

case KeyType_RSA2048, KeyType_RSA4096:
case KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096:
key := p.Keys[strconv.Itoa(ver)].RSAKey

var algo crypto.Hash
Expand Down Expand Up @@ -1464,8 +1467,11 @@ func (p *Policy) Rotate(ctx context.Context, storage logical.Storage, randReader
entry.Key = pri
entry.FormattedPublicKey = base64.StdEncoding.EncodeToString(pub)

case KeyType_RSA2048, KeyType_RSA4096:
case KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096:
bitSize := 2048
if p.Type == KeyType_RSA3072 {
bitSize = 3072
}
if p.Type == KeyType_RSA4096 {
bitSize = 4096
}
Expand Down
4 changes: 2 additions & 2 deletions ui/app/components/transit-key-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export default Component.extend(TRANSIT_PARAMS, {

keyIsRSA: computed('key.type', function() {
let type = get(this, 'key.type');
return type === 'rsa-2048' || type === 'rsa-4096';
return type === 'rsa-2048' || type === 'rsa-3072' || type === 'rsa-4096';
}),

getModelInfo() {
Expand Down Expand Up @@ -150,7 +150,7 @@ export default Component.extend(TRANSIT_PARAMS, {

compactData(data) {
let type = get(this, 'key.type');
let isRSA = type === 'rsa-2048' || type === 'rsa-4096';
let isRSA = type === 'rsa-2048' || type === 'rsa-3072' || type === 'rsa-4096';
return Object.keys(data).reduce((result, key) => {
if (key === 'signature_algorithm' && !isRSA) {
return result;
Expand Down
2 changes: 1 addition & 1 deletion ui/app/templates/components/transit-key-action/sign.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
</div>
</div>
</div>
{{#if (or (eq key.type 'rsa-2048') (eq key.type 'rsa-4096'))}}
{{#if (or (eq key.type 'rsa-2048') (eq key.type 'rsa-3072') (eq key.type 'rsa-4096'))}}
<div class="field">
<label for="signature_algorithm" class="is-label">Signature Algorithm</label>
<div class="control is-expanded">
Expand Down
3 changes: 3 additions & 0 deletions ui/app/templates/partials/transit-form-create.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
<option selected={{eq key.type "rsa-2048"}} value="rsa-2048">
rsa-2048
</option>
<option selected={{eq key.type "rsa-3072"}} value="rsa-3072">
rsa-3072
</option>
<option selected={{eq key.type "rsa-4096"}} value="rsa-4096">
rsa-4096
</option>
Expand Down
6 changes: 6 additions & 0 deletions ui/tests/acceptance/transit-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ const keyTypes = [
supportsSigning: true,
supportsEncryption: true,
},
{
name: ts => `rsa-3072-${ts}`,
type: `rsa-3072`,
supportsSigning: true,
supportsEncryption: true,
},
{
name: ts => `rsa-4096-${ts}`,
type: `rsa-4096`,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 15 additions & 9 deletions vendor/github.com/hashicorp/vault/sdk/helper/keysutil/policy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit f6547fa

Please sign in to comment.