Tuesday 21 May 2013

SAML Authentication on F5 Big-IP (Part 2)

I knew this question was too hard for F5 support team,  so in my first email I said

If it is not a known issue on VE BIGIP-11.3.0.2806.0, can you please ask your technical team to have a look?

I also knew there was no fast track for me to the right person in F5, the only thing I could do was WAIT and PROVIDE any data which they thought was necessary.

In the beginning, they doubted that the idp certificate registered on F5 Big-IP (by importing IDP metadata) was not right. I told them the SAML response contained a X509 certificate which was enough to verify the signature, but I agreed to check the idp certificate, actually it was identical to the X509 certificate.

Finally I got the feedback from their Engineering Service 47 days later. Typical bureaucratic in any big company I am afraid.

The feedback says,

------
Product Development has provided the way SAML Digest value is calculated by APM;
- if reference URI in the signature element matches the Response ID, then digest is calculated for the entire SAML response (signature must be within response),
- if reference URI matches Assertion ID, digest is calculated for the Assertion element only (signature must be within assertion),
- entire signature element is removed from response/assertion,
- resulting XML is canonicalized,
- SHA1 digest is calculated for the canonicalized XML,
- the Digest value from signature element is base64 decoded and compared to calculated digest.

In your case,the "reference URI" in signature element matches the Response ID "_ec3a47ec7dd9e6836d3458bec3124c61b49d89fd", so the digest is calculated for the entire SAML response.
------
Note: the data with Response ID _ec3a47ec7dd9e6836d3458bec3124c61b49d89fd was collected on 2013-04-17. It is different from the one I am going to test.

Sounds like they are not yet convinced by my research described in Part 1. They may also question me back - how can I myself prove that my research in Part 1 did the verification on Reference(s)?

The SAML module on F5 Big-IP was developed with C (or C++,  I believe), so this time I am going to use Apache Santuario C++ distribution.

I downloaded  Apache XML Security for C++ 1.7.0 source code onto Ubuntu 12.04, then followed its installation instruction, untar, configure, make, make install etc.

The package has a tool called "checksig", After building the package, we can make use of the tool straight away.

mike@ubuntu:/opt/bin$ ./checksig ~/saml02.xml
Signature verified OK!

Again, no complaint for digest value mismatch.
Now let check its source code. In checksig.cpp, around line 503, it has

if (skipRefs)
result = sig->verifySignatureOnly();
else
result = sig->verify();

Note I didn't add the option --skiprefs, which implied it verified the References as well.

Now, let us check sig->verify(), the source code is in DSIGSignature.cpp, line 1151

// First thing to do is check the references
referenceCheckResult = mp_signedInfo ->verify(m_errStr);

Let us step into this function DSIGSignedInfo::verify, we get the function SIGReference::verifyReferenceList in DSIGReference.cpp. On line 920, we have

if (!r->checkHash()) {

Step into once more, we get DSIGReference::checkHash() .
Now let us debug it with gdb, set a breakpoint on this function

(gdb) break DSIGReference::checkHash

Then run it, the program break at this point. go 3 steps with n3. Now let check the values in buffer calculatedHashVal and readHashVal.

(gdb) x/20bx calculatedHashVal
0xbfffc39c:     0xc0    0x35    0xd4    0xef    0x92    0x98    0xe3    0xfc
0xbfffc3a4:     0xbb    0x27    0xbd    0x5c    0x9d    0xa2    0xeb    0xfd
0xbfffc3ac:     0xb1    0x7d    0xa0    0x30
(gdb) x/20bx readHashVal
0xbfffc41c:     0xc0    0x35    0xd4    0xef    0x92    0x98    0xe3    0xfc
0xbfffc424:     0xbb    0x27    0xbd    0x5c    0x9d    0xa2    0xeb    0xfd
0xbfffc42c:     0xb1    0x7d    0xa0    0x30

They are identical! OK, now let's check the DigestValue

wDXU75KY4/y7J71cnaLr/bF9oDA=

After doing Base64 decode, we have 

c0 35 d4 ef 92 98 e3 fc bb 27 bd 5c 9d a2 eb fd b1 7d a0 30

Still have a question? I know you may want to know the actual XML content where the hash is calculated on. OK, no problem. The hash is done in TXFMSHA1.cpp, line 131,

while ((size = input->readBytes((XMLByte *) buffer, 1024)) != 0) {
#if 0
// Some useful debbugging code
FILE * f = fopen("debug.out","a+b");
fwrite(buffer, size, 1, f);
fclose(f);
#endif
mp_h->hash(buffer, size);
}

We can dump the buffer to a file (I did it by gdb append command). You can see the content in hashon.xml. This is the canonicalized XML.

Now I wonder if F5 Big-IP has the same handling on XML signature.













No comments: