code.pfad.fr/gohmekit@v0.2.1/pairing/pairings.go (about) 1 package pairing 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 8 "code.pfad.fr/gohmekit/tlv8" 9 ) 10 11 type pairingsRequest struct { 12 ktlvState 13 Method byte `tlv8:"kTLVType_Method"` 14 15 // for pairingsAdd and pairingsRemove 16 Identifier []byte `tlv8:"kTLVType_Identifier"` 17 // for pairingsAdd 18 PublicKey []byte `tlv8:"kTLVType_PublicKey"` 19 } 20 21 func (srv *HTTPServer) pairings(_ *encryptableConn, r io.Reader) ([]byte, error) { 22 var req pairingsRequest 23 err := tlv8.NewDecoder(r).Decode(&req) 24 if err != nil { 25 return nil, err 26 } 27 28 if req.State != 1 { 29 return nil, fmt.Errorf("unexpected state: %d", req.State) 30 } 31 32 switch req.Method { 33 case kTLVMethod_AddPairing: 34 return srv.pairingsAdd(req) 35 case kTLVMethod_RemovePairing: 36 return srv.pairingsRemove(req) 37 case kTLVMethod_ListPairings: 38 return srv.pairingsList(req) 39 default: 40 return nil, fmt.Errorf("unexpected method: %d", req.Method) 41 } 42 } 43 44 func (srv *HTTPServer) pairingsAdd(req pairingsRequest) ([]byte, error) { 45 saved, err := srv.Database.GetLongTermPublicKey(req.Identifier) 46 if err == nil && len(saved) > 0 { 47 if !bytes.Equal(saved, req.PublicKey) { 48 return ktlvError(2, kTLVError_Unknown) 49 } 50 // TODO: update permissions? 51 52 return tlv8.Marshal(ktlvState{2}) 53 } 54 55 err = srv.Database.AddLongTermPublicKey(Controller{ 56 PairingID: req.Identifier, 57 LongTermPublicKey: req.PublicKey, 58 }) 59 if err != nil { 60 return nil, err 61 } 62 return tlv8.Marshal(ktlvState{2}) 63 } 64 65 func (srv *HTTPServer) pairingsRemove(req pairingsRequest) ([]byte, error) { 66 err := srv.Database.RemoveLongTermPublicKey(req.Identifier) 67 if err != nil { 68 return nil, err 69 } 70 71 return tlv8.Marshal(ktlvState{2}) 72 } 73 74 func (srv *HTTPServer) pairingsList(_ pairingsRequest) ([]byte, error) { 75 controllers, err := srv.Database.ListLongTermPublicKey() 76 if err != nil { 77 return nil, err 78 } 79 80 type controller struct { 81 Identifier []byte `tlv8:"kTLVType_Identifier"` 82 PublicKey []byte `tlv8:"kTLVType_PublicKey"` 83 Permissions byte `tlv8:"kTLVType_Permissions"` 84 Separator struct{} `tlv8:"kTLVType_Separator"` 85 } 86 response := struct { 87 ktlvState 88 Controllers []controller `tlv8:""` 89 }{ 90 ktlvState: ktlvState{2}, 91 Controllers: make([]controller, 0, len(controllers)), 92 } 93 94 for _, c := range controllers { 95 response.Controllers = append(response.Controllers, controller{ 96 Identifier: c.PairingID, 97 PublicKey: c.LongTermPublicKey, 98 // Permissions: 0, 99 }) 100 } 101 102 return tlv8.Marshal(response) 103 }