class ProxyCertificate: """This is a wrapper class for handling proxy certificate generation. :param request: if specified this will be wrapped in a :class:`~arcs.gsi.certificate.Certificate` object :param proxykey: the key used to sign the proxy, if sepecified this will be wrapped in a :class:`~arcs.gsi.key.Key` object :param full: whether this is a full proxy or not """ 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}) def _fix_key_usage(self, values): """ invalid values are 'Non Repudiation' and 'keyCertSign' digitalSignature is required """ r = [] for v in values.split(', '): if v in ['Non Repudiation', 'keyCertSign']: continue r.append(v) if 'Digital Signature' not in r: r.append('Digital Signature') return ', '.join(r) def set_serial_number(self): message_digest = EVP.MessageDigest('sha1') pubkey = self._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) self._proxy._certificate.set_serial_number(sub_hash) def sign(self, md='sha1'): self._proxy.sign(self._certificate.get_key(), md) def __str__(self): return self._proxy.__str__() def __repr__(self): return self._proxy.__repr__() def as_der(self): return self._proxy._certificate.as_der()