Bug #88643 SSL connection error: protocol version mismatch
Submitted: 24 Nov 2017 12:18 Modified: 9 Jul 2019 17:28
Reporter: Iwo P Email Updates:
Status: Won't fix Impact on me:
None 
Category:MySQL Server: Security: Encryption Severity:S3 (Non-critical)
Version:5.7.20 OS:Any
Assigned to: CPU Architecture:Any
Tags: certificate, SSL, yassl

[24 Nov 2017 12:18] Iwo P
Description:
For the certificate that doesn't have line length of 65 characters (64+\n)  MySQL loads it correctly but any SSL connection is refused with an ambiguous error: `SSL connection error: protocol version mismatch`.

$ for l in $(<ServerCertificate.crt); do echo $l | wc -c; done;
11
17
61
61
61
61
61
61
61
61
61
61
61
61
61
61
61
61
61
61
61
61
61
61
61
61
61
61
61
61
61
57
9
17

From Non-SSL session:

mysql> show variables like 'have%ssl';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| have_openssl  | YES   |
| have_ssl      | YES   |
+---------------+-------+

From SSL Session:
$ mysql -h 127.0.0.1 -umsandbox -pmsandbox --ssl-mode=REQUIRED -P 5720
ERROR 2026 (HY000): SSL connection error: protocol version mismatch

Everything works fine when (the same) certificate have line length of 65 (64+\n) characters 

# openssl x509 -in ServerCertificate.crt -out rfc.crt

$ for l in $(<rfc.crt); do echo $l |wc -c; done;
11
17
65
65
65
65
65
65
65
65
65
65
65
65
65
65
65
65
65
65
65
65
65
65
65
65
65
65
65
65
5
9
17

$ mysql -h 127.0.0.1 -umsandbox -pmsandbox --ssl-mode=REQUIRED -P 5720
Server version: 5.7.20 MySQL Community Server (GPL)
mysql> \s
[...]
Current user:		msandbox@localhost
SSL:			Cipher in use is DHE-RSA-AES256-SHA

The certificates are basically the same, except for the line length.

$ for i in ServerCertificate.crt rfc.crt; do cat $i | tr -d '\n' | md5sum; done;
a94cc96c06512dcd7ae74e90b4938e86  -
a94cc96c06512dcd7ae74e90b4938e86  -

Note, that there's a hardcoded PEM line length in file extra/yassl/taocrypt/crd/coding.cpp:

67: const int pemLineSz = 64;
which is later used in 
128: void Base64Encoder::Encode()
129: {
130:    word32 bytes = plain_.size();
140:    word32 outSz = (bytes + 3 - 1) / 3 * 4;
150:
160:    outSz += (outSz + pemLineSz - 1) / pemLineSz;  // new lines
161:    encoded_.New(outSz);

Any version compiled with OpenSSL isn't affected.

Note, RFC 7468 says that:

   Generators MUST wrap the base64-encoded lines so that each line
   consists of exactly 64 characters except for the final line, which
   will encode the remainder of the data (within the 64-character line
   boundary), and they MUST NOT emit extraneous whitespace.  Parsers MAY
   handle other line sizes.  These requirements are consistent with PEM
   [RFC1421].

however, this isn't strictly followed by many SSL implementations.

How to repeat:
1. Generate SSL certificate that doesn't have a line length of 65 (64+\n) characters.
2. Run MySQL with this certificate loaded.
3. Change the line length of the certificate (openssl x509 -in ServerCertificate.crt -out rfc.crt).
4. Run MySQL with the new certificate.

Suggested fix:
1. It should be allowed to load certificate that line length differs from 64 or, at least, an Error should be returned. 
2. This should be included in the documentation because issues like that are really hard to debug.
[28 Nov 2017 12:29] MySQL Verification Team
Hello Iwo P,

Thank you for the report and feedback.

Thanks,
Umesh
[28 Nov 2017 12:30] MySQL Verification Team
test results

Attachment: 88643.results (application/octet-stream, text), 6.84 KiB.

[9 Jul 2019 17:28] Paul DuBois
Posted by developer:
 
This is a yaSSL issue. yaSSL support is removed as of MySQL 5.6.46/5.7.28, so this bug is being closed with no action taken.