IWConnect XML Digital Signature Snap Pack

IWConnect XML Digital Signature Snap Pack

SnapLogic is an excellent Integration Platform as a Service (iPaaS). It is based on Java and provides tons of integration components (Snaps) out of the box. At the same time, it supports custom Snap components development. The development documentation is online and available for everyone. These couple of sentences I wrote at the beginning convey the main message I want to share here: there are no limits if you want to develop some custom functionality not provided directly by the vendor. ?The platform is based on Java, which is, under my humble opinion, the most mature enterprise grade language that has available libraries and platforms for everything.

One of the Snap functionalities not provided out of the box, but sometimes important for the enterprises, is XML Digital Signature. The SOA concept started with the XML Web Services and the SOAP protocol. There are many WS-* specifications related to SOAP digital signatures, reliability, notifications etc. Large enterprises still rely on these protocols and specifications for reliable message delivery with strict rules related to the message integrity and confidentiality. It is fair to say that remoting protocols have evolved in time and today we are dealing with REST endpoints, JSON, GraphQL. But, it is also fair to say that these protocols and/or specifications are under specified compared with the XML Web Services, sometimes missing important enterprise grade features.

XML Digital Signature is something that is added to the XML document before sending it to the recipient. It provides integrity (the signed parts were not modified) and non-repudiation (the sender owning the private key cannot claim that she did not send that message).

<Signature
  <SignedInfo>
    <CanonicalizationMethod />
    <SignatureMethod />
    <Reference>
       <Transforms />
       <DigestMethod />
       <DigestValue />
    </Reference>
    <Reference /> etc.
  </SignedInfo>
  <SignatureValue />
  <KeyInfo />
  <Object />
</Signature>>        

In essence, the simplified process is:

  • The sender takes parts (references) of the input XML message or the whole message itself
  • For these parts, the sender calculates digests (hashes)
  • The sender digitally signs the combined hash with her private key
  • The XML Signature elements describing what has been digested (references), what transformations has been applied in order to calculate the digests and the value of the signature itself are added to the input XML message;
  • The recipient, after receiving the message, calculates the same digests and verifies the signature with the sender’s public key.

Java supports XML Digital Signatures and Oracle provides basic usage example. It seems that we have found an excellent opportunity to wrap enterprise grade functionality into custom SnapLogic Snap Pack.

IWConnect engineers recently created this custom Snap functionality. The package contains:

  • Crypto Key Pair Account: Supports RSA, DSA (Digital Signature Algorithm) and EC (Elliptic Curve) private/public key pairs
  • XML Digital Signature Signer: Supports many strong signing algorithms like RSA_SHA512, DSA_SHA256 or ECDSA_SHA512 (and their weaker variants as well).
  • XML Digital Signature Validator: Validates the XML document's digital signature.

The Crypto Key Pair Account accepts private keys in PKCS8 format. For example, an Elliptic Curve private key could be:

-----BEGIN PRIVATE KEY----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgcbi/wfQ3XKnHOOa+
kY0b6slEsOqojH5tsm4hualSYxyhRANCAAQ/m16G2ochyPf9k/TCFvxRF5dUVnQh
YUQHdzheCF6rpU77/gfoRf7ja1VeglZTxRdwlXR4EZ+0KiEklB3G7NjU
-----END PRIVATE KEY------        

The private key in the account is marked with high sensitivity. SnapLogic platform encrypts the key at rest and it is not visible in the UI once configured.

The Crypto Key Pair Account accepts public keys in X509 format. For example, an Elliptic Curve public key could be:

-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEP5tehtqHIcj3/ZP0whb8UReXVFZ0
IWFEB3c4Xgheq6VO+/4H6EX+42tVXoJWU8UXcJV0eBGftCohJJQdxuzY1A==
-----END PUBLIC KEY-----        
No alt text provided for this image

Let us say that we are dealing with the following XML document:

<?xml version="1.0" encoding="UTF-8"?>
<iwc:Employee xmlns:iwc="https://iwconnect.com">
?? ?<iwc:PersonalInfo iwc:id="personal">
?? ??? ?<iwc:FirstName>Marjan</iwc:FirstName>
?? ??? ?<iwc:LastName>Sterjev</iwc:LastName>
?? ??? ?<iwc:Age>48</iwc:Age>
?? ?</iwc:PersonalInfo>
?? ?<iwc:ProfessionalInfo iwc:id="professional">
?? ??? ?<iwc:Title>CTO</iwc:Title>
?? ?</iwc:ProfessionalInfo>
</iwc:Employee>
        

