Re: ReportLab fails with ValueError on FIPS enabled systems

Andy Robinson <[email protected]> Mon, 30 Jun 2025 08:38:35 +0200
Newsgroups gmane.comp.python.reportlab.user
Message-ID <CABjtApuxQza5RFAri1r3AP6F54Ni72gMgiQp_euqeoKFaWt8YQ@mail.gmail.com>
--===============4359365736090289006==
Content-Type: multipart/alternative; boundary="000000000000a2339e0638c447d5"

--000000000000a2339e0638c447d5
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Martin, thanks for this!  I had never heard of FIPS but this certainly
seems harmless and something we could include in an upcoming release.  I'll
wait for my colleague Robin to review.

--
Andy Robinson
Managing Director, ReportLab

On Mon, 30 Jun 2025 at 02:14, Martin Renters via reportlab-users <
[email protected]> wrote:

> First of all, I=E2=80=99d like to thank the ReportLab people for releasin=
g such a
> fabulous open-source toolkit. It truly makes generating PDFs so much easi=
er!
>
> The problem I=E2=80=99m reporting affects users that have enabled FIPS mo=
de on
> their systems. In my particular case, it is a RHEL 9.6 system. When in FI=
PS
> 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 encryptio=
n
> 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/doctempla=
te.py",
> line 1062, in build
>
>     self._startBuild(filename,canvasmaker)
>
>   File
> "//opt/dftoolkit/lib/python3.9/site-packages/reportlab/platypus/doctempla=
te.py",
> line 1032, in _startBuild
>
>     self.canv =3D self._makeCanvas(filename=3Dfilename,canvasmaker=3Dcanv=
asmaker)
>
>   File
> "//opt/dftoolkit/lib/python3.9/site-packages/reportlab/platypus/doctempla=
te.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 c=
an
> be passed a keyword argument called =E2=80=98usedforsecurity=E2=80=99 (de=
faulting to True)
> that can be set to False if the hash algorithm isn=E2=80=99t used for sec=
urity
> 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 r=
un
> 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 th=
e
> 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 20=
25-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()
>
>  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)
>
>      def _hash(self, text):
> -        hasher =3D md5()
> +        hasher =3D md5(usedforsecurity=3DFalse)
>          hasher.update(text)
>          return hasher.digest()
>
> 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 20=
25-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.p=
y
> reportlab/pdfgen/canvas.py
> --- ../venv3.9/lib/python3.9/site-packages/reportlab/pdfgen/canvas.py 202=
5-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:
>
> _______________________________________________
> reportlab-users mailing list
> [email protected]
> https://pairlist2.pair.net/mailman/listinfo/reportlab-users
>

--000000000000a2339e0638c447d5
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div dir=3D"ltr">Martin, thanks for this!=C2=A0 I had neve=
r heard of FIPS but this certainly seems harmless and something we could in=
clude in an upcoming release.=C2=A0 I&#39;ll wait for my colleague Robin to=
 review.<div><br></div><div><span class=3D"gmail_signature_prefix">--</span=
><br><div dir=3D"ltr" class=3D"gmail_signature"><div dir=3D"ltr">Andy Robin=
son<br>Managing Director, ReportLab<br></div><div dir=3D"ltr"><br></div></d=
iv></div></div><div class=3D"gmail_quote gmail_quote_container"><div dir=3D=
"ltr" class=3D"gmail_attr">On Mon, 30 Jun 2025 at 02:14, Martin Renters via=
 reportlab-users &lt;<a href=3D"mailto:[email protected]=
