mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-19 11:59:09 +02:00
[client, management] Fix the edge cases left open in the certificate posture check (#8174)
This commit is contained in:
@@ -2,6 +2,8 @@ package certposture
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha256"
|
||||
@@ -86,6 +88,7 @@ func TestSignVerify_RoundTripPerKeyType(t *testing.T) {
|
||||
ca := certtest.NewCA(t, "root")
|
||||
keys := map[string]crypto.Signer{
|
||||
SigAlgECDSASHA256: certtest.ECDSAKey(t),
|
||||
SigAlgECDSASHA384: p384Key(t),
|
||||
SigAlgRSAPSSSHA256: certtest.RSAKey(t),
|
||||
SigAlgEd25519: certtest.Ed25519Key(t),
|
||||
}
|
||||
@@ -103,6 +106,24 @@ func TestSignVerify_RoundTripPerKeyType(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func p384Key(t *testing.T) crypto.Signer {
|
||||
t.Helper()
|
||||
key, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
|
||||
require.NoError(t, err)
|
||||
return key
|
||||
}
|
||||
|
||||
// TestSign_RefusesCurvesTheProofDoesNotName: a proof names its algorithm from the key, and
|
||||
// the verifier only knows P-256 and P-384, so P-521 is refused before anything is signed.
|
||||
func TestSign_RefusesCurvesTheProofDoesNotName(t *testing.T) {
|
||||
key, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, err = Sign(key, NewChallenger(secret).Nonce(peerKey, now), peerKey)
|
||||
|
||||
assert.ErrorIs(t, err, ErrUnsupportedKey)
|
||||
}
|
||||
|
||||
func TestVerify_Rejections(t *testing.T) {
|
||||
ca := certtest.NewCA(t, "root")
|
||||
c := NewChallenger(secret)
|
||||
|
||||
@@ -12,6 +12,8 @@ import (
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
"github.com/netbirdio/netbird/client/system"
|
||||
"github.com/netbirdio/netbird/shared/management/certposture"
|
||||
mgmtProto "github.com/netbirdio/netbird/shared/management/proto"
|
||||
)
|
||||
|
||||
@@ -93,3 +95,25 @@ func TestMaxRecvMsgSizeIntegration(t *testing.T) {
|
||||
assert.Len(t, resp.Key, payloadSize)
|
||||
})
|
||||
}
|
||||
|
||||
// TestInfoToMetaData_CarriesCertificateProofs: management verifies the proofs it receives
|
||||
// in the peer meta, so a field dropped by the mapping fails the certificate check without
|
||||
// any error on either side.
|
||||
func TestInfoToMetaData_CarriesCertificateProofs(t *testing.T) {
|
||||
info := &system.Info{CertificateProofs: []certposture.Proof{
|
||||
{Nonce: []byte("nonce-1"), Chain: [][]byte{[]byte("leaf"), []byte("intermediate")}, SigAlg: "ecdsa-sha256", Signature: []byte("sig-1")},
|
||||
{Nonce: []byte("nonce-2"), Chain: [][]byte{[]byte("other")}, SigAlg: "rsa-pss-sha256", Signature: []byte("sig-2")},
|
||||
}}
|
||||
|
||||
meta := infoToMetaData(info)
|
||||
|
||||
require.Len(t, meta.GetCertificateProofs(), 2, "every proof reaches the meta")
|
||||
first := meta.GetCertificateProofs()[0]
|
||||
assert.Equal(t, []byte("nonce-1"), first.GetNonce())
|
||||
assert.Equal(t, [][]byte{[]byte("leaf"), []byte("intermediate")}, first.GetChain(), "the whole chain is carried, in order")
|
||||
assert.Equal(t, "ecdsa-sha256", first.GetSigAlg())
|
||||
assert.Equal(t, []byte("sig-1"), first.GetSignature())
|
||||
assert.Equal(t, "rsa-pss-sha256", meta.GetCertificateProofs()[1].GetSigAlg())
|
||||
|
||||
assert.Empty(t, infoToMetaData(&system.Info{}).GetCertificateProofs(), "a device without proofs sends none")
|
||||
}
|
||||
|
||||
@@ -1821,6 +1821,7 @@ components:
|
||||
ca_certificates:
|
||||
description: PEM encoded CA certificates the peer's certificate must chain to
|
||||
type: array
|
||||
minItems: 1
|
||||
items:
|
||||
type: string
|
||||
example: ["-----BEGIN CERTIFICATE-----\nMIIB...\n-----END CERTIFICATE-----"]
|
||||
|
||||
Reference in New Issue
Block a user