robrichards/xmlseclibs

Problem with namespaces in canonicalization

Opened this issue · 11 comments

I'm trying to sign an XML withe de first lines like this

<?xml version="1.0" encoding="UTF-8" standalone="no"?> <Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:sts="dian:gov:co:facturaelectronica:Structures-2-1" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" xmlns:xades141="http://uri.etsi.org/01903/v1.4.1#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 http://docs.oasis-open.org/ubl/os-UBL-2.1/xsd/maindoc/UBL-Invoice-2.1.xsd">

When try to sign this I have the following warnings when the sytem try to use DOMNode::C14N to canonicalize and the result is wrong:
DOMNode::C14N(): Relative namespace UR is invalid here : dian DOMNode::C14N(): Internal error : checking for relative namespaces DOMNode::C14N(): Internal error : processing docs children list

How can I fix them?

Thanks for the response.
The problem is issued when try to canonicalize de XML before the sign:

$objDSig = new XMLSecurityDSig(); $objDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N);

And the warning and failure is reported in line 296 of the script robrichards/xmlseclibs/src/XMLSecurityDSig.php:

return $node->C14N($exclusive, $withComments, $arXPath, $prefixList);

All seems to be good but always throw the error:
DOMNode::C14N(): Relative namespace UR is invalid here : dian DOMNode::C14N() Internal error : checking for relative namespaces DOMNode::C14N() Internal error : processing docs children list, except if the line
xmlns:sts="dian:gov:co:facturaelectronica:Structures-2-1" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" xmlns:xades141="http://uri.etsi.org/01903/v1.4.1#"
Is removed, but i cannot do this because this NS is essential part of my XML

I would need to see the full document and code being used to know what you are trying to sign and what's being passed in.

