Pergunta

Eu estou usando xmlseclibs para tentar assinar um documento SOAP, mas ele faz não parecem canonizar as coisas da mesma maneira, dependendo se eu vou assinar ou validar.

Vou te dar um exemplo. Este é o XML que eu estou tentando sinal:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" MajorVersion="1" MinorVersion="1" IssueInstant="2010-02-04T15:27:43Z" ResponseID="pfxe85313e6-e688-299a-df06-30f55e24f65a">
<samlp:Status>
<samlp:StatusCode Value="samlp:Requester"/>
</samlp:Status>
</samlp:Response>
</soapenv:Body>
</soapenv:Envelope>

Eu tenho algum código trabalhando em PHP para assiná-lo usando uma combinação de chaves públicas e certificados de chaves privadas, e parecia ao trabalho. Acrescentou o elemento <ds:Signature> com todo o material adequado, e parecia ótimo. Mas então eu testei pela imediatamente tentando validá-lo depois de assiná-lo, novamente com xmlseclibs (eo certificado de chave pública), mas a validação falhou. Então, exatamente a mesma biblioteca de código está fazendo tanto a assinatura e validação, mas os dois processos não concordar, por algum motivo.

Eu adicionei um código de depuração para xmlseclibs para descobrir o que ele está fazendo, e eu percebi que a razão a chave de assinatura que aparece com ea chave de validação que vem com são diferentes são porque Canonicaliza coisas de forma diferente nas duas situações . Quando eu diga a ele para assinar o elemento <samlp:Response>, esta é a forma canônica que sinais (Eu adicionei novas linhas aqui para facilitar a leitura):

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" IssueInstant="2010-02-04T15:27:43Z" MajorVersion="1" MinorVersion="1" ResponseID="pfxe85313e6-e688-299a-df06-30f55e24f65a" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">
<samlp:Status>
<samlp:StatusCode Value="samlp:Requester">
</samlp:StatusCode>
</samlp:Status>
</samlp:Response>

No entanto, quando ele vai para validar a assinatura, esta é a forma canônica ele calcula para validar contra (novas linhas novamente, eu adicionei aqui):

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" IssueInstant="2010-02-04T15:27:43Z" MajorVersion="1" MinorVersion="1" ResponseID="pfxe85313e6-e688-299a-df06-30f55e24f65a">
<samlp:Status>
<samlp:StatusCode Value="samlp:Requester">
</samlp:StatusCode>
</samlp:Status>
</samlp:Response>

Então, como você pode ver, esta versão omite o atributo xmlns:saml do elemento <samlp:Response>, enquanto o primeiro não. (Note que este é diferente do atributo xmlns:samlp, que está incluído em ambos.) Isso parece bastante claramente como um bug no xmlseclibs, mas mesmo assim é um que eu ficaria feliz em corrigir-me se eu só sabia que forma canônica era a correta 1. Caso esse atributo ser omitida pela canonização exclusivo? Ou deveria ser incluído? Qual é a forma canônica exclusivo correto?

Foi útil?

Solução

Você está criando o documento DOM de forma abusiva e tentando usar a árvore em memória inválido. Ou serialize e usar o resultado serializado ou criar adequadamente as declarações de namespace na árvore antes de tentar assinar. Veja o relatório de erro para mais informações: http://code.google. com / p / xmlseclibs / questões / detalhes? id = 6

Outras dicas

Nem são a forma canônica correto!

O XML assinatura tem uma declaração de namespace que vem após os atributos não-namespace, que quebra a regra de documento de ordem:

nós Namespace ter uma posição de menor ordem do documento de nós de atributo.

O XML verificação está faltando o nó namespace saml completamente. não canonicalisation não remover nós de namespace simplesmente porque não há conteúdo criança que as referências deles. Ele apenas remove nós namespace redundantes (ie. Namespaces que já estavam em vigor no pai).

Eu não sei o suficiente sobre xmlseclibs para dizer por que isso está acontecendo, mas é definitivamente errado em ambas as contagens. FWIW a função C14N no meu DOM aqui diz:

<samlp:Response xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" IssueInstant="2010-02-04T15:27:43Z" MajorVersion="1" MinorVersion="1" ResponseID="pfxe85313e6-e688-299a-df06-30f55e24f65a">
<samlp:Status>
<samlp:StatusCode Value="samlp:Requester"></samlp:StatusCode>
</samlp:Status>
</samlp:Response>

eta: Eu olhei para xmlseclibs.php no SVN, e não há uma solução fácil para isso como a sua abordagem atual é fundamentalmente falho. Ele tenta criar um DOM “canonicalised” e, em seguida, serialises-lo com simples saveXML() idade. Como existem regras de serialização C14N cerca de fim atributo e caracteres de escape que saveXML não promete a seguir, não há nenhuma maneira este trabalho pode possivelmente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top