|
1 | 1 | GSSAPI="BASE" # This ensures that a full module is generated by Cython |
2 | 2 |
|
| 3 | +import six |
| 4 | + |
3 | 5 | from libc.string cimport memcmp, memcpy |
4 | 6 | from libc.stdlib cimport free, malloc |
5 | 7 |
|
@@ -61,6 +63,54 @@ cdef class OID: |
61 | 63 | memcpy(self.raw_oid.elements, byte_str, self.raw_oid.length) |
62 | 64 | return 0 |
63 | 65 |
|
| 66 | + @classmethod |
| 67 | + def from_int_seq(cls, integer_sequence): |
| 68 | + """Create a OID from a sequence of integers |
| 69 | +
|
| 70 | + This method creates an OID from a sequence of integers. |
| 71 | + The sequence can either be in dotted form as a string, |
| 72 | + or in list form. |
| 73 | +
|
| 74 | + This method is not for BER-encoded byte strings, which |
| 75 | + can be passed directly to the OID constructor. |
| 76 | +
|
| 77 | + Args: |
| 78 | + integer_sequence: either a list of integers or |
| 79 | + a string in dotted form |
| 80 | +
|
| 81 | + Returns: |
| 82 | + OID: the OID represented by the given integer sequence |
| 83 | +
|
| 84 | + Raises: |
| 85 | + ValueError: the sequence is less than two elements long |
| 86 | + """ |
| 87 | + |
| 88 | + if isinstance(integer_sequence, six.string_types): |
| 89 | + integer_sequence = integer_sequence.split('.') |
| 90 | + |
| 91 | + oid_seq = [int(x) for x in integer_sequence] |
| 92 | + |
| 93 | + elements = cls._encode_asn1ber(oid_seq) |
| 94 | + |
| 95 | + return cls(elements=elements) |
| 96 | + |
| 97 | + @staticmethod |
| 98 | + def _encode_asn1ber(oid_seq): |
| 99 | + if len(oid_seq) < 2: |
| 100 | + raise ValueError("Sequence must be 2 or more elements long.") |
| 101 | + |
| 102 | + byte_seq = bytearray([oid_seq[0] * 40 + oid_seq[1]]) |
| 103 | + for element in oid_seq[2:]: |
| 104 | + element_seq = [element & 0x7f] |
| 105 | + |
| 106 | + while element > 127: |
| 107 | + element >>= 7 |
| 108 | + element_seq.insert(0, (element & 0x7f) | 0x80) |
| 109 | + |
| 110 | + byte_seq.extend(element_seq) |
| 111 | + |
| 112 | + return bytes(byte_seq) |
| 113 | + |
64 | 114 | def __dealloc__(self): |
65 | 115 | # NB(directxman12): MIT Kerberos has gss_release_oid |
66 | 116 | # for this purpose, but it's not in the RFC |
|
0 commit comments