示例#1
0
        /// <summary>
        /// Initializes this target.
        /// </summary>
        public override void Initialize()
        {
            _currentEntities.Clear();

            // write the mandatory header.
            _buffer.Seek(0, SeekOrigin.Begin);

            // create header block.
            var blockHeader = new HeaderBlock();

            blockHeader.required_features.Add("OsmSchema-V0.6");
            blockHeader.required_features.Add("DenseNodes");
            _runtimeTypeModel.Serialize(_buffer, blockHeader);
            var blockHeaderData = _buffer.ToArray();

            _buffer.SetLength(0);

            // create blob.
            var blob = new Blob();

            blob.raw = blockHeaderData;
            _runtimeTypeModel.Serialize(_buffer, blob);

            // create blobheader.
            var blobHeader = new BlobHeader();

            blobHeader.datasize  = (int)_buffer.Length;
            blobHeader.indexdata = null;
            blobHeader.type      = Encoder.OSMHeader;
            _runtimeTypeModel.SerializeWithLengthPrefix(_stream, blobHeader, _blobHeaderType, ProtoBuf.PrefixStyle.Fixed32BigEndian, 0);

            // flush to stream.
            _buffer.Seek(0, SeekOrigin.Begin);
            _buffer.CopyTo(_stream);
        }
示例#2
0
        /// <summary>
        /// Initializes a new instance of the PbfReader class that read data form specified stream.
        /// </summary>
        /// <param name="input">The input stream.</param>
        /// <param name="settings">The OsmReaderSettings object that determines behaviour of PbfReader.</param>
        public PbfReader(Stream input, OsmReaderSettings settings)
        {
            _input = input;
            _cache = new Queue <IEntityInfo>();

            this.Settings            = settings;
            this.Settings.IsReadOnly = true;

            BlobHeader blobHeader = null;

            while ((blobHeader = this.ReadBlobHeader()) != null)
            {
                if (blobHeader.Type == "OSMHeader")
                {
                    OsmHeader osmHeader = (OsmHeader)this.ReadBlob(blobHeader);
                    this.ProcessOsmHeader(osmHeader);
                    return;
                }
                else if (blobHeader.Type == "OSMData")
                {
                    throw new InvalidDataException("Input stream doesn't contain an 'OSMHeader' block before 'OSMData' block.");
                }
                else
                {
                    _input.Seek(blobHeader.DataSize, SeekOrigin.Current);
                }
            }

            throw new InvalidDataException("Input stream doesn't contain an 'OSMHeader' block.");
        }
示例#3
0
        /// <summary>
        /// Initializes a new instance of the PbfReader class that read data form specified file.
        /// </summary>
        /// <param name="path">The path to the input file.</param>
        /// <param name="settings">The OsmReaderSettings object that determines behaviour of PbfReader.</param>
        public PbfReader(string path, OsmReaderSettings settings)
        {
            _input = new FileStream(path, FileMode.Open, FileAccess.Read);
            _cache = new Queue <IEntityInfo>();

            this.Settings            = settings;
            this.Settings.IsReadOnly = true;

            BlobHeader blobHeader = null;

            while ((blobHeader = this.ReadBlobHeader()) != null)
            {
                try {
                    if (blobHeader.Type == "OSMHeader")
                    {
                        OsmHeader osmHeader = (OsmHeader)this.ReadBlob(blobHeader);
                        this.ProcessOsmHeader(osmHeader);
                        return;
                    }
                    else if (blobHeader.Type == "OSMData")
                    {
                        throw new InvalidDataException("Input stream doesn't contain an 'OSMHeader' block before 'OSMData' block.");
                    }
                    else
                    {
                        _input.Seek(blobHeader.DataSize, SeekOrigin.Current);
                    }
                } catch (ProtoException ex) {
                    throw new InvalidDataException("Input stream contains unsupported data", ex);
                }
            }

            throw new InvalidDataException("Input stream doesn't contain an 'OSMHeader' block.");
        }
示例#4
0
        /// <summary>
        /// Reads next OSM entity from the stream.
        /// </summary>
        /// <returns>Parsed OSM entity from the stream or null if no other entity is available.</returns>
        public IEntityInfo Read()
        {
            if (_cache.Count > 0)
            {
                return(_cache.Dequeue());
            }
            else
            {
                BlobHeader blobHeader = null;
                while (_cache.Count == 0 && (blobHeader = this.ReadBlobHeader()) != null)
                {
                    PrimitiveBlock data = this.ReadBlob(blobHeader) as PrimitiveBlock;
                    if (data != null)
                    {
                        foreach (PrimitiveGroup group in data.PrimitiveGroup)
                        {
                            this.ProcessPrimitiveGroup(data, group);
                        }
                    }
                }
            }

            if (_cache.Count > 0)
            {
                return(_cache.Dequeue());
            }
            else
            {
                return(null);
            }
        }
示例#5
0
        public IEnumerable <Node> ReadNodes(string fileName, AttributeRegistry attributeRegistry)
        {
            using (var file = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                BlobHeader blobHeader = null;

                while ((blobHeader = ReadBlobHeader(file)) != null)
                {
                    var block = ReadBlob(file, blobHeader) as PrimitiveBlock;
                    if (block != null)
                    {
                        foreach (PrimitiveGroup group in block.PrimitiveGroup)
                        {
                            foreach (var item in ProcessNodes(block, group, attributeRegistry))
                            {
                                yield return(item);
                            }

                            foreach (var item in ProcessDenseNodes(block, group, attributeRegistry))
                            {
                                yield return(item);
                            }
                        }
                    }
                }
            }
        }
        private static byte[] CreateSnPublicKeyBlob(BlobHeader header, RsaPubKey rsa, byte[] pubKeyData)
        {
            var snPubKey = new SnPublicKeyBlob()
            {
                SigAlgId      = AlgorithmId.RsaSign,
                HashAlgId     = AlgorithmId.Sha,
                PublicKeySize = (UInt32)(s_offsetToKeyData + pubKeyData.Length)
            };

            using (var ms = new MemoryStream(160))
                using (var binaryWriter = new BinaryWriter(ms))
                {
                    binaryWriter.Write(snPubKey.SigAlgId);
                    binaryWriter.Write(snPubKey.HashAlgId);
                    binaryWriter.Write(snPubKey.PublicKeySize);

                    binaryWriter.Write(header.Type);
                    binaryWriter.Write(header.Version);
                    binaryWriter.Write(header.Reserved);
                    binaryWriter.Write(header.AlgId);

                    binaryWriter.Write(rsa.Magic);
                    binaryWriter.Write(rsa.BitLen);
                    binaryWriter.Write(rsa.PubExp);

                    binaryWriter.Write(pubKeyData);

                    return(ms.ToArray());
                }
        }
示例#7
0
        public IEnumerable <Way> ReadWays(string fileName, AttributeRegistry attributeRegistry)
        {
            using (var file = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                BlobHeader blobHeader = null;

                while ((blobHeader = ReadBlobHeader(file)) != null)
                {
                    var block = ReadBlob(file, blobHeader) as PrimitiveBlock;
                    if (block != null)
                    {
                        foreach (PrimitiveGroup group in block.PrimitiveGroup)
                        {
                            if (group.Ways == null)
                            {
                                continue;
                            }
                            foreach (var way in group.Ways)
                            {
                                var tags         = new List <Tag>();
                                var usedTagTypes = new HashSet <int>();
                                if (way.Keys != null)
                                {
                                    for (int i = 0; i < way.Keys.Count; i++)
                                    {
                                        var tagType = attributeRegistry.GetAttributeValueId(OsmAttribute.TagType, block.StringTable[way.Keys[i]]);
                                        if (!usedTagTypes.Contains(tagType))
                                        {
                                            tags.Add(new Tag
                                            {
                                                Value = block.StringTable[way.Values[i]],
                                                Typ   = tagType
                                            });
                                            usedTagTypes.Add(tagType);
                                        }
                                    }
                                }

                                long refStore = 0;
                                var  refs     = new List <long>(way.Refs.Count);
                                foreach (var t in way.Refs)
                                {
                                    refStore += t;
                                    refs.Add(refStore);
                                }

                                yield return(new Way()
                                {
                                    WayId = way.ID,
                                    NodeRefs = refs,
                                    Tags = tags
                                });
                            }
                        }
                    }
                }
            }
        }
示例#8
0
        /// <summary>
        /// Flushes the current block of data.
        /// </summary>
        private void FlushBlock()
        {
            if (_currentEntities.Count == 0)
            {
                return;
            }

            // encode into block.
            var block = new PrimitiveBlock();

            Encoder.Encode(block, _reverseStringTable, _currentEntities, _compress);
            _currentEntities.Clear();
            _reverseStringTable.Clear();

            // serialize.
            _buffer.SetLength(0);
            _runtimeTypeModel.Serialize(_buffer, block);
            var blockBytes = _buffer.ToArray();

            _buffer.SetLength(0);

            // create blob.
            var blob = new Blob();

            blob.raw_size = blockBytes.Length;
            if (_compress)
            {
                using (var target = new MemoryStream())
                {
                    using (var source = new MemoryStream(blockBytes))
                        using (var deflate = new DeflaterOutputStream(target))
                        {
                            source.CopyTo(deflate);
                        }
                    blob.zlib_data = target.ToArray();
                }
            }
            else
            {
                blob.raw = blockBytes;
            }

            _runtimeTypeModel.Serialize(_buffer, blob);

            // create blobheader.
            var blobHeader = new BlobHeader();

            blobHeader.datasize  = (int)_buffer.Length;
            blobHeader.indexdata = null;
            blobHeader.type      = Encoder.OSMData;
            _runtimeTypeModel.SerializeWithLengthPrefix(_stream, blobHeader, _blobHeaderType, ProtoBuf.PrefixStyle.Fixed32BigEndian, 0);

            // serialize to stream.
            _buffer.Seek(0, SeekOrigin.Begin);
            _buffer.CopyTo(_stream);
        }
示例#9
0
        /// <summary>
        /// Read blob and deserializes its content.
        /// </summary>
        /// <param name="header">Header of the blob.</param>
        /// <returns>Deserialized content of the read blob or null if blob contains unknown data.</returns>
        private object ReadBlob(BlobHeader header)
        {
            byte[] buffer = new byte[header.DataSize];
            _input.Read(buffer, 0, header.DataSize);
            Blob blob = Serializer.Deserialize <Blob>(new MemoryStream(buffer));

            Stream blobContentStream;

            if (blob.Raw != null)
            {
                blobContentStream = new MemoryStream(blob.Raw);
            }
            else if (blob.ZlibData != null)
            {
                MemoryStream deflateStreamData = new MemoryStream(blob.ZlibData);

                //skip ZLIB header
                deflateStreamData.Seek(2, SeekOrigin.Begin);

                blobContentStream = new System.IO.Compression.DeflateStream(deflateStreamData, System.IO.Compression.CompressionMode.Decompress);
            }
            else
            {
                throw new NotSupportedException();
            }

            if (header.Type.Equals("OSMData", StringComparison.OrdinalIgnoreCase))
            {
                if ((blob.RawSize.HasValue && blob.RawSize > MaxDataBlockSize) || (blob.RawSize.HasValue == false && blobContentStream.Length > MaxDataBlockSize))
                {
                    throw new InvalidDataException("Invalid OSMData block");
                }

                return(Serializer.Deserialize <PrimitiveBlock>(blobContentStream));
            }
            else if (header.Type.Equals("OSMHeader", StringComparison.OrdinalIgnoreCase))
            {
                if ((blob.RawSize.HasValue && blob.RawSize > MaxHeaderBlockSize) || (blob.RawSize.HasValue == false && blobContentStream.Length > MaxHeaderBlockSize))
                {
                    throw new InvalidDataException("Invalid OSMHeader block");
                }

                try {
                    return(Serializer.Deserialize <OsmHeader>(blobContentStream));
                } catch (ProtoException ex) {
                    throw new InvalidDataException("Invalid OSMData block", ex);
                }
            }
            else
            {
                return(null);
            }
        }
示例#10
0
        /// <summary>
        /// Initializes this target.
        /// </summary>
        public override void Initialize()
        {
            _currentEntities.Clear();

            // write the mandatory header.
            _buffer.Seek(0, SeekOrigin.Begin);

            // create header block.
            var blockHeader = new HeaderBlock();

            blockHeader.required_features.Add("OsmSchema-V0.6");
            blockHeader.required_features.Add("DenseNodes");
            _runtimeTypeModel.Serialize(_buffer, blockHeader);
            var blockHeaderData = _buffer.ToArray();

            _buffer.SetLength(0);

            // create blob.
            var blob = new Blob();

            if (_compress)
            {
                using (var target = new MemoryStream())
                {
                    using (var source = new MemoryStream(blockHeaderData))
                        using (var deflate = new DeflaterOutputStream(target))
                        {
                            source.CopyTo(deflate);
                        }
                    blob.zlib_data = target.ToArray();
                }
            }
            else
            {
                blob.raw = blockHeaderData;
            }

            _runtimeTypeModel.Serialize(_buffer, blob);

            // create blobheader.
            var blobHeader = new BlobHeader();

            blobHeader.datasize  = (int)_buffer.Length;
            blobHeader.indexdata = null;
            blobHeader.type      = Encoder.OSMHeader;
            _runtimeTypeModel.SerializeWithLengthPrefix(_stream, blobHeader, _blobHeaderType, ProtoBuf.PrefixStyle.Fixed32BigEndian, 0);

            // flush to stream.
            _buffer.Seek(0, SeekOrigin.Begin);
            _buffer.CopyTo(_stream);
        }
示例#11
0
        /// <summary>
        /// Flushes the current block of data.
        /// </summary>
        private void FlushBlock()
        {
            if (_currentEntities.Count == 0)
            {
                return;
            }

            // encode into block.
            var block = new PrimitiveBlock();

            Encoder.Encode(block, _reverseStringTable, _currentEntities);
            _currentEntities.Clear();
            _reverseStringTable.Clear();

            // serialize.
            _buffer.SetLength(0);
            _runtimeTypeModel.Serialize(_buffer, block);
            var blockBytes = _buffer.ToArray();

            _buffer.SetLength(0);

            if (_compress)
            { // compress buffer.
                throw new NotSupportedException();
            }

            // create blob.
            var blob = new Blob();

            blob.raw = blockBytes;
            _runtimeTypeModel.Serialize(_buffer, blob);

            // create blobheader.
            var blobHeader = new BlobHeader();

            blobHeader.datasize  = (int)_buffer.Length;
            blobHeader.indexdata = null;
            blobHeader.type      = Encoder.OSMData;
            _runtimeTypeModel.SerializeWithLengthPrefix(_stream, blobHeader, _blobHeaderType, ProtoBuf.PrefixStyle.Fixed32BigEndian, 0);

            // serialize to stream.
            _buffer.Seek(0, SeekOrigin.Begin);
            _buffer.CopyTo(_stream);
        }
        private unsafe static bool TryGetPublicKeyFromPublicKeyBlob(byte *blob, int blobLen, out ImmutableArray <byte> publicKey)
        {
            BlobHeader header    = Marshal.PtrToStructure <BlobHeader>((IntPtr)blob);
            RsaPubKey  rsaPubKey = Marshal.PtrToStructure <RsaPubKey>((IntPtr)(blob + sizeof(BlobHeader)));

            byte[] modulus = new byte[rsaPubKey.BitLen >> 3];

            // The key blob data just contains the modulus
            if (blobLen - s_offsetToKeyData != modulus.Length)
            {
                publicKey = ImmutableArray <byte> .Empty;
                return(false);
            }

            Marshal.Copy((IntPtr)(blob + s_offsetToKeyData), modulus, 0, modulus.Length);

            publicKey = CreateSnPublicKeyBlob(header, rsaPubKey, modulus);
            return(true);
        }
        internal unsafe static bool TryGetPublicKeyFromPrivateKeyBlob(byte[] blob, out byte[] publicKey)
        {
            fixed(byte *blobPtr = blob)
            {
                var header = (BlobHeader *)blobPtr;
                var rsa    = (RsaPubKey *)(blobPtr + sizeof(BlobHeader));

                var version          = header->Version;
                var modulusBitLength = rsa->BitLen;
                var exponent         = rsa->PubExp;
                var modulus          = new byte[modulusBitLength >> 3];

                if (blob.Length - s_offsetToKeyData < modulus.Length)
                {
                    publicKey = null;
                    return(false);
                }

                Marshal.Copy((IntPtr)(blobPtr + s_offsetToKeyData), modulus, 0, modulus.Length);

                var newHeader = new BlobHeader()
                {
                    Type     = PublicKeyBlobId,
                    Version  = version,
                    Reserved = 0,
                    AlgId    = AlgorithmId.RsaSign
                };

                var newRsaKey = new RsaPubKey()
                {
                    Magic  = RSA1, // Public key
                    BitLen = modulusBitLength,
                    PubExp = exponent
                };

                publicKey = CreateSnPublicKeyBlob(newHeader, newRsaKey, modulus);
                return(true);
            }
        }
示例#14
0
        /// <summary>
        /// Writes blob and it's header to the underlaying stream.
        /// </summary>
        /// <param name="blobType">The type of the blob.</param>
        /// <param name="blobContent">The pbf serialized content of the blob.</param>
        private void WriteBlob(string blobType, byte[] blobContent)
        {
            Blob blob = new Blob();

            if (this.Settings.Compression == CompressionMode.None)
            {
                blob.Raw = blobContent;
            }
            else if (this.Settings.Compression == CompressionMode.ZlibDeflate)
            {
                MemoryStream zlibStream = new MemoryStream();

                //ZLIB header
                zlibStream.WriteByte(120);
                zlibStream.WriteByte(156);

                using (System.IO.Compression.DeflateStream deflateSteram = new System.IO.Compression.DeflateStream(zlibStream, System.IO.Compression.CompressionMode.Compress, true)) {
                    deflateSteram.Write(blobContent, 0, blobContent.Length);
                }

                blob.RawSize  = (int)blobContent.Length;
                blob.ZlibData = new byte[zlibStream.Length];
                Array.Copy(zlibStream.GetBuffer(), blob.ZlibData, zlibStream.Length);
            }

            MemoryStream blobStream = new MemoryStream();

            Serializer.Serialize <Blob>(blobStream, blob);

            BlobHeader header = new BlobHeader();

            header.Type     = blobType;
            header.DataSize = (int)blobStream.Length;
            Serializer.SerializeWithLengthPrefix(_output, header, PrefixStyle.Fixed32BigEndian);

            blobStream.WriteTo(_output);
        }
        private unsafe static bool TryGetPublicKeyFromPrivateKeyBlob(byte *blob, int blobLen, out ImmutableArray <byte> publicKey)
        {
            BlobHeader *header = (BlobHeader *)blob;
            RsaPubKey * rsa    = (RsaPubKey *)(blob + sizeof(BlobHeader));

            byte version          = header->Version;
            uint modulusBitLength = rsa->BitLen;
            uint exponent         = rsa->PubExp;

            byte[] modulus = new byte[modulusBitLength >> 3];

            if (blobLen - s_offsetToKeyData < modulus.Length)
            {
                publicKey = ImmutableArray <byte> .Empty;
                return(false);
            }

            Marshal.Copy((IntPtr)(blob + s_offsetToKeyData), modulus, 0, modulus.Length);

            BlobHeader newHeader = new BlobHeader()
            {
                Type     = PublicKeyBlobId,
                Version  = version,
                Reserved = 0,
                AlgId    = AlgorithmId.RsaSign
            };

            RsaPubKey newRsaKey = new RsaPubKey()
            {
                Magic  = RSA1, // Public key
                BitLen = modulusBitLength,
                PubExp = exponent
            };

            publicKey = CreateSnPublicKeyBlob(newHeader, newRsaKey, modulus);
            return(true);
        }
        /// <summary>
        /// Initializes this target.
        /// </summary>
        public override void Initialize()
        {
            _currentEntities.Clear();

            // write the mandatory header.
            _buffer.Seek(0, SeekOrigin.Begin);

            // create header block.
            var blockHeader = new HeaderBlock();
            blockHeader.required_features.Add("OsmSchema-V0.6");
            blockHeader.required_features.Add("DenseNodes");
            _runtimeTypeModel.Serialize(_buffer, blockHeader);
            var blockHeaderData = _buffer.ToArray();
            _buffer.SetLength(0);

            // create blob.
            var blob = new Blob();
            blob.raw = blockHeaderData;
            _runtimeTypeModel.Serialize(_buffer, blob);

            // create blobheader.
            var blobHeader = new BlobHeader();
            blobHeader.datasize = (int)_buffer.Length;
            blobHeader.indexdata = null;
            blobHeader.type = Encoder.OSMHeader;
            _runtimeTypeModel.SerializeWithLengthPrefix(_stream, blobHeader, _blobHeaderType, ProtoBuf.PrefixStyle.Fixed32BigEndian, 0);

            // flush to stream.
            _buffer.Seek(0, SeekOrigin.Begin);
            _buffer.CopyTo(_stream);
        }
        /// <summary>
        /// Flushes the current block of data.
        /// </summary>
        private void FlushBlock()
        {
            if (_currentEntities.Count == 0) { return; }

            // encode into block.
            var block = new PrimitiveBlock();
            Encoder.Encode(block, _reverseStringTable, _currentEntities);
            _currentEntities.Clear();
            _reverseStringTable.Clear();

            // serialize.
            _buffer.SetLength(0);
            _runtimeTypeModel.Serialize(_buffer, block);
            var blockBytes = _buffer.ToArray();
            _buffer.SetLength(0);

            if (_compress)
            { // compress buffer.
                throw new NotSupportedException();
            }

            // create blob.
            var blob = new Blob();
            blob.raw = blockBytes;
            _runtimeTypeModel.Serialize(_buffer, blob);

            // create blobheader.
            var blobHeader = new BlobHeader();
            blobHeader.datasize = (int)_buffer.Length;
            blobHeader.indexdata = null;
            blobHeader.type = Encoder.OSMData;
            _runtimeTypeModel.SerializeWithLengthPrefix(_stream, blobHeader, _blobHeaderType, ProtoBuf.PrefixStyle.Fixed32BigEndian, 0);

            // serialize to stream.
            _buffer.Seek(0, SeekOrigin.Begin);
            _buffer.CopyTo(_stream);
        }
