0

I have set up 802.1x authentication on my wireless network with EAP-TLS. The use case here is that I would like the presence of a certificate to be both necessary and sufficient for connecting to the network. The condition is that there should be no passwords of any kind involved in any point of the authentication process.

After generating the client certificate, I used openssl 1.1 to generate a .pfx file in PKCS12 format (the server certificate is different and is signed by Let's Encrypt to avoid requiring clients to trust the server CA). I sent it to my Android device, installed it as a wifi certificate, and it worked great.

Today I had a guest come by who wanted to connect using an iPhone. They were able to download the certificate (iOS seems to call it a profile), but when they went to import it, it asked for a password. The interface would not allow them to enter a blank password, the "Install" button would be greyed out unless they typed something. We could not figure out any way to convince iOS that the certificate had no password, nor a blank password. This comment seems to indicate that doing so is not possible.

I then tried the steps mentioned in this answer which gave the same result. I tried following the steps in this question but when piping the certificates, all I got was the error unable to load certificates. I thought -keypbe NONE -certpbe NONE might be the important part so I regenerated the .pfx file from scratch and added those parameters, but with the same result (iPhone prompted for password). Lastly I saw in this answer the -nomac flag, so I tried adding that, but this time the iPhone refused to load the certificate at all (errored with "Invalid Profile").

I am using openssl 1.1 to avoid any of the algorithm issues with openssl 3. How can I generate a PKCS12 container with no password that is accepted by iOS devices?

4
  • Re #218964/218969: the direct pipe openssl pkcs12 -in old -nodes | openssl pkcs12 -export -certpbe NONE -keypbe NONE [-nomac] -out new only works if old file has keybag before certbag, which varies depending where it's from; if you instead create a temp file openssl pkcs12 -in old -nodes >temp && openssl pkcs12 <temp -export ... it works always (but leaves a file with your key which you need to securely delete), and so does ( openssl pkcs12 -in old -nocerts -nodes; openssl pkcs12 -in old -nokeys ) | openssl pkcs12 -export ... (but you must enter pw twice). Commented Oct 29, 2022 at 0:40
  • However -keypbe NONE -certpbe NONE -nomac IS correct for no password at all, and if iOS doesn't accept that there's nothing else you can do. Commented Oct 29, 2022 at 0:43
  • You could create a version of the pkcs12 file with a password; you only need to enter the password on the iPhone once (when installing the certificate), not each time it's used. Commented Oct 29, 2022 at 7:36
  • Thanks all...looks like there may not be a way to do this. However I was looking on the Apple help site and it says "If the payload contains the password, the identity can be installed without prompting the user for it." What feature is this referring to - is there a way to embed a password? How can I use this with openssl?
    – matoro
    Commented Nov 1, 2022 at 22:56

1 Answer 1

1

I did manage to solve this and wanted to share the solution here for anyone attempting the same use case. What I did was export the certificate with an extremely long password, then create a .mobileconfig file with the certificate and password embedded in it.

From a threat model perspective, this .mobileconfig file is functionally the same as the unprotected certificate used for Android clients. The password in question will never have to be entered by a human.

At first I attempted to write this file by hand using the Apple documentation, but found that any mistakes, either syntactic or semantic, result in the same useless "Invalid configuration profile" message. So I borrowed a Mac to use Apple Configurator 2. The steps are as follows: create a new profile of type Certificate and attach the PKCS12, including the password (the app requires you to enter a password here, so there really is no way to distribute a passwordless PKCS12). Then create a profile of type Wifi and enter the details including SSID, whether you want to enable autojoin, etc. Add both these profiles to a new blueprint, export that blueprint to a .mobileconfig, and then distribute that, and it works! There are several places where the user will have to accept an untrusted connection, that you could probably cut down on, but I did not bother.

My final .mobileconfig is as follows (sensitive parts redacted):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>PayloadContent</key>
        <array>
                <dict>
                        <key>AutoJoin</key>
                        <true/>
                        <key>CaptiveBypass</key>
                        <false/>
                        <key>DisableAssociationMACRandomization</key>
                        <false/>
                        <key>EAPClientConfiguration</key>
                        <dict>
                                <key>AcceptEAPTypes</key>
                                <array>
                                        <integer>13</integer>
                                </array>
                                <key>TLSMaximumVersion</key>
                                <string>1.2</string>
                                <key>TLSMinimumVersion</key>
                                <string>1.2</string>
                        </dict>
                        <key>EncryptionType</key>
                        <string>WPA2</string>
                        <key>HIDDEN_NETWORK</key>
                        <false/>
                        <key>IsHotspot</key>
                        <false/>
                        <key>PayloadCertificateUUID</key>
                        <string>[REDACTED UUID]</string>
                        <key>PayloadDescription</key>
                        <string>Configures Wi-Fi settings</string>
                        <key>PayloadDisplayName</key>
                        <string>Wi-Fi</string>
                        <key>PayloadIdentifier</key>
                        <string>com.apple.wifi.managed.[REDACTED UUID]</string>
                        <key>PayloadType</key>
                        <string>com.apple.wifi.managed</string>
                        <key>PayloadUUID</key>
                        <string>[REDACTED UUID]</string>
                        <key>PayloadVersion</key>
                        <integer>1</integer>
                        <key>ProxyType</key>
                        <string>None</string>
                        <key>SSID_STR</key>
                        <string>[REDACTED SSID]</string>
                </dict>
                <dict>
                        <key>Password</key>
                        <string>[REDACTED PASSWORD]</string>
                        <key>PayloadCertificateFileName</key>
                        <string>[REDACTED FILENAME]</string>
                        <key>PayloadContent</key>
                        <data>
                        [REDACTED CERTIFICATE BASE64]
                        </data>
                        <key>PayloadDescription</key>
                        <string>Adds a PKCS#12-formatted certificate</string>
                        <key>PayloadDisplayName</key>
                        <string>[REDACTED FILENAME]</string>
                        <key>PayloadIdentifier</key>
                        <string>com.apple.security.pkcs12.[REDACTED UUID]</string>
                        <key>PayloadType</key>
                        <string>com.apple.security.pkcs12</string>
                        <key>PayloadUUID</key>
                        <string>[REDACTED UUID]</string>
                        <key>PayloadVersion</key>
                        <integer>1</integer>
                </dict>
        </array>
        <key>PayloadDisplayName</key>
        <string>Untitled</string>
        <key>PayloadIdentifier</key>
        <string>[REDACTED NAMESPACE]</string>
        <key>PayloadRemovalDisallowed</key>
        <false/>
        <key>PayloadType</key>
        <string>Configuration</string>
        <key>PayloadUUID</key>
        <string>[REDACTED UUID]</string>
        <key>PayloadVersion</key>
        <integer>1</integer>
</dict>
</plist>

There you go, passwordless wifi for iOS clients. As a bonus, this same .mobileconfig also works for macOS clients - just distribute it on a USB stick or something.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .