Open gcoxmoz opened 1 week ago
When you made the change to response.content
- did you validate that the returned .p12 data actually worked in the certificate manager? I ask because when I attempt in a lab what you have suggested, I cannot do anything with the byte data. I also tried directly on the APIExplorer with different outputs and it fails there as well. I am able to download the certificate from ClearPass Guest. Reading the documentation states 'The response is file data and does not contain JSON', which is fine, just usable text. Thx.
When you made the change to
response.content
- did you validate that the returned .p12 data actually worked in the certificate manager?
Yes. I made a quick-and-dirty hack since I figured this was no quick fix in the API. This stripped-down override form of _send_request works:
p12_pass = 'THEPASSWORD'
import requests # pylint: disable=import-outside-toplevel
response = requests.post(
url=login.server + f'/certificate/{cert_id}/export',
json=data,
headers={"Authorization": "Bearer " + login.api_token},
verify=True,
)
cert_export = response.content
with open(f'/tmp/testfile-{p12_pass}.txt', 'wb') as f:
f.write(cert_export)
f.close()
Then, running openssl pkcs12 -noenc -in /tmp/testfile-THEPASSWORD.txt -passin pass:THEPASSWORD
gets me back the key and certs (and I can run it through pkcs12.load_key_and_certificates(cert_export, p12_pass.encode())
on the python side.
Sticking with the API...
cert_export = ApiCertificateAuthority.new_certificate_by_cert_id_export(login,
cert_id=str(cert_id),
body=data)
with open(f'/tmp/testfile-{p12_pass}.txt', 'w') as f:
f.write(cert_export)
f.close()
... results (looking up the same user/cert) in a testfile
that is 2x the size due to corruption, and that openssl can't deal with: 008CAD0202000000:error:0680007B:asn1 encoding routines:ASN1_get_object:header too long:crypto/asn1/asn1_lib.c:105:
Ok. I think the problem originates from the API not returning in JSON. Most content does, this seems to be an exception. I have an idea of an approach on how to fix properly and look for other similar issues but it will take some time and I will need to do a bit of testing before implementing the change. Will take a while :). Good job you have suitable documented workaround. Thanks for the detail and the support so far.
From: gcoxmoz @.> Sent: Tuesday, June 25, 2024 4:18:43 PM To: aruba/pyclearpass @.> Cc: jazzyj123 @.>; Assign @.> Subject: Re: [aruba/pyclearpass] _send_request mangles binary API responses (Issue #2)
When you made the change to response.content - did you validate that the returned .p12 data actually worked in the certificate manager?
Yes. I made a quick-and-dirty hack since I figured this was no quick fix in the API. This stripped-down override form of _send_request works:
p12_pass = 'THEPASSWORD'
import requests # pylint: disable=import-outside-toplevel
response = requests.post(
url=login.server + f'/certificate/{cert_id}/export',
json=data,
headers={"Authorization": "Bearer " + login.api_token},
verify=True,
)
cert_export = response.content
with open(f'/tmp/testfile-{p12_pass}.txt', 'wb') as f:
f.write(cert_export)
f.close()
Then, running openssl pkcs12 -noenc -in /tmp/testfile-THEPASSWORD.txt -passin pass:THEPASSWORD gets me back the key and certs (and I can run it through pkcs12.load_key_and_certificates(cert_export, p12_pass.encode()) on the python side.
Sticking with the API...
cert_export = ApiCertificateAuthority.new_certificate_by_cert_id_export(login,
cert_id=str(cert_id),
body=data)
with open(f'/tmp/testfile-{p12_pass}.txt', 'w') as f:
f.write(cert_export)
f.close()
... results (looking up the same user/cert) in a testfile that is 2x the size due to corruption, and that openssl can't deal with: 008CAD0202000000:error:0680007B:asn1 encoding routines:ASN1_get_object:header too long:crypto/asn1/asn1_lib.c:105:
— Reply to this email directly, view it on GitHubhttps://github.com/aruba/pyclearpass/issues/2#issuecomment-2189240288, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ASKTXT6PIXOA4TWT5WCPYEDZJGC5HAVCNFSM6AAAAABJZY736OVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCOBZGI2DAMRYHA. You are receiving this because you were assigned.Message ID: @.***>
common.py
's_send_request
method does a thing at the end, returnresponse.text
if you didn't get a JSON response: https://github.com/aruba/pyclearpass/blob/b48a554e62442ad329044b7c7cfd27fc51ea9240/pyclearpass/common.py#L110-L113However... https://github.com/aruba/pyclearpass/blob/b48a554e62442ad329044b7c7cfd27fc51ea9240/pyclearpass/api_certificateauthority.py#L75
new_certificate_by_cert_id_export
exports certs. Now, if you're getting a textualized version of a PEM, that's all fine, but if you're exporting PKCS12 (the only reasonable way to get a private key back out) that's a bytes-blob. Getting backresponse.text
is a stringified "error corrected" mangling ofresponse.content
, which is pretty much irrecoverable/irreversible.I tried changing
_send_request
to returnresponse.content
and got back a usable PKCS12/.p12
"file", but that was just spot-testing one function call, I'm sure it would otherwise wreck the API by changing 'everything' to bytes.