">[email protected]</a>&gt; wrote:<br></div><blockquote =
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px sol=
id rgb(204,204,204);padding-left:1ex"><div>First of all, I=E2=80=99d like t=
o thank the ReportLab people for releasing such a fabulous open-source tool=
kit. 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 weaknes=
ses in the algorithms. In the case of ReportLab, this would be the MD5 func=
tion which is used to calculate a document ID and is also used to track fon=
ts 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"ma=
rgin:0px;font-style:normal;font-variant-caps:normal;font-stretch:normal;fon=
t-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-feature-set=
tings:normal"><span style=3D"font-variant-ligatures:no-common-ligatures">Tr=
aceback (most recent call last):</span></p>
<p style=3D"margin:0px;font-style:normal;font-variant-caps:normal;font-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-settings:normal"><span style=3D"font-variant-ligatures:no-common=
-ligatures">=C2=A0 File &quot;/opt/dftoolkit/bin/annotateCRF&quot;, line 82=
, in main</span></p>
<p style=3D"margin:0px;font-style:normal;font-variant-caps:normal;font-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-settings:normal"><span style=3D"font-variant-ligatures:no-common=
-ligatures">=C2=A0 =C2=A0 annotate.build_pdf(plate_filter=3Dargs.plates)</s=
pan></p>
<p style=3D"margin:0px;font-style:normal;font-variant-caps:normal;font-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-settings:normal"><span style=3D"font-variant-ligatures:no-common=
-ligatures">=C2=A0 File &quot;//opt/dftoolkit/lib/python3.9/site-packages/d=
ftoolkit/annotate.py&quot;, line 549, in build_pdf</span></p>
<p style=3D"margin:0px;font-style:normal;font-variant-caps:normal;font-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-settings:normal"><span style=3D"font-variant-ligatures:no-common=
-ligatures">=C2=A0 =C2=A0 self.doc.build(flowables)</span></p>
<p style=3D"margin:0px;font-style:normal;font-variant-caps:normal;font-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-settings:normal"><span style=3D"font-variant-ligatures:no-common=
-ligatures">=C2=A0 File &quot;//opt/dftoolkit/lib/python3.9/site-packages/r=
eportlab/platypus/doctemplate.py&quot;, line 1062, in build</span></p>
<p style=3D"margin:0px;font-style:normal;font-variant-caps:normal;font-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-settings:normal"><span style=3D"font-variant-ligatures:no-common=
-ligatures">=C2=A0 =C2=A0 self._startBuild(filename,canvasmaker)</span></p>
<p style=3D"margin:0px;font-style:normal;font-variant-caps:normal;font-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-settings:normal"><span style=3D"font-variant-ligatures:no-common=
-ligatures">=C2=A0 File &quot;//opt/dftoolkit/lib/python3.9/site-packages/r=
eportlab/platypus/doctemplate.py&quot;, line 1032, in _startBuild</span></p=
>
<p style=3D"margin:0px;font-style:normal;font-variant-caps:normal;font-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-settings:normal"><span style=3D"font-variant-ligatures:no-common=
-ligatures">=C2=A0 =C2=A0 self.canv =3D self._makeCanvas(filename=3Dfilenam=
e,canvasmaker=3Dcanvasmaker)</span></p>
<p style=3D"margin:0px;font-style:normal;font-variant-caps:normal;font-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-settings:normal"><span style=3D"font-variant-ligatures:no-common=
-ligatures">=C2=A0 File &quot;//opt/dftoolkit/lib/python3.9/site-packages/r=
eportlab/platypus/doctemplate.py&quot;, line 992, in _makeCanvas</span></p>
<p style=3D"margin:0px;font-style:normal;font-variant-caps:normal;font-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-settings:normal"><span style=3D"font-variant-ligatures:no-common=
-ligatures">=C2=A0 =C2=A0 canv =3D canvasmaker(filename or self.filename,</=
span></p>
<p style=3D"margin:0px;font-style:normal;font-variant-caps:normal;font-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-settings:normal"><span style=3D"font-variant-ligatures:no-common=
-ligatures">=C2=A0 File &quot;//opt/dftoolkit/lib/python3.9/site-packages/r=
eportlab/pdfgen/canvas.py&quot;, line 320, in __init__</span></p>
<p style=3D"margin:0px;font-style:normal;font-variant-caps:normal;font-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-settings:normal"><span style=3D"font-variant-ligatures:no-common=
-ligatures">=C2=A0 =C2=A0 self._doc =3D pdfdoc.PDFDocument(compression=3Dpa=
geCompression,</span></p>
<p style=3D"margin:0px;font-style:normal;font-variant-caps:normal;font-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-settings:normal"><span style=3D"font-variant-ligatures:no-common=
-ligatures">=C2=A0 File &quot;//opt/dftoolkit/lib/python3.9/site-packages/r=
eportlab/pdfbase/pdfdoc.py&quot;, line 137, in __init__</span></p>
<p style=3D"margin:0px;font-style:normal;font-variant-caps:normal;font-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-settings:normal"><span style=3D"font-variant-ligatures:no-common=
-ligatures">=C2=A0 =C2=A0 sig =3D self.signature =3D md5()</span></p>
<p style=3D"margin:0px;font-style:normal;font-variant-caps:normal;font-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-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, t=
he hashlib functions can be passed a keyword argument called =E2=80=98usedf=
orsecurity=E2=80=99 (defaulting to True) that can be set to False if the ha=
sh 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 successf=
ully 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 te=
st program demonstrating the hashlib problem on a FIPS enabled system, and =
the fix using usedforsecurity=3DFalse is as follows:</div><div><br></div><d=
iv><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:norm=
al;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-asi=
an:normal;font-feature-settings:normal"><span style=3D"font-variant-ligatur=
es:no-common-ligatures">from hashlib import md5</span></p>
<p style=3D"margin:0px;font-style:normal;font-variant-caps:normal;font-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-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-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-settings:normal"><span style=3D"font-variant-ligatures:no-common=
-ligatures">m.update(b&#39;This is a test&#39;)</span></p>
<p style=3D"margin:0px;font-style:normal;font-variant-caps:normal;font-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-settings:normal"><span style=3D"font-variant-ligatures:no-common=
-ligatures">print(m.hexdigest())</span></p><p style=3D"margin:0px;font-styl=
e:normal;font-variant-caps:normal;font-stretch:normal;font-size:11px;line-h=
eight:normal;font-family:Menlo;font-size-adjust:none;font-kerning:auto;font=
-variant-alternates:normal;font-variant-ligatures:normal;font-variant-numer=
ic:normal;font-variant-east-asian:normal;font-feature-settings:normal"><spa=
n style=3D"font-variant-ligatures:no-common-ligatures"><br></span></p><p st=
yle=3D"margin:0px;font-style:normal;font-variant-caps:normal;font-stretch:n=
ormal;font-size:11px;line-height:normal;font-family:Menlo;font-size-adjust:=
none;font-kerning:auto;font-variant-alternates:normal;font-variant-ligature=
s:normal;font-variant-numeric:normal;font-variant-east-asian:normal;font-fe=
ature-settings:normal"><span style=3D"font-variant-ligatures:no-common-liga=
tures">$ python md5test.py</span></p><p style=3D"margin:0px;font-style:norm=
al;font-variant-caps:normal;font-stretch:normal;font-size:11px;line-height:=
normal;font-family:Menlo;font-size-adjust:none;font-kerning:auto;font-varia=
nt-alternates:normal;font-variant-ligatures:normal;font-variant-numeric:nor=
mal;font-variant-east-asian:normal;font-feature-settings:normal"><span styl=
e=3D"font-variant-ligatures:no-common-ligatures">Traceback (most recent cal=
l last):</span></p><p style=3D"margin:0px;font-style:normal;font-variant-ca=
ps:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family=
:Menlo;font-size-adjust:none;font-kerning:auto;font-variant-alternates:norm=
al;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-e=
ast-asian:normal;font-feature-settings:normal"><span style=3D"font-variant-=
ligatures:no-common-ligatures">=C2=A0 File &quot;/home/martin/md5test.py&qu=
ot;, 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-hei=
ght:normal;font-family:Menlo;font-size-adjust:none;font-kerning:auto;font-v=
ariant-alternates:normal;font-variant-ligatures:normal;font-variant-numeric=
:normal;font-variant-east-asian:normal;font-feature-settings:normal"><span =
style=3D"font-variant-ligatures:no-common-ligatures">=C2=A0 =C2=A0 m =3D md=
5()</span></p><p style=3D"margin:0px;font-stretch:normal;font-size:11px;lin=
e-height:normal;font-family:Menlo;font-size-adjust:none;font-kerning:auto;f=
ont-variant-alternates:normal;font-variant-ligatures:normal;font-variant-nu=
meric:normal;font-variant-east-asian:normal;font-feature-settings:normal"><=
span style=3D"font-variant-ligatures:no-common-ligatures">



