Xceed .NET Libraries Documentation
How To Handle a PKCS #7 Formatted Client Certificate
Welcome to Xceed .NET, .NET Standard and Xamarin Libraries! > Task-Based Help > FTP capabilities > Making Secure Connections > How To Handle a PKCS #7 Formatted Client Certificate

Here is an example on how to handle a PKCS #7 formatted client certificate when making an SSL connection.

static void ClientCertificateExample()

{

  try

  {

    // Load the certificate file into a byte array

    byte[] certificateBytes = File.ReadAllBytes( @"D:\Xceed\PKCS7Certificates.p7b" );



    // Create an object that can decode the certificate data

    System.Security.Cryptography.Pkcs.SignedCms cms = new System.Security.Cryptography.Pkcs.SignedCms();

    

    // Decode the certificates

    cms.Decode( certificateBytes );



    FtpClient ftp = new FtpClient();

    //ftp.TraceWriter = Console.Out;



    string host = "localhost";

    int port = 990;



    // Pick an authentication method

    AuthenticationMethod authenticationMethod = AuthenticationMethod.Ssl;



    // Pick verification flags. If unsure, pick 'None'.

    VerificationFlags verificationFlags = VerificationFlags.None;



    // The client certificate to submit to the server

    Certificate clientCertificate = null;



    // Subscribe to the CertificateReceived event

    ftp.CertificateReceived += new CertificateReceivedEventHandler( OnCertificateReceived );



    /* A PKCS #7 file can contain more than one certificate. The certificates are in the collection

     * specified in the cms.Certificates property.

     * 

     * If you know which certificate the FTP server is waiting for, simply supply it to

     * the Connect() method. If you do not know which is the correct one, you can try to connect

     * using each one in turn until the server accepts one. */

     

    // Go through each certificate in the collection

    foreach( System.Security.Cryptography.X509Certificates.X509Certificate2 x509certificate in cms.Certificates )

    {

      // Create a client certificate out of the current x509 certificate

      clientCertificate = new Certificate( x509certificate );



      try

      {

        // Connect implicitly to the server using encryption.

        // This form always enables encryption for the data channel (for file transfers)

        ftp.Connect( host, port, authenticationMethod, verificationFlags, clientCertificate );

      }

      catch( FtpSslException )

      {

        // An FtpSslException exception will be thrown if the client certificate is rejected

      }



      // If we connected successfully to the server

      if( ftp.Connected )

      {

        // No need to try again

        break;

      }

    }



    try

    {

      // Login. The exchanged information will be encrypted

      ftp.Login( "username", "password" );



      /* Perform your file transfers */

    }

    finally

    {

      // Make sure we always disconnect

      ftp.Disconnect();



      ftp.CertificateReceived -= new CertificateReceivedEventHandler( OnCertificateReceived );

    }

  }

  catch( Exception exception )

  {

    // Output some information about it

    Console.WriteLine( "-->{0}: {1}\n{2}", exception.GetType().Name, exception.Message, exception.StackTrace );



    // Fetch the inner exception

    exception = exception.InnerException;



    // While there is an exception

    while( exception != null )

    {

      // Output some information about it

      Console.WriteLine( "-->Inner exception: {0}: {1}\n{2}", exception.GetType().Name, exception.Message, exception.StackTrace );



      // Fetch the inner exception

      exception = exception.InnerException;

    }

  }

}



static void OnCertificateReceived( object sender, CertificateReceivedEventArgs e )

{

  // Always accept the certificate

  e.Action = VerificationAction.Accept;

}
    Private Shared Sub ClientCertificateExample()

      Try

        ' Load the certificate file into a byte array

        Dim certificateBytes() As Byte = File.ReadAllBytes("D:\Xceed\PKCS7Certificates.p7b")



        ' Create an object that can decode the certificate data

        Dim cms As New System.Security.Cryptography.Pkcs.SignedCms()



        ' Decode the certificates

        cms.Decode(certificateBytes)



        Dim ftp As New FtpClient()

        'ftp.TraceWriter = Console.Out;



        Dim host As String = "localhost"

        Dim port As Integer = 990



        ' Pick an authentication method

        Dim authenticationMethod As AuthenticationMethod = AuthenticationMethod.Ssl



        ' Pick verification flags. If unsure, pick 'None'.

        Dim verificationFlags As VerificationFlags = VerificationFlags.None



        ' The client certificate to submit to the server

        Dim clientCertificate As Certificate = Nothing



        ' Subscribe to the CertificateReceived event

        AddHandler ftp.CertificateReceived, AddressOf OnCertificateReceived



'         A PKCS #7 file can contain more than one certificate. The certificates are in the collection

'         * specified in the cms.Certificates property.

'         * 

'         * If you know which certificate the FTP server is waiting for, simply supply it to

'         * the Connect() method. If you do not know which is the correct one, you can try to connect

'         * using each one in turn until the server accepts one. 



        ' Go through each certificate in the collection

        For Each x509certificate As System.Security.Cryptography.X509Certificates.X509Certificate2 In cms.Certificates

          ' Create a client certificate out of the current x509 certificate

          clientCertificate = New Certificate(x509certificate)



          Try

            ' Connect implicitly to the server using encryption.

            ' This form always enables encryption for the data channel (for file transfers)

            ftp.Connect(host, port, authenticationMethod, verificationFlags, clientCertificate)

          Catch e1 As FtpSslException

            ' An FtpSslException exception will be thrown if the client certificate is rejected

          End Try



          ' If we connected successfully to the server

          If ftp.Connected Then

            ' No need to try again

            Exit For

          End If

        Next x509certificate



        Try

          ' Login. The exchanged information will be encrypted

          ftp.Login("username", "password")



          ' Perform your file transfers 

        Finally

          ' Make sure we always disconnect

          ftp.Disconnect()



          RemoveHandler ftp.CertificateReceived, AddressOf OnCertificateReceived

        End Try

      Catch exception As Exception

        ' Output some information about it

        Console.WriteLine("-->{0}: {1}" & Constants.vbLf & "{2}", exception.GetType().Name, exception.Message, exception.StackTrace)



        ' Fetch the inner exception

        exception = exception.InnerException



        ' While there is an exception

        Do While exception IsNot Nothing

          ' Output some information about it

          Console.WriteLine("-->Inner exception: {0}: {1}" & Constants.vbLf & "{2}", exception.GetType().Name, exception.Message, exception.StackTrace)



          ' Fetch the inner exception

          exception = exception.InnerException

        Loop

      End Try

    End Sub



    Private Shared Sub OnCertificateReceived(ByVal sender As Object, ByVal e As CertificateReceivedEventArgs)

      ' Always accept the certificate

      e.Action = VerificationAction.Accept

    End Sub
See Also