Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .changelog/6540.internal.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
go: Bump Go to 1.26.3
1 change: 1 addition & 0 deletions .changelog/6540.internal.2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
go: Bump golangci-lint to v2.12.2
4 changes: 2 additions & 2 deletions docker/oasis-core-dev/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
FROM ubuntu:24.04

# Package versions.
ARG GO_VERSION=1.26.0
ARG GO_VERSION=1.26.3
ARG GO_NANCY_VERSION=1.0.33
ARG GO_NANCY_CHECKSUM=a4bf5290d41b095c04f941ed5380674770c79d59735e33b1bd07a5cd5fbb135d
ARG GO_PROTOC_VERSION=3.6.1
ARG GO_PROTOC_GEN_GO_VERSION=1.21.0
ARG GOLANGCILINT_VERSION=2.10.1
ARG GOLANGCILINT_VERSION=2.12.2
ARG GOCOVMERGE_VERSION=b5bfa59ec0adc420475f97f89b58045c721d761c
ARG GOFUMPT_VERSION=v0.8.0
ARG GOIMPORTS_VERSION=v0.36.0
Expand Down
89 changes: 48 additions & 41 deletions docs/development-setup/prerequisites.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,21 @@
The following is a list of prerequisites required to start developing on Oasis
Core:

* Linux (if you are not on Linux, you will need to either set up a VM with the
- Linux (if you are not on Linux, you will need to either set up a VM with the
proper environment or, if Docker is available for your platform, use the
provided Docker image which does this for you,
[see below](#using-the-development-docker-image)).

* System packages:
* [Bubblewrap] (at least version 0.3.3).
* [GCC] (including C++ subpackage).
* [Clang] (including development package).
* [Protobuf] compiler.
* [GNU Make].
* [CMake].
* [pkg-config].
* [OpenSSL] development package.
* [libseccomp] development package.
- System packages:
- [Bubblewrap] (at least version 0.3.3).
- [GCC] (including C++ subpackage).
- [Clang] (including development package).
- [Protobuf] compiler.
- [GNU Make].
- [CMake].
- [pkg-config].
- [OpenSSL] development package.
- [libseccomp] development package.

_NOTE: On Ubuntu/Debian systems, compiling [mbedtls] crate when building the
`oasis-core-runtime` binary requires having the `gcc-multilib` package
Expand All @@ -26,47 +26,52 @@ Core:
On Fedora 29+, you can install all the above with:

<!-- markdownlint-disable line-length -->

```
sudo dnf install bubblewrap gcc gcc-c++ clang-devel clang protobuf-compiler make cmake openssl-devel libseccomp-devel pkg-config
```

<!-- markdownlint-enable line-length -->

On Ubuntu 18.10+ (18.04 LTS provides overly-old `bubblewrap`), you can install
all the above with:

<!-- markdownlint-disable line-length -->

```
sudo apt install bubblewrap gcc g++ gcc-multilib libclang-dev clang protobuf-compiler make cmake libssl-dev libseccomp-dev pkg-config
```

<!-- markdownlint-enable line-length -->

* [Go] (at least version 1.26.0).
- [Go] (at least version 1.26.3).

If your distribution provides a new-enough version of Go, just use that.

Please note that if you want to compile Oasis Core v22.1.9 or earlier,
then go >=1.19 is not supported yet; you need to use 1.18.x.

Otherwise:
* install the Go version provided by your distribution,
* [ensure `$GOPATH/bin` is in your `PATH`](
https://tip.golang.org/doc/code.html#GOPATH),
* [install the desired version of Go](
https://golang.org/doc/install#extra_versions), e.g. 1.26.0, with:
- install the Go version provided by your distribution,
- ensure `$GOPATH/bin` is in your
[`PATH`](https://tip.golang.org/doc/code.html#GOPATH),
- install the desired
[version of Go](https://golang.org/doc/install#extra_versions),
e.g. 1.26.3, with:

```
go install golang.org/dl/go1.26.0@latest
go1.26.0 download
go install golang.org/dl/go1.26.3@latest
go1.26.3 download
```

* instruct the build system to use this particular version of Go by setting
- instruct the build system to use this particular version of Go by setting
the `OASIS_GO` environment variable in your `~/.bashrc`:

```
export OASIS_GO=go1.26.0
export OASIS_GO=go1.26.3
```

* [Rust].
- [Rust].

We follow [Rust upstream's recommendation][rust-upstream-rustup] on using
[rustup] to install and manage Rust versions.
Expand All @@ -88,18 +93,20 @@ Core:
This will run `rustup-init` which will download and install the latest stable
version of Rust on your system.

* [Fortanix Rust EDP] utilities.
- [Fortanix Rust EDP] utilities.

Install the Fortanix Rust EDP utilities by running:

<!-- markdownlint-disable line-length -->

```
cargo install fortanix-sgx-tools
cargo install sgxs-tools
```

<!-- markdownlint-enable line-length -->

* Oasis Core's Rust toolchain version with Fortanix SGX target.
- Oasis Core's Rust toolchain version with Fortanix SGX target.

The version of the Rust toolchain we use in Oasis Core is specified in the
[`rust-toolchain.toml`] file.
Expand Down Expand Up @@ -129,7 +136,7 @@ Core:
rustc 1.77.0-nightly (75c68cfd2 2024-01-07)
```

* (**OPTIONAL**) [gofumpt] and [goimports].
- (**OPTIONAL**) [gofumpt] and [goimports].

Required if you plan to change any of the Go code in order for automated code
formatting (`make fmt`) to work.
Expand All @@ -141,7 +148,7 @@ Core:
${OASIS_GO:-go} install golang.org/x/tools/cmd/goimports@v0.36.0
```

* (**OPTIONAL**) [golangci-lint].
- (**OPTIONAL**) [golangci-lint].

Required if you plan to change any of the Go code in order for automated code
linting (`make lint`) to work.
Expand All @@ -151,10 +158,10 @@ Core:
```
curl -sSfL \
https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh \
| sh -s -- -b $(${OASIS_GO:-go} env GOPATH)/bin v2.10.1
| sh -s -- -b $(${OASIS_GO:-go} env GOPATH)/bin v2.12.2
```

* (**OPTIONAL**) [protoc-gen-go].
- (**OPTIONAL**) [protoc-gen-go].

Download and install it with:

Expand All @@ -166,16 +173,18 @@ Core:
`protoc-gen-go` to `/usr/local/bin` (which is in `$PATH`) with:_

<!-- markdownlint-disable line-length -->

```
sudo GOBIN=/usr/local/bin ${OASIS_GO:-go} install google.golang.org/protobuf/cmd/protoc-gen-go@v1.21.0
```

<!-- markdownlint-enable line-length -->

_NOTE: The repository has the most up-to-date files generated by protoc-gen-go
committed for convenience. Installing protoc-gen-go is only required if you
committed for convenience. Installing protoc-gen-go is only required if you
are a developer making changes to protobuf definitions used by Go._

* (**OPTIONAL**) [jemalloc] (version 5.2.1, built with `'je_'` jemalloc-prefix)
- (**OPTIONAL**) [jemalloc] (version 5.2.1, built with `'je_'` jemalloc-prefix)

Alternatively set `OASIS_BADGER_NO_JEMALLOC=1` environment variable when
building `oasis-node` code, to build [BadgerDB] without `jemalloc` support.
Expand Down Expand Up @@ -214,6 +223,7 @@ In the following instructions, the top-level directory is the directory
where the code has been checked out.

<!-- markdownlint-disable line-length -->

[Bubblewrap]: https://github.com/projectatomic/bubblewrap
[GCC]: http://gcc.gnu.org/
[Clang]: https://clang.llvm.org/
Expand All @@ -227,30 +237,27 @@ where the code has been checked out.
[Go]: https://golang.org
[rustup]: https://rustup.rs/
[rust-upstream-rustup]: https://www.rust-lang.org/tools/install
[download `rustup-init` executable for your platform]:
https://github.com/rust-lang/rustup#other-installation-methods
[download `rustup-init` executable for your platform]: https://github.com/rust-lang/rustup#other-installation-methods
[Rust]: https://www.rust-lang.org/
[`rust-toolchain.toml`]:
https://github.com/oasisprotocol/oasis-core/tree/master/rust-toolchain.toml
[rust-toolchain-precedence]:
https://github.com/rust-lang/rustup/blob/master/README.md#override-precedence
[`rust-toolchain.toml`]: https://github.com/oasisprotocol/oasis-core/tree/master/rust-toolchain.toml
[rust-toolchain-precedence]: https://github.com/rust-lang/rustup/blob/master/README.md#override-precedence
[Fortanix Rust EDP]: https://edp.fortanix.com
[gofumpt]: https://github.com/mvdan/gofumpt
[goimports]: https://pkg.go.dev/golang.org/x/tools/cmd/goimports
[golangci-lint]: https://golangci-lint.run/
[protoc-gen-go]: https://github.com/golang/protobuf
[jemalloc]: https://github.com/jemalloc/jemalloc
[BadgerDB]: https://github.com/dgraph-io/badger/
[jemalloc-hardcode-path]:
https://github.com/dgraph-io/ristretto/blob/221ca9b2091d12e5d24aa5d7d56e49745fc175d8/z/calloc_jemalloc.go#L9-L13
[jemalloc-hardcode-path]: https://github.com/dgraph-io/ristretto/blob/221ca9b2091d12e5d24aa5d7d56e49745fc175d8/z/calloc_jemalloc.go#L9-L13

<!-- markdownlint-enable line-length -->

## Using the Development Docker Image

If for some reason you don't want or can't install the specified prerequisites
on the host system, you can use our development Docker image. This requires that
you have a [recent version of Docker installed](
https://docs.docker.com/install/).
on the host system, you can use our development Docker image. This requires
that you have a
[recent version of Docker installed](https://docs.docker.com/install/).

Oasis development environment with all the dependencies preinstalled is
available in the `ghcr.io/oasisprotocol/oasis-core-dev:master` image.
Expand Down
16 changes: 11 additions & 5 deletions go/common/cbor/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,14 @@ import (
"github.com/prometheus/client_golang/prometheus"
)

// Maximum message size.
const maxMessageSize = 64 * 1024 * 1024 // 64 MiB
const (
// maxMessageSize is the maximum message size.
maxMessageSize = 64 * 1024 * 1024 // 64 MiB
// labelCall is the label for the call method.
labelCall = "call"
// labelModule is the label for the module name.
labelModule = "module"
)

var (
errMessageTooLarge = errors.New("codec: message too large")
Expand All @@ -21,7 +27,7 @@ var (
Name: "oasis_codec_size",
Help: "CBOR codec message size (bytes).",
},
[]string{"call", "module"},
[]string{labelCall, labelModule},
)

codecCollectors = []prometheus.Collector{
Expand All @@ -47,7 +53,7 @@ func (c *MessageReader) Read(msg any) error {
return err
}

labels := prometheus.Labels{"module": c.module, "call": "read"}
labels := prometheus.Labels{labelModule: c.module, labelCall: "read"}
length := binary.BigEndian.Uint32(rawLength)
codecValueSize.With(labels).Observe(float64(length))
if length > maxMessageSize {
Expand Down Expand Up @@ -80,7 +86,7 @@ func (c *MessageWriter) Write(msg any) error {
// Encode into CBOR.
data := Marshal(msg)
length := len(data)
labels := prometheus.Labels{"module": c.module, "call": "write"}
labels := prometheus.Labels{labelModule: c.module, labelCall: "write"}
codecValueSize.With(labels).Observe(float64(length))
if length > maxMessageSize {
return errMessageTooLarge
Expand Down
19 changes: 8 additions & 11 deletions go/common/crypto/tls/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,20 @@ type VerifyOptions struct {
AllowNoCertificate bool
}

// VerifyCertificate verifies a TLS certificate as required by Oasis Core. Instead of using CAs,
// VerifyCertificates verifies a TLS certificates as required by Oasis Core. Instead of using CAs,
// public key pinning is used and certificates must follow the template.
func VerifyCertificate(rawCerts [][]byte, opts VerifyOptions) error {
func VerifyCertificates(certs []*x509.Certificate, opts VerifyOptions) error {
// Allowing no certificate is useful in case access control is performed by a higher layer.
if len(rawCerts) == 0 && opts.AllowNoCertificate {
if len(certs) == 0 && opts.AllowNoCertificate {
return nil
}

// Make sure there is only a single certificate.
if len(rawCerts) != 1 {
return fmt.Errorf("tls: expecting a single certificate (got: %d)", len(rawCerts))
if len(certs) != 1 {
return fmt.Errorf("tls: expecting a single certificate (got: %d)", len(certs))
}

cert, err := x509.ParseCertificate(rawCerts[0])
if err != nil {
return fmt.Errorf("tls: bad X509 certificate: %w", err)
}
cert := certs[0]

// Public key should match the pinned key.
if cert.PublicKeyAlgorithm != x509.Ed25519 || cert.SignatureAlgorithm != x509.PureEd25519 {
Expand All @@ -53,7 +50,7 @@ func VerifyCertificate(rawCerts [][]byte, opts VerifyOptions) error {
}
if !opts.AllowUnknownKeys || opts.Keys != nil {
var spk signature.PublicKey
if err = spk.UnmarshalBinary(pk[:]); err != nil {
if err := spk.UnmarshalBinary(pk[:]); err != nil {
// This should NEVER happen.
return fmt.Errorf("tls: bad public key: %w", err)
}
Expand Down Expand Up @@ -113,7 +110,7 @@ func VerifyCertificate(rawCerts [][]byte, opts VerifyOptions) error {
}

// Signature should be valid.
if err = cert.CheckSignature(cert.SignatureAlgorithm, cert.RawTBSCertificate, cert.Signature); err != nil {
if err := cert.CheckSignature(cert.SignatureAlgorithm, cert.RawTBSCertificate, cert.Signature); err != nil {
return fmt.Errorf("tls: bad signature: %w", err)
}

Expand Down
19 changes: 13 additions & 6 deletions go/common/crypto/tls/verify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package tls

import (
"crypto/ed25519"
"crypto/x509"
"testing"

"github.com/stretchr/testify/require"
Expand All @@ -19,36 +20,42 @@ func TestVerifyCertificate(t *testing.T) {
signer := memory.NewFromRuntime(cert.PrivateKey.(ed25519.PrivateKey))
signer2 := memory.NewTestSigner("common/crypto/tls: test signer")

rawCerts := cert.Certificate
err = VerifyCertificate(rawCerts, VerifyOptions{
certs := make([]*x509.Certificate, 0)
for _, der := range cert.Certificate {
c, err := x509.ParseCertificate(der)
require.NoError(err, "ParseCertificate")
certs = append(certs, c)
}

err = VerifyCertificates(certs, VerifyOptions{
CommonName: "my-common-name",
Keys: map[signature.PublicKey]bool{
signer.Public(): true,
},
})
require.NoError(err, "VerifyCertificate")

err = VerifyCertificate(rawCerts, VerifyOptions{
err = VerifyCertificates(certs, VerifyOptions{
CommonName: "my-common-name",
AllowUnknownKeys: true,
})
require.NoError(err, "VerifyCertificate")

err = VerifyCertificate(nil, VerifyOptions{
err = VerifyCertificates(nil, VerifyOptions{
CommonName: "my-common-name",
AllowNoCertificate: true,
})
require.NoError(err, "VerifyCertificate")

err = VerifyCertificate(rawCerts, VerifyOptions{
err = VerifyCertificates(certs, VerifyOptions{
CommonName: "other-common-name",
Keys: map[signature.PublicKey]bool{
signer.Public(): true,
},
})
require.Error(err, "VerifyCertificate should fail with mismatched common name")

err = VerifyCertificate(rawCerts, VerifyOptions{
err = VerifyCertificates(certs, VerifyOptions{
CommonName: "my-common-name",
Keys: map[signature.PublicKey]bool{
signer2.Public(): true,
Expand Down
Loading
Loading