時間順にソート可能なUUIDv6, UUIDv7, UUIDv8の提案仕様

IETFに「New UUID Formats」という提案仕様が提出されています。

これは、時系列順にソート可能なUUID version 6, UUID version 7, UUID version 8を新しく定義するものです。

詳しい背景は提案仕様にゆずりますが、ULIDを始めとして、時系列順にソート可能な一意な識別子を利用したいというユースケースがあります。例えば、データベースのキーとして使えば、ソートせずとも順番に並びますし、書き込む際も順々に書き込めるのでデータアクセスが局所的になります。

今回は簡単に、それぞれのUUIDのフォーマットを眺めていきます。なお、フォーマットは異なりますが、バージョンを示す値は同じ位置にあります。

UUIDv6

UUIDv6は128bit長で、UUIDv1と似てるフォーマットを取ります。

f:id:ASnoKaze:20210428021930p:plain

1582年10月15日(グレゴリオ暦)からの100ナノ秒単位でカウントした数値を60bit長で表現し、time_high(32bit), time_mid(16bit), time_low(12bit)に分割して並べます。

なお、time_low_and_versionは上位4bitがバージョンであり、6をしめす 0110 が入ります。

残りの部分はUUIDv1と同じで、クロックシーケンスおよび乱数が入ります。

UUIDv7

UUIDv7はユニックスタイムを使用し、ミリ秒、マイクロ秒、ナノ秒精度のタイムスタンプを表現できます。

UUIDv7の構成は、36bitのタイムスタンプ(unixts)、小数点以下の値(msecor usec or nsec)、乱数(rand)から構成されます。

ミリ秒精度の場合
f:id:ASnoKaze:20210428024421p:plain

マイクロ秒精度の場合
f:id:ASnoKaze:20210428024500p:plain

ナノ秒精度の場合
f:id:ASnoKaze:20210428025104p:plain

システムによって扱える精度が異なりますが、ナノ秒エンコードされたものを、マイクロ秒としてデコードしても残りはランダムな値として処理することが出来ます。

UUIDv8

UUIDv8は他のバージョンが使えない場合のみに使います。時間ソースとして何を使うかや、その精度を自由にきめて使用出来ます。どのようにエンコードされているか知らない実装は、タイムスタンプを得ることは出来ません。

フォーマットはタイムスタンプ、バージョン、シーケンスやノード(乱数)の位置のみが決められています。

f:id:ASnoKaze:20210428025923p:plain

