Esempio n. 1
0
    def test_x509_name(self):
        n = X509.X509_Name()
        n.C = 'US'  # It seems this actually needs to be a real 2 letter country code
        n.SP = 'State or Province'
        n.L = 'locality name'
        n.O = 'orhanization name'
        n.OU = 'org unit'
        n.CN = 'common name'
        n.Email = '*****@*****.**'
        n.serialNumber = '1234'
        n.SN = 'surname'
        n.GN = 'given name'

        n.givenName = 'name given'
        assert len(n) == 11, len(n)

        tl = map(x509_name_entry2tuple, x509_name2list(n))

        assert len(tl) == len(n), len(tl)

        x509_n = m2.x509_name_new()
        for o in map(tuple2x509_name_entry, tl):
            m2.x509_name_add_entry(x509_n, o._ptr(), -1, 0)
            o._pyfree = 0  # Take care of underlying object
        n1 = X509.X509_Name(x509_n)

        assert n.as_text() == n1.as_text(), n1.as_text()
Esempio n. 2
0
    def test_x509_name(self):
        n = X509.X509_Name()
        # It seems this actually needs to be a real 2 letter country code
        n.C = b'US'
        n.SP = b'State or Province'
        n.L = b'locality name'
        n.O = b'orhanization name'
        n.OU = b'org unit'
        n.CN = b'common name'
        n.Email = b'*****@*****.**'
        n.serialNumber = b'1234'
        n.SN = b'surname'
        n.GN = b'given name'

        n.givenName = b'name given'
        self.assertEqual(len(n), 11, len(n))

        # Thierry: this call to list seems extraneous...
        tl = [x509_name_entry2tuple(x) for x in x509_name2list(n)]

        self.assertEqual(len(tl), len(n), len(tl))

        x509_n = m2.x509_name_new()
        for o in [tuple2x509_name_entry(x) for x in tl]:
            m2.x509_name_add_entry(x509_n, o._ptr(), -1, 0)
            o._pyfree = 0  # Take care of underlying object
        n1 = X509.X509_Name(x509_n)

        self.assertEqual(n.as_text(), n1.as_text(), n1.as_text())
Esempio n. 3
0
    def test_x509_name(self):
        n = X509.X509_Name()
        # It seems this actually needs to be a real 2 letter country code
        n.C = b'US'
        n.SP = b'State or Province'
        n.L = b'locality name'
        n.O = b'orhanization name'
        n.OU = b'org unit'
        n.CN = b'common name'
        n.Email = b'*****@*****.**'
        n.serialNumber = b'1234'
        n.SN = b'surname'
        n.GN = b'given name'

        n.givenName = b'name given'
        self.assertEqual(len(n), 11, len(n))

        # Thierry: this call to list seems extraneous...
        tl = [x509_name_entry2tuple(x) for x in x509_name2list(n)]

        self.assertEqual(len(tl), len(n), len(tl))

        x509_n = m2.x509_name_new()
        for o in [tuple2x509_name_entry(x) for x in tl]:
            m2.x509_name_add_entry(x509_n, o._ptr(), -1, 0)
            o._pyfree = 0  # Take care of underlying object
        n1 = X509.X509_Name(x509_n)

        self.assertEqual(n.as_text(), n1.as_text(), n1.as_text())
Esempio n. 4
0
    def test_x509_name(self):
        n = X509.X509_Name()
        n.C = 'US' # It seems this actually needs to be a real 2 letter country code
        n.SP = 'State or Province'
        n.L = 'locality name'
        n.O = 'orhanization name'
        n.OU = 'org unit'
        n.CN = 'common name'
        n.Email = '*****@*****.**'
        n.serialNumber = '1234'
        n.SN = 'surname'
        n.GN = 'given name'
        
        n.givenName = 'name given'
        assert len(n) == 11, len(n)

        tl = map(x509_name_entry2tuple, x509_name2list(n))

        assert len(tl) == len(n), len(tl)

        x509_n = m2.x509_name_new()
        for o in map(tuple2x509_name_entry, tl):
            m2.x509_name_add_entry(x509_n, o._ptr(), -1, 0)
            o._pyfree = 0 # Take care of underlying object
        n1 = X509.X509_Name(x509_n)

        assert n.as_text() == n1.as_text(), n1.as_text()
