2006/08/31
EC2 SOAP + XMLSig + WSSE + X509 = Frustration
I'm exploring the EC2 SOAP API. Why ? I never really developed a client for a SOAP API, and this was a good occasion, and the interesting constraint is that it's not just a SOAP API, but a SOAP API complying with the WS-Security standard, where the messages are signed - in the EC2 case, it's with X.509 certificate with a public key.
A bit like what I did for S3 with my small Mac OS S3 Utility, I wanted to code a small OS X 'EC2 Console'. First problem: OS X SOAP support is not really exhaustive (although WebServices Core is a good start), but I need more: XML Signature, WSSE and BinarySecurityToken. SOAP support, for the subset I need for the EC2 API is not that hard and can be generated by hand easily. Signature is another matter: you have to canonicalize subset of the document, compute a digest on the canonical form, embed this in the signature part of the document (and actually do that twice, one for the actual SOAP body representing the request and another time for the timestamp), and then canonicalize and sign this signature section.
The first issue was canonicalization, NSXMLNode has a method and OpenSSL provides functions for sha1 digests and base64 encoding. The problem was the NSXMLNode method: it seems to be intended for canonicalization of entire documents, canonicalization of a subset does not correctly reintegrate XML namespaces defined on a parent tag. So the digest was not the same than my reference (a trace from the Amazon EC2 java tool). It took me a few hours to finally catch what was happening but, well. Simple fix: force namespace in the subset before computing de digest. Ugly, but works
The second issue is still open: my signature code generates something that's different from my 'reference' message (which might be explained by slight whitespace differences in the XML subset), and indeed, EC2 refuses my SOAP request with a authentication error. So either I'm missing something else in the canonicalization or I'm not using correctly OpenSSL to generate my rsa/sha1 signature, or the XML Signature expects something slightly different from what I get with my naive openssl use (load the private key pem file with PEM_read_bio_RSAPrivateKey then use RSA_private_encrypt(inlen, input, output, key, RSA_PKCS1_PADDING).
So I'm left with either: trying other openssl functions and options (RSA_sign maybe ? but it seems to be intended for PKCS #1 v2.0, and not PKCS #1 v1.5), learning how to use the xmlsec library and attempt a message generation with it, or look at the xmlsec or Axis sources to try to find if there's any subtlety with the rsa-sha1 signing process. Sigh
<< Home