Giter Site home page Giter Site logo

bcgit / bc-csharp Goto Github PK

View Code? Open in Web Editor NEW
1.6K 106.0 527.0 432.81 MB

BouncyCastle.NET Cryptography Library (Mirror)

Home Page: https://www.bouncycastle.org/csharp

License: MIT License

C# 99.92% HTML 0.07% Batchfile 0.01%
bouncycastle cryptography dtls encryption open-source openpgp post-quantum security tls

bc-csharp's Introduction

The Bouncy Castle Cryptography Library For .NET

NuGet NuGet

The Bouncy Castle Cryptography library is a .NET implementation of cryptographic algorithms and protocols. It was developed by the Legion of the Bouncy Castle, a registered Australian Charity, with a little help! The Legion, and the latest goings on with this package, can be found at https://www.bouncycastle.org.

In addition to providing basic cryptography algorithms, the package also provides support for CMS, OpenPGP, (D)TLS, TSP, X.509 certificate generation and more. The package also includes implementations of the following NIST Post-Quantum Cryptography Standardization algorithms: CRYSTALS-Dilithium, CRYSTALS-Kyber, Falcon, SPHINCS+, Classic McEliece, FrodoKEM, NTRU, NTRU Prime, Picnic, Saber, BIKE, and SIKE. These should all be considered EXPERIMENTAL and subject to change or removal. SIKE in particular is already slated for removal and should be used for research purposes only.

The Legion also gratefully acknowledges the contributions made to this package by others (see here for the current list). If you would like to contribute to our efforts please feel free to get in touch with us or visit our donations page, sponsor some specific work, or purchase a support contract.

Except where otherwise stated, this software is distributed under a license based on the MIT X Consortium license. To view the license, see here. This software includes a modified Bzip2 library, which is licensed under the Apache Software License, Version 2.0.

Note: This source tree is not the FIPS version of the APIs - if you are interested in our FIPS version please visit us here or contact us directly at [email protected].

Installing BouncyCastle

You should install BouncyCastle with NuGet:

Install-Package BouncyCastle.Cryptography

Or via the .NET Core command line interface:

dotnet add package BouncyCastle.Cryptography

Either commands, from Package Manager Console or .NET Core CLI, will download and install BouncyCastle.Cryptography.

Mailing Lists

For those who are interested, there are 2 mailing lists for participation in this project. To subscribe use the links below and include the word subscribe in the message body. (To unsubscribe, replace subscribe with unsubscribe in the message body)

  • [email protected]
    This mailing list is for new release announcements only, general subscribers cannot post to it.
  • [email protected]
    This mailing list is for discussion of development of the package. This includes bugs, comments, requests for enhancements, questions about use or operation.

NOTE: You need to be subscribed to send mail to the above mailing list.

Feedback

If you want to provide feedback directly to the members of The Legion then please use [email protected]. If you want to help this project survive please consider donating.

For bug reporting/requests you can report issues on github, or via [email protected] if required. We will accept pull requests based on this repository as well, but only on the basis that any code included may be distributed under the Bouncy Castle License.

Finally

Enjoy!

bc-csharp's People

Contributors

agpreynolds avatar anhvoms avatar avanpo avatar bartland avatar bb-froggy avatar beppler avatar blackthornyugen avatar cipherboy avatar darkoperator avatar deniszykov avatar dghbc avatar dghgit avatar fedelippo avatar gungora avatar harrison314 avatar jstedfast avatar konstantin-kretov avatar ligefeibouncycastle avatar marcinpaszylk avatar mdsitton avatar mus65 avatar mwcw avatar patagonaa avatar peterdettman avatar rastrup avatar rom-knowledgeware avatar scott-xu avatar timothymakkison avatar timw avatar zzmarquis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bc-csharp's Issues

DigestName should be EncryptionName?

In Cms.SignerInformation.cs line 348 DigestName is used to constuct the signature name. This should be the EncryptionName when the HASH algorithm is defined by EncryptionOid.

The fix was also done in Java BouncyCastle 2 years ago (9.5.2015) in DefaultCMSSignatureAlgorithmNameGenerator.java method getSignatureName

The source data (testing SOD) can be found in original issue created in Jira: http://www.bouncycastle.org/jira/browse/BMA-134

Expose KeyUsage in X509Certificate

The X509Certificate class exposes KeyUsage as a bool[], which is require the user to know the ordering of the bits in the KeyUsage field. It would be a lot more user friendly to expose the KeyUsage class, and provide an API in the KeyUsage class to test for a specific key usage.

Example:

X509Certificate cert = ...;
bool hasUsage = cert.GetKeyUsage().HasUsage(KeyUsage.CRLSign);

DTLS: After the connection is how retransmission timeout?

SecureRandom secureRandom = new SecureRandom();
DtlsClientProtocol dtlsClientProtocol = new DtlsClientProtocol(secureRandom);
TlsClient tlsServer = new MockDtlsClient(null);
DatagramTransport datagramTransport = network.Client;
datagramTransport = new UnreliableDatagramTransport(network.Server, secureRandom, 10, 10);
datagramTransport = new LoggingDatagramTransport(network.Server, Console.Out);
DtlsTransport dtlsTransport = dtlsClientProtocol.Connect(tlsServer, datagramTransport);
byte[] data = Encoding.ASCII.GetBytes("hello");
// After the connection is how retransmission timeout?
dtlsTransport.Send(data, 0, data.Length);
data = new byte[dtlsTransport.GetReceiveLimit()];
int len = dtlsTransport.Receive(data, 0, data.Length, 10000);
Console.WriteLine(Encoding.ASCII.GetString(data, 0, len));

TestInvalidNegativeSerialNumberTest15 failed

This is the test result

Expected: True
But was: False

in NUnit.Framework.Assert.That(Object actual, IResolveConstraint expression, String message, Object[] args)
in NUnit.Framework.Assert.IsTrue(Boolean condition)
in Org.BouncyCastle.Tests.Nist.NistCertPathTest.DoExceptionTest(String trustAnchor, String[] certs, String[] crls, Int32 index, String mesStart, String mesEnd) in C:\Users\andrea\Documents\GitHub\bc-csharp\crypto\test\src\test\nist\NistCertPathTest.cs:riga 627
in Org.BouncyCastle.Tests.Nist.NistCertPathTest.TestInvalidNegativeSerialNumberTest15() in C:\Users\andrea\Documents\GitHub\bc-csharp\crypto\test\src\test\nist\NistCertPathTest.cs:riga 184

the error is somewhere in the test I think, not in the library, at line 627 of NistCertCertPathtest.cs, in my italian system e.Message is
"Certificate revocation after gio apr 19 14:57:20 Z 2001, reason: keyCompromise"
but it's tested startwith against
"Certificate revocation after Thu Apr 19 14:57:20"

Andrea

BasicConstrains is not fully exposed in X509Certificate

In the X509Certificate, the BasicConstraint data is not fully exposed to the user. It actually exposes the PathLengthConstraint and two undocumented values in edge cases.

Change the GetBasicConstraint() to return the BasicConstraints class instead.

ChaChaEngine fails after 128 bytes

Hi,

First of all, what a great set of algorithms you guys have in this library, I use them a lot!

I am now using your chacha engine in a project together with poly1305 for AEAD-chacha20-poly1305 encryption.

Upon testing this all seemed to work fine.
It turns out, when the message becomes larger, the algorithm corrupts the data.

Please check test vector #2 in chapter A2, page 26: https://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-06

It is strange to notice, but the poly-1305 signature is actually correct.
But that is probably due to the design of the algorithm itself and not your specific implementation.

Many thanks for looking into this.

unknown PGP public key algorithm encountered (EDDSA?)

I'm working on adding logic to MimeKit to automatically fetch keys from a keyserver and import them when verifying signatures if an unknown key id is encountered (assuming MimeKit is configured to auto-fetch them).

I keep getting an exception about an unknown PGP public key algorithm when trying to read the returned stream. I modified my local copy of BouncyCastle to include the algorithm id in the IOException that gets thrown and the algorithm tag is 22 which doesn't have a mapping in the PublicKeyAlgorithmTag enum.

