Provides Crypto functions used in Steam protocols
Esempio n. 1
0
 public byte[] ProcessIncoming(byte[] data)
 {
     return(CryptoHelper.SymmetricDecrypt(data, sessionKey));
 }
Esempio n. 2
0
 public byte[] ProcessOutgoing(byte[] ms)
 {
     return(CryptoHelper.SymmetricEncrypt(ms, sessionKey));
 }
Esempio n. 3
0
        public static byte[] GenerateMachineID()
        {
            // this is steamkit's own implementation, it doesn't match what steamclient does
            // but this should make it so individual systems can be identified

            PlatformID platform = Environment.OSVersion.Platform;

            if (platform == PlatformID.Win32NT)
            {
                StringBuilder hwString = new StringBuilder();

                try
                {
                    using (ManagementClass procClass = new ManagementClass("Win32_Processor"))
                    {
                        foreach (var procObj in procClass.GetInstances())
                        {
                            hwString.AppendLine(procObj["ProcessorID"].ToString());
                        }
                    }
                }
                catch { }

                try
                {
                    using (ManagementClass hdClass = new ManagementClass("Win32_LogicalDisk"))
                    {
                        foreach (var hdObj in hdClass.GetInstances())
                        {
                            string hdType = hdObj["DriveType"].ToString();

                            if (hdType != "3")
                            {
                                continue; // only want local disks
                            }
                            hwString.AppendLine(hdObj["VolumeSerialNumber"].ToString());
                        }
                    }
                }
                catch { }

                try
                {
                    using (ManagementClass moboClass = new ManagementClass("Win32_BaseBoard"))
                    {
                        foreach (var moboObj in moboClass.GetInstances())
                        {
                            hwString.AppendLine(moboObj["SerialNumber"].ToString());
                        }
                    }
                }
                catch { }


                try
                {
                    return(CryptoHelper.SHAHash(Encoding.ASCII.GetBytes(hwString.ToString())));
                }
                catch { return(null); }
            }
            else
            {
                // todo: implement me!
                return(null);
            }
        }
Esempio n. 4
0
        byte[] DoRawCommand(Server server, string command, string data = null, string method = WebRequestMethods.Http.Get, bool doAuth = false, string args = "", string authtoken = null)
        {
            string url    = BuildCommand(server, command, args, authtoken);
            var    webReq = HttpWebRequest.Create(url) as HttpWebRequest;

            webReq.Method    = method;
            webReq.Pipelined = true;
            webReq.KeepAlive = true;

            if (doAuth && server.Type == "CS")
            {
                var req = Interlocked.Increment(ref reqCounter);

                byte[] shaHash;

                using (var ms = new MemoryStream())
                    using (var bw = new BinaryWriter(ms))
                    {
                        var uri = new Uri(url);

                        bw.Write(sessionId);
                        bw.Write(req);
                        bw.Write(sessionKey);
                        bw.Write(Encoding.UTF8.GetBytes(uri.AbsolutePath));

                        shaHash = CryptoHelper.SHAHash(ms.ToArray());
                    }

                string hexHash    = Utils.EncodeHexString(shaHash);
                string authHeader = string.Format("sessionid={0};req-counter={1};hash={2};", sessionId, req, hexHash);

                webReq.Headers["x-steam-auth"] = authHeader;
            }

            if (method == WebRequestMethods.Http.Post)
            {
                byte[] payload = Encoding.UTF8.GetBytes(data);
                webReq.ContentType   = "application/x-www-form-urlencoded";
                webReq.ContentLength = payload.Length;

                using (var reqStream = webReq.GetRequestStream())
                {
                    reqStream.Write(payload, 0, payload.Length);
                }
            }


            var result = webReq.BeginGetResponse(null, null);

            if (!result.AsyncWaitHandle.WaitOne(RequestTimeout))
            {
                webReq.Abort();
            }

            try
            {
                var response = webReq.EndGetResponse(result);

                using (var ms = new MemoryStream(( int )response.ContentLength))
                {
                    response.GetResponseStream().CopyTo(ms);
                    response.Close();

                    return(ms.ToArray());
                }
            }
            catch (Exception ex)
            {
                DebugLog.WriteLine("CDNClient", "Failed to complete web request to {0}: {1}", url, ex.Message);
                throw;
            }
        }
        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);
            }

            state = EncryptionState.Challenged;
            Send(response.Serialize());
        }
Esempio 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);
        }
Esempio n. 7
0
 public byte[] ProcessOutgoing(byte[] data)
 {
     return(CryptoHelper.SymmetricEncryptWithHMACIV(data, sessionKey, hmacSecret));
 }