Esempio n. 5
0
    def __init__(self, certificate, proxykey=None, full=True):
        if isinstance(certificate, Certificate):
            self._certificate = certificate
        elif isinstance(certificate, ProxyCertificate):
            self._certificate = certificate._proxy
        else:
            self._certificate = Certificate(certificate)
        self._full = full

        self._proxy = Certificate(key=proxykey)

        self._proxy.set_version(2)
        self.set_serial_number()
        issuer = self._certificate.get_subject()
        subject = X509.X509_Name()
        for n in issuer:
            m2.x509_name_add_entry(subject.x509_name, n.x509_name_entry, -1, 0)

        subject.add_entry_by_txt(field='CN', type=MBSTRING_ASC,
                                 entry=str(self._proxy.get_serial_number()),len=-1, loc=-1, set=0)

# CURRENT - this partly fools the system that it has a globus legacy proxy (needed by grisu/grid)
# can look up VOs, but can't access filesystems for running jobs with this on
#        subject.add_entry_by_txt(field='CN', type=MBSTRING_ASC, entry='proxy',len=-1, loc=-1, set=0)

        self._proxy.set_dn(subject)
        self._proxy.set_times(lifetime=43200)
        self._proxy.set_issuer_name(self._certificate.get_subject())

        try:
            key_usage = self._certificate._certificate.get_ext('keyUsage')
        except LookupError:
            pass
        else:
            self._proxy.add_extension({'name':key_usage.get_name(),
                                       'critical': key_usage.get_critical(),
                                       'value': self._fix_key_usage(key_usage.get_value())})

        if self._full:
            self._proxy.add_extension({'name':"proxyCertInfo",
                                       'value': PCI_VALUE_FULL,
                                       'critical': 1})
        else:
            self._proxy.add_extension({'name': "proxyCertInfo",
                                           'value': PCI_VALUE_LIMITED,
                                           'critical': 1})
Esempio n. 6
0
    def _signRequest(self, x509Request, lifetime):
        notBefore = ASN1.ASN1_UTCTIME()
        notBefore.set_datetime(datetime.now(pytz.UTC))
        notAfter = ASN1.ASN1_UTCTIME()
        notAfter.set_datetime(datetime.now(pytz.UTC) + lifetime)

        proxySubject = X509.X509_Name()
        for c in self.context.x509.get_subject():
            m2.x509_name_add_entry(proxySubject._ptr(), c._ptr(), -1, 0)
        proxySubject.add_entry_by_txt('commonName', 0x1000, 'proxy', -1, -1, 0)

        proxy = X509.X509()
        proxy.set_version(2)
        proxy.set_subject(proxySubject)
        proxy.set_serial_number(long(time.time()))
        proxy.set_version(x509Request.get_version())
        proxy.set_issuer(self.context.x509.get_subject())
        proxy.set_pubkey(x509Request.get_pubkey())

        # Make sure the proxy is not longer than any other inside the chain
        any_rfc_proxies = False
        for cert in self.context.x509List:
            if cert.get_not_after() < notAfter:
                notAfter = cert.get_not_after()
            try:
                cert.get_ext('1.3.6.1.5.5.7.1.14')
                any_rfc_proxies = True
            except:
                pass

        proxy.set_not_after(notAfter)
        proxy.set_not_before(notBefore)

        if any_rfc_proxies:
            raise NotImplementedError('RFC proxies not supported yet')

        proxy.sign(self.context.evpKey, 'sha1')

        return proxy