QUIC Version 2 という個人ドラフト(draft-duke-quic-v2❩

2021/11/23 追記
進展があったので、新しく記事を書きました
asnokaze.hatenablog.com

==
QUIC Version 1はQUIC WGとしてはとりくみが終わり、RFCとして出るのを待つばかりとなっています。

現在は、v1以後のQUICバージョンの前準備として、バージョンネゴシエーションの仕組みづくりの議論が活発に行われています。先日も、中間会議でバージョンネゴシエーションについて議論が行われました (詳細へのリンク)

そのバージョンネゴシエーションの議論のなかで、「QUIC Version 2 (draft-duke-quic-v2-00)」という DraftがIETFに提出されました。

draftは個人が自由に提出出来るということに注意してください。審査などもありません。これは、IETFやQUIC WGとしての意見を表すものではなく、何かが決まってしまうというものではありません(説明)。ほぼ多くのdraftは個人ドラフトから始まりますし、議論の呼び水と提出されることもよくあります。

このdraftもバージョンネゴシエーションに対する整理および議論のために書かれたものです。その論点について軽く紹介します。

draft-duke-quic-v2-00

いま取り上げているQUICv2を、ドラフト版数込みで明示するために、「draft-duke-quic-v2-00」と呼ぶこととします。

このdraft-duke-quic-v2-00では、QUICのバージョンとして2が与えられるところ以外、ほぼQUIC Version 1と同様です。そしてその目的として、QUICプロトコルの硬直化(Ossification)を防ぐためと、バージョンネゴシエーションを試すという点に主眼をおいています。

硬直化(Ossification)

硬直化とは、新しいバージョンのプロトコルを使おうとしたときに、対応していないネットワーク機器やミドルウェアが不具合を起こし、通信が阻害されることを言います。

具体的には以前書いた記事に書いてあります。
asnokaze.hatenablog.com

QUICも硬直化する可能性があります。将来デプロイされるQUICv2に対応してない実装が誤ってそのパケットを処理し、不具合が起き通信が阻害される可能性があります。Google QUICでの実験ではその問題がすでに起こっていたことを明らかにしています。もちろん、IETF QUICでは硬直化が起きないように対策されています。

QUICv1のパケットは、暗号化にバージョン固有のソルトを使用しています。将来のQUICでも同様にバージョン固有のソルトを使えば、そのバージョンに対応していない(=ソルトを知らない)実装は、暗号的に初期パケットを解読できません。ですので、間違えて処理をするという問題を軽減しています。

draft-duke-quic-v2-00ではソルトとしてv1とは異なり次の値を指定しています。

initial_salt = 0xa707c203a59b47184a1d62ca570406ea7ae3e5d3

実装がこのように、ソルトを変更できる事が確認できるように、draft-duke-quic-v2-00を使うことができます。

バージョンネゴシエーション

QUICのバージョンネゴシエーションは別の仕様となっており、「Compatible Version Negotiation for QUIC」という仕組みがあります。先述の通り、この仕様は議論されている最中で、今後変更される予定です。

実装がこの、このバージョンネゴシエーションの仕組みを試せるように、draft-duke-quic-v2-00 を使うことができます。

なお、draft-duke-quic-v2-00 実装はQUICv1も実装している必要があります。

おわりに

QUICが、更に前進していくためにバージョンネゴシエーションの話がホットになっています。バージョンネゴシエーションの具体的な仕様については、一段落したらブログに書きたいと思います。

HTTPコネクションでIPパケットをProxyさせる、新しいCONNECT-IPメソッドの仕様 (RFC 9484)

2022年7月追記: この記事は古くなっています。現在の最新仕様では、拡張CONNECTメソッドを使うことになってます
asnokaze.hatenablog.com


確立したHTTP/3コネクションをVPNのように使う、MASQUEという仕組みがIETFで議論されています。

以前書いた記事では、UDPパケットをProxyさせるCONNECT-UDPという提案仕様を紹介しました。
asnokaze.hatenablog.com

その後、同様に確立されたHTTP/3コネクション上で、IPパケットをトンネリング可能にする「The CONNECT-IP HTTP Method」という仕様が提案されています。

CONNECT-UDPと同様に経路上の第三者にはただのHTTP/3通信を行っているようにしか見えないため、検閲やブロッキングに対して耐性があると思われます。

それでは簡単に見ていきましょう。

CONNECT-IPメソッド

HTTP CONNECT-IPメソッドは、通常のHTTPリクエストのCONNECTメソッドと同様、いくつかの疑似ヘッダを持ちます

  • ":method" : "CONNECT-IP"を指定
  • ":scheme": "https"を指定
  • ":path": "/" を指定
  • ":authority": Proxyのホスト名とポート番号を指定

クライアントからのCONNECT-IPリクエストに対して、サーバが200レスポンスを返すことで、そのストリームがIPパケットのProxyに使用されます。

IPレイヤのセットアップ

COONECT-IPでストリームのトンネル化をしたあと、IPレイヤのセットアップをします。これらのメッセージは、そのストリーム上のDATAフレームに格納されて送受信されます。

  • クライアントはADDRESS_REQUESTメッセージを送り、IPアドレスの割当を要求します
  • サーバはADDRESS_ASSIGNメッセージを送り、IPアドレスの割当を行います
  • サーバはROUTE_ADVERTISEMENTメッセージを送り、ルーティング情報をクライアントに通知します

(通信を制御するために、その他のメッセージも定義されていますが割愛)

IPパケットの送信

セットアップが終わったらIPパケットを実際にやり取りしていきます。

主に二種類の方法があります

  • 該当ストリーム上で、IP_PACKETメッセージを送信します。IP VersionからIP PayloadまでのIPパケットがそのまま格納されます
  • QUIC DATAGRAMフレームで、同様にIPパケットを送信する

おわりに

まだまだ最初の仕様ですので、今後議論があるかと思いますが、HTTP/3でVPNを効率よく行うというところでIPパケットまで送れるようになりました。

活用方法や、セキュリティの議論など引き続き注視していこうかと思います

WebTransport over HTTP/3のプロトコル仕様

WebSocketに変わる、Webの新しい双方向通信仕様 WebTransportの標準化・実装が進められています。

このWebTransportではHTTP/3の特徴を活かし、パケットの順番が入れ替わったり、パケットロスがあったとしても受け取った順番に処理を行うことが出来ます。DATAGRAM拡張を使えば、パケットロスしたデータも再送不要にできます。

前回紹介した通り、WebTransportは「WebTransportover QUIC」や「WebTransportover HTTP/3」がありましたが、HTTP/3を使う方向で議論が進んでいます。
asnokaze.hatenablog.com

Chromeの開発者メーリングリストでは、この「WebTransport over HTTP/3」実装が進められている事が書かれています。
groups.google.com

そこで、今回はプロトコルの仕様部分について確認していきます。

目次

概要

WebTransport over HTTP/3」では、HTTP/3のコネクションは確立されたところから始まります。仕様通り順番に説明していきます

  • コネクション確立後、WebTransportに対応している事をお互いに示す
  • CONNECTメソッドでWebTransport通信を開始する
  • ストリーム, DATAGRAMを行う

f:id:ASnoKaze:20210418002323p:plain

コネクション確立後、WebTransportに対応している事をお互いに示す

通常通りHTTP/3コネクションを確立したあとに、クライアントとサーバはそれぞれ自身がWebTransportに対応している事を通知し合います。

具体的には、SETTINGSフレームでSETTINGS_ENABLE_WEBTRANSPORTを1に設定して送信します。DATAGRAMフレームを使うので、QUICレイヤでDATAGRAMを有効化しておく必要があります。

CONNECTメソッドでWebTransport通信を開始する

JavaScriptからはURLを指定して通信が開始されます。
```
new WebTransport(url)
```

このURLに対してCONNECTメソッドのリクエストを送信することで、WebTransport用の通信が開始されます。このCONNECTメソッドは「RFC8441 WebSockets over HTTP/2」で拡張されたヘッダを持ちます。

  • :protocol疑似ヘッダに "webtransport" を指定されます
  • :scheme疑似ヘッダには "https" が指定されます
  • :path, :authority 疑似ヘッダはコネクションを開始した際のURLに沿って設定されます

このリクエストに対してステータスコード200が返されると、WebTransportの通信が進められます。なお、このCONNECTメソッドを送信したストリームIDをセッションIDと呼びます。

ストリーム, DATAGRAM通信を行う

HTTP/3コネクション上に、アプリケーションが実際にデータを送信するQUICストリームをオープンします。これらは、セッションIDと紐付けて利用されます。

以下の通信の種類があります

  • 単方向ストリーム
  • クライアント開始双方向ストリーム
  • サーバ開始双方向ストリーム
  • DATAGRAMフレームの送信
単方向ストリーム

HTTP/では単方向ストリームを使用する際に、まずストリームタイプの値を送信します。

WebTransportではストリームタイプ0x54でストリームが開始されます。続いて紐づくセッションIDを送信し、その後データを送ることが出来ます

f:id:ASnoKaze:20210418001247p:plain

クライアント開始双方向ストリーム

新しいWEBTRANSPORT_STREAMフレームでストリームが開始されます。紐づくセッションIDを送信し、その後データが続きます。

f:id:ASnoKaze:20210418001311p:plain

サーバ開始双方向ストリーム

サーバ開始の双方向ストリームは通常HTTP/3では行わないません。この仕様では、QUICのルールに基づいてサーバから双方向通信ストリームをオープンします

f:id:ASnoKaze:20210418001326p:plain

DATAGRAMフレームの送信

QUIC DATAGRAMフレームの利用方法は「Using QUIC Datagrams with HTTP/3」で定義されています。(今後変更される予定です

DATAGRAMフレームで、紐づくセッションIDを送信し、その後データが続きます。

f:id:ASnoKaze:20210418001346p:plain

コネクションプーリング

HTTP/3ではコネクション上で複数のHTTPリクエストを送信することが出来ます。別タブで同じサーバに対してHTTPリクエストを送信したりする際も単一のコネクションが使用されます。

それと同じ用に、「new WebTransport(url)」で同一通信する際も同一コネクションを使う事ができるでしょう。

このようなコネクションプーリングの仕組みは現在議論されている段階です。今の所、SETTINGS_ENABLE_WEBTRANSPORTに2を設定することで、コネクションプーリングに対応していることを相手に通知する方法が考えられています。詳しくは下記を参照ください

github.com

その他

DATAGRAMフレームについては現在議論が進められている段階です。特にHTTP/3から利用する場合のフォーマットは今後変更される可能性があります。

github.com

RFC 8996でTLS1.0とTLS1.1が廃止に

IETFで、TLS1.0とTLS1.1を正式に非推奨にする「RFC 8996 Deprecating TLS 1.0 and TLS 1.1」が公開されました。

新しいプロトコルへの移行期間は十分であるとし、TLS1.0, TLS1.1, DTLS1.0は廃止となり、TLS 1.2, TLS1.3, DTLS 1.2のみが使用できます。表現としても、MUST NOTで利用を禁止しています。

  • TLS 1.0 MUST NOT be used
  • TLS 1.1 MUST NOT be used

2015年に公開された、TLS利用時の推奨事項を定めたRFC7525がありますが、今回の禁止内容も含めて改定作業が開始されています。詳細については以前書いたとおり
asnokaze.hatenablog.com

更新されるRFC

RFC 8996では、既存のRFCについても言及しており

TLS1.2以上では無用な、下記のRFCがobsleteされます

  • RFC 5469: DES and IDEA Cipher Suites for Transport Layer Security
  • RFC 7507: TLS Fallback Signaling Cipher Suite Value (SCSV) for Preventing Protocol Downgrade Attacks

下記のRFCの内容が更新されます

  • RFC 3261: SIP: Session Initiation Protocol
  • RFC 3329: Security Mechanism Agreement for the Session Initiation Protocol (SIP)
  • RFC 3436: Transport Layer Security over Stream Control Transmission Protocol
  • RFC 3470: Guidelines for the Use of Extensible Markup Language (XML) within IETF Protocols
  • RFC 3501: INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1
  • RFC 3552: Guidelines for Writing RFC Text on Security Considerations
  • RFC 3568: Known Content Network (CN) Request-Routing Mechanisms
  • RFC 3656: The Mailbox Update (MUPDATE) Distributed Mailbox Database Protocol
  • RFC 3749: Transport Layer Security Protocol Compression Methods
  • RFC 3767: Securely Available Credentials Protocol
  • RFC 3856: A Presence Event Package for the Session Initiation Protocol (SIP)
  • RFC 3871: Operational Security Requirements for Large Internet Service Provider (ISP) IP Network Infrastructure
  • RFC 3887: Message Tracking Query Protocol
  • RFC 3903: Session Initiation Protocol (SIP) Extension for Event State Publication
  • RFC 3943: Transport Layer Security (TLS) Protocol Compression Using Lempel-Ziv-Stac (LZS)
  • RFC 3983: Using the Internet Registry Information Service (IRIS) over the Blocks Extensible Exchange Protocol (BEEP)
  • RFC 4097: Middlebox Communications (MIDCOM) Protocol Evaluation
  • RFC 4111: Security Framework for Provider-Provisioned Virtual Private Networks (PPVPNs)
  • RFC 4162: Addition of SEED Cipher Suites to Transport Layer Security (TLS)
  • RFC 4168: The Stream Control Transmission Protocol (SCTP) as a Transport for the Session Initiation Protocol (SIP)
  • RFC 4217: Securing FTP with TLS
  • RFC 4235: An INVITE-Initiated Dialog Event Package for the Session Initiation Protocol (SIP)
  • RFC 4261: Common Open Policy Service (COPS) Over Transport Layer Security (TLS)
  • RFC 4279: Pre-Shared Key Ciphersuites for Transport Layer Security (TLS)
  • RFC 4497: Interworking between the Session Initiation Protocol (SIP) and QSIG
  • RFC 4513: Lightweight Directory Access Protocol (LDAP): Authentication Methods and Security Mechanisms
  • RFC 4531: Lightweight Directory Access Protocol (LDAP) Turn Operation
  • RFC 4540: NEC's Simple Middlebox Configuration (SIMCO) Protocol Version 3.0
  • RFC 4582: The Binary Floor Control Protocol (BFCP)
  • RFC 4616: The PLAIN Simple Authentication and Security Layer (SASL) Mechanism
  • RFC 4642: Using Transport Layer Security (TLS) with Network News Transfer Protocol (NNTP)
  • RFC 4680: TLS Handshake Message for Supplemental Data
  • RFC 4681: TLS User Mapping Extension
  • RFC 4712: Transport Mappings for Real-time Application Quality-of-Service Monitoring (RAQMON) Protocol Data Unit (PDU)
  • RFC 4732: Internet Denial-of-Service Considerations
  • RFC 4743: Using NETCONF over the Simple Object Access Protocol (SOAP)
  • RFC 4744: Using the NETCONF Protocol over the Blocks Extensible Exchange Protocol (BEEP)
  • RFC 4785: Pre-Shared Key (PSK) Ciphersuites with NULL Encryption for Transport Layer Security (TLS)
  • RFC 4791: Calendaring Extensions to WebDAV (CalDAV)
  • RFC 4823: FTP Transport for Secure Peer-to-Peer Business Data Interchange over the Internet
  • RFC 4851: The Flexible Authentication via Secure Tunneling Extensible Authentication Protocol Method (EAP-FAST)
  • RFC 4964: The P-Answer-State Header Extension to the Session Initiation Protocol for the Open Mobile Alliance Push to Talk over Cellular
  • RFC 4975: The Message Session Relay Protocol (MSRP)
  • RFC 4976: Relay Extensions for the Message Sessions Relay Protocol (MSRP)
  • RFC 4992: XML Pipelining with Chunks for the Internet Registry Information Service
  • RFC 5018: Connection Establishment in the Binary Floor Control Protocol (BFCP)
  • RFC 5019: The Lightweight Online Certificate Status Protocol (OCSP) Profile for High-Volume Environments
  • RFC 5023: The Atom Publishing Protocol
  • RFC 5024: ODETTE File Transfer Protocol 2.0
  • RFC 5049: Applying Signaling Compression (SigComp) to the Session Initiation Protocol (SIP)
  • RFC 5054: Using the Secure Remote Password (SRP) Protocol for TLS Authentication
  • RFC 5091: Identity-Based Cryptography Standard (IBCS) #1: Supersingular Curve Implementations of the BF and BB1 Cryptosystems
  • RFC 5158: 6to4 Reverse DNS Delegation Specification
  • RFC 5216: The EAP-TLS Authentication Protocol
  • RFC 5238: Datagram Transport Layer Security (DTLS) over the Datagram Congestion Control Protocol (DCCP)
  • RFC 5263: Session Initiation Protocol (SIP) Extension for Partial Notification of Presence Information
  • RFC 5281: Extensible Authentication Protocol Tunneled Transport Layer Security Authenticated Protocol Version 0 (EAP-TTLSv0)
  • RFC 5364: Extensible Markup Language (XML) Format Extension for Representing Copy Control Attributes in Resource Lists
  • RFC 5415: Control And Provisioning of Wireless Access Points (CAPWAP) Protocol Specification
  • RFC 5422: Dynamic Provisioning Using Flexible Authentication via Secure Tunneling Extensible Authentication Protocol (EAP-FAST)
  • RFC 5456: IAX: Inter-Asterisk eXchange Version 2
  • RFC 5734: Extensible Provisioning Protocol (EPP) Transport over TCP
  • RFC 5878: Transport Layer Security (TLS) Authorization Extensions
  • RFC 5953: Transport Layer Security (TLS) Transport Model for the Simple Network Management Protocol (SNMP)
  • RFC 6012: Datagram Transport Layer Security (DTLS) Transport Mapping for Syslog
  • RFC 6042: Transport Layer Security (TLS) Authorization Using KeyNote
  • RFC 6083: Datagram Transport Layer Security (DTLS) for Stream Control Transmission Protocol (SCTP)
  • RFC 6084: General Internet Signaling Transport (GIST) over Stream Control Transmission Protocol (SCTP) and Datagram Transport Layer Security (DTLS)
  • RFC 6176: Prohibiting Secure Sockets Layer (SSL) Version 2.0
  • RFC 6347: Datagram Transport Layer Security Version 1.2
  • RFC 6353: Transport Layer Security (TLS) Transport Model for the Simple Network Management Protocol (SNMP)
  • RFC 6367: Addition of the Camellia Cipher Suites to Transport Layer Security (TLS)
  • RFC 6460: Suite B Profile for Transport Layer Security (TLS)
  • RFC 6614: Transport Layer Security (TLS) Encryption for RADIUS
  • RFC 6739: Synchronizing Service Boundaries and <mapping> Elements Based on the Location-to-Service Translation (LoST) Protocol
  • RFC 6749: The OAuth 2.0 Authorization Framework
  • RFC 6750: The OAuth 2.0 Authorization Framework: Bearer Token Usage
  • RFC 7030: Enrollment over Secure Transport
  • RFC 7465: Prohibiting RC4 Cipher Suites
  • RFC 7525: Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS)
  • RFC 7562: Transport Layer Security (TLS) Authorization Using Digital Transmission Content Protection (DTCP) Certificates
  • RFC 7568: Deprecating Secure Sockets Layer Version 3.0
  • RFC 8261: Datagram Transport Layer Security (DTLS) Encapsulation of SCTP Packets
  • RFC 8422: Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS) Versions 1.2 and Earlier

HTTPレスポンスボディを送ったあとに、Cache-Controlを変更可能にする仕様

HTTPでキャッシュは、サーバがHTTPレスポンスを返す際、Cache-Controlヘッダをつけることで、どのようにキャッシュするか指示することができます。ヘッダ自体はレスポンスボディより前に送る必要があります。

Mark Nottingham氏らによって提案された「Updating HTTP Caching Policy in Trailers」という仕様では、HTTPレスポンスボディを送り終わってから、Cache-Controlを変更可能にします。

具体的には、Trailer FieldでCache-Controlを送った際の挙動について定義を与えています。

HTTP Trailer Field

まずは、Trailer Fieldについて説明します。

HTTPのセマンティクスの仕様(URL)では、HTTPボディを送ったあとにあとからヘッダ(正確にはFieldと呼ぶ)を送ることができます。これをTrailerと呼びます。HTTPセマンティクスで定義されていますので、HTTP/1.1 ~ HTTP/3どれでも使うことができます。

f:id:ASnoKaze:20210308002036p:plain

余談ですが、ヘッダ という呼び方は不正確ですので、ヘッダフィールド、トレーラフィールドという呼び方について別記事を書いています。ご参照いただければと思います。
qiita.com

Updating HTTP Caching Policy in Trailers

この仕様では、トレーラフィールドでCache-Controlを送りキャッシュ制御を更新する手順を定義しています。

