예제 #1
0
        public static ICertificatePal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
        {
            ICertificatePal?pal;
            bool            ephemeralSpecified = keyStorageFlags.HasFlag(X509KeyStorageFlags.EphemeralKeySet);

            // If we can't open the file, fail right away.
            using (SafeBioHandle fileBio = Interop.Crypto.BioNewFile(fileName, "rb"))
            {
                Interop.Crypto.CheckValidOpenSslHandle(fileBio);

                pal = FromBio(fileBio);
            }

            if (pal == null)
            {
                OpenSslPkcsFormatReader.TryReadPkcs12(
                    File.ReadAllBytes(fileName),
                    password,
                    ephemeralSpecified,
                    out pal,
                    out Exception? exception);

                if (exception != null)
                {
                    throw exception;
                }

                Debug.Assert(pal != null);
            }

            return(pal);
        }
예제 #2
0
        public static ICertificatePal FromBlob(ReadOnlySpan <byte> rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
        {
            Debug.Assert(password != null);

            bool            ephemeralSpecified = keyStorageFlags.HasFlag(X509KeyStorageFlags.EphemeralKeySet);
            X509ContentType contentType        = X509Certificate2.GetCertContentType(rawData);

            switch (contentType)
            {
            case X509ContentType.Pkcs7:
                // In single mode for a PKCS#7 signed or signed-and-enveloped file we're supposed to return
                // the certificate which signed the PKCS#7 file.
                // We don't support determining this on Android right now, so we throw.
                throw new CryptographicException(SR.Cryptography_X509_PKCS7_NoSigner);

            case X509ContentType.Pkcs12:
                return(ReadPkcs12(rawData, password, ephemeralSpecified));

            case X509ContentType.Cert:
            default:
            {
                ICertificatePal?cert;
                if (TryReadX509(rawData, out cert))
                {
                    return(cert);
                }

                break;
            }
            }

            // Unsupported
            throw new CryptographicException();
        }
예제 #3
0
        internal static partial ILoaderPal FromBlob(ReadOnlySpan <byte> rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
        {
            Debug.Assert(password != null);

            ICertificatePal?singleCert;
            bool            ephemeralSpecified = keyStorageFlags.HasFlag(X509KeyStorageFlags.EphemeralKeySet);

            if (OpenSslX509CertificateReader.TryReadX509Der(rawData, out singleCert) ||
                OpenSslX509CertificateReader.TryReadX509Pem(rawData, out singleCert))
            {
                // The single X509 structure methods shouldn't return true and out null, only empty
                // collections have that behavior.
                Debug.Assert(singleCert != null);

                return(SingleCertToLoaderPal(singleCert));
            }

            List <ICertificatePal>?certPals;
            Exception?openSslException;

            if (OpenSslPkcsFormatReader.TryReadPkcs7Der(rawData, out certPals) ||
                OpenSslPkcsFormatReader.TryReadPkcs7Pem(rawData, out certPals) ||
                OpenSslPkcsFormatReader.TryReadPkcs12(rawData, password, ephemeralSpecified, out certPals, out openSslException))
            {
                Debug.Assert(certPals != null);

                return(ListToLoaderPal(certPals));
            }

            Debug.Assert(openSslException != null);
            throw openSslException;
        }
예제 #4
0
        public static ICertificatePal FromBlob(ReadOnlySpan <byte> rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
        {
            Debug.Assert(password != null);

            ICertificatePal?cert;
            Exception?      openSslException;
            bool            ephemeralSpecified = keyStorageFlags.HasFlag(X509KeyStorageFlags.EphemeralKeySet);

            if (TryReadX509Der(rawData, out cert) ||
                TryReadX509Pem(rawData, out cert) ||
                OpenSslPkcsFormatReader.TryReadPkcs7Der(rawData, out cert) ||
                OpenSslPkcsFormatReader.TryReadPkcs7Pem(rawData, out cert) ||
                OpenSslPkcsFormatReader.TryReadPkcs12(rawData, password, ephemeralSpecified, out cert, out openSslException))
            {
                if (cert == null)
                {
                    // Empty collection, most likely.
                    throw new CryptographicException();
                }

                return(cert);
            }

            // Unsupported
            Debug.Assert(openSslException != null);
            throw openSslException;
        }
예제 #5
0
        internal static partial ILoaderPal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
        {
            bool ephemeralSpecified = keyStorageFlags.HasFlag(X509KeyStorageFlags.EphemeralKeySet);

            using (SafeBioHandle bio = Interop.Crypto.BioNewFile(fileName, "rb"))
            {
                Interop.Crypto.CheckValidOpenSslHandle(bio);

                return(FromBio(fileName, bio, password, ephemeralSpecified));
            }
        }
예제 #6
0
        internal static ICertificatePal FromDerBlob(
            ReadOnlySpan <byte> rawData,
            X509ContentType contentType,
            SafePasswordHandle password,
            X509KeyStorageFlags keyStorageFlags)
        {
            Debug.Assert(password != null);

            bool ephemeralSpecified = keyStorageFlags.HasFlag(X509KeyStorageFlags.EphemeralKeySet);

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

            if (contentType == X509ContentType.Pkcs12)
            {
                if ((keyStorageFlags & X509KeyStorageFlags.Exportable) == X509KeyStorageFlags.Exportable)
                {
                    throw new PlatformNotSupportedException(SR.Cryptography_X509_PKCS12_ExportableNotSupported);
                }

                if ((keyStorageFlags & X509KeyStorageFlags.PersistKeySet) == X509KeyStorageFlags.PersistKeySet)
                {
                    throw new PlatformNotSupportedException(SR.Cryptography_X509_PKCS12_PersistKeySetNotSupported);
                }

                return(ImportPkcs12(rawData, password, ephemeralSpecified));
            }

            SafeSecIdentityHandle    identityHandle;
            SafeSecCertificateHandle certHandle = Interop.AppleCrypto.X509ImportCertificate(
                rawData,
                contentType,
                password,
                out identityHandle);

            if (identityHandle.IsInvalid)
            {
                identityHandle.Dispose();
                return(new AppleCertificatePal(certHandle));
            }

            Debug.Fail("Non-PKCS12 import produced an identity handle");

            identityHandle.Dispose();
            certHandle.Dispose();
            throw new CryptographicException();
        }
        internal static ICertificatePal FromDerBlob(
            ReadOnlySpan <byte> rawData,
            X509ContentType contentType,
            SafePasswordHandle password,
            X509KeyStorageFlags keyStorageFlags)
        {
            Debug.Assert(password != null);

            bool ephemeralSpecified = keyStorageFlags.HasFlag(X509KeyStorageFlags.EphemeralKeySet);

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

            if (contentType == X509ContentType.Pkcs12)
            {
                // TODO:
                // We ignore keyStorageFlags which is tracked in https://github.com/dotnet/runtime/issues/52434.
                // The keys are always imported as ephemeral and never persisted. Exportability is ignored for
                // the moment and it needs to be investigated how to map it to iOS keychain primitives.
                return(ImportPkcs12(rawData, password, ephemeralSpecified));
            }

            SafeSecIdentityHandle    identityHandle;
            SafeSecCertificateHandle certHandle = Interop.AppleCrypto.X509ImportCertificate(
                rawData,
                contentType,
                password,
                out identityHandle);

            if (identityHandle.IsInvalid)
            {
                identityHandle.Dispose();
                return(new AppleCertificatePal(certHandle));
            }

            Debug.Fail("Non-PKCS12 import produced an identity handle");

            identityHandle.Dispose();
            certHandle.Dispose();
            throw new CryptographicException();
        }
예제 #8
0
        internal static partial ILoaderPal FromBlob(ReadOnlySpan <byte> rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
        {
            Debug.Assert(password != null);

            X509ContentType contentType        = X509Certificate2.GetCertContentType(rawData);
            bool            ephemeralSpecified = keyStorageFlags.HasFlag(X509KeyStorageFlags.EphemeralKeySet);

            if (contentType == X509ContentType.Pkcs12)
            {
                ICertificatePal[] certPals = ReadPkcs12Collection(rawData, password, ephemeralSpecified);
                return(new AndroidCertLoader(certPals));
            }
            else
            {
                SafeX509Handle[] certs = Interop.AndroidCrypto.X509DecodeCollection(rawData);
                return(new AndroidCertLoader(certs));
            }
        }
예제 #9
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));
            }

            bool            ephemeralSpecified = keyStorageFlags.HasFlag(X509KeyStorageFlags.EphemeralKeySet);
            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, ephemeralSpecified);
                    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));
        }