예제 #1
0
        private static ICertificatePal[] ReadPkcs12Collection(
            ReadOnlySpan <byte> rawData,
            SafePasswordHandle password,
            bool ephemeralSpecified)
        {
            using (var reader = new AndroidPkcs12Reader(rawData))
            {
                reader.Decrypt(password, ephemeralSpecified);

                ICertificatePal[] certs = new ICertificatePal[reader.GetCertCount()];
                int idx = 0;
                foreach (UnixPkcs12Reader.CertAndKey certAndKey in reader.EnumerateAll())
                {
                    AndroidCertificatePal pal = (AndroidCertificatePal)certAndKey.Cert !;
                    if (certAndKey.Key != null)
                    {
                        pal.SetPrivateKey(AndroidPkcs12Reader.GetPrivateKey(certAndKey.Key));
                    }

                    certs[idx] = pal;
                    idx++;
                }

                return(certs);
            }
        }
예제 #2
0
        public static ICertificatePal FromOtherCert(X509Certificate cert)
        {
            Debug.Assert(cert.Pal != null);

            // Ensure private key is copied
            AndroidCertificatePal certPal = (AndroidCertificatePal)cert.Pal;

            return(certPal.DuplicateHandles());
        }
예제 #3
0
 public AndroidCertLoader(SafeX509Handle[] certHandles)
 {
     _certs = new ICertificatePal[certHandles.Length];
     for (int i = 0; i < certHandles.Length; i++)
     {
         SafeX509Handle handle = certHandles[i];
         Debug.Assert(!handle.IsInvalid);
         _certs[i] = AndroidCertificatePal.FromHandle(handle.DangerousGetHandle());
     }
 }
예제 #4
0
        protected override ICertificatePalCore ReadX509Der(ReadOnlyMemory <byte> data)
        {
            ICertificatePal?cert;

            if (!AndroidCertificatePal.TryReadX509(data.Span, out cert))
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }

            return(cert);
        }
예제 #5
0
            private static IntPtr GetPublicKey(ICertificatePal pal, Interop.AndroidCrypto.PAL_KeyAlgorithm algorithm)
            {
                AndroidCertificatePal certPal = (AndroidCertificatePal)pal;
                IntPtr ptr = Interop.AndroidCrypto.X509GetPublicKey(certPal.SafeHandle, algorithm);

                if (ptr == IntPtr.Zero)
                {
                    throw new CryptographicException();
                }

                return(ptr);
            }
예제 #6
0
            private SafeEcKeyHandle DecodeECPublicKey(ICertificatePal pal)
            {
                AndroidCertificatePal certPal = (AndroidCertificatePal)pal;
                IntPtr ptr = Interop.AndroidCrypto.X509GetPublicKey(certPal.SafeHandle, Interop.AndroidCrypto.PAL_KeyAlgorithm.EC);

                if (ptr == IntPtr.Zero)
                {
                    throw new CryptographicException();
                }

                return(new SafeEcKeyHandle(ptr));
            }
예제 #7
0
            public void MoveTo(X509Certificate2Collection collection)
            {
                for (int i = 0; i < _certs.Length; i++)
                {
                    SafeX509Handle handle = _certs[i];
                    System.Diagnostics.Debug.Assert(!handle.IsInvalid);

                    ICertificatePal  certPal = AndroidCertificatePal.FromHandle(handle.DangerousGetHandle());
                    X509Certificate2 cert    = new X509Certificate2(certPal);
                    collection.Add(cert);
                }
            }
예제 #8
0
        private static ICertificatePal ReadPkcs12(ReadOnlySpan <byte> rawData, SafePasswordHandle password)
        {
            using (var reader = new AndroidPkcs12Reader(rawData))
            {
                reader.Decrypt(password);

                UnixPkcs12Reader.CertAndKey certAndKey = reader.GetSingleCert();
                AndroidCertificatePal       pal        = (AndroidCertificatePal)certAndKey.Cert !;
                if (certAndKey.Key != null)
                {
                    pal.SetPrivateKey(AndroidPkcs12Reader.GetPrivateKey(certAndKey.Key));
                }

                return(pal);
            }
        }
예제 #9
0
        public static ICertificatePal FromOtherCert(X509Certificate cert)
        {
            Debug.Assert(cert.Pal != null);

            AndroidCertificatePal certPal = (AndroidCertificatePal)cert.Pal;

            // Ensure private key is copied
            if (certPal.PrivateKeyHandle != null)
            {
                return(certPal.CopyWithPrivateKeyHandle(certPal.PrivateKeyHandle.DuplicateHandle()));
            }

            SafeX509Handle handle = new SafeX509Handle(Interop.JObjectLifetime.NewGlobalReference(certPal.Handle));

            return(new AndroidCertificatePal(handle));
        }
