Skip to content

Commit

Permalink
Handle utf8 XML better, don't alias everything
Browse files Browse the repository at this point in the history
* Don't make everything >126 into aliases; we still keep the
  same (slightly retarded) behaviour of making non-printables
  into aliases though, because xmerl can't tell us if they were
  in the document as an alias or a direct character

* Add some tests to cover this, as well as the 
 in the spec
  • Loading branch information
arekinath committed Oct 29, 2013
1 parent 90dd040 commit 9c5bf67
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 5 deletions.
9 changes: 7 additions & 2 deletions src/xmerl_c14n.erl
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ xml_safe_string(Str, Quotes) when is_list(Str) ->
[Next | Rest] = Str,
if
(not Quotes andalso ([Next] =:= "\n")) -> [Next | xml_safe_string(Rest, Quotes)];
(Next < 32) orelse (Next > 126) ->
(Next < 32) ->
lists:flatten(["&#x" ++ integer_to_list(Next, 16) ++ ";" | xml_safe_string(Rest, Quotes)]);
(Quotes andalso ([Next] =:= "\"")) -> lists:flatten(["&quot;" | xml_safe_string(Rest, Quotes)]);
([Next] =:= "&") -> lists:flatten(["&amp;" | xml_safe_string(Rest, Quotes)]);
Expand Down Expand Up @@ -276,7 +276,12 @@ xml_safe_string_test() ->
"foo \ngeorge" = xml_safe_string(<<"foo \ngeorge">>),
"foo &lt;&#x5;&gt; = &amp; help" = xml_safe_string(lists:flatten(["foo <", 5, "> = & help"])),
"&#xE;" = xml_safe_string(<<14>>),
"\"foo\"" = xml_safe_string("\"foo\"").
"\"foo\"" = xml_safe_string("\"foo\""),
"test&#xD;\n" = xml_safe_string("test\r\n").

xml_safe_string_utf8_test() ->
String = unicode:characters_to_list(<<"バカの名前">>),
String = xml_safe_string(String).

c14n_3_1_test() ->
{Doc, _} = xmerl_scan:string("<?xml version=\"1.0\"?>\n\n<?xml-stylesheet href=\"doc.xsl\"\n type=\"text/xsl\" ?>\n\n<doc>Hello, world!<!-- Comment 1 --></doc>\n\n<?pi-without-data ?>\n\n<!-- Comment 2 -->\n\n<!-- Comment 3 -->", [{namespace_conformant, true}, {document, true}]),
Expand Down
8 changes: 5 additions & 3 deletions src/xmerl_dsig.erl
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ sign(ElementIn, PrivateKey, CertBin) ->

% first we need the digest, to generate our SignedInfo element
CanonXml = xmerl_c14n:c14n(Element),
DigestValue = base64:encode_to_string(crypto:sha(CanonXml)),
DigestValue = base64:encode_to_string(
crypto:sha(unicode:characters_to_binary(CanonXml, unicode, utf8))),

Ns = #xmlNamespace{nodes = [{"ds", 'http://www.w3.org/2000/09/xmldsig#'}]},
SigInfo = esaml:build_nsinfo(Ns, #xmlElement{
Expand Down Expand Up @@ -86,7 +87,7 @@ sign(ElementIn, PrivateKey, CertBin) ->

% now we sign the SignedInfo element...
SigInfoCanon = xmerl_c14n:c14n(SigInfo),
Data = list_to_binary(SigInfoCanon),
Data = unicode:characters_to_binary(SigInfoCanon, unicode, utf8),

Signature = public_key:sign(Data, sha, PrivateKey),
Sig64 = base64:encode_to_string(Signature),
Expand Down Expand Up @@ -121,7 +122,8 @@ verify(Element, Fingerprints) ->

DsNs = [{"ds", 'http://www.w3.org/2000/09/xmldsig#'}],
[#xmlText{value = Sha64}] = xmerl_xpath:string("ds:Signature/ds:SignedInfo/ds:Reference/ds:DigestValue/text()", Element, [{namespace, DsNs}]),
CanonSha = crypto:sha(CanonXml),
CanonXmlUtf8 = unicode:characters_to_binary(CanonXml, unicode, utf8),
CanonSha = crypto:sha(CanonXmlUtf8),
CanonSha2 = base64:decode(Sha64),
if not (CanonSha =:= CanonSha2) ->
{error, bad_digest};
Expand Down

0 comments on commit 9c5bf67

Please sign in to comment.