WS Security for Apigee - Configurable Reference: SignatureConfirmation

Hi @dchiesa1 ,

@dchiesa1 

I am currently working on a service that requires sending the WS Security signature, so I used your contribution Java Callout for WS-Security Digital Signature[Apigee-Java-WsSec-Signature-2].
I could see that the structure is formed but there is no option to include SignatureConfirmation and interface is very stubborn to include it in response signature. 

writetorajeshku_0-1685887905232.png

how can I do to configure them.?

Thank you very much for your help.

 

 

 

 

Solved Solved
0 8 394
3 ACCEPTED SOLUTIONS

Hi Rajesh

What specifically are you attempting to do?  The WS-Security signature callout you are pointing to, is somewhat limited in that it is able to sign:

  • the soap:Body
  • the wssec:Security/wsu:Timestamp
  • or both

But today, not "other arbitrary elements", including the SignatureConfirmation elements. 

Do you simply want  the callout to also be able to sign the SignatureConfirmation elements? That would not be a difficult enhancement for me to make.  But that would mean that you (or your API proxy) would have to insure that the appropriate SignatureConfirmation elements were present in the unsigned response, before invoking the callout. 

OR, do you want the callout to also generate the SignatureConfirmation elements, inject them into the unsigned response message, and THEN sign the various elements?  To do this, your apiproxy would need to be able to provide the original signature values to be confirmed.  (and there may be more than one). 

Please advise in more detail what you want to accomplish.

EDIT: I modified the callout to add a new configuration property "confirmations".  re-pull the latest version, and Check the README.  In short, if you add that  property, and specify a comma-separated set of values, the callout will inject SignatureConfirmation elements into your SOAP document with those values; if you specify the special value "*all*", the callout will sign all existing SignatureConfigurations that are present in the document.  Try it and see if it does what you want. 

 

View solution in original post

OK great, I'm glad you were able to try the callout.

Regarding your concerns, I think you should not be bothered by any of the differences you described. I'll explain why.

First, you are saying that you expect the element to be wsse11:SignatureConfirmation but are getting wsse1.1:SignatureConfirmation. The thing before the colon in an XML element name is known as the "prefix". This is just a way to qualify elements in an XML document with a "namespace". The namespace - often a long URL, but in general it is a URN (any string) - is the semantically important thing. The prefix can be anything. In other words, the following two are exactly equivalent.

 

<foo:ElementName xmlns:foo="http://a.b.com/something"/>

<a:ElementName xmlns:a="http://a.b.com/something"/>

 

Any compliant XML processor will process those elements as being equivalent. It would be an error for an XML processing application to check the string values of the prefixes. It is required that the XML processor check the string values of the namespaces that the prefixes refer to. Therefore the difference you observe between wsse11 and wsse1.1 is immaterial.

Another thing you should be aware of - prefixes that are defined in a parent node of an element, will be effective for that element. Therefore, the following two are equivalent:

 

<s:Envelope 
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <wsse1.1:SignatureConfirmation 
       xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
       xmlns:wsse1.1="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" 
       Value="abc" wsu:Id="conf-101"/>
    ... 

<s:Envelope 
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
    xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    xmlns:wsse1.1="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">
  <s:Header>
    <wsse:Security>
      <wsse1.1:SignatureConfirmation Value="abc" wsu:Id="conf-101"/>
    ... 

 

You can see that the prefixes wsse1.1 and wsu are defined in the toplevel element, but are used only in the SignatureConfirmation element. That is no problem. Correct XML processors will treat them as the same.

You may also wonder about the value inside the quotes for the wsu:Id attribute . They are different from your "expected" and "actual observed" outputs. Here again, that won't matter. That ID is relative to the document itself. It merely provides a way for a Signature to refer to that signed element. So it does not matter if your example is "SigConfi-100" and the callout generates "Conf-103". That won't make a difference to the signature validator.

In summary, the observed output is exactly equivalent to what you describe as your "expected" output.

One more thing I will mention .... regarding "default" namespaces. This isn't important for the question you asked here, but you may come across this in the future, so I thought I'd explain it here. As I described above, you can use a prefix to "qualify" an XML element within a particular namespace. Therefore the following two are NOT equivalent, from an XML Infoset perspective:

 

<p1:address xmlns:p1="http://example.com/schemas">123 Main Street</p1:address>

<p1:address xmlns:p1="urn:abcdefg">123 Main Street</p1:address>

 

The reason is, the p1 prefix refers to two different namespaces. the address element in the namespace "http://example.com/schemas" is not the same , from an XML point of view, as the address element in the namespace "urn:abcdefg".

Beyond namespaces that are explicitly (if indirectly) referenced via a prefix, any element in an XML document has a "default" namespace. The following two ARE equivalent:

 

