]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.boringcrypto] all: merge master into dev.boringcrypto
authorFilippo Valsorda <filippo@golang.org>
Wed, 22 May 2019 18:04:16 +0000 (14:04 -0400)
committerFilippo Valsorda <filippo@golang.org>
Tue, 28 May 2019 16:28:07 +0000 (12:28 -0400)
Change-Id: I0f610a900fcd5575ca12b34bc74fa63c2146b10b

18 files changed:
1  2 
src/cmd/compile/internal/gc/reflect.go
src/cmd/go/go_test.go
src/cmd/go/internal/load/pkg.go
src/cmd/link/internal/ld/lib.go
src/crypto/sha1/sha1_test.go
src/crypto/sha256/sha256_test.go
src/crypto/sha512/sha512_test.go
src/crypto/tls/boring.go
src/crypto/tls/boring_test.go
src/crypto/tls/cipher_suites.go
src/crypto/tls/common.go
src/crypto/tls/handshake_client.go
src/crypto/tls/handshake_client_tls13.go
src/crypto/tls/handshake_server.go
src/crypto/tls/handshake_server_tls13.go
src/crypto/tls/key_agreement.go
src/crypto/x509/verify.go
src/go/build/deps_test.go

index e85d3d25073f6a6e409e195566c868fff8d60b58,3fc147e1469a3db2d39ac0845c11ff29ffc9e295..bee9384d76c237d56f5c785a3b0cbf890366706a
@@@ -4203,56 -4237,17 +4237,21 @@@ func TestBinaryOnlyPackages(t *testing.
                import _ "fmt"
                func G()
        `)
-       tg.wantNotStale("p1", "binary-only package", "should NOT want to rebuild p1 (first)")
-       tg.run("install", "-x", "p1") // no-op, up to date
-       tg.grepBothNot(`[\\/]compile`, "should not have run compiler")
-       tg.run("install", "p2") // does not rebuild p1 (or else p2 will fail)
-       tg.wantNotStale("p2", "", "should NOT want to rebuild p2")
-       // changes to the non-source-code do not matter,
-       // and only one file needs the special comment.
-       tg.tempFile("src/p1/missing2.go", `
-               package p1
-               func H()
-       `)
-       tg.wantNotStale("p1", "binary-only package", "should NOT want to rebuild p1 (second)")
-       tg.wantNotStale("p2", "", "should NOT want to rebuild p2")
-       tg.tempFile("src/p3/p3.go", `
-               package main
-               import (
-                       "p1"
-                       "p2"
-               )
-               func main() {
-                       p1.F(false)
-                       p2.F()
-               }
-       `)
-       tg.run("install", "p3")
-       tg.run("run", tg.path("src/p3/p3.go"))
-       tg.grepStdout("hello from p1", "did not see message from p1")
-       tg.tempFile("src/p4/p4.go", `package main`)
-       // The odd string split below avoids vet complaining about
-       // a // +build line appearing too late in this source file.
-       tg.tempFile("src/p4/p4not.go", `//go:binary-only-package
-               /`+`/ +build asdf
+       tg.wantStale("p1", "binary-only package", "should NOT want to rebuild p1 (first)")
+       tg.runFail("install", "p2")
+       tg.grepStderr("p1: binary-only packages are no longer supported", "did not report error for binary-only p1")
  
-               package main
-       `)
-       tg.run("list", "-f", "{{.BinaryOnly}}", "p4")
-       tg.grepStdout("false", "did not see BinaryOnly=false for p4")
+       tg.run("list", "-deps", "-f", "{{.ImportPath}}: {{.BinaryOnly}}", "p2")
+       tg.grepStdout("p1: true", "p1 not listed as BinaryOnly")
+       tg.grepStdout("p2: false", "p2 listed as BinaryOnly")
  }
  
 -// Issue 16050.
 -func TestAlwaysLinkSysoFiles(t *testing.T) {
 +// Issue 16050 and 21884.
 +func TestLinkSysoFiles(t *testing.T) {
 +      if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
 +              t.Skip("not linux/amd64")
 +      }
 +
        tg := testgo(t)
        defer tg.cleanup()
        tg.parallel()
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index f6d922c673f5e99b9bfc3cee8d71723544912116,0000000000000000000000000000000000000000..95256b19f7b9626cc44633662013e9a7b874e2af
mode 100644,000000..100644
--- /dev/null
@@@ -1,121 -1,0 +1,128 @@@
- // It knows that the FIPS-allowed ones are all at the beginning of
- // defaultSupportedSignatureAlgorithms.
 +// Copyright 2017 The Go Authors. All rights reserved.
 +// Use of this source code is governed by a BSD-style
 +// license that can be found in the LICENSE file.
 +
 +package tls
 +
 +import (
 +      "crypto/ecdsa"
 +      "crypto/internal/boring/fipstls"
 +      "crypto/rsa"
 +      "crypto/x509"
 +)
 +
 +// needFIPS returns fipstls.Required(); it avoids a new import in common.go.
 +func needFIPS() bool {
 +      return fipstls.Required()
 +}
 +
 +// fipsMinVersion replaces c.minVersion in FIPS-only mode.
 +func fipsMinVersion(c *Config) uint16 {
 +      // FIPS requires TLS 1.2.
 +      return VersionTLS12
 +}
 +
 +// fipsMaxVersion replaces c.maxVersion in FIPS-only mode.
 +func fipsMaxVersion(c *Config) uint16 {
 +      // FIPS requires TLS 1.2.
 +      return VersionTLS12
 +}
 +
 +// default defaultFIPSCurvePreferences is the FIPS-allowed curves,
 +// in preference order (most preferable first).
 +var defaultFIPSCurvePreferences = []CurveID{CurveP256, CurveP384, CurveP521}
 +
 +// fipsCurvePreferences replaces c.curvePreferences in FIPS-only mode.
 +func fipsCurvePreferences(c *Config) []CurveID {
 +      if c == nil || len(c.CurvePreferences) == 0 {
 +              return defaultFIPSCurvePreferences
 +      }
 +      var list []CurveID
 +      for _, id := range c.CurvePreferences {
 +              for _, allowed := range defaultFIPSCurvePreferences {
 +                      if id == allowed {
 +                              list = append(list, id)
 +                              break
 +                      }
 +              }
 +      }
 +      return list
 +}
 +
 +// default FIPSCipherSuites is the FIPS-allowed cipher suites,
 +// in preference order (most preferable first).
 +var defaultFIPSCipherSuites = []uint16{
 +      TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
 +      TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
 +      TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
 +      TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
 +      TLS_RSA_WITH_AES_128_GCM_SHA256,
 +      TLS_RSA_WITH_AES_256_GCM_SHA384,
 +}
 +
 +// fipsCipherSuites replaces c.cipherSuites in FIPS-only mode.
 +func fipsCipherSuites(c *Config) []uint16 {
 +      if c == nil || c.CipherSuites == nil {
 +              return defaultFIPSCipherSuites
 +      }
 +      var list []uint16
 +      for _, id := range c.CipherSuites {
 +              for _, allowed := range defaultFIPSCipherSuites {
 +                      if id == allowed {
 +                              list = append(list, id)
 +                              break
 +                      }
 +              }
 +      }
 +      return list
 +}
 +
 +// isBoringCertificate reports whether a certificate may be used
 +// when constructing a verified chain.
 +// It is called for each leaf, intermediate, and root certificate.
 +func isBoringCertificate(c *x509.Certificate) bool {
 +      if !needFIPS() {
 +              // Everything is OK if we haven't forced FIPS-only mode.
 +              return true
 +      }
 +
 +      // Otherwise the key must be RSA 2048, RSA 3072, or ECDSA P-256.
 +      switch k := c.PublicKey.(type) {
 +      default:
 +              return false
 +      case *rsa.PublicKey:
 +              if size := k.N.BitLen(); size != 2048 && size != 3072 {
 +                      return false
 +              }
 +      case *ecdsa.PublicKey:
 +              if name := k.Curve.Params().Name; name != "P-256" && name != "P-384" {
 +                      return false
 +              }
 +      }
 +
 +      return true
 +}
 +
++// fipsSupportedSignatureAlgorithms currently are a subset of
++// defaultSupportedSignatureAlgorithms without Ed25519 and SHA-1.
++var fipsSupportedSignatureAlgorithms = []SignatureScheme{
++      PSSWithSHA256,
++      PSSWithSHA384,
++      PSSWithSHA512,
++      PKCS1WithSHA256,
++      ECDSAWithP256AndSHA256,
++      PKCS1WithSHA384,
++      ECDSAWithP384AndSHA384,
++      PKCS1WithSHA512,
++      ECDSAWithP521AndSHA512,
++}
++
 +// supportedSignatureAlgorithms returns the supported signature algorithms.
-       all := defaultSupportedSignatureAlgorithms
 +func supportedSignatureAlgorithms() []SignatureScheme {
-               return all
-       }
-       i := 0
-       for i < len(all) && all[i] != PKCS1WithSHA1 {
-               i++
 +      if !needFIPS() {
-       return all[:i]
++              return defaultSupportedSignatureAlgorithms
 +      }
++      return fipsSupportedSignatureAlgorithms
 +}
 +
 +var testingOnlyForceClientHelloSignatureAlgorithms []SignatureScheme
index 7a522c6a1fcdd5f75fbfc743dbc84bf75f0b3ca3,0000000000000000000000000000000000000000..c785c01fcc196d6e69e7e752019a8a2abdbd658f
mode 100644,000000..100644
--- /dev/null
@@@ -1,628 -1,0 +1,631 @@@
-                       return suite.flags&suiteECDSA == suiteECDSA
 +// Copyright 2017 The Go Authors. All rights reserved.
 +// Use of this source code is governed by a BSD-style
 +// license that can be found in the LICENSE file.
 +
 +package tls
 +
 +import (
 +      "crypto/ecdsa"
 +      "crypto/elliptic"
 +      "crypto/internal/boring/fipstls"
 +      "crypto/rand"
 +      "crypto/rsa"
 +      "crypto/x509"
 +      "crypto/x509/pkix"
 +      "encoding/pem"
 +      "fmt"
 +      "math/big"
 +      "net"
 +      "runtime"
 +      "strings"
 +      "testing"
 +      "time"
 +)
 +
 +func TestBoringServerProtocolVersion(t *testing.T) {
 +      test := func(name string, v uint16, msg string) {
 +              t.Run(name, func(t *testing.T) {
 +                      serverConfig := testConfig.Clone()
 +                      serverConfig.MinVersion = VersionSSL30
 +                      clientHello := &clientHelloMsg{
 +                              vers:               v,
 +                              random:             make([]byte, 32),
 +                              cipherSuites:       allCipherSuites(),
 +                              compressionMethods: []uint8{compressionNone},
 +                              supportedVersions:  []uint16{v},
 +                      }
 +                      testClientHelloFailure(t, serverConfig, clientHello, msg)
 +              })
 +      }
 +
 +      test("VersionSSL30", VersionSSL30, "")
 +      test("VersionTLS10", VersionTLS10, "")
 +      test("VersionTLS11", VersionTLS11, "")
 +      test("VersionTLS12", VersionTLS12, "")
 +      test("VersionTLS13", VersionTLS13, "")
 +
 +      fipstls.Force()
 +      defer fipstls.Abandon()
 +      test("VersionSSL30", VersionSSL30, "client offered only unsupported versions")
 +      test("VersionTLS10", VersionTLS10, "client offered only unsupported versions")
 +      test("VersionTLS11", VersionTLS11, "client offered only unsupported versions")
 +      test("VersionTLS12", VersionTLS12, "")
 +      test("VersionTLS13", VersionTLS13, "client offered only unsupported versions")
 +}
 +
 +func isBoringVersion(v uint16) bool {
 +      return v == VersionTLS12
 +}
 +
 +func isBoringCipherSuite(id uint16) bool {
 +      switch id {
 +      case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
 +              TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
 +              TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
 +              TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
 +              TLS_RSA_WITH_AES_128_GCM_SHA256,
 +              TLS_RSA_WITH_AES_256_GCM_SHA384:
 +              return true
 +      }
 +      return false
 +}
 +
 +func isBoringCurve(id CurveID) bool {
 +      switch id {
 +      case CurveP256, CurveP384, CurveP521:
 +              return true
 +      }
 +      return false
 +}
 +
 +func isECDSA(id uint16) bool {
 +      for _, suite := range cipherSuites {
 +              if suite.id == id {
-                               serverConfig.Certificates = make([]Certificate, 1)
++                      return suite.flags&suiteECSign == suiteECSign
 +              }
 +      }
 +      panic(fmt.Sprintf("unknown cipher suite %#x", id))
 +}
 +
 +func isBoringSignatureScheme(alg SignatureScheme) bool {
 +      switch alg {
 +      default:
 +              return false
 +      case PKCS1WithSHA256,
 +              ECDSAWithP256AndSHA256,
 +              PKCS1WithSHA384,
 +              ECDSAWithP384AndSHA384,
 +              PKCS1WithSHA512,
 +              ECDSAWithP521AndSHA512,
 +              PSSWithSHA256,
 +              PSSWithSHA384,
 +              PSSWithSHA512:
 +              // ok
 +      }
 +      return true
 +}
 +
 +func TestBoringServerCipherSuites(t *testing.T) {
 +      serverConfig := testConfig.Clone()
 +      serverConfig.CipherSuites = allCipherSuites()
 +      serverConfig.Certificates = make([]Certificate, 1)
 +
 +      for _, id := range allCipherSuites() {
 +              if isECDSA(id) {
 +                      serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
 +                      serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
 +              } else {
 +                      serverConfig.Certificates[0].Certificate = [][]byte{testRSACertificate}
 +                      serverConfig.Certificates[0].PrivateKey = testRSAPrivateKey
 +              }
 +              serverConfig.BuildNameToCertificate()
 +              t.Run(fmt.Sprintf("suite=%#x", id), func(t *testing.T) {
 +                      clientHello := &clientHelloMsg{
 +                              vers:               VersionTLS12,
 +                              random:             make([]byte, 32),
 +                              cipherSuites:       []uint16{id},
 +                              compressionMethods: []uint8{compressionNone},
 +                              supportedCurves:    defaultCurvePreferences,
 +                              supportedPoints:    []uint8{pointFormatUncompressed},
 +                      }
 +
 +                      testClientHello(t, serverConfig, clientHello)
 +                      t.Run("fipstls", func(t *testing.T) {
 +                              fipstls.Force()
 +                              defer fipstls.Abandon()
 +                              msg := ""
 +                              if !isBoringCipherSuite(id) {
 +                                      msg = "no cipher suite supported by both client and server"
 +                              }
 +                              testClientHelloFailure(t, serverConfig, clientHello, msg)
 +                      })
 +              })
 +      }
 +}
 +
 +func TestBoringServerCurves(t *testing.T) {
 +      serverConfig := testConfig.Clone()
 +      serverConfig.Certificates = make([]Certificate, 1)
 +      serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
 +      serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
 +      serverConfig.BuildNameToCertificate()
 +
 +      for _, curveid := range defaultCurvePreferences {
 +              t.Run(fmt.Sprintf("curve=%d", curveid), func(t *testing.T) {
 +                      clientHello := &clientHelloMsg{
 +                              vers:               VersionTLS12,
 +                              random:             make([]byte, 32),
 +                              cipherSuites:       []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
 +                              compressionMethods: []uint8{compressionNone},
 +                              supportedCurves:    []CurveID{curveid},
 +                              supportedPoints:    []uint8{pointFormatUncompressed},
 +                      }
 +
 +                      testClientHello(t, serverConfig, clientHello)
 +
 +                      // With fipstls forced, bad curves should be rejected.
 +                      t.Run("fipstls", func(t *testing.T) {
 +                              fipstls.Force()
 +                              defer fipstls.Abandon()
 +                              msg := ""
 +                              if !isBoringCurve(curveid) {
 +                                      msg = "no cipher suite supported by both client and server"
 +                              }
 +                              testClientHelloFailure(t, serverConfig, clientHello, msg)
 +                      })
 +              })
 +      }
 +}
 +
 +func boringHandshake(t *testing.T, clientConfig, serverConfig *Config) (clientErr, serverErr error) {
 +      c, s := localPipe(t)
 +      client := Client(c, clientConfig)
 +      server := Server(s, serverConfig)
 +      done := make(chan error, 1)
 +      go func() {
 +              done <- client.Handshake()
 +              c.Close()
 +      }()
 +      serverErr = server.Handshake()
 +      s.Close()
 +      clientErr = <-done
 +      return
 +}
 +
 +func TestBoringServerSignatureAndHash(t *testing.T) {
 +      serverConfig := testConfig.Clone()
 +      serverConfig.Certificates = make([]Certificate, 1)
 +
 +      defer func() {
 +              testingOnlyForceClientHelloSignatureAlgorithms = nil
 +      }()
 +
 +      for _, sigHash := range defaultSupportedSignatureAlgorithms {
 +              testingOnlyForceClientHelloSignatureAlgorithms = []SignatureScheme{sigHash}
 +
 +              t.Run(fmt.Sprintf("%#x", sigHash), func(t *testing.T) {
 +                      switch sigHash {
 +                      case PKCS1WithSHA1, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512,
 +                              PSSWithSHA256, PSSWithSHA384, PSSWithSHA512:
 +                              serverConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}
 +                              serverConfig.Certificates[0].Certificate = [][]byte{testRSA2048Certificate}
 +                              serverConfig.Certificates[0].PrivateKey = testRSA2048PrivateKey
++                      case Ed25519:
++                              serverConfig.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}
++                              serverConfig.Certificates[0].Certificate = [][]byte{testEd25519Certificate}
++                              serverConfig.Certificates[0].PrivateKey = testEd25519PrivateKey
 +                      default:
 +                              serverConfig.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}
 +                              serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
 +                              serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
 +                      }
 +                      serverConfig.BuildNameToCertificate()
 +                      // PKCS#1 v1.5 signature algorithms can't be used standalone in TLS
 +                      // 1.3, and the ECDSA ones bind to the curve used.
 +                      serverConfig.MaxVersion = VersionTLS12
 +
 +                      clientErr, serverErr := boringHandshake(t, testConfig, serverConfig)
 +                      if clientErr != nil {
 +                              t.Fatalf("expected handshake with %#x to succeed; client error: %v; server error: %v", sigHash, clientErr, serverErr)
 +                      }
 +
 +                      // With fipstls forced, bad curves should be rejected.
 +                      t.Run("fipstls", func(t *testing.T) {
 +                              fipstls.Force()
 +                              defer fipstls.Abandon()
 +                              clientErr, _ := boringHandshake(t, testConfig, serverConfig)
 +                              if isBoringSignatureScheme(sigHash) {
 +                                      if clientErr != nil {
 +                                              t.Fatalf("expected handshake with %#x to succeed; err=%v", sigHash, clientErr)
 +                                      }
 +                              } else {
 +                                      if clientErr == nil {
 +                                              t.Fatalf("expected handshake with %#x to fail, but it succeeded", sigHash)
 +                                      }
 +                              }
 +                      })
 +              })
 +      }
 +}
 +
 +func TestBoringClientHello(t *testing.T) {
 +      // Test that no matter what we put in the client config,
 +      // the client does not offer non-FIPS configurations.
 +      fipstls.Force()
 +      defer fipstls.Abandon()
 +
 +      c, s := net.Pipe()
 +      defer c.Close()
 +      defer s.Close()
 +
 +      clientConfig := testConfig.Clone()
 +      // All sorts of traps for the client to avoid.
 +      clientConfig.MinVersion = VersionSSL30
 +      clientConfig.MaxVersion = VersionTLS13
 +      clientConfig.CipherSuites = allCipherSuites()
 +      clientConfig.CurvePreferences = defaultCurvePreferences
 +
 +      go Client(c, testConfig).Handshake()
 +      srv := Server(s, testConfig)
 +      msg, err := srv.readHandshake()
 +      if err != nil {
 +              t.Fatal(err)
 +      }
 +      hello, ok := msg.(*clientHelloMsg)
 +      if !ok {
 +              t.Fatalf("unexpected message type %T", msg)
 +      }
 +
 +      if !isBoringVersion(hello.vers) {
 +              t.Errorf("client vers=%#x, want %#x (TLS 1.2)", hello.vers, VersionTLS12)
 +      }
 +      for _, v := range hello.supportedVersions {
 +              if !isBoringVersion(v) {
 +                      t.Errorf("client offered disallowed version %#x", v)
 +              }
 +      }
 +      for _, id := range hello.cipherSuites {
 +              if !isBoringCipherSuite(id) {
 +                      t.Errorf("client offered disallowed suite %#x", id)
 +              }
 +      }
 +      for _, id := range hello.supportedCurves {
 +              if !isBoringCurve(id) {
 +                      t.Errorf("client offered disallowed curve %d", id)
 +              }
 +      }
 +      for _, sigHash := range hello.supportedSignatureAlgorithms {
 +              if !isBoringSignatureScheme(sigHash) {
 +                      t.Errorf("client offered disallowed signature-and-hash %v", sigHash)
 +              }
 +      }
 +}
 +
 +func TestBoringCertAlgs(t *testing.T) {
 +      // NaCl, arm and wasm time out generating keys. Nothing in this test is architecture-specific, so just don't bother on those.
 +      if runtime.GOOS == "nacl" || runtime.GOARCH == "arm" || runtime.GOOS == "js" {
 +              t.Skipf("skipping on %s/%s because key generation takes too long", runtime.GOOS, runtime.GOARCH)
 +      }
 +
 +      // Set up some roots, intermediate CAs, and leaf certs with various algorithms.
 +      // X_Y is X signed by Y.
 +      R1 := boringCert(t, "R1", boringRSAKey(t, 2048), nil, boringCertCA|boringCertFIPSOK)
 +      R2 := boringCert(t, "R2", boringRSAKey(t, 4096), nil, boringCertCA)
 +
 +      M1_R1 := boringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), R1, boringCertCA|boringCertFIPSOK)
 +      M2_R1 := boringCert(t, "M2_R1", boringECDSAKey(t, elliptic.P224()), R1, boringCertCA)
 +
 +      I_R1 := boringCert(t, "I_R1", boringRSAKey(t, 3072), R1, boringCertCA|boringCertFIPSOK)
 +      I_R2 := boringCert(t, "I_R2", I_R1.key, R2, boringCertCA|boringCertFIPSOK)
 +      I_M1 := boringCert(t, "I_M1", I_R1.key, M1_R1, boringCertCA|boringCertFIPSOK)
 +      I_M2 := boringCert(t, "I_M2", I_R1.key, M2_R1, boringCertCA|boringCertFIPSOK)
 +
 +      L1_I := boringCert(t, "L1_I", boringECDSAKey(t, elliptic.P384()), I_R1, boringCertLeaf|boringCertFIPSOK)
 +      L2_I := boringCert(t, "L2_I", boringRSAKey(t, 1024), I_R1, boringCertLeaf)
 +
 +      // boringCert checked that isBoringCertificate matches the caller's boringCertFIPSOK bit.
 +      // If not, no point in building bigger end-to-end tests.
 +      if t.Failed() {
 +              t.Fatalf("isBoringCertificate failures; not continuing")
 +      }
 +
 +      // client verifying server cert
 +      testServerCert := func(t *testing.T, desc string, pool *x509.CertPool, key interface{}, list [][]byte, ok bool) {
 +              clientConfig := testConfig.Clone()
 +              clientConfig.RootCAs = pool
 +              clientConfig.InsecureSkipVerify = false
 +              clientConfig.ServerName = "example.com"
 +
 +              serverConfig := testConfig.Clone()
 +              serverConfig.Certificates = []Certificate{{Certificate: list, PrivateKey: key}}
 +              serverConfig.BuildNameToCertificate()
 +
 +              clientErr, _ := boringHandshake(t, clientConfig, serverConfig)
 +
 +              if (clientErr == nil) == ok {
 +                      if ok {
 +                              t.Logf("%s: accept", desc)
 +                      } else {
 +                              t.Logf("%s: reject", desc)
 +                      }
 +              } else {
 +                      if ok {
 +                              t.Errorf("%s: BAD reject (%v)", desc, clientErr)
 +                      } else {
 +                              t.Errorf("%s: BAD accept", desc)
 +                      }
 +              }
 +      }
 +
 +      // server verifying client cert
 +      testClientCert := func(t *testing.T, desc string, pool *x509.CertPool, key interface{}, list [][]byte, ok bool) {
 +              clientConfig := testConfig.Clone()
 +              clientConfig.ServerName = "example.com"
 +              clientConfig.Certificates = []Certificate{{Certificate: list, PrivateKey: key}}
 +
 +              serverConfig := testConfig.Clone()
 +              serverConfig.ClientCAs = pool
 +              serverConfig.ClientAuth = RequireAndVerifyClientCert
 +
 +              _, serverErr := boringHandshake(t, clientConfig, serverConfig)
 +
 +              if (serverErr == nil) == ok {
 +                      if ok {
 +                              t.Logf("%s: accept", desc)
 +                      } else {
 +                              t.Logf("%s: reject", desc)
 +                      }
 +              } else {
 +                      if ok {
 +                              t.Errorf("%s: BAD reject (%v)", desc, serverErr)
 +                      } else {
 +                              t.Errorf("%s: BAD accept", desc)
 +                      }
 +              }
 +      }
 +
 +      // Run simple basic test with known answers before proceeding to
 +      // exhaustive test with computed answers.
 +      r1pool := x509.NewCertPool()
 +      r1pool.AddCert(R1.cert)
 +      testServerCert(t, "basic", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true)
 +      testClientCert(t, "basic (client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true)
 +      fipstls.Force()
 +      testServerCert(t, "basic (fips)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false)
 +      testClientCert(t, "basic (fips, client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false)
 +      fipstls.Abandon()
 +
 +      if t.Failed() {
 +              t.Fatal("basic test failed, skipping exhaustive test")
 +      }
 +
 +      if testing.Short() {
 +              t.Logf("basic test passed; skipping exhaustive test in -short mode")
 +              return
 +      }
 +
 +      for l := 1; l <= 2; l++ {
 +              leaf := L1_I
 +              if l == 2 {
 +                      leaf = L2_I
 +              }
 +              for i := 0; i < 64; i++ {
 +                      reachable := map[string]bool{leaf.parentOrg: true}
 +                      reachableFIPS := map[string]bool{leaf.parentOrg: leaf.fipsOK}
 +                      list := [][]byte{leaf.der}
 +                      listName := leaf.name
 +                      addList := func(cond int, c *boringCertificate) {
 +                              if cond != 0 {
 +                                      list = append(list, c.der)
 +                                      listName += "," + c.name
 +                                      if reachable[c.org] {
 +                                              reachable[c.parentOrg] = true
 +                                      }
 +                                      if reachableFIPS[c.org] && c.fipsOK {
 +                                              reachableFIPS[c.parentOrg] = true
 +                                      }
 +                              }
 +                      }
 +                      addList(i&1, I_R1)
 +                      addList(i&2, I_R2)
 +                      addList(i&4, I_M1)
 +                      addList(i&8, I_M2)
 +                      addList(i&16, M1_R1)
 +                      addList(i&32, M2_R1)
 +
 +                      for r := 1; r <= 3; r++ {
 +                              pool := x509.NewCertPool()
 +                              rootName := ","
 +                              shouldVerify := false
 +                              shouldVerifyFIPS := false
 +                              addRoot := func(cond int, c *boringCertificate) {
 +                                      if cond != 0 {
 +                                              rootName += "," + c.name
 +                                              pool.AddCert(c.cert)
 +                                              if reachable[c.org] {
 +                                                      shouldVerify = true
 +                                              }
 +                                              if reachableFIPS[c.org] && c.fipsOK {
 +                                                      shouldVerifyFIPS = true
 +                                              }
 +                                      }
 +                              }
 +                              addRoot(r&1, R1)
 +                              addRoot(r&2, R2)
 +                              rootName = rootName[1:] // strip leading comma
 +                              testServerCert(t, listName+"->"+rootName[1:], pool, leaf.key, list, shouldVerify)
 +                              testClientCert(t, listName+"->"+rootName[1:]+"(client cert)", pool, leaf.key, list, shouldVerify)
 +                              fipstls.Force()
 +                              testServerCert(t, listName+"->"+rootName[1:]+" (fips)", pool, leaf.key, list, shouldVerifyFIPS)
 +                              testClientCert(t, listName+"->"+rootName[1:]+" (fips, client cert)", pool, leaf.key, list, shouldVerifyFIPS)
 +                              fipstls.Abandon()
 +                      }
 +              }
 +      }
 +}
 +
 +const (
 +      boringCertCA = iota
 +      boringCertLeaf
 +      boringCertFIPSOK = 0x80
 +)
 +
 +func boringRSAKey(t *testing.T, size int) *rsa.PrivateKey {
 +      k, err := rsa.GenerateKey(rand.Reader, size)
 +      if err != nil {
 +              t.Fatal(err)
 +      }
 +      return k
 +}
 +
 +func boringECDSAKey(t *testing.T, curve elliptic.Curve) *ecdsa.PrivateKey {
 +      k, err := ecdsa.GenerateKey(curve, rand.Reader)
 +      if err != nil {
 +              t.Fatal(err)
 +      }
 +      return k
 +}
 +
 +type boringCertificate struct {
 +      name      string
 +      org       string
 +      parentOrg string
 +      der       []byte
 +      cert      *x509.Certificate
 +      key       interface{}
 +      fipsOK    bool
 +}
 +
 +func boringCert(t *testing.T, name string, key interface{}, parent *boringCertificate, mode int) *boringCertificate {
 +      org := name
 +      parentOrg := ""
 +      if i := strings.Index(org, "_"); i >= 0 {
 +              org = org[:i]
 +              parentOrg = name[i+1:]
 +      }
 +      tmpl := &x509.Certificate{
 +              SerialNumber: big.NewInt(1),
 +              Subject: pkix.Name{
 +                      Organization: []string{org},
 +              },
 +              NotBefore: time.Unix(0, 0),
 +              NotAfter:  time.Unix(0, 0),
 +
 +              KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
 +              ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
 +              BasicConstraintsValid: true,
 +      }
 +      if mode&^boringCertFIPSOK == boringCertLeaf {
 +              tmpl.DNSNames = []string{"example.com"}
 +      } else {
 +              tmpl.IsCA = true
 +              tmpl.KeyUsage |= x509.KeyUsageCertSign
 +      }
 +
 +      var pcert *x509.Certificate
 +      var pkey interface{}
 +      if parent != nil {
 +              pcert = parent.cert
 +              pkey = parent.key
 +      } else {
 +              pcert = tmpl
 +              pkey = key
 +      }
 +
 +      var pub interface{}
 +      var desc string
 +      switch k := key.(type) {
 +      case *rsa.PrivateKey:
 +              pub = &k.PublicKey
 +              desc = fmt.Sprintf("RSA-%d", k.N.BitLen())
 +      case *ecdsa.PrivateKey:
 +              pub = &k.PublicKey
 +              desc = "ECDSA-" + k.Curve.Params().Name
 +      default:
 +              t.Fatalf("invalid key %T", key)
 +      }
 +
 +      der, err := x509.CreateCertificate(rand.Reader, tmpl, pcert, pub, pkey)
 +      if err != nil {
 +              t.Fatal(err)
 +      }
 +      cert, err := x509.ParseCertificate(der)
 +      if err != nil {
 +              t.Fatal(err)
 +      }
 +
 +      // Tell isBoringCertificate to enforce FIPS restrictions for this check.
 +      fipstls.Force()
 +      defer fipstls.Abandon()
 +
 +      fipsOK := mode&boringCertFIPSOK != 0
 +      if isBoringCertificate(cert) != fipsOK {
 +              t.Errorf("isBoringCertificate(cert with %s key) = %v, want %v", desc, !fipsOK, fipsOK)
 +      }
 +      return &boringCertificate{name, org, parentOrg, der, cert, key, fipsOK}
 +}
 +
 +// A self-signed test certificate with an RSA key of size 2048, for testing
 +// RSA-PSS with SHA512. SAN of example.golang.
 +var (
 +      testRSA2048Certificate []byte
 +      testRSA2048PrivateKey  *rsa.PrivateKey
 +)
 +
 +func init() {
 +      block, _ := pem.Decode([]byte(`
 +-----BEGIN CERTIFICATE-----
 +MIIC/zCCAeegAwIBAgIRALHHX/kh4+4zMU9DarzBEcQwDQYJKoZIhvcNAQELBQAw
 +EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xMTAxMDExNTA0MDVaFw0yMDEyMjkxNTA0
 +MDVaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
 +ggEKAoIBAQCf8fk0N6ieCBX4IOVIfKitt4kGcOQLeimCfsjqqHcysMIVGEtFSM6E
 +4Ay141f/7IqdW0UtIqNb4PXhROID7yDxR284xL6XbCuv/t5hP3UcehYc3hmLiyVd
 +MkZQiZWtfUUJf/1qOtM+ohNg59LRWp4d+6iX0la1JL3EwCIckkNjJ9hQbF7Pb2CS
 ++ES9Yo55KAap8KOblpcR8MBSN38bqnwjfQdCXvOEOjam2HUxKzEFX5MA+fA0me4C
 +ioCcCRLWKl+GoN9F8fABfoZ+T+2eal4DLuO95rXR8SrOIVBh3XFOr/RVhjtXcNVF
 +ZKcvDt6d68V6jAKAYKm5nlj9GPpd4v+rAgMBAAGjUDBOMA4GA1UdDwEB/wQEAwIF
 +oDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBkGA1UdEQQSMBCC
 +DmV4YW1wbGUuZ29sYW5nMA0GCSqGSIb3DQEBCwUAA4IBAQCOoYsVcFCBhboqe3WH
 +dC6V7XXXECmnjh01r8h80yv0NR379nSD3cw2M+HKvaXysWqrl5hjGVKw0vtwD81r
 +V4JzDu7IfIog5m8+QNC+7LqDZsz88vDKOrsoySVOmUCgmCKFXew+LA+eO/iQEJTr
 +7ensddOeXJEp27Ed5vW+kmWW3Qmglc2Gwy8wFrMDIqnrnOzBA4oCnDEgtXJt0zog
 +nRwbfEMAWi1aQRy5dT9KA3SP9mo5SeTFSzGGHiE4s4gHUe7jvsAFF2qgtD6+wH6s
 +z9b6shxnC7g5IlBKhI7SVB/Uqt2ydJ+kH1YbjMcIq6NAM5eNMKgZuJr3+zwsSgwh
 +GNaE
 +-----END CERTIFICATE-----`))
 +      testRSA2048Certificate = block.Bytes
 +
 +      block, _ = pem.Decode([]byte(`
 +-----BEGIN RSA PRIVATE KEY-----
 +MIIEpAIBAAKCAQEAn/H5NDeonggV+CDlSHyorbeJBnDkC3opgn7I6qh3MrDCFRhL
 +RUjOhOAMteNX/+yKnVtFLSKjW+D14UTiA+8g8UdvOMS+l2wrr/7eYT91HHoWHN4Z
 +i4slXTJGUImVrX1FCX/9ajrTPqITYOfS0VqeHfuol9JWtSS9xMAiHJJDYyfYUGxe
 +z29gkvhEvWKOeSgGqfCjm5aXEfDAUjd/G6p8I30HQl7zhDo2pth1MSsxBV+TAPnw
 +NJnuAoqAnAkS1ipfhqDfRfHwAX6Gfk/tnmpeAy7jvea10fEqziFQYd1xTq/0VYY7
 +V3DVRWSnLw7enevFeowCgGCpuZ5Y/Rj6XeL/qwIDAQABAoIBAQCNpMZifd/vg42h
 +HdCvLuZaYS0R7SunFlpoXEsltGdLFsnp0IfoJZ/ugFQBSAIIfLwMumU6oXA1z7Uv
 +98aIYV61DePrTCDVDFBsHbNmP8JAo8WtbusEbwd5zyoB7LYG2+clkJklWE73KqUq
 +rmI+UJeyScl2Gin7ZTxBXz1WPBk9VwcnwkeaXpgASIBW23fhECM9gnYEEwaBez5T
 +6Me8d1tHtYQv7vsKe7ro9w9/HKrRXejqYKK1LxkhfFriyV+m8LZJZn2nXOa6G3gF
 +Nb8Qk1Uk5PUBENBmyMFJhT4M/uuSq4YtMrrO2gi8Q+fPhuGzc5SshYKRBp0W4P5r
 +mtVCtEFRAoGBAMENBIFLrV2+HsGj0xYFasKov/QPe6HSTR1Hh2IZONp+oK4oszWE
 +jBT4VcnITmpl6tC1Wy4GcrxjNgKIFZAj+1x1LUULdorXkuG8yr0tAhG9zNyfWsSy
 +PrSovC0UVbzr8Jxxla+kQVxEQQqWQxPlEVuL8kXaIDA6Lyt1Hpua2LvPAoGBANQZ
 +c6Lq2T7+BxLxNdi2m8kZzej5kgzBp/XdVsbFWRlebIX2KrFHsrHzT9PUk3DE1vZK
 +M6pzTt94nQhWSkDgCaw1SohElJ3HFIFwcusF1SJAc3pQepd8ug6IYdlpDMLtBj/P
 +/5P6BVUtgo05E4+I/T3iYatmglQxTtlZ0RkSV2llAoGBALOXkKFX7ahPvf0WksDh
 +uTfuFOTPoowgQG0EpgW0wRdCxeg/JLic3lSD0gsttQV2WsRecryWcxaelRg10RmO
 +38BbogmhaF4xvgsSvujOfiZTE8oK1T43M+6NKsIlML3YILbpU/9aJxPWy0s2DqDr
 +cQJhZrlk+pzjBA7Bnf/URdwxAoGAKR/CNw14D+mrL3YLbbiCXiydqxVwxv5pdZdz
 +8thi3TNcsWC4iGURdcVqbfUinVPdJiXe/Kac3WGCeRJaFVgbKAOxLti1RB5MkIhg
 +D8eyupBqk4W1L1gkrxqsdj4TFlxkwMywjl2E2S4YyQ8PBt6V04DoVRZsIKzqz+PF
 +UionPq0CgYBCYXvqioJhPewkOq/Y5wrDBeZW1FQK5QD9W5M8/5zxd4rdvJtjhbJp
 +oOrtvMdrl6upy9Hz4BJD3FXwVFiPFE7jqeNqi0F21viLxBPMMD3UODF6LL5EyLiR
 +9V4xVMS8KXxvg7rxsuqzMPscViaWUL6WNVBhsD2+92dHxSXzz5EJKQ==
 +-----END RSA PRIVATE KEY-----`))
 +      var err error
 +      testRSA2048PrivateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
 +      if err != nil {
 +              panic(err)
 +      }
 +}
Simple merge
index 6e3a8416f81c1480b152c5568680108c822d70aa,2949994ee667ec42275742ea409af0d56fe2f36a..9d501eca4a27e621f3812040c3625612e3e2364a
@@@ -150,23 -149,31 +150,31 @@@ const 
  // Certificate types (for certificateRequestMsg)
  const (
        certTypeRSASign   = 1
-       certTypeECDSASign = 64 // RFC 4492, Section 5.5
+       certTypeECDSASign = 64 // ECDSA or EdDSA keys, see RFC 8422, Section 3.
  )
  
- // Signature algorithms (for internal signaling use). Starting at 16 to avoid overlap with
+ // Signature algorithms (for internal signaling use). Starting at 225 to avoid overlap with
  // TLS 1.2 codepoints (RFC 5246, Appendix A.4.1), with which these have nothing to do.
  const (
-       signaturePKCS1v15 uint8 = iota + 16
-       signatureECDSA
+       signaturePKCS1v15 uint8 = iota + 225
        signatureRSAPSS
+       signatureECDSA
+       signatureEd25519
  )
  
 -// supportedSignatureAlgorithms contains the signature and hash algorithms that
+ // directSigning is a standard Hash value that signals that no pre-hashing
+ // should be performed, and that the input should be signed directly. It is the
+ // hash function associated with the Ed25519 signature scheme.
+ var directSigning crypto.Hash = 0
 +// defaultSupportedSignatureAlgorithms contains the signature and hash algorithms that
  // the code advertises as supported in a TLS 1.2+ ClientHello and in a TLS 1.2+
  // CertificateRequest. The two fields are merged to match with TLS 1.3.
  // Note that in TLS 1.2, the ECDSA algorithms are not constrained to P-256, etc.
 -var supportedSignatureAlgorithms = []SignatureScheme{
 +var defaultSupportedSignatureAlgorithms = []SignatureScheme{
        PSSWithSHA256,
+       ECDSAWithP256AndSHA256,
+       Ed25519,
        PSSWithSHA384,
        PSSWithSHA512,
        PKCS1WithSHA256,
Simple merge
Simple merge
Simple merge
Simple merge
index 14616d8ae24bfe0982567c8e35efc9d1cea809f6,709c43a52a611ce4c1d7478521e2fd4bc356dd64..83010bcaa3559039557c595ad049509ec6998305
@@@ -117,13 -119,8 +119,13 @@@ var pkgDeps = map[string][]string
        "image/color/palette":    {"L2", "image/color"},
        "internal/fmtsort":       {"reflect", "sort"},
        "reflect":                {"L2"},
-       "sort":                   {"reflect"},
+       "sort":                   {"internal/reflectlite"},
  
 +      "crypto/internal/boring":         {"L2", "C", "crypto", "crypto/cipher", "crypto/internal/boring/sig", "crypto/subtle", "encoding/asn1", "hash", "math/big"},
 +      "crypto/internal/boring/fipstls": {"sync/atomic"},
 +      "crypto/internal/cipherhw":       {"crypto/internal/boring"},
 +      "crypto/tls/fipsonly":            {"crypto/internal/boring/fipstls", "crypto/internal/boring/sig"},
 +
        "L3": {
                "L2",
                "crypto",