You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

188 lines
7.8 KiB

#!/usr/bin/env python3
#
# Copyright 2020 - The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import bluetooth_packets_python3 as bt_packets
from bluetooth_packets_python3 import hci_packets
from bluetooth_packets_python3 import l2cap_packets
from bluetooth_packets_python3.l2cap_packets import CommandCode, LeCommandCode
from cert.capture import Capture
from cert.matchers import HciMatchers
from cert.matchers import L2capMatchers
from cert.matchers import SecurityMatchers
from security.facade_pb2 import UiMsgType
class HalCaptures(object):
@staticmethod
def ReadBdAddrCompleteCapture():
return Capture(
lambda packet: packet.payload[0:5] == b'\x0e\x0a\x01\x09\x10', lambda packet: hci_packets.ReadBdAddrCompleteView(
hci_packets.CommandCompleteView(
hci_packets.EventView(bt_packets.PacketViewLittleEndian(list(packet.payload))))))
@staticmethod
def ConnectionRequestCapture():
return Capture(
lambda packet: packet.payload[0:2] == b'\x04\x0a', lambda packet: hci_packets.ConnectionRequestView(
hci_packets.EventView(bt_packets.PacketViewLittleEndian(list(packet.payload)))))
@staticmethod
def ConnectionCompleteCapture():
return Capture(
lambda packet: packet.payload[0:3] == b'\x03\x0b\x00', lambda packet: hci_packets.ConnectionCompleteView(
hci_packets.EventView(bt_packets.PacketViewLittleEndian(list(packet.payload)))))
@staticmethod
def DisconnectionCompleteCapture():
return Capture(
lambda packet: packet.payload[0:2] == b'\x05\x04', lambda packet: hci_packets.DisconnectionCompleteView(
hci_packets.EventView(bt_packets.PacketViewLittleEndian(list(packet.payload)))))
@staticmethod
def LeConnectionCompleteCapture():
return Capture(
lambda packet: packet.payload[0] == 0x3e and (packet.payload[2] == 0x01 or packet.payload[2] == 0x0a),
lambda packet: hci_packets.LeConnectionCompleteView(
hci_packets.LeMetaEventView(
hci_packets.EventView(bt_packets.PacketViewLittleEndian(list(packet.payload))))))
class HciCaptures(object):
@staticmethod
def ReadLocalOobDataCompleteCapture():
return Capture(
HciMatchers.CommandComplete(hci_packets.OpCode.READ_LOCAL_OOB_DATA),
lambda packet: HciMatchers.ExtractMatchingCommandComplete(packet.payload, hci_packets.OpCode.READ_LOCAL_OOB_DATA)
)
@staticmethod
def ReadLocalOobExtendedDataCompleteCapture():
return Capture(
HciMatchers.CommandComplete(hci_packets.OpCode.READ_LOCAL_OOB_EXTENDED_DATA),
lambda packet: HciMatchers.ExtractMatchingCommandComplete(packet.payload, hci_packets.OpCode.READ_LOCAL_OOB_EXTENDED_DATA)
)
@staticmethod
def ReadBdAddrCompleteCapture():
return Capture(
HciMatchers.CommandComplete(hci_packets.OpCode.READ_BD_ADDR),
lambda packet: hci_packets.ReadBdAddrCompleteView(HciMatchers.ExtractMatchingCommandComplete(packet.payload, hci_packets.OpCode.READ_BD_ADDR)))
@staticmethod
def ConnectionRequestCapture():
return Capture(
HciMatchers.EventWithCode(hci_packets.EventCode.CONNECTION_REQUEST),
lambda packet: hci_packets.ConnectionRequestView(
HciMatchers.ExtractEventWithCode(packet.payload, hci_packets.EventCode.CONNECTION_REQUEST)))
@staticmethod
def ConnectionCompleteCapture():
return Capture(
HciMatchers.EventWithCode(hci_packets.EventCode.CONNECTION_COMPLETE),
lambda packet: hci_packets.ConnectionCompleteView(
HciMatchers.ExtractEventWithCode(packet.payload, hci_packets.EventCode.CONNECTION_COMPLETE)))
@staticmethod
def DisconnectionCompleteCapture():
return Capture(
HciMatchers.EventWithCode(hci_packets.EventCode.DISCONNECTION_COMPLETE),
lambda packet: hci_packets.DisconnectionCompleteView(
HciMatchers.ExtractEventWithCode(packet.payload, hci_packets.EventCode.DISCONNECTION_COMPLETE)))
@staticmethod
def LeConnectionCompleteCapture():
return Capture(HciMatchers.LeConnectionComplete(),
lambda packet: HciMatchers.ExtractLeConnectionComplete(packet.payload))
@staticmethod
def SimplePairingCompleteCapture():
return Capture(HciMatchers.EventWithCode(hci_packets.EventCode.SIMPLE_PAIRING_COMPLETE),
lambda packet: hci_packets.SimplePairingCompleteView(
HciMatchers.ExtractEventWithCode(packet.payload, hci_packets.EventCode.SIMPLE_PAIRING_COMPLETE)))
class L2capCaptures(object):
@staticmethod
def ConnectionRequest(psm):
return Capture(L2capMatchers.ConnectionRequest(psm), L2capCaptures._extract_connection_request)
@staticmethod
def _extract_connection_request(packet):
frame = L2capMatchers.control_frame_with_code(packet, CommandCode.CONNECTION_REQUEST)
return l2cap_packets.ConnectionRequestView(frame)
@staticmethod
def ConnectionResponse(scid):
return Capture(L2capMatchers.ConnectionResponse(scid), L2capCaptures._extract_connection_response)
@staticmethod
def _extract_connection_response(packet):
frame = L2capMatchers.control_frame_with_code(packet, CommandCode.CONNECTION_RESPONSE)
return l2cap_packets.ConnectionResponseView(frame)
@staticmethod
def ConfigurationRequest(cid=None):
return Capture(L2capMatchers.ConfigurationRequest(cid), L2capCaptures._extract_configuration_request)
@staticmethod
def _extract_configuration_request(packet):
frame = L2capMatchers.control_frame_with_code(packet, CommandCode.CONFIGURATION_REQUEST)
return l2cap_packets.ConfigurationRequestView(frame)
@staticmethod
def CreditBasedConnectionRequest(psm):
return Capture(
L2capMatchers.CreditBasedConnectionRequest(psm), L2capCaptures._extract_credit_based_connection_request)
@staticmethod
def _extract_credit_based_connection_request(packet):
frame = L2capMatchers.le_control_frame_with_code(packet, LeCommandCode.LE_CREDIT_BASED_CONNECTION_REQUEST)
return l2cap_packets.LeCreditBasedConnectionRequestView(frame)
@staticmethod
def CreditBasedConnectionResponse():
return Capture(L2capMatchers.CreditBasedConnectionResponse(),
L2capCaptures._extract_credit_based_connection_response)
@staticmethod
def _extract_credit_based_connection_response(packet):
frame = L2capMatchers.le_control_frame_with_code(packet, LeCommandCode.LE_CREDIT_BASED_CONNECTION_RESPONSE)
return l2cap_packets.LeCreditBasedConnectionResponseView(frame)
@staticmethod
def LinkSecurityInterfaceCallbackEvent(type):
return Capture(L2capMatchers.LinkSecurityInterfaceCallbackEvent(type), L2capCaptures._extract_address)
@staticmethod
def _extract_address(packet):
return packet.address
class SecurityCaptures(object):
@staticmethod
def DisplayPasskey():
return Capture(SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PASSKEY), SecurityCaptures._extract_passkey)
@staticmethod
def _extract_passkey(event):
if event is None:
return None
return event.numeric_value