<address xmlns="http://example.com/schemas">123 Main Street</address>

<p1:address xmlns:p1="http://example.com/schemas">123 Main Street</p1:address>

 

In the first example, "http://example.com/schemas" is the default namespace for the element - it is the namespace the element, as well as any unqualified children of the element, gets. In the second example, the same namespace is present, but it has an explicitly declared prefix. Any correct XML processor will treat those two as exactly the same.

Maybe a more relevant example , these two are also the same:

 

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Header>
    <Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <SignatureConfirmation xmlns="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" Value="abc=="/>
      ...

<soap:Envelope 
   xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
   xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
   xmlns:wsse1.1="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">
  <soap:Header>
    <wsse:Security>
      <wsse1.1:SignatureConfirmation Value="abc=="/>
      ...

 

The former uses only default namespaces for each element. The latter uses explicitly defined prefixes. They are the same, from an XML infoset point of view.

View solution in original post

I built an example for rotating keys, some time ago.  Find the relevant community post here.  The post talks about rotating public keys (not certificates) , and in the context of JWKS, which would be used for validating JWT. But the tool I built for that example , generates public keys and uploads them into KVM, and can help "rotate" keys.  You could take that as a starting point for rotating certificates. Obtaining the cert is not covered by the tool, but you could insert your own mechanism for that - either generating a self-signed cert, or retrieving a cert from a trusted third-party CA. 

That key rotation tool is included in the repo, link provided in the post I referenced. There's also an accompany screencast linked in that post - not sure  that will be applicable because it talks about JWKS and JWT, but you might find it interesting. 

View solution in original post

8 REPLIES 8

Hi @dchiesa1 ,

Could you please help?

 

Hi Rajesh

What specifically are you attempting to do?  The WS-Security signature callout you are pointing to, is somewhat limited in that it is able to sign:

  • the soap:Body
  • the wssec:Security/wsu:Timestamp
  • or both

But today, not "other arbitrary elements", including the SignatureConfirmation elements. 

Do you simply want  the callout to also be able to sign the SignatureConfirmation elements? That would not be a difficult enhancement for me to make.  But that would mean that you (or your API proxy) would have to insure that the appropriate SignatureConfirmation elements were present in the unsigned response, before invoking the callout. 

OR, do you want the callout to also generate the SignatureConfirmation elements, inject them into the unsigned response message, and THEN sign the various elements?  To do this, your apiproxy would need to be able to provide the original signature values to be confirmed.  (and there may be more than one). 

Please advise in more detail what you want to accomplish.

EDIT: I modified the callout to add a new configuration property "confirmations".  re-pull the latest version, and Check the README.  In short, if you add that  property, and specify a comma-separated set of values, the callout will inject SignatureConfirmation elements into your SOAP document with those values; if you specify the special value "*all*", the callout will sign all existing SignatureConfigurations that are present in the document.  Try it and see if it does what you want. 

 

Thanks @dchiesa1 ,

I want the callout to also be able to sign the SignatureConfirmation elements based on the property value injected . 

I am able to generate the SignatureConfirmation sign with the latest update however we expect <wsse11:SignatureConfirmation> but getting <wsse1.1:SignatureConfirmation>  from Java callout policy. Please advise?

Expected Format-

<wsse11:SignatureConfirmation Value="eih54SXZJjCh0tDtg==" wsu:Id="SigConf-133" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" />

Java Callout Output:

<wssec1.1:SignatureConfirmation Value="eih54SXZJjCh0tDtg==" wsu:Id="Conf-102"/>

 

 

OK great, I'm glad you were able to try the callout.

Regarding your concerns, I think you should not be bothered by any of the differences you described. I'll explain why.

First, you are saying that you expect the element to be wsse11:SignatureConfirmation but are getting wsse1.1:SignatureConfirmation. The thing before the colon in an XML element name is known as the "prefix". This is just a way to qualify elements in an XML document with a "namespace". The namespace - often a long URL, but in general it is a URN (any string) - is the semantically important thing. The prefix can be anything. In other words, the following two are exactly equivalent.

 

<foo:ElementName xmlns:foo="http://a.b.com/something"/>

<a:ElementName xmlns:a="http://a.b.com/something"/>

 

Any compliant XML processor will process those elements as being equivalent. It would be an error for an XML processing application to check the string values of the prefixes. It is required that the XML processor check the string values of the namespaces that the prefixes refer to. Therefore the difference you observe between wsse11 and wsse1.1 is immaterial.

Another thing you should be aware of - prefixes that are defined in a parent node of an element, will be effective for that element. Therefore, the following two are equivalent:

 

<s:Envelope 
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <wsse1.1:SignatureConfirmation 
       xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
       xmlns:wsse1.1="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" 
       Value="abc" wsu:Id="conf-101"/>
    ... 

<s:Envelope 
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
    xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    xmlns:wsse1.1="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">
  <s:Header>
    <wsse:Security>
      <wsse1.1:SignatureConfirmation Value="abc" wsu:Id="conf-101"/>
    ... 

 

You can see that the prefixes wsse1.1 and wsu are defined in the toplevel element, but are used only in the SignatureConfirmation element. That is no problem. Correct XML processors will treat them as the same.

You may also wonder about the value inside the quotes for the wsu:Id attribute . They are different from your "expected" and "actual observed" outputs. Here again, that won't matter. That ID is relative to the document itself. It merely provides a way for a Signature to refer to that signed element. So it does not matter if your example is "SigConfi-100" and the callout generates "Conf-103". That won't make a difference to the signature validator.

In summary, the observed output is exactly equivalent to what you describe as your "expected" output.

One more thing I will mention .... regarding "default" namespaces. This isn't important for the question you asked here, but you may come across this in the future, so I thought I'd explain it here. As I described above, you can use a prefix to "qualify" an XML element within a particular namespace. Therefore the following two are NOT equivalent, from an XML Infoset perspective:

 

<p1:address xmlns:p1="http://example.com/schemas">123 Main Street</p1:address>

<p1:address xmlns:p1="urn:abcdefg">123 Main Street</p1:address>

 

The reason is, the p1 prefix refers to two different namespaces. the address element in the namespace "http://example.com/schemas" is not the same , from an XML point of view, as the address element in the namespace "urn:abcdefg".

Beyond namespaces that are explicitly (if indirectly) referenced via a prefix, any element in an XML document has a "default" namespace. The following two ARE equivalent:

 

<address xmlns="http://example.com/schemas">123 Main Street</address>

<p1:address xmlns:p1="http://example.com/schemas">123 Main Street</p1:address>

 

In the first example, "http://example.com/schemas" is the default namespace for the element - it is the namespace the element, as well as any unqualified children of the element, gets. In the second example, the same namespace is present, but it has an explicitly declared prefix. Any correct XML processor will treat those two as exactly the same.

Maybe a more relevant example , these two are also the same:

 

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Header>
    <Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <SignatureConfirmation xmlns="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" Value="abc=="/>
      ...

<soap:Envelope 
   xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
   xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
   xmlns:wsse1.1="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">
  <soap:Header>
    <wsse:Security>
      <wsse1.1:SignatureConfirmation Value="abc=="/>
      ...

 

The former uses only default namespaces for each element. The latter uses explicitly defined prefixes. They are the same, from an XML infoset point of view.

Thanks @dchiesa1 ,

Could you please advise, how should we rotate the certs in KVM?

 

I built an example for rotating keys, some time ago.  Find the relevant community post here.  The post talks about rotating public keys (not certificates) , and in the context of JWKS, which would be used for validating JWT. But the tool I built for that example , generates public keys and uploads them into KVM, and can help "rotate" keys.  You could take that as a starting point for rotating certificates. Obtaining the cert is not covered by the tool, but you could insert your own mechanism for that - either generating a self-signed cert, or retrieving a cert from a trusted third-party CA. 

That key rotation tool is included in the repo, link provided in the post I referenced. There's also an accompany screencast linked in that post - not sure  that will be applicable because it talks about JWKS and JWT, but you might find it interesting. 

 

Dear @dchiesa1 ,

We are facing an issue wherein getting below error when consumer sends x509IssuerName DN in below order

C=US,ST=xxx,L=xxx,O=xxx,CN=xxx

Error Message-

X509SerialNumber mismatch cert(CN=xxx,O=xxx,L= xxx,ST=xxx,C=US) doc(C=US,ST=xxx,L=xxx,O=xxx,CN=xxx)

Ideally RDN order shouldn't matter, could you please ?

Actually order *does* matter, per RFC 5280. A Distinguished Name (DN) is composed of an ordered sequence of relative distinguished names (RDNs), separated by commas. Per RFC 5280 section 7.1:

   Two distinguished names DN1 and DN2 match if they
   have the same number of RDNs, for each RDN in DN1 there is a matching
   RDN in DN2, and the matching RDNs appear in the same order in both
   DNs. 

When serializing the sequence of RDNs to a string, some systems and apps traverse the sequence from top to bottom, and some traverse from bottom to top. The Callout, when examining the certificate, sequences them from top to bottom. The system that produced your signed document, sequences them from bottom to top. The callout was simply doing a string comparison on the serialized DN. This is naive, and won't work when the sequence of RDNs is reversed.

To allow greater interoperability, I've updated the callout to allow for comparing the RDNs in the Issuer DN in reverse order, and also in unordered fashion. Get the latest version (20230721). Use the issuer-name-dn-comparison property. Set it to "reverse" in your policy config. That should work.