The Signer Snap configuration for signing both references iwc:id="personal" and iwc:id="professional" by using SHA3_512 as digest method and ECDSA_SHA256 as signature method could be:

No alt text provided for this image

The Signer works against string specified in the input document as a field with name xml.

It is worth mentioning what XML ID attribute name and XML ID attribute namespace mean in the Signer’s configuration above. That is the tricky part in the implementation that is not explained that well in the official Java documentation. When we deal with HTML, most JavaScript developers are comfortable with calls like document.getElementById(id). In HTML, the attribute with name id is the one that distinguishes HTML elements. The id attribute has been defined in the HTML specification. However, in arbitrary XML documents, the literal id attribute has no meaning at all, unless you define that meaning by yourself. XML Digital Signature relies on References when deciding what shall be digested and signed.

For example:

<Reference URI=”#personal”>…</Reference>

<Reference URI=”#professional”>…</Reference>        

So, how can we find the "#personal" and "#professional" references in the Employee document above? Note that the XML document has the attribute iwc:id for that purpose. The iwc prefix is bound to the https://iwconnect.com namespace. That's what has been configured in the Signer's screen above:

  • XML ID attribute name: id
  • XML ID attribute namespace: https://iwconnect.com

The Java code that deals with the referenced element search logic is XPath based and looks something like the following snippet:

String xPathExpression = null;

if (xmlIdAttributeNamespace == null)

?? ?xPathExpression = String.format("https://*[@%s=\"%s\"]", xmlIdAttributeName, reference);
else
?? ?xPathExpression = String.format("https://*[@%s:%s=\"%s\"]", DigSigNamespaceContext.IDNS,
?? ??? ??? ?xmlIdAttributeName, reference);


xPath.setNamespaceContext(namespaceContext);

Element elementToSign = (Element) xPath.compile(xPathExpression).evaluate(doc, XPathConstants.NODE);

if (elementToSign == null) {
?? ?writeError(.......);
?? ?return;
}

domSigningContext.setIdAttributeNS(elementToSign, xmlIdAttributeNamespace, xmlIdAttributeName);        

The last line with the call setIdAttributeNS() makes all of this work.

The Validator Snap configuration could be:

No alt text provided for this image

The XML ID attribute name and XML ID attribute namespace properties have the same meaning as in the Signer Snap. Now, the second, even more tricky part, is related to the properties XML Element Reference Parent Name and XML Element Reference Parent Namespace. Why do we need these properties?

In the world of XML Digital Signatures exists well known attack known as XML Signature Wrapping. Simplified explanation of the attack is:

  • Let us assume that we have SOAP:Envelope document with SOAP:Header and SOAP:Body parts within.
  • The Signer signs the content within the SOAP:Body part and the calculated signature is attached as a child of the SOAP:Header element.
  • The application logic processing the business payload does not care about the SOAP:Header or anything within. It is concerned only with the content of the SOAP:Body.
  • The attacker can detach the original SOAP:Body business payload and attach it as a child of the SOAP:Header. Technically, the original business payload is still in the XML document, but located somewhere "not visible" to the application logic. If the validation logic searches for Reference by its id only, not matter where it is located, the modified XML document will be still validated and verified. Finally, the attacker can attach new malicious business payload under the SOAP:Body.
  • UPS! XML document and its integrity has been validated, but application logic deals with malicious business payload!

In order to prevent these situations, we can specify the XML element that is the expected parent of the signed references. The expected parent shall be somewhere within the business payload visible to the application logic. This way the attacker can't move the original signed reference into arbitrary place in the XML document and put malicious stubs on their place.

The Java XPath processing in the Validator Snap is similar with the one presented for the Signer:

String referencesExpression = String.format("https://%s:Signature/%s:SignedInfo/%s:Reference",
?? ??? ??? ?DigSigNamespaceContext.XMLDSIG, DigSigNamespaceContext.XMLDSIG, DigSigNamespaceContext.XMLDSIG);


NodeList references = (NodeList) xPath.compile(referencesExpression).evaluate(doc, XPathConstants.NODESET);

