@@ -173,33 +173,41 @@ public override string ToString()
173
173
174
174
public static bool TryGetFrameHeader ( ReadOnlySpan < byte > frame , ref TlsFrameHeader header )
175
175
{
176
- bool result = frame . Length > 4 ;
177
-
178
- if ( frame . Length >= 1 )
176
+ header . Type = ( TlsContentType ) ( frame . Length >= 1 ? frame [ 0 ] : 0 ) ;
177
+ if ( frame . Length < TlsFrameHelper . HeaderSize )
179
178
{
180
- header . Type = ( TlsContentType ) frame [ 0 ] ;
181
-
182
- if ( frame . Length >= 3 )
183
- {
184
- // SSLv3, TLS or later
185
- if ( frame [ 1 ] == 3 )
186
- {
187
- if ( frame . Length > 4 )
188
- {
189
- header . Length = ( ( frame [ 3 ] << 8 ) | frame [ 4 ] ) ;
190
- }
179
+ header . Length = - 1 ;
180
+ header . Version = SslProtocols . None ;
181
+ return false ;
182
+ }
191
183
192
- header . Version = TlsMinorVersionToProtocol ( frame [ 2 ] ) ;
193
- }
194
- else
195
- {
196
- header . Length = - 1 ;
197
- header . Version = SslProtocols . None ;
198
- }
199
- }
184
+ // SSLv3, TLS or later
185
+ if ( frame [ 1 ] == ProtocolVersionTlsMajorValue )
186
+ {
187
+ header . Length = ( ( frame [ 3 ] << 8 ) | frame [ 4 ] ) ;
188
+ header . Version = TlsMinorVersionToProtocol ( frame [ 2 ] ) ;
189
+ }
190
+ // Sslv2 or Unified
191
+ else if ( frame [ 2 ] == ( byte ) TlsHandshakeType . ClientHello &&
192
+ frame [ 3 ] == ProtocolVersionTlsMajorValue ) // SSL3 or above
193
+ {
194
+ header . Length = ( frame [ 0 ] & 0x80 ) != 0 ?
195
+ ( ( ( frame [ 0 ] & 0x7f ) << 8 ) | frame [ 1 ] ) + 2 : // two bytes
196
+ ( ( ( frame [ 0 ] & 0x3f ) << 8 ) | frame [ 1 ] ) + 3 ; // three bytes
197
+ #pragma warning disable CS0618 // Ssl2 and Ssl3 are obsolete
198
+ header . Version = SslProtocols . Ssl2 ;
199
+ #pragma warning restore CS0618
200
+ header . Type = TlsContentType . Handshake ;
201
+ }
202
+ else
203
+ {
204
+ // neither looks like TLS nor Ssl2 Hello
205
+ header . Length = - 1 ;
206
+ header . Version = SslProtocols . None ;
207
+ return false ;
200
208
}
201
209
202
- return result ;
210
+ return true ;
203
211
}
204
212
205
213
// Returns frame size e.g. header + content
@@ -252,6 +260,18 @@ public static bool TryGetFrameInfo(ReadOnlySpan<byte> frame, ref TlsFrameInfo in
252
260
}
253
261
254
262
info . HandshakeType = ( TlsHandshakeType ) frame [ HandshakeTypeOffset ] ;
263
+ #pragma warning disable CS0618 // Ssl2 and Ssl3 are obsolete
264
+ if ( info . Header . Version == SslProtocols . Ssl2 )
265
+ {
266
+ // This is safe. We would not get here if the length is too small.
267
+ info . SupportedVersions |= TlsMinorVersionToProtocol ( frame [ 4 ] ) ;
268
+ // We only recognize Unified ClientHello at the moment.
269
+ // This is needed to trigger certificate selection callback in SslStream.
270
+ info . HandshakeType = TlsHandshakeType . ClientHello ;
271
+ // There is no more parsing for old protocols.
272
+ return true ;
273
+ }
274
+ #pragma warning restore CS0618
255
275
256
276
// Check if we have full frame.
257
277
bool isComplete = frame . Length >= HeaderSize + info . Header . Length ;
@@ -404,10 +424,10 @@ private static bool TryParseClientHello(ReadOnlySpan<byte> clientHello, ref TlsF
404
424
// Skip compression methods (max size 2^8-1 => size fits in 1 byte)
405
425
p = SkipOpaqueType1 ( p ) ;
406
426
407
- // is invalid structure or no extensions?
427
+ // no extensions
408
428
if ( p . IsEmpty )
409
429
{
410
- return false ;
430
+ return true ;
411
431
}
412
432
413
433
// client_hello_extension_list (max size 2^16-1 => size fits in 2 bytes)
0 commit comments