@@ -234,7 +234,7 @@ interface
234234 IdYarn;
235235
236236type
237- TIdSSLVersion = (sslvSSLv2, sslvSSLv23, sslvSSLv3, sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2);
237+ TIdSSLVersion = (sslvSSLv2, sslvSSLv23, sslvSSLv3, sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2, sslvTLSv1_3 );
238238 TIdSSLVersions = set of TIdSSLVersion;
239239 TIdSSLMode = (sslmUnassigned, sslmClient, sslmServer, sslmBoth);
240240 TIdSSLVerifyMode = (sslvrfPeer, sslvrfFailIfNoPeerCert, sslvrfClientOnce);
@@ -243,8 +243,8 @@ interface
243243 TIdSSLAction = (sslRead, sslWrite);
244244
245245const
246- DEF_SSLVERSION = sslvTLSv1 ;
247- DEF_SSLVERSIONS = [sslvTLSv1 ];
246+ DEF_SSLVERSION = sslvTLSv1_3 ;
247+ DEF_SSLVERSIONS = [sslvTLSv1_3 ];
248248 P12_FILETYPE = 3 ;
249249 MAX_SSL_PASSWORD_LENGTH = 128 ;
250250
@@ -901,10 +901,12 @@ function calls will reset that value and we can't know what a programmer will
901901 LockInfoCB.Enter;
902902 try
903903 IdSSLSocket := TIdSSLSocket(SSL_get_app_data(sslSocket));
904- if Supports(IdSSLSocket.fParent, IIdSSLOpenSSLCallbackHelper, IInterface(LHelper)) then begin
905- StatusStr := IndyFormat(RSOSSLStatusString, [String(SSL_state_string_long(sslSocket))]);
906- LHelper.StatusInfo(sslSocket, where, ret, StatusStr);
907- LHelper := nil ;
904+ if Assigned(IdSSLSocket) then begin
905+ if Supports(IdSSLSocket.fParent, IIdSSLOpenSSLCallbackHelper, IInterface(LHelper)) then begin
906+ StatusStr := IndyFormat(RSOSSLStatusString, [String(SSL_state_string_long(sslSocket))]);
907+ LHelper.StatusInfo(sslSocket, where, ret, StatusStr);
908+ LHelper := nil ;
909+ end ;
908910 end ;
909911 finally
910912 LockInfoCB.Leave;
@@ -946,7 +948,7 @@ function VerifyCallback(Ok: TIdC_INT; ctx: PX509_STORE_CTX): TIdC_INT; cdecl;
946948 try
947949 VerifiedOK := True;
948950 try
949- hSSL := X509_STORE_CTX_get_app_data (ctx);
951+ hSSL := X509_STORE_CTX_get_ex_data (ctx, SSL_get_ex_data_X509_STORE_CTX_idx );
950952 if hSSL = nil then begin
951953 Result := Ok;
952954 Exit;
@@ -955,21 +957,23 @@ function VerifyCallback(Ok: TIdC_INT; ctx: PX509_STORE_CTX): TIdC_INT; cdecl;
955957 Certificate := TIdX509.Create(hcert, False); // the certificate is owned by the store
956958 try
957959 IdSSLSocket := TIdSSLSocket(SSL_get_app_data(hSSL));
958- Error := X509_STORE_CTX_get_error(ctx);
959- Depth := X509_STORE_CTX_get_error_depth(ctx);
960- if not ((Ok > 0 ) and (IdSSLSocket.fSSLContext.VerifyDepth >= Depth)) then begin
961- Ok := 0 ;
962- { if Error = X509_V_OK then begin
963- Error := X509_V_ERR_CERT_CHAIN_TOO_LONG;
964- end;}
965- end ;
966- LOk := False;
967- if Ok = 1 then begin
968- LOk := True;
969- end ;
970- if Supports(IdSSLSocket.fParent, IIdSSLOpenSSLCallbackHelper, IInterface(LHelper)) then begin
971- VerifiedOK := LHelper.VerifyPeer(Certificate, LOk, Depth, Error);
972- LHelper := nil ;
960+ if Assigned(IdSSLSocket) then begin
961+ Error := X509_STORE_CTX_get_error(ctx);
962+ Depth := X509_STORE_CTX_get_error_depth(ctx);
963+ if not ((Ok > 0 ) and (IdSSLSocket.fSSLContext.VerifyDepth >= Depth)) then begin
964+ Ok := 0 ;
965+ { if Error = X509_V_OK then begin
966+ Error := X509_V_ERR_CERT_CHAIN_TOO_LONG;
967+ end;}
968+ end ;
969+ LOk := False;
970+ if Ok = 1 then begin
971+ LOk := True;
972+ end ;
973+ if Supports(IdSSLSocket.fParent, IIdSSLOpenSSLCallbackHelper, IInterface(LHelper)) then begin
974+ VerifiedOK := LHelper.VerifyPeer(Certificate, LOk, Depth, Error);
975+ LHelper := nil ;
976+ end ;
973977 end ;
974978 finally
975979 FreeAndNil(Certificate);
@@ -2360,33 +2364,11 @@ function LoadOpenSSLLibrary: Boolean;
23602364 // has to be done before anything that uses memory
23612365 IdSslCryptoMallocInit;
23622366{ $ENDIF}
2363- // required eg to encrypt a private key when writing
2364- OpenSSL_add_all_ciphers;
2365- OpenSSL_add_all_digests;
2366- InitializeRandom;
2367- // IdSslRandScreen;
2368- SSL_load_error_strings;
2369- // Successful loading if true
2370- Result := SSLeay_add_ssl_algorithms > 0 ;
2371- if not Result then begin
2372- Exit;
2373- end ;
23742367 // Create locking structures, we need them for callback routines
23752368 Assert(LockInfoCB = nil );
23762369 LockInfoCB := TIdCriticalSection.Create;
23772370 LockPassCB := TIdCriticalSection.Create;
23782371 LockVerifyCB := TIdCriticalSection.Create;
2379- // Handle internal OpenSSL locking
2380- CallbackLockList := TIdCriticalSectionThreadList.Create;
2381- PrepareOpenSSLLocking;
2382- CRYPTO_set_locking_callback(@SslLockingCallback);
2383- { $IFNDEF WIN32_OR_WIN64}
2384- if Assigned(CRYPTO_THREADID_set_callback) then begin
2385- CRYPTO_THREADID_set_callback(@_threadid_func);
2386- end else begin
2387- CRYPTO_set_id_callback(@_GetThreadID);
2388- end ;
2389- { $ENDIF}
23902372 SSLIsLoaded.Value := True;
23912373 Result := True;
23922374 finally
@@ -2460,7 +2442,7 @@ procedure TIdSSLOptions.SetMethod(const AValue: TIdSSLVersion);
24602442begin
24612443 fMethod := AValue;
24622444 if AValue = sslvSSLv23 then begin
2463- fSSLVersions := [sslvSSLv2,sslvSSLv3,sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2];
2445+ fSSLVersions := [sslvSSLv2,sslvSSLv3,sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2,sslvTLSv1_3 ];
24642446 end else begin
24652447 fSSLVersions := [AValue];
24662448 end ;
@@ -2484,12 +2466,15 @@ procedure TIdSSLOptions.SetSSLVersions(const AValue: TIdSSLVersions);
24842466 else if fSSLVersions = [sslvTLSv1_2 ] then begin
24852467 fMethod := sslvTLSv1_2;
24862468 end
2469+ else if fSSLVersions = [sslvTLSv1_3] then begin
2470+ fMethod := sslvTLSv1_3;
2471+ end
24872472 else begin
24882473 fMethod := sslvSSLv23;
24892474 if sslvSSLv23 in fSSLVersions then begin
24902475 Exclude(fSSLVersions, sslvSSLv23);
24912476 if fSSLVersions = [] then begin
2492- fSSLVersions := [sslvSSLv2,sslvSSLv3,sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2];
2477+ fSSLVersions := [sslvSSLv2,sslvSSLv3,sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2,sslvTLSv1_3 ];
24932478 end ;
24942479 end ;
24952480 end ;
@@ -3299,7 +3284,24 @@ procedure TIdSSLContext.InitContext(CtxMode: TIdSSLCtxMode);
32993284 SSL_CTX_clear_options(fContext, SSL_OP_NO_TLSv1_2);
33003285 end ;
33013286 end ;
3287+ if IsOpenSSL_TLSv1_3_Available then begin
3288+ if not (sslvTLSv1_3 in SSLVersions) then begin
3289+ SSL_CTX_set_options(fContext, SSL_OP_NO_TLSv1_3);
3290+ end
3291+ else if (fMethod = sslvSSLv23) then begin
3292+ SSL_CTX_clear_options(fContext, SSL_OP_NO_TLSv1_3);
3293+ end ;
3294+ end ;
33023295
3296+ if sslvTLSv1_3 in SSLVersions then
3297+ SSL_CTX_set_min_proto_version(fContext, TLS1_2_VERSION)
3298+ else if sslvTLSv1_2 in SSLVersions then
3299+ SSL_CTX_set_min_proto_version(fContext, TLS1_2_VERSION)
3300+ else if sslvTLSv1_1 in SSLVersions then
3301+ SSL_CTX_set_min_proto_version(fContext, TLS1_1_VERSION)
3302+ else
3303+ SSL_CTX_set_min_proto_version(fContext, TLS1_VERSION);
3304+ SSL_CTX_set_max_proto_version(fContext, TLS1_3_VERSION);
33033305 SSL_CTX_set_mode(fContext, SSL_MODE_AUTO_RETRY);
33043306 // assign a password lookup routine
33053307// if PasswordRoutineOn then begin
@@ -3462,22 +3464,10 @@ function TIdSSLContext.SetSSLMethod: PSSL_METHOD;
34623464 end ;
34633465 end ;
34643466 sslvSSLv23:
3465- case fMode of
3466- sslmServer : begin
3467- if Assigned(SSLv23_server_method) then begin
3468- Result := SSLv23_server_method();
3469- end ;
3470- end ;
3471- sslmClient : begin
3472- if Assigned(SSLv23_client_method) then begin
3473- Result := SSLv23_client_method();
3474- end ;
3475- end ;
3467+ if Assigned(TLS_method) then
3468+ Result := TLS_method()
34763469 else
3477- if Assigned(SSLv23_method) then begin
3478- Result := SSLv23_method();
3479- end ;
3480- end ;
3470+ Result := SelectTLS1Method(fMode);
34813471 sslvSSLv3:
34823472 case fMode of
34833473 sslmServer : begin
@@ -3555,6 +3545,11 @@ function TIdSSLContext.SetSSLMethod: PSSL_METHOD;
35553545 Result := SelectTLS1Method(fMode);
35563546 end ;
35573547 end ;
3548+ sslvTLSv1_3:
3549+ if Assigned(TLS_method) then
3550+ Result := TLS_method()
3551+ else
3552+ Result := SelectTLS1Method(fMode);
35583553 end ;
35593554 if Result = nil then begin
35603555 raise EIdOSSLGetMethodError.Create(RSSSLGetMethodError);
0 commit comments