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:
> crypto:hmac($message as xs:string, 
Hence your $body will be converted like so: 
> string(
>   <data>
>     <foo>Hello</foo>
>     <bar>World</bar>
>   </data>
> )


Turning it into: 
> „HelloWorld“


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


Treat your document as binary:
> %rest:consumes("application/octet-stream“)
And then decode that binary to a string and then compute the hash for the 
string, using: bin:decode-string#2:

>   let $str-doc  := bin:decode-string($body,'utf-8') (: xs:string :)
>   let $sig-cand := crypto:hmac($str-doc,$secret,'sha1','base64')


Hope this helps :-)

Michael

> Am 03.06.2019 um 12:17 schrieb Jerome Chauveau <jerome.chauv...@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";
> 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

Reply via email to