-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support non-standard X509 country names #3857
Comments
#3857 also has discussion of what to do with another RFC violation that we might still want to allow in parsing. There's a proposal there for allowing violating certificates during parsing but rejecting them during generation. |
I just ran into this. Certificate issued by Salesforce in 2017 for development purposes. Self-signed, but our customers use and we need to be able to work with it.
|
Today I found a similar case:
It looks like there are some certificates which uses an empty string... Here is an example:
In this particular case, there are empty strings in stateOrProvinceName, organizationName and organizationalUnitName for both issuer and subject. |
This certificate popped up in logs today. It uses "Taiwan" as jurisdiction country name, and thus triggers the same exception as this field is validated in the same way as country names:
|
I am using the library as a way to send alerts for expiring certificates. I have a certificate on file that is also throwing
Taking a look at the certificate which is breaking shows empty attributes for
cryptography version:
|
Figuring out how we want to handle this is on our roadmap for the next release. |
As a temporary fix to not being able to decode x509 certs with empty Country value, I removed/commented out this section in
if (
oid == NameOID.COUNTRY_NAME or
oid == NameOID.JURISDICTION_COUNTRY_NAME
):
if len(value.encode("utf8")) != 2:
raise ValueError(
"Country name must be a 2 character country code"
)
if len(value) == 0:
raise ValueError("Value cannot be an empty string") |
I'm using the cryptography library as part of a Microsoft Authenticode signature parsing project, and encountered the More info on the executable can be found at https://www.virustotal.com/gui/file/c32ade7ee7dac2bfb68c726739211f683fedb98624ba2c9aa7e9122ded1ccf56/details, and here's a program to reproduce: import binascii
from cryptography.hazmat.backends import default_backend
from cryptography.x509 import load_der_x509_certificate
cert_hex = '308203bb30820324a00302010202102c0e339024b942e5181f483f2d772131300d06092a864886f70d01010505003055310b3009060355040613025a4131253023060355040a131c54686177746520436f6e73756c74696e67202850747929204c74642e311f301d0603550403131654686177746520436f6465205369676e696e67204341301e170d3038303230353038313030385a170d3039303230343038313030385a3067310b3009060355040613024a50310d300b060355040813044f697461310e300c06035504071305426570707531163014060355040a130d4379626572466f7274204c4c4331093007060355040b1300311630140603550403130d4379626572466f7274204c4c4330820122300d06092a864886f70d01010105000382010f003082010a0282010100c617df265375d32d895aa61456b53d31bd5dbb65aa4b3561bf959466a9a14d4f2545e70640bdccca429fbc3ee8a8d7c35cae29a135747d1f8fbf6df94f96278d64ad5d6aae0794ffc40679d5171def855bf4ebc20e767b531bb8467ba9eeff5a15bab436d19bd28903d410665de313a54d395aebd63e941d594e290d689a80f938dfddb0c0e733d5fd79148ec50e62494a5d389adffe5ef720623dea14581296f209876ca40a5b493148fe65d2a12284961c92a6d68873005eda7f46d199f8ddf98193b42c9f00c500fb5d72cfc6eb5dc192e7f6b9a57380ba1fe3b59639b0164a8921e539a1a39df1ff42285beea65c2ae60da8223a9750ecf9a5b69e9f8e2b0203010001a381f53081f2301f0603551d250418301606082b06010505070303060a2b060104018237020116301106096086480186f8420101040403020410301d0603551d0404163014300e300c060a2b06010401823702011603020780301b0603551d110414301282107777772e6379626572666f72742e6a70303e0603551d1f043730353033a031a02f862d687474703a2f2f63726c2e7468617774652e636f6d2f546861777465436f64655369676e696e6743412e63726c303206082b0601050507010104263024302206082b060105050730018616687474703a2f2f6f6373702e7468617774652e636f6d300c0603551d130101ff04023000300d06092a864886f70d0101050500038181007201bdd2be014f0daf518338092577dc8ef4b8abd66d64e5b29ee7a80f7734cf3502ad872f1844cad6dbe521f4f8fe1504fda8d51cf085ddaf78d3fed0b466d9306acd2241d5a4931742310426b52c7cd5462c2068f5ab7e6c3bed07a2e04190b326382ac9bddb710a181b30b5df7dd32b684a92acf12fa43d0a8680e3e74b8b'
cert_bytes = binascii.unhexlify(cert_hex)
cert = load_der_x509_certificate(cert_bytes, default_backend())
subject = cert.subject.public_bytes(default_backend) |
I'm another user who is encountering malformed certificates in the wild, and it would be great to be able to finally work with them using |
bump http://pedump.me/16ac01292a94b86ecb1453330a2c893d/#signature https://github.com/konstantinstadler/country_converter
|
Can work around it for now by using OpenSSL.crypto which will parse the ASN.1 data as straight ASN.1 and not attempt to conform to specifications, example:
|
Given that certificates are a central component of security in many architectures, and invalid data is often the starting point for security exploits... why? This just seems like an invitation to disaster. Why have standards (like ISO-3166) if we're not going to follow them? More broadly, why encourage bad behavior? |
Because reality is messy and in too many cases developers would prefer to skip certificate validation over issuing a new certificate (especially if the certificate was issued by another department). I for example have to deal regularly with malformed certificates when auditing TLS configurations with sslyze. My solution so far is to monkeypatch cryptography. I want to assume, that I know what I am doing, but tbh that is something that want to disencourage. Especially in security sensitive contexts, I believe reasonable interoperability is often more beneficial than strict adherence to standards. This way we disencourage shadey workarounds. |
I used the cryptography library to parse android APK certificates in androguard.
But there are some people, who create their certificates in a non standard way. Usually they do not put the two char country code, but instead use some string.
Here is an example of such an certificate: ASN1. JavaScript Decoder with loaded Certificate.
As you can see, someone used
siavash
as the country name.From my point of view, such certificates are not common but also not very rare. I found out, that creating a new signing key in Android Studio does not reject the certificate if you enter something stupid in the country code field.
When you load the certificate (after removing the pkcs7 message around it), you will get an error message:
I know this is not really a bug, because the RFC says 2 char country code... But it would be nice to work with those "broken" certificates as well.
Versions (cryptography was installed via pip):
The text was updated successfully, but these errors were encountered: