Contents

AccessoryTransportSecurity

A protocol for an extension that handles cryptographic key exchange with your accessory.

Declaration

protocol AccessoryTransportSecurity : AppExtension

Mentioned 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.

Topics

Accepting session requests

See Also

Notification forwarding