I took a quick look at rfc4880 and there does not appear to be an algorithm id of 22.

The following test case illustrates the problem.

Test Case:

using System;
using System.IO;
using System.Net.Http;

using Org.BouncyCastle.Bcpg;
using Org.BouncyCastle.Bcpg.OpenPgp;

namespace KeyserverLookup {
    class Program
    {
        public static void Main (string[] args)
        {
            using (var stream = new MemoryStream ()) {
                using (var client = new HttpClient ()) {
                    var uri = new UriBuilder ();
                    uri.Scheme = "http";
                    uri.Host = "keys.gnupg.net";
                    uri.Port = 11371;
                    uri.Path = "/pks/lookup";
                    uri.Query = "op=get&search=0x24ECFF5AFF68370A";

                    using (var response = client.GetAsync (uri.ToString ()).GetAwaiter ().GetResult ()) {
                        response.Content.CopyToAsync (stream).GetAwaiter ().GetResult ();
                    }
                }

                stream.Position = 0;

                using (var armored = new ArmoredInputStream (stream)) {
                    var bundle = new PgpPublicKeyRingBundle (armored);

                    foreach (PgpPublicKeyRing keyring in bundle.GetKeyRings ()) {
                        foreach (PgpPublicKey key in keyring.GetPublicKeys ()) {
                            var valid = key.GetValidSeconds ();
                            var ctime = key.CreationTime;
                            var exp = ctime.AddSeconds (valid);
                            var now = DateTime.Now;
                            char algorithm = 'D';

                            if (!key.IsMasterKey && valid > 0 && now > exp)
                                continue;

                            switch (key.Algorithm) {
                            case PublicKeyAlgorithmTag.ECDH: algorithm = 'E'; break;
                            case PublicKeyAlgorithmTag.ElGamalEncrypt:
                            case PublicKeyAlgorithmTag.ElGamalGeneral: algorithm = 'g'; break;
                            case PublicKeyAlgorithmTag.RsaEncrypt:
                            case PublicKeyAlgorithmTag.RsaGeneral: algorithm = 'R'; break;
                            }

                            Console.Write ("{0}   {1}{2}/{3:X8} {4}",
                                key.IsMasterKey ? "pub" : "sub",
                                key.BitStrength,
                                algorithm,
                                (int) key.KeyId,
                                ctime.ToString ("yyyy-MM-dd"));
                            if (key.IsRevoked ()) {
                                Console.WriteLine (" [revoked: {0}]", exp.ToString ("yyyy-MM-dd"));
                            } else if (valid > 0) {
                                Console.WriteLine (" [expires: {0}]", exp.ToString ("yyyy-MM-dd"));
                            } else {
                                Console.WriteLine ();
                            }

                            foreach (string uid in key.GetUserIds ()) {
                                Console.WriteLine ("uid       {0}", uid);
                            }
                        }
			
                        Console.WriteLine ();
                    }
                }
            }
        }
    }
}

Error:

./keyserver-lookup.exe 

Unhandled Exception:
System.IO.IOException: unknown PGP public key algorithm encountered: 22
  at Org.BouncyCastle.Bcpg.PublicKeyPacket..ctor (Org.BouncyCastle.Bcpg.BcpgInputStream bcpgIn) [0x000fa] in <db94dee80fb04a8f9f9551caee933b45>:0 
  at Org.BouncyCastle.Bcpg.PublicSubkeyPacket..ctor (Org.BouncyCastle.Bcpg.BcpgInputStream bcpgIn) [0x00000] in <db94dee80fb04a8f9f9551caee933b45>:0 
  at Org.BouncyCastle.Bcpg.BcpgInputStream.ReadPacket () [0x002de] in <db94dee80fb04a8f9f9551caee933b45>:0 
  at (wrapper remoting-invoke-with-check) Org.BouncyCastle.Bcpg.BcpgInputStream:ReadPacket ()
  at Org.BouncyCastle.Bcpg.OpenPgp.PgpPublicKeyRing.ReadSubkey (Org.BouncyCastle.Bcpg.BcpgInputStream bcpgInput) [0x00001] in <db94dee80fb04a8f9f9551caee933b45>:0 
  at Org.BouncyCastle.Bcpg.OpenPgp.PgpPublicKeyRing..ctor (System.IO.Stream inputStream) [0x0009c] in <db94dee80fb04a8f9f9551caee933b45>:0 
  at Org.BouncyCastle.Bcpg.OpenPgp.PgpObjectFactory.NextPgpObject () [0x00123] in <db94dee80fb04a8f9f9551caee933b45>:0 
  at Org.BouncyCastle.Bcpg.OpenPgp.PgpObjectFactory.AllPgpObjects () [0x00013] in <db94dee80fb04a8f9f9551caee933b45>:0 
  at Org.BouncyCastle.Bcpg.OpenPgp.PgpPublicKeyRingBundle..ctor (System.IO.Stream inputStream) [0x00007] in <db94dee80fb04a8f9f9551caee933b45>:0 
  at LoadKeyBlockSample.Program.Main (System.String[] args) [0x000b2] in <69e5296966704328a35074713cc14eaa>:0 

Unresolved critical extensions issue in PkixCertPathChecker

When overriding Check method of PkixCertPathChecker.cs I can't remove unresolved critical extensions I don't want to check.
Reson: unresolvedCritExts object is immutable ICollection.
Fix: It could be of type Org.BouncyCastle.Utilities.Collections.ISet, this way I can call Remove() method on collection.

Current commit (efb5751f) tests fail, failure introduced in f6ff879, works in 41a48c2.

[...all ASN.1 tests and all Pgp tests before this pass...]
PgpECMessageTest: Okay
PgpParsingTest: Okay
Tests failed with exception: Object reference not set to an instance of an object.
at NUnit.Core.TestSuite.RunAllTests(TestResult suiteResult, EventListener listener, ITestFilter filter)
at NUnit.Core.TestSuite.RunSuite(EventListener listener, ITestFilter filter)
at NUnit.Core.TestSuite.RunSuiteInContext(EventListener listener, ITestFilter filter)
at NUnit.Core.TestSuite.Run(EventListener listener, ITestFilter filter)
at Org.BouncyCastle.Bcpg.OpenPgp.Examples.Tests.AllTests.Main(String[] args) in C:\work\bcgit\bc-csharp\crypto\test\src\openpgp\examples\test\AllTests.cs:line 423
at crypto_test.CryptoTest.Main(String[] args) in C:\work\bcgit\bc-csharp\crypto-test\CryptoTest.cs:line 20
Done in 46923ms.

This occurs in both Debug and Release configurations. Due to circular dependencies, I'm unable to compile a version of nunit that has debugging information enabled to provide better insight as to what's going on.

Nuget distrib of bc completely fucked up

You distributed 2 different versions of bc (light and full) using the EXACTLY SAME assembly name/version/signature.

Result: when referencing 2 different nugets, one depending on the light bc nuget, the other on the full bc nuget, the C# compiler fails to resolve at runtime one or the other assembly with an error in the fusion log.

I lost a full day finding this incompatibility issue with these nugets:

  • GoogleApis.Auth
  • MailKit

When using a method on mailkit while having GoogleApis.Auth referenced, the app crashes with a fusion log error on bounty castle.

I fixed the issue by using the GoogleApis.Auth sourcecode instead of the nuget, and updating the dependancy on Bounty Castle from it, so it uses the same bc nuget as MailKit.

SNK key file

So ... is the BouncyCastle.snk file the same one that's being used to generate the release versions? Because if it is, then that means that anyone could compile it with the "legitimate" key name, which would subvert the whole point of strong-named assemblies.

My recommendation is the following:

  1. Delete BouncyCastle.snk permanently.
  2. Create an entirely separate snk file; keep it secret, keep it away from the git repository, do not release or distribute it AT ALL. In fact, you should probably make one SNK file for each of the different versions (PCL.snk, Android.snk, iOS.snk, etc; c.f. #61).
  3. After building each version for release, sign each separate version with their respective SNK files (that link is specific to Visual Studio, but it explains the general principle), and distribute them through an unimpeachable source, i.e. the Releases page.

Yes, this will probably result in compatibility issues, given that people will need to recompile anything that references bc-csharp, but I think this is outweighed by the risk of, say, someone adding malicious code to the source and then passing it off as legitimate.

Unit tests in binary distribution

When installing BouncyCastle 1.7.0 from NuGet, all the unit tests are included in the binary distribution, making the distribution larger than it needs to be. What are the reasons for including the unit tests?

Verify digest for Sha256WithRSAEncryption

Hello,

I have problem with SignerInformation.VerifyDigest method. When algorithm equals to RSA there is check for equality of digInfo.AlgorithmID.Algorithm and digestAlgorithm.Algorithm. I don't know why.

In my case digInfo.AlgorithmID.Algorithm is 2.16.840.1.101.3.4.2.1 (SHA-256) and digestAlgorithm.Algorithm is 1.2.840.113549.1.1.11 (Sha256WithRSAEncryption). So check for equality fails end VerifyDigest result is false. But if I comment equality check, Arrays.ConstantTimeAreEqual(digest, sigHash) is true so digest compare is Ok.

I didn't found any informations in RFCs that contains equality check for used algorithms in this case. There is not way to bypass or override this behaviour.

TJ

Move to netstandard TFM

Moving this issue here from https://github.com/onovotny/BouncyCastle-PCL/issues/12

This is to move from dotnet to netstandard in the nuspec. See https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/standard-platform.md for details.

The nuspec will be greatly simplified as it required extra blank dependency groups and copies of the libs in platform-specific TFM \lib dirs. to work correctly.

This issue is dependent on https://github.com/dotnet/corefx/issues/4367 being completed.

/cc @peterdettman

Serpent implementation output not match to MCrypt implementation

Output from PHP Mcrypt cannot be decrypted with SerpentEngine. For Twofish or Rijndael conversion is working.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Paddings;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Utilities.Encoders;

namespace ConsoleApplication3
{
    public class SERPENT
    {
        private string _key = "anhEWHBNQnRCSHdNYW5jS0w1aEQ=";

        private readonly Encoding _encoding;
        private readonly IBlockCipher _blockCipher;
        private PaddedBufferedBlockCipher _cipher;
        private IBlockCipherPadding _padding;

        public SERPENT()
        {
            //_blockCipher = new CfbBlockCipher(new RijndaelEngine(128), 128);
            _blockCipher = new CfbBlockCipher(new SerpentEngine(), 128);
            _encoding = Encoding.UTF8;
            _padding = new Pkcs7Padding();
        }

        public string Encrypt(string plain, string iv)
        {
            byte[] ivBytes = this.GetIV(iv);
            byte[] keyBytes = this.GetKey();
            byte[] result = BouncyCastleCrypto(true, _encoding.GetBytes(plain), keyBytes, ivBytes);
            return _encoding.GetString(Base64.Encode(result));
        }

        private byte[] GetKey()
        {
            string key = Encoding.UTF8.GetString(Base64.Decode(this._key)).Substring(0, 16);
            return Encoding.UTF8.GetBytes(key);
        }

        private byte[] GetIV(string iv)
        {
            string hash = MD5Hash(iv).Substring(0, 16);
            return Encoding.UTF8.GetBytes(hash);
        }

        public string Decrypt(string cipher, string iv)
        {
            byte[] ivBytes = this.GetIV(iv);
            byte[] keyBytes = this.GetKey();
            byte[] result = BouncyCastleCrypto(false, Base64.Decode(cipher), keyBytes, ivBytes);
            return _encoding.GetString(result);
        }

        private byte[] BouncyCastleCrypto(bool forEncrypt, byte[] input, byte[] key, byte[] iv)
        {
            try
            {
                _cipher = _padding == null ? new PaddedBufferedBlockCipher(_blockCipher) : new PaddedBufferedBlockCipher(_blockCipher, _padding);
                ParametersWithIV param = new ParametersWithIV(new KeyParameter(key), iv);
                _cipher.Init(forEncrypt, param);
                return _cipher.DoFinal(input);
            }
            catch (Org.BouncyCastle.Crypto.CryptoException ex)
            {
                throw ex;
            }
        }

        public string MD5Hash(string input)
        {
            // step 1, calculate MD5 hash from input
            MD5 md5 = System.Security.Cryptography.MD5.Create();
            byte[] inputBytes = System.Text.Encoding.UTF8.GetBytes(input);
            byte[] hash = md5.ComputeHash(inputBytes);

            // step 2, convert byte array to hex string
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hash.Length; i++)
            {
                sb.Append(hash[i].ToString("x2"));
            }
            return sb.ToString();
        }
    }
}

PHP code:

<?php
class cryptor {
    private static $key = 'anhEWHBNQnRCSHdNYW5jS0w1aEQ=';

    public static function getKey(){
        $k = substr(base64_decode(cryptor::$key),0,16);
        return $k;
    }

    public static function getIv($iv){
        $k = substr(md5($iv),0,16);
        return $k;
    }

    public static function pkcs7padding($text){
        $block = mcrypt_get_block_size(cryptor::$cipher,cryptor::$mode);
        $padding = $block-(strlen($text)%$block);
        $text .= str_repeat(chr($padding), $padding);
        return $text;
    }

    public static function unpad($text){
        $dec_s = strlen($text); 
        $padding = ord($text[$dec_s-1]); 
        return substr($text, 0, -$padding);
        //return $text;
    }

    public static function encrypt($textArr,$iv) {
        $k = cryptor::getKey();
        return cryptor::encryptSerpent($textArr,$k,$iv);
    }

    public static function decrypt($encryptedArr,$iv) {
        $k = cryptor::getKey();
        return cryptor::decryptSerpent($encryptedArr,$k,$iv);
    }

    private static $cipher = 'serpent';
    private static $mode = 'ncfb';
    public static function encryptSerpent($textArr,$key,$iv) {
        $res = [];
        $cipher = mcrypt_module_open(cryptor::$cipher,'',cryptor::$mode,'');
        foreach($textArr as $ikey => $text){
            if(is_array($text)){
                $res[$ikey] = [];
                foreach($text as $key2 => $value2){
                    if($key2 == 'encoded' || empty($value2)){
                        continue;
                    }
                    //$decrypted = mcrypt_encrypt(cryptor::$cipher,$key,cryptor::pkcs7padding($value2),cryptor::$mode,$iv);
                    mcrypt_generic_init($cipher, $key, $iv);
                    $decrypted = mcrypt_generic($cipher,cryptor::pkcs7padding($value2));
                    $res[$ikey][$key2] = base64_encode($decrypted);
                    mcrypt_generic_deinit($cipher);
                }
            }else{
                mcrypt_generic_init($cipher, $key, $iv);
                $decrypted = mcrypt_generic($cipher,cryptor::pkcs7padding($text));
                //$decrypted = mcrypt_encrypt(cryptor::$cipher,$key,cryptor::pkcs7padding($text),cryptor::$mode,$iv);
                $res[$ikey] = base64_encode($decrypted);
                mcrypt_generic_deinit($cipher);
            }
        }
        mcrypt_module_close($cipher);
        return $res;
    }

    public static function decryptSerpent($encryptedArr,$key,$iv){
        $res = [];
        $cipher = mcrypt_module_open(cryptor::$cipher,'',cryptor::$mode,'');
        foreach($encryptedArr as $ikey => $encrypted_text){
            if(is_array($encrypted_text)){
                $res[$ikey] = [];
                foreach($encrypted_text as $key2 => $value2){
                    if($key2 == 'encoded' || empty($value2)){
                        continue;
                    }
                    mcrypt_generic_init($cipher, $key, $iv);
                    $decrypted = mdecrypt_generic($cipher,base64_decode($value2));
                    //$decrypted = mcrypt_decrypt(cryptor::$cipher,$key,base64_decode($value2),cryptor::$mode,$iv);
                    $res[$ikey][$key2] = cryptor::unpad($decrypted);
                    mcrypt_generic_deinit($cipher);
                }
            }else{
                mcrypt_generic_init($cipher, $key, $iv);
                $decrypted = mdecrypt_generic($cipher,base64_decode($encrypted_text));
                //$decrypted = mcrypt_decrypt(cryptor::$cipher,$key,base64_decode($encrypted_text),cryptor::$mode,$iv);
                $res[$ikey] = cryptor::unpad($decrypted);
                mcrypt_generic_deinit($cipher);
            }
        }
        mcrypt_module_close($cipher);
        return $res;
    }
}

