[dev.link] all: merge branch 'master' into dev.link

Clean merge.

Change-Id: I2ae0e4cc67e24216c85619717657dce36e887a54
This commit is contained in:
Cherry Zhang 2020-06-26 14:25:33 -04:00
commit 92051a989b
32 changed files with 2041 additions and 930 deletions

View File

@ -466,7 +466,15 @@ Do not send CLs removing the interior tags from such phrases.
certificate, and letting the package automatically select the best one.
Note that the performance of this selection is going to be poor unless the
<a href="/pkg/crypto/tls/#Certificate.Leaf"><code>Certificate.Leaf</code></a>
field is set.
field is set. The
<a href="/pkg/crypto/tls/#Config.NameToCertificate"><code>Config.NameToCertificate</code></a>
field, which only supports associating a single certificate with
a give name, is now deprecated and should be left as <code>nil</code>.
Similarly the
<a href="/pkg/crypto/tls/#Config.BuildNameToCertificate"><code>Config.BuildNameToCertificate</code></a>
method, which builds the <code>NameToCertificate</code> field
from the leaf certificates, is now deprecated and should not be
called.
</p>
<p><!-- CL 175517 -->

View File

@ -440,7 +440,7 @@ Do not send CLs removing the interior tags from such phrases.
</dd>
</dl><!-- crypto/rsa -->
<dl id="crypto/tls"><dt><a href="/crypto/tls/">crypto/tls</a></dt>
<dl id="crypto/tls"><dt><a href="/pkg/crypto/tls/">crypto/tls</a></dt>
<dd>
<p><!-- CL 214977 -->
The new
@ -782,6 +782,20 @@ Do not send CLs removing the interior tags from such phrases.
1.14 with the addition of asynchronous preemption. Now this is
handled transparently.
</p>
<p><!-- CL 229101 -->
The <a href="/pkg/os/#File"><code>os.File</code></a> type now
supports a <a href="/pkg/os/#File.ReadFrom"><code>ReadFrom</code></a>
method. This permits the use of the <code>copy_file_range</code>
system call on some systems when using
<a href="/pkg/io/#Copy"><code>io.Copy</code></a> to copy data
from one <code>os.File</code> to another. A consequence is that
<a href="/pkg/io/#CopyBuffer"><code>io.CopyBuffer</code></a>
will not always use the provided buffer when copying to a
<code>os.File</code>. If a program wants to force the use of
the provided buffer, it can be done by writing
<code>io.CopyBuffer(struct{ io.Writer }{dst}, src, buf)</code>.
</p>
</dd>
</dl>

View File

@ -515,7 +515,7 @@ when used well, can result in clean error-handling code.
See the <a href="/doc/articles/defer_panic_recover.html">Defer, Panic, and Recover</a> article for details.
Also, the <a href="https://blog.golang.org/errors-are-values">Errors are values</a> blog post
describes one approach to handling errors cleanly in Go by demonstrating that,
since errors are just values, the full power of Go can deployed in error handling.
since errors are just values, the full power of Go can be deployed in error handling.
</p>
<h3 id="assertions">

View File

@ -1028,3 +1028,9 @@ func TestGeneratedHash(t *testing.T) {
goCmd(nil, "install", "-buildmode=shared", "-linkshared", "./issue30768/issue30768lib")
goCmd(nil, "test", "-linkshared", "./issue30768")
}
// Test that packages can be added not in dependency order (here a depends on b, and a adds
// before b). This could happen with e.g. go build -buildmode=shared std. See issue 39777.
func TestPackageOrder(t *testing.T) {
goCmd(t, "install", "-buildmode=shared", "-linkshared", "./issue39777/a", "./issue39777/b")
}

View File

@ -0,0 +1,9 @@
// Copyright 2020 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 a
import "testshared/issue39777/b"
func F() { b.F() }

View File

@ -0,0 +1,7 @@
// Copyright 2020 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 b
func F() {}

View File

