diff --git a/handshake.go b/handshake.go index 435d3e8..fe31a43 100644 --- a/handshake.go +++ b/handshake.go @@ -7,6 +7,7 @@ package mtproto import ( "bytes" + "crypto/rsa" "encoding/binary" "encoding/hex" "fmt" @@ -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") } @@ -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") diff --git a/mtproto.go b/mtproto.go index 7ee97df..e3dabce 100644 --- a/mtproto.go +++ b/mtproto.go @@ -62,7 +62,7 @@ type MTProto struct { tokensStorage session.SessionLoader // один из публичных ключей telegram. нужен только для создания сессии. - publicKey *rsa.PublicKey + publicKeys []*rsa.PublicKey // serviceChannel нужен только на время создания ключей, т.к. это // не RpcResult, поэтому все данные отдаются в один поток без @@ -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) { @@ -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), diff --git a/telegram/common.go b/telegram/common.go index b8edab5..2995225 100644 --- a/telegram/common.go +++ b/telegram/common.go @@ -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")