Click here to Skip to main content
15,897,187 members
Home / Discussions / C#
   

C#

 
GeneralRe: Regarding .Net consultant Pin
Dave Kreskowiak22-May-14 11:15
mveDave Kreskowiak22-May-14 11:15 
GeneralComparison of 2 DataTable too slow Pin
diego_ric21-May-14 18:05
diego_ric21-May-14 18:05 
AnswerRe: Comparison of 2 DataTable too slow Pin
Karen Mitchelle21-May-14 18:54
professionalKaren Mitchelle21-May-14 18:54 
GeneralRe: Comparison of 2 DataTable too slow Pin
diego_ric22-May-14 4:32
diego_ric22-May-14 4:32 
GeneralRe: Comparison of 2 DataTable too slow Pin
Mycroft Holmes21-May-14 19:27
professionalMycroft Holmes21-May-14 19:27 
GeneralRe: Comparison of 2 DataTable too slow Pin
diego_ric22-May-14 6:30
diego_ric22-May-14 6:30 
GeneralRe: Comparison of 2 DataTable too slow Pin
Mycroft Holmes22-May-14 12:41
professionalMycroft Holmes22-May-14 12:41 
QuestionHow do you build a 1 click application that will alow you to change users using a smart card Pin
Steven Richardson21-May-14 10:37
Steven Richardson21-May-14 10:37 
I have been looking for the anwer to this question for days now. I found that their is very little on smart card implementaion for C# but from alot of research I and alot of playing around I have finialy solved the question. Below is a working example of my smart card class

SmartCard.cs file

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.Security;
using System.ComponentModel;

namespace SmartCardApp
{
   
       
       

    public class SmartCard
    {
      
        internal static int CertCredential = 1;
                      
        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern bool CredMarshalCredential(
            int credType,
            IntPtr credential,
            out IntPtr marshaledCredential
            );
      

        [DllImport("user32.dll")]
        private static extern IntPtr GetDC(IntPtr hWnd);
        [StructLayout(LayoutKind.Sequential)]
        internal struct CERT_CREDENTIAL_INFO
        {
            public uint cbSize;

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
            public byte[] rgbHashOfCert;
        }


        public static string pin = null;
        public static X509Certificate2 cert = null;
        public struct UserLoginInfo
        {
            public string domain;
            public string username;
            public SecureString password;
        }
        public void SmartCardLogon()
        {
            //First Get the Certificate
            cert = GetClientCertificate();
            //Create a pin logon form
            Form login = new Form();
            login.Height = 100;
            login.Width = 100;
            login.MaximizeBox = false;
            login.MinimizeBox = false;
            login.ControlBox = false;
            login.Name = "frmCaCLogin";
            login.Text = "Enter Pin";
            TextBox TextBox1 = new TextBox();
            TextBox1.Name = "txtCaCLogin";
            TextBox1.PasswordChar = '*';
            
            login.Controls.Add(TextBox1);
            Button b = new Button();
            b.FlatStyle = FlatStyle.Flat;
            b.Text = "Login";
            b.Name = "butCacLogin";
            b.Click += new EventHandler(b_Click);
          
            login.Controls.Add(b);
            login.Controls["butCacLogin"].Top += 20;
            login.TopMost = true;
            login.ShowDialog();



        }

        void b_Click(object sender, EventArgs e)
        {
            //Retrive the pin from the txt filed you added to the created form
            pin = Application.OpenForms["frmCaCLogin"].Controls["txtCaCLogin"].Text;
            //just hides the form
            Application.OpenForms["frmCaCLogin"].Hide();
            //
           
        
            if (cert != null)
            {
                //This returns the cert and pin as a username and password that can be used with processstartinfo
                UserLoginInfo user = Login(cert);
                ProcessStartInfo psi = new ProcessStartInfo();
                psi.FileName = Application.ExecutablePath;
                psi.UserName = user.username;
                psi.Password = user.password;
                psi.UseShellExecute = false;
                Process.Start(psi);
                Application.Exit();

            }
        }

