mirror of
https://github.com/saymrwulf/cryptography.git
synced 2026-05-14 20:37:55 +00:00
feat(admissions): add admissions extension type (#11886)
* feat(admissions): add admissions extension type Signed-off-by: Oleg Hoefling <oleg.hoefling@gmail.com> * fix: use tuple for admissions unpacking in hash code calculation Signed-off-by: Oleg Hoefling <oleg.hoefling@gmail.com> --------- Signed-off-by: Oleg Hoefling <oleg.hoefling@gmail.com>
This commit is contained in:
parent
78b3750a3b
commit
cf93084b0e
5 changed files with 163 additions and 0 deletions
|
|
@ -39,6 +39,7 @@ class ExtensionOID:
|
|||
PRECERT_POISON = ObjectIdentifier("1.3.6.1.4.1.11129.2.4.3")
|
||||
SIGNED_CERTIFICATE_TIMESTAMPS = ObjectIdentifier("1.3.6.1.4.1.11129.2.4.5")
|
||||
MS_CERTIFICATE_TEMPLATE = ObjectIdentifier("1.3.6.1.4.1.311.21.7")
|
||||
ADMISSIONS = ObjectIdentifier("1.3.36.8.3.3")
|
||||
|
||||
|
||||
class OCSPExtensionOID:
|
||||
|
|
@ -284,6 +285,7 @@ _OID_NAMES = {
|
|||
),
|
||||
ExtensionOID.PRECERT_POISON: "ctPoison",
|
||||
ExtensionOID.MS_CERTIFICATE_TEMPLATE: "msCertificateTemplate",
|
||||
ExtensionOID.ADMISSIONS: "Admissions",
|
||||
CRLEntryExtensionOID.CRL_REASON: "cRLReason",
|
||||
CRLEntryExtensionOID.INVALIDITY_DATE: "invalidityDate",
|
||||
CRLEntryExtensionOID.CERTIFICATE_ISSUER: "certificateIssuer",
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ from cryptography.x509.base import (
|
|||
from cryptography.x509.extensions import (
|
||||
AccessDescription,
|
||||
Admission,
|
||||
Admissions,
|
||||
AuthorityInformationAccess,
|
||||
AuthorityKeyIdentifier,
|
||||
BasicConstraints,
|
||||
|
|
@ -178,6 +179,7 @@ __all__ = [
|
|||
"OID_OCSP",
|
||||
"AccessDescription",
|
||||
"Admission",
|
||||
"Admissions",
|
||||
"Attribute",
|
||||
"AttributeNotFound",
|
||||
"Attributes",
|
||||
|
|
|
|||
|
|
@ -2389,6 +2389,54 @@ class Admission:
|
|||
)
|
||||
|
||||
|
||||
class Admissions(ExtensionType):
|
||||
oid = ExtensionOID.ADMISSIONS
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
authority: GeneralName | None,
|
||||
admissions: typing.Iterable[Admission],
|
||||
) -> None:
|
||||
if authority is not None and not isinstance(authority, GeneralName):
|
||||
raise TypeError("authority must be a GeneralName")
|
||||
|
||||
admissions = list(admissions)
|
||||
if not all(
|
||||
isinstance(admission, Admission) for admission in admissions
|
||||
):
|
||||
raise TypeError(
|
||||
"Every item in the contents_of_admissions list must be an "
|
||||
"Admission"
|
||||
)
|
||||
|
||||
self._authority = authority
|
||||
self._admissions = admissions
|
||||
|
||||
__len__, __iter__, __getitem__ = _make_sequence_methods("_admissions")
|
||||
|
||||
@property
|
||||
def authority(self) -> GeneralName | None:
|
||||
return self._authority
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return (
|
||||
f"<Admissions(authority={self._authority}, "
|
||||
f"admissions={self._admissions})>"
|
||||
)
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if not isinstance(other, Admissions):
|
||||
return NotImplemented
|
||||
|
||||
return (
|
||||
self.authority == other.authority
|
||||
and self._admissions == other._admissions
|
||||
)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash((self.authority, *tuple(self._admissions)))
|
||||
|
||||
|
||||
class UnrecognizedExtension(ExtensionType):
|
||||
def __init__(self, oid: ObjectIdentifier, value: bytes) -> None:
|
||||
if not isinstance(oid, ObjectIdentifier):
|
||||
|
|
|
|||
|
|
@ -326,6 +326,17 @@ pub struct Admission<'a> {
|
|||
*/
|
||||
}
|
||||
|
||||
// #[derive(asn1::Asn1Read, asn1::Asn1Write)]
|
||||
pub struct Admissions<'a> {
|
||||
pub admission_authority: Option<name::GeneralName<'a>>,
|
||||
/*
|
||||
pub contents_of_admissions: common::Asn1ReadableOrWritable<
|
||||
asn1::SequenceOf<'a, Admission<'a>>,
|
||||
asn1::SequenceOfWriter<'a, Admission<'a>, Vec<Admission<'a>>>,
|
||||
>,
|
||||
*/
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{BasicConstraints, Extension, Extensions, KeyUsage};
|
||||
|
|
|
|||
|
|
@ -6995,6 +6995,106 @@ class TestAdmission:
|
|||
assert hash(admission1) != hash(admission6)
|
||||
|
||||
|
||||
class TestAdmissions:
|
||||
def test_invalid_init(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.Admissions(
|
||||
42, # type:ignore[arg-type]
|
||||
[],
|
||||
)
|
||||
with pytest.raises(TypeError):
|
||||
x509.Admissions(
|
||||
None,
|
||||
42, # type:ignore[arg-type]
|
||||
)
|
||||
with pytest.raises(TypeError):
|
||||
x509.Admissions(
|
||||
None,
|
||||
[42], # type:ignore[list-item]
|
||||
)
|
||||
with pytest.raises(TypeError):
|
||||
x509.Admissions(
|
||||
None,
|
||||
[None], # type:ignore[list-item]
|
||||
)
|
||||
|
||||
def test_eq(self):
|
||||
admissions1 = x509.Admissions(None, [])
|
||||
admissions2 = x509.Admissions(None, [])
|
||||
assert admissions1 == admissions2
|
||||
|
||||
admissions1 = x509.Admissions(
|
||||
x509.UniformResourceIdentifier(value="https://www.example.de"),
|
||||
[x509.Admission(None, None, [])],
|
||||
)
|
||||
admissions2 = x509.Admissions(
|
||||
x509.UniformResourceIdentifier(value="https://www.example.de"),
|
||||
[x509.Admission(None, None, [])],
|
||||
)
|
||||
assert admissions1 == admissions2
|
||||
|
||||
def test_ne(self):
|
||||
admissions1 = x509.Admissions(
|
||||
x509.UniformResourceIdentifier(value="https://www.example.de"),
|
||||
[x509.Admission(None, None, [])],
|
||||
)
|
||||
admissions2 = x509.Admissions(
|
||||
x509.UniformResourceIdentifier(value="https://www.example.de"), []
|
||||
)
|
||||
admissions3 = x509.Admissions(
|
||||
None,
|
||||
[x509.Admission(None, None, [])],
|
||||
)
|
||||
admissions4 = x509.Admissions(None, [])
|
||||
|
||||
assert admissions1 != admissions2
|
||||
assert admissions1 != admissions3
|
||||
assert admissions1 != admissions4
|
||||
assert admissions1 != object()
|
||||
|
||||
def test_repr(self):
|
||||
admissions = x509.Admissions(None, [])
|
||||
assert repr(admissions) == (
|
||||
"<Admissions(authority=None, admissions=[])>"
|
||||
)
|
||||
|
||||
admissions = x509.Admissions(
|
||||
x509.UniformResourceIdentifier(value="https://www.example.de"),
|
||||
[x509.Admission(None, None, [])],
|
||||
)
|
||||
assert repr(admissions) == (
|
||||
"<Admissions("
|
||||
"authority=<UniformResourceIdentifier("
|
||||
"value='https://www.example.de')>, "
|
||||
"admissions=[<Admission("
|
||||
"admission_authority=None, "
|
||||
"naming_authority=None, "
|
||||
"profession_infos=[])>])>"
|
||||
)
|
||||
|
||||
def test_hash(self):
|
||||
admissions1 = x509.Admissions(
|
||||
x509.UniformResourceIdentifier(value="https://www.example.de"),
|
||||
[x509.Admission(None, None, [])],
|
||||
)
|
||||
admissions2 = x509.Admissions(
|
||||
x509.UniformResourceIdentifier(value="https://www.example.de"),
|
||||
[x509.Admission(None, None, [])],
|
||||
)
|
||||
admissions3 = x509.Admissions(
|
||||
x509.UniformResourceIdentifier(value="https://www.example.de"), []
|
||||
)
|
||||
admissions4 = x509.Admissions(
|
||||
None,
|
||||
[x509.Admission(None, None, [])],
|
||||
)
|
||||
admissions5 = x509.Admissions(None, [])
|
||||
assert hash(admissions1) == hash(admissions2)
|
||||
assert hash(admissions1) != hash(admissions3)
|
||||
assert hash(admissions1) != hash(admissions4)
|
||||
assert hash(admissions1) != hash(admissions5)
|
||||
|
||||
|
||||
def test_all_extension_oid_members_have_names_defined():
|
||||
for oid in dir(ExtensionOID):
|
||||
if oid.startswith("__"):
|
||||
|
|
|
|||
Loading…
Reference in a new issue