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