Skip to content

Commit

Permalink
Require admin role for making pairing changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Bouke committed Feb 2, 2018
1 parent 665aad2 commit 7aa8418
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 6 deletions.
10 changes: 5 additions & 5 deletions Sources/HAP/Controllers/PairVerifyController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class PairVerifyController {
return (resultOuter, session)
}

func finishRequest(_ data: PairTagTLV8, _ session: Session) throws -> PairTagTLV8 {
func finishRequest(_ data: PairTagTLV8, _ session: Session) throws -> (PairTagTLV8, Pairing) {
guard let encryptedData = data[.encryptedData] else {
throw Error.invalidParameters
}
Expand Down Expand Up @@ -115,14 +115,14 @@ class PairVerifyController {
logger.debug("--> username \(String(data: username, encoding: .utf8)!)")
logger.debug("--> signature \(signatureIn.hex)")

guard let publicKey = device.get(pairingWithIdentifier: username)?.publicKey else {
guard let pairing = device.get(pairingWithIdentifier: username) else {
throw Error.noPublicKeyForUser
}
logger.debug("--> public key \(publicKey.hex)")
logger.debug("--> public key \(pairing.publicKey.hex)")

let material = session.otherPublicKey + username + session.publicKey
do {
try Ed25519.verify(publicKey: publicKey, message: material, signature: signatureIn)
try Ed25519.verify(publicKey: pairing.publicKey, message: material, signature: signatureIn)
} catch {
throw Error.invalidSignature
}
Expand All @@ -131,6 +131,6 @@ class PairVerifyController {
let result: PairTagTLV8 = [
.state: Data(bytes: [PairVerifyStep.finishResponse.rawValue])
]
return result
return (result, pairing)
}
}
6 changes: 5 additions & 1 deletion Sources/HAP/Endpoints/pairVerify().swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,14 @@ func pairVerify(device: Device) -> Application {
connection.context[SESSION_KEY] = session
return Response(status: .ok, data: encode(response), mimeType: "application/pairing+tlv8")
case .finishRequest:
defer {
connection.context[SESSION_KEY] = nil
}
guard let session = connection.context[SESSION_KEY] as? Session else {
throw Error.noSession
}
let result = try controller.finishRequest(data, session)
let (result, pairing) = try controller.finishRequest(data, session)
connection.pairing = pairing
let response = UpgradeResponse(cryptographer: Cryptographer(sharedKey: session.sharedSecret))
response.headers["Content-Type"] = "application/pairing+tlv8"
response.body = encode(result)
Expand Down
10 changes: 10 additions & 0 deletions Sources/HAP/Endpoints/pairings().swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ func pairings(device: Device) -> Application {
else {
return .badRequest
}

guard connection.pairing?.role == .admin else {
logger.warning("Permission denied (non-admin) to update pairing data: \(data), method: \(method)")
let result: PairTagTLV8 = [
.state: Data(bytes: [PairStep.response.rawValue]),
.error: Data(bytes: [PairError.authenticationFailed.rawValue])
]
return Response(status: .ok, data: encode(result), mimeType: "application/pairing+tlv8")
}

logger.debug("Updating pairings data: \(data), method: \(method)")

switch method {
Expand Down
1 change: 1 addition & 0 deletions Sources/HAP/Server/Server.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public class Server: NSObject, NetServiceDelegate {
var context = [String: Any]()
var socket: Socket?
var cryptographer: Cryptographer?
var pairing: Pairing?
var notificationQueue: NotificationQueue

override init() {
Expand Down

0 comments on commit 7aa8418

Please sign in to comment.