"cmd/compile/internal/base"
"cmd/compile/internal/bitvec"
+ "cmd/compile/internal/compare"
"cmd/compile/internal/escape"
"cmd/compile/internal/inline"
"cmd/compile/internal/ir"
if t.Sym() != nil && t.Sym().Name != "" {
tflag |= tflagNamed
}
- if isRegularMemory(t) {
+ if compare.IsRegularMemory(t) {
tflag |= tflagRegularMemory
}
// for security, only the exported fields.
case types.TSTRUCT:
fields := t.Fields().Slice()
+
+ // omitFieldForAwfulBoringCryptoKludge reports whether
+ // the field t should be omitted from the reflect data.
+ // In the crypto/... packages we omit an unexported field
+ // named "boring", to keep from breaking client code that
+ // expects rsa.PublicKey etc to have only public fields.
+ // As the name suggests, this is an awful kludge, but it is
+ // limited to the dev.boringcrypto branch and avoids
+ // much more invasive effects elsewhere.
+ omitFieldForAwfulBoringCryptoKludge := func(t *types.Field) bool {
+ if t.Sym == nil || t.Sym.Name != "boring" || t.Sym.Pkg == nil {
+ return false
+ }
+ path := t.Sym.Pkg.Path
+ if t.Sym.Pkg == types.LocalPkg {
+ path = base.Ctxt.Pkgpath
+ }
+ return strings.HasPrefix(path, "crypto/")
+ }
+ newFields := fields[:0:0]
+ for _, t1 := range fields {
+ if !omitFieldForAwfulBoringCryptoKludge(t1) {
+ newFields = append(newFields, t1)
+ }
+ }
+ fields = newFields
+
for _, t1 := range fields {
writeType(t1.Type)
}
p.SwigFiles = pp.SwigFiles
p.SwigCXXFiles = pp.SwigCXXFiles
p.SysoFiles = pp.SysoFiles
+ if cfg.BuildMSan {
+ // There's no way for .syso files to be built both with and without
+ // support for memory sanitizer. Assume they are built without,
+ // and drop them.
+ p.SysoFiles = nil
+ }
p.CgoCFLAGS = pp.CgoCFLAGS
p.CgoCPPFLAGS = pp.CgoCPPFLAGS
p.CgoCXXFLAGS = pp.CgoCXXFLAGS
}
}
p.Internal.Imports = imports
- p.collectDeps()
+ if !opts.SuppressDeps {
+ p.collectDeps()
+ }
if p.Error == nil && p.Name == "main" && !p.Internal.ForceLibrary && len(p.DepsErrors) == 0 {
// TODO(bcmills): loading VCS metadata can be fairly slow.
// Consider starting this as a background goroutine and retrieving the result
// LoadVCS controls whether we also load version-control metadata for main packages.
LoadVCS bool
+
+ // NeedDepsFields is true if the caller does not need Deps and DepsErrors to be populated
+ // on the package. TestPackagesAndErrors examines the Deps field to determine if the test
+ // variant has an import cycle, so SuppressDeps should not be set if TestPackagesAndErrors
+ // will be called on the package.
+ SuppressDeps bool
}
// PackagesAndErrors returns the packages named by the command line arguments
"golang.org/x/crypto/cryptobyte/asn1"
)
+import (
+ "crypto/internal/boring"
+ "unsafe"
+)
+
// A invertible implements fast inverse in GF(N).
type invertible interface {
// Inverse returns the inverse of k mod Params().N.
type PublicKey struct {
elliptic.Curve
X, Y *big.Int
+
+ boring unsafe.Pointer
}
// Any methods implemented on PublicKey might need to also be implemented on
type PrivateKey struct {
PublicKey
D *big.Int
+
+ boring unsafe.Pointer
}
// Public returns the public key corresponding to priv.
// where the private part is kept in, for example, a hardware module. Common
// uses can use the SignASN1 function in this package directly.
func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
+ if boring.Enabled && rand == boring.RandReader {
+ b, err := boringPrivateKey(priv)
+ if err != nil {
+ return nil, err
+ }
+ return boring.SignMarshalECDSA(b, digest)
+ }
+ boring.UnreachableExceptTests()
+
r, s, err := Sign(rand, priv, digest)
if err != nil {
return nil, err
params := c.Params()
// Note that for P-521 this will actually be 63 bits more than the order, as
// division rounds down, but the extra bit is inconsequential.
- b := make([]byte, params.BitSize/8+8) // TODO: use params.N.BitLen()
+ b := make([]byte, params.N.BitLen()/8+8)
_, err = io.ReadFull(rand, b)
if err != nil {
return
// GenerateKey generates a public and private key pair.
func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) {
+ if boring.Enabled && rand == boring.RandReader {
+ x, y, d, err := boring.GenerateKeyECDSA(c.Params().Name)
+ if err != nil {
+ return nil, err
+ }
+ return &PrivateKey{PublicKey: PublicKey{Curve: c, X: x, Y: y}, D: d}, nil
+ }
+ boring.UnreachableExceptTests()
+
k, err := randFieldElement(c, rand)
if err != nil {
return nil, err
func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
randutil.MaybeReadByte(rand)
+ if boring.Enabled && rand == boring.RandReader {
+ b, err := boringPrivateKey(priv)
+ if err != nil {
+ return nil, nil, err
+ }
+ return boring.SignECDSA(b, hash)
+ }
+ boring.UnreachableExceptTests()
+
// This implementation derives the nonce from an AES-CTR CSPRNG keyed by:
//
// SHA2-512(priv.D || entropy || hash)[:32]
// Create a CSPRNG that xors a stream of zeros with
// the output of the AES-CTR instance.
- csprng := cipher.StreamReader{
+ csprng := &cipher.StreamReader{
R: zeroReader,
S: cipher.NewCTR(block, []byte(aesIV)),
}
c := priv.PublicKey.Curve
- return sign(priv, &csprng, c, hash)
+ return sign(priv, csprng, c, hash)
}
func signGeneric(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve, hash []byte) (r, s *big.Int, err error) {
// return value records whether the signature is valid. Most applications should
// use VerifyASN1 instead of dealing directly with r, s.
func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
+ if boring.Enabled {
+ b, err := boringPublicKey(pub)
+ if err != nil {
+ return false
+ }
+ return boring.VerifyECDSA(b, hash, r, s)
+ }
+ boring.UnreachableExceptTests()
+
c := pub.Curve
N := c.Params().N
return Verify(pub, hash, r, s)
}
- type zr struct {
- io.Reader
- }
+ type zr struct{}
- // Read replaces the contents of dst with zeros.
- func (z *zr) Read(dst []byte) (n int, err error) {
+ // Read replaces the contents of dst with zeros. It is safe for concurrent use.
+ func (zr) Read(dst []byte) (n int, err error) {
for i := range dst {
dst[i] = 0
}
return len(dst), nil
}
- var zeroReader = &zr{}
+ var zeroReader = zr{}
"crypto/x509"
"errors"
"fmt"
- "internal/godebug"
"io"
"net"
"strings"
// hash function associated with the Ed25519 signature scheme.
var directSigning crypto.Hash = 0
-// supportedSignatureAlgorithms contains the signature and hash algorithms that
+// 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,
}
func (c *Config) cipherSuites() []uint16 {
+ if needFIPS() {
+ return fipsCipherSuites(c)
+ }
if c.CipherSuites != nil {
return c.CipherSuites
}
VersionTLS10,
}
- // debugEnableTLS10 enables TLS 1.0. See issue 45428.
- var debugEnableTLS10 = godebug.Get("tls10default") == "1"
-
// roleClient and roleServer are meant to call supportedVersions and parents
// with more readability at the callsite.
const roleClient = true
func (c *Config) supportedVersions(isClient bool) []uint16 {
versions := make([]uint16, 0, len(supportedVersions))
for _, v := range supportedVersions {
- if (c == nil || c.MinVersion == 0) && !debugEnableTLS10 &&
+ if needFIPS() && (v < fipsMinVersion(c) || v > fipsMaxVersion(c)) {
+ continue
+ }
+ if (c == nil || c.MinVersion == 0) &&
isClient && v < VersionTLS12 {
continue
}
var defaultCurvePreferences = []CurveID{X25519, CurveP256, CurveP384, CurveP521}
func (c *Config) curvePreferences() []CurveID {
+ if needFIPS() {
+ return fipsCurvePreferences(c)
+ }
if c == nil || len(c.CurvePreferences) == 0 {
return defaultCurvePreferences
}
import (
"bytes"
+ "encoding/hex"
"math/rand"
"reflect"
"strings"
}
}
if rand.Intn(10) > 5 {
- m.supportedSignatureAlgorithms = supportedSignatureAlgorithms
+ m.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
}
if rand.Intn(10) > 5 {
- m.supportedSignatureAlgorithmsCert = supportedSignatureAlgorithms
+ m.supportedSignatureAlgorithmsCert = supportedSignatureAlgorithms()
}
for i := 0; i < rand.Intn(5); i++ {
m.alpnProtocols = append(m.alpnProtocols, randomString(rand.Intn(20)+1, rand))
m.scts = true
}
if rand.Intn(10) > 5 {
- m.supportedSignatureAlgorithms = supportedSignatureAlgorithms
+ m.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
}
if rand.Intn(10) > 5 {
- m.supportedSignatureAlgorithmsCert = supportedSignatureAlgorithms
+ m.supportedSignatureAlgorithmsCert = supportedSignatureAlgorithms()
}
if rand.Intn(10) > 5 {
m.certificateAuthorities = make([][]byte, 3)
t.Fatal("Unmarshaled ServerHello with zero-length SCT")
}
}
+
+ func TestRejectDuplicateExtensions(t *testing.T) {
+ clientHelloBytes, err := hex.DecodeString("010000440303000000000000000000000000000000000000000000000000000000000000000000000000001c0000000a000800000568656c6c6f0000000a000800000568656c6c6f")
+ if err != nil {
+ t.Fatalf("failed to decode test ClientHello: %s", err)
+ }
+ var clientHelloCopy clientHelloMsg
+ if clientHelloCopy.unmarshal(clientHelloBytes) {
+ t.Error("Unmarshaled ClientHello with duplicate extensions")
+ }
+
+ serverHelloBytes, err := hex.DecodeString("02000030030300000000000000000000000000000000000000000000000000000000000000000000000000080005000000050000")
+ if err != nil {
+ t.Fatalf("failed to decode test ServerHello: %s", err)
+ }
+ var serverHelloCopy serverHelloMsg
+ if serverHelloCopy.unmarshal(serverHelloBytes) {
+ t.Fatal("Unmarshaled ServerHello with duplicate extensions")
+ }
+ }
import (
"bytes"
"crypto"
+ "crypto/x509/pkix"
"errors"
"fmt"
"net"
// VerifyOptions contains parameters for Certificate.Verify.
type VerifyOptions struct {
+ // IsBoring is a validity check for BoringCrypto.
+ // If not nil, it will be called to check whether a given certificate
+ // can be used for constructing verification chains.
+ IsBoring func(*Certificate) bool
+
// DNSName, if set, is checked against the leaf certificate with
// Certificate.VerifyHostname or the platform verifier.
DNSName string
}
}
+ if opts.IsBoring != nil && !opts.IsBoring(c) {
+ // IncompatibleUsage is not quite right here,
+ // but it's also the "no chains found" error
+ // and is close enough.
+ return CertificateInvalidError{c, IncompatibleUsage, ""}
+ }
+
return nil
}
return n
}
+ // alreadyInChain checks whether a candidate certificate is present in a chain.
+ // Rather than doing a direct byte for byte equivalency check, we check if the
+ // subject, public key, and SAN, if present, are equal. This prevents loops that
+ // are created by mutual cross-signatures, or other cross-signature bridge
+ // oddities.
+ func alreadyInChain(candidate *Certificate, chain []*Certificate) bool {
+ type pubKeyEqual interface {
+ Equal(crypto.PublicKey) bool
+ }
+
+ var candidateSAN *pkix.Extension
+ for _, ext := range candidate.Extensions {
+ if ext.Id.Equal(oidExtensionSubjectAltName) {
+ candidateSAN = &ext
+ break
+ }
+ }
+
+ for _, cert := range chain {
+ if !bytes.Equal(candidate.RawSubject, cert.RawSubject) {
+ continue
+ }
+ if !candidate.PublicKey.(pubKeyEqual).Equal(cert.PublicKey) {
+ continue
+ }
+ var certSAN *pkix.Extension
+ for _, ext := range cert.Extensions {
+ if ext.Id.Equal(oidExtensionSubjectAltName) {
+ certSAN = &ext
+ break
+ }
+ }
+ if candidateSAN == nil && certSAN == nil {
+ return true
+ } else if candidateSAN == nil || certSAN == nil {
+ return false
+ }
+ if bytes.Equal(candidateSAN.Value, certSAN.Value) {
+ return true
+ }
+ }
+ return false
+ }
+
// maxChainSignatureChecks is the maximum number of CheckSignatureFrom calls
// that an invocation of buildChains will (transitively) make. Most chains are
// less than 15 certificates long, so this leaves space for multiple chains and
hintCert *Certificate
)
- type pubKeyEqual interface {
- Equal(crypto.PublicKey) bool
- }
-
considerCandidate := func(certType int, candidate *Certificate) {
- for _, cert := range currentChain {
- // If a certificate already appeared in the chain we've built, don't
- // reconsider it. This prevents loops, for isntance those created by
- // mutual cross-signatures, or other cross-signature bridges oddities.
- if bytes.Equal(cert.RawSubject, candidate.RawSubject) && cert.PublicKey.(pubKeyEqual).Equal(candidate.PublicKey) {
- return
- }
+ if alreadyInChain(candidate, currentChain) {
+ return
}
if sigChecks == nil {
if ctxt.CgoEnabled {
cgo = "1"
}
- cmd.Env = append(os.Environ(),
+ cmd.Env = append(cmd.Environ(),
"GOOS="+ctxt.GOOS,
"GOARCH="+ctxt.GOARCH,
"GOROOT="+ctxt.GOROOT,
"GOPATH="+ctxt.GOPATH,
"CGO_ENABLED="+cgo,
)
- if cmd.Dir != "" {
- // If possible, set PWD: if an error occurs and PWD includes a symlink, we
- // want the error to refer to Dir, not some other name for it.
- if abs, err := filepath.Abs(cmd.Dir); err == nil {
- cmd.Env = append(cmd.Env, "PWD="+abs)
- }
- }
if err := cmd.Run(); err != nil {
return fmt.Errorf("go/build: go list %s: %v\n%s\n", path, err, stderr.String())
// cgo (if cgo is enabled)
// $GOOS
// $GOARCH
+// boringcrypto
// ctxt.Compiler
// linux (if GOOS = android)
// solaris (if GOOS = illumos)
if name == "unix" && unixOS[ctxt.GOOS] {
return true
}
+ // Let applications know that the Go+BoringCrypto toolchain is in use.
+ if name == "boringcrypto" {
+ return true
+ }
// other tags
for _, tag := range ctxt.BuildTags {