From 381d0918e91cecf28ee1d2cc76d45681f88fe518 Mon Sep 17 00:00:00 2001 From: Marcel Lanz Date: Tue, 19 Jul 2022 19:06:28 +0200 Subject: [PATCH 01/10] =?UTF-8?q?[transit-pkcs1v15]=20transit=20support=20?= =?UTF-8?q?for=20the=20pkcs1v15=20padding=20scheme=20=E2=80=93=20without?= =?UTF-8?q?=20UI=20tests=20(yet).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- builtin/logical/transit/path_datakey.go | 9 +++++- builtin/logical/transit/path_decrypt.go | 9 +++++- builtin/logical/transit/path_encrypt.go | 9 +++++- builtin/logical/transit/path_rewrap.go | 11 +++++-- sdk/helper/keysutil/encrypted_key_storage.go | 4 +-- sdk/helper/keysutil/policy.go | 29 +++++++++++++++--- ui/app/components/transit-key-actions.js | 7 +++-- .../components/transit-key-action/datakey.hbs | 25 +++++++++++++++- .../components/transit-key-action/decrypt.hbs | 25 +++++++++++++++- .../components/transit-key-action/encrypt.hbs | 30 ++++++++++++++++++- .../components/transit-key-action/rewrap.hbs | 28 ++++++++++++++++- .../components/transit-key-actions.hbs | 1 + website/content/api-docs/secret/transit.mdx | 20 ++++++++++++- 13 files changed, 188 insertions(+), 19 deletions(-) diff --git a/builtin/logical/transit/path_datakey.go b/builtin/logical/transit/path_datakey.go index 42da16191639..1948f595499b 100644 --- a/builtin/logical/transit/path_datakey.go +++ b/builtin/logical/transit/path_datakey.go @@ -28,6 +28,12 @@ func (b *backend) pathDatakey() *framework.Path { ciphertext; "wrapped" will return the ciphertext only.`, }, + "padding_scheme": { + Type: framework.TypeString, + Description: `The padding scheme to use for decrypt. Currently only applies to RSA key types. +Options are 'oaep' or 'pkcs1v15'. Defaults to 'oaep'`, + }, + "context": { Type: framework.TypeString, Description: "Context for key derivation. Required for derived keys.", @@ -131,7 +137,8 @@ func (b *backend) pathDatakeyWrite(ctx context.Context, req *logical.Request, d return nil, err } - ciphertext, err := p.Encrypt(ver, context, nonce, base64.StdEncoding.EncodeToString(newKey)) + paddingScheme := d.Get("padding_scheme").(string) + ciphertext, err := p.Encrypt(ver, context, nonce, base64.StdEncoding.EncodeToString(newKey), paddingScheme) if err != nil { switch err.(type) { case errutil.UserError: diff --git a/builtin/logical/transit/path_decrypt.go b/builtin/logical/transit/path_decrypt.go index 9d732e1cb721..9f69855d0178 100644 --- a/builtin/logical/transit/path_decrypt.go +++ b/builtin/logical/transit/path_decrypt.go @@ -37,6 +37,12 @@ func (b *backend) pathDecrypt() *framework.Path { The ciphertext to decrypt, provided as returned by encrypt.`, }, + "padding_scheme": { + Type: framework.TypeString, + Description: `The padding scheme to use for decrypt. Currently only applies to RSA key types. +Options are 'oaep' or 'pkcs1v15'. Defaults to 'oaep'`, + }, + "context": { Type: framework.TypeString, Description: ` @@ -147,7 +153,8 @@ func (b *backend) pathDecryptWrite(ctx context.Context, req *logical.Request, d continue } - plaintext, err := p.Decrypt(item.DecodedContext, item.DecodedNonce, item.Ciphertext) + paddingScheme := d.Get("padding_scheme").(string) + plaintext, err := p.Decrypt(item.DecodedContext, item.DecodedNonce, item.Ciphertext, paddingScheme) if err != nil { switch err.(type) { case errutil.InternalError: diff --git a/builtin/logical/transit/path_encrypt.go b/builtin/logical/transit/path_encrypt.go index 7b162f895ac4..b9ac441fccea 100644 --- a/builtin/logical/transit/path_encrypt.go +++ b/builtin/logical/transit/path_encrypt.go @@ -69,6 +69,12 @@ func (b *backend) pathEncrypt() *framework.Path { Description: "Base64 encoded plaintext value to be encrypted", }, + "padding_scheme": { + Type: framework.TypeString, + Description: `The padding scheme to use for decrypt. Currently only applies to RSA key types. +Options are 'oaep' or 'pkcs1v15'. Defaults to 'oaep'`, + }, + "context": { Type: framework.TypeString, Description: "Base64 encoded context for key derivation. Required if key derivation is enabled", @@ -384,7 +390,8 @@ func (b *backend) pathEncryptWrite(ctx context.Context, req *logical.Request, d warnAboutNonceUsage = true } - ciphertext, err := p.Encrypt(item.KeyVersion, item.DecodedContext, item.DecodedNonce, item.Plaintext) + paddingScheme := d.Get("padding_scheme").(string) + ciphertext, err := p.Encrypt(item.KeyVersion, item.DecodedContext, item.DecodedNonce, item.Plaintext, paddingScheme) if err != nil { switch err.(type) { case errutil.InternalError: diff --git a/builtin/logical/transit/path_rewrap.go b/builtin/logical/transit/path_rewrap.go index 41e26587d747..59d3c21c2c2c 100644 --- a/builtin/logical/transit/path_rewrap.go +++ b/builtin/logical/transit/path_rewrap.go @@ -27,6 +27,12 @@ func (b *backend) pathRewrap() *framework.Path { Description: "Ciphertext value to rewrap", }, + "padding_scheme": { + Type: framework.TypeString, + Description: `The padding scheme to use for decrypt. Currently only applies to RSA key types. +Options are 'oaep' or 'pkcs1v15'. Defaults to 'oaep'`, + }, + "context": { Type: framework.TypeString, Description: "Base64 encoded context for key derivation. Required for derived keys.", @@ -135,7 +141,8 @@ func (b *backend) pathRewrapWrite(ctx context.Context, req *logical.Request, d * continue } - plaintext, err := p.Decrypt(item.DecodedContext, item.DecodedNonce, item.Ciphertext) + paddingScheme := d.Get("padding_scheme").(string) + plaintext, err := p.Decrypt(item.DecodedContext, item.DecodedNonce, item.Ciphertext, paddingScheme) if err != nil { switch err.(type) { case errutil.UserError: @@ -151,7 +158,7 @@ func (b *backend) pathRewrapWrite(ctx context.Context, req *logical.Request, d * warnAboutNonceUsage = true } - ciphertext, err := p.Encrypt(item.KeyVersion, item.DecodedContext, item.DecodedNonce, plaintext) + ciphertext, err := p.Encrypt(item.KeyVersion, item.DecodedContext, item.DecodedNonce, plaintext, paddingScheme) if err != nil { switch err.(type) { case errutil.UserError: diff --git a/sdk/helper/keysutil/encrypted_key_storage.go b/sdk/helper/keysutil/encrypted_key_storage.go index 90eaaf0bbae1..b182b8b2f455 100644 --- a/sdk/helper/keysutil/encrypted_key_storage.go +++ b/sdk/helper/keysutil/encrypted_key_storage.go @@ -183,7 +183,7 @@ func (s *encryptedKeyStorage) List(ctx context.Context, prefix string) ([]string } // Decrypt the data with the object's key policy. - encodedPlaintext, err := s.policy.Decrypt(context, nil, string(decoded[:])) + encodedPlaintext, err := s.policy.Decrypt(context, nil, string(decoded[:]), "") if err != nil { return nil, err } @@ -268,7 +268,7 @@ func (s *encryptedKeyStorage) encryptPath(path string) (string, error) { context := strings.TrimSuffix(s.prefix, "/") for _, p := range parts { encoded := base64.StdEncoding.EncodeToString([]byte(p)) - ciphertext, err := s.policy.Encrypt(0, []byte(context), nil, encoded) + ciphertext, err := s.policy.Encrypt(0, []byte(context), nil, encoded, "") if err != nil { return "", err } diff --git a/sdk/helper/keysutil/policy.go b/sdk/helper/keysutil/policy.go index 7e35b050fcee..8ecb6e4bb9e7 100644 --- a/sdk/helper/keysutil/policy.go +++ b/sdk/helper/keysutil/policy.go @@ -818,7 +818,7 @@ func (p *Policy) convergentVersion(ver int) int { return convergentVersion } -func (p *Policy) Encrypt(ver int, context, nonce []byte, value string) (string, error) { +func (p *Policy) Encrypt(ver int, context, nonce []byte, value string, paddingScheme string) (string, error) { if !p.Type.EncryptionSupported() { return "", errutil.UserError{Err: fmt.Sprintf("message encryption not supported for key type %v", p.Type)} } @@ -894,8 +894,19 @@ func (p *Policy) Encrypt(ver int, context, nonce []byte, value string) (string, if err != nil { return "", err } + if paddingScheme == "" { + paddingScheme = "oaep" + } key := keyEntry.RSAKey - ciphertext, err = rsa.EncryptOAEP(sha256.New(), rand.Reader, &key.PublicKey, plaintext, nil) + switch paddingScheme { + case "pkcs1v15": + ciphertext, err = rsa.EncryptPKCS1v15(rand.Reader, &key.PublicKey, plaintext) + case "oaep": + ciphertext, err = rsa.EncryptOAEP(sha256.New(), rand.Reader, &key.PublicKey, plaintext, nil) + default: + return "", errutil.InternalError{Err: fmt.Sprintf("unsupported RSA padding scheme %s", paddingScheme)} + } + if err != nil { return "", errutil.InternalError{Err: fmt.Sprintf("failed to RSA encrypt the plaintext: %v", err)} } @@ -913,7 +924,7 @@ func (p *Policy) Encrypt(ver int, context, nonce []byte, value string) (string, return encoded, nil } -func (p *Policy) Decrypt(context, nonce []byte, value string) (string, error) { +func (p *Policy) Decrypt(context, nonce []byte, value string, paddingScheme string) (string, error) { if !p.Type.DecryptionSupported() { return "", errutil.UserError{Err: fmt.Sprintf("message decryption not supported for key type %v", p.Type)} } @@ -994,8 +1005,18 @@ func (p *Policy) Decrypt(context, nonce []byte, value string) (string, error) { if err != nil { return "", err } + if paddingScheme == "" { + paddingScheme = "oaep" + } key := keyEntry.RSAKey - plain, err = rsa.DecryptOAEP(sha256.New(), rand.Reader, key, decoded, nil) + switch paddingScheme { + case "pkcs1v15": + plain, err = rsa.DecryptPKCS1v15(rand.Reader, key, decoded) + case "oaep": + plain, err = rsa.DecryptOAEP(sha256.New(), rand.Reader, key, decoded, nil) + default: + return "", errutil.InternalError{Err: fmt.Sprintf("unsupported RSA padding scheme %s", paddingScheme)} + } if err != nil { return "", errutil.InternalError{Err: fmt.Sprintf("failed to RSA decrypt the ciphertext: %v", err)} } diff --git a/ui/app/components/transit-key-actions.js b/ui/app/components/transit-key-actions.js index 1fd3894923b4..1e895efe1a40 100644 --- a/ui/app/components/transit-key-actions.js +++ b/ui/app/components/transit-key-actions.js @@ -10,6 +10,7 @@ const TRANSIT_PARAMS = { hash_algorithm: 'sha2-256', algorithm: 'sha2-256', signature_algorithm: 'pss', + padding_scheme: 'oaep', bits: 256, bytes: 32, ciphertext: null, @@ -39,9 +40,9 @@ const PARAMS_FOR_ACTION = { sign: ['input', 'hash_algorithm', 'key_version', 'prehashed', 'signature_algorithm'], verify: ['input', 'hmac', 'signature', 'hash_algorithm', 'prehashed'], hmac: ['input', 'algorithm', 'key_version'], - encrypt: ['plaintext', 'context', 'nonce', 'key_version'], - decrypt: ['ciphertext', 'context', 'nonce'], - rewrap: ['ciphertext', 'context', 'nonce', 'key_version'], + encrypt: ['plaintext', 'context', 'padding_scheme', 'nonce', 'key_version'], + decrypt: ['ciphertext', 'context', 'padding_scheme', 'nonce'], + rewrap: ['ciphertext', 'context', 'padding_scheme', 'nonce', 'key_version'], }; const SUCCESS_MESSAGE_FOR_ACTION = { sign: 'Signed your data', diff --git a/ui/app/templates/components/transit-key-action/datakey.hbs b/ui/app/templates/components/transit-key-action/datakey.hbs index fa73768bb8cd..594948ba1f8d 100644 --- a/ui/app/templates/components/transit-key-action/datakey.hbs +++ b/ui/app/templates/components/transit-key-action/datakey.hbs @@ -1,4 +1,6 @@ -
+
@@ -60,6 +62,27 @@
+ {{#if (or (eq @key.type "rsa-2048") (eq @key.type "rsa-3072") (eq @key.type "rsa-4096"))}} +
+ +
+
+ +
+
+
+ {{/if}}
diff --git a/ui/app/templates/components/transit-key-action/decrypt.hbs b/ui/app/templates/components/transit-key-action/decrypt.hbs index 85745296ed09..688a9a4a162f 100644 --- a/ui/app/templates/components/transit-key-action/decrypt.hbs +++ b/ui/app/templates/components/transit-key-action/decrypt.hbs @@ -1,4 +1,6 @@ - +

You can decrypt ciphertext using {{@key.name}} as the encryption key.

@@ -28,6 +30,27 @@
{{/if}} + {{#if (or (eq @key.type "rsa-2048") (eq @key.type "rsa-3072") (eq @key.type "rsa-4096"))}} +
+ +
+
+ +
+
+
+ {{/if}} {{#if (eq @key.convergentEncryptionVersion 1)}}
diff --git a/ui/app/templates/components/transit-key-action/encrypt.hbs b/ui/app/templates/components/transit-key-action/encrypt.hbs index 2a51e3d85af7..d3e22c8259db 100644 --- a/ui/app/templates/components/transit-key-action/encrypt.hbs +++ b/ui/app/templates/components/transit-key-action/encrypt.hbs @@ -1,7 +1,14 @@
@@ -40,6 +47,27 @@
{{/if}} + {{#if (or (eq @key.type "rsa-2048") (eq @key.type "rsa-3072") (eq @key.type "rsa-4096"))}} +
+ +
+
+ +
+
+
+ {{/if}} {{#if (eq @key.convergentEncryptionVersion 1)}}
diff --git a/ui/app/templates/components/transit-key-action/rewrap.hbs b/ui/app/templates/components/transit-key-action/rewrap.hbs index 0570b8e1c390..13f0d0340c8a 100644 --- a/ui/app/templates/components/transit-key-action/rewrap.hbs +++ b/ui/app/templates/components/transit-key-action/rewrap.hbs @@ -1,4 +1,9 @@ - +
@@ -29,6 +34,27 @@
{{/if}} + {{#if (or (eq @key.type "rsa-2048") (eq @key.type "rsa-3072") (eq @key.type "rsa-4096"))}} +
+ +
+
+ +
+
+
+ {{/if}} {{#if (eq @key.convergentEncryptionVersion 1)}}
diff --git a/ui/app/templates/components/transit-key-actions.hbs b/ui/app/templates/components/transit-key-actions.hbs index c7bb6f030813..c98e7a2f2583 100644 --- a/ui/app/templates/components/transit-key-actions.hbs +++ b/ui/app/templates/components/transit-key-actions.hbs @@ -36,6 +36,7 @@ signature=this.signature signature_algorithm=this.signature_algorithm hash_algorithm=this.hash_algorithm + padding_scheme=this.padding_scheme prehashed=this.prehashed wrappedToken=this.wrappedToken exportKeyType=this.exportKeyType diff --git a/website/content/api-docs/secret/transit.mdx b/website/content/api-docs/secret/transit.mdx index 711b607755bb..ad8093e79f35 100644 --- a/website/content/api-docs/secret/transit.mdx +++ b/website/content/api-docs/secret/transit.mdx @@ -509,6 +509,12 @@ will be returned. - `plaintext` `(string: )` – Specifies **base64 encoded** plaintext to be encoded. +- `algorithm` `(string: "oaep")` – When using a RSA key, specifies the RSA + decryption algorithm to use for decryption. Supported signature types are: + + - `oaep` + - `pkcs1v15` + - `context` `(string: "")` – Specifies the **base64 encoded** context for key derivation. This is required if key derivation is enabled for this key. @@ -605,7 +611,7 @@ This endpoint decrypts the provided ciphertext using the named key. | Method | Path | | :----- | :----------------------- | -| `POST` | `/transit/decrypt/:name` | +| `POST` | `/transit/decrypt/:name(/:algorithm)` | ### Parameters @@ -614,6 +620,12 @@ This endpoint decrypts the provided ciphertext using the named key. - `ciphertext` `(string: )` – Specifies the ciphertext to decrypt. +- `algorithm` `(string: "oaep")` – When using a RSA key, specifies the RSA + decryption algorithm to use for decryption. Supported signature types are: + + - `oaep` + - `pkcs1v15` + - `context` `(string: "")` – Specifies the **base64 encoded** context for key derivation. This is required if key derivation is enabled. @@ -685,6 +697,12 @@ functionality to untrusted users or scripts. - `ciphertext` `(string: )` – Specifies the ciphertext to re-encrypt. +- `algorithm` `(string: "oaep")` – When using a RSA key, specifies the RSA + decryption algorithm to use for decryption. Supported signature types are: + + - `oaep` + - `pkcs1v15` + - `context` `(string: "")` – Specifies the **base64 encoded** context for key derivation. This is required if key derivation is enabled. From 91d11dc8b3be06d011cf969c3bbb72100bce2ba4 Mon Sep 17 00:00:00 2001 From: Marcel Lanz Date: Tue, 19 Jul 2022 23:40:05 +0200 Subject: [PATCH 02/10] [transit-pkcs1v15] renamed padding_scheme parameter in transit documentation. --- website/content/api-docs/secret/transit.mdx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/website/content/api-docs/secret/transit.mdx b/website/content/api-docs/secret/transit.mdx index ad8093e79f35..ff912500d7e7 100644 --- a/website/content/api-docs/secret/transit.mdx +++ b/website/content/api-docs/secret/transit.mdx @@ -509,8 +509,8 @@ will be returned. - `plaintext` `(string: )` – Specifies **base64 encoded** plaintext to be encoded. -- `algorithm` `(string: "oaep")` – When using a RSA key, specifies the RSA - decryption algorithm to use for decryption. Supported signature types are: +- `padding_scheme` `(string: "oaep")` – When using a RSA key, specifies the RSA + padding scheme to use for encryption. Supported signature types are: - `oaep` - `pkcs1v15` @@ -620,8 +620,8 @@ This endpoint decrypts the provided ciphertext using the named key. - `ciphertext` `(string: )` – Specifies the ciphertext to decrypt. -- `algorithm` `(string: "oaep")` – When using a RSA key, specifies the RSA - decryption algorithm to use for decryption. Supported signature types are: +- `padding_scheme` `(string: "oaep")` – When using a RSA key, specifies the RSA + padding scheme to use for decryption. Supported signature types are: - `oaep` - `pkcs1v15` @@ -697,8 +697,8 @@ functionality to untrusted users or scripts. - `ciphertext` `(string: )` – Specifies the ciphertext to re-encrypt. -- `algorithm` `(string: "oaep")` – When using a RSA key, specifies the RSA - decryption algorithm to use for decryption. Supported signature types are: +- `padding_scheme` `(string: "oaep")` – When using a RSA key, specifies the RSA + padding scheme to use for re-encryption. Supported signature types are: - `oaep` - `pkcs1v15` From 31b0c51da37b6b8b8a977905512721936bd094ca Mon Sep 17 00:00:00 2001 From: Marcel Lanz Date: Wed, 20 Jul 2022 00:06:19 +0200 Subject: [PATCH 03/10] [transit-pkcs1v15] add changelog file. --- changelog/16368.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changelog/16368.txt diff --git a/changelog/16368.txt b/changelog/16368.txt new file mode 100644 index 000000000000..9293c69dba04 --- /dev/null +++ b/changelog/16368.txt @@ -0,0 +1,3 @@ +```release-note:improvement +secrets/transit: Add support for RSA padding scheme pkcs1v15 for encryption +``` From 8a7728d738e3f773f7500041bf0e05f16c49fa9d Mon Sep 17 00:00:00 2001 From: Marcel Lanz Date: Wed, 20 Jul 2022 00:11:16 +0200 Subject: [PATCH 04/10] [transit-pkcs1v15] remove the algorithm path as padding_scheme is chosen by parameter. --- website/content/api-docs/secret/transit.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/content/api-docs/secret/transit.mdx b/website/content/api-docs/secret/transit.mdx index ff912500d7e7..e82fff58952b 100644 --- a/website/content/api-docs/secret/transit.mdx +++ b/website/content/api-docs/secret/transit.mdx @@ -611,7 +611,7 @@ This endpoint decrypts the provided ciphertext using the named key. | Method | Path | | :----- | :----------------------- | -| `POST` | `/transit/decrypt/:name(/:algorithm)` | +| `POST` | `/transit/decrypt/:name` | ### Parameters From 99a82d484a967b7330b2f97964b4320942debb12 Mon Sep 17 00:00:00 2001 From: Marcel Lanz Date: Wed, 16 Aug 2023 17:03:07 +0200 Subject: [PATCH 05/10] Update ui/app/templates/components/transit-key-action/datakey.hbs Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com> --- ui/app/templates/components/transit-key-action/datakey.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/app/templates/components/transit-key-action/datakey.hbs b/ui/app/templates/components/transit-key-action/datakey.hbs index 594948ba1f8d..a65d3a55e2ac 100644 --- a/ui/app/templates/components/transit-key-action/datakey.hbs +++ b/ui/app/templates/components/transit-key-action/datakey.hbs @@ -70,7 +70,7 @@