Beispiel #1
0
        private PgpPublicKey GetPublicKeyByUserId(PgpPublicKeyRingBundle publicKeyRingBundle, String publicKeyUserId)
        {
            foreach (PgpPublicKeyRing kRing in publicKeyRingBundle.GetKeyRings())
            {
                PgpPublicKey key = kRing.GetPublicKeys()

                                   .Cast <PgpPublicKey>()

                                   .Where(k => k.IsEncryptionKey)

                                   .FirstOrDefault();


                if (key != null)
                {
                    foreach (String userId in key.GetUserIds())
                    {
                        if (userId.Contains(publicKeyUserId))
                        {
                            return(key);
                        }
                    }
                }
            }

            return(null);
        }
Beispiel #2
0
        public void AddKey(PgpPublicKey publicKey, bool nonErasable = false)
        {
            var fingerPrint = Tools.H16FP(publicKey.GetFingerprint().ToHexString());

            if (!publicKeys.ContainsKey(fingerPrint))
            {
                publicKeys[fingerPrint]          = publicKey;
                FP8TO16[Tools.H8FP(fingerPrint)] = fingerPrint;
                publicKeysInfo[fingerPrint]      = new KeyInfo {
                    FingerPrint         = fingerPrint,
                    Identifier          = publicKey.GetUserIds().Cast <string>().First(),
                    Bits                = publicKey.BitStrength,
                    ContainsPrivateKey  = false,
                    PrivateKeyDecrypted = false
                };
                if (!nonErasable)
                {
                    fingerPrints.Enqueue(fingerPrint);
                }
                if (Count > MaxCacheKeys)
                {
                    string fpToRemove = fingerPrints.Dequeue();
                    publicKeys.Remove(fpToRemove);
                    publicKeysInfo.Remove(fpToRemove);
                }
            }
        }
        /// <summary>
        /// Verify single signature against one pass signature.
        /// </summary>
        /// <param name="onePassSignature">
        /// The one pass signature.
        /// </param>
        /// <param name="publicKey">
        /// The public key for validating the signature.
        /// </param>
        /// <param name="signature">
        /// Signature to verify.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/> value indicating whether the signature was valid.
        /// </returns>
        private static bool VerifySingleSignatueAgainstOnePass(
            PgpOnePassSignature onePassSignature,
            PgpPublicKey publicKey,
            PgpSignature signature)
        {
            bool valid;

            if (onePassSignature.Verify(signature))
            {
                var userIds = publicKey.GetUserIds();
                foreach (var userId in userIds)
                {
                    Console.WriteLine($"Signed by {userId}");
                }

                Console.WriteLine("Signature verified");
                valid = true;
            }
            else
            {
                valid = false;
            }

            return(valid);
        }
Beispiel #4
0
 static void Main(string[] args)
 {
     using (Stream publicKeyStream = new FileStream(@"C:\inetpub\wwwroot\pgp\pgptest.asc", FileMode.Open))
     {
         PgpPublicKey pubKey = ReadPublicKey(publicKeyStream);
         var          UserId = pubKey.GetUserIds();
         var          KeyId  = pubKey.KeyId.ToString("X");
     }
 }
