JDK-8038184 : XMLSignature throws StringIndexOutOfBoundsException if ID attribute value is empty String
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.xml.crypto
  • Affected Version: 8
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2014-03-21
  • Updated: 2017-02-22
  • Resolved: 2014-04-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9 Other
8u101Fixed 9 b10Fixed openjdk7uFixed
Description
FULL PRODUCT VERSION :
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) Client VM (build 25.0-b70, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.2.9200]

A DESCRIPTION OF THE PROBLEM :
I'm trying to sign the "InfRps" tag on the following XML file:

<?xml version="1.0" encoding="UTF-8"?>
<EnviarLoteRpsEnvio xmlns="http://www.abrasf.org.br/nfse.xsd">
  <LoteRps Id="" versao="1.00">
    <NumeroLote>100</NumeroLote>
    <Cnpj>01339695000101</Cnpj>
    <InscricaoMunicipal>01323820024</InscricaoMunicipal>
    <QuantidadeRps>1</QuantidadeRps>
    <ListaRps>
      <Rps>
        <InfRps Id="1">
          <IdentificacaoRps>
            <Numero>500122</Numero>
            <Serie>900</Serie>
            <Tipo>1</Tipo>
          </IdentificacaoRps>
          <DataEmissao>2014-03-21T00:00:00.000-03:00</DataEmissao>
          <NaturezaOperacao>1</NaturezaOperacao>
          <OptanteSimplesNacional>2</OptanteSimplesNacional>
          <IncentivadorCultural>2</IncentivadorCultural>
          <Status>1</Status>
          <Servico>
            <Valores>
              <ValorServicos>98.01</ValorServicos>
              <ValorPis>0.00</ValorPis>
              <ValorCofins>0.00</ValorCofins>
              <ValorInss>0.00</ValorInss>
              <ValorIr>0.00</ValorIr>
              <IssRetido>2</IssRetido>
              <ValorIss>0.00</ValorIss>
              <Aliquota>0.00</Aliquota>
            </Valores>
            <ItemListaServico>1</ItemListaServico>
            <CodigoCnae>6201500</CodigoCnae>
            <Discriminacao>1 null - R$ 98,01</Discriminacao>
            <CodigoMunicipio>3106200</CodigoMunicipio>
          </Servico>
          <Prestador>
            <Cnpj>01339695000101</Cnpj>
            <InscricaoMunicipal>01323820024</InscricaoMunicipal>
          </Prestador>
          <Tomador>
            <IdentificacaoTomador>
              <CpfCnpj>
                <Cpf>01234567890</Cpf>
              </CpfCnpj>
            </IdentificacaoTomador>
            <RazaoSocial>CLIENTE AVULSO</RazaoSocial>
            <Endereco>
              <Endereco>RUA CATETE</Endereco>
              <Numero>999</Numero>
              <Complemento>601/701</Complemento>
              <Bairro>ALTO BARROCA</Bairro>
              <CodigoMunicipio>3106200</CodigoMunicipio>
              <Uf>MG</Uf>
              <Cep>30431016</Cep>
            </Endereco>
          </Tomador>
        </InfRps>
      </Rps>
    </ListaRps>
  </LoteRps>
</EnviarLoteRpsEnvio>


And I'm getting the following error message:

2014-03-21 09:27:17,747 ERROR [Tarefa NFe 34.034.264.168] ComandoAppletNFeQueueImpl.enviaComando(60) | Stack trace remoto referente a taskId 34034264168: com.ats.jnfe.exception.NfeConfigurationException:  erros: [Erro ao realizar a assinatura. Favor, verificar se o certificado est���� configurado corretamente nas configura��������es.] alertas: []
	at com.ats.jnfe.service.comunicacao.impl.MscapiSecurityHandlerBean.handle(MscapiSecurityHandlerBean.java:88)
	at com.ats.jnfe.applet.security.ConfigurableSecurityHandlerBean.handle(ConfigurableSecurityHandlerBean.java:42)
	at br.com.jnfe.base.service.DOMNFeSignatureHandler.sign(DOMNFeSignatureHandler.java:57)
	at com.ats.jnfe.applet.client.impl.ClientComandoAppletNFeServiceImpl.newSignature(ClientComandoAppletNFeServiceImpl.java:130)
	at com.ats.jnfe.applet.client.impl.ClientComandoAppletNFeHandlerImpl.trataComando(ClientComandoAppletNFeHandlerImpl.java:63)
	at com.ats.jnfe.applet.client.impl.ComandoAppletNFeExecutorImpl$1.run(ComandoAppletNFeExecutorImpl.java:64)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalArgumentException: Imposs����vel construir assinatura, 
	at br.com.jnfe.base.service.DOMNFeSignatureBuilder.build(DOMNFeSignatureBuilder.java:207)
	at br.com.jnfe.base.service.DOMNFeSignatureBuilder.build(DOMNFeSignatureBuilder.java:1)
	at br.com.jnfe.base.service.DOMNFeSignatureHandler$1.doInSecurityContext(DOMNFeSignatureHandler.java:59)
	at com.ats.jnfe.service.comunicacao.impl.MscapiSecurityHandlerBean.handle(MscapiSecurityHandlerBean.java:86)
	... 6 more
Caused by: javax.xml.crypto.dsig.XMLSignatureException: javax.xml.crypto.URIReferenceException: java.lang.StringIndexOutOfBoundsException: String index out of range: 0
	at org.jcp.xml.dsig.internal.dom.DOMReference.dereference(Unknown Source)
	at org.jcp.xml.dsig.internal.dom.DOMReference.digest(Unknown Source)
	at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.digestReference(Unknown Source)
	at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.sign(Unknown Source)
	at br.com.jnfe.base.service.DOMNFeSignatureBuilder.build(DOMNFeSignatureBuilder.java:195)
	... 9 more
