/// <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> /// 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."); }
/// <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."); }
/// <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); } }
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()); } }
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 }); } } } } } }
/// <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); }
/// <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); } }
/// <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); }
/// <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); } }
/// <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> /// 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(); }
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); } } } } } }
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(); } } }
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); } } } } } }
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(); } }
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; }
/// <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(); }