Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RSA3072 implementation in transit secrets engine #8151

Merged
merged 4 commits into from
Feb 15, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -48,6 +48,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