private void ProcessSymmetricKeyDataForElGamal(IPgpPrivateKey privateKey, IBufferedCipher cipher, IList <IBigInteger> symmetricKeyData) { var k = (ElGamalPrivateKeyParameters)privateKey.Key; var size = (k.Parameters.P.BitLength + 7) / 8; var bi = symmetricKeyData[0].ToByteArray(); var diff = bi.Length - size; if (diff >= 0) { cipher.ProcessBytes(bi, diff, size); } else { var zeros = new byte[-diff]; cipher.ProcessBytes(zeros); cipher.ProcessBytes(bi); } bi = symmetricKeyData[1].ToByteArray(); diff = bi.Length - size; if (diff >= 0) { cipher.ProcessBytes(bi, diff, size); } else { var zeros = new byte[-diff]; cipher.ProcessBytes(zeros); cipher.ProcessBytes(bi); } }
/// <summary>Initialise the generator for signing.</summary> public void InitSign( int sigType, IPgpPrivateKey key, SecureRandom random) { this.privKey = key; this.signatureType = sigType; try { ICipherParameters cp = key.Key; if (random != null) { cp = new ParametersWithRandom(key.Key, random); } sig.Init(true, cp); } catch (InvalidKeyException e) { throw new PgpException("invalid key.", e); } dig.Reset(); lastb = 0; }
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); }
private void doTestSigV3( PublicKeyAlgorithmTag encAlgorithm, HashAlgorithmTag hashAlgorithm, IPgpPublicKey pubKey, IPgpPrivateKey privKey) { byte[] bytes = generateV3BinarySig(privKey, encAlgorithm, hashAlgorithm); verifySignature(bytes, hashAlgorithm, pubKey, TEST_DATA); }
private byte[] ProcessSymmetricKeyDataForEcdh(IPgpPrivateKey privKey, IList <IBigInteger> symmetricKeyData) { var encSymKey = symmetricKeyData[1].ToByteArrayUnsigned(); var privateKey = (ECDHPrivateKeyParameters)privKey.Key; var publicKey = privateKey.PublicKeyParameters; var ephemeralKey = ECDHPublicKeyParameters.Create(symmetricKeyData[0], publicKey.PublicKeyParamSet, publicKey.HashAlgorithm, publicKey.SymmetricKeyAlgorithm); var engine = new RFC6637ECDHEngine(); engine.InitForDecryption(privateKey, ephemeralKey); return(engine.ProcessBlock(encSymKey, 0, encSymKey.Length)); }
private byte[] FetchSymmetricKeyData(IPgpPrivateKey privKey) { byte[] plain; var keyD = _keyData.GetEncSessionKey(); if (_keyData.Algorithm == PublicKeyAlgorithmTag.Ecdh) { plain = this.ProcessSymmetricKeyDataForEcdh(privKey, keyD); } else { var c1 = GetKeyCipher(_keyData.Algorithm); try { c1.Init(false, privKey.Key); } catch (InvalidKeyException e) { throw new PgpException("error setting asymmetric cipher", e); } switch (_keyData.Algorithm) { case PublicKeyAlgorithmTag.RsaGeneral: case PublicKeyAlgorithmTag.RsaEncrypt: this.ProcessSymmetricKeyDataForRsa(c1, keyD); break; default: this.ProcessSymmetricKeyDataForElGamal(privKey, c1, keyD); break; } try { plain = c1.DoFinal(); } catch (Exception e) { throw new PgpException("exception decrypting secret key", e); } } if (!ConfirmCheckSum(plain)) { throw new PgpKeyValidationException("key checksum failed"); } return(plain); }
private void doTestTextSig( PublicKeyAlgorithmTag encAlgorithm, HashAlgorithmTag hashAlgorithm, IPgpPublicKey pubKey, IPgpPrivateKey privKey, byte[] data, byte[] canonicalData) { PgpSignatureGenerator sGen = new PgpSignatureGenerator(encAlgorithm, HashAlgorithmTag.Sha1); MemoryStream bOut = new MemoryStream(); MemoryStream testIn = new MemoryStream(data, false); DateTime creationTime = DateTime.UtcNow; sGen.InitSign(PgpSignature.CanonicalTextDocument, privKey); sGen.GenerateOnePassVersion(false).Encode(bOut); PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator(); Stream lOut = lGen.Open( new UncloseableStream(bOut), PgpLiteralData.Text, "_CONSOLE", data.Length * 2, creationTime); int ch; while ((ch = testIn.ReadByte()) >= 0) { lOut.WriteByte((byte)ch); sGen.Update((byte)ch); } lOut.Write(data, 0, data.Length); sGen.Update(data); lGen.Close(); PgpSignature sig = sGen.Generate(); if (sig.CreationTime == DateTimeUtilities.UnixMsToDateTime(0)) { Fail("creation time not set in v4 signature"); } sig.Encode(bOut); verifySignature(bOut.ToArray(), hashAlgorithm, pubKey, canonicalData); }
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()); }
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(); } }
private void doTestSig( PublicKeyAlgorithmTag encAlgorithm, HashAlgorithmTag hashAlgorithm, IPgpPublicKey pubKey, IPgpPrivateKey privKey) { MemoryStream bOut = new MemoryStream(); MemoryStream testIn = new MemoryStream(TEST_DATA, false); PgpSignatureGenerator sGen = new PgpSignatureGenerator(encAlgorithm, hashAlgorithm); sGen.InitSign(PgpSignature.BinaryDocument, privKey); sGen.GenerateOnePassVersion(false).Encode(bOut); PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator(); Stream lOut = lGen.Open( new UncloseableStream(bOut), PgpLiteralData.Binary, "_CONSOLE", TEST_DATA.Length * 2, DateTime.UtcNow); int ch; while ((ch = testIn.ReadByte()) >= 0) { lOut.WriteByte((byte)ch); sGen.Update((byte)ch); } lOut.Write(TEST_DATA, 0, TEST_DATA.Length); sGen.Update(TEST_DATA); lGen.Close(); sGen.Generate().Encode(bOut); verifySignature(bOut.ToArray(), hashAlgorithm, pubKey, TEST_DATA); }
/** * 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(); }
/// <summary>Initialise the generator for signing.</summary> public void InitSign(int sigType, IPgpPrivateKey key, ISecureRandom random) { _privKey = key; _signatureType = sigType; try { ICipherParameters cp = key.Key; if (random != null) { cp = new ParametersWithRandom(key.Key, random); } _sig.Init(true, cp); } catch (InvalidKeyException e) { throw new PgpException("invalid key.", e); } _dig.Reset(); _lastb = 0; }
/// <summary>Initialise the generator for signing.</summary> public void InitSign(int sigType, IPgpPrivateKey key) { InitSign(sigType, key, null); }
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."); // } } } }
/** * Generated signature test * * @param sKey * @param pgpPrivKey * @return test result */ public void GenerateTest( PgpSecretKeyRing sKey, IPgpPublicKey pgpPubKey, IPgpPrivateKey pgpPrivKey) { string data = "hello world!"; MemoryStream bOut = new MemoryStream(); byte[] dataBytes = Encoding.ASCII.GetBytes(data); MemoryStream testIn = new MemoryStream(dataBytes, false); PgpSignatureGenerator sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1); sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey); PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator(); IEnumerator enumerator = sKey.GetSecretKey().PublicKey.GetUserIds().GetEnumerator(); enumerator.MoveNext(); string primaryUserId = (string)enumerator.Current; spGen.SetSignerUserId(true, primaryUserId); sGen.SetHashedSubpackets(spGen.Generate()); 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(); PgpObjectFactory 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(pgpPubKey); while ((ch = dIn.ReadByte()) >= 0) { ops.Update((byte)ch); } PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject(); if (!ops.Verify(p3[0])) { Fail("Failed generated signature check"); } }
private byte[] FetchSymmetricKeyData(IPgpPrivateKey privKey) { byte[] plain; var keyD = _keyData.GetEncSessionKey(); if (_keyData.Algorithm == PublicKeyAlgorithmTag.Ecdh) { plain = this.ProcessSymmetricKeyDataForEcdh(privKey, keyD); } else { var c1 = GetKeyCipher(_keyData.Algorithm); try { c1.Init(false, privKey.Key); } catch (InvalidKeyException e) { throw new PgpException("error setting asymmetric cipher", e); } switch (_keyData.Algorithm) { case PublicKeyAlgorithmTag.RsaGeneral: case PublicKeyAlgorithmTag.RsaEncrypt: this.ProcessSymmetricKeyDataForRsa(c1, keyD); break; default: this.ProcessSymmetricKeyDataForElGamal(privKey, c1, keyD); break; } try { plain = c1.DoFinal(); } catch (Exception e) { throw new PgpException("exception decrypting secret key", e); } } if (!ConfirmCheckSum(plain)) throw new PgpKeyValidationException("key checksum failed"); return plain; }
/// <summary> /// Return the algorithm code for the symmetric algorithm used to encrypt the data. /// </summary> /// <param name="privKey">The priv key.</param> /// <returns></returns> public SymmetricKeyAlgorithmTag GetSymmetricAlgorithm(IPgpPrivateKey privKey) { var plain = FetchSymmetricKeyData(privKey); return((SymmetricKeyAlgorithmTag)plain[0]); }
private void ProcessSymmetricKeyDataForElGamal(IPgpPrivateKey privateKey, IBufferedCipher cipher, IList<IBigInteger> symmetricKeyData) { var k = (ElGamalPrivateKeyParameters)privateKey.Key; var size = (k.Parameters.P.BitLength + 7) / 8; var bi = symmetricKeyData[0].ToByteArray(); var diff = bi.Length - size; if (diff >= 0) { cipher.ProcessBytes(bi, diff, size); } else { var zeros = new byte[-diff]; cipher.ProcessBytes(zeros); cipher.ProcessBytes(bi); } bi = symmetricKeyData[1].ToByteArray(); diff = bi.Length - size; if (diff >= 0) { cipher.ProcessBytes(bi, diff, size); } else { var zeros = new byte[-diff]; cipher.ProcessBytes(zeros); cipher.ProcessBytes(bi); } }
/// <summary> /// Return the decrypted data stream for the packet. /// </summary> /// <param name="privKey">The priv key.</param> /// <returns></returns> /// <exception cref="PgpException"> /// exception creating cipher /// or /// Exception starting decryption /// </exception> /// <exception cref="System.IO.EndOfStreamException"> /// unexpected end of stream. /// or /// unexpected end of stream. /// </exception> public Stream GetDataStream(IPgpPrivateKey privKey) { SymmetricKeyAlgorithmTag encryptionAlgorithm; return this.GetDataStream(privKey, out encryptionAlgorithm); }
/** * decrypt the passed in message stream */ private static void DecryptFile( Stream inputStream, Stream keyIn, char[] passwd, string defaultFileName) { inputStream = PgpUtilities.GetDecoderStream(inputStream); try { PgpObjectFactory pgpF = new PgpObjectFactory(inputStream); PgpEncryptedDataList enc; PgpObject o = pgpF.NextPgpObject(); // // the first object might be a PGP marker packet. // if (o is PgpEncryptedDataList) { enc = (PgpEncryptedDataList)o; } else { enc = (PgpEncryptedDataList)pgpF.NextPgpObject(); } // // find the secret key // IPgpPrivateKey sKey = null; PgpPublicKeyEncryptedData pbe = null; PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle( PgpUtilities.GetDecoderStream(keyIn)); foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects()) { sKey = PgpExampleUtilities.FindSecretKey(pgpSec, pked.KeyId, passwd); if (sKey != null) { pbe = pked; break; } } if (sKey == null) { throw new ArgumentException("secret key for message not found."); } Stream clear = pbe.GetDataStream(sKey); PgpObjectFactory plainFact = new PgpObjectFactory(clear); PgpObject message = plainFact.NextPgpObject(); if (message is PgpCompressedData) { PgpCompressedData cData = (PgpCompressedData)message; PgpObjectFactory pgpFact = new PgpObjectFactory(cData.GetDataStream()); message = pgpFact.NextPgpObject(); } if (message is PgpLiteralData) { PgpLiteralData ld = (PgpLiteralData)message; string outFileName = ld.FileName; if (outFileName.Length == 0) { outFileName = defaultFileName; } Stream fOut = File.Create(outFileName); Stream unc = ld.GetInputStream(); Streams.PipeAll(unc, fOut); fOut.Close(); } else if (message is PgpOnePassSignatureList) { throw new PgpException("encrypted message contains a signed message - not literal data."); } else { throw new PgpException("message is not a simple encrypted file - type unknown."); } if (pbe.IsIntegrityProtected()) { if (!pbe.Verify()) { Console.Error.WriteLine("message failed integrity check"); } else { Console.Error.WriteLine("message integrity check passed"); } } else { Console.Error.WriteLine("no message integrity check"); } } catch (PgpException e) { Console.Error.WriteLine(e); Exception underlyingException = e.InnerException; if (underlyingException != null) { Console.Error.WriteLine(underlyingException.Message); Console.Error.WriteLine(underlyingException.StackTrace); } } }
/// <summary> /// Gets the data stream. /// </summary> /// <param name="privKey">The priv key.</param> /// <param name="encryptionAlgorithm">The encryption algorithm.</param> /// <returns></returns> /// <exception cref="Org.BouncyCastle.Bcpg.OpenPgp.PgpException"> /// exception creating cipher /// or /// Exception starting decryption /// </exception> /// <exception cref="System.IO.EndOfStreamException"> /// unexpected end of stream. /// or /// unexpected end of stream. /// </exception> public Stream GetDataStream(IPgpPrivateKey privKey, out SymmetricKeyAlgorithmTag encryptionAlgorithm) { var plain = this.FetchSymmetricKeyData(privKey); encryptionAlgorithm = (SymmetricKeyAlgorithmTag)plain[0]; IBufferedCipher c2; var cipherName = PgpUtilities.GetSymmetricCipherName(encryptionAlgorithm); var cName = cipherName; try { if (EncData is SymmetricEncIntegrityPacket) { cName += "/CFB/NoPadding"; } else { cName += "/OpenPGPCFB/NoPadding"; } c2 = CipherUtilities.GetCipher(cName); } catch (PgpException) { throw; } catch (Exception e) { throw new PgpException("exception creating cipher", e); } if (c2 == null) { return(EncData.GetInputStream()); } try { var key = ParameterUtilities.CreateKeyParameter(cipherName, plain, 1, plain.Length - 3); var iv = new byte[c2.GetBlockSize()]; c2.Init(false, new ParametersWithIV(key, iv)); this.EncStream = BcpgInputStream.Wrap(new CipherStream(EncData.GetInputStream(), c2, null)); if (this.EncData is SymmetricEncIntegrityPacket) { this.TruncStream = new TruncatedStream(this.EncStream); var digest = DigestUtilities.GetDigest(PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1)); EncStream = new DigestStream(TruncStream, digest, null); } if (Streams.ReadFully(EncStream, iv, 0, iv.Length) < iv.Length) { throw new EndOfStreamException("unexpected end of stream."); } var v1 = this.EncStream.ReadByte(); var v2 = this.EncStream.ReadByte(); if (v1 < 0 || v2 < 0) { throw new EndOfStreamException("unexpected end of stream."); } // Note: the oracle attack on the "quick check" bytes is deemed // a security risk for typical public key encryption usages, // therefore we do not perform the check. // bool repeatCheckPassed = // iv[iv.Length - 2] == (byte)v1 // && iv[iv.Length - 1] == (byte)v2; // // // Note: some versions of PGP appear to produce 0 for the extra // // bytes rather than repeating the two previous bytes // bool zeroesCheckPassed = // v1 == 0 // && v2 == 0; // // if (!repeatCheckPassed && !zeroesCheckPassed) // { // throw new PgpDataValidationException("quick check failed."); // } return(this.EncStream); } catch (PgpException) { throw; } catch (Exception e) { throw new PgpException("Exception starting decryption", e); } }
/// <summary> /// Return the decrypted data stream for the packet. /// </summary> /// <param name="privKey">The priv key.</param> /// <returns></returns> /// <exception cref="PgpException"> /// exception creating cipher /// or /// Exception starting decryption /// </exception> /// <exception cref="System.IO.EndOfStreamException"> /// unexpected end of stream. /// or /// unexpected end of stream. /// </exception> public Stream GetDataStream(IPgpPrivateKey privKey) { SymmetricKeyAlgorithmTag encryptionAlgorithm; return(this.GetDataStream(privKey, out encryptionAlgorithm)); }
private void doTestTextSigV3( PublicKeyAlgorithmTag encAlgorithm, HashAlgorithmTag hashAlgorithm, IPgpPublicKey pubKey, IPgpPrivateKey privKey, byte[] data, byte[] canonicalData) { PgpV3SignatureGenerator sGen = new PgpV3SignatureGenerator(encAlgorithm, HashAlgorithmTag.Sha1); MemoryStream bOut = new MemoryStream(); MemoryStream testIn = new MemoryStream(data, false); sGen.InitSign(PgpSignature.CanonicalTextDocument, privKey); sGen.GenerateOnePassVersion(false).Encode(bOut); PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator(); Stream lOut = lGen.Open( new UncloseableStream(bOut), PgpLiteralData.Text, "_CONSOLE", data.Length * 2, DateTime.UtcNow); int ch; while ((ch = testIn.ReadByte()) >= 0) { lOut.WriteByte((byte)ch); sGen.Update((byte)ch); } lOut.Write(data, 0, data.Length); sGen.Update(data); lGen.Close(); PgpSignature sig = sGen.Generate(); if (sig.CreationTime == DateTimeUtilities.UnixMsToDateTime(0)) { Fail("creation time not set in v3 signature"); } sig.Encode(bOut); verifySignature(bOut.ToArray(), hashAlgorithm, pubKey, canonicalData); }
private byte[] ProcessSymmetricKeyDataForEcdh(IPgpPrivateKey privKey, IList<IBigInteger> symmetricKeyData) { var encSymKey = symmetricKeyData[1].ToByteArrayUnsigned(); var privateKey = (ECDHPrivateKeyParameters)privKey.Key; var publicKey = privateKey.PublicKeyParameters; var ephemeralKey = ECDHPublicKeyParameters.Create(symmetricKeyData[0], publicKey.PublicKeyParamSet, publicKey.HashAlgorithm, publicKey.SymmetricKeyAlgorithm); var engine = new RFC6637ECDHEngine(); engine.InitForDecryption(privateKey, ephemeralKey); return engine.ProcessBlock(encSymKey, 0, encSymKey.Length); }
/// <summary> /// Return the algorithm code for the symmetric algorithm used to encrypt the data. /// </summary> /// <param name="privKey">The priv key.</param> /// <returns></returns> public SymmetricKeyAlgorithmTag GetSymmetricAlgorithm(IPgpPrivateKey privKey) { var plain = FetchSymmetricKeyData(privKey); return (SymmetricKeyAlgorithmTag)plain[0]; }
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(); }
/** * Generated signature test * * @param sKey * @param pgpPrivKey * @return test result */ public void GenerateTest( PgpSecretKeyRing sKey, IPgpPublicKey pgpPubKey, IPgpPrivateKey pgpPrivKey) { string data = "hello world!"; MemoryStream bOut = new MemoryStream(); byte[] dataBytes = Encoding.ASCII.GetBytes(data); MemoryStream testIn = new MemoryStream(dataBytes, false); PgpSignatureGenerator sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1); sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey); PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator(); IEnumerator enumerator = sKey.GetSecretKey().PublicKey.GetUserIds().GetEnumerator(); enumerator.MoveNext(); string primaryUserId = (string) enumerator.Current; spGen.SetSignerUserId(true, primaryUserId); sGen.SetHashedSubpackets(spGen.Generate()); 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(); PgpObjectFactory 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(pgpPubKey); while ((ch = dIn.ReadByte()) >= 0) { ops.Update((byte) ch); } PgpSignatureList p3 = (PgpSignatureList) pgpFact.NextPgpObject(); if (!ops.Verify(p3[0])) { Fail("Failed generated signature check"); } }
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; }
/// <summary> /// Gets the data stream. /// </summary> /// <param name="privKey">The priv key.</param> /// <param name="encryptionAlgorithm">The encryption algorithm.</param> /// <returns></returns> /// <exception cref="Org.BouncyCastle.Bcpg.OpenPgp.PgpException"> /// exception creating cipher /// or /// Exception starting decryption /// </exception> /// <exception cref="System.IO.EndOfStreamException"> /// unexpected end of stream. /// or /// unexpected end of stream. /// </exception> public Stream GetDataStream(IPgpPrivateKey privKey, out SymmetricKeyAlgorithmTag encryptionAlgorithm) { var plain = this.FetchSymmetricKeyData(privKey); encryptionAlgorithm = (SymmetricKeyAlgorithmTag)plain[0]; IBufferedCipher c2; var cipherName = PgpUtilities.GetSymmetricCipherName(encryptionAlgorithm); var cName = cipherName; try { if (EncData is SymmetricEncIntegrityPacket) { cName += "/CFB/NoPadding"; } else { cName += "/OpenPGPCFB/NoPadding"; } c2 = CipherUtilities.GetCipher(cName); } catch (PgpException) { throw; } catch (Exception e) { throw new PgpException("exception creating cipher", e); } if (c2 == null) return EncData.GetInputStream(); try { var key = ParameterUtilities.CreateKeyParameter(cipherName, plain, 1, plain.Length - 3); var iv = new byte[c2.GetBlockSize()]; c2.Init(false, new ParametersWithIV(key, iv)); this.EncStream = BcpgInputStream.Wrap(new CipherStream(EncData.GetInputStream(), c2, null)); if (this.EncData is SymmetricEncIntegrityPacket) { this.TruncStream = new TruncatedStream(this.EncStream); var digest = DigestUtilities.GetDigest(PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1)); EncStream = new DigestStream(TruncStream, digest, null); } if (Streams.ReadFully(EncStream, iv, 0, iv.Length) < iv.Length) throw new EndOfStreamException("unexpected end of stream."); var v1 = this.EncStream.ReadByte(); var v2 = this.EncStream.ReadByte(); if (v1 < 0 || v2 < 0) throw new EndOfStreamException("unexpected end of stream."); // Note: the oracle attack on the "quick check" bytes is deemed // a security risk for typical public key encryption usages, // therefore we do not perform the check. // bool repeatCheckPassed = // iv[iv.Length - 2] == (byte)v1 // && iv[iv.Length - 1] == (byte)v2; // // // Note: some versions of PGP appear to produce 0 for the extra // // bytes rather than repeating the two previous bytes // bool zeroesCheckPassed = // v1 == 0 // && v2 == 0; // // if (!repeatCheckPassed && !zeroesCheckPassed) // { // throw new PgpDataValidationException("quick check failed."); // } return this.EncStream; } catch (PgpException) { throw; } catch (Exception e) { throw new PgpException("Exception starting decryption", e); } }
private byte[] generateV3BinarySig( IPgpPrivateKey privKey, PublicKeyAlgorithmTag encAlgorithm, HashAlgorithmTag hashAlgorithm) { MemoryStream bOut = new MemoryStream(); MemoryStream testIn = new MemoryStream(TEST_DATA, false); PgpV3SignatureGenerator sGen = new PgpV3SignatureGenerator(encAlgorithm, hashAlgorithm); sGen.InitSign(PgpSignature.BinaryDocument, privKey); sGen.GenerateOnePassVersion(false).Encode(bOut); PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator(); Stream lOut = lGen.Open( new UncloseableStream(bOut), PgpLiteralData.Binary, "_CONSOLE", TEST_DATA.Length * 2, DateTime.UtcNow); int ch; while ((ch = testIn.ReadByte()) >= 0) { lOut.WriteByte((byte)ch); sGen.Update((byte)ch); } lOut.Write(TEST_DATA, 0, TEST_DATA.Length); sGen.Update(TEST_DATA); lGen.Close(); sGen.Generate().Encode(bOut); return bOut.ToArray(); }
private void PerformTestSig( HashAlgorithmTag hashAlgorithm, IPgpPublicKey pubKey, IPgpPrivateKey privKey) { const string data = "hello world!"; byte[] dataBytes = Encoding.ASCII.GetBytes(data); MemoryStream bOut = new UncloseableMemoryStream(); MemoryStream testIn = new MemoryStream(dataBytes, false); PgpSignatureGenerator sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.RsaGeneral, hashAlgorithm); sGen.InitSign(PgpSignature.BinaryDocument, privKey); 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); // TODO Need a stream object to automatically call Update? // (via ISigner implementation of PgpSignatureGenerator) int ch; while ((ch = testIn.ReadByte()) >= 0) { lOut.WriteByte((byte)ch); sGen.Update((byte)ch); } lOut.Close(); sGen.Generate().Encode(bcOut); bcOut.Close(); // // verify generated signature // PgpObjectFactory 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); // TODO Need a stream object to automatically call Update? // (via ISigner implementation of PgpSignatureGenerator) while ((ch = dIn.ReadByte()) >= 0) { ops.Update((byte)ch); } PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject(); if (!ops.Verify(p3[0])) { Fail("Failed generated signature check - " + hashAlgorithm); } }