Sample code for 30+ languages & platforms
PureBasic

Verify DKIM-Signature Headers in Downloaded Email

See more DKIM / DomainKey Examples

Downloads email from an IMAP server and verifies the DKIM-Signature header(s) in each email, if present.

Chilkat PureBasic Downloads

PureBasic
IncludeFile "CkBinData.pb"
IncludeFile "CkDkim.pb"
IncludeFile "CkJsonObject.pb"
IncludeFile "CkImap.pb"

Procedure ChilkatExample()

    success.i = 0

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

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

    ; Connect to an IMAP server, login, select mailbox..
    ; Use TLS 
    CkImap::setCkSsl(imap, 1)
    CkImap::setCkPort(imap, 993)
    success = CkImap::ckConnect(imap,"imap.example.com")
    If success = 1
        success = CkImap::ckLogin(imap,"myLogin","myPassword")
        If success = 1
            success = CkImap::ckSelectMailbox(imap,"Inbox")
        EndIf

    EndIf

    If success <> 1
        Debug CkImap::ckLastErrorText(imap)
        CkImap::ckDispose(imap)
        ProcedureReturn
    EndIf

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

    ; Download a max of 10 emails and verify any DKIM-Signature headers
    ; that are present.

    ; Download emails by sequence numbers (not UIDs).
    bUid.i = 0
    seqNum.i
    j.i
    n.i = CkImap::ckNumMessages(imap)
    If n > 10
        n = 10
    EndIf

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

    CkJsonObject::setCkEmitCompact(json, 0)

    ; To verify DKIM-Signature headers, we need the exact unmodified MIME bytes of each email.
    mimeData.i = CkBinData::ckCreate()
    If mimeData.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    seqNum = 1
    While seqNum <= n
        ; The FetchSingleBd method was introduced in v9.5.0.76
        success = CkImap::ckFetchSingleBd(imap,seqNum,bUid,mimeData)
        If success <> 1
            Debug CkImap::ckLastErrorText(imap)
            CkImap::ckDispose(imap)
            CkDkim::ckDispose(dkim)
            CkJsonObject::ckDispose(json)
            CkBinData::ckDispose(mimeData)
            ProcedureReturn
        EndIf

        ; Get the number of DKIM-Signature headers.
        numDkim.i = CkDkim::ckNumDkimSigs(dkim,mimeData)

        ; Verify each..
        j = 0
        While j < numDkim
            Debug "------ DKIM Signature " + Str(j)

            success = CkDkim::ckDkimVerify(dkim,j,mimeData)
            If success <> 1
                Debug "Not valid."
            Else
                Debug "valid."
            EndIf

            ; Show the additional information about the signature verification
            CkJsonObject::ckLoad(json,CkDkim::ckVerifyInfo(dkim))
            Debug CkJsonObject::ckEmit(json)

            ; The JSON contains information such as this:

            ; 	{
            ; 	  "domain": "amazonses.com",
            ; 	  "selector": "7v7vs6w47njt4pimodk5mmttbegzsi6n",
            ; 	  "publicKey": "MIGfMA0GCSqG...v2GvWPqGHz6uqeQIDAQAB",
            ; 	  "canonicalization": "relaxed/simple",
            ; 	  "algorithm": "rsa-sha256",
            ; 	  "signedHeaders": "Subject:From:To:Date:Mime-Version:Content-Type:References:Message-Id:Feedback-ID",
            ; 	  "verified": "yes"
            ; 	}

            j = j + 1
        Wend
        seqNum = seqNum + 1
    Wend

    success = CkImap::ckDisconnect(imap)


    CkImap::ckDispose(imap)
    CkDkim::ckDispose(dkim)
    CkJsonObject::ckDispose(json)
    CkBinData::ckDispose(mimeData)


    ProcedureReturn
EndProcedure