Thanks, the XML document to be signed looks like:
<Invoice xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sts="dian:gov:co:facturaelectronica:Structures-2-1" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" xmlns:xades141="http://uri.etsi.org/01903/v1.4.1#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xsi:schemaLocation="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 http://docs.oasis-open.org/ubl/os-UBL-2.1/xsd/maindoc/UBL-Invoice-2.1.xsd" xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"> <ext:UBLExtensions> <ext:UBLExtension> <ext:ExtensionContent> <sts:DianExtensions> <sts:InvoiceControl> <sts:InvoiceAuthorization></sts:InvoiceAuthorization> <sts:AuthorizationPeriod> <cbc:StartDate></cbc:StartDate> <cbc:EndDate></cbc:EndDate> </sts:AuthorizationPeriod> <sts:AuthorizedInvoices> <sts:Prefix></sts:Prefix> <sts:From></sts:From> <sts:To></sts:To> </sts:AuthorizedInvoices> </sts:InvoiceControl> <sts:InvoiceSource> <cbc:IdentificationCode listAgencyID="6" listAgencyName="United Nations Economic Commission for Europe" listSchemeURI="urn:oasis:names:specification:ubl:codelist:gc:CountryIdentificationCode-2.0">CO</cbc:IdentificationCode> </sts:InvoiceSource> <sts:SoftwareProvider> <sts:ProviderID schemeAgencyID="195" schemeAgencyName="CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)" schemeID="4" schemeName="31"></sts:ProviderID> <sts:SoftwareID schemeAgencyID="195" schemeAgencyName="CO, DIAN (Direccion de Impuestos y Aduanas Nacionales)"></sts:SoftwareID> </sts:SoftwareProvider> <sts:SoftwareSecurityCode schemeAgencyID="195" schemeAgencyName="CO, DIAN (Direccion de Impuestos y Aduanas Nacionales)"></sts:SoftwareSecurityCode> <sts:AuthorizationProvider> <sts:AuthorizationProviderID schemeAgencyID="195" schemeAgencyName="CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)" schemeID="4" schemeName="31">800197268</sts:AuthorizationProviderID> </sts:AuthorizationProvider> <sts:QRCode></sts:QRCode> </sts:DianExtensions> </ext:ExtensionContent> </ext:UBLExtension> </ext:UBLExtensions> <cbc:UBLVersionID>UBL 2.1</cbc:UBLVersionID> <cbc:CustomizationID>05</cbc:CustomizationID> <cbc:ProfileID>DIAN 2.1</cbc:ProfileID> <cbc:ProfileExecutionID>2</cbc:ProfileExecutionID> <cbc:ID></cbc:ID> <cbc:UUID schemeID="2" schemeName="CUFE-SHA384"></cbc:UUID> <cbc:IssueDate></cbc:IssueDate> <cbc:IssueTime></cbc:IssueTime> <cbc:InvoiceTypeCode></cbc:InvoiceTypeCode> <cbc:DocumentCurrencyCode listAgencyID="6" listAgencyName="United Nations Economic Commission for Europe" listID="ISO 4217 Alpha">COP</cbc:DocumentCurrencyCode> <cbc:LineCountNumeric></cbc:LineCountNumeric> <cac:InvoicePeriod> <cbc:DurationMeasure unitCode="DAY"></cbc:DurationMeasure> </cac:InvoicePeriod> <cac:AccountingSupplierParty> <cbc:AdditionalAccountID>1</cbc:AdditionalAccountID> <cac:Party> <cac:PartyIdentification> <cbc:ID schemeAgencyID="195" schemeAgencyName="CO, DIAN (Direccion de Impuestos y Aduanas Nacionales)" schemeID="31"></cbc:ID> </cac:PartyIdentification> <cac:PartyName> <cbc:Name></cbc:Name> </cac:PartyName> <cac:PhysicalLocation> <cac:Address> <cbc:ID></cbc:ID> <cbc:CityName></cbc:CityName> <cbc:PostalZone></cbc:PostalZone> <cbc:CountrySubentity></cbc:CountrySubentity> <cbc:CountrySubentityCode></cbc:CountrySubentityCode> <cac:AddressLine> <cbc:Line></cbc:Line> </cac:AddressLine> <cac:Country> <cbc:IdentificationCode >CO</cbc:IdentificationCode> <cbc:Name languageID="es">Colombia</cbc:Name> </cac:Country> </cac:Address> </cac:PhysicalLocation> <cac:PartyTaxScheme> <cbc:RegistrationName></cbc:RegistrationName> <cbc:CompanyID schemeAgencyID="195" schemeAgencyName="CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)" schemeID="" schemeName="31"></cbc:CompanyID> <cbc:TaxLevelCode></cbc:TaxLevelCode> <cac:RegistrationAddress> <cbc:ID></cbc:ID> <cbc:CityName></cbc:CityName> <cbc:PostalZone></cbc:PostalZone> <cbc:CountrySubentity></cbc:CountrySubentity> <cbc:CountrySubentityCode></cbc:CountrySubentityCode> <cac:AddressLine> <cbc:Line></cbc:Line> </cac:AddressLine> <cac:Country> <cbc:IdentificationCode >CO</cbc:IdentificationCode> <cbc:Name languageID="es">Colombia</cbc:Name> </cac:Country> </cac:RegistrationAddress> <cac:TaxScheme> <cbc:ID></cbc:ID> <cbc:Name></cbc:Name> </cac:TaxScheme> </cac:PartyTaxScheme> <cac:PartyLegalEntity> <cbc:RegistrationName></cbc:RegistrationName> <cbc:CompanyID schemeAgencyID="195" schemeAgencyName="CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)" schemeName="31" schemeId=""></cbc:CompanyID> </cac:PartyLegalEntity> </cac:Party> </cac:AccountingSupplierParty> <cac:AccountingCustomerParty> <cbc:AdditionalAccountID></cbc:AdditionalAccountID> <cac:Party> <cac:PartyIdentification> <cbc:ID schemeAgencyID="195" schemeAgencyName="CO, DIAN (Direccion de Impuestos y Aduanas Nacionales)" schemeID="31"></cbc:ID> </cac:PartyIdentification> <cac:PartyName> <cbc:Name></cbc:Name> </cac:PartyName> <cac:PhysicalLocation> <cac:Address> <cbc:ID></cbc:ID> <cbc:CityName></cbc:CityName> <cbc:PostalZone></cbc:PostalZone> <cbc:CountrySubentity></cbc:CountrySubentity> <cbc:CountrySubentityCode></cbc:CountrySubentityCode> <cac:AddressLine> <cbc:Line></cbc:Line> </cac:AddressLine> <cac:Country> <cbc:IdentificationCode >CO</cbc:IdentificationCode> <cbc:Name languageID="es">Colombia</cbc:Name> </cac:Country> </cac:Address> </cac:PhysicalLocation> <cac:PartyTaxScheme> <cbc:RegistrationName></cbc:RegistrationName> <cbc:CompanyID schemeAgencyID="195" schemeAgencyName="CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)" schemeID="" schemeName="31"></cbc:CompanyID> <cbc:TaxLevelCode></cbc:TaxLevelCode> <cac:RegistrationAddress> <cbc:ID></cbc:ID> <cbc:CityName></cbc:CityName> <cbc:CountrySubentity></cbc:CountrySubentity> <cbc:CountrySubentityCode></cbc:CountrySubentityCode> <cac:AddressLine> <cbc:Line></cbc:Line> </cac:AddressLine> <cac:Country> <cbc:IdentificationCode>CO</cbc:IdentificationCode> <cbc:Name languageID="es">Colombia</cbc:Name> </cac:Country> </cac:RegistrationAddress> <cac:TaxScheme> <cbc:ID></cbc:ID> <cbc:Name></cbc:Name> </cac:TaxScheme> </cac:PartyTaxScheme> <cac:PartyLegalEntity> <cbc:RegistrationName></cbc:RegistrationName> <cbc:CompanyID schemeAgencyID="195" schemeAgencyName="CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)" schemeName="31" schemeId=""></cbc:CompanyID> </cac:PartyLegalEntity> </cac:Party> </cac:AccountingCustomerParty> <fe:LegalMonetaryTotal> <cbc:LineExtensionAmount currencyID="COP">0.00</cbc:LineExtensionAmount> <cbc:TaxExclusiveAmount currencyID="COP">0.00</cbc:TaxExclusiveAmount> <cbc:AllowanceTotalAmount currencyID="COP">0.00</cbc:AllowanceTotalAmount> <cbc:ChargeTotalAmount currencyID="COP">0.00</cbc:ChargeTotalAmount> <cbc:PrepaidAmount currencyID="COP">0.00</cbc:PrepaidAmount> <cbc:PayableAmount currencyID="COP">0.00</cbc:PayableAmount> </fe:LegalMonetaryTotal> </Invoice>

