Search code examples
c#tcpclientpkcs#11pkcs11interophardware-security-module

How to AuthenticateAsServer when Certificate is in HSM and privateKey is not embeded in Certificate and PrivateKey is not extractable from HSM


I want to ask a qusetion according to my code, My code is as bellow: in AuthenticateAsServer I get "The server mode SSL must use a certificate with the associated private key" error cause privatekey is not in my certificate and also privatekey is not extractable from the HSM, would you please guid me what is the solution here?

     static void ProcessClient(TcpClient client)
    {
        SslStream sslClientStream = new SslStream(client.GetStream(), true, AllowAnyServerCertificate, null, EncryptionPolicy.RequireEncryption);

        try
        {
            X509Certificate2 _HsmserverCertificate = null;

            string pkcs11LibraryPath = "C:\\Program Files (x86)\\nCipher\\nfast\\toolkits\\pkcs11\\cknfast-64.dll";

            Pkcs11InteropFactories factories = new Pkcs11InteropFactories();

            using (IPkcs11Library pkcs11Library = factories.Pkcs11LibraryFactory.LoadPkcs11Library(factories, pkcs11LibraryPath, AppType.MultiThreaded))
            {
                ISlot slot = HelpersMethods.GetUsableSlot(pkcs11Library);

                using (Net.Pkcs11Interop.HighLevelAPI.ISession session = slot.OpenSession(SessionType.ReadWrite))
                {
                    session.Login(CKU.CKU_USER, @"1234");

                    var certificate = ReadCertificates(slot, session)[0];

                    _HsmserverCertificate = new X509Certificate2(certificate.CkaValue);
                    
                    session.Logout();
                }
            }

            sslClientStream.ReadTimeout = glb_intReciveTimeOut;
            sslClientStream.WriteTimeout = glb_intSendTimeOut;

            sslClientStream.AuthenticateAsServer(_HsmserverCertificate,
                                                 clientCertificateRequired: false,
                                                 SslProtocols.Tls12,
                                                 checkCertificateRevocation: true);
    }
}

Solution

  • Unwritten rule in .NET world: If you want to use an instance X509Certificate2 class in SSL connection then you cannot create it manually but you need to acquire it from X509Store.

    X509Store class provides access to all certificates propagated into windows certificate store. Take a look at your device documentation for more details on how to propagate your device certificates into windows certificate store. Sometimes it is also referred to as CAPI, CSP, CNG, KSP etc. If you are unfamiliar with those terms then your best bet is to contact device vendor support.