Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Auth] #453 invalid signature error #457

Merged
merged 3 commits into from
Aug 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion Example/IntegrationTests/Auth/AuthTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ final class AuthTests: XCTestCase {
try! await wallet.pair(uri: uri)
wallet.authRequestPublisher.sink { [unowned self] (id, message) in
Task(priority: .high) {
let signature = try! MessageSigner(signer: Signer()).sign(message: message, privateKey: prvKey)
let signature = try! MessageSigner().sign(message: message, privateKey: prvKey)
let cacaoSignature = CacaoSignature(t: "eip191", s: signature)
try! await wallet.respond(requestId: id, result: .success(cacaoSignature))
}
Expand All @@ -80,4 +80,25 @@ final class AuthTests: XCTestCase {
.store(in: &publishers)
wait(for: [responseExpectation], timeout: 5)
}

func testRespondSignatureVerificationFailed() async {
let responseExpectation = expectation(description: "invalid signature response delivered")
let uri = try! await app.request(RequestParams.stub())
try! await wallet.pair(uri: uri)
wallet.authRequestPublisher.sink { [unowned self] (id, message) in
Task(priority: .high) {
let invalidSignature = "438effc459956b57fcd9f3dac6c675f9cee88abf21acab7305e8e32aa0303a883b06dcbd956279a7a2ca21ffa882ff55cc22e8ab8ec0f3fe90ab45f306938cfa1b"
let cacaoSignature = CacaoSignature(t: "eip191", s: invalidSignature)
try! await wallet.respond(requestId: id, result: .success(cacaoSignature))
}
}
.store(in: &publishers)
app.authResponsePublisher.sink { (id, result) in
guard case .failure(let error) = result else { XCTFail(); return }
XCTAssertEqual(error, .signatureVerificationFailed)
responseExpectation.fulfill()
}
.store(in: &publishers)
wait(for: [responseExpectation], timeout: 2)
}
}
2 changes: 1 addition & 1 deletion Sources/Auth/Services/App/AppRespondSubscriber.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class AppRespondSubscriber {
else { self.onResponse?(requestId, .failure(.messageCompromised)); return }

guard let _ = try? signatureVerifier.verify(signature: cacao.signature.s, message: message, address: address)
else { self.onResponse?(requestId, .failure(.messageVerificationFailed)); return }
else { self.onResponse?(requestId, .failure(.signatureVerificationFailed)); return }

onResponse?(requestId, .success(cacao))

Expand Down
8 changes: 4 additions & 4 deletions Sources/Auth/Services/Signer/MessageSigner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ protocol MessageSigning {
func sign(message: String, privateKey: Data) throws -> String
}

struct MessageSigner: MessageSignatureVerifying, MessageSigning {
public struct MessageSigner: MessageSignatureVerifying, MessageSigning {

enum Errors: Error {
case signatureValidationFailed
Expand All @@ -17,17 +17,17 @@ struct MessageSigner: MessageSignatureVerifying, MessageSigning {

private let signer: Signer

init(signer: Signer) {
public init(signer: Signer = Signer()) {
self.signer = signer
}

func sign(message: String, privateKey: Data) throws -> String {
public func sign(message: String, privateKey: Data) throws -> String {
guard let messageData = message.data(using: .utf8) else { throw Errors.utf8EncodingFailed }
let signature = try signer.sign(message: messageData, with: privateKey)
return signature.toHexString()
}

func verify(signature: String, message: String, address: String) throws {
public func verify(signature: String, message: String, address: String) throws {
guard let messageData = message.data(using: .utf8) else { throw Errors.utf8EncodingFailed }
let signatureData = Data(hex: signature)
guard try signer.isValid(signature: signatureData, message: messageData, address: address)
Expand Down
4 changes: 3 additions & 1 deletion Sources/Auth/Services/Signer/Signer.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import Foundation
import Web3

struct Signer {
public struct Signer {

typealias Signature = (v: UInt, r: [UInt8], s: [UInt8])

public init() {}

func sign(message: Data, with key: Data) throws -> Data {
let prefixed = prefixed(message: message)
let privateKey = try EthereumPrivateKey(privateKey: key.bytes)
Expand Down
12 changes: 9 additions & 3 deletions Sources/Auth/Types/Cacao/CacaoSignature.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import Foundation

public struct CacaoSignature: Codable, Equatable {
public let t: String
public let s: String
public let m: String? = nil
let t: String
let s: String
let m: String?

public init(t: String, s: String, m: String? = nil) {
self.t = t
self.s = s
self.m = m
}
}
6 changes: 3 additions & 3 deletions Sources/Auth/Types/Errors/AuthError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public enum AuthError: Codable, Equatable, Error {
case malformedResponseParams
case malformedRequestParams
case messageCompromised
case messageVerificationFailed
case signatureVerificationFailed
}

extension AuthError: Reason {
Expand All @@ -20,7 +20,7 @@ extension AuthError: Reason {
return 12002
case .messageCompromised:
return 12003
case .messageVerificationFailed:
case .signatureVerificationFailed:
return 12004
}
}
Expand All @@ -35,7 +35,7 @@ extension AuthError: Reason {
return "Request params malformed"
case .messageCompromised:
return "Original message compromised"
case .messageVerificationFailed:
case .signatureVerificationFailed:
return "Message verification failed"
}
}
Expand Down
7 changes: 6 additions & 1 deletion Sources/Auth/Types/RespondParams.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import Foundation

public struct RespondParams {
public struct RespondParams: Equatable {
let id: RPCID
let signature: CacaoSignature

public init(id: RPCID, signature: CacaoSignature) {
self.id = id
self.signature = signature
}
}