Xceed .NET Libraries Documentation
Welcome to Xceed Data Manipulation Compoents for .NET and .NET Standard / Task-Based Help / FTP capabilities / Making Secure Connections / How To Handle a PKCS #7 Formatted Client Certificate
In This Topic
    How To Handle a PKCS #7 Formatted Client Certificate
    In This Topic

    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