6 #include <Security/SecProtocolOptions.h> 
   7 #include <Security/SecProtocolMetadata.h> 
   8 #include <Security/SecProtocolPriv.h> 
   9 #include <Security/SecProtocolTypesPriv.h> 
  10 #include "SecProtocolInternal.h" 
  12 #include <Security/SecureTransportPriv.h> 
  14 #include <Security/SecFramework.h> 
  19 #include <sys/param.h> 
  21 #define MAX_SEC_PROTOCOL_OPTIONS_KEY_LEN 128 
  24 #define SEC_PROTOCOL_OPTIONS_KEY_min_version "min_version" 
  25 #define SEC_PROTOCOL_OPTIONS_KEY_max_version "max_version" 
  26 #define SEC_PROTOCOL_OPTIONS_KEY_minimum_rsa_key_size "minimum_rsa_key_size" 
  27 #define SEC_PROTOCOL_OPTIONS_KEY_minimum_ecdsa_key_size "minimum_ecdsa_key_size" 
  28 #define SEC_PROTOCOL_OPTIONS_KEY_minimum_signature_algorithm "minimum_signature_algorithm" 
  29 #define SEC_PROTOCOL_OPTIONS_KEY_ats_required "ats_required" 
  30 #define SEC_PROTOCOL_OPTIONS_KEY_ats_minimum_tls_version_allowed "ats_minimum_tls_version_allowed" 
  31 #define SEC_PROTOCOL_OPTIONS_KEY_ats_non_pfs_ciphersuite_allowed "ats_non_pfs_ciphersuite_allowed" 
  32 #define SEC_PROTOCOL_OPTIONS_KEY_trusted_peer_certificate "trusted_peer_certificate" 
  33 #define SEC_PROTOCOL_OPTIONS_KEY_disable_sni "disable_sni" 
  34 #define SEC_PROTOCOL_OPTIONS_KEY_enable_fallback_attempt "enable_fallback_attempt" 
  35 #define SEC_PROTOCOL_OPTIONS_KEY_enable_false_start "enable_false_start" 
  36 #define SEC_PROTOCOL_OPTIONS_KEY_enable_tickets "enable_tickets" 
  37 #define SEC_PROTOCOL_OPTIONS_KEY_enable_sct "enable_sct" 
  38 #define SEC_PROTOCOL_OPTIONS_KEY_enable_ocsp "enable_ocsp" 
  39 #define SEC_PROTOCOL_OPTIONS_KEY_enforce_ev "enforce_ev" 
  40 #define SEC_PROTOCOL_OPTIONS_KEY_enable_resumption "enable_resumption" 
  41 #define SEC_PROTOCOL_OPTIONS_KEY_enable_renegotiation "enable_renegotiation" 
  42 #define SEC_PROTOCOL_OPTIONS_KEY_enable_early_data "enable_early_data" 
  43 #define SEC_PROTOCOL_OPTIONS_KEY_peer_authentication_required "peer_authentication_required" 
  44 #define SEC_PROTOCOL_OPTIONS_KEY_certificate_compression_enabled "certificate_compression_enabled" 
  45 #define SEC_PROTOCOL_OPTIONS_KEY_tls_SIKE503_exchange_enabled "tls_SIKE503_exchange_enabled" 
  46 #define SEC_PROTOCOL_OPTIONS_KEY_tls_HRSS_exchange_enabled "tls_HRSS_exchange_enabled" 
  47 #define SEC_PROTOCOL_OPTIONS_KEY_eddsa_enabled "eddsa_enabled" 
  48 #define SEC_PROTOCOL_OPTIONS_KEY_tls_delegated_credentials_enabled "tls_delegated_credentials_enabled" 
  49 #define SEC_PROTOCOL_OPTIONS_KEY_tls_grease_enabled "tls_grease_enabled" 
  50 #define SEC_PROTOCOL_OPTIONS_KEY_tls_ticket_request_count "tls_ticket_request_count" 
  51 #define SEC_PROTOCOL_OPTIONS_KEY_ciphersuites "ciphersuites" 
  54 #define SEC_PROTOCOL_METADATA_KEY_PROCESS_IDENTIFIER "process" 
  55 #define SEC_PROTOCOL_METADATA_KEY_CIPHERSUITE "cipher_name" 
  56 #define SEC_PROTOCOL_METADATA_KEY_FALLBACK_ENABLED "fallback" 
  57 #define SEC_PROTOCOL_METADATA_KEY_DH_GROUP_SIZE "dhe_size" 
  58 #define SEC_PROTOCOL_METADATA_KEY_NEGOTIATED_CURVE "neg_curve" 
  59 #define SEC_PROTOCOL_METADATA_KEY_PEER_CERTIFICATE_REQUEST_TYPE "cert_request_type" 
  60 #define SEC_PROTOCOL_METADATA_KEY_LOCAL_PRIVATE_KEY_TYPE "private_key_type" 
  61 #define SEC_PROTOCOL_METADATA_KEY_PEER_PUBLIC_KEY_TYPE "peer_public_key_type" 
  62 #define SEC_PROTOCOL_METADATA_KEY_NEGOTIATED_PROTOCOL "negotiated_protocol" 
  63 #define SEC_PROTOCOL_METADATA_KEY_ALPN_USED "alpn_used" 
  64 #define SEC_PROTOCOL_METADATA_KEY_NPN_USED "npn_used" 
  65 #define SEC_PROTOCOL_METADATA_KEY_PROTOCOL_VERSION "version" 
  66 #define SEC_PROTOCOL_METADATA_KEY_FALSE_START_ENABLED "false_start_enabled" 
  67 #define SEC_PROTOCOL_METADATA_KEY_FALSE_START_USED "false_start_used" 
  68 #define SEC_PROTOCOL_METADATA_KEY_TICKET_OFFERED "ticket_offered" 
  69 #define SEC_PROTOCOL_METADATA_KEY_TICKET_RECEIVED "ticket_received" 
  70 #define SEC_PROTOCOL_METADATA_KEY_SESSION_RESUMED "session_resumed" 
  71 #define SEC_PROTOCOL_METADATA_KEY_SESSION_RENEWED "session_renewed" 
  72 #define SEC_PROTOCOL_METADATA_KEY_RESUMPTION_ATTEMPTED "resumption_attempted" 
  73 #define SEC_PROTOCOL_METADATA_KEY_TICKET_LIFETIME "ticket_lifetime" 
  74 #define SEC_PROTOCOL_METADATA_KEY_MAX_EARLY_DATA_SUPPORTED "max_early_data_supported" 
  75 #define SEC_PROTOCOL_METADATA_KEY_OCSP_ENABLED "ocsp_enabled" 
  76 #define SEC_PROTOCOL_METADATA_KEY_OCSP_RECEIVED "ocsp_received" 
  77 #define SEC_PROTOCOL_METADATA_KEY_SCT_ENABLED "sct_enabled" 
  78 #define SEC_PROTOCOL_METADATA_KEY_SCT_RECEIVED "sct_received" 
  79 #define SEC_PROTOCOL_METADATA_KEY_RSA_SIGNATURE_REQUESTED "client_rsa_requested" 
  80 #define SEC_PROTOCOL_METADATA_KEY_ECDSA_SIGNATURE_REQUESTED "client_ecdsa_requested" 
  81 #define SEC_PROTOCOL_METADATA_KEY_FAILURE_ALERT_TYPE "alert_type" 
  82 #define SEC_PROTOCOL_METADATA_KEY_FAILURE_ALERT_CODE "alert_code" 
  83 #define SEC_PROTOCOL_METADATA_KEY_FAILURE_HANDSHAKE_STATE "handshake_state" 
  84 #define SEC_PROTOCOL_METADATA_KEY_FAILURE_STACK_ERROR "stack_error" 
  85 #define SEC_PROTOCOL_METADATA_KEY_DEFAULT_EMPTY_STRING "none" 
  87 #define CFReleaseSafe(value) \ 
  88     if (value != NULL) { \ 
  93 sec_protocol_options_access_handle(sec_protocol_options_t options
, 
  94                                    sec_access_block_t access_block
) 
  96     static void *libnetworkImage 
= NULL
; 
  97     static dispatch_once_t onceToken
; 
  98     static bool (*_nw_protocol_options_access_handle
)(void *, sec_access_block_t
) = NULL
; 
 100     dispatch_once(&onceToken
, ^{ 
 101         libnetworkImage 
= dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY 
| RTLD_LOCAL
); 
 102         if (NULL 
!= libnetworkImage
) { 
 103             _nw_protocol_options_access_handle 
= (__typeof(_nw_protocol_options_access_handle
))dlsym(libnetworkImage
, 
 104                                                                                                      "nw_protocol_options_access_handle"); 
 105             if (NULL 
== _nw_protocol_options_access_handle
) { 
 106                 os_log_error(OS_LOG_DEFAULT
, "dlsym libnetwork nw_protocol_options_access_handle"); 
 109             os_log_error(OS_LOG_DEFAULT
, "dlopen libnetwork"); 
 113     if (_nw_protocol_options_access_handle 
== NULL
) { 
 117     return _nw_protocol_options_access_handle(options
, access_block
); 
 121 sec_protocol_metadata_access_handle(sec_protocol_metadata_t options
, 
 122                                     sec_access_block_t access_block
) 
 124     static void *libnetworkImage 
= NULL
; 
 125     static dispatch_once_t onceToken
; 
 126     static bool (*_nw_protocol_metadata_access_handle
)(void *, sec_access_block_t
) = NULL
; 
 128     dispatch_once(&onceToken
, ^{ 
 129         libnetworkImage 
= dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY 
| RTLD_LOCAL
); 
 130         if (NULL 
!= libnetworkImage
) { 
 131             _nw_protocol_metadata_access_handle 
= (__typeof(_nw_protocol_metadata_access_handle
))dlsym(libnetworkImage
, 
 132                                                                                                        "nw_protocol_metadata_access_handle"); 
 133             if (NULL 
== _nw_protocol_metadata_access_handle
) { 
 134                 os_log_error(OS_LOG_DEFAULT
, "dlsym libnetwork _nw_protocol_metadata_access_handle"); 
 137             os_log_error(OS_LOG_DEFAULT
, "dlopen libnetwork"); 
 141     if (_nw_protocol_metadata_access_handle 
== NULL
) { 
 145     return _nw_protocol_metadata_access_handle(options
, access_block
); 
 148 #define SEC_PROTOCOL_OPTIONS_VALIDATE(o,r)                                   \ 
 153 #define SEC_PROTOCOL_METADATA_VALIDATE(m,r)                                  \ 
 154     if (((void *)m == NULL) || ((size_t)m == 0)) {                           \ 
 159 sec_protocol_options_contents_are_equal(sec_protocol_options_content_t contentA
, sec_protocol_options_content_t contentB
) 
 161     if (contentA 
== contentB
) { 
 164     if (contentA 
== NULL 
|| contentB 
== NULL
) { 
 168     sec_protocol_options_content_t optionsA 
= (sec_protocol_options_content_t
)contentA
; 
 169     sec_protocol_options_content_t optionsB 
= (sec_protocol_options_content_t
)contentB
; 
 171     // Check boolean and primitive field types first 
 172 #define CHECK_FIELD(field) \ 
 173     if (optionsA->field != optionsB->field) { \ 
 177     CHECK_FIELD(min_version
); 
 178     CHECK_FIELD(max_version
); 
 179     CHECK_FIELD(minimum_rsa_key_size
); 
 180     CHECK_FIELD(minimum_ecdsa_key_size
); 
 181     CHECK_FIELD(minimum_signature_algorithm
); 
 182     CHECK_FIELD(tls_ticket_request_count
); 
 183     CHECK_FIELD(ats_required
); 
 184     CHECK_FIELD(ats_minimum_tls_version_allowed
); 
 185     CHECK_FIELD(ats_non_pfs_ciphersuite_allowed
); 
 186     CHECK_FIELD(trusted_peer_certificate
); 
 187     CHECK_FIELD(disable_sni
); 
 188     CHECK_FIELD(enable_fallback_attempt
); 
 189     CHECK_FIELD(enable_false_start
); 
 190     CHECK_FIELD(enable_tickets
); 
 191     CHECK_FIELD(enable_sct
); 
 192     CHECK_FIELD(enable_ocsp
); 
 193     CHECK_FIELD(enforce_ev
); 
 194     CHECK_FIELD(enable_resumption
); 
 195     CHECK_FIELD(enable_renegotiation
); 
 196     CHECK_FIELD(enable_early_data
); 
 197     CHECK_FIELD(peer_authentication_required
); 
 198     CHECK_FIELD(certificate_compression_enabled
); 
 199     CHECK_FIELD(tls_SIKE503_exchange_enabled
); 
 200     CHECK_FIELD(tls_HRSS_exchange_enabled
); 
 201     CHECK_FIELD(eddsa_enabled
); 
 202     CHECK_FIELD(tls_delegated_credentials_enabled
); 
 203     CHECK_FIELD(tls_grease_enabled
); 
 207     // Check callback block and queue pairs next 
 208 #define CHECK_BLOCK_QUEUE(block, queue) \ 
 209     if (optionsA->block && optionsB->block) { \ 
 210         if (optionsA->block != optionsB->block) { \ 
 213         if (optionsA->queue != optionsB->queue) { \ 
 216     } else if (optionsA->block || optionsB->block) { \ 
 220     CHECK_BLOCK_QUEUE(key_update_block
, key_update_queue
); 
 221     CHECK_BLOCK_QUEUE(psk_selection_block
, psk_selection_queue
); 
 222     CHECK_BLOCK_QUEUE(challenge_block
, challenge_queue
); 
 223     CHECK_BLOCK_QUEUE(verify_block
, verify_queue
); 
 224     CHECK_BLOCK_QUEUE(tls_secret_update_block
, tls_secret_update_queue
); 
 226 #undef CHECK_BLOCK_QUEUE 
 228     // Deep compare dispatch data fields 
 229 #define CHECK_DISPATCH_DATA(data) \ 
 230     if (optionsA->data && optionsB->data) { \ 
 231         if (false == sec_protocol_helper_dispatch_data_equal(optionsA->data, optionsB->data)) { \ 
 234     } else if (optionsA->data || optionsB->data) { \ 
 238     CHECK_DISPATCH_DATA(dh_params
); 
 239     CHECK_DISPATCH_DATA(quic_transport_parameters
); 
 240     CHECK_DISPATCH_DATA(psk_identity_hint
); 
 242 #undef CHECK_DISPATCH_DATA 
 244     // Deep compare XPC objects 
 245 #define CHECK_XPC_OBJECT(xpc) \ 
 246     if (optionsA->xpc && optionsB->xpc) { \ 
 247         if (false == xpc_equal(optionsA->xpc, optionsB->xpc)) { \ 
 250     } else if (optionsA->xpc || optionsB->xpc) { \ 
 254     CHECK_XPC_OBJECT(application_protocols
); 
 255     CHECK_XPC_OBJECT(ciphersuites
); 
 256     CHECK_XPC_OBJECT(key_exchange_groups
); 
 257     CHECK_XPC_OBJECT(pre_shared_keys
); 
 259 #undef CHECK_XPC_OBJECT 
 261     // Deep compare all other fields 
 262     if (optionsA
->server_name 
&& optionsB
->server_name
) { 
 263         if (0 != strcmp(optionsA
->server_name
, optionsB
->server_name
)) { 
 266     } else if (optionsA
->server_name 
|| optionsB
->server_name
) { 
 270     if (optionsA
->identity 
&& optionsB
->identity
) { 
 271         SecIdentityRef identityA 
= sec_identity_copy_ref((sec_identity_t
)optionsA
->identity
); 
 272         SecIdentityRef identityB 
= sec_identity_copy_ref((sec_identity_t
)optionsB
->identity
); 
 274         if (false == CFEqual(identityA
, identityB
)) { 
 278         CFRelease(identityA
); 
 279         CFRelease(identityB
); 
 280     } else if (optionsA
->identity 
|| optionsB
->identity
) { 
 284     if (optionsA
->output_handler_access_block 
&& optionsB
->output_handler_access_block
) { 
 285         if (optionsA
->output_handler_access_block 
!= optionsB
->output_handler_access_block
) { 
 288     } else if (optionsA
->output_handler_access_block 
|| optionsB
->output_handler_access_block
) { 
 296 sec_protocol_options_are_equal(sec_protocol_options_t handleA
, sec_protocol_options_t handleB
) 
 298     if (handleA 
== handleB
) { 
 301     if (handleA 
== NULL 
|| handleB 
== NULL
) { 
 305     return sec_protocol_options_access_handle(handleA
, ^bool(void *innerA
) { 
 306         sec_protocol_options_content_t optionsA 
= (sec_protocol_options_content_t
)innerA
; 
 307         return sec_protocol_options_access_handle(handleB
, ^bool(void *innerB
) { 
 308             sec_protocol_options_content_t optionsB 
= (sec_protocol_options_content_t
)innerB
; 
 309             return sec_protocol_options_contents_are_equal(optionsA
, optionsB
); 
 315 sec_protocol_options_set_local_identity(sec_protocol_options_t options
, sec_identity_t identity
) 
 317     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 319     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 320         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 321         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 323         if (content
->identity 
!= NULL
) { 
 324             sec_release(content
->identity
); 
 326         content
->identity 
= sec_retain(identity
); 
 332 sec_protocol_options_append_tls_ciphersuite(sec_protocol_options_t options
, tls_ciphersuite_t ciphersuite
) 
 334     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 336     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 337         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 338         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 340         if (content
->ciphersuites 
== NULL
) { 
 341             content
->ciphersuites 
= xpc_array_create(NULL
, 0); 
 343         xpc_array_set_uint64(content
->ciphersuites
, XPC_ARRAY_APPEND
, (uint64_t)ciphersuite
); 
 349 sec_protocol_options_add_tls_ciphersuite(sec_protocol_options_t options
, SSLCipherSuite ciphersuite
) 
 351     sec_protocol_options_append_tls_ciphersuite(options
, (tls_ciphersuite_t
)ciphersuite
); 
 355 sec_protocol_options_append_tls_ciphersuite_group(sec_protocol_options_t options
, tls_ciphersuite_group_t group
) 
 357     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 359     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 360         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 361         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 363         // Fetch the list of ciphersuites associated with the ciphersuite group 
 364         size_t ciphersuite_count 
= 0; 
 365         const tls_ciphersuite_t 
*list 
= sec_protocol_helper_ciphersuite_group_to_ciphersuite_list(group
, &ciphersuite_count
); 
 367             if (content
->ciphersuites 
== NULL
) { 
 368                 content
->ciphersuites 
= xpc_array_create(NULL
, 0); 
 371             for (size_t i 
= 0; i 
< ciphersuite_count
; i
++) { 
 372                 tls_ciphersuite_t ciphersuite 
= list
[i
]; 
 373                 xpc_array_set_uint64(content
->ciphersuites
, XPC_ARRAY_APPEND
, (uint64_t)ciphersuite
); 
 382 sec_protocol_options_add_tls_ciphersuite_group(sec_protocol_options_t options
, SSLCiphersuiteGroup group
) 
 385         case kSSLCiphersuiteGroupDefault
: 
 386             return sec_protocol_options_append_tls_ciphersuite_group(options
, tls_ciphersuite_group_default
); 
 387         case kSSLCiphersuiteGroupCompatibility
: 
 388             return sec_protocol_options_append_tls_ciphersuite_group(options
, tls_ciphersuite_group_compatibility
); 
 389         case kSSLCiphersuiteGroupLegacy
: 
 390             return sec_protocol_options_append_tls_ciphersuite_group(options
, tls_ciphersuite_group_legacy
); 
 391         case kSSLCiphersuiteGroupATS
: 
 392             return sec_protocol_options_append_tls_ciphersuite_group(options
, tls_ciphersuite_group_ats
); 
 393         case kSSLCiphersuiteGroupATSCompatibility
: 
 394             return sec_protocol_options_append_tls_ciphersuite_group(options
, tls_ciphersuite_group_ats_compatibility
); 
 399 sec_protocol_options_clear_tls_ciphersuites(sec_protocol_options_t options
) 
 401     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 403     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 404         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 405         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 407         if (content
->ciphersuites 
!= NULL
) { 
 408             xpc_release(content
->ciphersuites
); 
 409             content
->ciphersuites 
= NULL
; 
 416 sec_protocol_options_set_tls_min_version(sec_protocol_options_t options
, SSLProtocol version
) 
 418     tls_protocol_version_t protocol_version 
= (tls_protocol_version_t
)SSLProtocolGetVersionCodepoint(version
); 
 419     if (protocol_version 
!= 0) { 
 420         sec_protocol_options_set_min_tls_protocol_version(options
, protocol_version
); 
 425 sec_protocol_options_set_min_tls_protocol_version(sec_protocol_options_t options
, tls_protocol_version_t version
) 
 427     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 429     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 430         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 431         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 433         SSLProtocol converted_protocol 
= SSLProtocolFromVersionCodepoint(version
); 
 434         content
->min_version 
= converted_protocol
; 
 439 tls_protocol_version_t
 
 440 sec_protocol_options_get_default_min_tls_protocol_version(void) 
 442     return tls_protocol_version_TLSv10
; 
 445 tls_protocol_version_t
 
 446 sec_protocol_options_get_default_min_dtls_protocol_version(void) 
 448     return tls_protocol_version_DTLSv10
; 
 452 sec_protocol_options_set_tls_max_version(sec_protocol_options_t options
, SSLProtocol version
) 
 454     tls_protocol_version_t protocol_version 
= (tls_protocol_version_t
)SSLProtocolGetVersionCodepoint(version
); 
 455     if (protocol_version 
!= 0) { 
 456         sec_protocol_options_set_max_tls_protocol_version(options
, protocol_version
); 
 461 sec_protocol_options_set_max_tls_protocol_version(sec_protocol_options_t options
, tls_protocol_version_t version
) 
 463     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 465     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 466         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 467         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 469         SSLProtocol converted_protocol 
= SSLProtocolFromVersionCodepoint(version
); 
 470         content
->max_version 
= converted_protocol
; 
 475 tls_protocol_version_t
 
 476 sec_protocol_options_get_default_max_tls_protocol_version(void) 
 478     return tls_protocol_version_TLSv13
; 
 481 tls_protocol_version_t
 
 482 sec_protocol_options_get_default_max_dtls_protocol_version(void) 
 484     return tls_protocol_version_DTLSv12
; 
 488 sec_protocol_options_add_tls_application_protocol(sec_protocol_options_t options
, const char *application_protocol
) 
 490     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 491     SEC_PROTOCOL_OPTIONS_VALIDATE(application_protocol
,); 
 493     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 494         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 495         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 497         if (content
->application_protocols 
== NULL
) { 
 498             content
->application_protocols 
= xpc_array_create(NULL
, 0); 
 500         xpc_array_set_string(content
->application_protocols
, XPC_ARRAY_APPEND
, application_protocol
); 
 506 sec_protocol_options_set_tls_server_name(sec_protocol_options_t options
, const char *server_name
) 
 508     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 509     SEC_PROTOCOL_OPTIONS_VALIDATE(server_name
,); 
 511     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 512         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 513         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 515         CFStringRef serverName 
= CFStringCreateWithCString(NULL
, server_name
, kCFStringEncodingUTF8
); 
 516         if (serverName 
== NULL
) { 
 519         if (!SecFrameworkIsDNSName(serverName
)) { 
 520             CFRelease(serverName
); 
 523         CFRelease(serverName
); 
 525         free(content
->server_name
); 
 526         content
->server_name 
= strdup(server_name
); 
 532 sec_protocol_options_set_tls_diffie_hellman_parameters(sec_protocol_options_t options
, dispatch_data_t params
) 
 534     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 535     SEC_PROTOCOL_OPTIONS_VALIDATE(params
,); 
 537     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 538         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 539         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 541         if (content
->dh_params
) { 
 542             dispatch_release(content
->dh_params
); 
 544         content
->dh_params 
= params
; 
 545         dispatch_retain(params
); 
 551 sec_protocol_options_add_pre_shared_key(sec_protocol_options_t options
, dispatch_data_t psk
, dispatch_data_t psk_identity
) 
 553     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 554     SEC_PROTOCOL_OPTIONS_VALIDATE(psk
,); 
 555     SEC_PROTOCOL_OPTIONS_VALIDATE(psk_identity
,); 
 557     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 558         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 559         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 561         if (content
->pre_shared_keys 
== NULL
) { 
 562             content
->pre_shared_keys 
= xpc_array_create(NULL
, 0); 
 565         xpc_object_t psk_data 
= xpc_data_create_with_dispatch_data(psk
); 
 566         xpc_object_t psk_identity_data 
= xpc_data_create_with_dispatch_data(psk_identity
); 
 568         xpc_object_t tuple 
= xpc_array_create(NULL
, 0); 
 569         xpc_array_set_value(tuple
, XPC_ARRAY_APPEND
, psk_data
); 
 570         xpc_array_set_value(tuple
, XPC_ARRAY_APPEND
, psk_identity_data
); 
 571         xpc_release(psk_data
); 
 572         xpc_release(psk_identity_data
); 
 574         xpc_array_set_value(content
->pre_shared_keys
, XPC_ARRAY_APPEND
, tuple
); 
 581 sec_protocol_options_set_tls_pre_shared_key_identity_hint(sec_protocol_options_t options
, dispatch_data_t psk_identity_hint
) 
 583     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 584     SEC_PROTOCOL_OPTIONS_VALIDATE(psk_identity_hint
,); 
 586     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 587         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 588         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 590         if (content
->psk_identity_hint 
!= NULL
) { 
 591             dispatch_release(content
->psk_identity_hint
); 
 594         content
->psk_identity_hint 
= psk_identity_hint
; 
 595         dispatch_retain(psk_identity_hint
); 
 601 sec_protocol_options_set_pre_shared_key_selection_block(sec_protocol_options_t options
, sec_protocol_pre_shared_key_selection_t psk_selection_block
, dispatch_queue_t psk_selection_queue
) 
 603     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 604     SEC_PROTOCOL_OPTIONS_VALIDATE(psk_selection_block
,); 
 605     SEC_PROTOCOL_OPTIONS_VALIDATE(psk_selection_queue
,); 
 607     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 608         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 609         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 611         if (content
->psk_selection_block 
!= NULL
) { 
 612             Block_release(content
->psk_selection_block
); 
 614         if (content
->psk_selection_queue 
!= NULL
) { 
 615             dispatch_release(content
->psk_selection_queue
); 
 618         content
->psk_selection_block 
= Block_copy(psk_selection_block
); 
 619         content
->psk_selection_queue 
= psk_selection_queue
; 
 620         dispatch_retain(content
->psk_selection_queue
); 
 626 sec_protocol_options_set_tls_is_fallback_attempt(sec_protocol_options_t options
, bool fallback_attempt
) 
 628     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 630     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 631         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 632         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 634         content
->enable_fallback_attempt 
= fallback_attempt
; 
 635         content
->enable_fallback_attempt_override 
= true; 
 641 sec_protocol_options_set_tls_tickets_enabled(sec_protocol_options_t options
, bool tickets_enabled
) 
 643     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 645     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 646         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 647         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 649         content
->enable_tickets 
= tickets_enabled
; 
 650         content
->enable_tickets_override 
= true; 
 656 sec_protocol_options_set_tls_resumption_enabled(sec_protocol_options_t options
, bool resumption_enabled
) 
 658     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 660     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 661         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 662         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 664         content
->enable_resumption 
= resumption_enabled
; 
 665         content
->enable_resumption_override 
= true; 
 671 sec_protocol_options_set_tls_false_start_enabled(sec_protocol_options_t options
, bool false_start_enabled
) 
 673     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 675     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 676         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 677         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 679         content
->enable_false_start 
= false_start_enabled
; 
 680         content
->enable_false_start_override 
= true; 
 686 sec_protocol_options_set_tls_early_data_enabled(sec_protocol_options_t options
, bool early_data_enabled
) 
 688     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 690     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 691         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 692         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 694         content
->enable_early_data 
= early_data_enabled
; 
 695         content
->enable_early_data_override 
= true; 
 701 sec_protocol_options_set_tls_sni_disabled(sec_protocol_options_t options
, bool sni_disabled
) 
 703     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 705     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 706         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 707         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 709         content
->disable_sni 
= sni_disabled
; 
 710         content
->disable_sni_override 
= true; 
 716 sec_protocol_options_set_enforce_ev(sec_protocol_options_t options
, bool enforce_ev
) 
 718     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 720     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 721         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 722         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 724         content
->enforce_ev 
= enforce_ev
; 
 725         content
->enforce_ev_override 
= true; 
 731 sec_protocol_options_set_tls_ocsp_enabled(sec_protocol_options_t options
, bool ocsp_enabled
) 
 733     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 735     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 736         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 737         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 739         content
->enable_ocsp 
= ocsp_enabled
; 
 740         content
->enable_ocsp_override 
= true; 
 746 sec_protocol_options_set_tls_sct_enabled(sec_protocol_options_t options
, bool sct_enabled
) 
 748     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 750     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 751         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 752         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 754         content
->enable_sct 
= sct_enabled
; 
 755         content
->enable_sct_override 
= true; 
 761 sec_protocol_options_set_tls_renegotiation_enabled(sec_protocol_options_t options
, bool renegotiation_enabled
) 
 763     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 765     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 766         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 767         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 769         content
->enable_renegotiation 
= renegotiation_enabled
; 
 770         content
->enable_renegotiation_override 
= true; 
 776 sec_protocol_options_set_peer_authentication_required(sec_protocol_options_t options
, bool peer_authentication_required
) 
 778     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 780     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 781         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 782         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 784         content
->peer_authentication_required 
= peer_authentication_required
; 
 785         content
->peer_authentication_override 
= true; 
 791 sec_protocol_options_set_key_update_block(sec_protocol_options_t options
, sec_protocol_key_update_t update_block
, dispatch_queue_t update_queue
) 
 793     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 794     SEC_PROTOCOL_OPTIONS_VALIDATE(update_queue
,); 
 796     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 797         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 798         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 800         if (content
->key_update_block 
!= NULL
) { 
 801             Block_release(content
->key_update_block
); 
 803         if (content
->key_update_queue 
!= NULL
) { 
 804             dispatch_release(content
->key_update_queue
); 
 807         content
->key_update_block 
= Block_copy(update_block
); 
 808         content
->key_update_queue 
= Block_copy(update_queue
); 
 809         dispatch_retain(content
->key_update_queue
); 
 815 sec_protocol_options_set_challenge_block(sec_protocol_options_t options
, sec_protocol_challenge_t challenge_block
, dispatch_queue_t challenge_queue
) 
 817     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 818     SEC_PROTOCOL_OPTIONS_VALIDATE(challenge_queue
,); 
 820     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 821         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 822         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 824         if (content
->challenge_block 
!= NULL
) { 
 825             Block_release(content
->challenge_block
); 
 827         if (content
->challenge_queue 
!= NULL
) { 
 828             dispatch_release(content
->challenge_queue
); 
 831         content
->challenge_block 
= Block_copy(challenge_block
); 
 832         content
->challenge_queue 
= challenge_queue
; 
 833         dispatch_retain(content
->challenge_queue
); 
 839 sec_protocol_options_set_verify_block(sec_protocol_options_t options
, sec_protocol_verify_t verify_block
, dispatch_queue_t verify_queue
) 
 841     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 842     SEC_PROTOCOL_OPTIONS_VALIDATE(verify_queue
,); 
 844     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 845         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 846         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 848         if (content
->verify_block 
!= NULL
) { 
 849             Block_release(content
->verify_block
); 
 851         if (content
->verify_queue 
!= NULL
) { 
 852             dispatch_release(content
->verify_queue
); 
 855         content
->verify_block 
= Block_copy(verify_block
); 
 856         content
->verify_queue 
= verify_queue
; 
 857         dispatch_retain(content
->verify_queue
); 
 863 sec_protocol_options_set_session_update_block(sec_protocol_options_t options
, sec_protocol_session_update_t update_block
, dispatch_queue_t update_queue
) 
 865     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 866     SEC_PROTOCOL_OPTIONS_VALIDATE(update_block
,); 
 867     SEC_PROTOCOL_OPTIONS_VALIDATE(update_queue
,); 
 869     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 870         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 871         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 873         if (content
->session_update_block 
!= NULL
) { 
 874             Block_release(content
->session_update_block
); 
 876         if (content
->session_update_queue 
!= NULL
) { 
 877             dispatch_release(content
->session_update_queue
); 
 880         content
->session_update_block 
= Block_copy(update_block
); 
 881         content
->session_update_queue 
= update_queue
; 
 882         dispatch_retain(content
->session_update_queue
); 
 888 sec_protocol_options_set_tls_encryption_secret_update_block(sec_protocol_options_t options
, sec_protocol_tls_encryption_secret_update_t update_block
, dispatch_queue_t update_queue
) 
 890     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 891     SEC_PROTOCOL_OPTIONS_VALIDATE(update_block
,); 
 892     SEC_PROTOCOL_OPTIONS_VALIDATE(update_queue
,); 
 894     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 895         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 896         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 898         if (content
->tls_secret_update_block 
!= NULL
) { 
 899             Block_release(content
->tls_secret_update_block
); 
 901         if (content
->tls_secret_update_queue 
!= NULL
) { 
 902             dispatch_release(content
->tls_secret_update_queue
); 
 905         content
->tls_secret_update_block 
= Block_copy(update_block
); 
 906         content
->tls_secret_update_queue 
= update_queue
; 
 907         dispatch_retain(content
->tls_secret_update_queue
); 
 913 sec_protocol_options_set_session_state(sec_protocol_options_t options
, dispatch_data_t session_state
) 
 915     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 916     SEC_PROTOCOL_OPTIONS_VALIDATE(session_state
,); 
 918     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 919         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 920         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 922         if (content
->session_state 
!= NULL
) { 
 923             dispatch_release(content
->session_state
); 
 926         content
->session_state 
= session_state
; 
 927         dispatch_retain(session_state
); 
 933 sec_protocol_options_set_quic_transport_parameters(sec_protocol_options_t options
, dispatch_data_t transport_parameters
) 
 935     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 936     SEC_PROTOCOL_OPTIONS_VALIDATE(transport_parameters
,); 
 938     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 939         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 940         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 942         if (content
->quic_transport_parameters 
!= NULL
) { 
 943             dispatch_release(content
->quic_transport_parameters
); 
 946         content
->quic_transport_parameters 
= transport_parameters
; 
 947         dispatch_retain(transport_parameters
); 
 953 sec_protocol_options_set_ats_required(sec_protocol_options_t options
, bool required
) 
 955     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 957     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 958         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 959         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 961         content
->ats_required 
= required
; 
 967 sec_protocol_options_set_minimum_rsa_key_size(sec_protocol_options_t options
, size_t minimum_key_size
) 
 969     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 971     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 972         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 973         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 975         content
->minimum_rsa_key_size 
= minimum_key_size
; 
 981 sec_protocol_options_set_minimum_ecdsa_key_size(sec_protocol_options_t options
, size_t minimum_key_size
) 
 983     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 985     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
 986         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
 987         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
 989         content
->minimum_ecdsa_key_size 
= minimum_key_size
; 
 995 sec_protocol_options_set_minimum_signature_algorithm(sec_protocol_options_t options
, SecSignatureHashAlgorithm algorithm
) 
 997     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
 999     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
1000         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
1001         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
1003         content
->minimum_signature_algorithm 
= algorithm
; 
1009 sec_protocol_options_set_trusted_peer_certificate(sec_protocol_options_t options
, bool trusted_peer_certificate
) 
1011     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
1013     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
1014         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
1015         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
1017         content
->trusted_peer_certificate 
= trusted_peer_certificate
; 
1018         content
->trusted_peer_certificate_override 
= true; 
1024 sec_protocol_options_set_private_key_blocks(sec_protocol_options_t options
, 
1025                                             sec_protocol_private_key_sign_t sign_block
, 
1026                                             sec_protocol_private_key_decrypt_t decrypt_block
, 
1027                                             dispatch_queue_t operation_queue
) 
1029     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
1030     SEC_PROTOCOL_OPTIONS_VALIDATE(sign_block
,); 
1031     SEC_PROTOCOL_OPTIONS_VALIDATE(decrypt_block
,); 
1032     SEC_PROTOCOL_OPTIONS_VALIDATE(operation_queue
,); 
1034     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
1035         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
1036         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
1038         if (content
->private_key_sign_block 
!= NULL
) { 
1039             Block_release(content
->private_key_sign_block
); 
1041         if (content
->private_key_decrypt_block 
!= NULL
) { 
1042             Block_release(content
->private_key_decrypt_block
); 
1044         if (content
->private_key_queue 
!= NULL
) { 
1045             dispatch_release(content
->private_key_queue
); 
1048         content
->private_key_sign_block 
= Block_copy(sign_block
); 
1049         content
->private_key_decrypt_block 
= Block_copy(decrypt_block
); 
1050         content
->private_key_queue 
= operation_queue
; 
1051         dispatch_retain(content
->private_key_queue
); 
1058 sec_protocol_options_set_local_certificates(sec_protocol_options_t options
, sec_array_t certificates
) 
1060     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
1061     SEC_PROTOCOL_OPTIONS_VALIDATE(certificates
,); 
1063     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
1064         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
1065         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
1067         if (content
->certificates 
!= NULL
) { 
1068             sec_release(content
->certificates
); 
1071         content
->certificates 
= certificates
; 
1072         sec_retain(content
->certificates
); 
1078 sec_protocol_options_set_tls_certificate_compression_enabled(sec_protocol_options_t options
, bool certificate_compression_enabled
) 
1080     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
1082     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
1083         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
1084         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
1086         content
->certificate_compression_enabled 
= certificate_compression_enabled
; 
1092 sec_protocol_options_set_output_handler_access_block(sec_protocol_options_t options
, 
1093                                                      sec_protocol_output_handler_access_block_t access_block
) 
1095     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
1096     SEC_PROTOCOL_OPTIONS_VALIDATE(access_block
,); 
1098     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
1099         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
1100         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
1102         content
->output_handler_access_block 
= Block_copy(access_block
); 
1108 sec_protocol_options_tls_handshake_message_callback(sec_protocol_options_t options
, sec_protocol_tls_handshake_message_handler_t handler
, dispatch_queue_t queue
) 
1110     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
1111     SEC_PROTOCOL_OPTIONS_VALIDATE(handler
,); 
1112     SEC_PROTOCOL_OPTIONS_VALIDATE(queue
,); 
1114     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
1115         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
1116         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
1118         if (content
->handshake_message_callback 
!= NULL
) { 
1119             Block_release(content
->handshake_message_callback
); 
1121         if (content
->handshake_message_callback_queue 
!= NULL
) { 
1122             dispatch_release(content
->handshake_message_callback_queue
); 
1125         content
->handshake_message_callback 
= Block_copy(handler
); 
1126         content
->handshake_message_callback_queue 
= queue
; 
1127         dispatch_retain(content
->handshake_message_callback_queue
); 
1134 sec_protocol_options_set_tls_SIKE503_exchange_enabled(sec_protocol_options_t options
, bool tls_SIKE503_exchange_enabled
) 
1136     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
1138     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
1139         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
1140         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
1142         content
->tls_SIKE503_exchange_enabled 
= tls_SIKE503_exchange_enabled
; 
1148 sec_protocol_options_set_tls_HRSS_exchange_enabled(sec_protocol_options_t options
, bool tls_HRSS_exchange_enabled
) 
1150     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
1152     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
1153         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
1154         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
1156         content
->tls_HRSS_exchange_enabled 
= tls_HRSS_exchange_enabled
; 
1162 sec_protocol_options_set_eddsa_enabled(sec_protocol_options_t options
, bool eddsa_enabled
) 
1164     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
1166     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
1167         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
1168         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
1170         content
->eddsa_enabled 
= eddsa_enabled
; 
1176 sec_protocol_options_set_tls_delegated_credentials_enabled(sec_protocol_options_t options
, bool tls_delegated_credentials_enabled
) 
1178     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
1180     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
1181         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
1182         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
1184         content
->tls_delegated_credentials_enabled 
= tls_delegated_credentials_enabled
; 
1190 sec_protocol_options_set_tls_grease_enabled(sec_protocol_options_t options
, bool tls_grease_enabled
) 
1192     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
1194     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
1195         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
1196         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
1198         content
->tls_grease_enabled 
= tls_grease_enabled
; 
1204 sec_protocol_options_set_experiment_identifier(sec_protocol_options_t options
, const char *experiment_identifier
) 
1206     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
1207     SEC_PROTOCOL_OPTIONS_VALIDATE(experiment_identifier
,); 
1209     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
1210         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
1211         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
1213         if (content
->experiment_identifier 
!= NULL
) { 
1214             free(content
->experiment_identifier
); 
1216         if (experiment_identifier 
!= NULL
) { 
1217             content
->experiment_identifier 
= strdup(experiment_identifier
); 
1224 sec_protocol_options_set_connection_id(sec_protocol_options_t options
, uuid_t _Nonnull connection_id
) 
1226     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
1227     SEC_PROTOCOL_OPTIONS_VALIDATE(connection_id
,); 
1229     sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
1230         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
1231         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
1233         memcpy(content
->connection_id
, connection_id
, sizeof(content
->connection_id
)); 
1239 sec_protocol_options_set_tls_ticket_request_count(sec_protocol_options_t options
, uint8_t tls_ticket_request_count
) 
1241     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
1243     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
1244         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
1245         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
1247         content
->tls_ticket_request_count 
= tls_ticket_request_count
; 
1253 sec_protocol_options_set_ats_non_pfs_ciphersuite_allowed(sec_protocol_options_t options
, bool ats_non_pfs_ciphersuite_allowed
) 
1255     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
1257     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
1258         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
1259         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
1261         content
->ats_non_pfs_ciphersuite_allowed 
= ats_non_pfs_ciphersuite_allowed
; 
1267 sec_protocol_options_set_ats_minimum_tls_version_allowed(sec_protocol_options_t options
, bool ats_minimum_tls_version_allowed
) 
1269     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
1271     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
1272         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
1273         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
1275         content
->ats_minimum_tls_version_allowed 
= ats_minimum_tls_version_allowed
; 
1281 sec_protocol_options_append_tls_key_exchange_group(sec_protocol_options_t options
, tls_key_exchange_group_t group
) 
1283     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
1285     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
1286         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
1287         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
1289         if (content
->key_exchange_groups 
== NULL
) { 
1290             content
->key_exchange_groups 
= xpc_array_create(NULL
, 0); 
1292         xpc_array_set_uint64(content
->key_exchange_groups
, XPC_ARRAY_APPEND
, (uint64_t)group
); 
1298 sec_protocol_options_add_tls_key_exchange_group(sec_protocol_options_t options
, SSLKeyExchangeGroup group
) 
1300     return sec_protocol_options_append_tls_key_exchange_group(options
, (tls_key_exchange_group_t
)group
); 
1304 sec_protocol_options_append_tls_key_exchange_group_set(sec_protocol_options_t options
, tls_key_exchange_group_set_t set
) 
1306     SEC_PROTOCOL_OPTIONS_VALIDATE(options
,); 
1308     (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) { 
1309         sec_protocol_options_content_t content 
= (sec_protocol_options_content_t
)handle
; 
1310         SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false); 
1312         if (content
->key_exchange_groups 
== NULL
) { 
1313             content
->key_exchange_groups 
= xpc_array_create(NULL
, 0); 
1316         // Fetch the list of ciphersuites associated with the ciphersuite group 
1317         size_t group_set_count 
= 0; 
1318         const tls_key_exchange_group_t 
*group_set 
= sec_protocol_helper_tls_key_exchange_group_set_to_key_exchange_group_list(set
, &group_set_count
); 
1319         if (group_set 
!= NULL
) { 
1320             for (size_t i 
= 0; i 
< group_set_count
; i
++) { 
1321                 tls_key_exchange_group_t group 
= group_set
[i
]; 
1322                 xpc_array_set_uint64(content
->key_exchange_groups
, XPC_ARRAY_APPEND
, (uint64_t)group
); 
1331 sec_protocol_options_add_tls_key_exchange_group_set(sec_protocol_options_t options
, SSLKeyExchangeGroupSet set
) 
1334         case kSSLKeyExchangeGroupSetDefault
: 
1335             sec_protocol_options_append_tls_key_exchange_group_set(options
, tls_key_exchange_group_set_default
); 
1337         case kSSLKeyExchangeGroupSetCompatibility
: 
1338             sec_protocol_options_append_tls_key_exchange_group_set(options
, tls_key_exchange_group_set_compatibility
); 
1340         case kSSLKeyExchangeGroupSetLegacy
: 
1341             sec_protocol_options_append_tls_key_exchange_group_set(options
, tls_key_exchange_group_set_legacy
); 
1347 sec_protocol_metadata_get_negotiated_protocol(sec_protocol_metadata_t metadata
) 
1349     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
); 
1351     __block 
const char *negotiated_protocol 
= NULL
; 
1352     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
1353         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
1354         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
1355         negotiated_protocol 
= content
->negotiated_protocol
; 
1359     return negotiated_protocol
; 
1363 sec_protocol_metadata_get_server_name(sec_protocol_metadata_t metadata
) 
1365     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
); 
1367     __block 
const char *server_name 
= NULL
; 
1368     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
1369         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
1370         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
1371         server_name 
= content
->server_name
; 
1379 sec_protocol_metadata_get_handshake_time_ms(sec_protocol_metadata_t metadata
) 
1381     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0); 
1383     __block 
uint64_t time 
= 0; 
1384     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) { 
1385         sec_protocol_metadata_content_t metadata_content 
= (sec_protocol_metadata_content_t
)metadata_handle
; 
1386         SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false); 
1387         time 
= metadata_content
->handshake_time
; 
1395 sec_protocol_metadata_get_handshake_byte_count(sec_protocol_metadata_t metadata
) 
1397     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0); 
1399     __block 
uint64_t count 
= 0; 
1400     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) { 
1401         sec_protocol_metadata_content_t metadata_content 
= (sec_protocol_metadata_content_t
)metadata_handle
; 
1402         SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false); 
1403         count 
= metadata_content
->total_byte_count
; 
1411 sec_protocol_metadata_get_handshake_sent_byte_count(sec_protocol_metadata_t metadata
) 
1413     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0); 
1415     __block 
uint64_t count 
= 0; 
1416     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) { 
1417         sec_protocol_metadata_content_t metadata_content 
= (sec_protocol_metadata_content_t
)metadata_handle
; 
1418         SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false); 
1419         count 
= metadata_content
->sent_byte_count
; 
1427 sec_protocol_metadata_get_handshake_received_byte_count(sec_protocol_metadata_t metadata
) 
1429     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0); 
1431     __block 
uint64_t count 
= 0; 
1432     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) { 
1433         sec_protocol_metadata_content_t metadata_content 
= (sec_protocol_metadata_content_t
)metadata_handle
; 
1434         SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false); 
1435         count 
= metadata_content
->received_byte_count
; 
1443 sec_protocol_metadata_get_handshake_read_stall_count(sec_protocol_metadata_t metadata
) 
1445     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0); 
1447     __block 
size_t count 
= 0; 
1448     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) { 
1449         sec_protocol_metadata_content_t metadata_content 
= (sec_protocol_metadata_content_t
)metadata_handle
; 
1450         SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false); 
1451         count 
= metadata_content
->read_stall_count
; 
1459 sec_protocol_metadata_get_handshake_write_stall_count(sec_protocol_metadata_t metadata
) 
1461     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0); 
1463     __block 
size_t count 
= 0; 
1464     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) { 
1465         sec_protocol_metadata_content_t metadata_content 
= (sec_protocol_metadata_content_t
)metadata_handle
; 
1466         SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false); 
1467         count 
= metadata_content
->write_stall_count
; 
1475 sec_protocol_metadata_get_handshake_async_call_count(sec_protocol_metadata_t metadata
) 
1477     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0); 
1479     __block 
size_t count 
= 0; 
1480     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) { 
1481         sec_protocol_metadata_content_t metadata_content 
= (sec_protocol_metadata_content_t
)metadata_handle
; 
1482         SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false); 
1483         count 
= metadata_content
->async_call_count
; 
1491 sec_protocol_metadata_access_peer_certificate_chain(sec_protocol_metadata_t metadata
, 
1492                                                     void (^handler
)(sec_certificate_t certficate
)) 
1494     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false); 
1495     SEC_PROTOCOL_METADATA_VALIDATE(handler
, false); 
1497     return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
1498         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
1499         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
1500         if (content
->peer_certificate_chain 
== NULL
) { 
1503         sec_array_t array 
= content
->peer_certificate_chain
; 
1504         sec_array_apply(array
, ^bool(__unused 
size_t index
, sec_object_t object
) { 
1505             handler((sec_certificate_t
)object
); 
1513 sec_protocol_metadata_copy_peer_public_key(sec_protocol_metadata_t metadata
) 
1515     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
); 
1517     __block dispatch_data_t peer_public_key 
= NULL
; 
1518     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
1519         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
1520         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
1521         peer_public_key 
= ((dispatch_data_t
)content
->peer_public_key
); 
1522         if (peer_public_key
) { 
1523             dispatch_retain(peer_public_key
); 
1528     return peer_public_key
; 
1531 tls_protocol_version_t
 
1532 sec_protocol_metadata_get_negotiated_tls_protocol_version(sec_protocol_metadata_t metadata
) 
1534     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0x0000); 
1536     __block tls_protocol_version_t protocol_version 
= 0x0000; 
1537     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
1538         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
1539         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
1540         protocol_version 
= SSLProtocolGetVersionCodepoint(content
->negotiated_protocol_version
); 
1544     return protocol_version
; 
1548 sec_protocol_metadata_get_negotiated_protocol_version(sec_protocol_metadata_t metadata
) 
1550     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, kSSLProtocolUnknown
); 
1552     __block SSLProtocol protocol_version 
= kSSLProtocolUnknown
; 
1553     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
1554         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
1555         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
1556         protocol_version 
= content
->negotiated_protocol_version
; 
1560     return protocol_version
; 
1564 sec_protocol_metadata_get_negotiated_tls_ciphersuite(sec_protocol_metadata_t metadata
) 
1566     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0xFFFF); 
1568     __block tls_ciphersuite_t negotiated_ciphersuite 
= SSL_NO_SUCH_CIPHERSUITE
; 
1569     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
1570         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
1571         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
1572         negotiated_ciphersuite 
= content
->negotiated_ciphersuite
; 
1576     return negotiated_ciphersuite
; 
1580 sec_protocol_metadata_get_negotiated_ciphersuite(sec_protocol_metadata_t metadata
) 
1582     return (SSLCipherSuite
)sec_protocol_metadata_get_negotiated_tls_ciphersuite(metadata
); 
1586 sec_protocol_metadata_get_early_data_accepted(sec_protocol_metadata_t metadata
) 
1588     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false); 
1590     return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
1591         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
1592         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
1593         return content
->early_data_accepted
; 
1598 sec_protocol_metadata_access_supported_signature_algorithms(sec_protocol_metadata_t metadata
, 
1599                                                             void (^handler
)(uint16_t signature_algorithm
)) 
1601     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false); 
1602     SEC_PROTOCOL_METADATA_VALIDATE(handler
, false); 
1604     return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
1605         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
1606         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
1607         if (content
->supported_signature_algorithms 
== NULL
) { 
1610         xpc_object_t array 
= content
->supported_signature_algorithms
; 
1611         xpc_array_apply(array
, ^bool(__unused 
size_t index
, xpc_object_t _Nonnull value
) { 
1612             handler((uint16_t)xpc_uint64_get_value(value
)); 
1620 sec_protocol_metadata_access_ocsp_response(sec_protocol_metadata_t metadata
, 
1621                                            void (^handler
)(dispatch_data_t ocsp_data
)) 
1623     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false); 
1624     SEC_PROTOCOL_METADATA_VALIDATE(handler
, false); 
1626     return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
1627         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
1628         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
1629         if (content
->ocsp_response 
== NULL
) { 
1632         sec_array_t array 
= content
->ocsp_response
; 
1633         sec_array_apply(array
, ^bool(__unused 
size_t index
, sec_object_t object
) { 
1634             handler((dispatch_data_t
)object
); 
1642 sec_protocol_metadata_access_distinguished_names(sec_protocol_metadata_t metadata
, 
1643                                                  void (^handler
)(dispatch_data_t distinguished_name
)) 
1645     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false); 
1646     SEC_PROTOCOL_METADATA_VALIDATE(handler
, false); 
1648     return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
1649         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
1650         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
1651         if (content
->distinguished_names 
== NULL
) { 
1654         sec_array_t array 
= content
->distinguished_names
; 
1655         sec_array_apply(array
, ^bool(__unused 
size_t index
, sec_object_t object
) { 
1656             handler((dispatch_data_t
)object
); 
1663 static dispatch_data_t
 
1664 create_dispatch_data_from_xpc_data(xpc_object_t xpc_data
) 
1670     size_t data_len 
= xpc_data_get_length(xpc_data
); 
1671     if (data_len 
== 0) { 
1675     uint8_t *data_buffer 
= malloc(data_len
); 
1680     size_t copied_count 
= xpc_data_get_bytes(xpc_data
, data_buffer
, 0, data_len
); 
1681     if (copied_count 
!= data_len
) { 
1686     dispatch_data_t data 
= dispatch_data_create(data_buffer
, data_len
, NULL
, DISPATCH_DATA_DESTRUCTOR_DEFAULT
); 
1693 sec_protocol_metadata_access_pre_shared_keys(sec_protocol_metadata_t metadata
, 
1694                                              void (^handler
)(dispatch_data_t psk
, dispatch_data_t _Nullable psk_identity
)) 
1696     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false); 
1697     SEC_PROTOCOL_METADATA_VALIDATE(handler
, false); 
1699     return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
1700         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
1701         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
1702         if (content
->pre_shared_keys 
== NULL
) { 
1705         xpc_array_apply(content
->pre_shared_keys
, ^bool(size_t index
, xpc_object_t _Nonnull tuple
) { 
1706             if (xpc_array_get_count(tuple
) == 2) { 
1707                 xpc_object_t xpc_psk_data 
= xpc_array_get_value(tuple
, 0); 
1708                 xpc_object_t xpc_psk_identity_data 
= xpc_array_get_value(tuple
, 1); 
1710                 dispatch_data_t psk_data 
= create_dispatch_data_from_xpc_data(xpc_psk_data
); 
1711                 dispatch_data_t psk_identity_data 
= create_dispatch_data_from_xpc_data(xpc_psk_identity_data
); 
1712                 if (!psk_data 
|| !psk_identity_data
) { 
1713                     // Skip and return early if we can't create a PSK or identity from the provided data. Something's wrong. 
1717                 handler(psk_data
, psk_identity_data
); 
1726 sec_protocol_dispatch_data_are_equal(dispatch_data_t left
, dispatch_data_t right
) 
1728     if (!left 
|| !right 
|| left 
== right
) { 
1729         return left 
== right
; 
1731     if (dispatch_data_get_size(left
) != dispatch_data_get_size(right
)) { 
1735     __block 
bool equal 
= true; 
1736     dispatch_data_apply(left
, ^bool(__unused dispatch_data_t  _Nonnull lregion
, size_t loffset
, const void * _Nonnull lbuffer
, size_t lsize
) { 
1737         dispatch_data_apply(right
, ^bool(__unused dispatch_data_t  _Nonnull rregion
, size_t roffset
, const void * _Nonnull rbuffer
, size_t rsize
) { 
1738             // There is some overlap 
1739             const size_t start 
= MAX(loffset
, roffset
); 
1740             const size_t end 
= MIN(loffset 
+ lsize
, roffset 
+ rsize
); 
1742                 equal 
= memcmp(&((const uint8_t*)rbuffer
)[start 
- roffset
], &((const uint8_t*)lbuffer
)[start 
- loffset
], end 
- start
) == 0; 
1744                 if (roffset 
> loffset 
+ lsize
) { 
1745                     // Iteration of right has gone past where we're at on left, bail out of inner apply 
1749                 } else if (roffset 
+ rsize 
< loffset
) { 
1750                     // Iteration of right has not yet reached where we're at on left, keep going 
1764 sec_protocol_sec_array_of_dispatch_data_are_equal(sec_array_t arrayA
, sec_array_t arrayB
) 
1766     if (sec_array_get_count(arrayA
) != sec_array_get_count(arrayB
)) { 
1770     __block 
bool equal 
= true; 
1771     (void)sec_array_apply(arrayA
, ^bool(size_t indexA
, sec_object_t objectA
) { 
1772         return sec_array_apply(arrayB
, ^bool(size_t indexB
, sec_object_t objectB
) { 
1773             if (indexA 
== indexB
) { 
1774                 dispatch_data_t dataA 
= (dispatch_data_t
)objectA
; 
1775                 dispatch_data_t dataB 
= (dispatch_data_t
)objectB
; 
1776                 equal 
&= sec_protocol_dispatch_data_are_equal(dataA
, dataB
); 
1787 sec_protocol_sec_array_of_sec_certificate_are_equal(sec_array_t arrayA
, sec_array_t arrayB
) 
1789     if (sec_array_get_count(arrayA
) != sec_array_get_count(arrayB
)) { 
1793     __block 
bool equal 
= true; 
1794     (void)sec_array_apply(arrayA
, ^bool(size_t indexA
, sec_object_t objectA
) { 
1795         return sec_array_apply(arrayB
, ^bool(size_t indexB
, sec_object_t objectB
) { 
1796             if (indexA 
== indexB
) { 
1797                 sec_certificate_t certA 
= (sec_certificate_t
)objectA
; 
1798                 sec_certificate_t certB 
= (sec_certificate_t
)objectB
; 
1800                 SecCertificateRef certRefA 
= sec_certificate_copy_ref(certA
); 
1801                 SecCertificateRef certRefB 
= sec_certificate_copy_ref(certB
); 
1803                 if (certRefA 
== NULL 
&& certRefB 
!= NULL
) { 
1805                 } else if (certRefA 
!= NULL 
&& certRefB 
== NULL
) { 
1807                 } else if (certRefA 
== NULL 
&& certRefB 
== NULL
) { 
1810                     equal 
&= CFEqual(certRefA
, certRefB
); 
1813                 CFReleaseSafe(certRefA
); 
1814                 CFReleaseSafe(certRefB
); 
1826 sec_protocol_xpc_object_are_equal(xpc_object_t objectA
, xpc_object_t objectB
) 
1828     if (objectA 
== NULL 
&& objectB 
!= NULL
) { 
1830     } else if (objectA 
!= NULL 
&& objectB 
== NULL
) { 
1832     } else if (objectA 
== NULL 
&& objectB 
== NULL
) { 
1835         return xpc_equal(objectA
, objectB
); 
1840 sec_protocol_metadata_peers_are_equal(sec_protocol_metadata_t metadataA
, sec_protocol_metadata_t metadataB
) 
1842     SEC_PROTOCOL_METADATA_VALIDATE(metadataA
, false); 
1843     SEC_PROTOCOL_METADATA_VALIDATE(metadataB
, false); 
1845     return sec_protocol_metadata_access_handle(metadataA
, ^bool(void *handleA
) { 
1846         sec_protocol_metadata_content_t contentA 
= (sec_protocol_metadata_content_t
)handleA
; 
1847         SEC_PROTOCOL_METADATA_VALIDATE(contentA
, false); 
1849         return sec_protocol_metadata_access_handle(metadataB
, ^bool(void *handleB
) { 
1850             sec_protocol_metadata_content_t contentB 
= (sec_protocol_metadata_content_t
)handleB
; 
1851             SEC_PROTOCOL_METADATA_VALIDATE(contentB
, false); 
1853             // Relevant peer information includes: Certificate chain, public key, support signature algorithms, OCSP response, and distinguished names 
1854             if (!sec_protocol_sec_array_of_sec_certificate_are_equal(contentA
->peer_certificate_chain
, contentB
->peer_certificate_chain
)) { 
1857             if (!sec_protocol_dispatch_data_are_equal((dispatch_data_t
)contentA
->peer_public_key
, (dispatch_data_t
)contentB
->peer_public_key
)) { 
1860             if (!sec_protocol_xpc_object_are_equal((xpc_object_t
)contentA
->supported_signature_algorithms
, (xpc_object_t
)contentB
->supported_signature_algorithms
)) { 
1863             if (!sec_protocol_sec_array_of_dispatch_data_are_equal(contentA
->ocsp_response
, contentB
->ocsp_response
)) { 
1866             if (!sec_protocol_sec_array_of_dispatch_data_are_equal(contentA
->distinguished_names
, contentB
->distinguished_names
)) { 
1876 sec_protocol_metadata_challenge_parameters_are_equal(sec_protocol_metadata_t metadataA
, sec_protocol_metadata_t metadataB
) 
1878     SEC_PROTOCOL_METADATA_VALIDATE(metadataA
, false); 
1879     SEC_PROTOCOL_METADATA_VALIDATE(metadataB
, false); 
1881     return sec_protocol_metadata_access_handle(metadataA
, ^bool(void *handleA
) { 
1882         sec_protocol_metadata_content_t contentA 
= (sec_protocol_metadata_content_t
)handleA
; 
1883         SEC_PROTOCOL_METADATA_VALIDATE(contentA
, false); 
1885         return sec_protocol_metadata_access_handle(metadataB
, ^bool(void *handleB
) { 
1886             sec_protocol_metadata_content_t contentB 
= (sec_protocol_metadata_content_t
)handleB
; 
1887             SEC_PROTOCOL_METADATA_VALIDATE(contentB
, false); 
1889             if (!sec_protocol_xpc_object_are_equal((xpc_object_t
)contentA
->supported_signature_algorithms
, (xpc_object_t
)contentB
->supported_signature_algorithms
)) { 
1892             if (!sec_protocol_sec_array_of_dispatch_data_are_equal(contentA
->distinguished_names
, contentB
->distinguished_names
)) { 
1895             if (!sec_protocol_dispatch_data_are_equal(contentA
->request_certificate_types
, contentB
->request_certificate_types
)) { 
1905 sec_protocol_metadata_create_secret(sec_protocol_metadata_t metadata
, size_t label_len
, 
1906                                     const char *label
, size_t exporter_length
) 
1908     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
); 
1909     SEC_PROTOCOL_METADATA_VALIDATE(label_len
, NULL
); 
1910     SEC_PROTOCOL_METADATA_VALIDATE(label
, NULL
); 
1911     SEC_PROTOCOL_METADATA_VALIDATE(exporter_length
, NULL
); 
1913     __block dispatch_data_t secret 
= NULL
; 
1914     sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
1915         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
1916         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
1918         if (content
->exporter_function 
&& content
->exporter_context
) { 
1919             sec_protocol_metadata_exporter exporter 
= (sec_protocol_metadata_exporter
)content
->exporter_function
; 
1920             secret 
= exporter(content
->exporter_context
, label_len
, label
, 0, NULL
, exporter_length
); 
1928 sec_protocol_metadata_create_secret_with_context(sec_protocol_metadata_t metadata
, size_t label_len
, 
1929                                                  const char *label
, size_t context_len
, 
1930                                                  const uint8_t *context
, size_t exporter_length
) 
1932     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
); 
1933     SEC_PROTOCOL_METADATA_VALIDATE(label_len
, NULL
); 
1934     SEC_PROTOCOL_METADATA_VALIDATE(label
, NULL
); 
1935     SEC_PROTOCOL_METADATA_VALIDATE(context_len
, NULL
); 
1936     SEC_PROTOCOL_METADATA_VALIDATE(context
, NULL
); 
1937     SEC_PROTOCOL_METADATA_VALIDATE(exporter_length
, NULL
); 
1939     __block dispatch_data_t secret 
= NULL
; 
1940     sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
1941         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
1942         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
1944         if (content
->exporter_function 
&& content
->exporter_context
) { 
1945             sec_protocol_metadata_exporter exporter 
= (sec_protocol_metadata_exporter
)content
->exporter_function
; 
1946             secret 
= exporter(content
->exporter_context
, label_len
, label
, context_len
, context
, exporter_length
); 
1954 sec_protocol_metadata_get_tls_false_start_used(sec_protocol_metadata_t metadata
) 
1956     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false); 
1958     return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
1959         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
1960         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
1961         return content
->false_start_used
; 
1966 sec_protocol_metadata_get_ticket_offered(sec_protocol_metadata_t metadata
) 
1968     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false); 
1970     return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
1971         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
1972         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
1973         return content
->ticket_offered
; 
1978 sec_protocol_metadata_get_ticket_received(sec_protocol_metadata_t metadata
) 
1980     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false); 
1982     return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
1983         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
1984         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
1985         return content
->ticket_received
; 
1990 sec_protocol_metadata_get_session_resumed(sec_protocol_metadata_t metadata
) 
1992     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false); 
1994     return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
1995         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
1996         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
1997         return content
->session_resumed
; 
2002 sec_protocol_metadata_get_session_renewed(sec_protocol_metadata_t metadata
) 
2004     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false); 
2006     return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
2007         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
2008         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
2009         return content
->session_renewed
; 
2013 SSLConnectionStrength
 
2014 sec_protocol_metadata_get_connection_strength(sec_protocol_metadata_t metadata
) 
2016     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, SSLConnectionStrengthNonsecure
); 
2018     __block SSLConnectionStrength strength 
= SSLConnectionStrengthNonsecure
; 
2019     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
2020         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
2021         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
2023         // TLSv1.2 and higher are considered strong. Anything less than TLSv1.2 is considered weak at best. 
2024 #pragma clang diagnostic push 
2025 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 
2026         SSLProtocol version 
= content
->negotiated_protocol_version
; 
2027         if (version 
>= kTLSProtocol12
) { 
2028             strength 
= SSLConnectionStrengthStrong
; 
2029         } else if (version 
== kTLSProtocol11 
|| version 
== kTLSProtocol1
) { 
2030             strength 
= SSLConnectionStrengthWeak
; 
2032             strength 
= SSLConnectionStrengthNonsecure
; 
2035         // Legacy ciphersuites make the connection weak, for now. We may consider changing this to nonsecure. 
2036         SSLCipherSuite ciphersuite 
= content
->negotiated_ciphersuite
; 
2037         if (strength 
!= SSLConnectionStrengthNonsecure 
&& 
2038                 SSLCiphersuiteGroupContainsCiphersuite(kSSLCiphersuiteGroupLegacy
, ciphersuite
)) { 
2039             strength 
= SSLConnectionStrengthWeak
; 
2041 #pragma clang diagnostic pop 
2050 sec_protocol_metadata_copy_serialized_session(sec_protocol_metadata_t metadata
) 
2052     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
); 
2054     __block dispatch_data_t session 
= NULL
; 
2055     sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
2056         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
2057         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
2059         if (content
->session_exporter_function 
&& content
->session_exporter_context
) { 
2060             sec_protocol_metadata_session_exporter exporter 
= (sec_protocol_metadata_session_exporter
)content
->session_exporter_function
; 
2061             session 
= exporter(content
->session_exporter_context
); 
2068 const char * __nullable
 
2069 sec_protocol_metadata_get_experiment_identifier(sec_protocol_metadata_t metadata
) 
2071     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
); 
2073     __block 
const char *experiment_identifer 
= NULL
; 
2074     sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
2075         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
2076         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
2078         experiment_identifer 
= content
->experiment_identifier
; 
2081     return experiment_identifer
; 
2085 sec_protocol_metadata_copy_connection_id(sec_protocol_metadata_t metadata
, uuid_t _Nonnull output_uuid
) 
2087     SEC_PROTOCOL_METADATA_VALIDATE(metadata
,); 
2088     SEC_PROTOCOL_METADATA_VALIDATE(output_uuid
,); 
2090     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
2091         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
2092         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
2094         memcpy(output_uuid
, content
->connection_id
, sizeof(content
->connection_id
)); 
2099 static const char *_options_uint64_keys
[] = { 
2100     SEC_PROTOCOL_OPTIONS_KEY_min_version
, 
2101     SEC_PROTOCOL_OPTIONS_KEY_max_version
, 
2102     SEC_PROTOCOL_OPTIONS_KEY_minimum_rsa_key_size
, 
2103     SEC_PROTOCOL_OPTIONS_KEY_minimum_ecdsa_key_size
, 
2104     SEC_PROTOCOL_OPTIONS_KEY_minimum_signature_algorithm
, 
2105     SEC_PROTOCOL_OPTIONS_KEY_tls_ticket_request_count
, 
2107 static const size_t _options_uint64_keys_len 
= sizeof(_options_uint64_keys
) / sizeof(_options_uint64_keys
[0]); 
2109 static const char *_options_bool_keys
[] = { 
2110     SEC_PROTOCOL_OPTIONS_KEY_ats_required
, 
2111     SEC_PROTOCOL_OPTIONS_KEY_ats_minimum_tls_version_allowed
, 
2112     SEC_PROTOCOL_OPTIONS_KEY_ats_non_pfs_ciphersuite_allowed
, 
2113     SEC_PROTOCOL_OPTIONS_KEY_trusted_peer_certificate
, 
2114     SEC_PROTOCOL_OPTIONS_KEY_disable_sni
, 
2115     SEC_PROTOCOL_OPTIONS_KEY_enable_fallback_attempt
, 
2116     SEC_PROTOCOL_OPTIONS_KEY_enable_false_start
, 
2117     SEC_PROTOCOL_OPTIONS_KEY_enable_tickets
, 
2118     SEC_PROTOCOL_OPTIONS_KEY_enable_sct
, 
2119     SEC_PROTOCOL_OPTIONS_KEY_enable_ocsp
, 
2120     SEC_PROTOCOL_OPTIONS_KEY_enforce_ev
, 
2121     SEC_PROTOCOL_OPTIONS_KEY_enable_resumption
, 
2122     SEC_PROTOCOL_OPTIONS_KEY_enable_renegotiation
, 
2123     SEC_PROTOCOL_OPTIONS_KEY_enable_early_data
, 
2124     SEC_PROTOCOL_OPTIONS_KEY_peer_authentication_required
, 
2125     SEC_PROTOCOL_OPTIONS_KEY_certificate_compression_enabled
, 
2126     SEC_PROTOCOL_OPTIONS_KEY_tls_SIKE503_exchange_enabled
, 
2127     SEC_PROTOCOL_OPTIONS_KEY_tls_HRSS_exchange_enabled
, 
2128     SEC_PROTOCOL_OPTIONS_KEY_eddsa_enabled
, 
2129     SEC_PROTOCOL_OPTIONS_KEY_tls_delegated_credentials_enabled
, 
2130     SEC_PROTOCOL_OPTIONS_KEY_tls_grease_enabled
, 
2133 static const size_t _options_bool_keys_len 
= sizeof(_options_bool_keys
) / sizeof(_options_bool_keys
[0]); 
2136 _dictionary_has_key(xpc_object_t dict
, const char *target_key
) 
2138     if (xpc_get_type(dict
) != XPC_TYPE_DICTIONARY
) { 
2142     return !xpc_dictionary_apply(dict
, ^bool(const char * _Nonnull key
, xpc_object_t  _Nonnull value
) { 
2143         if (strncmp(key
, target_key
, strlen(target_key
)) == 0) { 
2151 _options_config_matches_partial_config(xpc_object_t full
, xpc_object_t partial
) 
2153     SEC_PROTOCOL_METADATA_VALIDATE(full
, false); 
2154     SEC_PROTOCOL_METADATA_VALIDATE(partial
, false); 
2156     return xpc_dictionary_apply(partial
, ^bool(const char * _Nonnull entry_key
, xpc_object_t _Nonnull value
) { 
2157         size_t entry_key_len 
= strnlen(entry_key
, MAX_SEC_PROTOCOL_OPTIONS_KEY_LEN
); 
2159         for (size_t i 
= 0; i 
< _options_uint64_keys_len
; i
++) { 
2160             const char *key 
= _options_uint64_keys
[i
]; 
2161             if (strncmp(entry_key
, key
, MAX(entry_key_len
, strlen(key
))) == 0) { 
2162                 if (_dictionary_has_key(full
, key
)) { 
2163                     if (xpc_dictionary_get_uint64(full
, key
) != xpc_dictionary_get_uint64(partial
, key
)) { 
2172         for (size_t i 
= 0; i 
< _options_bool_keys_len
; i
++) { 
2173             const char *key 
= _options_bool_keys
[i
]; 
2174             if (strncmp(entry_key
, key
, MAX(entry_key_len
, strlen(key
))) == 0) { 
2175                 if (_dictionary_has_key(full
, key
)) { 
2176                     if (xpc_dictionary_get_bool(full
, key
) != xpc_dictionary_get_bool(partial
, key
)) { 
2190 _serialize_options(xpc_object_t dictionary
, sec_protocol_options_content_t options_content
) 
2192 #define EXPAND_PARAMETER(field) \ 
2193     SEC_PROTOCOL_OPTIONS_KEY_##field , options_content->field 
2195     xpc_dictionary_set_uint64(dictionary
, EXPAND_PARAMETER(min_version
)); 
2196     xpc_dictionary_set_uint64(dictionary
, EXPAND_PARAMETER(max_version
)); 
2197     xpc_dictionary_set_uint64(dictionary
, EXPAND_PARAMETER(minimum_rsa_key_size
)); 
2198     xpc_dictionary_set_uint64(dictionary
, EXPAND_PARAMETER(minimum_ecdsa_key_size
)); 
2199     xpc_dictionary_set_uint64(dictionary
, EXPAND_PARAMETER(minimum_signature_algorithm
)); 
2200     xpc_dictionary_set_uint64(dictionary
, EXPAND_PARAMETER(tls_ticket_request_count
)); 
2202     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(ats_required
)); 
2203     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(ats_minimum_tls_version_allowed
)); 
2204     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(ats_non_pfs_ciphersuite_allowed
)); 
2205     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(trusted_peer_certificate
)); 
2206     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(disable_sni
)); 
2207     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_fallback_attempt
)); 
2208     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_false_start
)); 
2209     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_tickets
)); 
2210     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_sct
)); 
2211     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_ocsp
)); 
2212     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enforce_ev
)); 
2213     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_resumption
)); 
2214     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_renegotiation
)); 
2215     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_early_data
)); 
2216     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(peer_authentication_required
)); 
2217     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(certificate_compression_enabled
)); 
2218     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(tls_SIKE503_exchange_enabled
)); 
2219     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(tls_HRSS_exchange_enabled
)); 
2220     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(eddsa_enabled
)); 
2221     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(tls_delegated_credentials_enabled
)); 
2222     xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(tls_grease_enabled
)); 
2224 #undef EXPAND_PARAMETER 
2229 static struct _options_bool_key_setter 
{ 
2231     void (*setter_pointer
)(sec_protocol_options_t
, bool); 
2232 } _options_bool_key_setters
[] = { 
2234         .key 
= SEC_PROTOCOL_OPTIONS_KEY_ats_required
, 
2235         .setter_pointer 
= sec_protocol_options_set_ats_required
, 
2238         .key 
= SEC_PROTOCOL_OPTIONS_KEY_ats_minimum_tls_version_allowed
, 
2239         .setter_pointer 
= sec_protocol_options_set_ats_minimum_tls_version_allowed
, 
2242         .key 
= SEC_PROTOCOL_OPTIONS_KEY_ats_non_pfs_ciphersuite_allowed
, 
2243         .setter_pointer 
= sec_protocol_options_set_ats_non_pfs_ciphersuite_allowed
, 
2246         .key 
= SEC_PROTOCOL_OPTIONS_KEY_trusted_peer_certificate
, 
2247         .setter_pointer 
= sec_protocol_options_set_trusted_peer_certificate
, 
2250         .key 
= SEC_PROTOCOL_OPTIONS_KEY_disable_sni
, 
2251         .setter_pointer 
= sec_protocol_options_set_tls_sni_disabled
 
2254         .key 
= SEC_PROTOCOL_OPTIONS_KEY_enable_fallback_attempt
, 
2255         .setter_pointer 
= sec_protocol_options_set_tls_is_fallback_attempt
, 
2258         .key 
= SEC_PROTOCOL_OPTIONS_KEY_enable_false_start
, 
2259         .setter_pointer 
= sec_protocol_options_set_tls_false_start_enabled
, 
2262         .key 
= SEC_PROTOCOL_OPTIONS_KEY_enable_tickets
, 
2263         .setter_pointer 
= sec_protocol_options_set_tls_tickets_enabled
, 
2266         .key 
= SEC_PROTOCOL_OPTIONS_KEY_enable_sct
, 
2267         .setter_pointer 
= sec_protocol_options_set_tls_sct_enabled
 
2270         .key 
= SEC_PROTOCOL_OPTIONS_KEY_enable_ocsp
, 
2271         .setter_pointer 
= sec_protocol_options_set_tls_ocsp_enabled
, 
2274         .key 
= SEC_PROTOCOL_OPTIONS_KEY_enforce_ev
, 
2275         .setter_pointer 
= sec_protocol_options_set_enforce_ev
, 
2278         .key 
= SEC_PROTOCOL_OPTIONS_KEY_enable_resumption
, 
2279         .setter_pointer 
= sec_protocol_options_set_tls_resumption_enabled
, 
2282         .key 
= SEC_PROTOCOL_OPTIONS_KEY_enable_renegotiation
, 
2283         .setter_pointer 
= sec_protocol_options_set_tls_renegotiation_enabled
, 
2286         .key 
= SEC_PROTOCOL_OPTIONS_KEY_enable_early_data
, 
2287         .setter_pointer 
= sec_protocol_options_set_tls_early_data_enabled
, 
2290         .key 
= SEC_PROTOCOL_OPTIONS_KEY_peer_authentication_required
, 
2291         .setter_pointer 
= sec_protocol_options_set_peer_authentication_required
, 
2294         .key 
= SEC_PROTOCOL_OPTIONS_KEY_certificate_compression_enabled
, 
2295         .setter_pointer 
= sec_protocol_options_set_tls_certificate_compression_enabled
, 
2298         .key 
= SEC_PROTOCOL_OPTIONS_KEY_tls_SIKE503_exchange_enabled
, 
2299         .setter_pointer 
= sec_protocol_options_set_tls_SIKE503_exchange_enabled
, 
2302         .key 
= SEC_PROTOCOL_OPTIONS_KEY_tls_HRSS_exchange_enabled
, 
2303         .setter_pointer 
= sec_protocol_options_set_tls_HRSS_exchange_enabled
, 
2306         .key 
= SEC_PROTOCOL_OPTIONS_KEY_eddsa_enabled
, 
2307         .setter_pointer 
= sec_protocol_options_set_eddsa_enabled
, 
2310         .key 
= SEC_PROTOCOL_OPTIONS_KEY_tls_delegated_credentials_enabled
, 
2311         .setter_pointer 
= sec_protocol_options_set_tls_delegated_credentials_enabled
, 
2314         .key 
= SEC_PROTOCOL_OPTIONS_KEY_tls_grease_enabled
, 
2315         .setter_pointer 
= sec_protocol_options_set_tls_grease_enabled
, 
2318 static const size_t _options_bool_key_setters_len 
= sizeof(_options_bool_key_setters
) / sizeof(_options_bool_key_setters
[0]); 
2320 static struct _options_uint64_key_setter 
{ 
2322     void (*setter_pointer
)(sec_protocol_options_t
, uint64_t); 
2323 } _options_uint64_key_setters
[] = { 
2324 #pragma clang diagnostic push 
2325 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 
2327         .key 
= SEC_PROTOCOL_OPTIONS_KEY_min_version
, 
2328         .setter_pointer 
= (void (*)(sec_protocol_options_t
, uint64_t))sec_protocol_options_set_tls_min_version
 
2331         .key 
= SEC_PROTOCOL_OPTIONS_KEY_max_version
, 
2332         .setter_pointer 
= (void (*)(sec_protocol_options_t
, uint64_t))sec_protocol_options_set_tls_max_version
 
2334 #pragma clang diagnostic pop 
2336         .key 
= SEC_PROTOCOL_OPTIONS_KEY_minimum_rsa_key_size
, 
2337         .setter_pointer 
= (void (*)(sec_protocol_options_t
, uint64_t))sec_protocol_options_set_minimum_rsa_key_size
, 
2340         .key 
= SEC_PROTOCOL_OPTIONS_KEY_minimum_ecdsa_key_size
, 
2341         .setter_pointer 
= (void (*)(sec_protocol_options_t
, uint64_t))sec_protocol_options_set_minimum_ecdsa_key_size
, 
2344         .key 
= SEC_PROTOCOL_OPTIONS_KEY_minimum_signature_algorithm
, 
2345         .setter_pointer 
= (void (*)(sec_protocol_options_t
, uint64_t))sec_protocol_options_set_minimum_signature_algorithm
, 
2348         .key 
= SEC_PROTOCOL_OPTIONS_KEY_tls_ticket_request_count
, 
2349         .setter_pointer 
= (void (*)(sec_protocol_options_t
, uint64_t))sec_protocol_options_set_tls_ticket_request_count
, 
2352 static const size_t _options_uint64_key_setters_len 
= sizeof(_options_uint64_key_setters
) / sizeof(_options_uint64_key_setters
[0]); 
2355 _apply_config_options(sec_protocol_options_t options
, xpc_object_t config
) 
2357     return sec_protocol_options_access_handle(options
, ^bool(void *options_handle
) { 
2358         sec_protocol_options_content_t options_content 
= (sec_protocol_options_content_t
)options_handle
; 
2359         SEC_PROTOCOL_METADATA_VALIDATE(options_content
, false); 
2360         return xpc_dictionary_apply(config
, ^bool(const char * _Nonnull key
, xpc_object_t  _Nonnull value
) { 
2362             size_t key_len 
= strnlen(key
, MAX_SEC_PROTOCOL_OPTIONS_KEY_LEN
); 
2363             for (size_t i 
= 0; i 
< _options_bool_key_setters_len
; i
++) { 
2364                 const char *setter_key 
= _options_bool_key_setters
[i
].key
; 
2365                 size_t setter_key_len 
= strnlen(setter_key
, MAX_SEC_PROTOCOL_OPTIONS_KEY_LEN
); 
2366                 if (strncmp(setter_key
, key
, MAX(key_len
, setter_key_len
)) == 0) { 
2367                     _options_bool_key_setters
[i
].setter_pointer(options
, xpc_dictionary_get_bool(config
, key
)); 
2371             for (size_t i 
= 0; i 
< _options_uint64_key_setters_len
; i
++) { 
2372                 const char *setter_key 
= _options_uint64_key_setters
[i
].key
; 
2373                 size_t setter_key_len 
= strnlen(setter_key
, MAX_SEC_PROTOCOL_OPTIONS_KEY_LEN
); 
2374                 if (strncmp(setter_key
, key
, MAX(key_len
, setter_key_len
)) == 0) { 
2375                     _options_uint64_key_setters
[i
].setter_pointer(options
, xpc_dictionary_get_uint64(config
, key
)); 
2379             // Now check for ciphersuite options, as these are not expressed via serialized configs 
2380             if (strncmp(key
, SEC_PROTOCOL_OPTIONS_KEY_ciphersuites
, key_len
) == 0) { 
2381                 if (xpc_get_type(value
) == XPC_TYPE_ARRAY
) { 
2382                     xpc_array_apply(value
, ^bool(size_t index
, xpc_object_t  _Nonnull ciphersuite_value
) { 
2383                         SSLCipherSuite ciphersuite 
= (SSLCipherSuite
)xpc_array_get_uint64(value
, index
); 
2384                         sec_protocol_options_append_tls_ciphersuite(options
, ciphersuite
); 
2396 _serialize_metadata(xpc_object_t dictionary
, sec_protocol_metadata_content_t metadata_content
) 
2398 #define xpc_dictionary_set_string_default(d, key, value, default) \ 
2400         if (value != NULL) { \ 
2401             xpc_dictionary_set_string(d, key, value); \ 
2403             xpc_dictionary_set_string(d, key, default); \ 
2407     xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_CIPHERSUITE
, metadata_content
->negotiated_ciphersuite
); 
2408     xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_PROTOCOL_VERSION
, metadata_content
->negotiated_protocol_version
); 
2409     xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_TICKET_LIFETIME
, metadata_content
->ticket_lifetime
); 
2411     xpc_dictionary_set_string_default(dictionary
, SEC_PROTOCOL_METADATA_KEY_PEER_PUBLIC_KEY_TYPE
, 
2412                                       metadata_content
->peer_public_key_type
, SEC_PROTOCOL_METADATA_KEY_DEFAULT_EMPTY_STRING
); 
2413     xpc_dictionary_set_string_default(dictionary
, SEC_PROTOCOL_METADATA_KEY_NEGOTIATED_CURVE
, 
2414                                       metadata_content
->negotiated_curve
, SEC_PROTOCOL_METADATA_KEY_DEFAULT_EMPTY_STRING
); 
2415     xpc_dictionary_set_string_default(dictionary
, SEC_PROTOCOL_METADATA_KEY_PEER_CERTIFICATE_REQUEST_TYPE
, 
2416                                       metadata_content
->certificate_request_type
, SEC_PROTOCOL_METADATA_KEY_DEFAULT_EMPTY_STRING
); 
2417     xpc_dictionary_set_string_default(dictionary
, SEC_PROTOCOL_METADATA_KEY_NEGOTIATED_PROTOCOL
, 
2418                                       metadata_content
->negotiated_protocol
, SEC_PROTOCOL_METADATA_KEY_DEFAULT_EMPTY_STRING
); 
2420     xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_FALSE_START_USED
, metadata_content
->false_start_used
); 
2421     xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_SESSION_RESUMED
, metadata_content
->session_resumed
); 
2422     xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_TICKET_OFFERED
, metadata_content
->ticket_offered
); 
2423     xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_TICKET_RECEIVED
, metadata_content
->ticket_received
); 
2424     xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_SESSION_RENEWED
, metadata_content
->session_renewed
); 
2425     xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_RESUMPTION_ATTEMPTED
, metadata_content
->resumption_attempted
); 
2426     xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_ALPN_USED
, metadata_content
->alpn_used
); 
2427     xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_NPN_USED
, metadata_content
->npn_used
); 
2428     xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_OCSP_ENABLED
, metadata_content
->ocsp_enabled
); 
2429     xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_OCSP_RECEIVED
, metadata_content
->ocsp_response 
!= NULL
); 
2430     xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_SCT_ENABLED
, metadata_content
->sct_enabled
); 
2431     xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_SCT_RECEIVED
, metadata_content
->signed_certificate_timestamps 
!= NULL
); 
2433 #undef xpc_dictionary_set_string_default 
2439 _serialize_success_with_options(xpc_object_t dictionary
, sec_protocol_metadata_content_t metadata_content
, sec_protocol_options_content_t options_content
) 
2441     if (!_serialize_options(dictionary
, options_content
)) { 
2444     if (!_serialize_metadata(dictionary
, metadata_content
)) { 
2451 _serialize_failure_with_options(xpc_object_t dictionary
, sec_protocol_metadata_content_t metadata_content
, sec_protocol_options_content_t options_content
) 
2453     xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_FAILURE_ALERT_TYPE
, metadata_content
->alert_type
); 
2454     xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_FAILURE_ALERT_CODE
, metadata_content
->alert_code
); 
2455     xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_FAILURE_HANDSHAKE_STATE
, metadata_content
->handshake_state
); 
2456     xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_FAILURE_STACK_ERROR
, metadata_content
->stack_error
); 
2462 sec_protocol_metadata_serialize_with_options(sec_protocol_metadata_t metadata
, sec_protocol_options_t options
) 
2464     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
); 
2465     SEC_PROTOCOL_METADATA_VALIDATE(options
, NULL
); 
2467     __block xpc_object_t dictionary 
= xpc_dictionary_create(NULL
, NULL
, 0); 
2468     if (dictionary 
== NULL
) { 
2472     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) { 
2473         sec_protocol_metadata_content_t metadata_content 
= (sec_protocol_metadata_content_t
)metadata_handle
; 
2474         SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false); 
2476         return sec_protocol_options_access_handle(options
, ^bool(void *options_handle
) { 
2477             sec_protocol_options_content_t options_content 
= (sec_protocol_options_content_t
)options_handle
; 
2478             SEC_PROTOCOL_METADATA_VALIDATE(options_content
, false); 
2480             if (metadata_content
->failure
) { 
2481                 return _serialize_failure_with_options(dictionary
, metadata_content
, options_content
); 
2483                 return _serialize_success_with_options(dictionary
, metadata_content
, options_content
); 
2492 sec_protocol_metadata_copy_quic_transport_parameters(sec_protocol_metadata_t metadata
) 
2494     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
); 
2496     __block dispatch_data_t copied_parameters 
= NULL
; 
2497     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) { 
2498         sec_protocol_metadata_content_t metadata_content 
= (sec_protocol_metadata_content_t
)metadata_handle
; 
2499         SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false); 
2500         if (metadata_content
->quic_transport_parameters
) { 
2501             copied_parameters 
= metadata_content
->quic_transport_parameters
; 
2502             dispatch_retain(copied_parameters
); 
2507     return copied_parameters
; 
2511 sec_protocol_metadata_get_tls_certificate_compression_used(sec_protocol_metadata_t metadata
) 
2513     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false); 
2515     __block 
bool certificate_compression_used 
= false; 
2516     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) { 
2517         sec_protocol_metadata_content_t metadata_content 
= (sec_protocol_metadata_content_t
)metadata_handle
; 
2518         SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false); 
2519         certificate_compression_used 
= metadata_content
->certificate_compression_used
; 
2523     return certificate_compression_used
; 
2527 sec_protocol_metadata_get_tls_certificate_compression_algorithm(sec_protocol_metadata_t metadata
) 
2529     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0); 
2531     __block 
uint16_t certificate_compression_algorithm 
= 0; 
2532     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) { 
2533         sec_protocol_metadata_content_t metadata_content 
= (sec_protocol_metadata_content_t
)metadata_handle
; 
2534         SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false); 
2535         certificate_compression_algorithm 
= metadata_content
->certificate_compression_algorithm
; 
2539     return certificate_compression_algorithm
; 
2543 sec_protocol_metadata_get_handshake_rtt(sec_protocol_metadata_t metadata
) 
2545     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0); 
2547     __block 
uint64_t rtt 
= 0; 
2548     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) { 
2549         sec_protocol_metadata_content_t metadata_content 
= (sec_protocol_metadata_content_t
)metadata_handle
; 
2550         SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false); 
2551         rtt 
= metadata_content
->handshake_rtt
; 
2559 sec_protocol_metadata_copy_sec_trust(sec_protocol_metadata_t metadata
) 
2561     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, nil
); 
2563     __block sec_trust_t trust 
= nil
; 
2564     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) { 
2565         sec_protocol_metadata_content_t metadata_content 
= (sec_protocol_metadata_content_t
)metadata_handle
; 
2566         SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false); 
2567         if (metadata_content
->trust_ref 
!= nil
) { 
2568             trust 
= metadata_content
->trust_ref
; 
2578 sec_protocol_metadata_copy_sec_identity(sec_protocol_metadata_t metadata
) 
2580     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, nil
); 
2582     __block sec_identity_t identity 
= nil
; 
2583     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) { 
2584         sec_protocol_metadata_content_t metadata_content 
= (sec_protocol_metadata_content_t
)metadata_handle
; 
2585         SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false); 
2586         if (metadata_content
->identity 
!= nil
) { 
2587             identity 
= metadata_content
->identity
; 
2588             sec_retain(identity
); 
2597 sec_protocol_metadata_access_sent_certificates(sec_protocol_metadata_t metadata
, 
2598                                                void (^handler
)(sec_certificate_t certificate
)) 
2600     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false); 
2601     SEC_PROTOCOL_METADATA_VALIDATE(handler
, false); 
2603     return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
2604         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
2605         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
2607         if (content
->identity 
!= nil 
&& sec_identity_has_certificates(content
->identity
)) { 
2608             return sec_identity_access_certificates(content
->identity
, handler
); 
2611         if (content
->sent_certificate_chain 
!= NULL
) { 
2612             return sec_array_apply(content
->sent_certificate_chain
, ^bool(__unused 
size_t index
, sec_object_t object
) { 
2613                 handler((sec_certificate_t
)object
); 
2623 sec_protocol_metadata_get_tls_negotiated_group(sec_protocol_metadata_t metadata
) 
2625     SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
); 
2627     __block 
const char *negotiated_curve 
= NULL
; 
2628     (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) { 
2629         sec_protocol_metadata_content_t content 
= (sec_protocol_metadata_content_t
)handle
; 
2630         SEC_PROTOCOL_METADATA_VALIDATE(content
, false); 
2631         negotiated_curve 
= content
->negotiated_curve
; 
2635     return negotiated_curve
; 
2639 sec_retain(void *obj
) 
2642         return os_retain(obj
); 
2649 sec_release(void *obj
) 
2657 sec_protocol_options_create_config(sec_protocol_options_t options
) 
2659     SEC_PROTOCOL_METADATA_VALIDATE(options
, NULL
); 
2661     __block xpc_object_t dictionary 
= xpc_dictionary_create(NULL
, NULL
, 0); 
2662     if (dictionary 
== NULL
) { 
2666     bool serialized 
= sec_protocol_options_access_handle(options
, ^bool(void *options_handle
) { 
2667         sec_protocol_options_content_t options_content 
= (sec_protocol_options_content_t
)options_handle
; 
2668         SEC_PROTOCOL_METADATA_VALIDATE(options_content
, false); 
2670         return _serialize_options(dictionary
, options_content
); 
2674         return dictionary
; // retained reference 
2676         xpc_release(dictionary
); 
2682 sec_protocol_options_matches_config(sec_protocol_options_t options
, xpc_object_t config
) 
2684     SEC_PROTOCOL_METADATA_VALIDATE(options
, false); 
2685     SEC_PROTOCOL_METADATA_VALIDATE(config
, false); 
2687     if (xpc_get_type(config
) != XPC_TYPE_DICTIONARY
) { 
2691     xpc_object_t options_config 
= sec_protocol_options_create_config(options
); 
2692     if (options_config 
== NULL
) { 
2696     bool match 
= _options_config_matches_partial_config(options_config
, config
); 
2697     xpc_release(options_config
); 
2703 sec_protocol_options_apply_config(sec_protocol_options_t options
, xpc_object_t config
) 
2705     SEC_PROTOCOL_METADATA_VALIDATE(options
, false); 
2706     SEC_PROTOCOL_METADATA_VALIDATE(config
, false); 
2708     if (xpc_get_type(config
) != XPC_TYPE_DICTIONARY
) { 
2712     return _apply_config_options(options
, config
);