具体例とともに見ていきましょう。

HTTP/1.1 200 OK
Content-Type: text/html
Cache-Control: no-store; trailer-update

[body]
Cache-Control: max-age=3600
  • ヘッダフィールドでは、Cache-Controlヘッダにtrailer-updateディレクティブを使用し、トレーラにCache-Controlがあることを示唆します。それまでは、no-storeとして扱わせます。
  • レスポンスボディを送信します
  • サーバはレスポンスボディを送り終わったら、トレーラでmax-age=3600とし、キャッシュを指示します。(トレーラのCache-Controlで、ヘッダのCache-Controlを置き換える)

これがどのようなケースに役に立つかと言うと、レスポンスボディを動的に生成しながらクライアントに返し始めるケースです。レスポンスボディを生成しながら返し始めているので、送ってる途中でサーバ側で不具合が起こってしまった場合などは、そのコンテンツはキャッシュをしてほしくありません。今回の提案仕様を用いれば、問題なくレスポンスボディが生成し終わったら、あらためてキャッシュの許可を出すことができます。

なお、trailer-updateを認識できないクライアントからは単純に無視されるだけです。

QUIC用APIを実装したOpenSSL forkの登場 (quictls/openssl)

AkamaiMicrosoftらによって、QUIC用APIを実装したOpenSSLのforkが公開されています。
github.com

これらは、公式がQUIC用APIをサポートするまでの一次的なソリューションとのことですが、流れを簡単に整理しておく。

目次

背景: QUICとTLS

QUICと呼ばれる新しいトランスポートプロトコルは、IETFで標準化が進められていましたが、RFCがもうすぐ出るところまできています。

このQUICでは通信を暗号化しますが、コネクションを確立する際に、TLS1.3相当のメッセージをやりとりしサーバ認証および鍵の共有を行います。

f:id:ASnoKaze:20210307224808p:plain
(詳細については 「QUIC-TLS」の仕様を御覧ください)

そこで、QUICを実装するに当たり暗号ライブラリとしてOpenSSLを使いたいところです。

OpenSSL 3.0とQUICサポートの見解

OpenSSLのQUICに対する見解は、2020年2月に投稿された「QUIC and OpenSSL」で述べられています。

OpenSSL 3.0ではQUICをサポートをしない事が述べられています。

QUICが非常に重要だと述べつつも、その時点ではOpenSSL 3.0に注力する事。2020年2月時点では、QUICが成熟しているか判断できないことに触れています。

2019年頃には、QUICをサポートするプルリクエストも出されていますが、上記の理由によりマージされてはいません。
https://github.com/openssl/openssl/pull/8797

forkされたOpenSSL

QUICの標準化も終わりが見えてきており、様々なところでQUICの実装が進められています。各コミュニティのOpenSSLのQUIC APIサポートのニーズは高くなってきているようです。

そのような中で、AkamaiMicrosoftらによって、QUIC用APIを実装したOpenSSLのforkが公開されました。詳細については、Readmeにかかれているとおりだが、ここでは簡単にかいつまんで紹介する
github.com

このforkは、公式がQUICをサポートするまでな一次的なソリューションとして公開されている。

実装的には、上述の"プルリクエスト"を取り込んだ形です。このAPI実装はBoringSSLから取り込まれており、すでにChromiumMSQuicで使用されている。

また、本家のリリースには、1日遅れを目安に追従していくとのことです。

その他の動き

もともとAkamaiはOpenSSLをforkしていたが、MSと共同で、コミュニティー利用のためのforkとして新しく公開した形になるようだ。

Akamai版OpenSSLを利用していたNode.jsは、すでに新しいforkに切り替える準備が進められている。
github.com