Example #1
0
            public void MoveTo(X509Certificate2Collection collection)
            {
                foreach (UnixPkcs12Reader.CertAndKey certAndKey in _pkcs12.EnumerateAll())
                {
                    AppleCertificatePal pal = (AppleCertificatePal)certAndKey.Cert !;
                    SafeSecKeyRefHandle?safeSecKeyRefHandle =
                        ApplePkcs12Reader.GetPrivateKey(certAndKey.Key);

                    using (safeSecKeyRefHandle)
                    {
                        ICertificatePal newPal;

                        // SecItemImport doesn't seem to respect non-exportable import for PKCS#8,
                        // only PKCS#12.
                        //
                        // So, as part of reading this PKCS#12 we now need to write the minimum
                        // PKCS#12 in a normalized form, and ask the OS to import it.
                        if (!_exportable && safeSecKeyRefHandle != null)
                        {
                            newPal = AppleCertificatePal.ImportPkcs12NonExportable(
                                pal,
                                safeSecKeyRefHandle,
                                _password,
                                _keychain);
                        }
                        else
                        {
                            newPal = pal.MoveToKeychain(_keychain, safeSecKeyRefHandle) ?? pal;
                        }

                        X509Certificate2 cert = new X509Certificate2(newPal);
                        collection.Add(cert);
                    }
                }
            }
 private static AppleCertificatePal ImportPkcs12(
     ReadOnlySpan <byte> rawData,
     SafePasswordHandle password)
 {
     using (ApplePkcs12Reader reader = new ApplePkcs12Reader(rawData))
     {
         reader.Decrypt(password);
         return(ImportPkcs12(reader.GetSingleCert()));
     }
 }
        public ApplePkcs12CertLoader(
            ApplePkcs12Reader pkcs12,
            SafePasswordHandle password)
        {
            _pkcs12 = pkcs12;

            bool addedRef = false;

            password.DangerousAddRef(ref addedRef);
            _password = password;
        }
Example #4
0
            public ApplePkcs12CertLoader(
                ApplePkcs12Reader pkcs12,
                SafeKeychainHandle keychain,
                SafePasswordHandle password,
                bool exportable)
            {
                _pkcs12     = pkcs12;
                _keychain   = keychain;
                _exportable = exportable;

                bool addedRef = false;

                password.DangerousAddRef(ref addedRef);
                _password = password;
            }
        private static ICertificatePal ImportPkcs12(
            byte[] rawData,
            SafePasswordHandle password,
            bool exportable,
            SafeKeychainHandle keychain)
        {
            using (ApplePkcs12Reader reader = new ApplePkcs12Reader(rawData))
            {
                reader.Decrypt(password);

                UnixPkcs12Reader.CertAndKey certAndKey = reader.GetSingleCert();
                AppleCertificatePal         pal        = (AppleCertificatePal)certAndKey.Cert !;

                SafeSecKeyRefHandle?safeSecKeyRefHandle =
                    ApplePkcs12Reader.GetPrivateKey(certAndKey.Key);

                AppleCertificatePal?newPal;

                using (safeSecKeyRefHandle)
                {
                    // SecItemImport doesn't seem to respect non-exportable import for PKCS#8,
                    // only PKCS#12.
                    //
                    // So, as part of reading this PKCS#12 we now need to write the minimum
                    // PKCS#12 in a normalized form, and ask the OS to import it.
                    if (!exportable && safeSecKeyRefHandle != null)
                    {
                        using (pal)
                        {
                            return(ImportPkcs12NonExportable(pal, safeSecKeyRefHandle, password, keychain));
                        }
                    }

                    newPal = pal.MoveToKeychain(keychain, safeSecKeyRefHandle);

                    if (newPal != null)
                    {
                        pal.Dispose();
                    }
                }

                // If no new PAL came back, it means we moved the cert, but had no private key.
                return(newPal ?? pal);
            }
        }
        private static ILoaderPal ImportPkcs12(
            ReadOnlySpan <byte> rawData,
            SafePasswordHandle password,
            bool exportable,
            SafeKeychainHandle keychain)
        {
            ApplePkcs12Reader reader = new ApplePkcs12Reader(rawData);

            try
            {
                reader.Decrypt(password);
                return(new ApplePkcs12CertLoader(reader, keychain, password, exportable));
            }
            catch
            {
                reader.Dispose();
                keychain.Dispose();
                throw;
            }
        }
Example #7
0
        public static ILoaderPal FromBlob(ReadOnlySpan <byte> rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
        {
            List <ICertificatePal>?certificateList = null;

            AppleCertificatePal.TryDecodePem(
                rawData,
                (derData, contentType) =>
            {
                certificateList = certificateList ?? new List <ICertificatePal>();
                certificateList.Add(AppleCertificatePal.FromDerBlob(derData, contentType, password, keyStorageFlags));
                return(true);
            });

            if (certificateList != null)
            {
                return(new CertCollectionLoader(certificateList));
            }

            X509ContentType contentType = AppleCertificatePal.GetDerCertContentType(rawData);

            if (contentType == X509ContentType.Pkcs7)
            {
                throw new CryptographicException(
                          SR.Cryptography_X509_PKCS7_Unsupported,
                          new PlatformNotSupportedException(SR.Cryptography_X509_PKCS7_Unsupported));
            }

            if (contentType == X509ContentType.Pkcs12)
            {
                ApplePkcs12Reader reader = new ApplePkcs12Reader(rawData);

                try
                {
                    reader.Decrypt(password);
                    return(new ApplePkcs12CertLoader(reader, password));
                }
                catch
                {
                    reader.Dispose();
                    throw;
                }
            }

            SafeCFArrayHandle certs = Interop.AppleCrypto.X509ImportCollection(
                rawData,
                contentType,
                password);

            using (certs)
            {
                long longCount = Interop.CoreFoundation.CFArrayGetCount(certs);

                if (longCount > int.MaxValue)
                {
                    throw new CryptographicException();
                }

                int count = (int)longCount;

                // Apple returns things in the opposite order from Windows, so read backwards.
                certificateList = new List <ICertificatePal>(count);
                for (int i = count - 1; i >= 0; i--)
                {
                    IntPtr handle = Interop.CoreFoundation.CFArrayGetValueAtIndex(certs, i);

                    if (handle != IntPtr.Zero)
                    {
                        ICertificatePal?certPal = CertificatePal.FromHandle(handle, throwOnFail: false);

                        if (certPal != null)
                        {
                            certificateList.Add(certPal);
                        }
                    }
                }
            }

            return(new CertCollectionLoader(certificateList));
        }