Skip to content

Commit

Permalink
Merge pull request #27 from ooni/merged-main
Browse files Browse the repository at this point in the history
chore: upgrade to go1.21.9
  • Loading branch information
bassosimone authored Apr 12, 2024
2 parents 74768b3 + 1d387c4 commit 8306ec4
Show file tree
Hide file tree
Showing 140 changed files with 11,847 additions and 9,799 deletions.
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ will continue to keep this fork up to date as long as it serves our goals.

## Intended usage

You MUST use this package with the exact Go version from which we extracted
You SHOULD use this package with the exact Go version from which we extracted
the source, which is documented in the [Update procedure](#update-procedure) section. The
standard library is composed of tightly integrated packages, hence
using this code with another Go version could cause subtle security issues.
Expand Down Expand Up @@ -93,7 +93,7 @@ to improve hardware capability detection on `android/arm64`.
(Adapted from ooni/oohttp instructions.)

- [ ] check whether hardware capability detection has been improved upstream
by reading [os_linux.go](https://github.com/golang/go/blob/go1.20.14/src/runtime/os_linux.go#L246)
by reading [os_linux.go](https://github.com/golang/go/blob/go1.21.9/src/runtime/os_linux.go#L250)
and update the link to `os_linux.go` based on the upstream version that
we're tracking with this fork

Expand Down Expand Up @@ -121,12 +121,19 @@ the following checks (we could also use `go list` as follows

3. `git grep 'aes"'`

4. `git grep 'alias"'`

5. `git grep 'boring"'`

- [ ] double check whether we need to add more checks to the list above (you
can get a list of packages using `tree -d`)

- [ ] ensure that `stdlibwrapper.go` correctly fills `tls.ConnectionState`
in the `ConnStdlib.ConnectionState` method

- [ ] use `./tools/compare.bash` to make sure the changes with respect
to upstream are reasonable

- [ ] `go build -v ./...` must succeed

- [ ] `go test -race ./...` must succeed
Expand Down
2 changes: 1 addition & 1 deletion UPSTREAM
Original file line number Diff line number Diff line change
@@ -1 +1 @@
go1.20.14
go1.21.9
2 changes: 1 addition & 1 deletion aes/asm_arm64.s
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ ks128Loop:
BNE ks128Loop
CBZ R11, ksDone // If dec is nil we are done
SUB $176, R10
// Decryption keys are encryption keys with InverseMixColumns applied
// Decryption keys are encryption keys with InverseMixColumns applied
VLD1.P 64(R10), [V0.B16, V1.B16, V2.B16, V3.B16]
VMOV V0.B16, V7.B16
AESIMC V1.B16, V6.B16
Expand Down
2 changes: 1 addition & 1 deletion aes/gcm_arm64.s
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ initEncFinish:
AESE T0.B16, B0.B16
AESMC B0.B16, B0.B16
AESE T1.B16, B0.B16
VEOR T2.B16, B0.B16, B0.B16
VEOR T2.B16, B0.B16, B0.B16

VREV64 B0.B16, B0.B16

Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ module github.com/ooni/oocrypto

go 1.20

require golang.org/x/crypto v0.21.0
require golang.org/x/crypto v0.22.0

require golang.org/x/sys v0.18.0
require golang.org/x/sys v0.19.0
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
2 changes: 1 addition & 1 deletion internal/alias/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package alias implements memory alaising tests.
// Package alias implements memory aliasing tests.
// This code also exists as golang.org/x/crypto/internal/alias.
package alias

Expand Down
File renamed without changes.
10 changes: 10 additions & 0 deletions tls/alert.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ package tls

import "strconv"

// An AlertError is a TLS alert.
//
// When using a QUIC transport, QUICConn methods will return an error
// which wraps AlertError rather than sending a TLS alert.
type AlertError uint8

func (e AlertError) Error() string {
return alert(e).String()
}

type alert uint8

const (
Expand Down
6 changes: 3 additions & 3 deletions tls/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type cacheEntry struct {
// multiple Conns. Returned references should not be mutated by callers. Certificates
// are still safe to use after they are removed from the cache.
//
// Certificates are returned wrapped in a activeCert struct that should be held by
// Certificates are returned wrapped in an activeCert struct that should be held by
// the caller. When references to the activeCert are freed, the number of references
// to the certificate in the cache is decremented. Once the number of references
// reaches zero, the entry is evicted from the cache.
Expand All @@ -39,7 +39,7 @@ type certCache struct {
sync.Map
}

var clientCertCache = new(certCache)
var globalCertCache = new(certCache)

// activeCert is a handle to a certificate held in the cache. Once there are
// no alive activeCerts for a given certificate, the certificate is removed
Expand All @@ -49,7 +49,7 @@ type activeCert struct {
}

// active increments the number of references to the entry, wraps the
// certificate in the entry in a activeCert, and sets the finalizer.
// certificate in the entry in an activeCert, and sets the finalizer.
//
// Note that there is a race between active and the finalizer set on the
// returned activeCert, triggered if active is called after the ref count is
Expand Down
8 changes: 0 additions & 8 deletions tls/cipher_suites.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,14 +378,6 @@ var aesgcmCiphers = map[uint16]bool{
TLS_AES_256_GCM_SHA384: true,
}

var nonAESGCMAEADCiphers = map[uint16]bool{
// TLS 1.2
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305: true,
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: true,
// TLS 1.3
TLS_CHACHA20_POLY1305_SHA256: true,
}

// aesgcmPreferred returns whether the first known cipher in the preference list
// is an AES-GCM cipher, implying the peer has hardware support for it.
func aesgcmPreferred(ciphers []uint16) bool {
Expand Down
121 changes: 79 additions & 42 deletions tls/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,26 @@ const (
VersionSSL30 = 0x0300
)

// VersionName returns the name for the provided TLS version number
// (e.g. "TLS 1.3"), or a fallback representation of the value if the
// version is not implemented by this package.
func VersionName(version uint16) string {
switch version {
case VersionSSL30:
return "SSLv3"
case VersionTLS10:
return "TLS 1.0"
case VersionTLS11:
return "TLS 1.1"
case VersionTLS12:
return "TLS 1.2"
case VersionTLS13:
return "TLS 1.3"
default:
return fmt.Sprintf("0x%04X", version)
}
}

const (
maxPlaintext = 16384 // maximum plaintext payload length
maxCiphertext = 16384 + 2048 // maximum ciphertext payload length
Expand Down Expand Up @@ -90,6 +110,7 @@ const (
extensionSignatureAlgorithms uint16 = 13
extensionALPN uint16 = 16
extensionSCT uint16 = 18
extensionExtendedMasterSecret uint16 = 23
extensionSessionTicket uint16 = 35
extensionPreSharedKey uint16 = 41
extensionEarlyData uint16 = 42
Expand All @@ -99,6 +120,7 @@ const (
extensionCertificateAuthorities uint16 = 47
extensionSignatureAlgorithmsCert uint16 = 50
extensionKeyShare uint16 = 51
extensionQUICTransportParameters uint16 = 57
extensionRenegotiationInfo uint16 = 0xff01
)

Expand Down Expand Up @@ -270,12 +292,8 @@ type ConnectionState struct {
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.
// Section 3). This value will be nil for TLS 1.3 connections and for
// resumed connections that don't support Extended Master Secret (RFC 7627).
TLSUnique []byte

// ekm is a closure exposed via ExportKeyingMaterial.
Expand All @@ -286,6 +304,10 @@ type ConnectionState struct {
// slice as defined in RFC 5705. If context is nil, it is not used as part of
// the seed. If the connection was set to allow renegotiation via
// Config.Renegotiation, this function will return an error.
//
// There are conditions in which the returned values 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.
func (cs *ConnectionState) ExportKeyingMaterial(label string, context []byte, length int) ([]byte, error) {
return cs.ekm(label, context, length)
}
Expand Down Expand Up @@ -329,25 +351,6 @@ func requiresClientCert(c ClientAuthType) bool {
}
}

// ClientSessionState contains the state needed by clients to resume TLS
// sessions.
type ClientSessionState struct {
sessionTicket []uint8 // Encrypted ticket used for session resumption with server
vers uint16 // TLS version negotiated for the session
cipherSuite uint16 // Ciphersuite negotiated for the session
masterSecret []byte // Full handshake MasterSecret, or TLS 1.3 resumption_master_secret
serverCertificates []*x509.Certificate // Certificate chain presented by the server
verifiedChains [][]*x509.Certificate // Certificate chains we built for verification
receivedAt time.Time // When the session ticket was received from the server
ocspResponse []byte // Stapled OCSP response presented by the server
scts [][]byte // SCTs presented by the server

// TLS 1.3 fields.
nonce []byte // Ticket nonce sent by the server, to derive PSK
useBy time.Time // Expiration of the ticket lifetime as set by the server
ageAdd uint32 // Random obfuscation factor for sending the ticket age
}

// ClientSessionCache is a cache of ClientSessionState objects that can be used
// by a client to resume a TLS session with a given server. ClientSessionCache
// implementations should expect to be called concurrently from different
Expand Down Expand Up @@ -601,10 +604,16 @@ type Config struct {
// non-nil error, the handshake is aborted and that error results.
//
// If normal verification fails then the handshake will abort before
// considering this callback. If normal verification is disabled by
// setting InsecureSkipVerify, or (for a server) when ClientAuth is
// RequestClientCert or RequireAnyClientCert, then this callback will
// be considered but the verifiedChains argument will always be nil.
// considering this callback. If normal verification is disabled (on the
// client when InsecureSkipVerify is set, or on a server when ClientAuth is
// RequestClientCert or RequireAnyClientCert), then this callback will be
// considered but the verifiedChains argument will always be nil. When
// ClientAuth is NoClientCert, this callback is not called on the server.
// rawCerts may be empty on the server if ClientAuth is RequestClientCert or
// VerifyClientCertIfGiven.
//
// This callback is not invoked on resumed connections, as certificates are
// not re-verified on resumption.
//
// verifiedChains and its contents should not be modified.
VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error
Expand All @@ -615,8 +624,9 @@ type Config struct {
// and that error results.
//
// If normal verification fails then the handshake will abort before
// considering this callback. This callback will run for all connections
// regardless of InsecureSkipVerify or ClientAuth settings.
// considering this callback. This callback will run for all connections,
// including resumptions, regardless of InsecureSkipVerify or ClientAuth
// settings.
VerifyConnection func(ConnectionState) error

// RootCAs defines the set of root certificate authorities
Expand Down Expand Up @@ -691,6 +701,35 @@ type Config struct {
// session resumption. It is only used by clients.
ClientSessionCache ClientSessionCache

// UnwrapSession is called on the server to turn a ticket/identity
// previously produced by [WrapSession] into a usable session.
//
// UnwrapSession will usually either decrypt a session state in the ticket
// (for example with [Config.EncryptTicket]), or use the ticket as a handle
// to recover a previously stored state. It must use [ParseSessionState] to
// deserialize the session state.
//
// If UnwrapSession returns an error, the connection is terminated. If it
// returns (nil, nil), the session is ignored. crypto/tls may still choose
// not to resume the returned session.
UnwrapSession func(identity []byte, cs ConnectionState) (*SessionState, error)

// WrapSession is called on the server to produce a session ticket/identity.
//
// WrapSession must serialize the session state with [SessionState.Bytes].
// It may then encrypt the serialized state (for example with
// [Config.DecryptTicket]) and use it as the ticket, or store the state and
// return a handle for it.
//
// If WrapSession returns an error, the connection is terminated.
//
// Warning: the return value will be exposed on the wire and to clients in
// plaintext. The application is in charge of encrypting and authenticating
// it (and rotating keys) or returning high-entropy identifiers. Failing to
// do so correctly can compromise current, previous, and future connections
// depending on the protocol version.
WrapSession func(ConnectionState, *SessionState) ([]byte, error)

// MinVersion contains the minimum TLS version that is acceptable.
//
// By default, TLS 1.2 is currently used as the minimum when acting as a
Expand Down Expand Up @@ -747,10 +786,6 @@ type Config struct {
}

const (
// ticketKeyNameLen is the number of bytes of identifier that is prepended to
// an encrypted session ticket in order to identify the key used to encrypt it.
ticketKeyNameLen = 16

// ticketKeyLifetime is how long a ticket key remains valid and can be used to
// resume a client connection.
ticketKeyLifetime = 7 * 24 * time.Hour // 7 days
Expand All @@ -762,9 +797,6 @@ const (

// ticketKey is the internal representation of a session ticket key.
type ticketKey struct {
// keyName is an opaque byte string that serves to identify the session
// ticket key. It's exposed as plaintext in every session ticket.
keyName [ticketKeyNameLen]byte
aesKey [16]byte
hmacKey [16]byte
// created is the time at which this ticket key was created. See Config.ticketKeys.
Expand All @@ -776,15 +808,18 @@ type ticketKey struct {
// bytes and this function expands that into sufficient name and key material.
func (c *Config) ticketKeyFromBytes(b [32]byte) (key ticketKey) {
hashed := sha512.Sum512(b[:])
copy(key.keyName[:], hashed[:ticketKeyNameLen])
copy(key.aesKey[:], hashed[ticketKeyNameLen:ticketKeyNameLen+16])
copy(key.hmacKey[:], hashed[ticketKeyNameLen+16:ticketKeyNameLen+32])
// The first 16 bytes of the hash used to be exposed on the wire as a ticket
// prefix. They MUST NOT be used as a secret. In the future, it would make
// sense to use a proper KDF here, like HKDF with a fixed salt.
const legacyTicketKeyNameLen = 16
copy(key.aesKey[:], hashed[legacyTicketKeyNameLen:])
copy(key.hmacKey[:], hashed[legacyTicketKeyNameLen+len(key.aesKey):])
key.created = c.time()
return key
}

// maxSessionTicketLifetime is the maximum allowed lifetime of a TLS 1.3 session
// ticket, and the lifetime we set for tickets we send.
// ticket, and the lifetime we set for all tickets we send.
const maxSessionTicketLifetime = 7 * 24 * time.Hour

// Clone returns a shallow clone of c or nil if c is nil. It is safe to clone a Config that is
Expand Down Expand Up @@ -816,6 +851,8 @@ func (c *Config) Clone() *Config {
SessionTicketsDisabled: c.SessionTicketsDisabled,
SessionTicketKey: c.SessionTicketKey,
ClientSessionCache: c.ClientSessionCache,
UnwrapSession: c.UnwrapSession,
WrapSession: c.WrapSession,
MinVersion: c.MinVersion,
MaxVersion: c.MaxVersion,
CurvePreferences: c.CurvePreferences,
Expand Down
Loading

0 comments on commit 8306ec4

Please sign in to comment.