1
0
mirror of https://github.com/golang/go synced 2024-11-23 20:40:07 -07:00

crypto/x509: hardcode RSA PSS parameters rather than generating them

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>
This commit is contained in:
Roland Shoemaker 2020-09-28 08:59:13 -07:00 committed by Roland Shoemaker
parent a424f6e45e
commit f33263d11a
2 changed files with 66 additions and 46 deletions

View File

@ -351,6 +351,19 @@ var signatureAlgorithmDetails = []struct {
{PureEd25519, "Ed25519", oidSignatureEd25519, Ed25519, crypto.Hash(0) /* no pre-hashing */}, {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 // pssParameters reflects the parameters in an AlgorithmIdentifier that
// specifies RSA PSS. See RFC 3447, Appendix A.2.3. // specifies RSA PSS. See RFC 3447, Appendix A.2.3.
type pssParameters struct { type pssParameters struct {
@ -363,51 +376,6 @@ type pssParameters struct {
TrailerField int `asn1:"optional,explicit,tag:3,default:1"` 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 { func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) SignatureAlgorithm {
if ai.Algorithm.Equal(oidSignatureEd25519) { if ai.Algorithm.Equal(oidSignatureEd25519) {
// RFC 8410, Section 3 // RFC 8410, Section 3
@ -2015,7 +1983,7 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo SignatureAlgori
return return
} }
if requestedSigAlgo.isRSAPSS() { if requestedSigAlgo.isRSAPSS() {
sigAlgo.Parameters = rsaPSSParameters(hashFunc) sigAlgo.Parameters = hashToPSSParameters[hashFunc]
} }
found = true found = true
break break

View 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)
}
}
}