Hi Michael, It seems to work ... perfectly ! Thank you so much for that clear and quick answer :-) Jérôme De: "Michael Seiferle" <ms@basex.org> À: "jerome chauveau" <jerome.chauveau@unicaen.fr> Cc: "basex-talk" <basex-talk@mailman.uni-konstanz.de> Envoyé: Lundi 3 Juin 2019 16:39:07 Objet: Re: [basex-talk] XML in HTTP request body Hi Jerome, If I understand correctly, you want to create a hash value for the string serialization of the document you sent to restxq right? Currently inside RESTXQ your document is treated as an XML Document, hence: $body will be of type document-node(): <data> <foo>Hello</foo> <bar>World</bar> </data> where as crypto:hmac requires a string-type $message: BQ_BEGIN crypto:hmac ($message as xs:string, BQ_END Hence your $body will be converted like so: BQ_BEGIN string( <data> <foo>Hello</foo> <bar>World</bar> </data> ) BQ_END Turning it into: BQ_BEGIN „HelloWorld“ BQ_END In order to actually compute a hash on the bytes your document contains, do as follows: Working example here: [ https://git.basex.io/snippets/63 | https://git.basex.io/snippets/63 ] Treat your document as binary: BQ_BEGIN %rest:consumes("application/octet-stream“) BQ_END And then decode that binary to a string and then compute the hash for the string, using: bin:decode-string#2: BQ_BEGIN let $str-doc := bin:decode-string($body,'utf-8') (: xs:string :) let $sig-cand := crypto:hmac($str-doc,$secret,'sha1','base64') BQ_END Hope this helps :-) Michael BQ_BEGIN Am 03.06.2019 um 12:17 schrieb Jerome Chauveau < [ mailto:jerome.chauveau@unicaen.fr | jerome.chauveau@unicaen.fr ] >: Hi, I am trying to check XML content (HTTP posted) with an hmac function in a RESTXQ webapp. My Java client sends an HTTP post request where XML data looks like : <data><user>doe</user><content><TEI xsi:schemaLocation=" [ http://www.tei-c.org/ns/1.0 | http://www.tei-c.org/ns/1.0 ] " xml:id="idtest"
<teiHeader <fileDesc <titleStmt <title Test</title <author xml:id="authortest" XXX</author </titleStmt </teiHeader <text <front </front <body xml:space="preserve" <listPlace <place type="lieu" <placeName xml:lang="la" Burgunvilla</placeName </place </listPlace </body </text </TEI </content></data>
This content is HMAC encrypted and the signature is added to the HTTP header : [...] String secret = "1234"; StringEntity entity = new StringEntity(xml, ContentType.create("text/xml", Consts.UTF_8)); String signature = HTTPUtils.hmacSHA1(xml, secret); httppost.setHeader("Authorization", signature); httppost.setEntity(entity); [...] Here is my RESTXQ function : declare %rest:POST("{$body}") %rest:consumes("application/xml", "text/xml") %rest:header-param("Authorization", "{$signature}", "none") %rest:path("/sf/testpost") function sf.test:testPost($signature,$body){ let $secret := 1234 crypto:hmac($body,$secret,'sha1','base64') = $signature } Equality check always fails with such an XML sequence but works fine when XML does not contain any carriage return : <data><user>doe</user><content><TEI><front></front><text><body>This is a test</body></text></TEI> It seems to come when "The body of a POST or PUT request is converted to an XQuery item". I tried to set serializer's options without any success ! How could I retrieve xml (in $body) exactly serialized as sent by the client ? Tests are running on BaseX922. Thank you for your time. Jérôme BQ_END