예제 #1
0
        static SecKey ImportPrivateKey(X509Certificate2 certificate)
        {
            if (!certificate.HasPrivateKey)
            {
                throw new NotSupportedException();
            }

            CFArray items;

            using (var data = CFData.FromData(ExportKey((RSA)certificate.PrivateKey)))
                items = ItemImport(data, SecExternalFormat.OpenSSL, SecExternalItemType.PrivateKey);

            try {
                if (items.Count != 1)
                {
                    throw new InvalidOperationException("Private key import failed.");
                }

                var imported = items[0];
                if (CFType.GetTypeID(imported) != SecKey.GetTypeID())
                {
                    throw new InvalidOperationException("Private key import doesn't return SecKey.");
                }

                return(new SecKey(imported, items.Handle));
            } finally {
                items.Dispose();
            }
        }
        string[] CopyDistinguishedNames()
        {
            IntPtr arrayPtr;
            var    result = SSLCopyDistinguishedNames(Handle, out arrayPtr);

            CheckStatusAndThrow(result);

            if (arrayPtr == IntPtr.Zero)
            {
                return(new string[0]);
            }

            using (var array = new CFArray(arrayPtr, true)) {
                var names = new string [array.Count];
                for (int i = 0; i < array.Count; i++)
                {
                    using (var data = new CFData(array[i], false)) {
                        var buffer = new byte [(int)data.Length];
                        Marshal.Copy(data.Bytes, buffer, 0, buffer.Length);
                        var dn = new X500DistinguishedName(buffer);
                        names[i] = dn.Name;
                    }
                }
                return(names);
            }
        }
예제 #3
0
        static CFArray ItemImport(CFData data, ref SecExternalFormat format, ref SecExternalItemType itemType,
                                  SecItemImportExportFlags flags             = SecItemImportExportFlags.None,
                                  SecItemImportExportKeyParameters?keyParams = null)
        {
            IntPtr keyParamsPtr = IntPtr.Zero;

            if (keyParams != null)
            {
                keyParamsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(keyParams.Value));
                if (keyParamsPtr == IntPtr.Zero)
                {
                    throw new OutOfMemoryException();
                }
                Marshal.StructureToPtr(keyParams.Value, keyParamsPtr, false);
            }

            IntPtr result;
            var    status = SecItemImport(data.Handle, IntPtr.Zero, ref format, ref itemType, flags, keyParamsPtr, IntPtr.Zero, out result);

            if (keyParamsPtr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(keyParamsPtr);
            }

            if (status != SecStatusCode.Success)
            {
                throw new NotSupportedException(status.ToString());
            }

            return(new CFArray(result, true));
        }
예제 #4
0
 void Initialize(CFData data)
 {
     handle = SecCertificateCreateWithData(IntPtr.Zero, data.Handle);
     if (handle == IntPtr.Zero)
     {
         throw new ArgumentException("Not a valid DER-encoded X.509 certificate");
     }
 }
예제 #5
0
        static public CFArray ItemImport(byte[] buffer, string password)
        {
            using (var data = CFData.FromData(buffer))
                using (var pwstring = CFString.Create(password)) {
                    SecItemImportExportKeyParameters keyParams = new SecItemImportExportKeyParameters();
                    keyParams.passphrase = pwstring.Handle;

                    return(ItemImport(data, SecExternalFormat.PKCS12, SecExternalItemType.Aggregate, SecItemImportExportFlags.None, keyParams));
                }
        }
예제 #6
0
        internal SecCertificate(X509CertificateImpl impl)
        {
            handle = impl.GetNativeAppleCertificate();
            if (handle != IntPtr.Zero)
            {
                CFObject.CFRetain(handle);
                return;
            }

            using (CFData cert = CFData.FromData(impl.GetRawCertData())) {
                Initialize(cert);
            }
        }
예제 #7
0
        static public SecStatusCode ImportPkcs12(CFData data, CFDictionary options, out CFDictionary [] array)
        {
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            IntPtr        handle;
            SecStatusCode code = SecPKCS12Import(data.Handle, options.Handle, out handle);

            array = CFArray.ArrayFromHandle <CFDictionary> (handle, h => new CFDictionary(h, false));
            CFObject.CFRelease(handle);
            return(code);
        }
        static SecStatusCode ImportPkcs12(CFData data, CFDictionary options, out CFDictionary[] array)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            var code = SecPKCS12Import(data.Handle, options.Handle, out var handle);

            array = CFArray.ArrayFromHandle <CFDictionary> (handle, h => new CFDictionary(h, false));
            if (handle != IntPtr.Zero)
            {
                CFObject.CFRelease(handle);
            }
            return(code);
        }
