Skip to content

Instantly share code, notes, and snippets.

@rdj
Created August 4, 2015 16:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rdj/921a55bb56d4bc62bb52 to your computer and use it in GitHub Desktop.
Save rdj/921a55bb56d4bc62bb52 to your computer and use it in GitHub Desktop.
Using OpenSSL to create an iOS-compatible self-signed certificate with subjectAltName extension for use with NSURLConnection without overriding willSendRequestForAuthenticationChallenge
#!/bin/bash
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
ORGNAME=mytestorg
HOSTNAME=$(hostname -s)
KEY_LENGTH=4096
DIGEST=sha512
DAYS_VALID=9999
KEY_FILE="${DIR}/${HOSTNAME}.key"
CONF_FILE="${DIR}/${HOSTNAME}.conf"
CSR_FILE="${DIR}/${HOSTNAME}.csr"
CRT_FILE="${DIR}/${HOSTNAME}.crt"
OPENSSL=openssl
if [[ -x /usr/local/opt/openssl/bin/openssl ]]; then
# Use homebrew openssl
OPENSSL=/usr/local/opt/openssl/bin/openssl
fi
cat <<EOF > "${CONF_FILE}"
[ req ]
distinguished_name = req_distinguished_name
req_extensions = v3_req
[ req_distinguished_name ]
0.organizationName = Organization Name (eg, company)
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_max = 64
[ v3_req ]
basicConstraints = critical,CA:true,pathlen:1
keyUsage = nonRepudiation, digitalSignature, keyEncipherment, keyCertSign
subjectAltName = @alt_names
[alt_names]
DNS.1 = ${HOSTNAME}.local
DNS.2 = localhost
DNS.3 = ${HOSTNAME}
EOF
$OPENSSL req -new -newkey "rsa:${KEY_LENGTH}" -keyout "${KEY_FILE}" "-${DIGEST}" -config "${CONF_FILE}" -out "${CRT_FILE}" -nodes -subj "/O=${ORGNAME}/CN=${HOSTNAME}" -x509 -extensions v3_req -days "${DAYS_VALID}"
rm "${CONF_FILE}"
$OPENSSL x509 -in "${CRT_FILE}" -text
# Trusting on Mac:
# 1. This command will launch keychain utilities in import mode
# 2. Choose the login keychain
# 3. Double click the newly imported cert
# 4. Expand the trust section
# 5. Choose "Always Trust"
# 6. Close the pop-up dialog
# 7. Should prompt you for your admin password
#
# On an iOS device:
# 1. Email the .crt file to yourself
# 2. Tap in email
# 3. Choose "Install"
# 4. Enter your passcode
# 5. Choose "Install" (should see ROOT CERTIFICATE warning)
# 6. Choose "Install" again
# 7. Should so Verified with green checkmark
#
# On an iOS simulator, same steps but replace steps 1-2 with dragging
# the .crt file into the simulator window. Alternately, you could
# install into the trust stores of all your simulators at once by
# using something like the iostrust rubygem.
open "${CRT_FILE}"
@rdj
Copy link
Author

rdj commented Aug 4, 2015

Remember, iOS 9 by default requires perfect forward secrecy ciphers, so if your development environment isn't set up that way, you'll have to either fix it or add an exception to your Info.plist (which is probably what you were trying to avoid in the first place). Something like this:

    <key>NSAppTransportSecurity</key>
    <dict>
      <key>NSExceptionDomains</key>
      <dict>
        <key>localhost</key>
        <dict>
          <key>NSExceptionRequiresForwardSecrecy</key>
          <false/>
        </dict>
      </dict>
    </dict>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment