Some of this will apply to #PySVN as well. # SSL Certificate Trust ## Certificate Representations * Fingerprints seem to be SHA1 (but may depend on the certificate?) libsvn defines this in `svn_auth.h`: ```c typedef struct svn_auth_ssl_server_cert_info_t { /** Primary CN */ const char *hostname; /** ASCII fingerprint */ const char *fingerprint; /** ASCII date from which the certificate is valid */ const char *valid_from; /** ASCII date until which the certificate is valid */ const char *valid_until; /** DN of the certificate issuer */ const char *issuer_dname; /** Base-64 encoded DER certificate representation */ const char *ascii_cert; } svn_auth_ssl_server_cert_info_t; ``` PySVN's representation looks like: ```json { 'failures': <int>, 'hostname': <str>, 'finger_print': <SHA1 ':'-separated str>, 'valid_from': <ISO8601 timestamp>, 'valid_until': <ISO8601 timestamp>, 'issuer_dname': '<hostname>, <entity>, <city>, <state>, <country>', 'realm': 'https://<hostname>:<port>' } ``` E.g., ```json { 'failures': 8, 'hostname': '*.badssl.com', 'finger_print': '1D:B8:69:1E:B3:C4:52:9E:6A:BE:E4:1B:F3:54:74:A5:C7:A3:BA:8E', 'valid_from': 'Jul 21 21:56:12 2023 GMT', 'valid_until': 'Jul 20 21:56:12 2025 GMT', 'issuer_dname': '*.badssl.com, BadSSL, San Francisco, California, US', 'realm': 'https://self-signed.badssl.com:443' } ``` ## Callback handlers/providers In libsvn, all the functions below return a "provider" (`svn_auth_provider_object_t*`) that can be used when authenticating (`svn_auth_open()`). Not all of the below provide configuration options or callbacks. ### SSL Client Cert File Provider * Used to look up local client certificates when requested by the server for certificate-based authentication (see https://subgit.com/documentation/auth-book.html#ssl) * This does not provide any configuration. **libsvn:** `svn_auth_get_ssl_server_trust_file_provider` ```c // Signatures void svn_auth_get_ssl_server_trust_file_provider( svn_auth_provider_object_t** provider, apr_pool_t* pool); // Usage svn_auth_provider_object_t* provider = NULL; svn_auth_get_ssl_client_trust_file_provider( &provider, pool); ``` **PySVN:** None (handled internally) ### SSL Client Cert Prompt Provider * Used to prompt for a certificate file when using certificate-based authentication. **libsvn:** `svn_auth_get_ssl_client_cert_prompt_provider` ```c // Signatures typedef struct { const char* cert_file; svn_boolean_t may_save; } svn_auth_cred_ssl_cilent_cert_t; typedef svn_eror_t*(*svn_auth_ssl_client_cert_prompt_func_t)( svn_auth_cred_ssl_client_cert_t** cred, void* baton, const char* realm, svn_boolean_t may_save, apr_pool_t* pool); void svn_auth_get_ssl_client_cert_prompt_provider( svn_auth_provider_object_t** provider, svn_auth_ssl_client_cert_prompt_func_t prompt_func, void* prompt_baton, int retry_limit, apr_pool_t* pool); // Usage svn_error_t* _ssl_client_cert_prompt( svn_auth_cred_ssl_client_cert_t** cred, void* baton, const char* realm, svn_boolean_t may_save, apr_pool_t* pool) { // Set `cred` } svn_auth_provider_object_t* provider = NULL; svn_auth_get_ssl_client_cert_prompt_provider( &provider, _ssl_client_cert_prompt, customCallbackData, // The "baton" retry_limit, pool); ``` **PySVN:** `Client.callback_ssl_client_cert_prompt` ```python def _ssl_client_cert_prompt( ``` ### SSL Client Cert Password Prompt Provider * Used to prompt for a password for a certificate. * There are two versions of this in libsvn. Only documenting the first. **libsvn:** `svn_auth_get_ssl_client_cert_pw_file_provider2` **PySVN:** None (not available) ### SSL Server Trust File Provider * Used to look up trust information from the Subversion trust. * This does not provide any configuration. **libsvn:** `svn_auth_get_ssl_server_trust_file_provider` ```c svn_auth_provider_object_t* provider = NULL; svn_auth_get_ssl_server_trust_file_provider( &provider, pool); ``` **PySVN:** None (handled internally) ### SSL Server Trust Prompt Provider * Used to determine if a certificate is valid (for implementing verification or a custom trust store). * Can optionally tell Subversion to save the verification for the trust dictionary via `may_save`. **libsvn:** `svn_auth_get_ssl_server_trust_prompt_provider` ```c typedef struct { svn_boolean_t may_save; apr_uint32_t accepted_failures; } svn_auth_cred_ssl_server_trust_t; svn_error_t* _ssl_server_trust_prompt( svn_auth_cred_ssl_sever_trust_t** cred, void* baton, const char* realm, apr_uint32_t failures, const svn_auth_ssl_server_cert_info_t* cert_info, svn_boolean_t may_save, apr_pool_t* pool) { // Set `cred` } svn_auth_provider_object_t* provider = NULL; svn_auth_get_ssl_server_trust_prompt_provider( &provider, _ssl_server_trust_prompt, customCallbackData, // The "baton" pool); ``` * https://subversion.apache.org/docs/api/1.7/svn__auth_8h.html#a204388c3be43bff3c51e4490d7f40f43 **PySVN:** `Client.callback_ssl_server_trust_prompt` ```python class TrustDict(TypedDict): failures: int finger_print: str hostname: str issuer_dname: str realm: str valid_from: str valid_until: str def _ssl_server_trust_prompt( trust_data: TrustDict. ) -> Tuple[bool, int, bool]: # Return (verified, failures, may_save). ... client.callback_ssl_server_trust_prompt = _ssl_server_trust_prompt ```