Skip to content

Commit

Permalink
✨ Try all public keys
Browse files Browse the repository at this point in the history
Updates #111
  • Loading branch information
tdakkota authored Oct 12, 2022
1 parent d93f9ab commit 95c4542
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 12 deletions.
21 changes: 13 additions & 8 deletions handshake.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package mtproto

import (
"bytes"
"crypto/rsa"
"encoding/binary"
"encoding/hex"
"fmt"
Expand Down Expand Up @@ -35,14 +36,18 @@ func (m *MTProto) makeAuthKey() error { // nolint don't know how to make method
if nonceFirst.Cmp(res.Nonce.Int) != 0 {
return errors.New("handshake: Wrong nonce")
}
found := false
for _, b := range res.Fingerprints {
if uint64(b) == binary.LittleEndian.Uint64(keys.RSAFingerprint(m.publicKey)) {
found = true
break

var key *rsa.PublicKey
for _, publicKey := range m.publicKeys {
fp := keys.RSAFingerprint(publicKey)
for _, b := range res.Fingerprints {
if uint64(b) == binary.LittleEndian.Uint64(fp) {
key = publicKey
break
}
}
}
if !found {
if key == nil {
return errors.New("handshake: Can't find fingerprint")
}

Expand All @@ -65,9 +70,9 @@ func (m *MTProto) makeAuthKey() error { // nolint don't know how to make method
hashAndMsg := make([]byte, 255)
copy(hashAndMsg, append(dry.Sha1(string(message)), message...))

encryptedMessage := math.DoRSAencrypt(hashAndMsg, m.publicKey)
encryptedMessage := math.DoRSAencrypt(hashAndMsg, key)

keyFingerprint := int64(binary.LittleEndian.Uint64(keys.RSAFingerprint(m.publicKey)))
keyFingerprint := int64(binary.LittleEndian.Uint64(keys.RSAFingerprint(key)))
dhResponse, err := m.reqDHParams(nonceFirst, nonceServer, p.Bytes(), q.Bytes(), keyFingerprint, encryptedMessage)
if err != nil {
return errors.Wrap(err, "sending ReqDHParams")
Expand Down
7 changes: 4 additions & 3 deletions mtproto.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ type MTProto struct {
tokensStorage session.SessionLoader

// один из публичных ключей telegram. нужен только для создания сессии.
publicKey *rsa.PublicKey
publicKeys []*rsa.PublicKey

// serviceChannel нужен только на время создания ключей, т.к. это
// не RpcResult, поэтому все данные отдаются в один поток без
Expand All @@ -87,7 +87,8 @@ type Config struct {
SessionStorage session.SessionLoader

ServerHost string
PublicKey *rsa.PublicKey
PublicKey *rsa.PublicKey //! DEPRECATED // use PublicKeys
PublicKeys []*rsa.PublicKey
}

func NewMTProto(c Config) (*MTProto, error) {
Expand All @@ -112,7 +113,7 @@ func NewMTProto(c Config) (*MTProto, error) {
encrypted: s != nil, // if not nil, then it's already encrypted, otherwise makes no sense
sessionId: utils.GenerateSessionID(),
serviceChannel: make(chan tl.Object),
publicKey: c.PublicKey,
publicKeys: append([]*rsa.PublicKey{c.PublicKey}, c.PublicKeys...),
responseChannels: utils.NewSyncIntObjectChan(),
expectedTypes: utils.NewSyncIntReflectTypes(),
serverRequestHandlers: make([]customHandlerFunc, 0),
Expand Down
2 changes: 1 addition & 1 deletion telegram/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func NewClient(c ClientConfig) (*Client, error) { //nolint: gocritic arg is not
m, err := mtproto.NewMTProto(mtproto.Config{
AuthKeyFile: c.SessionFile,
ServerHost: c.ServerHost,
PublicKey: publicKeys[0],
PublicKeys: publicKeys,
})
if err != nil {
return nil, errors.Wrap(err, "setup common MTProto client")
Expand Down

0 comments on commit 95c4542

Please sign in to comment.