fix starting Gajim when pyasn1 is not installed. see #7066

This commit is contained in:
Yann Leboulanger 2012-01-02 17:01:31 +01:00
parent aa94671708
commit 9804572772
1 changed files with 157 additions and 146 deletions

View File

@ -1,164 +1,175 @@
from pyasn1.type import univ, constraint, char, namedtype, tag import logging
from pyasn1.codec.der.decoder import decode log = logging.getLogger('gajim.c.check_X509')
from common.helpers import prep, InvalidFormat
MAX = 64 try:
oid_xmppaddr = '(1, 3, 6, 1, 5, 5, 7, 8, 5)' import OpenSSL.SSL
oid_dnssrv = '(1, 3, 6, 1, 5, 5, 7, 8, 7)' import OpenSSL.crypto
from pyasn1.type import univ, constraint, char, namedtype, tag
from pyasn1.codec.der.decoder import decode
from common.helpers import prep, InvalidFormat
MAX = 64
oid_xmppaddr = '(1, 3, 6, 1, 5, 5, 7, 8, 5)'
oid_dnssrv = '(1, 3, 6, 1, 5, 5, 7, 8, 7)'
class DirectoryString(univ.Choice): class DirectoryString(univ.Choice):
componentType = namedtype.NamedTypes( componentType = namedtype.NamedTypes(
namedtype.NamedType( namedtype.NamedType(
'teletexString', char.TeletexString().subtype( 'teletexString', char.TeletexString().subtype(
subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
namedtype.NamedType( namedtype.NamedType(
'printableString', char.PrintableString().subtype( 'printableString', char.PrintableString().subtype(
subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
namedtype.NamedType( namedtype.NamedType(
'universalString', char.UniversalString().subtype( 'universalString', char.UniversalString().subtype(
subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
namedtype.NamedType( namedtype.NamedType(
'utf8String', char.UTF8String().subtype( 'utf8String', char.UTF8String().subtype(
subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
namedtype.NamedType( namedtype.NamedType(
'bmpString', char.BMPString().subtype( 'bmpString', char.BMPString().subtype(
subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
namedtype.NamedType( namedtype.NamedType(
'ia5String', char.IA5String().subtype( 'ia5String', char.IA5String().subtype(
subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
namedtype.NamedType( namedtype.NamedType(
'gString', univ.OctetString().subtype( 'gString', univ.OctetString().subtype(
subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
) )
class AttributeValue(DirectoryString): class AttributeValue(DirectoryString):
pass pass
class AttributeType(univ.ObjectIdentifier): class AttributeType(univ.ObjectIdentifier):
pass pass
class AttributeTypeAndValue(univ.Sequence): class AttributeTypeAndValue(univ.Sequence):
componentType = namedtype.NamedTypes( componentType = namedtype.NamedTypes(
namedtype.NamedType('type', AttributeType()), namedtype.NamedType('type', AttributeType()),
namedtype.NamedType('value', AttributeValue()), namedtype.NamedType('value', AttributeValue()),
) )
class RelativeDistinguishedName(univ.SetOf): class RelativeDistinguishedName(univ.SetOf):
componentType = AttributeTypeAndValue() componentType = AttributeTypeAndValue()
class RDNSequence(univ.SequenceOf): class RDNSequence(univ.SequenceOf):
componentType = RelativeDistinguishedName() componentType = RelativeDistinguishedName()
class Name(univ.Choice): class Name(univ.Choice):
componentType = namedtype.NamedTypes( componentType = namedtype.NamedTypes(
namedtype.NamedType('', RDNSequence()), namedtype.NamedType('', RDNSequence()),
) )
class GeneralName(univ.Choice): class GeneralName(univ.Choice):
componentType = namedtype.NamedTypes( componentType = namedtype.NamedTypes(
namedtype.NamedType('otherName', univ.Sequence().subtype( namedtype.NamedType('otherName', univ.Sequence().subtype(
implicitTag=tag.Tag(tag.tagClassContext, implicitTag=tag.Tag(tag.tagClassContext,
tag.tagFormatConstructed, 0x0))), tag.tagFormatConstructed, 0x0))),
namedtype.NamedType('rfc822Name', char.IA5String().subtype( namedtype.NamedType('rfc822Name', char.IA5String().subtype(
implicitTag=tag.Tag(tag.tagClassContext, implicitTag=tag.Tag(tag.tagClassContext,
tag.tagFormatSimple, 1))), tag.tagFormatSimple, 1))),
namedtype.NamedType('dNSName', char.IA5String().subtype( namedtype.NamedType('dNSName', char.IA5String().subtype(
implicitTag=tag.Tag(tag.tagClassContext, implicitTag=tag.Tag(tag.tagClassContext,
tag.tagFormatSimple, 2))), tag.tagFormatSimple, 2))),
namedtype.NamedType('x400Address', univ.Sequence().subtype( namedtype.NamedType('x400Address', univ.Sequence().subtype(
implicitTag=tag.Tag(tag.tagClassContext, implicitTag=tag.Tag(tag.tagClassContext,
tag.tagFormatConstructed, 0x3))), tag.tagFormatConstructed, 0x3))),
namedtype.NamedType('directoryName', Name().subtype( namedtype.NamedType('directoryName', Name().subtype(
implicitTag=tag.Tag(tag.tagClassContext, implicitTag=tag.Tag(tag.tagClassContext,
tag.tagFormatConstructed, 0x4))), tag.tagFormatConstructed, 0x4))),
namedtype.NamedType('ediPartyName', univ.Sequence().subtype( namedtype.NamedType('ediPartyName', univ.Sequence().subtype(
implicitTag=tag.Tag(tag.tagClassContext, implicitTag=tag.Tag(tag.tagClassContext,
tag.tagFormatConstructed, 0x5))), tag.tagFormatConstructed, 0x5))),
namedtype.NamedType('uniformResourceIdentifier', namedtype.NamedType('uniformResourceIdentifier',
char.IA5String().subtype( char.IA5String().subtype(
implicitTag=tag.Tag(tag.tagClassContext, implicitTag=tag.Tag(tag.tagClassContext,
tag.tagFormatSimple, 6))), tag.tagFormatSimple, 6))),
namedtype.NamedType('iPAddress', univ.OctetString().subtype( namedtype.NamedType('iPAddress', univ.OctetString().subtype(
implicitTag=tag.Tag(tag.tagClassContext, implicitTag=tag.Tag(tag.tagClassContext,
tag.tagFormatSimple, 7))), tag.tagFormatSimple, 7))),
namedtype.NamedType('registeredID', univ.ObjectIdentifier().subtype( namedtype.NamedType('registeredID', univ.ObjectIdentifier().subtype(
implicitTag=tag.Tag(tag.tagClassContext, implicitTag=tag.Tag(tag.tagClassContext,
tag.tagFormatSimple, 8))), tag.tagFormatSimple, 8))),
) )
class GeneralNames(univ.SequenceOf): class GeneralNames(univ.SequenceOf):
componentType = GeneralName() componentType = GeneralName()
sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX) sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX)
def _parse_asn1(asn1):
obj = decode(asn1, asn1Spec=GeneralNames())[0]
r = {}
for o in obj:
name = o.getName()
if name == 'dNSName':
if name not in r:
r[name] = []
r[name].append(str(o.getComponent()))
if name == 'otherName':
if name not in r:
r[name] = {}
tag = str(tuple(o.getComponent())[0])
val = str(tuple(o.getComponent())[1])
if tag not in r[name]:
r[name][tag] = []
r[name][tag].append(val)
if name == 'uniformResourceIdentifier':
r['uniformResourceIdentifier'] = True
return r
#s = '0\x1a\x82\rwww.gajim.org\x82\tgajim.org' def check_certificate(cert, domain):
s = '0\x81\x86\x82\x0c*.jabber.org\x82\njabber.org\xa0\x1a\x06\x08+\x06\x01\x05\x05\x07\x08\x05\xa0\x0e\x0c\x0c*.jabber.org\xa0\x1a\x06\x08+\x06\x01\x05\x05\x07\x08\x07\xa0\x0e\x16\x0c*.jabber.org\xa0\x18\x06\x08+\x06\x01\x05\x05\x07\x08\x05\xa0\x0c\x0c\njabber.org\xa0\x18\x06\x08+\x06\x01\x05\x05\x07\x08\x07\xa0\x0c\x16\njabber.org' cnt = cert.get_extension_count()
if '.' in domain:
def _parse_asn1(asn1): compared_domain = domain.split('.', 1)[1]
obj = decode(asn1, asn1Spec=GeneralNames())[0] else:
r = {} compared_domain = ''
for o in obj: srv_domain = '_xmpp-client.' + domain
name = o.getName() compared_srv_domain = '_xmpp-client.' + compared_domain
if name == 'dNSName': for i in range(0, cnt):
if name not in r: ext = cert.get_extension(i)
r[name] = [] if ext.get_short_name() == 'subjectAltName':
r[name].append(str(o.getComponent())) r = _parse_asn1(ext.get_data())
if name == 'otherName': if 'otherName' in r:
if name not in r: if oid_xmppaddr in r['otherName']:
r[name] = {} for host in r['otherName'][oid_xmppaddr]:
tag = str(tuple(o.getComponent())[0]) try:
val = str(tuple(o.getComponent())[1]) host = prep(None, host, None)
if tag not in r[name]: except InvalidFormat:
r[name][tag] = [] continue
r[name][tag].append(val) if host == domain:
if name == 'uniformResourceIdentifier': return True
r['uniformResourceIdentifier'] = True if oid_dnssrv in r['otherName']:
return r for host in r['otherName'][oid_dnssrv]:
if host.startswith('_xmpp-client.*.'):
def check_certificate(cert, domain): if host.replace('*.', '', 1) == compared_srv_domain:
cnt = cert.get_extension_count() return True
if '.' in domain: continue
compared_domain = domain.split('.', 1)[1] if host == srv_domain:
else: return True
compared_domain = '' if 'dNSName' in r:
srv_domain = '_xmpp-client.' + domain for host in r['dNSName']:
compared_srv_domain = '_xmpp-client.' + compared_domain if host.startswith('*.'):
for i in range(0, cnt): if host[2:] == compared_domain:
ext = cert.get_extension(i) return True
if ext.get_short_name() == 'subjectAltName':
r = _parse_asn1(ext.get_data())
if 'otherName' in r:
if oid_xmppaddr in r['otherName']:
for host in r['otherName'][oid_xmppaddr]:
try:
host = prep(None, host, None)
except InvalidFormat:
continue continue
if host == domain: if host == domain:
return True return True
if oid_dnssrv in r['otherName']: if r:
for host in r['otherName'][oid_dnssrv]: return False
if host.startswith('_xmpp-client.*.'): break
if host.replace('*.', '', 1) == compared_srv_domain:
return True
continue
if host == srv_domain:
return True
if 'dNSName' in r:
for host in r['dNSName']:
if host.startswith('*.'):
if host[2:] == compared_domain:
return True
continue
if host == domain:
return True
if r:
return False
break
subject = cert.get_subject() subject = cert.get_subject()
if subject.commonName == domain: if subject.commonName == domain:
return True return True
return False return False
except ImportError:
log.warn('Import of PyOpenSSL or pyasn1 failed. Cannot correctly check '
'SSL certificate')
def check_certificate(cert, domain):
subject = cert.get_subject()
if subject.commonName == domain:
return True
return False