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);
                }
            }
Beispiel #2
0
 internal static extern int EcKeyGetCurveName(SafeEcKeyHandle ecKey);
Beispiel #3
0
 private static partial int EcKeyCreateByKeyParameters(
     out SafeEcKeyHandle key,
     string oid,
     byte[]?qx, int qxLength,
     byte[]?qy, int qyLength,
     byte[]?d, int dLength);
Beispiel #4
0
 private static partial int CryptoNative_GetECKeyParameters(
     SafeEcKeyHandle key,
     [MarshalAs(UnmanagedType.Bool)] bool includePrivate,
     out SafeBignumHandle qx_bn, out int x_cb,
     out SafeBignumHandle qy_bn, out int y_cb,
     out IntPtr d_bn_not_owned, out int d_cb);
Beispiel #5
0
 private static partial int CryptoNative_EcKeyGetSize(SafeEcKeyHandle ecKey, out int keySize);
Beispiel #6
0
 private static partial int AndroidCryptoNative_EcKeyGetCurveName(SafeEcKeyHandle ecKey, out IntPtr curveName);
 private static extern int AndroidCryptoNative_GetECKeyParameters(
     SafeEcKeyHandle key,
     bool includePrivate,
     out SafeBignumHandle qx_bn, out int x_cb,
     out SafeBignumHandle qy_bn, out int y_cb,
     out IntPtr d_bn_not_owned, out int d_cb);
Beispiel #8
0
 private static partial int CryptoNative_EcDsaSize(SafeEcKeyHandle ecKey);
Beispiel #9
0
 internal static extern int EcDsaSize(SafeEcKeyHandle ecKey);
Beispiel #10
0
 internal static unsafe int EcDsaVerify(ReadOnlySpan <byte> dgst, int dgst_len, ReadOnlySpan <byte> sigbuf, int sig_len, SafeEcKeyHandle ecKey) =>
 EcDsaVerify(ref dgst.DangerousGetPinnableReference(), dgst_len, ref sigbuf.DangerousGetPinnableReference(), sig_len, ecKey);
Beispiel #11
0
 private static extern bool EcDsaSign(ref byte dgst, int dlen, ref byte sig, [In, Out] ref int siglen, SafeEcKeyHandle ecKey);
Beispiel #12
0
 internal static bool EcDsaSign(ReadOnlySpan <byte> dgst, int dlen, Span <byte> sig, [In, Out] ref int siglen, SafeEcKeyHandle ecKey) =>
 EcDsaSign(ref dgst.DangerousGetPinnableReference(), dlen, ref sig.DangerousGetPinnableReference(), ref siglen, ecKey);
Beispiel #13
0
 internal static bool EcDsaSign(ReadOnlySpan <byte> dgst, int dlen, Span <byte> sig, [In, Out] ref int siglen, SafeEcKeyHandle ecKey) =>
 EcDsaSign(ref MemoryMarshal.GetReference(dgst), dlen, ref MemoryMarshal.GetReference(sig), ref siglen, ecKey);
Beispiel #14
0
        internal static int EcDsaVerify(ReadOnlySpan <byte> dgst, ReadOnlySpan <byte> sigbuf, SafeEcKeyHandle ecKey)
        {
            int ret = EcDsaVerify(
                ref MemoryMarshal.GetReference(dgst),
                dgst.Length,
                ref MemoryMarshal.GetReference(sigbuf),
                sigbuf.Length,
                ecKey);

            if (ret == 0)
            {
                // OpenSSL ECDSA signature processing requires a DER encode and decode, so
                // the error queue may have been contaminated.
                ErrClearError();
            }

            return(ret);
        }
Beispiel #15
0
        internal static int EcDsaVerify(ReadOnlySpan <byte> dgst, ReadOnlySpan <byte> sigbuf, SafeEcKeyHandle ecKey)
        {
            int ret = EcDsaVerify(
                ref MemoryMarshal.GetReference(dgst),
                dgst.Length,
                ref MemoryMarshal.GetReference(sigbuf),
                sigbuf.Length,
                ecKey);

            if (ret < 0)
            {
                ErrClearError();
            }

            return(ret);
        }
Beispiel #16
0
 private static extern int EcKeyCreateByKeyParameters(
     out SafeEcKeyHandle key,
     string oid,
     byte[] qx, int qxLength,
     byte[] qy, int qyLength,
     byte[] d, int dLength);
Beispiel #17
0
 private static partial int EcDsaVerify(ref byte dgst, int dgst_len, ref byte sigbuf, int sig_len, SafeEcKeyHandle ecKey);
Beispiel #18
0
 private static extern int CryptoNative_EcDsaSize(SafeEcKeyHandle ecKey);
Beispiel #19
0
 internal static extern bool EvpPkeySetEcKey(SafeEvpPKeyHandle pkey, SafeEcKeyHandle key);
 private static partial int AndroidCryptoNative_GetECKeyParameters(
     SafeEcKeyHandle key,
     bool includePrivate,
     out SafeBignumHandle qx_bn, out int x_cb,
     out SafeBignumHandle qy_bn, out int y_cb,
     out SafeBignumHandle d_bn, out int d_cb);
Beispiel #21
0
        internal static SafeEcKeyHandle?EcKeyCreateByOid(string oid)
        {
            SafeEcKeyHandle handle = AndroidCryptoNative_EcKeyCreateByOid(oid);

            return(handle);
        }
Beispiel #22
0
 internal static extern bool EcKeyGenerateKey(SafeEcKeyHandle eckey);
Beispiel #23
0
 internal static partial bool EcKeyGenerateKey(SafeEcKeyHandle eckey);
Beispiel #24
0
 private static extern int CryptoNative_EcKeyGetSize(SafeEcKeyHandle ecKey, out int keySize);
Beispiel #25
0
 private static partial int CryptoNative_EcKeyGetCurveName(SafeEcKeyHandle ecKey, out int nid);
Beispiel #26
0
 internal static bool EcDsaSign(ReadOnlySpan <byte> dgst, Span <byte> sig, out int siglen, SafeEcKeyHandle ecKey) =>
 EcDsaSign(ref MemoryMarshal.GetReference(dgst), dgst.Length, ref MemoryMarshal.GetReference(sig), out siglen, ecKey);
Beispiel #27
0
        internal static ECParameters GetECKeyParameters(
            SafeEcKeyHandle key,
            bool includePrivate)
        {
            SafeBignumHandle qx_bn, qy_bn, d_bn;
            IntPtr           d_bn_not_owned;
            int          qx_cb, qy_cb, d_cb;
            ECParameters parameters = default;

            bool refAdded = false;

            try
            {
                key.DangerousAddRef(ref refAdded); // Protect access to d_bn_not_owned
                int rc = CryptoNative_GetECKeyParameters(
                    key,
                    includePrivate,
                    out qx_bn, out qx_cb,
                    out qy_bn, out qy_cb,
                    out d_bn_not_owned, out d_cb);

                using (qx_bn)
                    using (qy_bn)
                    {
                        if (rc == -1)
                        {
                            throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey);
                        }
                        else if (rc != 1)
                        {
                            throw Interop.Crypto.CreateOpenSslCryptographicException();
                        }

                        using (d_bn = new SafeBignumHandle(d_bn_not_owned, false))
                        {
                            // Match Windows semantics where qx, qy, and d have same length
                            int keySizeBits  = EcKeyGetSize(key);
                            int expectedSize = (keySizeBits + 7) / 8;
                            int cbKey        = GetMax(qx_cb, qy_cb, d_cb);

                            Debug.Assert(
                                cbKey <= expectedSize,
                                $"Expected output size was {expectedSize}, which a parameter exceeded. qx={qx_cb}, qy={qy_cb}, d={d_cb}");

                            cbKey = GetMax(cbKey, expectedSize);

                            parameters.Q = new ECPoint
                            {
                                X = Crypto.ExtractBignum(qx_bn, cbKey),
                                Y = Crypto.ExtractBignum(qy_bn, cbKey)
                            };
                            parameters.D = d_cb == 0 ? null : Crypto.ExtractBignum(d_bn, cbKey);
                        }
                    }
            }
            finally
            {
                if (refAdded)
                {
                    key.DangerousRelease();
                }
            }

            return(parameters);
        }
Beispiel #28
0
 private static partial bool EcDsaSign(ref byte dgst, int dlen, ref byte sig, out int siglen, SafeEcKeyHandle ecKey);
Beispiel #29
0
        internal static ECParameters GetECCurveParameters(
            SafeEcKeyHandle key,
            bool includePrivate)
        {
            ECCurve.ECCurveType curveType;
            SafeBignumHandle    qx_bn, qy_bn, p_bn, a_bn, b_bn, gx_bn, gy_bn, order_bn, cofactor_bn, seed_bn;
            IntPtr d_bn_not_owned;
            int    qx_cb, qy_cb, p_cb, a_cb, b_cb, gx_cb, gy_cb, order_cb, cofactor_cb, seed_cb, d_cb;

            bool refAdded = false;

            try
            {
                key.DangerousAddRef(ref refAdded); // Protect access to d_bn_not_owned
                int rc = CryptoNative_GetECCurveParameters(
                    key,
                    includePrivate,
                    out curveType,
                    out qx_bn, out qx_cb,
                    out qy_bn, out qy_cb,
                    out d_bn_not_owned, out d_cb,
                    out p_bn, out p_cb,
                    out a_bn, out a_cb,
                    out b_bn, out b_cb,
                    out gx_bn, out gx_cb,
                    out gy_bn, out gy_cb,
                    out order_bn, out order_cb,
                    out cofactor_bn, out cofactor_cb,
                    out seed_bn, out seed_cb);

                using (qx_bn)
                    using (qy_bn)
                        using (p_bn)
                            using (a_bn)
                                using (b_bn)
                                    using (gx_bn)
                                        using (gy_bn)
                                            using (order_bn)
                                                using (cofactor_bn)
                                                    using (seed_bn)
                                                    {
                                                        if (rc == -1)
                                                        {
                                                            throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey);
                                                        }
                                                        else if (rc != 1)
                                                        {
                                                            throw Interop.Crypto.CreateOpenSslCryptographicException();
                                                        }

                                                        using (var d_h = new SafeBignumHandle(d_bn_not_owned, false))
                                                        {
                                                            int cbFieldLength;
                                                            int pFieldLength;
                                                            if (curveType == ECCurve.ECCurveType.Characteristic2)
                                                            {
                                                                // Match Windows semantics where a,b,gx,gy,qx,qy have same length
                                                                // Treat length of m separately as it is not tied to other fields for Char2 (Char2 not supported by Windows)
                                                                cbFieldLength = GetMax(new[] { a_cb, b_cb, gx_cb, gy_cb, qx_cb, qy_cb });
                                                                pFieldLength  = p_cb;
                                                            }
                                                            else
                                                            {
                                                                // Match Windows semantics where p,a,b,gx,gy,qx,qy have same length
                                                                cbFieldLength = GetMax(new[] { p_cb, a_cb, b_cb, gx_cb, gy_cb, qx_cb, qy_cb });
                                                                pFieldLength  = cbFieldLength;
                                                            }

                                                            // Match Windows semantics where order and d have same length
                                                            int cbSubgroupOrder = GetMax(order_cb, d_cb);

                                                            // Copy values to ECParameters
                                                            ECParameters parameters = default;
                                                            parameters.Q = new ECPoint
                                                            {
                                                                X = Crypto.ExtractBignum(qx_bn, cbFieldLength),
                                                                Y = Crypto.ExtractBignum(qy_bn, cbFieldLength)
                                                            };
                                                            parameters.D = d_cb == 0 ? null : Crypto.ExtractBignum(d_h, cbSubgroupOrder);

                                                            var curve = parameters.Curve;
                                                            curve.CurveType = curveType;
                                                            curve.A         = Crypto.ExtractBignum(a_bn, cbFieldLength) !;
                                                            curve.B         = Crypto.ExtractBignum(b_bn, cbFieldLength) !;
                                                            curve.G         = new ECPoint
                                                            {
                                                                X = Crypto.ExtractBignum(gx_bn, cbFieldLength),
                                                                Y = Crypto.ExtractBignum(gy_bn, cbFieldLength)
                                                            };
                                                            curve.Order = Crypto.ExtractBignum(order_bn, cbSubgroupOrder) !;

                                                            if (curveType == ECCurve.ECCurveType.Characteristic2)
                                                            {
                                                                curve.Polynomial = Crypto.ExtractBignum(p_bn, pFieldLength) !;
                                                            }
                                                            else
                                                            {
                                                                curve.Prime = Crypto.ExtractBignum(p_bn, pFieldLength) !;
                                                            }

                                                            // Optional parameters
                                                            curve.Cofactor = cofactor_cb == 0 ? null : Crypto.ExtractBignum(cofactor_bn, cofactor_cb);
                                                            curve.Seed     = seed_cb == 0 ? null : Crypto.ExtractBignum(seed_bn, seed_cb);

                                                            parameters.Curve = curve;
                                                            return(parameters);
                                                        }
                                                    }
            }
            finally
            {
                if (refAdded)
                {
                    key.DangerousRelease();
                }
            }
        }
Beispiel #30
0
 internal static extern ECCurve.ECCurveType EcKeyGetCurveType(SafeEcKeyHandle key);