Sample code for 30+ languages & platforms
Visual FoxPro

Signed SOAP for www.sist.puglia.it/Schemas/PDD_SIST/SCATEL/ using BinarySecurityToken

See more XML Digital Signatures Examples

Creates a signed SOAP request for www.sist.puglia.it/Schemas/PDD_SIST/SCATEL/ using a BinarySecurityToken.

Chilkat Visual FoxPro Downloads

Visual FoxPro
LOCAL lnSuccess
LOCAL loXmlToSign
LOCAL loDtNow
LOCAL loGen
LOCAL loCert
LOCAL loXmlCustomKeyInfo
LOCAL loSbXml
LOCAL loBdCert
LOCAL loSbCert64
LOCAL lnNReplaced
LOCAL loVerifier
LOCAL lnNumSigs
LOCAL lnVerifyIdx
LOCAL lnVerified

lnSuccess = 0

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

* Create the following pre-signed SOAP XML:
* Note: We'll be constructing a placeholder for the wseBinarySecurityToken in the soapenv:Header.
* Chilkat will automatically replace the "BinarySecurityToken_Base64Binary_Content" with actual data when signing the XML.

* However: Your application should insert the actual desired timestamp values for wsu:Created and wsuExpires
* Typically this is the current system date/time and a few minutes from the current system date/time.
* The example below shows a 5 minute window.  We'll write code below to insert the current date/time and the current date/time + 5 minutes..

* <?xml version="1.0" encoding="utf-8"?>
* <soapenv:Envelope 
*   xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
*   xmlns:scat="www.sist.puglia.it/Schemas/PDD_SIST/SCATEL/"
*   xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
*   xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
*   xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
*   xmlns:exc14n="http://www.w3.org/2001/10/xml-exc-c14n#">
*     <soapenv:Header xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
*         <wsse:Security soapenv:mustUnderstand="1">
*             <wsse:BinarySecurityToken 
*                   ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
*                   EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
*                   wsu:Id="X509Token">BinarySecurityToken_Base64Binary_Content</wsse:BinarySecurityToken>
*             <wsu:Timestamp wsu:Id="_1">
*                 <wsu:Created>2020-03-20T18:08:19Z</wsu:Created>
*                 <wsu:Expires>2020-03-20T18:13:19Z</wsu:Expires>
*             </wsu:Timestamp>
*         </wsse:Security>
*         <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"/>
*     </soapenv:Header>
*     <soapenv:Body>
*         <scat:getRuoliStruttureOperatore>
*             <scat:codFiscaleOperatore>CLDxxxxxxxxxxxxL</scat:codFiscaleOperatore>
*         </scat:getRuoliStruttureOperatore>
*     </soapenv:Body>
* </soapenv:Envelope>

lnSuccess = 1
* Create the XML to be signed...
loXmlToSign = CreateObject('Chilkat.Xml')
loXmlToSign.Tag = "soapenv:Envelope"
loXmlToSign.AddAttribute("xmlns:soapenv","http://schemas.xmlsoap.org/soap/envelope/")
loXmlToSign.AddAttribute("xmlns:scat","www.sist.puglia.it/Schemas/PDD_SIST/SCATEL/")
loXmlToSign.AddAttribute("xmlns:wsse","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")
loXmlToSign.AddAttribute("xmlns:wsu","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd")
loXmlToSign.AddAttribute("xmlns:ds","http://www.w3.org/2000/09/xmldsig#")
loXmlToSign.AddAttribute("xmlns:exc14n","http://www.w3.org/2001/10/xml-exc-c14n#")
loXmlToSign.UpdateAttrAt("soapenv:Header",1,"xmlns:wsu","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd")
loXmlToSign.UpdateAttrAt("soapenv:Header|wsse:Security",1,"soapenv:mustUnderstand","1")
loXmlToSign.UpdateAttrAt("soapenv:Header|wsse:Security|wsse:BinarySecurityToken",1,"ValueType","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3")
loXmlToSign.UpdateAttrAt("soapenv:Header|wsse:Security|wsse:BinarySecurityToken",1,"EncodingType","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary")
loXmlToSign.UpdateAttrAt("soapenv:Header|wsse:Security|wsse:BinarySecurityToken",1,"wsu:Id","X509Token")
loXmlToSign.UpdateChildContent("soapenv:Header|wsse:Security|wsse:BinarySecurityToken","BinarySecurityToken_Base64Binary_Content")
loXmlToSign.UpdateAttrAt("soapenv:Header|wsse:Security|wsu:Timestamp",1,"wsu:Id","_1")

