Tag Archives: Certificate

[iOS] Verify return code: 20 (unable to get local issuer certificate) 해결

Push Notification 발송을 위한 작업은 매우 까다로운 부분인것 같습니다. 생각만큼 쉽게 되지도 않고 APNS서버측에서 날라오는 오류들은 하나같이 무엇이 문제인지 판단을 내리기가 쉽지 않습니다.

그중에 하나인 Verify return code: 20 (unable to get local issuer certificate) 오류를 수정하는 방법에 대해서 정리해 보겠습니다. 우선적으로 이 문제는 대부분 인증서가 잘못되었거나 발송하는 서버의 루트 인증서가 없거나 혹은 디렉토리 설정등에 문제가 있을 경우입니다.

방확벽 확인

방화벽 설정에 막혀 APNS서버에 접속하지 못하는 경우가 있습니다. 이 경우 우선적으로 방화벽에 막히는것인지 확인이 필요합니다. 다음과 같이 접속을 시도하여 다음과 같이 나온다면(접속이 된다면) 방화벽 문제는 아닌것입니다.

$ telnet gateway.push.apple.com 2195
Trying 17.149.35.167...
Connected to gateway.push-apple.com.akadns.net.
Escape character is '^]'.

정상적으로 PEM인증서를 생성했는지 확인

다음과 같은 방법으로 인증서를 생성하였는지 확인합니다. 다른 방법으로 하셨다면 다음의 방법을 추천합니다.

  1. [iPhone Developer Program Portal]에 로그인합니다.
  2. App IDs 메뉴에 들어간 후 새로운 App ID를 생성합니다. 이때에 와일드카드(*)를 사용하면 안됩니다. 예) 3L223ZX9Y3.kr.pe.theeye.pushsample
  3. 새로 생성된 App ID의 Configure 링크를 클릭하여 Development/Production Push SSL Certificate를 생성하는 마법사를 구동합니다. 참고: [LINK]
  4. 위의 과정을 거쳐 생성된 인증서(aps_developer_identity.cer)를 다운받아 더블클릭을 하여 키체인에 추가해 줍니다.
  5. 키체인 접근(Keychain Assistant)를 실행하여 왼쪽에 보이는 내 인증서(My Certificates)를 선택합니다. (1)
  6. Apple Development/Production IOS Push Service 의 왼쪽에 화살표를 클릭하여 확장후에 이 푸시 인증서와 확장하여 나타난 개인키를 함께 선택합니다. (2)
  7. 마우스 오른쪽 클릭후에 “2개 항목 보내기(Export 2 elements…)”를 눌러 p12형태의 인증서로 저장을 합니다. 저장시에 비밀번호를 물어오는데 비밀번호 없이 그냥 엔터를 쳐야 합니다.
  8. 터미널(Terminal)을 실행하여 방금 저장한 인증서가 있는 위치로 이동하여 다음의 명령을 실행합니다. (apns_certificate.p12 라고 가정)
$ openssl pkcs12 -in apns_certificate.p12 -out apns_certificate.pem -nodes -clcerts

사용자 삽입 이미지
인증서가 정상인지 확인

다음과 같은 명령을 사용하여 해당 인증서를 이용하여 현재의 서버 환경에서 정상적으로 푸시를 발송할 수 있는지 여부를 확인할 수 있습니다. 다음의 예시는 Production용 서버에 접속할 경우의 예시이며 Development환경에서는 gateway.sandbox.push.apple.com으로 접속하시면 됩니다.

$ openssl s_client -connect gateway.push.apple.com:2195 -cert apns_certificate.pem
CONNECTED(00000003)
depth=1 /C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
verify error:num=20:unable to get local issuer certificate
verify return:0

위와 같은 오류가 발생하는 것을 확인할 수 있습니다. 현재 확인한 결과 위의 메시지는 특정한 서버환경에서만 발생하는것으로 추측되고 있습니다.

외부 ROOT인증서를 이용하여 문제 해결

다음의 Root CA 인증서를 다운받아 서버의 적절한 위치에 두도록 합니다. 이제 이 인증서를 사용하여 다시한번 테스트를 해보도록 하겠습니다. [인증서다운로드]

$ openssl s_client -connect gateway.push.apple.com:2195 -cert apns_certificate.pem -CAfile entrust_2048_ca.cer 
CONNECTED(00000003)
depth=2 /O=Entrust.net/OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Certification Authority (2048)
verify return:1
depth=1 /C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
verify return:1
depth=0 /C=US/ST=California/L=Cupertino/O=Apple Inc./OU=iTMS Engineering/CN=gateway.push.apple.com
verify return:1
---
Certificate chain
0 s:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=iTMS Engineering/CN=gateway.push.apple.com
i:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
1 s:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
i:/O=Entrust.net/OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Certification Authority (2048)

