0

I am in the process of developing an iOS Mobile Device Management server as a learning exercise. (See here: iOS Device Enrollment with Self-Developed MDM for more background) It is developed in Java, and uses JAX-RS for the service endpoints. I have 2 JAX-RS endpoints designed to support device enrollment. The /enroll endpoint returns a config profile that looks something like this to kickoff the device enrollment process:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Inc//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
   <dict>
      <key>PayloadContent</key>
      <dict>
         <key>URL</key>
         <string>http://myhost.com/profile</string>
         <key>DeviceAttributes</key>
         <array>
            <string>UDID</string>
            <string>IMEI</string>
            <string>ICCID</string>
            <string>MAC_ADDRESS_EN0</string>
            <string>DEVICE_NAME</string>
            <string>VERSION</string>
            <string>PRODUCT</string>
         </array>
         <key>Challenge</key>
         <string>MyChallengeGoesHere</string>
      </dict>
      <key>PayloadOrganization</key>
      <string>Example Inc.</string>
      <key>PayloadDisplayName</key>
      <string>Profile Service</string>
      <key>PayloadVersion</key>
      <integer>1</integer>
      <key>PayloadUUID</key>
      <string>fdb376e5-b5bb-4d8c-829e-e90865f990c9</string>
      <key>PayloadIdentifier</key>
      <string>com.example.mobileconfig.profile-service</string>
      <key>PayloadDescription</key>
      <string>Enter device into the Example Inc encrypted profile service</string>
      <key>PayloadType</key>
      <string>Profile Service</string>
   </dict>
</plist>

The /profile endpoint accepts a POST from the iOS device once I have installed the enroll profile, and returns the requested information about the device. From there, I install a PKCS#12-formatted certificate/private key using the following profile:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Inc//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>PayloadVersion</key>
        <integer>1</integer>
        <key>PayloadType</key>
        <string>Configuration</string>
        <key>PayloadUUID</key>
            <string>7bec0d56-5463-486a-921d-c61a065639ca</string>
            <key>PayloadIdentifier</key>
            <string>org.example.mymdm</string>
        <key>PayloadContent</key>
        <array>
            <dict>
                <key>PayloadType</key>
                <string>com.apple.security.pkcs12</string>
                <key>PayloadUUID</key>
                <string>d76f716b-2336-47ec-8b16-681f096df7b9</string>
                <key>PayloadVersion</key>
                <integer>1</integer>
                <key>PayloadIdentifier</key>
                <string>com.mymdm.p12</string>
                <key>Password</key>
                <string>__MY_CERT_PASSWORD__</string>
                <key>PayloadContent</key>
                <data>__MY_P12_CERT__</data>
              </dict>
          </array>
    </dict>
</plist>

At this point, everything has worked as expected. If I go to Settings->General->Profiles I see my PKCS#12 certificate profile listed. Now I am trying to configure the necessary profiles to allow for device checkin with my MDM service. I have created a profile that looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Inc//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>PayloadVersion</key>
        <integer>1</integer>
        <key>PayloadType</key>
        <string>Configuration</string>
        <key>PayloadUUID</key>
            <string>12999a48-f7a4-4e54-bb60-4e53fc63c293</string>
            <key>PayloadIdentifier</key>
            <string>org.example.mymdm.checkin</string>
        <key>PayloadContent</key>
        <array>
            <dict>
                <key>AccessRights</key>
                <integer>8191</integer>
                <key>CheckInURL</key>
                <string>https://mymdmhost.com:8443/mdm/checkin</string>
                <key>CheckOutWhenRemoved</key>
                <true/>
                <key>IdentityCertificateUUID</key>
                <string>7299f0c7-4c19-44a5-96e3-14d77f3093a4</string>
                <key>PayloadDescription</key>
                <string>Checkin</string>
                <key>PayloadDisplayName</key>
                <string>Checkin</string>
                <key>PayloadIdentifier</key>
                <string>com.apple.mdm.02D2C93A-3F6D-4E54-B15D-EECC1B7BD583</string>
                <key>PayloadOrganization</key>
                <string>Gener-Tech</string>
                <key>PayloadType</key>
                <string>com.apple.mdm</string>
                <key>PayloadUUID</key>
                <string>61da6cc7-2f7e-4aba-aabb-fa0af3f2258d</string>
                <key>PayloadVersion</key>
                <integer>1</integer>
                <key>ServerURL</key>
                <string>https://mymdmhost.com:8443/mdm/checkin</string>
                <key>SignMessage</key>
                <true/>
                <key>Topic</key>
                <string>com.apple.mgmt.External.*</string>
                <key>UseDevelopmentAPNS</key>
                <true/>
            </dict>
        </array>
    </dict>
</plist>

