@@ -27,6 +27,8 @@ import (
2727 "io"
2828 "math/big"
2929 "os"
30+ "strconv"
31+ "strings"
3032
3133 "github.com/spf13/cobra"
3234 "go.step.sm/crypto/kms"
@@ -97,6 +99,22 @@ digest of the data file for you.`,
9799 in := flagutil .MustString (flags , "in" )
98100 verify := flagutil .MustBool (flags , "verify" )
99101
102+ var saltLength int
103+ switch s := strings .ToLower (flagutil .MustString (flags , "salt-length" )); s {
104+ case "" , "auto" :
105+ saltLength = rsa .PSSSaltLengthAuto
106+ case "equal-hash" , "hash" :
107+ saltLength = rsa .PSSSaltLengthEqualsHash
108+ default :
109+ var err error
110+ if saltLength , err = strconv .Atoi (s ); err != nil {
111+ return fmt .Errorf ("failed to parse --salt-length=%q: %w" , s , err )
112+ }
113+ if saltLength < rsa .PSSSaltLengthEqualsHash {
114+ return fmt .Errorf ("flag --salt-length=%q is not valid: salt length cannot be negative" , s )
115+ }
116+ }
117+
100118 kuri := ensureSchemePrefix (flagutil .MustString (flags , "kms" ))
101119 if kuri == "" {
102120 kuri = name
@@ -116,7 +134,7 @@ digest of the data file for you.`,
116134 }
117135
118136 pub := signer .Public ()
119- so , err := getSignerOptions (km , pub , alg , pss )
137+ so , err := getSignerOptions (km , pub , alg , pss , saltLength )
120138 if err != nil {
121139 return err
122140 }
@@ -231,7 +249,7 @@ func jwsSignature(sig []byte, pub crypto.PublicKey) ([]byte, error) {
231249 return append (rBytesPadded , sBytesPadded ... ), nil
232250}
233251
234- func getSignerOptions (km kms.KeyManager , pub crypto.PublicKey , alg string , pss bool ) (crypto.SignerOpts , error ) {
252+ func getSignerOptions (km kms.KeyManager , pub crypto.PublicKey , alg string , pss bool , saltLength int ) (crypto.SignerOpts , error ) {
235253 switch k := pub .(type ) {
236254 case * ecdsa.PublicKey :
237255 switch k .Curve {
@@ -259,15 +277,15 @@ func getSignerOptions(km kms.KeyManager, pub crypto.PublicKey, alg string, pss b
259277 if pss {
260278 pssOptions := & rsa.PSSOptions {
261279 Hash : h ,
262- SaltLength : rsa . PSSSaltLengthAuto ,
280+ SaltLength : saltLength ,
263281 }
264282 // rsa.PSSSaltLengthAuto is not supported by crypto11. The salt
265283 // length here is the same used by Go when PSSSaltLengthAuto is
266284 // used.
267285 //
268286 // This can be fixed if
269287 // https://github.com/ThalesIgnite/crypto11/pull/96 gets merged.
270- if _ , ok := km .(* pkcs11.PKCS11 ); ok {
288+ if _ , ok := km .(* pkcs11.PKCS11 ); ok && saltLength == rsa . PSSSaltLengthAuto {
271289 pssOptions .SaltLength = (k .N .BitLen ()- 1 + 7 )/ 8 - 2 - h .Size ()
272290 }
273291 return pssOptions , nil
@@ -280,7 +298,7 @@ func getSignerOptions(km kms.KeyManager, pub crypto.PublicKey, alg string, pss b
280298 if err != nil {
281299 return nil , err
282300 }
283- return getSignerOptions (km , pk , alg , pss )
301+ return getSignerOptions (km , pk , alg , pss , saltLength )
284302 default :
285303 return nil , fmt .Errorf ("unsupported public key type %T" , pub )
286304 }
@@ -341,6 +359,7 @@ func init() {
341359
342360 flags .Var (alg , "alg" , "The hashing `algorithm` to use on RSA PKCS #1 and RSA-PSS signatures.\n Options are SHA256, SHA384 or SHA512" )
343361 flags .Bool ("pss" , false , "Use RSA-PSS signature scheme instead of RSA PKCS #1" )
362+ flags .String ("salt-length" , "auto" , "The salt length used in the RSA-PSS signature scheme.\n Options are auto (0), equal-hash (-1) or a positive integer" )
344363 flags .Var (format , "format" , "The `format` to print the signature.\n Options are base64, hex, jws, or raw" )
345364 flags .String ("in" , "" , "The `file` to sign. Required for Ed25519 keys." )
346365 flags .Bool ("verify" , false , "Verify the signature with the public key" )
0 commit comments