예제 #1
0
        private static void AssignFriendlyNameToContext(IntPtr context, string value)
        {
            if (string.IsNullOrWhiteSpace(value))
                return;

            var dataPointer = IntPtr.Zero;
            try
            {
                using (var data = new NativeMethods.CryptAttributeBlob { data = Marshal.StringToHGlobalUni(value), dataSize = Encoding.Unicode.GetByteCount(value) })
                {
                    dataPointer = Marshal.AllocHGlobal(Marshal.SizeOf(data));
                    Marshal.StructureToPtr(data, dataPointer, false);

                    if (NativeMethods.CertSetCertificateContextProperty(
                        context, NativeMethods.CertFriendlyNamePropId, 0, dataPointer))
                        return;

                    var issue = new Win32Exception(Marshal.GetLastWin32Error());
                    Log.WarnFormat("Could not set friendly name for certificate: {0}", issue.Message);
                }
            }
            finally
            {
                if (dataPointer != IntPtr.Zero)
                    Marshal.FreeHGlobal(dataPointer);
            }
        }
예제 #2
0
        public static BooleanReason ImportUserCertificateFromBuffer(byte[] buffer, SecureString password, string friendlyName)
        {
            var info = new NativeMethods.CryptAttributeBlob();
            var temporaryStore = IntPtr.Zero;
            var context = IntPtr.Zero;
            var passwordPointer = IntPtr.Zero;
            try
            {
                if (buffer == null)
                    return new BooleanReason(false, "The provided certificate buffer is empty.");

                info.data = Marshal.AllocHGlobal(buffer.Length);
                info.dataSize = buffer.Length;

                if (password != null)
                    passwordPointer = Marshal.SecureStringToGlobalAllocUnicode(password);

                Marshal.Copy(buffer, 0, info.data, buffer.Length);

                temporaryStore = NativeMethods.PFXImportCertStore(ref info, passwordPointer, NativeMethods.UserKeyset);
                if (temporaryStore == IntPtr.Zero)
                {
                    var issue = new Win32Exception(Marshal.GetLastWin32Error());
                    return new BooleanReason(false, "Could not import cert data: " + issue.Message);
                }

                context = GetFirstUsableContextFromStore(temporaryStore);
                if (context == IntPtr.Zero)
                    return new BooleanReason(false, "Could not import cert data: no useable certificate in store");

                AssignFriendlyNameToContext(context, friendlyName);

                var importInfo = new NativeMethods.ContextImportInfo
                    {
                        SubjectChoice = NativeMethods.ImportFromContext,
                        context = context,
                        Password = passwordPointer
                    };
                importInfo.Size = Marshal.SizeOf(importInfo);

                var result = NativeMethods.CryptUIWizImport(NativeMethods.NoUserInterface | NativeMethods.ImportToCurrentuser, IntPtr.Zero, IntPtr.Zero, ref importInfo, IntPtr.Zero);
                if (!result)
                {
                    var issue = new Win32Exception(Marshal.GetLastWin32Error());
                    return new BooleanReason(false, issue.Message);
                }

                return new BooleanReason(true, "");
            }
            finally
            {
                if (context != IntPtr.Zero)
                    NativeMethods.CertFreeCertificateContext(context);

                if (info.data != IntPtr.Zero)
                    Marshal.FreeHGlobal(info.data);

                if (temporaryStore != IntPtr.Zero)
                    NativeMethods.CertCloseStore(temporaryStore, 0);

                if (passwordPointer != IntPtr.Zero)
                    Marshal.ZeroFreeGlobalAllocUnicode(passwordPointer);
            }
        }