// // SecProtocolPriv.h // Security // #ifndef SecProtocolPriv_h #define SecProtocolPriv_h #include <Security/SecProtocolOptions.h> #include <Security/SecProtocolMetadata.h> #include <Security/SecProtocolConfiguration.h> #include <Security/SecureTransportPriv.h> #include <Security/SecCertificatePriv.h> #include <xpc/xpc.h> __BEGIN_DECLS /* See: https://tools.ietf.org/html/rfc8446#section-4.2.7 */ typedef CF_ENUM(uint16_t, tls_key_exchange_group_t) { tls_key_exchange_group_Secp256r1 = 0x0017, tls_key_exchange_group_Secp384r1 = 0x0018, tls_key_exchange_group_Secp521r1 = 0x0019, tls_key_exchange_group_X25519 = 0x001D, tls_key_exchange_group_X448 = 0x001E, tls_key_exchange_group_FFDHE2048 = 0x0100, tls_key_exchange_group_FFDHE3072 = 0x0101, tls_key_exchange_group_FFDHE4096 = 0x0102, tls_key_exchange_group_FFDHE6144 = 0x0103, tls_key_exchange_group_FFDHE8192 = 0x0104, }; /* * Convenience key exchange groups that collate group identifiers of * comparable security into a single alias. */ typedef CF_ENUM(uint16_t, tls_key_exchange_group_set_t) { tls_key_exchange_group_set_default, tls_key_exchange_group_set_compatibility, tls_key_exchange_group_set_legacy, }; SEC_ASSUME_NONNULL_BEGIN #ifndef SEC_OBJECT_IMPL SEC_OBJECT_DECL(sec_array); #endif // !SEC_OBJECT_IMPL struct sec_protocol_options_content; typedef struct sec_protocol_options_content *sec_protocol_options_content_t; struct sec_protocol_metadata_content; typedef struct sec_protocol_metadata_content *sec_protocol_metadata_content_t; typedef void (^sec_protocol_tls_handshake_message_handler_t)(uint8_t type, dispatch_data_t message); typedef dispatch_data_t _Nullable (*sec_protocol_metadata_exporter)(void * handle, size_t label_len, const char *label, size_t context_len, const uint8_t * __nullable context, size_t exporter_len); typedef dispatch_data_t _Nullable (*sec_protocol_metadata_session_exporter)(void *handle); typedef bool (^sec_access_block_t)(void *handle); API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) SEC_RETURNS_RETAINED sec_array_t sec_array_create(void); API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) void sec_array_append(sec_array_t array, sec_object_t object); API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) size_t sec_array_get_count(sec_array_t array); typedef bool (^sec_array_applier_t) (size_t index, sec_object_t object); API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) bool sec_array_apply(sec_array_t array, sec_array_applier_t applier); /*! * @function sec_protocol_options_access_handle * * @abstract * Access the internal handle of a `sec_protocol_options` object. * * @param options * A `sec_protocol_options_t` instance. * * @param access_block * A block to invoke with access to the internal handle. * * @return True if the access was successful */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) bool sec_protocol_options_access_handle(sec_protocol_options_t options, sec_access_block_t access_block); /*! * @function sec_protocol_options_contents_are_equal * * @abstract * Compare two `sec_protocol_options_content_t` structs for equality. * * @param contentA * A `sec_protocol_options_t` instance. * * @param contentB * A `sec_protocol_options_t` instance. * * @return True if equal, and false otherwise. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) bool sec_protocol_options_contents_are_equal(sec_protocol_options_content_t contentA, sec_protocol_options_content_t contentB); /*! * @function sec_protocol_options_set_tls_early_data_enabled * * @abstract * Enable or disable early (0-RTT) data for TLS. * * @param options * A `sec_protocol_options_t` instance. * * @param early_data_enabled * Flag to enable or disable early (0-RTT) data. */ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) void sec_protocol_options_set_tls_early_data_enabled(sec_protocol_options_t options, bool early_data_enabled); /*! * @function sec_protocol_options_set_tls_sni_disabled * * @abstract * Enable or disable the TLS SNI extension. This defaults to `false`. * * @param options * A `sec_protocol_options_t` instance. * * @param sni_disabled * Flag to enable or disable use of the TLS SNI extension. */ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) void sec_protocol_options_set_tls_sni_disabled(sec_protocol_options_t options, bool sni_disabled); /*! * @function sec_protocol_options_set_enforce_ev * * @abstract * Enable or disable EV enforcement. * * @param options * A `sec_protocol_options_t` instance. * * @param enforce_ev * Flag to determine if EV is enforced. */ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) void sec_protocol_options_set_enforce_ev(sec_protocol_options_t options, bool enforce_ev); /*! * @block sec_protocol_session_update_t * * @abstract * Block to be invoked when a new session is established and ready. * * @param metadata * A `sec_protocol_metadata_t` instance. */ typedef void (^sec_protocol_session_update_t)(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_options_set_session_update_block * * @abstract * Set the session update block. This is fired whenever a new session is * created an inserted into the cache. * * @param options * A `sec_protocol_options_t` instance. * * @param update_block * A `sec_protocol_session_update_t` instance. * * @params update_queue * A `dispatch_queue_t` on which the update block should be called. */ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) void sec_protocol_options_set_session_update_block(sec_protocol_options_t options, sec_protocol_session_update_t update_block, dispatch_queue_t update_queue); /*! * @function sec_protocol_options_set_session_state * * @abstract * Set the session state using a serialized session blob. * * If the session state is invalid or otherwise corrupt, the state is ignored and * the connection will proceed as if no state was provided. * * @param options * A `sec_protocol_options_t` instance. * * @param session_state * A `dispatch_data_t` carrying serialized session state from a previous. */ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) void sec_protocol_options_set_session_state(sec_protocol_options_t options, dispatch_data_t session_state); /*! * @function sec_protocol_options_set_quic_transport_parameters * * @abstract * Set the opaque QUIC transport parameters to be used for this connection. * * @param options * A `sec_protocol_options_t` instance. * * @param transport_parameters * A `dispatch_data_t` carrying opqaue QUIC transport parameters. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void sec_protocol_options_set_quic_transport_parameters(sec_protocol_options_t options, dispatch_data_t transport_parameters); /*! * @enum sec_protocol_tls_encryption_level_t * * @abstract An enumeration of the different TLS encryption levels. */ typedef enum { sec_protocol_tls_encryption_level_initial = 0, sec_protocol_tls_encryption_level_early_data, sec_protocol_tls_encryption_level_handshake, sec_protocol_tls_encryption_level_application, } sec_protocol_tls_encryption_level_t; /*! * @block sec_protocol_tls_encryption_secret_update_t * * @abstract * Block to be invoked when a new session is established and ready. * * @param level * The `sec_protocol_tls_encryption_level_t` for this secret. * * @param is_write * True if this secret is for writing, and false if it's for reading. * * @param secret * Secret wrapped in a `dispatch_data_t` */ typedef void (^sec_protocol_tls_encryption_secret_update_t)(sec_protocol_tls_encryption_level_t level, bool is_write, dispatch_data_t secret); /*! * @function sec_protocol_options_set_tls_encryption_secret_update_block * * @abstract * Set the TLS secret update block. This is fired whenever a new TLS secret is * available. * * @param options * A `sec_protocol_options_t` instance. * * @param update_block * A `sec_protocol_tls_encryption_secret_update_t` instance. * * @params update_queue * A `dispatch_queue_t` on which the update block should be called. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void 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); /*! * @block sec_protocol_private_key_complete_t * * @abstract * Block to be invoked when a private key operation is complete. * * @param result * A `dispatch_data_t` object containing the private key result. */ typedef void (^sec_protocol_private_key_complete_t)(dispatch_data_t result); /*! * @block sec_protocol_private_key_sign_t * * @abstract * Block to be invoked when a private key signature operation is required. * * @param algorithm * The signature algorithm to use for the signature. * * @param input * The input to be signed. * * @param complete * The `sec_protocol_private_key_complete_t` block to invoke when the operation is complete. */ typedef void (^sec_protocol_private_key_sign_t)(uint16_t algorithm, dispatch_data_t input, sec_protocol_private_key_complete_t complete); /*! * @block sec_protocol_private_key_decrypt_t * * @abstract * Block to be invoked when a private key decryption operation is required. * * @param input * The input to be decrypted. * * @param complete * The `sec_protocol_private_key_complete_t` block to invoke when the operation is complete. */ typedef void (^sec_protocol_private_key_decrypt_t)(dispatch_data_t input, sec_protocol_private_key_complete_t complete); /*! * @block sec_protocol_options_set_private_key_blocks * * @abstract * Set the private key operation blocks for this connection. * * @param options * A `sec_protocol_options_t` instance. * * @param sign_block * A `sec_protocol_private_key_sign_t` block. * * @param decrypt_block * A `sec_protocol_private_key_decrypt_t` block. * * @param operation_queue * The `dispatch_queue_t` queue on which each private key operation is invoked. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void sec_protocol_options_set_private_key_blocks(sec_protocol_options_t options, sec_protocol_private_key_sign_t sign_block, sec_protocol_private_key_decrypt_t decrypt_block, dispatch_queue_t operation_queue); /*! * @block sec_protocol_options_set_local_certificates * * @abstract * Set the local certificates to be used for this protocol instance. * * @param options * A `sec_protocol_options_t` instance. * * @param certificates * A `sec_array_t` instance of `sec_certifiate_t` instances. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void sec_protocol_options_set_local_certificates(sec_protocol_options_t options, sec_array_t certificates); /*! * @block sec_protocol_options_set_tls_certificate_compression_enabled * * @abstract * Enable or disable TLS 1.3 certificate compression. * * See: https://tools.ietf.org/html/draft-ietf-tls-certificate-compression-04 * * @param options * A `sec_protocol_options_t` instance. * * @param certificate_compression_enabled * Flag to determine if certificate compression is enabled. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void sec_protocol_options_set_tls_certificate_compression_enabled(sec_protocol_options_t options, bool certificate_compression_enabled); /*! * @block sec_protocol_options_tls_handshake_message_callback * * @abstract * Set a callback to process each TLS handshake message. This function may be invoked at any point during * the TLS handshake, if at all. Clients MUST NOT rely on any behavior aspect of this function as they * risk breaking. * * @param options * A `sec_protocol_options_t` instance. * * @param handler * A `sec_protocol_tls_handshake_message_handler_t`. * * @param queue * The queue upon which to invoke the callback. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void sec_protocol_options_tls_handshake_message_callback(sec_protocol_options_t options, sec_protocol_tls_handshake_message_handler_t handler, dispatch_queue_t queue); /*! * @block sec_protocol_options_append_tls_key_exchange_group * * @abstract * Append a TLS key exchange group to the set of enabled groups. * * @param options * A `sec_protocol_options_t` instance. * * @param group * A `tls_key_exchange_group_t` value. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void sec_protocol_options_append_tls_key_exchange_group(sec_protocol_options_t options, tls_key_exchange_group_t group); /*! * @block sec_protocol_options_add_tls_key_exchange_group * * @abstract * Add a TLS key exchange group to the set of enabled groups. * * @param options * A `sec_protocol_options_t` instance. * * @param group * A SSLKeyExchangeGroup value. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void sec_protocol_options_add_tls_key_exchange_group(sec_protocol_options_t options, SSLKeyExchangeGroup group); /*! * @block sec_protocol_options_append_tls_key_exchange_group_set * * @abstract * Append a TLS key exchange group set to the set of enabled groups. * * @param options * A `sec_protocol_options_t` instance. * * @param set * A `tls_key_exchange_group_set_t` value. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void sec_protocol_options_append_tls_key_exchange_group_set(sec_protocol_options_t options, tls_key_exchange_group_set_t set); /*! * @block sec_protocol_options_tls_key_exchange_group_set * * @abstract * Add a TLS key exchange group set to the set of enabled groups. * * @param options * A `sec_protocol_options_t` instance. * * @param set * A SSLKeyExchangeGroupSet value. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void sec_protocol_options_add_tls_key_exchange_group_set(sec_protocol_options_t options, SSLKeyExchangeGroupSet set); /*! * @function sec_protocol_options_set_tls_SIKE503_exchange_enabled * * @abstract * Enable SIKE using P503 for TLS 1.3 key exchange. * * DO NOT DEPEND ON THIS SPI. IT IS FOR EXPERIMENTAL PURPOSES AND SUBJECT TO REMOVAL WITHOUT ADVANCE NOTICE. * BUILD BREAKAGE ISSUES WILL BE SENT TO THE CALLING PROJECT. * * @param options * A `sec_protocol_options_t` instance. * * @param tls_SIKE503_exchange_enabled * Flag to enable SIKE with P503. */ #define SEC_PROTOCOL_HAS_PQ_TLS_HANDLES 1 API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void sec_protocol_options_set_tls_SIKE503_exchange_enabled(sec_protocol_options_t options, bool tls_SIKE503_exchange_enabled); /*! * @function sec_protocol_options_set_tls_HRSS_exchange_enabled * * @abstract * Enable HRSS for TLS 1.3 key exchange. * * DO NOT DEPEND ON THIS SPI. IT IS FOR EXPERIMENTAL PURPOSES AND SUBJECT TO REMOVAL WITHOUT ADVANCE NOTICE. * BUILD BREAKAGE ISSUES WILL BE SENT TO THE CALLING PROJECT. * * @param options * A `sec_protocol_options_t` instance. * * @param tls_HRSS_exchange_enabled * Flag to enable HRSS. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void sec_protocol_options_set_tls_HRSS_exchange_enabled(sec_protocol_options_t options, bool tls_HRSS_exchange_enabled); /*! * @function sec_protocol_options_set_eddsa_enabled * * @abstract * Enable EDDSA support (for TLS 1.3). * * @param options * A `sec_protocol_options_t` instance. * * @param eddsa_enabled * Flag to enable EDDSA. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void sec_protocol_options_set_eddsa_enabled(sec_protocol_options_t options, bool eddsa_enabled); /*! * @function sec_protocol_options_set_tls_delegated_credentials_enabled * * @abstract * Enable TLS delegated credentials support. See https://tools.ietf.org/html/draft-ietf-tls-subcerts-02. * * DO NOT DEPEND ON THIS SPI. IT IS FOR EXPERIMENTAL PURPOSES AND SUBJECT TO REMOVAL WITHOUT ADVANCE NOTICE. * BUILD BREAKAGE ISSUES WILL BE SENT TO THE CALLING PROJECT. * * @param options * A `sec_protocol_options_t` instance. * * @param tls_delegated_credentials_enabled * Flag to enable TLS delegated credentials. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void sec_protocol_options_set_tls_delegated_credentials_enabled(sec_protocol_options_t options, bool tls_delegated_credentials_enabled); /*! * @function sec_protocol_options_set_tls_ticket_request_count * * @abstract * Enable TLS ticket request support, and specify the count of tickets. Ticket support * must also be explicitly enabled by `sec_protocol_options_set_tls_tickets_enabled`. * * DO NOT DEPEND ON THIS SPI. IT IS FOR EXPERIMENTAL PURPOSES AND SUBJECT TO REMOVAL WITHOUT ADVANCE NOTICE. * BUILD BREAKAGE ISSUES WILL BE SENT TO THE CALLING PROJECT. * * @param options * A `sec_protocol_options_t` instance. * * @param tls_ticket_request_count * Set the amount of tickets to request from the server. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void sec_protocol_options_set_tls_ticket_request_count(sec_protocol_options_t options, uint8_t tls_ticket_request_count); /*! * @function sec_protocol_options_set_tls_grease_enabled * * @abstract * Enable TLS GREASE support. See https://tools.ietf.org/html/draft-ietf-tls-grease-02. * * DO NOT DEPEND ON THIS SPI. IT IS FOR EXPERIMENTAL PURPOSES AND SUBJECT TO REMOVAL WITHOUT ADVANCE NOTICE. * BUILD BREAKAGE ISSUES WILL BE SENT TO THE CALLING PROJECT. * * @param options * A `sec_protocol_options_t` instance. * * @param tls_grease_enabled * Flag to enable TLS GREASE. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void sec_protocol_options_set_tls_grease_enabled(sec_protocol_options_t options, bool tls_grease_enabled); /*! * @function sec_protocol_options_set_experiment_identifier * * @abstract * Set the SecExperiment identifier for a given connection. * * Note: this SPI is meant to be called by libnetcore. It should not be called in any other circumstances. * * @param options * A `sec_protocol_options_t` instance. * * @param experiment_identifier * The identifier for a secure connection experiment. */ #define SEC_PROTOCOL_HAS_EXPERIMENT_IDENTIFIER 1 API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void sec_protocol_options_set_experiment_identifier(sec_protocol_options_t options, const char *experiment_identifier); /*! * @function sec_protocol_options_set_connection_id * * @abstract * Set the explciit connection identifier. If not set, one will be populated internally. * * @param options * A `sec_protocol_options_t` instance. * * @param connection_id * The `uuid_t`` connection identifier. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void sec_protocol_options_set_connection_id(sec_protocol_options_t options, uuid_t _Nonnull connection_id); /*! * @function sec_protocol_options_create_config * * @abstract * Create a `xpc_object_t` instance carrying a configuration for the given `sec_protocol_options_t` instance. * * @param options * A `sec_protocol_options_t` instance. * * @return A `xpc_object_t` instance carrying a configuration, or nil on failure. */ #define SEC_PROTOCOL_HAS_EXPERIMENT_HOOKS 1 API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) SEC_RETURNS_RETAINED __nullable xpc_object_t sec_protocol_options_create_config(sec_protocol_options_t options); /*! * @function sec_protocol_options_matches_config * * @abstract * Determine if a `sec_protocol_options_t` instance matches a given configuration. * * @param options * A `sec_protocol_options_t` instance. * * @param config * A `xpc_object_t` instance carrying a SecExperiment config. * * @return True if the parameters in `config` match that of `options`, and false otherwise. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) bool sec_protocol_options_matches_config(sec_protocol_options_t options, xpc_object_t config); /*! * @function sec_protocol_options_apply_config * * @abstract * Transform the given `sec_protocol_options_t` instance using the provided config. * * @param options * A `sec_protocol_options_t` instance. * * @param config * A `xpc_object_t` instance carrying a SecExperiment config. * * @return True if the options were applied successfully, and false otherwise. */ bool sec_protocol_options_apply_config(sec_protocol_options_t options, xpc_object_t config); /*! * @function sec_protocol_metadata_get_tls_negotiated_group * * @abstract * Get a human readable representation of the negotiated key exchange group. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return A string representation of the negotiated group, or NULL if it does not exist. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) const char * __nullable sec_protocol_metadata_get_tls_negotiated_group(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_get_experiment_identifier * * @abstract * Get the SecExperiment identifier for a given connection. * * Note: this SPI is meant to be called by libnetcore. It should not be called in any other circumstances. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return The identifier for a secure connection experiment, or NULL if none was specified. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) const char * __nullable sec_protocol_metadata_get_experiment_identifier(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_copy_connection_id * * @abstract * Copy the secure connection identifier. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @param output_uuid * A `uuid_t` into which the connection identifier is written. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void sec_protocol_metadata_copy_connection_id(sec_protocol_metadata_t metadata, uuid_t _Nonnull output_uuid); /*! * @function sec_protocol_metadata_get_tls_false_start_used * * @abstract * Determine if False Start was used. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return True if False Start was used, and false otherwise. */ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) bool sec_protocol_metadata_get_tls_false_start_used(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_get_ticket_offered * * @abstract * Determine if a ticket was offered for session resumption. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return True if a ticket was offered for resumption, and false otherwise. */ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) bool sec_protocol_metadata_get_ticket_offered(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_get_ticket_received * * @abstract * Determine if a ticket was received upon completing the new connection. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return True if a ticket was received from the peer (server), and false otherwise. */ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) bool sec_protocol_metadata_get_ticket_received(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_get_session_resumed * * @abstract * Determine if this new connection was a session resumption. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return True if this new connection was resumed, and false otherwise. */ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) bool sec_protocol_metadata_get_session_resumed(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_get_session_renewed * * @abstract * Determine if this resumed connection was renewed with a new ticket. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return True if this resumed connection was renewed with a new ticket, and false otherwise. */ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) bool sec_protocol_metadata_get_session_renewed(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_get_connection_strength * * @abstract * Determine the TLS connection strength. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return An `SSLConnectionStrength` enum. */ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) SSLConnectionStrength sec_protocol_metadata_get_connection_strength(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_copy_serialized_session * * @abstract * Copy a serialized representation of a session. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return A `dispatch_data_t` object containing a serialized session. */ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) SEC_RETURNS_RETAINED __nullable dispatch_data_t sec_protocol_metadata_copy_serialized_session(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_access_handle * * @abstract * Access the internal handle of a `sec_protocol_metadata` object. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @param access_block * A block to invoke with access to the internal handle. * * @return True if the access was successful */ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) bool sec_protocol_metadata_access_handle(sec_protocol_metadata_t metadata, sec_access_block_t access_block); /*! * @function sec_protocol_metadata_serialize_with_options * * @abstract * Serialize a `sec_protocol_metadata_t` to an `xpc_object_t` dictionary using information * contained in the `metadata` and `options` objects. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return A xpc_object_t carrying the serialized metadata. */ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) SEC_RETURNS_RETAINED __nullable xpc_object_t sec_protocol_metadata_serialize_with_options(sec_protocol_metadata_t metadata, sec_protocol_options_t options); /*! * @function sec_protocol_metadata_get_tls_certificate_compression_used * * @abstract * Determine if certificate compression was used for a given connection. * * See: https://tools.ietf.org/html/draft-ietf-tls-certificate-compression-04 * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return True if certificate compression was negotiated and used. */ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) bool sec_protocol_metadata_get_tls_certificate_compression_used(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_get_tls_certificate_compression_algorithm * * @abstract * Return the certificate compression algorithm used. This will return 0 * if `sec_protocol_metadata_get_tls_certificate_compression_used` is false. * * See: https://tools.ietf.org/html/draft-ietf-tls-certificate-compression-04 * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return IANA codepoint for the certificate compression algorithm. */ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) uint16_t sec_protocol_metadata_get_tls_certificate_compression_algorithm(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_copy_quic_transport_parameters * * @abstract * Copy the peer's QUIC transport parameters. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return A dispatch_data_t carrying the connection peer's opaque QUIC tranport parameters. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) SEC_RETURNS_RETAINED __nullable dispatch_data_t sec_protocol_metadata_copy_quic_transport_parameters(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_get_handshake_time_ms * * @abstract * Get the TLS handshake time in miliseconds. The result is undefined * for connections not yet connected. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return A millisecond measurement of the TLS handshake time from start to finish. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) #define SEC_PROTOCOL_HAS_METRIC_SPI_V1 uint64_t sec_protocol_metadata_get_handshake_time_ms(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_get_handshake_rtt * * @abstract * Get the observed TLS handshake RTT. This function must only be * called after the connection is established. Calling this before * the connection completes will yields an undefined result. * * This is computed as the average RTT across all 1-RTT exchanges. * For TLS 1.3, this will be the time for the normal exchange. For prior * versions, or TLS 1.3 with HRR, this will be the average RTT across * multiple message flights. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return A millisecond measurement of the TLS handshake RTT. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) uint64_t sec_protocol_metadata_get_handshake_rtt(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_get_handshake_byte_count * * @abstract * Get the total number of bytes sent and received for the handshake. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return Number of bytes sent and received for the handshake. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) uint64_t sec_protocol_metadata_get_handshake_byte_count(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_get_handshake_sent_byte_count * * @abstract * Get the total number of bytes sent for the handshake. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return Number of bytes sent for the handshake. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) uint64_t sec_protocol_metadata_get_handshake_sent_byte_count(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_get_handshake_received_byte_count * * @abstract * Get the total number of bytes received for the handshake. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return Number of bytes received for the handshake. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) uint64_t sec_protocol_metadata_get_handshake_received_byte_count(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_get_handshake_read_stall_count * * @abstract * Get the total number of read stalls during the handshake. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return Number of read stalls. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) size_t sec_protocol_metadata_get_handshake_read_stall_count(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_get_handshake_write_stall_count * * @abstract * Get the total number of write stalls during the handshake. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return Number of write stalls. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) size_t sec_protocol_metadata_get_handshake_write_stall_count(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_get_handshake_async_call_count * * @abstract * Get the total number of asynchronous callbacks invoked during the handshake. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return Number of asynchronous callbacks. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) size_t sec_protocol_metadata_get_handshake_async_call_count(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_copy_sec_trust * * @abstract * Copy the `sec_trust_t` associated with a connection. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return A `sec_trust_t` instance. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) SEC_RETURNS_RETAINED __nullable sec_trust_t sec_protocol_metadata_copy_sec_trust(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_copy_sec_identity * * @abstract * Copy the `sec_identity_t` associated with a connection. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return A `sec_identity_t` instance. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) SEC_RETURNS_RETAINED __nullable sec_identity_t sec_protocol_metadata_copy_sec_identity(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_metadata_access_sent_certificates * * @abstract * Access the certificates which were sent to the peer on this connection. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @param handler * A block to invoke one or more times with `sec_certificate_t` instances. * * @return Returns true if the peer certificates were accessible, false otherwise. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) bool sec_protocol_metadata_access_sent_certificates(sec_protocol_metadata_t metadata, void (^handler)(sec_certificate_t certificate)); /*! * @function sec_protocol_metadata_get_tls_negotiated_group * * @abstract * Get a human readable representation of the negotiated key exchange group. * * @param metadata * A `sec_protocol_metadata_t` instance. * * @return A string representation of the negotiated group, or NULL if it does not exist. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) const char * __nullable sec_protocol_metadata_get_tls_negotiated_group(sec_protocol_metadata_t metadata); /*! * @function sec_protocol_configuration_copy_singleton * * @abstract * Copy the per-process `sec_protocol_configuration_t` object. * * @return A non-nil `sec_protocol_configuration_t` instance. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) SEC_RETURNS_RETAINED sec_protocol_configuration_t sec_protocol_configuration_copy_singleton(void); #ifndef SEC_OBJECT_IMPL SEC_OBJECT_DECL(sec_protocol_configuration_builder); #endif // !SEC_OBJECT_IMPL /*! * @function sec_protocol_configuration_builder_create * * @abstract * This function is exposed for testing purposes only. It MUST NOT be called by clients. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) SEC_RETURNS_RETAINED sec_protocol_configuration_builder_t sec_protocol_configuration_builder_create(CFDictionaryRef dictionary, bool is_apple); /*! * @function sec_protocol_configuration_create_with_builder * * @abstract * This function is exposed for testing purposes only. It MUST NOT be called by clients. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) SEC_RETURNS_RETAINED __nullable sec_protocol_configuration_t sec_protocol_configuration_create_with_builder(sec_protocol_configuration_builder_t builder); /*! * @block sec_protocol_output_handler_access_block_t * * @abstract * Block to be invoked to obtain the output handler for a given encryption level. */ typedef void *_Nullable(^sec_protocol_output_handler_access_block_t)(sec_protocol_tls_encryption_level_t level); /*! * @function sec_protocol_options_set_output_handler_access_block * * @abstract * Set a block used to access output handler instances identified by encryption level. */ #define SEC_PROTOCOL_HAS_QUIC_OUTPUT_HANDLER_ACCESS_BLOCK 1 API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void sec_protocol_options_set_output_handler_access_block(sec_protocol_options_t options, sec_protocol_output_handler_access_block_t access_block); /*! * @function sec_protocol_helper_ciphersuite_group_to_ciphersuite_list * * @abstract * Return a pointer to a statically allocated list of ciphersuites corresponding to `group`. * * @param group * A `tls_ciphersuite_group_t` instance. * * @param list_count * Pointer to storage for the ciphersuite list length. * * @return Pointer to a statically allocated list, or NULL if an error occurred. */ API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) const tls_ciphersuite_t * __nullable sec_protocol_helper_ciphersuite_group_to_ciphersuite_list(tls_ciphersuite_group_t group, size_t *list_count); #define SEC_PROTOCOL_HAS_MULTI_PSK_SUPPORT 1 struct sec_protocol_options_content { SSLProtocol min_version; SSLProtocol max_version; char *server_name; char *experiment_identifier; uuid_t connection_id; __nullable xpc_object_t ciphersuites; xpc_object_t application_protocols; sec_identity_t identity; sec_array_t certificates; xpc_object_t pre_shared_keys; dispatch_data_t psk_identity_hint; sec_protocol_key_update_t key_update_block; dispatch_queue_t key_update_queue; sec_protocol_challenge_t challenge_block; dispatch_queue_t challenge_queue; sec_protocol_verify_t verify_block; dispatch_queue_t verify_queue; dispatch_data_t quic_transport_parameters; sec_protocol_tls_encryption_secret_update_t tls_secret_update_block; dispatch_queue_t tls_secret_update_queue; sec_protocol_session_update_t session_update_block; dispatch_queue_t session_update_queue; dispatch_data_t session_state; sec_protocol_private_key_sign_t private_key_sign_block; sec_protocol_private_key_decrypt_t private_key_decrypt_block; dispatch_queue_t private_key_queue; dispatch_data_t dh_params; xpc_object_t key_exchange_groups; sec_protocol_tls_handshake_message_handler_t handshake_message_callback; dispatch_queue_t handshake_message_callback_queue; sec_protocol_pre_shared_key_selection_t psk_selection_block; dispatch_queue_t psk_selection_queue; // ATS minimums size_t minimum_rsa_key_size; size_t minimum_ecdsa_key_size; SecSignatureHashAlgorithm minimum_signature_algorithm; // Non-boolean options uint8_t tls_ticket_request_count; // QUIC-specific access block sec_protocol_output_handler_access_block_t output_handler_access_block; // Boolean flags unsigned ats_required : 1; unsigned ats_minimum_tls_version_allowed : 1; unsigned ats_non_pfs_ciphersuite_allowed : 1; unsigned trusted_peer_certificate : 1; unsigned trusted_peer_certificate_override : 1; unsigned disable_sni : 1; unsigned disable_sni_override : 1; unsigned enable_fallback_attempt : 1; unsigned enable_fallback_attempt_override : 1; unsigned enable_false_start : 1; unsigned enable_false_start_override : 1; unsigned enable_tickets : 1; unsigned enable_tickets_override : 1; unsigned enable_sct : 1; unsigned enable_sct_override : 1; unsigned enable_ocsp : 1; unsigned enable_ocsp_override : 1; unsigned enforce_ev : 1; unsigned enforce_ev_override : 1; unsigned enable_resumption : 1; unsigned enable_resumption_override : 1; unsigned enable_renegotiation : 1; unsigned enable_renegotiation_override : 1; unsigned enable_early_data : 1; unsigned enable_early_data_override : 1; unsigned peer_authentication_required : 1; unsigned peer_authentication_override : 1; unsigned certificate_compression_enabled : 1; unsigned tls_SIKE503_exchange_enabled : 1; unsigned tls_HRSS_exchange_enabled : 1; unsigned eddsa_enabled : 1; unsigned tls_delegated_credentials_enabled : 1; unsigned tls_grease_enabled : 1; }; struct sec_protocol_metadata_content { void *exporter_context; // Opaque context for the exporter function sec_protocol_metadata_exporter exporter_function; // Exporter function pointer. This MUST be set by the metadata allocator. void *session_exporter_context; // Opaque context for the session exporter function sec_protocol_metadata_session_exporter session_exporter_function; SSLProtocol negotiated_protocol_version; SSLCipherSuite negotiated_ciphersuite; const char *negotiated_protocol; const char *server_name; const char *experiment_identifier; uuid_t connection_id; sec_array_t sent_certificate_chain; sec_array_t peer_certificate_chain; xpc_object_t pre_shared_keys; dispatch_data_t peer_public_key; xpc_object_t supported_signature_algorithms; dispatch_data_t request_certificate_types; sec_array_t signed_certificate_timestamps; sec_array_t ocsp_response; sec_array_t distinguished_names; dispatch_data_t quic_transport_parameters; sec_identity_t identity; sec_trust_t trust_ref; const char *negotiated_curve; const char *peer_public_key_type; const char *certificate_request_type; uint64_t ticket_lifetime; uint64_t max_early_data_supported; uint64_t alert_type; uint64_t alert_code; uint64_t handshake_state; uint64_t stack_error; uint64_t handshake_rtt; uint16_t certificate_compression_algorithm; uint64_t handshake_time; uint64_t total_byte_count; uint64_t sent_byte_count; uint64_t received_byte_count; size_t read_stall_count; size_t write_stall_count; size_t async_call_count; unsigned failure : 1; unsigned sct_enabled : 1; unsigned ocsp_enabled : 1; unsigned early_data_accepted : 1; unsigned false_start_used : 1; unsigned ticket_offered : 1; unsigned ticket_received : 1; unsigned session_resumed : 1; unsigned session_renewed : 1; unsigned resumption_attempted : 1; unsigned alpn_used : 1; unsigned npn_used : 1; unsigned early_data_sent : 1; unsigned certificate_compression_used : 1; }; SEC_ASSUME_NONNULL_END __END_DECLS #endif /* SecProtocolPriv_h */