4
4
using System . Collections . Generic ;
5
5
using System . ComponentModel ;
6
6
using System . Diagnostics ;
7
+ using System . Runtime . CompilerServices ;
7
8
using System . Runtime . InteropServices ;
8
9
using System . Security . Authentication ;
9
10
using System . Security . Authentication . ExtendedProtection ;
@@ -49,7 +50,8 @@ public static Exception GetException(SecurityStatusPal status)
49
50
50
51
private static byte [ ] InitSessionTokenBuffer ( )
51
52
{
52
- var schannelSessionToken = new Interop . SChannel . SCHANNEL_SESSION_TOKEN ( ) {
53
+ var schannelSessionToken = new Interop . SChannel . SCHANNEL_SESSION_TOKEN ( )
54
+ {
53
55
dwTokenType = Interop . SChannel . SCHANNEL_SESSION ,
54
56
dwFlags = Interop . SChannel . SSL_SESSION_DISABLE_RECONNECTS ,
55
57
} ;
@@ -61,7 +63,7 @@ public static void VerifyPackageInfo()
61
63
SSPIWrapper . GetVerifyPackageInfo ( GlobalSSPI . SSPISecureChannel , SecurityPackage , true ) ;
62
64
}
63
65
64
- private static unsafe void SetAlpn ( ref InputSecurityBuffers inputBuffers , List < SslApplicationProtocol > alpn , Span < byte > localBuffer )
66
+ private static void SetAlpn ( ref InputSecurityBuffers inputBuffers , List < SslApplicationProtocol > alpn , Span < byte > localBuffer )
65
67
{
66
68
if ( alpn . Count == 1 && alpn [ 0 ] == SslApplicationProtocol . Http11 )
67
69
{
@@ -82,7 +84,7 @@ private static unsafe void SetAlpn(ref InputSecurityBuffers inputBuffers, List<S
82
84
else
83
85
{
84
86
int protocolLength = Interop . Sec_Application_Protocols . GetProtocolLength ( alpn ) ;
85
- int bufferLength = sizeof ( Interop . Sec_Application_Protocols ) + protocolLength ;
87
+ int bufferLength = Unsafe . SizeOf < Interop . Sec_Application_Protocols > ( ) + protocolLength ;
86
88
87
89
Span < byte > alpnBuffer = bufferLength <= localBuffer . Length ? localBuffer : new byte [ bufferLength ] ;
88
90
Interop . Sec_Application_Protocols . SetProtocols ( alpnBuffer , alpn , protocolLength ) ;
@@ -99,7 +101,7 @@ public static SecurityStatusPal SelectApplicationProtocol(
99
101
throw new PlatformNotSupportedException ( nameof ( SelectApplicationProtocol ) ) ;
100
102
}
101
103
102
- public static unsafe ProtocolToken AcceptSecurityContext (
104
+ public static ProtocolToken AcceptSecurityContext (
103
105
ref SafeFreeCredentials ? credentialsHandle ,
104
106
ref SafeDeleteSslContext ? context ,
105
107
ReadOnlySpan < byte > inputBuffer ,
@@ -141,7 +143,7 @@ public static bool TryUpdateClintCertificate(
141
143
return false ;
142
144
}
143
145
144
- public static unsafe ProtocolToken InitializeSecurityContext (
146
+ public static ProtocolToken InitializeSecurityContext (
145
147
ref SafeFreeCredentials ? credentialsHandle ,
146
148
ref SafeDeleteSslContext ? context ,
147
149
string ? targetName ,
@@ -445,32 +447,32 @@ public static unsafe ProtocolToken EncryptMessage(SafeDeleteSslContext securityC
445
447
input . Span . CopyTo ( token . AvailableSpan . Slice ( headerSize , input . Length ) ) ;
446
448
447
449
const int NumSecBuffers = 4 ; // header + data + trailer + empty
448
- Interop . SspiCli . SecBuffer * unmanagedBuffer = stackalloc Interop . SspiCli . SecBuffer [ NumSecBuffers ] ;
450
+ Span < Interop . SspiCli . SecBuffer > unmanagedBuffers = stackalloc Interop . SspiCli . SecBuffer [ NumSecBuffers ] ;
449
451
Interop . SspiCli . SecBufferDesc sdcInOut = new Interop . SspiCli . SecBufferDesc ( NumSecBuffers )
450
452
{
451
- pBuffers = unmanagedBuffer
453
+ pBuffers = Unsafe . AsPointer ( ref MemoryMarshal . GetReference ( unmanagedBuffers ) )
452
454
} ;
453
455
fixed ( byte * outputPtr = token . Payload )
454
456
{
455
- Interop . SspiCli . SecBuffer * headerSecBuffer = & unmanagedBuffer [ 0 ] ;
456
- headerSecBuffer -> BufferType = SecurityBufferType . SECBUFFER_STREAM_HEADER ;
457
- headerSecBuffer -> pvBuffer = ( IntPtr ) outputPtr ;
458
- headerSecBuffer -> cbBuffer = headerSize ;
457
+ ref Interop . SspiCli . SecBuffer headerSecBuffer = ref unmanagedBuffers [ 0 ] ;
458
+ headerSecBuffer . BufferType = SecurityBufferType . SECBUFFER_STREAM_HEADER ;
459
+ headerSecBuffer . pvBuffer = ( IntPtr ) outputPtr ;
460
+ headerSecBuffer . cbBuffer = headerSize ;
459
461
460
- Interop . SspiCli . SecBuffer * dataSecBuffer = & unmanagedBuffer [ 1 ] ;
461
- dataSecBuffer -> BufferType = SecurityBufferType . SECBUFFER_DATA ;
462
- dataSecBuffer -> pvBuffer = ( IntPtr ) ( outputPtr + headerSize ) ;
463
- dataSecBuffer -> cbBuffer = input . Length ;
462
+ ref Interop . SspiCli . SecBuffer dataSecBuffer = ref unmanagedBuffers [ 1 ] ;
463
+ dataSecBuffer . BufferType = SecurityBufferType . SECBUFFER_DATA ;
464
+ dataSecBuffer . pvBuffer = ( IntPtr ) ( outputPtr + headerSize ) ;
465
+ dataSecBuffer . cbBuffer = input . Length ;
464
466
465
- Interop . SspiCli . SecBuffer * trailerSecBuffer = & unmanagedBuffer [ 2 ] ;
466
- trailerSecBuffer -> BufferType = SecurityBufferType . SECBUFFER_STREAM_TRAILER ;
467
- trailerSecBuffer -> pvBuffer = ( IntPtr ) ( outputPtr + headerSize + input . Length ) ;
468
- trailerSecBuffer -> cbBuffer = trailerSize ;
467
+ ref Interop . SspiCli . SecBuffer trailerSecBuffer = ref unmanagedBuffers [ 2 ] ;
468
+ trailerSecBuffer . BufferType = SecurityBufferType . SECBUFFER_STREAM_TRAILER ;
469
+ trailerSecBuffer . pvBuffer = ( IntPtr ) ( outputPtr + headerSize + input . Length ) ;
470
+ trailerSecBuffer . cbBuffer = trailerSize ;
469
471
470
- Interop . SspiCli . SecBuffer * emptySecBuffer = & unmanagedBuffer [ 3 ] ;
471
- emptySecBuffer -> BufferType = SecurityBufferType . SECBUFFER_EMPTY ;
472
- emptySecBuffer -> cbBuffer = 0 ;
473
- emptySecBuffer -> pvBuffer = IntPtr . Zero ;
472
+ ref Interop . SspiCli . SecBuffer emptySecBuffer = ref unmanagedBuffers [ 3 ] ;
473
+ emptySecBuffer . BufferType = SecurityBufferType . SECBUFFER_EMPTY ;
474
+ emptySecBuffer . cbBuffer = 0 ;
475
+ emptySecBuffer . pvBuffer = IntPtr . Zero ;
474
476
475
477
int errorCode = GlobalSSPI . SSPISecureChannel . EncryptMessage ( securityContext , ref sdcInOut , 0 ) ;
476
478
@@ -483,10 +485,10 @@ public static unsafe ProtocolToken EncryptMessage(SafeDeleteSslContext securityC
483
485
return token ;
484
486
}
485
487
486
- Debug . Assert ( headerSecBuffer -> cbBuffer >= 0 && dataSecBuffer -> cbBuffer >= 0 && trailerSecBuffer -> cbBuffer >= 0 ) ;
487
- Debug . Assert ( checked ( headerSecBuffer -> cbBuffer + dataSecBuffer -> cbBuffer + trailerSecBuffer -> cbBuffer ) <= token . Payload ! . Length ) ;
488
+ Debug . Assert ( headerSecBuffer . cbBuffer >= 0 && dataSecBuffer . cbBuffer >= 0 && trailerSecBuffer . cbBuffer >= 0 ) ;
489
+ Debug . Assert ( checked ( headerSecBuffer . cbBuffer + dataSecBuffer . cbBuffer + trailerSecBuffer . cbBuffer ) <= token . Payload ! . Length ) ;
488
490
489
- token . Size = checked ( headerSecBuffer -> cbBuffer + dataSecBuffer -> cbBuffer + trailerSecBuffer -> cbBuffer ) ;
491
+ token . Size = checked ( headerSecBuffer . cbBuffer + dataSecBuffer . cbBuffer + trailerSecBuffer . cbBuffer ) ;
490
492
token . Status = new SecurityStatusPal ( SecurityStatusPalErrorCode . OK ) ;
491
493
}
492
494
@@ -496,25 +498,26 @@ public static unsafe ProtocolToken EncryptMessage(SafeDeleteSslContext securityC
496
498
public static unsafe SecurityStatusPal DecryptMessage ( SafeDeleteSslContext ? securityContext , Span < byte > buffer , out int offset , out int count )
497
499
{
498
500
const int NumSecBuffers = 4 ; // data + empty + empty + empty
499
- fixed ( byte * bufferPtr = buffer )
501
+
502
+ Span < Interop . SspiCli . SecBuffer > unmanagedBuffers = stackalloc Interop . SspiCli . SecBuffer [ NumSecBuffers ] ;
503
+ for ( int i = 1 ; i < NumSecBuffers ; i ++ )
500
504
{
501
- Interop . SspiCli . SecBuffer * unmanagedBuffer = stackalloc Interop . SspiCli . SecBuffer [ NumSecBuffers ] ;
502
- Interop . SspiCli . SecBuffer * dataBuffer = & unmanagedBuffer [ 0 ] ;
503
- dataBuffer -> BufferType = SecurityBufferType . SECBUFFER_DATA ;
504
- dataBuffer -> pvBuffer = ( IntPtr ) bufferPtr ;
505
- dataBuffer -> cbBuffer = buffer . Length ;
505
+ ref Interop . SspiCli . SecBuffer emptyBuffer = ref unmanagedBuffers [ i ] ;
506
+ emptyBuffer . BufferType = SecurityBufferType . SECBUFFER_EMPTY ;
507
+ emptyBuffer . pvBuffer = IntPtr . Zero ;
508
+ emptyBuffer . cbBuffer = 0 ;
509
+ }
506
510
507
- for ( int i = 1 ; i < NumSecBuffers ; i ++ )
508
- {
509
- Interop . SspiCli . SecBuffer * emptyBuffer = & unmanagedBuffer [ i ] ;
510
- emptyBuffer ->BufferType = SecurityBufferType . SECBUFFER_EMPTY ;
511
- emptyBuffer ->pvBuffer = IntPtr . Zero ;
512
- emptyBuffer ->cbBuffer = 0 ;
513
- }
511
+ fixed ( byte * bufferPtr = buffer )
512
+ {
513
+ ref Interop . SspiCli . SecBuffer dataBuffer = ref unmanagedBuffers [ 0 ] ;
514
+ dataBuffer . BufferType = SecurityBufferType . SECBUFFER_DATA ;
515
+ dataBuffer . pvBuffer = ( IntPtr ) bufferPtr ;
516
+ dataBuffer . cbBuffer = buffer . Length ;
514
517
515
518
Interop . SspiCli . SecBufferDesc sdcInOut = new Interop . SspiCli . SecBufferDesc ( NumSecBuffers )
516
519
{
517
- pBuffers = unmanagedBuffer
520
+ pBuffers = Unsafe . AsPointer ( ref MemoryMarshal . GetReference ( unmanagedBuffers ) )
518
521
} ;
519
522
Interop . SECURITY_STATUS errorCode = ( Interop . SECURITY_STATUS ) GlobalSSPI . SSPISecureChannel . DecryptMessage ( securityContext ! , ref sdcInOut , out _ ) ;
520
523
@@ -525,12 +528,12 @@ public static unsafe SecurityStatusPal DecryptMessage(SafeDeleteSslContext? secu
525
528
for ( int i = 0 ; i < NumSecBuffers ; i ++ )
526
529
{
527
530
// Successfully decoded data and placed it at the following position in the buffer,
528
- if ( ( errorCode == Interop . SECURITY_STATUS . OK && unmanagedBuffer [ i ] . BufferType == SecurityBufferType . SECBUFFER_DATA )
531
+ if ( ( errorCode == Interop . SECURITY_STATUS . OK && unmanagedBuffers [ i ] . BufferType == SecurityBufferType . SECBUFFER_DATA )
529
532
// or we failed to decode the data, here is the encoded data.
530
- || ( errorCode != Interop . SECURITY_STATUS . OK && unmanagedBuffer [ i ] . BufferType == SecurityBufferType . SECBUFFER_EXTRA ) )
533
+ || ( errorCode != Interop . SECURITY_STATUS . OK && unmanagedBuffers [ i ] . BufferType == SecurityBufferType . SECBUFFER_EXTRA ) )
531
534
{
532
- offset = ( int ) ( ( byte * ) unmanagedBuffer [ i ] . pvBuffer - bufferPtr ) ;
533
- count = unmanagedBuffer [ i ] . cbBuffer ;
535
+ offset = ( int ) ( ( byte * ) unmanagedBuffers [ i ] . pvBuffer - bufferPtr ) ;
536
+ count = unmanagedBuffers [ i ] . cbBuffer ;
534
537
535
538
// output is ignored on Windows. We always decrypt in place and we set outputOffset to indicate where the data start.
536
539
Debug . Assert ( offset >= 0 && count >= 0 , $ "Expected offset and count greater than 0, got { offset } and { count } ") ;
0 commit comments