Skip to content

Commit

Permalink
Parameterize hashing for RSA signing and verification
Browse files Browse the repository at this point in the history
  • Loading branch information
vishalnayak committed Nov 3, 2017
1 parent 174f6d7 commit f245daf
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 17 deletions.
22 changes: 16 additions & 6 deletions builtin/logical/transit/path_sign_verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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{
Expand Down Expand Up @@ -109,14 +113,18 @@ 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
* sha2-512
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{
Expand All @@ -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 {
Expand Down Expand Up @@ -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":
Expand All @@ -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
}
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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":
Expand All @@ -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:
Expand Down
42 changes: 31 additions & 11 deletions helper/keysutil/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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
}
Expand All @@ -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)}
}
Expand Down Expand Up @@ -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

Expand Down

0 comments on commit f245daf

Please sign in to comment.