AndroidのCIパイプラインでAndroid StudioのJDKを使う
AndroidのCIパイプラインでgradleタスク実行する場合にはJDKが必要になります。
Android Studio経由でgradleタスク実行する場合はAndroid Studioに内包されたJDKが用いられます。
一方でmacOSのTerminalでプロジェクト作成時にimportされるgralde wrapper経由でgradleタスクを実行すると、利用するJDKはmacOSのものになります。
例えばCIパイプラインをmacOSのCI Runnerで実行する場合、何も設定しないとmacOS側のJDKが用いられてします。macOS側ではJava14、15を入れていた場合にはAndroid Studioで実行した結果と変わってしまう可能性があります。
例えばmacOSのTerminalでの./gradlew --version
の結果とAndroid Studio側での実行結果が微妙に異なっています。
# macOSでの./gradlew --versionの結果 $ ./gradlew --version ------------------------------------------------------------ Gradle 6.7.1 ------------------------------------------------------------ Build time: 2020-11-16 17:09:24 UTC Revision: 2972ff02f3210d2ceed2f1ea880f026acfbab5c0 Kotlin: 1.3.72 Groovy: 2.5.12 Ant: Apache Ant(TM) version 1.10.8 compiled on May 10 2020 JVM: 11.0.10 (Oracle Corporation 11.0.10+9) OS: Mac OS X 11.3.1 x86_64 # Android StudioのJREでの./gradlew --versionの結果 $ ./gradlew --version ------------------------------------------------------------ Gradle 6.7.1 ------------------------------------------------------------ Build time: 2020-11-16 17:09:24 UTC Revision: 2972ff02f3210d2ceed2f1ea880f026acfbab5c0 Kotlin: 1.3.72 Groovy: 2.5.12 Ant: Apache Ant(TM) version 1.10.8 compiled on May 10 2020 JVM: 11.0.8 (JetBrains s.r.o 11.0.8+10-b944.6916264) OS: Mac OS X 10.16 x86_64
ちなみにAndroid Studio 4.2からBundleされるJDKが11系に変わったようです。
build.gradleで利用するバージョンをきちんと指定していれば問題ないのですが、気になる場合はAndroid StudioのJDKでgralde タスクを実行するようにしておきましょう。
具体的にはgradleタスクを実行する前にJAVA_HOMEの設定をAndroid Studioが内包しているものに変更すればよいです。
例えばCIパイプラインを実行するシェルスクリプトの最初にJAVA_HOMEを入れ替えるようにするとよいでしょう。
macOSの場合、Android StudioのJDKは/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home
にあります。
!/bin/sh set -e set -x ... JAVA_HOME="/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home" ./gradlew --version ./gradlew lint ./gradlew test ./gradlew connectedAndroidTest
iOSアプリ開発を自習したい人が見るとよさそうなコンテンツをまとめてみた
以前Androidの学習コンテンツについてまとめましたが、今回はそのiOS版について少し見通しがたったのでまとめてみることにします。
macOS端末とiOS端末を用意する
iOSのアプリ開発はXcodeという開発キットを利用します。このXcodeはmacOSでしか動作しないため、iOSアプリ開発ではmacOS端末が必須になります。WindowsやLinuxではXcodeは利用できません。実際に実機端末で動作させたい場合はiOS端末も用意しましょう。
Apple Developer Programへの加入を検討する
手元のiOS端末でデバッグをするだけでなく、TestFlightを利用したり実際にAppStoreでアプリをリリースしたい場合はApple Devleloper Programに加入しましょう。個人向けライセンスであれば税込み12980円で1年単位での更新が必要です。
なお1台のみの実機デバッグだったりApp Storeで公開されているXcodeの利用のみであればApple Developer Programに加入しなくてもよいです。
Apple Developer Program - Apple Developer
メンバーシップの選択 - サポート - Apple Developer
公式のチュートリアルをやる
Androidと同様にiOSも基本的には公式の情報をキャッチアップするのがよいでしょう。
チュートリアルについては以下のリンクにSwiftUI版とUIKit版が公開されています。
https://developer.apple.com/tutorials/app-dev-training
一番最初のXcodeの操作はここを見るとよいでしょう。
https://developer.apple.com/documentation/xcode/creating_an_xcode_project_for_an_app
昨年のWWDCでSwiftUIがリリースされたときに公開されたSwiftUIのチュートリアルもあるので、SwiftUIを使う場合は余裕があれば見ておくとよいでしょう。
https://developer.apple.com/tutorials/swiftui
WWDCの動画を見る
Appleは毎年の開発者向けイベントであるWWDCの動画をアーカイブとして公開しています。新しい技術やアップデート情報はこちらからキャッチアップするとよいでしょう。
Design and Development Videos - Apple Developer
動画内で触れているサンプルコードについても公開されています。
Sample Code - WWDC20 - Apple Developer
WWDC 2020ではSwiftUIのサンプルコードとしてFrutaが公開されていました。
https://developer.apple.com/documentation/swiftui/fruta_building_a_feature-rich_app_with_swiftui
役立つ公式のリンク集
Appleの公式ドキュメントはなかなかたどり着くのが手間なのでせめて入り口だけでもブックマークしておくとよいでしょう。
- Apple Developer Documentation
- Xcode
- Swift
- TestFlight
- App Store Connect
- Help
- App Store Review Guidelines
- Identity Guidelines
- Support Articles
iBooksで公開されている情報
Apple EducationとしてiBooksで学習用のコンテンツも公開されています。書籍なので情報は少し古めです。
books.apple.com非公式の参考となるコンテンツ
スタンフォードの講義やUdemyの動画で学習するのもよいでしょう。mixiのコンテンツが長らく有名でしたがメンテナンスされてないようです。最近ゆめみさんがコンテツを公開したのでそちらも見てみるとよさそうです。
Xcodeのバージョンと各OSの対応表はここを見るとひと目で分かるのでよく使っています。
mixi groupの2021年新卒研修の資料が公開(2021/5/14追記)
mixiのSwiftUIの新卒向け研修のコンテンツが公開されていました。 SwiftUIの説明からCombineやXCTest、MVVMアーキテクチャについても触れられていてよいと思いました。
Peaksや技術書展の本
Peaksで公開されている設計本やテストの本も参考になるので、興味がある方は手元においておくとよいでしょう。紹介リンク付きのツイートを載せておきます。
設計を知る、パターンを知る、導入する「iOSアプリ設計パターン入門」が一般販売開始! https://t.co/yP18FyigjP #iOS_architecture
— takamii228 (@takamii228) 2021年4月25日
iOSテストのバイブル「iOSテスト全書」が一般販売開始! https://t.co/2B3Gb1FVKf #ios_testing
— takamii228 (@takamii228) 2021年4月25日
技術書展でもiOS関連の書籍を執筆している人がいるので、チュートリアルが物足りない方は合わせて見てみるとよさそうです。
RSS登録すべき情報
Appleは定期的に開発者向けにニュースで周知をしているので最新情報をキャッチアップするために以下をRSS登録しておくとよいでしょう。
OSやツールのアップデート情報は以下でRSS取得ができます。
Apple全体のニュースはこちらのようです。
まとめ
以上がiOS関連の技術をキャッチアップするときに見るべき情報一覧になります。
GWにiOSアプリをやっていくぞ、という方の参考になればと思います。
私はまずはチュートリアルを完走しようと思います。
APNsのルート証明書更新の影響について調査する方法を調べてみた
先月Apple Developer Newsの中でAPNs(Apple Push Notification service)のサーバー証明書更新のお知らせが来ていました。
どうやらPush通知依頼のリクエストを受けるAPNsのエンドポイントのルート証明書を2021/3/29にGeoTrust Global CA
からAAACertificateServices
に変更するようです。ルート証明書が切り替わったときにPush通知依頼が失敗しないように、2021/3/29までにPush通知サーバーのTrust Storeに両方の証明書が入ってるか確認しておいてね、とのことです。
なお記事の最後にある通り、Appleが我々デベロッパー向けに発行しているAPNsの証明書についての影響はないので混乱しないように注意が必要です。
Note that Apple Push Notification service SSL provider certificates issued to you by Apple do not need be to updated at this time.
FirebaseやサードパーティのPush通知サービスを使ってる場合、今回の対応は利用しているサービスに任せればよいですが、自前でAPNsへのリクエストを組んでいる場合は念の為確認しておく必要がありそうです。
そこでAPNsへのリクエストを行うアプリケーションが動作する環境でAAACertificateServicesの証明書がTrust Storeに入っていることを確認する方法を調べたので以下にまとめました。
なおAPNsへPush通知のリクエストを投げる方法は以前まとめたので参考にしてみてください。
ルート証明書とは何か
ルート証明書はhttps通信を行うときに用いられる証明書で、OSやブラウザにデフォルトで保存されているものです。ここでは詳細については触れないため、ルート証明書についてよくわからないという方はさくらインターネットさんのコラムを見るとよいでしょう。
2021/3/7時点のAPNsへ通信で使われるルート証明書
opensslコマンドを使ってsandboxと商用のAPNsへのhttps通信で使われるルート証明書を見てみましょう。
$ openssl s_client -connect api.development.push.apple.com:443 > /dev/null depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA verify return:1 depth=1 CN = Apple IST CA 2 - G1, OU = Certification Authority, O = Apple Inc., C = US verify return:1 depth=0 CN = api.development.push.apple.com, OU = management:idms.group.533599, O = Apple Inc., ST = California, C = US verify return:1 $ openssl s_client -connect api.push.apple.com:443 > /dev/null depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA verify return:1 depth=1 CN = Apple IST CA 2 - G1, OU = Certification Authority, O = Apple Inc., C = US verify return:1 depth=0 CN = api.push.apple.com, OU = management:idms.group.533599, O = Apple Inc., ST = California, C = US verify return:1
今はどちらもGeoTrust Global CAになっていることがわかります。
AAACertificateServicesの証明書の中身の確認
AAACertificateServicesのルート証明書のcrtファイルは上記のAppleのニュースの本文の中にあるリンクからダウンロードできます。
こちらもopensslコマンドで中身を見てみましょう。
$ openssl x509 -noout -text -in ~/Desktop/AAACertificateServices.crt Certificate: Data: Version: 3 (0x2) Serial Number: 1 (0x1) Signature Algorithm: sha1WithRSAEncryption Issuer: C=GB, ST=Greater Manchester, L=Salford, O=Comodo CA Limited, CN=AAA Certificate Services Validity Not Before: Jan 1 00:00:00 2004 GMT Not After : Dec 31 23:59:59 2028 GMT Subject: C=GB, ST=Greater Manchester, L=Salford, O=Comodo CA Limited, CN=AAA Certificate Services Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:be:40:9d:f4:6e:e1:ea:76:87:1c:4d:45:44:8e: be:46:c8:83:06:9d:c1:2a:fe:18:1f:8e:e4:02:fa: f3:ab:5d:50:8a:16:31:0b:9a:06:d0:c5:70:22:cd: 49:2d:54:63:cc:b6:6e:68:46:0b:53:ea:cb:4c:24: c0:bc:72:4e:ea:f1:15:ae:f4:54:9a:12:0a:c3:7a: b2:33:60:e2:da:89:55:f3:22:58:f3:de:dc:cf:ef: 83:86:a2:8c:94:4f:9f:68:f2:98:90:46:84:27:c7: 76:bf:e3:cc:35:2c:8b:5e:07:64:65:82:c0:48:b0: a8:91:f9:61:9f:76:20:50:a8:91:c7:66:b5:eb:78: 62:03:56:f0:8a:1a:13:ea:31:a3:1e:a0:99:fd:38: f6:f6:27:32:58:6f:07:f5:6b:b8:fb:14:2b:af:b7: aa:cc:d6:63:5f:73:8c:da:05:99:a8:38:a8:cb:17: 78:36:51:ac:e9:9e:f4:78:3a:8d:cf:0f:d9:42:e2: 98:0c:ab:2f:9f:0e:01:de:ef:9f:99:49:f1:2d:df: ac:74:4d:1b:98:b5:47:c5:e5:29:d1:f9:90:18:c7: 62:9c:be:83:c7:26:7b:3e:8a:25:c7:c0:dd:9d:e6: 35:68:10:20:9d:8f:d8:de:d2:c3:84:9c:0d:5e:e8: 2f:c9 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: A0:11:0A:23:3E:96:F1:07:EC:E2:AF:29:EF:82:A5:7F:D0:30:A4:B4 X509v3 Key Usage: critical Certificate Sign, CRL Sign X509v3 Basic Constraints: critical CA:TRUE X509v3 CRL Distribution Points: Full Name: URI:http://crl.comodoca.com/AAACertificateServices.crl Full Name: URI:http://crl.comodo.net/AAACertificateServices.crl Signature Algorithm: sha1WithRSAEncryption 08:56:fc:02:f0:9b:e8:ff:a4:fa:d6:7b:c6:44:80:ce:4f:c4: c5:f6:00:58:cc:a6:b6:bc:14:49:68:04:76:e8:e6:ee:5d:ec: 02:0f:60:d6:8d:50:18:4f:26:4e:01:e3:e6:b0:a5:ee:bf:bc: 74:54:41:bf:fd:fc:12:b8:c7:4f:5a:f4:89:60:05:7f:60:b7: 05:4a:f3:f6:f1:c2:bf:c4:b9:74:86:b6:2d:7d:6b:cc:d2:f3: 46:dd:2f:c6:e0:6a:c3:c3:34:03:2c:7d:96:dd:5a:c2:0e:a7: 0a:99:c1:05:8b:ab:0c:2f:f3:5c:3a:cf:6c:37:55:09:87:de: 53:40:6c:58:ef:fc:b6:ab:65:6e:04:f6:1b:dc:3c:e0:5a:15: c6:9e:d9:f1:59:48:30:21:65:03:6c:ec:e9:21:73:ec:9b:03: a1:e0:37:ad:a0:15:18:8f:fa:ba:02:ce:a7:2c:a9:10:13:2c: d4:e5:08:26:ab:22:97:60:f8:90:5e:74:d4:a2:9a:53:bd:f2: a9:68:e0:a2:6e:c2:d7:6c:b1:a3:0f:9e:bf:eb:68:e7:56:f2: ae:f2:e3:2b:38:3a:09:81:b5:6b:85:d7:be:2d:ed:3f:1a:b7: b2:63:e2:f5:62:2c:82:d4:6a:00:41:50:f1:39:83:9f:95:e9: 36:96:98:6e
2004年に発行されたもののようです。確認用にfingerprintを確認しておきましょう。
$ openssl x509 -sha256 -fingerprint -noout -in ~/Desktop/AAACertificateServices.crt SHA256 Fingerprint=D7:A7:A0:FB:5D:7E:27:31:D7:71:E9:48:4E:BC:DE:F7:1D:5F:0C:3E:0A:29:48:78:2B:C8:3E:E0:EA:69:9E:F4
次にAPNsへのPush通知のリクエストを投げる発射台に上記の証明書が含まれることを確認していきます。今回はJava、PHP、Nodeについて調べてみました。
Javaの場合
Javaアプリケーションの場合はJDK / JREのKeystore情報を確認すればよいです。keytool
コマンドつかってkeystoreの中身を確認します。
$ java -version openjdk version "11.0.10" 2021-01-19 OpenJDK Runtime Environment (build 11.0.10+9) OpenJDK 64-Bit Server VM (build 11.0.10+9, mixed mode) $ keytool -list -storepass changeit -keystore $JAVA_HOME/lib/security/cacerts | \ grep "55:92:60:84:EC:96:3A:64:B9:6E:2A:BE:01:CE:0B:A8:6A:64:FB:FE:BC:C7:AA:B5:AF:C1:55:B3:7F:D7:60:66" Warning: use -cacerts option to access cacerts keystore Certificate fingerprint (SHA-256): 55:92:60:84:EC:96:3A:64:B9:6E:2A:BE:01:CE:0B:A8:6A:64:FB:FE:BC:C7:AA:B5:AF:C1:55:B3:7F:D7:60:66
AAACertificateServicesのfingerprintがヒットしました。lessで詳しく見てみると、comodoaaaca
というAliase nameで登録されていました。
... Alias name: comodoaaaca [jdk] Creation date: Jan 1, 2004 Entry type: trustedCertEntry Owner: CN=AAA Certificate Services, O=Comodo CA Limited, L=Salford, ST=Greater Manchester, C=GB Issuer: CN=AAA Certificate Services, O=Comodo CA Limited, L=Salford, ST=Greater Manchester, C=GB Serial number: 1 Valid from: Thu Jan 01 09:00:00 JST 2004 until: Mon Jan 01 08:59:59 JST 2029 Certificate fingerprints: SHA1: D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49 SHA256: D7:A7:A0:FB:5D:7E:27:31:D7:71:E9:48:4E:BC:DE:F7:1D:5F:0C:3E:0A:29:48:78:2B:C8:3E:E0:EA:69:9E:F4 ...
OpenJDK11の場合は特に何もしなくてもよさそうですね。
PHPの場合
PHPアプリケーションの場合は以下の関数を実行することでPHPが参照しているルート証明書リストの情報が確認できます。
確認方法だけなのでここではmacOS上で実行してしまいます。
ちなみにTerminalでPHPを実行したら警告がでました。将来のmacOSにはPHPはバンドルされないんですね...。
$ php -v WARNING: PHP is not recommended PHP is included in macOS for compatibility with legacy software. Future versions of macOS will not include PHP. PHP 7.3.24-(to be removed in future macOS) (cli) (built: Dec 21 2020 21:33:25) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.3.24, Copyright (c) 1998-2018 Zend Technologies $ php -a Interactive shell php > var_dump(openssl_get_cert_locations()); array(8) { ["default_cert_file"]=> string(25) "/private/etc/ssl/cert.pem" ["default_cert_file_env"]=> string(13) "SSL_CERT_FILE" ["default_cert_dir"]=> string(22) "/private/etc/ssl/certs" ["default_cert_dir_env"]=> string(12) "SSL_CERT_DIR" ["default_private_dir"]=> string(24) "/private/etc/ssl/private" ["default_default_cert_area"]=> string(16) "/private/etc/ssl" ["ini_cafile"]=> string(0) "" ["ini_capath"]=> string(0) "" } php > quit
/private/etc/ssl/cert.pem
にある証明書リストを参照するようです。中身を見てみます。
$ awk -v cmd='openssl x509 -noout -sha256 -fingerprint' ' /BEGIN/{close(cmd)};{print | cmd}' < /private/etc/ssl/cert.pem | grep "D7:A7:A0:FB:5D:7E:27:31:D7:71:E9:48:4E:BC:DE:F7:1D:5F:0C:3E:0A:29:48:78:2B:C8:3E:E0:EA:69:9E:F4" unable to load certificate 4442443436:error:09FFF06C:PEM routines:CRYPTO_internal:no start line:/AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-56.60.2/libressl-2.8/crypto/pem/pem_lib.c:684:Expecting: TRUSTED CERTIFICATE SHA256 Fingerprint=D7:A7:A0:FB:5D:7E:27:31:D7:71:E9:48:4E:BC:DE:F7:1D:5F:0C:3E:0A:29:48:78:2B:C8:3E:E0:EA:69:9E:F4
AAACertificateServicesのfingerprintがヒットしました。lessで中身を見ても確認できました。
$ awk -v cmd='openssl x509 -noout -text ' ' /BEGIN/{close(cmd)};{print | cmd}' < /private/etc/ssl/cert.pem | less ... Certificate: Data: Version: 3 (0x2) Serial Number: 1 (0x1) Signature Algorithm: sha1WithRSAEncryption Issuer: C=GB, ST=Greater Manchester, L=Salford, O=Comodo CA Limited, CN=AAA Certificate Services Validity Not Before: Jan 1 00:00:00 2004 GMT Not After : Dec 31 23:59:59 2028 GMT Subject: C=GB, ST=Greater Manchester, L=Salford, O=Comodo CA Limited, CN=AAA Certificate Services] ...
Node.jsの場合
Node.jsの場合はtslモジュールが参照しているroot証明書を確認すればよいです。
ドキュメントを読むと、If the ca option is not given, then Node.js will default to using Mozilla's publicly trusted list of CAs.
とあるのでMozilaの証明書リストを使うようになっているようです。
https://hg.mozilla.org/mozilla-central/raw-file/tip/security/nss/lib/ckfw/builtins/certdata.txt
以下のコードを実際に実行して参照しているルート証明書のリストが確認できます。
const tls = require('tls'); const net = require('net'); var list = tls.rootCertificates; for(key in list){ const secureContext = tls.createSecureContext({ cert: list[key] }); const secureSocket = new tls.TLSSocket(new net.Socket(), { secureContext }); const cert = secureSocket.getCertificate(); console.log(cert); }
$ node -v v12.20.1 $ node rootCAList.js | grep "D7:A7:A0:FB:5D:7E:27:31:D7:71:E9:48:4E:BC:DE:F7:1D:5F:0C:3E:0A:29:48:78:2B:C8:3E:E0:EA:69:9E:F4" fingerprint256: 'D7:A7:A0:FB:5D:7E:27:31:D7:71:E9:48:4E:BC:DE:F7:1D:5F:0C:3E:0A:29:48:78:2B:C8:3E:E0:EA:69:9E:F4',
AAACertificateServicesのfingerprintがヒットしました。lessで詳細を見ても合致してますね。
$ node rootCAList.js | less ... { subject: [Object: null prototype] { C: 'GB', ST: 'Greater Manchester', L: 'Salford', O: 'Comodo CA Limited', CN: 'AAA Certificate Services' }, issuer: [Object: null prototype] { C: 'GB', ST: 'Greater Manchester', L: 'Salford', O: 'Comodo CA Limited', CN: 'AAA Certificate Services' }, ...
3/29までに何をすればよい?
Appleの通知の本文にある通り、APNsへリクエストを投げるアプリケーションがAAACertificateServicesのルート証明書を信頼するようになっていればよいです。ルート証明書を信頼するかどうかは上記の証明書リストにAAACertificateServicesのルート証明書が登録されていればよいです。
より厳密にやるのであれば、Push通知のリクエストをAAACertificateServices経由で行えばよいのですがこれは3/29を待たなければできません。sandboxだけでも先に変わってくれるとよいのですが、おそらく一括で変更が入るのでしょう。
どうしても心配な方は、AAACertificateServicesの証明書を経由するhttpsリクエストが正しく実行できることを確認してみるといいかなと思いました。
例えばsupport.sectigo.com
へのリクエストはAAACertificateServicesのルート証明書を経由するようです。
$ openssl s_client -connect support.sectigo.com:443 > /dev/null depth=3 C = GB, ST = Greater Manchester, L = Salford, O = Comodo CA Limited, CN = AAA Certificate Services verify return:1 depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority verify return:1 depth=1 C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Extended Validation Secure Server CA verify return:1 depth=0 serialNumber = 04058690, jurisdictionCountryName = GB, businessCategory = Private Organization, C = GB, postalCode = M5 3EQ, ST = Manchester, L = Salford, street = Trafford Road, street = Office Village Exchange Quay, street = 3rd Floor Building 26, O = Sectigo Limited, OU = IT, CN = support.sectigo.com verify return:1
まとめ
APNsのルート証明書変更に起因して、Java・PHP・Node.jsのアプリケーションが参照しているルート証明書情報を確認する手順をまとめました。検証を通してhttps通信の仕組みについて改めて理解を深めることができました。証明書の更新に関しては影響がある方は3/29以降問題が発生しないように事前に確認しておくとよいでしょう。
2021/4/2追記
切り替えあとに証明書チェインの情報を確認してみたら無事AAA Certificate Servicesに変わってました。
$ openssl s_client -connect api.development.push.apple.com:443 > /dev/null depth=2 C = GB, ST = Greater Manchester, L = Salford, O = Comodo CA Limited, CN = AAA Certificate Services verify return:1 depth=1 CN = Apple Public Server RSA CA 12 - G1, O = Apple Inc., ST = California, C = US verify return:1 depth=0 CN = api.development.push.apple.com, OU = management:idms.group.533599, O = Apple Inc., ST = California, C = US verify return:1 $ openssl s_client -connect api.push.apple.com:443 > /dev/null depth=2 C = GB, ST = Greater Manchester, L = Salford, O = Comodo CA Limited, CN = AAA Certificate Services verify return:1 depth=1 CN = Apple Public Server RSA CA 12 - G1, O = Apple Inc., ST = California, C = US verify return:1 depth=0 CN = api.push.apple.com, OU = management:idms.group.887777, O = Apple Inc., ST = California, C = US verify return:1