aboutsummaryrefslogtreecommitdiff
path: root/src/crypto/x509/x509.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/x509/x509.go')
-rw-r--r--src/crypto/x509/x509.go102
1 files changed, 47 insertions, 55 deletions
diff --git a/src/crypto/x509/x509.go b/src/crypto/x509/x509.go
index 49ac059a0e..93dca03840 100644
--- a/src/crypto/x509/x509.go
+++ b/src/crypto/x509/x509.go
@@ -28,7 +28,7 @@ import (
"strconv"
"strings"
"time"
- "unicode/utf8"
+ "unicode"
"golang.org/x/crypto/cryptobyte"
cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
@@ -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
@@ -1117,17 +1085,29 @@ func parseSANExtension(value []byte) (dnsNames, emailAddresses []string, ipAddre
err = forEachSAN(value, func(tag int, data []byte) error {
switch tag {
case nameTypeEmail:
- emailAddresses = append(emailAddresses, string(data))
+ email := string(data)
+ if err := isIA5String(email); err != nil {
+ return errors.New("x509: SAN rfc822Name is malformed")
+ }
+ emailAddresses = append(emailAddresses, email)
case nameTypeDNS:
- dnsNames = append(dnsNames, string(data))
+ name := string(data)
+ if err := isIA5String(name); err != nil {
+ return errors.New("x509: SAN dNSName is malformed")
+ }
+ dnsNames = append(dnsNames, string(name))
case nameTypeURI:
- uri, err := url.Parse(string(data))
+ uriStr := string(data)
+ if err := isIA5String(uriStr); err != nil {
+ return errors.New("x509: SAN uniformResourceIdentifier is malformed")
+ }
+ uri, err := url.Parse(uriStr)
if err != nil {
- return fmt.Errorf("x509: cannot parse URI %q: %s", string(data), err)
+ return fmt.Errorf("x509: cannot parse URI %q: %s", uriStr, err)
}
if len(uri.Host) > 0 {
if _, ok := domainToReverseLabels(uri.Host); !ok {
- return fmt.Errorf("x509: cannot parse URI %q: invalid domain", string(data))
+ return fmt.Errorf("x509: cannot parse URI %q: invalid domain", uriStr)
}
}
uris = append(uris, uri)
@@ -1657,9 +1637,15 @@ func oidInExtensions(oid asn1.ObjectIdentifier, extensions []pkix.Extension) boo
func marshalSANs(dnsNames, emailAddresses []string, ipAddresses []net.IP, uris []*url.URL) (derBytes []byte, err error) {
var rawValues []asn1.RawValue
for _, name := range dnsNames {
+ if err := isIA5String(name); err != nil {
+ return nil, err
+ }
rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeDNS, Class: 2, Bytes: []byte(name)})
}
for _, email := range emailAddresses {
+ if err := isIA5String(email); err != nil {
+ return nil, err
+ }
rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeEmail, Class: 2, Bytes: []byte(email)})
}
for _, rawIP := range ipAddresses {
@@ -1671,14 +1657,19 @@ func marshalSANs(dnsNames, emailAddresses []string, ipAddresses []net.IP, uris [
rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeIP, Class: 2, Bytes: ip})
}
for _, uri := range uris {
- rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeURI, Class: 2, Bytes: []byte(uri.String())})
+ uriStr := uri.String()
+ if err := isIA5String(uriStr); err != nil {
+ return nil, err
+ }
+ rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeURI, Class: 2, Bytes: []byte(uriStr)})
}
return asn1.Marshal(rawValues)
}
func isIA5String(s string) error {
for _, r := range s {
- if r >= utf8.RuneSelf {
+ // Per RFC5280 "IA5String is limited to the set of ASCII characters"
+ if r > unicode.MaxASCII {
return fmt.Errorf("x509: %q cannot be encoded as an IA5String", s)
}
}
@@ -1721,7 +1712,8 @@ func buildExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId
if oid, ok := oidFromExtKeyUsage(u); ok {
oids = append(oids, oid)
} else {
- panic("internal error")
+ err = errors.New("x509: unknown extended key usage")
+ return
}
}
@@ -2015,7 +2007,7 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo SignatureAlgori
return
}
if requestedSigAlgo.isRSAPSS() {
- sigAlgo.Parameters = rsaPSSParameters(hashFunc)
+ sigAlgo.Parameters = hashToPSSParameters[hashFunc]
}
found = true
break