Improve homekit tlv8 parsing
This commit is contained in:
+2
-2
@@ -124,7 +124,7 @@ func (c *Client) Dial() (err error) {
|
|||||||
EncryptedData string `tlv8:"5"`
|
EncryptedData string `tlv8:"5"`
|
||||||
State byte `tlv8:"6"`
|
State byte `tlv8:"6"`
|
||||||
}
|
}
|
||||||
if err = tlv8.UnmarshalReader(res.Body, &cipherM2); err != nil {
|
if err = tlv8.UnmarshalReader(res.Body, res.ContentLength, &cipherM2); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if cipherM2.State != StateM2 {
|
if cipherM2.State != StateM2 {
|
||||||
@@ -209,7 +209,7 @@ func (c *Client) Dial() (err error) {
|
|||||||
var plainM4 struct {
|
var plainM4 struct {
|
||||||
State byte `tlv8:"6"`
|
State byte `tlv8:"6"`
|
||||||
}
|
}
|
||||||
if err = tlv8.UnmarshalReader(res.Body, &plainM4); err != nil {
|
if err = tlv8.UnmarshalReader(res.Body, res.ContentLength, &plainM4); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if plainM4.State != StateM4 {
|
if plainM4.State != StateM4 {
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ func (c *Client) Pair(feature, pin string) (err error) {
|
|||||||
State byte `tlv8:"6"`
|
State byte `tlv8:"6"`
|
||||||
Error byte `tlv8:"7"`
|
Error byte `tlv8:"7"`
|
||||||
}
|
}
|
||||||
if err = tlv8.UnmarshalReader(res.Body, &plainM2); err != nil {
|
if err = tlv8.UnmarshalReader(res.Body, res.ContentLength, &plainM2); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if plainM2.State != StateM2 {
|
if plainM2.State != StateM2 {
|
||||||
@@ -159,7 +159,7 @@ func (c *Client) Pair(feature, pin string) (err error) {
|
|||||||
|
|
||||||
EncryptedData string `tlv8:"5"` // skip EncryptedData validation (for MFi devices)
|
EncryptedData string `tlv8:"5"` // skip EncryptedData validation (for MFi devices)
|
||||||
}
|
}
|
||||||
if err = tlv8.UnmarshalReader(res.Body, &plainM4); err != nil {
|
if err = tlv8.UnmarshalReader(res.Body, res.ContentLength, &plainM4); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if plainM4.State != StateM4 {
|
if plainM4.State != StateM4 {
|
||||||
@@ -232,7 +232,7 @@ func (c *Client) Pair(feature, pin string) (err error) {
|
|||||||
State byte `tlv8:"6"`
|
State byte `tlv8:"6"`
|
||||||
Error byte `tlv8:"7"`
|
Error byte `tlv8:"7"`
|
||||||
}{}
|
}{}
|
||||||
if err = tlv8.UnmarshalReader(res.Body, &cipherM6); err != nil {
|
if err = tlv8.UnmarshalReader(res.Body, res.ContentLength, &cipherM6); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if cipherM6.State != StateM6 || cipherM6.Error != 0 {
|
if cipherM6.State != StateM6 || cipherM6.Error != 0 {
|
||||||
@@ -296,7 +296,7 @@ func (c *Client) ListPairings() error {
|
|||||||
State byte `tlv8:"6"`
|
State byte `tlv8:"6"`
|
||||||
Permission byte `tlv8:"11"`
|
Permission byte `tlv8:"11"`
|
||||||
}
|
}
|
||||||
if err = tlv8.UnmarshalReader(res.Body, &plainM2); err != nil {
|
if err = tlv8.UnmarshalReader(res.Body, res.ContentLength, &plainM2); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,7 +329,7 @@ func (c *Client) PairingsAdd(clientID string, clientPublic []byte, admin bool) e
|
|||||||
State byte `tlv8:"6"`
|
State byte `tlv8:"6"`
|
||||||
Unknown byte `tlv8:"7"`
|
Unknown byte `tlv8:"7"`
|
||||||
}
|
}
|
||||||
if err = tlv8.UnmarshalReader(res.Body, &plainM2); err != nil {
|
if err = tlv8.UnmarshalReader(res.Body, res.ContentLength, &plainM2); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,7 +354,7 @@ func (c *Client) DeletePairing(id string) error {
|
|||||||
var plainM2 struct {
|
var plainM2 struct {
|
||||||
State byte `tlv8:"6"`
|
State byte `tlv8:"6"`
|
||||||
}
|
}
|
||||||
if err = tlv8.UnmarshalReader(res.Body, &plainM2); err != nil {
|
if err = tlv8.UnmarshalReader(res.Body, res.ContentLength, &plainM2); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if plainM2.State != StateM2 {
|
if plainM2.State != StateM2 {
|
||||||
|
|||||||
+2
-3
@@ -6,7 +6,6 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@@ -55,7 +54,7 @@ func (s *Server) PairVerify(req *http.Request, rw *bufio.ReadWriter, conn net.Co
|
|||||||
PublicKey string `tlv8:"3"`
|
PublicKey string `tlv8:"3"`
|
||||||
State byte `tlv8:"6"`
|
State byte `tlv8:"6"`
|
||||||
}
|
}
|
||||||
if err := tlv8.UnmarshalReader(io.LimitReader(rw, req.ContentLength), &plainM1); err != nil {
|
if err := tlv8.UnmarshalReader(req.Body, req.ContentLength, &plainM1); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if plainM1.State != StateM1 {
|
if plainM1.State != StateM1 {
|
||||||
@@ -125,7 +124,7 @@ func (s *Server) PairVerify(req *http.Request, rw *bufio.ReadWriter, conn net.Co
|
|||||||
EncryptedData string `tlv8:"5"`
|
EncryptedData string `tlv8:"5"`
|
||||||
State byte `tlv8:"6"`
|
State byte `tlv8:"6"`
|
||||||
}
|
}
|
||||||
if err = tlv8.UnmarshalReader(req.Body, &cipherM3); err != nil {
|
if err = tlv8.UnmarshalReader(req.Body, req.ContentLength, &cipherM3); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if cipherM3.State != StateM3 {
|
if cipherM3.State != StateM3 {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"crypto/sha512"
|
"crypto/sha512"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@@ -25,18 +24,33 @@ const (
|
|||||||
PairMethodList
|
PairMethodList
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) PairSetup(req *http.Request, rw *bufio.ReadWriter, conn net.Conn) error {
|
func (s *Server) HandleConn(conn net.Conn) error {
|
||||||
if req.Header.Get("Content-Type") != MimeTLV8 {
|
rd := bufio.NewReader(conn)
|
||||||
return errors.New("hap: wrong content type")
|
req, err := http.ReadRequest(rd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rw := bufio.NewReadWriter(rd, bufio.NewWriter(conn))
|
||||||
|
|
||||||
|
switch req.RequestURI {
|
||||||
|
case PathPairSetup:
|
||||||
|
return s.PairSetup(req, rw, conn)
|
||||||
|
case PathPairVerify:
|
||||||
|
return s.PairVerify(req, rw, conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.New("hap: unsupported request uri: " + req.RequestURI)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) PairSetup(req *http.Request, rw *bufio.ReadWriter, conn net.Conn) error {
|
||||||
// STEP 1. Request from iPhone
|
// STEP 1. Request from iPhone
|
||||||
var plainM1 struct {
|
var plainM1 struct {
|
||||||
Method byte `tlv8:"0"`
|
Method byte `tlv8:"0"`
|
||||||
State byte `tlv8:"6"`
|
State byte `tlv8:"6"`
|
||||||
Flags uint32 `tlv8:"19"`
|
Flags uint32 `tlv8:"19"`
|
||||||
}
|
}
|
||||||
if err := tlv8.UnmarshalReader(io.LimitReader(rw, req.ContentLength), &plainM1); err != nil {
|
if err := tlv8.UnmarshalReader(req.Body, req.ContentLength, &plainM1); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if plainM1.State != StateM1 {
|
if plainM1.State != StateM1 {
|
||||||
@@ -87,7 +101,7 @@ func (s *Server) PairSetup(req *http.Request, rw *bufio.ReadWriter, conn net.Con
|
|||||||
Proof string `tlv8:"4"`
|
Proof string `tlv8:"4"`
|
||||||
State byte `tlv8:"6"`
|
State byte `tlv8:"6"`
|
||||||
}
|
}
|
||||||
if err = tlv8.UnmarshalReader(req.Body, &plainM3); err != nil {
|
if err = tlv8.UnmarshalReader(req.Body, req.ContentLength, &plainM3); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if plainM3.State != StateM3 {
|
if plainM3.State != StateM3 {
|
||||||
@@ -129,7 +143,7 @@ func (s *Server) PairSetup(req *http.Request, rw *bufio.ReadWriter, conn net.Con
|
|||||||
EncryptedData string `tlv8:"5"`
|
EncryptedData string `tlv8:"5"`
|
||||||
State byte `tlv8:"6"`
|
State byte `tlv8:"6"`
|
||||||
}
|
}
|
||||||
if err = tlv8.UnmarshalReader(req.Body, &cipherM5); err != nil {
|
if err = tlv8.UnmarshalReader(req.Body, req.ContentLength, &cipherM5); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if cipherM5.State != StateM5 {
|
if cipherM5.State != StateM5 {
|
||||||
|
|||||||
+11
-2
@@ -170,11 +170,20 @@ func UnmarshalBase64(in any, out any) error {
|
|||||||
return Unmarshal(data, out)
|
return Unmarshal(data, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func UnmarshalReader(r io.Reader, v any) error {
|
func UnmarshalReader(r io.Reader, n int64, v any) error {
|
||||||
data, err := io.ReadAll(r)
|
var data []byte
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if n > 0 {
|
||||||
|
data = make([]byte, n)
|
||||||
|
_, err = io.ReadFull(r, data)
|
||||||
|
} else {
|
||||||
|
data, err = io.ReadAll(r)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return Unmarshal(data, v)
|
return Unmarshal(data, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ func handlePairings(conn net.Conn, req *http.Request, pair ServerPair) (*http.Re
|
|||||||
Permissions byte `tlv8:"11"`
|
Permissions byte `tlv8:"11"`
|
||||||
}{}
|
}{}
|
||||||
|
|
||||||
if err := tlv8.UnmarshalReader(req.Body, &cmd); err != nil {
|
if err := tlv8.UnmarshalReader(req.Body, req.ContentLength, &cmd); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user