I tried accessing a URL that would push this profile down to the device, however when I tapped "Install" I got an error indicating that it couldn't find the certificate with that UUID. So, I modified the profile to include another PKCS#12 certificate within it:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Inc//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>PayloadVersion</key>
        <integer>1</integer>
        <key>PayloadType</key>
        <string>Configuration</string>
        <key>PayloadUUID</key>
            <string>12999a48-f7a4-4e54-bb60-4e53fc63c293</string>
            <key>PayloadIdentifier</key>
            <string>org.example.mymdm.checkin</string>
        <key>PayloadContent</key>
        <array>
            <dict>
                <key>PayloadType</key>
                <string>com.apple.security.pkcs12</string>
                <key>PayloadUUID</key>
                <string>7299f0c7-4c19-44a5-96e3-14d77f3093a4</string>
                <key>PayloadVersion</key>
                <integer>1</integer>
                <key>PayloadIdentifier</key>
                <string>com.mymdm.cert.p12</string>
                <key>Password</key>
                <string>__MY_CERT_PASSWORD__</string>
                <key>PayloadContent</key>
                <data>__MY_CERT_P12__</data>
              </dict>
            <dict>
                <key>AccessRights</key>
                <integer>8191</integer>
                <key>CheckInURL</key>
                <string>https://mymdmhost.com:8443/mdm/checkin</string>
                <key>CheckOutWhenRemoved</key>
                <true/>
                <key>IdentityCertificateUUID</key>
                <string>7299f0c7-4c19-44a5-96e3-14d77f3093a4</string>
                <key>PayloadDescription</key>
                <string>Checkin</string>
                <key>PayloadDisplayName</key>
                <string>Checkin</string>
                <key>PayloadIdentifier</key>
                <string>com.apple.mdm.02D2C93A-3F6D-4E54-B15D-EECC1B7BD583</string>
                <key>PayloadOrganization</key>
                <string>Gener-Tech</string>
                <key>PayloadType</key>
                <string>com.apple.mdm</string>
                <key>PayloadUUID</key>
                <string>61da6cc7-2f7e-4aba-aabb-fa0af3f2258d</string>
                <key>PayloadVersion</key>
                <integer>1</integer>
                <key>ServerURL</key>
                <string>https://mymdmhost.com:8443/mdm/checkin</string>
                <key>SignMessage</key>
                <true/>
                <key>Topic</key>
                <string>com.apple.mgmt.External.*</string>
                <key>UseDevelopmentAPNS</key>
                <true/>
            </dict>
        </array>
    </dict>
</plist>

However, now I see an error in the device console saying

The certificate for https://mymdmhost.com:8443/mdm/checkin is invalid.

I assume that this error is due to the fact that I am using self-signed certificates for testing. I have tried including another <dict /> with the self-signed certificate in PEM format as a trusted root. I've also tried creating an entirely separate profile with ONLY the trusted root as the payload. However, neither of these options has worked.

Is there something I'm doing wrong here? How can I go about testing my MDM and Checkin support using a self-signed certificate? Is that even possible?

Shadowman
  • 11,150
  • 19
  • 100
  • 198
  • Yes it is possible, i've run into many problems when setting up my MDM server such as the one you're facing now. But are you trying to install the profile through SCEP or are you just installing the raw profile straight? – TNguyen Dec 06 '17 at 22:20
  • Here's a great github tutorial on how to set it up but it doesn't teach you how to setup the SCEP. If you still run into trouble i'll be glad to help https://github.com/project-imas/mdm-server – TNguyen Dec 06 '17 at 22:21
  • No, I am not installing any certificates via scep. I would be using PKCS12 certificates, since this is just a simple proof-of-concept MDM. – Shadowman Dec 06 '17 at 22:41
  • also I would put the `.p12` payload data and info into the `enroll.mobileconfig` file. But you'll probably have to install a CA Cert before installt he mdm mobileconfig because it won't trust your server – TNguyen Dec 06 '17 at 23:11
  • By Enroll.mobileconfig, are you referring to the first XML document I posted in the question? – Shadowman Dec 06 '17 at 23:36
  • if you're doing this just for the purpose of seeing how it interacts with the phone then you can skip those steps. I.e. you only need to implement `/server` and `/checkIn`. And just have the device install the Enroll.mobileconfig straight (probably will have to install the CA crt first since its self signed though). The `/enroll` and `/profile` routes only need to be implemented for SCEP afaik – TNguyen Dec 06 '17 at 23:53
  • I can see how it interacts with the device. My goal as a learning exercise is to create a simple OTA enrollment MDM. I’d like to see how to do it from start to finish. – Shadowman Dec 06 '17 at 23:54
  • I'm not sure if you can get away with implementing an OTA enrollment mdm without following the SCEP – TNguyen Dec 07 '17 at 00:02
  • AFAIK you can either do it through SCEP or you just install the final profile straight. I can't really see the inspiration behind doing something inbetween – TNguyen Dec 07 '17 at 00:05
  • Maybe I'll code up a quick SCEP servlet to see how that will work, too. Thanks for your help! – Shadowman Dec 07 '17 at 15:20
  • I wrote up a quick and dirty SCEP servlet and managed to get everything working successfully. Device gets SCEP certs and even installs the MDM checkin profile. Thanks for your help! – Shadowman Dec 07 '17 at 19:40
  • great to hear! mdm can be a headache sometimes with iOS – TNguyen Dec 07 '17 at 20:16
  • I just posted another question related to MDMs and push notifications. Any ideas? https://stackoverflow.com/questions/47759637/ios-mdm-sending-mdm-push-notifications-from-java – Shadowman Dec 11 '17 at 19:41

0 Answers0