示例#1
0
        internal static SafeSecCertificateHandle X509ImportCertificate(
            ReadOnlySpan <byte> bytes,
            X509ContentType contentType,
            SafePasswordHandle importPassword,
            out SafeSecIdentityHandle identityHandle)
        {
            SafeCreateHandle?cfPassphrase    = null;
            bool             releasePassword = false;

            try
            {
                if (!importPassword.IsInvalid)
                {
                    importPassword.DangerousAddRef(ref releasePassword);
                    cfPassphrase = CoreFoundation.CFStringCreateFromSpan(importPassword.DangerousGetSpan());
                }

                return(X509ImportCertificate(
                           bytes,
                           contentType,
                           cfPassphrase,
                           out identityHandle));
            }
            finally
            {
                if (releasePassword)
                {
                    importPassword.DangerousRelease();
                }

                cfPassphrase?.Dispose();
            }
        }
        internal static byte[] X509ExportPfx(IntPtr[] certHandles, SafePasswordHandle exportPassword)
        {
            SafeCreateHandle cfPassphrase    = s_emptyExportString;
            bool             releasePassword = false;

            try
            {
                if (!exportPassword.IsInvalid)
                {
                    exportPassword.DangerousAddRef(ref releasePassword);
                    IntPtr passwordHandle = exportPassword.DangerousGetHandle();

                    if (passwordHandle != IntPtr.Zero)
                    {
                        cfPassphrase = CoreFoundation.CFStringCreateWithCString(passwordHandle);
                    }
                }

                return(X509Export(X509ContentType.Pkcs12, cfPassphrase, certHandles));
            }
            finally
            {
                if (releasePassword)
                {
                    exportPassword.DangerousRelease();
                }

                if (cfPassphrase != s_emptyExportString)
                {
                    cfPassphrase.Dispose();
                }
            }
        }
示例#3
0
        public void Decrypt(SafePasswordHandle password)
        {
            ReadOnlyMemory <byte> authSafeContents =
                Helpers.DecodeOctetStringAsMemory(_pfxAsn.AuthSafe.Content);

            bool hasRef = false;

            password.DangerousAddRef(ref hasRef);

            try
            {
                ReadOnlySpan <char> passwordChars = password.DangerousGetSpan();

                if (_pfxAsn.MacData.HasValue)
                {
                    VerifyAndDecrypt(passwordChars, authSafeContents);
                }
                else if (passwordChars.IsEmpty)
                {
                    try
                    {
                        // Try the empty password first.
                        // If anything goes wrong, try the null password.
                        //
                        // The same password has to work for the entirety of the file,
                        // null and empty aren't interchangeable between parts.
                        Decrypt("", authSafeContents);
                    }
                    catch (CryptographicException)
                    {
                        ContentInfoAsn[] partialSuccess = _safeContentsValues;
                        _safeContentsValues = null;

                        if (partialSuccess != null)
                        {
                            ReturnRentedContentInfos(partialSuccess);
                        }

                        Decrypt(null, authSafeContents);
                    }
                }
                else
                {
                    Decrypt(passwordChars, authSafeContents);
                }
            }
            catch (Exception e)
            {
                throw new CryptographicException(SR.Cryptography_Pfx_BadPassword, e)
                      {
                          HResult = ErrorInvalidPasswordHResult
                      };
            }
            finally
            {
                password.DangerousRelease();
            }
        }
        public ApplePkcs12CertLoader(
            ApplePkcs12Reader pkcs12,
            SafePasswordHandle password)
        {
            _pkcs12 = pkcs12;

            bool addedRef = false;

            password.DangerousAddRef(ref addedRef);
            _password = password;
        }
示例#5
0
        internal static SafeCFArrayHandle X509ImportCollection(
            ReadOnlySpan <byte> bytes,
            X509ContentType contentType,
            SafePasswordHandle importPassword)
        {
            SafeCreateHandle  cfPassphrase    = s_emptyExportString;
            bool              releasePassword = false;
            SafeCFArrayHandle collectionHandle;
            int osStatus;

            try
            {
                if (!importPassword.IsInvalid)
                {
                    importPassword.DangerousAddRef(ref releasePassword);
                    IntPtr passwordHandle = importPassword.DangerousGetHandle();

                    if (passwordHandle != IntPtr.Zero)
                    {
                        cfPassphrase = CoreFoundation.CFStringCreateWithCString(passwordHandle);
                    }
                }

                osStatus = AppleCryptoNative_X509ImportCollection(
                    ref MemoryMarshal.GetReference(bytes),
                    bytes.Length,
                    contentType,
                    cfPassphrase,
                    out collectionHandle);

                if (osStatus == 0)
                {
                    return(collectionHandle);
                }
            }
            finally
            {
                if (releasePassword)
                {
                    importPassword.DangerousRelease();
                }

                if (cfPassphrase != s_emptyExportString)
                {
                    cfPassphrase.Dispose();
                }
            }

            collectionHandle.Dispose();
            throw CreateExceptionForOSStatus(osStatus);
        }
示例#6
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;
            }
        internal static SafeCFArrayHandle X509ImportCollection(
            byte[] bytes,
            X509ContentType contentType,
            SafePasswordHandle importPassword,
            SafeKeychainHandle keychain,
            bool exportable)
        {
            SafeCreateHandle cfPassphrase    = s_nullExportString;
            bool             releasePassword = false;

            int ret;
            SafeCFArrayHandle collectionHandle;
            int osStatus;

            try
            {
                if (!importPassword.IsInvalid)
                {
                    importPassword.DangerousAddRef(ref releasePassword);
                    IntPtr passwordHandle = importPassword.DangerousGetHandle();

                    if (passwordHandle != IntPtr.Zero)
                    {
                        cfPassphrase = CoreFoundation.CFStringCreateWithCString(passwordHandle);
                    }
                }

                ret = AppleCryptoNative_X509ImportCollection(
                    bytes,
                    bytes.Length,
                    contentType,
                    cfPassphrase,
                    keychain,
                    exportable ? 1 : 0,
                    out collectionHandle,
                    out osStatus);

                if (ret == 1)
                {
                    return(collectionHandle);
                }
            }
            finally
            {
                if (releasePassword)
                {
                    importPassword.DangerousRelease();
                }

                if (cfPassphrase != s_nullExportString)
                {
                    cfPassphrase.Dispose();
                }
            }

            collectionHandle.Dispose();

            const int SeeOSStatus         = 0;
            const int ImportReturnedEmpty = -2;
            const int ImportReturnedNull  = -3;

            switch (ret)
            {
            case SeeOSStatus:
                throw CreateExceptionForOSStatus(osStatus);

            case ImportReturnedNull:
            case ImportReturnedEmpty:
                throw new CryptographicException();

            default:
                Debug.Fail($"Unexpected return value {ret}");
                throw new CryptographicException();
            }
        }
示例#8
0
        private byte[] ExportPfx(SafePasswordHandle password)
        {
            int certCount = 1;

            if (_singleCertPal == null)
            {
                Debug.Assert(_certs != null);
                certCount = _certs.Count;
            }

            CertBagAsn[] certBags = ArrayPool <CertBagAsn> .Shared.Rent(certCount);

            SafeBagAsn[] keyBags = ArrayPool <SafeBagAsn> .Shared.Rent(certCount);

            AttributeAsn[] certAttrs = ArrayPool <AttributeAsn> .Shared.Rent(certCount);

            certAttrs.AsSpan(0, certCount).Clear();

            AsnWriter           tmpWriter       = new AsnWriter(AsnEncodingRules.DER);
            ArraySegment <byte> encodedAuthSafe = default;

            bool gotRef = false;

            password.DangerousAddRef(ref gotRef);

            try
            {
                ReadOnlySpan <char> passwordSpan = password.DangerousGetSpan();

                int keyIdx  = 0;
                int certIdx = 0;

                if (_singleCertPal != null)
                {
                    BuildBags(
                        _singleCertPal,
                        passwordSpan,
                        tmpWriter,
                        certBags,
                        certAttrs,
                        keyBags,
                        ref certIdx,
                        ref keyIdx);
                }
                else
                {
                    foreach (X509Certificate2 cert in _certs !)
                    {
                        BuildBags(
                            cert.Pal,
                            passwordSpan,
                            tmpWriter,
                            certBags,
                            certAttrs,
                            keyBags,
                            ref certIdx,
                            ref keyIdx);
                    }
                }

                encodedAuthSafe = EncodeAuthSafe(
                    tmpWriter,
                    keyBags,
                    keyIdx,
                    certBags,
                    certAttrs,
                    certIdx,
                    passwordSpan);

                return(MacAndEncode(tmpWriter, encodedAuthSafe, passwordSpan));
            }
            finally
            {
                password.DangerousRelease();
                certAttrs.AsSpan(0, certCount).Clear();
                certBags.AsSpan(0, certCount).Clear();
                keyBags.AsSpan(0, certCount).Clear();
                ArrayPool <AttributeAsn> .Shared.Return(certAttrs);

                ArrayPool <CertBagAsn> .Shared.Return(certBags);

                ArrayPool <SafeBagAsn> .Shared.Return(keyBags);

                if (encodedAuthSafe.Array != null)
                {
                    CryptoPool.Return(encodedAuthSafe);
                }
            }
        }