Skip to content

Commit

Permalink
fixes decryption failure on unreadable perms (Paweł Jackowski)
Browse files Browse the repository at this point in the history
git-svn-id: svn://tug.org/texlive/trunk/Build/source@67196 c570f23f-e606-0410-a88d-b1316a301751
  • Loading branch information
luigiScarso committed May 23, 2023
1 parent a0ef997 commit 8c3f304
Show file tree
Hide file tree
Showing 25 changed files with 643 additions and 317 deletions.
4 changes: 4 additions & 0 deletions libs/pplib/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
2023-05-23 Luigi Scarso luigi.scarso@gmail.com
* sync with the upstrem repo.:
fixes decryption failure on unreadable perms (Paweł Jackowski)

2020-04-18 Luigi Scarso luigi.scarso@gmail.com
* Moved luatexdir/luapplib under libs/pplib.
Binary file modified libs/pplib/pplib-src/doc/_build/doctrees/environment.pickle
Binary file not shown.
Binary file modified libs/pplib/pplib-src/doc/_build/doctrees/ppapi-1.x.doctree
Binary file not shown.
Binary file modified libs/pplib/pplib-src/doc/_build/doctrees/ppapi-2.x.doctree
Binary file not shown.
Binary file modified libs/pplib/pplib-src/doc/_build/doctrees/ppcode.doctree
Binary file not shown.
Binary file modified libs/pplib/pplib-src/doc/_build/doctrees/pplib.doctree
Binary file not shown.
Binary file modified libs/pplib/pplib-src/doc/_build/doctrees/ppnew.doctree
Binary file not shown.
33 changes: 21 additions & 12 deletions libs/pplib/pplib-src/doc/_build/html/_sources/ppapi-2.x.rst.txt
Original file line number Diff line number Diff line change
Expand Up @@ -677,15 +677,14 @@ It is a common practise to *protect* documents with an empty password. Such docu
for a password), but some features (eg. printing) may restricted by the application.

When ``pplib`` detects encryption, it follows Acrobat approach and first tries an empty password. If it succeeds, ``pplib`` proceeeds normally, providing
an access to decrypted strings and streams, as if they weren't ciphered. If the document is protected with non-empty password, ``pplib`` gives
a way to provide a password and proceed. Until you provide a password, ``ppdoc`` object returned by ``ppdoc_load()`` function has all object wntries
set to ``null``.
an access to decrypted strings and streams, as if they weren't ciphered. If the document is protected with non-empty password, you have to call
``ppdoc_crypt_pass()``. Until you provide a password, ``ppdoc`` object returned by ``ppdoc_load()`` function has all object entries set to ``null``.

After loading a document you should check encryption status with::
Once the document is loaded, encryption status can be checked with::

ppcrypt_status ppdoc_crypt_status (ppdoc *pdf);

``ppcrypt_status`` (integer) may have the following values:
``ppcrypt_status`` (enum) may have the following values:

``PPCRYPT_NONE`` - no encryption, go ahead
``PPCRYPT_DONE`` - encryption present but password succeeded, go ahead
Expand All @@ -697,10 +696,12 @@ If a password is needed, you can provide one with::
ppcrypt_status ppdoc_crypt_pass (ppdoc *pdf, const void *userpass, size_t userpasslength,
const void *ownerpass, size_t ownerpasslength);

Well, yes, there are actually two passwords in encrypted documents. Relation between them is obscure to me, but enough
to know that having one of them is enough to decrypt the document. If you know the password, you probably mean
``userpass``, in which case you should put ``NULL`` as ``ownerpass``. The function returns ``PPCRYPT_DONE`` if the password
succeeds and the previous status otherwise. Your custom loader function may look like that::
Providing one of two is enough to decrypt the document.
It is ok to use the same password for owner and user -- ``pplib`` will try both.

The function returns ``PPCRYPT_DONE`` if the password succeeds and the previous crypt status otherwise.

Your custom loader function may look like that::

ppdoc *pdf;
pdf = ppdoc_load("file.pdf");
Expand All @@ -712,8 +713,7 @@ succeeds and the previous status otherwise. Your custom loader function may look
case PPCRYPT_DONE:
return pdf;
case PPCRYPT_PASS:
if (ppdoc_crypt_pass(pdf, "dummy", 5, NULL, 0) == PPCRYPT_DONE ||
ppdoc_crypt_pass(pdf, NULL, 0, "dummy", 5) == PPCRYPT_DONE)
if (ppdoc_crypt_pass(pdf, "dummy", 5, "dummy", 5) == PPCRYPT_DONE)
return pdf;
printf("sorry, password needed\n");
ppdoc_free(pdf);
Expand All @@ -724,7 +724,7 @@ succeeds and the previous status otherwise. Your custom loader function may look
return NULL;
}

[If you get ``PPCRYPT_FAIL`` it might mean *I failed*, so treat as a bug.]
See ``pplib`` tests suite for a complete code.

If you'd like to know what permissions are given/restricted to encrypted document::

Expand All @@ -751,6 +751,15 @@ In encrypted documents most of streams are encrypted. To check if a given stream

Encryption is independent from compression, don't confuse with ``ppstream_compressed()``

.. caution::
Starting from ``pplib v2.10`` all passwords should be passed as ``UTF-8``.
Earlier PDF encryption algorithms (/V 1..4, PDF 1.7) were based on ``PdfDocEncoding``.
Newer algorithms (/V 5, PDF 1.8-2.0) expect Unicode encoded as ``UTF-8``.
``pplib`` API now expects ``UTF-8`` and if opening documents with older encryption methods,
it tries to make a conversion to 8-bit encoding. In earlier versions ``pplib`` didn't
make any password preprocessing, treating them as raw byte arrays.
So in case of passwords with fancy characters, it may behave differently.

Pages
-----

Expand Down
8 changes: 4 additions & 4 deletions libs/pplib/pplib-src/doc/_build/html/_sources/ppcode.rst.txt
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ v2.05
uint8_t instead of ppbyte in internals; ppbyte intent is "the most natural 8-bit integer", so it is 'char',
but internally we almost always need uint8_t (char may be signed or not..)

TODO
====
- external streams (egzotic)

