Tag Archives: Ultimate IMAP

Providing client’s certificate required by server

This topic explains how to authenticate the client using a certificate. IMAP servers might be configured to request the client to authenticate using its certificate during SSL negotiation. The client can either process, or inform the server that it has no suitable certificate.

The example below demonstrates how to use ComponentPro IMAP library and handle the CertificateRequired event of the ImapClient to find a suitable certificate for the client authentication:

C#:

public void HandleCertificateRequiredEvent()
{
   // Create a new instance.
   ImapClient client = new ImapClient();
   client.CertificateRequired += client_CertificateRequired;
   // Connect to the IMAP server.
   client.Connect("myserver", 143, SecurityMode.Explicit);
   // Authenticate.
   client.Authenticate("userName", "password");
   // Do something here...
   // ...
   // Disconnect.
   client.Disconnect();
}
void client_CertificateRequired(object sender, ComponentPro.Security.CertificateRequiredEventArgs e)
{
   // Load certificates from the local machine.
   X509Store my = new X509Store(StoreName.My, StoreLocation.CurrentUser);
   my.Open(OpenFlags.ReadOnly);
   // Retrieve a list of available certificates.
   X509Certificate2Collection certs = my.Certificates;
   // If no certificate found, return.
   if (certs.Count == 0)
   {
       e.Certificate = null;
       return;
   }
   // Show all certificates.
   Console.WriteLine("Select certificate:");
   for (int i = 0; i <= certs.Count; i++)
   {
       if (i == 0)
       {
           Console.WriteLine(string.Format("{0}. [Nothing, skip this step]", i));
           continue;
       }
       Console.WriteLine(string.Format("{0}. {1}", i, certs[i - 1].SubjectName.Name));
   }
   // And ask user to choose an appropriate certificate.
   while (true)
   {
       Console.Write(string.Format("Select certificate [0 - {0}]: ", certs.Count));
       int certIndex;
       try
       {
           certIndex = int.Parse(Console.ReadLine());
       }
       catch
       {
           Console.WriteLine("ERROR: Wrong certificate index input!");
           continue;
       }
       if (certIndex > 0 && certIndex <= certs.Count)
       {
           e.Certificate = certs[certIndex];
           return;
       }
       if (certIndex == 0)
           break;
       Console.WriteLine(string.Format("ERROR: You must enter number between 0 and {0}.", certs.Count));
   }
}

VB.NET

Public Sub HandleCertificateRequiredEvent()
    ' Create a new instance.
    Dim client As New ImapClient()
    AddHandler client.CertificateRequired, AddressOf client_CertificateRequired
    ' Connect to the IMAP server.
    client.Connect("myserver", 143, SecurityMode.Explicit)
    ' Authenticate.
    client.Authenticate("userName", "password")
    ' Do something here...
    ' ...
    ' Disconnect.
    client.Disconnect()
End Sub
Private Sub client_CertificateRequired(ByVal sender As Object, ByVal e As ComponentPro.Security.CertificateRequiredEventArgs)
    ' Load certificates from the local machine.
    Dim my As New X509Store(StoreName.My, StoreLocation.CurrentUser)
    my.Open(OpenFlags.ReadOnly)
    ' Retrieve a list of available certificates.
    Dim certs As X509Certificate2Collection = my.Certificates
    ' If no certificate found, return.
    If certs.Count = 0 Then
        e.Certificate = Nothing
        Return
    End If
    ' Show all certificates.
    Console.WriteLine("Select certificate:")
    For i As Integer = 0 To certs.Count
        If i = 0 Then
            Console.WriteLine(String.Format("{0}. [Nothing, skip this step]", i))
            Continue For
        End If
        Console.WriteLine(String.Format("{0}. {1}", i, certs(i - 1).SubjectName.Name))
    Next i
    ' And ask user to choose an appropriate certificate.
    Do
        Console.Write(String.Format("Select certificate [0 - {0}]: ", certs.Count))
        Dim certIndex As Integer
        Try
            certIndex = Integer.Parse(Console.ReadLine())
        Catch
            Console.WriteLine("ERROR: Wrong certificate index input!")
            Continue Do
        End Try
        If certIndex > 0 AndAlso certIndex <= certs.Count Then
            e.Certificate = certs(certIndex)
            Return
        End If
        If certIndex = 0 Then
            Exit Do
        End If
        Console.WriteLine(String.Format("ERROR: You must enter number between 0 and {0}.", certs.Count))
    Loop
End Sub