def dn_setup(self): # ava1 must sort before ava2 self.attr1 = 'cn' self.value1 = u'Bob' self.str_ava1 = '%s=%s' % (self.attr1, self.value1) self.ava1 = AVA(self.attr1, self.value1) self.str_rdn1 = '%s=%s' % (self.attr1, self.value1) self.rdn1 = RDN((self.attr1, self.value1)) self.attr2 = 'ou' self.value2 = u'people' self.str_ava2 = '%s=%s' % (self.attr2, self.value2) self.ava2 = AVA(self.attr2, self.value2) self.str_rdn2 = '%s=%s' % (self.attr2, self.value2) self.rdn2 = RDN((self.attr2, self.value2)) self.str_dn1 = self.str_rdn1 self.dn1 = DN(self.rdn1) self.str_dn2 = self.str_rdn2 self.dn2 = DN(self.rdn2) self.str_dn3 = '%s,%s' % (self.str_rdn1, self.str_rdn2) self.dn3 = DN(self.rdn1, self.rdn2) self.base_rdn1 = RDN(('dc', 'redhat')) self.base_rdn2 = RDN(('dc', 'com')) self.base_dn = DN(self.base_rdn1, self.base_rdn2) self.container_rdn1 = RDN(('cn', 'sudorules')) self.container_rdn2 = RDN(('cn', 'sudo')) self.container_dn = DN(self.container_rdn1, self.container_rdn2) self.base_container_dn = DN((self.attr1, self.value1), self.container_dn, self.base_dn) ou = x509.NameAttribute( x509.NameOID.ORGANIZATIONAL_UNIT_NAME, self.value2) cn = x509.NameAttribute(x509.NameOID.COMMON_NAME, self.value1) c = x509.NameAttribute(x509.NameOID.COUNTRY_NAME, 'AU') st = x509.NameAttribute( x509.NameOID.STATE_OR_PROVINCE_NAME, 'Queensland') self.x500name = x509.Name([ou, cn]) self.x500nameMultiRDN = x509.Name([ x509.RelativeDistinguishedName([c, st]), x509.RelativeDistinguishedName([cn]), ]) self.x500nameMultiRDN2 = x509.Name([ x509.RelativeDistinguishedName([st, c]), x509.RelativeDistinguishedName([cn]), ])
def test_multi_valued_rdns(self, tdata): subject = x509.Name([ x509.RelativeDistinguishedName([ x509.NameAttribute(NameOID.TITLE, u'Test'), x509.NameAttribute(NameOID.COMMON_NAME, u'Multivalue'), x509.NameAttribute(NameOID.SURNAME, u'RDNs'), x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'TSLA'), ]), x509.RelativeDistinguishedName( [x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA')]), ]) expected = [('2.5.4.12', 'Test'), ('CN', 'Multivalue'), ('2.5.4.4', 'RDNs'), ('O', 'TSLA'), ('O', 'PyCA')] assert (certs._name_to_keyval(subject)) == expected
def test_format(self): rdn = x509.RelativeDistinguishedName( [x509.NameAttribute(NameOID.COMMON_NAME, u'example.com')]) self.assertEqual( format_relative_name([('C', 'AT'), ('CN', 'example.com')]), '/C=AT/CN=example.com') self.assertEqual(format_relative_name(rdn), '/CN=example.com')
def _decode_distpoint(backend, distpoint): if distpoint.type == _DISTPOINT_TYPE_FULLNAME: full_name = _decode_general_names(backend, distpoint.name.fullname) return full_name, None # OpenSSL code doesn't test for a specific type for # relativename, everything that isn't fullname is considered # relativename. Per RFC 5280: # # DistributionPointName ::= CHOICE { # fullName [0] GeneralNames, # nameRelativeToCRLIssuer [1] RelativeDistinguishedName } rns = distpoint.name.relativename rnum = backend._lib.sk_X509_NAME_ENTRY_num(rns) attributes = set() for i in range(rnum): rn = backend._lib.sk_X509_NAME_ENTRY_value( rns, i ) backend.openssl_assert(rn != backend._ffi.NULL) attributes.add( _decode_x509_name_entry(backend, rn) ) relative_name = x509.RelativeDistinguishedName(attributes) return None, relative_name
def x509_relative_name(name: str) -> x509.RelativeDistinguishedName: """Parse a relative name (RDN) into a :py:class:`~cg:cryptography.x509.RelativeDistinguishedName`. >>> x509_relative_name('/CN=example.com') <RelativeDistinguishedName(CN=example.com)> """ msg = f"Passing a {name.__class__.__name__} to x509_relative_name() is deprecated, pass a str instead" if isinstance(name, x509.RelativeDistinguishedName): warnings.warn(msg, category=RemovedInDjangoCA122Warning, stacklevel=1) return name if isinstance(name, (list, tuple)): warnings.warn(msg, category=RemovedInDjangoCA122Warning, stacklevel=1) return x509.RelativeDistinguishedName( [x509.NameAttribute(NAME_OID_MAPPINGS[typ], value) for typ, value in name] ) return x509.RelativeDistinguishedName(parse_name_x509(name))
def x509_relative_name(name): """Parse a relative name (RDN) into a :py:class:`~cg:cryptography.x509.RelativeDistinguishedName`. >>> x509_relative_name('/CN=example.com') <RelativeDistinguishedName(CN=example.com)> >>> x509_relative_name([('CN', 'example.com')]) <RelativeDistinguishedName(CN=example.com)> """ if isinstance(name, six.string_types): name = parse_name(name) return x509.RelativeDistinguishedName([ x509.NameAttribute(NAME_OID_MAPPINGS[typ], force_text(value)) for typ, value in name ])
def _decode_x509_name(backend, x509_name): count = backend._lib.X509_NAME_entry_count(x509_name) attributes = [] prev_set_id = -1 for x in range(count): entry = backend._lib.X509_NAME_get_entry(x509_name, x) attribute = _decode_x509_name_entry(backend, entry) set_id = backend._lib.Cryptography_X509_NAME_ENTRY_set(entry) if set_id != prev_set_id: attributes.append(set[attribute]) else: attributes[-1].add(attribute) prev_set_id = set_id return x509.Name(x509.RelativeDistinguishedName(rdn) for rdn in attributes)
def parse_rfc4514_string(value: str) -> x509.Name: """Parses an RFC 4514 string into a x509.Name. See: https://tools.ietf.org/html/rfc4514.html """ name = _parse(value) attributes: List[x509.RelativeDistinguishedName] = [] for entry in name: parts = [] for part in entry: if "=" not in part: raise ValueError("Invalid RFC 4514 string") k, v = part.split("=", 1) if k not in _NAME_ATTRIBUTES: raise ValueError(f"Unsupported attribute: '{k}'") parts.append(x509.NameAttribute(_NAME_ATTRIBUTES[k], v)) attributes.insert(0, x509.RelativeDistinguishedName(parts)) return x509.Name(attributes)
def x509_relative_name( name: Union[str, Iterable[Tuple[str, str]]]) -> x509.RelativeDistinguishedName: """Parse a relative name (RDN) into a :py:class:`~cg:cryptography.x509.RelativeDistinguishedName`. >>> x509_relative_name('/CN=example.com') <RelativeDistinguishedName(CN=example.com)> >>> x509_relative_name([('CN', 'example.com')]) <RelativeDistinguishedName(CN=example.com)> """ if isinstance(name, x509.RelativeDistinguishedName): return name if isinstance(name, str): name = parse_name(name) return x509.RelativeDistinguishedName([ x509.NameAttribute(NAME_OID_MAPPINGS[typ], force_str(value)) for typ, value in name ])
def _parse_rdn(self, rdn): """Parse an X.509 relative distinguished name""" return x509.RelativeDistinguishedName( self._parse_nameattr(av) for av in self._split_rdn.findall(rdn))
def rdn( name: typing.Iterable[typing.Tuple[x509.ObjectIdentifier, str]] ) -> x509.RelativeDistinguishedName: # just a shortcut """Shortcut to get a :py:class:`cg:cryptography.x509..RelativeDistinguishedNam`.""" return x509.RelativeDistinguishedName([x509.NameAttribute(*t) for t in name])
def _decode_dist_points(backend, cdps): cdps = backend._ffi.cast("Cryptography_STACK_OF_DIST_POINT *", cdps) cdps = backend._ffi.gc(cdps, backend._lib.CRL_DIST_POINTS_free) num = backend._lib.sk_DIST_POINT_num(cdps) dist_points = [] for i in range(num): full_name = None relative_name = None crl_issuer = None reasons = None cdp = backend._lib.sk_DIST_POINT_value(cdps, i) if cdp.reasons != backend._ffi.NULL: # We will check each bit from RFC 5280 # ReasonFlags ::= BIT STRING { # unused (0), # keyCompromise (1), # cACompromise (2), # affiliationChanged (3), # superseded (4), # cessationOfOperation (5), # certificateHold (6), # privilegeWithdrawn (7), # aACompromise (8) } reasons = [] get_bit = backend._lib.ASN1_BIT_STRING_get_bit if get_bit(cdp.reasons, 1): reasons.append(x509.ReasonFlags.key_compromise) if get_bit(cdp.reasons, 2): reasons.append(x509.ReasonFlags.ca_compromise) if get_bit(cdp.reasons, 3): reasons.append(x509.ReasonFlags.affiliation_changed) if get_bit(cdp.reasons, 4): reasons.append(x509.ReasonFlags.superseded) if get_bit(cdp.reasons, 5): reasons.append(x509.ReasonFlags.cessation_of_operation) if get_bit(cdp.reasons, 6): reasons.append(x509.ReasonFlags.certificate_hold) if get_bit(cdp.reasons, 7): reasons.append(x509.ReasonFlags.privilege_withdrawn) if get_bit(cdp.reasons, 8): reasons.append(x509.ReasonFlags.aa_compromise) reasons = frozenset(reasons) if cdp.CRLissuer != backend._ffi.NULL: crl_issuer = _decode_general_names(backend, cdp.CRLissuer) # Certificates may have a crl_issuer/reasons and no distribution # point so make sure it's not null. if cdp.distpoint != backend._ffi.NULL: # Type 0 is fullName, there is no #define for it in the code. if cdp.distpoint.type == _DISTPOINT_TYPE_FULLNAME: full_name = _decode_general_names(backend, cdp.distpoint.name.fullname) # OpenSSL code doesn't test for a specific type for # relativename, everything that isn't fullname is considered # relativename. Per RFC 5280: # # DistributionPointName ::= CHOICE { # fullName [0] GeneralNames, # nameRelativeToCRLIssuer [1] RelativeDistinguishedName } else: rns = cdp.distpoint.name.relativename rnum = backend._lib.sk_X509_NAME_ENTRY_num(rns) attributes = set() for i in range(rnum): rn = backend._lib.sk_X509_NAME_ENTRY_value(rns, i) backend.openssl_assert(rn != backend._ffi.NULL) attributes.add(_decode_x509_name_entry(backend, rn)) relative_name = x509.RelativeDistinguishedName(attributes) dist_points.append( x509.DistributionPoint(full_name, relative_name, reasons, crl_issuer)) return dist_points
def test_parse(self): expected = x509.RelativeDistinguishedName( [x509.NameAttribute(NameOID.COMMON_NAME, u'example.com')]) self.assertEqual(x509_relative_name('/CN=example.com'), expected) self.assertEqual(x509_relative_name([('CN', 'example.com')]), expected)
def rdn(name): # just a shortcut """Shortcut to get a :py:class:`cg:cryptography.x509..RelativeDistinguishedNam`.""" return x509.RelativeDistinguishedName( [x509.NameAttribute(*t) for t in name])