{"record":{"id":"94bdd52878bf2a6f","repo":"AlexxIT/go2rtc","slug":"hap-validatesignature-94bdd5","errorCode":null,"errorMessage":"hap: ValidateSignature","messagePattern":"hap: ValidateSignature","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/hap/client_pairing.go","lineNumber":266,"sourceCode":"\t\tIdentifier string `tlv8:\"1\"`\n\t\tPublicKey  string `tlv8:\"3\"`\n\t\tSignature  string `tlv8:\"10\"`\n\t}{}\n\tif err = tlv8.Unmarshal(b, &plainM6); err != nil {\n\t\treturn\n\t}\n\n\t// STEP M6. Verify payload\n\tremoteSign, err := hkdf.Sha512(\n\t\tsessionShared, \"Pair-Setup-Accessory-Sign-Salt\", \"Pair-Setup-Accessory-Sign-Info\",\n\t)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tb = Append(remoteSign, plainM6.Identifier, plainM6.PublicKey)\n\tif !ed25519.ValidateSignature([]byte(plainM6.PublicKey), b, []byte(plainM6.Signature)) {\n\t\treturn errors.New(\"hap: ValidateSignature\")\n\t}\n\n\tif c.DeviceID != plainM6.Identifier {\n\t\treturn errors.New(\"hap: wrong DeviceID: \" + plainM6.Identifier)\n\t}\n\n\tc.DevicePublic = []byte(plainM6.PublicKey)\n\n\treturn nil\n}\n\nfunc (c *Client) ListPairings() error {\n\tplainM1 := struct {\n\t\tMethod byte `tlv8:\"0\"`\n\t\tState  byte `tlv8:\"6\"`\n\t}{\n\t\tMethod: MethodListPairings,\n\t\tState:  StateM1,","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/hap/client_pairing.go#L248-L284","documentation":"In Pair's STEP M6, the client verifies the accessory's signature over its signed data using the ed25519 public key carried inside the M6 message itself. This error means the accessory's self-attested identity did not verify — the exchange is untrustworthy, so Pair aborts before comparing DeviceID.","triggerScenarios":"A corrupted or truncated M6 response over a flaky transport; a device (or MITM) answering the pairing exchange without valid long-term key material; firmware bug producing a malformed M6 payload; mixing pairing responses from two devices (e.g. duplicate mDNS entries).","commonSituations":"Two accessories on the network exposing the same mDNS name so the client talks to the wrong one; experimental/clone firmware with broken signing; radio-level packet corruption during pairing; replayed M6 from a previous aborted pairing.","solutions":["Retry Pair on a fresh session — transient corruption resolves on a clean exchange.","Ensure only the intended accessory responds: match the mDNS entry id to DeviceID and remove duplicates on the network.","Power-cycle the accessory and repeat pairing; if it still fails, update or replace the firmware.","Treat repeated failures as a security signal: the peer cannot prove its identity, so do not persist pairing data from the attempt."],"exampleFix":"// before: Pair failure leaves partial state persisted\nerr := client.Pair(pin)\nsavePairing(client) // persisted even on ValidateSignature failure\n// after: persist only after a fully verified pairing\nif err := client.Pair(pin); err != nil {\n    if strings.Contains(err.Error(), \"ValidateSignature\") {\n        return errors.New(\"device identity could not be verified; pairing aborted\")\n    }\n    return err\n}\nsavePairing(client)","handlingStrategy":"try-catch","validationCode":"entries := mdns.Query(mdns.ServiceHAP)\nids := map[string]int{}\nfor _, e := range entries { if e.Complete() { ids[e.Info[\"id\"]]++ } }\nfor id, n := range ids {\n    if n > 1 { return fmt.Errorf(\"duplicate HAP device id %s on network\", id) }\n}","typeGuard":null,"tryCatchPattern":"if err := client.Pair(pin); err != nil {\n    if strings.Contains(err.Error(), \"ValidateSignature\") {\n        // identity not verifiable: abort, do not persist pairing data\n        return errors.New(\"device identity verification failed; check for duplicate devices or bad firmware, then retry on a fresh session\")\n    }\n    return err\n}","preventionTips":["Retry pairing on a fresh session once — transient corruption is the most common cause.","Eliminate duplicate mDNS names/ids on the network so the client cannot talk to the wrong accessory.","Never persist pairing state from a failed M6 verification.","Update clone/experimental firmware that may produce malformed signatures."],"tags":["hap","ed25519","signature","pairing","security"],"backgroundTag":"signature-verification-failed","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}