6 #include <Security/SecProtocolOptions.h>
7 #include <Security/SecProtocolMetadata.h>
8 #include <Security/SecProtocolPriv.h>
10 #include <Security/SecureTransportPriv.h>
15 #include <sys/param.h>
17 #define CFReleaseSafe(value) \
18 if (value != NULL) { \
22 typedef bool (^sec_access_block_t
)(void *handle
);
25 sec_protocol_options_access_handle(sec_protocol_options_t options
,
26 sec_access_block_t access_block
)
28 static void *libnetworkImage
= NULL
;
29 static dispatch_once_t onceToken
;
30 static bool (*_nw_protocol_options_access_handle
)(void *, sec_access_block_t
) = NULL
;
32 dispatch_once(&onceToken
, ^{
33 libnetworkImage
= dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY
| RTLD_LOCAL
);
34 if (NULL
!= libnetworkImage
) {
35 _nw_protocol_options_access_handle
= (__typeof(_nw_protocol_options_access_handle
))dlsym(libnetworkImage
,
36 "nw_protocol_options_access_handle");
37 if (NULL
== _nw_protocol_options_access_handle
) {
38 os_log_error(OS_LOG_DEFAULT
, "dlsym libnetwork nw_protocol_options_access_handle");
41 os_log_error(OS_LOG_DEFAULT
, "dlopen libnetwork");
45 if (_nw_protocol_options_access_handle
== NULL
) {
49 return _nw_protocol_options_access_handle(options
, access_block
);
53 sec_protocol_metadata_access_handle(sec_protocol_metadata_t options
,
54 sec_access_block_t access_block
)
56 static void *libnetworkImage
= NULL
;
57 static dispatch_once_t onceToken
;
58 static bool (*_nw_protocol_metadata_access_handle
)(void *, sec_access_block_t
) = NULL
;
60 dispatch_once(&onceToken
, ^{
61 libnetworkImage
= dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY
| RTLD_LOCAL
);
62 if (NULL
!= libnetworkImage
) {
63 _nw_protocol_metadata_access_handle
= (__typeof(_nw_protocol_metadata_access_handle
))dlsym(libnetworkImage
,
64 "nw_protocol_metadata_access_handle");
65 if (NULL
== _nw_protocol_metadata_access_handle
) {
66 os_log_error(OS_LOG_DEFAULT
, "dlsym libnetwork _nw_protocol_metadata_access_handle");
69 os_log_error(OS_LOG_DEFAULT
, "dlopen libnetwork");
73 if (_nw_protocol_metadata_access_handle
== NULL
) {
77 return _nw_protocol_metadata_access_handle(options
, access_block
);
80 #define SEC_PROTOCOL_OPTIONS_VALIDATE(o,r) \
85 #define SEC_PROTOCOL_METADATA_VALIDATE(m,r) \
86 if (((void *)m == NULL) || ((size_t)m == 0)) { \
91 sec_protocol_options_set_local_identity(sec_protocol_options_t options
, sec_identity_t identity
)
93 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
95 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
96 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
97 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
99 if (content
->identity
!= NULL
) {
100 sec_release(content
->identity
);
102 content
->identity
= sec_retain(identity
);
108 sec_protocol_options_add_tls_ciphersuite(sec_protocol_options_t options
, SSLCipherSuite ciphersuite
)
110 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
112 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
113 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
114 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
116 if (content
->ciphersuites
== NULL
) {
117 content
->ciphersuites
= xpc_array_create(NULL
, 0);
119 xpc_array_set_uint64(content
->ciphersuites
, XPC_ARRAY_APPEND
, (uint64_t)ciphersuite
);
125 sec_protocol_options_add_tls_ciphersuite_group(sec_protocol_options_t options
, SSLCiphersuiteGroup group
)
127 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
129 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
130 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
131 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
133 if (content
->ciphersuites
== NULL
) {
134 content
->ciphersuites
= xpc_array_create(NULL
, 0);
137 // Fetch the list of ciphersuites associated with the ciphersuite group
138 size_t ciphersuite_count
= 0;
139 const SSLCipherSuite
*list
= SSLCiphersuiteGroupToCiphersuiteList(group
, &ciphersuite_count
);
141 for (size_t i
= 0; i
< ciphersuite_count
; i
++) {
142 SSLCipherSuite ciphersuite
= list
[i
];
143 xpc_array_set_uint64(content
->ciphersuites
, XPC_ARRAY_APPEND
, (uint64_t)ciphersuite
);
152 sec_protocol_options_set_tls_min_version(sec_protocol_options_t options
, SSLProtocol version
)
154 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
156 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
157 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
158 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
160 content
->min_version
= version
;
166 sec_protocol_options_set_tls_max_version(sec_protocol_options_t options
, SSLProtocol version
)
168 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
170 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
171 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
172 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
174 content
->max_version
= version
;
180 sec_protocol_options_add_tls_application_protocol(sec_protocol_options_t options
, const char *application_protocol
)
182 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
183 SEC_PROTOCOL_OPTIONS_VALIDATE(application_protocol
,);
185 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
186 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
187 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
189 if (content
->application_protocols
== NULL
) {
190 content
->application_protocols
= xpc_array_create(NULL
, 0);
192 xpc_array_set_string(content
->application_protocols
, XPC_ARRAY_APPEND
, application_protocol
);
198 sec_protocol_options_set_tls_server_name(sec_protocol_options_t options
, const char *server_name
)
200 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
201 SEC_PROTOCOL_OPTIONS_VALIDATE(server_name
,);
203 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
204 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
205 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
207 if (content
->server_name
!= NULL
) {
208 free(content
->server_name
);
210 content
->server_name
= strdup(server_name
);
216 sec_protocol_options_set_tls_diffie_hellman_parameters(sec_protocol_options_t options
, dispatch_data_t params
)
218 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
219 SEC_PROTOCOL_OPTIONS_VALIDATE(params
,);
221 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
222 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
223 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
225 if (content
->dh_params
) {
226 dispatch_release(content
->dh_params
);
228 content
->dh_params
= params
;
229 dispatch_retain(params
);
235 sec_protocol_options_add_pre_shared_key(sec_protocol_options_t options
, dispatch_data_t psk
, dispatch_data_t psk_identity
)
237 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
238 SEC_PROTOCOL_OPTIONS_VALIDATE(psk
,);
239 SEC_PROTOCOL_OPTIONS_VALIDATE(psk_identity
,);
241 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
242 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
243 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
245 if (content
->pre_shared_keys
== NULL
) {
246 content
->pre_shared_keys
= xpc_array_create(NULL
, 0);
249 xpc_object_t psk_data
= xpc_data_create_with_dispatch_data(psk
);
250 xpc_object_t psk_identity_data
= xpc_data_create_with_dispatch_data(psk_identity
);
252 xpc_object_t tuple
= xpc_array_create(NULL
, 0);
253 xpc_array_set_value(tuple
, XPC_ARRAY_APPEND
, psk_data
);
254 xpc_array_set_value(tuple
, XPC_ARRAY_APPEND
, psk_identity_data
);
255 xpc_release(psk_data
);
256 xpc_release(psk_identity_data
);
258 xpc_array_set_value(content
->pre_shared_keys
, XPC_ARRAY_APPEND
, tuple
);
265 sec_protocol_options_set_tls_is_fallback_attempt(sec_protocol_options_t options
, bool fallback_attempt
)
267 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
269 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
270 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
271 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
273 content
->enable_fallback_attempt
= fallback_attempt
;
279 sec_protocol_options_set_tls_tickets_enabled(sec_protocol_options_t options
, bool tickets_enabled
)
281 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
283 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
284 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
285 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
287 content
->enable_tickets
= tickets_enabled
;
293 sec_protocol_options_set_tls_resumption_enabled(sec_protocol_options_t options
, bool resumption_enabled
)
295 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
297 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
298 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
299 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
301 content
->enable_resumption
= resumption_enabled
;
307 sec_protocol_options_set_tls_false_start_enabled(sec_protocol_options_t options
, bool false_start_enabled
)
309 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
311 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
312 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
313 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
315 content
->enable_false_start
= false_start_enabled
;
321 sec_protocol_options_set_tls_early_data_enabled(sec_protocol_options_t options
, bool early_data_enabled
)
323 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
325 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
326 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
327 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
329 content
->enable_early_data
= early_data_enabled
;
335 sec_protocol_options_set_tls_sni_disabled(sec_protocol_options_t options
, bool sni_disabled
)
337 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
339 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
340 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
341 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
343 content
->disable_sni
= sni_disabled
;
349 sec_protocol_options_set_enforce_ev(sec_protocol_options_t options
, bool enforce_ev
)
351 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
353 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
354 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
355 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
357 content
->enforce_ev
= enforce_ev
;
363 sec_protocol_options_set_tls_ocsp_enabled(sec_protocol_options_t options
, bool ocsp_enabled
)
365 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
367 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
368 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
369 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
371 content
->enable_ocsp
= ocsp_enabled
;
377 sec_protocol_options_set_tls_sct_enabled(sec_protocol_options_t options
, bool sct_enabled
)
379 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
381 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
382 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
383 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
385 content
->enable_sct
= sct_enabled
;
391 sec_protocol_options_set_tls_renegotiation_enabled(sec_protocol_options_t options
, bool renegotiation_enabled
)
393 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
395 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
396 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
397 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
399 content
->enable_renegotiation
= renegotiation_enabled
;
405 sec_protocol_options_set_peer_authentication_required(sec_protocol_options_t options
, bool peer_authentication_required
)
407 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
409 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
410 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
411 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
413 content
->peer_authentication_required
= peer_authentication_required
;
414 content
->peer_authentication_override
= true;
420 sec_protocol_options_set_key_update_block(sec_protocol_options_t options
, sec_protocol_key_update_t update_block
, dispatch_queue_t update_queue
)
422 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
423 SEC_PROTOCOL_OPTIONS_VALIDATE(update_queue
,);
425 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
426 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
427 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
429 if (content
->key_update_block
!= NULL
) {
430 Block_release(content
->key_update_block
);
432 if (content
->key_update_queue
!= NULL
) {
433 dispatch_release(content
->key_update_queue
);
436 content
->key_update_block
= Block_copy(update_block
);
437 content
->key_update_queue
= Block_copy(update_queue
);
438 dispatch_retain(content
->key_update_queue
);
444 sec_protocol_options_set_challenge_block(sec_protocol_options_t options
, sec_protocol_challenge_t challenge_block
, dispatch_queue_t challenge_queue
)
446 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
447 SEC_PROTOCOL_OPTIONS_VALIDATE(challenge_queue
,);
449 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
450 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
451 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
453 if (content
->challenge_block
!= NULL
) {
454 Block_release(content
->challenge_block
);
456 if (content
->challenge_queue
!= NULL
) {
457 dispatch_release(content
->challenge_queue
);
460 content
->challenge_block
= Block_copy(challenge_block
);
461 content
->challenge_queue
= challenge_queue
;
462 dispatch_retain(content
->challenge_queue
);
468 sec_protocol_options_set_verify_block(sec_protocol_options_t options
, sec_protocol_verify_t verify_block
, dispatch_queue_t verify_queue
)
470 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
471 SEC_PROTOCOL_OPTIONS_VALIDATE(verify_queue
,);
473 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
474 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
475 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
477 if (content
->verify_block
!= NULL
) {
478 Block_release(content
->verify_block
);
480 if (content
->verify_queue
!= NULL
) {
481 dispatch_release(content
->verify_queue
);
484 content
->verify_block
= Block_copy(verify_block
);
485 content
->verify_queue
= verify_queue
;
486 dispatch_retain(content
->verify_queue
);
492 sec_protocol_options_add_tls_extension(sec_protocol_options_t options
, sec_tls_extension_t extension
)
494 SEC_PROTOCOL_OPTIONS_VALIDATE(options
,);
495 SEC_PROTOCOL_OPTIONS_VALIDATE(extension
,);
497 (void)sec_protocol_options_access_handle(options
, ^bool(void *handle
) {
498 sec_protocol_options_content_t content
= (sec_protocol_options_content_t
)handle
;
499 SEC_PROTOCOL_OPTIONS_VALIDATE(content
, false);
501 if (content
->custom_extensions
== NULL
) {
502 content
->custom_extensions
= sec_array_create();
505 sec_array_append(content
->custom_extensions
, (sec_object_t
)extension
);
511 sec_protocol_metadata_get_negotiated_protocol(sec_protocol_metadata_t metadata
)
513 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
515 __block
const char *negotiated_protocol
= NULL
;
516 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
517 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
518 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
519 negotiated_protocol
= content
->negotiated_protocol
;
523 return negotiated_protocol
;
527 sec_protocol_metadata_access_peer_certificate_chain(sec_protocol_metadata_t metadata
,
528 void (^handler
)(sec_certificate_t certficate
))
530 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
531 SEC_PROTOCOL_METADATA_VALIDATE(handler
, false);
533 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
534 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
535 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
536 if (content
->peer_certificate_chain
== NULL
) {
539 sec_array_t array
= content
->peer_certificate_chain
;
540 sec_array_apply(array
, ^bool(__unused
size_t index
, sec_object_t object
) {
541 handler((sec_certificate_t
)object
);
549 sec_protocol_metadata_copy_peer_public_key(sec_protocol_metadata_t metadata
)
551 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
553 __block dispatch_data_t peer_public_key
= NULL
;
554 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
555 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
556 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
557 peer_public_key
= ((dispatch_data_t
)content
->peer_public_key
);
558 if (peer_public_key
) {
559 dispatch_retain(peer_public_key
);
564 return peer_public_key
;
568 sec_protocol_metadata_get_negotiated_protocol_version(sec_protocol_metadata_t metadata
)
570 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, kSSLProtocolUnknown
);
572 __block SSLProtocol protocol_version
= kSSLProtocolUnknown
;
573 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
574 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
575 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
576 protocol_version
= content
->negotiated_protocol_version
;
580 return protocol_version
;
584 sec_protocol_metadata_get_negotiated_ciphersuite(sec_protocol_metadata_t metadata
)
586 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, SSL_NO_SUCH_CIPHERSUITE
);
588 __block SSLCipherSuite negotiated_ciphersuite
= SSL_NO_SUCH_CIPHERSUITE
;
589 (void)sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
590 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
591 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
592 negotiated_ciphersuite
= content
->negotiated_ciphersuite
;
596 return negotiated_ciphersuite
;
600 sec_protocol_metadata_get_early_data_accepted(sec_protocol_metadata_t metadata
)
602 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
604 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
605 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
606 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
607 return content
->early_data_accepted
;
612 sec_protocol_metadata_access_supported_signature_algorithms(sec_protocol_metadata_t metadata
,
613 void (^handler
)(uint16_t signature_algorithm
))
615 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
616 SEC_PROTOCOL_METADATA_VALIDATE(handler
, false);
618 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
619 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
620 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
621 if (content
->supported_signature_algorithms
== NULL
) {
624 xpc_object_t array
= content
->supported_signature_algorithms
;
625 xpc_array_apply(array
, ^bool(__unused
size_t index
, xpc_object_t _Nonnull value
) {
626 handler((uint16_t)xpc_uint64_get_value(value
));
634 sec_protocol_metadata_access_ocsp_response(sec_protocol_metadata_t metadata
,
635 void (^handler
)(dispatch_data_t ocsp_data
))
637 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
638 SEC_PROTOCOL_METADATA_VALIDATE(handler
, false);
640 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
641 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
642 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
643 if (content
->ocsp_response
== NULL
) {
646 sec_array_t array
= content
->ocsp_response
;
647 sec_array_apply(array
, ^bool(__unused
size_t index
, sec_object_t object
) {
648 handler((dispatch_data_t
)object
);
656 sec_protocol_metadata_access_distinguished_names(sec_protocol_metadata_t metadata
,
657 void (^handler
)(dispatch_data_t distinguished_name
))
659 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
660 SEC_PROTOCOL_METADATA_VALIDATE(handler
, false);
662 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
663 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
664 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
665 if (content
->distinguished_names
== NULL
) {
668 sec_array_t array
= content
->distinguished_names
;
669 sec_array_apply(array
, ^bool(__unused
size_t index
, sec_object_t object
) {
670 handler((dispatch_data_t
)object
);
678 sec_protocol_dispatch_data_are_equal(dispatch_data_t left
, dispatch_data_t right
)
680 if (!left
|| !right
|| left
== right
) {
681 return left
== right
;
683 if (dispatch_data_get_size(left
) != dispatch_data_get_size(right
)) {
687 __block
bool equal
= true;
688 dispatch_data_apply(left
, ^bool(__unused dispatch_data_t _Nonnull lregion
, size_t loffset
, const void * _Nonnull lbuffer
, size_t lsize
) {
689 dispatch_data_apply(right
, ^bool(__unused dispatch_data_t _Nonnull rregion
, size_t roffset
, const void * _Nonnull rbuffer
, size_t rsize
) {
690 // There is some overlap
691 const size_t start
= MAX(loffset
, roffset
);
692 const size_t end
= MIN(loffset
+ lsize
, roffset
+ rsize
);
694 equal
= memcmp(&((const uint8_t*)rbuffer
)[start
- roffset
], &((const uint8_t*)lbuffer
)[start
- loffset
], end
- start
) == 0;
696 if (roffset
> loffset
+ lsize
) {
697 // Iteration of right has gone past where we're at on left, bail out of inner apply
701 } else if (roffset
+ rsize
< loffset
) {
702 // Iteration of right has not yet reached where we're at on left, keep going
716 sec_protocol_sec_array_of_dispatch_data_are_equal(sec_array_t arrayA
, sec_array_t arrayB
)
718 if (sec_array_get_count(arrayA
) != sec_array_get_count(arrayB
)) {
722 __block
bool equal
= true;
723 (void)sec_array_apply(arrayA
, ^bool(size_t indexA
, sec_object_t objectA
) {
724 return sec_array_apply(arrayB
, ^bool(size_t indexB
, sec_object_t objectB
) {
725 if (indexA
== indexB
) {
726 dispatch_data_t dataA
= (dispatch_data_t
)objectA
;
727 dispatch_data_t dataB
= (dispatch_data_t
)objectB
;
728 equal
&= sec_protocol_dispatch_data_are_equal(dataA
, dataB
);
739 sec_protocol_sec_array_of_sec_certificate_are_equal(sec_array_t arrayA
, sec_array_t arrayB
)
741 if (sec_array_get_count(arrayA
) != sec_array_get_count(arrayB
)) {
745 __block
bool equal
= true;
746 (void)sec_array_apply(arrayA
, ^bool(size_t indexA
, sec_object_t objectA
) {
747 return sec_array_apply(arrayB
, ^bool(size_t indexB
, sec_object_t objectB
) {
748 if (indexA
== indexB
) {
749 sec_certificate_t certA
= (sec_certificate_t
)objectA
;
750 sec_certificate_t certB
= (sec_certificate_t
)objectB
;
752 SecCertificateRef certRefA
= sec_certificate_copy_ref(certA
);
753 SecCertificateRef certRefB
= sec_certificate_copy_ref(certB
);
755 if (certRefA
== NULL
&& certRefB
!= NULL
) {
757 } else if (certRefA
!= NULL
&& certRefB
== NULL
) {
759 } else if (certRefA
== NULL
&& certRefB
== NULL
) {
762 equal
&= CFEqual(certRefA
, certRefB
);
765 CFReleaseSafe(certRefA
);
766 CFReleaseSafe(certRefB
);
778 sec_protocol_xpc_object_are_equal(xpc_object_t objectA
, xpc_object_t objectB
)
780 if (objectA
== NULL
&& objectB
!= NULL
) {
782 } else if (objectA
!= NULL
&& objectB
== NULL
) {
784 } else if (objectA
== NULL
&& objectB
== NULL
) {
787 return xpc_equal(objectA
, objectB
);
792 sec_protocol_metadata_peers_are_equal(sec_protocol_metadata_t metadataA
, sec_protocol_metadata_t metadataB
)
794 SEC_PROTOCOL_METADATA_VALIDATE(metadataA
, false);
795 SEC_PROTOCOL_METADATA_VALIDATE(metadataB
, false);
797 return sec_protocol_metadata_access_handle(metadataA
, ^bool(void *handleA
) {
798 sec_protocol_metadata_content_t contentA
= (sec_protocol_metadata_content_t
)handleA
;
799 SEC_PROTOCOL_METADATA_VALIDATE(contentA
, false);
801 return sec_protocol_metadata_access_handle(metadataB
, ^bool(void *handleB
) {
802 sec_protocol_metadata_content_t contentB
= (sec_protocol_metadata_content_t
)handleB
;
803 SEC_PROTOCOL_METADATA_VALIDATE(contentB
, false);
805 // Relevant peer information includes: Certificate chain, public key, support signature algorithms, OCSP response, and distinguished names
806 if (!sec_protocol_sec_array_of_sec_certificate_are_equal(contentA
->peer_certificate_chain
, contentB
->peer_certificate_chain
)) {
809 if (!sec_protocol_dispatch_data_are_equal((dispatch_data_t
)contentA
->peer_public_key
, (dispatch_data_t
)contentB
->peer_public_key
)) {
812 if (!sec_protocol_xpc_object_are_equal((xpc_object_t
)contentA
->supported_signature_algorithms
, (xpc_object_t
)contentB
->supported_signature_algorithms
)) {
815 if (!sec_protocol_sec_array_of_dispatch_data_are_equal(contentA
->ocsp_response
, contentB
->ocsp_response
)) {
818 if (!sec_protocol_sec_array_of_dispatch_data_are_equal(contentA
->distinguished_names
, contentB
->distinguished_names
)) {
828 sec_protocol_metadata_challenge_parameters_are_equal(sec_protocol_metadata_t metadataA
, sec_protocol_metadata_t metadataB
)
830 SEC_PROTOCOL_METADATA_VALIDATE(metadataA
, false);
831 SEC_PROTOCOL_METADATA_VALIDATE(metadataB
, false);
833 return sec_protocol_metadata_access_handle(metadataA
, ^bool(void *handleA
) {
834 sec_protocol_metadata_content_t contentA
= (sec_protocol_metadata_content_t
)handleA
;
835 SEC_PROTOCOL_METADATA_VALIDATE(contentA
, false);
837 return sec_protocol_metadata_access_handle(metadataB
, ^bool(void *handleB
) {
838 sec_protocol_metadata_content_t contentB
= (sec_protocol_metadata_content_t
)handleB
;
839 SEC_PROTOCOL_METADATA_VALIDATE(contentB
, false);
841 if (!sec_protocol_xpc_object_are_equal((xpc_object_t
)contentA
->supported_signature_algorithms
, (xpc_object_t
)contentB
->supported_signature_algorithms
)) {
844 if (!sec_protocol_sec_array_of_dispatch_data_are_equal(contentA
->distinguished_names
, contentB
->distinguished_names
)) {
847 if (!sec_protocol_dispatch_data_are_equal(contentA
->request_certificate_types
, contentB
->request_certificate_types
)) {
857 sec_protocol_metadata_create_secret(sec_protocol_metadata_t metadata
, size_t label_len
,
858 const char *label
, size_t exporter_length
)
860 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
861 SEC_PROTOCOL_METADATA_VALIDATE(label_len
, NULL
);
862 SEC_PROTOCOL_METADATA_VALIDATE(label
, NULL
);
863 SEC_PROTOCOL_METADATA_VALIDATE(exporter_length
, NULL
);
865 __block dispatch_data_t secret
= NULL
;
866 sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
867 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
868 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
870 if (content
->exporter_function
&& content
->exporter_context
) {
871 sec_protocol_metadata_exporter exporter
= (sec_protocol_metadata_exporter
)content
->exporter_function
;
872 secret
= exporter(content
->exporter_context
, label_len
, label
, 0, NULL
, exporter_length
);
880 sec_protocol_metadata_create_secret_with_context(sec_protocol_metadata_t metadata
, size_t label_len
,
881 const char *label
, size_t context_len
,
882 const uint8_t *context
, size_t exporter_length
)
884 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, NULL
);
885 SEC_PROTOCOL_METADATA_VALIDATE(label_len
, NULL
);
886 SEC_PROTOCOL_METADATA_VALIDATE(label
, NULL
);
887 SEC_PROTOCOL_METADATA_VALIDATE(context_len
, NULL
);
888 SEC_PROTOCOL_METADATA_VALIDATE(context
, NULL
);
889 SEC_PROTOCOL_METADATA_VALIDATE(exporter_length
, NULL
);
891 __block dispatch_data_t secret
= NULL
;
892 sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
893 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
894 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
896 if (content
->exporter_function
&& content
->exporter_context
) {
897 sec_protocol_metadata_exporter exporter
= (sec_protocol_metadata_exporter
)content
->exporter_function
;
898 secret
= exporter(content
->exporter_context
, label_len
, label
, context_len
, context
, exporter_length
);
906 sec_protocol_metadata_get_tls_false_start_used(sec_protocol_metadata_t metadata
)
908 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
910 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
911 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
912 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
913 return content
->false_start_used
;
918 sec_protocol_metadata_get_ticket_offered(sec_protocol_metadata_t metadata
)
920 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
922 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
923 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
924 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
925 return content
->ticket_offered
;
930 sec_protocol_metadata_get_ticket_received(sec_protocol_metadata_t metadata
)
932 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
934 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
935 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
936 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
937 return content
->ticket_received
;
942 sec_protocol_metadata_get_session_resumed(sec_protocol_metadata_t metadata
)
944 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
946 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
947 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
948 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
949 return content
->session_resumed
;
954 sec_protocol_metadata_get_session_renewed(sec_protocol_metadata_t metadata
)
956 SEC_PROTOCOL_METADATA_VALIDATE(metadata
, false);
958 return sec_protocol_metadata_access_handle(metadata
, ^bool(void *handle
) {
959 sec_protocol_metadata_content_t content
= (sec_protocol_metadata_content_t
)handle
;
960 SEC_PROTOCOL_METADATA_VALIDATE(content
, false);
961 return content
->session_renewed
;
966 sec_retain(void *obj
)
969 return os_retain(obj
);
976 sec_release(void *obj
)