Sample code for 30+ languages & platforms
PureBasic Requires Chilkat v11.0.0+

Examine Client Certificates for an Accepted TLS Connection

See more Socket/SSL/TLS Examples

Demonstrates how to access the client certificates for a TLS connection accepted by your application acting as the server.

Chilkat PureBasic Downloads

PureBasic
IncludeFile "CkSocket.pb"
IncludeFile "CkCert.pb"

Procedure ChilkatExample()

    success.i = 0

    ;  This example requires the Chilkat API to have been previously unlocked.
    ;  See Global Unlock Sample for sample code.

    listenSslSocket.i = CkSocket::ckCreate()
    If listenSslSocket.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    ;  An SSL/TLS server needs a digital certificate.  This example loads it from a PFX file.
    ;  This is the server's certificate.

    cert.i = CkCert::ckCreate()
    If cert.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    success = CkCert::ckLoadPfxFile(cert,"qa_data/serverCert/myServerCert.pfx","pfx_password")
    If success = 0
        Debug CkCert::ckLastErrorText(cert)
        CkSocket::ckDispose(listenSslSocket)
        CkCert::ckDispose(cert)
        ProcedureReturn
    EndIf

    ;  To accept client client certificates in the TLS handshake,
    ;  we must indicate a list of acceptable client certificate root CA DN's
    ;  that are allowed.  (DN is an acronym for Distinguished Name.)
    ;  Call AddSslAcceptableClientCaDn once for each acceptable CA DN.
    ;  Here are a few examples so you can see the general format of a DN.
    CkSocket::ckAddSslAcceptableClientCaDn(listenSslSocket,"C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root")
    CkSocket::ckAddSslAcceptableClientCaDn(listenSslSocket,"O=Digital Signature Trust Co., CN=DST Root CA X3")

    ;  Initialize with our server's TLS certificate.
    success = CkSocket::ckInitSslServer(listenSslSocket,cert)
    If success = 0
        Debug CkSocket::ckLastErrorText(listenSslSocket)
        CkSocket::ckDispose(listenSslSocket)
        CkCert::ckDispose(cert)
        ProcedureReturn
    EndIf

    ;  Bind and listen on a port:
    myPort.i = 8123
    ;  Allow for a max of 5 queued connect requests.
    backLog.i = 5
    success = CkSocket::ckBindAndListen(listenSslSocket,myPort,backLog)
    If success = 0
        Debug CkSocket::ckLastErrorText(listenSslSocket)
        CkSocket::ckDispose(listenSslSocket)
        CkCert::ckDispose(cert)
        ProcedureReturn
    EndIf

    ;  Accept the next incoming connection.
    maxWaitMillisec.i = 20000

    clientSock.i = CkSocket::ckCreate()
    If clientSock.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    success = CkSocket::ckAcceptNext(listenSslSocket,maxWaitMillisec,clientSock)
    If success = 0
        Debug CkSocket::ckLastErrorText(listenSslSocket)
        CkSocket::ckDispose(listenSslSocket)
        CkCert::ckDispose(cert)
        CkSocket::ckDispose(clientSock)
        ProcedureReturn
    EndIf

    ;  Examine the client certs chain.  The 1st cert will be the client certificate, and
    ;  the subsequent certs will be the certs in the chain of authentication.
    numClientCerts.i = CkSocket::ckNumReceivedClientCerts(clientSock)
    Debug "numClientCerts = " + Str(numClientCerts)

    clientCert.i = CkCert::ckCreate()
    If clientCert.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    i.i = 0
    While i < numClientCerts
        CkSocket::ckGetRcvdClientCert(clientSock,i,clientCert)
        Debug CkCert::ckSubjectDN(clientCert)
        i = i + 1
    Wend

    ;  Close the connection with the client
    success = CkSocket::ckClose(clientSock,1000)


    CkSocket::ckDispose(listenSslSocket)
    CkCert::ckDispose(cert)
    CkSocket::ckDispose(clientSock)
    CkCert::ckDispose(clientCert)


    ProcedureReturn
EndProcedure