Tighten up checks for PublicKey.init(keyBytes:)

For historical reasons libsignal's PublicKey.init(_:) allows trailing
data, because the type byte specifies how much of the data is relevant
anyway. init(keyBytes:), however, should not be so lax, since it's
assuming the key data is a Curve25519 public point.
This commit is contained in:
Jordan Rose 2024-05-20 10:02:47 -07:00
parent 0ac5558493
commit cbaae3fb08
2 changed files with 14 additions and 0 deletions

View File

@ -8,10 +8,14 @@ import LibSignalClient
extension PublicKey {
public convenience init(keyData: Data) throws {
if keyData.count != Constants.keyLengthDJB {
throw SignalError.invalidKey("invalid number of public key bytes (expected \(Constants.keyLengthDJB), was \(keyData.count))")
}
try self.init([Constants.keyTypeDJB] + keyData)
}
public enum Constants {
public static let keyTypeDJB: UInt8 = 0x05
public static let keyLengthDJB: Int = 32
}
}

View File

@ -9,6 +9,16 @@ import XCTest
@testable import SignalServiceKit
final class ECKeyPairTest: XCTestCase {
func testInvalidPublicSerializationLibsignalExtensions() throws {
let keyPair = ECKeyPair.generateKeyPair()
let serializedPublic = keyPair.publicKey
let deserializedPublic = try PublicKey(keyData: serializedPublic)
XCTAssertEqual(deserializedPublic, keyPair.identityKeyPair.publicKey)
XCTAssertThrowsError(try PublicKey(keyData: serializedPublic.dropFirst()))
XCTAssertThrowsError(try PublicKey(keyData: serializedPublic + [0x41]))
}
func testEncodeDecode() throws {
let privateKey = try PrivateKey(Array(repeating: 0, count: 31) + [0x41])
let keyPair = ECKeyPair(IdentityKeyPair(publicKey: privateKey.publicKey, privateKey: privateKey))