[xmlsec] Fw: SignedXML

Aleksey Sanin aleksey at aleksey.com
Tue Mar 21 09:18:26 PDT 2017


The ruble sign doesn't look like a UTF8 character but rather like
a Windows unicode one. You might want to check this since it's
important for C14N and follow up digest.

Aleksey

On 3/21/17 8:07 AM, Грибанов Петр Борисович wrote:
> Dear sirs,
> 
> Looks like we need your help.
> 
> I write you on behalf of 1C company, one of the biggest ERP software
> vendors in Eastern Europe.
> 
> We use your library XMLSec (BTW, thank you very much for this great
> lib!) to verify Signed XML in our applications.
> One of the areas we use XMLSec in is verifying SignedXML produced by
> Windows Store (Windows Store produce In-app purchase receipts in this
> format).
> XMLSec works just fine in all cases except receipts in Russian Roubles.
> 
> It works perfectly for USD, Euros, Saudi riyals etc.
> 
> My guess is that problem is that russina Rouble has kinda strange sign
> *₽ *that cannot be processed correctly for some reason by XMLSec library
> (but it is only guess!).
> 
> May be there is something wrong in our code (code goes below).
> 
> *receiptStr* is receipt loaded from file (receipt*.xml in attachment).
> 
> *responseStr* is a key we downloaded from MS service (key.txt in
> attachment).
> 
> The issue is that for receipt if Russian Rouble*dsigCtx->status* is
> always not equal to *xmlSecDSigStatusSucceeded* although receipt is
> perfectly fine.
> For all other currencies we tested it works fine.
> Please see  XML receipts in different currencies attached.
> 
> See string PurchasePrice="₽0" in receipt_ruble.xml file; may be Rouble
> sign  *₽ *is the cause of the issue?
> 
> Would appreciate any idea on what may be wrong.
> Please let me know if we can provide more info.
> 
>  ----------------------------------------------
> 
>     std::string xmltext = narrow(*receiptStr*, Converter::utf8());
>     std::string keytext = narrow(*responseStr*, Converter::utf8());
> 
>     xmlDocPtr doc = NULL;
>     xmlNodePtr node = NULL;
>     xmlSecDSigCtxPtr dsigCtx = NULL;
> 
>     /* load file */
>     doc = xmlParseMemory(xmltext.c_str(), xmltext.size());
> 
>     if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){
>         throw "Error: unable to parse file \"%s\"\n";
>     }
> 
>     /* find start node */
>     node = xmlSecFindNode(xmlDocGetRootElement(doc),
> xmlSecNodeSignature, xmlSecDSigNs);
>     if(node == NULL) {
>         throw "Error: start node not found in \"%s\"\n";
>     }
> 
>     /* create signature context, we don't need keys manager in this
> example */
>     dsigCtx = xmlSecDSigCtxCreate(0);
>     if(dsigCtx == NULL) {
>         throw "Error: failed to create signature context\n";
>     }
> 
>     /* in addition, limit possible key data to valid X509 certificates
> only */
>     if(xmlSecPtrListAdd(&(dsigCtx->keyInfoReadCtx.enabledKeyData),
> BAD_CAST xmlSecKeyDataX509Id) < 0) {
>         throw "Error: failed to limit allowed key data\n";
>     }
> 
>     /* load public key */
> 
>     dsigCtx->signKey = xmlSecCryptoAppKeyLoadMemory((const xmlSecByte
> *)keytext.c_str(), keytext.size(), xmlSecKeyDataFormatCertPem,0,0,0);
>     if(dsigCtx->signKey == NULL) {
>         throw "Error: failed to load public pem key from \"%s\"\n";
>     }
> 
>     /* Verify signature */
>     if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
>         throw "Error: signature verify\n";
>     }
> 
>     bool result = dsigCtx->status == xmlSecDSigStatusSucceeded;
>  
> 
> ----------------------------------------------
> 
> Best regards,
> 
> Peter Gribanov
> 
> 1C LLC
> 
> Tel.: +7 (495) 258-44-08, 688-89-29
> Mobile: +7 (903) 180-69-86
> Skype: peter.gribanov
> 


More information about the xmlsec mailing list