I have a unsigned mobileconfig file in xml format (template) generated by iphone configuration utility. I would like to encrypt and sign it using openssl and be able to inst
Incase if still anybody is having issues with signing and encrypting the profile with Ruby, following answer would be useful.
I have used OpenSSL module available in Ruby and Plist gem.
Consider a passcode restriction profile.
passcode_payload ={
'PayloadUUID' => 'RANDOM_STRING_UUID',
'PayloadOrganization' => 'PayloadOrganization',
'PayloadVersion' => 1,
'PayloadIdentifier' => 'com.test.PayloadIdentifier',
'PayloadType' => 'Configuration',
'PayloadDisplayName' => 'PayloadDisplayName',
'PayloadRemovalDisallowed' => false
}
passcode_payload_content = {
'PayloadDescription' => 'PayloadDescription',
'PayloadDisplayName' => 'PayloadDisplayName',
'PayloadIdentifier' => 'PayloadIdentifier',
'PayloadOrganization' => 'PayloadOrganization',
'PayloadType' => 'com.apple.mobiledevice.passwordpolicy',
'PayloadUUID' => "RANDOM_STRING_UUID",
'PayloadVersion' => 1,
'allowSimple' => true,
'forcePIN' => true
'maxPINAgeInDays' => 20,
'minComplexChars' => 1,
'minLength' => 4,
'requireAlphanumeric' => true
}
**
**
Usually for a normal profile the passcode_payload_content goes into the passcode_payload['PayloadContent'] as array of dictionaries.
passcode_payload['PayloadContent'] = [passcode_payload_content]
But for an encrypted profile, PayloadContent should be removed and EncryptedPayloadContent should be used as per the configuration profile key reference document.
from the doc,
To encrypt a profile do the following:
- Remove the
PayloadContentarray and serialize it as a proper plist.- Note that the top-level object in this plist is an array, not a dictionary.
- CMS-encrypt the serialized plist as enveloped data. Serialize the encrypted data in DER format.
- Set the serialized data as the value of as a Data plist item in the profile, using the key
EncryptedPayloadContent
Since top level object in the plist should be an array
passcode_payload_content_array = [passcode_payload_content]
Serializing to proper plist
to_be_encrypted_plist = passcode_payload_content_array.to_plist
Encrypting the certificate payload content,
device_certificate = OpenSSL::X509::Certificate.new File.read('deviceIdentityCertificate.pem')
encrypted_payload = OpenSSL::PKCS7.encrypt([device_certificate],to_be_encrypted_plist, OpenSSL::Cipher::Cipher::new("des-ede3-cbc"),OpenSSL::PKCS7::BINARY)
Add encrypted payload content to the original payload in der format
passcode_payload['EncryptedPayloadContent'] = StringIO.new(encrypted_payload.to_der)
**
**
signed_passcode_profile = OpenSSL::PKCS7.sign(SSL_CERTIFICATE, SSL_KEY, passcode_payload.to_plist, [], OpenSSL::PKCS7::BINARY)
At last, you can use
send_data signed_passcode_profile.to_der, :type => "application/x-apple-aspen-config"
to send the payload.