Sample code for 30+ languages & platforms
Unicode C++

Sign Italian SPID Metadata XML

See more XML Digital Signatures Examples

Demonstrates how to create an XML digital signature for Italian SPID Metadata.

Chilkat Unicode C++ Downloads

Unicode C++
#include <CkStringBuilderW.h>
#include <CkXmlDSigGenW.h>
#include <CkCertW.h>
#include <CkXmlDSigW.h>

void ChilkatSample(void)
    {
    bool success = false;

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

    success = true;

    // Load the XML to be signed.
    CkStringBuilderW sbXml;
    success = sbXml.LoadFile(L"qa_data/xml_dsig/spid_metadata.xml",L"utf-8");
    if (success == false) {
        wprintf(L"Failed to load the input file.\n");
        return;
    }

    // The XML to sign contains XML such as this:

    // <?xml version="1.0" encoding="utf-8"?>
    // <md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" entityID="https://***.it" ID="_AE17AFFF-A600-49D5-B81D-76EEA55B50FF">
    //     <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol" AuthnRequestsSigned="true" WantAssertionsSigned="true">
    //         <md:KeyDescriptor use="signing">
    //             <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    //                 <ds:X509Data>
    //                     <ds:X509Certificate>MIIF5...</ds:X509Certificate>
    //                 </ds:X509Data>
    //             </ds:KeyInfo>
    //         </md:KeyDescriptor>
    //         <md:KeyDescriptor use="encryption">
    //             <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    //                 <ds:X509Data>
    //                     <ds:X509Certificate>MIIF5...</ds:X509Certificate>
    //                 </ds:X509Data>
    //             </ds:KeyInfo>
    //         </md:KeyDescriptor>
    //         <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://***.it/it-it/spid/logout"/>
    //         <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
    //         <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://***.it/it-it/spid/loginresp" index="0" isDefault="true"/>
    //         <md:AttributeConsumingService index="1">
    //             <md:ServiceName xml:lang="it">Servizi Online</md:ServiceName>
    //             <md:ServiceDescription xml:lang="it">Accesso ai Servizi Online</md:ServiceDescription>
    //             <md:RequestedAttribute Name="spidCode" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
    //             <md:RequestedAttribute Name="name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
    //             <md:RequestedAttribute Name="familyName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
    //             <md:RequestedAttribute Name="fiscalNumber" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
    //         </md:AttributeConsumingService>
    //     </md:SPSSODescriptor>
    //     <md:Organization>
    //         <md:OrganizationName xml:lang="it">SomeCompany s.r.l.</md:OrganizationName>
    //         <md:OrganizationDisplayName xml:lang="it">SomeCompany s.r.l.</md:OrganizationDisplayName>
    //         <md:OrganizationURL xml:lang="it">https://***.it</md:OrganizationURL>
    //     </md:Organization>
    // </md:EntityDescriptor>

    CkXmlDSigGenW gen;

    gen.put_SigLocation(L"md:EntityDescriptor|md:SPSSODescriptor");
    gen.put_SigLocationMod(2);
    gen.put_SignedInfoCanonAlg(L"EXCL_C14N");
    gen.put_SignedInfoDigestMethod(L"sha256");

    // -------- Reference 1 --------
    gen.AddSameDocRef(L"_AE17AFFF-A600-49D5-B81D-76EEA55B50FF",L"sha256",L"EXCL_C14N",L"",L"");

    // Provide a certificate + private key. (PFX password is test123)
    CkCertW cert;
    success = cert.LoadPfxFile(L"qa_data/pfx/cert_test123.pfx",L"test123");
    if (success != true) {
        wprintf(L"%s\n",cert.lastErrorText());
        return;
    }

    gen.SetX509Cert(cert,true);

    gen.put_KeyInfoType(L"X509Data+KeyValue");
    gen.put_X509Type(L"Certificate");

    gen.put_Behaviors(L"IndentedSignature,ForceAddEnvelopedSignatureTransform,OmitAlreadyDefinedSigNamespace");

    // Sign the XML...
    success = gen.CreateXmlDSigSb(sbXml);
    if (success != true) {
        wprintf(L"%s\n",gen.lastErrorText());
        return;
    }

    // -----------------------------------------------

    // Save the signed XML to a file.
    success = sbXml.WriteFile(L"qa_output/signedXml.xml",L"utf-8",false);

    wprintf(L"%s\n",sbXml.getAsString());

    // ----------------------------------------
    // Verify the signatures we just produced...
    CkXmlDSigW verifier;
    success = verifier.LoadSignatureSb(sbXml);
    if (success != true) {
        wprintf(L"%s\n",verifier.lastErrorText());
        return;
    }

    int numSigs = verifier.get_NumSignatures();
    int verifyIdx = 0;
    while (verifyIdx < numSigs) {
        verifier.put_Selector(verifyIdx);
        bool verified = verifier.VerifySignature(true);
        if (verified != true) {
            wprintf(L"%s\n",verifier.lastErrorText());
            return;
        }

        verifyIdx = verifyIdx + 1;
    }

    wprintf(L"All signatures were successfully verified.\n");
    }