Esempio n. 7
0
	def _signRequest(self, x509Request, lifetime):		
		notBefore = ASN1.ASN1_UTCTIME()
		notBefore.set_datetime(datetime.now(pytz.UTC))
		notAfter  = ASN1.ASN1_UTCTIME()
		notAfter.set_datetime(datetime.now(pytz.UTC) + lifetime)
		
		proxySubject = X509.X509_Name()
		for c in self.context.x509.get_subject():
			m2.x509_name_add_entry(proxySubject._ptr(), c._ptr(), -1, 0)
		proxySubject.add_entry_by_txt('commonName', 0x1000, 'proxy', -1, -1, 0)
		
		proxy = X509.X509()
		proxy.set_version(2)
		proxy.set_subject(proxySubject)
		proxy.set_serial_number(long(time.time()))
		proxy.set_version(x509Request.get_version())
		proxy.set_issuer(self.context.x509.get_subject())
		proxy.set_pubkey(x509Request.get_pubkey())
		
		# Make sure the proxy is not longer than any other inside the chain
		any_rfc_proxies = False
		for cert in self.context.x509List:
			if cert.get_not_after() < notAfter:
				notAfter = cert.get_not_after()
			try:
				cert.get_ext('1.3.6.1.5.5.7.1.14')
				any_rfc_proxies = True
			except:
				pass	

		proxy.set_not_after(notAfter)
		proxy.set_not_before(notBefore)
		
		if any_rfc_proxies:
			raise NotImplementedError('RFC proxies not supported yet')		
		
		proxy.sign(self.context.evpKey, 'sha1')
		
		return proxy
Esempio n. 8
0
def generate_proxycert(new_pkey, cert, key, **kwargs):
    """Generate a proxy certificate.

     * new_pkey: EVP.PKey for the proxy certificate
     * cert: Issuer certificate
     * key: Issuer private key

    Optional arguments:

     * lifetime: proxy certificate lifetime, in seconds. Default: is 12 hours.
     * full: proxy type, full or limited. Default is False (limited proxy).
     * hash_algorithm: hash algorithm to use for certificate signing. Default: sha1.
     * globus_bug: do not use basicConstraints extension and do not allow Key Agreement. Default: true
    """
    args = kwargs.copy()
    if 'args' in args:
        args.update(args.pop('args'))

    legacy = args.get('legacy', is_legacy_proxy(cert))
    full = args.get('full', False)
    globus_bug = args.get('globus_bug', True)

    proxy = X509.X509()
    proxy.set_pubkey(new_pkey)
    proxy.set_version(2)

    now = int(time.time())
    not_before = ASN1.ASN1_UTCTIME()
    not_before.set_time(now  - CLOCK_SKEW)
    proxy.set_not_before(not_before)
    not_after = ASN1.ASN1_UTCTIME()
    not_after.set_time(now + args.get('lifetime', 12*60*60) + CLOCK_SKEW)
    proxy.set_not_after(not_after)

    proxy.set_issuer_name(cert.get_subject())
    digest = EVP.MessageDigest('sha1')
    digest.update(new_pkey.as_der())
    serial = struct.unpack("<L", digest.final()[:4])[0]
    proxy.set_serial_number(int(serial & 0x7fffffff))

    # It is not completely clear what happens with memory allocation
    # within the next calls, so after building the whole thing we are
    # going to reload it through der encoding/decoding.
    proxy_subject = X509.X509_Name()
    subject = cert.get_subject()
    for idx in xrange(subject.entry_count()):
        entry = subject[idx].x509_name_entry
        m2.x509_name_add_entry(proxy_subject._ptr(), entry, -1, 0)
    if legacy:
        if full:
            proxy_subject.add_entry_by_txt('CN',
                                           ASN1.MBSTRING_ASC,
                                           "proxy", -1, -1, 0)
        else:
            proxy_subject.add_entry_by_txt('CN',
                                           ASN1.MBSTRING_ASC,
                                           "limited proxy", -1, -1, 0)
    else:
        proxy_subject.add_entry_by_txt('CN',
                                       ASN1.MBSTRING_ASC,
                                       str(serial), -1, -1, 0)
    proxy.set_subject(proxy_subject)
    if legacy:
        if globus_bug:
            proxy.add_ext(X509.new_extension(
                "keyUsage",
                "Digital Signature, Key Encipherment, Data Encipherment", 1))
        else:
            proxy.add_ext(X509.new_extension(
                "keyUsage",
                "Digital Signature, Key Encipherment, Data Encipherment, Key Agreement", 1))
            proxy.add_ext(X509.new_extension("basicConstraints", "CA:FALSE", 1))

            # does not work (?) seems like need to add authorityCertIssuer
            # and authorityCertSerialNumber somehow, see rfc 3280 for more
            # details

            # try:
            #     subjkey = cert.get_ext('subjectKeyIdentifier')
            #     keyid = "keyid:%s" % subjkey.get_value()
            #     ext = X509.new_extension("authorityKeyIdentifier", keyid, 0)
            #     proxy.add_ext(ext)
            # except LookupError:
            #     pass
    else:
        if globus_bug:
            proxy.add_ext(X509.new_extension("keyUsage", "Digital Signature, Key Encipherment, Data Encipherment", 1))
        else:
            proxy.add_ext(X509.new_extension("basicConstraints", "CA:FALSE", 1))
            proxy.add_ext(X509.new_extension("keyUsage", "Digital Signature, Key Encipherment, Data Encipherment, Key Agreement", 1))
    if not legacy:
        if full:
            proxy.add_ext(X509.new_extension("proxyCertInfo",
                                             "critical, language:Inherit all",
                                             1))
        else:
            proxy.add_ext(X509.new_extension("proxyCertInfo",
                                             "critical, language:1.3.6.1.4.1.3536.1.1.1.9",
                                             1))

    sign_pkey = EVP.PKey()
    sign_pkey.assign_rsa(key, 0)
    proxy.sign(sign_pkey, args.get('hash_algorithm', 'sha1'))

    return X509.load_cert_string(proxy.as_pem())
Esempio n. 9
0
def generate_proxycert(new_pkey, cert, key, **kwargs):
    """Generate a proxy certificate.

     * new_pkey: EVP.PKey for the proxy certificate
     * cert: Issuer certificate
     * key: Issuer private key

    Optional arguments:

     * lifetime: proxy certificate lifetime, in seconds. Default: is 12 hours.
     * full: proxy type, full or limited. Default is False (limited proxy).
     * hash_algorithm: hash algorithm to use for certificate signing. Default: sha1.
     * globus_bug: do not use basicConstraints extension and do not allow Key Agreement. Default: true
    """
    args = kwargs.copy()
    if 'args' in args:
        args.update(args.pop('args'))

    legacy = args.get('legacy', is_legacy_proxy(cert))
    full = args.get('full', False)
    globus_bug = args.get('globus_bug', True)

    proxy = X509.X509()
    proxy.set_pubkey(new_pkey)
    proxy.set_version(2)

    now = int(time.time())
    not_before = ASN1.ASN1_UTCTIME()
    not_before.set_time(now - CLOCK_SKEW)
    proxy.set_not_before(not_before)
    not_after = ASN1.ASN1_UTCTIME()
    not_after.set_time(now + args.get('lifetime', 12 * 60 * 60) + CLOCK_SKEW)
    proxy.set_not_after(not_after)

    proxy.set_issuer_name(cert.get_subject())
    digest = EVP.MessageDigest('sha1')
    digest.update(new_pkey.as_der())
    serial = struct.unpack("<L", digest.final()[:4])[0]
    proxy.set_serial_number(int(serial & 0x7fffffff))

    # Не совсем понятно, что и как с памятью в следующих операциях,
    # поэтому по завершению всего действа будет перезагрузка
    # сертификата через der
    proxy_subject = X509.X509_Name()
    subject = cert.get_subject()
    for idx in xrange(subject.entry_count()):
        entry = subject[idx].x509_name_entry
        m2.x509_name_add_entry(proxy_subject._ptr(), entry, -1, 0)
    if legacy:
        if full:
            proxy_subject.add_entry_by_txt('CN', ASN1.MBSTRING_ASC, "proxy",
                                           -1, -1, 0)
        else:
            proxy_subject.add_entry_by_txt('CN', ASN1.MBSTRING_ASC,
                                           "limited proxy", -1, -1, 0)
    else:
        proxy_subject.add_entry_by_txt('CN', ASN1.MBSTRING_ASC, str(serial),
                                       -1, -1, 0)
    proxy.set_subject(proxy_subject)
    if legacy:
        if globus_bug:
            proxy.add_ext(
                X509.new_extension(
                    "keyUsage",
                    "Digital Signature, Key Encipherment, Data Encipherment",
                    1))
        else:
            proxy.add_ext(
                X509.new_extension(
                    "keyUsage",
                    "Digital Signature, Key Encipherment, Data Encipherment, Key Agreement",
                    1))
            proxy.add_ext(X509.new_extension("basicConstraints", "CA:FALSE",
                                             1))

            # does not work (?) seems like need to add authorityCertIssuer
            # and authorityCertSerialNumber somehow, see rfc 3280 for more
            # details

            # try:
            #     subjkey = cert.get_ext('subjectKeyIdentifier')
            #     keyid = "keyid:%s" % subjkey.get_value()
            #     ext = X509.new_extension("authorityKeyIdentifier", keyid, 0)
            #     proxy.add_ext(ext)
            # except LookupError:
            #     pass
    else:
        if globus_bug:
            proxy.add_ext(
                X509.new_extension(
                    "keyUsage",
                    "Digital Signature, Key Encipherment, Data Encipherment",
                    1))
        else:
            proxy.add_ext(X509.new_extension("basicConstraints", "CA:FALSE",
                                             1))
            proxy.add_ext(
                X509.new_extension(
                    "keyUsage",
                    "Digital Signature, Key Encipherment, Data Encipherment, Key Agreement",
                    1))
    if not legacy:
        if full:
            proxy.add_ext(
                X509.new_extension("proxyCertInfo",
                                   "critical, language:Inherit all", 1))
        else:
            proxy.add_ext(
                X509.new_extension(
                    "proxyCertInfo",
                    "critical, language:1.3.6.1.4.1.3536.1.1.1.9", 1))

    sign_pkey = EVP.PKey()
    sign_pkey.assign_rsa(key, 0)
    proxy.sign(sign_pkey, args.get('hash_algorithm', 'sha1'))

    return X509.load_cert_string(proxy.as_pem())
