Notation.Plugin.AzureKeyVault/Certificate/Pkcs12.cs (39 lines of code) (raw):

using System.Security.Cryptography.Pkcs; using Notation.Plugin.Protocol; namespace Notation.Plugin.AzureKeyVault.Certificate { static class Pkcs12 { /// <summary> /// Re-encode the PKCS12 data to remove the MAC and keys. /// The macOS doesn't support PKCS12 with non-encrypted MAC. /// </summary> /// <param name="data"></param> /// <returns></returns> /// <exception cref="ValidationException"></exception> public static byte[] ReEncode(byte[] data) { Pkcs12Info pfx = Pkcs12Info.Decode(data, out _); // only remove the MAC if it is password protected if (pfx.IntegrityMode != Pkcs12IntegrityMode.Password) { return data; } // verify the MAC with null password if (!pfx.VerifyMac(null)) { throw new ValidationException("Invalid MAC or the MAC password is not null"); } // re-build PFX without MAC and keys Pkcs12Builder pfxBuilder = new Pkcs12Builder(); foreach (var safeContent in pfx.AuthenticatedSafe) { // decrypt with null password if (safeContent.ConfidentialityMode == Pkcs12ConfidentialityMode.Password) { safeContent.Decrypt((byte[]?)null); } // create a newSafeContent and only contains the certificate bag var newSafeContent = new Pkcs12SafeContents(); foreach (var bag in safeContent.GetBags()) { if (bag is Pkcs12CertBag) { newSafeContent.AddSafeBag(bag); } } pfxBuilder.AddSafeContentsUnencrypted(newSafeContent); } pfxBuilder.SealWithoutIntegrity(); return pfxBuilder.Encode(); } } }