PGPSecretKey does not support unicode pass phrases

If a passphrase contains an umlaut (รค, รถ, รผ, รœ, ร„, ร–, รŸ, ...), the key cannot be extracted/unlocked. The problem can be traced into PgpUtilities.MakeKeyFromPassPhrase which calls Strings.ToByteArray. Strings.ToByteArray will convert a char[] passphrase string into bytes assuming a 1-to-1 mapping of chars to bytes. In reality these functions should probably use the Encoding classes to perform such conversions so proper encoding can be taken into account such as UTF-8.

Code flow:

PGPSecretKey::ExtractPrivateKey(passPhrase)
PGPSecretKey::ExtractKeyData(passPhrase)
PgpUtilities.MakeKeyFromPassPhrase(..., passPhrase)
Strings.ToByteArray(passPhrase)

Undefined length - ASN1 (Problem to convert it to a right ASN1 structure)

I try to get a X509Certificate2 from a BountyCastle X509Certificate and a PKCS12. I use the following code:

 certificate = new X509Certificate2(rawData, password, storageFlags);

I generate the rawData, like the following:

using (MemoryStream pfxData = new MemoryStream())
{
   X509CertificateEntry[] chain = new X509CertificateEntry[1];
               
   chain[0] = new X509CertificateEntry(x509);
   pkcsStore.SetKeyEntry(applicationName, new AsymmetricKeyEntry(subjectKeyPair.Private), chain);
   pkcsStore.Save(pfxData, passcode.ToCharArray(), random);
   var rawData = pfx.ToArray();
}

The problem is, that I get the following exception:

enter image description here

After some days of researching, I figured out, that the problem is based on the Mono implementation of ASN1. This implementation doesn't allow "Undefined length encoding". If I use the code on Windows it works great.

My question

Is there any way, to convert the pfxData stream to a valid ASN1 structure?

I have tried it with the following code:

Asn1InputStream asn1InputStream = new Asn1InputStream(pfxData);
var asn1Object = asn1InputStream.ReadObject();

MemoryStream memoryStream = new MemoryStream();
new Asn1OutputStream((Stream)memoryStream).WriteObject(asn1Object);
var asn1ByteArray = memoryStream.ToArray();

certificate = new X509Certificate2(asn1ByteArray);

But with this code, I get the following exception:

"Index was out of range. Must be non-negative and less than the size of the collection.\nParameter name: startIndex"

Exception Stack Trace (Converting BER to DER):

05-28 15:19:54.895 D/Mono    ( 3808): Assembly Ref addref Mono.Security[0x9b4fe080] -> System[0xac8de400]: 17
05-28 15:19:54.957 I/mono-stdout( 3808): System.AggregateException: One or more errors occurred. ---> System.Security.Cryptography.CryptographicException: Unable to decode certificate. ---> System.Security.Cryptography.CryptographicException: Input data cannot be coded as a valid certificate. ---> System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
System.AggregateException: One or more errors occurred. ---> System.Security.Cryptography.CryptographicException: Unable to decode certificate. ---> System.Security.Cryptography.CryptographicException: Input data cannot be coded as a valid certificate. ---> System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: startIndex
  at System.String.IndexOf (System.String value, System.Int32 startIndex, System.Int32 count, System.StringComparison comparisonType) [0x0002a] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at System.String.IndexOf (System.String value, System.Int32 startIndex, System.StringComparison comparisonType) [0x00009] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at System.String.IndexOf (System.String value, System.Int32 startIndex) [0x00000] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at Mono.Security.X509.X509Certificate.PEM (System.String type, System.Byte[] data) [0x00030] in <2940be14d5a1446694e2193e9029b558>:0 
  at Mono.Security.X509.X509Certificate..ctor (System.Byte[] data) [0x00014] in <2940be14d5a1446694e2193e9029b558>:0 
   --- End of inner exception stack trace ---
  at Mono.Security.X509.X509Certificate..ctor (System.Byte[] data) [0x0002f] in <2940be14d5a1446694e2193e9029b558>:0 
05-28 15:19:54.958 I/mono-stdout( 3808): Parameter name: startIndex
  at System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x0000b] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
   --- End of inner exception stack trace ---
  at System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x00031] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
  at System.Security.Cryptography.X509Certificates.X509Helper2.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags, System.Boolean disableProvider) [0x00020] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
  at System.Security.Cryptography.X509Certificates.X509Certificate2.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x00000] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
  at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor (System.Byte[] rawData) [0x00011] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
05-28 15:19:54.958 I/mono-stdout( 3808):   at System.String.IndexOf (System.String value, System.Int32 startIndex, System.Int32 count, System.StringComparison comparisonType) [0x0002a] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at APP.Models.Services.ACommunicationService.CreateCertificate (System.String storeType, System.String storePath, System.String password, System.String applicationUri, System.String applicationName, System.String subjectName, System.Collections.Generic.IList`1[T] domainNames, System.UInt16 keySize, System.DateTime startTime, System.UInt16 lifetimeInMonths, System.UInt16 hashSizeInBits, System.Boolean isCA, System.Security.Cryptography.X509Certificates.X509Certificate2 issuerCAKeyCert) [0x003b5] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:517 
05-28 15:19:54.958 I/mono-stdout( 3808):   at System.String.IndexOf (System.String value, System.Int32 startIndex, System.StringComparison comparisonType) [0x00009] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at APP.Models.Services.ACommunicationService.CreateCertificate (System.String storeType, System.String storePath, System.String applicationUri, System.String applicationName, System.String subjectName, System.Collections.Generic.IList`1[T] serverDomainNames, System.UInt16 keySize, System.UInt16 lifetimeInMonths, System.UInt16 hashSizeInBits) [0x00001] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:318 
  at APP.Models.Services.ACommunicationService+<ACommunicationServiceAsync>d__18.MoveNext () [0x00972] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:214 
   --- End of inner exception stack trace ---
