1
0
Fork 0
mirror of https://github.com/ACINQ/eclair.git synced 2025-03-11 01:35:01 +01:00

Add validation on the recid in verifymessage (#1928)

We offset the `recid` by `31` for compatibility with `lnd` [1] but we
should also support normal values (0-3), and also add boundary checks.

[1] https://twitter.com/rusty_twit/status/1182102005914800128
This commit is contained in:
Pierre-Marie Padiou 2021-08-31 15:28:40 +02:00 committed by GitHub
parent 59ccf3427a
commit 54fa208c7d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 1 deletions

View file

@ -458,7 +458,11 @@ class EclairImpl(appKit: Kit) extends Eclair with Logging {
override def verifyMessage(message: ByteVector, recoverableSignature: ByteVector): VerifiedMessage = {
val signedBytes = SignedMessage.signedBytes(message)
val signature = ByteVector64(recoverableSignature.tail)
val recoveryId = recoverableSignature.head.toInt - 31
val recoveryId = recoverableSignature.head.toInt match {
case lndFormat if (lndFormat - 31) >= 0 && (lndFormat - 31) <= 3 => lndFormat - 31
case normalFormat if normalFormat >= 0 && normalFormat <= 3 => normalFormat
case invalidFormat => throw new RuntimeException(s"invalid recid prefix $invalidFormat")
}
val pubKeyFromSignature = Crypto.recoverPublicKey(signature, signedBytes, recoveryId)
VerifiedMessage(valid = true, pubKeyFromSignature)
}

View file

@ -469,6 +469,16 @@ class EclairImplSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with I
assert(verifiedMessage.publicKey !== kit.nodeParams.nodeId)
}
test("verify a signature with different recid formats") { f =>
import f._
val eclair = new EclairImpl(kit)
val bytesMsg = ByteVector("hello, world".getBytes)
val sig = hex"730dce842c31b692dc041c2d0f00423d2a2a67b0c63c1a905d500f09652a5b1a036763a1603333fa589ae92d1f7963428ff170e976d0966a113f4b9f9d0efc7f"
assert(eclair.verifyMessage(bytesMsg, hex"1f" ++ sig).valid) // 0x1f = 31, format used by lnd (spec: https://twitter.com/rusty_twit/status/1182102005914800128)
assert(eclair.verifyMessage(bytesMsg, hex"00" ++ sig).valid)
}
test("ensure that an invalid recoveryId cause the signature verification to fail") { f =>
import f._