示例#18
0
        /// <summary>
        /// Answers the message.
        /// </summary>
        /// <param name='messageStream'>Message stream.</param>
        /// <param name="process">The calling process or <c>null</c> if the process
        /// could not be obtained.</param>
        /// <remarks>code based on winpgnt.c from PuTTY source code</remarks>
        public void AnswerMessage(Stream messageStream, Process process = null)
        {
            if (messageStream.CanTimeout)
            {
                messageStream.ReadTimeout = 5000;
            }
            var        messageParser   = new BlobParser(messageStream);
            var        responseBuilder = new BlobBuilder();
            BlobHeader header;

            try {
                header = messageParser.ReadHeader();

                if (MessageReceived != null)
                {
                    var eventArgs = new MessageReceivedEventArgs(header);
                    MessageReceived(this, eventArgs);
                    if (eventArgs.Fail)
                    {
                        throw new Exception();
                    }
                }
            } catch (Exception) {
                header         = new BlobHeader();
                header.Message = Message.UNKNOWN;
                // this will cause the switch statement below to use the default case
                // which returns an error to the stream.
            }

            switch (header.Message)
            {
            case Message.SSH1_AGENTC_REQUEST_RSA_IDENTITIES:
                /*
                 * Reply with SSH1_AGENT_RSA_IDENTITIES_ANSWER.
                 */
                try {
                    if (header.BlobLength > 1)
                    {
                        // ruby net-ssh tries to send a SSH2_AGENT_REQUEST_VERSION message
                        // which has the same id number as SSH1_AGENTC_REQUEST_RSA_IDENTITIES
                        // with a string tacked on. We need to read the string from the
                        // stream, but it is not used for anything.
                        messageParser.ReadString();
                    }
                    var keyList = ListKeys(SshVersion.SSH1);
                    if (FilterKeyListCallback != null)
                    {
                        keyList = FilterKeyListCallback(keyList);
                    }
                    foreach (SshKey key in keyList)
                    {
                        responseBuilder.AddBytes(key.GetPublicKeyBlob());
                        responseBuilder.AddStringBlob(key.Comment);
                    }
                    responseBuilder.InsertHeader(Message.SSH1_AGENT_RSA_IDENTITIES_ANSWER,
                                                 keyList.Count);
                    // TODO may want to check that there is enough room in the message stream
                    break; // succeeded
                } catch (Exception ex) {
                    Debug.Fail(ex.ToString());
                }
                goto default; // failed

            case Message.SSH2_AGENTC_REQUEST_IDENTITIES:
                /*
                 * Reply with SSH2_AGENT_IDENTITIES_ANSWER.
                 */
                try {
                    var keyList = ListKeys(SshVersion.SSH2);
                    if (FilterKeyListCallback != null)
                    {
                        keyList = FilterKeyListCallback(keyList);
                    }
                    foreach (SshKey key in keyList)
                    {
                        responseBuilder.AddBlob(key.GetPublicKeyBlob());
                        responseBuilder.AddStringBlob(key.Comment);
                    }
                    responseBuilder.InsertHeader(Message.SSH2_AGENT_IDENTITIES_ANSWER,
                                                 keyList.Count);
                    // TODO may want to check that there is enough room in the message stream
                    break; // succeeded
                } catch (Exception ex) {
                    Debug.Fail(ex.ToString());
                }
                goto default; // failed

            case Message.SSH1_AGENTC_RSA_CHALLENGE:
                /*
                 * Reply with either SSH1_AGENT_RSA_RESPONSE or
                 * SSH_AGENT_FAILURE, depending on whether we have that key
                 * or not.
                 */

                try {
                    //Reading publicKey information
                    var publicKeyParams = messageParser.ReadSsh1PublicKeyData(true);

                    //Searching for Key here
                    var matchingKey = mKeyList.Where(key => key.Version == SshVersion.SSH1 &&
                                                     (key.GetPublicKeyParameters().Equals(publicKeyParams))).Single();

                    //Reading challenge
                    var encryptedChallenge = messageParser.ReadSsh1BigIntBlob();
                    var sessionId          = messageParser.ReadBytes(16);

                    //Checking responseType field
                    if (messageParser.ReadUInt32() != 1)
                    {
                        goto default; //responseType !=1  is not longer supported
                    }

                    //Answering to the challenge
                    var engine = new Pkcs1Encoding(new RsaEngine());
                    engine.Init(false /* decrypt */, matchingKey.GetPrivateKeyParameters());

                    var decryptedChallenge = engine.ProcessBlock(encryptedChallenge,
                                                                 0, encryptedChallenge.Length);

                    using (MD5 md5 = MD5.Create()) {
                        var md5Buffer = new byte[48];
                        decryptedChallenge.CopyTo(md5Buffer, 0);
                        sessionId.CopyTo(md5Buffer, 32);

                        responseBuilder.AddBytes(md5.ComputeHash(md5Buffer));
                        responseBuilder.InsertHeader(Message.SSH1_AGENT_RSA_RESPONSE);
                        break;
                    }
                } catch (InvalidOperationException) {
                    // this is expected if there is not a matching key
                } catch (Exception ex) {
                    Debug.Fail(ex.ToString());
                }

                goto default; // failed

            case Message.SSH2_AGENTC_SIGN_REQUEST:
                /*
                 * Reply with either SSH2_AGENT_SIGN_RESPONSE or SSH_AGENT_FAILURE,
                 * depending on whether we have that key or not.
                 */
                try {
                    var keyBlob = messageParser.ReadBlob();
                    var reqData = messageParser.ReadBlob();
                    var flags   = new SignRequestFlags();
                    try {
                        // usually, there are no flags, so parser will throw
                        flags = (SignRequestFlags)messageParser.ReadUInt32();
                    } catch { }

                    var matchingKey =
                        mKeyList.Where(key => key.Version == SshVersion.SSH2 &&
                                       key.GetPublicKeyBlob().SequenceEqual(keyBlob)).First();
                    var confirmConstraints = matchingKey.Constraints
                                             .Where(constraint => constraint.Type ==
                                                    KeyConstraintType.SSH_AGENT_CONSTRAIN_CONFIRM);
                    if (confirmConstraints.Count() > 0)
                    {
                        if (!ConfirmUserPermissionCallback.Invoke(matchingKey, process))
                        {
                            goto default;
                        }
                    }

                    /* create signature */
                    var signKey = matchingKey;
                    var signer  = signKey.GetSigner();
                    var algName = signKey.Algorithm.GetIdentifierString();
                    signer.Init(true, signKey.GetPrivateKeyParameters());
                    signer.BlockUpdate(reqData, 0, reqData.Length);
                    byte[] signature = signer.GenerateSignature();
                    signature = signKey.FormatSignature(signature);
                    BlobBuilder signatureBuilder = new BlobBuilder();
                    if (!flags.HasFlag(SignRequestFlags.SSH_AGENT_OLD_SIGNATURE))
                    {
                        signatureBuilder.AddStringBlob(algName);
                    }
                    signatureBuilder.AddBlob(signature);
                    responseBuilder.AddBlob(signatureBuilder.GetBlob());
                    responseBuilder.InsertHeader(Message.SSH2_AGENT_SIGN_RESPONSE);
                    try {
                        KeyUsed(this, new KeyUsedEventArgs(signKey, process));
                    } catch { }
                    break; // succeeded
                } catch (InvalidOperationException) {
                    // this is expected if there is not a matching key
                } catch (Exception ex) {
                    Debug.Fail(ex.ToString());
                }
                goto default; // failure

            case Message.SSH1_AGENTC_ADD_RSA_IDENTITY:
            case Message.SSH1_AGENTC_ADD_RSA_ID_CONSTRAINED:
                /*
                 * Add to the list and return SSH_AGENT_SUCCESS, or
                 * SSH_AGENT_FAILURE if the key was malformed.
                 */

                if (IsLocked)
                {
                    goto default;
                }

                bool ssh1constrained = (header.Message == Message.SSH1_AGENTC_ADD_RSA_ID_CONSTRAINED);

                try {
                    var publicKeyParams = messageParser.ReadSsh1PublicKeyData(false);
                    var keyPair         = messageParser.ReadSsh1KeyData(publicKeyParams);

                    SshKey key = new SshKey(SshVersion.SSH1, keyPair);
                    key.Comment = messageParser.ReadString();
                    key.Source  = "External client";

                    if (ssh1constrained)
                    {
                        while (messageStream.Position < header.BlobLength + 4)
                        {
                            KeyConstraint constraint = new KeyConstraint();
                            constraint.Type = (KeyConstraintType)messageParser.ReadUInt8();
                            if (constraint.Type ==
                                KeyConstraintType.SSH_AGENT_CONSTRAIN_LIFETIME)
                            {
                                constraint.Data = messageParser.ReadUInt32();
                            }
                            key.AddConstraint(constraint);
                        }
                    }
                    AddKey(key);
                    responseBuilder.InsertHeader(Message.SSH_AGENT_SUCCESS);
                    break;
                } catch (CallbackNullException) {
                    // this is expected
                } catch (Exception ex) {
                    Debug.Fail(ex.ToString());
                }

                goto default; // failed

            case Message.SSH2_AGENTC_ADD_IDENTITY:
            case Message.SSH2_AGENTC_ADD_ID_CONSTRAINED:
                /*
                 * Add to the list and return SSH_AGENT_SUCCESS, or
                 * SSH_AGENT_FAILURE if the key was malformed.
                 */

                if (IsLocked)
                {
                    goto default;
                }

                bool constrained = (header.Message ==
                                    Message.SSH2_AGENTC_ADD_ID_CONSTRAINED);

                try {
                    OpensshCertificate cert;
                    var    publicKeyParams = messageParser.ReadSsh2PublicKeyData(out cert);
                    var    keyPair         = messageParser.ReadSsh2KeyData(publicKeyParams);
                    SshKey key             = new SshKey(SshVersion.SSH2, keyPair, null, cert);
                    key.Comment = messageParser.ReadString();
                    key.Source  = "External client";

                    if (constrained)
                    {
                        while (messageStream.Position < header.BlobLength + 4)
                        {
                            KeyConstraint constraint = new KeyConstraint();
                            constraint.Type =
                                (KeyConstraintType)messageParser.ReadUInt8();
                            if (constraint.Type ==
                                KeyConstraintType.SSH_AGENT_CONSTRAIN_LIFETIME)
                            {
                                constraint.Data = messageParser.ReadUInt32();
                            }
                            key.AddConstraint(constraint);
                        }
                    }
                    AddKey(key);
                    responseBuilder.InsertHeader(Message.SSH_AGENT_SUCCESS);
                    break; // success!
                } catch (CallbackNullException) {
                    // this is expected
                } catch (Exception ex) {
                    Debug.Fail(ex.ToString());
                }
                goto default; // failed

            case Message.SSH1_AGENTC_REMOVE_RSA_IDENTITY:
            case Message.SSH2_AGENTC_REMOVE_IDENTITY:
                /*
                 * Remove from the list and return SSH_AGENT_SUCCESS, or
                 * perhaps SSH_AGENT_FAILURE if it wasn't in the list to
                 * start with.
                 */

                if (IsLocked)
                {
                    goto default;
                }

                SshVersion removeVersion;
                byte[]     rKeyBlob;
                if (header.Message == Message.SSH1_AGENTC_REMOVE_RSA_IDENTITY)
                {
                    removeVersion = SshVersion.SSH1;
                    rKeyBlob      = messageParser.ReadBytes(header.BlobLength - 1);
                }
                else if (header.Message == Message.SSH2_AGENTC_REMOVE_IDENTITY)
                {
                    removeVersion = SshVersion.SSH2;
                    rKeyBlob      = messageParser.ReadBlob();
                }
                else
                {
                    Debug.Fail("Should not get here.");
                    goto default;
                }

                try {
                    var matchingKey        = mKeyList.Get(removeVersion, rKeyBlob);
                    var startKeyListLength = mKeyList.Count;
                    RemoveKey(matchingKey);
                    // only succeed if key was removed
                    if (mKeyList.Count == startKeyListLength - 1)
                    {
                        responseBuilder.InsertHeader(Message.SSH_AGENT_SUCCESS);
                        break; //success!
                    }
                } catch (Exception ex) {
                    Debug.Fail(ex.ToString());
                }
                goto default; // failed

            case Message.SSH1_AGENTC_REMOVE_ALL_RSA_IDENTITIES:
            case Message.SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
                /*
                 * Remove all SSH-1 or SSH-2 keys.
                 */

                if (IsLocked)
                {
                    goto default;
                }

                SshVersion removeAllVersion;
                if (header.Message == Message.SSH1_AGENTC_REMOVE_ALL_RSA_IDENTITIES)
                {
                    removeAllVersion = SshVersion.SSH1;
                }
                else if (header.Message == Message.SSH2_AGENTC_REMOVE_ALL_IDENTITIES)
                {
                    removeAllVersion = SshVersion.SSH2;
                }
                else
                {
                    Debug.Fail("Should not get here.");
                    goto default;
                }

                try {
                    RemoveAllKeys(removeAllVersion);
                    responseBuilder.InsertHeader(Message.SSH_AGENT_SUCCESS);
                    break; //success!
                } catch (Exception ex) {
                    Debug.Fail(ex.ToString());
                }
                goto default; // failed

            case Message.SSH_AGENTC_LOCK:
                try {
                    var passphrase = new PinnedArray <byte>(messageParser.ReadBlob());
                    try {
                        Lock(passphrase.Data);
                    } finally {
                        passphrase.Clear();
                    }
                    if (IsLocked)
                    {
                        responseBuilder.InsertHeader(Message.SSH_AGENT_SUCCESS);
                        break;
                    }
                } catch (AgentLockedException) {
                    // This is expected
                } catch (Exception ex) {
                    Debug.Fail(ex.ToString());
                }
                goto default;

            case Message.SSH_AGENTC_UNLOCK:
                try {
                    var passphrase = new PinnedArray <byte>(messageParser.ReadBlob());
                    try {
                        Unlock(passphrase.Data);
                    } finally {
                        passphrase.Clear();
                    }
                    if (!IsLocked)
                    {
                        responseBuilder.InsertHeader(Message.SSH_AGENT_SUCCESS);
                        break;
                    }
                } catch (AgentLockedException) {
                    // This is expected
                } catch (PassphraseException) {
                    // This is expected
                } catch (Exception ex) {
                    Debug.Fail(ex.ToString());
                }
                goto default;

            default:
                responseBuilder.Clear();
                responseBuilder.InsertHeader(Message.SSH_AGENT_FAILURE);
                break;
            }
            /* write response to stream */
            if (messageStream.CanSeek)
            {
                messageStream.Position = 0;
            }
            messageStream.Write(responseBuilder.GetBlob(), 0, responseBuilder.Length);
            messageStream.Flush();
        }