예제 #9
0
        public SecCertificate(X509Certificate certificate)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException("certificate");
            }

            handle = certificate.Impl.GetNativeAppleCertificate();
            if (handle != IntPtr.Zero)
            {
                CFObject.CFRetain(handle);
                return;
            }

            using (CFData cert = CFData.FromData(certificate.GetRawCertData())) {
                Initialize(cert);
            }
        }
예제 #10
0
        public static byte[] GetRawData(SafeSecCertificateHandle certificate)
        {
            if (certificate == null || certificate.IsInvalid)
            {
                throw new ArgumentNullException(nameof(certificate));
            }

            var dataPtr = SecCertificateCopyData(certificate.DangerousGetHandle());

            if (dataPtr == IntPtr.Zero)
            {
                throw new ArgumentException("Not a valid certificate");
            }

            using (var data = new CFData(dataPtr, true)) {
                var buffer = new byte[(int)data.Length];
                Marshal.Copy(data.Bytes, buffer, 0, buffer.Length);
                return(buffer);
            }
        }
예제 #11
0
        public static SafeSecCertificateHandle FromOtherCertificate(X509CertificateImpl impl)
        {
            X509Helper.ThrowIfContextInvalid(impl);

            var handle = impl.GetNativeAppleCertificate();

            if (handle != IntPtr.Zero)
            {
                return(new SafeSecCertificateHandle(handle, false));
            }

            using (var data = CFData.FromData(impl.RawData)) {
                handle = SecCertificateCreateWithData(IntPtr.Zero, data.Handle);
                if (handle == IntPtr.Zero)
                {
                    throw new ArgumentException("Not a valid DER-encoded X.509 certificate");
                }

                return(new SafeSecCertificateHandle(handle, true));
            }
        }
예제 #12
0
        public static bool Equals(SafeSecCertificateHandle first, SafeSecCertificateHandle second)
        {
            /*
             * This is a little bit expensive, but unfortunately there is no better API to compare two
             * SecCertificateRef's for equality.
             */
            if (first == null || first.IsInvalid)
            {
                throw new ArgumentNullException(nameof(first));
            }
            if (second == null || second.IsInvalid)
            {
                throw new ArgumentNullException(nameof(second));
            }
            if (first.DangerousGetHandle() == second.DangerousGetHandle())
            {
                return(true);
            }

            var firstDataPtr  = SecCertificateCopyData(first.DangerousGetHandle());
            var secondDataPtr = SecCertificateCopyData(first.DangerousGetHandle());

            try {
                if (firstDataPtr == IntPtr.Zero || secondDataPtr == IntPtr.Zero)
                {
                    throw new ArgumentException("Not a valid certificate.");
                }
                if (firstDataPtr == secondDataPtr)
                {
                    return(true);
                }

                var firstLength  = (int)CFData.CFDataGetLength(firstDataPtr);
                var secondLength = (int)CFData.CFDataGetLength(secondDataPtr);
                if (firstLength != secondLength)
                {
                    return(false);
                }

                var firstBytePtr  = CFData.CFDataGetBytePtr(firstDataPtr);
                var secondBytePtr = CFData.CFDataGetBytePtr(secondDataPtr);
                if (firstBytePtr == secondBytePtr)
                {
                    return(true);
                }

                var firstBuffer  = new byte[firstLength];
                var secondBuffer = new byte[secondLength];
                Marshal.Copy(firstBytePtr, firstBuffer, 0, firstBuffer.Length);
                Marshal.Copy(secondBytePtr, secondBuffer, 0, secondBuffer.Length);

                for (int i = 0; i < firstBuffer.Length; i++)
                {
                    if (firstBuffer[i] != secondBuffer[i])
                    {
                        return(false);
                    }
                }

                return(true);
            } finally {
                if (firstDataPtr != null)
                {
                    CFObject.CFRelease(firstDataPtr);
                }
                if (secondDataPtr != null)
                {
                    CFObject.CFRelease(secondDataPtr);
                }
            }
        }
예제 #13
0
 static CFArray ItemImport(CFData data, SecExternalFormat format, SecExternalItemType itemType,
                           SecItemImportExportFlags flags             = SecItemImportExportFlags.None,
                           SecItemImportExportKeyParameters?keyParams = null)
 {
     return(ItemImport(data, ref format, ref itemType, flags, keyParams));
 }
예제 #14
0
 static public SecStatusCode ImportPkcs12(byte[] buffer, CFDictionary options, out CFDictionary[] array)
 {
     using (CFData data = CFData.FromData(buffer)) {
         return(ImportPkcs12(data, options, out array));
     }
 }
예제 #15
0
 internal void SetBody(CFData data)
 {
     CFHTTPMessageSetBody(Handle, data.Handle);
 }
예제 #16
0
 internal void SetBody(CFData data)
 {
     ThrowIfDisposed();
     CFHTTPMessageSetBody(Handle, data.Handle);
 }