05-28 15:19:54.959 I/mono-stdout( 3808):   at System.String.IndexOf (System.String value, System.Int32 startIndex) [0x00000] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at System.Threading.Tasks.Task.ThrowIfExceptional (System.Boolean includeTaskCanceledExceptions) [0x00011] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at System.Threading.Tasks.Task.Wait (System.Int32 millisecondsTimeout, System.Threading.CancellationToken cancellationToken) [0x00043] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at System.Threading.Tasks.Task.Wait () [0x00000] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at APP.Models.Services.ACommunicationService..ctor (PCLStorage.IFolder rootFolder) [0x00010] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:46 
05-28 15:19:54.959 I/mono-stdout( 3808):   at Mono.Security.X509.X509Certificate.PEM (System.String type, System.Byte[] data) [0x00030] in <2940be14d5a1446694e2193e9029b558>:0 
05-28 15:19:54.959 I/mono-stdout( 3808):   at Mono.Security.X509.X509Certificate..ctor (System.Byte[] data) [0x00014] in <2940be14d5a1446694e2193e9029b558>:0 
05-28 15:19:54.959 I/mono-stdout( 3808):    --- End of inner exception stack trace ---
05-28 15:19:54.959 I/mono-stdout( 3808):   at Mono.Security.X509.X509Certificate..ctor (System.Byte[] data) [0x0002f] in <2940be14d5a1446694e2193e9029b558>:0 
05-28 15:19:54.959 I/mono-stdout( 3808):   at System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x0000b] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
---> (Inner Exception #0) System.Security.Cryptography.CryptographicException: Unable to decode certificate. ---> System.Security.Cryptography.CryptographicException: Input data cannot be coded as a valid certificate. ---> System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
05-28 15:19:54.961 I/mono-stdout( 3808):    --- End of inner exception stack trace ---
05-28 15:19:54.961 I/mono-stdout( 3808):   at System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x00031] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
05-28 15:19:54.961 I/mono-stdout( 3808):   at System.Security.Cryptography.X509Certificates.X509Helper2.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags, System.Boolean disableProvider) [0x00020] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
05-28 15:19:54.962 I/mono-stdout( 3808):   at System.Security.Cryptography.X509Certificates.X509Certificate2.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x00000] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
05-28 15:19:54.962 I/mono-stdout( 3808):   at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor (System.Byte[] rawData) [0x00011] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
Parameter name: startIndex
05-28 15:19:54.963 I/mono-stdout( 3808):   at APP.Models.Services.ACommunicationService.CreateCertificate (System.String storeType, System.String storePath, System.String password, System.String applicationUri, System.String applicationName, System.String subjectName, System.Collections.Generic.IList`1[T] domainNames, System.UInt16 keySize, System.DateTime startTime, System.UInt16 lifetimeInMonths, System.UInt16 hashSizeInBits, System.Boolean isCA, System.Security.Cryptography.X509Certificates.X509Certificate2 issuerCAKeyCert) [0x003b5] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:517 
05-28 15:19:54.963 I/mono-stdout( 3808):   at APP.Models.Services.ACommunicationService.CreateCertificate (System.String storeType, System.String storePath, System.String applicationUri, System.String applicationName, System.String subjectName, System.Collections.Generic.IList`1[T] serverDomainNames, System.UInt16 keySize, System.UInt16 lifetimeInMonths, System.UInt16 hashSizeInBits) [0x00001] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:318 
05-28 15:19:54.964 I/mono-stdout( 3808):   at APP.Models.Services.ACommunicationService+<ACommunicationServiceAsync>d__18.MoveNext () [0x00972] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:214 
05-28 15:19:54.964 I/mono-stdout( 3808):    --- End of inner exception stack trace ---
05-28 15:19:54.965 I/mono-stdout( 3808):   at System.Threading.Tasks.Task.ThrowIfExceptional (System.Boolean includeTaskCanceledExceptions) [0x00011] in <d18287e1d683419a8ec3216fd78947b9>:0 
05-28 15:19:54.965 I/mono-stdout( 3808):   at System.Threading.Tasks.Task.Wait (System.Int32 millisecondsTimeout, System.Threading.CancellationToken cancellationToken) [0x00043] in <d18287e1d683419a8ec3216fd78947b9>:0 
05-28 15:19:54.965 I/mono-stdout( 3808):   at System.Threading.Tasks.Task.Wait () [0x00000] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at System.String.IndexOf (System.String value, System.Int32 startIndex, System.Int32 count, System.StringComparison comparisonType) [0x0002a] in <d18287e1d683419a8ec3216fd78947b9>:0 
05-28 15:19:54.965 I/mono-stdout( 3808):   at APP.Models.Services.ACommunicationService..ctor (PCLStorage.IFolder rootFolder) [0x00010] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:46 
05-28 15:19:54.966 I/mono-stdout( 3808): ---> (Inner Exception #0) System.Security.Cryptography.CryptographicException: Unable to decode certificate. ---> System.Security.Cryptography.CryptographicException: Input data cannot be coded as a valid certificate. ---> System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
05-28 15:19:54.966 I/mono-stdout( 3808): Parameter name: startIndex
05-28 15:19:54.967 I/mono-stdout( 3808):   at System.String.IndexOf (System.String value, System.Int32 startIndex, System.Int32 count, System.StringComparison comparisonType) [0x0002a] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at System.String.IndexOf (System.String value, System.Int32 startIndex, System.StringComparison comparisonType) [0x00009] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at System.String.IndexOf (System.String value, System.Int32 startIndex) [0x00000] in <d18287e1d683419a8ec3216fd78947b9>:0 
  at Mono.Security.X509.X509Certificate.PEM (System.String type, System.Byte[] data) [0x00030] in <2940be14d5a1446694e2193e9029b558>:0 
  at Mono.Security.X509.X509Certificate..ctor (System.Byte[] data) [0x00014] in <2940be14d5a1446694e2193e9029b558>:0 
   --- End of inner exception stack trace ---
  at Mono.Security.X509.X509Certificate..ctor (System.Byte[] data) [0x0002f] in <2940be14d5a1446694e2193e9029b558>:0 
  at System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x0000b] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
   --- End of inner exception stack trace ---
  at System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certif
icates.X509KeyStorageFlags keyStorageFlags) [0x00031] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
  at System.Security.Cryptography.X509Certificates.X509Helper2.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags, System.Boolean disableProvider) [0x00020] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
  at System.Security.Cryptography.X509Certificates.X509Certificate2.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x00000] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
  at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor (System.Byte[] rawData) [0x00011] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
  at APP.Models.Services.ACommunicationService.CreateCertificate (System.String storeType, System.String storePath, System.String password, System.String applicationUri, System.String applicationName, System.String subjectName, System.Collections.Generic.IList`1[T] domainNames, System.UInt16 keySize, System.DateTime startTime, 
System.UInt16 lifetimeInMonths, System.UInt16 hashSizeInBits, System.Boolean isCA, System.Security.Cryptography.X509Certificates.X509Certificate2 issuerCAKeyCert) [0x003b5] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:517 
  at APP.Models.Services.ACommunicationService.CreateCertificate (System.String storeType, System.String storePath, System.String applicationUri, System.String applicationName, System.String subjectName, System.Collections.Generic.IList`1[T] serverDomainNames, System.UInt16 keySize, System.UInt16 lifetimeInMonths, System.UInt16 hashSizeInBits) [0x00001] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:318 
  at APP.Models.Services.ACommunicationService+<ACommunicationServiceAsync>d__18.MoveNext () [0x00972] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:214 <---
05-28 15:19:54.968 I/mono-stdout( 3808):   at System.String.IndexOf (System.String value, System.Int32 startIndex, System.StringComparison comparisonType) [0x00009] in <d18287e1d683419a8ec3216fd78947b9>:0 
05-28 15:19:54.969 I/mono-stdout( 3808):   at System.String.IndexOf (System.String value, System.Int32 startIndex) [0x00000] in <d18287e1d683419a8ec3216fd78947b9>:0 
05-28 15:19:54.969 I/mono-stdout( 3808):   at Mono.Security.X509.X509Certificate.PEM (System.String type, System.Byte[] data) [0x00030] in <2940be14d5a1446694e2193e9029b558>:0 
05-28 15:19:54.969 I/mono-stdout( 3808):   at Mono.Security.X509.X509Certificate..ctor (System.Byte[] data) [0x00014] in <2940be14d5a1446694e2193e9029b558>:0 
05-28 15:19:54.969 I/mono-stdout( 3808):    --- End of inner exception stack trace ---
05-28 15:19:54.969 I/mono-stdout( 3808):   at Mono.Security.X509.X509Certificate..ctor (System.Byte[] data) [0x0002f] in <2940be14d5a1446694e2193e9029b558>:0 
05-28 15:19:54.969 I/mono-stdout( 3808):   at System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x0000b] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
05-28 15:19:54.969 I/mono-stdout( 3808):    --- End of inner exception stack trace ---
05-28 15:19:54.969 I/mono-stdout( 3808):   at System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x00031] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
05-28 15:19:54.970 I/mono-stdout( 3808):   at System.Security.Cryptography.X509Certificates.X509Helper2.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags, System.Boolean disableProvider) [0x00020] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
05-28 15:19:54.970 I/mono-stdout( 3808):   at System.Security.Cryptography.X509Certificates.X509Certificate2.Import (System.Byte[] rawData, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) [0x00000] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
05-28 15:19:54.970 I/mono-stdout( 3808):   at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor (System.Byte[] rawData) [0x00011] in <1a27f8ea09e3480db932cbde0eaedfb2>:0 
05-28 15:19:54.970 I/mono-stdout( 3808):   at APP.Models.Services.ACommunicationService.CreateCertificate (System.String storeType, System.String storePath, System.String password, System.String applicationUri, System.String applicationName, System.String subjectName, System.Collections.Generic.IList`1[T] domainNames, System.UInt16 keySize, System.DateTime startTime, System.UInt16 lifetimeInMonths, System.UInt16 hashSizeInBits, System.Boolean isCA, System.Security.Cryptography.X509Certificates.X509Certificate2 issuerCAKeyCert) [0x003b5] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:517 
05-28 15:19:54.971 I/mono-stdout( 3808):   at APP.Models.Services.ACommunicationService.CreateCertificate (System.String storeType, System.String storePath, System.String applicationUri, System.String applicationName, System.String subjectName, System.Collections.Generic.IList`1[T] serverDomainNames, System.UInt16 keySize, System.UInt16 lifetimeInMonths, System.UInt16 hashSizeInBits) [0x00001] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:318 
05-28 15:19:54.971 I/mono-stdout( 3808):   at APP.Models.Services.ACommunicationService+<ACommunicationServiceAsync>d__18.MoveNext () [0x00972] in C:\projects\APP - Kopie\APP_XamarinApplication\APP\APP\APP\Models\Services\ACommunicationService.cs:214 <---

