Sample code for 30+ languages & platforms
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 C++ Downloads

C++
#include <CkStringBuilder.h>
#include <CkXmlDSigGen.h>
#include <CkCert.h>
#include <CkXmlDSig.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.
    CkStringBuilder sbXml;
    success = sbXml.LoadFile("qa_data/xml_dsig/spid_metadata.xml","utf-8");
    if (success == false) {
        std::cout << "Failed to load the input file." << "\r\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>

    CkXmlDSigGen gen;

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

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

    //  Provide a certificate + private key. (PFX password is test123)
    CkCert cert;
    success = cert.LoadPfxFile("qa_data/pfx/cert_test123.pfx","test123");
    if (success != true) {
        std::cout << cert.lastErrorText() << "\r\n";
        return;
    }

    gen.SetX509Cert(cert,true);

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

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

    //  Sign the XML...
    success = gen.CreateXmlDSigSb(sbXml);
    if (success != true) {
        std::cout << gen.lastErrorText() << "\r\n";
        return;
    }

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

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

    std::cout << sbXml.getAsString() << "\r\n";

    //  ----------------------------------------
    //  Verify the signatures we just produced...
    CkXmlDSig verifier;
    success = verifier.LoadSignatureSb(sbXml);
    if (success != true) {
        std::cout << verifier.lastErrorText() << "\r\n";
        return;
    }

    int numSigs = verifier.get_NumSignatures();
    int verifyIdx = 0;
    while (verifyIdx < numSigs) {
        verifier.put_Selector(verifyIdx);
        bool verified = verifier.VerifySignature(true);
        if (verified != true) {
            std::cout << verifier.lastErrorText() << "\r\n";
            return;
        }

        verifyIdx = verifyIdx + 1;
    }

    std::cout << "All signatures were successfully verified." << "\r\n";
    }