v2.10
-----
Rework on encryption; algorithms /V5 /R6.
Passwords passed to ppdoc_crypt_pass() should be UTF-8 (backward incompatible).
2 changes: 1 addition & 1 deletion libs/pplib/pplib-src/doc/_build/html/genindex.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ <h3>Navigation</h3>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2019, p.jackowski@gust.org.pl.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.5.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.6.
</div>
</body>
</html>
2 changes: 1 addition & 1 deletion libs/pplib/pplib-src/doc/_build/html/ppapi-1.x.html
Original file line number Diff line number Diff line change
Expand Up @@ -1024,7 +1024,7 @@ <h3>Navigation</h3>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2019, p.jackowski@gust.org.pl.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.5.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.6.
</div>
</body>
</html>
34 changes: 21 additions & 13 deletions libs/pplib/pplib-src/doc/_build/html/ppapi-2.x.html
Original file line number Diff line number Diff line change
Expand Up @@ -752,14 +752,13 @@ <h2>Encryption<a class="headerlink" href="#encryption" title="Permalink to this
It is a common practise to <em>protect</em> documents with an empty password. Such documents remain readable in Acrobat (just opens them without prompting
for a password), but some features (eg. printing) may restricted by the application.</p>
<p>When <code class="docutils literal notranslate"><span class="pre">pplib</span></code> detects encryption, it follows Acrobat approach and first tries an empty password. If it succeeds, <code class="docutils literal notranslate"><span class="pre">pplib</span></code> proceeeds normally, providing
an access to decrypted strings and streams, as if they weren’t ciphered. If the document is protected with non-empty password, <code class="docutils literal notranslate"><span class="pre">pplib</span></code> gives
a way to provide a password and proceed. Until you provide a password, <code class="docutils literal notranslate"><span class="pre">ppdoc</span></code> object returned by <code class="docutils literal notranslate"><span class="pre">ppdoc_load()</span></code> function has all object wntries
set to <code class="docutils literal notranslate"><span class="pre">null</span></code>.</p>
<p>After loading a document you should check encryption status with:</p>
an access to decrypted strings and streams, as if they weren’t ciphered. If the document is protected with non-empty password, you have to call
<code class="docutils literal notranslate"><span class="pre">ppdoc_crypt_pass()</span></code>. Until you provide a password, <code class="docutils literal notranslate"><span class="pre">ppdoc</span></code> object returned by <code class="docutils literal notranslate"><span class="pre">ppdoc_load()</span></code> function has all object entries set to <code class="docutils literal notranslate"><span class="pre">null</span></code>.</p>
<p>Once the document is loaded, encryption status can be checked with:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ppcrypt_status</span> <span class="n">ppdoc_crypt_status</span> <span class="p">(</span><span class="n">ppdoc</span> <span class="o">*</span><span class="n">pdf</span><span class="p">);</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">ppcrypt_status</span></code> (integer) may have the following values:</p>
<p><code class="docutils literal notranslate"><span class="pre">ppcrypt_status</span></code> (enum) may have the following values:</p>
<blockquote>
<div><code class="docutils literal notranslate"><span class="pre">PPCRYPT_NONE</span></code> - no encryption, go ahead
<code class="docutils literal notranslate"><span class="pre">PPCRYPT_DONE</span></code> - encryption present but password succeeded, go ahead
Expand All @@ -770,10 +769,10 @@ <h2>Encryption<a class="headerlink" href="#encryption" title="Permalink to this
<span class="n">const</span> <span class="n">void</span> <span class="o">*</span><span class="n">ownerpass</span><span class="p">,</span> <span class="n">size_t</span> <span class="n">ownerpasslength</span><span class="p">);</span>
</pre></div>
</div>
<p>Well, yes, there are actually two passwords in encrypted documents. Relation between them is obscure to me, but enough
to know that having one of them is enough to decrypt the document. If you know the password, you probably mean
<code class="docutils literal notranslate"><span class="pre">userpass</span></code>, in which case you should put <code class="docutils literal notranslate"><span class="pre">NULL</span></code> as <code class="docutils literal notranslate"><span class="pre">ownerpass</span></code>. The function returns <code class="docutils literal notranslate"><span class="pre">PPCRYPT_DONE</span></code> if the password
succeeds and the previous status otherwise. Your custom loader function may look like that:</p>
<p>Providing one of two is enough to decrypt the document.
It is ok to use the same password for owner and user – <code class="docutils literal notranslate"><span class="pre">pplib</span></code> will try both.</p>
<p>The function returns <code class="docutils literal notranslate"><span class="pre">PPCRYPT_DONE</span></code> if the password succeeds and the previous crypt status otherwise.</p>
<p>Your custom loader function may look like that:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ppdoc</span> <span class="o">*</span><span class="n">pdf</span><span class="p">;</span>
<span class="n">pdf</span> <span class="o">=</span> <span class="n">ppdoc_load</span><span class="p">(</span><span class="s2">&quot;file.pdf&quot;</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">pdf</span> <span class="o">==</span> <span class="n">NULL</span><span class="p">)</span>
Expand All @@ -784,8 +783,7 @@ <h2>Encryption<a class="headerlink" href="#encryption" title="Permalink to this
<span class="n">case</span> <span class="n">PPCRYPT_DONE</span><span class="p">:</span>
<span class="k">return</span> <span class="n">pdf</span><span class="p">;</span>
<span class="n">case</span> <span class="n">PPCRYPT_PASS</span><span class="p">:</span>
<span class="k">if</span> <span class="p">(</span><span class="n">ppdoc_crypt_pass</span><span class="p">(</span><span class="n">pdf</span><span class="p">,</span> <span class="s2">&quot;dummy&quot;</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="n">NULL</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">==</span> <span class="n">PPCRYPT_DONE</span> <span class="o">||</span>
<span class="n">ppdoc_crypt_pass</span><span class="p">(</span><span class="n">pdf</span><span class="p">,</span> <span class="n">NULL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">&quot;dummy&quot;</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span> <span class="o">==</span> <span class="n">PPCRYPT_DONE</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">ppdoc_crypt_pass</span><span class="p">(</span><span class="n">pdf</span><span class="p">,</span> <span class="s2">&quot;dummy&quot;</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="s2">&quot;dummy&quot;</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span> <span class="o">==</span> <span class="n">PPCRYPT_DONE</span><span class="p">)</span>
<span class="k">return</span> <span class="n">pdf</span><span class="p">;</span>
<span class="n">printf</span><span class="p">(</span><span class="s2">&quot;sorry, password needed</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">);</span>
<span class="n">ppdoc_free</span><span class="p">(</span><span class="n">pdf</span><span class="p">);</span>
Expand All @@ -797,7 +795,7 @@ <h2>Encryption<a class="headerlink" href="#encryption" title="Permalink to this
<span class="p">}</span>
</pre></div>
</div>
<p>[If you get <code class="docutils literal notranslate"><span class="pre">PPCRYPT_FAIL</span></code> it might mean <em>I failed</em>, so treat as a bug.]</p>
<p>See <code class="docutils literal notranslate"><span class="pre">pplib</span></code> tests suite for a complete code.</p>
<p>If you’d like to know what permissions are given/restricted to encrypted document:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ppint</span> <span class="n">ppdoc_permissions</span> <span class="p">(</span><span class="n">ppdoc</span> <span class="o">*</span><span class="n">pdf</span><span class="p">);</span>
</pre></div>
Expand All @@ -821,6 +819,16 @@ <h2>Encryption<a class="headerlink" href="#encryption" title="Permalink to this
</pre></div>
</div>
<p>Encryption is independent from compression, don’t confuse with <code class="docutils literal notranslate"><span class="pre">ppstream_compressed()</span></code></p>
<div class="admonition caution">
<p class="first admonition-title">Caution</p>
<p class="last">Starting from <code class="docutils literal notranslate"><span class="pre">pplib</span> <span class="pre">v2.10</span></code> all passwords should be passed as <code class="docutils literal notranslate"><span class="pre">UTF-8</span></code>.
Earlier PDF encryption algorithms (/V 1..4, PDF 1.7) were based on <code class="docutils literal notranslate"><span class="pre">PdfDocEncoding</span></code>.
Newer algorithms (/V 5, PDF 1.8-2.0) expect Unicode encoded as <code class="docutils literal notranslate"><span class="pre">UTF-8</span></code>.
<code class="docutils literal notranslate"><span class="pre">pplib</span></code> API now expects <code class="docutils literal notranslate"><span class="pre">UTF-8</span></code> and if opening documents with older encryption methods,
it tries to make a conversion to 8-bit encoding. In earlier versions <code class="docutils literal notranslate"><span class="pre">pplib</span></code> didn’t
make any password preprocessing, treating them as raw byte arrays.
So in case of passwords with fancy characters, it may behave differently.</p>
</div>
</div>
<div class="section" id="pages">
<h2>Pages<a class="headerlink" href="#pages" title="Permalink to this headline"></a></h2>
Expand Down Expand Up @@ -1025,7 +1033,7 @@ <h3>Navigation</h3>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2019, p.jackowski@gust.org.pl.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.5.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.6.
</div>
</body>
</html>
Loading

0 comments on commit 8c3f304

Please sign in to comment.