Skip to content

Commit

Permalink
Merge branch 'dev' into update-versions-v1.10.18
Browse files Browse the repository at this point in the history
  • Loading branch information
StephenButtolph authored Jan 18, 2024
2 parents 0d65027 + f5884bb commit e87667f
Show file tree
Hide file tree
Showing 22 changed files with 424 additions and 127 deletions.
3 changes: 2 additions & 1 deletion indexer/examples/p-chain/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"time"

"github.com/ava-labs/avalanchego/indexer"
"github.com/ava-labs/avalanchego/version"
"github.com/ava-labs/avalanchego/wallet/subnet/primary"

platformvmblock "github.com/ava-labs/avalanchego/vms/platformvm/block"
Expand All @@ -34,7 +35,7 @@ func main() {
}

platformvmBlockBytes := container.Bytes
proposerVMBlock, err := proposervmblock.Parse(container.Bytes)
proposerVMBlock, err := proposervmblock.Parse(container.Bytes, version.DefaultUpgradeTime)
if err == nil {
platformvmBlockBytes = proposerVMBlock.Block()
}
Expand Down
3 changes: 2 additions & 1 deletion indexer/examples/x-chain-blocks/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"time"

"github.com/ava-labs/avalanchego/indexer"
"github.com/ava-labs/avalanchego/version"
"github.com/ava-labs/avalanchego/vms/proposervm/block"
"github.com/ava-labs/avalanchego/wallet/chain/x"
"github.com/ava-labs/avalanchego/wallet/subnet/primary"
Expand All @@ -32,7 +33,7 @@ func main() {
continue
}

proposerVMBlock, err := block.Parse(container.Bytes)
proposerVMBlock, err := block.Parse(container.Bytes, version.DefaultUpgradeTime)
if err != nil {
log.Fatalf("failed to parse proposervm block: %s\n", err)
}
Expand Down
10 changes: 8 additions & 2 deletions network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,12 @@ func NewNetwork(
IPSigner: peer.NewIPSigner(config.MyIPPort, config.TLSKey),
}

// Invariant: We delay the activation of durango during the TLS handshake to
// avoid gossiping any TLS certs that anyone else in the network may
// consider invalid. Recall that if a peer gossips an invalid cert, the
// connection is terminated.
durangoTime := version.GetDurangoTime(config.NetworkID)
durangoTimeWithClockSkew := durangoTime.Add(config.MaxClockDifference)
onCloseCtx, cancel := context.WithCancel(context.Background())
n := &network{
config: config,
Expand All @@ -283,8 +289,8 @@ func NewNetwork(
inboundConnUpgradeThrottler: throttling.NewInboundConnUpgradeThrottler(log, config.ThrottlerConfig.InboundConnUpgradeThrottlerConfig),
listener: listener,
dialer: dialer,
serverUpgrader: peer.NewTLSServerUpgrader(config.TLSConfig, metrics.tlsConnRejected),
clientUpgrader: peer.NewTLSClientUpgrader(config.TLSConfig, metrics.tlsConnRejected),
serverUpgrader: peer.NewTLSServerUpgrader(config.TLSConfig, metrics.tlsConnRejected, durangoTimeWithClockSkew),
clientUpgrader: peer.NewTLSClientUpgrader(config.TLSConfig, metrics.tlsConnRejected, durangoTimeWithClockSkew),

onCloseCtx: onCloseCtx,
onCloseCtxCancel: cancel,
Expand Down
18 changes: 15 additions & 3 deletions network/peer/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -1194,10 +1194,22 @@ func (p *peer) handlePeerList(msg *p2p.PeerList) {
close(p.onFinishHandshake)
}

// the peers this peer told us about
discoveredIPs := make([]*ips.ClaimedIPPort, len(msg.ClaimedIpPorts))
// Invariant: We do not account for clock skew here, as the sender of the
// certificate is expected to account for clock skew during the activation
// of Durango.
durangoTime := version.GetDurangoTime(p.NetworkID)
beforeDurango := time.Now().Before(durangoTime)
discoveredIPs := make([]*ips.ClaimedIPPort, len(msg.ClaimedIpPorts)) // the peers this peer told us about
for i, claimedIPPort := range msg.ClaimedIpPorts {
tlsCert, err := staking.ParseCertificate(claimedIPPort.X509Certificate)
var (
tlsCert *staking.Certificate
err error
)
if beforeDurango {
tlsCert, err = staking.ParseCertificate(claimedIPPort.X509Certificate)
} else {
tlsCert, err = staking.ParseCertificatePermissive(claimedIPPort.X509Certificate)
}
if err != nil {
p.Log.Debug("message with invalid field",
zap.Stringer("nodeID", p.id),
Expand Down
1 change: 1 addition & 0 deletions network/peer/test_peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func StartTestPeer(
clientUpgrader := NewTLSClientUpgrader(
tlsConfg,
prometheus.NewCounter(prometheus.CounterOpts{}),
version.GetDurangoTime(networkID),
)

peerID, conn, cert, err := clientUpgrader.Upgrade(conn)
Expand Down
36 changes: 21 additions & 15 deletions network/peer/upgrader.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"crypto/tls"
"errors"
"net"
"time"

"github.com/prometheus/client_golang/prometheus"

Expand All @@ -29,36 +30,40 @@ type Upgrader interface {
type tlsServerUpgrader struct {
config *tls.Config
invalidCerts prometheus.Counter
durangoTime time.Time
}

func NewTLSServerUpgrader(config *tls.Config, invalidCerts prometheus.Counter) Upgrader {
func NewTLSServerUpgrader(config *tls.Config, invalidCerts prometheus.Counter, durangoTime time.Time) Upgrader {
return &tlsServerUpgrader{
config: config,
invalidCerts: invalidCerts,
durangoTime: durangoTime,
}
}

func (t *tlsServerUpgrader) Upgrade(conn net.Conn) (ids.NodeID, net.Conn, *staking.Certificate, error) {
return connToIDAndCert(tls.Server(conn, t.config), t.invalidCerts)
return connToIDAndCert(tls.Server(conn, t.config), t.invalidCerts, t.durangoTime)
}

type tlsClientUpgrader struct {
config *tls.Config
invalidCerts prometheus.Counter
durangoTime time.Time
}

func NewTLSClientUpgrader(config *tls.Config, invalidCerts prometheus.Counter) Upgrader {
func NewTLSClientUpgrader(config *tls.Config, invalidCerts prometheus.Counter, durangoTime time.Time) Upgrader {
return &tlsClientUpgrader{
config: config,
invalidCerts: invalidCerts,
durangoTime: durangoTime,
}
}

func (t *tlsClientUpgrader) Upgrade(conn net.Conn) (ids.NodeID, net.Conn, *staking.Certificate, error) {
return connToIDAndCert(tls.Client(conn, t.config), t.invalidCerts)
return connToIDAndCert(tls.Client(conn, t.config), t.invalidCerts, t.durangoTime)
}

func connToIDAndCert(conn *tls.Conn, invalidCerts prometheus.Counter) (ids.NodeID, net.Conn, *staking.Certificate, error) {
func connToIDAndCert(conn *tls.Conn, invalidCerts prometheus.Counter, durangoTime time.Time) (ids.NodeID, net.Conn, *staking.Certificate, error) {
if err := conn.Handshake(); err != nil {
return ids.EmptyNodeID, nil, nil, err
}
Expand All @@ -72,17 +77,18 @@ func connToIDAndCert(conn *tls.Conn, invalidCerts prometheus.Counter) (ids.NodeI
// Invariant: ParseCertificate is used rather than CertificateFromX509 to
// ensure that signature verification can assume the certificate was
// parseable according the staking package's parser.
peerCert, err := staking.ParseCertificate(tlsCert.Raw)
if err != nil {
invalidCerts.Inc()
return ids.EmptyNodeID, nil, nil, err
//
// TODO: Remove pre-Durango parsing after v1.11.x has activated.
var (
peerCert *staking.Certificate
err error
)
if time.Now().Before(durangoTime) {
peerCert, err = staking.ParseCertificate(tlsCert.Raw)
} else {
peerCert, err = staking.ParseCertificatePermissive(tlsCert.Raw)
}

// We validate the certificate here to attempt to make the validity of the
// peer certificate as clear as possible. Specifically, a node running a
// prior version using an invalid certificate should not be able to report
// healthy.
if err := staking.ValidateCertificate(peerCert); err != nil {
if err != nil {
invalidCerts.Inc()
return ids.EmptyNodeID, nil, nil, err
}
Expand Down
8 changes: 2 additions & 6 deletions scripts/mock.gen.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,8 @@ if ! [[ "$0" =~ scripts/mock.gen.sh ]]; then
exit 255
fi

if ! command -v mockgen &> /dev/null
then
echo "mockgen not found, installing..."
# https://github.com/uber-go/mock
go install -v go.uber.org/mock/[email protected]
fi
# https://github.com/uber-go/mock
go install -v go.uber.org/mock/[email protected]

source ./scripts/constants.sh

Expand Down
28 changes: 23 additions & 5 deletions staking/asn1.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package staking
import (
"crypto"
"crypto/x509"
"encoding/asn1"
"fmt"

// Explicitly import for the crypto.RegisterHash init side-effects.
Expand All @@ -14,11 +15,28 @@ import (
_ "crypto/sha256"
)

// Ref: https://github.com/golang/go/blob/go1.19.12/src/crypto/x509/x509.go#L326-L350
var signatureAlgorithmVerificationDetails = map[x509.SignatureAlgorithm]x509.PublicKeyAlgorithm{
x509.SHA256WithRSA: x509.RSA,
x509.ECDSAWithSHA256: x509.ECDSA,
}
var (
// Ref: https://github.com/golang/go/blob/go1.19.12/src/crypto/x509/x509.go#L433-L452
//
// RFC 3279, 2.3 Public Key Algorithms
//
// pkcs-1 OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
// rsadsi(113549) pkcs(1) 1 }
//
// rsaEncryption OBJECT IDENTIFIER ::== { pkcs1-1 1 }
oidPublicKeyRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
// RFC 5480, 2.1.1 Unrestricted Algorithm Identifier and Parameters
//
// id-ecPublicKey OBJECT IDENTIFIER ::= {
// iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}

// Ref: https://github.com/golang/go/blob/go1.19.12/src/crypto/x509/x509.go#L326-L350
signatureAlgorithmVerificationDetails = map[x509.SignatureAlgorithm]x509.PublicKeyAlgorithm{
x509.SHA256WithRSA: x509.RSA,
x509.ECDSAWithSHA256: x509.ECDSA,
}
)

func init() {
if !crypto.SHA256.Available() {
Expand Down
10 changes: 7 additions & 3 deletions staking/certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@

package staking

import "crypto/x509"
import (
"crypto"
"crypto/x509"
)

type Certificate struct {
Raw []byte
PublicKey any
Raw []byte
PublicKey crypto.PublicKey
// TODO: Remove after v1.11.x activates.
SignatureAlgorithm x509.SignatureAlgorithm
}

Expand Down
Binary file removed staking/large_rsa_key.sig
Binary file not shown.
Loading

0 comments on commit e87667f

Please sign in to comment.