1# This file is dual licensed under the terms of the Apache License, Version 2# 2.0, and the BSD License. See the LICENSE file in the root of this repository 3# for complete details. 4 5from __future__ import absolute_import, division, print_function 6 7import calendar 8import ipaddress 9 10import six 11 12from cryptography import utils, x509 13from cryptography.hazmat.backends.openssl.decode_asn1 import ( 14 _CRL_ENTRY_REASON_ENUM_TO_CODE, _DISTPOINT_TYPE_FULLNAME, 15 _DISTPOINT_TYPE_RELATIVENAME 16) 17from cryptography.x509.name import _ASN1Type 18from cryptography.x509.oid import ( 19 CRLEntryExtensionOID, ExtensionOID, OCSPExtensionOID, 20) 21 22 23def _encode_asn1_int(backend, x): 24 """ 25 Converts a python integer to an ASN1_INTEGER. The returned ASN1_INTEGER 26 will not be garbage collected (to support adding them to structs that take 27 ownership of the object). Be sure to register it for GC if it will be 28 discarded after use. 29 30 """ 31 # Convert Python integer to OpenSSL "bignum" in case value exceeds 32 # machine's native integer limits (note: `int_to_bn` doesn't automatically 33 # GC). 34 i = backend._int_to_bn(x) 35 i = backend._ffi.gc(i, backend._lib.BN_free) 36 37 # Wrap in an ASN.1 integer. Don't GC -- as documented. 38 i = backend._lib.BN_to_ASN1_INTEGER(i, backend._ffi.NULL) 39 backend.openssl_assert(i != backend._ffi.NULL) 40 return i 41 42 43def _encode_asn1_int_gc(backend, x): 44 i = _encode_asn1_int(backend, x) 45 i = backend._ffi.gc(i, backend._lib.ASN1_INTEGER_free) 46 return i 47 48 49def _encode_asn1_str(backend, data): 50 """ 51 Create an ASN1_OCTET_STRING from a Python byte string. 52 """ 53 s = backend._lib.ASN1_OCTET_STRING_new() 54 res = backend._lib.ASN1_OCTET_STRING_set(s, data, len(data)) 55 backend.openssl_assert(res == 1) 56 return s 57 58 59def _encode_asn1_utf8_str(backend, string): 60 """ 61 Create an ASN1_UTF8STRING from a Python unicode string. 62 This object will be an ASN1_STRING with UTF8 type in OpenSSL and 63 can be decoded with ASN1_STRING_to_UTF8. 64 """ 65 s = backend._lib.ASN1_UTF8STRING_new() 66 res = backend._lib.ASN1_STRING_set( 67 s, string.encode("utf8"), len(string.encode("utf8")) 68 ) 69 backend.openssl_assert(res == 1) 70 return s 71 72 73def _encode_asn1_str_gc(backend, data): 74 s = _encode_asn1_str(backend, data) 75 s = backend._ffi.gc(s, backend._lib.ASN1_OCTET_STRING_free) 76 return s 77 78 79def _encode_inhibit_any_policy(backend, inhibit_any_policy): 80 return _encode_asn1_int_gc(backend, inhibit_any_policy.skip_certs) 81 82 83def _encode_name(backend, name): 84 """ 85 The X509_NAME created will not be gc'd. Use _encode_name_gc if needed. 86 """ 87 subject = backend._lib.X509_NAME_new() 88 for rdn in name.rdns: 89 set_flag = 0 # indicate whether to add to last RDN or create new RDN 90 for attribute in rdn: 91 name_entry = _encode_name_entry(backend, attribute) 92 # X509_NAME_add_entry dups the object so we need to gc this copy 93 name_entry = backend._ffi.gc( 94 name_entry, backend._lib.X509_NAME_ENTRY_free 95 ) 96 res = backend._lib.X509_NAME_add_entry( 97 subject, name_entry, -1, set_flag) 98 backend.openssl_assert(res == 1) 99 set_flag = -1 100 return subject 101 102 103def _encode_name_gc(backend, attributes): 104 subject = _encode_name(backend, attributes) 105 subject = backend._ffi.gc(subject, backend._lib.X509_NAME_free) 106 return subject 107 108 109def _encode_sk_name_entry(backend, attributes): 110 """ 111 The sk_X509_NAME_ENTRY created will not be gc'd. 112 """ 113 stack = backend._lib.sk_X509_NAME_ENTRY_new_null() 114 for attribute in attributes: 115 name_entry = _encode_name_entry(backend, attribute) 116 res = backend._lib.sk_X509_NAME_ENTRY_push(stack, name_entry) 117 backend.openssl_assert(res >= 1) 118 return stack 119 120 121def _encode_name_entry(backend, attribute): 122 if attribute._type is _ASN1Type.BMPString: 123 value = attribute.value.encode('utf_16_be') 124 else: 125 value = attribute.value.encode('utf8') 126 127 obj = _txt2obj_gc(backend, attribute.oid.dotted_string) 128 129 name_entry = backend._lib.X509_NAME_ENTRY_create_by_OBJ( 130 backend._ffi.NULL, obj, attribute._type.value, value, len(value) 131 ) 132 return name_entry 133 134 135def _encode_crl_number_delta_crl_indicator(backend, ext): 136 return _encode_asn1_int_gc(backend, ext.crl_number) 137 138 139def _encode_issuing_dist_point(backend, ext): 140 idp = backend._lib.ISSUING_DIST_POINT_new() 141 backend.openssl_assert(idp != backend._ffi.NULL) 142 idp = backend._ffi.gc(idp, backend._lib.ISSUING_DIST_POINT_free) 143 idp.onlyuser = 255 if ext.only_contains_user_certs else 0 144 idp.onlyCA = 255 if ext.only_contains_ca_certs else 0 145 idp.indirectCRL = 255 if ext.indirect_crl else 0 146 idp.onlyattr = 255 if ext.only_contains_attribute_certs else 0 147 if ext.only_some_reasons: 148 idp.onlysomereasons = _encode_reasonflags( 149 backend, ext.only_some_reasons 150 ) 151 152 if ext.full_name: 153 idp.distpoint = _encode_full_name(backend, ext.full_name) 154 155 if ext.relative_name: 156 idp.distpoint = _encode_relative_name(backend, ext.relative_name) 157 158 return idp 159 160 161def _encode_crl_reason(backend, crl_reason): 162 asn1enum = backend._lib.ASN1_ENUMERATED_new() 163 backend.openssl_assert(asn1enum != backend._ffi.NULL) 164 asn1enum = backend._ffi.gc(asn1enum, backend._lib.ASN1_ENUMERATED_free) 165 res = backend._lib.ASN1_ENUMERATED_set( 166 asn1enum, _CRL_ENTRY_REASON_ENUM_TO_CODE[crl_reason.reason] 167 ) 168 backend.openssl_assert(res == 1) 169 170 return asn1enum 171 172 173def _encode_invalidity_date(backend, invalidity_date): 174 time = backend._lib.ASN1_GENERALIZEDTIME_set( 175 backend._ffi.NULL, calendar.timegm( 176 invalidity_date.invalidity_date.timetuple() 177 ) 178 ) 179 backend.openssl_assert(time != backend._ffi.NULL) 180 time = backend._ffi.gc(time, backend._lib.ASN1_GENERALIZEDTIME_free) 181 182 return time 183 184 185def _encode_certificate_policies(backend, certificate_policies): 186 cp = backend._lib.sk_POLICYINFO_new_null() 187 backend.openssl_assert(cp != backend._ffi.NULL) 188 cp = backend._ffi.gc(cp, backend._lib.sk_POLICYINFO_free) 189 for policy_info in certificate_policies: 190 pi = backend._lib.POLICYINFO_new() 191 backend.openssl_assert(pi != backend._ffi.NULL) 192 res = backend._lib.sk_POLICYINFO_push(cp, pi) 193 backend.openssl_assert(res >= 1) 194 oid = _txt2obj(backend, policy_info.policy_identifier.dotted_string) 195 pi.policyid = oid 196 if policy_info.policy_qualifiers: 197 pqis = backend._lib.sk_POLICYQUALINFO_new_null() 198 backend.openssl_assert(pqis != backend._ffi.NULL) 199 for qualifier in policy_info.policy_qualifiers: 200 pqi = backend._lib.POLICYQUALINFO_new() 201 backend.openssl_assert(pqi != backend._ffi.NULL) 202 res = backend._lib.sk_POLICYQUALINFO_push(pqis, pqi) 203 backend.openssl_assert(res >= 1) 204 if isinstance(qualifier, six.text_type): 205 pqi.pqualid = _txt2obj( 206 backend, x509.OID_CPS_QUALIFIER.dotted_string 207 ) 208 pqi.d.cpsuri = _encode_asn1_str( 209 backend, 210 qualifier.encode("ascii"), 211 ) 212 else: 213 assert isinstance(qualifier, x509.UserNotice) 214 pqi.pqualid = _txt2obj( 215 backend, x509.OID_CPS_USER_NOTICE.dotted_string 216 ) 217 un = backend._lib.USERNOTICE_new() 218 backend.openssl_assert(un != backend._ffi.NULL) 219 pqi.d.usernotice = un 220 if qualifier.explicit_text: 221 un.exptext = _encode_asn1_utf8_str( 222 backend, qualifier.explicit_text 223 ) 224 225 un.noticeref = _encode_notice_reference( 226 backend, qualifier.notice_reference 227 ) 228 229 pi.qualifiers = pqis 230 231 return cp 232 233 234def _encode_notice_reference(backend, notice): 235 if notice is None: 236 return backend._ffi.NULL 237 else: 238 nr = backend._lib.NOTICEREF_new() 239 backend.openssl_assert(nr != backend._ffi.NULL) 240 # organization is a required field 241 nr.organization = _encode_asn1_utf8_str(backend, notice.organization) 242 243 notice_stack = backend._lib.sk_ASN1_INTEGER_new_null() 244 nr.noticenos = notice_stack 245 for number in notice.notice_numbers: 246 num = _encode_asn1_int(backend, number) 247 res = backend._lib.sk_ASN1_INTEGER_push(notice_stack, num) 248 backend.openssl_assert(res >= 1) 249 250 return nr 251 252 253def _txt2obj(backend, name): 254 """ 255 Converts a Python string with an ASN.1 object ID in dotted form to a 256 ASN1_OBJECT. 257 """ 258 name = name.encode('ascii') 259 obj = backend._lib.OBJ_txt2obj(name, 1) 260 backend.openssl_assert(obj != backend._ffi.NULL) 261 return obj 262 263 264def _txt2obj_gc(backend, name): 265 obj = _txt2obj(backend, name) 266 obj = backend._ffi.gc(obj, backend._lib.ASN1_OBJECT_free) 267 return obj 268 269 270def _encode_ocsp_nocheck(backend, ext): 271 # Doesn't need to be GC'd 272 return backend._lib.ASN1_NULL_new() 273 274 275def _encode_key_usage(backend, key_usage): 276 set_bit = backend._lib.ASN1_BIT_STRING_set_bit 277 ku = backend._lib.ASN1_BIT_STRING_new() 278 ku = backend._ffi.gc(ku, backend._lib.ASN1_BIT_STRING_free) 279 res = set_bit(ku, 0, key_usage.digital_signature) 280 backend.openssl_assert(res == 1) 281 res = set_bit(ku, 1, key_usage.content_commitment) 282 backend.openssl_assert(res == 1) 283 res = set_bit(ku, 2, key_usage.key_encipherment) 284 backend.openssl_assert(res == 1) 285 res = set_bit(ku, 3, key_usage.data_encipherment) 286 backend.openssl_assert(res == 1) 287 res = set_bit(ku, 4, key_usage.key_agreement) 288 backend.openssl_assert(res == 1) 289 res = set_bit(ku, 5, key_usage.key_cert_sign) 290 backend.openssl_assert(res == 1) 291 res = set_bit(ku, 6, key_usage.crl_sign) 292 backend.openssl_assert(res == 1) 293 if key_usage.key_agreement: 294 res = set_bit(ku, 7, key_usage.encipher_only) 295 backend.openssl_assert(res == 1) 296 res = set_bit(ku, 8, key_usage.decipher_only) 297 backend.openssl_assert(res == 1) 298 else: 299 res = set_bit(ku, 7, 0) 300 backend.openssl_assert(res == 1) 301 res = set_bit(ku, 8, 0) 302 backend.openssl_assert(res == 1) 303 304 return ku 305 306 307def _encode_authority_key_identifier(backend, authority_keyid): 308 akid = backend._lib.AUTHORITY_KEYID_new() 309 backend.openssl_assert(akid != backend._ffi.NULL) 310 akid = backend._ffi.gc(akid, backend._lib.AUTHORITY_KEYID_free) 311 if authority_keyid.key_identifier is not None: 312 akid.keyid = _encode_asn1_str( 313 backend, 314 authority_keyid.key_identifier, 315 ) 316 317 if authority_keyid.authority_cert_issuer is not None: 318 akid.issuer = _encode_general_names( 319 backend, authority_keyid.authority_cert_issuer 320 ) 321 322 if authority_keyid.authority_cert_serial_number is not None: 323 akid.serial = _encode_asn1_int( 324 backend, authority_keyid.authority_cert_serial_number 325 ) 326 327 return akid 328 329 330def _encode_basic_constraints(backend, basic_constraints): 331 constraints = backend._lib.BASIC_CONSTRAINTS_new() 332 constraints = backend._ffi.gc( 333 constraints, backend._lib.BASIC_CONSTRAINTS_free 334 ) 335 constraints.ca = 255 if basic_constraints.ca else 0 336 if basic_constraints.ca and basic_constraints.path_length is not None: 337 constraints.pathlen = _encode_asn1_int( 338 backend, basic_constraints.path_length 339 ) 340 341 return constraints 342 343 344def _encode_authority_information_access(backend, authority_info_access): 345 aia = backend._lib.sk_ACCESS_DESCRIPTION_new_null() 346 backend.openssl_assert(aia != backend._ffi.NULL) 347 aia = backend._ffi.gc( 348 aia, backend._lib.sk_ACCESS_DESCRIPTION_free 349 ) 350 for access_description in authority_info_access: 351 ad = backend._lib.ACCESS_DESCRIPTION_new() 352 method = _txt2obj( 353 backend, access_description.access_method.dotted_string 354 ) 355 gn = _encode_general_name(backend, access_description.access_location) 356 ad.method = method 357 ad.location = gn 358 res = backend._lib.sk_ACCESS_DESCRIPTION_push(aia, ad) 359 backend.openssl_assert(res >= 1) 360 361 return aia 362 363 364def _encode_general_names(backend, names): 365 general_names = backend._lib.GENERAL_NAMES_new() 366 backend.openssl_assert(general_names != backend._ffi.NULL) 367 for name in names: 368 gn = _encode_general_name(backend, name) 369 res = backend._lib.sk_GENERAL_NAME_push(general_names, gn) 370 backend.openssl_assert(res != 0) 371 372 return general_names 373 374 375def _encode_alt_name(backend, san): 376 general_names = _encode_general_names(backend, san) 377 general_names = backend._ffi.gc( 378 general_names, backend._lib.GENERAL_NAMES_free 379 ) 380 return general_names 381 382 383def _encode_subject_key_identifier(backend, ski): 384 return _encode_asn1_str_gc(backend, ski.digest) 385 386 387def _encode_general_name(backend, name): 388 if isinstance(name, x509.DNSName): 389 gn = backend._lib.GENERAL_NAME_new() 390 backend.openssl_assert(gn != backend._ffi.NULL) 391 gn.type = backend._lib.GEN_DNS 392 393 ia5 = backend._lib.ASN1_IA5STRING_new() 394 backend.openssl_assert(ia5 != backend._ffi.NULL) 395 # ia5strings are supposed to be ITU T.50 but to allow round-tripping 396 # of broken certs that encode utf8 we'll encode utf8 here too. 397 value = name.value.encode("utf8") 398 399 res = backend._lib.ASN1_STRING_set(ia5, value, len(value)) 400 backend.openssl_assert(res == 1) 401 gn.d.dNSName = ia5 402 elif isinstance(name, x509.RegisteredID): 403 gn = backend._lib.GENERAL_NAME_new() 404 backend.openssl_assert(gn != backend._ffi.NULL) 405 gn.type = backend._lib.GEN_RID 406 obj = backend._lib.OBJ_txt2obj( 407 name.value.dotted_string.encode('ascii'), 1 408 ) 409 backend.openssl_assert(obj != backend._ffi.NULL) 410 gn.d.registeredID = obj 411 elif isinstance(name, x509.DirectoryName): 412 gn = backend._lib.GENERAL_NAME_new() 413 backend.openssl_assert(gn != backend._ffi.NULL) 414 dir_name = _encode_name(backend, name.value) 415 gn.type = backend._lib.GEN_DIRNAME 416 gn.d.directoryName = dir_name 417 elif isinstance(name, x509.IPAddress): 418 gn = backend._lib.GENERAL_NAME_new() 419 backend.openssl_assert(gn != backend._ffi.NULL) 420 if isinstance(name.value, ipaddress.IPv4Network): 421 packed = ( 422 name.value.network_address.packed + 423 utils.int_to_bytes(((1 << 32) - name.value.num_addresses), 4) 424 ) 425 elif isinstance(name.value, ipaddress.IPv6Network): 426 packed = ( 427 name.value.network_address.packed + 428 utils.int_to_bytes((1 << 128) - name.value.num_addresses, 16) 429 ) 430 else: 431 packed = name.value.packed 432 ipaddr = _encode_asn1_str(backend, packed) 433 gn.type = backend._lib.GEN_IPADD 434 gn.d.iPAddress = ipaddr 435 elif isinstance(name, x509.OtherName): 436 gn = backend._lib.GENERAL_NAME_new() 437 backend.openssl_assert(gn != backend._ffi.NULL) 438 other_name = backend._lib.OTHERNAME_new() 439 backend.openssl_assert(other_name != backend._ffi.NULL) 440 441 type_id = backend._lib.OBJ_txt2obj( 442 name.type_id.dotted_string.encode('ascii'), 1 443 ) 444 backend.openssl_assert(type_id != backend._ffi.NULL) 445 data = backend._ffi.new("unsigned char[]", name.value) 446 data_ptr_ptr = backend._ffi.new("unsigned char **") 447 data_ptr_ptr[0] = data 448 value = backend._lib.d2i_ASN1_TYPE( 449 backend._ffi.NULL, data_ptr_ptr, len(name.value) 450 ) 451 if value == backend._ffi.NULL: 452 backend._consume_errors() 453 raise ValueError("Invalid ASN.1 data") 454 other_name.type_id = type_id 455 other_name.value = value 456 gn.type = backend._lib.GEN_OTHERNAME 457 gn.d.otherName = other_name 458 elif isinstance(name, x509.RFC822Name): 459 gn = backend._lib.GENERAL_NAME_new() 460 backend.openssl_assert(gn != backend._ffi.NULL) 461 # ia5strings are supposed to be ITU T.50 but to allow round-tripping 462 # of broken certs that encode utf8 we'll encode utf8 here too. 463 data = name.value.encode("utf8") 464 asn1_str = _encode_asn1_str(backend, data) 465 gn.type = backend._lib.GEN_EMAIL 466 gn.d.rfc822Name = asn1_str 467 elif isinstance(name, x509.UniformResourceIdentifier): 468 gn = backend._lib.GENERAL_NAME_new() 469 backend.openssl_assert(gn != backend._ffi.NULL) 470 # ia5strings are supposed to be ITU T.50 but to allow round-tripping 471 # of broken certs that encode utf8 we'll encode utf8 here too. 472 data = name.value.encode("utf8") 473 asn1_str = _encode_asn1_str(backend, data) 474 gn.type = backend._lib.GEN_URI 475 gn.d.uniformResourceIdentifier = asn1_str 476 else: 477 raise ValueError( 478 "{0} is an unknown GeneralName type".format(name) 479 ) 480 481 return gn 482 483 484def _encode_extended_key_usage(backend, extended_key_usage): 485 eku = backend._lib.sk_ASN1_OBJECT_new_null() 486 eku = backend._ffi.gc(eku, backend._lib.sk_ASN1_OBJECT_free) 487 for oid in extended_key_usage: 488 obj = _txt2obj(backend, oid.dotted_string) 489 res = backend._lib.sk_ASN1_OBJECT_push(eku, obj) 490 backend.openssl_assert(res >= 1) 491 492 return eku 493 494 495_CRLREASONFLAGS = { 496 x509.ReasonFlags.key_compromise: 1, 497 x509.ReasonFlags.ca_compromise: 2, 498 x509.ReasonFlags.affiliation_changed: 3, 499 x509.ReasonFlags.superseded: 4, 500 x509.ReasonFlags.cessation_of_operation: 5, 501 x509.ReasonFlags.certificate_hold: 6, 502 x509.ReasonFlags.privilege_withdrawn: 7, 503 x509.ReasonFlags.aa_compromise: 8, 504} 505 506 507def _encode_reasonflags(backend, reasons): 508 bitmask = backend._lib.ASN1_BIT_STRING_new() 509 backend.openssl_assert(bitmask != backend._ffi.NULL) 510 for reason in reasons: 511 res = backend._lib.ASN1_BIT_STRING_set_bit( 512 bitmask, _CRLREASONFLAGS[reason], 1 513 ) 514 backend.openssl_assert(res == 1) 515 516 return bitmask 517 518 519def _encode_full_name(backend, full_name): 520 dpn = backend._lib.DIST_POINT_NAME_new() 521 backend.openssl_assert(dpn != backend._ffi.NULL) 522 dpn.type = _DISTPOINT_TYPE_FULLNAME 523 dpn.name.fullname = _encode_general_names(backend, full_name) 524 return dpn 525 526 527def _encode_relative_name(backend, relative_name): 528 dpn = backend._lib.DIST_POINT_NAME_new() 529 backend.openssl_assert(dpn != backend._ffi.NULL) 530 dpn.type = _DISTPOINT_TYPE_RELATIVENAME 531 dpn.name.relativename = _encode_sk_name_entry(backend, relative_name) 532 return dpn 533 534 535def _encode_cdps_freshest_crl(backend, cdps): 536 cdp = backend._lib.sk_DIST_POINT_new_null() 537 cdp = backend._ffi.gc(cdp, backend._lib.sk_DIST_POINT_free) 538 for point in cdps: 539 dp = backend._lib.DIST_POINT_new() 540 backend.openssl_assert(dp != backend._ffi.NULL) 541 542 if point.reasons: 543 dp.reasons = _encode_reasonflags(backend, point.reasons) 544 545 if point.full_name: 546 dp.distpoint = _encode_full_name(backend, point.full_name) 547 548 if point.relative_name: 549 dp.distpoint = _encode_relative_name(backend, point.relative_name) 550 551 if point.crl_issuer: 552 dp.CRLissuer = _encode_general_names(backend, point.crl_issuer) 553 554 res = backend._lib.sk_DIST_POINT_push(cdp, dp) 555 backend.openssl_assert(res >= 1) 556 557 return cdp 558 559 560def _encode_name_constraints(backend, name_constraints): 561 nc = backend._lib.NAME_CONSTRAINTS_new() 562 backend.openssl_assert(nc != backend._ffi.NULL) 563 nc = backend._ffi.gc(nc, backend._lib.NAME_CONSTRAINTS_free) 564 permitted = _encode_general_subtree( 565 backend, name_constraints.permitted_subtrees 566 ) 567 nc.permittedSubtrees = permitted 568 excluded = _encode_general_subtree( 569 backend, name_constraints.excluded_subtrees 570 ) 571 nc.excludedSubtrees = excluded 572 573 return nc 574 575 576def _encode_policy_constraints(backend, policy_constraints): 577 pc = backend._lib.POLICY_CONSTRAINTS_new() 578 backend.openssl_assert(pc != backend._ffi.NULL) 579 pc = backend._ffi.gc(pc, backend._lib.POLICY_CONSTRAINTS_free) 580 if policy_constraints.require_explicit_policy is not None: 581 pc.requireExplicitPolicy = _encode_asn1_int( 582 backend, policy_constraints.require_explicit_policy 583 ) 584 585 if policy_constraints.inhibit_policy_mapping is not None: 586 pc.inhibitPolicyMapping = _encode_asn1_int( 587 backend, policy_constraints.inhibit_policy_mapping 588 ) 589 590 return pc 591 592 593def _encode_general_subtree(backend, subtrees): 594 if subtrees is None: 595 return backend._ffi.NULL 596 else: 597 general_subtrees = backend._lib.sk_GENERAL_SUBTREE_new_null() 598 for name in subtrees: 599 gs = backend._lib.GENERAL_SUBTREE_new() 600 gs.base = _encode_general_name(backend, name) 601 res = backend._lib.sk_GENERAL_SUBTREE_push(general_subtrees, gs) 602 assert res >= 1 603 604 return general_subtrees 605 606 607def _encode_nonce(backend, nonce): 608 return _encode_asn1_str_gc(backend, nonce.nonce) 609 610 611_EXTENSION_ENCODE_HANDLERS = { 612 ExtensionOID.BASIC_CONSTRAINTS: _encode_basic_constraints, 613 ExtensionOID.SUBJECT_KEY_IDENTIFIER: _encode_subject_key_identifier, 614 ExtensionOID.KEY_USAGE: _encode_key_usage, 615 ExtensionOID.SUBJECT_ALTERNATIVE_NAME: _encode_alt_name, 616 ExtensionOID.ISSUER_ALTERNATIVE_NAME: _encode_alt_name, 617 ExtensionOID.EXTENDED_KEY_USAGE: _encode_extended_key_usage, 618 ExtensionOID.AUTHORITY_KEY_IDENTIFIER: _encode_authority_key_identifier, 619 ExtensionOID.CERTIFICATE_POLICIES: _encode_certificate_policies, 620 ExtensionOID.AUTHORITY_INFORMATION_ACCESS: ( 621 _encode_authority_information_access 622 ), 623 ExtensionOID.CRL_DISTRIBUTION_POINTS: _encode_cdps_freshest_crl, 624 ExtensionOID.FRESHEST_CRL: _encode_cdps_freshest_crl, 625 ExtensionOID.INHIBIT_ANY_POLICY: _encode_inhibit_any_policy, 626 ExtensionOID.OCSP_NO_CHECK: _encode_ocsp_nocheck, 627 ExtensionOID.NAME_CONSTRAINTS: _encode_name_constraints, 628 ExtensionOID.POLICY_CONSTRAINTS: _encode_policy_constraints, 629} 630 631_CRL_EXTENSION_ENCODE_HANDLERS = { 632 ExtensionOID.ISSUER_ALTERNATIVE_NAME: _encode_alt_name, 633 ExtensionOID.AUTHORITY_KEY_IDENTIFIER: _encode_authority_key_identifier, 634 ExtensionOID.AUTHORITY_INFORMATION_ACCESS: ( 635 _encode_authority_information_access 636 ), 637 ExtensionOID.CRL_NUMBER: _encode_crl_number_delta_crl_indicator, 638 ExtensionOID.DELTA_CRL_INDICATOR: _encode_crl_number_delta_crl_indicator, 639 ExtensionOID.ISSUING_DISTRIBUTION_POINT: _encode_issuing_dist_point, 640} 641 642_CRL_ENTRY_EXTENSION_ENCODE_HANDLERS = { 643 CRLEntryExtensionOID.CERTIFICATE_ISSUER: _encode_alt_name, 644 CRLEntryExtensionOID.CRL_REASON: _encode_crl_reason, 645 CRLEntryExtensionOID.INVALIDITY_DATE: _encode_invalidity_date, 646} 647 648_OCSP_REQUEST_EXTENSION_ENCODE_HANDLERS = { 649 OCSPExtensionOID.NONCE: _encode_nonce, 650} 651 652_OCSP_BASICRESP_EXTENSION_ENCODE_HANDLERS = { 653 OCSPExtensionOID.NONCE: _encode_nonce, 654} 655