Beispiel #5
0
        /// <summary>
        /// Attempt to sign a PGP message using the specific private key.
        /// </summary>
        /// <param name="messageStream">Stream containing the message to sign.</param>
        /// <param name="signatureStream">Stream to write the signature into.</param>
        /// <param name="senderPublicKey">The BouncyCastle public key associated with the signature.</param>
        /// <param name="senderPrivateKey">The BouncyCastle private key to be used for signing.</param>
        /// <param name="hashAlgorithmTag">The hash algorithm tag to use for signing.</param>
        /// <param name="armor">Whether to wrap the message with ASCII armor.</param>
        /// <returns>Whether the signature completed successfully.</returns>
        public static bool Sign(Stream messageStream, Stream signatureStream, PgpPublicKey senderPublicKey, PgpPrivateKey senderPrivateKey, HashAlgorithmTag hashAlgorithmTag = HashAlgorithmTag.Sha256, bool armor = true)
        {
            // Create a signature generator.
            PgpSignatureGenerator signatureGenerator = new PgpSignatureGenerator(senderPublicKey.Algorithm, hashAlgorithmTag);

            signatureGenerator.InitSign(PgpSignature.BinaryDocument, senderPrivateKey);

            // Add the public key user ID.
            foreach (string userId in senderPublicKey.GetUserIds())
            {
                PgpSignatureSubpacketGenerator signatureSubGenerator = new PgpSignatureSubpacketGenerator();
                signatureSubGenerator.SetSignerUserId(false, userId);
                signatureGenerator.SetHashedSubpackets(signatureSubGenerator.Generate());
                break;
            }

            // Handle ASCII armor.
            if (armor)
            {
                using (ArmoredOutputStream armoredStream = new ArmoredOutputStream(signatureStream))
                {
                    armoredStream.BeginClearText(hashAlgorithmTag);

                    // Process each character in the message.
                    int messageChar;
                    while ((messageChar = messageStream.ReadByte()) >= 0)
                    {
                        armoredStream.WriteByte((byte)messageChar);
                        signatureGenerator.Update((byte)messageChar);
                    }

                    armoredStream.EndClearText();

                    using (BcpgOutputStream bcpgStream = new BcpgOutputStream(armoredStream))
                    {
                        signatureGenerator.Generate().Encode(bcpgStream);
                    }
                }
            }
            else
            {
                // Process each character in the message.
                int messageChar;
                while ((messageChar = messageStream.ReadByte()) >= 0)
                {
                    signatureGenerator.Update((byte)messageChar);
                }

                signatureGenerator.Generate().Encode(signatureStream);
            }

            return(true);
        }
        private void Load(PgpPublicKey key)
        {
            this.KeyId = key.KeyId.ToString("X");
            if (this.KeyId != null && this.KeyId.Length >= 15)
            {
                this.KeyIdShort = this.KeyId.Substring(this.KeyId.Length - 8);
            }
            this.Algorithm       = key.Algorithm.ToString();
            this.BitStrength     = key.BitStrength;
            this.IsMasterKey     = key.IsMasterKey;
            this.IsEncryptionKey = key.IsEncryptionKey;
            this.Version         = key.Version;
            this.CreatedOnUtc    = key.CreationTime.ToUniversalTime();

            var validForSeconds = key.GetValidSeconds();

            if (validForSeconds > 0)
            {
                this.Expires = this.CreatedOnUtc.Value.AddSeconds(validForSeconds);
            }

            //this.ValidDays = key.ValidDays;
            //if (this.ValidDays.HasValue)
            //{
            //    this.Expires = this.CreatedOnUtc.Value.AddDays(this.ValidDays.Value);
            //}
            //else
            //{
            //    this.Expires = null;
            //}

            try
            {
                var userIds = key.GetUserIds();
                if (userIds != null)
                {
                    var enumerator = userIds.GetEnumerator();
                    if (enumerator.MoveNext())
                    {
                        var userIdentity = enumerator.Current as string;
                        if (userIdentity != null && userIdentity.Contains("<") && userIdentity.Contains(">"))
                        {
                            var name = userIdentity.Substring(0, userIdentity.IndexOf("<") - 1).Trim();
                            this.IdentityName = name;
                            var email = userIdentity.Substring(userIdentity.IndexOf("<") + 1);
                            email = email.Substring(0, email.IndexOf(">")).Trim();
                            this.IdentityEmail = email;
                        }
                    }
                }
            }
            catch { }
        }
