[Libreoffice-commits] core.git: xmlsecurity/inc xmlsecurity/source

Miklos Vajna vmiklos at collabora.co.uk
Fri Oct 14 13:44:03 UTC 2016


 xmlsecurity/inc/pdfio/pdfdocument.hxx    |    3 +
 xmlsecurity/source/pdfio/pdfdocument.cxx |   80 ++++++++++++++++++++++---------
 2 files changed, 61 insertions(+), 22 deletions(-)

New commits:
commit d550f5e6b670e75907be5ea81e8fd5c0f4f67401
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Oct 14 15:38:57 2016 +0200

    xmlsecurity: expose reason string of PDF signatures
    
    Also known as comment or description. And since then we need the hex
    decoding mechanism for this and Content as well, extract that to a new
    DecodeHexString().
    
    Change-Id: Ie260b470c951661c80c0921b5ce2aa4c461f692c

diff --git a/xmlsecurity/inc/pdfio/pdfdocument.hxx b/xmlsecurity/inc/pdfio/pdfdocument.hxx
index 79cd716..0eaaa09 100644
--- a/xmlsecurity/inc/pdfio/pdfdocument.hxx
+++ b/xmlsecurity/inc/pdfio/pdfdocument.hxx
@@ -25,6 +25,7 @@ namespace pdfio
 
 class PDFTrailerElement;
 class PDFObjectElement;
+class PDFHexStringElement;
 
 /// A byte range in a PDF file.
 class PDFElement
@@ -44,6 +45,8 @@ class XMLSECURITY_DLLPUBLIC PDFDocument
     PDFTrailerElement* m_pTrailer;
 
     static int AsHex(char ch);
+    /// Decode a hex dump.
+    static std::vector<unsigned char> DecodeHexString(PDFHexStringElement* pElement);
 
 public:
     PDFDocument();
diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx
index 225c588..3766e4d 100644
--- a/xmlsecurity/source/pdfio/pdfdocument.cxx
+++ b/xmlsecurity/source/pdfio/pdfdocument.cxx
@@ -681,6 +681,37 @@ int PDFDocument::AsHex(char ch)
     return nRet;
 }
 
+std::vector<unsigned char> PDFDocument::DecodeHexString(PDFHexStringElement* pElement)
+{
+    std::vector<unsigned char> aRet;
+    const OString& rHex = pElement->GetValue();
+    size_t nHexLen = rHex.getLength();
+    {
+        int nByte = 0;
+        int nCount = 2;
+        for (size_t i = 0; i < nHexLen; ++i)
+        {
+            nByte = nByte << 4;
+            sal_Int8 nParsed = AsHex(rHex[i]);
+            if (nParsed == -1)
+            {
+                SAL_WARN("xmlsecurity.pdfio", "PDFDocument::DecodeHexString: invalid hex value");
+                return aRet;
+            }
+            nByte += nParsed;
+            --nCount;
+            if (!nCount)
+            {
+                aRet.push_back(nByte);
+                nCount = 2;
+                nByte = 0;
+            }
+        }
+    }
+
+    return aRet;
+}
+
 bool PDFDocument::ValidateSignature(SvStream& rStream, PDFObjectElement* pSignature, SignatureInformation& rInformation)
 {
     PDFObjectElement* pValue = pSignature->LookupObject("V");
@@ -711,33 +742,38 @@ bool PDFDocument::ValidateSignature(SvStream& rStream, PDFObjectElement* pSignat
         return false;
     }
 
-    // At this point there is no obviously missing info to validate the
-    // signature, so let's turn the hex dump of the signature into a memory
-    // stream.
-    const OString& rSignatureHex = pContents->GetValue();
-    size_t nSignatureHexLen = rSignatureHex.getLength();
-    std::vector<unsigned char> aSignature;
+    // Reason / comment / description is optional.
+    auto pReason = dynamic_cast<PDFHexStringElement*>(pValue->Lookup("Reason"));
+    if (pReason)
     {
-        int nByte = 0;
-        int nCount = 2;
-        for (size_t i = 0; i < nSignatureHexLen; ++i)
+        // See appendUnicodeTextString() for the export equivalent of this.
+        std::vector<unsigned char> aReason = PDFDocument::DecodeHexString(pReason);
+        OUStringBuffer aBuffer;
+        sal_uInt16 nByte = 0;
+        for (size_t i = 0; i < aReason.size(); ++i)
         {
-            nByte = nByte << 4;
-            sal_Int8 nParsed = AsHex(rSignatureHex[i]);
-            if (nParsed == -1)
-            {
-                SAL_WARN("xmlsecurity.pdfio", "PDFDocument::ValidateSignature: invalid hex value");
-                return false;
-            }
-            nByte += nParsed;
-            --nCount;
-            if (!nCount)
+            if (i % 2 == 0)
+                nByte = aReason[i];
+            else
             {
-                aSignature.push_back(nByte);
-                nCount = 2;
-                nByte = 0;
+                sal_Unicode nUnicode;
+                nUnicode = (nByte << 8);
+                nUnicode |= aReason[i];
+                aBuffer.append(nUnicode);
             }
         }
+
+        if (!aBuffer.isEmpty())
+            rInformation.ouDescription = aBuffer.makeStringAndClear();
+    }
+
+    // At this point there is no obviously missing info to validate the
+    // signature.
+    std::vector<unsigned char> aSignature = PDFDocument::DecodeHexString(pContents);
+    if (aSignature.empty())
+    {
+        SAL_WARN("xmlsecurity.pdfio", "PDFDocument::ValidateSignature: empty contents");
+        return false;
     }
 
 #ifdef XMLSEC_CRYPTO_NSS


More information about the Libreoffice-commits mailing list