for (int i = 0; i < references.getLength(); i++) {

?? ?Element reference = (Element) references.item(i);

?? ?String uri = reference.getAttribute("URI");

?? ?if (uri == null || !(uri.startsWith("#") || "".equals(uri)))
?? ??? ?throw new SnapDataException("Invalid XML Digital Signature Reference URI:" + uri);

?? ?if ("".equals(uri))
?? ??? ?continue;

?? ?String nodeId = uri.substring(1);

?? ?String nodeExpression = "";

?? ?if (xmlElementReferenceParentName != null) {

?? ??? ?if (xmlElementReferenceParentNamespace == null)
?? ??? ??? ?nodeExpression = String.format("https://%s", xmlElementReferenceParentName);
?? ??? ?else
?? ??? ??? ?nodeExpression = String.format("https://%s:%s", P, xmlElementReferenceParentName);
?? ?}

?? ?if (xmlIdAttributeNamespace == null)

?? ??? ?nodeExpression = String.format("%s//*[@%s=\"%s\"]", nodeExpression, xmlIdAttributeName, nodeId);
?? ?else
?? ??? ?nodeExpression = String.format("%s//*[@%s:%s=\"%s\"]", nodeExpression, DigSigNamespaceContext.IDNS,
?? ??? ??? ??? ?xmlIdAttributeName, nodeId);

?? ?Node signedDataNode = (Node) xPath.compile(nodeExpression).evaluate(doc, XPathConstants.NODE);

?? ?if (signedDataNode == null)
?? ??? ?throw new SnapDataException(
?? ??? ??? ??? ?String.format("Signed data node with id '%s' in the search path '%s' does not exist!",
?? ??? ??? ??? ??? ??? ?nodeId, nodeExpression));

?? ?domValidateContext.setIdAttributeNS((Element) signedDataNode, xmlIdAttributeNamespace,
?? ??? ??? ?xmlIdAttributeName);

}        

The output of the Validator Snap contains the XML string, the validation status and the public key the XML has been validated with (locally configured or embedded in the XML document as a KeyInfo element).

No alt text provided for this image

The public key information available in the output could be used in some downstream Snaps for the signer (subject) identification (a map of public-key <-> subject name for example).

If the document has not been validated, the errors are routed to the Error view.

It works! Probably there are more tricky use cases that can be added in the Validator Snap implementation, but we know where to look for if needed :). Tomorrow is a new day, brand new challenges and solutions for the IWConnect employees!

...because, you know, we connect the dots!...

Marjan

Aleksandar Polizovski

Software Engineer == Akta Manniskor

2 年

Nice snap, keep on snapping to connect the dots.

要查看或添加评论,请登录

Marjan Sterjev的更多文章

  • Secure Multi-Party Computation: Idea and Example

    Secure Multi-Party Computation: Idea and Example

    We are seeing massive AI adoption these days. At least everyone is talking about it.

    1 条评论
  • Theseus TryHackMe Room Writeup

    Theseus TryHackMe Room Writeup

    Theseus is an old room, almost 5 years old. Its difficulty has been specified as Insane.

  • Breaking weak Captcha: Tesseract OCR

    Breaking weak Captcha: Tesseract OCR

    Capture Returns TryHackMe room has been recently added. Sometimes CTF scenarios could be artificial.

  • Behaviour Analysis: Outlier Sequence Detection

    Behaviour Analysis: Outlier Sequence Detection

    Each production system deals with a lot of signals and sequence of events. Some of the sequences are unusual and…

    6 条评论
  • RSA Optimizations: Think Twice

    RSA Optimizations: Think Twice

    I will start here straight ahead with the summary: Resist your temptations and do not implement your customised and…

    2 条评论
  • RSA & Chinese Remainder Theorem MEGA Exploits

    RSA & Chinese Remainder Theorem MEGA Exploits

    There is a lot of data we are dealing with today. Most of us have multiple digital devices.

    4 条评论
  • A word or two about the parallelisation

    A word or two about the parallelisation

    This article will be a short one. It talks about parallelisation and efficiency, so it shall waste as less as possible…

  • Covert Tcp - Scapy Version

    Covert Tcp - Scapy Version

    Covert Tcp is one of the tools for covert communication mentioned in the white hacking courses. Instead of sending…

  • Network Traffic Anomaly Detection

    Network Traffic Anomaly Detection

    It is well known today that anomaly detection helps us spot interesting data, events, malicious behaviour, potential…

  • Kyber: NTT and Efficient Polynomial Multiplication

    Kyber: NTT and Efficient Polynomial Multiplication

    In my previous article From Baby to Teenage Kyber I've explained how Kyber encryption/decryption works. As it was…

    4 条评论

社区洞察

其他会员也浏览了