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 = <[email protected]> wrote:</div><br = class=3D"Apple-interchange-newline"><div><div dir=3D"ltr"><div = dir=3D"ltr">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.<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 <<a = href=3D"mailto:[email protected]">reportlab-users@lists= 2.reportlab.com</a>> 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"> 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"> = 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"> 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"> = 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"> 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"> = 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"> 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"> = 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"> 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"> 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"> 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"> = 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"> 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"> 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"> File = "/home/martin/md5test.py", line 2, in <module></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><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> = """Base this on the directories...same set of = directories</div><div> should give same = cache"""</div><div> fsEncoding =3D = self._fsEncoding</div><div>- hash =3D = md5(b''.join(asBytes(_,enc=3DfsEncoding) for _ in = sorted(self._dirs))).hexdigest()</div><div>+ = hash =3D md5(b''.join(asBytes(_,enc=3DfsEncoding) for _ in = sorted(self._dirs)),usedforsecurity=3DFalse).hexdigest()</div><div> = from reportlab.lib.utils import = get_rl_tempfile</div><div> fn =3D = get_rl_tempfile('fonts_%s.dat' % hash)</div><div> = 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> _rl_NoneType=3Dtype(None)</div><div> strTypes =3D = (str,bytes)</div><div> def _digester(s):</div><div>- = return md5(s if isBytes(s) else = s.encode('utf8')).hexdigest()</div><div>+ return md5(s if = isBytes(s) else = s.encode('utf8'),usedforsecurity=3DFalse).hexdigest()</div><div> </di= v><div> def asBytes(v,enc=3D'utf8'):</div><div> = 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> = = self.parseCMAPFile(name)</div><div> </div><div> = def _hash(self, text):</div><div>- = hasher =3D md5()</div><div>+ hasher =3D = md5(usedforsecurity=3DFalse)</div><div> = hasher.update(text)</div><div> = return hasher.digest()</div><div> </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> = self.setCompression(compression)</div><div> = self._pdfVersion =3D pdfVersion</div><div> = # signature for creating PDF ID</div><div>- = sig =3D self.signature =3D md5()</div><div>+ = sig =3D self.signature =3D = md5(usedforsecurity=3DFalse)</div><div> = sig.update(b"a reportlab document")</div><div> = self._timeStamp =3D = TimeStamp(self.invariant)</div><div> = 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> = """</div><div> #check if = we've done this one already...</div><div> = if isUnicode(command):</div><div>- = rawName =3D 'PS' + = hashlib.md5(command.encode('utf-8')).hexdigest()</div><div>+ = rawName =3D 'PS' + = hashlib.md5(command.encode('utf-8'),usedforsecurity=3DFalse).hexdigest()</= div><div> else:</div><div>- = rawName =3D 'PS' + = hashlib.md5(command).hexdigest()</div><div>+ = rawName =3D 'PS' + = hashlib.md5(command,usedforsecurity=3DFalse).hexdigest()</div><div> = regName =3D = self._doc.getXObjectName(rawName)</div><div> = psObj =3D self._doc.idToObject.get(regName, None)</div><div> = 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