Re: ReportLab fails with ValueError on FIPS enabled systems

Martin Renters via reportlab-users <[email protected]> Mon, 14 Jul 2025 16:06:06 -0400
Newsgroups gmane.comp.python.reportlab.user
Message-ID <[email protected]>
--===============4737996655217945473==
Content-Type: multipart/alternative;
	boundary="Apple-Mail=_29884004-5BD2-42BD-B5D0-0F4183907531"


--Apple-Mail=_29884004-5BD2-42BD-B5D0-0F4183907531
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=utf-8

Hi Andy,

I=E2=80=99m just following up to see how the review is going and whether =
you need anything else from me. Do you have an anticipated release date =
for the next version which will include this FIP fix?

Thanks,

Martin


> On Jun 30, 2025, at 2:38=E2=80=AFAM, Andy Robinson =
<[email protected]> wrote:
>=20
> 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.
>=20
> --
> Andy Robinson
> Managing Director, ReportLab
>=20
> On Mon, 30 Jun 2025 at 02:14, Martin Renters via reportlab-users =
<[email protected] =
<mailto:[email protected]>> wrote:
>> 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!
>>=20
>> 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.
>>=20
>> When in FIPS mode, running a program will cause an exception similar =
to:
>>=20
>> 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
>>=20
>> 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.
>>=20
>> A small test program demonstrating the hashlib problem on a FIPS =
enabled system, and the fix using usedforsecurity=3DFalse is as follows:
>>=20
>> $ more md5test.py
>> from hashlib import md5
>> m =3D md5()
>> m.update(b'This is a test')
>> print(m.hexdigest())
>>=20
>> $ 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
>>=20
>> Changing the m=3Dmd5() to m=3Dmd5(usedforsecurity=3DFalse) causes it =
to run successfully:
>>=20
>> $ more md5test.py
>> from hashlib import md5
>> m =3D md5(usedforsecurity=3DFalse)
>> m.update(b'This is a test')
>> print(m.hexdigest())
>>=20
>> $ python md5test.py
>> ce114e4501d2f4e2dcea3e17b546f339
>>=20
>> 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.
>>=20
>> Thanks for considering this patch,
>>=20
>> Martin
>>=20
>> 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:
>>=20
>> _______________________________________________
>> reportlab-users mailing list
>> [email protected] =
<mailto:[email protected]>
>> https://pairlist2.pair.net/mailman/listinfo/reportlab-users
>=20
>=20
>=20


--Apple-Mail=_29884004-5BD2-42BD-B5D0-0F4183907531
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;">Hi =
Andy,<div><br></div><div>I=E2=80=99m just following up to see how the =
review is going and whether you need anything else from me. Do you have =
an anticipated release date for the next version which will include this =
FIP =
fix?</div><div><br></div><div>Thanks,</div><div><br></div><div>Martin</div=
><div><br id=3D"lineBreakAtBeginningOfMessage"><div><br><blockquote =
type=3D"cite"><div>On Jun 30, 2025, at 2:38=E2=80=AFAM, Andy Robinson =
&lt;[email protected]&gt; wrote:</div><br =
class=3D"Apple-interchange-newline"><div><div dir=3D"ltr"><div =
dir=3D"ltr">Martin, thanks for this!&nbsp; I had never heard of FIPS but =
this certainly seems harmless and something we could include in an =
upcoming release.&nbsp; I'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 Robinson<br>Managing =
Director, ReportLab<br></div><div =
dir=3D"ltr"><br></div></div></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]">reportlab-users@lists=
2.reportlab.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" =
style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid =
rgb(204,204,204);padding-left:1ex"><div>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><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">Traceback (most =
recent call last):</span></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">&nbsp; File =
"/opt/dftoolkit/bin/annotateCRF", line 82, in main</span></div><div =
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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">&nbsp; &nbsp; =
annotate.build_pdf(plate_filter=3Dargs.plates)</span></div><div =
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-feature-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></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">&nbsp; &nbsp; =
self.doc.build(flowables)</span></div><div 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-feature-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></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">&nbsp; &nbsp; =
self._startBuild(filename,canvasmaker)</span></div><div 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-feature-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></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">&nbsp; &nbsp; =
self.canv =3D =
self._makeCanvas(filename=3Dfilename,canvasmaker=3Dcanvasmaker)</span></di=
v><div 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-feature-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></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">&nbsp; &nbsp; canv =
=3D canvasmaker(filename or self.filename,</span></div><div =
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-feature-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></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">&nbsp; &nbsp; =
self._doc =3D =
pdfdoc.PDFDocument(compression=3DpageCompression,</span></div><div =
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-feature-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></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">&nbsp; &nbsp; sig =3D=
 self.signature =3D md5()</span></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">ValueError: =
[digital envelope routines] =
unsupported</span></div></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><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">from hashlib import =
md5</span></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">m =3D =
md5()</span></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">m.update(b'This is =
a test')</span></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">print(m.hexdigest())<=
/span></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures"><br></span></div><div=
 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">$ python =
md5test.py</span></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">Traceback (most =
recent call last):</span></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">&nbsp; File =
"/home/martin/md5test.py", line 2, in &lt;module&gt;</span></div><div =
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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">&nbsp; &nbsp; m =3D =
md5()</span></div><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-alt=
ernates:normal;font-variant-ligatures:normal;font-variant-numeric:normal;f=
ont-variant-east-asian:normal;font-feature-settings:normal"><span =
style=3D"font-variant-ligatures:no-common-ligatures">



</span></p><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">ValueError: =
[digital envelope routines] unsupported</span></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures"><br></span></div></di=
v><div>Changing the m=3Dmd5() to m=3Dmd5(usedforsecurity=3DFalse) causes =
it to run successfully:</div><div><br></div><div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">$ more =
md5test.py</span></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">from hashlib import =
md5</span></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">m =3D =
md5(usedforsecurity=3DFalse)</span></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">m.update(b'This is =
a test')</span></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">print(m.hexdigest())<=
/span></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures"><br></span></div><div=
 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">$ python =
md5test.py</span></div><div 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-feature-settings: normal;"><span =
style=3D"font-variant-ligatures:no-common-ligatures">ce114e4501d2f4e2dcea3=
e17b546f339</span></div></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 =
style=3D"white-space:pre-wrap">	</span>2025-06-27 12:37:23.507252855 =
-0400</div><div>+++ reportlab/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>&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 =
style=3D"white-space:pre-wrap">	</span>2025-06-27 12:37:23.512252786 =
-0400</div><div>+++ reportlab/lib/utils.py<span =
style=3D"white-space:pre-wrap">	</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 =
style=3D"white-space:pre-wrap">	</span>2025-06-27 12:37:23.519252690 =
-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>&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 =
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">	</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 =
style=3D"white-space:pre-wrap">	</span>2025-06-27 12:37:23.523252635 =
-0400</div><div>+++ reportlab/pdfgen/canvas.py<span =
style=3D"white-space:pre-wrap">	</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></div>_____________________________=
__________________<br>
reportlab-users mailing list<br>
<a href=3D"mailto:[email protected]" =
target=3D"_blank">[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/listinfo/reportlab-us=
ers</a><br>
</blockquote></div><div><br clear=3D"all"></div><div><br></div></div>
</div></blockquote></div><br></div></body></html>=

--Apple-Mail=_29884004-5BD2-42BD-B5D0-0F4183907531--

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