Skip to content

[BUG] PFX generated via bouncycastle Pkcs12Store are not loading in .Net 9 #605

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
hiddenshadow21 opened this issue Apr 9, 2025 · 7 comments
Assignees
Labels
bug Something isn't working

Comments

@hiddenshadow21
Copy link

Describe the Bug

Client certificate generated when creating whole chain (CA, server, and client certificates) is not loading. It fails
AllowDuplicates check added in .Net 9 (check discussion about it here).

As a last step of generating the client pfx we are attaching issuer certificate to have correct chain using bouncyCastle Pkcs12Store as shown below:

        Pkcs12Store store = new Pkcs12StoreBuilder().Build();
        var serverCert = DotNetUtilities.FromX509Certificate(certificateHolder.Certificate);

        store.Load(new MemoryStream(certBytes), Array.Empty<char>());
        store.SetCertificateEntry(serverCert.SubjectDN.ToString(), new X509CertificateEntry(serverCert));

        var memoryStream = new MemoryStream();
        store.Save(memoryStream, Array.Empty<char>(), GetSeededSecureRandom());

While debugging we found that loading our client.pfx fails duplicate check for OID 2.16.840.1.113894.746875.1.1. This one is added automatically, under the hood, when saving PKCS12 store with certificate that does not have private key attached and has an EKU (see source code here).

Are we misusing the BouncyCastle API in this scenario, or is there a recommended way to prevent this OID duplication?
Is bouncycastle not compatible with .Net 9?

To Reproduce

Steps to reproduce the behavior:

  1. Download uploaded app
  2. Run scenario 3.

Expected Behavior

The PFX should load successfully without triggering the duplicate attribute check.

Screenshots and Logs

Image

Desktop

  • OS: Windows 11

Additional Context

There is issue in .Net 9 regarding this problem - dotnet/runtime#113726

In .NET, a workaround was introduced via the internal property Pkcs12LoaderLimits.AllowDuplicateAttributes, but it is not publicly accessible.

Sample .Net 9 console app:
PfxLimitsNet9.zip

There are 3 scenarios in the app:

  1. Self-signed certificates - working correctly
  2. Creating CA and server certificate (without including any in the chain) - loading these certificates is working correctly as well.
  3. Creating whole chain with client cert containing server cert in the pfx chain - not working
@hiddenshadow21 hiddenshadow21 added the bug Something isn't working label Apr 9, 2025
@peterdettman
Copy link
Collaborator

We have this OID as Org.BouncyCastle.Asn1.Misc.MiscObjectIdentifiers.id_oracle_pkcs12_trusted_key_usage. We became aware of a problem with duplicate attributes having this OID via an issue raised against bc-java at the end of last year: bcgit/bc-java#1945 .

The duplication was addressed as part of this commit .

We'd appreciate if you could try one of the recent beta releases (e.g. https://www.nuget.org/packages/BouncyCastle.Cryptography/2.6.0-beta.114) and see if the issue is resolved for you.

@hiddenshadow21
Copy link
Author

Unfortunately the problem still exists in version 2.6.0-beta.114. There is only one attribute, but it has 2 values, which is not allowed in .Net 9:

        private static void RejectDuplicateAttributes(AttributeAsn[] bagAttributes, HashSet<string> duplicateAttributeCheck)
        {
            duplicateAttributeCheck.Clear();

            foreach (AttributeAsn attrSet in bagAttributes)
            {
                // Use >1 instead of =1 to account for MsPkcs12MachineKeySet, which is a named set with no values.
                // An empty attribute set can't be followed by the same empty set, or a non-empty set.
                if (!duplicateAttributeCheck.Add(attrSet.AttrType) || attrSet.AttrValues.Length > 1)
                {
                    throw new Pkcs12LoadLimitExceededException(nameof(Pkcs12LoaderLimits.AllowDuplicateAttributes));
                }
            }
        }

@peterdettman peterdettman self-assigned this Apr 17, 2025
@peterdettman
Copy link
Collaborator

Thanks, I will look into it further.

@hiddenshadow21
Copy link
Author

@peterdettman Did you have a chance to take a peek at this issue?

@peterdettman
Copy link
Collaborator

Probably the restriction disallowing multiple values is too strict, at least for the Oracle TrustedCert OID involved here.

I've checked with the latest JDK code and it appears it can generate multiple attribute values (in the case of an EKU with multiple OIDs), so I don't think BC is inconsistent with that.

Assuming that's the case, it might be best to create a sample PKCS#12 file using JDK (or just keytool), with a trusted cert entry (and suitable ExtendedKeyUsage), then verify failure to load it in .NET 9 and report to dotnet the incompatibility with JDK.

I think it's also worth adding an option to bc-csharp to not include this attribute when saving.

@hiddenshadow21
Copy link
Author

Hi Peter,

Thanks a lot for the detailed analysis and suggestions.

Would you be able to perform the test with keytool/JDK and .NET 9 yourself to confirm the behavior?
We would prefer not to handle this testing ourselves if possible.

Also, adding an option to bc-csharp to omit writing this attribute when saving sounds like a great idea - it would definitely help.

Thanks again for all your help and for considering these improvements!

@peterdettman
Copy link
Collaborator

I've added the option to Pkcs12StoreBuilder and will follow up on the reproducer and bug report when I get the chance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants