Sample code for 30+ languages & platforms
PureBasic

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