44using System . Collections . Generic ;
55using System . ComponentModel ;
66using System . Diagnostics ;
7+ using System . Runtime . CompilerServices ;
78using System . Runtime . InteropServices ;
89using System . Security . Authentication ;
910using System . Security . Authentication . ExtendedProtection ;
@@ -49,7 +50,8 @@ public static Exception GetException(SecurityStatusPal status)
4950
5051 private static byte [ ] InitSessionTokenBuffer ( )
5152 {
52- var schannelSessionToken = new Interop . SChannel . SCHANNEL_SESSION_TOKEN ( ) {
53+ var schannelSessionToken = new Interop . SChannel . SCHANNEL_SESSION_TOKEN ( )
54+ {
5355 dwTokenType = Interop . SChannel . SCHANNEL_SESSION ,
5456 dwFlags = Interop . SChannel . SSL_SESSION_DISABLE_RECONNECTS ,
5557 } ;
@@ -61,7 +63,7 @@ public static void VerifyPackageInfo()
6163 SSPIWrapper . GetVerifyPackageInfo ( GlobalSSPI . SSPISecureChannel , SecurityPackage , true ) ;
6264 }
6365
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 )
6567 {
6668 if ( alpn . Count == 1 && alpn [ 0 ] == SslApplicationProtocol . Http11 )
6769 {
@@ -82,7 +84,7 @@ private static unsafe void SetAlpn(ref InputSecurityBuffers inputBuffers, List<S
8284 else
8385 {
8486 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 ;
8688
8789 Span < byte > alpnBuffer = bufferLength <= localBuffer . Length ? localBuffer : new byte [ bufferLength ] ;
8890 Interop . Sec_Application_Protocols . SetProtocols ( alpnBuffer , alpn , protocolLength ) ;
@@ -99,7 +101,7 @@ public static SecurityStatusPal SelectApplicationProtocol(
99101 throw new PlatformNotSupportedException ( nameof ( SelectApplicationProtocol ) ) ;
100102 }
101103
102- public static unsafe ProtocolToken AcceptSecurityContext (
104+ public static ProtocolToken AcceptSecurityContext (
103105 ref SafeFreeCredentials ? credentialsHandle ,
104106 ref SafeDeleteSslContext ? context ,
105107 ReadOnlySpan < byte > inputBuffer ,
@@ -141,7 +143,7 @@ public static bool TryUpdateClintCertificate(
141143 return false ;
142144 }
143145
144- public static unsafe ProtocolToken InitializeSecurityContext (
146+ public static ProtocolToken InitializeSecurityContext (
145147 ref SafeFreeCredentials ? credentialsHandle ,
146148 ref SafeDeleteSslContext ? context ,
147149 string ? targetName ,
@@ -445,32 +447,32 @@ public static unsafe ProtocolToken EncryptMessage(SafeDeleteSslContext securityC
445447 input . Span . CopyTo ( token . AvailableSpan . Slice ( headerSize , input . Length ) ) ;
446448
447449 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 ] ;
449451 Interop . SspiCli . SecBufferDesc sdcInOut = new Interop . SspiCli . SecBufferDesc ( NumSecBuffers )
450452 {
451- pBuffers = unmanagedBuffer
453+ pBuffers = Unsafe . AsPointer ( ref MemoryMarshal . GetReference ( unmanagedBuffers ) )
452454 } ;
453455 fixed ( byte * outputPtr = token . Payload )
454456 {
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 ;
459461
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 ;
464466
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 ;
469471
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 ;
474476
475477 int errorCode = GlobalSSPI . SSPISecureChannel . EncryptMessage ( securityContext , ref sdcInOut , 0 ) ;
476478
@@ -483,10 +485,10 @@ public static unsafe ProtocolToken EncryptMessage(SafeDeleteSslContext securityC
483485 return token ;
484486 }
485487
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 ) ;
488490
489- token . Size = checked ( headerSecBuffer -> cbBuffer + dataSecBuffer -> cbBuffer + trailerSecBuffer -> cbBuffer ) ;
491+ token . Size = checked ( headerSecBuffer . cbBuffer + dataSecBuffer . cbBuffer + trailerSecBuffer . cbBuffer ) ;
490492 token . Status = new SecurityStatusPal ( SecurityStatusPalErrorCode . OK ) ;
491493 }
492494
@@ -496,25 +498,26 @@ public static unsafe ProtocolToken EncryptMessage(SafeDeleteSslContext securityC
496498 public static unsafe SecurityStatusPal DecryptMessage ( SafeDeleteSslContext ? securityContext , Span < byte > buffer , out int offset , out int count )
497499 {
498500 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 ++ )
500504 {
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+ }
506510
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 ;
514517
515518 Interop . SspiCli . SecBufferDesc sdcInOut = new Interop . SspiCli . SecBufferDesc ( NumSecBuffers )
516519 {
517- pBuffers = unmanagedBuffer
520+ pBuffers = Unsafe . AsPointer ( ref MemoryMarshal . GetReference ( unmanagedBuffers ) )
518521 } ;
519522 Interop . SECURITY_STATUS errorCode = ( Interop . SECURITY_STATUS ) GlobalSSPI . SSPISecureChannel . DecryptMessage ( securityContext ! , ref sdcInOut , out _ ) ;
520523
@@ -525,12 +528,12 @@ public static unsafe SecurityStatusPal DecryptMessage(SafeDeleteSslContext? secu
525528 for ( int i = 0 ; i < NumSecBuffers ; i ++ )
526529 {
527530 // 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 )
529532 // 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 ) )
531534 {
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 ;
534537
535538 // output is ignored on Windows. We always decrypt in place and we set outputOffset to indicate where the data start.
536539 Debug . Assert ( offset >= 0 && count >= 0 , $ "Expected offset and count greater than 0, got { offset } and { count } ") ;
0 commit comments