If you still have problems signing and encrypting your profile using Ruby, the following answer will be helpful.
I used the OpenSSL module available in Ruby and Plist gem.
Consider the password 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 }
**
Encryption
**
Usually for a normal profile, passcode_payload_content
goes into passcode_payload['PayloadContent']
as an array of dictionaries.
passcode_payload ['PayloadContent'] = [passcode_payload_content]
But for the encrypted profile, PayloadContent
should be deleted and EncryptedPayloadContent
should be used in accordance with the configuration profile key reference document .
from the document
To encrypt a profile, follow these steps:
Remove the PayloadContent
array and serialize it as the correct plist. Note that the top-level object in this plist is an array, not a dictionary. CMS encryption of serialized plist as data envelopes. Serialize encrypted data in DER format. Set serialized data as a value as a data item in a profile using the EncryptedPayloadContent
key
Since the top level object in plist should be an array
passcode_payload_content_array = [passcode_payload_content]
Serialization for the correct plist
to_be_encrypted_plist = passcode_payload_content_array.to_plist
Encrypting the contents of the certificate payload,
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 the format
passcode_payload['EncryptedPayloadContent'] = StringIO.new(encrypted_payload.to_der)
**
Conclusion
**
signed_passcode_profile = OpenSSL::PKCS7.sign(SSL_CERTIFICATE, SSL_KEY, passcode_payload.to_plist, [], OpenSSL::PKCS7::BINARY)
Finally you can use
send_data signed_passcode_profile.to_der, :type => "application/x-apple-aspen-config"
to send the payload.