diff options
Diffstat (limited to 'libgo/go/crypto/tls/auth.go')
-rw-r--r-- | libgo/go/crypto/tls/auth.go | 73 |
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) } |