private static void AddFile(object OFullFileName) { try { string FullFileName = OFullFileName.ToString(); var FileName = Path.GetFileName(FullFileName); string BinaryGPGFile = GetBinaryFile(FullFileName); ByteBlock StartBlock = OpenPGP.Process(BinaryGPGFile); OpenPGP.Validate(); AddComplete?.Invoke(FileName, StartBlock); } catch (Exception ex) { Error?.Invoke(ex.Message, true); } }
public ByteBlock AddChildBlock(ByteBlock block) { var LastBlock = ChildBlock; var PreviousBlock = ChildBlock; while (LastBlock != null) { PreviousBlock = LastBlock; LastBlock = LastBlock.NextBlock; } if (PreviousBlock == null) { ChildBlock = block; } else { PreviousBlock.NextBlock = block; } return(block); }
private void AddComplete(string FileName, ByteBlock StartBlock) { if (InvokeRequired) { BeginInvoke(new AddCompleteDelegate(AddComplete), new object[] { FileName, StartBlock }); return; } ResetStatus(); var tn = treeView1.Nodes.Add(FileName); tn.ImageKey = "file"; tn.NodeFont = new Font(treeView1.Font, FontStyle.Bold); tn.Text = FileName; CreateBlockTree(tn, StartBlock); RefreshNodes(treeView1.Nodes); }
public ByteBlock AddBlock(ByteBlock NewBlock) { var LastBlock = NextBlock; var PreviousBlock = NextBlock; while (LastBlock != null) { PreviousBlock = LastBlock; LastBlock = LastBlock.NextBlock; } if (PreviousBlock == null) { NextBlock = NewBlock; } else { PreviousBlock.NextBlock = NewBlock; } return(NewBlock); }
public override void Parse(TreeBuilder tree) { base.Parse(tree); bool IsEncrypted = true; tree.SetBookMark(); var S2K = new S2K { S2KUsage = tree.ReadByte() }; if (S2K.S2KUsage == 254 || S2K.S2KUsage == 255) { S2K.SymAlgo = tree.ReadByte("Symmetric Algorithm", SymmetricAlgorithmTypes.Get); byte S2KSpecifier = tree.ReadByte("S2K Specifier", S2KTypes.Get); if (S2KSpecifier != S2KTypes.Salted && S2KSpecifier != S2KTypes.Simple && S2KSpecifier != S2KTypes.IteratedAndSalted) { //tree.AddCalculated("Invalid S2K", S2KSpecifier.ToString()); tree.AddCalculated("Unable to Process", S2KSpecifier.ToString(), ByteBlockType.CalculatedError); return; } S2K.HashAlgorithm = tree.ReadByte("Hash Algorithm", HashAlgorithmTypes.Get); if (S2KSpecifier == S2KTypes.Salted || S2KSpecifier == S2KTypes.IteratedAndSalted) { S2K.Salt = tree.ReadBytes("Salt", 8); if (S2KSpecifier == S2KTypes.IteratedAndSalted) { byte CodedCount = tree.ReadByte("Coded Iteration"); S2K.ByteCount = (16 + (CodedCount & 15)) << ((CodedCount >> 4) + 6); } } int BlockSizeBytes = SymmetricAlgorithmTypes.GetBlockSize(S2K.SymAlgo) / 8; S2K.IV = tree.ReadBytes("IV", BlockSizeBytes); } else { byte SymAlgo = S2K.S2KUsage; S2K.SymAlgo = SymAlgo; if (SymAlgo != 0) { tree.GoToBookMark(); tree.ReadByte("Symmetric Algorithm", SymmetricAlgorithmTypes.Get); int BlockSize = SymmetricAlgorithmTypes.GetBlockSize(SymAlgo) / 8; S2K.IV = tree.ReadBytes("IV", BlockSize); } else { IsEncrypted = false; } } PublicKeyAlgorithm.S2K = S2K; if (IsEncrypted) { byte[] Encrypted = tree.ReadBytes("Encrypted Secret Key"); PublicKeyAlgorithm.EncryptedPrivateKey = Encrypted; tree.CurrentBlock.ProcessBlock += ExtractPrivateKey; SecretKeyNode = tree.CurrentBlock; } else { byte[] ClearBytes = tree.ReadBytes("Unencrypted Secret Key"); var SecBlockClear = PublicKeyAlgorithm.SetPrivate(ClearBytes); tree.AddChild(PublicKeyAlgorithm.GetPrivateByteBlocks()); } }
public ByteBlock AddChildBlock(string Label, string Description, long Position, byte[] RawBytes) { var NewBlock = new ByteBlock(Label, Description, Position, RawBytes); return(AddChildBlock(NewBlock)); }
public static ByteBlock Process(string PGPFile) { var Root = new ByteBlock(); PGPPacket pgp; PublicKeyPacket PrimaryKeyPacket = null; PublicKeyPacket SubKeyPacket = null; UserIDPacket UIDPacket = null; Stack <OnePassSignaturePacket> OPSigPacketStack = new Stack <OnePassSignaturePacket>(); HashAlgorithm[] HashAlgorithms = null; using (var PacketReader = new PGPReader(PGPFile)) { PacketReader.DoIndexUpdate += IndexUpdate; while ((pgp = PacketReader.ReadNextPacket()) != null) { TreeBuilder Tree = new TreeBuilder(PacketReader); pgp.Parse(Tree); if (pgp is LiteralDataPacket litPgp) { if (HashAlgorithms == null) { HashAlgorithms = GetHashAlgorithms(OPSigPacketStack); } litPgp.ProgressUpdate += StatusUpdate; litPgp.DoHash(PacketReader, HashAlgorithms); } else { if (pgp is OnePassSignaturePacket OPSig) { OPSigPacketStack.Push(OPSig); } else if (pgp.PacketTag == 6 || pgp.PacketTag == 5) { PrimaryKeyPacket = (PublicKeyPacket)pgp; } else if (pgp is UserIDPacket) { UIDPacket = (UserIDPacket)pgp; } else if (pgp.PacketTag == 14 || pgp.PacketTag == 7) { SubKeyPacket = (PublicKeyPacket)pgp; } else if (pgp is SignaturePacket Sig) { if ((Sig.SignatureType == 0x18 || Sig.SignatureType == 0x19) && PrimaryKeyPacket != null && SubKeyPacket != null && SubKeyPacket.PacketDataPublicKey != null) { Sig.GenerateSubKeyBindingHash(PrimaryKeyPacket, SubKeyPacket); } if (Sig.SignatureType >= 0x10 && Sig.SignatureType <= 0x13 && PrimaryKeyPacket != null && UIDPacket != null) { Sig.GenerateCertifyHash(PrimaryKeyPacket, UIDPacket); } // Signature of a Binary Document if (Sig.SignatureType == 0x00) { // Are we generating hash for One Pass Signature Packet if (OPSigPacketStack.Count() > 0) { var OnePassSignaturePacket = OPSigPacketStack.Pop(); if (OnePassSignaturePacket.HashAlgorithm == Sig.HashAlgorithm) { Sig.GenerateBinaryHash(HashAlgorithmTypes.GetHashAlgoManaged(Sig.HashAlgorithm, HashAlgorithms)); } } } } } PacketBlock pb = new PacketBlock(pgp); pb.AddChildBlock(Tree.StartBlock); Root.AddChildBlock(pb); _PacketNodes.Add(pb); } } return(Root.ChildBlock); }
//public void Seek(long FromCurrentPosition) //{ // _fs.Seek(FromCurrentPosition, SeekOrigin.Current); //} public ByteBlock AddChild(ByteBlock ChildBlock) { return(CurrentBlock.AddChildBlock(ChildBlock)); }
private void ExtractData() { string DecryptedFileName = null; string Password = null; if (MessageBox.Show("Decrypt Encrypted Data", "Please Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != System.Windows.Forms.DialogResult.Yes) { return; } PGPPacket Packet = this; List <byte[]> SessionKeys = new List <byte[]>(); List <PKEncSessionKeyPacket> PKSessions = new List <PKEncSessionKeyPacket>(); List <SymEncSessionKeyPacket> SymSessions = new List <SymEncSessionKeyPacket>(); //byte SymmetricAlgorithm = 0; string ErrorMsg = ""; while ((Packet = OpenPGP.GetPreviousPacket(Packet)) != null) { if (Packet is PKEncSessionKeyPacket PKSessionPacket) { PKSessions.Add(PKSessionPacket); } else if (Packet is SymEncSessionKeyPacket SymKeySessionPacket) { SymSessions.Add(SymKeySessionPacket); } } // First try to see if we have any PK Secret keys foreach (var PKSession in PKSessions) { // Get all matching secret keys var SecKeyList = OpenPGP.FindPrimaryKey(PKSession.KeyId, true).Where(p => p.PacketTag == 5 || p.PacketTag == 7).ToList(); foreach (SecretKeyPacket SecKey in SecKeyList) { var PKAlgorithm = SecKey.PublicKeyAlgorithm; if (!PKAlgorithm.PrivateKeyDecrypted) { ErrorMsg = "Secret Key is encrypted, click on the encrypted node to decrypt it first"; continue; } var ClearBytes = PKAlgorithm.Decrypt(PKSession.PublicKeyTransformedData); long CheckSum = 0; for (int i = 1; i < ClearBytes.Length - 2; i++) { CheckSum += ClearBytes[i]; } CheckSum %= 65536; if ((CheckSum >> 8) != ClearBytes[ClearBytes.Length - 2] || (CheckSum & 0xFF) != ClearBytes[ClearBytes.Length - 1]) { continue; } //SymmetricAlgorithm = ClearBytes[0]; SessionKeys.Add(ClearBytes.SubArray(0, ClearBytes.Length - 2)); } } if (SessionKeys.Count() == 0) { if (ErrorMsg != "") { throw new Exception(ErrorMsg); } } // If no Public Key Encrypted keys found, then try any Sym keys if (SessionKeys.Count() == 0) { foreach (var SymSession in SymSessions) { if (Password == null) { // Ask for password only once PinEntry frm = new PinEntry(); if (frm.ShowDialog() == DialogResult.Cancel) { break; } Password = frm.Password; } byte[] DecryptionKey = SymSession.S2K.GetKey(Password); if (SymSession.EncryptedSessionKey == null) { byte[] SessionKey = new byte[DecryptionKey.Length + 1]; SessionKey[0] = SymSession.S2K.SymAlgo; Array.Copy(DecryptionKey, 0, SessionKey, 1, DecryptionKey.Length); SessionKeys.Add(SessionKey); } else { var KeyDecryptor = SymmProcess.GetDecryptor(SymSession.S2K.SymAlgo, DecryptionKey); var BlockSizeBytes = KeyDecryptor.InputBlockSize; int EncryptedLength = SymSession.EncryptedSessionKey.Length; int BlockFillLength = BlockSizeBytes * ((EncryptedLength / BlockSizeBytes) + 1); byte[] CryptBytes = new byte[BlockFillLength]; Array.Copy(SymSession.EncryptedSessionKey, 0, CryptBytes, 0, EncryptedLength); byte[] ClearBytes; using (MemoryStream msDecrypt = new MemoryStream()) { using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, KeyDecryptor, CryptoStreamMode.Write)) csDecrypt.Write(CryptBytes, 0, CryptBytes.Length); ClearBytes = msDecrypt.ToArray().SubArray(0, EncryptedLength); } SessionKeys.Add(ClearBytes); } } } //if (Packet == null || (Packet.PacketTag != 1 && Packet.PacketTag != 3)) // throw new Exception("No Public-Key/Symmetric-Key encrypted session key packet"); //if (SecKeyList.Count() == 0) // throw new Exception("Secret Key not available, please add the secret key to decrypt data"); if (SessionKeys.Count() == 0) { throw new Exception("Unable to Decrypt"); } // Session Key found DecryptedFileName = TempFiles.GetNewTempFile(); bool Success = false; using (PGPReader fsSource = new PGPReader(FileName)) { fsSource.DoIndexUpdate += OnIndexUpdate; fsSource.GetPacket(PacketIndex); fsSource.DoIndexUpdate -= OnIndexUpdate; byte version = fsSource.ReadByte(); long FileSize = fsSource.BytesRemaining; fsSource.BookMark(); foreach (var SessionKey in SessionKeys) { try { var decryptor = SymmProcess.GetDecryptor(SessionKey[0], SessionKey.SubArray(1, SessionKey.Length - 1)); int BlockSize = decryptor.InputBlockSize; fsSource.GoToBookMark(); using (FileStream fsDecrypt = new FileStream(DecryptedFileName, FileMode.Create, FileAccess.Write)) { SHA1 Sha1 = new SHA1Managed(); byte[] CryptBytes = new byte[BlockSize * 256]; // IMPORTANT: Make sure it is a multiple of block size byte[] PlainBytes = new byte[BlockSize * 256]; var BytesRemaining = FileSize - 22; // 2 byte MDC tag (0xD3, 0x14) and length, 20 byte SHA-1 hash int BlockAlign = (int)(BytesRemaining % BlockSize); BytesRemaining -= BlockAlign; // Transformation has to be done in blocks, so make sure it fits in blocks bool FirstTime = true; while (BytesRemaining > 0) { int ReadBytes = (int)BytesRemaining; if (BytesRemaining > CryptBytes.Length) { ReadBytes = CryptBytes.Length; } fsSource.Read(CryptBytes, 0, ReadBytes); decryptor.TransformBlock(CryptBytes, 0, ReadBytes, PlainBytes, 0); if (FirstTime) { // Validate the repeating bytes if (PlainBytes[BlockSize - 2] != PlainBytes[BlockSize] || PlainBytes[BlockSize - 1] != PlainBytes[BlockSize + 1]) { throw new Exception("Pre validation failed, session key may be invalid"); } fsDecrypt.Write(PlainBytes, BlockSize + 2, ReadBytes - BlockSize - 2); FirstTime = false; } else { fsDecrypt.Write(PlainBytes, 0, ReadBytes); } Sha1.TransformBlock(PlainBytes, 0, ReadBytes, PlainBytes, 0); StatusUpdate("Decrypting...", (int)(100 * (FileSize - BytesRemaining) / FileSize)); BytesRemaining -= ReadBytes; } int FinalBytes = BlockAlign + 22; fsSource.Read(CryptBytes, 0, FinalBytes); decryptor.TransformBlock(CryptBytes, 0, FinalBytes + Program.GetBlockAlignRemainder(FinalBytes, BlockSize), PlainBytes, 0); fsDecrypt.Write(PlainBytes, 0, BlockAlign); // Validate the MDC Packet if (PlainBytes[BlockAlign] != 0xD3 || PlainBytes[BlockAlign + 1] != 0x14) { throw new Exception("Modification Detection validation failed, data is corrupt"); } Sha1.TransformFinalBlock(PlainBytes, 0, BlockAlign + 2); // 0xD3, 0x14 bytes if (!PlainBytes.SubArray(BlockAlign + 2, 20).SequenceEqual(Sha1.Hash)) { throw new Exception("MDC hash verification failed, Data may have been modified or is corrupt"); } Success = true; break; } } catch (Exception ex) { } } } if (Success) { ByteBlock StartBlock = OpenPGP.Process(DecryptedFileName); OpenPGP.Validate(); ThisBlock.AddChildBlock(StartBlock); } }
public void Extract(string SourceFileName) { string DestFileName; using (PGPReader fsSource = new PGPReader(SourceFileName)) { fsSource.DoIndexUpdate += OnIndexUpdate; fsSource.GetPacket(PacketIndex); fsSource.DoIndexUpdate -= OnIndexUpdate; byte CompressionAlgorithm = fsSource.ReadByte(); if (CompressionAlgorithm != 0 && CompressionAlgorithm != 1 && CompressionAlgorithm != 2 && CompressionAlgorithm != 3) { throw new Exception("Compression algorithm not supported"); } int HashBytes = 0; if (CompressionAlgorithm == 2) { // RFC 1950 HashBytes = 4; byte CMF = fsSource.ReadByte(); byte FLG = fsSource.ReadByte(); if ((FLG & 32) != 0) { byte[] DICT = new byte[4]; fsSource.Read(DICT, 0, 4); } } Adler32 adler32 = new Adler32(); byte[] Hash = null; PGPStream PGPStream = new PGPStream(fsSource, HashBytes); DestFileName = TempFiles.GetNewTempFile(); using (FileStream fsDest = new FileStream(DestFileName, FileMode.Create, FileAccess.Write)) { if (CompressionAlgorithm == 0) { CopyStream(PGPStream, PGPStream, fsDest); } else if (CompressionAlgorithm == 3) { using (var BZip2Stream = new BZip2InputStream(PGPStream)) { CopyStream(PGPStream, BZip2Stream, fsDest); } } else { using (DeflateStream decompressionStream = new DeflateStream(PGPStream, CompressionMode.Decompress)) { CopyStream(PGPStream, decompressionStream, fsDest, adler32); Hash = adler32.Hash; } } } if (HashBytes > 0) { byte[] HashCompare = new byte[4]; fsSource.Read(HashCompare, 0, 4); if (!HashCompare.Reverse().SequenceEqual(Hash)) { throw new Exception("Decompressed Hash Mismatch"); } } } ByteBlock StartBlock = OpenPGP.Process(DestFileName); OpenPGP.Validate(); ThisBlock.AddChildBlock(StartBlock); }