* Insert a 5-minute timestampe window.
loDtNow = CreateObject('Chilkat.CkDateTime')
loDtNow.SetFromCurrentSystemTime()
loXmlToSign.UpdateChildContent("soapenv:Header|wsse:Security|wsu:Timestamp|wsu:Created",loDtNow.GetAsTimestamp(0))
* Add 5 minutes to the time.
loDtNow.AddSeconds(300)
loXmlToSign.UpdateChildContent("soapenv:Header|wsse:Security|wsu:Timestamp|wsu:Expires",loDtNow.GetAsTimestamp(0))
loXmlToSign.UpdateAttrAt("soapenv:Header|wsse:Security[1]",1,"xmlns:wsse","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")
loXmlToSign.UpdateChildContent("soapenv:Body|scat:getRuoliStruttureOperatore|scat:codFiscaleOperatore","CLDxxxxxxxxxxxxL")

? "XML to sign:"
? loXmlToSign.GetXml()

loGen = CreateObject('Chilkat.XmlDSigGen')

loGen.SigLocation = "soapenv:Envelope|soapenv:Header|wsse:Security"
loGen.SigLocationMod = 0
loGen.SigNamespacePrefix = "ds"
loGen.SigNamespaceUri = "http://www.w3.org/2000/09/xmldsig#"
loGen.SignedInfoCanonAlg = "EXCL_C14N"
loGen.SignedInfoDigestMethod = "sha1"

* Set the KeyInfoId before adding references..
loGen.KeyInfoId = "X509KeyId"

* -------- Reference 1 --------
loGen.AddSameDocRef("_1","sha1","EXCL_C14N","","")

* Provide a certificate + private key. (PFX password is test123)
loCert = CreateObject('Chilkat.Cert')
lnSuccess = loCert.LoadPfxFile("qa_data/pfx/cert_test123.pfx","test123")
IF (lnSuccess <> 1) THEN
    ? loCert.LastErrorText
    RELEASE loXmlToSign
    RELEASE loDtNow
    RELEASE loGen
    RELEASE loCert
    CANCEL
ENDIF

loGen.SetX509Cert(loCert,1)

loGen.KeyInfoType = "Custom"

* Create the custom KeyInfo XML..
loXmlCustomKeyInfo = CreateObject('Chilkat.Xml')
loXmlCustomKeyInfo.Tag = "wsse:SecurityTokenReference"
loXmlCustomKeyInfo.AddAttribute("wsu:Id","X509TokenReference")
loXmlCustomKeyInfo.UpdateAttrAt("wsse:Reference",1,"URI","#X509Token")
loXmlCustomKeyInfo.UpdateAttrAt("wsse:Reference",1,"ValueType","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3")

loXmlCustomKeyInfo.EmitXmlDecl = 0
loGen.CustomKeyInfoXml = loXmlCustomKeyInfo.GetXml()

* Load XML to be signed...
loSbXml = CreateObject('Chilkat.StringBuilder')
loXmlToSign.GetXmlSb(loSbXml)

* Update BinarySecurityToken_Base64Binary_Content with the actual X509 of the signing cert.
loBdCert = CreateObject('Chilkat.BinData')
loCert.ExportCertDerBd(loBdCert)
loSbCert64 = CreateObject('Chilkat.StringBuilder')
loBdCert.GetEncodedSb("base64",loSbCert64)

lnNReplaced = loSbXml.Replace("BinarySecurityToken_Base64Binary_Content",loSbCert64.GetAsString())

loGen.Behaviors = "IndentedSignature"

