@@ -242,8 +242,12 @@ static int certificate_check(winhttp_stream *s, int valid)
242242 git_cert_x509 cert ;
243243
244244 /* If there is no override, we should fail if WinHTTP doesn't think it's fine */
245- if (t -> owner -> certificate_check_cb == NULL && !valid )
245+ if (t -> owner -> certificate_check_cb == NULL && !valid ) {
246+ if (!giterr_last ())
247+ giterr_set (GITERR_NET , "unknown certificate check failure" );
248+
246249 return GIT_ECERTIFICATE ;
250+ }
247251
248252 if (t -> owner -> certificate_check_cb == NULL || !t -> connection_data .use_ssl )
249253 return 0 ;
@@ -691,6 +695,38 @@ static int user_agent(git_buf *ua)
691695 return git_buf_putc (ua , ')' );
692696}
693697
698+ static void CALLBACK winhttp_status (
699+ HINTERNET connection ,
700+ DWORD_PTR ctx ,
701+ DWORD code ,
702+ LPVOID info ,
703+ DWORD info_len )
704+ {
705+ DWORD status ;
706+
707+ if (code != WINHTTP_CALLBACK_STATUS_SECURE_FAILURE )
708+ return ;
709+
710+ status = * ((DWORD * )info );
711+
712+ if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID ))
713+ giterr_set (GITERR_NET , "SSL certificate issued for different common name" );
714+ else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID ))
715+ giterr_set (GITERR_NET , "SSL certificate has expired" );
716+ else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA ))
717+ giterr_set (GITERR_NET , "SSL certificate signed by unknown CA" );
718+ else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT ))
719+ giterr_set (GITERR_NET , "SSL certificate is invalid" );
720+ else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED ))
721+ giterr_set (GITERR_NET , "certificate revocation check failed" );
722+ else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED ))
723+ giterr_set (GITERR_NET , "SSL certificate was revoked" );
724+ else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR ))
725+ giterr_set (GITERR_NET , "security libraries could not be loaded" );
726+ else
727+ giterr_set (GITERR_NET , "unknown security error %d" , status );
728+ }
729+
694730static int winhttp_connect (
695731 winhttp_subtransport * t )
696732{
@@ -760,6 +796,11 @@ static int winhttp_connect(
760796 goto on_error ;
761797 }
762798
799+ if (WinHttpSetStatusCallback (t -> connection , winhttp_status , WINHTTP_CALLBACK_FLAG_SECURE_FAILURE , 0 ) == WINHTTP_INVALID_STATUS_CALLBACK ) {
800+ giterr_set (GITERR_OS , "failed to set status callback" );
801+ goto on_error ;
802+ }
803+
763804 error = 0 ;
764805
765806on_error :
@@ -798,16 +839,15 @@ static int send_request(winhttp_stream *s, size_t len, int ignore_length)
798839 int request_failed = 0 , cert_valid = 1 , error = 0 ;
799840 DWORD ignore_flags ;
800841
801- if ((error = do_send_request (s , len , ignore_length )) < 0 )
802- request_failed = 1 ;
803-
804- if (request_failed ) {
842+ giterr_clear ();
843+ if ((error = do_send_request (s , len , ignore_length )) < 0 ) {
805844 if (GetLastError () != ERROR_WINHTTP_SECURE_FAILURE ) {
806845 giterr_set (GITERR_OS , "failed to send request" );
807846 return -1 ;
808- } else {
809- cert_valid = 0 ;
810847 }
848+
849+ request_failed = 1 ;
850+ cert_valid = 0 ;
811851 }
812852
813853 giterr_clear ();
0 commit comments