示例#19
0
 public MessageReceivedEventArgs(BlobHeader aMessageHeader)
 {
     MessageHeader = aMessageHeader;
     Fail          = false;
 }
        public IEnumerable <Address> ReadAddresses(string fileName)
        {
            //var max_streetLength = 0;
            //var max_housenumberLength = 0;
            //var max_cityLength = 0;
            //var max_postcodeLength = 0;
            //var max_countryLength = 0;

            using (var file = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                BlobHeader blobHeader = null;

                while ((blobHeader = ReadBlobHeader(file)) != null)
                {
                    var block = ReadBlob(file, blobHeader) as PrimitiveBlock;
                    if (block != null)
                    {
                        foreach (PrimitiveGroup group in block.PrimitiveGroup)
                        {
                            if (group.Ways == null)
                            {
                                continue;
                            }
                            foreach (var way in group.Ways)
                            {
                                var returnAddress = new Address()
                                {
                                    Country = "DE"
                                };
                                bool anyAddress = false;

                                if (way.Keys != null)
                                {
                                    for (int i = 0; i < way.Keys.Count; i++)
                                    {
                                        string tagType  = block.StringTable[way.Keys[i]];
                                        string tagValue = block.StringTable[way.Values[i]];

                                        //int tempCount = tagValue.Length;

                                        switch (tagType)
                                        {
                                        case "":
                                            break;

                                        case "addr:street":
                                            anyAddress           = true;
                                            returnAddress.Street = tagValue;

                                            //max_streetLength = tempCount > max_streetLength ? tempCount : max_streetLength;
                                            break;

                                        case "addr:housenumber":
                                            anyAddress = true;
                                            returnAddress.Housenumber = tagValue;

                                            //max_housenumberLength = tempCount > max_housenumberLength ? tempCount : max_housenumberLength;
                                            break;

                                        case "addr:city":
                                            anyAddress         = true;
                                            returnAddress.City = tagValue;

                                            //max_cityLength = tempCount > max_cityLength ? tempCount : max_cityLength;
                                            break;

                                        case "addr:postcode":
                                            anyAddress             = true;
                                            returnAddress.Postcode = tagValue;

                                            //max_postcodeLength = tempCount > max_postcodeLength ? tempCount : max_postcodeLength;
                                            break;
                                        //case "addr:country":
                                        //    anyAddress = true;
                                        //    returnAddress.Country = tagValue;

                                        //    //max_countryLength = tempCount > max_countryLength ? tempCount : max_countryLength;
                                        //    break;
                                        default:
                                            break;
                                        }
                                    }
                                }

                                if (!anyAddress || string.IsNullOrEmpty(returnAddress.Street) || string.IsNullOrEmpty(returnAddress.Postcode) || string.IsNullOrEmpty(returnAddress.City))
                                {
                                    continue;
                                }


                                yield return(returnAddress);
                            }
                        }
                    }
                }
            }
        }
