/// <summary> /// Return a copy of the passed in secret key, encrypted using a new password /// and the passed in algorithm. /// </summary> /// <param name="key">The PgpSecretKey to be copied.</param> /// <param name="oldPassPhrase">The current password for the key.</param> /// <param name="newPassPhrase">The new password for the key.</param> /// <param name="newEncAlgorithm">The algorithm to be used for the encryption.</param> /// <param name="rand">Source of randomness.</param> public static PgpSecretKey CopyWithNewPassword(IPgpSecretKey key, char[] oldPassPhrase, char[] newPassPhrase, SymmetricKeyAlgorithmTag newEncAlgorithm, SecureRandom rand) { var rawKeyData = key.ExtractKeyData(oldPassPhrase); var s2KUsage = key.SecretPacket.S2KUsage; byte[] iv = null; S2k s2K = null; byte[] keyData; if (newEncAlgorithm == SymmetricKeyAlgorithmTag.Null) { s2KUsage = SecretKeyPacket.UsageNone; if (key.SecretPacket.S2KUsage == SecretKeyPacket.UsageSha1) // SHA-1 hash, need to rewrite Checksum { keyData = new byte[rawKeyData.Length - 18]; Array.Copy(rawKeyData, 0, keyData, 0, keyData.Length - 2); var check = Checksum(false, keyData, keyData.Length - 2); keyData[keyData.Length - 2] = check[0]; keyData[keyData.Length - 1] = check[1]; } else { keyData = rawKeyData; } } else { try { keyData = EncryptKeyData(rawKeyData, newEncAlgorithm, newPassPhrase, rand, out s2K, out iv); } catch (PgpException) { throw; } catch (Exception e) { throw new PgpException("Exception encrypting key", e); } } SecretKeyPacket secret; if (key.SecretPacket is SecretSubkeyPacket) { secret = new SecretSubkeyPacket(key.SecretPacket.PublicKeyPacket, newEncAlgorithm, s2KUsage, s2K, iv, keyData); } else { secret = new SecretKeyPacket(key.SecretPacket.PublicKeyPacket, newEncAlgorithm, s2KUsage, s2K, iv, keyData); } return(new PgpSecretKey(secret, key.PublicKey)); }
/// <summary>Replace the passed public key on the passed in secret key.</summary> /// <param name="secretKey">Secret key to change.</param> /// <param name="publicKey">New public key.</param> /// <returns>A new secret key.</returns> /// <exception cref="ArgumentException">If KeyId's do not match.</exception> public static IPgpSecretKey ReplacePublicKey(IPgpSecretKey secretKey, IPgpPublicKey publicKey) { if (publicKey.KeyId != secretKey.KeyId) { throw new ArgumentException("KeyId's do not match"); } return(new PgpSecretKey(secretKey.SecretPacket, publicKey)); }
private void generateTest( string message, string type) { IPgpSecretKey pgpSecKey = ReadSecretKey(new MemoryStream(secretKey)); IPgpPrivateKey pgpPrivKey = pgpSecKey.ExtractPrivateKey("".ToCharArray()); PgpSignatureGenerator sGen = new PgpSignatureGenerator(pgpSecKey.PublicKey.Algorithm, HashAlgorithmTag.Sha256); PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator(); sGen.InitSign(PgpSignature.CanonicalTextDocument, pgpPrivKey); IEnumerator it = pgpSecKey.PublicKey.GetUserIds().GetEnumerator(); if (it.MoveNext()) { spGen.SetSignerUserId(false, (string)it.Current); sGen.SetHashedSubpackets(spGen.Generate()); } MemoryStream bOut = new MemoryStream(); ArmoredOutputStream aOut = new ArmoredOutputStream(bOut); MemoryStream bIn = new MemoryStream(Encoding.ASCII.GetBytes(message), false); aOut.BeginClearText(HashAlgorithmTag.Sha256); // // note the last \n m_in the file is ignored // MemoryStream lineOut = new MemoryStream(); int lookAhead = ReadInputLine(lineOut, bIn); ProcessLine(aOut, sGen, lineOut.ToArray()); if (lookAhead != -1) { do { lookAhead = ReadInputLine(lineOut, lookAhead, bIn); sGen.Update((byte)'\r'); sGen.Update((byte)'\n'); ProcessLine(aOut, sGen, lineOut.ToArray()); }while (lookAhead != -1); } aOut.EndClearText(); BcpgOutputStream bcpgOut = new BcpgOutputStream(aOut); sGen.Generate().Encode(bcpgOut); aOut.Close(); byte[] bs = bOut.ToArray(); messageTest(Encoding.ASCII.GetString(bs, 0, bs.Length), type); }
/** * Search a secret key ring collection for a secret key corresponding to keyID if it * exists. * * @param pgpSec a secret key ring collection. * @param keyID keyID we want. * @param pass passphrase to decrypt secret key with. * @return * @throws PGPException * @throws NoSuchProviderException */ internal static IPgpPrivateKey FindSecretKey(PgpSecretKeyRingBundle pgpSec, long keyID, char[] pass) { IPgpSecretKey pgpSecKey = pgpSec.GetSecretKey(keyID); if (pgpSecKey == null) { return(null); } return(pgpSecKey.ExtractPrivateKey(pass)); }
private static byte[] SignPublicKey( IPgpSecretKey secretKey, string secretKeyPass, IPgpPublicKey keyToBeSigned, string notationName, string notationValue, bool armor) { Stream os = new MemoryStream(); if (armor) { os = new ArmoredOutputStream(os); } IPgpPrivateKey pgpPrivKey = secretKey.ExtractPrivateKey( secretKeyPass.ToCharArray()); PgpSignatureGenerator sGen = new PgpSignatureGenerator( secretKey.PublicKey.Algorithm, HashAlgorithmTag.Sha1); sGen.InitSign(PgpSignature.DirectKey, pgpPrivKey); BcpgOutputStream bOut = new BcpgOutputStream(os); sGen.GenerateOnePassVersion(false).Encode(bOut); PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator(); bool isHumanReadable = true; spGen.SetNotationData(true, isHumanReadable, notationName, notationValue); PgpSignatureSubpacketVector packetVector = spGen.Generate(); sGen.SetHashedSubpackets(packetVector); bOut.Flush(); if (armor) { os.Close(); } return(PgpPublicKey.AddCertification(keyToBeSigned, sGen.Generate()).GetEncoded()); }
/// <summary> /// Returns a new key ring with the secret key passed in either added or /// replacing an existing one with the same key ID. /// </summary> /// <param name="secRing">The secret key ring to be modified.</param> /// <param name="secKey">The secret key to be inserted.</param> /// <returns>A new <c>PgpSecretKeyRing</c></returns> public static PgpSecretKeyRing InsertSecretKey(IPgpSecretKeyRing secRing, IPgpSecretKey secKey) { var keys = Platform.CreateArrayList(secRing.GetSecretKeys()); var found = false; var masterFound = false; for (var i = 0; i != keys.Count; i++) { var key = keys[i]; if (key.KeyId == secKey.KeyId) { found = true; keys[i] = secKey; } if (key.IsMasterKey) { masterFound = true; } } if (!found) { if (secKey.IsMasterKey) { if (masterFound) { throw new ArgumentException("cannot add a master key to a ring that already has one"); } keys.Insert(0, secKey); } else { keys.Add(secKey); } } return(new PgpSecretKeyRing(keys, secRing.GetExtraPublicKeys())); }
private static void CreateSignature( string fileName, Stream keyIn, Stream outputStream, char[] pass, bool armor) { if (armor) { outputStream = new ArmoredOutputStream(outputStream); } IPgpSecretKey pgpSec = PgpExampleUtilities.ReadSecretKey(keyIn); IPgpPrivateKey pgpPrivKey = pgpSec.ExtractPrivateKey(pass); PgpSignatureGenerator sGen = new PgpSignatureGenerator( pgpSec.PublicKey.Algorithm, HashAlgorithmTag.Sha1); sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey); BcpgOutputStream bOut = new BcpgOutputStream(outputStream); Stream fIn = File.OpenRead(fileName); int ch; while ((ch = fIn.ReadByte()) >= 0) { sGen.Update((byte)ch); } fIn.Close(); sGen.Generate().Encode(bOut); if (armor) { outputStream.Close(); } }
/// <summary>Replace the passed public key on the passed in secret key.</summary> /// <param name="secretKey">Secret key to change.</param> /// <param name="publicKey">New public key.</param> /// <returns>A new secret key.</returns> /// <exception cref="ArgumentException">If KeyId's do not match.</exception> public static IPgpSecretKey ReplacePublicKey(IPgpSecretKey secretKey, IPgpPublicKey publicKey) { if (publicKey.KeyId != secretKey.KeyId) throw new ArgumentException("KeyId's do not match"); return new PgpSecretKey(secretKey.SecretPacket, publicKey); }
/// <summary> /// Return a copy of the passed in secret key, encrypted using a new password /// and the passed in algorithm. /// </summary> /// <param name="key">The PgpSecretKey to be copied.</param> /// <param name="oldPassPhrase">The current password for the key.</param> /// <param name="newPassPhrase">The new password for the key.</param> /// <param name="newEncAlgorithm">The algorithm to be used for the encryption.</param> /// <param name="rand">Source of randomness.</param> public static PgpSecretKey CopyWithNewPassword(IPgpSecretKey key, char[] oldPassPhrase, char[] newPassPhrase, SymmetricKeyAlgorithmTag newEncAlgorithm, SecureRandom rand) { var rawKeyData = key.ExtractKeyData(oldPassPhrase); var s2KUsage = key.SecretPacket.S2KUsage; byte[] iv = null; S2k s2K = null; byte[] keyData; if (newEncAlgorithm == SymmetricKeyAlgorithmTag.Null) { s2KUsage = SecretKeyPacket.UsageNone; if (key.SecretPacket.S2KUsage == SecretKeyPacket.UsageSha1) // SHA-1 hash, need to rewrite Checksum { keyData = new byte[rawKeyData.Length - 18]; Array.Copy(rawKeyData, 0, keyData, 0, keyData.Length - 2); var check = Checksum(false, keyData, keyData.Length - 2); keyData[keyData.Length - 2] = check[0]; keyData[keyData.Length - 1] = check[1]; } else { keyData = rawKeyData; } } else { try { keyData = EncryptKeyData(rawKeyData, newEncAlgorithm, newPassPhrase, rand, out s2K, out iv); } catch (PgpException) { throw; } catch (Exception e) { throw new PgpException("Exception encrypting key", e); } } SecretKeyPacket secret; if (key.SecretPacket is SecretSubkeyPacket) { secret = new SecretSubkeyPacket(key.SecretPacket.PublicKeyPacket, newEncAlgorithm, s2KUsage, s2K, iv, keyData); } else { secret = new SecretKeyPacket(key.SecretPacket.PublicKeyPacket, newEncAlgorithm, s2KUsage, s2K, iv, keyData); } return new PgpSecretKey(secret, key.PublicKey); }
public override void PerformTest() { // // Read the public key // PgpObjectFactory pgpFact = new PgpObjectFactory(testPubKeyRing); PgpPublicKeyRing pgpPub = (PgpPublicKeyRing)pgpFact.NextPgpObject(); var pubKey = pgpPub.GetPublicKey(); if (pubKey.BitStrength != 1024) { Fail("failed - key strength reported incorrectly."); } // // Read the private key // PgpSecretKeyRing sKey = new PgpSecretKeyRing(testPrivKeyRing); IPgpSecretKey secretKey = sKey.GetSecretKey(); IPgpPrivateKey pgpPrivKey = secretKey.ExtractPrivateKey(pass); // // signature generation // const string data = "hello world!"; byte[] dataBytes = Encoding.ASCII.GetBytes(data); MemoryStream bOut = new MemoryStream(); MemoryStream testIn = new MemoryStream(dataBytes, false); PgpSignatureGenerator sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1); sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey); PgpCompressedDataGenerator cGen = new PgpCompressedDataGenerator( CompressionAlgorithmTag.Zip); BcpgOutputStream bcOut = new BcpgOutputStream( cGen.Open(new UncloseableStream(bOut))); sGen.GenerateOnePassVersion(false).Encode(bcOut); PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator(); DateTime testDateTime = new DateTime(1973, 7, 27); Stream lOut = lGen.Open( new UncloseableStream(bcOut), PgpLiteralData.Binary, "_CONSOLE", dataBytes.Length, testDateTime); int ch; while ((ch = testIn.ReadByte()) >= 0) { lOut.WriteByte((byte)ch); sGen.Update((byte)ch); } lGen.Close(); sGen.Generate().Encode(bcOut); cGen.Close(); // // verify Generated signature // pgpFact = new PgpObjectFactory(bOut.ToArray()); PgpCompressedData c1 = (PgpCompressedData)pgpFact.NextPgpObject(); pgpFact = new PgpObjectFactory(c1.GetDataStream()); PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject(); PgpOnePassSignature ops = p1[0]; PgpLiteralData p2 = (PgpLiteralData)pgpFact.NextPgpObject(); if (!p2.ModificationTime.Equals(testDateTime)) { Fail("Modification time not preserved"); } Stream dIn = p2.GetInputStream(); ops.InitVerify(pubKey); while ((ch = dIn.ReadByte()) >= 0) { ops.Update((byte)ch); } PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject(); if (!ops.Verify(p3[0])) { Fail("Failed Generated signature check"); } // // test encryption // // // find a key sutiable for encryption // long pgpKeyID = 0; IAsymmetricKeyParameter pKey = null; foreach (PgpPublicKey pgpKey in pgpPub.GetPublicKeys()) { if (pgpKey.Algorithm == PublicKeyAlgorithmTag.ElGamalEncrypt || pgpKey.Algorithm == PublicKeyAlgorithmTag.ElGamalGeneral) { pKey = pgpKey.GetKey(); pgpKeyID = pgpKey.KeyId; if (pgpKey.BitStrength != 1024) { Fail("failed - key strength reported incorrectly."); } // // verify the key // } } IBufferedCipher c = CipherUtilities.GetCipher("ElGamal/None/PKCS1Padding"); c.Init(true, pKey); byte[] inBytes = Encoding.ASCII.GetBytes("hello world"); byte[] outBytes = c.DoFinal(inBytes); pgpPrivKey = sKey.GetSecretKey(pgpKeyID).ExtractPrivateKey(pass); c.Init(false, pgpPrivKey.Key); outBytes = c.DoFinal(outBytes); if (!Arrays.AreEqual(inBytes, outBytes)) { Fail("decryption failed."); } // // encrypted message // byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l',(byte)'d', (byte)'!', (byte)'\n' }; PgpObjectFactory pgpF = new PgpObjectFactory(encMessage); PgpEncryptedDataList encList = (PgpEncryptedDataList)pgpF.NextPgpObject(); PgpPublicKeyEncryptedData encP = (PgpPublicKeyEncryptedData)encList[0]; Stream clear = encP.GetDataStream(pgpPrivKey); pgpFact = new PgpObjectFactory(clear); c1 = (PgpCompressedData)pgpFact.NextPgpObject(); pgpFact = new PgpObjectFactory(c1.GetDataStream()); PgpLiteralData ld = (PgpLiteralData)pgpFact.NextPgpObject(); if (!ld.FileName.Equals("test.txt")) { throw new Exception("wrong filename in packet"); } Stream inLd = ld.GetDataStream(); byte[] bytes = Streams.ReadAll(inLd); if (!Arrays.AreEqual(bytes, text)) { Fail("wrong plain text in decrypted packet"); } // // signed and encrypted message // pgpF = new PgpObjectFactory(signedAndEncMessage); encList = (PgpEncryptedDataList)pgpF.NextPgpObject(); encP = (PgpPublicKeyEncryptedData)encList[0]; clear = encP.GetDataStream(pgpPrivKey); pgpFact = new PgpObjectFactory(clear); c1 = (PgpCompressedData)pgpFact.NextPgpObject(); pgpFact = new PgpObjectFactory(c1.GetDataStream()); p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject(); ops = p1[0]; ld = (PgpLiteralData)pgpFact.NextPgpObject(); bOut = new MemoryStream(); if (!ld.FileName.Equals("test.txt")) { throw new Exception("wrong filename in packet"); } inLd = ld.GetDataStream(); // // note: we use the DSA public key here. // ops.InitVerify(pgpPub.GetPublicKey()); while ((ch = inLd.ReadByte()) >= 0) { ops.Update((byte)ch); bOut.WriteByte((byte)ch); } p3 = (PgpSignatureList)pgpFact.NextPgpObject(); if (!ops.Verify(p3[0])) { Fail("Failed signature check"); } if (!Arrays.AreEqual(bOut.ToArray(), text)) { Fail("wrong plain text in decrypted packet"); } // // encrypt // MemoryStream cbOut = new MemoryStream(); PgpEncryptedDataGenerator cPk = new PgpEncryptedDataGenerator( SymmetricKeyAlgorithmTag.TripleDes, random); IPgpPublicKey puK = sKey.GetSecretKey(pgpKeyID).PublicKey; cPk.AddMethod(puK); Stream cOut = cPk.Open(new UncloseableStream(cbOut), bOut.ToArray().Length); cOut.Write(text, 0, text.Length); cOut.Close(); pgpF = new PgpObjectFactory(cbOut.ToArray()); encList = (PgpEncryptedDataList)pgpF.NextPgpObject(); encP = (PgpPublicKeyEncryptedData)encList[0]; pgpPrivKey = sKey.GetSecretKey(pgpKeyID).ExtractPrivateKey(pass); clear = encP.GetDataStream(pgpPrivKey); outBytes = Streams.ReadAll(clear); if (!Arrays.AreEqual(outBytes, text)) { Fail("wrong plain text in Generated packet"); } // // use of PgpKeyPair // IBigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); IBigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); ElGamalParameters elParams = new ElGamalParameters(p, g); IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator("ELGAMAL"); kpg.Init(new ElGamalKeyGenerationParameters(random, elParams)); IAsymmetricCipherKeyPair kp = kpg.GenerateKeyPair(); PgpKeyPair pgpKp = new PgpKeyPair(PublicKeyAlgorithmTag.ElGamalGeneral, kp.Public, kp.Private, DateTime.UtcNow); PgpPublicKey k1 = pgpKp.PublicKey; PgpPrivateKey k2 = pgpKp.PrivateKey; // Test bug with ElGamal P size != 0 mod 8 (don't use these sizes at home!) for (int pSize = 257; pSize < 264; ++pSize) { // Generate some parameters of the given size ElGamalParametersGenerator epg = new ElGamalParametersGenerator(); epg.Init(pSize, 2, random); elParams = epg.GenerateParameters(); kpg = GeneratorUtilities.GetKeyPairGenerator("ELGAMAL"); kpg.Init(new ElGamalKeyGenerationParameters(random, elParams)); // Run a short encrypt/decrypt test with random key for the given parameters kp = kpg.GenerateKeyPair(); PgpKeyPair elGamalKeyPair = new PgpKeyPair( PublicKeyAlgorithmTag.ElGamalGeneral, kp, DateTime.UtcNow); cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, random); puK = elGamalKeyPair.PublicKey; cPk.AddMethod(puK); cbOut = new MemoryStream(); cOut = cPk.Open(new UncloseableStream(cbOut), text.Length); cOut.Write(text, 0, text.Length); cOut.Close(); pgpF = new PgpObjectFactory(cbOut.ToArray()); encList = (PgpEncryptedDataList)pgpF.NextPgpObject(); encP = (PgpPublicKeyEncryptedData)encList[0]; pgpPrivKey = elGamalKeyPair.PrivateKey; // Note: This is where an exception would be expected if the P size causes problems clear = encP.GetDataStream(pgpPrivKey); byte[] decText = Streams.ReadAll(clear); if (!Arrays.AreEqual(text, decText)) { Fail("decrypted message incorrect"); } } // check sub key encoding foreach (PgpPublicKey pgpKey in pgpPub.GetPublicKeys()) { if (!pgpKey.IsMasterKey) { byte[] kEnc = pgpKey.GetEncoded(); PgpObjectFactory objF = new PgpObjectFactory(kEnc); // TODO Make PgpPublicKey a PgpObject or return a PgpPublicKeyRing // PgpPublicKey k = (PgpPublicKey)objF.NextPgpObject(); // // pKey = k.GetKey(); // pgpKeyID = k.KeyId; // if (k.BitStrength != 1024) // { // Fail("failed - key strength reported incorrectly."); // } // // if (objF.NextPgpObject() != null) // { // Fail("failed - stream not fully parsed."); // } } } }
/// <summary> /// Returns a new key ring with the secret key passed in either added or /// replacing an existing one with the same key ID. /// </summary> /// <param name="secRing">The secret key ring to be modified.</param> /// <param name="secKey">The secret key to be inserted.</param> /// <returns>A new <c>PgpSecretKeyRing</c></returns> public static PgpSecretKeyRing InsertSecretKey(IPgpSecretKeyRing secRing, IPgpSecretKey secKey) { var keys = Platform.CreateArrayList(secRing.GetSecretKeys()); var found = false; var masterFound = false; for (var i = 0; i != keys.Count; i++) { var key = keys[i]; if (key.KeyId == secKey.KeyId) { found = true; keys[i] = secKey; } if (key.IsMasterKey) { masterFound = true; } } if (!found) { if (secKey.IsMasterKey) { if (masterFound) throw new ArgumentException("cannot add a master key to a ring that already has one"); keys.Insert(0, secKey); } else { keys.Add(secKey); } } return new PgpSecretKeyRing(keys, secRing.GetExtraPublicKeys()); }
public override void PerformTest() { // // Read the public key // PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(testPubKey); var pubKey = pgpPub.GetPublicKey(); // // Read the private key // PgpSecretKeyRing sKey = new PgpSecretKeyRing(testPrivKey); IPgpSecretKey secretKey = sKey.GetSecretKey(); IPgpPrivateKey pgpPrivKey = secretKey.ExtractPrivateKey(pass); // // test signature message // PgpObjectFactory pgpFact = new PgpObjectFactory(sig1); PgpCompressedData c1 = (PgpCompressedData)pgpFact.NextPgpObject(); pgpFact = new PgpObjectFactory(c1.GetDataStream()); PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject(); PgpOnePassSignature ops = p1[0]; PgpLiteralData p2 = (PgpLiteralData)pgpFact.NextPgpObject(); Stream dIn = p2.GetInputStream(); ops.InitVerify(pubKey); int ch; while ((ch = dIn.ReadByte()) >= 0) { ops.Update((byte)ch); } PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject(); if (!ops.Verify(p3[0])) { Fail("Failed signature check"); } // // signature generation // GenerateTest(sKey, pubKey, pgpPrivKey); // // signature generation - canonical text // const string data = "hello world!"; byte[] dataBytes = Encoding.ASCII.GetBytes(data); MemoryStream bOut = new MemoryStream(); MemoryStream testIn = new MemoryStream(dataBytes, false); PgpSignatureGenerator sGen = new PgpSignatureGenerator( PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1); sGen.InitSign(PgpSignature.CanonicalTextDocument, pgpPrivKey); PgpCompressedDataGenerator cGen = new PgpCompressedDataGenerator( CompressionAlgorithmTag.Zip); BcpgOutputStream bcOut = new BcpgOutputStream(cGen.Open(new UncloseableStream(bOut))); sGen.GenerateOnePassVersion(false).Encode(bcOut); PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator(); DateTime testDateTime = new DateTime(1973, 7, 27); Stream lOut = lGen.Open( new UncloseableStream(bcOut), PgpLiteralData.Text, "_CONSOLE", dataBytes.Length, testDateTime); while ((ch = testIn.ReadByte()) >= 0) { lOut.WriteByte((byte)ch); sGen.Update((byte)ch); } lGen.Close(); sGen.Generate().Encode(bcOut); cGen.Close(); // // verify Generated signature - canconical text // pgpFact = new PgpObjectFactory(bOut.ToArray()); c1 = (PgpCompressedData)pgpFact.NextPgpObject(); pgpFact = new PgpObjectFactory(c1.GetDataStream()); p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject(); ops = p1[0]; p2 = (PgpLiteralData)pgpFact.NextPgpObject(); if (!p2.ModificationTime.Equals(testDateTime)) { Fail("Modification time not preserved"); } dIn = p2.GetInputStream(); ops.InitVerify(pubKey); while ((ch = dIn.ReadByte()) >= 0) { ops.Update((byte)ch); } p3 = (PgpSignatureList)pgpFact.NextPgpObject(); if (!ops.Verify(p3[0])) { Fail("Failed generated signature check"); } // // Read the public key with user attributes // pgpPub = new PgpPublicKeyRing(testPubWithUserAttr); pubKey = pgpPub.GetPublicKey(); int count = 0; foreach (PgpUserAttributeSubpacketVector attributes in pubKey.GetUserAttributes()) { int sigCount = 0; foreach (object sigs in pubKey.GetSignaturesForUserAttribute(attributes)) { if (sigs == null) { Fail("null signature found"); } sigCount++; } if (sigCount != 1) { Fail("Failed user attributes signature check"); } count++; } if (count != 1) { Fail("Failed user attributes check"); } byte[] pgpPubBytes = pgpPub.GetEncoded(); pgpPub = new PgpPublicKeyRing(pgpPubBytes); pubKey = pgpPub.GetPublicKey(); count = 0; foreach (object ua in pubKey.GetUserAttributes()) { if (ua == null) { Fail("null user attribute found"); } count++; } if (count != 1) { Fail("Failed user attributes reread"); } // // reading test extra data - key with edge condition for DSA key password. // char[] passPhrase = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; sKey = new PgpSecretKeyRing(testPrivKey2); pgpPrivKey = sKey.GetSecretKey().ExtractPrivateKey(passPhrase); // // reading test - aes256 encrypted passphrase. // sKey = new PgpSecretKeyRing(aesSecretKey); pgpPrivKey = sKey.GetSecretKey().ExtractPrivateKey(pass); // // reading test - twofish encrypted passphrase. // sKey = new PgpSecretKeyRing(twofishSecretKey); pgpPrivKey = sKey.GetSecretKey().ExtractPrivateKey(pass); // // use of PgpKeyPair // DsaParametersGenerator pGen = new DsaParametersGenerator(); pGen.Init(512, 80, new SecureRandom()); // TODO Is the certainty okay? DsaParameters dsaParams = pGen.GenerateParameters(); DsaKeyGenerationParameters kgp = new DsaKeyGenerationParameters(new SecureRandom(), dsaParams); IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator("DSA"); kpg.Init(kgp); IAsymmetricCipherKeyPair kp = kpg.GenerateKeyPair(); PgpKeyPair pgpKp = new PgpKeyPair(PublicKeyAlgorithmTag.Dsa, kp.Public, kp.Private, DateTime.UtcNow); PgpPublicKey k1 = pgpKp.PublicKey; PgpPrivateKey k2 = pgpKp.PrivateKey; }
public override void PerformTest() { // // RSA tests // PgpSecretKeyRing pgpPriv = new PgpSecretKeyRing(rsaKeyRing); IPgpSecretKey secretKey = pgpPriv.GetSecretKey(); IPgpPrivateKey pgpPrivKey = secretKey.ExtractPrivateKey(rsaPass); try { doTestSig(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey); Fail("RSA wrong key test failed."); } catch (PgpException) { // expected } try { doTestSigV3(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey); Fail("RSA V3 wrong key test failed."); } catch (PgpException) { // expected } // // certifications // PgpSignatureGenerator sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1); sGen.InitSign(PgpSignature.KeyRevocation, pgpPrivKey); PgpSignature sig = sGen.GenerateCertification(secretKey.PublicKey); sig.InitVerify(secretKey.PublicKey); if (!sig.VerifyCertification(secretKey.PublicKey)) { Fail("revocation verification failed."); } PgpSecretKeyRing pgpDSAPriv = new PgpSecretKeyRing(dsaKeyRing); IPgpSecretKey secretDSAKey = pgpDSAPriv.GetSecretKey(); IPgpPrivateKey pgpPrivDSAKey = secretDSAKey.ExtractPrivateKey(dsaPass); sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1); sGen.InitSign(PgpSignature.SubkeyBinding, pgpPrivDSAKey); PgpSignatureSubpacketGenerator unhashedGen = new PgpSignatureSubpacketGenerator(); PgpSignatureSubpacketGenerator hashedGen = new PgpSignatureSubpacketGenerator(); hashedGen.SetSignatureExpirationTime(false, TEST_EXPIRATION_TIME); hashedGen.SetSignerUserId(true, TEST_USER_ID); hashedGen.SetPreferredCompressionAlgorithms(false, PREFERRED_COMPRESSION_ALGORITHMS); hashedGen.SetPreferredHashAlgorithms(false, PREFERRED_HASH_ALGORITHMS); hashedGen.SetPreferredSymmetricAlgorithms(false, PREFERRED_SYMMETRIC_ALGORITHMS); sGen.SetHashedSubpackets(hashedGen.Generate()); sGen.SetUnhashedSubpackets(unhashedGen.Generate()); sig = sGen.GenerateCertification(secretDSAKey.PublicKey, secretKey.PublicKey); byte[] sigBytes = sig.GetEncoded(); PgpObjectFactory f = new PgpObjectFactory(sigBytes); sig = ((PgpSignatureList)f.NextPgpObject())[0]; sig.InitVerify(secretDSAKey.PublicKey); if (!sig.VerifyCertification(secretDSAKey.PublicKey, secretKey.PublicKey)) { Fail("subkey binding verification failed."); } var hashedPcks = sig.GetHashedSubPackets(); var unhashedPcks = sig.GetUnhashedSubPackets(); if (hashedPcks.Count != 6) { Fail("wrong number of hashed packets found."); } if (unhashedPcks.Count != 1) { Fail("wrong number of unhashed packets found."); } if (!hashedPcks.GetSignerUserId().Equals(TEST_USER_ID)) { Fail("test userid not matching"); } if (hashedPcks.GetSignatureExpirationTime() != TEST_EXPIRATION_TIME) { Fail("test signature expiration time not matching"); } if (unhashedPcks.GetIssuerKeyId() != secretDSAKey.KeyId) { Fail("wrong issuer key ID found in certification"); } int[] prefAlgs = hashedPcks.GetPreferredCompressionAlgorithms(); preferredAlgorithmCheck("compression", PREFERRED_COMPRESSION_ALGORITHMS, prefAlgs); prefAlgs = hashedPcks.GetPreferredHashAlgorithms(); preferredAlgorithmCheck("hash", PREFERRED_HASH_ALGORITHMS, prefAlgs); prefAlgs = hashedPcks.GetPreferredSymmetricAlgorithms(); preferredAlgorithmCheck("symmetric", PREFERRED_SYMMETRIC_ALGORITHMS, prefAlgs); SignatureSubpacketTag[] criticalHashed = hashedPcks.GetCriticalTags(); if (criticalHashed.Length != 1) { Fail("wrong number of critical packets found."); } if (criticalHashed[0] != SignatureSubpacketTag.SignerUserId) { Fail("wrong critical packet found in tag list."); } // // no packets passed // sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1); sGen.InitSign(PgpSignature.SubkeyBinding, pgpPrivDSAKey); sGen.SetHashedSubpackets(null); sGen.SetUnhashedSubpackets(null); sig = sGen.GenerateCertification(TEST_USER_ID, secretKey.PublicKey); sig.InitVerify(secretDSAKey.PublicKey); if (!sig.VerifyCertification(TEST_USER_ID, secretKey.PublicKey)) { Fail("subkey binding verification failed."); } hashedPcks = sig.GetHashedSubPackets(); if (hashedPcks.Count != 1) { Fail("found wrong number of hashed packets"); } unhashedPcks = sig.GetUnhashedSubPackets(); if (unhashedPcks.Count != 1) { Fail("found wrong number of unhashed packets"); } try { sig.VerifyCertification(secretKey.PublicKey); Fail("failed to detect non-key signature."); } catch (InvalidOperationException) { // expected } // // override hash packets // sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1); sGen.InitSign(PgpSignature.SubkeyBinding, pgpPrivDSAKey); hashedGen = new PgpSignatureSubpacketGenerator(); DateTime creationTime = new DateTime(1973, 7, 27); hashedGen.SetSignatureCreationTime(false, creationTime); sGen.SetHashedSubpackets(hashedGen.Generate()); sGen.SetUnhashedSubpackets(null); sig = sGen.GenerateCertification(TEST_USER_ID, secretKey.PublicKey); sig.InitVerify(secretDSAKey.PublicKey); if (!sig.VerifyCertification(TEST_USER_ID, secretKey.PublicKey)) { Fail("subkey binding verification failed."); } hashedPcks = sig.GetHashedSubPackets(); if (hashedPcks.Count != 1) { Fail("found wrong number of hashed packets in override test"); } if (!hashedPcks.HasSubpacket(SignatureSubpacketTag.CreationTime)) { Fail("hasSubpacket test for creation time failed"); } DateTime sigCreationTime = hashedPcks.GetSignatureCreationTime(); if (!sigCreationTime.Equals(creationTime)) { Fail("creation of overridden date failed."); } prefAlgs = hashedPcks.GetPreferredCompressionAlgorithms(); preferredAlgorithmCheck("compression", NO_PREFERENCES, prefAlgs); prefAlgs = hashedPcks.GetPreferredHashAlgorithms(); preferredAlgorithmCheck("hash", NO_PREFERENCES, prefAlgs); prefAlgs = hashedPcks.GetPreferredSymmetricAlgorithms(); preferredAlgorithmCheck("symmetric", NO_PREFERENCES, prefAlgs); if (hashedPcks.GetKeyExpirationTime() != 0) { Fail("unexpected key expiration time found"); } if (hashedPcks.GetSignatureExpirationTime() != 0) { Fail("unexpected signature expiration time found"); } if (hashedPcks.GetSignerUserId() != null) { Fail("unexpected signer user ID found"); } criticalHashed = hashedPcks.GetCriticalTags(); if (criticalHashed.Length != 0) { Fail("critical packets found when none expected"); } unhashedPcks = sig.GetUnhashedSubPackets(); if (unhashedPcks.Count != 1) { Fail("found wrong number of unhashed packets in override test"); } // // general signatures // doTestSig(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha256, secretKey.PublicKey, pgpPrivKey); doTestSig(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha384, secretKey.PublicKey, pgpPrivKey); doTestSig(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha512, secretKey.PublicKey, pgpPrivKey); doTestSigV3(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey); doTestTextSig(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA_WITH_CRLF, TEST_DATA_WITH_CRLF); doTestTextSig(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA, TEST_DATA_WITH_CRLF); doTestTextSigV3(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA_WITH_CRLF, TEST_DATA_WITH_CRLF); doTestTextSigV3(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA, TEST_DATA_WITH_CRLF); // // DSA Tests // pgpPriv = new PgpSecretKeyRing(dsaKeyRing); secretKey = pgpPriv.GetSecretKey(); pgpPrivKey = secretKey.ExtractPrivateKey(dsaPass); try { doTestSig(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey); Fail("DSA wrong key test failed."); } catch (PgpException) { // expected } try { doTestSigV3(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey); Fail("DSA V3 wrong key test failed."); } catch (PgpException) { // expected } doTestSig(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey); doTestSigV3(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey); doTestTextSig(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA_WITH_CRLF, TEST_DATA_WITH_CRLF); doTestTextSig(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA, TEST_DATA_WITH_CRLF); doTestTextSigV3(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA_WITH_CRLF, TEST_DATA_WITH_CRLF); doTestTextSigV3(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA, TEST_DATA_WITH_CRLF); // special cases // doTestMissingSubpackets(nullPacketsSubKeyBinding); doTestMissingSubpackets(generateV3BinarySig(pgpPrivKey, PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1)); // keyflags doTestKeyFlagsValues(); }
/** * Generate an encapsulated signed file. * * @param fileName * @param keyIn * @param outputStream * @param pass * @param armor */ private static void SignFile( string fileName, Stream keyIn, Stream outputStream, char[] pass, bool armor, bool compress) { if (armor) { outputStream = new ArmoredOutputStream(outputStream); } IPgpSecretKey pgpSec = PgpExampleUtilities.ReadSecretKey(keyIn); IPgpPrivateKey pgpPrivKey = pgpSec.ExtractPrivateKey(pass); PgpSignatureGenerator sGen = new PgpSignatureGenerator(pgpSec.PublicKey.Algorithm, HashAlgorithmTag.Sha1); sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey); foreach (string userId in pgpSec.PublicKey.GetUserIds()) { PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator(); spGen.SetSignerUserId(false, userId); sGen.SetHashedSubpackets(spGen.Generate()); // Just the first one! break; } Stream cOut = outputStream; PgpCompressedDataGenerator cGen = null; if (compress) { cGen = new PgpCompressedDataGenerator(CompressionAlgorithmTag.ZLib); cOut = cGen.Open(cOut); } BcpgOutputStream bOut = new BcpgOutputStream(cOut); sGen.GenerateOnePassVersion(false).Encode(bOut); FileInfo file = new FileInfo(fileName); PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator(); Stream lOut = lGen.Open(bOut, PgpLiteralData.Binary, file); FileStream fIn = file.OpenRead(); int ch = 0; while ((ch = fIn.ReadByte()) >= 0) { lOut.WriteByte((byte)ch); sGen.Update((byte)ch); } fIn.Close(); lGen.Close(); sGen.Generate().Encode(bOut); if (cGen != null) { cGen.Close(); } if (armor) { outputStream.Close(); } }
/* * create a clear text signed file. */ private static void SignFile( string fileName, Stream keyIn, Stream outputStream, char[] pass, string digestName) { HashAlgorithmTag digest; if (digestName.Equals("SHA256")) { digest = HashAlgorithmTag.Sha256; } else if (digestName.Equals("SHA384")) { digest = HashAlgorithmTag.Sha384; } else if (digestName.Equals("SHA512")) { digest = HashAlgorithmTag.Sha512; } else if (digestName.Equals("MD5")) { digest = HashAlgorithmTag.MD5; } else if (digestName.Equals("RIPEMD160")) { digest = HashAlgorithmTag.RipeMD160; } else { digest = HashAlgorithmTag.Sha1; } IPgpSecretKey pgpSecKey = PgpExampleUtilities.ReadSecretKey(keyIn); IPgpPrivateKey pgpPrivKey = pgpSecKey.ExtractPrivateKey(pass); PgpSignatureGenerator sGen = new PgpSignatureGenerator(pgpSecKey.PublicKey.Algorithm, digest); PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator(); sGen.InitSign(PgpSignature.CanonicalTextDocument, pgpPrivKey); IEnumerator enumerator = pgpSecKey.PublicKey.GetUserIds().GetEnumerator(); if (enumerator.MoveNext()) { spGen.SetSignerUserId(false, (string)enumerator.Current); sGen.SetHashedSubpackets(spGen.Generate()); } Stream fIn = File.OpenRead(fileName); ArmoredOutputStream aOut = new ArmoredOutputStream(outputStream); aOut.BeginClearText(digest); // // note the last \n/\r/\r\n in the file is ignored // MemoryStream lineOut = new MemoryStream(); int lookAhead = ReadInputLine(lineOut, fIn); ProcessLine(aOut, sGen, lineOut.ToArray()); if (lookAhead != -1) { do { lookAhead = ReadInputLine(lineOut, lookAhead, fIn); sGen.Update((byte)'\r'); sGen.Update((byte)'\n'); ProcessLine(aOut, sGen, lineOut.ToArray()); }while (lookAhead != -1); } fIn.Close(); aOut.EndClearText(); BcpgOutputStream bOut = new BcpgOutputStream(aOut); sGen.Generate().Encode(bOut); aOut.Close(); }
private static byte[] SignPublicKey( IPgpSecretKey secretKey, string secretKeyPass, IPgpPublicKey keyToBeSigned, string notationName, string notationValue, bool armor) { Stream os = new MemoryStream(); if (armor) { os = new ArmoredOutputStream(os); } IPgpPrivateKey pgpPrivKey = secretKey.ExtractPrivateKey( secretKeyPass.ToCharArray()); PgpSignatureGenerator sGen = new PgpSignatureGenerator( secretKey.PublicKey.Algorithm, HashAlgorithmTag.Sha1); sGen.InitSign(PgpSignature.DirectKey, pgpPrivKey); BcpgOutputStream bOut = new BcpgOutputStream(os); sGen.GenerateOnePassVersion(false).Encode(bOut); PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator(); bool isHumanReadable = true; spGen.SetNotationData(true, isHumanReadable, notationName, notationValue); PgpSignatureSubpacketVector packetVector = spGen.Generate(); sGen.SetHashedSubpackets(packetVector); bOut.Flush(); if (armor) { os.Close(); } return PgpPublicKey.AddCertification(keyToBeSigned, sGen.Generate()).GetEncoded(); }