def test_https_cert_invalid(self): """Verify vikidia SSL certificate is invalid.""" try: from pyasn1_modules import pem, rfc2459 from pyasn1.codec.der import decoder except ImportError: raise unittest.SkipTest('pyasn1 and pyasn1_modules not available.') import ssl import io cert = ssl.get_server_certificate(addr=('en.vikidia.org', 443)) s = io.StringIO(unicode(cert)) substrate = pem.readPemFromFile(s) cert = decoder.decode(substrate, asn1Spec=rfc2459.Certificate())[0] tbs_cert = cert.getComponentByName('tbsCertificate') issuer = tbs_cert.getComponentByName('issuer') organisation = None for rdn in issuer.getComponent(): for attr in rdn: attr_type = attr.getComponentByName('type') if attr_type == rfc2459.id_at_organizationName: value, _ = decoder.decode(attr.getComponentByName('value'), asn1Spec=rfc2459.X520name()) organisation = str(value.getComponent()) break self.assertEqual(organisation, 'TuxFamily.org non-profit organization')
def get_subject(f): """ return a list of subjects frmo a tbsCertificate """ tbs = f.read() res = [] # based on the original ct tools cert, rest = decoder.decode(tbs, asn1Spec=TBSCertificate()) # First, try the CN field in the subject subject = cert['subject'] l = subject.getComponent() for i in l: for attr in i: if attr['type'] == rfc2459.id_at_commonName: val, rest = decoder.decode(attr.getComponentByName('value'), asn1Spec=rfc2459.X520name()) valt = val.getName() val = val.getComponent() s = decode_string(valt, val) if (" " not in s): res.append(s) # Now, try the SubjectAlternativeName in the extensions try: # based on https://github.com/google/certificate-transparency/blob/master/cpp/client/fix-chain.py ext = cert['extensions'] for i in ext: oid = i['extnID'] if oid != rfc2459.id_ce_subjectAltName: continue subject_alt_names_raw = decoder.decode( i.getComponentByName('extnValue'), asn1Spec=pyasn1.type.univ.OctetString())[0] subject_alt_names = decoder.decode( subject_alt_names_raw, asn1Spec=rfc2459.SubjectAltName())[0] for general_name in subject_alt_names: subject_alt_name_type = general_name.getName() subject_alt_name_value = general_name.getComponent() if (subject_alt_name_type == "dNSName"): res.append(str(subject_alt_name_value)) except: pass return res
def DNToString(dn): rdns = dn.getComponent() ret = '' for rdn in rdns: ret += '[' for attr in rdn: attrType = attr.getComponentByName('type') if attrType == rfc2459.emailAddress: val, rest = decoder.decode(attr.getComponentByName('value'), asn1Spec=rfc2459.Pkcs9email()) assert rest == "" # Strictly speaking, this is IA5, not ASCII. val = str(val).decode('ascii') else: val, rest = decoder.decode(attr.getComponentByName('value'), asn1Spec=rfc2459.X520name()) assert rest == "" valt = val.getName() val = val.getComponent() if valt == 'printableString': val = str(val) elif valt == 'teletexString': # Strictly this is a T.61 string. T.61 no longer exists as a # standard and some certs mark ISO 8859-1 as # teletexString. And we should never see this, but we do. val = str(val).decode('iso8859-1') elif valt == 'utf8String': val = str(val) else: print valt assert False assert val is not None ret += '/' + str(attrType) + '=' + val ret += ']' return ret