WS Security for Apigee - X509SerialNumber mismatch

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 help to close this issue.

Please note - consumer and APIGEE both are using the same certificate.

Solved Solved
0 6 218
2 ACCEPTED SOLUTIONS

Looking at your  certificate, the subject and issuer are the same , which means it is a self-signed certificate. Therefore the bug in the prior version of the callout, which checked the IssuerName in the document against the SUBJECT of the cert, rather than the ISSUER, ...would not have affected you. 

Looking at the signed document, I see that the order of the RDNs in the IssuerName is the exact reverse of the order of RDNs in the cert. This is what you originally reported, I just didn't quite realize it yesterday.  

I've modified the callout so that you can request a "reversed" comparison of RDNs. Get the 20230721 version of the callout, on the main branch.  Configure the properties like this: 

<JavaCallout name='Java-WSSEC-Validate'>
  <Properties>
    <Property name='source'>message.content</Property>
    <Property name='max-lifetime'>10m</Property>
    <Property name="certificate">{myCertificate}</Property>
    <Property name="issuer-name-style">dn</Property>
    <!-- use this new property -->
    <Property name="issuer-name-dn-comparison">reverse</Property>
    <Property name="required-signed-elements">wsu:Timestamp, soap:Body</Property>
  </Properties>
  <ClassName>com.google.apigee.callouts.wssecdsig.Validate</ClassName>
  <ResourceURL>java://apigee-wssecdsig-20230721.jar</ResourceURL>
</JavaCallout>

View solution in original post

it worked for you?

View solution in original post

6 REPLIES 6

Hi,

I understand the issue you are describing.

First, the error condition is correct, but the error message is incorrect. It mentions X509SerialNumber, but that should be X509IssuerName. But this is a relatively minor thing. I have corrected this error message in the 20230720 version of the callout.

Second, according to RFC 5230 section7.1,

Two naming attributes match if the attribute types are the same and the values of the attributes are an exact match after processing with the string preparation algorithm. Two relative distinguished names RDN1 and RDN2 match if they have the same number of naming attributes and for each naming attribute in RDN1 there is a matching naming attribute in RDN2. 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. ..

The current callout follows this directive - it allows the match of DNs only when the order of RDNs is the same. I believe this is correct behavior.

There are platform-embedded libraries that produce a stringified version of a DN, and they respect the order of the sequence in the certificate. If the client in this case is using a platform-based library, then the string form that the client embeds into the signed document (which in your case looks like C=US,ST=xxx,L=xxx,O=xxx,CN=xxx), reflects the actual order of the sequence of RDNs in the signing certificate. The DN of the certificate you supplied (which in your case looks like CN=xxx,O=xxx,L= xxx,ST=xxx,C=US), is created by the Java platform library, which we can presume is correct. These strings are different, therefore the sequence order is different, therefore we should conclude that the certificates are different. The cert identified in the signed document is not the same cert you are supplying in your policy configuration. They're different and the error message is telling you that.

To sort this out, you can use the openssl tool to examine what IT THINKS is the DN for the cert you are specifying in the Validation config, as well as the cert specified by the client during its signing process. I would expect that openssl will give you different DN strings. If you just do a file comparison of the PEM files, you should see a difference as well.

How can you avoid this?

The check that is failing for you, happens when the inbound document identifies the signing certificate via a KeyInfo element that looks like this:

 

 <KeyInfo>
   <wsse:SecurityTokenReference wsu:Id="STR-2795B41DA34FD80A771574109162615125">
     <X509Data>
       <X509IssuerSerial>
         <X509IssuerName>C=US,ST=xxx,L=xxx,O=xxx,CN=xxx</X509IssuerName>
         <X509SerialNumber>1323432320</X509SerialNumber>
       </X509IssuerSerial>
     </X509Data>
   </wsse:SecurityTokenReference>
 </KeyInfo>

 

One way to avoid this is for the caller (the client) to encode the cert differently into the signed document. I don't know if that is possible for you.

Another way to avoid this is to obtain the exact certificate that the client used during signing., and use that in the configuration for the Validation policy.

A possibility, which I consider to be unlikely, is that there is a bug in the client code that performs the signing, and it is creating the DN string in a  manner that does not respect the sequence order, for some reason. If this is the case, then I could introduce a flag to relax the requirement on the ordering of RDNs . This feels wrong to me, but I understand when getting systems to interoperate, it may be necessary.

Can you check the new branch I've produced, "check-issuer-name" ? available here.

There are some changes in this callout.

  1. The check for the issuer name was incorrect in the prior versions. It actually checked the SUBJECT of the cert, and not the issuer. This is wrong. This new branch checks the issuer name. It's possible that simply dropping in the updated JAR and may fix your problem.
  2. If that does not correct the problem, then there is a new configuration property in that build, issuer-name-unordered-comparison-of-rdns , which takes a true/false value, default false. If true, it tells the callout to compare the issuer RDNs in an unordered fashion.

Dear @dchiesa1 ,

Thanks, I will check and update you.

Looking at your  certificate, the subject and issuer are the same , which means it is a self-signed certificate. Therefore the bug in the prior version of the callout, which checked the IssuerName in the document against the SUBJECT of the cert, rather than the ISSUER, ...would not have affected you. 

Looking at the signed document, I see that the order of the RDNs in the IssuerName is the exact reverse of the order of RDNs in the cert. This is what you originally reported, I just didn't quite realize it yesterday.  

I've modified the callout so that you can request a "reversed" comparison of RDNs. Get the 20230721 version of the callout, on the main branch.  Configure the properties like this: 

<JavaCallout name='Java-WSSEC-Validate'>
  <Properties>
    <Property name='source'>message.content</Property>
    <Property name='max-lifetime'>10m</Property>
    <Property name="certificate">{myCertificate}</Property>
    <Property name="issuer-name-style">dn</Property>
    <!-- use this new property -->
    <Property name="issuer-name-dn-comparison">reverse</Property>
    <Property name="required-signed-elements">wsu:Timestamp, soap:Body</Property>
  </Properties>
  <ClassName>com.google.apigee.callouts.wssecdsig.Validate</ClassName>
  <ResourceURL>java://apigee-wssecdsig-20230721.jar</ResourceURL>
</JavaCallout>

it worked for you?

Yes, it's working as expected.  Thanks