PHP はいろいろ難しい

わけあって,以前 php4 で自分で作った Web サイトを改造することに.php正規表現がよく分からなかったり,大きな数の計算とかできなくて,困ったのでメモ.

複数行にわたる文字列から,正規表現にマッチする部分を抜き出したい.具体的にやりたいのは,PKI証明書の CSR を openssl コマンドを使って人が読める形式で表示した内容の中から,特定の文字列が含まれているかどうかの判定.

% openssl req -noout -text -nameopt esc_ctrl,esc_msb,sep_multiline,space_eq,align,sname -in HOGEHOGE.CSR

Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject:
            C          = JP
            L          = ********
            O          = ********
            OU         = ********
            CN         = www.****.****.**.**
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (1024 bit)
                Modulus (1024 bit):
                    00:b1:03:ca:5d:e9:4f:54:ad:3e:e3:de:d9:b8:c4:
                    :
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha1WithRSAEncryption
        13:24:94:40:98:ac:df:d5:25:52:91:07:5a:73:e2:9c:9b:64:
        :

のように表示された内容から,L や O や OU の ***** の部分が適切に登録されているかチェックしたい.複数行の文字列から正規表現で特定の部分を抜き出すには preg_match_all という関数を使えば良いようだが,この関数では行頭や行末を表わす ^ や $ が使えないようだ.つまり,下記の例で,前者は機能するが後者は機能しない.全ての行を一つに繋いでしまって処理しているのだろうか!?

preg_match_all('/\s*L\s*=\s*(.+)/', $csrinfo, $match);
preg_match_all('/^\s*L\s*=\s*(.+)$/', $csrinfo, $match);

mb_ereg を使えば問題ないんだろうか.PHPは何かしようとする度に,各関数で何ができて何ができないかがはっきり分からなくて,いつも試行錯誤を繰り返すことになってしまう.調べ方がよくないだけなんだろうか….

もう一つの大きな数の計算は,同じく PKI 証明書がらみで,シリアル番号の扱い.
扱かっているPKI証明書に,16進数で書くと20〜30桁くらいのシリアル番号が付くのだが,これを10進数に直したい.openssl で普通に表示すると16進数で表示してしまう.
PHPはデフォルトでは CPU の扱える整数の範囲くらいしかサポートしていない模様.
PHPGNU MP library PHP: gmp_init - Manual を使うと解決できるようだが,これ,PHPコンパイル時に enable にしてコンパイルしていないと使えない.私が使おうとした環境では使えなかった.
GMP だけ追加できれば嬉しいのだが,PHPコンパイルやり直しになると,古いシステムを壊さずに移行できるか自信が無いので別の方法を探してみよう…