class SignedData(Sequence): componentType = NamedTypes( NamedType('digestAlgorithm', UniversalString()), NamedType('signatureAlgorithm', UniversalString()), NamedType('certificate', OctetString()), NamedType('signature', OctetString()), NamedType('dataGroupHash', DataGroupHash()))
class NegTokenInit(Sequence): """ [RFC-4178] NegTokenInit ::= SEQUENCE { mechTypes [0] MechTypeList, regFlags [1] ContextFlags OPTIONAL, mechToken [2] OCTET STRING OPTIONAL, mechListMIC [3] OCTER STRING OPTIONAL, ... } """ componentType = NamedTypes( NamedType( 'mechTypes', MechTypeList().subtype( explicitTag=Tag(tagClassContext, tagFormatConstructed, 0) ) ), OptionalNamedType( 'reqFlags', ContextFlags().subtype( explicitTag=Tag(tagClassContext, tagFormatConstructed, 1) ) ), OptionalNamedType( 'mechToken', OctetString().subtype( explicitTag=Tag(tagClassContext, tagFormatSimple, 2) ) ), OptionalNamedType( 'mechListMIC', OctetString().subtype( explicitTag=Tag(tagClassContext, tagFormatSimple, 3) ) ) )
def encode(ecdsa_key: object, **kwargs): alg_id = SequenceOf() alg_id.setComponentByPosition( 0, ObjectIdentifier([1, 2, 840, 10045, 2, 1])) alg_id.setComponentByPosition( 1, ObjectIdentifier( ber_decoder.decode(b'\x06' + bytes([len(ecdsa_key.G.curve.oid)]) + ecdsa_key.G.curve.oid)[0].asTuple())) zero_fill = math.ceil(ecdsa_key.G.curve.q.bit_length() / 8) params_seq = Sequence() params_seq.setComponentByPosition(0, Integer(1)) params_seq.setComponentByPosition( 1, OctetString(Bytes(ecdsa_key.d).zfill(zero_fill))) params_seq.setComponentByPosition( 2, PublicPoint(ecdsa_key.format_public_point())) param_oct = OctetString(encoder.encode(params_seq)) top_seq = Sequence() top_seq.setComponentByPosition(0, Integer(0)) top_seq.setComponentByPosition(1, alg_id) top_seq.setComponentByPosition(2, param_oct) encoded = encoder.encode(top_seq) encoded = PKCS8ECDSAPrivateKey.transport_encode(encoded, **kwargs) return encoded
class TSPasswordCreds(Sequence): """ [MS-CSSP] 2.2.1.2.1 TSPasswordCreds https://msdn.microsoft.com/en-us/library/cc226783.aspx Contains the user's password credentials that are delegated to the server. TSPasswordCreds ::= SEQUENCE { domainName [0] OCTET STRING, userName [1] OCTET STRING, password [2] OCTET STRING } """ CRED_TYPE = 1 # 2.2.1.2 TSCredentials componentType = NamedTypes( NamedType( 'domainName', OctetString().subtype( explicitTag=Tag(tagClassContext, tagFormatConstructed, 0) ) ), NamedType( 'userName', OctetString().subtype( explicitTag=Tag(tagClassContext, tagFormatConstructed, 1) ) ), NamedType( 'password', OctetString().subtype( explicitTag=Tag(tagClassContext, tagFormatConstructed, 2) ) ), )
def validate_engine_id(engine_id): # Validate engine_id, check octet string can be formed from it try: OctetString.fromHexString(engine_id) except ValueError: msg = "engine_id should be a set of octets in " \ "hexadecimal format." raise exception.InvalidInput(msg)
def test_ip_unexpected(self): errname = "Enc_DER_Struct_GenName_IPAddress_Unexpected" self._validate("iPAddress", OctetString(bytes([172, 31, 12, 4])), assert_absent=errname) self._validate("iPAddress", OctetString(bytes([172, 31, 12, 4])), additional_errors=[errname], assert_present=errname)
def encodeLoginData(key, data): iv = secrets.token_bytes(8) des = DES3.new(key, DES3.MODE_CBC, iv) ciphertext = des.encrypt(PKCS7pad(data.encode())) asn1data = Sequence() asn1data[0] = OctetString(MAGIC1) asn1data[1] = Sequence() asn1data[1][0] = ObjectIdentifier(MAGIC2) asn1data[1][1] = OctetString(iv) asn1data[2] = OctetString(ciphertext) return b64encode(der_encode(asn1data)).decode()
class RootOfTrust(Sequence): """Information about the device's status. References: * https://developer.android.com/training/articles/security-key-attestation#certificate_schema_rootoftrust """ componentType = NamedTypes( NamedType('verifiedBootKey', OctetString()), NamedType('deviceLocked', Boolean()), NamedType('verifiedBootState', VerifiedBootState()), NamedType('verifiedBootHash', OctetString()), )
def test_get(self): self.datastore.should_receive('get').with_args((1, 1)) \ .and_return((1, 1), OctetString('test')) self.service.message_received(self.transport_dispatcher, sentinel.transport_domain, sentinel.transport_address, MSG_SNMP_GET) varbindlist = TraversableMessage( self.capture_matcher.obj)[PDUs][ResponsePDU][VarBindList] self.assertEqual(varbindlist[VarBind][ObjectName].value, (1, 1)) self.assertEqual( varbindlist[VarBind][_BindValue][ObjectSyntax][SimpleSyntax] [OctetString].value, OctetString("test"))
class RingSignatureSchema(Sequence): """An ASN.1 schema for ring signatures. Ring signatures are identified with an object ID following Recommendation ITU-T X.667. The UUID4 used is 3b5e61af-c4ec-496e-95e9-4b64bccdc809. """ componentType = NamedTypes( NamedType("algorithm", ObjectIdentifier(value=_OBJECT_ID)), NamedType("key_image", OctetString()), NamedType("public_keys", SequenceOf(componentType=OctetString())), NamedType("c", SequenceOf(componentType=OctetString())), NamedType("r", SequenceOf(componentType=OctetString())), )
def mock_extended(self, request_message, controls): # ExtendedRequest ::= [APPLICATION 23] SEQUENCE { # requestName [0] LDAPOID, # requestValue [1] OCTET STRING OPTIONAL } # # ExtendedResponse ::= [APPLICATION 24] SEQUENCE { # COMPONENTS OF LDAPResult, # responseName [10] LDAPOID OPTIONAL, # responseValue [11] OCTET STRING OPTIONAL } # # IntermediateResponse ::= [APPLICATION 25] SEQUENCE { # responseName [0] LDAPOID OPTIONAL, # responseValue [1] OCTET STRING OPTIONAL } request = extended_request_to_dict(request_message) result_code = RESULT_UNWILLING_TO_PERFORM message = 'not implemented' response_name = None response_value = None if self.connection.server.info: for extension in self.connection.server.info.supported_extensions: if request['name'] == extension[ 0]: # server can answer the extended request if extension[ 0] == '2.16.840.1.113719.1.27.100.31': # getBindDNRequest [NOVELL] result_code = 0 message = '' response_name = OctetString( '2.16.840.1.113719.1.27.100.32' ) # getBindDNResponse [NOVELL] response_value = OctetString(self.bound) elif extension[ 0] == '1.3.6.1.4.1.4203.1.11.3': # WhoAmI [RFC4532] result_code = 0 message = '' response_name = OctetString( '1.3.6.1.4.1.4203.1.11.3') # WhoAmI [RFC4532] response_value = OctetString(self.bound) break return { 'resultCode': result_code, 'matchedDN': '', 'diagnosticMessage': to_unicode(message, SERVER_ENCODING), 'referral': None, 'responseName': response_name, 'responseValue': response_value }
def test_signing_consistency(self): # test signature creation and verification for each test message for msg in self.TEST_MSGS: # generate a test RSA private key private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=default_backend()) # get a corresponding public key public_key = private_key.public_key() # precreate simple ASN.1 structure to encode and encrypt test_der = encode(OctetString(msg)) # generate a signature of a test message sign = self.crypto_obj._Crypto__sign_content(test_der, private_key) # attempt to verify a signature res = self.crypto_obj._Crypto__verify_signature( sign, public_key, test_der) # check whether verification was successful self.assertTrue(res)
def parse_certificate(certificate_path): fqdns = set() substrate = pem.readPemFromFile(open(certificate_path)) cert = decoder.decode(substrate, asn1Spec=rfc2459.Certificate())[0] core = cert['tbsCertificate'] # Hash public key der = encoder.encode(core.getComponentByName('subjectPublicKeyInfo')) hash_der = hashlib.sha256() hash_der.update(der) pkhash = hash_der.hexdigest() # Extract CommonName for rdnss in core['subject']: for rdns in rdnss: for name in rdns: if name.getComponentByName('type') == rfc2459.id_at_commonName: value = decoder.decode( name.getComponentByName('value'), asn1Spec=rfc2459.DirectoryString())[0] fqdns.add(str(value.getComponent())) # Extract SubjectAltName for extension in core['extensions']: if extension['extnID'] == rfc2459.id_ce_subjectAltName: octet_string = decoder.decode( extension.getComponentByName('extnValue'), asn1Spec=OctetString())[0] (san_list, r) = decoder.decode(octet_string, rfc2459.SubjectAltName()) for san_struct in san_list: if san_struct.getName() == 'dNSName': fqdns.add(str(san_struct.getComponent())) return (pkhash, fqdns)
class Control(Sequence): """ Control ::= SEQUENCE { controlType LDAPOID, criticality BOOLEAN DEFAULT FALSE, controlValue OCTET STRING OPTIONAL } """ componentType = NamedTypes( NamedType('controlType', LDAPOID()), DefaultedNamedType('criticality', Boolean(False)), OptionalNamedType('controlValue', OctetString()), ) def setComponentByPosition(self, idx, value=None, verifyConstraints=True, exactTypes=False, matchTags=True, matchConstraints=True): if idx == 0: # controlType try: cls = KNOWN_CONTROLS[value] if self.__class__ != cls: self.__class__ = cls except KeyError: pass return Sequence.setComponentByPosition(self, idx, value, verifyConstraints, exactTypes, matchTags, matchConstraints)
class Ed25519FingerprintContents(Sequence): componentType = NamedTypes( NamedType( 'publicKey', OctetString().subtype( subtypeSpec=ValueSizeConstraint(32, 32)).subtype( implicitTag=Tag(tagClassContext, tagFormatSimple, 0))), )
class KeyDescription(Sequence): """Information about the key pair being verified through key attestation. References: * https://developer.android.com/training/articles/security-key-attestation#certificate_schema_keydescription """ componentType = NamedTypes( NamedType('attestationVersion', Integer()), NamedType('attestationSecurityLevel', SecurityLevel()), NamedType('keymasterVersion', Integer()), NamedType('keymasterSecurityLevel', SecurityLevel()), NamedType('attestationChallenge', OctetString()), NamedType('uniqueId', OctetString()), NamedType('softwareEnforced', AuthorizationList()), NamedType('teeEnforced', AuthorizationList()), )
def pkcs7_sign_msg(self, msg): '''WIP: PKCS#7 sign with certificate ''' signed = self.sign(msg) owner_cert_pub = self.pub_cert # signedData (PKCS #7) oi_pkcs7_signed = ObjectIdentifier((1, 2, 840, 113549, 1, 7, 2)) oi_pkcs7_data = ObjectIdentifier((1, 2, 840, 113549, 1, 7, 1)) oi_sha256 = ObjectIdentifier((2, 16, 840, 1, 101, 3, 4, 2, 1)) oi_pkcs7_rsa_enc = ObjectIdentifier((1, 2, 840, 113549, 1, 1, 1)) der = Sequence().setComponentByPosition(0, oi_pkcs7_signed) data = Sequence() data = data.setComponentByPosition(0, Integer(1)) data = data.setComponentByPosition(1, Set().setComponentByPosition(0, Sequence().setComponentByPosition(0, oi_sha256).setComponentByPosition(1, Null('')))) data = data.setComponentByPosition(2, Sequence().setComponentByPosition(0, oi_pkcs7_data).setComponentByPosition(1, Sequence().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)).setComponentByPosition(0, OctetString(hexValue=msg.encode('hex'))))) data = data.setComponentByPosition(3, Sequence().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)).setComponentByPosition(0, owner_cert_pub)) data4001 = Sequence().setComponentByPosition(0, owner_cert_pub[0][3]) data4001 = data4001.setComponentByPosition(1, owner_cert_pub[0][1]) data4002 = Sequence().setComponentByPosition(0, oi_sha256).setComponentByPosition(1, Null('')) data4003 = Sequence().setComponentByPosition(0, oi_pkcs7_rsa_enc).setComponentByPosition(1, Null('')) data4004 = OctetString(hexValue=signed.encode('hex')) data = data.setComponentByPosition(4, Set().setComponentByPosition(0, Sequence().setComponentByPosition(0, Integer(1)).setComponentByPosition(1, data4001).setComponentByPosition(2, data4002).setComponentByPosition(3, data4003).setComponentByPosition(4, data4004))) der = der.setComponentByPosition(1, Sequence().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)).setComponentByPosition(0, data)) return der_encoder.encode(der)
def scts_from_ocsp_resp(ocsp_resp_der): '''Return list of SCTs of the OCSP status response. Args: ocsp_resp_der(bytes): DER encoded OCSP status response Return: [<ctutlz.rfc6962.SignedCertificateTimestamp>, ...] ''' if ocsp_resp_der: ocsp_resp, _ = der_decoder( ocsp_resp_der, asn1Spec=pyasn1_modules.rfc2560.OCSPResponse()) response_bytes = ocsp_resp.getComponentByName('responseBytes') if response_bytes is not None: # os: octet string response_os = response_bytes.getComponentByName('response') der_decoder.defaultErrorState = ber.decoder.stDumpRawValue response, _ = der_decoder(response_os, Sequence()) sctlist_os_hex = sctlist_hex_from_ocsp_pretty_print( response.prettyPrint()) if sctlist_os_hex: sctlist_os_der = binascii.unhexlify(sctlist_os_hex) sctlist_os, _ = der_decoder(sctlist_os_der, OctetString()) sctlist_hex = sctlist_os.prettyPrint().split('0x')[-1] sctlist_der = binascii.unhexlify(sctlist_hex) sctlist = SignedCertificateTimestampList(sctlist_der) return [SignedCertificateTimestamp(entry.sct_der) for entry in sctlist.sct_list] return []
def dir_sync_control(criticality, object_security, ancestors_first, public_data_only, incremental_values, max_length, cookie): control_value = DirSyncControlRequestValue() flags = 0x0 if object_security: flags |= 0x00000001 if ancestors_first: flags |= 0x00000800 if public_data_only: flags |= 0x00002000 if incremental_values: flags |= 0x80000000 # converts flags to signed 32 bit (AD expects a 4 bytes long unsigned integer, but ASN.1 Integer type is signed # so the BER encoder gives back a 5 bytes long signed integer flags = ctypes.c_long(flags & 0xFFFFFFFF).value control_value.setComponentByName('Flags', flags) control_value.setComponentByName('MaxBytes', max_length) if cookie: control_value.setComponentByName('Cookie', cookie) else: control_value.setComponentByName('Cookie', OctetString('')) return build_control('1.2.840.113556.1.4.841', criticality, control_value)
def _encode_octet(obj: univ.OctetString) -> str: """ Encodes a STRING OCTET type Args: obj: A PyASN1 STRING_OCTET type Returns: A string containing the encoded binary """ dec_constraint = _extract_value_size_constraint(str(obj.getSubtypeSpec())) oct_str = str(obj) if dec_constraint == -1: # No constraint length = len(str(obj)) len_det = _bit_str_pad(bin(length)[2:], 8, '0') return len_det + ''.join([_bit_str_pad(bin(ord(oct_str[x]))[2:], 8, '0') for x in range(len(oct_str))]) if dec_constraint[1] == 0: return None elif dec_constraint[0] == dec_constraint[1]: if len(obj) == dec_constraint[0]: return ''.join([_bit_str_pad(bin(ord(oct_str[x]))[2:], 8, '0') for x in range( len(oct_str))]) else: raise ValueError('[PyASN1PEREncoder][ERROR]: Octet string does not fit the ' 'constraints - cannot encode [len != const_len]') elif len(oct_str) < dec_constraint[0] or len(oct_str) > dec_constraint[1]: raise ValueError('[PyASN1PEREncoder][ERROR]: Octet string does not fit the ' 'constraints - cannot encode ![lb < x < ub]') else: offset_bitfield_range = len(str(bin(dec_constraint[1]-dec_constraint[0])[2:])) len_det = _bit_str_pad(bin(len(oct_str)-dec_constraint[0])[2:], offset_bitfield_range, '0') return len_det + ''.join([_bit_str_pad(bin(ord(oct_str[x]))[2:], 8, '0') for x in range(len(oct_str))])
def scts_from_cert(cert_der): '''Return list of SCTs of the SCTList SAN extension of the certificate. Args: cert_der(bytes): DER encoded ASN.1 Certificate Return: [<ctutlz.rfc6962.SignedCertificateTimestamp>, ...] ''' cert, _ = der_decoder( cert_der, asn1Spec=pyasn1_modules.rfc5280.Certificate()) sctlist_oid = ObjectIdentifier(value='1.3.6.1.4.1.11129.2.4.2') exts = [] if 'extensions' in cert['tbsCertificate'].keys(): exts = [extension for extension in cert['tbsCertificate']['extensions'] if extension['extnID'] == sctlist_oid] if len(exts) != 0: extension_sctlist = exts[0] os_inner_der = extension_sctlist['extnValue'] # type: OctetString() os_inner, _ = der_decoder(os_inner_der, OctetString()) sctlist_hex = os_inner.prettyPrint().split('0x')[-1] sctlist_der = binascii.unhexlify(sctlist_hex) sctlist = SignedCertificateTimestampList(sctlist_der) return [SignedCertificateTimestamp(entry.sct_der) for entry in sctlist.sct_list] return []
def dir_sync_control(criticality, object_security, ancestors_first, public_data_only, incremental_values, max_length, cookie): control_value = DirSyncControlRequestValue() flags = 0x0 if object_security: flags |= 0x00000001 if ancestors_first: flags |= 0x00000800 if public_data_only: flags |= 0x00002000 if incremental_values: flags |= 0x80000000 # converts flags to signed 32 bit (AD expects a 4 bytes long unsigned integer, but ASN.1 Integer type is signed # so the BER encoder gives back a 5 bytes long signed integer """flags = ctypes.c_long(flags & 0xFFFFFFFF).value""" # Dominique Vocat, avoid using ctypes to not rely on compiled libraries so we flip the bits manually flags_bin = bin(flags) flags = int(flags_bin, 2) if flags_bin[ 0] == '1': #so if the first bit is a 1 we need to invert due to delivering a signed long flags ^= 0xFFFFFFFF flags += 1 flags = -flags control_value.setComponentByName('Flags', flags) control_value.setComponentByName('MaxBytes', max_length) if cookie: control_value.setComponentByName('Cookie', cookie) else: control_value.setComponentByName('Cookie', OctetString('')) return build_control('1.2.840.113556.1.4.841', criticality, control_value)
def extract_names(raw_cert): results = { 'CN': set(), 'DNS': set(), 'SRV': set(), 'URI': set(), 'XMPPAddr': set() } cert = decoder.decode(raw_cert, asn1Spec=Certificate())[0] tbs = cert.getComponentByName('tbsCertificate') subject = tbs.getComponentByName('subject') extensions = tbs.getComponentByName('extensions') or [] # Extract the CommonName(s) from the cert. for rdnss in subject: for rdns in rdnss: for name in rdns: oid = name.getComponentByName('type') value = name.getComponentByName('value') if oid != COMMON_NAME: continue value = decoder.decode(value, asn1Spec=DirectoryString())[0] value = decode_str(value.getComponent()) results['CN'].add(value) # Extract the Subject Alternate Names (DNS, SRV, URI, XMPPAddr) for extension in extensions: oid = extension.getComponentByName('extnID') if oid != SUBJECT_ALT_NAME: continue value = decoder.decode(extension.getComponentByName('extnValue'), asn1Spec=OctetString())[0] sa_names = decoder.decode(value, asn1Spec=SubjectAltName())[0] for name in sa_names: name_type = name.getName() if name_type == 'dNSName': results['DNS'].add(decode_str(name.getComponent())) if name_type == 'uniformResourceIdentifier': value = decode_str(name.getComponent()) if value.startswith('xmpp:'): results['URI'].add(value[5:]) elif name_type == 'otherName': name = name.getComponent() oid = name.getComponentByName('type-id') value = name.getComponentByName('value') if oid == XMPP_ADDR: value = decoder.decode(value, asn1Spec=UTF8String())[0] results['XMPPAddr'].add(decode_str(value)) elif oid == SRV_NAME: value = decoder.decode(value, asn1Spec=IA5String())[0] results['SRV'].add(decode_str(value)) return results
class DirSyncControlRequestValue(Sequence): # DirSyncRequestValue ::= SEQUENCE { # Flags integer # MaxBytes integer # Cookie OCTET STRING } componentType = NamedTypes(NamedType('Flags', Integer()), NamedType('MaxBytes', Integer()), NamedType('Cookie', OctetString()))
def pkcs7_enveloped_msg(self, msg, data, iv="0123456789012345"): """WIP: PKCS#7 envelop msg, data with cert""" oi_pkcs7_rsa_enc = ObjectIdentifier((1, 2, 840, 113549, 1, 1, 1)) oi_pkcs7_data = ObjectIdentifier((1, 2, 840, 113549, 1, 7, 1)) oi_seed_cbc = ObjectIdentifier(id_seed_cbc) der = Sequence().setComponentByPosition( 0, ObjectIdentifier(id_pkcs7_enveloped_data)) data_set = Sequence().setComponentByPosition(0, Integer(0)) data_set = data_set.setComponentByPosition( 1, Sequence().setComponentByPosition( 0, self.pub_cert[0][3]).setComponentByPosition( 1, self.pub_cert[0][1])) data_set = data_set.setComponentByPosition( 2, Sequence().setComponentByPosition( 0, oi_pkcs7_rsa_enc).setComponentByPosition(1, Null(''))) data_set = data_set.setComponentByPosition( 3, OctetString(hexValue=msg.encode('hex'))) data_seq = Sequence().setComponentByPosition(0, oi_pkcs7_data) data_seq = data_seq.setComponentByPosition( 1, Sequence().setComponentByPosition( 0, oi_seed_cbc).setComponentByPosition( 1, OctetString(hexValue=iv.encode('hex')))) data_seq = data_seq.setComponentByPosition( 2, OctetString( hexValue=data.encode('hex')).subtype(implicitTag=tag.Tag( tag.tagClassContext, tag.tagFormatSimple, 0))) data = Sequence().setComponentByPosition(0, Integer(0)) data = data.setComponentByPosition( 1, Set().setComponentByPosition(0, data_set)) data = data.setComponentByPosition(2, data_seq) der = der.setComponentByPosition( 1, Sequence().subtype( implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)).setComponentByPosition(0, data)) return der_encoder.encode(der)
def _decode_octet_string(self, remains=None): if remains: buff = remains else: buff = self._raw[8:] octet_string, remains = der_decode(buff, OctetString()) return octet_string, remains
def encode(eddsa_key: object, **kwargs): alg_id = SequenceOf() alg_id.setComponentByPosition(0, ObjectIdentifier(eddsa_key.curve.oid)) zero_fill = math.ceil(eddsa_key.d.int().bit_length() / 8) priv_key = OctetString( encoder.encode( OctetString(Bytes.wrap(eddsa_key.d).zfill(zero_fill)))) top_seq = Sequence() top_seq.setComponentByPosition(0, Integer(0)) top_seq.setComponentByPosition(1, alg_id) top_seq.setComponentByPosition(2, priv_key) encoded = encoder.encode(top_seq) encoded = PKCS8EdDSAPrivateKey.transport_encode(encoded, **kwargs) return encoded
class NegoToken(Sequence): componentType = NamedTypes( NamedType( 'negoToken', OctetString().subtype( explicitTag=Tag(tagClassContext, tagFormatConstructed, 0) ) ) )
class NegTokenInit2(Sequence): """ [MS-SPNG] v14.0 2017-09-15 2.2.1 NegTokenInit2 NegTokenInit2 is the message structure that extends NegTokenInit with a negotiation hints (negHints) field. On a server initiated SPNEGO process, it sends negTokenInit2 message instead of just the plain NegTokenInit. NegTokenInit2 ::= SEQUENCE { mechTypes [0] MechTypeList OPTIONAL, reqFlags [1] ContextFlags OPTIONAL, mechToken [2] OCTET STRING OPTIONAL, negHints [3] NegHints OPTIONAL, mechListMIC [4] OCTET STRING OPTIONAL, ... } """ componentType = NamedTypes( OptionalNamedType( 'mechTypes', MechTypeList().subtype( explicitTag=Tag(tagClassContext, tagFormatConstructed, 0) ) ), OptionalNamedType( 'reqFlags', ContextFlags().subtype( explicitTag=Tag(tagClassContext, tagFormatConstructed, 1) ) ), OptionalNamedType( 'mechToken', OctetString().subtype( explicitTag=Tag(tagClassContext, tagFormatSimple, 2) ) ), OptionalNamedType( 'negHints', NegHints().subtype( explicitTag=Tag(tagClassContext, tagFormatConstructed, 3) ) ), OptionalNamedType( 'mechListMIC', OctetString().subtype( explicitTag=Tag(tagClassContext, tagFormatSimple, 4) ) ), )
class DirSyncControlResponseValue(Sequence): # DirSyncResponseValue ::= SEQUENCE { # MoreResults INTEGER # unused INTEGER # CookieServer OCTET STRING # } componentType = NamedTypes(NamedType('MoreResults', Integer()), NamedType('unused', Integer()), NamedType('CookieServer', OctetString()))
def _decode_octet_string(item: univ.OctetString, data: str) -> Tuple[int, base.Asn1Item]: """ Decodes an ASN.1 PER Encoded octet-string object Args: item: The enumerated base object that defines the encoded data data: The PER unaligned encoded binary string Returns: A tuple containing the PyASN.1 object populated with the decoded data and the length of the data processed (used for error checking) """ dec_constraint = _extract_value_size_constraint(str(item.getSubtypeSpec())) if dec_constraint == -1: # No constraint length = int(data[:8], 2) decoded_str = '' for i in range(0, length): decoded_str += chr(int(data[(8+i*8):(16+i*8)], 2)) return 8*(length+1), item.clone(decoded_str) elif dec_constraint[1] == 0: return 0, item.clone() elif dec_constraint[0] == dec_constraint[1]: decoded_str = '' for i in range(0, dec_constraint[0]): decoded_str += chr(int(data[(8+i*8):(16+i*8)], 2)) return 8*dec_constraint[0], item.clone(decoded_str) else: offset_bitfield_range = len(str(bin(dec_constraint[1]-dec_constraint[0])[2:])) length = int(data[:offset_bitfield_range], 2) + dec_constraint[0] decoded_str = '' for i in range(0, length): decoded_str += chr(int(data[(offset_bitfield_range+(i*8)):( (offset_bitfield_range+8)+i*8)], 2)) return offset_bitfield_range+(8*length), item.clone(decoded_str)