Exemplo n.º 1
0
        /// <summary>
        /// Sign a file with PGP signature. See documentation at https://github.com/CommunityHiQ/Frends.Community.PgpSignature Returns: Object {string FilePath}
        /// </summary>
        public static PgpSignatureResult SignFile(PgpSignatureInput input)
        {
            HashAlgorithmTag digest = input.HashFunction.ConvertEnum <HashAlgorithmTag>();

            using (var privateKeyStream = File.OpenRead(input.PrivateKeyFile))
            {
                var pgpSecKey                   = PgpServices.SignatureReadSecretKey(privateKeyStream);
                var pgpPrivKey                  = pgpSecKey.ExtractPrivateKey(input.Password.ToCharArray());
                var signatureGenerator          = new PgpSignatureGenerator(pgpSecKey.PublicKey.Algorithm, digest);
                var signatureSubpacketGenerator = new PgpSignatureSubpacketGenerator();

                signatureGenerator.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);

                var enumerator = pgpSecKey.PublicKey.GetUserIds().GetEnumerator();
                if (enumerator.MoveNext())
                {
                    signatureSubpacketGenerator.SetSignerUserId(false, (string)enumerator.Current);
                    signatureGenerator.SetHashedSubpackets(signatureSubpacketGenerator.Generate());
                }

                using (var outputStream = File.Create(input.OutputFile))
                {
                    var armoredOutputStream = new ArmoredOutputStream(outputStream);

                    var bcbgOutputStream = new BcpgOutputStream(armoredOutputStream);
                    signatureGenerator.GenerateOnePassVersion(false).Encode(bcbgOutputStream);

                    var file = new FileInfo(input.InputFile);
                    var literalDataGenerator = new PgpLiteralDataGenerator();
                    var literalDataOut       = literalDataGenerator.Open(bcbgOutputStream, PgpLiteralData.Binary, file.Name, file.Length, DateTime.Now);
                    using (var fileIn = file.OpenRead())
                    {
                        int ch;

                        while ((ch = fileIn.ReadByte()) >= 0)
                        {
                            literalDataOut.WriteByte((byte)ch);
                            signatureGenerator.Update((byte)ch);
                        }

                        fileIn.Close();
                        literalDataGenerator.Close();
                        signatureGenerator.Generate().Encode(bcbgOutputStream);
                        armoredOutputStream.Close();
                        outputStream.Close();

                        var ret = new PgpSignatureResult
                        {
                            FilePath = input.OutputFile
                        };
                        return(ret);
                    }
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Encrypts a file using public key.
        /// If needed, the file can also be signed with private key, in this case, the order is sign and encrypt.
        /// See https://github.com/CommunityHiQ/Frends.Community.PgpEncryptFile
        /// </summary>
        /// <param name="input">Task input</param>
        /// <returns>Returns: Object {string FilePath}</returns>
        public static PgpEncryptResult EncryptFile(PgpEncryptInput input)
        {
            // source file to encrypt
            var inputFile = new FileInfo(input.InputFile);

            if (!inputFile.Exists)
            {
                throw new ArgumentException("File to encrypt does not exists", input.InputFile);
            }

            // destination file
            using (Stream outputStream = File.OpenWrite(input.OutputFile))
                // ascii output?
                using (var armoredStream = input.UseArmor ? new ArmoredOutputStream(outputStream) : outputStream)
                    using (var encryptedOut = PgpServices.GetEncryptionStream(armoredStream, input))
                        using (var compressedOut = PgpServices.GetCompressionStream(encryptedOut, input))
                        {
                            // signature init - if necessary
                            var signatureGenerator = input.SignWithPrivateKey ? PgpServices.InitPgpSignatureGenerator(compressedOut, input) : null;

                            // writing to configured output
                            var literalDataGenerator = new PgpLiteralDataGenerator();
                            var file = new FileInfo(input.InputFile);
                            using (var literalOut = literalDataGenerator.Open(compressedOut, PgpLiteralData.Binary, file.Name, file.Length, DateTime.Now))
                                using (var inputStream = inputFile.OpenRead())
                                {
                                    var buf = new byte[EncryptBufferSize];
                                    int len;

                                    while ((len = inputStream.Read(buf, 0, buf.Length)) > 0)
                                    {
                                        literalOut.Write(buf, 0, len);
                                        if (input.SignWithPrivateKey)
                                        {
                                            signatureGenerator.Update(buf, 0, len);
                                        }
                                    }

                                    if (input.SignWithPrivateKey)
                                    {
                                        signatureGenerator.Generate().Encode(compressedOut);
                                    }
                                }
                        }

            return(new PgpEncryptResult
            {
                FilePath = input.OutputFile
            });
        }
Exemplo n.º 3
0
        internal static bool Decrypt(Stream inputStream, Stream privateKeyStream, string passPhrase, string outputFile)
        {
            PgpPrivateKey             sKey = null;
            PgpPublicKeyEncryptedData pbe  = null;
            var pgpF = new PgpObjectFactory(PgpUtilities.GetDecoderStream(inputStream));
            // find secret key
            var pgpSec = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream));
            var o      = pgpF.NextPgpObject();

            PgpEncryptedDataList enc;

            // the first object might be a PGP marker packet.
            if (o is PgpEncryptedDataList list)
            {
                enc = list;
            }
            else
            {
                enc = (PgpEncryptedDataList)pgpF.NextPgpObject();
            }

            // decrypt
            foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects())
            {
                sKey = PgpServices.FindSecretKey(pgpSec, pked.KeyId, passPhrase.ToCharArray());

                if (sKey == null)
                {
                    continue;
                }
                pbe = pked;
                break;
            }

            if (sKey == null)
            {
                throw new ArgumentException("Secret key for message not found.");
            }

            PgpObjectFactory plainFact;

            using (var clear = pbe.GetDataStream(sKey))
            {
                plainFact = new PgpObjectFactory(clear);
            }

            var message = plainFact.NextPgpObject();

            switch (message)
            {
            case PgpCompressedData cData:
            {
                PgpObjectFactory of;

                using (var compDataIn = cData.GetDataStream())
                {
                    of = new PgpObjectFactory(compDataIn);
                }

                message = of.NextPgpObject();
                if (message is PgpOnePassSignatureList)
                {
                    message = of.NextPgpObject();
                    var ld = (PgpLiteralData)message;
                    using (var output = File.Create(outputFile))
                    {
                        var unc = ld.GetInputStream();
                        Streams.PipeAll(unc, output);
                    }
                }
                else
                {
                    var ld = (PgpLiteralData)message;
                    using (var output = File.Create(outputFile))
                    {
                        var unc = ld.GetInputStream();
                        Streams.PipeAll(unc, output);
                    }
                }

                break;
            }

            case PgpLiteralData ld:
            {
                using (var fOut = File.Create(outputFile))
                {
                    var unc = ld.GetInputStream();
                    Streams.PipeAll(unc, fOut);
                }

                break;
            }

            case PgpOnePassSignatureList _:
                throw new PgpException("Encrypted message contains a signed message - not literal data.");

            default:
                throw new PgpException("Message is not a simple encrypted file - type unknown.");
            }

            return(true);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Verifies clear text PGP signature. See documentation at https://github.com/CommunityHiQ/Frends.Community.PgpVerifyClearTextSignature Returns: Object {string FilePath, Boolean Verified}
        /// </summary>
        public static PgpVerifyClearTextSignatureResult VerifyFileClearTextSignature(PgpVerifyClearTextSignatureInput input)
        {
            using (var inStr = File.OpenRead(input.InputFile))
                using (var outStr = File.Create(input.OutputFile))
                    using (var keyStr = PgpUtilities.GetDecoderStream(File.OpenRead(input.PublicKeyFile)))
                    {
                        var aInputStr = new ArmoredInputStream(inStr);

                        //
                        // write out signed section using the local line separator.
                        // note: trailing white space needs to be removed from the end of
                        // each line RFC 4880 Section 7.1
                        //
                        var lineOut   = new MemoryStream();
                        var lookAhead = PgpServices.VerifyClearTextSignatureReadInputLine(lineOut, aInputStr);
                        var lineSep   = Encoding.ASCII.GetBytes(Environment.NewLine);


                        if (lookAhead != -1 && aInputStr.IsClearText())
                        {
                            var line = lineOut.ToArray();
                            outStr.Write(line, 0, PgpServices.GetLengthWithoutSeparatorOrTrailingWhitespace(line));
                            outStr.Write(lineSep, 0, lineSep.Length);

                            while (lookAhead != -1 && aInputStr.IsClearText())
                            {
                                lookAhead = PgpServices.VerifyClearTextSignatureReadInputLine(lineOut, lookAhead, aInputStr);

                                line = lineOut.ToArray();
                                outStr.Write(line, 0, PgpServices.GetLengthWithoutSeparatorOrTrailingWhitespace(line));
                                outStr.Write(lineSep, 0, lineSep.Length);
                            }
                        }
                        else
                        {
                            // a single line file
                            if (lookAhead != -1)
                            {
                                var line = lineOut.ToArray();
                                outStr.Write(line, 0, PgpServices.GetLengthWithoutSeparatorOrTrailingWhitespace(line));
                                outStr.Write(lineSep, 0, lineSep.Length);
                            }
                        }
                        outStr.Close();

                        var pgpRings = new PgpPublicKeyRingBundle(keyStr);

                        var pgpFact = new PgpObjectFactory(aInputStr);
                        var p3      = (PgpSignatureList)pgpFact.NextPgpObject();
                        var sig     = p3[0];
                        inStr.Close();


                        sig.InitVerify(pgpRings.GetPublicKey(sig.KeyId));
                        // read the input, making sure we ignore the last newline.
                        bool verified;
                        using (var sigIn = File.OpenRead(input.OutputFile))
                        {
                            lookAhead = PgpServices.VerifyClearTextSignatureReadInputLine(lineOut, sigIn);
                            PgpServices.ProcessLine(sig, lineOut.ToArray());
                            while (lookAhead != -1)
                            {
                                lookAhead = PgpServices.VerifyClearTextSignatureReadInputLine(lineOut, lookAhead, sigIn);

                                sig.Update((byte)'\r');
                                sig.Update((byte)'\n');

                                PgpServices.ProcessLine(sig, lineOut.ToArray());
                            }

                            verified = sig.Verify();
                            sigIn.Close();
                        }
                        var ret = new PgpVerifyClearTextSignatureResult
                        {
                            FilePath = input.OutputFile,
                            Verified = verified
                        };

                        return(ret);
                    }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Create a file with PGP clear text signature. See documentation at https://github.com/CommunityHiQ/Frends.Community.PgpClearTextSignature Returns: Object {string FilePath}
        /// </summary>
        public static PgpClearTextSignatureResult ClearTextSignFile(PgpClearTextSignatureInput input)
        {
            HashAlgorithmTag digest;

            switch (input.HashFunction)
            {
            case PgpClearTextSignatureHashFunctionType.Md5:
                digest = HashAlgorithmTag.MD5;
                break;

            case PgpClearTextSignatureHashFunctionType.RipeMd160:
                digest = HashAlgorithmTag.RipeMD160;
                break;

            case PgpClearTextSignatureHashFunctionType.Sha1:
                digest = HashAlgorithmTag.Sha1;
                break;

            case PgpClearTextSignatureHashFunctionType.Sha224:
                digest = HashAlgorithmTag.Sha224;
                break;

            case PgpClearTextSignatureHashFunctionType.Sha384:
                digest = HashAlgorithmTag.Sha384;
                break;

            case PgpClearTextSignatureHashFunctionType.Sha512:
                digest = HashAlgorithmTag.Sha512;
                break;

            case PgpClearTextSignatureHashFunctionType.Sha256:
                digest = HashAlgorithmTag.Sha256;
                break;

            default:
                digest = HashAlgorithmTag.Sha256;
                break;
            }

            var privateKeyStream = File.OpenRead(input.PrivateKeyFile);

            var pgpSecKey  = PgpServices.ReadSecretKey(privateKeyStream);
            var pgpPrivKey = pgpSecKey.ExtractPrivateKey(input.Password.ToCharArray());
            var sGen       = new PgpSignatureGenerator(pgpSecKey.PublicKey.Algorithm, digest);
            var spGen      = new PgpSignatureSubpacketGenerator();

            sGen.InitSign(PgpSignature.CanonicalTextDocument, pgpPrivKey);

            var enumerator = pgpSecKey.PublicKey.GetUserIds().GetEnumerator();

            if (enumerator.MoveNext())
            {
                spGen.SetSignerUserId(false, (string)enumerator.Current);
                sGen.SetHashedSubpackets(spGen.Generate());
            }

            var fIn          = File.OpenRead(input.InputFile);
            var outputStream = File.Create(input.OutputFile);

            var aOut = new ArmoredOutputStream(outputStream);

            aOut.BeginClearText(digest);

            //
            // note the last \n/\r/\r\n in the file is ignored
            //
            var lineOut   = new MemoryStream();
            var lookAhead = PgpServices.ReadInputLine(lineOut, fIn);

            PgpServices.ProcessLine(aOut, sGen, lineOut.ToArray());

            while (lookAhead != -1)
            {
                lookAhead = PgpServices.ReadInputLine(lineOut, lookAhead, fIn);

                sGen.Update((byte)'\r');
                sGen.Update((byte)'\n');

                PgpServices.ProcessLine(aOut, sGen, lineOut.ToArray());
            }

            fIn.Close();

            aOut.EndClearText();

            var bOut = new BcpgOutputStream(aOut);

            sGen.Generate().Encode(bOut);

            aOut.Close();
            outputStream.Close();

            var ret = new PgpClearTextSignatureResult
            {
                FilePath = input.OutputFile
            };

            return(ret);
        }