前回は MSYS2 で MinGW-w64 の環境を入れるところで終わってしまい,(その後仕事が忙しくなったこともあり)そのまま投げっぱなしの状態だったが,とりあえず gcc の動作確認まで終わらせておく。そうそう, pacman -Syu
で最新版に更新するのを忘れないように。
今回のターゲットは pgpdump。
pgpdump は OpenPGP パケットを可視化してくれる(ただし復号は行わない)便利ツールだ。ソースコードのみの提供でバイナリは提供されてない(ただし Linux ディストリビュータによってはバイナリを提供している場合がある)。ビルドすれば Windows 環境でも動作可能。
ソースコードは GitHub で提供されているので,あらかじめ git clone
で取得しておく。
Win32 版のビルド
まずは mingw32_shell.bat
を起動して Win32 の環境を立ち上げる(mingw32_shell.bat
って何? ってかたは前回の記事を参照あれ)。
まずは configure
を走らせて環境を確認する。
$ ./configure
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.exe
checking for suffix of executables... .exe
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for inflate in -lz... yes
checking for BZ2_bzBuffToBuffDecompress in -lbz2... yes
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for unistd.h... (cached) yes
checking sys/time.h usability... yes
checking sys/time.h presence... yes
checking for sys/time.h... yes
checking unixlib/local.h usability... no
checking unixlib/local.h presence... no
checking for unixlib/local.h... no
checking whether time.h and sys/time.h may both be included... yes
checking whether struct tm is in sys/time.h or time.h... time.h
checking for struct tm.tm_zone... no
checking whether tzname is declared... yes
checking for tzname... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: WARNING: 'Makefile.in' seems to ignore the --datarootdir setting
config.status: creating config.h
特にエラーもなく終了。
pgpdump では,パケット内の圧縮データを扱うため, libz
および libbz2
が必要となる。昔の MinGW32 ではこれらのライブラリを個別にインストールする必要があったが,最近のはあらかじめ開発環境に入ってるので助かる。
これで生成される Makefile
は以下のとおり。
prefix = /usr/local
exec_prefix = ${prefix}
bindir = ${exec_prefix}/bin
mandir = ${prefix}/share/man
LIBS = -lbz2 -lz
CFLAGS = -g -O2 -O -Wall
LDFLAGS =
VERSION = `git tag | tail -1 | sed -e 's/v//'`
RM = rm -f
INSTALL = install
INCS = pgpdump.h
SRCS = pgpdump.c types.c tagfuncs.c packet.c subfunc.c signature.c keys.c \
buffer.c uatfunc.c
OBJS = pgpdump.o types.o tagfuncs.o packet.o subfunc.o signature.o keys.o \
buffer.o uatfunc.o
PROG = pgpdump
MAN = pgpdump.1
CNF = config.h config.status config.cache config.log
MKF = Makefile
.c.o:
$(CC) -c $(CFLAGS) $<
all: $(PROG)
$(PROG): $(OBJS)
$(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBS) $(LDFLAGS)
clean:
$(RM) $(OBJS) $(PROG)
distclean:
$(RM) $(OBJS) $(PROG) $(CNF) $(MKF)
install: all
$(INSTALL) -d $(DESTDIR)$(bindir)
$(INSTALL) -cp -pm755 $(PROG) $(DESTDIR)$(bindir)
$(INSTALL) -d $(DESTDIR)$(mandir)/man1
$(INSTALL) -cp -pm644 $(MAN) $(DESTDIR)$(mandir)/man1
archive:
git archive master -o ~/pgpdump-$(VERSION).tar --prefix=pgpdump-$(VERSION)/
gzip ~/pgpdump-$(VERSION).tar
この時点での問題は3つ。
-
prefix
が/usr/local
になっている。このままでもエラーにはならないが,今回は Win32 版と Win64 版を分けたいので/mingw32
としたい -
CC
が明示されないのでこのままmingw32-make
を走らせるとcc
コマンドを呼びだそうとする - リンク時のオプション(
LDFLAGS
)に-static
がないため,このままビルドすると DLL に依存する構成になってしまう
このうち2番目の問題は少し厄介だが
- Malefile.in に
CC = @CC@
の記述を追加してconfigure
しなおす -
mingw32-make
起動時の引数にCC=gcc
を追加する - 環境変数に
CC=gcc
を追加する
のいずれかで対処できる。
1番目と3番目は configure
コマンドに情報を渡せばよい。
$ ./configure --prefix=/mingw32 LDFLAGS=-static
では,作りなおした Makefile
でビルドする。
$ mingw32-make
gcc -c -g -O2 -O -Wall pgpdump.c
gcc -c -g -O2 -O -Wall types.c
gcc -c -g -O2 -O -Wall tagfuncs.c
gcc -c -g -O2 -O -Wall packet.c
gcc -c -g -O2 -O -Wall subfunc.c
gcc -c -g -O2 -O -Wall signature.c
gcc -c -g -O2 -O -Wall keys.c
gcc -c -g -O2 -O -Wall buffer.c
gcc -c -g -O2 -O -Wall uatfunc.c
gcc -g -O2 -O -Wall -o pgpdump pgpdump.o types.o tagfuncs.o packet.o subfunc.o signature.o keys.o buffer.o uatfunc.o -lbz2 -lz -static
$ strip pgpdump.exe
Win64 版のビルド
次は Win64 版。 mingw64_shell.bat
を起動して Win64 の環境を立ち上げる。 Win32 版で要領は分かったので一気に終わらせてしまおう。
$ ./configure --prefix=/mingw64 LDFLAGS=-static
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.exe
checking for suffix of executables... .exe
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for inflate in -lz... yes
checking for BZ2_bzBuffToBuffDecompress in -lbz2... yes
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for unistd.h... (cached) yes
checking sys/time.h usability... yes
checking sys/time.h presence... yes
checking for sys/time.h... yes
checking unixlib/local.h usability... no
checking unixlib/local.h presence... no
checking for unixlib/local.h... no
checking whether time.h and sys/time.h may both be included... yes
checking whether struct tm is in sys/time.h or time.h... time.h
checking for struct tm.tm_zone... no
checking whether tzname is declared... yes
checking for tzname... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: WARNING: 'Makefile.in' seems to ignore the --datarootdir setting
config.status: creating config.h
$ mingw32-make.exe
gcc -c -g -O2 -O -Wall pgpdump.c
gcc -c -g -O2 -O -Wall types.c
gcc -c -g -O2 -O -Wall tagfuncs.c
gcc -c -g -O2 -O -Wall packet.c
gcc -c -g -O2 -O -Wall subfunc.c
gcc -c -g -O2 -O -Wall signature.c
gcc -c -g -O2 -O -Wall keys.c
gcc -c -g -O2 -O -Wall buffer.c
gcc -c -g -O2 -O -Wall uatfunc.c
gcc -g -O2 -O -Wall -o pgpdump pgpdump.o types.o tagfuncs.o packet.o subfunc.o signature.o keys.o buffer.o uatfunc.o -lbz2 -lz -static
$ strip pgpdump.exe
動作確認
pgpdump の動作確認のために JPCERT/CC の公開鍵をダンプしてみる。 Windows 環境で問題なく動くことを確かめるためにコマンドプロンプトから起動する。
C:>pgpdump info-0x69ECE048.asc
Old: Public Key Packet(tag 6)(269 bytes)
Ver 4 - new
Public key creation time - Tue Jun 02 14:43:57 東京 (標準時) 2009
Pub alg - RSA Encrypt or Sign(pub 1)
RSA n(2048 bits) - ...
RSA e(17 bits) - ...
Old: User ID Packet(tag 13)(29 bytes)
User ID - JPCERT/CC <info@jpcert.or.jp>
Old: Signature Packet(tag 2)(316 bytes)
Ver 4 - new
Sig type - Generic certification of a User ID and Public Key packet(0x10).
Pub alg - RSA Encrypt or Sign(pub 1)
Hash alg - SHA1(hash 2)
Hashed Sub: preferred symmetric algorithms(sub 11)(3 bytes)
Sym alg - AES with 256-bit key(sym 9)
Sym alg - CAST5(sym 3)
Sym alg - Triple-DES(sym 2)
Hashed Sub: key server preferences(sub 23)(4 bytes)
Flag - No-modify
Hashed Sub: key flags(sub 27)(4 bytes)
Flag - This key may be used to certify other keys
Flag - This key may be used to sign data
Flag - This key may be used to encrypt communications
Flag - This key may be used to encrypt storage
Flag - The private component of this key may be in the possession of more than one person
Hashed Sub: preferred compression algorithms(sub 22)(2 bytes)
Comp alg - ZLIB <RFC1950>(comp 2)
Comp alg - ZIP <RFC1951>(comp 1)
Hashed Sub: features(sub 30)(4 bytes)
Flag - Modification detection (packets 18 and 19)
Hashed Sub: preferred hash algorithms(sub 21)(3 bytes)
Hash alg - SHA256(hash 8)
Hash alg - SHA384(hash 9)
Hash alg - SHA512(hash 10)
Hashed Sub: signature creation time(sub 2)(4 bytes)
Time - Tue Jun 16 12:51:22 東京 (標準時) 2009
Sub: issuer key ID(sub 16)(8 bytes)
Key ID - 0x317D97A469ECE048
Hash left 2 bytes - cd 79
RSA m^d mod n(2047 bits) - ...
-> PKCS-1
Old: Signature Packet(tag 2)(277 bytes)
Ver 3 - old
Hash material(5 bytes):
Sig type - Generic certification of a User ID and Public Key packet(0x10).
Creation time - Tue Jun 02 14:43:57 東京 (標準時) 2009
Key ID - 0xE7734FA60C7BDE12
Pub alg - RSA Encrypt or Sign(pub 1)
Hash alg - SHA1(hash 2)
Hash left 2 bytes - e9 53
RSA m^d mod n(2047 bits) - ...
-> PKCS-1
Old: Signature Packet(tag 2)(156 bytes)
Ver 4 - new
Sig type - Generic certification of a User ID and Public Key packet(0x10).
Pub alg - RSA Encrypt or Sign(pub 1)
Hash alg - SHA1(hash 2)
Hashed Sub: signature creation time(sub 2)(4 bytes)
Time - Mon Jun 15 14:51:27 東京 (標準時) 2009
Sub: issuer key ID(sub 16)(8 bytes)
Key ID - 0x8C756B2E2C94D4ED
Hash left 2 bytes - 35 fd
RSA m^d mod n(1022 bits) - ...
-> PKCS-1
Old: Public Subkey Packet(tag 14)(269 bytes)
Ver 4 - new
Public key creation time - Tue Jun 02 14:43:57 東京 (標準時) 2009
Pub alg - RSA Encrypt or Sign(pub 1)
RSA n(2048 bits) - ...
RSA e(17 bits) - ...
Old: Signature Packet(tag 2)(577 bytes)
Ver 4 - new
Sig type - Subkey Binding Signature(0x18).
Pub alg - RSA Encrypt or Sign(pub 1)
Hash alg - SHA1(hash 2)
Hashed Sub: signature creation time(sub 2)(4 bytes)
Time - Tue Jun 02 14:43:58 東京 (標準時) 2009
Hashed Sub: key flags(sub 27)(4 bytes)
Flag - This key may be used to encrypt communications
Flag - This key may be used to encrypt storage
Hashed Sub: embedded signature(sub 32)(284 bytes)
Ver 4 - new
Sig type - Primary Key Binding Signature(0x19).
Pub alg - RSA Encrypt or Sign(pub 1)
Hash alg - SHA256(hash 8)
Hashed Sub: signature creation time(sub 2)(4 bytes)
Time - Tue Jun 02 14:43:57 東京 (標準時) 2009
Sub: issuer key ID(sub 16)(8 bytes)
Key ID - 0x09D704B753BA1622
Hash left 2 bytes - 71 2d
RSA m^d mod n(2048 bits) - ...
-> PKCS-1
Sub: issuer key ID(sub 16)(8 bytes)
Key ID - 0x317D97A469ECE048
Hash left 2 bytes - 1d e2
RSA m^d mod n(2046 bits) - ...
-> PKCS-1
うむ,問題ないようだな。ちなみに Windows バイナリはうちのサイトでも公開しているのでご自由にどうぞ。