diff --git a/NearbyShare/Connection/InboundNearbyConnection.swift b/NearbyShare/Connection/InboundNearbyConnection.swift index 55d4c3f..b5b493b 100644 --- a/NearbyShare/Connection/InboundNearbyConnection.swift +++ b/NearbyShare/Connection/InboundNearbyConnection.swift @@ -410,29 +410,25 @@ class InboundNearbyConnection: NearbyConnection { try automaticAuthFailed() return } - - guard pkeFrame.signedData.count == 72 else { + + do { + let signature = try ECSignature(asn1: .build(pkeFrame.signedData), domain: domain) + + if peerPublicKey.verify(signature: signature, msg: authKeyData) { + log("[InboundNearbyConnection \(self.id)] Paired key authentication successful.") + try sendPairedKeyResult(status: .success) + isAuthenticated = true + } else { + log("[InboundNearbyConnection \(self.id)] Paired key auth failed: Signature verification failed.") + try automaticAuthFailed() + } + } + catch { log("[InboundNearbyConnection \(self.id)] Paired key auth failed: Invalid signature length.") try automaticAuthFailed() return } - - // Strip header - let signedData = pkeFrame.signedData.subdata(in: 8..<72) - - let r = Array(signedData.prefix(32)) - let s = Array(signedData.suffix(32)) - - let signature = ECSignature(domain: domain, r: r, s: s) - if peerPublicKey.verify(signature: signature, msg: authKeyData) { - log("[InboundNearbyConnection \(self.id)] Paired key authentication successful.") - try sendPairedKeyResult(status: .success) - isAuthenticated = true - } else { - log("[InboundNearbyConnection \(self.id)] Paired key auth failed: Signature verification failed.") - try automaticAuthFailed() - } } else { try automaticAuthFailed() } diff --git a/NearbyShare/Connection/OutboundNearbyConnection.swift b/NearbyShare/Connection/OutboundNearbyConnection.swift index f135337..3f3479c 100644 --- a/NearbyShare/Connection/OutboundNearbyConnection.swift +++ b/NearbyShare/Connection/OutboundNearbyConnection.swift @@ -13,6 +13,8 @@ import System import UniformTypeIdentifiers import BigInt import SwiftECC +import ASN1 +import BigInt // required dependency of ASN1 class OutboundNearbyConnection: NearbyConnection { @@ -265,8 +267,11 @@ class OutboundNearbyConnection: NearbyConnection { private func processConnectionResponse(frame: Location_Nearby_Connections_OfflineFrame) throws { + guard frame.version == .v1 else { throw NearbyError.protocolError("Unexpected offline frame version \(frame.version)") } + guard frame.v1.type == .connectionResponse else { throw NearbyError.protocolError("Unexpected frame type \(frame.v1.type)") } + guard frame.v1.connectionResponse.response == .accept else { throw NearbyError.protocolError("Connection was rejected by recipient") } var pairedEncryption = Sharing_Nearby_Frame() @@ -288,18 +293,8 @@ class OutboundNearbyConnection: NearbyConnection { let signatureTuple = signingPrivateKey.sign(msg: authKeyData) - let rBytes = signatureTuple.r - let sBytes = signatureTuple.s - - // Make sure r and s are 32 bytes each by padding with leading zeros if necessary - let paddedR = Data(repeating: 0, count: 32 - rBytes.count) + rBytes - let paddedS = Data(repeating: 0, count: 32 - sBytes.count) + sBytes - - // Signature: Header (8 bytes) + r (32 bytes) + s (32 bytes) - let signatureData = Data(repeating: 0, count: 8) + paddedR + paddedS - pairedEncryption.v1.certificateInfo.publicCertificate.append(cert) - pairedEncryption.v1.pairedKeyEncryption.signedData = signatureData + pairedEncryption.v1.pairedKeyEncryption.signedData = Data(signatureTuple.asn1.encode()) pairedEncryption.v1.pairedKeyEncryption.secretIDHash = cert.secretID pairedEncryption.v1.pairedKeyResult.status = .success