문제 없이 잘 되는것을 확인하였습니다. 여기서 문제가 없다면 인증서는 더이상 의심하지 않으셔도 됩니다. PHP코드상에서 CA Root 인증서를 따로 지정하려면 다음의 코드를 사용하시면 됩니다.

stream_context_set_option($ctx, 'ssl', 'cafile', 'entrust_2048_ca.cer');

참고자료

http://code.google.com/p/apns-php/wiki/CertificateCreation#Verify_peer_using_Entrust_Root_Certification_Authority
http://stackoverflow.com/questions/10585283/apns-sandbox-connection-failed-error-0-in-php-file
https://www.entrust.net/downloads/root_request.cfm

[iPhone] Missing Push Notification Entitlement 해결하기

앱스토어에 새로 앱을 등록하고 아이튠즈 커넥트에서 Waiting for Review상태가 된것을 확인하고 안심하기에도 전에 다음과 같은 메일이 날라오는 경우가 있습니다.

사용자 삽입 이미지Missing Push Notification Entitlement라는 경고 메일이 도착하였습니다. 애플의 개발자 센터에서 Push Notification 서비스를 활성화 했지만 Entitlement에는 Push Notification의 활성화 여부를 기록하는 aps-environment정보가 존재하지 않는다는 메시지 입니다.

사용자 삽입 이미지
문제를 확인하기 위해 만들었던 Provisioning이 정상적으로 Active상태인지 확인합니다. 맞다면 다운 받아서 다음을 확인해 보도록 합니다. 터미널에서 다음의 명령으로 Provisioning의 내용을 확인할 수 있습니다.

$ security cms -D -i <filename.mobileprovision>
.
.
.
<dict>
    <key>application-identifier</key>
    <string>6JBPC845B4.kr.pe.theeye.sampleapp</string>
    <key>aps-environment</key>
    <string>production</string>
    <key>get-task-allow</key>
    <false/>
    <key>keychain-access-groups</key>
    <array>
        <string>6JBPC845B4.*</string>
    </array>
</dict>
.
.
.

Push Notification 설정이 잘못 되어있다면 위의 내용중에서 보이는 aps-environment정보가 누락되어있게 됩니다. 즉 다음의 내용이 존재하지 않을것입니다.

<key>aps-environment</key>
<string>production</string>

말이 복잡하지만 간단히 생각하면 사용하시는 Provisioning에 Push Notification정보가 누락된 상태라고 보시면 됩니다. 사실 푸시를 사용하지 않는 앱일 경우 무시해도 될 경고 메시지입니다만 리젝되는 경우도 많이 있다고 하니 무시하시면 안될 메일입니다.

사용자 삽입 이미지우선 가장 먼저 확인해 보셔야 할 부분은 개발자 센터의 App ID 메뉴에 진입하여 개발중인 앱의 Push Notification 정보를 확인해 보셔야 합니다. 당장에 Production환경의 Push Notification정보만 Enabled되어있으면 되지만 간혹 정상적으로 설정 되어있지만 위와 같이 나오지 않고 Configurable로 나오는 경우가 있습니다. 설정에 들어가 보면 정상적으로 설정이 되어있음에도 불구하고요.

사용자 삽입 이미지

[이 내용은 푸시 설정이 되어있음에도 App ID리스트 상에서 Enabled로 나오지 않을경우에만 참고하세요]
그 경우 어쩔수 없이 위와 같이 Production Push 인증서를 추가로 설정해 주셔야 합니다. 서비스의 무중단을 위하여 Production용 인증서는 동시에 2개까지 설정이 가능합니다. 추가를 해주시고 기존에 사용중인 인증서를 새로운 인증서로 교체해 주시기 바랍니다.

사용자 삽입 이미지정상적으로 추가가 되었다면 위와같이 Production용 인증서가 둘다 Enabled되어있는것을 확인하실 수 있습니다.

사용자 삽입 이미지

이제 다시 Provisioning을 갱신하여 사용하시면 됩니다. 하지만 여기서 중요한점은 단순히 갱신하는것보다는 위와 같이 아예 삭제를 한 뒤에 다시 새로 추가하시는것이 확실합니다. 몇번 해보니 갱신으로는 잘 안되는 경우가 있더군요.

위와 같은 과정을 거치게 되면 Provisioning에 정상적으로 aps-environment가 추가 되어있을 것이고 빌드하여 앱스토어에 등록하시면 문제 없이 등록이 될 것입니다.