@ -73,9 +73,11 @@ func dse(f *Func) {
}
// Walk backwards looking for dead stores. Keep track of shadowed addresses.
// An "address" is an SSA Value which encodes both the address and size of
// the write. This code will not remove dead stores to the same address
// of different types.
// A "shadowed address" is a pointer and a size describing a memory region that
// is known to be written. We keep track of shadowed addresses in the shadowed
// map, mapping the ID of the address to the size of the shadowed region.
// Since we're walking backwards, writes to a shadowed region are useless,
// as they will be immediately overwritten.
shadowed.clear()
v := last
@ -93,17 +95,13 @@ func dse(f *Func) {
sz = v.AuxInt
}
if shadowedSize := int64(shadowed.get(v.Args[0].ID)); shadowedSize != -1 && shadowedSize >= sz {
// Modify store into a copy
// Modify the store/zero into a copy of the memory state,
// effectively eliding the store operation.
if v.Op == OpStore {
// store addr value mem
v.SetArgs1(v.Args[2])
} else {
// zero addr mem
typesz := v.Args[0].Type.Elem().Size()
if sz != typesz {
f.Fatalf("mismatched zero/store sizes: %d and %d [%s]",
sz, typesz, v.LongString())
}
v.SetArgs1(v.Args[1])
}
v.Aux = nil

12
src/cmd/dist/test.go vendored
View File

@ -461,6 +461,18 @@ func (t *tester) registerTests() {
})
}
// Test the ios build tag on darwin/amd64 for the iOS simulator.
if goos == "darwin" && !t.iOS() {
t.tests = append(t.tests, distTest{
name: "amd64ios",
heading: "ios tag on darwin/amd64",
fn: func(dt *distTest) error {
t.addCmd(dt, "src", t.goTest(), t.timeout(300), "-tags=ios", "-run=SystemRoots", "crypto/x509")
return nil
},
})
}
if t.race {
return
}

View File

