From f245daf52467fae0d08688876094a51ab1ef316c Mon Sep 17 00:00:00 2001 From: vishalnayak Date: Fri, 3 Nov 2017 05:56:39 -0400 Subject: [PATCH] Parameterize hashing for RSA signing and verification --- builtin/logical/transit/path_sign_verify.go | 22 ++++++++--- helper/keysutil/policy.go | 42 +++++++++++++++------ 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/builtin/logical/transit/path_sign_verify.go b/builtin/logical/transit/path_sign_verify.go index 074f7ff22236..6bdc96d3c6f7 100644 --- a/builtin/logical/transit/path_sign_verify.go +++ b/builtin/logical/transit/path_sign_verify.go @@ -37,7 +37,6 @@ derivation is enabled; currently only available with ed25519 keys.`, Default: "sha2-256", Description: `Hash algorithm to use (POST body parameter). Valid values are: -* none * sha2-224 * sha2-256 * sha2-384 @@ -58,6 +57,11 @@ including ed25519.`, Must be 0 (for latest) or a value greater than or equal to the min_encryption_version configured on the key.`, }, + + "prehashed": &framework.FieldSchema{ + 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.`, + }, }, Callbacks: map[logical.Operation]framework.OperationFunc{ @@ -109,7 +113,6 @@ derivation is enabled; currently only available with ed25519 keys.`, Default: "sha2-256", Description: `Hash algorithm to use (POST body parameter). Valid values are: -* none * sha2-224 * sha2-256 * sha2-384 @@ -117,6 +120,11 @@ derivation is enabled; currently only available with ed25519 keys.`, Defaults to "sha2-256". Not valid for all key types.`, }, + + "prehashed": &framework.FieldSchema{ + 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.`, + }, }, Callbacks: map[logical.Operation]framework.OperationFunc{ @@ -137,6 +145,7 @@ func (b *backend) pathSignWrite( if algorithm == "" { algorithm = d.Get("algorithm").(string) } + prehashed := d.Get("prehashed").(bool) input, err := base64.StdEncoding.DecodeString(inputB64) if err != nil { @@ -168,7 +177,7 @@ func (b *backend) pathSignWrite( } } - if p.Type.HashSignatureInput() && algorithm != "none" { + if p.Type.HashSignatureInput() && !prehashed { var hf hash.Hash switch algorithm { case "sha2-224": @@ -186,7 +195,7 @@ func (b *backend) pathSignWrite( input = hf.Sum(nil) } - sig, err := p.Sign(ver, context, input) + sig, err := p.Sign(ver, context, input, algorithm) if err != nil { return nil, err } @@ -230,6 +239,7 @@ func (b *backend) pathVerifyWrite( if algorithm == "" { algorithm = d.Get("algorithm").(string) } + prehashed := d.Get("prehashed").(bool) input, err := base64.StdEncoding.DecodeString(inputB64) if err != nil { @@ -261,7 +271,7 @@ func (b *backend) pathVerifyWrite( } } - if p.Type.HashSignatureInput() && algorithm != "none" { + if p.Type.HashSignatureInput() && !prehashed { var hf hash.Hash switch algorithm { case "sha2-224": @@ -279,7 +289,7 @@ func (b *backend) pathVerifyWrite( input = hf.Sum(nil) } - valid, err := p.VerifySignature(context, input, sig) + valid, err := p.VerifySignature(context, input, sig, algorithm) if err != nil { switch err.(type) { case errutil.UserError: diff --git a/helper/keysutil/policy.go b/helper/keysutil/policy.go index 0e9730ad724f..b0169a2a2c9f 100644 --- a/helper/keysutil/policy.go +++ b/helper/keysutil/policy.go @@ -88,7 +88,7 @@ func (kt KeyType) SigningSupported() bool { func (kt KeyType) HashSignatureInput() bool { switch kt { - case KeyType_ECDSA_P256: + case KeyType_ECDSA_P256, KeyType_RSA2048, KeyType_RSA4096: return true } return false @@ -724,7 +724,7 @@ func (p *Policy) HMACKey(version int) ([]byte, error) { return p.Keys[version].HMACKey, nil } -func (p *Policy) Sign(ver int, context, input []byte) (*SigningResult, error) { +func (p *Policy) Sign(ver int, context, input []byte, algorithm string) (*SigningResult, error) { if !p.Type.SigningSupported() { return nil, fmt.Errorf("message signing not supported for key type %v", p.Type) } @@ -792,11 +792,21 @@ func (p *Policy) Sign(ver int, context, input []byte) (*SigningResult, error) { case KeyType_RSA2048, KeyType_RSA4096: key := p.Keys[ver].RSAKey - hash := crypto.SHA256.New() - hash.Write(input) - inputHash := hash.Sum(nil) + var algo crypto.Hash + switch algorithm { + case "sha2-224": + algo = crypto.SHA224 + case "sha2-256": + algo = crypto.SHA256 + case "sha2-384": + algo = crypto.SHA384 + case "sha2-512": + algo = crypto.SHA512 + default: + return nil, errutil.InternalError{Err: fmt.Sprintf("unsupported algorithm %s", algorithm)} + } - sig, err = rsa.SignPSS(rand.Reader, key, crypto.SHA256, inputHash, nil) + sig, err = rsa.SignPSS(rand.Reader, key, algo, input, nil) if err != nil { return nil, err } @@ -816,7 +826,7 @@ func (p *Policy) Sign(ver int, context, input []byte) (*SigningResult, error) { return res, nil } -func (p *Policy) VerifySignature(context, input []byte, sig string) (bool, error) { +func (p *Policy) VerifySignature(context, input []byte, sig, algorithm string) (bool, error) { if !p.Type.SigningSupported() { return false, errutil.UserError{Err: fmt.Sprintf("message verification not supported for key type %v", p.Type)} } @@ -888,11 +898,21 @@ func (p *Policy) VerifySignature(context, input []byte, sig string) (bool, error case KeyType_RSA2048, KeyType_RSA4096: key := p.Keys[ver].RSAKey - hash := crypto.SHA256.New() - hash.Write(input) - inputHash := hash.Sum(nil) + var algo crypto.Hash + switch algorithm { + case "sha2-224": + algo = crypto.SHA224 + case "sha2-256": + algo = crypto.SHA256 + case "sha2-384": + algo = crypto.SHA384 + case "sha2-512": + algo = crypto.SHA512 + default: + return false, errutil.InternalError{Err: fmt.Sprintf("unsupported algorithm %s", algorithm)} + } - err = rsa.VerifyPSS(&key.PublicKey, crypto.SHA256, inputHash, sigBytes, nil) + err = rsa.VerifyPSS(&key.PublicKey, algo, input, sigBytes, nil) return err == nil, nil