Sample code for 30+ languages & platforms
Swift

Sign XML (XAdES) using USB Token or Smartcard on iOS iPhone

Demonstrates how to sign XML using an HSM (USB token or smart card) connected to an iPhone.

Note: This example requires Chilkat v10.0.0 or greater.

Chilkat Swift Downloads

Swift

func chilkatTest() {
    var success: Bool = false

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

    // When signing with a USB token or smartcard, the only coding difference is how the certificate
    // gets loaded.  To load the default certificate from the connected USB token or smartcard, just call
    // LoadFromSmartcard with an empty string argument.
    // 
    // This requires Chilkat v10.0.0 or later.
    // 
    // ------------------------------------------------------------------------------------------------------------------------------------------------------
    // Important: In your Xcode project, you'll need to add the "com.apple.token" entitlement.
    // Also, adding the com.apple.token in the "Project > Signing & Capabilities" will actually add $(AppIdentifierPrefix)com.apple.token, which does not work. 
    // Edit the entitlements file directly and add only com.apple.token
    // If using a Yubikey, you'll only find the certificate if it is added in the Yubikey app as Public.
    // ------------------------------------------------------------------------------------------------------------------------------------------------------
    let cert = CkoCert()!
    success = cert.load(fromSmartcard: "")
    if success == false {
        print("\(cert.lastErrorText!)")
        return
    }

    // Create the XML to be signed.
    let sbXml = CkoStringBuilder()!

    var bCrlf: Bool = true
    sbXml.appendLine(str: "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>", crlf: bCrlf)
    sbXml.appendLine(str: "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">", crlf: bCrlf)
    sbXml.appendLine(str: "    <SOAP-ENV:Header>", crlf: bCrlf)
    sbXml.appendLine(str: "        <wsse:Security xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" SOAP-ENV:mustUnderstand=\"1\"></wsse:Security>", crlf: bCrlf)
    sbXml.appendLine(str: "    </SOAP-ENV:Header>", crlf: bCrlf)
    sbXml.appendLine(str: "    <SOAP-ENV:Body xmlns:SOAP-SEC=\"http://schemas.xmlsoap.org/soap/security/2000-12\" SOAP-SEC:id=\"Body\">", crlf: bCrlf)
    sbXml.appendLine(str: "        <z:FooBar xmlns:z=\"http://example.com\" />", crlf: bCrlf)
    sbXml.appendLine(str: "    </SOAP-ENV:Body>", crlf: bCrlf)
    sbXml.appendLine(str: "</SOAP-ENV:Envelope>", crlf: bCrlf)

    // Prepare for signing...
    let gen = CkoXmlDSigGen()!

    // Indicate where the Signature will be inserted.
    gen.sigLocation = "SOAP-ENV:Envelope|SOAP-ENV:Header|wsse:Security"

    // Add a reference to the fragment of the XML to be signed.

    // Note: "Body" refers to the XML element having an "id" equal to "Body", where "id" is case insensitive
    // and where any namespace might qualify the attribute.  In this case, the SOAP-ENV:Body fragment is signed
    // NOT because the tag = "Body", but because it has SOAP-SEC:id="Body"
    gen.addSameDocRef(id: "Body", digestMethod: "sha1", canonMethod: "EXCL_C14N", prefixList: "", refType: "")

    // (You can read about the SignedInfoPrefixList in the online reference documentation.  It's optional..)
    gen.signedInfoPrefixList = "wsse SOAP-ENV"

    gen.keyInfoType = "X509Data"
    gen.x509Type = "IssuerSerial"

    var bUsePrivateKey: Bool = true
    success = gen.setX509Cert(cert: cert, usePrivateKey: bUsePrivateKey)
    if success != true {
        print("\(gen.lastErrorText!)")
        cert = nil
        return
    }

    // Everything's specified.  Now create and insert the Signature
    success = gen.createXmlDSigSb(sbXml: sbXml)
    if success != true {
        print("\(gen.lastErrorText!)")
        return
    }

    // Examine the XML with the digital signature inserted
    print("\(sbXml.getAsString()!)")

}