Beispiel #7
0
        /*
         * Checks to see if public key matches filter and returns true if so.
         */
        internal static bool IsMatch(PgpPublicKey key, List <string> filters, bool matchUserIds)
        {
            // Checking if there are no filters, at which point we return everything.
            if (filters.Count == 0)
            {
                return(true);
            }

            // Looping through each filter.
            foreach (var filter in filters)
            {
                // Checking fingerprint.
                var fingerprint = Fingerprint.FingerprintString(key.GetFingerprint());
                if (fingerprint == filter)
                {
                    return(true);
                }

                // Checking key ID.
                var keyID = ((int)key.KeyId).ToString("X").ToLower();
                if (keyID == filter)
                {
                    return(true);
                }

                // Checking if caller wants to match user IDs.
                if (matchUserIds)
                {
                    // Iterating all user IDs.
                    foreach (var idxUserID in key.GetUserIds())
                    {
                        // Checking if user ID is a string, and if so, checking for a match.
                        var userID = idxUserID as string;
                        if (userID != null)
                        {
                            // Checking if currently iterated userID contains specified filter.
                            if (userID.ToLower().Contains(filter))
                            {
                                return(true);
                            }
                        }
                    }
                }
            }

            // No match.
            return(false);
        }
        internal OpenPgpDigitalCertificate(PgpPublicKey pubkey)
        {
            var data    = pubkey.GetFingerprint();
            var builder = new StringBuilder();

            for (int i = 0; i < data.Length; i++)
            {
                builder.Append(data[i].ToString("X"));
            }

            var trust = pubkey.GetTrustData();

            if (trust != null)
            {
                TrustLevel = (TrustLevel)(trust[0] & 15);
            }
            else
            {
                TrustLevel = TrustLevel.None;
            }

            Fingerprint = builder.ToString();
            PublicKey   = pubkey;

            foreach (string userId in pubkey.GetUserIds())
            {
                data = Encoding.UTF8.GetBytes(userId);
                InternetAddress address;
                int             index = 0;

                if (!InternetAddress.TryParse(ParserOptions.Default, data, ref index, data.Length, false, out address))
                {
                    continue;
                }

                Name = address.Name;

                var mailbox = address as MailboxAddress;
                if (mailbox == null)
                {
                    continue;
                }

                Email = mailbox.Address;
                break;
            }
        }
        private PgpSignatureGenerator createSignatureGenerator()
        {
            PgpPrivateKey         privateKey         = secretKey.ExtractPrivateKey(password);
            PgpPublicKey          internalPublicKey  = secretKey.PublicKey;
            PgpSignatureGenerator signatureGenerator = new PgpSignatureGenerator(internalPublicKey.Algorithm, HashAlgorithmTag.Sha1);

            signatureGenerator.InitSign(PgpSignature.BinaryDocument, privateKey);
            var userIds = internalPublicKey.GetUserIds();

            foreach (var userId in userIds)
            {
                PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator();
                spGen.SetSignerUserId(false, (String)userId);
                signatureGenerator.SetHashedSubpackets(spGen.Generate());
                break;
            }
            return(signatureGenerator);
        }
        bool UpdateUserId(PgpPublicKey pubkey)
        {
            foreach (string userId in pubkey.GetUserIds())
            {
                var            bytes = Encoding.UTF8.GetBytes(userId);
                MailboxAddress mailbox;
                int            index = 0;

                if (!MailboxAddress.TryParse(ParserOptions.Default, bytes, ref index, bytes.Length, false, out mailbox))
                {
                    continue;
                }

                Email = mailbox.Address;
                Name  = mailbox.Name;
                return(true);
            }

            return(false);
        }
        internal static void InvokeLambda(
            ISignaler signaler,
            Node lambda,
            PgpPublicKey key)
        {
            // Parametrizing [.lambda] callback with key and data.
            var keyNode = new Node(".key");

            keyNode.Add(new Node("private", false));
            keyNode.Add(new Node("fingerprint", PgpHelpers.GetFingerprint(key)));
            keyNode.Add(new Node("id", key.KeyId));
            keyNode.Add(new Node("content", PgpHelpers.GetAsciiArmoredPublicKey(key)));
            keyNode.Add(new Node("created", key.CreationTime));
            keyNode.Add(new Node("valid-seconds", key.GetValidSeconds()));
            keyNode.Add(new Node("algorithm", key.Algorithm.ToString()));
            keyNode.Add(new Node("bit-strength", key.BitStrength));
            keyNode.Add(new Node("is-encryption", key.IsEncryptionKey));
            keyNode.Add(new Node("is-master", key.IsMasterKey));
            keyNode.Add(new Node("is-revoked", key.IsRevoked()));

            // Adding ID for key.
            var ids = new Node("ids");

            foreach (var idxId in key.GetUserIds())
            {
                ids.Add(new Node(".", idxId.ToString()));
            }
            if (ids.Children.Any())
            {
                keyNode.Add(ids);
            }

            // Invoking [.lambda] making sure we reset it after evaluation.
            var exe = lambda.Clone();

            lambda.Insert(0, keyNode);
            signaler.Signal("eval", lambda);
            lambda.Clear();
            lambda.AddRange(exe.Children.ToList());
        }
        /*
         * Checks to see if public key matches filter and returns true if so.
         */
        internal static bool IsMatch(PgpPublicKey key, string filter, bool matchUserID = true)
        {
            // Checking fingerprint.
            var fingerprint = BitConverter.ToString(key.GetFingerprint()).Replace("-", "").ToLower();

            if (fingerprint == filter.ToLower())
            {
                return(true);
            }

            // Checking keyID.
            var keyID = ((int)key.KeyId).ToString("X").ToLower();

            if (keyID == filter.ToLower())
            {
                return(true);
            }

            // Enumerating user IDs for key, but only if caller has specified we should search in UserIDs.
            if (matchUserID)
            {
                // Enumerating UerIDs looking for a match.
                foreach (var idxUserID in key.GetUserIds())
                {
                    // Checking if user ID is a string, and if so, checking for a match.
                    var userID = idxUserID as string;
                    if (userID != null)
                    {
                        // Checking if currently iterated userID contains specified filter.
                        if (userID.ToLower().Contains(filter))
                        {
                            return(true);
                        }
                    }
                }
            }

            // No match!
            return(false);
        }
        /// <summary>
        /// Sign public key with secret key. To access the private key from the
        /// secret container a password needs to be provided.
        /// </summary>
        /// <param name="secretKey">
        /// The secret key containing the private key for signing the public
        /// key.
        /// </param>
        /// <param name="password">
        /// The password of the secret key.
        /// </param>
        /// <param name="keyToBeSigned">
        /// The public key to be signed.
        /// </param>
        /// <param name="certain">
        /// Flag indicating whether or not the certification is positive or just
        /// casual.
        /// </param>
        /// <returns>
        /// Returns the <see cref="PgpPublicKey"/> adorned with a signature by the
        /// private key passed in.
        /// </returns>
        public static PgpPublicKey SignPublicKey(
            PgpSecretKey secretKey,
            string password,
            PgpPublicKey keyToBeSigned,
            bool certain)
        {
            var id = keyToBeSigned.GetUserIds().Cast <string>().FirstOrDefault();

            // Extracting private key, and getting ready to create a signature.
            var privateKey         = secretKey.ExtractPrivateKey(password.ToCharArray());
            var signatureGenerator = new PgpSignatureGenerator(secretKey.PublicKey.Algorithm, HashAlgorithmTag.Sha256);

            signatureGenerator.InitSign(
                certain ? PgpSignature.PositiveCertification : PgpSignature.CasualCertification,
                privateKey);

            // Creating a stream to wrap the results of operation.
            var outputStream       = new MemoryStream();
            var packetOutputStream = new BcpgOutputStream(outputStream);

            signatureGenerator.GenerateOnePassVersion(false).Encode(packetOutputStream);

            // Creating a generator.
            var subpacketSignatureGenerator = new PgpSignatureSubpacketGenerator();

            subpacketSignatureGenerator.SetSignerUserId(false, id);
            var packetVector = subpacketSignatureGenerator.Generate();

            signatureGenerator.SetHashedSubpackets(packetVector);
            packetOutputStream.Flush();

            // Returning the signed public key.
            return(PgpPublicKey.AddCertification(
                       keyToBeSigned,
                       id,
                       signatureGenerator.GenerateCertification(id, keyToBeSigned)));
        }
        public static string EncryptAndSign(
            Stream messageStream,
            string publicKeyIn,
            string privateKeyIn,
            string passPhrase,
            out Stream outputStream)
        {
            PgpPublicKey  senderPublicKey  = ReadPublicKey(publicKeyIn);
            PgpPrivateKey senderPrivateKey = ReadPrivateKey(privateKeyIn, passPhrase);

            outputStream = new MemoryStream();

            // Create a signature generator.
            PgpSignatureGenerator signatureGenerator = new PgpSignatureGenerator(senderPublicKey.Algorithm, HashAlgorithmTag.Sha256);

            signatureGenerator.InitSign(PgpSignature.BinaryDocument, senderPrivateKey);

            // Add the public key user ID.
            foreach (string userId in senderPublicKey.GetUserIds())
            {
                PgpSignatureSubpacketGenerator signatureSubGenerator = new PgpSignatureSubpacketGenerator();
                signatureSubGenerator.SetSignerUserId(false, userId);
                signatureGenerator.SetHashedSubpackets(signatureSubGenerator.Generate());
                break;
            }

            // Allow any of the corresponding keys to be used for decryption.
            PgpEncryptedDataGenerator encryptedDataGenerator = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.TripleDes, true, new SecureRandom());

            encryptedDataGenerator.AddMethod(senderPublicKey);


            using (Stream armoredStream = new ArmoredOutputStream(outputStream))
            {
                using (Stream encryptedStream = encryptedDataGenerator.Open(armoredStream, new byte[0x10000]))
                {
                    PgpCompressedDataGenerator compressedDataGenerator = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Uncompressed);
                    using (Stream compressedStream = compressedDataGenerator.Open(encryptedStream))
                    {
                        signatureGenerator.GenerateOnePassVersion(false).Encode(compressedStream);

                        PgpLiteralDataGenerator literalDataGenerator = new PgpLiteralDataGenerator();
                        using (Stream literalStream = literalDataGenerator.Open(compressedStream, PgpLiteralData.Binary,
                                                                                PgpLiteralData.Console, DateTime.Now, new byte[0x10000]))
                        {
                            // Process each character in the message.
                            int messageChar;
                            while ((messageChar = messageStream.ReadByte()) >= 0)
                            {
                                literalStream.WriteByte((byte)messageChar);
                                signatureGenerator.Update((byte)messageChar);
                            }
                        }

                        signatureGenerator.Generate().Encode(compressedStream);
                    }
                }
            }

            byte[] signedAndEncryptedMessageBuffer = (outputStream as MemoryStream).ToArray();

            Console.WriteLine(Encoding.ASCII.GetString(signedAndEncryptedMessageBuffer));
            return(Encoding.ASCII.GetString(signedAndEncryptedMessageBuffer));
        }
