php imap_open ssl cert verification FAILS; test with openssl s_client verification WORKS. what's this config's problem ?
| From: | PGNet Dev | Date: | Fri, 14 Aug 2020 19:03:25 +0000 |
| Subject: | php imap_open ssl cert verification FAILS; test with openssl s_client verification WORKS. what's this config's problem ? | ||
| Groups: | php.general | ||
| Request: | Send a blank email to php-general+get-327281@lists.php.net to get a copy of this message | ||
i've a local imap server (dovecot)
i run
php -v
PHP 7.4.8 (cli) (built: Jul 9 2020 08:57:23) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.8, Copyright (c), by Zend Technologies
php -m | grep imap
imap
TL;DR
i'm setting up to use ssl certificate verification.
with
openssl s_client verification works; with php imap_open
verification fails. what's wrong/missing in my php config?
connecting via php 'imap_open' to the imap server, on exec of the following test script
imap_connect_test.php
<?php
$config = array();
$host = 'mx.example.com';
$port = '993';
$spec = '/debug/imap/ssl/norsh/novalidate-cert';
$mailbox = "{{$host}:{$port}{$spec}}INBOX";
$username = 'me@example2.com';
$password = 'changeme';
$options = 0;
$params = array(
'ssl' => array(
'verify_peer' => true,
'verify_peer_name' => false,
'peer_name' => 'internal.mx.example.com',
'verify_depth' => 9,
'allow_self_signed' => true,
'SNI_enabled' => true,
'ciphers' =>
'TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-CHACHA20-POLY1305',
'local_cert' => '/srv/ssl/mail.client.EC.crt',
'local_pk' => '/srv/ssl/mail.client.EC.key',
'cafile' => '/srv/ssl/myCA.CHAIN.crt'
),
);
$imap = imap_open($mailbox, $username, $password, $options, 0, $params);
$folders = imap_listmailbox($imap, "{mx.example.com:993}", "*");
if ($folders == false) {
echo "Call failed<br />\n";
} else {
foreach ($folders as $val) {
echo $val . "<br />\n";
}
}
function printArray($array, $prefix) {
if (is_array($array)) {
foreach ($array as $entry) {
print "$prefix: $entry\n";
}
} else {
print "$prefix: None\n";
}
}
printArray(imap_errors(), "ERR");
printArray(imap_alerts(), "Alert");
if ($imap !== FALSE) {
imap_close($imap);
}
?>
returns, as expected,
php imap_connect_test.php -e
{mx.example.com:993}Drafts<br />
{mx.example.com:993}Trash<br />
{mx.example.com:993}Junk<br />
{mx.example.com:993}Sent<br />
{mx.example.com:993}INBOX<br />
ERR: None
Alert: None
and in imap logs
==> /var/log/dovecot/dovecot-debug.log <==
2020-08-14 11:13:25 auth: Debug: auth client connected (pid=11483)
==> /var/log/dovecot/dovecot-info.log <==
2020-08-14 11:13:25 imap-login: Info: Disconnected (no auth attempts in 0 secs): user=<>,
rip=127.0.0.1, lip=127.0.0.1, TLS handshaking: SSL_accept() failed: error:14094418:SSL
routines:ssl3_read_bytes:tlsv1 alert unknown ca: SSL alert number 48
==> /var/log/dovecot/dovecot-debug.log <==
2020-08-14 11:14:14 auth: Debug: auth client connected (pid=11499)
2020-08-14 11:14:14 auth: Debug: client in: AUTH 1 PLAIN service=imap secured=tls
session=9X5tY9qshuR/AAAB lip=127.0.0.1 rip=127.0.0.1 lport=993 rport=58502
ssl_cipher=TLS_AES_256_GCM_SHA384 ssl_cipher_bits=256 ssl_pfs=KxANY ssl_protocol=TLSv1.3
2020-08-14 11:14:14 auth: Debug: client passdb out: CONT 1
2020-08-14 11:14:14 auth: Debug: client in: CONT 1
AGJsYWtlcnNAY3hvbG9naWMuY29tAHRlc3RwYXNzdGVzdHBhc3M= (previous base64 data may contain sensitive
data)
2020-08-14 11:14:14 auth: Debug: passwd-file(me@example2.com,127.0.0.1,<9X5tY9qshuR/AAAB>):
Performing passdb lookup
2020-08-14 11:14:14 auth: Debug: passwd-file(me@example2.com,127.0.0.1,<9X5tY9qshuR/AAAB>):
lookup: user=me@example2.com file=/etc/dovecot/sec/users.conf
2020-08-14 11:14:14 auth: Debug: passwd-file(me@example2.com,127.0.0.1,<9X5tY9qshuR/AAAB>):
Finished passdb lookup
2020-08-14 11:14:14 auth: Debug: auth(me@example2.com,127.0.0.1,<9X5tY9qshuR/AAAB>): Auth
request finished
2020-08-14 11:14:14 auth: Debug: client passdb out: OK 1 user=me@example2.com
2020-08-14 11:14:14 auth: Debug: master in: REQUEST 3214278657 11499 1
1d2580e127909e48d03637a8e369054d session_pid=11500 request_auth_token
2020-08-14 11:14:14 auth: Debug: static(me@example2.com,127.0.0.1,<9X5tY9qshuR/AAAB>):
Performing userdb lookup
2020-08-14 11:14:14 auth: Debug: static(me@example2.com,127.0.0.1,<9X5tY9qshuR/AAAB>):
Finished userdb lookup
2020-08-14 11:14:14 auth: Debug: master userdb out: USER 3214278657 me@example2.com
uid=5000 gid=5000 home=/data/vmail/example2.com/me/Maildir auth_mech=PLAIN
auth_token=898caadcaf538866cd07a36dda4a46c28556434c
==> /var/log/dovecot/dovecot-info.log <==
2020-08-14 11:14:14 imap-login: Info: Login: user=<me@example2.com>, method=PLAIN,
rip=127.0.0.1, lip=127.0.0.1, mpid=11500, TLS
2020-08-14 11:14:14 imap(me@example2.com)<9X5tY9qshuR/AAAB>: Info: Logged out in=58 out=1187
deleted=0 expunged=0 trashed=0 hdr_count=0 hdr_bytes=0 body_count=0 body_bytes=0
if I toggle certificate validation -> ON
- $spec = '/debug/imap/ssl/norsh/novalidate-cert';
+ $spec = '/debug/imap/ssl/norsh/validate-cert';
and re-exec, it fails
php imap_connect_test.php -e
PHP Warning: imap_open(): Couldn't open stream
{mx.example.com:993/debug/imap/ssl/norsh/validate-cert}INBOX in /home/test/imap_connect_test.php on
line 42
Warning: imap_open(): Couldn't open stream
{mx.example.com:993/debug/imap/ssl/norsh/validate-cert}INBOX in /home/test/imap_connect_test.php on
line 42
ERR: Certificate failure for mx.example.com: unable to get local issuer certificate:
/C=US/ST=NY/L=NY/O=example.com/OU=example.com_CA/CN=internal.mx.example.com/emailAddress=ssl@example.com
Alert: None
and in imap logs
2020-08-14 11:19:02 imap-login: Info: Disconnected (disconnected before auth was ready, waited 0
secs): user=<>, rip=127.0.0.1, lip=127.0.0.1, TLS handshaking: SSL_accept() failed:
error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca: SSL alert number 48
if I check certificate verification with openssl s_client, it WORKS
openssl s_client \
-verify +9 \
-verify_return_error \
-verifyCAfile /srv/ssl/myCA.CHAIN.crt \
-verify_hostname internal.mx1-dev.example.com \
-crlf \
-4 \
-showcerts \
-bind 172.30.11.49 \
-connect mx1-dev.example.com:41993 \
-cert /srv/ssl/roundcube.example.com.client.EC.crt \
-key /srv/ssl/roundcube.example.com.client.EC.key \
-CAfile /srv/ssl/myCA.CHAIN.crt \
-cipher ECDHE \
-ciphersuites "TLS_CHACHA20_POLY1305_SHA256" \
-min_protocol TLSv1.2
...
verify depth is 9
CONNECTED(00000003)
depth=2 O = example.com, OU = myCA, L = NY, ST = NY, C = US, emailAddress = ssl@example.com, CN =
myCA_ROOT
verify return:1
depth=1 C = US, ST = NY, O = example.com, OU = myCA, CN = myCA_INTERMEDIATE, emailAddress =
ssl@example.com
verify return:1
depth=0 C = US, ST = NY, L = NY, O = example.com, OU = myCA, CN = internal.mx1-dev.example.com,
emailAddress = ssl@example.com
verify return:1
---
Certificate chain
0 s:C = US, ST = NY, L = NY, O = example.com, OU = myCA, CN = internal.mx1-dev.example.com,
emailAddress = ssl@example.com
i:C = US, ST = NY, O = example.com, OU = myCA, CN = myCA_INTERMEDIATE, emailAddress =
ssl@example.com
-----BEGIN CERTIFICATE-----
MII...YVe
-----END CERTIFICATE-----
---
Server certificate
subject=C = US, ST = NY, L = NY, O = example.com, OU = myCA, CN = internal.mx1-dev.example.com,
emailAddress = ssl@example.com
issuer=C = US, ST = NY, O = example.com, OU = myCA, CN = myCA_INTERMEDIATE, emailAddress =
ssl@example.com
---
No client certificate CA names sent
Peer signing digest: SHA384
Peer signature type: ECDSA
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 1573 bytes and written 380 bytes
Verification: OK
Verified peername: internal.mx1-dev.example.com
---
New, TLSv1.3, Cipher is TLS_CHACHA20_POLY1305_SHA256
Server public key is 384 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_CHACHA20_POLY1305_SHA256
Session-ID: 978233572BFFB63870CC2FE3E24DCEF6664B79EC723579252032B8CA34D7D953
Session-ID-ctx:
Resumption PSK: 64903664B2D25A5D72DADECEFD08402C27C69B242AF2A044F1EFF41CAF0FCB57
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 7200 (seconds)
TLS session ticket:
0000 - 74 67 31 81 3a 28 12 40-06 50 52 54 55 cf d2 95 tg1.:(.@.PRTU...
0010 - fc b9 09 ec eb 22 79 87-1d 29 46 8a be 38 51 fd ....."y..)F..8Q.
Start Time: 1597430604
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: no
Max Early Data: 0
---
read R BLOCK
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_CHACHA20_POLY1305_SHA256
Session-ID: 9E120BCCC0389D6E21749E66764B369E1507C3FE8D379F82F791DC367C5E80CE
Session-ID-ctx:
Resumption PSK: 44C0E08FDEF2E6037EB03FC67306340E0B8AA037FA571F59821473129EA374BB
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 7200 (seconds)
TLS session ticket:
0000 - 62 10 d1 6c 0d 77 fa 40-5c d3 47 76 dc ce 6e 52 b..l.w.@\.Gv..nR
0010 - 90 1f 19 37 02 41 a9 2e-06 6b 28 42 c8 52 e1 d1 ...7.A...k(B.R..
Start Time: 1597430604
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: no
Max Early Data: 0
---
read R BLOCK
* OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SPECIAL-USE LITERAL+
AUTH=PLAIN] Dovecot ready.
>> a1 login "me@example2.com" "changeme"
a1 OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY
THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT
CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES
WITHIN CONTEXT=SEARCH LIST-STATUS BINARY MOVE SNIPPET=FUZZY PREVIEW=FUZZY STATUS=SIZE SPECIAL-USE
LITERAL+ NOTIFY SPECIAL-USE QUOTA ACL RIGHTS=texk] Logged in
>> x select inbox
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted.
* 2 EXISTS
* 0 RECENT
* OK [UIDVALIDITY 1595625368] UIDs valid
* OK [UIDNEXT 3] Predicted next UID
* OK [HIGHESTMODSEQ 5] Highest
x OK [READ-WRITE] Select completed (0.001 + 0.000 secs).
etc etc etc
i've found many posts re: "couldn't open stream" in similar cases, and have
only, so far, found 'resolution' by NOT validating certs; i.e., $spec +=
"/novalidate-cert" :-/
as openssl s_client connect & verifies, clearly, something in my php config/usage
is wrong ...
what/where ?