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
);