Beispiel #15
0
        public int ImportPublicKey(string fileName, string filePath, KeyStoreDB keyStoreDB)
        {
            int          cntImport         = 0;
            string       keyPath           = Path.Combine(filePath, fileName);
            string       stringFileContent = File.ReadAllText(keyPath);
            PgpPublicKey pubKey            = ReadPublicKey(keyPath);

            try {
                keyStoreDB.KeyStores.Add(new KeyStores()
                {
                    KeyStoreID      = pubKey.KeyId,
                    ArmouredKeyFile = stringFileContent,
                    Fingerprint     = pubKey.GetFingerprint(),
                    CreationTime    = pubKey.CreationTime,
                    ValidDays       = pubKey.ValidDays,
                    IsEncryptionKey = pubKey.IsEncryptionKey,
                    IsMasterKey     = pubKey.IsMasterKey,
                    IsSigningKey    = false,
                    IsRevoked       = pubKey.IsRevoked(),
                    KeyType         = "Public"
                });
                IEnumerable userIDs = pubKey.GetUserIds();
                foreach (string userId in userIDs)
                {
                    Match match = Regex.Match(userId, strRegex, RegexOptions.Compiled);
                    if (match != null)
                    {
                        string comment1 = match.Groups["comment1"] != null ? match.Groups["comment1"].Value : string.Empty;
                        string comment2 = match.Groups["comment2"] != null ? match.Groups["comment2"].Value : string.Empty;
                        if (!string.IsNullOrEmpty(comment2))
                        {
                            comment1 += " " + comment2;
                        }
                        KeyUsers userExists = keyStoreDB.KeyUsers.Find(pubKey.KeyId);
                        if (userExists != null)
                        {
                            keyStoreDB.KeyUsers.Remove(userExists);
                            keyStoreDB.SaveChanges();
                        }
                        keyStoreDB.KeyUsers.Add(new KeyUsers()
                        {
                            KeyStoreID     = pubKey.KeyId,
                            UserName       = match.Groups["user"] != null ? match.Groups["user"].Value : string.Empty,
                            Email          = match.Groups["email"] != null ? match.Groups["email"].Value : string.Empty,
                            Comment        = comment1,
                            EncryptionType = ((PublicKeyAlgorithmTag)pubKey.Algorithm).ToString(),
                            KeySize        = pubKey.BitStrength
                        });
                    }
                }
                keyStoreDB.SaveChanges();
            }
            catch (DbUpdateConcurrencyException dbConEx) {
                throw new DbUpdateConcurrencyException(dbConEx.Message);
            }
            catch (DbUpdateException dbEx) {
                throw new DbUpdateException(dbEx.Message);
            }
            catch (Exception ex) {
                throw new Exception(ex.Message);
            }
            return(++cntImport);
        }