예제 #10
0
        // Handles both DER and PEM
        internal static bool TryReadX509(ReadOnlySpan <byte> rawData, [NotNullWhen(true)] out ICertificatePal?handle)
        {
            handle = null;
            SafeX509Handle certHandle = Interop.AndroidCrypto.X509Decode(
                ref MemoryMarshal.GetReference(rawData),
                rawData.Length);

            if (certHandle.IsInvalid)
            {
                certHandle.Dispose();
                return(false);
            }

            handle = new AndroidCertificatePal(certHandle);
            return(true);
        }
            public void Add(ICertificatePal cert)
            {
                if (_readOnly)
                {
                    throw new CryptographicException(SR.Cryptography_X509_StoreReadOnly);
                }

                AndroidCertificatePal certPal = (AndroidCertificatePal)cert;
                string hashString             = GetCertificateHashString(cert);

                bool success;

                if (certPal.HasPrivateKey)
                {
                    Interop.AndroidCrypto.PAL_KeyAlgorithm algorithm = certPal.PrivateKeyHandle switch
                    {
                        // The AndroidKeyStore doesn't support adding DSA private key entries in newer versions (API 23+)
                        // Our minimum supported version (API 21) does support it, but for simplicity, we simply block adding
                        // certificates with DSA private keys on all versions instead of trying to support it on two versions.
                        SafeDsaHandle _ => throw new PlatformNotSupportedException(SR.Cryptography_X509_StoreDSAPrivateKeyNotSupported),
                              SafeEcKeyHandle _ => Interop.AndroidCrypto.PAL_KeyAlgorithm.EC,
                              SafeRsaHandle _ => Interop.AndroidCrypto.PAL_KeyAlgorithm.RSA,
                              _ => throw new NotSupportedException(SR.NotSupported_KeyAlgorithm)
                    };

                    success = Interop.AndroidCrypto.X509StoreAddCertificateWithPrivateKey(_keyStoreHandle, certPal.SafeHandle, certPal.PrivateKeyHandle, algorithm, hashString);
                }
                else
                {
                    success = Interop.AndroidCrypto.X509StoreAddCertificate(_keyStoreHandle, certPal.SafeHandle, hashString);
                }

                if (!success)
                {
                    throw new CryptographicException(SR.Cryptography_X509_StoreAddFailure);
                }
            }
            public void Remove(ICertificatePal cert)
            {
                string hashString             = GetCertificateHashString(cert);
                AndroidCertificatePal certPal = (AndroidCertificatePal)cert;

                if (_readOnly)
                {
                    bool containsCert = Interop.AndroidCrypto.X509StoreContainsCertificate(_keyStoreHandle, certPal.SafeHandle, hashString);
                    if (containsCert)
                    {
                        throw new CryptographicException(SR.Cryptography_X509_StoreReadOnly);
                    }

                    // Removing a non-existent certificate is not an error
                    return;
                }

                bool success = Interop.AndroidCrypto.X509StoreRemoveCertificate(_keyStoreHandle, certPal.SafeHandle, hashString);

                if (!success)
                {
                    throw new CryptographicException(SR.Cryptography_X509_StoreRemoveFailure);
                }
            }
예제 #13
0
 protected override X509Certificate2 CloneCertificate(X509Certificate2 cert)
 {
     return(new X509Certificate2(AndroidCertificatePal.FromOtherCert(cert)));
 }
예제 #14
0
 public static ICertificatePal FromOtherCert(X509Certificate cert)
 {
     return(AndroidCertificatePal.FromOtherCert(cert));
 }
예제 #15
0
 public static ICertificatePal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
 {
     return(AndroidCertificatePal.FromFile(fileName, password, keyStorageFlags));
 }
예제 #16
0
 public static ICertificatePal FromBlob(ReadOnlySpan <byte> rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
 {
     return(AndroidCertificatePal.FromBlob(rawData, password, keyStorageFlags));
 }
예제 #17
0
            protected override byte[] GetSubjectPublicKeyInfo(X509Certificate2 cert)
            {
                AndroidCertificatePal pal = (AndroidCertificatePal)cert.Pal;

                return(pal.SubjectPublicKeyInfo);
            }
예제 #18
0
 public static ICertificatePal FromHandle(IntPtr handle)
 {
     return(AndroidCertificatePal.FromHandle(handle));
 }