Delphi や C++Builder で作成した iOS または macOS アプリで TLS を提供するには、これまで OpenSSL を同梱する必要がありました。つまり、libssl.dylib と libcrypto.dylib をアプリにパッケージし、バージョンを合わせ、自分でパッチを当てるということです。sgcWebSockets はその要件をなくします。新しいネイティブ TLS バックエンド iohAppleTLS は Apple 自身の TLS を使うため、配布する OpenSSL の .dylib なしで安全に接続できます。これは Enterprise エディションで利用できます。
さらに良いことに、最新のシステムでは TLS 1.3 を利用できます。このバックエンドはデバイスに最適なシステム API を自動選択し、すべてを一つの設定の背後で処理します。そのため OS のバージョンで分岐する必要がなく、どこでもコードは同じままです。
切り替えはたった一行
TLS バックエンドは TLSOptions.IOHandler を通じて選択します。Apple のネイティブ TLS を使うには、これを iohAppleTLS に設定します。残りのネットワークコードは変わりません。
uses
sgcWebSocket, sgcWebSocket_Types;
WSClient.TLS := True;
WSClient.TLSOptions.IOHandler := iohAppleTLS;
WSClient.URL := 'wss://www.esegece.com:2053';
WSClient.Active := True;
他のプラットフォームでは、適したバックエンドをそのまま使えます。iohOpenSSL はどこでも動作し、iohSChannel は Windows でのネイティブ、iohAndroidTLS は Android での配布物なしのネイティブな選択肢です。小さな条件分岐により、一つのクライアントコンポーネントをあらゆるターゲットで正しく保てます。
WSClient.TLS := True;
{$IF Defined(IOS) or Defined(MACOS)}
WSClient.TLSOptions.IOHandler := iohAppleTLS; // native, no OpenSSL .dylib
{$ELSEIF Defined(ANDROID)}
WSClient.TLSOptions.IOHandler := iohAndroidTLS; // native, no OpenSSL .so
{$ELSEIF Defined(MSWINDOWS)}
WSClient.TLSOptions.IOHandler := iohSChannel; // native on Windows
{$ELSE}
WSClient.TLSOptions.IOHandler := iohOpenSSL; // OpenSSL elsewhere
{$ENDIF}
WSClient.URL := 'wss://www.esegece.com:2053';
WSClient.Active := True;
配布する OpenSSL の .dylib は不要
ネイティブバックエンドでは、同梱したり、バージョンを合わせたり、パッチを当てたりする OpenSSL がありません。TLS スタックはオペレーティングシステムに付属しているため、アプリはより軽量になり、サードパーティの暗号依存からも解放されます。App Store への申請では、これは正当化すべきネイティブライブラリが一つ減ることも意味します。そして TLS ポリシーは、数か月前に固定したライブラリのビルドではなく Apple のものに従います。セキュリティ修正は OS のアップデートを通じて届きます。
自動フォールバック付きの TLS 1.3
一つの iohAppleTLS 設定が、デバイスごとに適切なシステム API を選びます。macOS 10.14 以降および iOS 12 以降では Network.framework を使い、TLS 1.3 をもたらします。古いシステムでは Secure Transport にフォールバックし、その上限は TLS 1.2 です。バージョンチェックを一切書く必要はありません。バックエンドが経路を選択し、どちらの場合もコードは同一です。
完全な TLS クライアント
これは機能を削った簡易版ではなく、完全なクライアントです。システムトラストストアを使用し、SNI とホスト名の検証を行い、OnAppleTLSVerifyPeer コールバックを公開するので、証明書を自分で検査して受け入れるか拒否するかを決められます。RootCertFile によってカスタム CA ルートでプライベートな認証局を信頼でき、CertFile と Password によって相互 TLS 用のクライアント証明書を提示でき、ALPN を通じて http/1.1 などのアプリケーションプロトコルをアドバタイズできます。
WSClient.TLS := True;
WSClient.TLSOptions.IOHandler := iohAppleTLS;
WSClient.TLSOptions.VerifyCertificate := True;
WSClient.TLSOptions.ALPNProtocols.Add('http/1.1');
WSClient.TLSOptions.RootCertFile := ''; // optional custom CA (PEM/DER)
WSClient.TLSOptions.CertFile := ''; // optional client cert (PKCS#12) for mTLS
WSClient.TLSOptions.Password := ''; // client cert password
WSClient.OnAppleTLSVerifyPeer := DoVerifyPeer; // optional custom validation
WSClient.Host := 'your.server.com';
WSClient.Port := 443;
WSClient.Active := True;
verify-peer コールバックは、証明書のサブジェクトとその SHA-256 フィンガープリント、トラスト評価の結果、そして接続を許可またはブロックするために設定する Accept フラグを提供します。ここは、証明書をピン留めしたり、システムのトラスト判定の上に独自のポリシーを適用したりするのに自然な場所です。
すでに使っているコンポーネントと連携
このバックエンドは共有の TLSOptions の背後にあるため、WebSocket クライアントに限定されません。TCP クライアントや HTTP/2 クライアント、その他 TLSOptions を公開するコンポーネントも同じ方法で選択します。コードがすでに TLSOptions を構成しているなら、ネイティブ Apple TLS を有効にするのは一つの代入だけで、接続やデータ交換の方法は変わりません。
Android でも同じ考え方
Android もターゲットにする場合、対となる iohAndroidTLS バックエンドがそこで同じ仕事をします。プラットフォームの SSLEngine を通じて Android 自身の TLS を使い、配布する OpenSSL の .so はありません。パターンは同一で、プラットフォームごとにネイティブハンドラを選びます。詳細はネイティブ Android TLS ページにあります。
提供状況
ネイティブ Apple TLS(iohAppleTLS)は sgcWebSockets の Enterprise エディションで提供されます。4 つの TLS バックエンド、すなわちすべてのプラットフォームでの OpenSSL、Windows での SChannel、そしてネイティブの Android および Apple ハンドラの完全な内訳については、SSL / TLS セクションとネイティブ Apple TLS ページをご覧ください。
sgcWebSockets のダウンロードページからダウンロードするか、GetIt または登録済みアカウントを通じて入手してください。
ご質問やフィードバック、あるいは iOS または macOS アプリを OpenSSL から移行する際のお手伝いが必要ですか。お問い合わせください。コードを書いた本人から返信が届きます。
