diff options
author | David Hook <david.hook@keyfactor.com> | 2022-11-07 17:30:00 +1100 |
---|---|---|
committer | David Hook <david.hook@keyfactor.com> | 2022-11-07 17:30:00 +1100 |
commit | 146be77300207031b6b9477b8e48428278e841b8 (patch) | |
tree | d7342aad04bca424b56229d1d5eba558bbb4afd3 /crypto/test/src | |
parent | resolve conflicts (diff) | |
parent | GOST 2012 private key reading (diff) | |
download | BouncyCastle.NET-ed25519-146be77300207031b6b9477b8e48428278e841b8.tar.xz |
Merge branch 'master' of gitlab.cryptoworkshop.com:root/bc-csharp
Diffstat (limited to 'crypto/test/src')
-rw-r--r-- | crypto/test/src/cms/test/CMSTestUtil.cs | 10 | ||||
-rw-r--r-- | crypto/test/src/cms/test/SignedDataStreamTest.cs | 112 | ||||
-rw-r--r-- | crypto/test/src/crypto/test/HkdfGeneratorTest.cs (renamed from crypto/test/src/crypto/test/HKDFGeneratorTest.cs) | 0 | ||||
-rw-r--r-- | crypto/test/src/math/ec/test/ECPointPerformanceTest.cs | 14 | ||||
-rw-r--r-- | crypto/test/src/math/test/BigIntegerTest.cs | 2 | ||||
-rw-r--r-- | crypto/test/src/openpgp/test/DSA2Test.cs | 14 | ||||
-rw-r--r-- | crypto/test/src/openpgp/test/PgpECDHTest.cs | 74 | ||||
-rw-r--r-- | crypto/test/src/openpgp/test/PgpEdDsaTest.cs | 334 | ||||
-rw-r--r-- | crypto/test/src/openpgp/test/PgpKeyRingTest.cs | 79 | ||||
-rw-r--r-- | crypto/test/src/openssl/test/ReaderTest.cs | 18 | ||||
-rw-r--r-- | crypto/test/src/security/test/TestDotNetUtil.cs | 32 | ||||
-rw-r--r-- | crypto/test/src/tls/test/LoggingDatagramTransport.cs | 62 | ||||
-rw-r--r-- | crypto/test/src/tls/test/MockDatagramAssociation.cs | 59 | ||||
-rw-r--r-- | crypto/test/src/tls/test/UnreliableDatagramTransport.cs | 47 | ||||
-rw-r--r-- | crypto/test/src/tsp/test/TSPTestUtil.cs | 2 | ||||
-rw-r--r-- | crypto/test/src/util/test/SimpleTest.cs | 4 |
16 files changed, 826 insertions, 37 deletions
diff --git a/crypto/test/src/cms/test/CMSTestUtil.cs b/crypto/test/src/cms/test/CMSTestUtil.cs index e98810c84..e7ec50f53 100644 --- a/crypto/test/src/cms/test/CMSTestUtil.cs +++ b/crypto/test/src/cms/test/CMSTestUtil.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Text; +using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.CryptoPro; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; @@ -455,6 +456,15 @@ namespace Org.BouncyCastle.Cms.Tests return CollectionUtilities.CreateStore(crlList); } + internal static IStore<Asn1Encodable> MakeOtherRevocationInfoStore(byte[] ocspResponseBytes) + { + var otherRevocationInfoList = new List<Asn1Encodable> + { + Asn1Object.FromByteArray(ocspResponseBytes) + }; + return CollectionUtilities.CreateStore(otherRevocationInfoList); + } + private static AuthorityKeyIdentifier CreateAuthorityKeyId( AsymmetricKeyParameter _pubKey) { diff --git a/crypto/test/src/cms/test/SignedDataStreamTest.cs b/crypto/test/src/cms/test/SignedDataStreamTest.cs index 37f41783d..3d7892c6d 100644 --- a/crypto/test/src/cms/test/SignedDataStreamTest.cs +++ b/crypto/test/src/cms/test/SignedDataStreamTest.cs @@ -38,6 +38,40 @@ namespace Org.BouncyCastle.Cms.Tests private static X509Crl signCrl; private static X509Crl origCrl; + private static readonly byte[] OcspResponseBytes = Base64.Decode( + "MIIFnAoBAKCCBZUwggWRBgkrBgEFBQcwAQEEggWCMIIFfjCCARehgZ8wgZwx" + + "CzAJBgNVBAYTAklOMRcwFQYDVQQIEw5BbmRocmEgcHJhZGVzaDESMBAGA1UE" + + "BxMJSHlkZXJhYmFkMQwwCgYDVQQKEwNUQ1MxDDAKBgNVBAsTA0FUQzEeMBwG" + + "A1UEAxMVVENTLUNBIE9DU1AgUmVzcG9uZGVyMSQwIgYJKoZIhvcNAQkBFhVv" + + "Y3NwQHRjcy1jYS50Y3MuY28uaW4YDzIwMDMwNDAyMTIzNDU4WjBiMGAwOjAJ" + + "BgUrDgMCGgUABBRs07IuoCWNmcEl1oHwIak1BPnX8QQUtGyl/iL9WJ1VxjxF" + + "j0hAwJ/s1AcCAQKhERgPMjAwMjA4MjkwNzA5MjZaGA8yMDAzMDQwMjEyMzQ1" + + "OFowDQYJKoZIhvcNAQEFBQADgYEAfbN0TCRFKdhsmvOdUoiJ+qvygGBzDxD/" + + "VWhXYA+16AphHLIWNABR3CgHB3zWtdy2j7DJmQ/R7qKj7dUhWLSqclAiPgFt" + + "QQ1YvSJAYfEIdyHkxv4NP0LSogxrumANcDyC9yt/W9yHjD2ICPBIqCsZLuLk" + + "OHYi5DlwWe9Zm9VFwCGgggPMMIIDyDCCA8QwggKsoAMCAQICAQYwDQYJKoZI" + + "hvcNAQEFBQAwgZQxFDASBgNVBAMTC1RDUy1DQSBPQ1NQMSYwJAYJKoZIhvcN" + + "AQkBFhd0Y3MtY2FAdGNzLWNhLnRjcy5jby5pbjEMMAoGA1UEChMDVENTMQww" + + "CgYDVQQLEwNBVEMxEjAQBgNVBAcTCUh5ZGVyYWJhZDEXMBUGA1UECBMOQW5k" + + "aHJhIHByYWRlc2gxCzAJBgNVBAYTAklOMB4XDTAyMDgyOTA3MTE0M1oXDTAz" + + "MDgyOTA3MTE0M1owgZwxCzAJBgNVBAYTAklOMRcwFQYDVQQIEw5BbmRocmEg" + + "cHJhZGVzaDESMBAGA1UEBxMJSHlkZXJhYmFkMQwwCgYDVQQKEwNUQ1MxDDAK" + + "BgNVBAsTA0FUQzEeMBwGA1UEAxMVVENTLUNBIE9DU1AgUmVzcG9uZGVyMSQw" + + "IgYJKoZIhvcNAQkBFhVvY3NwQHRjcy1jYS50Y3MuY28uaW4wgZ8wDQYJKoZI" + + "hvcNAQEBBQADgY0AMIGJAoGBAM+XWW4caMRv46D7L6Bv8iwtKgmQu0SAybmF" + + "RJiz12qXzdvTLt8C75OdgmUomxp0+gW/4XlTPUqOMQWv463aZRv9Ust4f8MH" + + "EJh4ekP/NS9+d8vEO3P40ntQkmSMcFmtA9E1koUtQ3MSJlcs441JjbgUaVnm" + + "jDmmniQnZY4bU3tVAgMBAAGjgZowgZcwDAYDVR0TAQH/BAIwADALBgNVHQ8E" + + "BAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwkwNgYIKwYBBQUHAQEEKjAoMCYG" + + "CCsGAQUFBzABhhpodHRwOi8vMTcyLjE5LjQwLjExMDo3NzAwLzAtBgNVHR8E" + + "JjAkMCKgIKAehhxodHRwOi8vMTcyLjE5LjQwLjExMC9jcmwuY3JsMA0GCSqG" + + "SIb3DQEBBQUAA4IBAQB6FovM3B4VDDZ15o12gnADZsIk9fTAczLlcrmXLNN4" + + "PgmqgnwF0Ymj3bD5SavDOXxbA65AZJ7rBNAguLUo+xVkgxmoBH7R2sBxjTCc" + + "r07NEadxM3HQkt0aX5XYEl8eRoifwqYAI9h0ziZfTNes8elNfb3DoPPjqq6V" + + "mMg0f0iMS4W8LjNPorjRB+kIosa1deAGPhq0eJ8yr0/s2QR2/WFD5P4aXc8I" + + "KWleklnIImS3zqiPrq6tl2Bm8DZj7vXlTOwmraSQxUwzCKwYob1yGvNOUQTq" + + "pG6jxn7jgDawHU1+WjWQe4Q34/pWeGLysxTraMa+Ug9kPe+jy/qRX2xwvKBZ"); + private static AsymmetricCipherKeyPair SignKP { get { return signKP == null ? (signKP = CmsTestUtil.MakeKeyPair()) : signKP; } @@ -341,7 +375,83 @@ namespace Org.BouncyCastle.Cms.Tests Assert.IsTrue(col.Contains(OrigCrl)); } - [Test] + [Test] + public void TestCrlAndOtherRevocationInfoFormat() + { + MemoryStream bOut = new MemoryStream(); + + var x509Certs = CmsTestUtil.MakeCertStore(OrigCert, SignCert); + var x509Crls = CmsTestUtil.MakeCrlStore(SignCrl, OrigCrl); + var x509OtherRevocationInfos = CmsTestUtil.MakeOtherRevocationInfoStore(OcspResponseBytes); + + CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator(); + gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedGenerator.DigestSha1); + gen.AddCertificates(x509Certs); + gen.AddCrls(x509Crls); + gen.AddOtherRevocationInfos(CmsObjectIdentifiers.id_ri_ocsp_response, x509OtherRevocationInfos); + + Stream sigOut = gen.Open(bOut); + + byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage); + sigOut.Write(testBytes, 0, testBytes.Length); + + sigOut.Close(); + + CheckSigParseable(bOut.ToArray()); + + CmsSignedDataParser sp = new CmsSignedDataParser( + new CmsTypedStream(new MemoryStream(testBytes, false)), bOut.ToArray()); + + sp.GetSignedContent().Drain(); + + // compute expected content digest + byte[] hash = DigestUtilities.CalculateDigest("SHA1", testBytes); + + VerifySignatures(sp, hash); + + // + // try using existing signer + // + gen = new CmsSignedDataStreamGenerator(); + gen.AddSigners(sp.GetSignerInfos()); + gen.AddCertificates(sp.GetCertificates()); + gen.AddCrls(sp.GetCrls()); + + var spOtherRevocationInfos = sp.GetOtherRevInfos(CmsObjectIdentifiers.id_ri_ocsp_response); + gen.AddOtherRevocationInfos(CmsObjectIdentifiers.id_ri_ocsp_response, spOtherRevocationInfos); + + bOut.SetLength(0); + + sigOut = gen.Open(bOut, true); + sigOut.Write(testBytes, 0, testBytes.Length); + sigOut.Close(); + + VerifyEncodedData(bOut); + + // + // look for the CRLs + // + var crls = new List<X509Crl>(x509Crls.EnumerateMatches(null)); + + Assert.AreEqual(2, crls.Count); + Assert.IsTrue(crls.Contains(SignCrl)); + Assert.IsTrue(crls.Contains(OrigCrl)); + + // + // look for OtherRevocationInfo + // + var x509OtherRevocationInfoList = new List<Asn1Encodable>( + x509OtherRevocationInfos.EnumerateMatches(null)); + + Assert.AreEqual(1, x509OtherRevocationInfoList.Count); + + var spOtherRevocationInfoList = new List<Asn1Encodable>( + spOtherRevocationInfos.EnumerateMatches(null)); + + Assert.AreEqual(1, spOtherRevocationInfoList.Count); + } + + [Test] public void TestSha1WithRsaNonData() { MemoryStream bOut = new MemoryStream(); diff --git a/crypto/test/src/crypto/test/HKDFGeneratorTest.cs b/crypto/test/src/crypto/test/HkdfGeneratorTest.cs index fa540e41e..fa540e41e 100644 --- a/crypto/test/src/crypto/test/HKDFGeneratorTest.cs +++ b/crypto/test/src/crypto/test/HkdfGeneratorTest.cs diff --git a/crypto/test/src/math/ec/test/ECPointPerformanceTest.cs b/crypto/test/src/math/ec/test/ECPointPerformanceTest.cs index 18051226b..49ae6d195 100644 --- a/crypto/test/src/math/ec/test/ECPointPerformanceTest.cs +++ b/crypto/test/src/math/ec/test/ECPointPerformanceTest.cs @@ -29,7 +29,7 @@ namespace Org.BouncyCastle.Math.EC.Tests private static string[] COORD_NAMES = new string[]{ "AFFINE", "HOMOGENEOUS", "JACOBIAN", "JACOBIAN-CHUDNOVSKY", "JACOBIAN-MODIFIED", "LAMBDA-AFFINE", "LAMBDA-PROJECTIVE", "SKEWED" }; - private void RandMult(string curveName) + private static void RandMult(string curveName) { X9ECParameters spec = ECNamedCurveTable.GetByName(curveName); if (spec != null) @@ -44,13 +44,13 @@ namespace Org.BouncyCastle.Math.EC.Tests } } - private void RandMult(string label, X9ECParameters spec) + private static void RandMult(string label, X9ECParameters spec) { ECCurve C = spec.Curve; - ECPoint G = (ECPoint)spec.G; + ECPoint G = spec.G; BigInteger n = spec.N; - SecureRandom random = new SecureRandom(); + var random = new SecureRandom(); random.SetSeed(DateTimeUtilities.CurrentUnixMs()); Console.WriteLine(label); @@ -98,7 +98,7 @@ namespace Org.BouncyCastle.Math.EC.Tests Console.Out.Flush(); } - private double RandMult(SecureRandom random, ECPoint g, BigInteger n) + private static double RandMult(SecureRandom random, ECPoint g, BigInteger n) { BigInteger[] ks = new BigInteger[128]; for (int i = 0; i < ks.Length; ++i) @@ -107,7 +107,7 @@ namespace Org.BouncyCastle.Math.EC.Tests } int ki = 0; - ECPoint p = g; + ECPoint p; { long startTime = DateTimeUtilities.CurrentUnixMs(); @@ -129,7 +129,7 @@ namespace Org.BouncyCastle.Math.EC.Tests while (DateTimeUtilities.CurrentUnixMs() < goalTime); } - double minRate = Double.MaxValue, maxRate = Double.MinValue, totalRate = 0.0; + double minRate = double.MaxValue, maxRate = double.MinValue, totalRate = 0.0; for (int i = 1; i <= NUM_ROUNDS; i++) { diff --git a/crypto/test/src/math/test/BigIntegerTest.cs b/crypto/test/src/math/test/BigIntegerTest.cs index f5973c197..8f477d684 100644 --- a/crypto/test/src/math/test/BigIntegerTest.cs +++ b/crypto/test/src/math/test/BigIntegerTest.cs @@ -773,11 +773,13 @@ namespace Org.BouncyCastle.Math.Tests BigInteger x = new BigInteger(128, random); object y; +#pragma warning disable SYSLIB0011 // Type or member is obsolete var formatter = new BinaryFormatter(); formatter.Serialize(buf, x); buf.Position = 0; y = formatter.Deserialize(buf); +#pragma warning restore SYSLIB0011 // Type or member is obsolete Assert.AreEqual(buf.Length, buf.Position); Assert.AreEqual(x, y); diff --git a/crypto/test/src/openpgp/test/DSA2Test.cs b/crypto/test/src/openpgp/test/DSA2Test.cs index 507afceae..54c2cb2b5 100644 --- a/crypto/test/src/openpgp/test/DSA2Test.cs +++ b/crypto/test/src/openpgp/test/DSA2Test.cs @@ -73,40 +73,40 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests [Test] public void TestGenerateK1024H224() { - doSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", HashAlgorithmTag.Sha224); + DoSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", HashAlgorithmTag.Sha224); } [Test] public void TestGenerateK1024H256() { - doSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", HashAlgorithmTag.Sha256); + DoSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", HashAlgorithmTag.Sha256); } [Test] public void TestGenerateK1024H384() { - doSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", HashAlgorithmTag.Sha384); + DoSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", HashAlgorithmTag.Sha384); } [Test] public void TestGenerateK1024H512() { - doSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", HashAlgorithmTag.Sha512); + DoSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", HashAlgorithmTag.Sha512); } [Test] public void TestGenerateK2048H256() { - doSigGenerateTest("DSA-2048-224.sec", "DSA-2048-224.pub", HashAlgorithmTag.Sha256); + DoSigGenerateTest("DSA-2048-224.sec", "DSA-2048-224.pub", HashAlgorithmTag.Sha256); } [Test] public void TestGenerateK2048H512() { - doSigGenerateTest("DSA-2048-224.sec", "DSA-2048-224.pub", HashAlgorithmTag.Sha512); + DoSigGenerateTest("DSA-2048-224.sec", "DSA-2048-224.pub", HashAlgorithmTag.Sha512); } - private void doSigGenerateTest( + private void DoSigGenerateTest( string privateKeyFile, string publicKeyFile, HashAlgorithmTag digest) diff --git a/crypto/test/src/openpgp/test/PgpECDHTest.cs b/crypto/test/src/openpgp/test/PgpECDHTest.cs index aa4fc2117..45dd641f1 100644 --- a/crypto/test/src/openpgp/test/PgpECDHTest.cs +++ b/crypto/test/src/openpgp/test/PgpECDHTest.cs @@ -51,6 +51,41 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests "6HiuFH7VKWcxPUBjXwf5+Z3uOKEp28tBgNyDrdbr1BbqlgYzIKq/pe9zUbUXfitn" + "vFc6HcGhvmRQreQ+Yw1x3x0HJeoPwg=="); + private static readonly byte[] curve25519Message = Base64.Decode( + "hE4Dg5N9lpwvavoSAQdApL1xhvz/28almLuqHjyrzwVRnB+37yODIRZCkfPk" + + "GEIgd9uff5j8mYbI9ErePgRI47fDnQPu8mI4hTOhe8pHzyXSTwFf5CesSdME" + + "Td9g+UG6cYt/i+cHQWMQD7a53fMNFxPGVYLUFXC5cQh+KvBPghfdoFQMhbR+" + + "GDgauMrgtk//Os0WCYWJa7VZkD5ak3sbMwk="); + + //private static readonly byte[] curve25519Pub = Base64.Decode( + // "mDMEXEzydhYJKwYBBAHaRw8BAQdAwHPDYhq7hIsCT0jHNxGh4Mbao9kDkcHZilME" + + // "jfgnnG60N1Rlc3QgS2V5IChEbyBub3QgdXNlIGZvciByZWFsLikgPHRlc3RAd29v" + + // "ZHMtZ2VibGVyLmNvbT6IlgQTFggAPhYhBIuq+f4gKmIa9ZKEqJdUhr00IJstBQJc" + + // "TPJ2AhsDBQkB4TOABQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEJdUhr00IJst" + + // "dHAA/RDOjus5OZL2m9Q9dxOVnWNguT7Cr5cWdJxUeKAWE2c6AQCcQZWA4SmV1dkJ" + + // "U0XKmLeu3xWDpqrydT4+vQXb/Qm9B7g4BFxM8nYSCisGAQQBl1UBBQEBB0AY3XTS" + + // "6S1pwFNc1QhNpEKTStG+LAJpiHPK9QyXBbW9dQMBCAeIfgQYFggAJhYhBIuq+f4g" + + // "KmIa9ZKEqJdUhr00IJstBQJcTPJ2AhsMBQkB4TOAAAoJEJdUhr00IJstmAsBAMRJ" + + // "pvh8iegwrJDMoQc53ZqDRsbieElV6ofB80a+jkzZAQCgpAaY4hZc8GUan2JIqkg0" + + // "gs23h4au7H79KqXYG4a+Bg=="); + + private static readonly byte[] curve25519Priv = Base64.Decode( + "lIYEXEzydhYJKwYBBAHaRw8BAQdAwHPDYhq7hIsCT0jHNxGh4Mbao9kDkcHZilME" + + "jfgnnG7+BwMCgEr7OFDl3dTpT73rmw6vIwiTGqjx+Xbe8cq4l24q2AOtzO+UR97q" + + "7ypL41jtt7BY7uoxhF+NCKzYEtRoqyaM0lfjDlOVRJP6SYRixK2UHLQ3VGVzdCBL" + + "ZXkgKERvIG5vdCB1c2UgZm9yIHJlYWwuKSA8dGVzdEB3b29kcy1nZWJsZXIuY29t" + + "PoiWBBMWCAA+FiEEi6r5/iAqYhr1koSol1SGvTQgmy0FAlxM8nYCGwMFCQHhM4AF" + + "CwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQl1SGvTQgmy10cAD9EM6O6zk5kvab" + + "1D13E5WdY2C5PsKvlxZ0nFR4oBYTZzoBAJxBlYDhKZXV2QlTRcqYt67fFYOmqvJ1" + + "Pj69Bdv9Cb0HnIsEXEzydhIKKwYBBAGXVQEFAQEHQBjddNLpLWnAU1zVCE2kQpNK" + + "0b4sAmmIc8r1DJcFtb11AwEIB/4HAwItKjH+kGqkMelkEdIRxSLFeCsB/A64n+os" + + "X9nWVYsrixEWT5JcRWBniI1PKt9Cm15Yt8KQSAFDJIj5tnEm28x5RM0CzFHQ9Ej2" + + "8Q2Lt0RoiH4EGBYIACYWIQSLqvn+ICpiGvWShKiXVIa9NCCbLQUCXEzydgIbDAUJ" + + "AeEzgAAKCRCXVIa9NCCbLZgLAQDESab4fInoMKyQzKEHOd2ag0bG4nhJVeqHwfNG" + + "vo5M2QEAoKQGmOIWXPBlGp9iSKpINILNt4eGrux+/Sql2BuGvgY="); + + private static readonly char[] curve25519Pwd = "foobar".ToCharArray(); + private void Generate() { SecureRandom random = SecureRandom.GetInstance("SHA1PRNG"); @@ -105,6 +140,41 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests PgpPrivateKey pgpPrivKey = secRing.GetSecretKey().ExtractPrivateKey(passPhrase); } + private void TestCurve25519Message() + { + PgpSecretKeyRing ring = new PgpSecretKeyRing(curve25519Priv); + + PgpObjectFactory pgpF = new PgpObjectFactory(curve25519Message); + + PgpEncryptedDataList encList = (PgpEncryptedDataList)pgpF.NextPgpObject(); + + PgpPublicKeyEncryptedData encP = (PgpPublicKeyEncryptedData)encList[0]; + + Stream clear = encP.GetDataStream(ring.GetSecretKey(encP.KeyId).ExtractPrivateKey(curve25519Pwd)); + + pgpF = new PgpObjectFactory(clear); + + PgpCompressedData cd = (PgpCompressedData)pgpF.NextPgpObject(); + + PgpLiteralData ld = (PgpLiteralData)new PgpObjectFactory(cd.GetDataStream()).NextPgpObject(); + + clear = ld.GetInputStream(); + MemoryStream bOut = new MemoryStream(); + + int ch; + while ((ch = clear.ReadByte()) >= 0) + { + bOut.WriteByte((byte)ch); + } + + byte[] output = bOut.ToArray(); + + if (!AreEqual(output, Strings.ToByteArray("Hello world\n"))) + { + Fail("wrong plain text in generated packet"); + } + } + private void TestDecrypt(PgpSecretKeyRing secretKeyRing) { PgpObjectFactory pgpF = new PgpObjectFactory(testMessage); @@ -215,6 +285,8 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests EncryptDecryptTest(); + TestCurve25519Message(); + Generate(); } @@ -240,7 +312,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests { certification.InitVerify(pubKeyRing.GetPublicKey()); - if (!certification.VerifyCertification((string)First(pubKeyRing.GetPublicKey().GetUserIds()), pubKeyRing.GetPublicKey())) + if (!certification.VerifyCertification(First(pubKeyRing.GetPublicKey().GetUserIds()), pubKeyRing.GetPublicKey())) { Fail("subkey certification does not verify"); } diff --git a/crypto/test/src/openpgp/test/PgpEdDsaTest.cs b/crypto/test/src/openpgp/test/PgpEdDsaTest.cs new file mode 100644 index 000000000..c5b25320c --- /dev/null +++ b/crypto/test/src/openpgp/test/PgpEdDsaTest.cs @@ -0,0 +1,334 @@ +using System; +using System.Collections.Generic; +using System.IO; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests +{ + [TestFixture] + public class PgpEdDsaTest + : SimpleTest + { + private static readonly string edDSASampleKey = + "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" + + "Comment: Alice's OpenPGP certificate\n" + + "Comment: https://www.ietf.org/id/draft-bre-openpgp-samples-01.html\n" + + "\n" + + "mDMEXEcE6RYJKwYBBAHaRw8BAQdArjWwk3FAqyiFbFBKT4TzXcVBqPTB3gmzlC/U\n" + + "b7O1u120JkFsaWNlIExvdmVsYWNlIDxhbGljZUBvcGVucGdwLmV4YW1wbGU+iJAE\n" + + "ExYIADgCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQTrhbtfozp14V6UTmPy\n" + + "MVUMT0fjjgUCXaWfOgAKCRDyMVUMT0fjjukrAPoDnHBSogOmsHOsd9qGsiZpgRnO\n" + + "dypvbm+QtXZqth9rvwD9HcDC0tC+PHAsO7OTh1S1TC9RiJsvawAfCPaQZoed8gK4\n" + + "OARcRwTpEgorBgEEAZdVAQUBAQdAQv8GIa2rSTzgqbXCpDDYMiKRVitCsy203x3s\n" + + "E9+eviIDAQgHiHgEGBYIACAWIQTrhbtfozp14V6UTmPyMVUMT0fjjgUCXEcE6QIb\n" + + "DAAKCRDyMVUMT0fjjlnQAQDFHUs6TIcxrNTtEZFjUFm1M0PJ1Dng/cDW4xN80fsn\n" + + "0QEA22Kr7VkCjeAEC08VSTeV+QFsmz55/lntWkwYWhmvOgE=\n" + + "=iIGO\n" + + "-----END PGP PUBLIC KEY BLOCK-----\n"; + + private static readonly string edDSASecretKey = + "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + + "Comment: Alice's OpenPGP Transferable Secret Key\n" + + "Comment: https://www.ietf.org/id/draft-bre-openpgp-samples-01.html\n" + + "\n" + + "lFgEXEcE6RYJKwYBBAHaRw8BAQdArjWwk3FAqyiFbFBKT4TzXcVBqPTB3gmzlC/U\n" + + "b7O1u10AAP9XBeW6lzGOLx7zHH9AsUDUTb2pggYGMzd0P3ulJ2AfvQ4RtCZBbGlj\n" + + "ZSBMb3ZlbGFjZSA8YWxpY2VAb3BlbnBncC5leGFtcGxlPoiQBBMWCAA4AhsDBQsJ\n" + + "CAcCBhUKCQgLAgQWAgMBAh4BAheAFiEE64W7X6M6deFelE5j8jFVDE9H444FAl2l\n" + + "nzoACgkQ8jFVDE9H447pKwD6A5xwUqIDprBzrHfahrImaYEZzncqb25vkLV2arYf\n" + + "a78A/R3AwtLQvjxwLDuzk4dUtUwvUYibL2sAHwj2kGaHnfICnF0EXEcE6RIKKwYB\n" + + "BAGXVQEFAQEHQEL/BiGtq0k84Km1wqQw2DIikVYrQrMttN8d7BPfnr4iAwEIBwAA\n" + + "/3/xFPG6U17rhTuq+07gmEvaFYKfxRB6sgAYiW6TMTpQEK6IeAQYFggAIBYhBOuF\n" + + "u1+jOnXhXpROY/IxVQxPR+OOBQJcRwTpAhsMAAoJEPIxVQxPR+OOWdABAMUdSzpM\n" + + "hzGs1O0RkWNQWbUzQ8nUOeD9wNbjE3zR+yfRAQDbYqvtWQKN4AQLTxVJN5X5AWyb\n" + + "Pnn+We1aTBhaGa86AQ==\n" + + "=n8OM\n" + + "-----END PGP PRIVATE KEY BLOCK-----\n"; + + private static readonly string revBlock = + "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" + + "Comment: Alice's revocation certificate\n" + + "Comment: https://www.ietf.org/id/draft-bre-openpgp-samples-01.html\n" + + "\n" + + "iHgEIBYIACAWIQTrhbtfozp14V6UTmPyMVUMT0fjjgUCXaWkOwIdAAAKCRDyMVUM\n" + + "T0fjjoBlAQDA9ukZFKRFGCooVcVoDVmxTaHLUXlIg9TPh2f7zzI9KgD/SLNXUOaH\n" + + "O6TozOS7C9lwIHwwdHdAxgf5BzuhLT9iuAM=\n" + + "=Tm8h\n" + + "-----END PGP PUBLIC KEY BLOCK-----\n"; + + public override string Name + { + get { return "PgpEdDsaTest"; } + } + + private void EncryptDecryptTest(PgpPublicKey pubKey, PgpPrivateKey secKey) + { + 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'}; + + PgpLiteralDataGenerator lData = new PgpLiteralDataGenerator(); + MemoryStream ldOut = new MemoryStream(); + Stream pOut = lData.Open(ldOut, PgpLiteralDataGenerator.Utf8, PgpLiteralData.Console, text.Length, DateTime.UtcNow); + + pOut.Write(text, 0, text.Length); + pOut.Close(); + + byte[] data = ldOut.ToArray(); + + MemoryStream cbOut = new MemoryStream(); + + PgpEncryptedDataGenerator cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, new SecureRandom()); + cPk.AddMethod(pubKey); + + Stream cOut = cPk.Open(new UncloseableStream(cbOut), data.Length); + + cOut.Write(data, 0, data.Length); + cOut.Close(); + + PgpObjectFactory pgpF = new PgpObjectFactory(cbOut.ToArray()); + + PgpEncryptedDataList encList = (PgpEncryptedDataList)pgpF.NextPgpObject(); + + PgpPublicKeyEncryptedData encP = (PgpPublicKeyEncryptedData)encList[0]; + + Stream clear = encP.GetDataStream(secKey); + + pgpF = new PgpObjectFactory(clear); + + PgpLiteralData ld = (PgpLiteralData)pgpF.NextPgpObject(); + + clear = ld.GetInputStream(); + MemoryStream bOut = new MemoryStream(); + + int ch; + while ((ch = clear.ReadByte()) >= 0) + { + bOut.WriteByte((byte)ch); + } + + byte[] output = bOut.ToArray(); + + if (!AreEqual(output, text)) + { + Fail("wrong plain text in generated packet"); + } + } + + private void KeyRingTest() + { + SecureRandom random = new SecureRandom(); + + string identity = "eric@bouncycastle.org"; + char[] passPhrase = "Hello, world!".ToCharArray(); + + Ed25519KeyPairGenerator edKp = new Ed25519KeyPairGenerator(); + edKp.Init(new Ed25519KeyGenerationParameters(random)); + + PgpKeyPair dsaKeyPair = new PgpKeyPair(PublicKeyAlgorithmTag.EdDsa, edKp.GenerateKeyPair(), DateTime.UtcNow); + + X25519KeyPairGenerator dhKp = new X25519KeyPairGenerator(); + dhKp.Init(new X25519KeyGenerationParameters(random)); + + PgpKeyPair dhKeyPair = new PgpKeyPair(PublicKeyAlgorithmTag.ECDH, dhKp.GenerateKeyPair(), DateTime.UtcNow); + + EncryptDecryptTest(dhKeyPair.PublicKey, dhKeyPair.PrivateKey); + + PgpKeyRingGenerator keyRingGen = new PgpKeyRingGenerator(PgpSignature.PositiveCertification, dsaKeyPair, + identity, SymmetricKeyAlgorithmTag.Aes256, passPhrase, true, null, null, random); + + keyRingGen.AddSubKey(dhKeyPair); + + MemoryStream secretOut = new MemoryStream(); + + PgpSecretKeyRing secRing = keyRingGen.GenerateSecretKeyRing(); + + PgpPublicKeyRing pubRing = keyRingGen.GeneratePublicKeyRing(); + + secRing.Encode(secretOut); + + secretOut.Close(); + secRing = new PgpSecretKeyRing(secretOut.ToArray()); + + var publicKeys = new List<PgpPublicKey>(secRing.GetPublicKeys()); + + PgpPublicKey sKey = publicKeys[1]; + PgpPublicKey vKey = secRing.GetPublicKey(); + + int count = 0; + foreach (var sig in sKey.GetSignatures()) + { + if (sig.KeyId == vKey.KeyId + && sig.SignatureType == PgpSignature.SubkeyBinding) + { + count++; + sig.InitVerify(vKey); + + if (!sig.VerifyCertification(vKey, sKey)) + { + Fail("failed to verify sub-key signature."); + } + } + } + + IsTrue(count == 1); + + secRing = new PgpSecretKeyRing(secretOut.ToArray()); + PgpPublicKey pubKey = null; + PgpPrivateKey privKey = null; + + foreach (var candidate in secRing.GetPublicKeys()) + { + if (candidate.IsEncryptionKey) + { + pubKey = candidate; + privKey = secRing.GetSecretKey(pubKey.KeyId).ExtractPrivateKey(passPhrase); + break; + } + } + + EncryptDecryptTest(pubKey, privKey); + } + + public override void PerformTest() + { + ArmoredInputStream aIn = new ArmoredInputStream(new MemoryStream(Strings.ToByteArray(edDSASampleKey), false)); + + PgpPublicKeyRing pubKeyRing = new PgpPublicKeyRing(aIn); + + IsTrue(AreEqual(Hex.Decode("EB85 BB5F A33A 75E1 5E94 4E63 F231 550C 4F47 E38E"), + pubKeyRing.GetPublicKey().GetFingerprint())); + + aIn = new ArmoredInputStream(new MemoryStream(Strings.ToByteArray(edDSASecretKey), false)); + + PgpSecretKeyRing secRing = new PgpSecretKeyRing(aIn); + + IsTrue(secRing.GetSecretKey().IsSigningKey); + + PgpSignatureGenerator pgpGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.EdDsa, HashAlgorithmTag.Sha256); + + pgpGen.InitSign(PgpSignature.SubkeyBinding, secRing.GetSecretKey().ExtractPrivateKey(null)); + + PgpSignature sig = pgpGen.GenerateCertification(pubKeyRing.GetPublicKey(), + pubKeyRing.GetPublicKey(5145070902336167606L)); + + sig.InitVerify(pubKeyRing.GetPublicKey()); + + IsTrue(sig.VerifyCertification(pubKeyRing.GetPublicKey(), pubKeyRing.GetPublicKey(5145070902336167606L))); + + EncryptDecryptTest(pubKeyRing.GetPublicKey(5145070902336167606L), + secRing.GetSecretKey(5145070902336167606L).ExtractPrivateKey(null)); + + aIn = new ArmoredInputStream(new MemoryStream(Strings.ToByteArray(revBlock), false)); + + PgpSignatureList sigs = (PgpSignatureList)new PgpObjectFactory(aIn).NextPgpObject(); + + sig = sigs[0]; + + sig.InitVerify(pubKeyRing.GetPublicKey()); + + IsTrue(sig.VerifyCertification(pubKeyRing.GetPublicKey())); + + KeyRingTest(); + SksKeyTest(); + AliceKeyTest(); + } + + private void AliceKeyTest() + { + 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'}; + ArmoredInputStream aIn = new ArmoredInputStream(new MemoryStream(Strings.ToByteArray(edDSASampleKey), false)); + + PgpPublicKeyRing rng = new PgpPublicKeyRing(aIn); + + aIn = new ArmoredInputStream(new MemoryStream(Strings.ToByteArray(edDSASecretKey), false)); + + PgpSecretKeyRing secRing = new PgpSecretKeyRing(aIn); + + PgpPublicKey pubKey = rng.GetPublicKey(5145070902336167606L); + PgpPrivateKey privKey = secRing.GetSecretKey(5145070902336167606L).ExtractPrivateKey(null); + + PgpLiteralDataGenerator lData = new PgpLiteralDataGenerator(); + MemoryStream ldOut = new MemoryStream(); + Stream pOut = lData.Open(ldOut, PgpLiteralDataGenerator.Utf8, PgpLiteralData.Console, text.Length, DateTime.UtcNow); + + pOut.Write(text, 0, text.Length); + pOut.Close(); + + byte[] data = ldOut.ToArray(); + + MemoryStream cbOut = new MemoryStream(); + + PgpEncryptedDataGenerator cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Aes128, true); + + cPk.AddMethod(pubKey); + + Stream cOut = cPk.Open(new UncloseableStream(cbOut), data.Length); + + cOut.Write(data, 0, data.Length); + cOut.Close(); + + PgpObjectFactory pgpF = new PgpObjectFactory(cbOut.ToArray()); + + PgpEncryptedDataList encList = (PgpEncryptedDataList)pgpF.NextPgpObject(); + + PgpPublicKeyEncryptedData encP = (PgpPublicKeyEncryptedData)encList[0]; + + Stream clear = encP.GetDataStream(privKey); + + pgpF = new PgpObjectFactory(clear); + + PgpLiteralData ld = (PgpLiteralData)pgpF.NextPgpObject(); + + clear = ld.GetInputStream(); + MemoryStream bOut = new MemoryStream(); + + int ch; + while ((ch = clear.ReadByte()) >= 0) + { + bOut.WriteByte((byte)ch); + } + + byte[] output = bOut.ToArray(); + + if (!AreEqual(output, text)) + { + Fail("wrong plain text in generated packet"); + } + } + + private void SksKeyTest() + { + byte[] data = Strings.ToByteArray("testing, 1, 2, 3, testing..."); + + ArmoredInputStream aIn = new ArmoredInputStream(GetTestDataAsStream("openpgp.eddsa-sks-pub-keyring.asc")); + + // make sure we can parse it without falling over. + PgpPublicKeyRing rng = new PgpPublicKeyRing(aIn); + + PgpEncryptedDataGenerator encDataGen = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Aes128, true); + + encDataGen.AddMethod(rng.GetPublicKey(6752245936421807937L)); + + MemoryStream cbOut = new MemoryStream(); + + Stream cOut = encDataGen.Open(new UncloseableStream(cbOut), data.Length); + cOut.Write(data, 0, data.Length); + cOut.Close(); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + } +} diff --git a/crypto/test/src/openpgp/test/PgpKeyRingTest.cs b/crypto/test/src/openpgp/test/PgpKeyRingTest.cs index a5dc4963b..821a7f295 100644 --- a/crypto/test/src/openpgp/test/PgpKeyRingTest.cs +++ b/crypto/test/src/openpgp/test/PgpKeyRingTest.cs @@ -1346,6 +1346,35 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests + "WDoIM5gfjeZgwht1vl6+7J+h20yjFrBdf7gJj9OcIGmwlpQ56qzbT4U++mw3" + "pW2tN2VuYtreceEoI4B6yUGMEhI9t/asLgn7wEAU2lpuE7ACAAM="); + private static readonly byte[] curve25519Pub = Base64.Decode( + "mDMEXEzydhYJKwYBBAHaRw8BAQdAwHPDYhq7hIsCT0jHNxGh4Mbao9kDkcHZilME" + + "jfgnnG60N1Rlc3QgS2V5IChEbyBub3QgdXNlIGZvciByZWFsLikgPHRlc3RAd29v" + + "ZHMtZ2VibGVyLmNvbT6IlgQTFggAPhYhBIuq+f4gKmIa9ZKEqJdUhr00IJstBQJc" + + "TPJ2AhsDBQkB4TOABQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEJdUhr00IJst" + + "dHAA/RDOjus5OZL2m9Q9dxOVnWNguT7Cr5cWdJxUeKAWE2c6AQCcQZWA4SmV1dkJ" + + "U0XKmLeu3xWDpqrydT4+vQXb/Qm9B7g4BFxM8nYSCisGAQQBl1UBBQEBB0AY3XTS" + + "6S1pwFNc1QhNpEKTStG+LAJpiHPK9QyXBbW9dQMBCAeIfgQYFggAJhYhBIuq+f4g" + + "KmIa9ZKEqJdUhr00IJstBQJcTPJ2AhsMBQkB4TOAAAoJEJdUhr00IJstmAsBAMRJ" + + "pvh8iegwrJDMoQc53ZqDRsbieElV6ofB80a+jkzZAQCgpAaY4hZc8GUan2JIqkg0" + + "gs23h4au7H79KqXYG4a+Bg=="); + + private static readonly byte[] curve25519Priv = Base64.Decode( + "lIYEXEzydhYJKwYBBAHaRw8BAQdAwHPDYhq7hIsCT0jHNxGh4Mbao9kDkcHZilME" + + "jfgnnG7+BwMCgEr7OFDl3dTpT73rmw6vIwiTGqjx+Xbe8cq4l24q2AOtzO+UR97q" + + "7ypL41jtt7BY7uoxhF+NCKzYEtRoqyaM0lfjDlOVRJP6SYRixK2UHLQ3VGVzdCBL" + + "ZXkgKERvIG5vdCB1c2UgZm9yIHJlYWwuKSA8dGVzdEB3b29kcy1nZWJsZXIuY29t" + + "PoiWBBMWCAA+FiEEi6r5/iAqYhr1koSol1SGvTQgmy0FAlxM8nYCGwMFCQHhM4AF" + + "CwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQl1SGvTQgmy10cAD9EM6O6zk5kvab" + + "1D13E5WdY2C5PsKvlxZ0nFR4oBYTZzoBAJxBlYDhKZXV2QlTRcqYt67fFYOmqvJ1" + + "Pj69Bdv9Cb0HnIsEXEzydhIKKwYBBAGXVQEFAQEHQBjddNLpLWnAU1zVCE2kQpNK" + + "0b4sAmmIc8r1DJcFtb11AwEIB/4HAwItKjH+kGqkMelkEdIRxSLFeCsB/A64n+os" + + "X9nWVYsrixEWT5JcRWBniI1PKt9Cm15Yt8KQSAFDJIj5tnEm28x5RM0CzFHQ9Ej2" + + "8Q2Lt0RoiH4EGBYIACYWIQSLqvn+ICpiGvWShKiXVIa9NCCbLQUCXEzydgIbDAUJ" + + "AeEzgAAKCRCXVIa9NCCbLZgLAQDESab4fInoMKyQzKEHOd2ag0bG4nhJVeqHwfNG" + + "vo5M2QEAoKQGmOIWXPBlGp9iSKpINILNt4eGrux+/Sql2BuGvgY="); + + //private static readonly char[] curve25519Pwd = "foobar".ToCharArray(); + [Test] public void PerformTest1() { @@ -1744,15 +1773,12 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests [Test] public void PerformTest4() { - PgpSecretKeyRingBundle secretRings1 = new PgpSecretKeyRingBundle(sec4); - int count = 0; - + PgpSecretKeyRingBundle secretRings = new PgpSecretKeyRingBundle(sec4); + byte[] encRing = secretRings.GetEncoded(); + secretRings = new PgpSecretKeyRingBundle(encRing); - byte[] encRing = secretRings1.GetEncoded(); - - PgpSecretKeyRingBundle secretRings2 = new PgpSecretKeyRingBundle(encRing); - - foreach (PgpSecretKeyRing pgpSec1 in secretRings1.GetKeyRings()) + int count = 0; + foreach (PgpSecretKeyRing pgpSec1 in secretRings.GetKeyRings()) { count++; @@ -2486,22 +2512,22 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests [Test] public void PublicKeyRingWithX509Test() { - checkPublicKeyRingWithX509(pubWithX509); + CheckPublicKeyRingWithX509(pubWithX509); PgpPublicKeyRing pubRing = new PgpPublicKeyRing(pubWithX509); - checkPublicKeyRingWithX509(pubRing.GetEncoded()); + CheckPublicKeyRingWithX509(pubRing.GetEncoded()); } [Test] public void SecretKeyRingWithPersonalCertificateTest() { - checkSecretKeyRingWithPersonalCertificate(secWithPersonalCertificate); + CheckSecretKeyRingWithPersonalCertificate(secWithPersonalCertificate); PgpSecretKeyRingBundle secRing = new PgpSecretKeyRingBundle(secWithPersonalCertificate); - checkSecretKeyRingWithPersonalCertificate(secRing.GetEncoded()); + CheckSecretKeyRingWithPersonalCertificate(secRing.GetEncoded()); } - private void checkSecretKeyRingWithPersonalCertificate( + private void CheckSecretKeyRingWithPersonalCertificate( byte[] keyRing) { PgpSecretKeyRingBundle secCol = new PgpSecretKeyRingBundle(keyRing); @@ -2523,21 +2549,20 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests } } - private void checkPublicKeyRingWithX509( - byte[] keyRing) + private void CheckPublicKeyRingWithX509(byte[] keyRing) { PgpPublicKeyRing pubRing = new PgpPublicKeyRing(keyRing); var en = pubRing.GetPublicKeys().GetEnumerator(); if (en.MoveNext()) { - PgpPublicKey key = (PgpPublicKey) en.Current; + PgpPublicKey key = en.Current; var sEn = key.GetSignatures().GetEnumerator(); if (sEn.MoveNext()) { - PgpSignature sig = (PgpSignature) sEn.Current; + PgpSignature sig = sEn.Current; if (sig.KeyAlgorithm != PublicKeyAlgorithmTag.Experimental_1) { Fail("experimental signature not found"); @@ -2581,6 +2606,26 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests } } + [Test] + public void TestEdDsaRing() + { + ArmoredInputStream aIn = new ArmoredInputStream(GetTestDataAsStream("openpgp.eddsa-pub-keyring.asc")); + + // make sure we can parse it without falling over. + PgpPublicKeyRing rng = new PgpPublicKeyRing(aIn); + Assert.IsNotNull(rng); + } + + [Test] + public void TestCurve25519Ring() + { + // make sure we can parse it without falling over. + PgpPublicKeyRing rng = new PgpPublicKeyRing(new MemoryStream(curve25519Pub)); + + PgpSecretKeyRing priv = new PgpSecretKeyRing(new MemoryStream(curve25519Priv)); + Assert.IsNotNull(priv); + } + public override void PerformTest() { TestExpiryDate(); diff --git a/crypto/test/src/openssl/test/ReaderTest.cs b/crypto/test/src/openssl/test/ReaderTest.cs index 78b06abc2..8cb66d6a6 100644 --- a/crypto/test/src/openssl/test/ReaderTest.cs +++ b/crypto/test/src/openssl/test/ReaderTest.cs @@ -3,6 +3,7 @@ using System.IO; using NUnit.Framework; +using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cms; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Generators; @@ -42,6 +43,23 @@ namespace Org.BouncyCastle.OpenSsl.Tests get { return "PEMReaderTest"; } } + [Test] + public void TestGost3410_2012() + { + string data = + "-----BEGIN PRIVATE KEY-----" + + "MEMCAQAwHAYGKoUDAgITMBIGByqFAwICIwEGByqFAwICHgEEIIBidanaO5G6Go8A" + + "thlDjR9rk4hij/PpjAQvXJr+zTqz" + + "-----END PRIVATE KEY-----"; + + using (var textReader = new StringReader(data)) + { + var pemReader = new PemReader(textReader); + var pemObj = pemReader.ReadPemObject(); + PrivateKeyFactory.CreateKey(pemObj.Content); + } + } + public override void PerformTest() { IPasswordFinder pGet = new Password("secret".ToCharArray()); diff --git a/crypto/test/src/security/test/TestDotNetUtil.cs b/crypto/test/src/security/test/TestDotNetUtil.cs index b83a94a36..5d0177ead 100644 --- a/crypto/test/src/security/test/TestDotNetUtil.cs +++ b/crypto/test/src/security/test/TestDotNetUtil.cs @@ -22,6 +22,36 @@ namespace Org.BouncyCastle.Security.Tests [TestFixture] public class TestDotNetUtilities { +//#if NETCOREAPP1_0_OR_GREATER || NET47_OR_GREATER || NETSTANDARD1_6_OR_GREATER +#if NET6_0_OR_GREATER + [Test] + public void TestECDsaInterop() + { + byte[] data = new byte[1024]; + + for (int i = 0; i < 10; ++i) + { + var ecDsa = ECDsa.Create(ECCurve.NamedCurves.nistP256); + byte[] sig1 = ecDsa.SignData(data, HashAlgorithmName.SHA256); + + AsymmetricCipherKeyPair kp = DotNetUtilities.GetECDsaKeyPair(ecDsa); + Assert.IsNotNull(kp.Private); + Assert.IsNotNull(kp.Public); + ISigner signer = SignerUtilities.GetSigner("SHA256withPLAIN-ECDSA"); + + signer.Init(false, kp.Public); + signer.BlockUpdate(data, 0, data.Length); + Assert.IsTrue(signer.VerifySignature(sig1)); + + signer.Init(true, kp.Private); + signer.BlockUpdate(data, 0, data.Length); + byte[] sig2 = signer.GenerateSignature(); + + Assert.IsTrue(ecDsa.VerifyData(data, sig2, HashAlgorithmName.SHA256)); + } + } +#endif + //#if NET5_0_OR_GREATER #if NET6_0_OR_GREATER [SupportedOSPlatform("windows")] @@ -29,7 +59,7 @@ namespace Org.BouncyCastle.Security.Tests [Test] public void TestRsaInterop() { - for (int i = 0; i < 100; ++i) + for (int i = 0; i < 10; ++i) { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(512); RSAParameters rp = rsa.ExportParameters(true); diff --git a/crypto/test/src/tls/test/LoggingDatagramTransport.cs b/crypto/test/src/tls/test/LoggingDatagramTransport.cs index f675b72fc..0ad15e065 100644 --- a/crypto/test/src/tls/test/LoggingDatagramTransport.cs +++ b/crypto/test/src/tls/test/LoggingDatagramTransport.cs @@ -34,25 +34,86 @@ namespace Org.BouncyCastle.Tls.Tests public virtual int Receive(byte[] buf, int off, int len, int waitMillis) { +//#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET6_0_OR_GREATER + return Receive(buf.AsSpan(off, len), waitMillis); +#else int length = m_transport.Receive(buf, off, len, waitMillis); if (length >= 0) { DumpDatagram("Received", buf, off, length); } return length; +#endif } +//#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET6_0_OR_GREATER + public virtual int Receive(Span<byte> buffer, int waitMillis) + { + int length = m_transport.Receive(buffer, waitMillis); + if (length >= 0) + { + DumpDatagram("Received", buffer[..length]); + } + return length; + } +#endif + public virtual void Send(byte[] buf, int off, int len) { +//#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET6_0_OR_GREATER + Send(buf.AsSpan(off, len)); +#else DumpDatagram("Sending", buf, off, len); m_transport.Send(buf, off, len); +#endif } +//#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET6_0_OR_GREATER + public virtual void Send(ReadOnlySpan<byte> buffer) + { + DumpDatagram("Sending", buffer); + m_transport.Send(buffer); + } +#endif + public virtual void Close() { m_transport.Close(); } +//#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET6_0_OR_GREATER + private void DumpDatagram(string verb, ReadOnlySpan<byte> buffer) + { + int len = buffer.Length; + long timestamp = DateTimeUtilities.CurrentUnixMs() - m_launchTimestamp; + StringBuilder sb = new StringBuilder("(+" + timestamp + "ms) " + verb + " " + len + " byte datagram:"); + for (int pos = 0; pos < len; ++pos) + { + if (pos % 16 == 0) + { + sb.Append(Environment.NewLine); + sb.Append(" "); + } + else if (pos % 16 == 8) + { + sb.Append('-'); + } + else + { + sb.Append(' '); + } + int val = buffer[pos] & 0xFF; + sb.Append(HEX_CHARS[val >> 4]); + sb.Append(HEX_CHARS[val & 0xF]); + } + Dump(sb.ToString()); + } +#else private void DumpDatagram(string verb, byte[] buf, int off, int len) { long timestamp = DateTimeUtilities.CurrentUnixMs() - m_launchTimestamp; @@ -78,6 +139,7 @@ namespace Org.BouncyCastle.Tls.Tests } Dump(sb.ToString()); } +#endif private void Dump(string s) { diff --git a/crypto/test/src/tls/test/MockDatagramAssociation.cs b/crypto/test/src/tls/test/MockDatagramAssociation.cs index ef317c7b6..3612bec40 100644 --- a/crypto/test/src/tls/test/MockDatagramAssociation.cs +++ b/crypto/test/src/tls/test/MockDatagramAssociation.cs @@ -58,6 +58,10 @@ namespace Org.BouncyCastle.Tls.Tests public virtual int Receive(byte[] buf, int off, int len, int waitMillis) { +//#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET6_0_OR_GREATER + return Receive(buf.AsSpan(off, len), waitMillis); +#else lock (m_receiveQueue) { if (m_receiveQueue.Count < 1) @@ -81,10 +85,45 @@ namespace Org.BouncyCastle.Tls.Tests Array.Copy(packet, 0, buf, off, copyLength); return copyLength; } +#endif } +//#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET6_0_OR_GREATER + public virtual int Receive(Span<byte> buffer, int waitMillis) + { + lock (m_receiveQueue) + { + if (m_receiveQueue.Count < 1) + { + try + { + Monitor.Wait(m_receiveQueue, waitMillis); + } + catch (ThreadInterruptedException) + { + // TODO Keep waiting until full wait expired? + } + + if (m_receiveQueue.Count < 1) + return -1; + } + + byte[] packet = m_receiveQueue[0]; + m_receiveQueue.RemoveAt(0); + int copyLength = System.Math.Min(buffer.Length, packet.Length); + packet.AsSpan(0, copyLength).CopyTo(buffer); + return copyLength; + } + } +#endif + public virtual void Send(byte[] buf, int off, int len) { +//#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET6_0_OR_GREATER + Send(buf.AsSpan(off, len)); +#else if (len > m_outer.m_mtu) { // TODO Simulate rejection? @@ -97,7 +136,27 @@ namespace Org.BouncyCastle.Tls.Tests m_sendQueue.Add(packet); Monitor.PulseAll(m_sendQueue); } +#endif + } + +//#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET6_0_OR_GREATER + public virtual void Send(ReadOnlySpan<byte> buffer) + { + if (buffer.Length > m_outer.m_mtu) + { + // TODO Simulate rejection? + } + + byte[] packet = buffer.ToArray(); + + lock (m_sendQueue) + { + m_sendQueue.Add(packet); + Monitor.PulseAll(m_sendQueue); + } } +#endif public virtual void Close() { diff --git a/crypto/test/src/tls/test/UnreliableDatagramTransport.cs b/crypto/test/src/tls/test/UnreliableDatagramTransport.cs index bdbfd6e67..7769db9d1 100644 --- a/crypto/test/src/tls/test/UnreliableDatagramTransport.cs +++ b/crypto/test/src/tls/test/UnreliableDatagramTransport.cs @@ -37,6 +37,10 @@ namespace Org.BouncyCastle.Tls.Tests public virtual int Receive(byte[] buf, int off, int len, int waitMillis) { +//#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET6_0_OR_GREATER + return Receive(buf.AsSpan(off, len), waitMillis); +#else long endMillis = DateTimeUtilities.CurrentUnixMs() + waitMillis; for (;;) { @@ -52,10 +56,37 @@ namespace Org.BouncyCastle.Tls.Tests waitMillis = (int)(endMillis - now); } +#endif } +//#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET6_0_OR_GREATER + public virtual int Receive(Span<byte> buffer, int waitMillis) + { + long endMillis = DateTimeUtilities.CurrentUnixMs() + waitMillis; + for (;;) + { + int length = m_transport.Receive(buffer, waitMillis); + if (length < 0 || !LostPacket(m_percentPacketLossReceiving)) + return length; + + Console.WriteLine("PACKET LOSS (" + length + " byte packet not received)"); + + long now = DateTimeUtilities.CurrentUnixMs(); + if (now >= endMillis) + return -1; + + waitMillis = (int)(endMillis - now); + } + } +#endif + public virtual void Send(byte[] buf, int off, int len) { +//#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET6_0_OR_GREATER + Send(buf.AsSpan(off, len)); +#else if (LostPacket(m_percentPacketLossSending)) { Console.WriteLine("PACKET LOSS (" + len + " byte packet not sent)"); @@ -64,7 +95,23 @@ namespace Org.BouncyCastle.Tls.Tests { m_transport.Send(buf, off, len); } +#endif + } + +//#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET6_0_OR_GREATER + public virtual void Send(ReadOnlySpan<byte> buffer) + { + if (LostPacket(m_percentPacketLossSending)) + { + Console.WriteLine("PACKET LOSS (" + buffer.Length + " byte packet not sent)"); + } + else + { + m_transport.Send(buffer); + } } +#endif public virtual void Close() { diff --git a/crypto/test/src/tsp/test/TSPTestUtil.cs b/crypto/test/src/tsp/test/TSPTestUtil.cs index abe153ac1..4e08bd76d 100644 --- a/crypto/test/src/tsp/test/TSPTestUtil.cs +++ b/crypto/test/src/tsp/test/TSPTestUtil.cs @@ -347,7 +347,7 @@ namespace Org.BouncyCastle.Tsp.Tests else { _v3CertGen.AddExtension(X509Extensions.ExtendedKeyUsage, true, - ExtendedKeyUsage.GetInstance(new DerSequence(KeyPurposeID.IdKPTimeStamping))); + ExtendedKeyUsage.GetInstance(new DerSequence(KeyPurposeID.id_kp_timeStamping))); } X509Certificate _cert = _v3CertGen.Generate( diff --git a/crypto/test/src/util/test/SimpleTest.cs b/crypto/test/src/util/test/SimpleTest.cs index 0a2b5e991..21b4daabb 100644 --- a/crypto/test/src/util/test/SimpleTest.cs +++ b/crypto/test/src/util/test/SimpleTest.cs @@ -168,12 +168,12 @@ namespace Org.BouncyCastle.Utilities.Test private static string GetFullName(string name) { - return "BouncyCastle.Crypto.Tests.data." + name; + return "Org.BouncyCastle.data." + name; } private static string GetShortName(string fullName) { - return fullName.Substring("BouncyCastle.Crypto.Tests.data.".Length); + return fullName.Substring("Org.BouncyCastle.data.".Length); } private static string GetNewLine() |