2222# include "streams/curl.h"
2323#endif
2424
25+ #ifndef GIT_DEFAULT_CERT_LOCATION
26+ #define GIT_DEFAULT_CERT_LOCATION NULL
27+ #endif
28+
2529#include <mbedtls/config.h>
2630#include <mbedtls/ssl.h>
31+ #include <mbedtls/error.h>
2732#include <mbedtls/entropy.h>
2833#include <mbedtls/ctr_drbg.h>
2934
30- #define CRT_LOC "/etc/ssl/certs"
31-
3235mbedtls_ssl_config * git__ssl_conf ;
3336mbedtls_entropy_context * mbedtls_entropy ;
3437
@@ -57,9 +60,13 @@ static void shutdown_ssl(void)
5760 }
5861}
5962
63+ int git_mbedtls__set_cert_location (const char * path , int is_dir );
64+
6065int git_mbedtls_stream_global_init (void )
6166{
62- int ret ;
67+ int loaded = 0 ;
68+ char * crtpath = GIT_DEFAULT_CERT_LOCATION ;
69+ struct stat statbuf ;
6370 mbedtls_ctr_drbg_context * ctr_drbg = NULL ;
6471
6572 int * ciphers_list = NULL ;
@@ -121,16 +128,11 @@ int git_mbedtls_stream_global_init(void)
121128
122129 mbedtls_ssl_conf_rng (git__ssl_conf , mbedtls_ctr_drbg_random , ctr_drbg );
123130
124- // set root certificates
125- cacert = git__malloc (sizeof (mbedtls_x509_crt ));
126- mbedtls_x509_crt_init (cacert );
127- ret = mbedtls_x509_crt_parse_path (cacert , CRT_LOC );
128- if (ret ) {
129- giterr_set (GITERR_SSL , "failed to load CA certificates: %d" , ret );
130- goto cleanup ;
131- }
132-
133- mbedtls_ssl_conf_ca_chain (git__ssl_conf , cacert , NULL );
131+ /* load default certificates */
132+ if (crtpath != NULL && stat (crtpath , & statbuf ) == 0 && S_ISREG (statbuf .st_mode ))
133+ loaded = (git_mbedtls__set_cert_location (crtpath , 0 ) == 0 );
134+ if (!loaded && crtpath != NULL && stat (crtpath , & statbuf ) == 0 && S_ISDIR (statbuf .st_mode ))
135+ loaded = (git_mbedtls__set_cert_location (crtpath , 1 ) == 0 );
134136
135137 git__on_shutdown (shutdown_ssl );
136138
@@ -388,20 +390,34 @@ int git_mbedtls_stream_new(git_stream **out, const char *host, const char *port)
388390 return error ;
389391}
390392
391- int git_mbedtls__set_cert_location (const char * file , const char * path )
393+ int git_mbedtls__set_cert_location (const char * path , int is_dir )
392394{
393395 int ret = 0 ;
394396 char errbuf [512 ];
395- if (!file ) {
396- ret = mbedtls_x509_crt_parse_file (git__ssl_conf -> ca_chain , file );
397- } else if (!path ) {
398- ret = mbedtls_x509_crt_parse_path (git__ssl_conf -> ca_chain , path );
397+ mbedtls_x509_crt * cacert ;
398+
399+ assert (path != NULL );
400+
401+ cacert = git__malloc (sizeof (mbedtls_x509_crt ));
402+ mbedtls_x509_crt_init (cacert );
403+ if (is_dir ) {
404+ ret = mbedtls_x509_crt_parse_path (cacert , path );
405+ } else {
406+ ret = mbedtls_x509_crt_parse_file (cacert , path );
399407 }
400- if (ret != 0 ) {
408+ /* mbedtls_x509_crt_parse_path returns the number of invalid certs on success */
409+ if (ret < 0 ) {
410+ mbedtls_x509_crt_free (cacert );
411+ git__free (cacert );
401412 mbedtls_strerror ( ret , errbuf , 512 );
402- giterr_set (GITERR_NET , "SSL error: %d - %s " , ret , errbuf );
413+ giterr_set (GITERR_SSL , "failed to load CA certificates : %s (%d) " , errbuf , ret );
403414 return -1 ;
404415 }
416+
417+ mbedtls_x509_crt_free (git__ssl_conf -> ca_chain );
418+ git__free (git__ssl_conf -> ca_chain );
419+ mbedtls_ssl_conf_ca_chain (git__ssl_conf , cacert , NULL );
420+
405421 return 0 ;
406422}
407423
@@ -424,10 +440,10 @@ int git_mbedtls_stream_new(git_stream **out, const char *host, const char *port)
424440 return -1 ;
425441}
426442
427- int git_mbedtls__set_cert_location (const char * file , const char * path )
443+ int git_mbedtls__set_cert_location (const char * path , int is_dir )
428444{
429- GIT_UNUSED (file );
430445 GIT_UNUSED (path );
446+ GIT_UNUSED (is_dir );
431447
432448 giterr_set (GITERR_SSL , "mbedTLS is not supported in this version" );
433449 return -1 ;
0 commit comments