I use Xamarin PCL with .NET Standard 1.3 and I can only use the "Portable.BouncyCastle" Nuget package.

Release 1.8.1 - NuGet Publish

Hi,

Sorry - looked on your website but wasn't sure who to contact.

I notice that release 1.8.1 has not been put on Nuget (it's currently v1.7).

Please could you let me know - Have you stopped updating NuGet, or is this in progress?

I could put the current release on NuGet, but thought that would be rude seeing as I haven't written any of the code (and it wouldn't update the existing version).

Kind regards,

Justin

DerUtcTime.ToAdjustedDateTime() fails for Apple Mail messages

Here's a link to the error encountered in MimeKit: jstedfast/MimeKit#103

I think the problem is that the date encoded by Apple Mail has a seconds value of "60" (the value should probably be between 0 and 59, inclusive, if my understanding is correct for DateTime's parser).

I have a workaround in the most recent comment on that issue that basically rewrites DerUtcTime's ParseDateString() method to fixificate the hour/minute/second values and then re-serialize them back into a fixedDateStr string to pass to DateTime's parser (if we target .NET >= 3.5, that method could probably be fixed to parse out the TimeZone and use that, but in .NET <= 2.0, TimeZoneInfo does not exist so I don't know of a way of doing it other than hard-coding all known timezones).

Built Binary

I would like to get the latest binary. I check the bouncy castle site and the latest binary is from 2011. I cant get this code to build because of missing nunit libraries. If someone could include the latest built DLL, that would be really helpful. Thanks.

Performance issue when CRL list is very large

Hi,
I have a problem with using BC to validate certificate revocation when the CRL is very large, e.g. 10MB or 20MB. When I look into relevant code of the IsRevoked method below, I find some potential issues. First of all, the c.GetRevokedCertificates() returns a copy of all revoked certificates. Secondly, because it loops through all items sequently and the list is very large, it takes about 200ms to verify a single certificate which is a big hit to my application. While I can easily fork and improve code to eliminate the copy and change to use Dictionary, I would like to know if there are any potential issues with doing that? Or to put it differently, could you please give me some insight about why code was done like that in the first place?

Thank you very much :)

	public virtual bool IsRevoked(
		X509Certificate cert)
	{
		CrlEntry[] certs = c.GetRevokedCertificates();

		if (certs != null)
		{
			//BigInteger serial = ((X509Certificate)cert).SerialNumber;
			BigInteger serial = cert.SerialNumber;

			for (int i = 0; i < certs.Length; i++)
			{
				if (certs[i].UserCertificate.Value.Equals(serial))
				{
					return true;
				}
			}
		}

		return false;
	}

How to implement RSA512 (SSLeavy)

Hello, how can I implement the signature, and verification, for the strandard RSA 512 (SSLeavy) with BouncyCastle ?

EDIT:

I have tried to verify a signature, but return always false

   static public bool VerifyData(string value, string b64_signature, string pemFileName)
    {
        byte[] data_in = Encoding.UTF8.GetBytes(value);
        byte[] hash = Convert.FromBase64String(b64_signature);
        return VerifyData(data_in, hash, pemFileName);
    }

    static public bool VerifyData(byte[] data, byte[] signature, string pemFileName)
    {
            RsaKeyParameters key = ReadPem(pemFileName) as RsaKeyParameters;
            ISigner sig = SignerUtilities.GetSigner("SHA512WITHRSA");
            sig.Init(false, key);
            sig.BlockUpdate(data, 0, data.Length);
            return sig.VerifySignature(signature);
    }

    static private Object ReadPem(string fileName)
    {
        string fname = HttpContext.Current.Server.MapPath("/pem/" + fileName);
        using (TextReader stream = File.OpenText(fname))
        {
            PemReader pem = new PemReader(stream);
            return pem.ReadObject();
        }
    }

Constructor for X9FieldElement would need static ECCurve.FromBigInteger method

    public X9FieldElement(
        BigInteger      p,
        Asn1OctetString s)

would require a static ECCurve.FromBigInteger method in order to comply with the [Obsolete] attribute on the FpFieldElement(BigInteger, BigInteger) constructor. I understand that it was probably marked obsolete because its use is almost always going to cause more processing than originally intended due to FpFieldElement(BigInteger, BigInteger) performing additional residue calculation. However... there would also be an additional processing window to figure out if p was a known curve so its class could be appropriately invoked or instantiated.

I don't know if it's appropriate for FpFieldElement(BigInteger, BigInteger) to be marked obsolete, given that this X9FieldElement constructor is not obsolete.

In any case, I think a #pragma warning disable CS0618 around the offending X9FieldElement constructor would be appropriate, as it's a utility function to permit passing an arbitrary BigInteger from a Asn1OctetString.

However, I also don't know what your design decisions here actually are, so I can't figure out how best to approach this.

CMS Unit tests - SignedDataTests.cs TestSha1WithRsaAndAttributeTable() uses the wrong cert to perform the signature

SignedDataTests.cs is one of the CMS unit test files. TestSha1WithRsaAndAttributeTable() is one of the unit tests that steps through the full procedure of picking a full certificate chain to sign a simple message with, producing a detached signature, and then verifying the signature.

The test uses two certificates defined/created by the test harness - OrigCert and SignCert.

Here is how they are created:

        private static X509Certificate OrigCert
        {
            get { return origCert == null ? (origCert = CmsTestUtil.MakeCertificate(OrigKP, OrigDN, OrigKP, OrigDN)) : origCert; }
        }

        private static X509Certificate SignCert
        {
            get { return signCert == null ? (signCert = CmsTestUtil.MakeCertificate(SignKP, SignDN, OrigKP, OrigDN)) : signCert; }
        }

And here is where they are included in the certificate chain as part of the signature process.

    IList certList = new ArrayList();
    certList.Add(OrigCert);
    certList.Add(SignCert);

From the names of the properties, and how the certs they represent are constructed, it would seem that OrigCert is supposed to be a root cert - it is self signed, and it is used to issue SignCert. Presumably, SignCert then is used to sign the payload - the 'hello world' message in the test.

The problem is that when the signature is generated in the test, SignCert is not used to generate the signature - OrigCert is used instead:

gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataGenerator.DigestSha1,
    new AttributeTable(v), null);

This probably was supposed to use SignCert, not OrigCert, since it doesn't make practical sense to include a subordinate cert when signing a message with a cert higher in the chain; this signature could've been completed all the same without the statement certList.Add(SignCert);.

About subject chinese character Problem of Pkcs10CertificationRequest

Hi dear guys,