Esempio n. 10
0
def generate_proxy(certificate, proxykey=None, full=True,
                   lifetime=43200, extensions=[]):
    """
    generate a new proxy certificate

    :param certificate: the parent certificate
    :param proxykey: the key used to sign the proxy
    :param full: whether this is a full proxy or not
    """
    _certificate = certificate
    _full = full

    _proxy, _key = generate_certificate(key=proxykey)

    _proxy.set_version(2)

    # generate serial
    message_digest = EVP.MessageDigest('sha1')
    pubkey = _proxy.get_pubkey()
    der_encoding = pubkey.as_der()
    message_digest.update(der_encoding)
    digest = message_digest.final()
    digest_tuple = struct.unpack('BBBB', digest[:4])
    sub_hash = long(digest_tuple[0] +
                    (digest_tuple[1] +
                     (digest_tuple[2] +
                       (digest_tuple[3] >> 1) * 256) * 256) * 256)
    _proxy.set_serial_number(sub_hash)

    # set issuer
    issuer = _certificate.get_subject()

    # set subject
    subject = X509.X509_Name()
    for n in issuer:
        m2.x509_name_add_entry(subject.x509_name, n.x509_name_entry, -1, 0)
    subject.add_entry_by_txt(field='CN', type=MBSTRING_ASC,
                             entry=str(_proxy.get_serial_number()),
                             len=-1, loc=-1, set=0)
    _proxy.set_subject_name(subject)

    # set times
    not_before = ASN1.ASN1_UTCTIME()
    not_after = ASN1.ASN1_UTCTIME()
    not_before.set_time(int(time.time()) - 300)
    not_after.set_time(int(time.time()) + lifetime)
    _proxy.set_not_before(not_before)
    _proxy.set_not_after(not_after)

    _proxy.set_issuer_name(_certificate.get_subject())

    # add extensions
    try:
        key_usage = _certificate.get_ext('keyUsage')
    except LookupError:
        pass
    else:
        r = []
        for v in key_usage.get_value().split(', '):
            if v in ['Non Repudiation', 'keyCertSign']:
                continue
            r.append(v)
        if 'Digital Signature' not in r:
            r.append('Digital Signature')
        key_usage_value = ', '.join(r)
        extensions.append({'name': key_usage.get_name(),
                           'critical': key_usage.get_critical(),
                           'value': key_usage_value})

    if _full:
        extensions.append({'name': "proxyCertInfo",
                           'value': PCI_VALUE_FULL,
                           'critical': 1})
    else:
        extensions.append({'name': "proxyCertInfo",
                           'value': PCI_VALUE_LIMITED,
                           'critical': 1})
    if extensions:
        sslower = lambda s: s.lower().replace(' ', '')

        for e in extensions:
            name = e['name']
            key = sslower(name)
            critical = e['critical']
            if key in multi_attrs:
                e['value'] = ', '.join([multi_attrs[key][sslower(v)]
                               for v in e['value'].split(',')])
            _proxy.add_ext(X509.new_extension(Att_map[key],
                                              e['value'],
                                              critical=int(critical)))

    return _proxy, _key