* Sign the XML...
lnSuccess = loGen.CreateXmlDSigSb(loSbXml)
IF (lnSuccess <> 1) THEN
    ? loGen.LastErrorText
    RELEASE loXmlToSign
    RELEASE loDtNow
    RELEASE loGen
    RELEASE loCert
    RELEASE loXmlCustomKeyInfo
    RELEASE loSbXml
    RELEASE loBdCert
    RELEASE loSbCert64
    CANCEL
ENDIF

* -----------------------------------------------

* Save the signed XML to a file.
lnSuccess = loSbXml.WriteFile("qa_output/signedXml.xml","utf-8",0)

? loSbXml.GetAsString()

* Produces the following signed XML:
* Note: The following has been edited for readability.  Therefore, what you see here will not actually validate because it's been modified.

* <?xml version="1.0" encoding="utf-8"?>
* <soapenv:Envelope 
*   xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
*   xmlns:scat="www.sist.puglia.it/Schemas/PDD_SIST/SCATEL/" 
*   xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
*   xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
*   xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:exc14n="http://www.w3.org/2001/10/xml-exc-c14n#">
*     <soapenv:Header xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
*         <wsse:Security soapenv:mustUnderstand="1">
*             <wsse:BinarySecurityToken ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" wsu:Id="X509Token">MIIFNTCCBB2gAwIBAgIQHozVnBl1lTsusAh26u6WZTANBgkqhkiG9w0BAQsFADCB
* lzELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
* A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxPTA7BgNV
* BAMTNENPTU9ETyBSU0EgQ2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBTZWN1cmUg
* RW1haWwgQ0EwHhcNMTcxMjE0MDAwMDAwWhcNMTgxMjE0MjM1OTU5WjAmMSQwIgYJ
* KoZIhvcNAQkBFhVhc2Rhc2Rhc2Rhc2RkQGJ5b20uZGUwggEiMA0GCSqGSIb3DQEB
* AQUAA4IBDwAwggEKAoIBAQC96oQe50EDoiuJVITeKJzy6GzVq74cEa14eFypjMNb
* YVyedfCI6cn9pVClLqL7dlwxFGCRA62bbNE9woKLBT3SO1IvgoFDVIrbJm+84GEo
* qQReZe8HpZnF06d3DWwhUjjcuO1z2yliGdSymSee8/1OaztxEAEOWaZR+4MkfSNc
* AzzjGtKcKjVMSdiiO0JGAG/IXEwzlulfkF8zVdqDGkQTQesvT4WBys4BYwTDI64d
* sM7rcC9vwuK6gvpkUi9i1Wzu0W4v9T3iHAbl3rLihPcjQ95c4q7+NjwpRqQW1VXR
* enR/0iyLEFOek0D4JvOoscUwJ0LYd8f9SxFEWIzc4iAfAgMBAAGjggHrMIIB5zAf
* BgNVHSMEGDAWgBSCr2yM+MX+lmF86B89K3FIXsSLwDAdBgNVHQ4EFgQUrC0DOyBB
* AgOWgo2EfVZbppe3xfEwDgYDVR0PAQH/BAQDAgWgMAwGA1UdEwEB/wQCMAAwIAYD
* VR0lBBkwFwYIKwYBBQUHAwQGCysGAQQBsjEBAwUCMBEGCWCGSAGG+EIBAQQEAwIF
* IDBGBgNVHSAEPzA9MDsGDCsGAQQBsjEBAgEBATArMCkGCCsGAQUFBwIBFh1odHRw
* czovL3NlY3VyZS5jb21vZG8ubmV0L0NQUzBaBgNVHR8EUzBRME+gTaBLhklodHRw
* Oi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9SU0FDbGllbnRBdXRoZW50aWNhdGlv
* bmFuZFNlY3VyZUVtYWlsQ0EuY3JsMIGLBggrBgEFBQcBAQR/MH0wVQYIKwYBBQUH
* MAKGSWh0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9ET1JTQUNsaWVudEF1dGhl
* bnRpY2F0aW9uYW5kU2VjdXJlRW1haWxDQS5jcnQwJAYIKwYBBQUHMAGGGGh0dHA6
* Ly9vY3NwLmNvbW9kb2NhLmNvbTAgBgNVHREEGTAXgRVhc2Rhc2Rhc2Rhc2RkQGJ5
* b20uZGUwDQYJKoZIhvcNAQELBQADggEBAHEQTr0WFcwHVk0xozn26P3s6i3RWEco
* kNr8AdOtEvU0UYf1AfyVxUs04rS3Fs0lu2TD0840S3R687xF4HXhLYxSdD0QoZyU
* S2mgxxyVxCqhwptmLn7ZQjUKEuK6Kv6wZ3/XugsBoNrMYWlYX8g2jWVDBCJ+Z0eT
* QkaYkeSxzBSMQP3DxJS/bWh5LfwSyWYk4a3SVRJV4QVyBDXKt2uwjj1wWfxfGtiw
* 6uAd2F3YIymZKsRVdrU6+h0gXMnmtpX8T+SDV6M72PP2/ZzF6gVVItyyrIScK1J8
* mcEaR5GGkLBk1s9qQM9esp3FRlACVeb1Qlytr4vgc5FlCqn0rMtjlF4=
* </wsse:BinarySecurityToken>
*             <wsu:Timestamp wsu:Id="_1">
*                 <wsu:Created>2020-03-26T17:19:50Z</wsu:Created>
*                 <wsu:Expires>2020-03-26T17:24:50Z</wsu:Expires>
*             </wsu:Timestamp>
*         </wsse:Security>
*         <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
*   <ds:SignedInfo>
*     <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
*     <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
*     <ds:Reference URI="#_1">
*       <ds:Transforms>
*         <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
*       </ds:Transforms>
*       <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
*       <ds:DigestValue>cwrTw7wFZqNc50NxE//UT11qZCY=</ds:DigestValue>
*     </ds:Reference>
*   </ds:SignedInfo>
*   <ds:SignatureValue>s2UmYNVDz9dm3eU ... 619qSZqw==</ds:SignatureValue>
*   <ds:KeyInfo Id="X509KeyId"><wsse:SecurityTokenReference wsu:Id="X509TokenReference">
*     <wsse:Reference URI="#X509Token" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
* </wsse:SecurityTokenReference>
*   </ds:KeyInfo>
* </ds:Signature></wsse:Security>
*     </soapenv:Header>
*     <soapenv:Body>
*         <scat:getRuoliStruttureOperatore>
*             <scat:codFiscaleOperatore>CLDxxxxxxxxxxxxL</scat:codFiscaleOperatore>
*         </scat:getRuoliStruttureOperatore>
*     </soapenv:Body>
* </soapenv:Envelope>

* ----------------------------------------
* Verify the signatures we just produced...
loVerifier = CreateObject('Chilkat.XmlDSig')
lnSuccess = loVerifier.LoadSignatureSb(loSbXml)
IF (lnSuccess <> 1) THEN
    ? loVerifier.LastErrorText
    RELEASE loXmlToSign
    RELEASE loDtNow
    RELEASE loGen
    RELEASE loCert
    RELEASE loXmlCustomKeyInfo
    RELEASE loSbXml
    RELEASE loBdCert
    RELEASE loSbCert64
    RELEASE loVerifier
    CANCEL
ENDIF

lnNumSigs = loVerifier.NumSignatures
lnVerifyIdx = 0
DO WHILE lnVerifyIdx < lnNumSigs
    loVerifier.Selector = lnVerifyIdx
    lnVerified = loVerifier.VerifySignature(1)
    IF (lnVerified <> 1) THEN
        ? loVerifier.LastErrorText
        RELEASE loXmlToSign
        RELEASE loDtNow
        RELEASE loGen
        RELEASE loCert
        RELEASE loXmlCustomKeyInfo
        RELEASE loSbXml
        RELEASE loBdCert
        RELEASE loSbCert64
        RELEASE loVerifier
        CANCEL
    ENDIF

    lnVerifyIdx = lnVerifyIdx + 1
ENDDO
? "All signatures were successfully verified."

RELEASE loXmlToSign
RELEASE loDtNow
RELEASE loGen
RELEASE loCert
RELEASE loXmlCustomKeyInfo
RELEASE loSbXml
RELEASE loBdCert
RELEASE loSbCert64
RELEASE loVerifier