]> Cypherpunks.ru repositories - gostls13.git/commitdiff
crypto/x509: hardcode RSA PSS parameters rather than generating them
authorRoland Shoemaker <rolandshoemaker@gmail.com>
Mon, 28 Sep 2020 15:59:13 +0000 (08:59 -0700)
committerRoland Shoemaker <roland@golang.org>
Mon, 28 Sep 2020 18:46:39 +0000 (18:46 +0000)
Rather than generating the three possible RSA PSS parameters each time
they are needed just hardcode them and pick the required one based on
the hash function.

Fixes #41407

Change-Id: Id43bdaf40b3ca82c4c04c6588e3b643f63107657
Reviewed-on: https://go-review.googlesource.com/c/go/+/258037
Run-TryBot: Roland Shoemaker <roland@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Roland Shoemaker <roland@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
src/crypto/x509/x509.go
src/crypto/x509/x509_test.go

index 49ac059a0e2c839e739933b5846b9eeacabc6bb3..16655a3c7041120f6d2609f47579bcb5457beef0 100644 (file)
@@ -351,6 +351,19 @@ var signatureAlgorithmDetails = []struct {
        {PureEd25519, "Ed25519", oidSignatureEd25519, Ed25519, crypto.Hash(0) /* no pre-hashing */},
 }
 
+// hashToPSSParameters contains the DER encoded RSA PSS parameters for the
+// SHA256, SHA384, and SHA512 hashes as defined in RFC 3447, Appendix A.2.3.
+// The parameters contain the following values:
+//   * hashAlgorithm contains the associated hash identifier with NULL parameters
+//   * maskGenAlgorithm always contains the default mgf1SHA1 identifier
+//   * saltLength contains the length of the associated hash
+//   * trailerField always contains the default trailerFieldBC value
+var hashToPSSParameters = map[crypto.Hash]asn1.RawValue{
+       crypto.SHA256: asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0, 162, 3, 2, 1, 32}},
+       crypto.SHA384: asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 2, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 2, 5, 0, 162, 3, 2, 1, 48}},
+       crypto.SHA512: asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 3, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 3, 5, 0, 162, 3, 2, 1, 64}},
+}
+
 // pssParameters reflects the parameters in an AlgorithmIdentifier that
 // specifies RSA PSS. See RFC 3447, Appendix A.2.3.
 type pssParameters struct {
@@ -363,51 +376,6 @@ type pssParameters struct {
        TrailerField int                      `asn1:"optional,explicit,tag:3,default:1"`
 }
 
-// rsaPSSParameters returns an asn1.RawValue suitable for use as the Parameters
-// in an AlgorithmIdentifier that specifies RSA PSS.
-func rsaPSSParameters(hashFunc crypto.Hash) asn1.RawValue {
-       var hashOID asn1.ObjectIdentifier
-
-       switch hashFunc {
-       case crypto.SHA256:
-               hashOID = oidSHA256
-       case crypto.SHA384:
-               hashOID = oidSHA384
-       case crypto.SHA512:
-               hashOID = oidSHA512
-       }
-
-       params := pssParameters{
-               Hash: pkix.AlgorithmIdentifier{
-                       Algorithm:  hashOID,
-                       Parameters: asn1.NullRawValue,
-               },
-               MGF: pkix.AlgorithmIdentifier{
-                       Algorithm: oidMGF1,
-               },
-               SaltLength:   hashFunc.Size(),
-               TrailerField: 1,
-       }
-
-       mgf1Params := pkix.AlgorithmIdentifier{
-               Algorithm:  hashOID,
-               Parameters: asn1.NullRawValue,
-       }
-
-       var err error
-       params.MGF.Parameters.FullBytes, err = asn1.Marshal(mgf1Params)
-       if err != nil {
-               panic(err)
-       }
-
-       serialized, err := asn1.Marshal(params)
-       if err != nil {
-               panic(err)
-       }
-
-       return asn1.RawValue{FullBytes: serialized}
-}
-
 func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) SignatureAlgorithm {
        if ai.Algorithm.Equal(oidSignatureEd25519) {
                // RFC 8410, Section 3
@@ -2015,7 +1983,7 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo SignatureAlgori
                                return
                        }
                        if requestedSigAlgo.isRSAPSS() {
-                               sigAlgo.Parameters = rsaPSSParameters(hashFunc)
+                               sigAlgo.Parameters = hashToPSSParameters[hashFunc]
                        }
                        found = true
                        break
index 840f535e552a34979acca3e8c172b608b3b5fb94..d0315900e47c5399dddf328552733b49c852233e 100644 (file)
@@ -2702,3 +2702,55 @@ func TestCreateRevocationList(t *testing.T) {
                })
        }
 }
+
+func TestRSAPSAParameters(t *testing.T) {
+       generateParams := func(hashFunc crypto.Hash) []byte {
+               var hashOID asn1.ObjectIdentifier
+
+               switch hashFunc {
+               case crypto.SHA256:
+                       hashOID = oidSHA256
+               case crypto.SHA384:
+                       hashOID = oidSHA384
+               case crypto.SHA512:
+                       hashOID = oidSHA512
+               }
+
+               params := pssParameters{
+                       Hash: pkix.AlgorithmIdentifier{
+                               Algorithm:  hashOID,
+                               Parameters: asn1.NullRawValue,
+                       },
+                       MGF: pkix.AlgorithmIdentifier{
+                               Algorithm: oidMGF1,
+                       },
+                       SaltLength:   hashFunc.Size(),
+                       TrailerField: 1,
+               }
+
+               mgf1Params := pkix.AlgorithmIdentifier{
+                       Algorithm:  hashOID,
+                       Parameters: asn1.NullRawValue,
+               }
+
+               var err error
+               params.MGF.Parameters.FullBytes, err = asn1.Marshal(mgf1Params)
+               if err != nil {
+                       t.Fatalf("failed to marshal MGF parameters: %s", err)
+               }
+
+               serialized, err := asn1.Marshal(params)
+               if err != nil {
+                       t.Fatalf("failed to marshal parameters: %s", err)
+               }
+
+               return serialized
+       }
+
+       for h, params := range hashToPSSParameters {
+               generated := generateParams(h)
+               if !bytes.Equal(params.FullBytes, generated) {
+                       t.Errorf("hardcoded parameters for %s didn't match generated parameters: got (generated) %x, wanted (hardcoded) %x", h, generated, params.FullBytes)
+               }
+       }
+}