コード例 #1
0
ファイル: Worker.cs プロジェクト: titasraha/opex
        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);
            }
        }
コード例 #2
0
        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);
        }
コード例 #3
0
ファイル: frmMain.cs プロジェクト: titasraha/opex
        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);
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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());
            }
        }
コード例 #6
0
        public ByteBlock AddChildBlock(string Label, string Description, long Position, byte[] RawBytes)
        {
            var NewBlock = new ByteBlock(Label, Description, Position, RawBytes);

            return(AddChildBlock(NewBlock));
        }
コード例 #7
0
ファイル: OpenPGP.cs プロジェクト: titasraha/opex
        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);
        }
コード例 #8
0
ファイル: TreeBuilder.cs プロジェクト: titasraha/opex
        //public void Seek(long FromCurrentPosition)
        //{
        //    _fs.Seek(FromCurrentPosition, SeekOrigin.Current);
        //}

        public ByteBlock AddChild(ByteBlock ChildBlock)
        {
            return(CurrentBlock.AddChildBlock(ChildBlock));
        }
コード例 #9
0
        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);
            }
        }
コード例 #10
0
        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);
        }