示例#21
0
        private object ReadBlob(Stream inputStream, BlobHeader header)
        {
            var buffer = new byte[header.DataSize];

            inputStream.Read(buffer, 0, header.DataSize);
            Blob blob;

            using (var s = new MemoryStream(buffer))
            {
                blob = Serializer.Deserialize <Blob>(s);
            }

            Stream blobContentStream = null;

            try
            {
                if (blob.Raw != null)
                {
                    blobContentStream = new MemoryStream(blob.Raw);
                }
                else if (blob.ZlibData != null)
                {
                    var deflateStreamData = new MemoryStream(blob.ZlibData);
                    deflateStreamData.Seek(2, SeekOrigin.Begin);
                    blobContentStream = new DeflateStream(deflateStreamData, CompressionMode.Decompress);
                }

                if (header.Type.Equals("OSMData", StringComparison.InvariantCultureIgnoreCase))
                {
                    if (blobContentStream != null && ((blob.RawSize.HasValue && blob.RawSize > MaxDataBlockSize) ||
                                                      (blob.RawSize.HasValue == false && blobContentStream.Length > MaxDataBlockSize)))
                    {
                        throw new InvalidDataException("Invalid OSMData block");
                    }

                    return(Serializer.Deserialize <PrimitiveBlock>(blobContentStream));
                }
                else if (header.Type.Equals("OSMHeader", StringComparison.InvariantCultureIgnoreCase))
                {
                    if (blobContentStream != null && ((blob.RawSize.HasValue && blob.RawSize > MaxHeaderBlockSize) ||
                                                      (blob.RawSize.HasValue == false && blobContentStream.Length > MaxHeaderBlockSize)))
                    {
                        throw new InvalidDataException("Invalid OSMHeader block");
                    }

                    return(Serializer.Deserialize <OsmHeader>(blobContentStream));
                }
                else
                {
                    return(null);
                }
            }
            finally
            {
                if (blobContentStream != null)
                {
                    blobContentStream.Close();
                    blobContentStream.Dispose();
                }
            }
        }
示例#22
0
        public IEnumerable <Relation> ReadRelations(string fileName, AttributeRegistry attributeRegistry)
        {
            using (var file = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                BlobHeader blobHeader = null;

                while ((blobHeader = ReadBlobHeader(file)) != null)
                {
                    var block = ReadBlob(file, blobHeader) as PrimitiveBlock;
                    if (block != null)
                    {
                        foreach (PrimitiveGroup group in block.PrimitiveGroup)
                        {
                            if (group.Relations == null)
                            {
                                continue;
                            }

                            foreach (var relation in group.Relations)
                            {
                                var rel = new Relation
                                {
                                    RelationId = relation.ID
                                };
                                long memberRefStore = 0;

                                for (int i = 0; i < relation.MemberIds.Count; i++)
                                {
                                    memberRefStore += relation.MemberIds[i];
                                    string role = block.StringTable[relation.RolesIndexes[i]];

                                    rel.Members.Add(
                                        new Relation.Member
                                    {
                                        Type = attributeRegistry.GetAttributeValueId(OsmAttribute.MemberType, relation.Types[i].ToString()),
                                        Ref  = memberRefStore,
                                        Role = attributeRegistry.GetAttributeValueId(OsmAttribute.MemberRole, role),
                                    });
                                }


                                var usedTagTypes = new HashSet <int>();
                                if (relation.Keys != null)
                                {
                                    for (int i = 0; i < relation.Keys.Count; i++)
                                    {
                                        var tagType = attributeRegistry.GetAttributeValueId(OsmAttribute.TagType, block.StringTable[relation.Keys[i]]);
                                        if (!usedTagTypes.Contains(tagType))
                                        {
                                            rel.Tags.Add(new Tag
                                            {
                                                Value = block.StringTable[relation.Values[i]],
                                                Typ   = tagType
                                            });
                                            usedTagTypes.Add(tagType);
                                        }
                                    }
                                }
                                yield return(rel);
                            }
                        }
                    }
                }
            }
        }
示例#23
0
 public MessageReceivedEventArgs(BlobHeader aMessageHeader)
 {
     MessageHeader = aMessageHeader;
     Fail = false;
 }
示例#24
0
        private static ImmutableArray<byte> CreateSnPublicKeyBlob(BlobHeader header, RsaPubKey rsa, byte[] pubKeyData)
        {
            var snPubKey = new SnPublicKeyBlob()
            {
                SigAlgId = AlgorithmId.RsaSign,
                HashAlgId = AlgorithmId.Sha,
                PublicKeySize = (UInt32)(s_offsetToKeyData + pubKeyData.Length)
            };

            using (var ms = new MemoryStream(160))
            using (var binaryWriter = new BinaryWriter(ms))
            {
                binaryWriter.Write(snPubKey.SigAlgId);
                binaryWriter.Write(snPubKey.HashAlgId);
                binaryWriter.Write(snPubKey.PublicKeySize);

                binaryWriter.Write(header.Type);
                binaryWriter.Write(header.Version);
                binaryWriter.Write(header.Reserved);
                binaryWriter.Write(header.AlgId);

                binaryWriter.Write(rsa.Magic);
                binaryWriter.Write(rsa.BitLen);
                binaryWriter.Write(rsa.PubExp);

                binaryWriter.Write(pubKeyData);

                return ms.ToImmutable();
            }
        }