I want to check the CSR and get the subject using BouncyCastle(c#).
If CSR contains chinese character, the result contains messy code.

The following is my code and CSR content, can you help me to resolve?

-----BEGIN CERTIFICATE REQUEST-----
MIIBWDCB/wIBADCBnDELMAkGA1UEBhMCQ04xFTATBgNVBAgMDMOkwrjCrcOlwpvC
vTEVMBMGA1UEBwwMw6TCuMKtw6XCm8K9MRUwEwYDVQQKDAzDpMK4wq3DpcKbwr0x
FTATBgNVBAsMDMOkwrjCrcOlwpvCvTERMA8GA1UEAwwIdGVzdC5jb20xHjAcBgkq
hkiG9w0BCQEWD2NtczFAd29zaWduLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEH
A0IABH5BKV5EksxpQSgs3N6KG58rUdFCEN00uIZLSfy7figQAYFE9oQhXC+5C59R
8g81DOsi8zfhOYexhvjLT+OUdemgADAKBggqhkjOPQQDAgNIADBFAiEA2se8iUlw
RwMAk/QCXEdCssnypRlxBOvFoetWwwl6a1MCID+OjMjdgSTk2VZidb7lpj15mLrE
WMy7tfeaFSuZfKIR
-----END CERTIFICATE REQUEST-----

public bool CheckCSR(string csr,ref string subject, ref int length, ref string signatureAlgorithmName,ref string encryptAlgorithmName)
{

         Pkcs10CertificationRequest request = (Pkcs10CertificationRequest)PemReader(csr);

        if (request.Verify())
        {
           
            subject = request.GetCertificationRequestInfo().Subject.ToString();
            var publicKey = request.GetPublicKey();
            return true;
       }
        return false;
    }

    private  object PemReader(string pem)
    {
     
        using (TextReader reader = new StringReader(pem))
        {
            var pemreader = new PemReader(reader);
            return pemreader.ReadPemObject();
        }
    }

Thank you very much.

Roy from China

Thoughts on code modernization?

Some idioms seem outdated (implementing IEnumberable but not IEnumerable being a big one).

Is this just an effect of making the C# and Java code look similar? Would clean-up contributions be accepted?

Thanks!

Cleanup repository

The repository could use some cleaning up in terms of naming and solution files.
I would recommend the following changes:

  • Delete csharp.sln as it is for an old version of Visual Studio (VS2015 Community is free)
  • Delete the crypto-test and crypto.tests.Net45 projects as they are no longer needed. Test Explorer, Resharper and so on have test discovery and can run all tests directly from VS2015. For everyone else, the tests are built to be run as console applications.
  • Rename the "crypto" project files to BouncyCastle instead.
  • Have common naming on project files such as "BouncyCastle.DotNet45", "BouncyCastle.PCL", "BouncyCastle.iOS". Only small adjustments are needed as some project files already follow this naming.

Having these changes just makes it a lot easier to identify what you are working with as a contributor.

Inconsistent line terminators

Hey,

I'm having trouble cloning your repo due to the file crypto/src/asn1/isismtt/x509/AdmissionSyntax.cs. I think the problem is that the file has inconsistent line terminators and I'm running with Git's standard eol settings that convert text files to native line endings. As a result I get garbage output in the file.

For reference if I disable my eol settings (or download the repo as an zip archive) I can confirm the line ending issue. Running the UNIX tool "file" on all the files in the repo confirms that all files have the Linux LF file terminator (default Git internal representation) with the exception of AdmissionSyntax.cs:
./crypto/src/asn1/isismtt/x509/AdmissionSyntax.cs: Little-endian UTF-16 Unicode text, with CRLF, CR line terminators

I've seen this sort of thing before when tools like Visual Studio get a little bit confused about the line endings...

Would it be possible for you to fix this?

Thanks =)

Update Nuget Package

Please, update the nuget package !
The ECC operations are at least 10* faster, which I really need for NBitcoin.

I'm thinking about copying only the ECC part of BouncyCastle directly into the source of NBitcoin, but this give a trust problem, where people would wonder if I have not inserted some flaws to steal keys.

Let me know if I can do anything to help you on that.
Peter, I already sent you powershell scripts to push BouncyCastle easily to nuget.

DerGeneralizedTime StackOverflowException

DerGeneralizedTime time = new DerGeneralizedTime("20160601140601GMT-04:00");

... throws a StackOverflowException when it tries to call DerGeneralizedTime.ToDateTime() in the constructor. This happens because, when the string specifies a time zone instead of ending in "Z", DerGeneralizedTime.ToDateTime() first calls GetTime(), which calls CalculateGmtOffset() ... which calls ToDateTime().

(I also notice that the time-zoned format follows the general form of yyyyMMddHHmmss'GMT'zzz -- that is, containing the literal text 'GMT' before the offset. This is incorrect; the ASN.1 specification says it should be yyyyMMddHHmmsszzz.)

PKCS12Store.GetCertificateChain() fails when signing algorithm is 1.3.14.3.2.29 (legacy SHA1 with RSA)

Microsoft's makecert.exe utility by default generates certificate signed using the 1.3.14.3.2.29 - SHA1 with RSA signature algorithm.

This algorithm is currently not recognised by the SignerUtilities class, causing the PKCS12Store.GetCertificateChain() method to fail with:

Org.BouncyCastle.Security.SecurityUtilityException: Signer 1.3.14.3.2.29 not recognised. 
at Org.BouncyCastle.Security.SignerUtilities.GetSigner(String algorithm) 

Update PgpKeyRingGenerator and PGPSecretKey key use of SHA256 Digest

Currently it supports only the use of SHA1. The latest changes in RFC 4880 in section 13.6 for DSA http://tools.ietf.org/html/rfc4880#section-13.6 if a value for DSA higher than 1024 us used SHA1 is no longer valid this will also affect RFC 6637 where it would be SHA 256. Here is an example of a key with DSA 20148 with SHA1 used in pgpdump:

Old: Public Key Packet(tag 6)(814 bytes)
        Ver 4 - new
        Public key creation time - Sat Jun  7 00:44:19 UTC 2014
        Pub alg - DSA Digital Signature Algorithm(pub 17)
        DSA p(2048 bits) - ...
        DSA q(256 bits) - ...
        DSA g(2047 bits) - ...
        DSA y(2048 bits) - ...
Old: User ID Packet(tag 13)(32 bytes)
        User ID - Carlos Perez <[email protected]>
Old: Signature Packet(tag 2)(113 bytes)
        Ver 4 - new
        Sig type - Generic certification of a User ID and Public Key packet(0x10).
        Pub alg - DSA Digital Signature Algorithm(pub 17)
        Hash alg - SHA1(hash 2)
        Hashed Sub: signature creation time(sub 2)(4 bytes)
                Time - Sat Jun  7 00:44:19 UTC 2014
        Hashed Sub: preferred symmetric algorithms(sub 11)(6 bytes)
                Sym alg - AES with 256-bit key(sym 9)
                Sym alg - AES with 192-bit key(sym 8)
                Sym alg - AES with 128-bit key(sym 7)
                Sym alg - Twofish with 256-bit key(sym 10)
                Sym alg - CAST5(sym 3)
                Sym alg - Triple-DES(sym 2)
        Hashed Sub: preferred hash algorithms(sub 21)(4 bytes)
                Hash alg - SHA256(hash 8)
                Hash alg - SHA384(hash 9)
                Hash alg - SHA512(hash 10)
                Hash alg - RIPEMD160(hash 3)
        Hashed Sub: preferred compression algorithms(sub 22)(3 bytes)
                Comp alg - ZLIB <RFC1950>(comp 2)
                Comp alg - ZIP <RFC1951>(comp 1)
                Comp alg - BZip2(comp 3)
        Sub: issuer key ID(sub 16)(8 bytes)
                Key ID - 0x9379B62B9FF38C62
        Hash left 2 bytes - 44 ec 
        DSA r(256 bits) - ...
        DSA s(254 bits) - ...
                -> hash(DSA q bits)
Old: Public Subkey Packet(tag 14)(525 bytes)
        Ver 4 - new
        Public key creation time - Sat Jun  7 00:44:19 UTC 2014
        Pub alg - ElGamal Encrypt-Only(pub 16)
        ElGamal p(2048 bits) - ...
        ElGamal g(2 bits) - ...
        ElGamal y(2048 bits) - ...