And the code used to sign:

`
use RobRichards\XMLSecLibs\XMLSecurityDSig;
use RobRichards\XMLSecLibs\XMLSecurityKey;

    $doc = new DOMDocument();
    $doc->load($xml_without_sign);
    // Create a new Security object 
    $objDSig = new XMLSecurityDSig();
    // Use the c14n exclusive canonicalization
    $objDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N);
    // Sign using SHA-256
    $objDSig->addReference(
        $doc,
        XMLSecurityDSig::SHA256,
        array('http://www.w3.org/2000/09/xmldsig#enveloped-signature')
    );
    // Create a new (private) Security key
    $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, array('type' => 'private'));
    // Load the private key
    $objKey->loadKey($KEY, TRUE);

    // Sign the XML file
    $objDSig->sign($objKey);

    // Add the associated public key to the signature
    $objDSig->add509Cert(file_get_contents($CERTIFICATE));

    // Append the signature to the XML
    $objDSig->appendSignature($doc->documentElement);
    // Save the signed XML
    $doc->save($xml_signed);

And the warning is:
DOMNode::C14N(): Relative namespace UR is invalid here : dian DOMNode::C14N() Internal error : checking for relative namespaces DOMNode::C14N() Internal error : processing docs children list
`
Causing the xml output without sign.

Alguna solución a este problema? Tengo el mismo problema

I'm trying to sign an XML withe de first lines like this

<?xml version="1.0" encoding="UTF-8" standalone="no"?> <Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:sts="dian:gov:co:facturaelectronica:Structures-2-1" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" xmlns:xades141="http://uri.etsi.org/01903/v1.4.1#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 http://docs.oasis-open.org/ubl/os-UBL-2.1/xsd/maindoc/UBL-Invoice-2.1.xsd">

When try to sign this I have the following warnings when the sytem try to use DOMNode::C14N to canonicalize and the result is wrong:
DOMNode::C14N(): Relative namespace UR is invalid here : dian DOMNode::C14N(): Internal error : checking for relative namespaces DOMNode::C14N(): Internal error : processing docs children list

How can I fix them?

se pudo solucionar este problema?

I am no expert in this topic but did a little research as I recently run into this issue myself. Here are my foundings:

  • Relative namespaces were deprecated in the W3C standard:

    Note: This specification supports the recent XML plenary decision to deprecate relative namespace URIs as follows: implementations of XML canonicalization MUST report an operation failure on documents containing relative namespace URIs. XML canonicalization MUST NOT be implemented with an XML parser that converts relative URIs to absolute URIs.

  • The error is probably coming from libxml2, not from this package.

@moltam Thanks for posting your analysis which solved the issue for me. I'm using canonicalization in PHP and, as a third party test, using the canonicalization class built into the Microsoft .NET Framework cryptography package. PHP (libxml) does report errors with relative namespaces but the .NET Framework implementation does not which caught me out.

I am sorry.
xmlns:sts="https://www.dian.gov.co/contratos/facturaelectronica/v1/Structures"
OR
xmlns:sts="urn:dian:gov:co:facturaelectronica:Structures-2-1"

I have found a solution to this issue, this is in https://es.stackoverflow.com/a/532015/283864

Regards!