aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/crypto/tls/auth.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/crypto/tls/auth.go')
-rw-r--r--libgo/go/crypto/tls/auth.go73
1 files changed, 54 insertions, 19 deletions
diff --git a/libgo/go/crypto/tls/auth.go b/libgo/go/crypto/tls/auth.go
index 6fe9718..c62c9af 100644
--- a/libgo/go/crypto/tls/auth.go
+++ b/libgo/go/crypto/tls/auth.go
@@ -5,8 +5,10 @@
package tls
import (
+ "bytes"
"crypto"
"crypto/ecdsa"
+ "crypto/ed25519"
"crypto/elliptic"
"crypto/rsa"
"encoding/asn1"
@@ -38,6 +40,15 @@ func pickSignatureAlgorithm(pubkey crypto.PublicKey, peerSigAlgs, ourSigAlgs []S
}
case *ecdsa.PublicKey:
return ECDSAWithSHA1, signatureECDSA, crypto.SHA1, nil
+ case ed25519.PublicKey:
+ if tlsVersion < VersionTLS12 {
+ // RFC 8422 specifies support for Ed25519 in TLS 1.0 and 1.1,
+ // but it requires holding on to a handshake transcript to do a
+ // full signature, and not even OpenSSL bothers with the
+ // complexity, so we can't even test it properly.
+ return 0, 0, 0, fmt.Errorf("tls: Ed25519 public keys are not supported before TLS 1.2")
+ }
+ return Ed25519, signatureEd25519, directSigning, nil
default:
return 0, 0, 0, fmt.Errorf("tls: unsupported public key: %T", pubkey)
}
@@ -60,6 +71,10 @@ func pickSignatureAlgorithm(pubkey crypto.PublicKey, peerSigAlgs, ourSigAlgs []S
if sigType == signatureECDSA {
return sigAlg, sigType, hashAlg, nil
}
+ case ed25519.PublicKey:
+ if sigType == signatureEd25519 {
+ return sigAlg, sigType, hashAlg, nil
+ }
default:
return 0, 0, 0, fmt.Errorf("tls: unsupported public key: %T", pubkey)
}
@@ -67,9 +82,9 @@ func pickSignatureAlgorithm(pubkey crypto.PublicKey, peerSigAlgs, ourSigAlgs []S
return 0, 0, 0, errors.New("tls: peer doesn't support any common signature algorithms")
}
-// verifyHandshakeSignature verifies a signature against pre-hashed handshake
-// contents.
-func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc crypto.Hash, digest, sig []byte) error {
+// verifyHandshakeSignature verifies a signature against pre-hashed
+// (if required) handshake contents.
+func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc crypto.Hash, signed, sig []byte) error {
switch sigType {
case signatureECDSA:
pubKey, ok := pubkey.(*ecdsa.PublicKey)
@@ -83,15 +98,23 @@ func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc c
if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
return errors.New("tls: ECDSA signature contained zero or negative values")
}
- if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) {
+ if !ecdsa.Verify(pubKey, signed, ecdsaSig.R, ecdsaSig.S) {
return errors.New("tls: ECDSA verification failure")
}
+ case signatureEd25519:
+ pubKey, ok := pubkey.(ed25519.PublicKey)
+ if !ok {
+ return errors.New("tls: Ed25519 signing requires a Ed25519 public key")
+ }
+ if !ed25519.Verify(pubKey, signed, sig) {
+ return errors.New("tls: Ed25519 verification failure")
+ }
case signaturePKCS1v15:
pubKey, ok := pubkey.(*rsa.PublicKey)
if !ok {
return errors.New("tls: RSA signing requires a RSA public key")
}
- if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil {
+ if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, signed, sig); err != nil {
return err
}
case signatureRSAPSS:
@@ -100,7 +123,7 @@ func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc c
return errors.New("tls: RSA signing requires a RSA public key")
}
signOpts := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash}
- if err := rsa.VerifyPSS(pubKey, hashFunc, digest, sig, signOpts); err != nil {
+ if err := rsa.VerifyPSS(pubKey, hashFunc, signed, sig, signOpts); err != nil {
return err
}
default:
@@ -125,18 +148,29 @@ var signaturePadding = []byte{
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
}
-// writeSignedMessage writes the content to be signed by certificate keys in TLS
-// 1.3 to sigHash. See RFC 8446, Section 4.4.3.
-func writeSignedMessage(sigHash io.Writer, context string, transcript hash.Hash) {
- sigHash.Write(signaturePadding)
- io.WriteString(sigHash, context)
- sigHash.Write(transcript.Sum(nil))
+// signedMessage returns the pre-hashed (if necessary) message to be signed by
+// certificate keys in TLS 1.3. See RFC 8446, Section 4.4.3.
+func signedMessage(sigHash crypto.Hash, context string, transcript hash.Hash) []byte {
+ if sigHash == directSigning {
+ b := &bytes.Buffer{}
+ b.Write(signaturePadding)
+ io.WriteString(b, context)
+ b.Write(transcript.Sum(nil))
+ return b.Bytes()
+ }
+ h := sigHash.New()
+ h.Write(signaturePadding)
+ io.WriteString(h, context)
+ h.Write(transcript.Sum(nil))
+ return h.Sum(nil)
}
// signatureSchemesForCertificate returns the list of supported SignatureSchemes
-// for a given certificate, based on the public key and the protocol version. It
-// does not support the crypto.Decrypter interface, so shouldn't be used on the
-// server side in TLS 1.2 and earlier.
+// for a given certificate, based on the public key and the protocol version.
+//
+// It does not support the crypto.Decrypter interface, so shouldn't be used for
+// server certificates in TLS 1.2 and earlier, and it must be kept in sync with
+// supportedSignatureAlgorithms.
func signatureSchemesForCertificate(version uint16, cert *Certificate) []SignatureScheme {
priv, ok := cert.PrivateKey.(crypto.Signer)
if !ok {
@@ -168,21 +202,19 @@ func signatureSchemesForCertificate(version uint16, cert *Certificate) []Signatu
case *rsa.PublicKey:
if version != VersionTLS13 {
return []SignatureScheme{
- PSSWithSHA256,
- PSSWithSHA384,
- PSSWithSHA512,
PKCS1WithSHA256,
PKCS1WithSHA384,
PKCS1WithSHA512,
PKCS1WithSHA1,
}
}
- // RSA keys with RSA-PSS OID are not supported by crypto/x509.
return []SignatureScheme{
PSSWithSHA256,
PSSWithSHA384,
PSSWithSHA512,
}
+ case ed25519.PublicKey:
+ return []SignatureScheme{Ed25519}
default:
return nil
}
@@ -195,6 +227,8 @@ func unsupportedCertificateError(cert *Certificate) error {
case rsa.PrivateKey, ecdsa.PrivateKey:
return fmt.Errorf("tls: unsupported certificate: private key is %T, expected *%T",
cert.PrivateKey, cert.PrivateKey)
+ case *ed25519.PrivateKey:
+ return fmt.Errorf("tls: unsupported certificate: private key is *ed25519.PrivateKey, expected ed25519.PrivateKey")
}
signer, ok := cert.PrivateKey.(crypto.Signer)
@@ -213,6 +247,7 @@ func unsupportedCertificateError(cert *Certificate) error {
return fmt.Errorf("tls: unsupported certificate curve (%s)", pub.Curve.Params().Name)
}
case *rsa.PublicKey:
+ case ed25519.PublicKey:
default:
return fmt.Errorf("tls: unsupported certificate key (%T)", pub)
}