示例#25
0
        private unsafe static bool TryGetPublicKeyFromPrivateKeyBlob(byte* blob, int blobLen, out ImmutableArray<byte> publicKey)
        {
            var header = (BlobHeader*)blob;
            var rsa = (RsaPubKey*)(blob + sizeof(BlobHeader));

            var version = header->Version;
            var modulusBitLength = rsa->BitLen;
            var exponent = rsa->PubExp;
            var modulus = new byte[modulusBitLength >> 3];

            if (blobLen - s_offsetToKeyData < modulus.Length)
            {
                publicKey = ImmutableArray<byte>.Empty;
                return false;
            }

            Marshal.Copy((IntPtr)(blob + s_offsetToKeyData), modulus, 0, modulus.Length);

            var newHeader = new BlobHeader()
            {
                Type = PublicKeyBlobId,
                Version = version,
                Reserved = 0,
                AlgId = AlgorithmId.RsaSign
            };

            var newRsaKey = new RsaPubKey()
            {
                Magic = RSA1, // Public key
                BitLen = modulusBitLength,
                PubExp = exponent
            };

            publicKey = CreateSnPublicKeyBlob(newHeader, newRsaKey, modulus);
            return true;
        }
示例#26
0
        /// <summary>
        /// Answers the message.
        /// </summary>
        /// <param name='messageStream'>Message stream.</param>
        /// <param name="process">The calling process or <c>null</c> if the process
        /// could not be obtained.</param>
        /// <remarks>code based on winpgnt.c from PuTTY source code</remarks>
        public void AnswerMessage(Stream messageStream, Process process = null)
        {
            if (messageStream.CanTimeout) {
            messageStream.ReadTimeout = 5000;
              }
              var messageParser = new BlobParser(messageStream);
              var responseBuilder = new BlobBuilder();
              BlobHeader header;
              try {
            header = messageParser.ReadHeader();

            if (MessageReceived != null) {
              var eventArgs = new MessageReceivedEventArgs(header);
              MessageReceived(this, eventArgs);
              if (eventArgs.Fail) {
            throw new Exception ();
              }
            }
              } catch (Exception) {
            header = new BlobHeader();
            header.Message = Message.UNKNOWN;
            // this will cause the switch statement below to use the default case
            // which returns an error to the stream.
              }

              switch (header.Message) {
            case Message.SSH1_AGENTC_REQUEST_RSA_IDENTITIES:
              /*
               * Reply with SSH1_AGENT_RSA_IDENTITIES_ANSWER.
               */
              try {
            if (header.BlobLength > 1) {
              // ruby net-ssh tries to send a SSH2_AGENT_REQUEST_VERSION message
              // which has the same id number as SSH1_AGENTC_REQUEST_RSA_IDENTITIES
              // with a string tacked on. We need to read the string from the
              // stream, but it is not used for anything.
              messageParser.ReadString ();
            }
            var keyList = ListKeys(SshVersion.SSH1);
            if (FilterKeyListCallback != null) {
              keyList = FilterKeyListCallback(keyList);
            }
            foreach (SshKey key in keyList) {
              responseBuilder.AddBytes(key.GetPublicKeyBlob());
              responseBuilder.AddStringBlob(key.Comment);
            }
            responseBuilder.InsertHeader(Message.SSH1_AGENT_RSA_IDENTITIES_ANSWER,
              keyList.Count);
            // TODO may want to check that there is enough room in the message stream
            break; // succeeded
              } catch (Exception ex) {
            Debug.Fail(ex.ToString());
              }
              goto default; // failed

            case Message.SSH2_AGENTC_REQUEST_IDENTITIES:
              /*
               * Reply with SSH2_AGENT_IDENTITIES_ANSWER.
               */
              try {
            var keyList = ListKeys(SshVersion.SSH2);
            if (FilterKeyListCallback != null) {
              keyList = FilterKeyListCallback(keyList);
            }
            foreach (SshKey key in keyList) {
              responseBuilder.AddBlob(key.GetPublicKeyBlob());
              responseBuilder.AddStringBlob(key.Comment);
            }
            responseBuilder.InsertHeader(Message.SSH2_AGENT_IDENTITIES_ANSWER,
              keyList.Count);
            // TODO may want to check that there is enough room in the message stream
            break; // succeeded
              } catch (Exception ex) {
            Debug.Fail(ex.ToString());
              }
              goto default; // failed

            case Message.SSH1_AGENTC_RSA_CHALLENGE:
              /*
               * Reply with either SSH1_AGENT_RSA_RESPONSE or
               * SSH_AGENT_FAILURE, depending on whether we have that key
               * or not.
               */

              try {
            //Reading publicKey information
            var publicKeyParams = messageParser.ReadSsh1PublicKeyData(true);

            //Searching for Key here
            var matchingKey = mKeyList.Where(key => key.Version == SshVersion.SSH1
                && (key.GetPublicKeyParameters().Equals(publicKeyParams))).Single();

            //Reading challenge
            var encryptedChallenge = messageParser.ReadSsh1BigIntBlob();
            var sessionId = messageParser.ReadBytes(16);

            //Checking responseType field
            if (messageParser.ReadInt() != 1) {
              goto default; //responseType !=1  is not longer supported
            }

            //Answering to the challenge
            var engine = new Pkcs1Encoding(new RsaEngine());
            engine.Init(false /* decrypt */, matchingKey.GetPrivateKeyParameters());

            var decryptedChallenge = engine.ProcessBlock(encryptedChallenge,
                0, encryptedChallenge.Length);

            using (MD5 md5 = MD5.Create()) {
              var md5Buffer = new byte[48];
              decryptedChallenge.CopyTo(md5Buffer, 0);
              sessionId.CopyTo(md5Buffer, 32);

              responseBuilder.AddBytes(md5.ComputeHash(md5Buffer));
              responseBuilder.InsertHeader(Message.SSH1_AGENT_RSA_RESPONSE);
              break;
            }
              } catch (InvalidOperationException) {
            // this is expected if there is not a matching key
              } catch (Exception ex) {
            Debug.Fail(ex.ToString());
              }

              goto default; // failed

            case Message.SSH2_AGENTC_SIGN_REQUEST:
              /*
               * Reply with either SSH2_AGENT_SIGN_RESPONSE or SSH_AGENT_FAILURE,
               * depending on whether we have that key or not.
               */
              try {
            var keyBlob = messageParser.ReadBlob();
            var reqData = messageParser.ReadBlob();
            var flags = new SignRequestFlags();
            try {
              // usually, there are no flags, so parser will throw
              flags = (SignRequestFlags)messageParser.ReadInt();
            } catch { }

            var matchingKey =
              mKeyList.Where(key => key.Version == SshVersion.SSH2 &&
              key.GetPublicKeyBlob().SequenceEqual(keyBlob)).First();
            var confirmConstraints = matchingKey.Constraints
              .Where(constraint => constraint.Type ==
                KeyConstraintType.SSH_AGENT_CONSTRAIN_CONFIRM);
            if (confirmConstraints.Count() > 0) {
              if (!ConfirmUserPermissionCallback.Invoke(matchingKey, process)) {
                goto default;
              }
            }

            /* create signature */
            var signKey = matchingKey;
            var signer = signKey.GetSigner();
            var algName = signKey.Algorithm.GetIdentifierString();
            signer.Init(true, signKey.GetPrivateKeyParameters());
            signer.BlockUpdate(reqData, 0, reqData.Length);
            byte[] signature = signer.GenerateSignature();
            signature = signKey.FormatSignature(signature);
            BlobBuilder signatureBuilder = new BlobBuilder();
            if (!flags.HasFlag(SignRequestFlags.SSH_AGENT_OLD_SIGNATURE)) {
              signatureBuilder.AddStringBlob(algName);
            }
            signatureBuilder.AddBlob(signature);
            responseBuilder.AddBlob(signatureBuilder.GetBlob());
            responseBuilder.InsertHeader(Message.SSH2_AGENT_SIGN_RESPONSE);
            try {
              KeyUsed(this, new KeyUsedEventArgs(signKey, process));
            } catch { }
            break; // succeeded
              } catch (InvalidOperationException) {
            // this is expected if there is not a matching key
              } catch (Exception ex) {
            Debug.Fail(ex.ToString());
              }
              goto default; // failure

            case Message.SSH1_AGENTC_ADD_RSA_IDENTITY:
            case Message.SSH1_AGENTC_ADD_RSA_ID_CONSTRAINED:
              /*
               * Add to the list and return SSH_AGENT_SUCCESS, or
               * SSH_AGENT_FAILURE if the key was malformed.
               */

              if (IsLocked) {
            goto default;
              }

              bool ssh1constrained = (header.Message == Message.SSH1_AGENTC_ADD_RSA_ID_CONSTRAINED);

              try {
            var publicKeyParams = messageParser.ReadSsh1PublicKeyData(false);
            var keyPair = messageParser.ReadSsh1KeyData(publicKeyParams);

            SshKey key = new SshKey(SshVersion.SSH1, keyPair);
            key.Comment = messageParser.ReadString();
            key.Source = "External client";

            if (ssh1constrained) {
              while (messageStream.Position < header.BlobLength + 4) {
                KeyConstraint constraint = new KeyConstraint();
                constraint.Type = (KeyConstraintType)messageParser.ReadByte();
                if (constraint.Type ==
                  KeyConstraintType.SSH_AGENT_CONSTRAIN_LIFETIME) {
                  constraint.Data = messageParser.ReadInt();
                }
                key.AddConstraint(constraint);
              }
            }
            AddKey(key);
            responseBuilder.InsertHeader(Message.SSH_AGENT_SUCCESS);
            break;

              } catch (CallbackNullException) {
            // this is expected
              } catch (Exception ex) {
            Debug.Fail(ex.ToString());
              }

              goto default; // failed

            case Message.SSH2_AGENTC_ADD_IDENTITY:
            case Message.SSH2_AGENTC_ADD_ID_CONSTRAINED:
              /*
               * Add to the list and return SSH_AGENT_SUCCESS, or
               * SSH_AGENT_FAILURE if the key was malformed.
               */

              if (IsLocked) {
            goto default;
              }

              bool constrained = (header.Message ==
              Message.SSH2_AGENTC_ADD_ID_CONSTRAINED);

              try {
            var publicKeyParams = messageParser.ReadSsh2PublicKeyData();
            var keyPair = messageParser.ReadSsh2KeyData(publicKeyParams);
            SshKey key = new SshKey(SshVersion.SSH2, keyPair);
            key.Comment = messageParser.ReadString();
            key.Source = "External client";

            if (constrained) {
              while (messageStream.Position < header.BlobLength + 4) {
                KeyConstraint constraint = new KeyConstraint();
                constraint.Type =
                  (KeyConstraintType)messageParser.ReadByte();
                if (constraint.Type ==
                  KeyConstraintType.SSH_AGENT_CONSTRAIN_LIFETIME) {
                  constraint.Data = messageParser.ReadInt();
                }
                key.AddConstraint(constraint);
              }
            }
            AddKey(key);
            responseBuilder.InsertHeader(Message.SSH_AGENT_SUCCESS);
            break; // success!
              } catch (CallbackNullException) {
            // this is expected
              } catch (Exception ex) {
            Debug.Fail(ex.ToString());
              }
              goto default; // failed

            case Message.SSH1_AGENTC_REMOVE_RSA_IDENTITY:
            case Message.SSH2_AGENTC_REMOVE_IDENTITY:
              /*
               * Remove from the list and return SSH_AGENT_SUCCESS, or
               * perhaps SSH_AGENT_FAILURE if it wasn't in the list to
               * start with.
               */

              if (IsLocked) {
            goto default;
              }

              SshVersion removeVersion;
              byte[] rKeyBlob;
              if (header.Message == Message.SSH1_AGENTC_REMOVE_RSA_IDENTITY) {
            removeVersion = SshVersion.SSH1;
            rKeyBlob = messageParser.ReadBytes(header.BlobLength - 1);
              } else if (header.Message == Message.SSH2_AGENTC_REMOVE_IDENTITY) {
            removeVersion = SshVersion.SSH2;
            rKeyBlob = messageParser.ReadBlob();
              } else {
            Debug.Fail("Should not get here.");
            goto default;
              }

              try {
            var matchingKey = mKeyList.Get(removeVersion, rKeyBlob);
            var startKeyListLength = mKeyList.Count;
            RemoveKey(matchingKey);
            // only succeed if key was removed
            if (mKeyList.Count == startKeyListLength - 1) {
              responseBuilder.InsertHeader(Message.SSH_AGENT_SUCCESS);
              break; //success!
            }
              } catch (Exception ex) {
            Debug.Fail(ex.ToString());
              }
              goto default; // failed

            case Message.SSH1_AGENTC_REMOVE_ALL_RSA_IDENTITIES:
            case Message.SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
              /*
               * Remove all SSH-1 or SSH-2 keys.
               */

              if (IsLocked) {
            goto default;
              }

              SshVersion removeAllVersion;
              if (header.Message == Message.SSH1_AGENTC_REMOVE_ALL_RSA_IDENTITIES) {
            removeAllVersion = SshVersion.SSH1;
              } else if (header.Message == Message.SSH2_AGENTC_REMOVE_ALL_IDENTITIES) {
            removeAllVersion = SshVersion.SSH2;
              } else {
            Debug.Fail("Should not get here.");
            goto default;
              }

              try {
            RemoveAllKeys(removeAllVersion);
            responseBuilder.InsertHeader(Message.SSH_AGENT_SUCCESS);
            break; //success!
              } catch (Exception ex) {
            Debug.Fail(ex.ToString());
              }
              goto default; // failed

            case Message.SSH_AGENTC_LOCK:
              try {
            var passphrase = new PinnedArray<byte>(messageParser.ReadBlob());
            try {
              Lock(passphrase.Data);
            } finally {
              passphrase.Clear();
            }
            if (IsLocked) {
              responseBuilder.InsertHeader(Message.SSH_AGENT_SUCCESS);
              break;
            }
              } catch (AgentLockedException) {
            // This is expected
              } catch (Exception ex) {
            Debug.Fail(ex.ToString());
              }
              goto default;

            case Message.SSH_AGENTC_UNLOCK:
              try {
            var passphrase = new PinnedArray<byte>(messageParser.ReadBlob());
            try {
              Unlock(passphrase.Data);
            } finally {
              passphrase.Clear();
            }
            if (!IsLocked) {
              responseBuilder.InsertHeader(Message.SSH_AGENT_SUCCESS);
              break;
            }
              } catch (AgentLockedException) {
            // This is expected
              } catch (PassphraseException) {
            // This is expected
              } catch (Exception ex) {
            Debug.Fail(ex.ToString());
              }
              goto default;

            default:
              responseBuilder.Clear();
              responseBuilder.InsertHeader(Message.SSH_AGENT_FAILURE);
              break;
              }
              /* write response to stream */
              if (messageStream.CanSeek)
            messageStream.Position = 0;
              messageStream.Write(responseBuilder.GetBlob(), 0, responseBuilder.Length);
              messageStream.Flush();
        }