Old: Signature Packet(tag 2)(113 bytes)
        Ver 4 - new
        Sig type - Subkey Binding Signature(0x18).
        Pub alg - DSA Digital Signature Algorithm(pub 17)
        Hash alg - SHA1(hash 2)
        Hashed Sub: signature creation time(sub 2)(4 bytes)
                Time - Sat Jun  7 00:44:19 UTC 2014
        Hashed Sub: preferred symmetric algorithms(sub 11)(6 bytes)
                Sym alg - AES with 256-bit key(sym 9)
                Sym alg - AES with 192-bit key(sym 8)
                Sym alg - AES with 128-bit key(sym 7)
                Sym alg - Twofish with 256-bit key(sym 10)
                Sym alg - CAST5(sym 3)
                Sym alg - Triple-DES(sym 2)
        Hashed Sub: preferred hash algorithms(sub 21)(4 bytes)
                Hash alg - SHA256(hash 8)
                Hash alg - SHA384(hash 9)
                Hash alg - SHA512(hash 10)
                Hash alg - RIPEMD160(hash 3)
        Hashed Sub: preferred compression algorithms(sub 22)(3 bytes)
                Comp alg - ZLIB <RFC1950>(comp 2)
                Comp alg - ZIP <RFC1951>(comp 1)
                Comp alg - BZip2(comp 3)
        Sub: issuer key ID(sub 16)(8 bytes)
                Key ID - 0x9379B62B9FF38C62
        Hash left 2 bytes - e1 de 
        DSA r(255 bits) - ...
        DSA s(256 bits) - ...
                -> hash(DSA q bits)

when we try to import it we can see that GPG will complain

gpg2 --import -v ~/Desktop/9379B62B9FF38C62_pub.asc 
Version: BCPG C# v1.7.5056.37991
gpg: armor header: 
gpg: pub  2048D/9FF38C62 2014-06-07  Carlos Perez <[email protected]>
gpg: DSA key 9FF38C62 requires a 256 bit or larger hash
gpg: DSA key 9FF38C62 requires a 256 bit or larger hash
gpg: key 9FF38C62: invalid self-signature on user ID "Carlos Perez <[email protected]>"
gpg: DSA key 9FF38C62 requires a 256 bit or larger hash
gpg: DSA key 9FF38C62 requires a 256 bit or larger hash
gpg: key 9FF38C62: invalid subkey binding
gpg: key 9FF38C62: skipped user ID "Carlos Perez <[email protected]>"
gpg: key 9FF38C62: skipped subkey
gpg: key 9FF38C62: no valid user IDs
gpg: this may be caused by a missing self-signature
gpg: Total number processed: 1
gpg:           w/o user IDs: 1

I used the following code to generate the DSA key

public AsymmetricCipherKeyPair DSA2KeyGen(int KeySize)
        {
            // Check that we got a proper key size
            int[] allowedKeySizes = {1024, 2048, 3072};
            if (!(allowedKeySizes.Contains(KeySize)))
            {
                throw new ArgumentException("KeySize provided is not 1024, 2048 or 3072.", "KeySize");
            }

            // Set the proper N parameter depending on the bit key size.
            int DSA2NParam;
            if (KeySize == 1024)
            {
                DSA2NParam = 160;
            }
            else
            {
                DSA2NParam = 256;
            }

            var secRand = new SecureRandom();
            var dsa2Genertor = GeneratorUtilities.GetKeyPairGenerator("DSA");

            // Generate the proper parameters for the DSA2 Key.
            var digest = new Sha256Digest();
            var paramGen = new DsaParametersGenerator(digest);
            var dsaParamsList = new DsaParameterGenerationParameters(KeySize, DSA2NParam, 80, secRand);
            paramGen.Init(dsaParamsList);

            // This will take a while since it has to find a valid random prime number for use.
            var dsaParams = paramGen.GenerateParameters();

            var dsaOptions = new DsaKeyGenerationParameters(secRand,dsaParams);
            AsymmetricCipherKeyPair keyPair = dsa2Genertor.GenerateKeyPair();

            return keyPair;
        }

X509SignatureFactory : ISignatureFactory doesn't verify construction with a private key

X509SignatureFactory doesn't verify that it is constructed with a private key. An error here will eventually be discovered when it comes time to generate the signature, but because the Pkcs10CertificationRequest constructor verifies that the private key is private (though not that it matches publicKey) I think the constructor of an ISignatureFactory should probably check for its construction with valid parameters before it gets to generation time -- if only to make it quicker for clients to detect the error, and thus quicker to debug the issues they have.

Code changes break CF compatibility

It seems as if .NET CF is being dropped? Many of the newest code changes are not CF compatible, but they are not being conditioned by CF.

For instance:

    private static long counter = Times.NanoTime ();

    private static long NextCounterValue ()
        {
        return Interlocked.Increment (ref counter);
        }

where Interlocked.Increment (Int64) is not supported in CF.

PCL support

Are you interested in having BC compiled/released as a Portable Class Library? Crypto is an issue with cross-platform development now as the Microsoft API's are all platform-specific.

I have BC compiled as a PCL targeting .NET 4, SL 5, WP8, Win8, Xam.iOS and Xam.Android. That's pretty much the widest-range of current platform targets. The only real pieces missing are the direct file-based access as there's no cross-plat file manipulation mechanism either :)

I can incorporate my changes into a fork of this repo and submit a PR if desired. The biggest thing I can't figure out is really how to deal with the NAnt build that you're using. AFAIK, NAnt has no support for PCL's. It requires MSBuild to build the csproj using the PCL targets and reference assemblies.

You can see my code here: https://github.com/onovotny/BouncyCastle-PCL, though it's not a direct fork of this repo (but I can easily reapply those changes here).

CcmBlockCipher implementation is not streamable

It appears the CcmBlockCipher implementation has a fake interface, and states that CCM is a packet mode.

This isn't quite true; the CTR stream cipher itself is not only streamable, but seekable to the byte (for reads - seeking writes is dangerous), and the CBC-MAC tag used allows streaming accumulation of the MAC to eventually output as a tag.

Missing Embedded Signature subpacket generation in PgpSignatureGenerator.AddSubkey

In RFC4880 section 5.2.1 (https://tools.ietf.org/html/rfc4880#section-5.2.1) it is stated that a subkey binding signature which relates to a signing subkey MUST have an embedded signature subpacket. The embedded signature is the reverse signature of the subkey against the master key.

I think, it should be implemented in PgpSignatureGenerator.AddSubkey.

I could not find an appropriate implementation in the BC-java either.

Add Coverity scan for static code analysis

I'm using BouncyCastle in my C# project (https://github.com/Pro/dkim-exchange) in combination with Coverity (http://www.coverity.com/, free for open source) to test my code for flaws and problems. Coverity did find about 150 problems in the BouncyCastle code (i.e., race conditions, integer overflows, infinite loops, bad bit shift operations, null dereferences, ...).

I would suggest that you submit your builds to Coverity to have some (static) code checking.

If you need help setting it up just write here or look at my project, especially:
https://github.com/Pro/dkim-exchange/blob/master/coverity_build.bat
and
https://github.com/Pro/dkim-exchange/blob/master/travis.proj

Platform.CreateHashTable() Failing in PCL running on Windows Phone 8.1

Seems to be the root cause of trying to construct a BouncyCastle BigInteger in a PCL using the BouncyCastle-PCL 1.0.0.6 from Nuget, as I get a MethodAccessException when running my Windows Phone 8.1 emulator. The Android emulator works by the way.

So, to sum up:

  • Android works
  • Windows Phone 8.1 does not

  • BigInteger(1, bytes[128]); is the offending line
  • Platform.CreateHashTable() is the offending InnerException method
  • Xamarin.Forms.Device.OS recognizes the OS as "Windows" not "Windows Phone"
  • Seems to be an issue in Crypto\util\Platform.cs with defines
    • It seems to reference System.Collections rather than System.Collections.Generic for some reason

Add support for mixed hashing (RSA/ECB/OAEPWithSHA-256AndMGF1Padding)

In java (up to JDK8) per default the MGF digesting algorithm used is SHA1, currently there is no way to specify a different hashing algorithm between OAEP and MGF.

One (bad way) to circumvent this is to use reflection to change mgfHash field in the cipher:

var cipherImpl = GetInstanceField(c.GetType(), c, "cipher");
var newDigest = new Sha1Digest();
var prop = cipherImpl.GetType().GetField("mgf1Hash", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
prop.SetValue(cipherImpl, newDigest);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.