New self-signed SSL Certificate for iOS 13
Updated 2019-12-03.
The instructions in Replacement of macOS Server: Calendar, Contacts, and Mail called for the creation of a self-signed SSL certificate. This certificate needed to be installed in the local CentOS server that supported the back end for the Calendar, Contacts, Mail, Notes, and Reminders apps on my local network.
The method used no longer works with the latest iOS 13 nor (I believe) with the latest macOS 10.15 ("Catalina").
The following describes changes to the previous instructions needed to get things working again.
Create local domain name
Even previously, it was somewhat problematic to refer to the Calendar/Contacts/Mail server only by a local IP address (e.g., 172.16.1.123
) instead of by a domain name. That became even more problematic with the new systems.
The easiest solution was to use avahi
, a library that gives functionality equivalent to Apple's Bonjour software.
In the following, mercury
is the new hostname for the CentOS server, which can then be reached at the domain name mercury.local
from any device on the local network.
sudo yum install avahi
sudo hostnamectl set-hostname mercury
sudo firewall-cmd --add-port=5353/udp --permanent
sudo systemctl restart firewalld
sudo systemctl start avahi-daemon
sudo systemctl enable avahi-daemon
Edit the hosts
file.
sudo vi /etc/hosts
As follows:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 mercury.local
172.16.1.150 localhost localhost.localdomain localhost4 localhost4.localdomain4 mercury.local
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 mercury.local
To test the new domain name, open a terminal on another device, and try pinging:
ping mercury.local
Create SSL certificate
The new requirements for an SSL certificate to be accepted by iOS 13 and macOS 10.15 are given in https://support.apple.com/en-us/HT210176. The key points are:
- Key size must be greater than or equal to 2048 bits.
- Certificate must have a validity period of 825 days or fewer.
- Don't sign the certificate with SHA-1.
- DNS name must be in the Subject Alternative Name extension of the certificate.
- Certificate must have an ExtendedKeyUsage containing serverAuth.
The last two were the tricky bits; I found the following sources helpful in understanding what they were and how to proceed.
- How can I generate a self-signed certificate with SubjectAltName using OpenSSL?.
- OpenSSL Version V3 with Subject Alternative Name.
- More strict Server Certificate handling in iOS 13 macOS 10.15.
- iOS 13 Self Signed SSL certificate updates in Mail.
- How to create local TLS certificates for development on macOS.
- DER vs. CRT vs. CER vs. PEM Certificates and How To Convert Them.
Note that there are two different methods that are suggested out there. One way is to create your own Certificate Authority (CA) and use that to issue your SSL certificate. The other way is to just create the self-signed SSL certificate directly.
I found that the simpler method (just create the certificate directly) worked fine for me. I think the other way (creating a CA) might be better if you had the need to create multiple SSL certificates.
On the CentOS server, set up a directory to work in.
cd ~
mkdir work
cd work
Copy the default openssl
configuration file, and modify it.
cp /etc/ssl/openssl.cnf mercury.cnf
vi mercury.cnf
Find the section labelled v3_ca
and add two lines.
subjectAltName = DNS:mercury.local
extendedKeyUsage = serverAuth
Find this comment and add the following line.
# Extension copying option: use with caution.
copy_extensions = copy
Save and close the mercury.cnf
file. Run openssl
:
sudo openssl req -x509 -nodes -days 825 -newkey rsa:2048 -config mercury.cnf -keyout mercury.key -out mercury.crt
Answer the prompts:
Country Name (2 letter code) [XX]:US
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:.
Organization Name (eg, company) [Default Company Ltd]:.
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:mercury.local
Email Address []:
Verify the certificate has the right entries.
openssl x509 -text -in mercury.crt -noout
by looking for lines like this in the output:
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:mercury.local
X509v3 Extended Key Usage:
TLS Web Server Authentication
Copy files to appropriate locations.
sudo cp mercury.key /etc/ssl/private
sudo cp mercury.crt /etc/ssl/certs/
This step is likely overkill for this application (and may be pointless without also modifying the necessary apache
parameters), but it was recommended here, so I've been doing it.
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
cat /etc/ssl/certs/dhparam.pem | sudo tee -a /etc/ssl/certs/mercury.crt
For more information about this last step, see the following.
- What's the purpose of DH Parameters?.
- Deploying Forward Secrecy.
- Configuring Apache, Nginx, and OpenSSL for Forward Secrecy.
Install the certificate
- Mail the
mercury.crt
to the iPhone. - Double-click the
mercury.crt
attachment in the email message when received on the iPhone. - Briskly proceed, ignoring all threats and warnings, to install, accept, trust, etc. the certificate when prompted on the iPhone.
- Go to Settings App > General > Profile on the iPhone. mercury.crt should appear under the heading
configuration profile . - Tap the entry. It should show a status of
Verified ✔ .- Go to Settings App > General > About > Certificate Trust Settings.
- Under
enable full trust for root certificates , bravely enable mercury.local. - Tap the entry. It should show a status of
Modify server files for new certificate
Edit ssl.conf
file.
sudo vi /etc/httpd/conf.d/ssl.conf
As follows:.
#SSLCertificateFile /etc/pki/tls/certs/localhost.crt
#SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt
SSLCertificateFile /etc/ssl/certs/mercury.crt
and
#SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
#SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key
SSLCertificateKeyFile /etc/ssl/private/mercury.key
Restart apache
sudo systemctl restart httpd
Edit dovecot
ssl config file.
sudo vi /etc/dovecot/conf.d/10-ssl.conf
As follows (don't forget the unmatched '<' before the paths):
#SSLCertificateFile /etc/pki/tls/certs/localhost.crt
ssl_cert = </etc/ssl/certs/mercury.crt
ssl_key = </etc/ssl/private/mercury.key
Edit postfix
config file.
sudo vi /etc/postfix/main.cf
As follows:
myorigin = mercury.local
inet_interfaces = localhost, mercury.local
mydestination = $myhostname, localhost.$mydomain, localhost, mercury.local
smtpd_banner = mercury.local
Edit dovecot
config file.
sudo vi /etc/dovecot/conf.d/15-lda.conf
As follows:
postmaster_address = admin@mercury.local
Restart mail systems
sudo systemctl restart postfix
sudo systemctl restart dovecot
Recreate the CalDAV, CardDAV, and email accounts
Follow instructions in Replacement of macOS Server: Calendar, Contacts, and Mail,
except use mercury.local
wherever 172.16.1.123
appears.
Delete the Reminders app from iOS and macOS
It's dead to me.
To contact the author, send email.
As a side note, I recommend avoiding upgrading to iOS 13 or macOS 10.15 if at all possible. The most appalling change is that the Reminders app is not backwards compatible, and if you have any mix of devices running either of those new versions along with any device running pre iOS 13 or pre macOS 10.15, then shared Reminders is completely non-functional.
See the Apple support document, (cheerfully titled, "Get ready for the new Reminders app") which gives the official bad news.