Ejemplo n.º 1
0
        void OnLoginKey(SteamUser.LoginKeyCallback callback)
        {
            string SessionID = WebHelpers.EncodeBase64(callback.UniqueID.ToString());

            using (dynamic userAuth = WebAPI.GetInterface("ISteamUserAuth"))
            {
                // generate an AES session key
                var sessionKey = CryptoHelper.GenerateRandomBlock(32);

                // rsa encrypt it with the public key for the universe we're on
                byte[] cryptedSessionKey = null;
                using (var rsa = new RSACrypto(KeyDictionary.GetPublicKey(Client.ConnectedUniverse)))
                {
                    cryptedSessionKey = rsa.Encrypt(sessionKey);
                }

                byte[] loginKey = new byte[20];
                Array.Copy(Encoding.ASCII.GetBytes(callback.LoginKey), loginKey, callback.LoginKey.Length);

                // AES encrypt the loginkey with our session key.
                byte[] cryptedLoginKey = CryptoHelper.SymmetricEncrypt(loginKey, sessionKey);

                KeyValue authResult = null;
                EResult  result     = EResult.OK;

                try
                {
                    authResult = userAuth.AuthenticateUser(
                        steamid: Client.SteamID.ConvertToUInt64(),
                        sessionkey: WebHelpers.UrlEncode(cryptedSessionKey),
                        encrypted_loginkey: WebHelpers.UrlEncode(cryptedLoginKey),
                        method: "POST"
                        );
                }
                catch (Exception)
                {
                    result = EResult.Fail;
                }

                Login.SessionId = SessionID;

                if (authResult != null)
                {
                    Login.Token = authResult["token"].AsString();
                }

                this.Client.PostCallback(new WebLoggedOnCallback()
                {
                    Result = result,
                    Login  = Login
                });
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Connects and authenticates to the specified content server.
        /// </summary>
        /// <param name="csServer">The content server to connect to.</param>
        /// <exception cref="System.ArgumentNullException">csServer was null.</exception>
        public void Connect(Server csServer)
        {
            DebugLog.Assert(steamClient.IsConnected, "CDNClient", "CMClient is not connected!");

            if (csServer == null)
            {
                throw new ArgumentNullException("csServer");
            }

            byte[] pubKey = KeyDictionary.GetPublicKey(steamClient.ConnectedUniverse);

            sessionKey = CryptoHelper.GenerateRandomBlock(32);

            byte[] cryptedSessKey = null;
            using (var rsa = new RSACrypto(pubKey))
            {
                cryptedSessKey = rsa.Encrypt(sessionKey);
            }

            string data;

            if (appTicket == null)
            {
                // no appticket, doing anonymous connection
                data = string.Format("sessionkey={0}&anonymoususer=1&steamid={1}", WebHelpers.UrlEncode(cryptedSessKey), steamClient.SteamID.ConvertToUInt64());
            }
            else
            {
                byte[] encryptedAppTicket = CryptoHelper.SymmetricEncrypt(appTicket, sessionKey);
                data = string.Format("sessionkey={0}&appticket={1}", WebHelpers.UrlEncode(cryptedSessKey), WebHelpers.UrlEncode(encryptedAppTicket));
            }

            KeyValue initKv = DoCommand(csServer, "initsession", data, WebRequestMethods.Http.Post);

            sessionId  = ( ulong )initKv["sessionid"].AsLong();
            reqCounter = initKv["req-counter"].AsLong();

            if (appTicket == null)
            {
                data = string.Format("depotid={0}", depotId);
            }
            else
            {
                byte[] encryptedAppTicket = CryptoHelper.SymmetricEncrypt(appTicket, sessionKey);
                data = string.Format("appticket={0}", WebHelpers.UrlEncode(encryptedAppTicket));
            }

            DoCommand(csServer, "authdepot", data, WebRequestMethods.Http.Post, true);

            connectedServer = csServer;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Connects this instance to the server.
        /// </summary>
        /// <returns><c>true</c> if the connection was a success; otherwise, <c>false</c>.</returns>
        public bool Connect()
        {
            byte[] encryptedKey = null;

            // TODO: handle other universes?
            byte[] universeKey = KeyDictionary.GetPublicKey(EUniverse.Public);
            using (var rsa = new RSACrypto(universeKey))
            {
                encryptedKey = rsa.Encrypt(sessionKey);
            }

            byte[] encryptedTicket = CryptoHelper.SymmetricEncrypt(appTicket, sessionKey);

            string payload = String.Format("sessionkey={0}&appticket={1}", WebHelpers.UrlEncode(encryptedKey), WebHelpers.UrlEncode(encryptedTicket));

            webClient.Headers.Clear();
            webClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded");

            string response;

            try
            {
                response = webClient.UploadString(BuildCommand(endPoint, "initsession"), payload);
            }
            catch (WebException)
            {
                return(false);
            }

            var responsekv  = KeyValue.LoadFromString(response);
            var sessionidn  = responsekv.Children.Where(c => c.Name == "sessionid").First();
            var reqcountern = responsekv.Children.Where(c => c.Name == "req-counter").First();

            sessionID  = (ulong)(sessionidn.AsLong(0));
            reqcounter = reqcountern.AsLong(0);

            try
            {
                AuthDepot();
            }
            catch (WebException)
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Connects and initializes a session to the specified content server.
        /// </summary>
        /// <param name="csServer">The content server to connect to.</param>
        /// <exception cref="System.ArgumentNullException">csServer was null.</exception>
        /// <exception cref="HttpRequestException">An network error occurred when performing the request.</exception>
        /// <exception cref="SteamKitWebRequestException">A network error occurred when performing the request.</exception>
        public async Task ConnectAsync(Server csServer)
        {
            DebugLog.Assert(steamClient.IsConnected, "CDNClient", "CMClient is not connected!");

            if (csServer == null)
            {
                throw new ArgumentNullException(nameof(csServer));
            }

            // Nothing needs to be done to initialize a session to a CDN server
            if (csServer.Type == "CDN")
            {
                connectedServer = csServer;
                return;
            }

            byte[] pubKey = KeyDictionary.GetPublicKey(steamClient.Universe);

            sessionKey = CryptoHelper.GenerateRandomBlock(32);

            byte[] cryptedSessKey = null;
            using (var rsa = new RSACrypto(pubKey))
            {
                cryptedSessKey = rsa.Encrypt(sessionKey);
            }

            string data;

            if (appTicket == null)
            {
                // no appticket, doing anonymous connection
                data = string.Format("sessionkey={0}&anonymoususer=1&steamid={1}", WebHelpers.UrlEncode(cryptedSessKey), steamClient.SteamID.ConvertToUInt64());
            }
            else
            {
                byte[] encryptedAppTicket = CryptoHelper.SymmetricEncrypt(appTicket, sessionKey);
                data = string.Format("sessionkey={0}&appticket={1}", WebHelpers.UrlEncode(cryptedSessKey), WebHelpers.UrlEncode(encryptedAppTicket));
            }

            var initKv = await DoCommandAsync(csServer, HttpMethod.Post, "initsession", data).ConfigureAwait(false);

            sessionId       = initKv["sessionid"].AsUnsignedLong();
            reqCounter      = initKv["req-counter"].AsLong();
            connectedServer = csServer;
        }
Ejemplo n.º 5
0
        void HandleEncryptRequest(IPacketMsg packetMsg)
        {
            var encRequest = new Msg <MsgChannelEncryptRequest>(packetMsg);

            EUniverse eUniv        = encRequest.Body.Universe;
            uint      protoVersion = encRequest.Body.ProtocolVersion;

            DebugLog.WriteLine("UFSClient", "Got encryption request. Universe: {0} Protocol ver: {1}", eUniv, protoVersion);
            DebugLog.Assert(protoVersion == 1, "UFSClient", "Encryption handshake protocol version mismatch!");

            byte[] pubKey = KeyDictionary.GetPublicKey(eUniv);

            if (pubKey == null)
            {
                DebugLog.WriteLine("UFSClient", "HandleEncryptionRequest got request for invalid universe! Universe: {0} Protocol ver: {1}", eUniv, protoVersion);
                return;
            }

            ConnectedUniverse = eUniv;

            var encResp = new Msg <MsgChannelEncryptResponse>();

            tempSessionKey = CryptoHelper.GenerateRandomBlock(32);
            byte[] cryptedSessKey = null;

            using (var rsa = new RSACrypto(pubKey))
            {
                cryptedSessKey = rsa.Encrypt(tempSessionKey);
            }

            byte[] keyCrc = CryptoHelper.CRCHash(cryptedSessKey);

            encResp.Write(cryptedSessKey);
            encResp.Write(keyCrc);
            encResp.Write(( uint )0);

            this.Send(encResp);
        }
Ejemplo n.º 6
0
        void HandleEncryptRequest(IPacketMsg packetMsg)
        {
            var encRequest = new Msg <MsgChannelEncryptRequest>(packetMsg);

            EUniverse eUniv        = encRequest.Body.Universe;
            uint      protoVersion = encRequest.Body.ProtocolVersion;

            DebugLog.WriteLine("UFSClient", "Got encryption request. Universe: {0} Protocol ver: {1}", eUniv, protoVersion);
            DebugLog.Assert(protoVersion == 1, "UFSClient", "Encryption handshake protocol version mismatch!");

            byte[] randomChallenge;
            if (encRequest.Payload.Length >= 16)
            {
                randomChallenge = encRequest.Payload.ToArray();
            }
            else
            {
                randomChallenge = null;
            }

            byte[] pubKey = KeyDictionary.GetPublicKey(eUniv);

            if (pubKey == null)
            {
                connection.Disconnect();

                DebugLog.WriteLine("UFSClient", "HandleEncryptionRequest got request for invalid universe! Universe: {0} Protocol ver: {1}", eUniv, protoVersion);
                return;
            }

            ConnectedUniverse = eUniv;

            var encResp = new Msg <MsgChannelEncryptResponse>();

            var tempSessionKey = CryptoHelper.GenerateRandomBlock(32);

            byte[] encryptedHandshakeBlob = null;

            using (var rsa = new RSACrypto(pubKey))
            {
                if (randomChallenge != null)
                {
                    var blobToEncrypt = new byte[tempSessionKey.Length + randomChallenge.Length];
                    Array.Copy(tempSessionKey, blobToEncrypt, tempSessionKey.Length);
                    Array.Copy(randomChallenge, 0, blobToEncrypt, tempSessionKey.Length, randomChallenge.Length);

                    encryptedHandshakeBlob = rsa.Encrypt(blobToEncrypt);
                }
                else
                {
                    encryptedHandshakeBlob = rsa.Encrypt(tempSessionKey);
                }
            }

            var keyCrc = CryptoHelper.CRCHash(encryptedHandshakeBlob);

            encResp.Write(encryptedHandshakeBlob);
            encResp.Write(keyCrc);
            encResp.Write(( uint )0);

            if (randomChallenge != null)
            {
                pendingNetFilterEncryption = new NetFilterEncryptionWithHMAC(tempSessionKey);
            }
            else
            {
                pendingNetFilterEncryption = new NetFilterEncryption(tempSessionKey);
            }

            this.Send(encResp);
        }
Ejemplo n.º 7
0
        void HandleEncryptRequest( IPacketMsg packetMsg )
        {
            var request = new Msg<MsgChannelEncryptRequest>( packetMsg );

            var connectedUniverse = request.Body.Universe;
            var protoVersion = request.Body.ProtocolVersion;

            log.LogDebug( nameof(EnvelopeEncryptedConnection), "Got encryption request. Universe: {0} Protocol ver: {1}", connectedUniverse, protoVersion );
            DebugLog.Assert( protoVersion == 1, nameof(EnvelopeEncryptedConnection), "Encryption handshake protocol version mismatch!" );
            DebugLog.Assert( connectedUniverse == universe, nameof(EnvelopeEncryptedConnection), FormattableString.Invariant( $"Expected universe {universe} but server reported universe {connectedUniverse}" ) );

            byte[]? randomChallenge;
            if ( request.Payload.Length >= 16 )
            {
                randomChallenge = request.Payload.ToArray();
            }
            else
            {
                randomChallenge = null;
            }

            var publicKey = KeyDictionary.GetPublicKey( connectedUniverse );

            if ( publicKey == null )
            {
                log.LogDebug( nameof(EnvelopeEncryptedConnection), "HandleEncryptRequest got request for invalid universe! Universe: {0} Protocol ver: {1}", connectedUniverse, protoVersion );

                Disconnect( userInitiated: false );
                return;
            }

            var response = new Msg<MsgChannelEncryptResponse>();
            
            var tempSessionKey = CryptoHelper.GenerateRandomBlock( 32 );
            byte[] encryptedHandshakeBlob;
            
            using ( var rsa = new RSACrypto( publicKey ) )
            {
                if ( randomChallenge != null )
                {
                    var blobToEncrypt = new byte[ tempSessionKey.Length + randomChallenge.Length ];
                    Array.Copy( tempSessionKey, blobToEncrypt, tempSessionKey.Length );
                    Array.Copy( randomChallenge, 0, blobToEncrypt, tempSessionKey.Length, randomChallenge.Length );

                    encryptedHandshakeBlob = rsa.Encrypt( blobToEncrypt );
                }
                else
                {
                    encryptedHandshakeBlob = rsa.Encrypt( tempSessionKey );
                }
            }

            var keyCrc = CryptoHelper.CRCHash( encryptedHandshakeBlob );

            response.Write( encryptedHandshakeBlob );
            response.Write( keyCrc );
            response.Write( ( uint )0 );
            
            if (randomChallenge != null)
            {
                encryption = new NetFilterEncryptionWithHMAC( tempSessionKey, log );
            }
            else
            {
                encryption = new NetFilterEncryption( tempSessionKey, log );
            }

            var serialized = response.Serialize();

            try
            {
                debugNetworkListener?.OnOutgoingNetworkMessage( response.MsgType, serialized );
            }
            catch ( Exception e )
            {
                log.LogDebug( nameof( EnvelopeEncryptedConnection ), "DebugNetworkListener threw an exception: {0}", e );
            }

            state = EncryptionState.Challenged;
            Send( serialized );
        }