6 #include <Security/SecProtocolOptions.h>
7 #include <Security/SecProtocolMetadata.h>
8 #include <Security/SecProtocolPriv.h>
9 #include <Security/SecProtocolTypesPriv.h>
10 #include "SecProtocolInternal.h"
12 #include <Security/SecureTransportPriv.h>
14 #include <Security/SecFramework.h>
19 #include <sys/param.h>
21 #define MAX_SEC_PROTOCOL_OPTIONS_KEY_LEN 128
24 #define SEC_PROTOCOL_OPTIONS_KEY_min_version "min_version"
25 #define SEC_PROTOCOL_OPTIONS_KEY_max_version "max_version"
26 #define SEC_PROTOCOL_OPTIONS_KEY_minimum_rsa_key_size "minimum_rsa_key_size"
27 #define SEC_PROTOCOL_OPTIONS_KEY_minimum_ecdsa_key_size "minimum_ecdsa_key_size"
28 #define SEC_PROTOCOL_OPTIONS_KEY_minimum_signature_algorithm "minimum_signature_algorithm"
29 #define SEC_PROTOCOL_OPTIONS_KEY_ats_required "ats_required"
30 #define SEC_PROTOCOL_OPTIONS_KEY_ats_minimum_tls_version_allowed "ats_minimum_tls_version_allowed"
31 #define SEC_PROTOCOL_OPTIONS_KEY_ats_non_pfs_ciphersuite_allowed "ats_non_pfs_ciphersuite_allowed"
32 #define SEC_PROTOCOL_OPTIONS_KEY_trusted_peer_certificate "trusted_peer_certificate"
33 #define SEC_PROTOCOL_OPTIONS_KEY_disable_sni "disable_sni"
34 #define SEC_PROTOCOL_OPTIONS_KEY_enable_fallback_attempt "enable_fallback_attempt"
35 #define SEC_PROTOCOL_OPTIONS_KEY_enable_false_start "enable_false_start"
36 #define SEC_PROTOCOL_OPTIONS_KEY_enable_tickets "enable_tickets"
37 #define SEC_PROTOCOL_OPTIONS_KEY_enable_sct "enable_sct"
38 #define SEC_PROTOCOL_OPTIONS_KEY_enable_ocsp "enable_ocsp"
39 #define SEC_PROTOCOL_OPTIONS_KEY_enforce_ev "enforce_ev"
40 #define SEC_PROTOCOL_OPTIONS_KEY_enable_resumption "enable_resumption"
41 #define SEC_PROTOCOL_OPTIONS_KEY_enable_renegotiation "enable_renegotiation"
42 #define SEC_PROTOCOL_OPTIONS_KEY_enable_early_data "enable_early_data"
43 #define SEC_PROTOCOL_OPTIONS_KEY_peer_authentication_required "peer_authentication_required"
44 #define SEC_PROTOCOL_OPTIONS_KEY_certificate_compression_enabled "certificate_compression_enabled"
45 #define SEC_PROTOCOL_OPTIONS_KEY_tls_SIKE503_exchange_enabled "tls_SIKE503_exchange_enabled"
46 #define SEC_PROTOCOL_OPTIONS_KEY_tls_HRSS_exchange_enabled "tls_HRSS_exchange_enabled"
47 #define SEC_PROTOCOL_OPTIONS_KEY_eddsa_enabled "eddsa_enabled"
48 #define SEC_PROTOCOL_OPTIONS_KEY_tls_delegated_credentials_enabled "tls_delegated_credentials_enabled"
49 #define SEC_PROTOCOL_OPTIONS_KEY_tls_grease_enabled "tls_grease_enabled"
50 #define SEC_PROTOCOL_OPTIONS_KEY_tls_ticket_request_count "tls_ticket_request_count"
51 #define SEC_PROTOCOL_OPTIONS_KEY_ciphersuites "ciphersuites"
54 #define SEC_PROTOCOL_METADATA_KEY_PROCESS_IDENTIFIER "process"
55 #define SEC_PROTOCOL_METADATA_KEY_CIPHERSUITE "cipher_name"
56 #define SEC_PROTOCOL_METADATA_KEY_FALLBACK_ENABLED "fallback"
57 #define SEC_PROTOCOL_METADATA_KEY_DH_GROUP_SIZE "dhe_size"
58 #define SEC_PROTOCOL_METADATA_KEY_NEGOTIATED_CURVE "neg_curve"
59 #define SEC_PROTOCOL_METADATA_KEY_PEER_CERTIFICATE_REQUEST_TYPE "cert_request_type"
60 #define SEC_PROTOCOL_METADATA_KEY_LOCAL_PRIVATE_KEY_TYPE "private_key_type"
61 #define SEC_PROTOCOL_METADATA_KEY_PEER_PUBLIC_KEY_TYPE "peer_public_key_type"
62 #define SEC_PROTOCOL_METADATA_KEY_NEGOTIATED_PROTOCOL "negotiated_protocol"
63 #define SEC_PROTOCOL_METADATA_KEY_ALPN_USED "alpn_used"
64 #define SEC_PROTOCOL_METADATA_KEY_NPN_USED "npn_used"
65 #define SEC_PROTOCOL_METADATA_KEY_PROTOCOL_VERSION "version"
66 #define SEC_PROTOCOL_METADATA_KEY_FALSE_START_ENABLED "false_start_enabled"
67 #define SEC_PROTOCOL_METADATA_KEY_FALSE_START_USED "false_start_used"
68 #define SEC_PROTOCOL_METADATA_KEY_TICKET_OFFERED "ticket_offered"
69 #define SEC_PROTOCOL_METADATA_KEY_TICKET_RECEIVED "ticket_received"
70 #define SEC_PROTOCOL_METADATA_KEY_SESSION_RESUMED "session_resumed"
71 #define SEC_PROTOCOL_METADATA_KEY_SESSION_RENEWED "session_renewed"
72 #define SEC_PROTOCOL_METADATA_KEY_RESUMPTION_ATTEMPTED "resumption_attempted"
73 #define SEC_PROTOCOL_METADATA_KEY_TICKET_LIFETIME "ticket_lifetime"
74 #define SEC_PROTOCOL_METADATA_KEY_MAX_EARLY_DATA_SUPPORTED "max_early_data_supported"
75 #define SEC_PROTOCOL_METADATA_KEY_OCSP_ENABLED "ocsp_enabled"
76 #define SEC_PROTOCOL_METADATA_KEY_OCSP_RECEIVED "ocsp_received"
77 #define SEC_PROTOCOL_METADATA_KEY_SCT_ENABLED "sct_enabled"
78 #define SEC_PROTOCOL_METADATA_KEY_SCT_RECEIVED "sct_received"
79 #define SEC_PROTOCOL_METADATA_KEY_RSA_SIGNATURE_REQUESTED "client_rsa_requested"
80 #define SEC_PROTOCOL_METADATA_KEY_ECDSA_SIGNATURE_REQUESTED "client_ecdsa_requested"
81 #define SEC_PROTOCOL_METADATA_KEY_FAILURE_ALERT_TYPE "alert_type"
82 #define SEC_PROTOCOL_METADATA_KEY_FAILURE_ALERT_CODE "alert_code"
83 #define SEC_PROTOCOL_METADATA_KEY_FAILURE_HANDSHAKE_STATE "handshake_state"
84 #define SEC_PROTOCOL_METADATA_KEY_FAILURE_STACK_ERROR "stack_error"
85 #define SEC_PROTOCOL_METADATA_KEY_DEFAULT_EMPTY_STRING "none"
87 #define CFReleaseSafe(value) \
88 if (value != NULL) { \
93 sec_protocol_options_access_handle(sec_protocol_options_t options
,
94 sec_access_block_t access_block
)
96 static void *libnetworkImage
= NULL
;
97 static dispatch_once_t onceToken
;
98 static bool (*_nw_protocol_options_access_handle
)(void *, sec_access_block_t
) = NULL
;
100 dispatch_once(&onceToken
, ^{
101 libnetworkImage
= dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY
| RTLD_LOCAL
);
102 if (NULL
!= libnetworkImage
) {
103 _nw_protocol_options_access_handle
= (__typeof(_nw_protocol_options_access_handle
))dlsym(libnetworkImage
,
104 "nw_protocol_options_access_handle");
105 if (NULL
== _nw_protocol_options_access_handle
) {
106 os_log_error(OS_LOG_DEFAULT
, "dlsym libnetwork nw_protocol_options_access_handle");
109 os_log_error(OS_LOG_DEFAULT
, "dlopen libnetwork");
113 if (_nw_protocol_options_access_handle
== NULL
) {
117 return _nw_protocol_options_access_handle(options
, access_block
);
121 sec_protocol_metadata_access_handle(sec_protocol_metadata_t options
,
122 sec_access_block_t access_block
)
124 static void *libnetworkImage
= NULL
;
125 static dispatch_once_t onceToken
;
126 static bool (*_nw_protocol_metadata_access_handle
)(void *, sec_access_block_t
) = NULL
;
128 dispatch_once(&onceToken
, ^{
129 libnetworkImage
= dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY
| RTLD_LOCAL
);
130 if (NULL
!= libnetworkImage
) {
131 _nw_protocol_metadata_access_handle
= (__typeof(_nw_protocol_metadata_access_handle
))dlsym(libnetworkImage
,
132 "nw_protocol_metadata_access_handle");
133 if (NULL
== _nw_protocol_metadata_access_handle
) {
134 os_log_error(OS_LOG_DEFAULT
, "dlsym libnetwork _nw_protocol_metadata_access_handle");
137 os_log_error(OS_LOG_DEFAULT
, "dlopen libnetwork");
141 if (_nw_protocol_metadata_access_handle
== NULL
) {
145 return _nw_protocol_metadata_access_handle(options
, access_block
);
148 #define SEC_PROTOCOL_OPTIONS_VALIDATE(o,r) \
153 #define SEC_PROTOCOL_METADATA_VALIDATE(m,r) \
154 if (((void *)m == NULL) || ((size_t)m == 0)) { \
159 sec_protocol_options_contents_are_equal(sec_protocol_options_content_t contentA
, sec_protocol_options_content_t contentB
)
161 if (contentA
== contentB
) {
164 if (contentA
== NULL
|| contentB
== NULL
) {
168 sec_protocol_options_content_t optionsA
= (sec_protocol_options_content_t
)contentA
;
169 sec_protocol_options_content_t optionsB
= (sec_protocol_options_content_t
)contentB
;
171 // Check boolean and primitive field types first
172 #define CHECK_FIELD(field) \
173 if (optionsA->field != optionsB->field) { \
177 CHECK_FIELD(min_version
);
178 CHECK_FIELD(max_version
);
179 CHECK_FIELD(minimum_rsa_key_size
);
180 CHECK_FIELD(minimum_ecdsa_key_size
);
181 CHECK_FIELD(minimum_signature_algorithm
);
182 CHECK_FIELD(tls_ticket_request_count
);
183 CHECK_FIELD(ats_required
);
184 CHECK_FIELD(ats_minimum_tls_version_allowed
);
185 CHECK_FIELD(ats_non_pfs_ciphersuite_allowed
);
186 CHECK_FIELD(trusted_peer_certificate
);
187 CHECK_FIELD(disable_sni
);
188 CHECK_FIELD(enable_fallback_attempt
);
189 CHECK_FIELD(enable_false_start
);
190 CHECK_FIELD(enable_tickets
);
191 CHECK_FIELD(enable_sct
);
192 CHECK_FIELD(enable_ocsp
);
193 CHECK_FIELD(enforce_ev
);
194 CHECK_FIELD(enable_resumption
);
195 CHECK_FIELD(enable_renegotiation
);
196 CHECK_FIELD(enable_early_data
);
197 CHECK_FIELD(peer_authentication_required
);
198 CHECK_FIELD(certificate_compression_enabled
);
199 CHECK_FIELD(tls_SIKE503_exchange_enabled
);
200 CHECK_FIELD(tls_HRSS_exchange_enabled
);
201 CHECK_FIELD(eddsa_enabled
);
202 CHECK_FIELD(tls_delegated_credentials_enabled
);
203 CHECK_FIELD(tls_grease_enabled
);
207 // Check callback block and queue pairs next
208 #define CHECK_BLOCK_QUEUE(block, queue) \
209 if (optionsA->block && optionsB->block) { \
210 if (optionsA->block != optionsB->block) { \
213 if (optionsA->queue != optionsB->queue) { \
216 } else if (optionsA->block || optionsB->block) { \
220 CHECK_BLOCK_QUEUE(key_update_block
, key_update_queue
);
221 CHECK_BLOCK_QUEUE(psk_selection_block
, psk_selection_queue
);
222 CHECK_BLOCK_QUEUE(challenge_block
, challenge_queue
);
223 CHECK_BLOCK_QUEUE(verify_block
, verify_queue
);
224 CHECK_BLOCK_QUEUE(tls_secret_update_block
, tls_secret_update_queue
);
226 #undef CHECK_BLOCK_QUEUE
228 // Deep compare dispatch data fields
229 #define CHECK_DISPATCH_DATA(data) \
230 if (optionsA->data && optionsB->data) { \
231 if (false == sec_protocol_helper_dispatch_data_equal(optionsA->data, optionsB->data)) { \
234 } else if (optionsA->data || optionsB->data) { \
238 CHECK_DISPATCH_DATA(dh_params
);
239 CHECK_DISPATCH_DATA(quic_transport_parameters
);
240 CHECK_DISPATCH_DATA(psk_identity_hint
);
242 #undef CHECK_DISPATCH_DATA
244 // Deep compare XPC objects
245 #define CHECK_XPC_OBJECT(xpc) \
246 if (optionsA->xpc && optionsB->xpc) { \
247 if (false == xpc_equal(optionsA->xpc, optionsB->xpc)) { \
250 } else if (optionsA->xpc || optionsB->xpc) { \
254 CHECK_XPC_OBJECT(application_protocols
);
255 CHECK_XPC_OBJECT(ciphersuites
);
256 CHECK_XPC_OBJECT(key_exchange_groups
);
257 CHECK_XPC_OBJECT(pre_shared_keys
);
259 #undef CHECK_XPC_OBJECT
261 // Deep compare all other fields
262 if (optionsA
->server_name
&& optionsB
->server_name
) {
263 if (0 != strcmp(optionsA
->server_name
, optionsB
->server_name
)) {
266 } else if (optionsA
->server_name
|| optionsB
->server_name
) {
270 if (optionsA
->identity
&& optionsB
->identity
) {
271 SecIdentityRef identityA
= sec_identity_copy_ref((sec_identity_t
)optionsA
->identity
);
272 SecIdentityRef identityB
= sec_identity_copy_ref((sec_identity_t
)optionsB
->identity
);
274 if (false == CFEqual(identityA
, identityB
)) {
278 CFRelease(identityA
);
279 CFRelease(identityB
);
280 } else if (optionsA
->identity
|| optionsB
->identity
) {
284 if (optionsA
->output_handler_access_block
&& optionsB
->output_handler_access_block
) {
285 if (optionsA
->output_handler_access_block
!= optionsB
->output_handler_access_block
) {
288 } else if (optionsA
->output_handler_access_block
|| optionsB
->output_handler_access_block
) {
296 sec_protocol_options_are_equal(sec_protocol_options_t handleA
, sec_protocol_options_t handleB
)
298 if (handleA
== handleB
) {
301 if (handleA
== NULL
|| handleB
== NULL
) {
305 return sec_protocol_options_access_handle(handleA
, ^bool(void *innerA
) {
306 sec_protocol_options_content_t optionsA
= (sec_protocol_options_content_t
)innerA
;
307 return sec_protocol_options_access_handle(handleB
, ^bool(void *innerB
) {
308 sec_protocol_options_content_t optionsB
= (sec_protocol_options_content_t
)innerB
;
309 return sec_protocol_options_contents_are_equal(optionsA
, optionsB
);
315 sec_protocol_options_set_local_identity(sec_protocol_options_t options
, sec_identity_t identity
)
317 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
319 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
320 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
321 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
323 if (content
->identity
!= NULL
) {
324 sec_release(content
->identity
);
326 content
->identity
= sec_retain(identity
);
332 sec_protocol_options_append_tls_ciphersuite(sec_protocol_options_t options
, tls_ciphersuite_t ciphersuite
)
334 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
336 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
337 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
338 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
340 if (content
->ciphersuites
== NULL
) {
341 content
->ciphersuites
= xpc_array_create(NULL
, 0);
343 xpc_array_set_uint64(content
->ciphersuites
, XPC_ARRAY_APPEND
, (uint64_t)ciphersuite
);
349 sec_protocol_options_add_tls_ciphersuite(sec_protocol_options_t options
, SSLCipherSuite ciphersuite
)
351 sec_protocol_options_append_tls_ciphersuite(options
, (tls_ciphersuite_t
)ciphersuite
);
355 sec_protocol_options_append_tls_ciphersuite_group(sec_protocol_options_t options
, tls_ciphersuite_group_t group
)
357 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
359 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
360 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
361 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
363 // Fetch the list of ciphersuites associated with the ciphersuite group
364 size_t ciphersuite_count
= 0;
365 const tls_ciphersuite_t
*list
= sec_protocol_helper_ciphersuite_group_to_ciphersuite_list(group
, &ciphersuite_count
);
367 if (content
->ciphersuites
== NULL
) {
368 content
->ciphersuites
= xpc_array_create(NULL
, 0);
371 for (size_t i
= 0; i
< ciphersuite_count
; i
++) {
372 tls_ciphersuite_t ciphersuite
= list
[i
];
373 xpc_array_set_uint64(content
->ciphersuites
, XPC_ARRAY_APPEND
, (uint64_t)ciphersuite
);
382 sec_protocol_options_add_tls_ciphersuite_group(sec_protocol_options_t options
, SSLCiphersuiteGroup group
)
385 case kSSLCiphersuiteGroupDefault
:
386 return sec_protocol_options_append_tls_ciphersuite_group(options
, tls_ciphersuite_group_default
);
387 case kSSLCiphersuiteGroupCompatibility
:
388 return sec_protocol_options_append_tls_ciphersuite_group(options
, tls_ciphersuite_group_compatibility
);
389 case kSSLCiphersuiteGroupLegacy
:
390 return sec_protocol_options_append_tls_ciphersuite_group(options
, tls_ciphersuite_group_legacy
);
391 case kSSLCiphersuiteGroupATS
:
392 return sec_protocol_options_append_tls_ciphersuite_group(options
, tls_ciphersuite_group_ats
);
393 case kSSLCiphersuiteGroupATSCompatibility
:
394 return sec_protocol_options_append_tls_ciphersuite_group(options
, tls_ciphersuite_group_ats_compatibility
);
399 sec_protocol_options_clear_tls_ciphersuites(sec_protocol_options_t options
)
401 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
403 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
404 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
405 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
407 if (content
->ciphersuites
!= NULL
) {
408 xpc_release(content
->ciphersuites
);
409 content
->ciphersuites
= NULL
;
416 sec_protocol_options_set_tls_min_version(sec_protocol_options_t options
, SSLProtocol version
)
418 tls_protocol_version_t protocol_version
= (tls_protocol_version_t
)SSLProtocolGetVersionCodepoint(version
);
419 if (protocol_version
!= 0) {
420 sec_protocol_options_set_min_tls_protocol_version(options
, protocol_version
);
425 sec_protocol_options_set_min_tls_protocol_version(sec_protocol_options_t options
, tls_protocol_version_t version
)
427 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
429 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
430 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
431 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
433 SSLProtocol converted_protocol
= SSLProtocolFromVersionCodepoint(version
);
434 content
->min_version
= converted_protocol
;
439 tls_protocol_version_t
440 sec_protocol_options_get_default_min_tls_protocol_version(void)
442 return tls_protocol_version_TLSv10
;
445 tls_protocol_version_t
446 sec_protocol_options_get_default_min_dtls_protocol_version(void)
448 return tls_protocol_version_DTLSv10
;
452 sec_protocol_options_set_tls_max_version(sec_protocol_options_t options
, SSLProtocol version
)
454 tls_protocol_version_t protocol_version
= (tls_protocol_version_t
)SSLProtocolGetVersionCodepoint(version
);
455 if (protocol_version
!= 0) {
456 sec_protocol_options_set_max_tls_protocol_version(options
, protocol_version
);
461 sec_protocol_options_set_max_tls_protocol_version(sec_protocol_options_t options
, tls_protocol_version_t version
)
463 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
465 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
466 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
467 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
469 SSLProtocol converted_protocol
= SSLProtocolFromVersionCodepoint(version
);
470 content
->max_version
= converted_protocol
;
475 tls_protocol_version_t
476 sec_protocol_options_get_default_max_tls_protocol_version(void)
478 return tls_protocol_version_TLSv13
;
481 tls_protocol_version_t
482 sec_protocol_options_get_default_max_dtls_protocol_version(void)
484 return tls_protocol_version_DTLSv12
;
488 sec_protocol_options_add_tls_application_protocol(sec_protocol_options_t options
, const char *application_protocol
)
490 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
491 SEC_PROTOCOL_OPTIONS_VALIDATE(application_protocol
,);
493 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
494 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
495 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
497 if (content
->application_protocols
== NULL
) {
498 content
->application_protocols
= xpc_array_create(NULL
, 0);
500 xpc_array_set_string(content
->application_protocols
, XPC_ARRAY_APPEND
, application_protocol
);
506 sec_protocol_options_set_tls_server_name(sec_protocol_options_t options
, const char *server_name
)
508 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
509 SEC_PROTOCOL_OPTIONS_VALIDATE(server_name
,);
511 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
512 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
513 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
515 CFStringRef serverName
= CFStringCreateWithCString(NULL
, server_name
, kCFStringEncodingUTF8
);
516 if (serverName
== NULL
) {
519 if (!SecFrameworkIsDNSName(serverName
)) {
520 CFRelease(serverName
);
523 CFRelease(serverName
);
525 free(content
->server_name
);
526 content
->server_name
= strdup(server_name
);
532 sec_protocol_options_set_tls_diffie_hellman_parameters(sec_protocol_options_t options
, dispatch_data_t params
)
534 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
535 SEC_PROTOCOL_OPTIONS_VALIDATE(params
,);
537 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
538 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
539 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
541 if (content
->dh_params
) {
542 dispatch_release(content
->dh_params
);
544 content
->dh_params
= params
;
545 dispatch_retain(params
);
551 sec_protocol_options_add_pre_shared_key(sec_protocol_options_t options
, dispatch_data_t psk
, dispatch_data_t psk_identity
)
553 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
554 SEC_PROTOCOL_OPTIONS_VALIDATE(psk
,);
555 SEC_PROTOCOL_OPTIONS_VALIDATE(psk_identity
,);
557 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
558 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
559 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
561 if (content
->pre_shared_keys
== NULL
) {
562 content
->pre_shared_keys
= xpc_array_create(NULL
, 0);
565 xpc_object_t psk_data
= xpc_data_create_with_dispatch_data(psk
);
566 xpc_object_t psk_identity_data
= xpc_data_create_with_dispatch_data(psk_identity
);
568 xpc_object_t tuple
= xpc_array_create(NULL
, 0);
569 xpc_array_set_value(tuple
, XPC_ARRAY_APPEND
, psk_data
);
570 xpc_array_set_value(tuple
, XPC_ARRAY_APPEND
, psk_identity_data
);
571 xpc_release(psk_data
);
572 xpc_release(psk_identity_data
);
574 xpc_array_set_value(content
->pre_shared_keys
, XPC_ARRAY_APPEND
, tuple
);
581 sec_protocol_options_set_tls_pre_shared_key_identity_hint(sec_protocol_options_t options
, dispatch_data_t psk_identity_hint
)
583 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
584 SEC_PROTOCOL_OPTIONS_VALIDATE(psk_identity_hint
,);
586 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
587 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
588 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
590 if (content
->psk_identity_hint
!= NULL
) {
591 dispatch_release(content
->psk_identity_hint
);
594 content
->psk_identity_hint
= psk_identity_hint
;
595 dispatch_retain(psk_identity_hint
);
601 sec_protocol_options_set_pre_shared_key_selection_block(sec_protocol_options_t options
, sec_protocol_pre_shared_key_selection_t psk_selection_block
, dispatch_queue_t psk_selection_queue
)
603 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
604 SEC_PROTOCOL_OPTIONS_VALIDATE(psk_selection_block
,);
605 SEC_PROTOCOL_OPTIONS_VALIDATE(psk_selection_queue
,);
607 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
608 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
609 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
611 if (content
->psk_selection_block
!= NULL
) {
612 Block_release(content
->psk_selection_block
);
614 if (content
->psk_selection_queue
!= NULL
) {
615 dispatch_release(content
->psk_selection_queue
);
618 content
->psk_selection_block
= Block_copy(psk_selection_block
);
619 content
->psk_selection_queue
= psk_selection_queue
;
620 dispatch_retain(content
->psk_selection_queue
);
626 sec_protocol_options_set_tls_is_fallback_attempt(sec_protocol_options_t options
, bool fallback_attempt
)
628 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
630 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
631 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
632 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
634 content
->enable_fallback_attempt
= fallback_attempt
;
635 content
->enable_fallback_attempt_override
= true;
641 sec_protocol_options_set_tls_tickets_enabled(sec_protocol_options_t options
, bool tickets_enabled
)
643 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
645 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
646 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
647 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
649 content
->enable_tickets
= tickets_enabled
;
650 content
->enable_tickets_override
= true;
656 sec_protocol_options_set_tls_resumption_enabled(sec_protocol_options_t options
, bool resumption_enabled
)
658 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
660 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
661 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
662 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
664 content
->enable_resumption
= resumption_enabled
;
665 content
->enable_resumption_override
= true;
671 sec_protocol_options_set_tls_false_start_enabled(sec_protocol_options_t options
, bool false_start_enabled
)
673 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
675 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
676 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
677 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
679 content
->enable_false_start
= false_start_enabled
;
680 content
->enable_false_start_override
= true;
686 sec_protocol_options_set_tls_early_data_enabled(sec_protocol_options_t options
, bool early_data_enabled
)
688 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
690 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
691 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
692 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
694 content
->enable_early_data
= early_data_enabled
;
695 content
->enable_early_data_override
= true;
701 sec_protocol_options_set_tls_sni_disabled(sec_protocol_options_t options
, bool sni_disabled
)
703 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
705 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
706 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
707 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
709 content
->disable_sni
= sni_disabled
;
710 content
->disable_sni_override
= true;
716 sec_protocol_options_set_enforce_ev(sec_protocol_options_t options
, bool enforce_ev
)
718 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
720 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
721 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
722 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
724 content
->enforce_ev
= enforce_ev
;
725 content
->enforce_ev_override
= true;
731 sec_protocol_options_set_tls_ocsp_enabled(sec_protocol_options_t options
, bool ocsp_enabled
)
733 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
735 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
736 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
737 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
739 content
->enable_ocsp
= ocsp_enabled
;
740 content
->enable_ocsp_override
= true;
746 sec_protocol_options_set_tls_sct_enabled(sec_protocol_options_t options
, bool sct_enabled
)
748 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
750 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
751 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
752 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
754 content
->enable_sct
= sct_enabled
;
755 content
->enable_sct_override
= true;
761 sec_protocol_options_set_tls_renegotiation_enabled(sec_protocol_options_t options
, bool renegotiation_enabled
)
763 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
765 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
766 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
767 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
769 content
->enable_renegotiation
= renegotiation_enabled
;
770 content
->enable_renegotiation_override
= true;
776 sec_protocol_options_set_peer_authentication_required(sec_protocol_options_t options
, bool peer_authentication_required
)
778 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
780 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
781 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
782 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
784 content
->peer_authentication_required
= peer_authentication_required
;
785 content
->peer_authentication_override
= true;
791 sec_protocol_options_set_key_update_block(sec_protocol_options_t options
, sec_protocol_key_update_t update_block
, dispatch_queue_t update_queue
)
793 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
794 SEC_PROTOCOL_OPTIONS_VALIDATE(update_queue
,);
796 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
797 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
798 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
800 if (content
->key_update_block
!= NULL
) {
801 Block_release(content
->key_update_block
);
803 if (content
->key_update_queue
!= NULL
) {
804 dispatch_release(content
->key_update_queue
);
807 content
->key_update_block
= Block_copy(update_block
);
808 content
->key_update_queue
= Block_copy(update_queue
);
809 dispatch_retain(content
->key_update_queue
);
815 sec_protocol_options_set_challenge_block(sec_protocol_options_t options
, sec_protocol_challenge_t challenge_block
, dispatch_queue_t challenge_queue
)
817 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
818 SEC_PROTOCOL_OPTIONS_VALIDATE(challenge_queue
,);
820 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
821 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
822 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
824 if (content
->challenge_block
!= NULL
) {
825 Block_release(content
->challenge_block
);
827 if (content
->challenge_queue
!= NULL
) {
828 dispatch_release(content
->challenge_queue
);
831 content
->challenge_block
= Block_copy(challenge_block
);
832 content
->challenge_queue
= challenge_queue
;
833 dispatch_retain(content
->challenge_queue
);
839 sec_protocol_options_set_verify_block(sec_protocol_options_t options
, sec_protocol_verify_t verify_block
, dispatch_queue_t verify_queue
)
841 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
842 SEC_PROTOCOL_OPTIONS_VALIDATE(verify_queue
,);
844 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
845 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
846 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
848 if (content
->verify_block
!= NULL
) {
849 Block_release(content
->verify_block
);
851 if (content
->verify_queue
!= NULL
) {
852 dispatch_release(content
->verify_queue
);
855 content
->verify_block
= Block_copy(verify_block
);
856 content
->verify_queue
= verify_queue
;
857 dispatch_retain(content
->verify_queue
);
863 sec_protocol_options_set_session_update_block(sec_protocol_options_t options
, sec_protocol_session_update_t update_block
, dispatch_queue_t update_queue
)
865 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
866 SEC_PROTOCOL_OPTIONS_VALIDATE(update_block
,);
867 SEC_PROTOCOL_OPTIONS_VALIDATE(update_queue
,);
869 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
870 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
871 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
873 if (content
->session_update_block
!= NULL
) {
874 Block_release(content
->session_update_block
);
876 if (content
->session_update_queue
!= NULL
) {
877 dispatch_release(content
->session_update_queue
);
880 content
->session_update_block
= Block_copy(update_block
);
881 content
->session_update_queue
= update_queue
;
882 dispatch_retain(content
->session_update_queue
);
888 sec_protocol_options_set_tls_encryption_secret_update_block(sec_protocol_options_t options
, sec_protocol_tls_encryption_secret_update_t update_block
, dispatch_queue_t update_queue
)
890 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
891 SEC_PROTOCOL_OPTIONS_VALIDATE(update_block
,);
892 SEC_PROTOCOL_OPTIONS_VALIDATE(update_queue
,);
894 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
895 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
896 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
898 if (content
->tls_secret_update_block
!= NULL
) {
899 Block_release(content
->tls_secret_update_block
);
901 if (content
->tls_secret_update_queue
!= NULL
) {
902 dispatch_release(content
->tls_secret_update_queue
);
905 content
->tls_secret_update_block
= Block_copy(update_block
);
906 content
->tls_secret_update_queue
= update_queue
;
907 dispatch_retain(content
->tls_secret_update_queue
);
913 sec_protocol_options_set_session_state(sec_protocol_options_t options
, dispatch_data_t session_state
)
915 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
916 SEC_PROTOCOL_OPTIONS_VALIDATE(session_state
,);
918 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
919 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
920 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
922 if (content
->session_state
!= NULL
) {
923 dispatch_release(content
->session_state
);
926 content
->session_state
= session_state
;
927 dispatch_retain(session_state
);
933 sec_protocol_options_set_quic_transport_parameters(sec_protocol_options_t options
, dispatch_data_t transport_parameters
)
935 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
936 SEC_PROTOCOL_OPTIONS_VALIDATE(transport_parameters
,);
938 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
939 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
940 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
942 if (content
->quic_transport_parameters
!= NULL
) {
943 dispatch_release(content
->quic_transport_parameters
);
946 content
->quic_transport_parameters
= transport_parameters
;
947 dispatch_retain(transport_parameters
);
953 sec_protocol_options_set_ats_required(sec_protocol_options_t options
, bool required
)
955 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
957 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
958 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
959 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
961 content
->ats_required
= required
;
967 sec_protocol_options_set_minimum_rsa_key_size(sec_protocol_options_t options
, size_t minimum_key_size
)
969 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
971 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
972 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
973 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
975 content
->minimum_rsa_key_size
= minimum_key_size
;
981 sec_protocol_options_set_minimum_ecdsa_key_size(sec_protocol_options_t options
, size_t minimum_key_size
)
983 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
985 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
986 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
987 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
989 content
->minimum_ecdsa_key_size
= minimum_key_size
;
995 sec_protocol_options_set_minimum_signature_algorithm(sec_protocol_options_t options
, SecSignatureHashAlgorithm algorithm
)
997 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
999 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1000 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1001 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1003 content
->minimum_signature_algorithm
= algorithm
;
1009 sec_protocol_options_set_trusted_peer_certificate(sec_protocol_options_t options
, bool trusted_peer_certificate
)
1011 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1013 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1014 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1015 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1017 content
->trusted_peer_certificate
= trusted_peer_certificate
;
1018 content
->trusted_peer_certificate_override
= true;
1024 sec_protocol_options_set_private_key_blocks(sec_protocol_options_t options
,
1025 sec_protocol_private_key_sign_t sign_block
,
1026 sec_protocol_private_key_decrypt_t decrypt_block
,
1027 dispatch_queue_t operation_queue
)
1029 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1030 SEC_PROTOCOL_OPTIONS_VALIDATE(sign_block
,);
1031 SEC_PROTOCOL_OPTIONS_VALIDATE(decrypt_block
,);
1032 SEC_PROTOCOL_OPTIONS_VALIDATE(operation_queue
,);
1034 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1035 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1036 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1038 if (content
->private_key_sign_block
!= NULL
) {
1039 Block_release(content
->private_key_sign_block
);
1041 if (content
->private_key_decrypt_block
!= NULL
) {
1042 Block_release(content
->private_key_decrypt_block
);
1044 if (content
->private_key_queue
!= NULL
) {
1045 dispatch_release(content
->private_key_queue
);
1048 content
->private_key_sign_block
= Block_copy(sign_block
);
1049 content
->private_key_decrypt_block
= Block_copy(decrypt_block
);
1050 content
->private_key_queue
= operation_queue
;
1051 dispatch_retain(content
->private_key_queue
);
1058 sec_protocol_options_set_local_certificates(sec_protocol_options_t options
, sec_array_t certificates
)
1060 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1061 SEC_PROTOCOL_OPTIONS_VALIDATE(certificates
,);
1063 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1064 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1065 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1067 if (content
->certificates
!= NULL
) {
1068 sec_release(content
->certificates
);
1071 content
->certificates
= certificates
;
1072 sec_retain(content
->certificates
);
1078 sec_protocol_options_set_tls_certificate_compression_enabled(sec_protocol_options_t options
, bool certificate_compression_enabled
)
1080 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1082 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1083 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1084 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1086 content
->certificate_compression_enabled
= certificate_compression_enabled
;
1092 sec_protocol_options_set_output_handler_access_block(sec_protocol_options_t options
,
1093 sec_protocol_output_handler_access_block_t access_block
)
1095 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1096 SEC_PROTOCOL_OPTIONS_VALIDATE(access_block
,);
1098 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1099 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1100 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1102 content
->output_handler_access_block
= Block_copy(access_block
);
1108 sec_protocol_options_tls_handshake_message_callback(sec_protocol_options_t options
, sec_protocol_tls_handshake_message_handler_t handler
, dispatch_queue_t queue
)
1110 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1111 SEC_PROTOCOL_OPTIONS_VALIDATE(handler
,);
1112 SEC_PROTOCOL_OPTIONS_VALIDATE(queue
,);
1114 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1115 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1116 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1118 if (content
->handshake_message_callback
!= NULL
) {
1119 Block_release(content
->handshake_message_callback
);
1121 if (content
->handshake_message_callback_queue
!= NULL
) {
1122 dispatch_release(content
->handshake_message_callback_queue
);
1125 content
->handshake_message_callback
= Block_copy(handler
);
1126 content
->handshake_message_callback_queue
= queue
;
1127 dispatch_retain(content
->handshake_message_callback_queue
);
1134 sec_protocol_options_set_tls_SIKE503_exchange_enabled(sec_protocol_options_t options
, bool tls_SIKE503_exchange_enabled
)
1136 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1138 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1139 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1140 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1142 content
->tls_SIKE503_exchange_enabled
= tls_SIKE503_exchange_enabled
;
1148 sec_protocol_options_set_tls_HRSS_exchange_enabled(sec_protocol_options_t options
, bool tls_HRSS_exchange_enabled
)
1150 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1152 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1153 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1154 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1156 content
->tls_HRSS_exchange_enabled
= tls_HRSS_exchange_enabled
;
1162 sec_protocol_options_set_eddsa_enabled(sec_protocol_options_t options
, bool eddsa_enabled
)
1164 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1166 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1167 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1168 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1170 content
->eddsa_enabled
= eddsa_enabled
;
1176 sec_protocol_options_set_tls_delegated_credentials_enabled(sec_protocol_options_t options
, bool tls_delegated_credentials_enabled
)
1178 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1180 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1181 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1182 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1184 content
->tls_delegated_credentials_enabled
= tls_delegated_credentials_enabled
;
1190 sec_protocol_options_set_tls_grease_enabled(sec_protocol_options_t options
, bool tls_grease_enabled
)
1192 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1194 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1195 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1196 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1198 content
->tls_grease_enabled
= tls_grease_enabled
;
1204 sec_protocol_options_set_tls_ticket_request_count(sec_protocol_options_t options
, uint8_t tls_ticket_request_count
)
1206 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1208 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1209 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1210 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1212 content
->tls_ticket_request_count
= tls_ticket_request_count
;
1218 sec_protocol_options_set_ats_non_pfs_ciphersuite_allowed(sec_protocol_options_t options
, bool ats_non_pfs_ciphersuite_allowed
)
1220 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1222 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1223 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1224 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1226 content
->ats_non_pfs_ciphersuite_allowed
= ats_non_pfs_ciphersuite_allowed
;
1232 sec_protocol_options_set_ats_minimum_tls_version_allowed(sec_protocol_options_t options
, bool ats_minimum_tls_version_allowed
)
1234 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1236 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1237 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1238 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1240 content
->ats_minimum_tls_version_allowed
= ats_minimum_tls_version_allowed
;
1246 sec_protocol_options_append_tls_key_exchange_group(sec_protocol_options_t options
, tls_key_exchange_group_t group
)
1248 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1250 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1251 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1252 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1254 if (content
->key_exchange_groups
== NULL
) {
1255 content
->key_exchange_groups
= xpc_array_create(NULL
, 0);
1257 xpc_array_set_uint64(content
->key_exchange_groups
, XPC_ARRAY_APPEND
, (uint64_t)group
);
1263 sec_protocol_options_add_tls_key_exchange_group(sec_protocol_options_t options
, SSLKeyExchangeGroup group
)
1265 return sec_protocol_options_append_tls_key_exchange_group(options
, (tls_key_exchange_group_t
)group
);
1269 sec_protocol_options_append_tls_key_exchange_group_set(sec_protocol_options_t options
, tls_key_exchange_group_set_t set
)
1271 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
1273 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
1274 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
1275 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
1277 if (content
->key_exchange_groups
== NULL
) {
1278 content
->key_exchange_groups
= xpc_array_create(NULL
, 0);
1281 // Fetch the list of ciphersuites associated with the ciphersuite group
1282 size_t group_set_count
= 0;
1283 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
);
1284 if (group_set
!= NULL
) {
1285 for (size_t i
= 0; i
< group_set_count
; i
++) {
1286 tls_key_exchange_group_t group
= group_set
[i
];
1287 xpc_array_set_uint64(content
->key_exchange_groups
, XPC_ARRAY_APPEND
, (uint64_t)group
);
1296 sec_protocol_options_add_tls_key_exchange_group_set(sec_protocol_options_t options
, SSLKeyExchangeGroupSet set
)
1299 case kSSLKeyExchangeGroupSetDefault
:
1300 sec_protocol_options_append_tls_key_exchange_group_set(options
, tls_key_exchange_group_set_default
);
1302 case kSSLKeyExchangeGroupSetCompatibility
:
1303 sec_protocol_options_append_tls_key_exchange_group_set(options
, tls_key_exchange_group_set_compatibility
);
1305 case kSSLKeyExchangeGroupSetLegacy
:
1306 sec_protocol_options_append_tls_key_exchange_group_set(options
, tls_key_exchange_group_set_legacy
);
1312 sec_protocol_metadata_get_negotiated_protocol(sec_protocol_metadata_t metadata
)
1314 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
1316 __block
const char *negotiated_protocol
= NULL
;
1317 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1318 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1319 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1320 negotiated_protocol
= content
->negotiated_protocol
;
1324 return negotiated_protocol
;
1328 sec_protocol_metadata_get_server_name(sec_protocol_metadata_t metadata
)
1330 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
1332 __block
const char *server_name
= NULL
;
1333 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1334 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1335 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1336 server_name
= content
->server_name
;
1344 sec_protocol_metadata_get_handshake_time_ms(sec_protocol_metadata_t metadata
)
1346 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0);
1348 __block
uint64_t time
= 0;
1349 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
1350 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
1351 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
1352 time
= metadata_content
->handshake_time
;
1360 sec_protocol_metadata_get_handshake_byte_count(sec_protocol_metadata_t metadata
)
1362 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0);
1364 __block
uint64_t count
= 0;
1365 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
1366 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
1367 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
1368 count
= metadata_content
->total_byte_count
;
1376 sec_protocol_metadata_get_handshake_sent_byte_count(sec_protocol_metadata_t metadata
)
1378 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0);
1380 __block
uint64_t count
= 0;
1381 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
1382 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
1383 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
1384 count
= metadata_content
->sent_byte_count
;
1392 sec_protocol_metadata_get_handshake_received_byte_count(sec_protocol_metadata_t metadata
)
1394 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0);
1396 __block
uint64_t count
= 0;
1397 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
1398 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
1399 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
1400 count
= metadata_content
->received_byte_count
;
1408 sec_protocol_metadata_get_handshake_read_stall_count(sec_protocol_metadata_t metadata
)
1410 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0);
1412 __block
size_t count
= 0;
1413 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
1414 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
1415 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
1416 count
= metadata_content
->read_stall_count
;
1424 sec_protocol_metadata_get_handshake_write_stall_count(sec_protocol_metadata_t metadata
)
1426 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0);
1428 __block
size_t count
= 0;
1429 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
1430 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
1431 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
1432 count
= metadata_content
->write_stall_count
;
1440 sec_protocol_metadata_get_handshake_async_call_count(sec_protocol_metadata_t metadata
)
1442 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0);
1444 __block
size_t count
= 0;
1445 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
1446 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
1447 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
1448 count
= metadata_content
->async_call_count
;
1456 sec_protocol_metadata_access_peer_certificate_chain(sec_protocol_metadata_t metadata
,
1457 void (^handler
)(sec_certificate_t certficate
))
1459 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
1460 SEC_PROTOCOL_METADATA_VALIDATE(handler
, false);
1462 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1463 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1464 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1465 if (content
->peer_certificate_chain
== NULL
) {
1468 sec_array_t array
= content
->peer_certificate_chain
;
1469 sec_array_apply(array
, ^bool(__unused
size_t index
, sec_object_t object
) {
1470 handler((sec_certificate_t
)object
);
1478 sec_protocol_metadata_copy_peer_public_key(sec_protocol_metadata_t metadata
)
1480 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
1482 __block dispatch_data_t peer_public_key
= NULL
;
1483 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1484 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1485 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1486 peer_public_key
= ((dispatch_data_t
)content
->peer_public_key
);
1487 if (peer_public_key
) {
1488 dispatch_retain(peer_public_key
);
1493 return peer_public_key
;
1496 tls_protocol_version_t
1497 sec_protocol_metadata_get_negotiated_tls_protocol_version(sec_protocol_metadata_t metadata
)
1499 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0x0000);
1501 __block tls_protocol_version_t protocol_version
= 0x0000;
1502 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1503 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1504 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1505 protocol_version
= SSLProtocolGetVersionCodepoint(content
->negotiated_protocol_version
);
1509 return protocol_version
;
1513 sec_protocol_metadata_get_negotiated_protocol_version(sec_protocol_metadata_t metadata
)
1515 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, kSSLProtocolUnknown
);
1517 __block SSLProtocol protocol_version
= kSSLProtocolUnknown
;
1518 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1519 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1520 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1521 protocol_version
= content
->negotiated_protocol_version
;
1525 return protocol_version
;
1529 sec_protocol_metadata_get_negotiated_tls_ciphersuite(sec_protocol_metadata_t metadata
)
1531 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0xFFFF);
1533 __block tls_ciphersuite_t negotiated_ciphersuite
= SSL_NO_SUCH_CIPHERSUITE
;
1534 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1535 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1536 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1537 negotiated_ciphersuite
= content
->negotiated_ciphersuite
;
1541 return negotiated_ciphersuite
;
1545 sec_protocol_metadata_get_negotiated_ciphersuite(sec_protocol_metadata_t metadata
)
1547 return (SSLCipherSuite
)sec_protocol_metadata_get_negotiated_tls_ciphersuite(metadata
);
1551 sec_protocol_metadata_get_early_data_accepted(sec_protocol_metadata_t metadata
)
1553 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
1555 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1556 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1557 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1558 return content
->early_data_accepted
;
1563 sec_protocol_metadata_access_supported_signature_algorithms(sec_protocol_metadata_t metadata
,
1564 void (^handler
)(uint16_t signature_algorithm
))
1566 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
1567 SEC_PROTOCOL_METADATA_VALIDATE(handler
, false);
1569 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1570 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1571 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1572 if (content
->supported_signature_algorithms
== NULL
) {
1575 xpc_object_t array
= content
->supported_signature_algorithms
;
1576 xpc_array_apply(array
, ^bool(__unused
size_t index
, xpc_object_t _Nonnull value
) {
1577 handler((uint16_t)xpc_uint64_get_value(value
));
1585 sec_protocol_metadata_access_ocsp_response(sec_protocol_metadata_t metadata
,
1586 void (^handler
)(dispatch_data_t ocsp_data
))
1588 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
1589 SEC_PROTOCOL_METADATA_VALIDATE(handler
, false);
1591 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1592 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1593 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1594 if (content
->ocsp_response
== NULL
) {
1597 sec_array_t array
= content
->ocsp_response
;
1598 sec_array_apply(array
, ^bool(__unused
size_t index
, sec_object_t object
) {
1599 handler((dispatch_data_t
)object
);
1607 sec_protocol_metadata_access_distinguished_names(sec_protocol_metadata_t metadata
,
1608 void (^handler
)(dispatch_data_t distinguished_name
))
1610 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
1611 SEC_PROTOCOL_METADATA_VALIDATE(handler
, false);
1613 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1614 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1615 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1616 if (content
->distinguished_names
== NULL
) {
1619 sec_array_t array
= content
->distinguished_names
;
1620 sec_array_apply(array
, ^bool(__unused
size_t index
, sec_object_t object
) {
1621 handler((dispatch_data_t
)object
);
1628 static dispatch_data_t
1629 create_dispatch_data_from_xpc_data(xpc_object_t xpc_data
)
1635 size_t data_len
= xpc_data_get_length(xpc_data
);
1636 if (data_len
== 0) {
1640 uint8_t *data_buffer
= malloc(data_len
);
1645 size_t copied_count
= xpc_data_get_bytes(xpc_data
, data_buffer
, 0, data_len
);
1646 if (copied_count
!= data_len
) {
1651 dispatch_data_t data
= dispatch_data_create(data_buffer
, data_len
, NULL
, DISPATCH_DATA_DESTRUCTOR_DEFAULT
);
1658 sec_protocol_metadata_access_pre_shared_keys(sec_protocol_metadata_t metadata
,
1659 void (^handler
)(dispatch_data_t psk
, dispatch_data_t _Nullable psk_identity
))
1661 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
1662 SEC_PROTOCOL_METADATA_VALIDATE(handler
, false);
1664 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1665 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1666 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1667 if (content
->pre_shared_keys
== NULL
) {
1670 xpc_array_apply(content
->pre_shared_keys
, ^bool(size_t index
, xpc_object_t _Nonnull tuple
) {
1671 if (xpc_array_get_count(tuple
) == 2) {
1672 xpc_object_t xpc_psk_data
= xpc_array_get_value(tuple
, 0);
1673 xpc_object_t xpc_psk_identity_data
= xpc_array_get_value(tuple
, 1);
1675 dispatch_data_t psk_data
= create_dispatch_data_from_xpc_data(xpc_psk_data
);
1676 dispatch_data_t psk_identity_data
= create_dispatch_data_from_xpc_data(xpc_psk_identity_data
);
1677 if (!psk_data
|| !psk_identity_data
) {
1678 // Skip and return early if we can't create a PSK or identity from the provided data. Something's wrong.
1682 handler(psk_data
, psk_identity_data
);
1691 sec_protocol_dispatch_data_are_equal(dispatch_data_t left
, dispatch_data_t right
)
1693 if (!left
|| !right
|| left
== right
) {
1694 return left
== right
;
1696 if (dispatch_data_get_size(left
) != dispatch_data_get_size(right
)) {
1700 __block
bool equal
= true;
1701 dispatch_data_apply(left
, ^bool(__unused dispatch_data_t _Nonnull lregion
, size_t loffset
, const void * _Nonnull lbuffer
, size_t lsize
) {
1702 dispatch_data_apply(right
, ^bool(__unused dispatch_data_t _Nonnull rregion
, size_t roffset
, const void * _Nonnull rbuffer
, size_t rsize
) {
1703 // There is some overlap
1704 const size_t start
= MAX(loffset
, roffset
);
1705 const size_t end
= MIN(loffset
+ lsize
, roffset
+ rsize
);
1707 equal
= memcmp(&((const uint8_t*)rbuffer
)[start
- roffset
], &((const uint8_t*)lbuffer
)[start
- loffset
], end
- start
) == 0;
1709 if (roffset
> loffset
+ lsize
) {
1710 // Iteration of right has gone past where we're at on left, bail out of inner apply
1714 } else if (roffset
+ rsize
< loffset
) {
1715 // Iteration of right has not yet reached where we're at on left, keep going
1729 sec_protocol_sec_array_of_dispatch_data_are_equal(sec_array_t arrayA
, sec_array_t arrayB
)
1731 if (sec_array_get_count(arrayA
) != sec_array_get_count(arrayB
)) {
1735 __block
bool equal
= true;
1736 (void)sec_array_apply(arrayA
, ^bool(size_t indexA
, sec_object_t objectA
) {
1737 return sec_array_apply(arrayB
, ^bool(size_t indexB
, sec_object_t objectB
) {
1738 if (indexA
== indexB
) {
1739 dispatch_data_t dataA
= (dispatch_data_t
)objectA
;
1740 dispatch_data_t dataB
= (dispatch_data_t
)objectB
;
1741 equal
&= sec_protocol_dispatch_data_are_equal(dataA
, dataB
);
1752 sec_protocol_sec_array_of_sec_certificate_are_equal(sec_array_t arrayA
, sec_array_t arrayB
)
1754 if (sec_array_get_count(arrayA
) != sec_array_get_count(arrayB
)) {
1758 __block
bool equal
= true;
1759 (void)sec_array_apply(arrayA
, ^bool(size_t indexA
, sec_object_t objectA
) {
1760 return sec_array_apply(arrayB
, ^bool(size_t indexB
, sec_object_t objectB
) {
1761 if (indexA
== indexB
) {
1762 sec_certificate_t certA
= (sec_certificate_t
)objectA
;
1763 sec_certificate_t certB
= (sec_certificate_t
)objectB
;
1765 SecCertificateRef certRefA
= sec_certificate_copy_ref(certA
);
1766 SecCertificateRef certRefB
= sec_certificate_copy_ref(certB
);
1768 if (certRefA
== NULL
&& certRefB
!= NULL
) {
1770 } else if (certRefA
!= NULL
&& certRefB
== NULL
) {
1772 } else if (certRefA
== NULL
&& certRefB
== NULL
) {
1775 equal
&= CFEqual(certRefA
, certRefB
);
1778 CFReleaseSafe(certRefA
);
1779 CFReleaseSafe(certRefB
);
1791 sec_protocol_xpc_object_are_equal(xpc_object_t objectA
, xpc_object_t objectB
)
1793 if (objectA
== NULL
&& objectB
!= NULL
) {
1795 } else if (objectA
!= NULL
&& objectB
== NULL
) {
1797 } else if (objectA
== NULL
&& objectB
== NULL
) {
1800 return xpc_equal(objectA
, objectB
);
1805 sec_protocol_metadata_peers_are_equal(sec_protocol_metadata_t metadataA
, sec_protocol_metadata_t metadataB
)
1807 SEC_PROTOCOL_METADATA_VALIDATE(metadataA
, false);
1808 SEC_PROTOCOL_METADATA_VALIDATE(metadataB
, false);
1810 return sec_protocol_metadata_access_handle(metadataA
, ^bool(void *handleA
) {
1811 sec_protocol_metadata_content_t contentA
= (sec_protocol_metadata_content_t
)handleA
;
1812 SEC_PROTOCOL_METADATA_VALIDATE(contentA
, false);
1814 return sec_protocol_metadata_access_handle(metadataB
, ^bool(void *handleB
) {
1815 sec_protocol_metadata_content_t contentB
= (sec_protocol_metadata_content_t
)handleB
;
1816 SEC_PROTOCOL_METADATA_VALIDATE(contentB
, false);
1818 // Relevant peer information includes: Certificate chain, public key, support signature algorithms, OCSP response, and distinguished names
1819 if (!sec_protocol_sec_array_of_sec_certificate_are_equal(contentA
->peer_certificate_chain
, contentB
->peer_certificate_chain
)) {
1822 if (!sec_protocol_dispatch_data_are_equal((dispatch_data_t
)contentA
->peer_public_key
, (dispatch_data_t
)contentB
->peer_public_key
)) {
1825 if (!sec_protocol_xpc_object_are_equal((xpc_object_t
)contentA
->supported_signature_algorithms
, (xpc_object_t
)contentB
->supported_signature_algorithms
)) {
1828 if (!sec_protocol_sec_array_of_dispatch_data_are_equal(contentA
->ocsp_response
, contentB
->ocsp_response
)) {
1831 if (!sec_protocol_sec_array_of_dispatch_data_are_equal(contentA
->distinguished_names
, contentB
->distinguished_names
)) {
1841 sec_protocol_metadata_challenge_parameters_are_equal(sec_protocol_metadata_t metadataA
, sec_protocol_metadata_t metadataB
)
1843 SEC_PROTOCOL_METADATA_VALIDATE(metadataA
, false);
1844 SEC_PROTOCOL_METADATA_VALIDATE(metadataB
, false);
1846 return sec_protocol_metadata_access_handle(metadataA
, ^bool(void *handleA
) {
1847 sec_protocol_metadata_content_t contentA
= (sec_protocol_metadata_content_t
)handleA
;
1848 SEC_PROTOCOL_METADATA_VALIDATE(contentA
, false);
1850 return sec_protocol_metadata_access_handle(metadataB
, ^bool(void *handleB
) {
1851 sec_protocol_metadata_content_t contentB
= (sec_protocol_metadata_content_t
)handleB
;
1852 SEC_PROTOCOL_METADATA_VALIDATE(contentB
, false);
1854 if (!sec_protocol_xpc_object_are_equal((xpc_object_t
)contentA
->supported_signature_algorithms
, (xpc_object_t
)contentB
->supported_signature_algorithms
)) {
1857 if (!sec_protocol_sec_array_of_dispatch_data_are_equal(contentA
->distinguished_names
, contentB
->distinguished_names
)) {
1860 if (!sec_protocol_dispatch_data_are_equal(contentA
->request_certificate_types
, contentB
->request_certificate_types
)) {
1870 sec_protocol_metadata_create_secret(sec_protocol_metadata_t metadata
, size_t label_len
,
1871 const char *label
, size_t exporter_length
)
1873 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
1874 SEC_PROTOCOL_METADATA_VALIDATE(label_len
, NULL
);
1875 SEC_PROTOCOL_METADATA_VALIDATE(label
, NULL
);
1876 SEC_PROTOCOL_METADATA_VALIDATE(exporter_length
, NULL
);
1878 __block dispatch_data_t secret
= NULL
;
1879 sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1880 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1881 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1883 if (content
->exporter_function
&& content
->exporter_context
) {
1884 sec_protocol_metadata_exporter exporter
= (sec_protocol_metadata_exporter
)content
->exporter_function
;
1885 secret
= exporter(content
->exporter_context
, label_len
, label
, 0, NULL
, exporter_length
);
1893 sec_protocol_metadata_create_secret_with_context(sec_protocol_metadata_t metadata
, size_t label_len
,
1894 const char *label
, size_t context_len
,
1895 const uint8_t *context
, size_t exporter_length
)
1897 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
1898 SEC_PROTOCOL_METADATA_VALIDATE(label_len
, NULL
);
1899 SEC_PROTOCOL_METADATA_VALIDATE(label
, NULL
);
1900 SEC_PROTOCOL_METADATA_VALIDATE(context_len
, NULL
);
1901 SEC_PROTOCOL_METADATA_VALIDATE(context
, NULL
);
1902 SEC_PROTOCOL_METADATA_VALIDATE(exporter_length
, NULL
);
1904 __block dispatch_data_t secret
= NULL
;
1905 sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1906 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1907 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1909 if (content
->exporter_function
&& content
->exporter_context
) {
1910 sec_protocol_metadata_exporter exporter
= (sec_protocol_metadata_exporter
)content
->exporter_function
;
1911 secret
= exporter(content
->exporter_context
, label_len
, label
, context_len
, context
, exporter_length
);
1919 sec_protocol_metadata_get_tls_false_start_used(sec_protocol_metadata_t metadata
)
1921 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
1923 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1924 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1925 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1926 return content
->false_start_used
;
1931 sec_protocol_metadata_get_ticket_offered(sec_protocol_metadata_t metadata
)
1933 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
1935 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1936 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1937 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1938 return content
->ticket_offered
;
1943 sec_protocol_metadata_get_ticket_received(sec_protocol_metadata_t metadata
)
1945 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
1947 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1948 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1949 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1950 return content
->ticket_received
;
1955 sec_protocol_metadata_get_session_resumed(sec_protocol_metadata_t metadata
)
1957 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
1959 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1960 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1961 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1962 return content
->session_resumed
;
1967 sec_protocol_metadata_get_session_renewed(sec_protocol_metadata_t metadata
)
1969 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
1971 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1972 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1973 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1974 return content
->session_renewed
;
1978 SSLConnectionStrength
1979 sec_protocol_metadata_get_connection_strength(sec_protocol_metadata_t metadata
)
1981 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, SSLConnectionStrengthNonsecure
);
1983 __block SSLConnectionStrength strength
= SSLConnectionStrengthNonsecure
;
1984 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
1985 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
1986 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
1988 // TLSv1.2 and higher are considered strong. Anything less than TLSv1.2 is considered weak at best.
1989 #pragma clang diagnostic push
1990 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
1991 SSLProtocol version
= content
->negotiated_protocol_version
;
1992 if (version
>= kTLSProtocol12
) {
1993 strength
= SSLConnectionStrengthStrong
;
1994 } else if (version
== kTLSProtocol11
|| version
== kTLSProtocol1
) {
1995 strength
= SSLConnectionStrengthWeak
;
1997 strength
= SSLConnectionStrengthNonsecure
;
2000 // Legacy ciphersuites make the connection weak, for now. We may consider changing this to nonsecure.
2001 SSLCipherSuite ciphersuite
= content
->negotiated_ciphersuite
;
2002 if (strength
!= SSLConnectionStrengthNonsecure
&&
2003 SSLCiphersuiteGroupContainsCiphersuite(kSSLCiphersuiteGroupLegacy
, ciphersuite
)) {
2004 strength
= SSLConnectionStrengthWeak
;
2006 #pragma clang diagnostic pop
2015 sec_protocol_metadata_copy_serialized_session(sec_protocol_metadata_t metadata
)
2017 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
2019 __block dispatch_data_t session
= NULL
;
2020 sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
2021 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
2022 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
2024 if (content
->session_exporter_function
&& content
->session_exporter_context
) {
2025 sec_protocol_metadata_session_exporter exporter
= (sec_protocol_metadata_session_exporter
)content
->session_exporter_function
;
2026 session
= exporter(content
->session_exporter_context
);
2033 static const char *_options_uint64_keys
[] = {
2034 SEC_PROTOCOL_OPTIONS_KEY_min_version
,
2035 SEC_PROTOCOL_OPTIONS_KEY_max_version
,
2036 SEC_PROTOCOL_OPTIONS_KEY_minimum_rsa_key_size
,
2037 SEC_PROTOCOL_OPTIONS_KEY_minimum_ecdsa_key_size
,
2038 SEC_PROTOCOL_OPTIONS_KEY_minimum_signature_algorithm
,
2039 SEC_PROTOCOL_OPTIONS_KEY_tls_ticket_request_count
,
2041 static const size_t _options_uint64_keys_len
= sizeof(_options_uint64_keys
) / sizeof(_options_uint64_keys
[0]);
2043 static const char *_options_bool_keys
[] = {
2044 SEC_PROTOCOL_OPTIONS_KEY_ats_required
,
2045 SEC_PROTOCOL_OPTIONS_KEY_ats_minimum_tls_version_allowed
,
2046 SEC_PROTOCOL_OPTIONS_KEY_ats_non_pfs_ciphersuite_allowed
,
2047 SEC_PROTOCOL_OPTIONS_KEY_trusted_peer_certificate
,
2048 SEC_PROTOCOL_OPTIONS_KEY_disable_sni
,
2049 SEC_PROTOCOL_OPTIONS_KEY_enable_fallback_attempt
,
2050 SEC_PROTOCOL_OPTIONS_KEY_enable_false_start
,
2051 SEC_PROTOCOL_OPTIONS_KEY_enable_tickets
,
2052 SEC_PROTOCOL_OPTIONS_KEY_enable_sct
,
2053 SEC_PROTOCOL_OPTIONS_KEY_enable_ocsp
,
2054 SEC_PROTOCOL_OPTIONS_KEY_enforce_ev
,
2055 SEC_PROTOCOL_OPTIONS_KEY_enable_resumption
,
2056 SEC_PROTOCOL_OPTIONS_KEY_enable_renegotiation
,
2057 SEC_PROTOCOL_OPTIONS_KEY_enable_early_data
,
2058 SEC_PROTOCOL_OPTIONS_KEY_peer_authentication_required
,
2059 SEC_PROTOCOL_OPTIONS_KEY_certificate_compression_enabled
,
2060 SEC_PROTOCOL_OPTIONS_KEY_tls_SIKE503_exchange_enabled
,
2061 SEC_PROTOCOL_OPTIONS_KEY_tls_HRSS_exchange_enabled
,
2062 SEC_PROTOCOL_OPTIONS_KEY_eddsa_enabled
,
2063 SEC_PROTOCOL_OPTIONS_KEY_tls_delegated_credentials_enabled
,
2064 SEC_PROTOCOL_OPTIONS_KEY_tls_grease_enabled
,
2067 static const size_t _options_bool_keys_len
= sizeof(_options_bool_keys
) / sizeof(_options_bool_keys
[0]);
2070 _dictionary_has_key(xpc_object_t dict
, const char *target_key
)
2072 if (xpc_get_type(dict
) != XPC_TYPE_DICTIONARY
) {
2076 return !xpc_dictionary_apply(dict
, ^bool(const char * _Nonnull key
, xpc_object_t _Nonnull value
) {
2077 if (strncmp(key
, target_key
, strlen(target_key
)) == 0) {
2085 _arrays_uint64_contents_are_equal(xpc_object_t arrayA
, xpc_object_t arrayB
)
2087 if (xpc_array_get_count(arrayA
) != xpc_array_get_count(arrayB
)) {
2091 return xpc_array_apply(arrayA
, ^bool(size_t indexA
, xpc_object_t _Nonnull valueA
) {
2092 uint64_t raw_valueA
= xpc_array_get_uint64(arrayA
, indexA
);
2094 bool contains_value
= !xpc_array_apply(arrayB
, ^bool(size_t indexB
, xpc_object_t _Nonnull valueB
) {
2095 uint64_t raw_valueB
= xpc_array_get_uint64(arrayB
, indexB
);
2096 if (raw_valueA
== raw_valueB
) {
2102 if (!contains_value
) {
2111 _options_config_matches_partial_config(xpc_object_t full
, xpc_object_t partial
)
2113 SEC_PROTOCOL_METADATA_VALIDATE(full
, false);
2114 SEC_PROTOCOL_METADATA_VALIDATE(partial
, false);
2116 return xpc_dictionary_apply(partial
, ^bool(const char * _Nonnull entry_key
, xpc_object_t _Nonnull value
) {
2117 size_t entry_key_len
= strnlen(entry_key
, MAX_SEC_PROTOCOL_OPTIONS_KEY_LEN
);
2119 for (size_t i
= 0; i
< _options_uint64_keys_len
; i
++) {
2120 const char *key
= _options_uint64_keys
[i
];
2121 if (strncmp(entry_key
, key
, MAX(entry_key_len
, strlen(key
))) == 0) {
2122 if (_dictionary_has_key(full
, key
)) {
2123 if (xpc_dictionary_get_uint64(full
, key
) != xpc_dictionary_get_uint64(partial
, key
)) {
2132 for (size_t i
= 0; i
< _options_bool_keys_len
; i
++) {
2133 const char *key
= _options_bool_keys
[i
];
2134 if (strncmp(entry_key
, key
, MAX(entry_key_len
, strlen(key
))) == 0) {
2135 if (_dictionary_has_key(full
, key
)) {
2136 if (xpc_dictionary_get_bool(full
, key
) != xpc_dictionary_get_bool(partial
, key
)) {
2145 // Now check for ciphersuite options, as these are not expressed via serialized configs
2146 if (strncmp(entry_key
, SEC_PROTOCOL_OPTIONS_KEY_ciphersuites
, entry_key_len
) == 0) {
2147 if (xpc_get_type(value
) == XPC_TYPE_ARRAY
) {
2148 bool matching
= xpc_dictionary_apply(full
, ^bool(const char * _Nonnull full_key
, xpc_object_t _Nonnull full_value
) {
2149 if (strncmp(full_key
, SEC_PROTOCOL_OPTIONS_KEY_ciphersuites
, entry_key_len
) == 0) {
2150 if (xpc_get_type(full_value
) == XPC_TYPE_ARRAY
) {
2151 return _arrays_uint64_contents_are_equal(value
, full_value
);
2168 _serialize_options(xpc_object_t dictionary
, sec_protocol_options_content_t options_content
)
2170 #define xpc_dictionary_set_string_default(d, key, value, default) \
2172 if (value != NULL) { \
2173 xpc_dictionary_set_string(d, key, value); \
2175 xpc_dictionary_set_string(d, key, default); \
2179 #define EXPAND_PARAMETER(field) \
2180 SEC_PROTOCOL_OPTIONS_KEY_##field , options_content->field
2182 xpc_dictionary_set_uint64(dictionary
, EXPAND_PARAMETER(min_version
));
2183 xpc_dictionary_set_uint64(dictionary
, EXPAND_PARAMETER(max_version
));
2184 xpc_dictionary_set_uint64(dictionary
, EXPAND_PARAMETER(minimum_rsa_key_size
));
2185 xpc_dictionary_set_uint64(dictionary
, EXPAND_PARAMETER(minimum_ecdsa_key_size
));
2186 xpc_dictionary_set_uint64(dictionary
, EXPAND_PARAMETER(minimum_signature_algorithm
));
2187 xpc_dictionary_set_uint64(dictionary
, EXPAND_PARAMETER(tls_ticket_request_count
));
2189 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(ats_required
));
2190 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(ats_minimum_tls_version_allowed
));
2191 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(ats_non_pfs_ciphersuite_allowed
));
2192 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(trusted_peer_certificate
));
2193 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(disable_sni
));
2194 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_fallback_attempt
));
2195 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_false_start
));
2196 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_tickets
));
2197 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_sct
));
2198 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_ocsp
));
2199 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enforce_ev
));
2200 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_resumption
));
2201 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_renegotiation
));
2202 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(enable_early_data
));
2203 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(peer_authentication_required
));
2204 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(certificate_compression_enabled
));
2205 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(tls_SIKE503_exchange_enabled
));
2206 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(tls_HRSS_exchange_enabled
));
2207 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(eddsa_enabled
));
2208 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(tls_delegated_credentials_enabled
));
2209 xpc_dictionary_set_bool(dictionary
, EXPAND_PARAMETER(tls_grease_enabled
));
2211 #undef EXPAND_PARAMETER
2212 #undef xpc_dictionary_set_string_default
2217 static struct _options_bool_key_setter
{
2219 void (*setter_pointer
)(sec_protocol_options_t
, bool);
2220 } _options_bool_key_setters
[] = {
2222 .key
= SEC_PROTOCOL_OPTIONS_KEY_ats_required
,
2223 .setter_pointer
= sec_protocol_options_set_ats_required
,
2226 .key
= SEC_PROTOCOL_OPTIONS_KEY_ats_minimum_tls_version_allowed
,
2227 .setter_pointer
= sec_protocol_options_set_ats_minimum_tls_version_allowed
,
2230 .key
= SEC_PROTOCOL_OPTIONS_KEY_ats_non_pfs_ciphersuite_allowed
,
2231 .setter_pointer
= sec_protocol_options_set_ats_non_pfs_ciphersuite_allowed
,
2234 .key
= SEC_PROTOCOL_OPTIONS_KEY_trusted_peer_certificate
,
2235 .setter_pointer
= sec_protocol_options_set_trusted_peer_certificate
,
2238 .key
= SEC_PROTOCOL_OPTIONS_KEY_disable_sni
,
2239 .setter_pointer
= sec_protocol_options_set_tls_sni_disabled
2242 .key
= SEC_PROTOCOL_OPTIONS_KEY_enable_fallback_attempt
,
2243 .setter_pointer
= sec_protocol_options_set_tls_is_fallback_attempt
,
2246 .key
= SEC_PROTOCOL_OPTIONS_KEY_enable_false_start
,
2247 .setter_pointer
= sec_protocol_options_set_tls_false_start_enabled
,
2250 .key
= SEC_PROTOCOL_OPTIONS_KEY_enable_tickets
,
2251 .setter_pointer
= sec_protocol_options_set_tls_tickets_enabled
,
2254 .key
= SEC_PROTOCOL_OPTIONS_KEY_enable_sct
,
2255 .setter_pointer
= sec_protocol_options_set_tls_sct_enabled
2258 .key
= SEC_PROTOCOL_OPTIONS_KEY_enable_ocsp
,
2259 .setter_pointer
= sec_protocol_options_set_tls_ocsp_enabled
,
2262 .key
= SEC_PROTOCOL_OPTIONS_KEY_enforce_ev
,
2263 .setter_pointer
= sec_protocol_options_set_enforce_ev
,
2266 .key
= SEC_PROTOCOL_OPTIONS_KEY_enable_resumption
,
2267 .setter_pointer
= sec_protocol_options_set_tls_resumption_enabled
,
2270 .key
= SEC_PROTOCOL_OPTIONS_KEY_enable_renegotiation
,
2271 .setter_pointer
= sec_protocol_options_set_tls_renegotiation_enabled
,
2274 .key
= SEC_PROTOCOL_OPTIONS_KEY_enable_early_data
,
2275 .setter_pointer
= sec_protocol_options_set_tls_early_data_enabled
,
2278 .key
= SEC_PROTOCOL_OPTIONS_KEY_peer_authentication_required
,
2279 .setter_pointer
= sec_protocol_options_set_peer_authentication_required
,
2282 .key
= SEC_PROTOCOL_OPTIONS_KEY_certificate_compression_enabled
,
2283 .setter_pointer
= sec_protocol_options_set_tls_certificate_compression_enabled
,
2286 .key
= SEC_PROTOCOL_OPTIONS_KEY_tls_SIKE503_exchange_enabled
,
2287 .setter_pointer
= sec_protocol_options_set_tls_SIKE503_exchange_enabled
,
2290 .key
= SEC_PROTOCOL_OPTIONS_KEY_tls_HRSS_exchange_enabled
,
2291 .setter_pointer
= sec_protocol_options_set_tls_HRSS_exchange_enabled
,
2294 .key
= SEC_PROTOCOL_OPTIONS_KEY_eddsa_enabled
,
2295 .setter_pointer
= sec_protocol_options_set_eddsa_enabled
,
2298 .key
= SEC_PROTOCOL_OPTIONS_KEY_tls_delegated_credentials_enabled
,
2299 .setter_pointer
= sec_protocol_options_set_tls_delegated_credentials_enabled
,
2302 .key
= SEC_PROTOCOL_OPTIONS_KEY_tls_grease_enabled
,
2303 .setter_pointer
= sec_protocol_options_set_tls_grease_enabled
,
2306 static const size_t _options_bool_key_setters_len
= sizeof(_options_bool_key_setters
) / sizeof(_options_bool_key_setters
[0]);
2308 static struct _options_uint64_key_setter
{
2310 void (*setter_pointer
)(sec_protocol_options_t
, uint64_t);
2311 } _options_uint64_key_setters
[] = {
2312 #pragma clang diagnostic push
2313 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
2315 .key
= SEC_PROTOCOL_OPTIONS_KEY_min_version
,
2316 .setter_pointer
= (void (*)(sec_protocol_options_t
, uint64_t))sec_protocol_options_set_tls_min_version
2319 .key
= SEC_PROTOCOL_OPTIONS_KEY_max_version
,
2320 .setter_pointer
= (void (*)(sec_protocol_options_t
, uint64_t))sec_protocol_options_set_tls_max_version
2322 #pragma clang diagnostic pop
2324 .key
= SEC_PROTOCOL_OPTIONS_KEY_minimum_rsa_key_size
,
2325 .setter_pointer
= (void (*)(sec_protocol_options_t
, uint64_t))sec_protocol_options_set_minimum_rsa_key_size
,
2328 .key
= SEC_PROTOCOL_OPTIONS_KEY_minimum_ecdsa_key_size
,
2329 .setter_pointer
= (void (*)(sec_protocol_options_t
, uint64_t))sec_protocol_options_set_minimum_ecdsa_key_size
,
2332 .key
= SEC_PROTOCOL_OPTIONS_KEY_minimum_signature_algorithm
,
2333 .setter_pointer
= (void (*)(sec_protocol_options_t
, uint64_t))sec_protocol_options_set_minimum_signature_algorithm
,
2336 .key
= SEC_PROTOCOL_OPTIONS_KEY_tls_ticket_request_count
,
2337 .setter_pointer
= (void (*)(sec_protocol_options_t
, uint64_t))sec_protocol_options_set_tls_ticket_request_count
,
2340 static const size_t _options_uint64_key_setters_len
= sizeof(_options_uint64_key_setters
) / sizeof(_options_uint64_key_setters
[0]);
2343 _apply_config_options(sec_protocol_options_t options
, xpc_object_t config
)
2345 return sec_protocol_options_access_handle(options
, ^bool(void *options_handle
) {
2346 sec_protocol_options_content_t options_content
= (sec_protocol_options_content_t
)options_handle
;
2347 SEC_PROTOCOL_METADATA_VALIDATE(options_content
, false);
2348 return xpc_dictionary_apply(config
, ^bool(const char * _Nonnull key
, xpc_object_t _Nonnull value
) {
2350 size_t key_len
= strnlen(key
, MAX_SEC_PROTOCOL_OPTIONS_KEY_LEN
);
2351 for (size_t i
= 0; i
< _options_bool_key_setters_len
; i
++) {
2352 const char *setter_key
= _options_bool_key_setters
[i
].key
;
2353 size_t setter_key_len
= strnlen(setter_key
, MAX_SEC_PROTOCOL_OPTIONS_KEY_LEN
);
2354 if (strncmp(setter_key
, key
, MAX(key_len
, setter_key_len
)) == 0) {
2355 _options_bool_key_setters
[i
].setter_pointer(options
, xpc_dictionary_get_bool(config
, key
));
2359 for (size_t i
= 0; i
< _options_uint64_key_setters_len
; i
++) {
2360 const char *setter_key
= _options_uint64_key_setters
[i
].key
;
2361 size_t setter_key_len
= strnlen(setter_key
, MAX_SEC_PROTOCOL_OPTIONS_KEY_LEN
);
2362 if (strncmp(setter_key
, key
, MAX(key_len
, setter_key_len
)) == 0) {
2363 _options_uint64_key_setters
[i
].setter_pointer(options
, xpc_dictionary_get_uint64(config
, key
));
2367 // Now check for ciphersuite options, as these are not expressed via serialized configs
2368 if (strncmp(key
, SEC_PROTOCOL_OPTIONS_KEY_ciphersuites
, key_len
) == 0) {
2369 if (xpc_get_type(value
) == XPC_TYPE_ARRAY
) {
2370 xpc_array_apply(value
, ^bool(size_t index
, xpc_object_t _Nonnull ciphersuite_value
) {
2371 SSLCipherSuite ciphersuite
= (SSLCipherSuite
)xpc_array_get_uint64(value
, index
);
2372 sec_protocol_options_append_tls_ciphersuite(options
, ciphersuite
);
2384 _serialize_metadata(xpc_object_t dictionary
, sec_protocol_metadata_content_t metadata_content
)
2386 #define xpc_dictionary_set_string_default(d, key, value, default) \
2388 if (value != NULL) { \
2389 xpc_dictionary_set_string(d, key, value); \
2391 xpc_dictionary_set_string(d, key, default); \
2395 xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_CIPHERSUITE
, metadata_content
->negotiated_ciphersuite
);
2396 xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_PROTOCOL_VERSION
, metadata_content
->negotiated_protocol_version
);
2397 xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_TICKET_LIFETIME
, metadata_content
->ticket_lifetime
);
2399 xpc_dictionary_set_string_default(dictionary
, SEC_PROTOCOL_METADATA_KEY_PEER_PUBLIC_KEY_TYPE
,
2400 metadata_content
->peer_public_key_type
, SEC_PROTOCOL_METADATA_KEY_DEFAULT_EMPTY_STRING
);
2401 xpc_dictionary_set_string_default(dictionary
, SEC_PROTOCOL_METADATA_KEY_NEGOTIATED_CURVE
,
2402 metadata_content
->negotiated_curve
, SEC_PROTOCOL_METADATA_KEY_DEFAULT_EMPTY_STRING
);
2403 xpc_dictionary_set_string_default(dictionary
, SEC_PROTOCOL_METADATA_KEY_PEER_CERTIFICATE_REQUEST_TYPE
,
2404 metadata_content
->certificate_request_type
, SEC_PROTOCOL_METADATA_KEY_DEFAULT_EMPTY_STRING
);
2405 xpc_dictionary_set_string_default(dictionary
, SEC_PROTOCOL_METADATA_KEY_NEGOTIATED_PROTOCOL
,
2406 metadata_content
->negotiated_protocol
, SEC_PROTOCOL_METADATA_KEY_DEFAULT_EMPTY_STRING
);
2408 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_FALSE_START_USED
, metadata_content
->false_start_used
);
2409 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_SESSION_RESUMED
, metadata_content
->session_resumed
);
2410 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_TICKET_OFFERED
, metadata_content
->ticket_offered
);
2411 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_TICKET_RECEIVED
, metadata_content
->ticket_received
);
2412 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_SESSION_RENEWED
, metadata_content
->session_renewed
);
2413 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_RESUMPTION_ATTEMPTED
, metadata_content
->resumption_attempted
);
2414 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_ALPN_USED
, metadata_content
->alpn_used
);
2415 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_NPN_USED
, metadata_content
->npn_used
);
2416 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_OCSP_ENABLED
, metadata_content
->ocsp_enabled
);
2417 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_OCSP_RECEIVED
, metadata_content
->ocsp_response
!= NULL
);
2418 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_SCT_ENABLED
, metadata_content
->sct_enabled
);
2419 xpc_dictionary_set_bool(dictionary
, SEC_PROTOCOL_METADATA_KEY_SCT_RECEIVED
, metadata_content
->signed_certificate_timestamps
!= NULL
);
2421 #undef xpc_dictionary_set_string_default
2427 _serialize_success_with_options(xpc_object_t dictionary
, sec_protocol_metadata_content_t metadata_content
, sec_protocol_options_content_t options_content
)
2429 if (!_serialize_options(dictionary
, options_content
)) {
2432 if (!_serialize_metadata(dictionary
, metadata_content
)) {
2439 _serialize_failure_with_options(xpc_object_t dictionary
, sec_protocol_metadata_content_t metadata_content
, sec_protocol_options_content_t options_content
)
2441 xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_FAILURE_ALERT_TYPE
, metadata_content
->alert_type
);
2442 xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_FAILURE_ALERT_CODE
, metadata_content
->alert_code
);
2443 xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_FAILURE_HANDSHAKE_STATE
, metadata_content
->handshake_state
);
2444 xpc_dictionary_set_uint64(dictionary
, SEC_PROTOCOL_METADATA_KEY_FAILURE_STACK_ERROR
, metadata_content
->stack_error
);
2450 sec_protocol_metadata_serialize_with_options(sec_protocol_metadata_t metadata
, sec_protocol_options_t options
)
2452 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
2453 SEC_PROTOCOL_METADATA_VALIDATE(options
, NULL
);
2455 __block xpc_object_t dictionary
= xpc_dictionary_create(NULL
, NULL
, 0);
2456 if (dictionary
== NULL
) {
2460 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
2461 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
2462 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
2464 return sec_protocol_options_access_handle(options
, ^bool(void *options_handle
) {
2465 sec_protocol_options_content_t options_content
= (sec_protocol_options_content_t
)options_handle
;
2466 SEC_PROTOCOL_METADATA_VALIDATE(options_content
, false);
2468 if (metadata_content
->failure
) {
2469 return _serialize_failure_with_options(dictionary
, metadata_content
, options_content
);
2471 return _serialize_success_with_options(dictionary
, metadata_content
, options_content
);
2480 sec_protocol_metadata_copy_quic_transport_parameters(sec_protocol_metadata_t metadata
)
2482 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
2484 __block dispatch_data_t copied_parameters
= NULL
;
2485 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
2486 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
2487 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
2488 if (metadata_content
->quic_transport_parameters
) {
2489 copied_parameters
= metadata_content
->quic_transport_parameters
;
2490 dispatch_retain(copied_parameters
);
2495 return copied_parameters
;
2499 sec_protocol_metadata_get_tls_certificate_compression_used(sec_protocol_metadata_t metadata
)
2501 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
2503 __block
bool certificate_compression_used
= false;
2504 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
2505 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
2506 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
2507 certificate_compression_used
= metadata_content
->certificate_compression_used
;
2511 return certificate_compression_used
;
2515 sec_protocol_metadata_get_tls_certificate_compression_algorithm(sec_protocol_metadata_t metadata
)
2517 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0);
2519 __block
uint16_t certificate_compression_algorithm
= 0;
2520 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
2521 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
2522 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
2523 certificate_compression_algorithm
= metadata_content
->certificate_compression_algorithm
;
2527 return certificate_compression_algorithm
;
2531 sec_protocol_metadata_get_handshake_rtt(sec_protocol_metadata_t metadata
)
2533 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, 0);
2535 __block
uint64_t rtt
= 0;
2536 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
2537 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
2538 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
2539 rtt
= metadata_content
->handshake_rtt
;
2547 sec_protocol_metadata_copy_sec_trust(sec_protocol_metadata_t metadata
)
2549 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, nil
);
2551 __block sec_trust_t trust
= nil
;
2552 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
2553 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
2554 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
2555 if (metadata_content
->trust_ref
!= nil
) {
2556 trust
= metadata_content
->trust_ref
;
2566 sec_protocol_metadata_copy_sec_identity(sec_protocol_metadata_t metadata
)
2568 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, nil
);
2570 __block sec_identity_t identity
= nil
;
2571 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *metadata_handle
) {
2572 sec_protocol_metadata_content_t metadata_content
= (sec_protocol_metadata_content_t
)metadata_handle
;
2573 SEC_PROTOCOL_METADATA_VALIDATE(metadata_content
, false);
2574 if (metadata_content
->identity
!= nil
) {
2575 identity
= metadata_content
->identity
;
2576 sec_retain(identity
);
2585 sec_protocol_metadata_access_sent_certificates(sec_protocol_metadata_t metadata
,
2586 void (^handler
)(sec_certificate_t certificate
))
2588 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
2589 SEC_PROTOCOL_METADATA_VALIDATE(handler
, false);
2591 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
2592 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
2593 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
2595 if (content
->identity
!= nil
&& sec_identity_has_certificates(content
->identity
)) {
2596 return sec_identity_access_certificates(content
->identity
, handler
);
2599 if (content
->sent_certificate_chain
!= NULL
) {
2600 return sec_array_apply(content
->sent_certificate_chain
, ^bool(__unused
size_t index
, sec_object_t object
) {
2601 handler((sec_certificate_t
)object
);
2611 sec_protocol_metadata_get_tls_negotiated_group(sec_protocol_metadata_t metadata
)
2613 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
2615 __block
const char *negotiated_curve
= NULL
;
2616 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
2617 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
2618 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
2619 negotiated_curve
= content
->negotiated_curve
;
2623 return negotiated_curve
;
2627 sec_retain(void *obj
)
2630 return os_retain(obj
);
2637 sec_release(void *obj
)
2645 sec_protocol_options_create_config(sec_protocol_options_t options
)
2647 SEC_PROTOCOL_METADATA_VALIDATE(options
, NULL
);
2649 __block xpc_object_t dictionary
= xpc_dictionary_create(NULL
, NULL
, 0);
2650 if (dictionary
== NULL
) {
2654 bool serialized
= sec_protocol_options_access_handle(options
, ^bool(void *options_handle
) {
2655 sec_protocol_options_content_t options_content
= (sec_protocol_options_content_t
)options_handle
;
2656 SEC_PROTOCOL_METADATA_VALIDATE(options_content
, false);
2658 if (_serialize_options(dictionary
, options_content
)) {
2659 xpc_dictionary_set_value(dictionary
, SEC_PROTOCOL_OPTIONS_KEY_ciphersuites
, options_content
->ciphersuites
);
2667 return dictionary
; // retained reference
2669 xpc_release(dictionary
);
2675 sec_protocol_options_matches_config(sec_protocol_options_t options
, xpc_object_t config
)
2677 SEC_PROTOCOL_METADATA_VALIDATE(options
, false);
2678 SEC_PROTOCOL_METADATA_VALIDATE(config
, false);
2680 if (xpc_get_type(config
) != XPC_TYPE_DICTIONARY
) {
2684 xpc_object_t options_config
= sec_protocol_options_create_config(options
);
2685 if (options_config
== NULL
) {
2689 bool match
= _options_config_matches_partial_config(options_config
, config
);
2690 xpc_release(options_config
);
2696 sec_protocol_options_apply_config(sec_protocol_options_t options
, xpc_object_t config
)
2698 SEC_PROTOCOL_METADATA_VALIDATE(options
, false);
2699 SEC_PROTOCOL_METADATA_VALIDATE(config
, false);
2701 if (xpc_get_type(config
) != XPC_TYPE_DICTIONARY
) {
2705 return _apply_config_options(options
, config
);