@@ -295,62 +295,24 @@ private string[] GetRequestCertificateAuthorities()
295
295
return issuers ;
296
296
}
297
297
298
- /*++
299
- AcquireCredentials - Attempts to find Client Credential
300
- Information, that can be sent to the server. In our case,
301
- this is only Client Certificates, that we have Credential Info.
302
-
303
- How it works:
304
- case 0: Cert Selection delegate is present
305
- Always use its result as the client cert answer.
306
- Try to use cached credential handle whenever feasible.
307
- Do not use cached anonymous creds if the delegate has returned null
308
- and the collection is not empty (allow responding with the cert later).
309
-
310
- case 1: Certs collection is empty
311
- Always use the same statically acquired anonymous SSL Credential
312
-
313
- case 2: Before our Connection with the Server
314
- If we have a cached credential handle keyed by first X509Certificate
315
- **content** in the passed collection, then we use that cached
316
- credential and hoping to restart a session.
317
-
318
- Otherwise create a new anonymous (allow responding with the cert later).
319
-
320
- case 3: After our Connection with the Server (i.e. during handshake or re-handshake)
321
- The server has requested that we send it a Certificate then
322
- we Enumerate a list of server sent Issuers trying to match against
323
- our list of Certificates, the first match is sent to the server.
324
-
325
- Once we got a cert we again try to match cached credential handle if possible.
326
- This will not restart a session but helps minimizing the number of handles we create.
327
-
328
- In the case of an error getting a Certificate or checking its private Key we fall back
329
- to the behavior of having no certs, case 1.
330
-
331
- Returns: True if cached creds were used, false otherwise.
332
-
333
- --*/
334
-
335
- private bool AcquireClientCredentials ( ref byte [ ] ? thumbPrint )
298
+ internal X509Certificate2 ? SelectClientCertificate ( out bool sessionRestartAttempt )
336
299
{
337
- // Acquire possible Client Certificate information and set it on the handle.
338
- X509Certificate ? clientCertificate = null ; // This is a candidate that can come from the user callback or be guessed when targeting a session restart.
339
- List < X509Certificate > ? filteredCerts = null ; // This is an intermediate client certs collection that try to use if no selectedCert is available yet.
340
- string [ ] issuers ; // This is a list of issuers sent by the server, only valid is we do know what the server cert is.
300
+ sessionRestartAttempt = false ;
341
301
342
- bool sessionRestartAttempt = false ; // If true and no cached creds we will use anonymous creds.
302
+ X509Certificate ? clientCertificate = null ; // candidate certificate that can come from the user callback or be guessed when targeting a session restart.
303
+ X509Certificate2 ? selectedCert = null ; // final selected cert (ensured that it does have private key with it).
304
+ List < X509Certificate > ? filteredCerts = null ; // This is an intermediate client certs collection that try to use if no selectedCert is available yet.
305
+ string [ ] issuers ; // This is a list of issuers sent by the server, only valid if we do know what the server cert is.
343
306
344
307
if ( _sslAuthenticationOptions . CertSelectionDelegate != null )
345
308
{
346
- issuers = GetRequestCertificateAuthorities ( ) ;
347
-
348
309
if ( NetEventSource . Log . IsEnabled ( ) )
349
310
NetEventSource . Info ( this , "Calling CertificateSelectionCallback" ) ;
350
311
351
312
X509Certificate2 ? remoteCert = null ;
352
313
try
353
314
{
315
+ issuers = GetRequestCertificateAuthorities ( ) ;
354
316
remoteCert = CertificateValidationPal . GetRemoteCertificate ( _securityContext ! ) ;
355
317
if ( _sslAuthenticationOptions . ClientCertificates == null )
356
318
{
@@ -363,7 +325,6 @@ private bool AcquireClientCredentials(ref byte[]? thumbPrint)
363
325
remoteCert ? . Dispose ( ) ;
364
326
}
365
327
366
-
367
328
if ( clientCertificate != null )
368
329
{
369
330
if ( _credentialsHandle == null )
@@ -505,9 +466,6 @@ private bool AcquireClientCredentials(ref byte[]? thumbPrint)
505
466
}
506
467
}
507
468
508
- bool cachedCred = false ; // This is a return result from this method.
509
- X509Certificate2 ? selectedCert = null ; // This is a final selected cert (ensured that it does have private key with it).
510
-
511
469
clientCertificate = null ;
512
470
513
471
if ( NetEventSource . Log . IsEnabled ( ) )
@@ -550,6 +508,56 @@ private bool AcquireClientCredentials(ref byte[]? thumbPrint)
550
508
551
509
if ( NetEventSource . Log . IsEnabled ( ) ) NetEventSource . Info ( this , $ "Selected cert = { selectedCert } ") ;
552
510
511
+ _selectedClientCertificate = clientCertificate ;
512
+ return selectedCert ;
513
+ }
514
+
515
+ /*++
516
+ AcquireCredentials - Attempts to find Client Credential
517
+ Information, that can be sent to the server. In our case,
518
+ this is only Client Certificates, that we have Credential Info.
519
+
520
+ How it works:
521
+ case 0: Cert Selection delegate is present
522
+ Always use its result as the client cert answer.
523
+ Try to use cached credential handle whenever feasible.
524
+ Do not use cached anonymous creds if the delegate has returned null
525
+ and the collection is not empty (allow responding with the cert later).
526
+
527
+ case 1: Certs collection is empty
528
+ Always use the same statically acquired anonymous SSL Credential
529
+
530
+ case 2: Before our Connection with the Server
531
+ If we have a cached credential handle keyed by first X509Certificate
532
+ **content** in the passed collection, then we use that cached
533
+ credential and hoping to restart a session.
534
+
535
+ Otherwise create a new anonymous (allow responding with the cert later).
536
+
537
+ case 3: After our Connection with the Server (i.e. during handshake or re-handshake)
538
+ The server has requested that we send it a Certificate then
539
+ we Enumerate a list of server sent Issuers trying to match against
540
+ our list of Certificates, the first match is sent to the server.
541
+
542
+ Once we got a cert we again try to match cached credential handle if possible.
543
+ This will not restart a session but helps minimizing the number of handles we create.
544
+
545
+ In the case of an error getting a Certificate or checking its private Key we fall back
546
+ to the behavior of having no certs, case 1.
547
+
548
+ Returns: True if cached creds were used, false otherwise.
549
+
550
+ --*/
551
+
552
+ private bool AcquireClientCredentials ( ref byte [ ] ? thumbPrint )
553
+ {
554
+ // Acquire possible Client Certificate information and set it on the handle.
555
+
556
+ bool sessionRestartAttempt ; // If true and no cached creds we will use anonymous creds.
557
+ bool cachedCred = false ; // this is a return result from this method.
558
+
559
+ X509Certificate2 ? selectedCert = SelectClientCertificate ( out sessionRestartAttempt ) ;
560
+
553
561
try
554
562
{
555
563
// Try to locate cached creds first.
@@ -574,22 +582,21 @@ private bool AcquireClientCredentials(ref byte[]? thumbPrint)
574
582
// So we don't want to reuse **anonymous** cached credential for a new SSL connection if the client has passed some certificate.
575
583
// The following block happens if client did specify a certificate but no cached creds were found in the cache.
576
584
// Since we don't restart a session the server side can still challenge for a client cert.
577
- if ( ( object ? ) clientCertificate != ( object ? ) selectedCert )
585
+ if ( ( object ? ) _selectedClientCertificate != ( object ? ) selectedCert )
578
586
{
579
587
selectedCert . Dispose ( ) ;
580
588
}
581
589
582
590
guessedThumbPrint = null ;
583
591
selectedCert = null ;
584
- clientCertificate = null ;
592
+ _selectedClientCertificate = null ;
585
593
}
586
594
587
595
if ( cachedCredentialHandle != null )
588
596
{
589
597
if ( NetEventSource . Log . IsEnabled ( ) )
590
598
NetEventSource . Log . UsingCachedCredential ( this ) ;
591
599
_credentialsHandle = cachedCredentialHandle ;
592
- _selectedClientCertificate = clientCertificate ;
593
600
cachedCred = true ;
594
601
if ( selectedCert != null )
595
602
{
@@ -607,7 +614,6 @@ private bool AcquireClientCredentials(ref byte[]? thumbPrint)
607
614
_sslAuthenticationOptions . EnabledSslProtocols , _sslAuthenticationOptions . EncryptionPolicy , _sslAuthenticationOptions . IsServer ) ;
608
615
609
616
thumbPrint = guessedThumbPrint ; // Delay until here in case something above threw.
610
- _selectedClientCertificate = clientCertificate ;
611
617
}
612
618
}
613
619
finally
@@ -792,6 +798,7 @@ private SecurityStatusPal GenerateToken(ReadOnlySpan<byte> inputBuffer, ref byte
792
798
if ( _sslAuthenticationOptions . IsServer )
793
799
{
794
800
status = SslStreamPal . AcceptSecurityContext (
801
+ this ,
795
802
ref _credentialsHandle ! ,
796
803
ref _securityContext ,
797
804
inputBuffer ,
@@ -801,6 +808,7 @@ private SecurityStatusPal GenerateToken(ReadOnlySpan<byte> inputBuffer, ref byte
801
808
else
802
809
{
803
810
status = SslStreamPal . InitializeSecurityContext (
811
+ this ,
804
812
ref _credentialsHandle ! ,
805
813
ref _securityContext ,
806
814
_sslAuthenticationOptions . TargetHost ,
@@ -841,6 +849,7 @@ private SecurityStatusPal GenerateToken(ReadOnlySpan<byte> inputBuffer, ref byte
841
849
internal SecurityStatusPal Renegotiate ( out byte [ ] ? output )
842
850
{
843
851
return SslStreamPal . Renegotiate (
852
+ this ,
844
853
ref _credentialsHandle ! ,
845
854
ref _securityContext ,
846
855
_sslAuthenticationOptions ,
0 commit comments