第26章 署名付きモジュールとホットコードスワップ
この章の目的
本章の終わりまでに、あなたは完成したプログラムに起こり得る二つのこと、すなわちその出所が証明できるように署名できることと、実行中に新しいコードへと差し替えられることを理解します。
署名、プログラムの出所を証明する
バイトコードファイルは移動します。それは一つのマシンでコンパイルされ、遠く離れた別のマシンで実行され得ます。それを実行するマシンには一つの問いがあります。これは期待される作者による、改変されていない本物のプログラムか、というものです。署名がその問いに答えます。
意図された用途は多者間配信です。スタジオがプログラムをコンパイルし、スタジオのみが保持する秘密鍵でそれに署名します。現場のデバイスは対応する公開鍵を保持し、その鍵に対して署名が検証されないプログラムの実行を拒否します。
プログラムを署名付きとして印付けする
プログラムはそのエントリ関数に signed 修飾子を付けてオプトインします。
signed fn main() -> Word {
21 + 21
}
signed は、そのプログラムがロードされる前に有効な署名を持たなければならないものとして印付けします。これはエントリ関数においてのみ許され、三種類の関数のいずれにおいても機能します。すなわち signed fn main、signed yield main、signed loop main です。
署名のフロー
まず、鍵ペアを作成します。
keleusma keygen --seed studio.seed --public studio.pub
これは二つのファイルを書き出します。studio.seed は秘密鍵であり、スタジオが守る秘密です。studio.pub は公開鍵であり、検証を必要とする誰にでも渡されます。鍵は長命の秘密であるため、ツールは既存の鍵ファイルの上書きを拒否します。
上記のプログラムを app.kel として保存し、それをコンパイルして署名します。
keleusma compile app.kel --signing-key studio.seed -o app.kel.bin
署名付きバイトコードを、検証に用いる公開鍵を供給して実行します。
keleusma run app.kel.bin --verifying-key studio.pub
出力は 42 です。ランタイムは studio.pub に対して署名を検査し、有効であることを確認して、プログラムを実行しました。
鍵なしで実行すると、プログラムはロードされません。
error: verify_module_signature: InvalidSignature
signed プログラムは、その署名が検証されない限り実行されません。それは封をされ署名された楽譜であり、その封を信頼する演奏者です。署名方式は標準的で十分に信頼された Ed25519 です。
暗号化、転送中にプログラムを機密に保つ
署名付きバイトコード成果物は完全性の保証を持ちますが、その内容はそれを傍受する誰にとっても依然として読み取り可能です。機密性も必要とする配備のために、バイトコードはコンパイル時に特定の受信者宛てに暗号化できます。
受信者は暗号化鍵ペア(X25519)を生成し、その公開側を成果物を生成する者に渡します。
keleusma keygen --kind encryption --seed device.seed --public device.pub
コンパイルステップは署名鍵と受信者の公開暗号化鍵の両方を取ります。
keleusma compile app.kel \
--signing-key studio.seed \
--encryption-key device.pub \
-o app.kel.bin
受信者は検証鍵と自身の復号鍵の両方を用いて成果物を実行します。
keleusma run app.kel.bin \
--verifying-key studio.pub \
--decryption-key device.seed
暗号化は署名の上に層として重ねられます。署名は暗号化された本体を覆うため、敵対者は署名を無効にすることなく暗号化を剥がして平文に置き換えることはできません。暗号化は X25519 鍵交換と AES-256-GCM 認証付き暗号化を組み合わせて用います。
SECURITY_POLICY.md のリファレンスは、両方のゲートを配備ポリシーとして記述します。二つのポリシーは独立しており、いずれもプラットフォーム慣習的なディレクトリ内の登録された鍵ストアを通じて有効化できます。
ホットコードスワップ、実行中にプログラムを変更する
完成したプログラムに起こり得る二つ目のことは、実行中に新しいプログラムへと置き換えられることです。
第17章の RESET を思い出してください。すなわち loop 関数の各サイクルの先頭にある境界です。RESET はまた、プログラムを差し替えられる瞬間でもあります。実行中のプログラムがサイクルを終えます。RESET 境界において、ホストは古いコードの代わりに新しいコードをインストールします。次のサイクルは新しいプログラムを実行します。
対話は中断されません。スワップをまたいで同一のままでなければならない唯一のものは、第16章の対話、すなわち各 yield で交換される合意された型の対です。新しいプログラムが同じ対話を話す限り、ホストは途切れることなくそれと話し続けます。これは、バンドを止めることなく、次の拍頭で新しい編曲へと差し替えることです。
プログラムは自身を差し替えません。ホストが RESET 境界でスワップを実行します。第VIII部はそれを直接示します。ピアノロールにおいて、キーを押すと実行中の曲が別の曲へと差し替えられ、それがホットコードスワップです。
この章のまとめ
- バイトコードファイルは署名できるため、実行するマシンはその出所を証明できます。
- エントリ関数の
signed修飾子は、プログラムを有効な署名を必要とするものとして印付けします。 - フローは
keleusma keygen、次いでkeleusma compile --signing-key、次いでkeleusma run --verifying-keyです。 - 署名付きバイトコード成果物は、さらに
--encryption-keyで特定の受信者宛てに暗号化できます。受信者は--decryption-keyでそれを実行します。 - 厳格モードの配備ポリシーは
SECURITY_POLICY.mdにあります。 - ホットコードスワップは RESET 境界で実行中のプログラムを新しいコードへと置き換え、対話はスワップをまたいで同一のままでなければなりません。
これで第VII部が完了します。プログラムは書かれ、コンパイルされ、配布可能になりました。第VIII部は実際のプログラムを稼働させ、それを聞こえるようにします。