code.pfad.fr/gohmekit@v0.2.1/pairing/pair_verify_test.go (about) 1 package pairing_test 2 3 import ( 4 "crypto/ed25519" 5 "net" 6 "net/http" 7 "testing" 8 9 "code.pfad.fr/gohmekit/pairing" 10 "code.pfad.fr/gohmekit/storage" 11 "github.com/brutella/hc/db" 12 "github.com/brutella/hc/hap" 13 "github.com/brutella/hc/hap/pair" 14 "github.com/brutella/hc/util" 15 "gotest.tools/v3/assert" 16 ) 17 18 // Tests the pairing key verification. 19 func TestPairVerifyIntegration(t *testing.T) { 20 database := storage.NewMemDatabase() 21 _, privateKey, err := ed25519.GenerateKey(nil) 22 assert.NilError(t, err) 23 bridge, err := pairing.NewDeviceWithPin(pairing.NewRandomPairingID(), "001-02-003", privateKey) 24 assert.NilError(t, err) 25 26 s := pairing.NewServer(&http.Server{}, bridge, database) 27 28 addr := startServer(t, s) 29 30 clientStorage, err := util.NewFileStorage(t.TempDir()) 31 assert.NilError(t, err) 32 33 clientDatabase := db.NewDatabaseWithStorage(clientStorage) 34 bridgeEntity := db.NewEntity(string(bridge.PairingID()), bridge.OwnLongTermPublicKey(), nil) 35 err = clientDatabase.SaveEntity(bridgeEntity) 36 assert.NilError(t, err) 37 38 client, err := hap.NewDevice("HomeKit Client", clientDatabase) 39 assert.NilError(t, err) 40 err = database.AddLongTermPublicKey(pairing.Controller{PairingID: []byte(client.Name()), LongTermPublicKey: client.PublicKey()}) 41 assert.NilError(t, err) 42 43 clientController := pair.NewVerifyClientController(client, clientDatabase) 44 45 tlvVerifyStepStartRequest := clientController.InitialKeyVerifyRequest() 46 47 httpClient, encryptClientConn := newHTTPClient() 48 _ = encryptClientConn 49 50 // 1) C -> S 51 resp, err := httpClient.Post(addr+"pair-verify", pairing.ContentType, tlvVerifyStepStartRequest) 52 assert.NilError(t, err) 53 assert.Equal(t, 200, resp.StatusCode) 54 55 // 2) S -> C 56 tlvFinishRequest, err := pair.HandleReaderForHandler(resp.Body, clientController) 57 assert.NilError(t, err) 58 assert.NilError(t, resp.Body.Close()) 59 60 // 3) C -> S 61 resp, err = httpClient.Post(addr+"pair-verify", pairing.ContentType, tlvFinishRequest) 62 assert.NilError(t, err) 63 assert.Equal(t, 200, resp.StatusCode) 64 65 // // 4) S -> C 66 response, err := pair.HandleReaderForHandler(resp.Body, clientController) 67 assert.NilError(t, err) 68 assert.NilError(t, resp.Body.Close()) 69 assert.Equal(t, response, nil) 70 } 71 72 func BenchmarkPairVerify(b *testing.B) { 73 database := storage.NewMemDatabase() 74 _, privateKey, err := ed25519.GenerateKey(nil) 75 76 assert.NilError(b, err) 77 bridge, err := pairing.NewDeviceWithPin(pairing.NewRandomPairingID(), "001-02-003", privateKey) 78 assert.NilError(b, err) 79 80 s := pairing.NewServer(&http.Server{}, bridge, database) 81 82 ln, err := net.Listen("tcp", ":0") 83 assert.NilError(b, err) 84 defer func() { 85 assert.NilError(b, ln.Close()) 86 }() 87 go s.Serve(ln) //nolint:errcheck 88 addr := "http://" + ln.Addr().String() + "/" 89 90 clientStorage, err := util.NewFileStorage(b.TempDir()) 91 assert.NilError(b, err) 92 93 clientDatabase := db.NewDatabaseWithStorage(clientStorage) 94 bridgeEntity := db.NewEntity(string(bridge.PairingID()), bridge.OwnLongTermPublicKey(), nil) 95 err = clientDatabase.SaveEntity(bridgeEntity) 96 assert.NilError(b, err) 97 98 client, err := hap.NewDevice("HomeKit Client", clientDatabase) 99 assert.NilError(b, err) 100 err = database.AddLongTermPublicKey(pairing.Controller{PairingID: []byte(client.Name()), LongTermPublicKey: client.PublicKey()}) 101 assert.NilError(b, err) 102 103 for i := 0; i < b.N; i++ { 104 clientController := pair.NewVerifyClientController(client, clientDatabase) 105 106 tlvVerifyStepStartRequest := clientController.InitialKeyVerifyRequest() 107 108 httpClient, encryptClientConn := newHTTPClient() 109 _ = encryptClientConn 110 111 // 1) C -> S 112 resp, err := httpClient.Post(addr+"pair-verify", pairing.ContentType, tlvVerifyStepStartRequest) 113 assert.NilError(b, err) 114 assert.Equal(b, 200, resp.StatusCode) 115 116 // 2) S -> C 117 tlvFinishRequest, err := pair.HandleReaderForHandler(resp.Body, clientController) 118 assert.NilError(b, err) 119 assert.NilError(b, resp.Body.Close()) 120 121 // 3) C -> S 122 resp, err = httpClient.Post(addr+"pair-verify", pairing.ContentType, tlvFinishRequest) 123 assert.NilError(b, err) 124 assert.Equal(b, 200, resp.StatusCode) 125 126 // // 4) S -> C 127 response, err := pair.HandleReaderForHandler(resp.Body, clientController) 128 assert.NilError(b, err) 129 assert.NilError(b, resp.Body.Close()) 130 assert.Equal(b, response, nil) 131 } 132 }