Caused by: javax.xml.crypto.URIReferenceException: java.lang.StringIndexOutOfBoundsException: String index out of range: 0
	at org.jcp.xml.dsig.internal.dom.DOMURIDereferencer.dereference(Unknown Source)
	... 14 more
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: 0
	at java.lang.String.charAt(Unknown Source)
	at com.sun.org.apache.xml.internal.security.utils.XMLUtils.protectAgainstWrappingAttack(Unknown Source)
	at com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverFragment.engineResolveURI(Unknown Source)
	at com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver.resolve(Unknown Source)
	at com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver.resolve(Unknown Source)
	... 15 more

I'm still not sure whether there's an error on the XML or not, but the error message definitely doesn't point me towards any useful direction.


ERROR MESSAGES/STACK TRACES THAT OCCUR :
2014-03-21 09:27:17,747 ERROR [Tarefa NFe 34.034.264.168] ComandoAppletNFeQueueImpl.enviaComando(60) | Stack trace remoto referente a taskId 34034264168: com.ats.jnfe.exception.NfeConfigurationException:  erros: [Erro ao realizar a assinatura. Favor, verificar se o certificado est���� configurado corretamente nas configura��������es.] alertas: []
	at com.ats.jnfe.service.comunicacao.impl.MscapiSecurityHandlerBean.handle(MscapiSecurityHandlerBean.java:88)
	at com.ats.jnfe.applet.security.ConfigurableSecurityHandlerBean.handle(ConfigurableSecurityHandlerBean.java:42)
	at br.com.jnfe.base.service.DOMNFeSignatureHandler.sign(DOMNFeSignatureHandler.java:57)
	at com.ats.jnfe.applet.client.impl.ClientComandoAppletNFeServiceImpl.newSignature(ClientComandoAppletNFeServiceImpl.java:130)
	at com.ats.jnfe.applet.client.impl.ClientComandoAppletNFeHandlerImpl.trataComando(ClientComandoAppletNFeHandlerImpl.java:63)
	at com.ats.jnfe.applet.client.impl.ComandoAppletNFeExecutorImpl$1.run(ComandoAppletNFeExecutorImpl.java:64)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalArgumentException: Imposs����vel construir assinatura, 
	at br.com.jnfe.base.service.DOMNFeSignatureBuilder.build(DOMNFeSignatureBuilder.java:207)
	at br.com.jnfe.base.service.DOMNFeSignatureBuilder.build(DOMNFeSignatureBuilder.java:1)
	at br.com.jnfe.base.service.DOMNFeSignatureHandler$1.doInSecurityContext(DOMNFeSignatureHandler.java:59)
	at com.ats.jnfe.service.comunicacao.impl.MscapiSecurityHandlerBean.handle(MscapiSecurityHandlerBean.java:86)
	... 6 more
Caused by: javax.xml.crypto.dsig.XMLSignatureException: javax.xml.crypto.URIReferenceException: java.lang.StringIndexOutOfBoundsException: String index out of range: 0
	at org.jcp.xml.dsig.internal.dom.DOMReference.dereference(Unknown Source)
	at org.jcp.xml.dsig.internal.dom.DOMReference.digest(Unknown Source)
	at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.digestReference(Unknown Source)
	at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.sign(Unknown Source)
	at br.com.jnfe.base.service.DOMNFeSignatureBuilder.build(DOMNFeSignatureBuilder.java:195)
	... 9 more
Caused by: javax.xml.crypto.URIReferenceException: java.lang.StringIndexOutOfBoundsException: String index out of range: 0
	at org.jcp.xml.dsig.internal.dom.DOMURIDereferencer.dereference(Unknown Source)
	... 14 more
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: 0
	at java.lang.String.charAt(Unknown Source)
	at com.sun.org.apache.xml.internal.security.utils.XMLUtils.protectAgainstWrappingAttack(Unknown Source)
	at com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverFragment.engineResolveURI(Unknown Source)
	at com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver.resolve(Unknown Source)
	at com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver.resolve(Unknown Source)
	... 15 more

REPRODUCIBILITY :
This bug can be reproduced always.


Comments
I looked more into this. Even though the IDs in the example above are technically illegal accoding to the XML Schema Recommendation, the DOM API (org.w3c.dom) permits them. Thus, I think it makes sense for the XML DSig impl (which is based on DOM) to permit them under the assumption that an application should run the document through a schema validator to check for these types of illegal values. So, I have fixed the code to not throw this exception. It was a very simple fix, just a couple of lines.
14-04-2014

One of the problems in the XML document above is that an illegal values are being used for the ID attribute: <LoteRps Id="" versao="1.00"> ... <InfRps Id="1"> ID values can't be empty or start with a digit. See: http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ID The DSig impl however is assuming that the ID value is not an empty string, and should instead detect that and provide a better error message.
14-04-2014

It would be useful if the XML Signature was included in the bug report, but I can make a guess as to what the problem is. It is likely that they incorrectly specified the XML Signature Reference URI as "1" instead of "#1". The "#" is required for resolving same-document fragment URIs. However, the implementation should check for this and throw an exception if the syntax for fragment URIs does not start with a "#".
24-03-2014

Root cause would appear to be a "if (id.charAt(0) == '#') " call on what appears to be an empty string in the XMLUtils helper class. I wonder if the root element of "<LoteRps Id="" versao="1.00"> " is a legal declaration.
22-03-2014