Qt for AndroidのQtライブラリを自前でビルドしてかつ、SSLを使用する時のルート証明書を用意する

タイトル長いですね。

Qt for AndroidのソースをダウンロードするとOpenSSLのソースも入ってて自動的にコンパイルされます。
Qt for Androidをソースからビルドして環境を作る」で紹介した全体をビルドするスクリプトのパラメータでOpenSSLのソースをダウンロードするかとかも指定できるようになっています。

なので、基本的な機能の部分で心配はいりません。

ですが、ルート証明書が同梱されてないので自分で用意する必要があります。
Verisignとかから自分でもらってこれば(多分配ってる)OKなのですが手間が大変です。
自分のアプリで使用するアプリが決まったWebサービスしか使わないとかなら簡単ですけども。
なんとか、世間で出回っているブラウザが標準的に添付しているような証明書は一発で入手したいものです。
その辺を含めて説明します。

また、アプリ起動時に読み込む「QtIndustrius-X.jar」へ渡すパラメータに情報を追加する必要があります。


/// まとめ ///
・証明書を入手する
・端末へ証明書をコピーする
・起動時に「QtIndustrius-X.jar」へ証明書の場所を教える

以上の内容でSSLが使えるようになります。
おそらくですが、ブラウザでこのサイトは信頼できませんけどどおする?ってダイアログが出てくる状態になると処理が停止するのだと思われます。


/// パラメータの修正 ///
証明書の場所を指定します。
修正するファイルと場所と内容は以下の感じです。
注意
プロジェクトの「実行時の設定」でAndroidのバージョンを変更すると修正内容が消えるかもしれません。

ファイル:<PROJECT_DIR>/android/src/org/kde/necessitas/origo/QtActivity.java
330行目あたりで「ENVIRONMENT_VARIABLES_KEY」をpushStringしてるところがあるので修正します。
loaderParams.putString(ENVIRONMENT_VARIABLES_KEY
        ,"QML_IMPORT_PATH=/data/local/qt/imports"
        + "\tQT_PLUGIN_PATH=/data/local/qt/plugins"
        + "\tMINISTRO_SSL_CERTS_PATH=/data/local/qt/ssl");



/// ルート証明書の入手 ///
opensslのパッケージに入ってるんじゃないか疑惑で調べたら 「The OpenSSL project does not (any longer) include root CA certificates.」と書かれてて「How can I set up a bundle of commercial root CA certificates?」ってFAQに誘導されました。
で、mozillaのcvsのリポジトリに含まれる情報を引っ張ってきて変換するplスクリプトがあるからそれ使ってねって事でした。
解説ページはこちら(FAQからリンクされてる)「updating ca-bundle.crt」 ただ、ここに記載されてるスクリプトそのものではうまく使えません。
確認できた範囲では使用できるファイル形式は「*.der」だけでした。
なのでスクリプト1発で複数の「*.der」が作成できるようにしました。
あと端末に転送するスクリプトも用意しました。
どちらも最後に記載。

手順
 1.後述のサンプルスクリプトをどこかに保存
 2.実行権限を与える
 3.der形式にDLして変換
  「x509_X.der」なファイルがたくさんできます。
> getcertdata.pl
 4.端末へ転送
> ls *.der | pushfiles.sh


/// cvsからデータを取得してderに変換する「getcertdata.pl」のサンプル ///
#!/usr/bin/perl -w
#
# Used to regenerate ca-bundle.crt from the Mozilla certdata.txt.
# Run as ./thisfile.pl
#

my $cvsroot = ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot';
my $certdata = 'mozilla/security/nss/lib/ckfw/builtins/certdata.txt';

open(IN, "cvs -d $cvsroot co -p $certdata|")
    || die "could not check out certdata.txt";

my $incert = 0;
my $counter = 0;

print<<EOH;
# This is a bundle of X.509 certificates of public Certificate
# Authorities.  It was generated from the Mozilla root CA list.
#
# Source: $certdata
#
EOH

while (<IN>) {
    if (/^CKA_VALUE MULTILINE_OCTAL/) {
        $incert = 1;
	$counter = $counter + 1;
        open(OUT, "|openssl x509 -text -inform DER|openssl x509 -inform PEM -outform DER -out x509_$counter.der")
            || die "could not pipe to openssl x509";
    } elsif (/^END/ && $incert) {
        close(OUT);
        $incert = 0;
        print ".";
    } elsif ($incert) {
        my @bs = split(/\\/);
        foreach my $b (@bs) {
            chomp $b;
            printf(OUT "%c", oct($b)) unless $b eq '';
        }
    } elsif (/^CVS_ID.*Revision: ([^ ]*).*/) {
        print "# Generated from certdata.txt RCS revision $1\n#\n";
    }
}
print "\n";

/// ファイルを端末へ転送する「pushfiles.sh」のサンプル ///
adbへのパスは通して置いてください。
#!/bin/bash -x
# lsの結果をパイプで渡してadb pushするスクリプト

while read DATA
do
adb push $DATA /data/local/qt/ssl/$DATA
done