1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

picoquicをWindows環境でビルドしてみる

Last updated at Posted at 2025-08-01

前説

QUICにちょっと興味あるから、qicoquicちょっとビルドしてみようぜ!みたいな記事です
手を出すなら王道のQUICHEやらMsQuicのが良いんじゃね、という気もしますが、
純粋なQUIC実装になっていて、確認しやすそうだったのでこちらにしました

参考にした資料はこちら
picoquic
Private Octopus and QUIC

ということで、軽くビルド関連の資料を読んでみた感じ、
picoquicはpicotlsに依存しており、qicotlsはOpenSSLに依存しているようです
今回はビルドが少しだけ面倒なOpenSSLではなく、LibreSSL4.1を使用することにしました
(LibreSSLのX25519がqicotlsで非対応になっているようなので、qicotlsに別途パッチを当てています)
また、最小限ビルドのようなものにすればOpenSSLも不要っぽいのですが、
とりあえずサンプルやテストが動作するものを使ってみたかったのでそのままビルドしております

今回は家のノートPCにOpenSSLのビルド環境が整っていなかったのでLibreSSLを採用する非公式チャートとなっております…
一般的な環境であればOpenSSLを採用するチャートが大変にオススメです
(ビルドが高速で簡単に静的リンクの状態に持ち込めるので、LibreSSLも悪くない選択だと思っています)

事前に必要なものをインストールしておく

Visual Studio

当記事の手順は最新のVisual Studio 2022 Communityで確認しています
「C++によるデスクトップ開発」が必要になります

cmake

LibreSSLのビルドにはcmakeが必要になります
以下のURLからcmakeをダウンロードしてインストールします
https://cmake.org/download/

https://github.com/Kitware/CMake/releases/download/v3.31.8/cmake-3.31.8-windows-x86_64.msi
テスト環境ではこのバージョンを使っていました

LibreSSLのビルド

LibreSSLをビルドするには、VisualStudio開発環境が必要です
x64 Native Tools Command Prompt for VS 2022
等のVisualStudio開発環境で実行しましょう

LibreSSLからファイルを取得します
https://www.libressl.org/

今回は4.1のパッケージを使用しました
https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-4.1.0.tar.gz

ダウンロードして展開し、展開したディレクトリに移動します

LibreSSLのビルドは以下のコマンドで行います

cmake -S . -B build -G "Visual Studio 17 2022" -DCMAKE_INSTALL_PREFIX=c:\libressl

CMAKE_INSTALL_PREFIXはLibreSSLをインストールするディレクトリを指定しています、
管理者権限が必要なフォルダにインストールする設定がデフォルトになっているようなので必要に応じて対処してください

cd build
MSBuild LibreSSL.sln /t:rebuild /p:Configuration=Release -m

ビルド成功したらそのままインストールします

MSBuild INSTALL.vcxproj /t:build /p:Configuration=Release

インストールが終わったら、OpenSSLとして環境変数を登録します
CMAKE_INSTALL_PREFIXで指定したパスを設定します

setx OPENSSL64DIR c:\libressl

次にOpenSSLとLibreSSLでは提供されるファイル名が異なっているため、OpenSSL合わせで統一します
c:\libressl\crypto.lib -> c:\libressl\libcrypto.lib
コピーしたり、シンボリックリンクを作成したりしてください
01.jpg

picotlsをビルドする

をチェックアウト、picotls\picotlsvs\picotlsvs.slnを開きビルドします
(※X25519がサポートされていない状態でのビルド結果となります)

git clone https://github.com/h2o/picotls.git

チェックアウトだけではファイルがすべてそろっていないことがあるようなので、テスト関連のビルド時にエラーが出た場合は、サブモジュール更新を行う必要があるようです

cd picotls
git submodule init
git submodule update

picoquicをビルドする

をpicotlsの兄弟フォルダとしてチェックアウトします
(↓のような関係性になるように配置します)
03.jpg

git clone https://github.com/private-octopus/picoquic.git

picoquic\picoquic.sln を開いてビルドしますが、
LibreSSLでビルドした場合、qicotlsでX25519がサポートされていない状態となるため
変数未定義によりビルドエラーになってしまいます
02.jpg

picotlsを若干修正する

二箇所ほど修正するとビルドが通るようになります、
正しいコードなのかは不勉強なためイマイチ分かっておらず……
(OpenSSLの通過テストと同じ結果やからまあええやろ…の精神ぐらいで生存させていただいております)

修正そのものはこちらのリポジトリから取得できます
https://github.com/kei-y/picotls/tree/f350eab_with_libressl-4.1.0

diff --git a/include/picotls/openssl.h b/include/picotls/openssl.h
index 49c1cf2..6eba68c 100644
--- a/include/picotls/openssl.h
+++ b/include/picotls/openssl.h
@@ -60,7 +60,7 @@ extern ptls_key_exchange_algorithm_t ptls_openssl_secp521r1;
 #ifdef EVP_PKEY_ED25519
 #define PTLS_OPENSSL_HAVE_ED25519 1
 #endif
-#if defined(NID_X25519) && !defined(LIBRESSL_VERSION_NUMBER)
+#if defined(NID_X25519)
 #define PTLS_OPENSSL_HAVE_X25519 1
 #define PTLS_OPENSSL_HAS_X25519 1 /* deprecated; use HAVE_ */
 extern ptls_key_exchange_algorithm_t ptls_openssl_x25519;
diff --git a/lib/openssl.c b/lib/openssl.c
index 01fcfce..408bdb7 100644
diff --git a/lib/openssl.c b/lib/openssl.c
index 01fcfce..408bdb7 100644
--- a/lib/openssl.c
+++ b/lib/openssl.c
@@ -558,6 +558,14 @@ static int evp_keyex_on_exchange(ptls_key_exchange_context_t **_ctx, int release
 #undef X25519_KEY_SIZE
 #endif
 
+#if defined(LIBRESSL_VERSION_NUMBER)
+    const int key_type = EVP_PKEY_id(ctx->privkey);
+
+    if ((evppeer = EVP_PKEY_new_raw_public_key(key_type, NULL, peerkey.base, peerkey.len)) == NULL) {
+        ret = PTLS_ERROR_LIBRARY;
+        goto Exit;
+    }
+#else
     if ((evppeer = EVP_PKEY_new()) == NULL) {
         ret = PTLS_ERROR_NO_MEMORY;
         goto Exit;
@@ -570,6 +578,7 @@ static int evp_keyex_on_exchange(ptls_key_exchange_context_t **_ctx, int release
         ret = PTLS_ERROR_LIBRARY;
         goto Exit;
     }
+#endif
     if ((evpctx = EVP_PKEY_CTX_new(ctx->privkey, NULL)) == NULL) {
         ret = PTLS_ERROR_LIBRARY;
         goto Exit;
@@ -627,12 +636,40 @@ static int evp_keyex_init(ptls_key_exchange_algorithm_t *algo, ptls_key_exchange
     }
     *ctx = (struct st_evp_keyex_context_t){{algo, {NULL}, evp_keyex_on_exchange}, pkey};
 
+#if defined(LIBRESSL_VERSION_NUMBER)
+    size_t key_len;
+
+    // required key size
+    if (EVP_PKEY_get_raw_public_key(ctx->privkey, NULL, &key_len) == 0) {
+        ret = PTLS_ERROR_LIBRARY;
+        goto Exit;
+    }
+    if (key_len == 0) {
+        ret = PTLS_ERROR_LIBRARY;
+        goto Exit;
+    }
+
+    if ((ctx->super.pubkey.base = OPENSSL_malloc(key_len)) == NULL) {
+        ret = PTLS_ERROR_NO_MEMORY;
+        goto Exit;
+    }
+    ctx->super.pubkey.len = key_len;
+
+    /* set public key */
+    if (EVP_PKEY_get_raw_public_key(ctx->privkey, ctx->super.pubkey.base, &ctx->super.pubkey.len) == 0) {
+        ret = PTLS_ERROR_LIBRARY;
+        OPENSSL_free(ctx->super.pubkey.base);
+        ctx->super.pubkey.base = NULL;
+        goto Exit;
+    }
+#else
     /* set public key */
     if ((ctx->super.pubkey.len = EVP_PKEY_get1_tls_encodedpoint(ctx->privkey, &ctx->super.pubkey.base)) == 0) {
         ctx->super.pubkey.base = NULL;
         ret = PTLS_ERROR_NO_MEMORY;
         goto Exit;
     }
+#endif
 
     *_ctx = &ctx->super;
     ret = 0;
-- 

この変更を適応した状態でpicotlsのビルドを行いX25519関連の定義をアクティブにします

picotlsのビルドが通ったらqicoquicのビルドを再度行います
(こちらも記事作成段階ではvs2022環境でリンクエラーになるものがあったため、
https://github.com/kei-y/picoquic/tree/6b9a563_fix_x64_linkerror
微修正を行っています)

ビルドエラーが発生せず、VisualStudioのテストエクスプローラですべてのテストが成功することを確認しておしまいです、お疲れ様でした!
06.jpg

実際のビルドに使用したソースコード

ビルドに実際に使用したコードへのリンク
qicoquic
qicotls
libressl-4.1.0

最後に

公式マニュアルに非常に丁寧な資料があって良かったです
実家の帰省中にでも動作確認したり、内部コードを読み込んでみようと思います

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?