ククログ

株式会社クリアコード > ククログ > Firefox用アドオンのデジタル署名の自動化

Firefox用アドオンのデジタル署名の自動化

このククログでも既に何度か触れていますが、Firefox 44以降ではアドオンのインストール用パッケージ(XPIパッケージ)について、Mozillaによるデジタル署名が施されていない物はインストールできないようになります。

この変更は、一般の利用者にとっては使い勝手の面であまり変化はありませんが、アドオンを開発・公開する側にとっては大きな影響があります。 その1つとして、アドオンをMozilla Add-ons以外の方法で頒布する場合に必要なステップが1つ増えるという事が挙げられます。

というのも、Mozillaによるデジタル署名が施された状態のXPIパッケージを入手するには、Mozilla Add-onsのWebサイトにXPIパッケージをアップロードし、場合によってはエディターによる承認を得た上で、署名済みのXPIパッケージを改めてダウンロードしなくてはなりません。 この作業自体は簡単なのですが、「Webサイトを訪問して、ログインして、フォームを使ってファイルを送信して、署名済みのファイルをダウンロードする」という手作業が必要でした。 このような定型的な作業を毎回人の手で行うのは非効率であるのみならず、ミスの発生原因になりうるので、可能であれば自動化したいところです。

このような状況を受けて、Mozilla Add-onsのWebサイト側にSigning APIという物が実装され、上記の作業のある程度の自動化が可能になりました。

上記リンク先の記事では具体的な手順が案内されていますが、「このようにすればコマンド一発で可能」というものではないため、自分でやるには若干ハードルが高いです。 そのため、アドオンSDKに含まれるコマンドラインツールのjpmに署名APIを使ってXPIに署名するためのサブコマンドが追加されました。 SDKを使ってアドオンを開発する場合は、これを使うことで署名の申請までを自動化することができます。

それとは別のものとして、SDKを使わないでアドオンを開発する場合向けに、XPIパッケージの署名申請を支援するBashスクリプトを作成しました。 この記事では、jpmではなくこのスクリプトを用いてXPIパッケージへのデジタル署名を申請する手順を解説します。

※2015年12月21日追記:上記のjpmコマンドは、SDKを導入しなくてもjpmというNPMパッケージ単体の導入により利用可能になるとのことです。 よって、基本的にはアドオンのXPIパッケージへの署名にはjpmのサブコマンドsignを使うことをお薦めします。 以下で紹介するスクリプトは、jpm signではカバーできない範囲のニーズを満たす必要がある場合にのみ使うようにして下さい。

スクリプトの動作準備

署名申請の支援スクリプトは、Ubuntu 14.04LTS上で動作を確認済みです。 スクリプトそのものはBashスクリプトですが、APIへのアクセスにcurlを使用します。 また、Node.js用のJWTライブラリを使うため、nodejsコマンドおよびnpmコマンドが利用可能になっている必要があります。

以下の説明では、例としてUbuntuでの操作手順を示します。 他の環境で使う場合は、環境依存の記述を適宜読み替えて下さい。

署名申請にの支援スクリプトは複数に分かれているため、スクリプトは単体でダウンロードするのではなく、スクリプト群一式を作業ディレクトリに保存するようにして下さい。 例えば以下の要領です。

$ mkdir -p /tmp/signxpi
$ cd /tmp/signxpi
$ git clone https://github.com/piroor/makexpi.git

APIキーの生成

署名の申請を自動化するにあたっては、JSON Web Token(JWT)用のAPIキーが必要です。 これは、Mozilla Add-onsの開発者センターのAPIキー管理画面で生成できます。 本記事執筆時点では用途別の複数APIキーの使い分けは考慮されていないようで、生成できるAPIキーは一種類のみとなっています。 既にAPIキーを生成済みの場合、APIキーを生成し直すと古いAPIキーは無効になる模様ですのでご注意下さい。

APIキーは、「JWT発行者(JWT issuer)」と「JWT秘密鍵(JWT secret)」の2つの文字列のペアとして生成されます。 APIキーを準備できたら、次のステップに進みます。

