ReportLab fails with ValueError on FIPS enabled systems

Martin Renters via reportlab-users <[email protected]> Sun, 29 Jun 2025 20:13:59 -0400
Newsgroups gmane.comp.python.reportlab.user
Message-ID <[email protected]>
--===============6416592183070504230==
Content-Type: multipart/alternative;
	boundary="Apple-Mail=_247A24E9-6E45-45DA-B332-D90E59CB95FB"


--Apple-Mail=_247A24E9-6E45-45DA-B332-D90E59CB95FB
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=utf-8

First of all, I=E2=80=99d like to thank the ReportLab people for =
releasing such a fabulous open-source toolkit. It truly makes generating =
PDFs so much easier!

The problem I=E2=80=99m reporting affects users that have enabled FIPS =
mode on their systems. In my particular case, it is a RHEL 9.6 system. =
When in FIPS mode, certain cryptographic functions are not permitted =
because of weaknesses in the algorithms. In the case of ReportLab, this =
would be the MD5 function which is used to calculate a document ID and =
is also used to track fonts used, and a few other things, as well as in =
the PDF encryption functions themselves.

When in FIPS mode, running a program will cause an exception similar to:

Traceback (most recent call last):
  File "/opt/dftoolkit/bin/annotateCRF", line 82, in main
    annotate.build_pdf(plate_filter=3Dargs.plates)
  File =
"//opt/dftoolkit/lib/python3.9/site-packages/dftoolkit/annotate.py", =
line 549, in build_pdf
    self.doc.build(flowables)
  File =
"//opt/dftoolkit/lib/python3.9/site-packages/reportlab/platypus/doctemplat=
e.py", line 1062, in build
    self._startBuild(filename,canvasmaker)
  File =
"//opt/dftoolkit/lib/python3.9/site-packages/reportlab/platypus/doctemplat=
e.py", line 1032, in _startBuild
    self.canv =3D =
self._makeCanvas(filename=3Dfilename,canvasmaker=3Dcanvasmaker)
  File =
