Sfoglia il codice sorgente

Add RPC structs for nonce

tags/0.9
9seconds 7 anni fa
parent
commit
9f90f87758
3 ha cambiato i file con 130 aggiunte e 0 eliminazioni
  1. 5
    0
      mtproto/rpc/rpc.go
  2. 67
    0
      mtproto/rpc/rpc_nonce_request.go
  3. 58
    0
      mtproto/rpc/rpc_nonce_response.go

+ 5
- 0
mtproto/rpc/rpc.go Vedi File

@@ -0,0 +1,5 @@
1
+package rpc
2
+
3
+type RPC interface {
4
+	Bytes() []byte
5
+}

+ 67
- 0
mtproto/rpc/rpc_nonce_request.go Vedi File

@@ -0,0 +1,67 @@
1
+package rpc
2
+
3
+import (
4
+	"bytes"
5
+	"crypto/rand"
6
+	"encoding/binary"
7
+	"time"
8
+
9
+	"github.com/juju/errors"
10
+)
11
+
12
+const (
13
+	RPCNonceSeqNo = -2
14
+
15
+	rpcNonceLength            = 16
16
+	rpcNonceKeySelectorLength = 4
17
+	rpcNonceCryptoTSLength    = 4
18
+	rpcNonceTagLength         = 4
19
+	rpcNonceCryptoAESLength   = 4
20
+
21
+	rpcNonceRequestLength = rpcNonceTagLength + rpcNonceKeySelectorLength +
22
+		rpcNonceCryptoAESLength + rpcNonceCryptoTSLength + rpcNonceLength
23
+)
24
+
25
+var (
26
+	rpcNonceTag          = [rpcNonceTagLength]byte{0xaa, 0x87, 0xcb, 0x7a}
27
+	rpcNonceCryptoAESTag = [rpcNonceCryptoAESLength]byte{0x01, 0x00, 0x00, 0x00}
28
+)
29
+
30
+type RPCNonceRequest struct {
31
+	KeySelector [rpcNonceKeySelectorLength]byte
32
+	CryptoTS    [rpcNonceCryptoTSLength]byte
33
+	Nonce       [rpcNonceLength]byte
34
+}
35
+
36
+func (r *RPCNonceRequest) Bytes() []byte {
37
+	buf := &bytes.Buffer{}
38
+	buf.Grow(rpcNonceRequestLength)
39
+
40
+	buf.Write(rpcNonceTag[:])
41
+	buf.Write(r.KeySelector[:])
42
+	buf.Write(rpcNonceCryptoAESTag[:])
43
+	buf.Write(r.CryptoTS[:])
44
+	buf.Write(r.Nonce[:])
45
+
46
+	return buf.Bytes()
47
+}
48
+
49
+func NewRPCNonceRequest(proxySecret []byte) (*RPCNonceRequest, error) {
50
+	var nonce [rpcNonceLength]byte
51
+	var keySelector [rpcNonceKeySelectorLength]byte
52
+	var cryptoTS [rpcNonceCryptoTSLength]byte
53
+
54
+	if _, err := rand.Read(nonce[:]); err != nil {
55
+		return nil, errors.Annotate(err, "Cannot generate nonce")
56
+	}
57
+	copy(keySelector[:], proxySecret)
58
+
59
+	timestamp := time.Now().Truncate(time.Second).Unix() % 4294967296 // 256 ^ 4 - do not know how to name
60
+	binary.LittleEndian.PutUint32(cryptoTS[:], uint32(timestamp))
61
+
62
+	return &RPCNonceRequest{
63
+		KeySelector: keySelector,
64
+		CryptoTS:    cryptoTS,
65
+		Nonce:       nonce,
66
+	}, nil
67
+}

+ 58
- 0
mtproto/rpc/rpc_nonce_response.go Vedi File

@@ -0,0 +1,58 @@
1
+package rpc
2
+
3
+import (
4
+	"bytes"
5
+
6
+	"github.com/juju/errors"
7
+)
8
+
9
+const rpcNonceResponseLength = rpcNonceRequestLength
10
+
11
+type RPCNonceResponse struct {
12
+	RPCNonceRequest
13
+
14
+	RPCType [rpcNonceTagLength]byte
15
+	Crypto  [rpcNonceCryptoAESLength]byte
16
+}
17
+
18
+func (r *RPCNonceResponse) Bytes() []byte {
19
+	buf := &bytes.Buffer{}
20
+	buf.Grow(rpcNonceResponseLength)
21
+
22
+	buf.Write(r.RPCType[:])
23
+	buf.Write(r.KeySelector[:])
24
+	buf.Write(r.Crypto[:])
25
+	buf.Write(r.CryptoTS[:])
26
+	buf.Write(r.Nonce[:])
27
+
28
+	return buf.Bytes()
29
+}
30
+
31
+func (r *RPCNonceResponse) Valid(req *RPCNonceRequest) error {
32
+	if r.RPCType != rpcNonceTag {
33
+		return errors.New("Unexpected RPC type")
34
+	}
35
+	if r.Crypto != rpcNonceCryptoAESTag {
36
+		return errors.New("Unexpected crypto type")
37
+	}
38
+	if r.KeySelector != req.KeySelector {
39
+		return errors.New("Unexpected key selector")
40
+	}
41
+
42
+	return nil
43
+}
44
+
45
+func NewRPCNonceResponse(data []byte) (*RPCNonceResponse, error) {
46
+	if len(data) != rpcNonceResponseLength {
47
+		return nil, errors.New("Unexpected message length")
48
+	}
49
+
50
+	resp := RPCNonceResponse{}
51
+	copy(resp.RPCType[:], data[:4])
52
+	copy(resp.KeySelector[:], data[4:8])
53
+	copy(resp.Crypto[:], data[8:12])
54
+	copy(resp.CryptoTS[:], data[12:16])
55
+	copy(resp.Nonce[:], data[16:])
56
+
57
+	return &resp, nil
58
+}

Loading…
Annulla
Salva