2012年7月13日金曜日

Xcode 3.2.6 と Gate Keeper

Mac OS X 10.8 (Mountain Lion)では、ダウンロードされた不正なアプリからシステムを防御するため Gate Keeper という機能が新設された。デフォルトのシステム設定では、Appleから認証されたCode Sign (Mac Developer ID)が付加されていないアプリをダウンロードし起動しようとすると、以下のようアラートが出て起動することができない。


というわけで、Mac OS X 10.8 からはデベロッパーは自分の製品を「Mac Developer ID」で Code Sign しないといけなくなった。


まず、Mac Developer ID をAppleから発行してもらう。Mac Developer ID をどうやって発行してもらうかは、この投稿の本題ではない。Mac Developer IDをまだもっていないひとは以下のページを参照して取得してください。
Developer Certificate Utility - Mac Developer Program - Support - Apple Developer

無事、Mac Developer ID が取得できたら Xcodeで目的の製品をbuildするときに、buildオプション CodeSign にMac Developer ID :Application を指定しbuildすればよい(詳しくは以下を参照)。
Tools Workflow Guide for Mac: Distributing Outside the Mac App Store

以上でめでたく Mac Developer ID でCode Sign された製品ができる(はずな)わけである。(だったら、なんでわざわざこんな投稿をする必要があるのか。)


それがどっこい、そうではないのだ。


Mac Developer ID で Code Sign をするときは、
Xcode 4.3 でないといけないのだ!!

Xcode 4.2 とか Xcode 3.2. でbuild してしまうと、付加される Code Sign の内容が異なり、Mac OS X 10.5あるいは Mac OS 10.6 で動作させたときMac Developer ID がシステムに正しく認識されないという問題が生じる。
Mac Developer ID が認識されなくとも、もともと、Mac OS X 10.5/10.6 では Gate Keeper が動作していないので問題ないではないか思うかもしれないが、そうではない。

たとえば KeyChain に登録されているベーシック認証のページを開こうとすると、初めて開くときだけ 開くかどうか許可ダイアログで聞いてくるが、2回目以降は許可ダイアログなしに直接開くことができる。


Xcode3.2.6やXcode4.2 で Developer ID のCodeSign でbuild したアプリでは、システムに正しく認証されていないので、ベーシック認証のページを開こうとすると、毎回、許可ダイアログが表示されてしまうのだ。このようなアプリのもとでは KeyChain が正しく動作しないのだ。


では、実際に Xcode4.3でbuildされた場合と、Xcode3.2でbuildされたときで、Mac Developer ID のCode Signのどこが違うのか、ターミナルから コマンド「codesign -d -r-」で直接みてみよう。


Xcode3.2.6 でビルドされた foo.app では
$ codesign -d -r- foo.app 
Executable= foo.app/Contents/MacOS/foo
library => identifier "com.apple.Cocoa" and anchor apple or identifier "com.apple.Carbon"  <--  略 --> and anchor apple or identifier "com.apple.Foundation" and anchor apple
# designated => identifier "jp.co.artman21.foo" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = F8FSQZCDV7


緑の字の部分[ designated record ]は、ルート証明書「anchor apple generic」と中間証明書「certificate 1[field.1.2.840.113635.100.6.2.6] 」そして自分のDeveloper IDの証明書「certificate leaf[field.1.2.840.113635.100.6.1.13]が存在しなければならず、Developer IDのの値はF8FSQZCDV7 であると指定している。
ところが、なんと中間証明書 certificate1[field.1.2.840.113635.100.6.2.6]は、Mac OS 10.5/10.6 ではシステムに実装されていないだ。これが foo.app がシステムに正しく認証されない原因だ。

一方、Xcode 4.3 でビルドされた bar.app では

$ codesign -d -r- bar.app  
Executable= foo.app/Contents/MacOS/bar
library => identifier "com.apple.Cocoa" and anchor apple or identifier "com.apple.Carbon"  <--  略 --> and anchor apple or identifier "com.apple.Foundation" and anchor apple
designated => anchor apple generic and identifier "jp.co.artman21.bar" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = F8FSQZCDV7)

緑の字の部分[ designated record ] の内容が Xcode3.2.6 の場合とちがって、中間証明書が「(certificate leaf[field.1.2.840.113635.100.6.1.9] または certificate 1[field.1.2.840.113635.100.6.2.6] 」のどちらかとなっている。中間証明書 のどちらかが存在すればエラーにならない。すなわち、bar.app はMac OS 10.5/10.6 でもシステムに正しく認証される。

でも、Xcode 4.3 に移行できない
ときはどうすればいいのだ 

新製品はともかく、昔からある製品は、過去のしがらみがあって、Mac OS X 10.4 もサポートしなければいけなかったり、ppc もサポートしななればいけなかったりで、Xcode 4.3 に移行できない場合も多い。

そんなときは、とりあえず Xcode 3.2.6 でbuild して、CodeSign の[ designated record ]の部分だけ、以下のように Xcode4.3 の[ designated record ]に入れ替えるとうまくいく。

まず、Xcode4.3 でbuild した bar.app[ designated record ]をもとに foo.app の[ designated record ]を以下のように作成しファイル「fooDR.txt」として保存する。

designated => anchor apple generic and identifier "jp.co.artman21.foo" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = F8FSQZCDV7)

そして、ターミナルから以下のコマンドで

$ codesign -r fooDR.txt -s "Developer ID Application: Artman21 Inc." -f foo.app
foo.app: replacing existing signature

うまくかきかわったかどうかは、

$ codesign -d -r- foo.app 

で調べられる。
ー 以上 ー

<謝辞> 今回の投稿の作成にあたっては、BRadikoの作者 bui さんからいろいろ貴重な示唆をいただきました。また、Daniel Jalkut さんの Red Seater Blog の投稿 Developer ID Gotcha も非常に参考になりました。


0 件のコメント: