.Net Framework 4.0 で TLS 1.2 が本当に使えないのか調べてみた その3

Windows 2000で TLS 1.2 が本当に使えないのか調べてみた
Windows XP + .Net Framework で TLS 1.2 を使ってみた

.Net Framework 4.0 で TLS 1.2 が本当に使えないのか調べてみた その1
.Net Framework 4.0 で TLS 1.2 が本当に使えないのか調べてみた その2

  .method assembly hidebysig specialname instance valuetype System.Security.Authentication.SslProtocols get_SslProtocol()
                                        // CODE XREF: get_SslProtocol+6p
                                        // sub_D2B00+A1p ...
  {
    .maxstack 2
    .locals init (class System.Net.SslConnectionInfo V0,
                  valuetype System.Security.Authentication.SslProtocols V1)
    ldarg.0
    ldc.i4.1
    call     instance void System.Net.Security.SslState::CheckThrow(bool authSucessCheck)
    ldarg.0
    call     instance class System.Net.Security.SecureChannel System.Net.Security.SslState::get_Context()
    callvirt instance class System.Net.SslConnectionInfo System.Net.Security.SecureChannel::get_ConnectionInfo()
    stloc.0
    ldloc.0
    brtrue.s loc_D2808
    ldc.i4.0
    ret

loc_D2808:                              // CODE XREF: sub_D27F0+14j
    ldloc.0
    ldfld    int32 System.Net.SslConnectionInfo::Protocol
    stloc.1
    ldloc.1
    ldc.i4.s 0xC
    and
    brfalse.s loc_D281A
    ldloc.1
    ldc.i4.s 0xC
    or
    stloc.1

loc_D281A:                              // CODE XREF: sub_D27F0+23j
    ldloc.1
    ldc.i4.s 0x30
    and
    brfalse.s loc_D2825
    ldloc.1
    ldc.i4.s 0x30
    or
    stloc.1

loc_D2825:                              // CODE XREF: sub_D27F0+2Ej
    ldloc.1
    ldc.i4   0xC0
    and
    brfalse.s loc_D2836
    ldloc.1
    ldc.i4   0xC0
    or
    stloc.1

loc_D2836:                              // CODE XREF: sub_D27F0+3Cj
    ldloc.1
    ret
  }

上記の関数TLS1.1/1.2に対応してないので大幅変更が必要なのだが普通にコードを書くと倍の大きさになるので工夫する

どうやら、クライアントとサーバー機能のフラグがどちらかたっていたら両方立てるってことらしい。

.method assembly hidebysig specialname instance valuetype System.Security.Authentication.SslProtocols get_SslProtocol()
                                        // CODE XREF: get_SslProtocol+6p
                                        // sub_D2B00+A1p ...
  {
    .maxstack 4
    .locals init (class System.Net.SslConnectionInfo V0,
                  valuetype System.Security.Authentication.SslProtocols V1)
    ldarg.0
    ldc.i4.1
    call     instance void System.Net.Security.SslState::CheckThrow(bool authSucessCheck)
    ldarg.0
    call     instance class System.Net.Security.SecureChannel System.Net.Security.SslState::get_Context()
    callvirt instance class System.Net.SslConnectionInfo System.Net.Security.SecureChannel::get_ConnectionInfo()
    stloc.0
    ldloc.0
    brtrue.s loc_D2808
    ldc.i4.0
    ret

loc_D2808:                              // CODE XREF: sub_D27F0+14j
    ldloc.0
    ldfld    int32 System.Net.SslConnectionInfo::Protocol
    stloc.1
    ldloc.1
    ldc.i4   0x551
    and
    ldloc.1
    ldc.i4   0xAA2
    and
    ldc.i4.s 1
    shr
    or
    ldc.i4.s 3
    mul

    stloc.1
    ldloc.1
    ret

簡略化成功

アルゴリズム的には、クライアント(0xaa2)とサーバー(0x551)のフラグを個別に取り出した後 シフトして or かけた後、3倍して同じことを実現している。

Common Language Runtime detected an invalid program.  (スタック数オーバーらしい)
とか
JIT Compiler encountered an internal limitation
とか
Field token out of range.
出て困ったけど、maxstack増やして解決できた。

おすすめ

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です