        public UserLoginInfo Login(X509Certificate2 cert)
        {
            UserLoginInfo uli = new UserLoginInfo();

            CERT_CREDENTIAL_INFO certInfo =
                 new CERT_CREDENTIAL_INFO();
            certInfo.cbSize = (uint)Marshal.SizeOf(typeof(CERT_CREDENTIAL_INFO));
            // certCredential.Certificate is an instance of the X509Certificate2 class.
            certInfo.rgbHashOfCert = cert.GetCertHash();

            int size = Marshal.SizeOf(certInfo);
            IntPtr pCertInfo = Marshal.AllocHGlobal(size);
            Marshal.StructureToPtr(certInfo, pCertInfo, false);

            IntPtr marshaledCredential = IntPtr.Zero;
            bool result =
               CredMarshalCredential(CertCredential,
                                pCertInfo,
                                out marshaledCredential);
            string domainName = string.Empty;
            string userName = string.Empty;
            string password = string.Empty;
            if (result)
            {
                // we need to do this here, before we free marshaledCredential
                domainName = String.Empty;
                userName = Marshal.PtrToStringUni(marshaledCredential);
                password = pin;
            }
            SecureString sc = new SecureString();
            foreach (char c in pin)
            {
                sc.AppendChar(c);
            }

            uli.domain = Environment.UserDomainName;
            uli.username = userName;
            uli.password = sc;

           
            return uli;
        }

        
        public static X509Certificate2 GetClientCertificate()
        {
            WindowsImpersonationContext impersonationContext = null;
            IntPtr ptr = IntPtr.Zero;
            X509Certificate2 certificate = null;
            X509Certificate t = null;
            var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            try
            {
                store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
                // Nothing to do if no cert found.
                if (store.Certificates != null && store.Certificates.Count > 0)
                {
                    if (store.Certificates.Count == 1)
                    {
                        // Return the certificate present.
                        certificate = store.Certificates[0];
                    }
                    else
                    {
                        // Request the user to select a certificate 

                        var certificates = X509Certificate2UI.SelectFromCollection(store.Certificates, "Digital Certificates", "Select a certificate from the following list:", X509SelectionFlag.SingleSelection, ptr);
                        // Check if one has been returned

                        if (certificates != null && certificates.Count > 0)
                            certificate = certificates[0];

                    }
                }
            }
            finally
            {
                store.Close();
            }

            return certificate;


        }
    }


this is the code i use for the smartcard login button
form1.cs file

just ad a button to a form call it butCacLogin put all the code from the class above into a new class called SmartCard.cs then just run the code.
private void butCacLogin_Click(object sender, EventArgs e)
     {
         this.Hide();
         SmartCard sc = new SmartCard();
         sc.SmartCardLogon();
         this.Close();
     }


The form for the pin could use some decorating but this works like a charm. At first I tried to use wiondws LogonUser method and using impersantation however when trying to start the process back up with the new credentials it was getting either directory not found or file not found. I then decided to just pass the credentials I recived back from the cert directly to the process and that worked perfectly. I looked for days never found full code for this only bits and pieaces of code and never a good working example.

The reason I started this up is because you can't do a runas on a one click application by right clicking it. Then I figured out how to pass the username and password to the process but our network is cac enforced. Then I decided to find a way to enable the process to start with cac credentials. I hope this helps somone out because this is probally the only place you can find the full working code for C# every other place i looked was just pieaces of code.

modified 21-May-14 17:58pm.

AnswerRe: How do you build a 1 click application that will alow you to change users using a smart card Pin
Mycroft Holmes21-May-14 19:32
professionalMycroft Holmes21-May-14 19:32 
SuggestionRe: How do you build a 1 click application that will alow you to change users using a smart card Pin
Richard MacCutchan21-May-14 21:59
mveRichard MacCutchan21-May-14 21:59 
GeneralRe: How do you build a 1 click application that will alow you to change users using a smart card Pin
Steven Richardson22-May-14 5:25
Steven Richardson22-May-14 5:25 
GeneralRe: How do you build a 1 click application that will alow you to change users using a smart card Pin
Richard MacCutchan22-May-14 6:28
mveRichard MacCutchan22-May-14 6:28 
GeneralRe: How do you build a 1 click application that will alow you to change users using a smart card Pin
Steven Richardson22-May-14 7:19
Steven Richardson22-May-14 7:19 
GeneralRe: How do you build a 1 click application that will alow you to change users using a smart card Pin
Richard MacCutchan22-May-14 7:21
mveRichard MacCutchan22-May-14 7:21 
Questionunity 2D C# coding problem Pin
Sepehr M21-May-14 9:00
Sepehr M21-May-14 9:00 
AnswerRe: unity 2D C# coding problem Pin
OriginalGriff21-May-14 9:13
mveOriginalGriff21-May-14 9:13 
QuestionPolymorphism In C# Pin
Member 1059122721-May-14 6:14
Member 1059122721-May-14 6:14 
AnswerRe: Polymorphism In C# Pin
OriginalGriff21-May-14 6:23
mveOriginalGriff21-May-14 6:23 
GeneralRe: Polymorphism In C# Pin
Member 1059122721-May-14 7:08
Member 1059122721-May-14 7:08 
GeneralRe: Polymorphism In C# Pin
OriginalGriff21-May-14 8:02
mveOriginalGriff21-May-14 8:02 
AnswerRe: Polymorphism In C# Pin
Eddy Vluggen21-May-14 9:40
professionalEddy Vluggen21-May-14 9:40 
QuestionMVC Pin
Pramod Singh (C)21-May-14 2:34
professionalPramod Singh (C)21-May-14 2:34 
AnswerRe: MVC Pin
Kornfeld Eliyahu Peter21-May-14 2:50
professionalKornfeld Eliyahu Peter21-May-14 2:50 
GeneralRe: MVC Pin
Pramod Singh (C)21-May-14 18:59
professionalPramod Singh (C)21-May-14 18:59 
AnswerRe: MVC Pin
Keith Barrow21-May-14 2:58
professionalKeith Barrow21-May-14 2:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.