Sample code for 30+ languages & platforms
PureBasic

Verify Opaque Signature and Retrieve Signing Certificates

See more Digital Signatures Examples

Demonstrates how to verify a PCKS7 opaque digital signature (signed data), extract the original file/data, and then extract the certificate(s) that were used to sign.

Chilkat PureBasic Downloads

PureBasic
IncludeFile "CkBinData.pb"
IncludeFile "CkCert.pb"
IncludeFile "CkCertChain.pb"
IncludeFile "CkCrypt2.pb"

Procedure ChilkatExample()

    success.i = 0

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

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

    ; Verify a PKCS7 signed-data (opaque signature) file and extract the original content to a file.
    success = CkCrypt2::ckVerifyP7M(crypt,"qa_data/p7m/opaqueSig.p7","qa_output/originalData.dat")
    If success = 0
        Debug CkCrypt2::ckLastErrorText(crypt)
        CkCrypt2::ckDispose(crypt)
        ProcedureReturn
    EndIf

    ; Alternatively, we can do it in memory...
    binData.i = CkBinData::ckCreate()
    If binData.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    success = CkBinData::ckLoadFile(binData,"qa_data/p7m/opaqueSig.p7")
    ; Your app should check for success, but we'll skip the check for brevity..

    ; If verified, the signature is unwrapped and binData is replaced with the original data that was signed.
    success = CkCrypt2::ckOpaqueVerifyBd(crypt,binData)
    If success = 0
        Debug CkCrypt2::ckLastErrorText(crypt)
        CkCrypt2::ckDispose(crypt)
        CkBinData::ckDispose(binData)
        ProcedureReturn
    EndIf

    ; For our testing, we signed some text, so we can get it from the binData..
    Debug "Original Data:"
    Debug CkBinData::ckGetString(binData,"utf-8")

    ; After any method call that verifies a signature, the crypt object will contain the certificate(s)
    ; that were used for signing (assuming the X.509 certs were available in the signature, which is typically the case).

    ; Get each signing certificate, and build the certificate chain for each.
    cert.i = CkCert::ckCreate()
    If cert.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

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

    numCerts.i = CkCrypt2::ckNumSignerCerts(crypt)
    i.i = 0
    While i < numCerts
        CkCrypt2::ckLastSignerCert(crypt,i,cert)
        Debug CkCert::ckSubjectDN(cert)

        success = CkCert::ckBuildCertChain(cert,certChain)
        If success = 0
            Debug CkCert::ckLastErrorText(cert)
            CkCrypt2::ckDispose(crypt)
            CkBinData::ckDispose(binData)
            CkCert::ckDispose(cert)
            CkCertChain::ckDispose(certChain)
            ProcedureReturn
        EndIf

        i = i + 1
    Wend


    CkCrypt2::ckDispose(crypt)
    CkBinData::ckDispose(binData)
    CkCert::ckDispose(cert)
    CkCertChain::ckDispose(certChain)


    ProcedureReturn
EndProcedure