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_peer_authentication_optional "peer_authentication_optional"
45 #define SEC_PROTOCOL_OPTIONS_KEY_certificate_compression_enabled "certificate_compression_enabled"
46 #define SEC_PROTOCOL_OPTIONS_KEY_eddsa_enabled "eddsa_enabled"
47 #define SEC_PROTOCOL_OPTIONS_KEY_tls_delegated_credentials_enabled "tls_delegated_credentials_enabled"
48 #define SEC_PROTOCOL_OPTIONS_KEY_tls_grease_enabled "tls_grease_enabled"
49 #define SEC_PROTOCOL_OPTIONS_KEY_tls_ticket_request_count "tls_ticket_request_count"
50 #define SEC_PROTOCOL_OPTIONS_KEY_ciphersuites "ciphersuites"
53 #define SEC_PROTOCOL_METADATA_KEY_PROCESS_IDENTIFIER "process"
54 #define SEC_PROTOCOL_METADATA_KEY_CIPHERSUITE "cipher_name"
55 #define SEC_PROTOCOL_METADATA_KEY_FALLBACK_ENABLED "fallback"
56 #define SEC_PROTOCOL_METADATA_KEY_DH_GROUP_SIZE "dhe_size"
57 #define SEC_PROTOCOL_METADATA_KEY_NEGOTIATED_CURVE "neg_curve"
58 #define SEC_PROTOCOL_METADATA_KEY_PEER_CERTIFICATE_REQUEST_TYPE "cert_request_type"
59 #define SEC_PROTOCOL_METADATA_KEY_LOCAL_PRIVATE_KEY_TYPE "private_key_type"
60 #define SEC_PROTOCOL_METADATA_KEY_PEER_PUBLIC_KEY_TYPE "peer_public_key_type"
61 #define SEC_PROTOCOL_METADATA_KEY_NEGOTIATED_PROTOCOL "negotiated_protocol"
62 #define SEC_PROTOCOL_METADATA_KEY_ALPN_USED "alpn_used"
63 #define SEC_PROTOCOL_METADATA_KEY_NPN_USED "npn_used"
64 #define SEC_PROTOCOL_METADATA_KEY_PROTOCOL_VERSION "version"
65 #define SEC_PROTOCOL_METADATA_KEY_FALSE_START_ENABLED "false_start_enabled"
66 #define SEC_PROTOCOL_METADATA_KEY_FALSE_START_USED "false_start_used"
67 #define SEC_PROTOCOL_METADATA_KEY_TICKET_OFFERED "ticket_offered"
68 #define SEC_PROTOCOL_METADATA_KEY_TICKET_RECEIVED "ticket_received"
69 #define SEC_PROTOCOL_METADATA_KEY_SESSION_RESUMED "session_resumed"
70 #define SEC_PROTOCOL_METADATA_KEY_SESSION_RENEWED "session_renewed"
71 #define SEC_PROTOCOL_METADATA_KEY_RESUMPTION_ATTEMPTED "resumption_attempted"
72 #define SEC_PROTOCOL_METADATA_KEY_TICKET_LIFETIME "ticket_lifetime"
73 #define SEC_PROTOCOL_METADATA_KEY_MAX_EARLY_DATA_SUPPORTED "max_early_data_supported"
74 #define SEC_PROTOCOL_METADATA_KEY_OCSP_ENABLED "ocsp_enabled"
75 #define SEC_PROTOCOL_METADATA_KEY_OCSP_RECEIVED "ocsp_received"
76 #define SEC_PROTOCOL_METADATA_KEY_SCT_ENABLED "sct_enabled"
77 #define SEC_PROTOCOL_METADATA_KEY_SCT_RECEIVED "sct_received"
78 #define SEC_PROTOCOL_METADATA_KEY_RSA_SIGNATURE_REQUESTED "client_rsa_requested"
79 #define SEC_PROTOCOL_METADATA_KEY_ECDSA_SIGNATURE_REQUESTED "client_ecdsa_requested"
80 #define SEC_PROTOCOL_METADATA_KEY_FAILURE_ALERT_TYPE "alert_type"
81 #define SEC_PROTOCOL_METADATA_KEY_FAILURE_ALERT_CODE "alert_code"
82 #define SEC_PROTOCOL_METADATA_KEY_FAILURE_HANDSHAKE_STATE "handshake_state"
83 #define SEC_PROTOCOL_METADATA_KEY_FAILURE_STACK_ERROR "stack_error"
84 #define SEC_PROTOCOL_METADATA_KEY_DEFAULT_EMPTY_STRING "none"
86 #define CFReleaseSafe(value) \
87 if (value != NULL) { \
92 sec_protocol_options_access_handle(sec_protocol_options_t options
,
93 sec_access_block_t access_block
)
95 static void *libnetworkImage
= NULL
;
96 static dispatch_once_t onceToken
;
97 static bool (*_nw_protocol_options_access_handle
)(void *, sec_access_block_t
) = NULL
;
99 dispatch_once(&onceToken
, ^{
100 libnetworkImage
= dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY
| RTLD_LOCAL
);
101 if (NULL
!= libnetworkImage
) {
102 _nw_protocol_options_access_handle
= (__typeof(_nw_protocol_options_access_handle
))dlsym(libnetworkImage
,
103 "nw_protocol_options_access_handle");
104 if (NULL
== _nw_protocol_options_access_handle
) {
105 os_log_error(OS_LOG_DEFAULT
, "dlsym libnetwork nw_protocol_options_access_handle");
108 os_log_error(OS_LOG_DEFAULT
, "dlopen libnetwork");
112 if (_nw_protocol_options_access_handle
== NULL
) {
116 return _nw_protocol_options_access_handle(options
, access_block
);
120 sec_protocol_metadata_access_handle(sec_protocol_metadata_t options
,
121 sec_access_block_t access_block
)
123 static void *libnetworkImage
= NULL
;
124 static dispatch_once_t onceToken
;
125 static bool (*_nw_protocol_metadata_access_handle
)(void *, sec_access_block_t
) = NULL
;
127 dispatch_once(&onceToken
, ^{
128 libnetworkImage
= dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY
| RTLD_LOCAL
);
129 if (NULL
!= libnetworkImage
) {
130 _nw_protocol_metadata_access_handle
= (__typeof(_nw_protocol_metadata_access_handle
))dlsym(libnetworkImage
,
131 "nw_protocol_metadata_access_handle");
132 if (NULL
== _nw_protocol_metadata_access_handle
) {
133 os_log_error(OS_LOG_DEFAULT
, "dlsym libnetwork _nw_protocol_metadata_access_handle");
136 os_log_error(OS_LOG_DEFAULT
, "dlopen libnetwork");
140 if (_nw_protocol_metadata_access_handle
== NULL
) {
144 return _nw_protocol_metadata_access_handle(options
, access_block
);
147 #define SEC_PROTOCOL_OPTIONS_VALIDATE(o,r) \
152 #define SEC_PROTOCOL_METADATA_VALIDATE(m,r) \
153 if (((void *)m == NULL) || ((size_t)m == 0)) { \
158 sec_protocol_options_contents_are_equal(sec_protocol_options_content_t contentA
, sec_protocol_options_content_t contentB
)
160 if (contentA
== contentB
) {
163 if (contentA
== NULL
|| contentB
== NULL
) {
167 sec_protocol_options_content_t optionsA
= (sec_protocol_options_content_t
)contentA
;
168 sec_protocol_options_content_t optionsB
= (sec_protocol_options_content_t
)contentB
;
170 // Check boolean and primitive field types first
171 #define CHECK_FIELD(field) \
172 if (optionsA->field != optionsB->field) { \
176 CHECK_FIELD(min_version
);
177 CHECK_FIELD(max_version
);
178 CHECK_FIELD(minimum_rsa_key_size
);
179 CHECK_FIELD(minimum_ecdsa_key_size
);
180 CHECK_FIELD(minimum_signature_algorithm
);
181 CHECK_FIELD(tls_ticket_request_count
);
182 CHECK_FIELD(ats_required
);
183 CHECK_FIELD(ats_minimum_tls_version_allowed
);
184 CHECK_FIELD(ats_non_pfs_ciphersuite_allowed
);
185 CHECK_FIELD(trusted_peer_certificate
);
186 CHECK_FIELD(disable_sni
);
187 CHECK_FIELD(enable_fallback_attempt
);
188 CHECK_FIELD(enable_false_start
);
189 CHECK_FIELD(enable_tickets
);
190 CHECK_FIELD(enable_sct
);
191 CHECK_FIELD(enable_ocsp
);
192 CHECK_FIELD(enforce_ev
);
193 CHECK_FIELD(enable_resumption
);
194 CHECK_FIELD(enable_renegotiation
);
195 CHECK_FIELD(enable_early_data
);
196 CHECK_FIELD(peer_authentication_required
);
197 CHECK_FIELD(peer_authentication_optional
);
198 CHECK_FIELD(certificate_compression_enabled
);
199 CHECK_FIELD(eddsa_enabled
);
200 CHECK_FIELD(tls_delegated_credentials_enabled
);
201 CHECK_FIELD(tls_grease_enabled
);
202 CHECK_FIELD(allow_unknown_alpn_protos
);
206 // Check callback block and queue pairs next
207 #define CHECK_BLOCK_QUEUE(block, queue) \
208 if (optionsA->block && optionsB->block) { \
209 if (optionsA->block != optionsB->block) { \
212 if (optionsA->queue != optionsB->queue) { \
215 } else if (optionsA->block || optionsB->block) { \
219 CHECK_BLOCK_QUEUE(key_update_block
, key_update_queue
);
220 CHECK_BLOCK_QUEUE(psk_selection_block
, psk_selection_queue
);
221 CHECK_BLOCK_QUEUE(challenge_block
, challenge_queue
);
222 CHECK_BLOCK_QUEUE(verify_block
, verify_queue
);
223 CHECK_BLOCK_QUEUE(tls_secret_update_block
, tls_secret_update_queue
);
224 CHECK_BLOCK_QUEUE(tls_encryption_level_update_block
, tls_encryption_level_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_add_transport_specific_application_protocol(sec_protocol_options_t options
, const char *application_protocol
, sec_protocol_transport_t specific_transport
)
508 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
509 SEC_PROTOCOL_OPTIONS_VALIDATE(application_protocol
,);
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 if (content
->application_protocols
== NULL
) {
516 content
->application_protocols
= xpc_array_create(NULL
, 0);
518 xpc_object_t tuple
= xpc_array_create(NULL
, 0);
520 xpc_array_set_string(tuple
, XPC_ARRAY_APPEND
, application_protocol
);
521 xpc_array_set_uint64(tuple
, XPC_ARRAY_APPEND
, (uint64_t)specific_transport
);
523 xpc_array_append_value(content
->application_protocols
, tuple
);
531 sec_protocol_options_copy_transport_specific_application_protocol(sec_protocol_options_t options
, sec_protocol_transport_t specific_transport
)
533 SEC_PROTOCOL_OPTIONS_VALIDATE(options
, NULL
);
535 xpc_object_t filtered_application_protocols
= xpc_array_create(NULL
, 0);
537 bool success
= 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 xpc_object_t application_protocols
= content
->application_protocols
;
542 if (application_protocols
== NULL
) {
546 size_t application_protocol_count
= xpc_array_get_count(application_protocols
);
547 for (size_t i
= 0; i
< application_protocol_count
; i
++) {
548 xpc_object_t application_protocol
= xpc_array_get_value(application_protocols
, i
);
550 if (xpc_get_type(application_protocol
) == XPC_TYPE_STRING
) {
551 xpc_array_set_string(filtered_application_protocols
, XPC_ARRAY_APPEND
, xpc_string_get_string_ptr(application_protocol
));
555 if (xpc_get_type(application_protocol
) == XPC_TYPE_ARRAY
) {
556 uint64_t application_protocol_transport
= xpc_array_get_uint64(application_protocol
, 1);
557 if (application_protocol_transport
!= (uint64_t)specific_transport
&& specific_transport
!= sec_protocol_transport_any
) {
561 xpc_array_set_string(filtered_application_protocols
, XPC_ARRAY_APPEND
, xpc_array_get_string(application_protocol
, 0));
566 return xpc_array_get_count(filtered_application_protocols
) != 0;
570 xpc_release(filtered_application_protocols
);
571 filtered_application_protocols
= NULL
;
574 return filtered_application_protocols
;
578 sec_protocol_options_set_tls_server_name(sec_protocol_options_t options
, const char *server_name
)
580 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
581 SEC_PROTOCOL_OPTIONS_VALIDATE(server_name
,);
583 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
584 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
585 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
587 free(content
->server_name
);
588 content
->server_name
= strdup(server_name
);
594 sec_protocol_options_set_tls_diffie_hellman_parameters(sec_protocol_options_t options
, dispatch_data_t params
)
596 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
597 SEC_PROTOCOL_OPTIONS_VALIDATE(params
,);
599 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
600 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
601 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
603 if (content
->dh_params
) {
604 dispatch_release(content
->dh_params
);
606 content
->dh_params
= params
;
607 dispatch_retain(params
);
613 sec_protocol_options_add_pre_shared_key(sec_protocol_options_t options
, dispatch_data_t psk
, dispatch_data_t psk_identity
)
615 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
616 SEC_PROTOCOL_OPTIONS_VALIDATE(psk
,);
617 SEC_PROTOCOL_OPTIONS_VALIDATE(psk_identity
,);
619 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
620 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
621 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
623 if (content
->pre_shared_keys
== NULL
) {
624 content
->pre_shared_keys
= xpc_array_create(NULL
, 0);
627 xpc_object_t psk_data
= xpc_data_create_with_dispatch_data(psk
);
628 xpc_object_t psk_identity_data
= xpc_data_create_with_dispatch_data(psk_identity
);
630 xpc_object_t tuple
= xpc_array_create(NULL
, 0);
631 xpc_array_set_value(tuple
, XPC_ARRAY_APPEND
, psk_data
);
632 xpc_array_set_value(tuple
, XPC_ARRAY_APPEND
, psk_identity_data
);
633 xpc_release(psk_data
);
634 xpc_release(psk_identity_data
);
636 xpc_array_set_value(content
->pre_shared_keys
, XPC_ARRAY_APPEND
, tuple
);
643 sec_protocol_options_set_tls_pre_shared_key_identity_hint(sec_protocol_options_t options
, dispatch_data_t psk_identity_hint
)
645 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
646 SEC_PROTOCOL_OPTIONS_VALIDATE(psk_identity_hint
,);
648 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
649 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
650 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
652 if (content
->psk_identity_hint
!= NULL
) {
653 dispatch_release(content
->psk_identity_hint
);
656 content
->psk_identity_hint
= psk_identity_hint
;
657 dispatch_retain(psk_identity_hint
);
663 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
)
665 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
666 SEC_PROTOCOL_OPTIONS_VALIDATE(psk_selection_block
,);
667 SEC_PROTOCOL_OPTIONS_VALIDATE(psk_selection_queue
,);
669 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
670 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
671 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
673 if (content
->psk_selection_block
!= NULL
) {
674 Block_release(content
->psk_selection_block
);
676 if (content
->psk_selection_queue
!= NULL
) {
677 dispatch_release(content
->psk_selection_queue
);
680 content
->psk_selection_block
= Block_copy(psk_selection_block
);
681 content
->psk_selection_queue
= psk_selection_queue
;
682 dispatch_retain(content
->psk_selection_queue
);
688 sec_protocol_options_set_tls_is_fallback_attempt(sec_protocol_options_t options
, bool fallback_attempt
)
690 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
692 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
693 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
694 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
696 content
->enable_fallback_attempt
= fallback_attempt
;
697 content
->enable_fallback_attempt_override
= true;
703 sec_protocol_options_set_tls_tickets_enabled(sec_protocol_options_t options
, bool tickets_enabled
)
705 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
707 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
708 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
709 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
711 content
->enable_tickets
= tickets_enabled
;
712 content
->enable_tickets_override
= true;
718 sec_protocol_options_set_tls_resumption_enabled(sec_protocol_options_t options
, bool resumption_enabled
)
720 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
722 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
723 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
724 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
726 content
->enable_resumption
= resumption_enabled
;
727 content
->enable_resumption_override
= true;
733 sec_protocol_options_set_tls_false_start_enabled(sec_protocol_options_t options
, bool false_start_enabled
)
735 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
737 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
738 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
739 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
741 content
->enable_false_start
= false_start_enabled
;
742 content
->enable_false_start_override
= true;
748 sec_protocol_options_set_tls_early_data_enabled(sec_protocol_options_t options
, bool early_data_enabled
)
750 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
752 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
753 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
754 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
756 content
->enable_early_data
= early_data_enabled
;
757 content
->enable_early_data_override
= true;
763 sec_protocol_options_set_tls_sni_disabled(sec_protocol_options_t options
, bool sni_disabled
)
765 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
767 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
768 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
769 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
771 content
->disable_sni
= sni_disabled
;
772 content
->disable_sni_override
= true;
778 sec_protocol_options_set_enforce_ev(sec_protocol_options_t options
, bool enforce_ev
)
780 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
782 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
783 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
784 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
786 content
->enforce_ev
= enforce_ev
;
787 content
->enforce_ev_override
= true;
793 sec_protocol_options_set_tls_ocsp_enabled(sec_protocol_options_t options
, bool ocsp_enabled
)
795 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
797 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
798 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
799 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
801 content
->enable_ocsp
= ocsp_enabled
;
802 content
->enable_ocsp_override
= true;
808 sec_protocol_options_set_tls_sct_enabled(sec_protocol_options_t options
, bool sct_enabled
)
810 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
812 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
813 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
814 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
816 content
->enable_sct
= sct_enabled
;
817 content
->enable_sct_override
= true;
823 sec_protocol_options_set_tls_renegotiation_enabled(sec_protocol_options_t options
, bool renegotiation_enabled
)
825 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
827 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
828 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
829 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
831 content
->enable_renegotiation
= renegotiation_enabled
;
832 content
->enable_renegotiation_override
= true;
838 sec_protocol_options_set_peer_authentication_required(sec_protocol_options_t options
, bool peer_authentication_required
)
840 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
842 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
843 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
844 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
846 content
->peer_authentication_required
= peer_authentication_required
;
847 content
->peer_authentication_override
= true;
853 sec_protocol_options_set_peer_authentication_optional(sec_protocol_options_t options
, bool peer_authentication_optional
) {
854 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
856 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
857 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
858 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
860 content
->peer_authentication_optional
= peer_authentication_optional
;
861 content
->peer_authentication_override
= true;
867 sec_protocol_options_set_key_update_block(sec_protocol_options_t options
, sec_protocol_key_update_t update_block
, dispatch_queue_t update_queue
)
869 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
870 SEC_PROTOCOL_OPTIONS_VALIDATE(update_queue
,);
872 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
873 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
874 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
876 if (content
->key_update_block
!= NULL
) {
877 Block_release(content
->key_update_block
);
879 if (content
->key_update_queue
!= NULL
) {
880 dispatch_release(content
->key_update_queue
);
883 content
->key_update_block
= Block_copy(update_block
);
884 content
->key_update_queue
= Block_copy(update_queue
);
885 dispatch_retain(content
->key_update_queue
);
891 sec_protocol_options_set_challenge_block(sec_protocol_options_t options
, sec_protocol_challenge_t challenge_block
, dispatch_queue_t challenge_queue
)
893 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
894 SEC_PROTOCOL_OPTIONS_VALIDATE(challenge_queue
,);
896 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
897 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
898 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
900 if (content
->challenge_block
!= NULL
) {
901 Block_release(content
->challenge_block
);
903 if (content
->challenge_queue
!= NULL
) {
904 dispatch_release(content
->challenge_queue
);
907 content
->challenge_block
= Block_copy(challenge_block
);
908 content
->challenge_queue
= challenge_queue
;
909 dispatch_retain(content
->challenge_queue
);
915 sec_protocol_options_set_verify_block(sec_protocol_options_t options
, sec_protocol_verify_t verify_block
, dispatch_queue_t verify_queue
)
917 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
918 SEC_PROTOCOL_OPTIONS_VALIDATE(verify_queue
,);
920 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
921 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
922 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
924 if (content
->verify_block
!= NULL
) {
925 Block_release(content
->verify_block
);
927 if (content
->verify_queue
!= NULL
) {
928 dispatch_release(content
->verify_queue
);
931 content
->verify_block
= Block_copy(verify_block
);
932 content
->verify_queue
= verify_queue
;
933 dispatch_retain(content
->verify_queue
);
939 sec_protocol_options_set_session_update_block(sec_protocol_options_t options
, sec_protocol_session_update_t update_block
, dispatch_queue_t update_queue
)
941 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
942 SEC_PROTOCOL_OPTIONS_VALIDATE(update_block
,);
943 SEC_PROTOCOL_OPTIONS_VALIDATE(update_queue
,);
945 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
946 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
947 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
949 if (content
->session_update_block
!= NULL
) {
950 Block_release(content
->session_update_block
);
952 if (content
->session_update_queue
!= NULL
) {
953 dispatch_release(content
->session_update_queue
);
956 content
->session_update_block
= Block_copy(update_block
);
957 content
->session_update_queue
= update_queue
;
958 dispatch_retain(content
->session_update_queue
);
964 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
)
966 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
967 SEC_PROTOCOL_OPTIONS_VALIDATE(update_block
,);
968 SEC_PROTOCOL_OPTIONS_VALIDATE(update_queue
,);
970 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
971 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
972 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
974 if (content
->tls_secret_update_block
!= NULL
) {
975 Block_release(content
->tls_secret_update_block
);
977 if (content
->tls_secret_update_queue
!= NULL
) {
978 dispatch_release(content
->tls_secret_update_queue
);
981 content
->tls_secret_update_block
= Block_copy(update_block
);
982 content
->tls_secret_update_queue
= update_queue
;
983 dispatch_retain(content
->tls_secret_update_queue
);
989 sec_protocol_options_set_tls_encryption_level_update_block(sec_protocol_options_t options
, sec_protocol_tls_encryption_level_update_t update_block
, dispatch_queue_t update_queue
)
991 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
992 SEC_PROTOCOL_OPTIONS_VALIDATE(update_block
,);
993 SEC_PROTOCOL_OPTIONS_VALIDATE(update_queue
,);
995 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
996 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
997 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
999 if (content
->tls_encryption_level_update_block
!= NULL
) {
1000 Block_release(content
->tls_encryption_level_update_block
);
1002 if (content
->tls_encryption_level_update_queue
!= NULL
) {
1003 dispatch_release(content
->tls_encryption_level_update_queue
);
1006 content
->tls_encryption_level_update_block
= Block_copy(update_block
);
1007 content
->tls_encryption_level_update_queue
= update_queue
;
1008 dispatch_retain(content
->tls_encryption_level_update_queue
);
1014 sec_protocol_options_set_session_state(sec_protocol_options_t options
, dispatch_data_t session_state
)
1016 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1017 SEC_PROTOCOL_OPTIONS_VALIDATE(session_state
,);
1019 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1020 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1021 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1023 if (content
->session_state
!= NULL
) {
1024 dispatch_release(content
->session_state
);
1027 content
->session_state
= session_state
;
1028 dispatch_retain(session_state
);
1034 sec_protocol_options_set_quic_transport_parameters(sec_protocol_options_t options
, dispatch_data_t transport_parameters
)
1036 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1037 SEC_PROTOCOL_OPTIONS_VALIDATE(transport_parameters
,);
1039 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1040 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1041 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1043 if (content
->quic_transport_parameters
!= NULL
) {
1044 dispatch_release(content
->quic_transport_parameters
);
1047 content
->quic_transport_parameters
= transport_parameters
;
1048 dispatch_retain(transport_parameters
);
1054 sec_protocol_options_set_ats_required(sec_protocol_options_t options
, bool required
)
1056 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1058 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1059 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1060 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1062 content
->ats_required
= required
;
1068 sec_protocol_options_set_minimum_rsa_key_size(sec_protocol_options_t options
, size_t minimum_key_size
)
1070 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1072 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1073 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1074 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1076 content
->minimum_rsa_key_size
= minimum_key_size
;
1082 sec_protocol_options_set_minimum_ecdsa_key_size(sec_protocol_options_t options
, size_t minimum_key_size
)
1084 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1086 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1087 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1088 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1090 content
->minimum_ecdsa_key_size
= minimum_key_size
;
1096 sec_protocol_options_set_minimum_signature_algorithm(sec_protocol_options_t options
, SecSignatureHashAlgorithm algorithm
)
1098 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1100 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1101 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1102 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1104 content
->minimum_signature_algorithm
= algorithm
;
1110 sec_protocol_options_set_trusted_peer_certificate(sec_protocol_options_t options
, bool trusted_peer_certificate
)
1112 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
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 content
->trusted_peer_certificate
= trusted_peer_certificate
;
1119 content
->trusted_peer_certificate_override
= true;
1125 sec_protocol_options_set_private_key_blocks(sec_protocol_options_t options
,
1126 sec_protocol_private_key_sign_t sign_block
,
1127 sec_protocol_private_key_decrypt_t decrypt_block
,
1128 dispatch_queue_t operation_queue
)
1130 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1131 SEC_PROTOCOL_OPTIONS_VALIDATE(sign_block
,);
1132 SEC_PROTOCOL_OPTIONS_VALIDATE(decrypt_block
,);
1133 SEC_PROTOCOL_OPTIONS_VALIDATE(operation_queue
,);
1135 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1136 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1137 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1139 if (content
->private_key_sign_block
!= NULL
) {
1140 Block_release(content
->private_key_sign_block
);
1142 if (content
->private_key_decrypt_block
!= NULL
) {
1143 Block_release(content
->private_key_decrypt_block
);
1145 if (content
->private_key_queue
!= NULL
) {
1146 dispatch_release(content
->private_key_queue
);
1149 content
->private_key_sign_block
= Block_copy(sign_block
);
1150 content
->private_key_decrypt_block
= Block_copy(decrypt_block
);
1151 content
->private_key_queue
= operation_queue
;
1152 dispatch_retain(content
->private_key_queue
);
1159 sec_protocol_options_set_local_certificates(sec_protocol_options_t options
, sec_array_t certificates
)
1161 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1162 SEC_PROTOCOL_OPTIONS_VALIDATE(certificates
,);
1164 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1165 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1166 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1168 if (content
->certificates
!= NULL
) {
1169 sec_release(content
->certificates
);
1172 content
->certificates
= certificates
;
1173 sec_retain(content
->certificates
);
1179 sec_protocol_options_set_tls_certificate_compression_enabled(sec_protocol_options_t options
, bool certificate_compression_enabled
)
1181 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1183 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1184 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1185 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1187 content
->certificate_compression_enabled
= certificate_compression_enabled
;
1193 sec_protocol_options_set_output_handler_access_block(sec_protocol_options_t options
,
1194 sec_protocol_output_handler_access_block_t access_block
)
1196 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1197 SEC_PROTOCOL_OPTIONS_VALIDATE(access_block
,);
1199 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1200 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1201 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1203 content
->output_handler_access_block
= Block_copy(access_block
);
1209 sec_protocol_options_tls_handshake_message_callback(sec_protocol_options_t options
, sec_protocol_tls_handshake_message_handler_t handler
, dispatch_queue_t queue
)
1211 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1212 SEC_PROTOCOL_OPTIONS_VALIDATE(handler
,);
1213 SEC_PROTOCOL_OPTIONS_VALIDATE(queue
,);
1215 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1216 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1217 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1219 if (content
->handshake_message_callback
!= NULL
) {
1220 Block_release(content
->handshake_message_callback
);
1222 if (content
->handshake_message_callback_queue
!= NULL
) {
1223 dispatch_release(content
->handshake_message_callback_queue
);
1226 content
->handshake_message_callback
= Block_copy(handler
);
1227 content
->handshake_message_callback_queue
= queue
;
1228 dispatch_retain(content
->handshake_message_callback_queue
);
1235 sec_protocol_options_set_eddsa_enabled(sec_protocol_options_t options
, bool eddsa_enabled
)
1237 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1239 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1240 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1241 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1243 content
->eddsa_enabled
= eddsa_enabled
;
1249 sec_protocol_options_set_tls_delegated_credentials_enabled(sec_protocol_options_t options
, bool tls_delegated_credentials_enabled
)
1251 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1253 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1254 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1255 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1257 content
->tls_delegated_credentials_enabled
= tls_delegated_credentials_enabled
;
1263 sec_protocol_options_set_tls_grease_enabled(sec_protocol_options_t options
, bool tls_grease_enabled
)
1265 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1267 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1268 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1269 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1271 content
->tls_grease_enabled
= tls_grease_enabled
;
1277 sec_protocol_options_set_allow_unknown_alpn_protos(sec_protocol_options_t options
, bool allow_unknown_alpn_protos
)
1279 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1281 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1282 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1283 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1285 content
->allow_unknown_alpn_protos
= allow_unknown_alpn_protos
;
1286 content
->allow_unknown_alpn_protos_override
= true;
1292 sec_protocol_options_set_experiment_identifier(sec_protocol_options_t options
, const char *experiment_identifier
)
1294 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1295 SEC_PROTOCOL_OPTIONS_VALIDATE(experiment_identifier
,);
1297 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1298 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1299 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1301 if (content
->experiment_identifier
!= NULL
) {
1302 free(content
->experiment_identifier
);
1304 if (experiment_identifier
!= NULL
) {
1305 content
->experiment_identifier
= strdup(experiment_identifier
);
1312 sec_protocol_options_set_connection_id(sec_protocol_options_t options
, uuid_t _Nonnull connection_id
)
1314 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1315 SEC_PROTOCOL_OPTIONS_VALIDATE(connection_id
,);
1317 sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1318 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1319 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1321 memcpy(content
->connection_id
, connection_id
, sizeof(content
->connection_id
));
1327 sec_protocol_options_set_tls_ticket_request_count(sec_protocol_options_t options
, uint8_t tls_ticket_request_count
)
1329 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1331 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1332 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1333 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1335 content
->tls_ticket_request_count
= tls_ticket_request_count
;
1341 sec_protocol_options_set_ats_non_pfs_ciphersuite_allowed(sec_protocol_options_t options
, bool ats_non_pfs_ciphersuite_allowed
)
1343 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1345 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1346 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1347 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1349 content
->ats_non_pfs_ciphersuite_allowed
= ats_non_pfs_ciphersuite_allowed
;
1355 sec_protocol_options_set_ats_minimum_tls_version_allowed(sec_protocol_options_t options
, bool ats_minimum_tls_version_allowed
)
1357 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1359 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1360 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1361 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1363 content
->ats_minimum_tls_version_allowed
= ats_minimum_tls_version_allowed
;
1369 sec_protocol_options_append_tls_key_exchange_group(sec_protocol_options_t options
, tls_key_exchange_group_t group
)
1371 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1373 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1374 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1375 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1377 if (content
->key_exchange_groups
== NULL
) {
1378 content
->key_exchange_groups
= xpc_array_create(NULL
, 0);
1380 xpc_array_set_uint64(content
->key_exchange_groups
, XPC_ARRAY_APPEND
, (uint64_t)group
);
1386 sec_protocol_options_add_tls_key_exchange_group(sec_protocol_options_t options
, SSLKeyExchangeGroup group
)
1388 return sec_protocol_options_append_tls_key_exchange_group(options
, (tls_key_exchange_group_t
)group
);
1392 sec_protocol_options_append_tls_key_exchange_group_set(sec_protocol_options_t options
, tls_key_exchange_group_set_t set
)
1394 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1396 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1397 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1398 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1400 if (content
->key_exchange_groups
== NULL
) {
1401 content
->key_exchange_groups
= xpc_array_create(NULL
, 0);
1404 // Fetch the list of ciphersuites associated with the ciphersuite group
1405 size_t group_set_count
= 0;
1406 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
);
1407 if (group_set
!= NULL
) {
1408 for (size_t i
= 0; i
< group_set_count
; i
++) {
1409 tls_key_exchange_group_t group
= group_set
[i
];
1410 xpc_array_set_uint64(content
->key_exchange_groups
, XPC_ARRAY_APPEND
, (uint64_t)group
);
1419 sec_protocol_options_add_tls_key_exchange_group_set(sec_protocol_options_t options
, SSLKeyExchangeGroupSet set
)
1422 case kSSLKeyExchangeGroupSetDefault
:
1423 sec_protocol_options_append_tls_key_exchange_group_set(options
, tls_key_exchange_group_set_default
);
1425 case kSSLKeyExchangeGroupSetCompatibility
:
1426 sec_protocol_options_append_tls_key_exchange_group_set(options
, tls_key_exchange_group_set_compatibility
);
1428 case kSSLKeyExchangeGroupSetLegacy
:
1429 sec_protocol_options_append_tls_key_exchange_group_set(options
, tls_key_exchange_group_set_legacy
);
1435 sec_protocol_metadata_get_negotiated_protocol(sec_protocol_metadata_t metadata
)
1437 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
1439 __block
const char *negotiated_protocol
= NULL
;
1440 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1441 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1442 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1443 negotiated_protocol
= content
->negotiated_protocol
;
1447 return negotiated_protocol
;
1451 sec_protocol_metadata_get_server_name(sec_protocol_metadata_t metadata
)
1453 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
1455 __block
const char *server_name
= NULL
;
1456 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1457 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1458 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1459 server_name
= content
->server_name
;
1467 sec_protocol_metadata_get_handshake_time_ms(sec_protocol_metadata_t metadata
)
1469 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0);
1471 __block
uint64_t time
= 0;
1472 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
1473 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
1474 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
1475 time
= metadata_content
->handshake_time
;
1483 sec_protocol_metadata_get_handshake_byte_count(sec_protocol_metadata_t metadata
)
1485 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0);
1487 __block
uint64_t count
= 0;
1488 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
1489 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
1490 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
1491 count
= metadata_content
->total_byte_count
;
1499 sec_protocol_metadata_get_handshake_sent_byte_count(sec_protocol_metadata_t metadata
)
1501 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0);
1503 __block
uint64_t count
= 0;
1504 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
1505 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
1506 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
1507 count
= metadata_content
->sent_byte_count
;
1515 sec_protocol_metadata_get_handshake_received_byte_count(sec_protocol_metadata_t metadata
)
1517 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0);
1519 __block
uint64_t count
= 0;
1520 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
1521 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
1522 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
1523 count
= metadata_content
->received_byte_count
;
1531 sec_protocol_metadata_get_handshake_read_stall_count(sec_protocol_metadata_t metadata
)
1533 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0);
1535 __block
size_t count
= 0;
1536 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
1537 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
1538 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
1539 count
= metadata_content
->read_stall_count
;
1547 sec_protocol_metadata_get_handshake_write_stall_count(sec_protocol_metadata_t metadata
)
1549 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0);
1551 __block
size_t count
= 0;
1552 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
1553 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
1554 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
1555 count
= metadata_content
->write_stall_count
;
1563 sec_protocol_metadata_get_handshake_async_call_count(sec_protocol_metadata_t metadata
)
1565 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0);
1567 __block
size_t count
= 0;
1568 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
1569 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
1570 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
1571 count
= metadata_content
->async_call_count
;
1579 sec_protocol_metadata_access_peer_certificate_chain(sec_protocol_metadata_t metadata
,
1580 void (^handler
)(sec_certificate_t certficate
))
1582 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
1583 SEC_PROTOCOL_METADATA_VALIDATE(handler
, false);
1585 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1586 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1587 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1588 if (content
->peer_certificate_chain
== NULL
) {
1591 sec_array_t array
= content
->peer_certificate_chain
;
1592 sec_array_apply(array
, ^bool(__unused
size_t index
, sec_object_t object
) {
1593 handler((sec_certificate_t
)object
);
1601 sec_protocol_metadata_copy_peer_public_key(sec_protocol_metadata_t metadata
)
1603 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
1605 __block dispatch_data_t peer_public_key
= NULL
;
1606 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1607 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1608 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1609 peer_public_key
= ((dispatch_data_t
)content
->peer_public_key
);
1610 if (peer_public_key
) {
1611 dispatch_retain(peer_public_key
);
1616 return peer_public_key
;
1619 tls_protocol_version_t
1620 sec_protocol_metadata_get_negotiated_tls_protocol_version(sec_protocol_metadata_t metadata
)
1622 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0x0000);
1624 __block tls_protocol_version_t protocol_version
= 0x0000;
1625 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1626 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1627 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1628 protocol_version
= SSLProtocolGetVersionCodepoint(content
->negotiated_protocol_version
);
1632 return protocol_version
;
1636 sec_protocol_metadata_get_negotiated_protocol_version(sec_protocol_metadata_t metadata
)
1638 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, kSSLProtocolUnknown
);
1640 __block SSLProtocol protocol_version
= kSSLProtocolUnknown
;
1641 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1642 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1643 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1644 protocol_version
= content
->negotiated_protocol_version
;
1648 return protocol_version
;
1652 sec_protocol_metadata_get_negotiated_tls_ciphersuite(sec_protocol_metadata_t metadata
)
1654 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0xFFFF);
1656 __block tls_ciphersuite_t negotiated_ciphersuite
= SSL_NO_SUCH_CIPHERSUITE
;
1657 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1658 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1659 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1660 negotiated_ciphersuite
= content
->negotiated_ciphersuite
;
1664 return negotiated_ciphersuite
;
1668 sec_protocol_metadata_get_negotiated_ciphersuite(sec_protocol_metadata_t metadata
)
1670 return (SSLCipherSuite
)sec_protocol_metadata_get_negotiated_tls_ciphersuite(metadata
);
1674 sec_protocol_metadata_get_early_data_accepted(sec_protocol_metadata_t metadata
)
1676 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
1678 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1679 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1680 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1681 return content
->early_data_accepted
;
1686 sec_protocol_metadata_access_supported_signature_algorithms(sec_protocol_metadata_t metadata
,
1687 void (^handler
)(uint16_t signature_algorithm
))
1689 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
1690 SEC_PROTOCOL_METADATA_VALIDATE(handler
, false);
1692 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1693 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1694 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1695 if (content
->supported_signature_algorithms
== NULL
) {
1698 xpc_object_t array
= content
->supported_signature_algorithms
;
1699 xpc_array_apply(array
, ^bool(__unused
size_t index
, xpc_object_t _Nonnull value
) {
1700 handler((uint16_t)xpc_uint64_get_value(value
));
1708 sec_protocol_metadata_access_ocsp_response(sec_protocol_metadata_t metadata
,
1709 void (^handler
)(dispatch_data_t ocsp_data
))
1711 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
1712 SEC_PROTOCOL_METADATA_VALIDATE(handler
, false);
1714 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1715 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1716 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1717 if (content
->ocsp_response
== NULL
) {
1720 sec_array_t array
= content
->ocsp_response
;
1721 sec_array_apply(array
, ^bool(__unused
size_t index
, sec_object_t object
) {
1722 handler((dispatch_data_t
)object
);
1730 sec_protocol_metadata_access_distinguished_names(sec_protocol_metadata_t metadata
,
1731 void (^handler
)(dispatch_data_t distinguished_name
))
1733 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
1734 SEC_PROTOCOL_METADATA_VALIDATE(handler
, false);
1736 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1737 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1738 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1739 if (content
->distinguished_names
== NULL
) {
1742 sec_array_t array
= content
->distinguished_names
;
1743 sec_array_apply(array
, ^bool(__unused
size_t index
, sec_object_t object
) {
1744 handler((dispatch_data_t
)object
);
1751 static dispatch_data_t
1752 create_dispatch_data_from_xpc_data(xpc_object_t xpc_data
)
1758 size_t data_len
= xpc_data_get_length(xpc_data
);
1759 if (data_len
== 0) {
1763 uint8_t *data_buffer
= malloc(data_len
);
1768 size_t copied_count
= xpc_data_get_bytes(xpc_data
, data_buffer
, 0, data_len
);
1769 if (copied_count
!= data_len
) {
1774 dispatch_data_t data
= dispatch_data_create(data_buffer
, data_len
, NULL
, DISPATCH_DATA_DESTRUCTOR_DEFAULT
);
1781 sec_protocol_metadata_access_pre_shared_keys(sec_protocol_metadata_t metadata
,
1782 void (^handler
)(dispatch_data_t psk
, dispatch_data_t _Nullable psk_identity
))
1784 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
1785 SEC_PROTOCOL_METADATA_VALIDATE(handler
, false);
1787 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1788 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1789 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1790 if (content
->pre_shared_keys
== NULL
) {
1793 xpc_array_apply(content
->pre_shared_keys
, ^bool(size_t index
, xpc_object_t _Nonnull tuple
) {
1794 if (xpc_array_get_count(tuple
) == 2) {
1795 xpc_object_t xpc_psk_data
= xpc_array_get_value(tuple
, 0);
1796 xpc_object_t xpc_psk_identity_data
= xpc_array_get_value(tuple
, 1);
1798 dispatch_data_t psk_data
= create_dispatch_data_from_xpc_data(xpc_psk_data
);
1799 dispatch_data_t psk_identity_data
= create_dispatch_data_from_xpc_data(xpc_psk_identity_data
);
1800 if (!psk_data
|| !psk_identity_data
) {
1801 // Skip and return early if we can't create a PSK or identity from the provided data. Something's wrong.
1805 handler(psk_data
, psk_identity_data
);
1814 sec_protocol_dispatch_data_are_equal(dispatch_data_t left
, dispatch_data_t right
)
1816 if (!left
|| !right
|| left
== right
) {
1817 return left
== right
;
1819 if (dispatch_data_get_size(left
) != dispatch_data_get_size(right
)) {
1823 __block
bool equal
= true;
1824 dispatch_data_apply(left
, ^bool(__unused dispatch_data_t _Nonnull lregion
, size_t loffset
, const void * _Nonnull lbuffer
, size_t lsize
) {
1825 dispatch_data_apply(right
, ^bool(__unused dispatch_data_t _Nonnull rregion
, size_t roffset
, const void * _Nonnull rbuffer
, size_t rsize
) {
1826 // There is some overlap
1827 const size_t start
= MAX(loffset
, roffset
);
1828 const size_t end
= MIN(loffset
+ lsize
, roffset
+ rsize
);
1830 equal
= memcmp(&((const uint8_t*)rbuffer
)[start
- roffset
], &((const uint8_t*)lbuffer
)[start
- loffset
], end
- start
) == 0;
1832 if (roffset
> loffset
+ lsize
) {
1833 // Iteration of right has gone past where we're at on left, bail out of inner apply
1837 } else if (roffset
+ rsize
< loffset
) {
1838 // Iteration of right has not yet reached where we're at on left, keep going
1852 sec_protocol_sec_array_of_dispatch_data_are_equal(sec_array_t arrayA
, sec_array_t arrayB
)
1854 if (sec_array_get_count(arrayA
) != sec_array_get_count(arrayB
)) {
1858 __block
bool equal
= true;
1859 (void)sec_array_apply(arrayA
, ^bool(size_t indexA
, sec_object_t objectA
) {
1860 return sec_array_apply(arrayB
, ^bool(size_t indexB
, sec_object_t objectB
) {
1861 if (indexA
== indexB
) {
1862 dispatch_data_t dataA
= (dispatch_data_t
)objectA
;
1863 dispatch_data_t dataB
= (dispatch_data_t
)objectB
;
1864 equal
&= sec_protocol_dispatch_data_are_equal(dataA
, dataB
);
1875 sec_protocol_sec_array_of_sec_certificate_are_equal(sec_array_t arrayA
, sec_array_t arrayB
)
1877 if (sec_array_get_count(arrayA
) != sec_array_get_count(arrayB
)) {
1881 __block
bool equal
= true;
1882 (void)sec_array_apply(arrayA
, ^bool(size_t indexA
, sec_object_t objectA
) {
1883 return sec_array_apply(arrayB
, ^bool(size_t indexB
, sec_object_t objectB
) {
1884 if (indexA
== indexB
) {
1885 sec_certificate_t certA
= (sec_certificate_t
)objectA
;
1886 sec_certificate_t certB
= (sec_certificate_t
)objectB
;
1888 SecCertificateRef certRefA
= sec_certificate_copy_ref(certA
);
1889 SecCertificateRef certRefB
= sec_certificate_copy_ref(certB
);
1891 if (certRefA
== NULL
&& certRefB
!= NULL
) {
1893 } else if (certRefA
!= NULL
&& certRefB
== NULL
) {
1895 } else if (certRefA
== NULL
&& certRefB
== NULL
) {
1898 equal
&= CFEqual(certRefA
, certRefB
);
1901 CFReleaseSafe(certRefA
);
1902 CFReleaseSafe(certRefB
);
1914 sec_protocol_xpc_object_are_equal(xpc_object_t objectA
, xpc_object_t objectB
)
1916 if (objectA
== NULL
&& objectB
!= NULL
) {
1918 } else if (objectA
!= NULL
&& objectB
== NULL
) {
1920 } else if (objectA
== NULL
&& objectB
== NULL
) {
1923 return xpc_equal(objectA
, objectB
);
1928 sec_protocol_metadata_peers_are_equal(sec_protocol_metadata_t metadataA
, sec_protocol_metadata_t metadataB
)
1930 SEC_PROTOCOL_METADATA_VALIDATE(metadataA
, false);
1931 SEC_PROTOCOL_METADATA_VALIDATE(metadataB
, false);
1933 return sec_protocol_metadata_access_handle(metadataA
, ^bool(void *handleA
) {
1934 sec_protocol_metadata_content_t contentA
= (sec_protocol_metadata_content_t
)handleA
;
1935 SEC_PROTOCOL_METADATA_VALIDATE(contentA
, false);
1937 return sec_protocol_metadata_access_handle(metadataB
, ^bool(void *handleB
) {
1938 sec_protocol_metadata_content_t contentB
= (sec_protocol_metadata_content_t
)handleB
;
1939 SEC_PROTOCOL_METADATA_VALIDATE(contentB
, false);
1941 // Relevant peer information includes: Certificate chain, public key, support signature algorithms, OCSP response, and distinguished names
1942 if (!sec_protocol_sec_array_of_sec_certificate_are_equal(contentA
->peer_certificate_chain
, contentB
->peer_certificate_chain
)) {
1945 if (!sec_protocol_dispatch_data_are_equal((dispatch_data_t
)contentA
->peer_public_key
, (dispatch_data_t
)contentB
->peer_public_key
)) {
1948 if (!sec_protocol_xpc_object_are_equal((xpc_object_t
)contentA
->supported_signature_algorithms
, (xpc_object_t
)contentB
->supported_signature_algorithms
)) {
1951 if (!sec_protocol_sec_array_of_dispatch_data_are_equal(contentA
->ocsp_response
, contentB
->ocsp_response
)) {
1954 if (!sec_protocol_sec_array_of_dispatch_data_are_equal(contentA
->distinguished_names
, contentB
->distinguished_names
)) {
1964 sec_protocol_metadata_challenge_parameters_are_equal(sec_protocol_metadata_t metadataA
, sec_protocol_metadata_t metadataB
)
1966 SEC_PROTOCOL_METADATA_VALIDATE(metadataA
, false);
1967 SEC_PROTOCOL_METADATA_VALIDATE(metadataB
, false);
1969 return sec_protocol_metadata_access_handle(metadataA
, ^bool(void *handleA
) {
1970 sec_protocol_metadata_content_t contentA
= (sec_protocol_metadata_content_t
)handleA
;
1971 SEC_PROTOCOL_METADATA_VALIDATE(contentA
, false);
1973 return sec_protocol_metadata_access_handle(metadataB
, ^bool(void *handleB
) {
1974 sec_protocol_metadata_content_t contentB
= (sec_protocol_metadata_content_t
)handleB
;
1975 SEC_PROTOCOL_METADATA_VALIDATE(contentB
, false);
1977 if (!sec_protocol_xpc_object_are_equal((xpc_object_t
)contentA
->supported_signature_algorithms
, (xpc_object_t
)contentB
->supported_signature_algorithms
)) {
1980 if (!sec_protocol_sec_array_of_dispatch_data_are_equal(contentA
->distinguished_names
, contentB
->distinguished_names
)) {
1983 if (!sec_protocol_dispatch_data_are_equal(contentA
->request_certificate_types
, contentB
->request_certificate_types
)) {
1993 sec_protocol_metadata_create_secret(sec_protocol_metadata_t metadata
, size_t label_len
,
1994 const char *label
, size_t exporter_length
)
1996 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
1997 SEC_PROTOCOL_METADATA_VALIDATE(label_len
, NULL
);
1998 SEC_PROTOCOL_METADATA_VALIDATE(label
, NULL
);
1999 SEC_PROTOCOL_METADATA_VALIDATE(exporter_length
, NULL
);
2001 __block dispatch_data_t secret
= NULL
;
2002 sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
2003 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
2004 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
2006 if (content
->exporter_function
&& content
->exporter_context
) {
2007 sec_protocol_metadata_exporter exporter
= (sec_protocol_metadata_exporter
)content
->exporter_function
;
2008 secret
= exporter(content
->exporter_context
, label_len
, label
, 0, NULL
, exporter_length
);
2016 sec_protocol_metadata_create_secret_with_context(sec_protocol_metadata_t metadata
, size_t label_len
,
2017 const char *label
, size_t context_len
,
2018 const uint8_t *context
, size_t exporter_length
)
2020 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
2021 SEC_PROTOCOL_METADATA_VALIDATE(label_len
, NULL
);
2022 SEC_PROTOCOL_METADATA_VALIDATE(label
, NULL
);
2023 SEC_PROTOCOL_METADATA_VALIDATE(context_len
, NULL
);
2024 SEC_PROTOCOL_METADATA_VALIDATE(context
, NULL
);
2025 SEC_PROTOCOL_METADATA_VALIDATE(exporter_length
, NULL
);
2027 __block dispatch_data_t secret
= NULL
;
2028 sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
2029 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
2030 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
2032 if (content
->exporter_function
&& content
->exporter_context
) {
2033 sec_protocol_metadata_exporter exporter
= (sec_protocol_metadata_exporter
)content
->exporter_function
;
2034 secret
= exporter(content
->exporter_context
, label_len
, label
, context_len
, context
, exporter_length
);
2042 sec_protocol_metadata_get_tls_false_start_used(sec_protocol_metadata_t metadata
)
2044 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
2046 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
2047 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
2048 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
2049 return content
->false_start_used
;
2054 sec_protocol_metadata_get_ticket_offered(sec_protocol_metadata_t metadata
)
2056 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
2058 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
2059 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
2060 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
2061 return content
->ticket_offered
;
2066 sec_protocol_metadata_get_ticket_received(sec_protocol_metadata_t metadata
)
2068 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
2070 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
2071 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
2072 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
2073 return content
->ticket_received
;
2078 sec_protocol_metadata_get_session_resumed(sec_protocol_metadata_t metadata
)
2080 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
2082 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
2083 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
2084 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
2085 return content
->session_resumed
;
2090 sec_protocol_metadata_get_session_renewed(sec_protocol_metadata_t metadata
)
2092 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
2094 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
2095 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
2096 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
2097 return content
->session_renewed
;
2101 SSLConnectionStrength
2102 sec_protocol_metadata_get_connection_strength(sec_protocol_metadata_t metadata
)
2104 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, SSLConnectionStrengthNonsecure
);
2106 __block SSLConnectionStrength strength
= SSLConnectionStrengthNonsecure
;
2107 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
2108 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
2109 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
2111 // TLSv1.2 and higher are considered strong. Anything less than TLSv1.2 is considered weak at best.
2112 #pragma clang diagnostic push
2113 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
2114 SSLProtocol version
= content
->negotiated_protocol_version
;
2115 if (version
>= kTLSProtocol12
) {
2116 strength
= SSLConnectionStrengthStrong
;
2117 } else if (version
== kTLSProtocol11
|| version
== kTLSProtocol1
) {
2118 strength
= SSLConnectionStrengthWeak
;
2120 strength
= SSLConnectionStrengthNonsecure
;
2123 // Legacy ciphersuites make the connection weak, for now. We may consider changing this to nonsecure.
2124 SSLCipherSuite ciphersuite
= content
->negotiated_ciphersuite
;
2125 if (strength
!= SSLConnectionStrengthNonsecure
&&
2126 SSLCiphersuiteGroupContainsCiphersuite(kSSLCiphersuiteGroupLegacy
, ciphersuite
)) {
2127 strength
= SSLConnectionStrengthWeak
;
2129 #pragma clang diagnostic pop
2138 sec_protocol_metadata_copy_serialized_session(sec_protocol_metadata_t metadata
)
2140 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
2142 __block dispatch_data_t session
= NULL
;
2143 sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
2144 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
2145 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
2147 if (content
->session_exporter_function
&& content
->session_exporter_context
) {
2148 sec_protocol_metadata_session_exporter exporter
= (sec_protocol_metadata_session_exporter
)content
->session_exporter_function
;
2149 session
= exporter(content
->session_exporter_context
);
2156 const char * __nullable
2157 sec_protocol_metadata_get_experiment_identifier(sec_protocol_metadata_t metadata
)
2159 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
2161 __block
const char *experiment_identifer
= NULL
;
2162 sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
2163 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
2164 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
2166 experiment_identifer
= content
->experiment_identifier
;
2169 return experiment_identifer
;
2173 sec_protocol_metadata_copy_connection_id(sec_protocol_metadata_t metadata
, uuid_t _Nonnull output_uuid
)
2175 SEC_PROTOCOL_METADATA_VALIDATE(metadata
,);
2176 SEC_PROTOCOL_METADATA_VALIDATE(output_uuid
,);
2178 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
2179 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
2180 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
2182 memcpy(output_uuid
, content
->connection_id
, sizeof(content
->connection_id
));
2187 static const char *_options_uint64_keys
[] = {
2188 SEC_PROTOCOL_OPTIONS_KEY_min_version
,
2189 SEC_PROTOCOL_OPTIONS_KEY_max_version
,
2190 SEC_PROTOCOL_OPTIONS_KEY_minimum_rsa_key_size
,
2191 SEC_PROTOCOL_OPTIONS_KEY_minimum_ecdsa_key_size
,
2192 SEC_PROTOCOL_OPTIONS_KEY_minimum_signature_algorithm
,
2193 SEC_PROTOCOL_OPTIONS_KEY_tls_ticket_request_count
,
2195 static const size_t _options_uint64_keys_len
= sizeof(_options_uint64_keys
) / sizeof(_options_uint64_keys
[0]);
2197 static const char *_options_bool_keys
[] = {
2198 SEC_PROTOCOL_OPTIONS_KEY_ats_required
,
2199 SEC_PROTOCOL_OPTIONS_KEY_ats_minimum_tls_version_allowed
,
2200 SEC_PROTOCOL_OPTIONS_KEY_ats_non_pfs_ciphersuite_allowed
,
2201 SEC_PROTOCOL_OPTIONS_KEY_trusted_peer_certificate
,
2202 SEC_PROTOCOL_OPTIONS_KEY_disable_sni
,
2203 SEC_PROTOCOL_OPTIONS_KEY_enable_fallback_attempt
,
2204 SEC_PROTOCOL_OPTIONS_KEY_enable_false_start
,
2205 SEC_PROTOCOL_OPTIONS_KEY_enable_tickets
,
2206 SEC_PROTOCOL_OPTIONS_KEY_enable_sct
,
2207 SEC_PROTOCOL_OPTIONS_KEY_enable_ocsp
,
2208 SEC_PROTOCOL_OPTIONS_KEY_enforce_ev
,
2209 SEC_PROTOCOL_OPTIONS_KEY_enable_resumption
,
2210 SEC_PROTOCOL_OPTIONS_KEY_enable_renegotiation
,
2211 SEC_PROTOCOL_OPTIONS_KEY_enable_early_data
,
2212 SEC_PROTOCOL_OPTIONS_KEY_peer_authentication_required
,
2213 SEC_PROTOCOL_OPTIONS_KEY_peer_authentication_optional
,
2214 SEC_PROTOCOL_OPTIONS_KEY_certificate_compression_enabled
,
2215 SEC_PROTOCOL_OPTIONS_KEY_eddsa_enabled
,
2216 SEC_PROTOCOL_OPTIONS_KEY_tls_delegated_credentials_enabled
,
2217 SEC_PROTOCOL_OPTIONS_KEY_tls_grease_enabled
,
2220 static const size_t _options_bool_keys_len
= sizeof(_options_bool_keys
) / sizeof(_options_bool_keys
[0]);
2223 _dictionary_has_key(xpc_object_t dict
, const char *target_key
)
2225 if (xpc_get_type(dict
) != XPC_TYPE_DICTIONARY
) {
2229 return !xpc_dictionary_apply(dict
, ^bool(const char * _Nonnull key
, xpc_object_t _Nonnull value
) {
2230 if (strncmp(key
, target_key
, strlen(target_key
)) == 0) {
2238 _options_config_matches_partial_config(xpc_object_t full
, xpc_object_t partial
)
2240 SEC_PROTOCOL_METADATA_VALIDATE(full
, false);
2241 SEC_PROTOCOL_METADATA_VALIDATE(partial
, false);
2243 return xpc_dictionary_apply(partial
, ^bool(const char * _Nonnull entry_key
, xpc_object_t _Nonnull value
) {
2244 size_t entry_key_len
= strnlen(entry_key
, MAX_SEC_PROTOCOL_OPTIONS_KEY_LEN
);
2246 for (size_t i
= 0; i
< _options_uint64_keys_len
; i
++) {
2247 const char *key
= _options_uint64_keys
[i
];
2248 if (strncmp(entry_key
, key
, MAX(entry_key_len
, strlen(key
))) == 0) {
2249 if (_dictionary_has_key(full
, key
)) {
2250 if (xpc_dictionary_get_uint64(full
, key
) != xpc_dictionary_get_uint64(partial
, key
)) {
2259 for (size_t i
= 0; i
< _options_bool_keys_len
; i
++) {
2260 const char *key
= _options_bool_keys
[i
];
2261 if (strncmp(entry_key
, key
, MAX(entry_key_len
, strlen(key
))) == 0) {
2262 if (_dictionary_has_key(full
, key
)) {
2263 if (xpc_dictionary_get_bool(full
, key
) != xpc_dictionary_get_bool(partial
, key
)) {
2277 _serialize_options(xpc_object_t dictionary
, sec_protocol_options_content_t options_content
)
2279 #define EXPAND_PARAMETER(field) \
2280 SEC_PROTOCOL_OPTIONS_KEY_##field , options_content->field
2282 xpc_dictionary_set_uint64(dictionary
, EXPAND_PARAMETER(min_version
));
2283 xpc_dictionary_set_uint64(dictionary
, EXPAND_PARAMETER(max_version
));
2284 xpc_dictionary_set_uint64(dictionary
, EXPAND_PARAMETER(minimum_rsa_key_size
));
2285 xpc_dictionary_set_uint64(dictionary
, EXPAND_PARAMETER(minimum_ecdsa_key_size
));
2286 xpc_dictionary_set_uint64(dictionary
, EXPAND_PARAMETER(minimum_signature_algorithm
));
2287 xpc_dictionary_set_uint64(dictionary
, EXPAND_PARAMETER(tls_ticket_request_count
));
2289 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(ats_required
));
2290 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(ats_minimum_tls_version_allowed
));
2291 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(ats_non_pfs_ciphersuite_allowed
));
2292 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(trusted_peer_certificate
));
2293 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(disable_sni
));
2294 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_fallback_attempt
));
2295 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_false_start
));
2296 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_tickets
));
2297 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_sct
));
2298 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_ocsp
));
2299 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enforce_ev
));
2300 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_resumption
));
2301 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_renegotiation
));
2302 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_early_data
));
2303 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(peer_authentication_required
));
2304 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(peer_authentication_optional
));
2305 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(certificate_compression_enabled
));
2306 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(eddsa_enabled
));
2307 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(tls_delegated_credentials_enabled
));
2308 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(tls_grease_enabled
));
2310 #undef EXPAND_PARAMETER
2315 static struct _options_bool_key_setter
{
2317 void (*setter_pointer
)(sec_protocol_options_t
, bool);
2318 } _options_bool_key_setters
[] = {
2320 .key
= SEC_PROTOCOL_OPTIONS_KEY_ats_required
,
2321 .setter_pointer
= sec_protocol_options_set_ats_required
,
2324 .key
= SEC_PROTOCOL_OPTIONS_KEY_ats_minimum_tls_version_allowed
,
2325 .setter_pointer
= sec_protocol_options_set_ats_minimum_tls_version_allowed
,
2328 .key
= SEC_PROTOCOL_OPTIONS_KEY_ats_non_pfs_ciphersuite_allowed
,
2329 .setter_pointer
= sec_protocol_options_set_ats_non_pfs_ciphersuite_allowed
,
2332 .key
= SEC_PROTOCOL_OPTIONS_KEY_trusted_peer_certificate
,
2333 .setter_pointer
= sec_protocol_options_set_trusted_peer_certificate
,
2336 .key
= SEC_PROTOCOL_OPTIONS_KEY_disable_sni
,
2337 .setter_pointer
= sec_protocol_options_set_tls_sni_disabled
2340 .key
= SEC_PROTOCOL_OPTIONS_KEY_enable_fallback_attempt
,
2341 .setter_pointer
= sec_protocol_options_set_tls_is_fallback_attempt
,
2344 .key
= SEC_PROTOCOL_OPTIONS_KEY_enable_false_start
,
2345 .setter_pointer
= sec_protocol_options_set_tls_false_start_enabled
,
2348 .key
= SEC_PROTOCOL_OPTIONS_KEY_enable_tickets
,
2349 .setter_pointer
= sec_protocol_options_set_tls_tickets_enabled
,
2352 .key
= SEC_PROTOCOL_OPTIONS_KEY_enable_sct
,
2353 .setter_pointer
= sec_protocol_options_set_tls_sct_enabled
2356 .key
= SEC_PROTOCOL_OPTIONS_KEY_enable_ocsp
,
2357 .setter_pointer
= sec_protocol_options_set_tls_ocsp_enabled
,
2360 .key
= SEC_PROTOCOL_OPTIONS_KEY_enforce_ev
,
2361 .setter_pointer
= sec_protocol_options_set_enforce_ev
,
2364 .key
= SEC_PROTOCOL_OPTIONS_KEY_enable_resumption
,
2365 .setter_pointer
= sec_protocol_options_set_tls_resumption_enabled
,
2368 .key
= SEC_PROTOCOL_OPTIONS_KEY_enable_renegotiation
,
2369 .setter_pointer
= sec_protocol_options_set_tls_renegotiation_enabled
,
2372 .key
= SEC_PROTOCOL_OPTIONS_KEY_enable_early_data
,
2373 .setter_pointer
= sec_protocol_options_set_tls_early_data_enabled
,
2376 .key
= SEC_PROTOCOL_OPTIONS_KEY_peer_authentication_required
,
2377 .setter_pointer
= sec_protocol_options_set_peer_authentication_required
,
2380 .key
= SEC_PROTOCOL_OPTIONS_KEY_peer_authentication_optional
,
2381 .setter_pointer
= sec_protocol_options_set_peer_authentication_optional
,
2384 .key
= SEC_PROTOCOL_OPTIONS_KEY_certificate_compression_enabled
,
2385 .setter_pointer
= sec_protocol_options_set_tls_certificate_compression_enabled
,
2388 .key
= SEC_PROTOCOL_OPTIONS_KEY_eddsa_enabled
,
2389 .setter_pointer
= sec_protocol_options_set_eddsa_enabled
,
2392 .key
= SEC_PROTOCOL_OPTIONS_KEY_tls_delegated_credentials_enabled
,
2393 .setter_pointer
= sec_protocol_options_set_tls_delegated_credentials_enabled
,
2396 .key
= SEC_PROTOCOL_OPTIONS_KEY_tls_grease_enabled
,
2397 .setter_pointer
= sec_protocol_options_set_tls_grease_enabled
,
2400 static const size_t _options_bool_key_setters_len
= sizeof(_options_bool_key_setters
) / sizeof(_options_bool_key_setters
[0]);
2402 static struct _options_uint64_key_setter
{
2404 void (*setter_pointer
)(sec_protocol_options_t
, uint64_t);
2405 } _options_uint64_key_setters
[] = {
2406 #pragma clang diagnostic push
2407 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
2409 .key
= SEC_PROTOCOL_OPTIONS_KEY_min_version
,
2410 .setter_pointer
= (void (*)(sec_protocol_options_t
, uint64_t))sec_protocol_options_set_tls_min_version
2413 .key
= SEC_PROTOCOL_OPTIONS_KEY_max_version
,
2414 .setter_pointer
= (void (*)(sec_protocol_options_t
, uint64_t))sec_protocol_options_set_tls_max_version
2416 #pragma clang diagnostic pop
2418 .key
= SEC_PROTOCOL_OPTIONS_KEY_minimum_rsa_key_size
,
2419 .setter_pointer
= (void (*)(sec_protocol_options_t
, uint64_t))sec_protocol_options_set_minimum_rsa_key_size
,
2422 .key
= SEC_PROTOCOL_OPTIONS_KEY_minimum_ecdsa_key_size
,
2423 .setter_pointer
= (void (*)(sec_protocol_options_t
, uint64_t))sec_protocol_options_set_minimum_ecdsa_key_size
,
2426 .key
= SEC_PROTOCOL_OPTIONS_KEY_minimum_signature_algorithm
,
2427 .setter_pointer
= (void (*)(sec_protocol_options_t
, uint64_t))sec_protocol_options_set_minimum_signature_algorithm
,
2430 .key
= SEC_PROTOCOL_OPTIONS_KEY_tls_ticket_request_count
,
2431 .setter_pointer
= (void (*)(sec_protocol_options_t
, uint64_t))sec_protocol_options_set_tls_ticket_request_count
,
2434 static const size_t _options_uint64_key_setters_len
= sizeof(_options_uint64_key_setters
) / sizeof(_options_uint64_key_setters
[0]);
2437 _apply_config_options(sec_protocol_options_t options
, xpc_object_t config
)
2439 return sec_protocol_options_access_handle(options
, ^bool(void *options_handle
) {
2440 sec_protocol_options_content_t options_content
= (sec_protocol_options_content_t
)options_handle
;
2441 SEC_PROTOCOL_METADATA_VALIDATE(options_content
, false);
2442 return xpc_dictionary_apply(config
, ^bool(const char * _Nonnull key
, xpc_object_t _Nonnull value
) {
2444 size_t key_len
= strnlen(key
, MAX_SEC_PROTOCOL_OPTIONS_KEY_LEN
);
2445 for (size_t i
= 0; i
< _options_bool_key_setters_len
; i
++) {
2446 const char *setter_key
= _options_bool_key_setters
[i
].key
;
2447 size_t setter_key_len
= strnlen(setter_key
, MAX_SEC_PROTOCOL_OPTIONS_KEY_LEN
);
2448 if (strncmp(setter_key
, key
, MAX(key_len
, setter_key_len
)) == 0) {
2449 _options_bool_key_setters
[i
].setter_pointer(options
, xpc_dictionary_get_bool(config
, key
));
2453 for (size_t i
= 0; i
< _options_uint64_key_setters_len
; i
++) {
2454 const char *setter_key
= _options_uint64_key_setters
[i
].key
;
2455 size_t setter_key_len
= strnlen(setter_key
, MAX_SEC_PROTOCOL_OPTIONS_KEY_LEN
);
2456 if (strncmp(setter_key
, key
, MAX(key_len
, setter_key_len
)) == 0) {
2457 _options_uint64_key_setters
[i
].setter_pointer(options
, xpc_dictionary_get_uint64(config
, key
));
2461 // Now check for ciphersuite options, as these are not expressed via serialized configs
2462 if (strncmp(key
, SEC_PROTOCOL_OPTIONS_KEY_ciphersuites
, key_len
) == 0) {
2463 if (xpc_get_type(value
) == XPC_TYPE_ARRAY
) {
2464 xpc_array_apply(value
, ^bool(size_t index
, xpc_object_t _Nonnull ciphersuite_value
) {
2465 SSLCipherSuite ciphersuite
= (SSLCipherSuite
)xpc_array_get_uint64(value
, index
);
2466 sec_protocol_options_append_tls_ciphersuite(options
, ciphersuite
);
2478 _serialize_metadata(xpc_object_t dictionary
, sec_protocol_metadata_content_t metadata_content
)
2480 #define xpc_dictionary_set_string_default(d, key, value, default) \
2482 if (value != NULL) { \
2483 xpc_dictionary_set_string(d, key, value); \
2485 xpc_dictionary_set_string(d, key, default); \
2489 xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_CIPHERSUITE
, metadata_content
->negotiated_ciphersuite
);
2490 xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_PROTOCOL_VERSION
, metadata_content
->negotiated_protocol_version
);
2491 xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_TICKET_LIFETIME
, metadata_content
->ticket_lifetime
);
2493 xpc_dictionary_set_string_default(dictionary
, SEC_PROTOCOL_METADATA_KEY_PEER_PUBLIC_KEY_TYPE
,
2494 metadata_content
->peer_public_key_type
, SEC_PROTOCOL_METADATA_KEY_DEFAULT_EMPTY_STRING
);
2495 xpc_dictionary_set_string_default(dictionary
, SEC_PROTOCOL_METADATA_KEY_NEGOTIATED_CURVE
,
2496 metadata_content
->negotiated_curve
, SEC_PROTOCOL_METADATA_KEY_DEFAULT_EMPTY_STRING
);
2497 xpc_dictionary_set_string_default(dictionary
, SEC_PROTOCOL_METADATA_KEY_PEER_CERTIFICATE_REQUEST_TYPE
,
2498 metadata_content
->certificate_request_type
, SEC_PROTOCOL_METADATA_KEY_DEFAULT_EMPTY_STRING
);
2499 xpc_dictionary_set_string_default(dictionary
, SEC_PROTOCOL_METADATA_KEY_NEGOTIATED_PROTOCOL
,
2500 metadata_content
->negotiated_protocol
, SEC_PROTOCOL_METADATA_KEY_DEFAULT_EMPTY_STRING
);
2502 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_FALSE_START_USED
, metadata_content
->false_start_used
);
2503 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_SESSION_RESUMED
, metadata_content
->session_resumed
);
2504 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_TICKET_OFFERED
, metadata_content
->ticket_offered
);
2505 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_TICKET_RECEIVED
, metadata_content
->ticket_received
);
2506 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_SESSION_RENEWED
, metadata_content
->session_renewed
);
2507 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_RESUMPTION_ATTEMPTED
, metadata_content
->resumption_attempted
);
2508 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_ALPN_USED
, metadata_content
->alpn_used
);
2509 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_NPN_USED
, metadata_content
->npn_used
);
2510 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_OCSP_ENABLED
, metadata_content
->ocsp_enabled
);
2511 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_OCSP_RECEIVED
, metadata_content
->ocsp_response
!= NULL
);
2512 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_SCT_ENABLED
, metadata_content
->sct_enabled
);
2513 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_SCT_RECEIVED
, metadata_content
->signed_certificate_timestamps
!= NULL
);
2515 #undef xpc_dictionary_set_string_default
2521 _serialize_success_with_options(xpc_object_t dictionary
, sec_protocol_metadata_content_t metadata_content
, sec_protocol_options_content_t options_content
)
2523 if (!_serialize_options(dictionary
, options_content
)) {
2526 if (!_serialize_metadata(dictionary
, metadata_content
)) {
2533 _serialize_failure_with_options(xpc_object_t dictionary
, sec_protocol_metadata_content_t metadata_content
, sec_protocol_options_content_t options_content
)
2535 xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_FAILURE_ALERT_TYPE
, metadata_content
->alert_type
);
2536 xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_FAILURE_ALERT_CODE
, metadata_content
->alert_code
);
2537 xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_FAILURE_HANDSHAKE_STATE
, metadata_content
->handshake_state
);
2538 xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_FAILURE_STACK_ERROR
, metadata_content
->stack_error
);
2544 sec_protocol_metadata_serialize_with_options(sec_protocol_metadata_t metadata
, sec_protocol_options_t options
)
2546 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
2547 SEC_PROTOCOL_METADATA_VALIDATE(options
, NULL
);
2549 __block xpc_object_t dictionary
= xpc_dictionary_create(NULL
, NULL
, 0);
2550 if (dictionary
== NULL
) {
2554 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
2555 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
2556 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
2558 return sec_protocol_options_access_handle(options
, ^bool(void *options_handle
) {
2559 sec_protocol_options_content_t options_content
= (sec_protocol_options_content_t
)options_handle
;
2560 SEC_PROTOCOL_METADATA_VALIDATE(options_content
, false);
2562 if (metadata_content
->failure
) {
2563 return _serialize_failure_with_options(dictionary
, metadata_content
, options_content
);
2565 return _serialize_success_with_options(dictionary
, metadata_content
, options_content
);
2574 sec_protocol_metadata_copy_quic_transport_parameters(sec_protocol_metadata_t metadata
)
2576 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
2578 __block dispatch_data_t copied_parameters
= NULL
;
2579 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
2580 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
2581 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
2582 if (metadata_content
->quic_transport_parameters
) {
2583 copied_parameters
= metadata_content
->quic_transport_parameters
;
2584 dispatch_retain(copied_parameters
);
2589 return copied_parameters
;
2593 sec_protocol_metadata_get_tls_certificate_compression_used(sec_protocol_metadata_t metadata
)
2595 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
2597 __block
bool certificate_compression_used
= false;
2598 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
2599 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
2600 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
2601 certificate_compression_used
= metadata_content
->certificate_compression_used
;
2605 return certificate_compression_used
;
2609 sec_protocol_metadata_get_tls_certificate_compression_algorithm(sec_protocol_metadata_t metadata
)
2611 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0);
2613 __block
uint16_t certificate_compression_algorithm
= 0;
2614 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
2615 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
2616 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
2617 certificate_compression_algorithm
= metadata_content
->certificate_compression_algorithm
;
2621 return certificate_compression_algorithm
;
2625 sec_protocol_metadata_get_handshake_rtt(sec_protocol_metadata_t metadata
)
2627 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0);
2629 __block
uint64_t rtt
= 0;
2630 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
2631 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
2632 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
2633 rtt
= metadata_content
->handshake_rtt
;
2641 sec_protocol_metadata_copy_sec_trust(sec_protocol_metadata_t metadata
)
2643 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, nil
);
2645 __block sec_trust_t trust
= nil
;
2646 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
2647 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
2648 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
2649 if (metadata_content
->trust_ref
!= nil
) {
2650 trust
= metadata_content
->trust_ref
;
2660 sec_protocol_metadata_copy_sec_identity(sec_protocol_metadata_t metadata
)
2662 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, nil
);
2664 __block sec_identity_t identity
= nil
;
2665 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
2666 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
2667 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
2668 if (metadata_content
->identity
!= nil
) {
2669 identity
= metadata_content
->identity
;
2670 sec_retain(identity
);
2679 sec_protocol_metadata_access_sent_certificates(sec_protocol_metadata_t metadata
,
2680 void (^handler
)(sec_certificate_t certificate
))
2682 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
2683 SEC_PROTOCOL_METADATA_VALIDATE(handler
, false);
2685 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
2686 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
2687 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
2689 if (content
->identity
!= nil
&& sec_identity_has_certificates(content
->identity
)) {
2690 return sec_identity_access_certificates(content
->identity
, handler
);
2693 if (content
->sent_certificate_chain
!= NULL
) {
2694 return sec_array_apply(content
->sent_certificate_chain
, ^bool(__unused
size_t index
, sec_object_t object
) {
2695 handler((sec_certificate_t
)object
);
2705 sec_protocol_metadata_get_tls_negotiated_group(sec_protocol_metadata_t metadata
)
2707 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
2709 __block
const char *negotiated_curve
= NULL
;
2710 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
2711 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
2712 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
2713 negotiated_curve
= content
->negotiated_curve
;
2717 return negotiated_curve
;
2721 sec_retain(void *obj
)
2724 return os_retain(obj
);
2731 sec_release(void *obj
)
2739 sec_protocol_options_create_config(sec_protocol_options_t options
)
2741 SEC_PROTOCOL_METADATA_VALIDATE(options
, NULL
);
2743 __block xpc_object_t dictionary
= xpc_dictionary_create(NULL
, NULL
, 0);
2744 if (dictionary
== NULL
) {
2748 bool serialized
= sec_protocol_options_access_handle(options
, ^bool(void *options_handle
) {
2749 sec_protocol_options_content_t options_content
= (sec_protocol_options_content_t
)options_handle
;
2750 SEC_PROTOCOL_METADATA_VALIDATE(options_content
, false);
2752 return _serialize_options(dictionary
, options_content
);
2756 return dictionary
; // retained reference
2758 xpc_release(dictionary
);
2764 sec_protocol_options_matches_config(sec_protocol_options_t options
, xpc_object_t config
)
2766 SEC_PROTOCOL_METADATA_VALIDATE(options
, false);
2767 SEC_PROTOCOL_METADATA_VALIDATE(config
, false);
2769 if (xpc_get_type(config
) != XPC_TYPE_DICTIONARY
) {
2773 xpc_object_t options_config
= sec_protocol_options_create_config(options
);
2774 if (options_config
== NULL
) {
2778 bool match
= _options_config_matches_partial_config(options_config
, config
);
2779 xpc_release(options_config
);
2785 sec_protocol_options_apply_config(sec_protocol_options_t options
, xpc_object_t config
)
2787 SEC_PROTOCOL_METADATA_VALIDATE(options
, false);
2788 SEC_PROTOCOL_METADATA_VALIDATE(config
, false);
2790 if (xpc_get_type(config
) != XPC_TYPE_DICTIONARY
) {
2794 return _apply_config_options(options
, config
);
2798 sec_protocol_options_set_tls_block_length_padding(sec_protocol_options_t options
, sec_protocol_block_length_padding_t block_length_padding
)
2800 SEC_PROTOCOL_METADATA_VALIDATE(options
, false);
2802 return sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
2803 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
2804 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
2806 content
->tls_block_length_padding
= block_length_padding
;