Esempio n. 11
0
    def _sign_request(self, x509_request, lifetime):
        not_before = ASN1.ASN1_UTCTIME()
        not_before.set_datetime(datetime.now(UTC))
        not_after = ASN1.ASN1_UTCTIME()
        not_after.set_datetime(datetime.now(UTC) + lifetime)

        proxy_subject = X509.X509_Name()
        for entry in self.context.x509.get_subject():
            ret = m2.x509_name_add_entry(proxy_subject._ptr(), entry._ptr(), -1, 0)
            if ret == 0:
                raise Exception(
                    "%s: '%s'" % (m2.err_reason_error_string(m2.err_get_error()), entry)
                )

        proxy = X509.X509()
        proxy.set_serial_number(self.context.x509.get_serial_number())
        proxy.set_version(x509_request.get_version())
        proxy.set_issuer(self.context.x509.get_subject())
        proxy.set_pubkey(x509_request.get_pubkey())

        # Extensions are broken in SL5!!
        if _m2crypto_extensions_broken():
            log.warning("X509v3 extensions disabled!")
        else:
            # X509v3 Basic Constraints
            proxy.add_ext(X509.new_extension('basicConstraints', 'CA:FALSE', critical=True))
            # X509v3 Key Usage
            proxy.add_ext(X509.new_extension('keyUsage', 'Digital Signature, Key Encipherment', critical=True))
            #X509v3 Authority Key Identifier
            identifier_ext = _workaround_new_extension(
                'authorityKeyIdentifier', 'keyid', critical=False, issuer=self.context.x509
            )
            proxy.add_ext(identifier_ext)

        any_rfc_proxies = False
        # FTS-1217 Ignore the user input and select the min proxy lifetime available on the list
        min_cert_lifetime = self.context.x509_list[0].get_not_after()
        for cert in self.context.x509_list:
            if cert.get_not_after().get_datetime() < min_cert_lifetime.get_datetime():
                not_after = cert.get_not_after()
                min_cert_lifetime = cert.get_not_after()
            try:
                cert.get_ext('proxyCertInfo')
                any_rfc_proxies = True
            except:
                pass

        proxy.set_not_after(not_after)
        proxy.set_not_before(not_before)

        if any_rfc_proxies:
            if _m2crypto_extensions_broken():
                raise NotImplementedError("X509v3 extensions are disabled, so RFC proxies can not be generated!")
            else:
                _add_rfc3820_extensions(proxy)

        if any_rfc_proxies:
            m2.x509_name_set_by_nid(proxy_subject._ptr(), X509.X509_Name.nid['commonName'], str(int(time.time())))
        else:
            m2.x509_name_set_by_nid(proxy_subject._ptr(), X509.X509_Name.nid['commonName'], 'proxy')

        proxy.set_subject(proxy_subject)
        proxy.set_version(2)
        proxy.sign(self.context.evp_key, 'sha1')

        return proxy