don't panic on bad ed25519 key lengths (#1601)
Some checks failed
gofmt / Run gofmt (push) Failing after 4s
smoke-extra / Run extra smoke tests (push) Failing after 3s
smoke / Run multi node smoke test (push) Failing after 3s
Build and test / Build all and test on ubuntu-linux (push) Failing after 3s
Build and test / Build and test on linux with boringcrypto (push) Failing after 2s
Build and test / Build and test on linux with pkcs11 (push) Failing after 2s
Build and test / Build and test on macos-latest (push) Has been cancelled
Build and test / Build and test on windows-latest (push) Has been cancelled

* don't panic on bad ed25519 key lengths

* don't allow mismatched curves

* add test
This commit is contained in:
Jack Doan
2026-05-06 17:00:07 -05:00
committed by GitHub
parent 213dd46588
commit a82a8dc547
5 changed files with 39 additions and 0 deletions

View File

@@ -217,6 +217,10 @@ func (ncp *CAPool) verify(c Certificate, now time.Time, certFp string, signerFp
return nil, err
}
if signer.Certificate.Curve() != c.Curve() {
return nil, ErrCurveMismatch
}
if signer.Certificate.Expired(now) {
return nil, ErrRootExpired
}

View File

@@ -654,3 +654,31 @@ func TestCertificateV2_Verify_Subnets(t *testing.T) {
_, err = caPool.VerifyCertificate(time.Now(), c)
require.NoError(t, err)
}
func TestCertificateV2_CurveMismatch(t *testing.T) {
caIp1 := mustParsePrefixUnmapped("10.0.0.0/16")
caIp2 := mustParsePrefixUnmapped("192.168.0.0/24")
ca, _, caKey, _ := NewTestCaCert(Version2, Curve_P256, time.Now(), time.Now().Add(10*time.Minute), []netip.Prefix{caIp1, caIp2}, nil, []string{"test"})
caPem, err := ca.MarshalPEM()
require.NoError(t, err)
caPool := NewCAPool()
b, err := caPool.AddCAFromPEM(caPem)
require.NoError(t, err)
assert.Empty(t, b)
// ip is outside the network
cIp1 := mustParsePrefixUnmapped("10.0.0.1/24")
c, _, _, _ := NewTestCert(Version2, Curve_P256, ca, caKey, "test", time.Now(), time.Now().Add(5*time.Minute), []netip.Prefix{cIp1}, nil, []string{"test"})
fp, _ := c.Fingerprint()
_, err = caPool.verify(c, time.Now(), fp, c.Issuer())
require.NoError(t, err)
//
c2 := c.(*certificateV2)
c2.curve = Curve_CURVE25519
fp, _ = c.Fingerprint()
_, err = caPool.verify(c, time.Now(), fp, c.Issuer())
require.Error(t, err)
}

View File

@@ -112,6 +112,9 @@ func (c *certificateV1) CheckSignature(key []byte) bool {
}
switch c.details.curve {
case Curve_CURVE25519:
if len(key) != ed25519.PublicKeySize {
return false //avoids a panic internal to ed25519
}
return ed25519.Verify(key, b, c.signature)
case Curve_P256:
pubKey, err := ecdsa.ParseUncompressedPublicKey(elliptic.P256(), key)

View File

@@ -151,6 +151,9 @@ func (c *certificateV2) CheckSignature(key []byte) bool {
switch c.curve {
case Curve_CURVE25519:
if len(key) != ed25519.PublicKeySize {
return false //avoids a panic internal to ed25519
}
return ed25519.Verify(key, b, c.signature)
case Curve_P256:
pubKey, err := ecdsa.ParseUncompressedPublicKey(elliptic.P256(), key)

View File

@@ -22,6 +22,7 @@ var (
ErrCaNotFound = errors.New("could not find ca for the certificate")
ErrUnknownVersion = errors.New("certificate version unrecognized")
ErrCertPubkeyPresent = errors.New("certificate has unexpected pubkey present")
ErrCurveMismatch = errors.New("certificate curve does not match CA")
ErrInvalidPEMBlock = errors.New("input did not contain a valid PEM encoded block")
ErrInvalidPEMCertificateBanner = errors.New("bytes did not contain a proper certificate banner")