AccessoryTransportSecurity
A protocol for an extension that handles cryptographic key exchange with your accessory.
Declaration
protocol AccessoryTransportSecurity : AppExtensionMentioned in
Overview
Implement this protocol in an extension with an EXExtensionPointIdentifier value of com.apple.accessory-transport-security to manage the key exchange process that establishes encrypted communication with your accessory. The extension runs in a separate process for security isolation and communicates with the system through the extension’s configuration object (AccessoryTransportSecurityConfiguration).
Add the necessary target configuration
In your extension’s target properties, specify the extension point identifier:
<plist>
<dict>
<key>EXAppExtensionAttributes</key>
<dict>
<key>EXExtensionPointIdentifier</key>
<string>com.apple.accessory-transport-security</string>
</dict>
</dict>
</plist>Implement the extension point
In your extension’s Swift code, implement the protocol and provide an event handler that responds to key exchange messages:
@main
struct TransportSecurity: AccessoryTransportSecurity {
@AppExtensionPoint.Bind
static var boundExtensionPoint: AppExtensionPoint {
Identifier("com.apple.accessory-transport-security")
}
func accept(sessionRequest: AccessorySecuritySession.Request) -> AccessorySecuritySession.Request.Decision {
return sessionRequest.accept {
SecurityEventHandler(session: sessionRequest.session)
}
}
}
class SecurityEventHandler: AccessorySecuritySession.EventHandler {
private var session: AccessorySecuritySession
init(session: AccessorySecuritySession) {
self.session = session
}
func messageReceived(_ message: SecurityMessage,
completion: @escaping @Sendable (AccessoryMessage.Result) -> Void) {
// Handle encapsulated key from system.
sendKeyMaterialToAccessory(message)
completion(.success)
}
func sessionInvalidated(error: (any Error)?) {
// Clean up key material.
}
}Initiate key exchange
Your accessory initiates the key exchange by generating a public-private key pair and sending the public key to the system. Choose SecurityMessage.CipherSuite.xWing for post-quantum security or SecurityMessage.CipherSuite.p256 as a fallback:
// Generate key pair.
let privateKey = try XWingMLKEM768X25519.PrivateKey()
let publicKey = privateKey.publicKey.rawRepresentation
// Send public key to system.
let message = SecurityMessage(
keyType: .publicKey,
cipherSuite: .xWing,
version: .version1,
key: publicKey,
supportedTransports: [.bluetooth]
)
try session.sendSecurityMessage(message)The system generates cryptographic key material and delivers it to your extension by calling messageReceived(_:completion:) with a SecurityMessage containing SecurityMessage.KeyType.encapsulatedKey. Forward this key material to your accessory via Bluetooth and call the completion handler with the transmission result.
For more information, see Receiving iOS notifications on an accessory.