Monday, November 20, 2023

SAML, RHEL7 and you

Updating to a new IDP with Django 2.2 & Djangosaml2 on Python 3.6

The Bechtel Center @ Purdue uses a lightweight Project Management System that I created using Django 2.2, the Djangosaml2 project built on PySAML2, and Python 3.6. Now in 2023 both the Python interpreter version and the Django version are very much End of Life.

Purdue has been updating its SAML provider as a member of Internet2 / InCommon and switching my development environment SP to the new credentials failed to log in with the following error:

ERROR ::2023-11-10 16:47:47,443::sigver sigver.py:850 ::returncode=1
error=func=xmlSecTransformNodeRead:file=transforms.c:line=1549:obj=unknown:subj=xmlSecTransformIdListFindByHref:error=1:xmlsec library function failed:href=http://www.w3.org/2009/xmlenc11#aes128-gcm
func=xmlSecTransformCtxNodeRead:file=transforms.c:line=694:obj=unknown:subj=xmlSecTransformNodeRead:error=1:xmlsec library function failed:name=EncryptionMethod
func=xmlSecEncCtxEncDataNodeRead:file=xmlenc.c:line=905:obj=unknown:subj=xmlSecTransformCtxNodeRead:error=1:xmlsec library function failed:node=EncryptionMethod
func=xmlSecEncCtxDecryptToBuffer:file=xmlenc.c:line=715:obj=unknown:subj=xmlSecEncCtxEncDataNodeRead:error=1:xmlsec library function failed:
func=xmlSecEncCtxDecrypt:file=xmlenc.c:line=623:obj=unknown:subj=xmlSecEncCtxDecryptToBuffer:error=1:xmlsec library function failed:
Error: failed to decrypt file
Error: failed to decrypt file "/tmp/tmptkxst803"

output=
ERROR ::2023-11-10 16:47:47,458::sigver sigver.py:850 ::returncode=1
error=func=xmlSecTransformNodeRead:file=transforms.c:line=1549:obj=unknown:subj=xmlSecTransformIdListFindByHref:error=1:xmlsec library function failed:href=http://www.w3.org/2009/xmlenc11#aes128-gcm
func=xmlSecTransformCtxNodeRead:file=transforms.c:line=694:obj=unknown:subj=xmlSecTransformNodeRead:error=1:xmlsec library function failed:name=EncryptionMethod
func=xmlSecEncCtxEncDataNodeRead:file=xmlenc.c:line=905:obj=unknown:subj=xmlSecTransformCtxNodeRead:error=1:xmlsec library function failed:node=EncryptionMethod
func=xmlSecEncCtxDecryptToBuffer:file=xmlenc.c:line=715:obj=unknown:subj=xmlSecEncCtxEncDataNodeRead:error=1:xmlsec library function failed:
func=xmlSecEncCtxDecrypt:file=xmlenc.c:line=623:obj=unknown:subj=xmlSecEncCtxDecryptToBuffer:error=1:xmlsec library function failed:
Error: failed to decrypt file
Error: failed to decrypt file "/tmp/tmpmpjdtmyj"

After going down several rabbit-holes, testing different signing algorithms, I finally read the error message carefully.

The error comes from the xmlsec1 binary which is used to perform the actual cryptographic functions needed by PySAML2, namely signing, verification and encrypt/decryption, and actually clearly states the issue in the first line:

error=func=xmlSecTransformNodeRead:file=transforms.c:line=1549:obj=unknown:subj=xmlSecTransformIdListFindByHref:error=1:xmlsec library function failed:href=http://www.w3.org/2009/xmlenc11#aes128-gcm

 Breaking it down into pieces and translating:

error=func=xmlSecTransformNodeRead:file=transforms.c:line=1549:obj=unknown:

 - Error reading a node in the target XML file due to an unknown object (executable code)

file=transforms.c:line=1549:obj=unknown:

 - Error reading a node in the XML file

subj=xmlSecTransformIdListFindByHref:error=1:xmlsec library function failed:href=http://www.w3.org/2009/xmlenc11#aes128-gcm:

 - The missing executable code referred to in the target XML file is identified by the URL 'http://www.w3.org/2009/xmlenc11#aes128-gcm'

Specifically the last part "aes128-gcm" refers to an encryption/decryption algorithm based on the AES algorithm. Now encryption is a very complex and difficult subject, as security is almost impossible to generalize, and even minor changes in how it applies can completely change its effectiveness. However it seems that the specific implementations in the 2001 W3C XML Encryption Standard require AES CBC and were completely vulnerable to attack, detailed by Matthew Green here

However, if we look at the xmlsec1 changelog here https://www.aleksey.com/xmlsec/news.html, AES CBC support was added to the xmlsec1 (openssl) edition in version 1.2.27 on  October 23 2018, and the version shipped with RHEL 7 is xmlsec1 (openssl) 1.2.20. Creating a local copy is not easy as xmlsec1 relies on libXML, OpenSSL, and other system packages, and compiling/linking against secure versions of them is not a trivial exercise.

Luckily they were able to downgrade the requirements back to AES128-CBC for my specific SP and mitigate the risks as all IDP/SP request/responses are only available over SSL, however time to finish up the OS2 replacement built on RHEL 8, Python 3.11 with a more modern xmlsec1!

Laird Tpcm 7250 is as good as Honeywell PTM7950 as thermal paste / interface for PC

[This is not very scientific, however it is notable. At 7.5W/m-K vs the installed SYY-157 at 15.7 W/m-K it performed better in real world lo...