// Tests the pairing key verification func TestInvalidPublicKey(t *testing.T) { storage, err := util.NewTempFileStorage() if err != nil { t.Fatal(err) } database := db.NewDatabaseWithStorage(storage) bridge, err := hap.NewSecuredDevice("Macbook Bridge", "001-02-003", database) if err != nil { t.Fatal(err) } context := hap.NewContextForSecuredDevice(bridge) controller := NewVerifyServerController(database, context) client, _ := hap.NewDevice("HomeKit Client", database) clientController := NewVerifyClientController(client, database) req := clientController.InitialKeyVerifyRequest() reqContainer, err := util.NewTLV8ContainerFromReader(req) if err != nil { t.Fatal(err) } reqContainer.SetByte(TagPublicKey, byte(0x01)) // 1) C -> S if _, err = HandleReaderForHandler(reqContainer.BytesBuffer(), controller); err != errInvalidClientKeyLength { t.Fatal("expected invalid client key length error") } }
// NewIPTransport creates a transport to provide accessories over IP. // // The IP transports stores the crypto keys inside a database, which // is by default inside a folder at the current working directory. // The folder is named exactly as the accessory name. // // The transports can contain more than one accessory. If this is the // case, the first accessory acts as the HomeKit bridge. // // *Important:* Changing the name of the accessory, or letting multiple // transports store the data inside the same database lead to // unexpected behavior – don't do that. // // The transport is secured with an 8-digit pin, which must be entered // by an iOS client to successfully pair with the accessory. If the // provided transport config does not specify any pin, 00102003 is used. func NewIPTransport(config Config, a *accessory.Accessory, as ...*accessory.Accessory) (Transport, error) { // Find transport name which is visible in mDNS name := a.Info.Name.GetValue() if len(name) == 0 { log.Info.Panic("Invalid empty name for first accessory") } cfg := defaultConfig(name) cfg.merge(config) storage, err := util.NewFileStorage(cfg.StoragePath) if err != nil { return nil, err } database := db.NewDatabaseWithStorage(storage) hap_pin, err := NewPin(cfg.Pin) if err != nil { return nil, err } cfg.load(storage) device, err := hap.NewSecuredDevice(cfg.id, hap_pin, database) t := &ipTransport{ storage: storage, database: database, device: device, config: cfg, container: accessory.NewContainer(), mutex: &sync.Mutex{}, context: hap.NewContextForSecuredDevice(device), emitter: event.NewEmitter(), } t.addAccessory(a) for _, a := range as { t.addAccessory(a) } // Users can only pair discoverable accessories if t.isPaired() { cfg.discoverable = false } cfg.categoryId = int(t.container.AccessoryType()) cfg.updateConfigHash(t.container.ContentHash()) cfg.save(storage) // Listen for events to update mDNS txt records t.emitter.AddListener(t) return t, err }
// Tests the pairing key verification func TestPairVerifyIntegration(t *testing.T) { storage, err := util.NewTempFileStorage() if err != nil { t.Fatal(err) } database := db.NewDatabaseWithStorage(storage) bridge, err := hap.NewSecuredDevice("Macbook Bridge", "001-02-003", database) if err != nil { t.Fatal(err) } context := hap.NewContextForSecuredDevice(bridge) controller := NewVerifyServerController(database, context) clientDatabase, _ := db.NewTempDatabase() bridgeEntity := db.NewEntity(bridge.Name(), bridge.PublicKey(), nil) err = clientDatabase.SaveEntity(bridgeEntity) if err != nil { t.Fatal(err) } client, _ := hap.NewDevice("HomeKit Client", clientDatabase) clientEntity := db.NewEntity(client.Name(), client.PublicKey(), nil) err = database.SaveEntity(clientEntity) if err != nil { t.Fatal(err) } clientController := NewVerifyClientController(client, clientDatabase) tlvVerifyStepStartRequest := clientController.InitialKeyVerifyRequest() // 1) C -> S tlvVerifyStepStartResponse, err := HandleReaderForHandler(tlvVerifyStepStartRequest, controller) if err != nil { t.Fatal(err) } // 2) S -> C tlvFinishRequest, err := HandleReaderForHandler(tlvVerifyStepStartResponse, clientController) if err != nil { t.Fatal(err) } // 3) C -> S tlvFinishRespond, err := HandleReaderForHandler(tlvFinishRequest, controller) if err != nil { t.Fatal(err) } // 4) S -> C response, err := HandleReaderForHandler(tlvFinishRespond, clientController) if err != nil { t.Fatal(err) } if response != nil { t.Fatal(response) } }
// Tests the pairing setup func TestPairingIntegration(t *testing.T) { storage, err := util.NewTempFileStorage() if err != nil { t.Fatal(err) } database := db.NewDatabaseWithStorage(storage) bridge, err := hap.NewSecuredDevice("Macbook Bridge", "001-02-003", database) if err != nil { t.Fatal(err) } controller, err := NewSetupServerController(bridge, database) if err != nil { t.Fatal(err) } clientDatabase, _ := db.NewTempDatabase() client, _ := hap.NewDevice("Client", clientDatabase) clientController := NewSetupClientController("001-02-003", client, clientDatabase) pairStartRequest := clientController.InitialPairingRequest() // 1) C -> S pairStartResponse, err := HandleReaderForHandler(pairStartRequest, controller) if err != nil { t.Fatal(err) } // 2) S -> C pairVerifyRequest, err := HandleReaderForHandler(pairStartResponse, clientController) if err != nil { t.Fatal(err) } // 3) C -> S pairVerifyResponse, err := HandleReaderForHandler(pairVerifyRequest, controller) if err != nil { t.Fatal(err) } // 4) S -> C pairKeyRequest, err := HandleReaderForHandler(pairVerifyResponse, clientController) if err != nil { t.Fatal(err) } // 5) C -> S pairKeyRespond, err := HandleReaderForHandler(pairKeyRequest, controller) if err != nil { t.Fatal(err) } // 6) S -> C request, err := HandleReaderForHandler(pairKeyRespond, clientController) if err != nil { t.Fatal(err) } if request != nil { t.Fatal(request) } }