"//opt/dftoolkit/lib/python3.9/site-packages/reportlab/platypus/doctemplat=
e.py", line 992, in _makeCanvas
    canv =3D canvasmaker(filename or self.filename,
  File =
"//opt/dftoolkit/lib/python3.9/site-packages/reportlab/pdfgen/canvas.py", =
line 320, in __init__
    self._doc =3D pdfdoc.PDFDocument(compression=3DpageCompression,
  File =
"//opt/dftoolkit/lib/python3.9/site-packages/reportlab/pdfbase/pdfdoc.py",=
 line 137, in __init__
    sig =3D self.signature =3D md5()
ValueError: [digital envelope routines] unsupported

Most of the uses of MD5, aside from the use in the actual PDF =
encryption, appear not to be security related. In Python 3.9, the =
hashlib functions can be passed a keyword argument called =
=E2=80=98usedforsecurity=E2=80=99 (defaulting to True) that can be set =
to False if the hash algorithm isn=E2=80=99t used for security purposes. =
This allows the use of MD5 hashes even on FIPS enabled systems and =
allows ReportLab to successfully generate PDFs. Passing this keyword =
argument on the older Python 3.6.8 doesn=E2=80=99t cause any ill =
effects.

A small test program demonstrating the hashlib problem on a FIPS enabled =
system, and the fix using usedforsecurity=3DFalse is as follows:

$ more md5test.py
from hashlib import md5
m =3D md5()
m.update(b'This is a test')
print(m.hexdigest())

$ python md5test.py
Traceback (most recent call last):
  File "/home/martin/md5test.py", line 2, in <module>
    m =3D md5()
ValueError: [digital envelope routines] unsupported

Changing the m=3Dmd5() to m=3Dmd5(usedforsecurity=3DFalse) causes it to =
run successfully:

$ more md5test.py
from hashlib import md5
m =3D md5(usedforsecurity=3DFalse)
m.update(b'This is a test')
print(m.hexdigest())

$ python md5test.py
ce114e4501d2f4e2dcea3e17b546f339

Attached is a patch that adds the usedforsecurity=3DFalse parameter in =
the cases I believe are not security related. Alternatively, a different =
hash function permitted by FIPS could be used. The actual PDF encryption =
code isn=E2=80=99t modified by this patch and it will probably require =
the use of different algorithms to be FIPS compatible.

Thanks for considering this patch,

Martin

diff -ru =
../venv3.9/lib/python3.9/site-packages/reportlab/lib/fontfinder.py =
reportlab/lib/fontfinder.py
--- ../venv3.9/lib/python3.9/site-packages/reportlab/lib/fontfinder.py	=
2025-06-27 12:37:23.507252855 -0400
+++ reportlab/lib/fontfinder.py	2025-06-29 15:08:52.470092313 -0400
@@ -216,7 +216,7 @@
         """Base this on the directories...same set of directories
         should give same cache"""
         fsEncoding =3D self._fsEncoding
-        hash =3D md5(b''.join(asBytes(_,enc=3DfsEncoding) for _ in =
sorted(self._dirs))).hexdigest()
+        hash =3D md5(b''.join(asBytes(_,enc=3DfsEncoding) for _ in =
sorted(self._dirs)),usedforsecurity=3DFalse).hexdigest()
         from reportlab.lib.utils import get_rl_tempfile
         fn =3D get_rl_tempfile('fonts_%s.dat' % hash)
         return fn
diff -ru ../venv3.9/lib/python3.9/site-packages/reportlab/lib/utils.py =
reportlab/lib/utils.py
--- ../venv3.9/lib/python3.9/site-packages/reportlab/lib/utils.py	=
2025-06-27 12:37:23.512252786 -0400
+++ reportlab/lib/utils.py	2025-06-29 15:08:52.473092276 -0400
@@ -55,7 +55,7 @@
 _rl_NoneType=3Dtype(None)
 strTypes =3D (str,bytes)
 def _digester(s):
-    return md5(s if isBytes(s) else s.encode('utf8')).hexdigest()
+    return md5(s if isBytes(s) else =
s.encode('utf8'),usedforsecurity=3DFalse).hexdigest()
=20
 def asBytes(v,enc=3D'utf8'):
     if isinstance(v,bytes): return v
diff -ru =
../venv3.9/lib/python3.9/site-packages/reportlab/pdfbase/cidfonts.py =
reportlab/pdfbase/cidfonts.py
--- ../venv3.9/lib/python3.9/site-packages/reportlab/pdfbase/cidfonts.py	=
2025-06-27 12:37:23.519252690 -0400
+++ reportlab/pdfbase/cidfonts.py	2025-06-29 15:08:52.668089932 =
-0400
@@ -85,7 +85,7 @@
                 self.parseCMAPFile(name)
=20
     def _hash(self, text):
-        hasher =3D md5()
+        hasher =3D md5(usedforsecurity=3DFalse)
         hasher.update(text)
         return hasher.digest()
=20
diff -ru =
../venv3.9/lib/python3.9/site-packages/reportlab/pdfbase/pdfdoc.py =
reportlab/pdfbase/pdfdoc.py
--- ../venv3.9/lib/python3.9/site-packages/reportlab/pdfbase/pdfdoc.py	=
2025-06-27 12:37:23.520252676 -0400
+++ reportlab/pdfbase/pdfdoc.py	2025-06-29 15:08:52.672089884 -0400
@@ -134,7 +134,7 @@
         self.setCompression(compression)
         self._pdfVersion =3D pdfVersion
         # signature for creating PDF ID
-        sig =3D self.signature =3D md5()
+        sig =3D self.signature =3D md5(usedforsecurity=3DFalse)
         sig.update(b"a reportlab document")
         self._timeStamp =3D TimeStamp(self.invariant)
         cat =3D self._timeStamp.t
diff -ru =
../venv3.9/lib/python3.9/site-packages/reportlab/pdfgen/canvas.py =
reportlab/pdfgen/canvas.py
--- ../venv3.9/lib/python3.9/site-packages/reportlab/pdfgen/canvas.py	=
2025-06-27 12:37:23.523252635 -0400
+++ reportlab/pdfgen/canvas.py	2025-06-29 15:08:52.786088514 -0400
@@ -1131,9 +1131,9 @@
         """
         #check if we've done this one already...
         if isUnicode(command):
-            rawName =3D 'PS' + =
hashlib.md5(command.encode('utf-8')).hexdigest()
+            rawName =3D 'PS' + =
hashlib.md5(command.encode('utf-8'),usedforsecurity=3DFalse).hexdigest()
         else:
-            rawName =3D 'PS' + hashlib.md5(command).hexdigest()
+            rawName =3D 'PS' + =
hashlib.md5(command,usedforsecurity=3DFalse).hexdigest()
         regName =3D self._doc.getXObjectName(rawName)
         psObj =3D self._doc.idToObject.get(regName, None)
         if not psObj:


--Apple-Mail=_247A24E9-6E45-45DA-B332-D90E59CB95FB
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
	charset=utf-8

<html><head><meta http-equiv=3D"content-type" content=3D"text/html; =
charset=3Dutf-8"></head><body style=3D"overflow-wrap: break-word; =
-webkit-nbsp-mode: space; line-break: after-white-space;">First of all, =
I=E2=80=99d like to thank the ReportLab people for releasing such a =
fabulous open-source toolkit. It truly makes generating PDFs so much =
easier!<div><br></div><div>The problem I=E2=80=99m reporting affects =
users that have enabled FIPS mode on their systems. In my particular =
case, it is a RHEL 9.6 system. When in FIPS mode, certain cryptographic =
functions are not permitted because of weaknesses in the algorithms. In =
the case of ReportLab, this would be the MD5 function which is used to =
calculate a document ID and is also used to track fonts used, and a few =
other things, as well as in the PDF encryption functions =
themselves.</div><div><br></div><div>When in FIPS mode, running a =
program will cause an exception similar to:</div><div><br></div><div><p =
style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">Traceback (most recent call last):</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">&nbsp; File "/opt/dftoolkit/bin/annotateCRF", line =
82, in main</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">&nbsp; &nbsp; =
annotate.build_pdf(plate_filter=3Dargs.plates)</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">&nbsp; File =
"//opt/dftoolkit/lib/python3.9/site-packages/dftoolkit/annotate.py", =
line 549, in build_pdf</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">&nbsp; &nbsp; self.doc.build(flowables)</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">&nbsp; File =
"//opt/dftoolkit/lib/python3.9/site-packages/reportlab/platypus/doctemplat=
e.py", line 1062, in build</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">&nbsp; &nbsp; =
self._startBuild(filename,canvasmaker)</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">&nbsp; File =
"//opt/dftoolkit/lib/python3.9/site-packages/reportlab/platypus/doctemplat=
e.py", line 1032, in _startBuild</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">&nbsp; &nbsp; self.canv =3D =
self._makeCanvas(filename=3Dfilename,canvasmaker=3Dcanvasmaker)</span></p>=

<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">&nbsp; File =
"//opt/dftoolkit/lib/python3.9/site-packages/reportlab/platypus/doctemplat=
e.py", line 992, in _makeCanvas</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">&nbsp; &nbsp; canv =3D canvasmaker(filename or =
self.filename,</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">&nbsp; File =
"//opt/dftoolkit/lib/python3.9/site-packages/reportlab/pdfgen/canvas.py", =
line 320, in __init__</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">&nbsp; &nbsp; self._doc =3D =
pdfdoc.PDFDocument(compression=3DpageCompression,</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">&nbsp; File =
"//opt/dftoolkit/lib/python3.9/site-packages/reportlab/pdfbase/pdfdoc.py",=
 line 137, in __init__</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">&nbsp; &nbsp; sig =3D self.signature =3D =
md5()</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">ValueError: [digital envelope routines] =
unsupported</span></p></div><div><br></div><div>Most of the uses of MD5, =
aside from the use in the actual PDF encryption, appear not to be =
security related. In Python 3.9, the hashlib functions can be passed a =
keyword argument called =E2=80=98usedforsecurity=E2=80=99 (defaulting to =
True) that can be set to False if the hash algorithm isn=E2=80=99t used =
for security purposes. This allows the use of MD5 hashes even on FIPS =
enabled systems and allows ReportLab to successfully generate PDFs. =
Passing this keyword argument on the older Python 3.6.8 doesn=E2=80=99t =
cause any ill effects.</div><div><br></div><div>A small test program =
demonstrating the hashlib problem on a FIPS enabled system, and the fix =
using usedforsecurity=3DFalse is as =
follows:</div><div><br></div><div><span style=3D"font-family: Menlo; =
font-size: 11px;">$ more md5test.py</span></div><div><p style=3D"margin: =
0px; font-style: normal; font-variant-caps: normal; font-stretch: =
normal; font-size: 11px; line-height: normal; font-family: Menlo; =
font-size-adjust: none; font-kerning: auto; font-variant-alternates: =
normal; font-variant-ligatures: normal; font-variant-numeric: normal; =
font-variant-east-asian: normal; font-variant-position: normal; =
font-variant-emoji: normal; font-feature-settings: normal; =
font-optical-sizing: auto; font-variation-settings: normal;"><span =
style=3D"font-variant-ligatures: no-common-ligatures">from hashlib =
import md5</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">m =3D md5()</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">m.update(b'This is a test')</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">print(m.hexdigest())</span></p><p style=3D"margin: =
0px; font-style: normal; font-variant-caps: normal; font-stretch: =
normal; font-size: 11px; line-height: normal; font-family: Menlo; =
font-size-adjust: none; font-kerning: auto; font-variant-alternates: =
normal; font-variant-ligatures: normal; font-variant-numeric: normal; =
font-variant-east-asian: normal; font-variant-position: normal; =
font-variant-emoji: normal; font-feature-settings: normal; =
font-optical-sizing: auto; font-variation-settings: normal;"><span =
style=3D"font-variant-ligatures: no-common-ligatures"><br></span></p><p =
style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">$ python md5test.py</span></p><p style=3D"margin: =
0px; font-style: normal; font-variant-caps: normal; font-stretch: =
normal; font-size: 11px; line-height: normal; font-family: Menlo; =
font-size-adjust: none; font-kerning: auto; font-variant-alternates: =
normal; font-variant-ligatures: normal; font-variant-numeric: normal; =
font-variant-east-asian: normal; font-variant-position: normal; =
font-variant-emoji: normal; font-feature-settings: normal; =
font-optical-sizing: auto; font-variation-settings: normal;"><span =
style=3D"font-variant-ligatures: no-common-ligatures">Traceback (most =
recent call last):</span></p><p style=3D"margin: 0px; font-style: =
normal; font-variant-caps: normal; font-stretch: normal; font-size: =
11px; line-height: normal; font-family: Menlo; font-size-adjust: none; =
font-kerning: auto; font-variant-alternates: normal; =
font-variant-ligatures: normal; font-variant-numeric: normal; =
font-variant-east-asian: normal; font-variant-position: normal; =
font-variant-emoji: normal; font-feature-settings: normal; =
font-optical-sizing: auto; font-variation-settings: normal;"><span =
style=3D"font-variant-ligatures: no-common-ligatures">&nbsp; File =
"/home/martin/md5test.py", line 2, in &lt;module&gt;</span></p><p =
style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">&nbsp; &nbsp; m =3D md5()</span></p><p =
style=3D"margin: 0px; font-stretch: normal; font-size: 11px; =
line-height: normal; font-family: Menlo; font-size-adjust: none; =
font-kerning: auto; font-variant-alternates: normal; =
font-variant-ligatures: normal; font-variant-numeric: normal; =
font-variant-east-asian: normal; font-variant-position: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">



</span></p><p style=3D"margin: 0px; font-style: normal; =
font-variant-caps: normal; font-stretch: normal; font-size: 11px; =
line-height: normal; font-family: Menlo; font-size-adjust: none; =
font-kerning: auto; font-variant-alternates: normal; =
font-variant-ligatures: normal; font-variant-numeric: normal; =
font-variant-east-asian: normal; font-variant-position: normal; =
font-variant-emoji: normal; font-feature-settings: normal; =
font-optical-sizing: auto; font-variation-settings: normal;"><span =
style=3D"font-variant-ligatures: no-common-ligatures">ValueError: =
[digital envelope routines] unsupported</span></p><p style=3D"margin: =
0px; font-style: normal; font-variant-caps: normal; font-stretch: =
normal; font-size: 11px; line-height: normal; font-family: Menlo; =
font-size-adjust: none; font-kerning: auto; font-variant-alternates: =
normal; font-variant-ligatures: normal; font-variant-numeric: normal; =
font-variant-east-asian: normal; font-variant-position: normal; =
font-variant-emoji: normal; font-feature-settings: normal; =
font-optical-sizing: auto; font-variation-settings: normal;"><span =
style=3D"font-variant-ligatures: =
no-common-ligatures"><br></span></p></div><div>Changing the m=3Dmd5() to =
m=3Dmd5(usedforsecurity=3DFalse) causes it to run =
successfully:</div><div><br></div><div><p style=3D"margin: 0px; =
font-style: normal; font-variant-caps: normal; font-stretch: normal; =
font-size: 11px; line-height: normal; font-family: Menlo; =
font-size-adjust: none; font-kerning: auto; font-variant-alternates: =
normal; font-variant-ligatures: normal; font-variant-numeric: normal; =
font-variant-east-asian: normal; font-variant-position: normal; =
font-variant-emoji: normal; font-feature-settings: normal; =
font-optical-sizing: auto; font-variation-settings: normal;"><span =
style=3D"font-variant-ligatures: no-common-ligatures">$ more =
md5test.py</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">from hashlib import md5</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">m =3D md5(usedforsecurity=3DFalse)</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">m.update(b'This is a test')</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">print(m.hexdigest())</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures"><br></span></p><p style=3D"margin: 0px; font-style: =
normal; font-variant-caps: normal; font-stretch: normal; font-size: =
11px; line-height: normal; font-family: Menlo; font-size-adjust: none; =
font-kerning: auto; font-variant-alternates: normal; =
font-variant-ligatures: normal; font-variant-numeric: normal; =
font-variant-east-asian: normal; font-variant-position: normal; =
font-variant-emoji: normal; font-feature-settings: normal; =
font-optical-sizing: auto; font-variation-settings: normal;"><span =
style=3D"font-variant-ligatures: no-common-ligatures">$ python =
md5test.py</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">ce114e4501d2f4e2dcea3e17b546f339</span></p></div><div=
><span style=3D"font-variant-ligatures: =
no-common-ligatures"><br></span></div><div>Attached is a patch that adds =
the usedforsecurity=3DFalse parameter in the cases I believe are not =
security related. Alternatively, a different hash function permitted by =
FIPS could be used. The actual PDF encryption code isn=E2=80=99t =
modified by this patch and it will probably require the use of different =
algorithms to be FIPS compatible.</div><div><br></div><div>Thanks for =
considering this =
patch,</div><div><br></div><div>Martin</div><div><br></div><div><div><div>=
diff -ru =
../venv3.9/lib/python3.9/site-packages/reportlab/lib/fontfinder.py =
reportlab/lib/fontfinder.py</div><div>--- =
../venv3.9/lib/python3.9/site-packages/reportlab/lib/fontfinder.py<span =
class=3D"Apple-tab-span" style=3D"white-space:pre">	=
</span>2025-06-27 12:37:23.507252855 -0400</div><div>+++ =
reportlab/lib/fontfinder.py<span class=3D"Apple-tab-span" =
style=3D"white-space:pre">	</span>2025-06-29 15:08:52.470092313 =
-0400</div><div>@@ -216,7 +216,7 @@</div><div>&nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp;"""Base this on the directories...same set of =
directories</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;should give same =
cache"""</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fsEncoding =3D =
self._fsEncoding</div><div>- &nbsp; &nbsp; &nbsp; &nbsp;hash =3D =
md5(b''.join(asBytes(_,enc=3DfsEncoding) for _ in =
sorted(self._dirs))).hexdigest()</div><div>+ &nbsp; &nbsp; &nbsp; =
&nbsp;hash =3D md5(b''.join(asBytes(_,enc=3DfsEncoding) for _ in =
sorted(self._dirs)),usedforsecurity=3DFalse).hexdigest()</div><div>&nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp;from reportlab.lib.utils import =
get_rl_tempfile</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fn =3D =
get_rl_tempfile('fonts_%s.dat' % hash)</div><div>&nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp;return fn</div><div>diff -ru =
../venv3.9/lib/python3.9/site-packages/reportlab/lib/utils.py =
reportlab/lib/utils.py</div><div>--- =
../venv3.9/lib/python3.9/site-packages/reportlab/lib/utils.py<span =
class=3D"Apple-tab-span" style=3D"white-space:pre">	=
</span>2025-06-27 12:37:23.512252786 -0400</div><div>+++ =
reportlab/lib/utils.py<span class=3D"Apple-tab-span" =
style=3D"white-space:pre">	</span>2025-06-29 15:08:52.473092276 =
-0400</div><div>@@ -55,7 +55,7 =
@@</div><div>&nbsp;_rl_NoneType=3Dtype(None)</div><div>&nbsp;strTypes =3D =
(str,bytes)</div><div>&nbsp;def _digester(s):</div><div>- &nbsp; =
&nbsp;return md5(s if isBytes(s) else =
s.encode('utf8')).hexdigest()</div><div>+ &nbsp; &nbsp;return md5(s if =
isBytes(s) else =
s.encode('utf8'),usedforsecurity=3DFalse).hexdigest()</div><div>&nbsp;</di=
v><div>&nbsp;def asBytes(v,enc=3D'utf8'):</div><div>&nbsp; &nbsp; =
&nbsp;if isinstance(v,bytes): return v</div><div>diff -ru =
../venv3.9/lib/python3.9/site-packages/reportlab/pdfbase/cidfonts.py =
reportlab/pdfbase/cidfonts.py</div><div>--- =
../venv3.9/lib/python3.9/site-packages/reportlab/pdfbase/cidfonts.py<span =
class=3D"Apple-tab-span" style=3D"white-space:pre">	=
</span>2025-06-27 12:37:23.519252690 -0400</div><div>+++ =
reportlab/pdfbase/cidfonts.py<span class=3D"Apple-tab-span" =
style=3D"white-space:pre">	</span>2025-06-29 15:08:52.668089932 =
-0400</div><div>@@ -85,7 +85,7 @@</div><div>&nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp;self.parseCMAPFile(name)</div><div>&nbsp;</div><div>&nbsp; &nbsp; =
&nbsp;def _hash(self, text):</div><div>- &nbsp; &nbsp; &nbsp; =
&nbsp;hasher =3D md5()</div><div>+ &nbsp; &nbsp; &nbsp; &nbsp;hasher =3D =
md5(usedforsecurity=3DFalse)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp;hasher.update(text)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp;return hasher.digest()</div><div>&nbsp;</div><div>diff -ru =
../venv3.9/lib/python3.9/site-packages/reportlab/pdfbase/pdfdoc.py =
reportlab/pdfbase/pdfdoc.py</div><div>--- =
../venv3.9/lib/python3.9/site-packages/reportlab/pdfbase/pdfdoc.py<span =
class=3D"Apple-tab-span" style=3D"white-space:pre">	=
</span>2025-06-27 12:37:23.520252676 -0400</div><div>+++ =
reportlab/pdfbase/pdfdoc.py<span class=3D"Apple-tab-span" =
style=3D"white-space:pre">	</span>2025-06-29 15:08:52.672089884 =
-0400</div><div>@@ -134,7 +134,7 @@</div><div>&nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp;self.setCompression(compression)</div><div>&nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp;self._pdfVersion =3D pdfVersion</div><div>&nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp;# signature for creating PDF ID</div><div>- =
&nbsp; &nbsp; &nbsp; &nbsp;sig =3D self.signature =3D md5()</div><div>+ =
&nbsp; &nbsp; &nbsp; &nbsp;sig =3D self.signature =3D =
md5(usedforsecurity=3DFalse)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp;sig.update(b"a reportlab document")</div><div>&nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp;self._timeStamp =3D =
TimeStamp(self.invariant)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp;cat =3D self._timeStamp.t</div><div>diff -ru =
../venv3.9/lib/python3.9/site-packages/reportlab/pdfgen/canvas.py =
reportlab/pdfgen/canvas.py</div><div>--- =
../venv3.9/lib/python3.9/site-packages/reportlab/pdfgen/canvas.py<span =
class=3D"Apple-tab-span" style=3D"white-space:pre">	=
</span>2025-06-27 12:37:23.523252635 -0400</div><div>+++ =
reportlab/pdfgen/canvas.py<span class=3D"Apple-tab-span" =
style=3D"white-space:pre">	</span>2025-06-29 15:08:52.786088514 =
-0400</div><div>@@ -1131,9 +1131,9 @@</div><div>&nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp;"""</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;#check if =
we've done this one already...</div><div>&nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp;if isUnicode(command):</div><div>- &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp;rawName =3D 'PS' + =
hashlib.md5(command.encode('utf-8')).hexdigest()</div><div>+ &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rawName =3D 'PS' + =
hashlib.md5(command.encode('utf-8'),usedforsecurity=3DFalse).hexdigest()</=
div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else:</div><div>- &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rawName =3D 'PS' + =
hashlib.md5(command).hexdigest()</div><div>+ &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp;rawName =3D 'PS' + =
hashlib.md5(command,usedforsecurity=3DFalse).hexdigest()</div><div>&nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp;regName =3D =
self._doc.getXObjectName(rawName)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp;psObj =3D self._doc.idToObject.get(regName, None)</div><div>&nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp;if not =
psObj:</div></div></div><div><br></div></body></html>=

--Apple-Mail=_247A24E9-6E45-45DA-B332-D90E59CB95FB--

--===============6416592183070504230==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline