Check CA cert and key match in nebula-cert sign (#503)
`func (nc *NebulaCertificate) VerifyPrivateKey(key []byte) error` would previously return an error even if passed the correct private key for a CA certificate `nc`. That function has been updated to support CA certificates, and nebula-cert now calls it before signing a new certificate. Previously, it would perform all constraint checks against the CA certificate provided, take a SHA256 fingerprint of the provided certificate, insert it into the new node certificate, and then finally sign it with the mismatching private key provided.
This commit is contained in:
13
cert/cert.go
13
cert/cert.go
@ -325,12 +325,25 @@ func (nc *NebulaCertificate) CheckRootConstrains(signer *NebulaCertificate) erro
|
||||
|
||||
// VerifyPrivateKey checks that the public key in the Nebula certificate and a supplied private key match
|
||||
func (nc *NebulaCertificate) VerifyPrivateKey(key []byte) error {
|
||||
if nc.Details.IsCA {
|
||||
// the call to PublicKey below will panic slice bounds out of range otherwise
|
||||
if len(key) != ed25519.PrivateKeySize {
|
||||
return fmt.Errorf("key was not 64 bytes, is invalid ed25519 private key")
|
||||
}
|
||||
|
||||
if !ed25519.PublicKey(nc.Details.PublicKey).Equal(ed25519.PrivateKey(key).Public()) {
|
||||
return fmt.Errorf("public key in cert and private key supplied don't match")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var dst, key32 [32]byte
|
||||
copy(key32[:], key)
|
||||
curve25519.ScalarBaseMult(&dst, &key32)
|
||||
if !bytes.Equal(dst[:], nc.Details.PublicKey) {
|
||||
return fmt.Errorf("public key in cert and private key supplied don't match")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -375,9 +375,16 @@ func TestNebulaCertificate_Verify_Subnets(t *testing.T) {
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestNebulaVerifyPrivateKey(t *testing.T) {
|
||||
func TestNebulaCertificate_VerifyPrivateKey(t *testing.T) {
|
||||
ca, _, caKey, err := newTestCaCert(time.Time{}, time.Time{}, []*net.IPNet{}, []*net.IPNet{}, []string{})
|
||||
assert.Nil(t, err)
|
||||
err = ca.VerifyPrivateKey(caKey)
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, _, caKey2, err := newTestCaCert(time.Time{}, time.Time{}, []*net.IPNet{}, []*net.IPNet{}, []string{})
|
||||
assert.Nil(t, err)
|
||||
err = ca.VerifyPrivateKey(caKey2)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
c, _, priv, err := newTestCert(ca, caKey, time.Time{}, time.Time{}, []*net.IPNet{}, []*net.IPNet{}, []string{})
|
||||
err = c.VerifyPrivateKey(priv)
|
||||
|
Reference in New Issue
Block a user