@ -160,7 +160,12 @@ func addlib(ctxt *Link, src, obj, lib string, fingerprint goobj2.FingerprintType
pkg := pkgname(ctxt, lib)
// already loaded?
if l := ctxt.LibraryByPkg[pkg]; l != nil {
if l := ctxt.LibraryByPkg[pkg]; l != nil && !l.Fingerprint.IsZero() {
// Normally, packages are loaded in dependency order, and if l != nil
// l is already loaded with the actual fingerprint. In shared build mode,
// however, packages may be added not in dependency order, and it is
// possible that l's fingerprint is not yet loaded -- exclude it in
// checking.
checkFingerprint(l, l.Fingerprint, src, fingerprint)
return l
}

View File

@ -20,7 +20,10 @@ import (
)
// A Curve represents a short-form Weierstrass curve with a=-3.
// See https://www.hyperelliptic.org/EFD/g1p/auto-shortw.html
//
// Note that the point at infinity (0, 0) is not considered on the curve, and
// although it can be returned by Add, Double, ScalarMult, or ScalarBaseMult, it
// can't be marshaled or unmarshaled, and IsOnCurve will return false for it.
type Curve interface {
// Params returns the parameters for the curve.
Params() *CurveParams
@ -307,7 +310,8 @@ func GenerateKey(curve Curve, rand io.Reader) (priv []byte, x, y *big.Int, err e
return
}
// Marshal converts a point into the uncompressed form specified in section 4.3.6 of ANSI X9.62.
// Marshal converts a point on the curve into the uncompressed form specified in
// section 4.3.6 of ANSI X9.62.
func Marshal(curve Curve, x, y *big.Int) []byte {
byteLen := (curve.Params().BitSize + 7) / 8
@ -320,7 +324,8 @@ func Marshal(curve Curve, x, y *big.Int) []byte {
return ret
}
// MarshalCompressed converts a point into the compressed form specified in section 4.3.6 of ANSI X9.62.
// MarshalCompressed converts a point on the curve into the compressed form
// specified in section 4.3.6 of ANSI X9.62.
func MarshalCompressed(curve Curve, x, y *big.Int) []byte {
byteLen := (curve.Params().BitSize + 7) / 8
compressed := make([]byte, 1+byteLen)

View File

@ -418,41 +418,62 @@ func TestP256Mult(t *testing.T) {
}
}
func testInfinity(t *testing.T, curve Curve) {
_, x, y, _ := GenerateKey(curve, rand.Reader)
x, y = curve.ScalarMult(x, y, curve.Params().N.Bytes())
if x.Sign() != 0 || y.Sign() != 0 {
t.Errorf("x^q != ∞")
}
x, y = curve.ScalarBaseMult([]byte{0})
if x.Sign() != 0 || y.Sign() != 0 {
t.Errorf("b^0 != ∞")
x.SetInt64(0)
y.SetInt64(0)
}
x2, y2 := curve.Double(x, y)
if x2.Sign() != 0 || y2.Sign() != 0 {
t.Errorf("2∞ != ∞")
}
baseX := curve.Params().Gx
baseY := curve.Params().Gy
x3, y3 := curve.Add(baseX, baseY, x, y)
if x3.Cmp(baseX) != 0 || y3.Cmp(baseY) != 0 {
t.Errorf("x+∞ != x")
}
x4, y4 := curve.Add(x, y, baseX, baseY)
if x4.Cmp(baseX) != 0 || y4.Cmp(baseY) != 0 {
t.Errorf("∞+x != x")
}
if curve.IsOnCurve(x, y) {
t.Errorf("IsOnCurve(∞) == true")
}
}
func TestInfinity(t *testing.T) {
tests := []struct {
name string
curve Curve
}{
{"p224", P224()},
{"p256", P256()},
{"P-224", P224()},
{"P-256", P256()},
{"P-256/Generic", P256().Params()},
{"P-384", P384()},
{"P-521", P521()},
}
if testing.Short() {
tests = tests[:1]
}
for _, test := range tests {
curve := test.curve
x, y := curve.ScalarBaseMult(nil)
if x.Sign() != 0 || y.Sign() != 0 {
t.Errorf("%s: x^0 != ∞", test.name)
}
x.SetInt64(0)
y.SetInt64(0)
x2, y2 := curve.Double(x, y)
if x2.Sign() != 0 || y2.Sign() != 0 {
t.Errorf("%s: 2∞ != ∞", test.name)
}
baseX := curve.Params().Gx
baseY := curve.Params().Gy
x3, y3 := curve.Add(baseX, baseY, x, y)
if x3.Cmp(baseX) != 0 || y3.Cmp(baseY) != 0 {
t.Errorf("%s: x+∞ != x", test.name)
}
x4, y4 := curve.Add(x, y, baseX, baseY)
if x4.Cmp(baseX) != 0 || y4.Cmp(baseY) != 0 {
t.Errorf("%s: ∞+x != x", test.name)
}
t.Run(test.name, func(t *testing.T) {
testInfinity(t, curve)
})
}
}

View File

@ -213,28 +213,72 @@ var testingOnlyForceDowngradeCanary bool
// ConnectionState records basic TLS details about the connection.
type ConnectionState struct {
Version uint16 // TLS version used by the connection (e.g. VersionTLS12)
HandshakeComplete bool // TLS handshake is complete
DidResume bool // connection resumes a previous TLS connection
CipherSuite uint16 // cipher suite in use (TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, ...)
NegotiatedProtocol string // negotiated next protocol (not guaranteed to be from Config.NextProtos)
NegotiatedProtocolIsMutual bool // negotiated protocol was advertised by server (client side only)
ServerName string // server name requested by client, if any
PeerCertificates []*x509.Certificate // certificate chain presented by remote peer
VerifiedChains [][]*x509.Certificate // verified chains built from PeerCertificates
SignedCertificateTimestamps [][]byte // SCTs from the peer, if any
OCSPResponse []byte // stapled OCSP response from peer, if any
// Version is the TLS version used by the connection (e.g. VersionTLS12).
Version uint16
// HandshakeComplete is true if the handshake has concluded.
HandshakeComplete bool
// DidResume is true if this connection was successfully resumed from a
// previous session with a session ticket or similar mechanism.
DidResume bool
// CipherSuite is the cipher suite negotiated for the connection (e.g.
// TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_AES_128_GCM_SHA256).
CipherSuite uint16
// NegotiatedProtocol is the application protocol negotiated with ALPN.
//
// Note that on the client side, this is currently not guaranteed to be from
// Config.NextProtos.
NegotiatedProtocol string
// NegotiatedProtocolIsMutual used to indicate a mutual NPN negotiation.
//
// Deprecated: this value is always true.
NegotiatedProtocolIsMutual bool
// ServerName is the value of the Server Name Indication extension sent by
// the client. It's available both on the server and on the client side.
ServerName string
// PeerCertificates are the parsed certificates sent by the peer, in the
// order in which they were sent. The first element is the leaf certificate
// that the connection is verified against.
//
// On the client side, it can't be empty. On the server side, it can be
// empty if Config.ClientAuth is not RequireAnyClientCert or
// RequireAndVerifyClientCert.
PeerCertificates []*x509.Certificate
// VerifiedChains is a list of one or more chains where the first element is
// PeerCertificates[0] and the last element is from Config.RootCAs (on the
// client side) or Config.ClientCAs (on the server side).
//
// On the client side, it's set if Config.InsecureSkipVerify is false. On
// the server side, it's set if Config.ClientAuth is VerifyClientCertIfGiven
// (and the peer provided a certificate) or RequireAndVerifyClientCert.
VerifiedChains [][]*x509.Certificate
// SignedCertificateTimestamps is a list of SCTs provided by the peer
// through the TLS handshake for the leaf certificate, if any.
SignedCertificateTimestamps [][]byte
// OCSPResponse is a stapled Online Certificate Status Protocol (OCSP)
// response provided by the peer for the leaf certificate, if any.
OCSPResponse []byte
// TLSUnique contains the "tls-unique" channel binding value (see RFC 5929,
// Section 3). This value will be nil for TLS 1.3 connections and for all
// resumed connections.
//
// Deprecated: there are conditions in which this value might not be unique
// to a connection. See the Security Considerations sections of RFC 5705 and
// RFC 7627, and https://mitls.org/pages/attacks/3SHAKE#channelbindings.
TLSUnique []byte
// ekm is a closure exposed via ExportKeyingMaterial.
ekm func(label string, context []byte, length int) ([]byte, error)
// TLSUnique contains the "tls-unique" channel binding value (see RFC
// 5929, section 3). For resumed sessions this value will be nil
// because resumption does not include enough context (see
// https://mitls.org/pages/attacks/3SHAKE#channelbindings). This will
// change in future versions of Go once the TLS master-secret fix has
// been standardized and implemented. It is not defined in TLS 1.3.
TLSUnique []byte
}
// ExportKeyingMaterial returns length bytes of exported key material in a new

View File

@ -7,7 +7,6 @@ package tls_test
import (
"crypto/tls"
"crypto/x509"
"errors"
"log"
"net/http"
"net/http/httptest"
@ -184,54 +183,50 @@ EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA==
log.Fatal(srv.ListenAndServeTLS("", ""))
}
func ExampleConfig_verifyPeerCertificate() {
// VerifyPeerCertificate can be used to replace and customize certificate
// verification. This example shows a VerifyPeerCertificate implementation
// that will be approximately equivalent to what crypto/tls does normally.
func ExampleConfig_verifyConnection() {
// VerifyConnection can be used to replace and customize connection
// verification. This example shows a VerifyConnection implementation that
// will be approximately equivalent to what crypto/tls does normally to
// verify the peer's certificate.
config := &tls.Config{
// Client side configuration.
_ = &tls.Config{
// Set InsecureSkipVerify to skip the default validation we are
// replacing. This will not disable VerifyPeerCertificate.
// replacing. This will not disable VerifyConnection.
InsecureSkipVerify: true,
// While packages like net/http will implicitly set ServerName, the
// VerifyPeerCertificate callback can't access that value, so it has to be set
// explicitly here or in VerifyPeerCertificate on the client side. If in
// an http.Transport DialTLS callback, this can be obtained by passing
// the addr argument to net.SplitHostPort.
ServerName: "example.com",
// On the server side, set ClientAuth to require client certificates (or
// VerifyPeerCertificate will run anyway and panic accessing certs[0])
// but not verify them with the default verifier.
// ClientAuth: tls.RequireAnyClientCert,
}
config.VerifyPeerCertificate = func(certificates [][]byte, _ [][]*x509.Certificate) error {
certs := make([]*x509.Certificate, len(certificates))
for i, asn1Data := range certificates {
cert, err := x509.ParseCertificate(asn1Data)
if err != nil {
return errors.New("tls: failed to parse certificate from server: " + err.Error())
VerifyConnection: func(cs tls.ConnectionState) error {
opts := x509.VerifyOptions{
DNSName: cs.ServerName,
Intermediates: x509.NewCertPool(),
}
certs[i] = cert
}
opts := x509.VerifyOptions{
Roots: config.RootCAs, // On the server side, use config.ClientCAs.
DNSName: config.ServerName,
Intermediates: x509.NewCertPool(),
// On the server side, set KeyUsages to ExtKeyUsageClientAuth. The
// default value is appropriate for clients side verification.
// KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
}
for _, cert := range certs[1:] {
opts.Intermediates.AddCert(cert)
}
_, err := certs[0].Verify(opts)
return err
for _, cert := range cs.PeerCertificates[1:] {
opts.Intermediates.AddCert(cert)
}
_, err := cs.PeerCertificates[0].Verify(opts)
return err
},
}
// Note that when InsecureSkipVerify and VerifyPeerCertificate are in use,
// Server side configuration.
_ = &tls.Config{
// Require client certificates (or VerifyConnection will run anyway and
// panic accessing cs.PeerCertificates[0]) but don't verify them with the
// default verifier. This will not disable VerifyConnection.
ClientAuth: tls.RequireAnyClientCert,
VerifyConnection: func(cs tls.ConnectionState) error {
opts := x509.VerifyOptions{
DNSName: cs.ServerName,
Intermediates: x509.NewCertPool(),
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
}
for _, cert := range cs.PeerCertificates[1:] {
opts.Intermediates.AddCert(cert)
}
_, err := cs.PeerCertificates[0].Verify(opts)
return err
},
}
// Note that when certificates are not handled by the default verifier
// ConnectionState.VerifiedChains will be nil.
}

View File

@ -235,7 +235,7 @@ func (d *Dialer) netDialer() *net.Dialer {
return new(net.Dialer)
}
// Dial connects to the given network address and initiates a TLS
// DialContext connects to the given network address and initiates a TLS
// handshake, returning the resulting TLS connection.
//
// The provided Context must be non-nil. If the context expires before

View File

@ -47,11 +47,15 @@ func (s *CertPool) copy() *CertPool {
// SystemCertPool returns a copy of the system cert pool.
//
// Any mutations to the returned pool are not written to disk and do
// not affect any other pool returned by SystemCertPool.
// On Unix systems other than macOS the environment variables SSL_CERT_FILE and
// SSL_CERT_DIR can be used to override the system default locations for the SSL
// certificate file and SSL certificate files directory, respectively. The
// latter can be a colon-separated list.
//
// New changes in the system cert pool might not be reflected
// in subsequent calls.
// Any mutations to the returned pool are not written to disk and do not affect
// any other pool returned by SystemCertPool.
//
// New changes in the system cert pool might not be reflected in subsequent calls.
func SystemCertPool() (*CertPool, error) {
if runtime.GOOS == "windows" {
// Issue 16736, 18609:

View File

@ -4,6 +4,8 @@
package x509
//go:generate go run root_darwin_ios_gen.go -version 55161.80.1
import "sync"
var (

View File

@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !ios
package x509
// This cgo implementation exists only to support side-by-side testing by

View File

@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !ios
package x509
import (

View File

@ -1,188 +0,0 @@
// Copyright 2015 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.
// +build ignore
// Generates root_darwin_arm64.go.
//
// As of iOS 8, there is no API for querying the system trusted X.509 root
// certificates. We could use SecTrustEvaluate to verify that a trust chain
// exists for a certificate, but the x509 API requires returning the entire
// chain.
//
// Apple publishes the list of trusted root certificates for iOS on
// support.apple.com. So we parse the list and extract the certificates from
// an OS X machine and embed them into the x509 package.
package main
import (
"bytes"
"crypto/sha256"
"crypto/x509"
"encoding/hex"
"encoding/pem"
"flag"
"fmt"
"go/format"
"io/ioutil"
"log"
"net/http"
"os/exec"
"regexp"
"strings"
)
var output = flag.String("output", "root_darwin_arm64.go", "file name to write")
func main() {
certs, err := selectCerts()
if err != nil {
log.Fatal(err)
}
buf := new(bytes.Buffer)
fmt.Fprintf(buf, "%s", header)
fmt.Fprintf(buf, "const systemRootsPEM = `\n")
for _, cert := range certs {
b := &pem.Block{
Type: "CERTIFICATE",
Bytes: cert.Raw,
}
if err := pem.Encode(buf, b); err != nil {
log.Fatal(err)
}
}
fmt.Fprintf(buf, "`")
source, err := format.Source(buf.Bytes())
if err != nil {
log.Fatal("source format error:", err)
}
if err := ioutil.WriteFile(*output, source, 0644); err != nil {
log.Fatal(err)
}
}
func selectCerts() ([]*x509.Certificate, error) {
ids, err := fetchCertIDs()
if err != nil {
return nil, err
}
scerts, err := sysCerts()
if err != nil {
return nil, err
}
var certs []*x509.Certificate
for _, id := range ids {
if c, ok := scerts[id.fingerprint]; ok {
certs = append(certs, c)
} else {
fmt.Printf("WARNING: cannot find certificate: %s (fingerprint: %s)\n", id.name, id.fingerprint)
}
}
return certs, nil
}
func sysCerts() (certs map[string]*x509.Certificate, err error) {
cmd := exec.Command("/usr/bin/security", "find-certificate", "-a", "-p", "/System/Library/Keychains/SystemRootCertificates.keychain")
data, err := cmd.Output()
if err != nil {
return nil, err
}
certs = make(map[string]*x509.Certificate)
for len(data) > 0 {
var block *pem.Block
block, data = pem.Decode(data)
if block == nil {
break
}
if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
continue
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
continue
}
fingerprint := sha256.Sum256(cert.Raw)
certs[hex.EncodeToString(fingerprint[:])] = cert
}
return certs, nil
}
type certID struct {
name string
fingerprint string
}
// fetchCertIDs fetches IDs of iOS X509 certificates from apple.com.
func fetchCertIDs() ([]certID, error) {
// Download the iOS 11 support page. The index for all iOS versions is here:
// https://support.apple.com/en-us/HT204132
resp, err := http.Get("https://support.apple.com/en-us/HT208125")
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
text := string(body)
text = text[strings.Index(text, "<div id=trusted"):]
text = text[:strings.Index(text, "</div>")]
var ids []certID
cols := make(map[string]int)
for i, rowmatch := range regexp.MustCompile("(?s)<tr>(.*?)</tr>").FindAllStringSubmatch(text, -1) {
row := rowmatch[1]
if i == 0 {
// Parse table header row to extract column names
for i, match := range regexp.MustCompile("(?s)<th>(.*?)</th>").FindAllStringSubmatch(row, -1) {
cols[match[1]] = i
}
continue
}
values := regexp.MustCompile("(?s)<td>(.*?)</td>").FindAllStringSubmatch(row, -1)
name := values[cols["Certificate name"]][1]
fingerprint := values[cols["Fingerprint (SHA-256)"]][1]
fingerprint = strings.ReplaceAll(fingerprint, "<br>", "")
fingerprint = strings.ReplaceAll(fingerprint, "\n", "")
fingerprint = strings.ReplaceAll(fingerprint, " ", "")
fingerprint = strings.ToLower(fingerprint)
ids = append(ids, certID{
name: name,
fingerprint: fingerprint,
})
}
return ids, nil
}
const header = `// Code generated by root_darwin_arm64_gen.go; DO NOT EDIT.
//go:generate go run root_darwin_arm64_gen.go -output root_darwin_arm64.go
// +build !x509omitbundledroots
package x509
func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
return nil, nil
}
// loadSystemRootsWithCgo is not available on iOS.
var loadSystemRootsWithCgo func() (*CertPool, error)
func loadSystemRoots() (*CertPool, error) {
p := NewCertPool()
p.AppendCertsFromPEM([]byte(systemRootsPEM))
return p, nil
}
`

View File

@ -0,0 +1,179 @@
// Copyright 2015 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.
// +build ignore
// Generates root_darwin_ios.go.
//
// As of iOS 13, there is no API for querying the system trusted X.509 root
// certificates.
//
// Apple publishes the trusted root certificates for iOS and macOS on
// opensource.apple.com so we embed them into the x509 package.
//
// Note that this ignores distrusted and revoked certificates.
package main
import (
"archive/tar"
"bytes"
"compress/gzip"
"crypto/sha256"
"crypto/tls"
"crypto/x509"
"encoding/pem"
"flag"
"fmt"
"go/format"
"io"
"io/ioutil"
"log"
"net/http"
"path"
"sort"
"strings"
"time"
)
func main() {
var output = flag.String("output", "root_darwin_ios.go", "file name to write")
var version = flag.String("version", "", "security_certificates version")
flag.Parse()
if *version == "" {
log.Fatal("Select the latest security_certificates version from " +
"https://opensource.apple.com/source/security_certificates/")
}
url := "https://opensource.apple.com/tarballs/security_certificates/security_certificates-%s.tar.gz"
hc := &http.Client{Timeout: 1 * time.Minute}
resp, err := hc.Get(fmt.Sprintf(url, *version))
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
log.Fatalf("HTTP status not OK: %s", resp.Status)
}
zr, err := gzip.NewReader(resp.Body)
if err != nil {
log.Fatal(err)
}
defer zr.Close()
var certs []*x509.Certificate
pool := x509.NewCertPool()
tr := tar.NewReader(zr)
for {
hdr, err := tr.Next()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
rootsDirectory := fmt.Sprintf("security_certificates-%s/certificates/roots/", *version)
if dir, file := path.Split(hdr.Name); hdr.Typeflag != tar.TypeReg ||
dir != rootsDirectory || strings.HasPrefix(file, ".") {
continue
}
der, err := ioutil.ReadAll(tr)
if err != nil {
log.Fatal(err)
}
c, err := x509.ParseCertificate(der)
if err != nil {
log.Printf("Failed to parse certificate %q: %v", hdr.Name, err)
continue
}
certs = append(certs, c)
pool.AddCert(c)
}
// Quick smoke test to check the pool is well formed, and that we didn't end
// up trusting roots in the removed folder.
for _, c := range certs {
if c.Subject.CommonName == "Symantec Class 2 Public Primary Certification Authority - G4" {
log.Fatal("The pool includes a removed root!")
}
}
conn, err := tls.Dial("tcp", "mail.google.com:443", &tls.Config{
RootCAs: pool,
})
if err != nil {
log.Fatal(err)
}
conn.Close()
certName := func(c *x509.Certificate) string {
if c.Subject.CommonName != "" {
return c.Subject.CommonName
}
if len(c.Subject.OrganizationalUnit) > 0 {
return c.Subject.OrganizationalUnit[0]
}
return c.Subject.Organization[0]
}
sort.Slice(certs, func(i, j int) bool {
if strings.ToLower(certName(certs[i])) != strings.ToLower(certName(certs[j])) {
return strings.ToLower(certName(certs[i])) < strings.ToLower(certName(certs[j]))
}
return certs[i].NotBefore.Before(certs[j].NotBefore)
})
out := new(bytes.Buffer)
fmt.Fprintf(out, header, *version)
fmt.Fprintf(out, "const systemRootsPEM = `\n")
for _, c := range certs {
fmt.Fprintf(out, "# %q\n", certName(c))
h := sha256.Sum256(c.Raw)
fmt.Fprintf(out, "# % X\n", h[:len(h)/2])
fmt.Fprintf(out, "# % X\n", h[len(h)/2:])
b := &pem.Block{
Type: "CERTIFICATE",
Bytes: c.Raw,
}
if err := pem.Encode(out, b); err != nil {
log.Fatal(err)
}
}
fmt.Fprintf(out, "`")
source, err := format.Source(out.Bytes())
if err != nil {
log.Fatal(err)
}
if err := ioutil.WriteFile(*output, source, 0644); err != nil {
log.Fatal(err)
}
}
const header = `// Code generated by root_darwin_ios_gen.go -version %s; DO NOT EDIT.
// Update the version in root.go and regenerate with "go generate".
// +build darwin,arm64 darwin,amd64,ios
// +build !x509omitbundledroots
package x509
func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
return nil, nil
}
// loadSystemRootsWithCgo is not available on iOS.
var loadSystemRootsWithCgo func() (*CertPool, error)
func loadSystemRoots() (*CertPool, error) {
p := NewCertPool()
p.AppendCertsFromPEM([]byte(systemRootsPEM))
return p, nil
}
`

View File

@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin,arm64,x509omitbundledroots
// +build darwin,arm64 darwin,amd64,ios
// +build x509omitbundledroots
// This file provides the loadSystemRoots func when the
// "x509omitbundledroots" build tag has disabled bundling a copy,

View File

@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin,arm64,x509omitbundledroots
// +build darwin,arm64 darwin,amd64,ios
// +build x509omitbundledroots
package x509

View File

@ -3,10 +3,6 @@
// license that can be found in the LICENSE file.
// Package x509 parses X.509-encoded keys and certificates.
//
// On UNIX systems the environment variables SSL_CERT_FILE and SSL_CERT_DIR
// can be used to override the system default locations for the SSL certificate
// file and SSL certificate files directory, respectively.
package x509
import (

View File

@ -30,11 +30,13 @@ import (
// value is a filename on the native file system, not a URL, so it is separated
// by filepath.Separator, which isn't necessarily '/'.
//
// Note that Dir will allow access to files and directories starting with a
// period, which could expose sensitive directories like a .git directory or
// sensitive files like .htpasswd. To exclude files with a leading period,
// remove the files/directories from the server or create a custom FileSystem
// implementation.
// Note that Dir could expose sensitive files and directories. Dir will follow
// symlinks pointing out of the directory tree, which can be especially dangerous
// if serving from a directory in which users are able to create arbitrary symlinks.
// Dir will also allow access to files and directories starting with a period,
// which could expose sensitive directories like .git or sensitive files like
// .htpasswd. To exclude files with a leading period, remove the files/directories
// from the server or create a custom FileSystem implementation.
//
// An empty Dir is treated as ".".
type Dir string

View File

@ -111,13 +111,13 @@ type Addr interface {
// Multiple goroutines may invoke methods on a Conn simultaneously.
type Conn interface {
// Read reads data from the connection.
// Read can be made to time out and return an Error with Timeout() == true
// after a fixed time limit; see SetDeadline and SetReadDeadline.
// Read can be made to time out and return an error after a fixed
// time limit; see SetDeadline and SetReadDeadline.
Read(b []byte) (n int, err error)
// Write writes data to the connection.
// Write can be made to time out and return an Error with Timeout() == true
// after a fixed time limit; see SetDeadline and SetWriteDeadline.
// Write can be made to time out and return an error after a fixed
// time limit; see SetDeadline and SetWriteDeadline.
Write(b []byte) (n int, err error)
// Close closes the connection.
@ -313,15 +313,13 @@ type PacketConn interface {
// It returns the number of bytes read (0 <= n <= len(p))
// and any error encountered. Callers should always process
// the n > 0 bytes returned before considering the error err.
// ReadFrom can be made to time out and return
// an Error with Timeout() == true after a fixed time limit;
// see SetDeadline and SetReadDeadline.
// ReadFrom can be made to time out and return an error after a
// fixed time limit; see SetDeadline and SetReadDeadline.
ReadFrom(p []byte) (n int, addr Addr, err error)
// WriteTo writes a packet with payload p to addr.
// WriteTo can be made to time out and return
// an Error with Timeout() == true after a fixed time limit;
// see SetDeadline and SetWriteDeadline.
// WriteTo can be made to time out and return an Error after a
// fixed time limit; see SetDeadline and SetWriteDeadline.
// On packet-oriented connections, write timeouts are rare.
WriteTo(p []byte, addr Addr) (n int, err error)
@ -337,11 +335,17 @@ type PacketConn interface {
// SetReadDeadline and SetWriteDeadline.
//
// A deadline is an absolute time after which I/O operations
// fail with a timeout (see type Error) instead of
// blocking. The deadline applies to all future and pending
// I/O, not just the immediately following call to ReadFrom or
// WriteTo. After a deadline has been exceeded, the connection
// can be refreshed by setting a deadline in the future.
// fail instead of blocking. The deadline applies to all future
// and pending I/O, not just the immediately following call to
// Read or Write. After a deadline has been exceeded, the
// connection can be refreshed by setting a deadline in the future.
//
// If the deadline is exceeded a call to Read or Write or to other
// I/O methods will return an error that wraps os.ErrDeadlineExceeded.
// This can be tested using errors.Is(err, os.ErrDeadlineExceeded).
// The error's Timeout method will return true, but note that there
// are other possible errors for which the Timeout method will
// return true even if the deadline has not been exceeded.
//
// An idle timeout can be implemented by repeatedly extending
// the deadline after successful ReadFrom or WriteTo calls.

View File

@ -233,10 +233,10 @@ func (f *File) Sync() error {
var buf [syscall.STATFIXLEN]byte
n, err := d.Marshal(buf[:])
if err != nil {
return NewSyscallError("fsync", err)
return &PathError{"sync", f.name, err}
}
if err = syscall.Fwstat(f.fd, buf[:n]); err != nil {
return NewSyscallError("fsync", err)
return &PathError{"sync", f.name, err}
}
return nil
}

View File

@ -536,7 +536,7 @@ func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
return
}
if sig == sigPreempt {
if sig == sigPreempt && debug.asyncpreemptoff == 0 {
// Might be a preemption signal.
doSigPreempt(gp, c)
// Even if this was definitely a preemption signal, it

View File

@ -130,7 +130,7 @@ func fastrandn(n uint32) uint32 {
//go:linkname sync_fastrand sync.fastrand
func sync_fastrand() uint32 { return fastrand() }
// in asm_*.s
// in internal/bytealg/equal_*.s
//go:noescape
func memequal(a, b unsafe.Pointer, size uintptr) bool

View File

@ -35,6 +35,20 @@ func Creat(path string, mode uint32) (fd int, err error) {
return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
}
func isGroupMember(gid int) bool {
groups, err := Getgroups()
if err != nil {
return false
}
for _, g := range groups {
if g == gid {
return true
}
}
return false
}
//sys faccessat(dirfd int, path string, mode uint32) (err error)
func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
@ -92,7 +106,7 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
gid = Getgid()
}
if uint32(gid) == st.Gid {
if uint32(gid) == st.Gid || isGroupMember(gid) {
fmode = (st.Mode >> 3) & 7
} else {
fmode = st.Mode & 7

View File

@ -349,7 +349,7 @@ func (i *IdentifierNode) Copy() Node {
return NewIdentifier(i.Ident).SetTree(i.tr).SetPos(i.Pos)
}
// AssignNode holds a list of variable names, possibly with chained field
// VariableNode holds a list of variable names, possibly with chained field
// accesses. The dollar sign is part of the (first) name.
type VariableNode struct {
NodeType

View File

@ -0,0 +1,22 @@
// compile
// Copyright 2020 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 p
type T struct { // big enough to be an unSSAable type
a, b, c, d, e, f int
}
func f(x interface{}, p *int) {
_ = *p // trigger nil check here, removing it from below
switch x := x.(type) {
case *T:
// Zero twice, so one of them will be removed by the deadstore pass
*x = T{}
*p = 0 // store op to prevent Zero ops from being optimized by the earlier opt pass rewrite rules
*x = T{}
}
}