LFX Mentorship:從對密碼學一無所知到在 WasmEdge 中實現 wasi-crypto 提案

語言: CN / TW / HK

GSoC 申請將在 UTC 時間 4月19日結束,如果你對 WasmEdge 的專案感興趣,歡迎申請。這篇文章將為大家介紹 sonder-joker 通過 LFX Mentorship 為 WasmEdge 實現標準 WebAssembly 的經歷。

我是 sonder-joker,一名軟體工程專業的本科生,喜歡開源、軟體基礎架構和具有挑戰性的工作。去年秋季,我申請了 2021 年秋季的 CNCF 專案 WasmEdge 在 LFX Mentorship [1] 的開源任務:在 WasmEdge 中實現 WASI-Crypto 提案。

在 WasmEdge 實現 Wasi-crypto 的程式碼已經基本完成,我想把 LFX mentorship 的經歷和大家分享一下。希望這篇文章能為想要加入開源專案併為之做出貢獻的人提供一些幫助。我會在這篇文章介紹 LFX mentorship 是如何工作的,我是如何完成任務,以及我在這其中的所思所想。

我之所以選擇這個專案,是因為我想參與一個具有挑戰的開源專案的開發,而虛擬機器正是我感興趣的一個領域。通過 LFX Mentorship 來申請加入一個開源專案正是開始做開源貢獻的好選擇。

在 LFX Mentorship 之前,我在密碼學相關領域的知識為零。在參與了 wasi-crypto 的實現之後,我瞭解了不少關於密碼學程式設計的知識。通過 LFX Mentorship,我將成為 WasmEdge Runtime 專案的貢獻者(程式碼還沒正式 merge [2] )。更進一步,我還成為了 wasi-crypto 專案的 collaborator!

wasi-crypto 的簡要概述

wasi-crypto 簡介

wasi-crypto [3] 是一組可移植的、模組化的、執行時獨立的 WebAssembly 原生的 API。在我們可以在保留 WebAssembly sandbox 特性的同時使用 wasi-crypto 來執行加密操作。

為什麼我們需要 wasi-crypto

WasmEdge 提供了一個實驗性的 WASI Socket API,用於支援 Wasm 中的 Berkeley Sockets API。WasmEdge 提供了一種開啟新 socket、偵聽現有 socket 以及傳送和接收資料的新方法。

在此之上,我們可以支援更多相關功能(例如 SSL)。要實現此功能,一種可選的方法是將 OpenSSL 庫編譯為 Wasm 並將其連結為庫。但是,效能可能並不好,因為所有計算都是在 Wasm 級別完成的。而另一種可選的方法則是將 OpenSSL 庫包裝到 Wasm 的 external function 中,例如,將openssl 中的 ssl_connect 繫結到 (import "OpenSSL" "ssl_connect" .. . . )

然而,實現這個功能並不簡單。為了簡化工作量,我們決定先實現 WASI-crypto 提案,然後再通過這個提案來完成以上事情。

我如何實現 wasi-crypto

分解整體任務

wasi-crypto 是一個比較複雜的專案。但是,我們可以先梳理整個工作,然後分解為幾個子任務。我根據 wasi-crypto 提案的模組 [4] 和 WasmEdge 的需求對其進行了劃分。

選擇一個合適的的開源加密庫

顯然,從頭開始實現加密庫是不現實的,沒有必要重新發明輪子。C/C++ 中有許多與加密相關的庫,我們很容易就能找到一個開源加密庫作為我們的底層實現。經過挑選和研究,我們選擇了 OpenSSL [5]

原因如下:

OpenSSL 是最著名的加密庫,它足夠強大和安全。大多數 Linux 發行版都預裝了 OpenSSL 包。在大多數邊緣裝置上執行 Linux 系統和 WasmEdge 的情況下,使用 OpenSSL 庫可以使 WasmEdge 的大小保持較小。而且,OpenSSL 的開源許可證不影響 WasmEdge 的開源許可證,OpenSSL 由兩部分組成:libssl 和 libcrypto,其中的 libssl 提供了我們需要的演算法。

當然,也有缺點。OpenSSL 的 API 設計對開發人員並不友好,這在 3.0 中已進行了改進。

此外, OpenSSL 3.0 的效能並不令人滿意 [6]

因此,在與我的導師 Hydai(WasmEdge 的核心維護者)討論後,我們選擇了 OpenSSL v1.1.1。

在 GitHub 上記錄進度

我每週會與 WasmEdge 的 mentor  Hydai 開會,討論進展和下一步安排。每次會議結束後,我都會記錄當前的進度,並將它們與最初的安排進行比較,看看我是否能夠按時完成工作。在實施 wasi-crypto 過程中,我的計劃發生了多次更改,但我認為這是不可避免的——動態調整任務的安排十分重要。

受邀成為 wasi-crypto 的維護者

為了在 WasmEdge 中實現 wasi-crypto,我反覆閱讀了很多次規範。在此過程中,我發現了 wasi-crypto 規範中的一些問題,包括typo、示例和規範不一致的一些地方以及一些標準未覆蓋的地方。

所以我在 wasi-crypto 建立了一些 issue 與社群溝通,而對於已經確定的問題,我會通過 pull request 來修復它們。在這個過程中,我收到了來自 wasi-cryotp 維護者的積極響應。直到某天,我收到為 wasi-crypto 編寫測試的邀請,並且受邀成為一名 maintainer 以進一步改進 wasi-crypto。 這真的很令人驚訝——開源不需要你特別的專業,你只需要保持熱情。從簡單的 typo 開始,然後更多地參與並提出一些示例/標準上的建議,社群將永遠歡迎你並幫助你糾正錯誤。

開源協作過程中的一些問題

避免大量無意義的 git log

在專案開始時,由於我對於 wasi-crypto 的瞭解還不夠深入,經常有一些大規模的改動。這些改動有時候毫無相關性,但是粘連在一起,我提交了很多沒有意義的 git commit,這讓 reviewer 感到困惑。從這件事情,我學到的教訓是,在編寫程式碼之前,必須要建立起一個合適的模型並弄清楚如何設計,更好的做法是什麼。否則,我們可能會在後面的階段浪費大量的時間。

編寫足夠的單元測試

在大多數開源專案中,測試是必不可少的。例如,WasmEdge 使用測試覆蓋率作為程式碼質量評估的關鍵指標。

wasi-crypto 有一個定義良好的類 POSIX 介面 [7] ,並且很容易編寫單元測試。但是我前期只寫了幾個簡單的單元測試,顯然還不夠。

因此當我寫了更多的單元測試來達成要求的覆蓋率時,我發現了不少實現上的問題。藉此,我瞭解到單元測試和 TDD(Test-Driven Development)的必要性。

接下來做什麼

對於目前的設計,仍然有很多可以優化的的地方,我會去嘗試重構以獲得更好的效能。

另外,儘管我已經在 host side 做了很多測試,但 client side 的測試也是必不可少的。而且 wasi-crytpo 提案目前並沒有通用的 .wasm 測試。 所以我會將在 WasmEdge 中新增 .wasm 的測試,並且將其推進到 wasi-crypto 提案之中。

總結

因為既要照顧到自己的學業,也要同時完成專案,以之前從未學習過密碼學的基礎,在為期 3 個月的指導期間內我並沒有完成所有任務。但我仍然在努力在 WasmEdge 中實現 wasi-crypto - 我相信在社群的幫助下我將能夠完成這一目標。現在這一工作已經處於收尾工作。

參與開源專案, 尤其是基礎設施工作方面的開發是一種令人興奮的體驗,我希望這篇文章可以幫助那些想要申請類似 LFX MentorShip 專案的新開發者,比如正在進行中的 GSoC 以及即將開始的開源之夏。對於想要參與開源專案並嘗試實現一些有意思的工作的開發者來說,這種社群專案是很好的第一步。

參考資料

[1]

LFX Mentorship: https://lfx.linuxfoundation.org/tools/mentorship/

[2]

merge: https://github.com/WasmEdge/WasmEdge/pull/1282

[3]

wasi-crypto: https://github.com/WebAssembly/wasi-crypto

[4]

wasi-crypto 提案的模組: https://github.com/WebAssembly/wasi-crypto/blob/main/docs/wasi-crypto.md#modules

[5]

OpenSSL: https://github.com/OpenSSL/OpenSSL

[6]

OpenSSL 3.0 的效能並不令人滿意: https://github.com/OpenSSL/OpenSSL/issues/17627

[7]

wasi-crypto 有一個定義良好的類 POSIX 介面: https://github.com/WebAssembly/wasi-crypto/blob/main/witx/codegen/wasi_ephemeral_crypto.txt

關於 WasmEdge

WasmEdge 是輕量級、安全、高效能、實時的軟體容器與執行環境。目前是 CNCF 沙箱專案。WasmEdge 被應用在 SaaS、雲原生,service mesh、邊緣計算、汽車等領域。

 :sparkles: GitHub :https://github.com/WasmEdge/WasmEdge

 :computer: 官網 :https://wasmedge.org/

:man:‍:computer:‍ Discord  群: https://discord.gg/WCXUEBNV

文件:https://wasmedge.org/book/en

點選閱讀原文,檢視 GSoC 專案