</span></p><p style=3D"margin:0px;font-style:normal;font-variant-caps:norma=
l;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;f=
ont-size-adjust:none;font-kerning:auto;font-variant-alternates:normal;font-=
variant-ligatures:normal;font-variant-numeric:normal;font-variant-east-asia=
n:normal;font-feature-settings:normal"><span style=3D"font-variant-ligature=
s: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;fo=
nt-size-adjust:none;font-kerning:auto;font-variant-alternates:normal;font-v=
ariant-ligatures:normal;font-variant-numeric:normal;font-variant-east-asian=
:normal;font-feature-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><b=
r></div><div><p style=3D"margin:0px;font-style:normal;font-variant-caps:nor=
mal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo=
;font-size-adjust:none;font-kerning:auto;font-variant-alternates:normal;fon=
t-variant-ligatures:normal;font-variant-numeric:normal;font-variant-east-as=
ian:normal;font-feature-settings:normal"><span style=3D"font-variant-ligatu=
res:no-common-ligatures">$ more md5test.py</span></p>
<p style=3D"margin:0px;font-style:normal;font-variant-caps:normal;font-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-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-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-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-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-settings:normal"><span style=3D"font-variant-ligatures:no-common=
-ligatures">m.update(b&#39;This is a test&#39;)</span></p>
<p style=3D"margin:0px;font-style:normal;font-variant-caps:normal;font-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-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-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-settings:normal"><span style=3D"font-variant-ligatures:no-common=
-ligatures"><br></span></p><p style=3D"margin:0px;font-style:normal;font-va=
riant-caps:normal;font-stretch:normal;font-size:11px;line-height:normal;fon=
t-family:Menlo;font-size-adjust:none;font-kerning:auto;font-variant-alterna=
tes:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-v=
ariant-east-asian:normal;font-feature-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-stre=
tch:normal;font-size:11px;line-height:normal;font-family:Menlo;font-size-ad=
just:none;font-kerning:auto;font-variant-alternates:normal;font-variant-lig=
atures:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fo=
nt-feature-settings:normal"><span style=3D"font-variant-ligatures:no-common=
-ligatures">ce114e4501d2f4e2dcea3e17b546f339</span></p></div><div><span sty=
le=3D"font-variant-ligatures:no-common-ligatures"><br></span></div><div>Att=
ached is a patch that adds the usedforsecurity=3DFalse parameter in the cas=
es I believe are not security related. Alternatively, a different hash func=
tion 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 diff=
erent algorithms to be FIPS compatible.</div><div><br></div><div>Thanks for=
 considering this patch,</div><div><br></div><div>Martin</div><div><br></di=