署名申請の送信

署名申請を行うスクリプトは、リポジトリ内にあるsign_xpi.shです。 以下のようにオプションを指定して実行します。

$ makexpi/sign_xpi.sh -p "XPIファイルのパス" \
                      -o "署名済みファイルの保存先ディレクトリのパス" \
                      -k "JWT発行者" \
                      -s "JWT秘密鍵" \
                      -d

例えば、XPIファイルがカレントディレクトリにある「myaddon.xpi」で、署名済みのファイルを同じくカレントディレクトリに保存するのであれば、以下のようになります。

$ JWT_ISSUER=user:xxxxxx:xxx
$ JWT_SECRET=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
$ makexpi/sign_xpi.sh -p "./myaddon.xpi" \
                      -o "./" \
                      -k "$JWT_ISSUER" \
                      -s "$JWT_SECRET" \
                      -d
The file will be uploaded for signing.

The file will be uploaded for signing.という出力を得られたでしょうか? 実は、この時点ではまだファイルは送信されていません。 -dはいわゆるdry runを行うためのオプションで、このオプションが指定された場合、実際のファイル送信は行われないようになっています。 dry runに成功したら、改めて-dオプションを外し、実際にファイルを署名申請します。 (慣れてきたら、dry runでの確認はスキップして構いません。)

$ makexpi/sign_xpi.sh -p "./myaddon.xpi" \
                      -o "./" \
                      -k "$JWT_ISSUER" \
                      -s "$JWT_SECRET"

申請に成功し、署名済みのファイルが得られた場合、署名済みのファイルがカレントディレクトリに保存されます。

なお、署名APIは、「アドオンの新しいバージョンをアップロードするためのAPI」という形をとっているため、この時点で、署名申請を行ったバージョンは当該アドオンの新バージョンとして登録されることになります。 この時、当該バージョンは詳細情報が入力されていない状態になりますので、公開用の(listedな)アドオンの場合は、別途バージョン一覧から詳細情報を入力する必要があります。

後から署名済みのファイルをダウンロードする

レビュー待ちなどの理由で署名済みのファイルをすぐには入手できなかった場合、Not signed yet. You must retry downloading after signed.というメッセージが表示されてエラーとなります。 この場合、レビューが完了して署名済みファイルをダウンロードできるようになった段階で再挑戦する必要があります。 また、署名済みのファイルを紛失してしまった場合にも、再度ダウンロードしなくてはなりません。

このようなケースでは、download_signed_xpi.shという別のスクリプトを使います。

$ makexpi/download_signed_xpi.sh -i "アドオンの内部ID" \
                                 -v "署名済みファイルをダウンロードするバージョン" \
                                 -o "署名済みファイルの保存先ディレクトリのパス" \
                                 -k "JWT発行者" \
                                 -s "JWT秘密鍵"

例えば、アドオンのIDが「myaddon@example.com」で、「バージョン1.5」の署名済みのファイルをカレントディレクトリに保存するのであれば、以下のようになります。

$ JWT_ISSUER=user:xxxxxx:xxx
$ JWT_SECRET=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
$ makexpi/download_signed_xpi.sh -i "myaddon@example.com" \
                                 -v "1.5" \
                                 -o "./" \
                                 -k "$JWT_ISSUER" \
                                 -s "$JWT_SECRET"

まとめ

De-coupling Reviews from Signing Unlisted Add-ons | Mozilla Add-ons Blog私的翻訳)によると、非公開(unlisted)のアドオンについては、人力のレビューを経ずに即座に署名済みのXPIパッケージを入手できるようになっている模様です。

ただ、人力レビューが必要な場合であっても、この署名APIによって「新バージョンリリース時のファイルのアップロード」までは自動化できます。 署名義務化の発表以降、アドオンの開発や提供、検証にあたって手間が増えた部分はいくつかありますが、こういった部分でささやかながらリリースの自動化をしやすくなってくれたことは、素直に有り難いことだと言えるでしょう。