Beispiel #16
0
        public void PerformTest()
        {
            //
            // Read the public key
            //
            PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(testPubKey);

            var firstUserId = pgpPub.GetPublicKey().GetUserIds().FirstOrDefault();

            Assert.NotNull(firstUserId);
            Assert.AreEqual(1, firstUserId.SelfCertifications.Count);
            Assert.IsTrue(firstUserId.SelfCertifications[0].Verify());

            //
            // write a public key
            //
            MemoryStream bOut = new MemoryStream();

            pgpPub.Encode(bOut);
            Assert.AreEqual(testPubKey, bOut.ToArray());

            //
            // Read the public key
            //
            PgpPublicKeyRing pgpPubV3 = new PgpPublicKeyRing(testPubKeyV3);

            //
            // write a V3 public key
            //
            bOut = new MemoryStream();

            pgpPubV3.Encode(bOut);

            //
            // Read a v3 private key
            //
            var passP = "FIXCITY_QA";

            {
                PgpSecretKeyRing pgpPriv2         = new PgpSecretKeyRing(testPrivKeyV3);
                PgpSecretKey     pgpPrivSecretKey = pgpPriv2.GetSecretKey();
                PgpPrivateKey    pgpPrivKey2      = pgpPrivSecretKey.ExtractPrivateKey(passP);

                //
                // write a v3 private key
                //
                bOut = new MemoryStream();
                pgpPriv2.Encode(bOut);
                byte[] result = bOut.ToArray();
                Assert.AreEqual(testPrivKeyV3, result);
            }

            //
            // Read the private key
            //
            PgpSecretKeyRing pgpPriv    = new PgpSecretKeyRing(testPrivKey);
            PgpPrivateKey    pgpPrivKey = pgpPriv.GetSecretKey().ExtractPrivateKey(pass);

            //
            // write a private key
            //
            bOut = new MemoryStream();
            pgpPriv.Encode(bOut);
            Assert.AreEqual(testPrivKey, bOut.ToArray());

            //
            // test encryption
            //

            /*var c = pubKey;
             *
             * //                c.Init(Cipher.ENCRYPT_MODE, pubKey);
             *
             * byte[] inBytes = Encoding.ASCII.GetBytes("hello world");
             * byte[] outBytes = c.DoFinal(inBytes);
             *
             * //                c.Init(Cipher.DECRYPT_MODE, pgpPrivKey.GetKey());
             * c.Init(false, pgpPrivKey.Key);
             *
             * outBytes = c.DoFinal(outBytes);
             *
             * if (!Arrays.AreEqual(inBytes, outBytes))
             * {
             *  Fail("decryption failed.");
             * }*/

            //
            // test signature message
            //
            var compressedMessage = (PgpCompressedMessage)PgpMessage.ReadMessage(sig1);
            var signedMessage     = (PgpSignedMessage)compressedMessage.ReadMessage();
            var literalMessage    = (PgpLiteralMessage)signedMessage.ReadMessage();

            literalMessage.GetStream().CopyTo(Stream.Null);
            Assert.True(signedMessage.Verify(pgpPub.GetPublicKey(signedMessage.KeyId)));

            //
            // encrypted message - read subkey
            //
            pgpPriv = new PgpSecretKeyRing(subKey);

            //
            // encrypted message
            //
            byte[] text             = Encoding.ASCII.GetBytes("hello world!\n");
            var    encryptedMessage = (PgpEncryptedMessage)PgpMessage.ReadMessage(enc1);

            var encKeyId = encryptedMessage.KeyIds.First();

            pgpPrivKey        = pgpPriv.GetSecretKey(encKeyId).ExtractPrivateKey(pass);
            compressedMessage = (PgpCompressedMessage)encryptedMessage.DecryptMessage(pgpPrivKey);
            literalMessage    = (PgpLiteralMessage)compressedMessage.ReadMessage();
            Assert.AreEqual("test.txt", literalMessage.FileName);
            byte[] bytes = Streams.ReadAll(literalMessage.GetStream());
            Assert.AreEqual(text, bytes);

            //
            // encrypt - short message
            //
            byte[] shortText = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o' };

            MemoryStream cbOut = new MemoryStream();

            var messageGenerator = new PgpMessageGenerator(cbOut);

            using (var encryptedGenerator = messageGenerator.CreateEncrypted(PgpSymmetricKeyAlgorithm.Cast5))
            {
                encryptedGenerator.AddMethod(pgpPriv.GetSecretKey(encKeyId));
                using (var literalStream = encryptedGenerator.CreateLiteral(PgpDataFormat.Binary, "", DateTime.UtcNow))
                {
                    literalStream.Write(shortText);
                }
            }

            cbOut.Position   = 0;
            encryptedMessage = (PgpEncryptedMessage)PgpMessage.ReadMessage(cbOut);
            pgpPrivKey       = pgpPriv.GetSecretKey(encryptedMessage.KeyIds.First()).ExtractPrivateKey(pass);
            //Assert.AreEqual(SymmetricKeyAlgorithmTag.Cast5, ((PgpPublicKeyEncryptedData)encryptedMessage.Methods[0]).GetSymmetricAlgorithm(pgpPrivKey));
            literalMessage = (PgpLiteralMessage)encryptedMessage.DecryptMessage(pgpPrivKey);
            Assert.AreEqual("", literalMessage.FileName);
            bytes = Streams.ReadAll(literalMessage.GetStream());
            Assert.AreEqual(shortText, bytes);

            //
            // encrypt
            //
            cbOut = new MemoryStream();

            messageGenerator = new PgpMessageGenerator(cbOut);
            using (var encryptedGenerator = messageGenerator.CreateEncrypted(PgpSymmetricKeyAlgorithm.Cast5))
            {
                encryptedGenerator.AddMethod(pgpPriv.GetSecretKey(encKeyId));
                using (var literalStream = encryptedGenerator.CreateLiteral(PgpDataFormat.Binary, "", DateTime.UtcNow))
                {
                    literalStream.Write(text);
                }
            }

            cbOut.Position   = 0;
            encryptedMessage = (PgpEncryptedMessage)PgpMessage.ReadMessage(cbOut);
            pgpPrivKey       = pgpPriv.GetSecretKey(encryptedMessage.KeyIds.First()).ExtractPrivateKey(pass);
            literalMessage   = (PgpLiteralMessage)encryptedMessage.DecryptMessage(pgpPrivKey);
            bytes            = Streams.ReadAll(literalMessage.GetStream());
            Assert.AreEqual(text, bytes);

            //
            // read public key with sub key.
            //

            /*pgpF = new PgpObjectFactory(subPubKey);
             * object o;
             * while ((o = pgpFact.NextPgpObject()) != null)
             * {
             *  // TODO Should something be tested here?
             *  // Console.WriteLine(o);
             * }*/

            //
            // key pair generation - CAST5 encryption
            //
            var passPhrase = "hello";
            var rsa        = RSA.Create(1024);

            var keyRingGenerator = new PgpKeyRingGenerator(rsa, "fred", passPhrase);

            var secretKey = keyRingGenerator.GenerateSecretKeyRing().GetSecretKey();

            PgpPublicKey key = new PgpPublicKey(secretKey);

            firstUserId = key.GetUserIds().FirstOrDefault();
            Assert.NotNull(firstUserId);
            Assert.AreEqual(1, firstUserId.SelfCertifications.Count);
            Assert.IsTrue(firstUserId.SelfCertifications[0].Verify());

            pgpPrivKey = secretKey.ExtractPrivateKey(passPhrase);

            key = PgpPublicKey.RemoveCertification(key, firstUserId, firstUserId.SelfCertifications[0]);
            Assert.NotNull(key);

            byte[] keyEnc = key.GetEncoded();

            key = PgpPublicKey.AddCertification(key, firstUserId.UserId, firstUserId.SelfCertifications[0]);

            keyEnc = key.GetEncoded();

            var revocation = PgpCertification.GenerateKeyRevocation(
                secretKey,
                secretKey.ExtractPrivateKey(passPhrase),
                key);

            key = PgpPublicKey.AddCertification(key, revocation);

            keyEnc = key.GetEncoded();

            PgpPublicKeyRing tmpRing = new PgpPublicKeyRing(keyEnc);

            key = tmpRing.GetPublicKey();

            revocation = key.KeyCertifications.Where(c => c.SignatureType == PgpSignatureType.KeyRevocation).FirstOrDefault();
            Assert.NotNull(revocation);
            Assert.IsTrue(revocation.Verify(key));

            //
            // use of PgpKeyPair
            //
            PgpKeyPair pgpKp = new PgpKeyPair(rsa, DateTime.UtcNow);

            PgpPublicKey  k1 = pgpKp.PublicKey;
            PgpPrivateKey k2 = pgpKp.PrivateKey;

            k1.GetEncoded();

            MixedTest(k2, k1);

            //
            // key pair generation - AES_256 encryption. -- XXX
            //
            //kp = kpg.GenerateKeyPair();
            rsa = RSA.Create(1024);

            keyRingGenerator = new PgpKeyRingGenerator(rsa, "fred", passPhrase /*, encAlgorithm: PgpSymmetricKeyAlgorithm.Aes256*/);

            secretKey = keyRingGenerator.GenerateSecretKeyRing().GetSecretKey();

            secretKey.ExtractPrivateKey(passPhrase);

            secretKey.Encode(new MemoryStream());

            //
            // secret key password changing.
            //
            const string newPass = "******";

            secretKey = PgpSecretKey.CopyWithNewPassword(secretKey, passPhrase, newPass);

            secretKey.ExtractPrivateKey(newPass);

            secretKey.Encode(new MemoryStream());

            key = new PgpPublicKey(secretKey);

            key.Encode(new MemoryStream());

            firstUserId = key.GetUserIds().FirstOrDefault();
            Assert.NotNull(firstUserId);
            Assert.AreEqual(1, firstUserId.SelfCertifications.Count);
            Assert.IsTrue(firstUserId.SelfCertifications[0].Verify());

            pgpPrivKey = secretKey.ExtractPrivateKey(newPass);

            //
            // signature generation
            //
            const string data = "hello world!";

            byte[]   dataBytes    = Encoding.ASCII.GetBytes(data);
            DateTime testDateTime = new DateTime(1973, 7, 27);

            bOut             = new MemoryStream();
            messageGenerator = new PgpMessageGenerator(bOut);
            using (var compressedGenerator = messageGenerator.CreateCompressed(PgpCompressionAlgorithm.Zip))
                using (var signingGenerator = compressedGenerator.CreateSigned(PgpSignatureType.BinaryDocument, pgpPrivKey, PgpHashAlgorithm.Sha1))
                    using (var literalStream = signingGenerator.CreateLiteral(PgpDataFormat.Binary, "_CONSOLE", testDateTime))
                    {
                        literalStream.Write(dataBytes);
                    }

            //
            // verify generated signature
            //
            bOut.Position     = 0;
            compressedMessage = (PgpCompressedMessage)PgpMessage.ReadMessage(bOut);
            signedMessage     = (PgpSignedMessage)compressedMessage.ReadMessage();
            literalMessage    = (PgpLiteralMessage)signedMessage.ReadMessage();
            Assert.AreEqual(testDateTime, literalMessage.ModificationTime);
            literalMessage.GetStream().CopyTo(Stream.Null);
            Assert.IsTrue(signedMessage.Verify(secretKey));

            //
            // signature generation - version 3
            //
            bOut             = new MemoryStream();
            messageGenerator = new PgpMessageGenerator(bOut);
            using (var compressedGenerator = messageGenerator.CreateCompressed(PgpCompressionAlgorithm.Zip))
                using (var signingGenerator = compressedGenerator.CreateSigned(PgpSignatureType.BinaryDocument, pgpPrivKey, PgpHashAlgorithm.Sha1, version: 3))
                    using (var literalStream = signingGenerator.CreateLiteral(PgpDataFormat.Binary, "_CONSOLE", testDateTime))
                    {
                        literalStream.Write(dataBytes);
                    }

            //
            // verify generated signature
            //
            bOut.Position     = 0;
            compressedMessage = (PgpCompressedMessage)PgpMessage.ReadMessage(bOut);
            signedMessage     = (PgpSignedMessage)compressedMessage.ReadMessage();
            literalMessage    = (PgpLiteralMessage)signedMessage.ReadMessage();
            Assert.AreEqual(testDateTime, literalMessage.ModificationTime);
            literalMessage.GetStream().CopyTo(Stream.Null);
            Assert.IsTrue(signedMessage.Verify(secretKey));

            //
            // extract PGP 8 private key
            //
            pgpPriv = new PgpSecretKeyRing(pgp8Key);

            secretKey = pgpPriv.GetSecretKey();

            pgpPrivKey = secretKey.ExtractPrivateKey(pgp8Pass);

            //
            // other sig tests
            //
            PerformTestSig(PgpHashAlgorithm.Sha256, secretKey, pgpPrivKey);
            PerformTestSig(PgpHashAlgorithm.Sha384, secretKey, pgpPrivKey);
            PerformTestSig(PgpHashAlgorithm.Sha512, secretKey, pgpPrivKey);
        }
Beispiel #17
0
        /// <summary>
        /// Attempt to encrypt a message using PGP with the specified public key(s).
        /// </summary>
        /// <param name="messageStream">Stream containing the message to encrypt.</param>
        /// <param name="fileName">File name of for the message.</param>
        /// <param name="signedAndEncryptedMessageStream">Stream to write the encrypted message into.</param>
        /// <param name="senderPublicKey">The BouncyCastle public key associated with the signature.</param>
        /// <param name="senderPrivateKey">The BouncyCastle private key to be used for signing.</param>
        /// <param name="recipientPublicKeys">Collection of BouncyCastle public keys to be used for encryption.</param>
        /// <param name="hashAlgorithmTag">The hash algorithm tag to use for signing.</param>
        /// <param name="symmetricKeyAlgorithmTag">The symmetric key algorithm tag to use for encryption.</param>
        /// <param name="armor">Whether to wrap the message with ASCII armor.</param>
        /// <returns>Whether the encryption completed successfully.</returns>
        public static bool SignAndEncrypt(Stream messageStream, string fileName, Stream signedAndEncryptedMessageStream, PgpPublicKey senderPublicKey, PgpPrivateKey senderPrivateKey, IEnumerable <PgpPublicKey> recipientPublicKeys, HashAlgorithmTag hashAlgorithmTag = HashAlgorithmTag.Sha256, SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag = SymmetricKeyAlgorithmTag.TripleDes, bool armor = true)
        {
            // Create a signature generator.
            PgpSignatureGenerator signatureGenerator = new PgpSignatureGenerator(senderPublicKey.Algorithm, hashAlgorithmTag);

            signatureGenerator.InitSign(PgpSignature.BinaryDocument, senderPrivateKey);

            // Add the public key user ID.
            foreach (string userId in senderPublicKey.GetUserIds())
            {
                PgpSignatureSubpacketGenerator signatureSubGenerator = new PgpSignatureSubpacketGenerator();
                signatureSubGenerator.SetSignerUserId(false, userId);
                signatureGenerator.SetHashedSubpackets(signatureSubGenerator.Generate());
                break;
            }

            // Allow any of the corresponding keys to be used for decryption.
            PgpEncryptedDataGenerator encryptedDataGenerator = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.TripleDes, true, new SecureRandom());

            foreach (PgpPublicKey publicKey in recipientPublicKeys)
            {
                encryptedDataGenerator.AddMethod(publicKey);
            }

            // Handle optional ASCII armor.
            if (armor)
            {
                using (Stream armoredStream = new ArmoredOutputStream(signedAndEncryptedMessageStream))
                {
                    using (Stream encryptedStream = encryptedDataGenerator.Open(armoredStream, new byte[Constants.LARGEBUFFERSIZE]))
                    {
                        PgpCompressedDataGenerator compressedDataGenerator = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Uncompressed);
                        using (Stream compressedStream = compressedDataGenerator.Open(encryptedStream))
                        {
                            signatureGenerator.GenerateOnePassVersion(false).Encode(compressedStream);

                            PgpLiteralDataGenerator literalDataGenerator = new PgpLiteralDataGenerator();
                            using (Stream literalStream = literalDataGenerator.Open(compressedStream, PgpLiteralData.Binary,
                                                                                    fileName, DateTime.Now, new byte[Constants.LARGEBUFFERSIZE]))
                            {
                                // Process each character in the message.
                                int messageChar;
                                while ((messageChar = messageStream.ReadByte()) >= 0)
                                {
                                    literalStream.WriteByte((byte)messageChar);
                                    signatureGenerator.Update((byte)messageChar);
                                }
                            }

                            signatureGenerator.Generate().Encode(compressedStream);
                        }
                    }
                }
            }
            else
            {
                using (Stream encryptedStream = encryptedDataGenerator.Open(signedAndEncryptedMessageStream, new byte[Constants.LARGEBUFFERSIZE]))
                {
                    PgpCompressedDataGenerator compressedDataGenerator = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Uncompressed);
                    using (Stream compressedStream = compressedDataGenerator.Open(encryptedStream))
                    {
                        signatureGenerator.GenerateOnePassVersion(false).Encode(compressedStream);

                        PgpLiteralDataGenerator literalDataGenerator = new PgpLiteralDataGenerator();
                        using (Stream literalStream = literalDataGenerator.Open(compressedStream, PgpLiteralData.Binary,
                                                                                fileName, DateTime.Now, new byte[Constants.LARGEBUFFERSIZE]))
                        {
                            // Process each character in the message.
                            int messageChar;
                            while ((messageChar = messageStream.ReadByte()) >= 0)
                            {
                                literalStream.WriteByte((byte)messageChar);
                                signatureGenerator.Update((byte)messageChar);
                            }
                        }

                        signatureGenerator.Generate().Encode(compressedStream);
                    }
                }
            }

            return(true);
        }