v><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 style=3D"white-spa=
ce:pre-wrap">	</span>2025-06-27 12:37:23.507252855 -0400</div><div>+++ repo=
rtlab/lib/fontfinder.py<span style=3D"white-space:pre-wrap">	</span>2025-06=
-29 15:08:52.470092313 -0400</div><div>@@ -216,7 +216,7 @@</div><div>=C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0&quot;&quot;&quot;Base this on the directories.=
..same set of directories</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0shoul=
d give same cache&quot;&quot;&quot;</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0fsEncoding =3D self._fsEncoding</div><div>- =C2=A0 =C2=A0 =C2=A0 =C2=
=A0hash =3D md5(b&#39;&#39;.join(asBytes(_,enc=3DfsEncoding) for _ in sorte=
d(self._dirs))).hexdigest()</div><div>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0hash =3D=
 md5(b&#39;&#39;.join(asBytes(_,enc=3DfsEncoding) for _ in sorted(self._dir=
s)),usedforsecurity=3DFalse).hexdigest()</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0from reportlab.lib.utils import get_rl_tempfile</div><div>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0fn =3D get_rl_tempfile(&#39;fonts_%s.dat&#39; % =
hash)</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return 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/reportla=
b/lib/utils.py<span style=3D"white-space:pre-wrap">	</span>2025-06-27 12:37=
:23.512252786 -0400</div><div>+++ reportlab/lib/utils.py<span style=3D"whit=
e-space:pre-wrap">	</span>2025-06-29 15:08:52.473092276 -0400</div><div>@@ =
-55,7 +55,7 @@</div><div>=C2=A0_rl_NoneType=3Dtype(None)</div><div>=C2=A0st=
rTypes =3D (str,bytes)</div><div>=C2=A0def _digester(s):</div><div>- =C2=A0=
 =C2=A0return md5(s if isBytes(s) else s.encode(&#39;utf8&#39;)).hexdigest(=
)</div><div>+ =C2=A0 =C2=A0return md5(s if isBytes(s) else s.encode(&#39;ut=
f8&#39;),usedforsecurity=3DFalse).hexdigest()</div><div>=C2=A0</div><div>=
=C2=A0def asBytes(v,enc=3D&#39;utf8&#39;):</div><div>=C2=A0 =C2=A0 =C2=A0if=
 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/cidfo=
nts.py<span style=3D"white-space:pre-wrap">	</span>2025-06-27 12:37:23.5192=
52690 -0400</div><div>+++ reportlab/pdfbase/cidfonts.py<span style=3D"white=
-space:pre-wrap">	</span>2025-06-29 15:08:52.668089932 -0400</div><div>@@ -=
85,7 +85,7 @@</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0self.parseCMAPFile(name)</div><div>=C2=A0</div><div>=C2=A0 =C2=
=A0 =C2=A0def _hash(self, text):</div><div>- =C2=A0 =C2=A0 =C2=A0 =C2=A0has=
her =3D md5()</div><div>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0hasher =3D md5(usedfor=
security=3DFalse)</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0hasher.update=
(text)</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return hasher.digest()</=
div><div>=C2=A0</div><div>diff -ru ../venv3.9/lib/python3.9/site-packages/r=
eportlab/pdfbase/pdfdoc.py reportlab/pdfbase/pdfdoc.py</div><div>--- ../ven=
v3.9/lib/python3.9/site-packages/reportlab/pdfbase/pdfdoc.py<span style=3D"=
white-space:pre-wrap">	</span>2025-06-27 12:37:23.520252676 -0400</div><div=
>+++ reportlab/pdfbase/pdfdoc.py<span style=3D"white-space:pre-wrap">	</spa=
n>2025-06-29 15:08:52.672089884 -0400</div><div>@@ -134,7 +134,7 @@</div><d=
iv>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self.setCompression(compression)</div>=
<div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self._pdfVersion =3D pdfVersion</div=
><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0# signature for creating PDF ID</di=
v><div>- =C2=A0 =C2=A0 =C2=A0 =C2=A0sig =3D self.signature =3D md5()</div><=
div>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0sig =3D self.signature =3D md5(usedforsecu=
rity=3DFalse)</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sig.update(b&quot=
;a reportlab document&quot;)</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0se=
lf._timeStamp =3D TimeStamp(self.invariant)</div><div>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0cat =3D self._timeStamp.t</div><div>diff -ru ../venv3.9/lib/py=
thon3.9/site-packages/reportlab/pdfgen/canvas.py reportlab/pdfgen/canvas.py=
</div><div>--- ../venv3.9/lib/python3.9/site-packages/reportlab/pdfgen/canv=
as.py<span style=3D"white-space:pre-wrap">	</span>2025-06-27 12:37:23.52325=
2635 -0400</div><div>+++ reportlab/pdfgen/canvas.py<span style=3D"white-spa=
ce:pre-wrap">	</span>2025-06-29 15:08:52.786088514 -0400</div><div>@@ -1131=
,9 +1131,9 @@</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&quot;&quot;&quot=
;</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0#check if we&#39;ve done this=
 one already...</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if isUnicode(co=
mmand):</div><div>- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rawName =3D &#=
39;PS&#39; + hashlib.md5(command.encode(&#39;utf-8&#39;)).hexdigest()</div>=
<div>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rawName =3D &#39;PS&#39; + =
hashlib.md5(command.encode(&#39;utf-8&#39;),usedforsecurity=3DFalse).hexdig=
est()</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else:</div><div>- =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rawName =3D &#39;PS&#39; + hashlib.md5(co=
mmand).hexdigest()</div><div>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0raw=
Name =3D &#39;PS&#39; + hashlib.md5(command,usedforsecurity=3DFalse).hexdig=
est()</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0regName =3D self._doc.get=
XObjectName(rawName)</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0psObj =3D =
self._doc.idToObject.get(regName, None)</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0if not psObj:</div></div></div><div><br></div></div>_____________=
__________________________________<br>
reportlab-users mailing list<br>
<a href=3D"mailto:[email protected]" target=3D"_blank">r=
[email protected]</a><br>
<a href=3D"https://pairlist2.pair.net/mailman/listinfo/reportlab-users" rel=
=3D"noreferrer" target=3D"_blank">https://pairlist2.pair.net/mailman/listin=
fo/reportlab-users</a><br>
</blockquote></div><div><br clear=3D"all"></div><div><br></div></div>

--000000000000a2339e0638c447d5--

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