docker-library / php

Docker Official Image packaging for PHP
https://php.net
MIT License
3.83k stars 2.01k forks source link

7.3.18 APNS unable to get local issuer certificate #1032

Closed Patrick-Remy closed 2 years ago

Patrick-Remy commented 4 years ago

Since version 7.3.18 it seems that Apple's intermediate CA cert is not included in the container.

Output from 7.3.18 (unable to get local issuer certificate)

docker run php:7.3.18-cli curl -v --http2 'https://api.push.apple.com/3/device/123'
* Connected to api.push.apple.com (17.188.157.160) port 443 (#0)
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [104 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [3307 bytes data]
* TLSv1.2 (OUT), TLS alert, unknown CA (560):
} [2 bytes data]
* SSL certificate problem: unable to get local issuer certificate
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
* Closing connection 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

Working in 7.3.17 (MethodNotAllowed is expected here, as no login certs or valid Device Id is provided)

docker run php:7.3.17-cli curl -v --http2 'https://api.push.apple.com/3/device/123'
.....
*   Trying 17.188.157.160...
* TCP_NODELAY set
* Expire in 149993 ms for 3 (transfer 0x55d404f56f50)
* Expire in 200 ms for 4 (transfer 0x55d404f56f50)
* Connected to api.push.apple.com (17.188.157.160) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [104 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [3307 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [300 bytes data]
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
{ [798 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
} [7 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [37 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=api.push.apple.com; OU=management:idms.group.533599; O=Apple Inc.; ST=California; C=US
*  start date: Mar 14 17:50:10 2019 GMT
*  expire date: Apr 12 17:50:10 2021 GMT
*  subjectAltName: host "api.push.apple.com" matched cert's "api.push.apple.com"
*  issuer: CN=Apple IST CA 2 - G1; OU=Certification Authority; O=Apple Inc.; C=US
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
} [5 bytes data]
* Using Stream ID: 1 (easy handle 0x55d404f56f50)
} [5 bytes data]
> GET /3/device/5AEC054 HTTP/2
> Host: api.push.apple.com
> User-Agent: curl/7.64.0
> Accept: */*
> 
{ [5 bytes data]
* Connection state changed (MAX_CONCURRENT_STREAMS == 1)!
} [5 bytes data]
< HTTP/2 405 
< apns-id: FB4803E9-F361-C27B-65F7-937A327495C9
< 
{ [29 bytes data]
100    29    0    29    0     0     38      0 --:--:-- --:--:-- --:--:--    38
* Connection #0 to host api.push.apple.com left intact
{"reason":"MethodNotAllowed"}%                  
phy25 commented 4 years ago

I can also reproduce this on latest debian image. Looks like it's an issue of ca-certificate removing GeoTrust_Global_CA.pem , but not exactly sure why this happens.

$ diff <(docker run php:7.3.17-cli ls -1 /etc/ssl/certs) <(docker run php:7.3.18-cli ls -1 /etc/ssl/certs)
7a8
> 0a775a30.0
10a12
> 0f5dc4f3.0
11a14
> 1001acf7.0
13d15
< 116bf586.0
15c17
< 157753a5.0
---
> 14bc7599.0
21a24
> 2923b3f9.0
24,25d26
< 2c543cd1.0
< 2e4eed3c.0
35a37
> 406c9bb1.0
37d38
< 480720ec.0
39a41
> 4b718d9b.0
50a53
> 5e98733a.0
52a56
> 626dceaf.0
54a59
> 68dd7389.0
66d70
< 7d0b38bd.0
68d71
< 812e17de.0
79d81
< 9f0f5fd6.0
83d84
< AddTrust_External_Root.pem
103,104c104
< Certinomis_-_Root_CA.pem
< Certplus_Class_2_Primary_CA.pem
---
> Certigna_Root_CA.pem
113d112
< Deutsche_Telekom_Root_CA_2.pem
128a128
> Entrust_Root_Certification_Authority_-_G4.pem
130,134c130,133
< GeoTrust_Global_CA.pem
< GeoTrust_Primary_Certification_Authority.pem
< GeoTrust_Primary_Certification_Authority_-_G2.pem
< GeoTrust_Primary_Certification_Authority_-_G3.pem
< GeoTrust_Universal_CA.pem
---
> GTS_Root_R1.pem
> GTS_Root_R2.pem
> GTS_Root_R3.pem
> GTS_Root_R4.pem
148a148
> Hongkong_Post_Root_CA_3.pem
195a196,197
> UCA_Extended_Validation_Root.pem
> UCA_Global_G2_Root.pem
198,200d199
< VeriSign_Class_3_Public_Primary_Certification_Authority_-_G4.pem
< VeriSign_Class_3_Public_Primary_Certification_Authority_-_G5.pem
< VeriSign_Universal_Root_Certification_Authority.pem
202a202
> a3418fda.0
204d203
< ad088e1d.0
209d207
< b204d74a.0
213,215c211
< ba89ed3b.0
< c01cdfa2.0
< c089bbbd.0
---
> c01eb047.0
237d232
< e2799e36.0
245c240,243
< f060240e.0
---
> emSign_ECC_Root_CA_-_C3.pem
> emSign_ECC_Root_CA_-_G3.pem
> emSign_Root_CA_-_C1.pem
> emSign_Root_CA_-_G1.pem
251a250
> f51bb24c.0
255,257d253
< thawte_Primary_Root_CA.pem
< thawte_Primary_Root_CA_-_G2.pem
< thawte_Primary_Root_CA_-_G3.pem
phy25 commented 4 years ago

"GeoTrust Global CA" has been denied as the Symantec Root CA block: https://salsa.debian.org/debian/ca-certificates/-/commit/1efe81a680eedb94111716c8825290a0cde509af

See also https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=911289

What's interesting is that my latest Firefox/Chrome on Windows still works, but I guess Apple should be the one to update the certificate.

phy25 commented 4 years ago

Looks like a better place to report this is at https://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg=ca-certificates; https://wiki.mozilla.org/CA/Upcoming_Distrust_Actions says the following but it might be hard for system certificate storage to respect that.

Certificates issued by the independently-operated Google and Apple sub-CAs are exempt, but unless you are Google or Apple you will not be using those.

Patrick-Remy commented 4 years ago

Thanks for your deep investigation!

phy25 commented 4 years ago

See also https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=962596

tianon commented 2 years ago

Looks like this is fixed: :+1:

$ docker run --rm --pull=always php:7-cli curl -v --http2 'https://api.push.apple.com/3/device/123'
7-cli: Pulling from library/php
42c077c10790: Already exists 
8934009a9160: Pull complete 
5357ac116991: Pull complete 
54ae63894b5a: Pull complete 
7ed5ecf24d64: Pull complete 
6b5ed150674e: Pull complete 
ff74f385d8d9: Pull complete 
c8f1157ee4de: Pull complete 
f4c15932d60f: Pull complete 
Digest: sha256:06c6f58ae43d78b86f57c629438d0fbe33af6c0865d1163e39c2387d929a9e41
Status: Downloaded newer image for php:7-cli
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 17.188.181.139:443...
* Connected to api.push.apple.com (17.188.181.139) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [122 bytes data]
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
{ [19 bytes data]
* TLSv1.3 (IN), TLS handshake, Request CERT (13):
{ [927 bytes data]
* TLSv1.3 (IN), TLS handshake, Certificate (11):
{ [4402 bytes data]
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
{ [264 bytes data]
* TLSv1.3 (IN), TLS handshake, Finished (20):
{ [52 bytes data]
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.3 (OUT), TLS handshake, Certificate (11):
} [8 bytes data]
* TLSv1.3 (OUT), TLS handshake, Finished (20):
} [52 bytes data]
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=api.push.apple.com; OU=management:idms.group.887777; O=Apple Inc.; ST=California; C=US
*  start date: Dec  9 03:25:59 2021 GMT
*  expire date: Jan  8 03:25:58 2023 GMT
*  subjectAltName: host "api.push.apple.com" matched cert's "api.push.apple.com"
*  issuer: CN=Apple Public Server RSA CA 12 - G1; O=Apple Inc.; ST=California; C=US
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
} [5 bytes data]
* Using Stream ID: 1 (easy handle 0x5642658eb5c0)
} [5 bytes data]
> GET /3/device/123 HTTP/2
> Host: api.push.apple.com
> user-agent: curl/7.74.0
> accept: */*
> 
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [214 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [214 bytes data]
* old SSL session ID is stale, removing
{ [5 bytes data]
* Connection state changed (MAX_CONCURRENT_STREAMS == 1)!
} [5 bytes data]
< HTTP/2 405 
< apns-id: 97E38552-0B4C-E699-2EBB-1C67D0DC9ACB
< 
{ [29 bytes data]
100    29    0    29    0     0    325      0 --:--:-- --:--:-- --:--:--   325
* Connection #0 to host api.push.apple.com left intact
{"reason":"MethodNotAllowed"}

(but also not something we likely can/would fix in the images directly :see_no_evil:)