[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