New Developer’s Resource Documents from Apple

« Return to previous page.

Apple Developer’s Resource – What’s New in iPhone OS

.::. .::. .::. .::. .::. .::. .::. .::. .::. .::. .::. .::. .::. .::. .::. .::. .::.

Apple Developer’s Resource – Over-the-Air Profile Delivery & Configuration root certificate and install it so it becomes trusted.

We are using a self-signedcertificate here, for production it should be issued by a known CA.

After that, go ahead and enrollWELCOME_MESSAGE} If you used a self-signed certificate above, when the user goes to this page, Safari asks whether you want totrust the server’s SSL certificate. Agreeing allows you to view the page. This is not sufficient for enrollment,however.Regardless of whether the site certificate is self-signed or not, the enrollment process with the SCEP servicealso requires the device to trust the custom certificate authority’s root certificate, which means adding theCA root certificate to the device’s trusted anchors list. To do this, you must create a URL handler that providesthe certificate with the correct MIME type. Root Certificate (/CA) URL Handler The link to /CA in the welcome page provides a means for the user to add the custom certificate authority’sroot certificate to the device’s trusted anchors list. This is required for the SCEP stage of the enrollmentprocess.After Safari on iPhone loads the root certificate from that URL, it asks the user for permission to add the newroot certificate to the device’s trusted anchors list. (You should access this page only over a secure connection.)The handler in Listing 2-3 sends the root certificate.Listing 2-3Handler for /CA URL world.mount_proc("/CA") { |req, res|res['Content-Type'] = "application/x-x509-ca-cert"res.body = @@root_cert.to_der} After the user has downloaded the root certificate from a trusted web server over HTTPS, the user can clickto continue the enrollment process. Enrollment (/enroll) URL Handler Listing 2-4 provides a handler for the /enroll link on the welcome page. 20 Profile Service Handlers 2010-03-24 | © 2010 Apple Inc. All Rights Reserved. CHAPTER 2 Creating a Profile Server for Over-The-Air Enrollment and Configuration
Page 21
Listing 2-4Handler for /enroll URL world.mount_proc("/enroll") { |req, res|HTTPAuth.basic_auth(req, res, "realm") {|user, password|user == 'apple' && password == 'apple'}res['Content-Type'] = "application/x-apple-aspen-config"configuration = profile_service_payload(req, "signed-auth-token")signed_profile = OpenSSL::PKCS7.sign(@@ssl_cert, @@ssl_key, configuration, [], OpenSSL::PKCS7::BINARY)res.body = signed_profile.to_der} The handler above performs very limited authentication to identify the user. The user logs in by sending theword apple as the user name and password over a connection authenticated with HTTP basic authentication.In a production server environment, you should instead tie this code into a directory service or some otheraccount system. To learn more about tying a Ruby application into a directory service, read the article Using Open Directory from PHP and Ruby to Manage Mailing Lists for Leopard Server. This handler sets the MIME type of its response to application/x-apple-aspen-config , so Safari oniPhone treats the response as a configuration profile.The profile_service_payload function (“Profile Service Payload” (page 21)) produces a specialconfigurationthattellsthephonetoenrollitselfintheprofileservice.Theliteralstring "signed-auth-token" should be replaced with an authorization token from the authentication service that verified the user'scredentials.Finally, this function signs the profile by calling OpenSSL::PKCS7.sign and sends the signed profile to thedevice.Security Note: This exchange occurs through HTTPS to protect the user name, password, and signedauthorization token, so signing with the SSL certificate does not provide additional security. It does, however,make sense if the profile service uses a different SSL certificate and resides on a separate HTTPS server. Profile Service Payload The first payload sent to the device (after establishing that it is allowed to enroll) is the profile service payload.This payload is sent by a call to profile_service_payload(req, "signed-auth-token") from the /enroll handler (Listing 2-4).For a sample profile service payload, see “Sample Phase 1 Server Response” in Enterprise Deployment Guide.Listing 2-5 profile_service_payload function def profile_service_payload(request, challenge)payload = general_payload()payload['PayloadType'] = "Profile Service" # do not modifypayload['PayloadIdentifier'] = "com.acme.mobileconfig.profile-service"# strings that show up in UI, customisablepayload['PayloadDisplayName'] = "ACME Profile Service" Profile Service Handlers 21 2010-03-24 | © 2010 Apple Inc. All Rights Reserved. CHAPTER 2 Creating a Profile Server for Over-The-Air Enrollment and Configuration
Page 22
payload['PayloadDescription'] = "Install this profile to enroll for secureaccess to ACME Inc."payload_content = Hash.newpayload_content['URL'] = "https://" + service_address(request) + "/profile"payload_content['DeviceAttributes'] = ["UDID", "VERSION"=begin"PRODUCT", # ie. iPhone1,1 or iPod2,1"MAC_ADDRESS_EN0", # WiFi MAC address"DEVICE_NAME", # given device name "iPhone"# Items below are only available on iPhones"IMEI","ICCID"=end];if (challenge && !challenge.empty?)payload_content['Challenge'] = challengeendpayload['PayloadContent'] = payload_contentPlist::Emit.dump(payload)end This function starts by calling general_payload , which sets the version and organization (these valuesdon’t change on a given server) and returns a template payload that provides a UUID for the profile.The payload content provides a URL where the device should send its identification (using HTTP POST), alongwith a list of attributes that the server expects the device to provide (software version, IMEI, and so on).If an authorization token (representing a user authentication) is passed in from the caller (shown in Listing 2-4 (page 21)), that token is added as the Challenge attribute.In response, the device sends back the list of requested attributes along with their values. If the server senta Challenge valueinitsrequest,thedevicealsoincludesthisvaluealongwiththerequesteddeviceattributes.Finally, to prove it is an iPhone, the device signs this identification with its device certificate. This responseis sent to the handler for the /profile URL. 22 Profile Service Handlers 2010-03-24 | © 2010 Apple Inc. All Rights Reserved. CHAPTER 2 Creating a Profile Server for Over-The-Air Enrollment and Configuration
Page 23
Values Note: The payload type must not be changed; the phone expects to see the literal string "ProfileService" .The identifier should be changed to an appropriate reverse-DNS-style identifier. The identifier should remainconstant for any given profile service.The display name and description values are presented in the user interface to explain to the user what isabout to happen. Phase 2: Certificate Enrollment Profile Request (/profile) URL Handler The handler for the /profile URL is called twice—once to send the device authentication request beforethe device is allowed to enroll using SCEP, then again after the SCEP step to deliver the final profile to thedevice.In this handler, the profile server receives a PKCS#7 signed data payload from the device, which it then unpackand verifies. For a sample of this profile, see “Sample Phase 2 Device Response” in Enterprise DeploymentGuide.To make it easier to follow, the /profile handler is divided into smaller pieces. The first piece of this handleris shown in Listing 2-6.Listing 2-6Handler for /profile URL, part 1 of 7 world.mount_proc("/profile") { |req, res|# verify CMS blob, but don't check signer certificatep7sign = OpenSSL::PKCS7::PKCS7.new(req.body)store = OpenSSL::X509::Store.newp7sign.verify(nil, store, nil, OpenSSL::PKCS7::NOVERIFY)signers = p7sign.signers Security Note: The reference implementation does not verify the signer here. You should verify it againsta trust store made up of intermediates from the device certificate authority up to the root CA and the hierarchyyou'll use to issue profile service identities.If the device signed the request with a certificate that belongs to the hierarchy that issues profile serviceidentities (that is, if this device has enrolled previously), execution follows the first path (shown in Listing2-7). This path either issues an updated encrypted configuration or, as implemented here, redirects the deviceto enroll again. For testing purposes, any device that has gotten a profile previously must reenroll.Listing 2-7Handler for /profile URL, part 2 of 7 # this should be checking whether the signer is a cert we issued# if (signers[0].issuer.to_s == @@root_cert.subject.to_s)print "Request from cert with serial #{signers[0].serial}"" seen previously: #{@@issued_first_profile.include?(signers[0].serial.to_s)}"" (profiles issued to #{@@issued_first_profile.to_a}) \n" Profile Service Handlers 23 2010-03-24 | © 2010 Apple Inc. All Rights Reserved. CHAPTER 2 Creating a Profile Server for Over-The-Air Enrollment and Configuration
Page 24
if (@@issued_first_profile.include?(signers[0].serial.to_s))res.set_redirect(WEBrick::HTTPStatus::MovedPermanently, "/enroll")print res By this point, any previously fully enrolled clients have been redirected to the enrollment page to enrollagain.If the code gets past this step, it has received either a list of properties or a new request for a final profile.In Listing 2-8, the encrypted profile is generated. Because this is part of phase 3 (device configuration), it isincluded here without further comment, and is explained further in “The /profile Handler Revisited” (page25).Listing 2-8Handler for /profile URL, part 3 of 7 else@@issued_first_profile.add(signers[0].serial.to_s)payload = client_cert_configuration_payload(req)# vpn_configuration_payload(req)#File.open("payload", "w") { |f| f.write payload }encrypted_profile = OpenSSL::PKCS7.encrypt(p7sign.certificates,payload, OpenSSL::Cipher::Cipher::new("des-ede3-cbc"), OpenSSL::PKCS7::BINARY)configuration = configuration_payload(req, encrypted_profile.to_der)end The code in Listing 2-9 handles the case where the device sent its identification. This part should ideally verifythat the response was signed with a valid device certificate and should parse the attributes.Listing 2-9Handler for /profile URL, part 4 of 7 else#File.open("signeddata", "w") { |f| f.write p7sign.data }device_attributes = Plist::parse_xml(p7sign.data)#print device_attributes The next bit of code, Listing 2-10, is commented out with =begin and =end . It shows how you can restrictissuance of profiles to a single device (by its unique device ID, or UDID) and verify that the Challenge is thesame as the Challenge value issued previously.In a production environment, this is typically replaced by site-specific code that queries a directory serviceto validate the authorization token and queries a database of authorized UDID values for devices owned byyour organization.Listing 2-10Handler for /profile URL, part 5 of 7 =begin# Limit issuing of profiles to one device and validate challengeif device_attributes['UDID'] == "213cee5cd11778bee2cd1cea624bcc0ab813d235"&&device_attributes['CHALLENGE'] == "signed-auth-token"end=end 24 Profile Service Handlers 2010-03-24 | © 2010 Apple Inc. All Rights Reserved. CHAPTER 2 Creating a Profile Server for Over-The-Air Enrollment and Configuration
Page 25
Next, the snippet in Listing 2-11 obtains a payload to send to the device that will tell it how to complete theenrollment process. The details of this configuration are described in the discussion of encryption_cert_payload .Listing 2-11Handler for /profile URL, part 6 of 7 configuration = encryption_cert_payload(req, "")end Finally, if this function has nothing to send, it raises an exception that makes the http request fail. Otherwiseit signs the profile to be sent and returns it. These bits of code are shown in Listing 2-12 (page 25).Listing 2-12Handler for /profile URL, part 7 of 7 if !configuration || configuration.empty?raise "you lose"else# we're either sending a configuration to enroll the profile service cert# or a profile specifically for this deviceres['Content-Type'] = "application/x-apple-aspen-config"signed_profile = OpenSSL::PKCS7.sign(@@ssl_cert, @@ssl_key, configuration, [], OpenSSL::PKCS7::BINARY)res.body = signed_profile.to_derFile.open("profile.der", "w") { |f| f.write signed_profile.to_der }end} After this function sends the configuration to tell the device how to enroll, the device enrolls its identityusing SCEP. Then, it sends a request for the /profile URL associated with this handler a second time toobtain the final profile.The actual payload is described in “Configuration Profile Payload” (page 26) and “Encryption Certificate Payload” (page 26). For a sample configuration profile, see “Sample Phase 3 Server Response With SCEP Specifications” in Enterprise Deployment Guide. Phase 3: Device Configuration The /profile Handler Revisited Previously, Listing 2-8 (page 24) showed the encrypted profile generation process. The code in questiondoesn’t actually run until phase 3, however, so the details were deferred. This section revisits that section ofthe /profile handler and provides explanation.The encrypted profile is generated as follows: ■ A configuration is generated with a set of configuration payloads. (See “Configuration Profile Format”in Enterprise Deployment Guide to learn about the contents of these payloads in detail.)In this reference implementation, every device gets the same profile. If desired, however, the Challenge information can be used to identify the user requesting the profile, and the code can generate a profilespecific to that user.Profile Service Handlers 25 2010-03-24 | © 2010 Apple Inc. All Rights Reserved. CHAPTER 2 Creating a Profile Server for Over-The-Air Enrollment and Configuration
Page 26
Similarly, the device information provided can be used to generate a profile specific to a given deviceor a particular type of device (for example, providing a different profile for different models of iPhone). ■ The configuration is encrypted with the public key of the device that signed the original request. ■ The encrypted blob of data is wrapped in a configuration profile.The details of this encrypted blob are explained in the descriptions of client_cert_configuration_payload (Listing A-1 (page 29)) and configuration_payload (“Configuration Profile Payload” (page 26)).Listing 2-13Handler for /profile URL, part 3 of 7 (revisited) else@@issued_first_profile.add(signers[0].serial.to_s)payload = client_cert_configuration_payload(req)# vpn_configuration_payload(req)#File.open("payload", "w") { |f| f.write payload }encrypted_profile = OpenSSL::PKCS7.encrypt(p7sign.certificates,payload, OpenSSL::Cipher::Cipher::new("des-ede3-cbc"), OpenSSL::PKCS7::BINARY)configuration = configuration_payload(req, encrypted_profile.to_der)end Configuration Profile Payload The configuration profile payload (provided by configuration_payload ) resembles the profile servicepayload described in “Profile Service Payload” (page 21). The only difference is in the payload its carries.For a sample profile for this phase, see “Sample Phase 4 Device Response” in Enterprise Deployment Guide. Encryption Certificate Payload Listing 2-14 describes the encryption certificate payload. This payload tells the client how to complete theenrollment process.Listing 2-14 encryption_cert_payload function def encryption_cert_payload(request, challenge)payload = general_payload()payload['PayloadIdentifier'] = "com.acme.encrypted-profile-service"payload['PayloadType'] = "Configuration" # do not modify# strings that show up in UI, customisablepayload['PayloadDisplayName'] = "Profile Service Enroll"payload['PayloadDescription'] = "Enrolls identity for the encrypted profileservice"payload['PayloadContent'] = [scep_cert_payload(request, "Profile Service",challenge)];Plist::Emit.dump(payload) 26 Profile Service Handlers 2010-03-24 | © 2010 Apple Inc. All Rights Reserved. CHAPTER 2 Creating a Profile Server for Over-The-Air Enrollment and Configuration
Page 27
end The scep_cert_payload function is described in “SCEP Certificate Payload” (page 27). SCEP Certificate Payload As the name of the scep_cert_payload function suggests, the function shown in Listing 2-15 producesan SCEP payload that gives the device the information it needs to enroll a certificate.Listing 2-15 scep_cert_payload function def scep_cert_payload(request, purpose, challenge)payload = general_payload()payload['PayloadIdentifier'] = "com.acme.encryption-cert-request"payload['PayloadType'] = "com.apple.security.scep" # do not modify The payload type of com.apple.security.scep indicates an SCEP payload and the content specifies theparameters. # strings that show up in UI, customisablepayload['PayloadDisplayName'] = purposepayload['PayloadDescription'] = "Provides device encryption identity"payload_content = Hash.newpayload_content['URL'] = "https://" + service_address(request) + "/scep" First and foremost, there is the base URL for the SCEP service, which for convenience is handled by the sampleservice as well. It looks a little different for IOS ( http://scep-server/cgi-bin/pkiclient.exe ) andWindows SCEP servers ( http://scep-server/certsrv/mscep/mscep.dll ). =begin# scep instance NOTE: required for MS SCEP serverspayload_content['Name'] = "" =end The service can provide different certificate issuing services parameterized on the Name value that becomespart of the final URL. In the case of Windows, this value needs to be set, although any value will do. payload_content['Subject'] = [ [ [ "O", "ACME Inc." ] ], [ [ "CN", purpose + " (" + UUIDTools::UUID.random_create().to_s + ")" ] ] ];if (!challenge.empty?)payload_content['Challenge'] = challengeend The subject allows the client to specify the requested subject. In this case, it is populated by the profile service.Some services may not want to grant the client the ability to specify it, and may use the Challenge toencode the identity of the requester.X.509 subjects are elaborate structures and are mimicked here as an array of arrays, to fully specify it. Eachkey-value pair is specified as an array. The key is the first element and is a string with a value that is eitheran ID (for example, "0.9.2342.19200300.100.1.25" is DC) or one of the recognized abbreviations (CN, C, ST, L,O, OU). The example above represents a subject that will often be displayed as "/O=ACME Inc./CN={purpose}({random UUID})".Profile Service Handlers 27 2010-03-24 | © 2010 Apple Inc. All Rights Reserved. CHAPTER 2 Creating a Profile Server for Over-The-Air Enrollment and Configuration
Page 28
payload_content['Keysize'] = 1024 Next up are some, simple parameters, although they require some consideration. Key size requests the deviceto generate a keypair of a certain size. Only 1024-bit and 2048-bit key sizes should be used. Keys larger than2048 bits are not supported. In general, 1024-bit keys are recommended because of the overhead involvedin generating 2048-bit keys. payload_content['Key Type'] = "RSA" The key type should always be RSA because this reference implementation (and in practice, SCEP) onlysupport RSA keys. payload_content['Key Usage'] = 5 # digital signature (1) | key encipherment(4) Key usage specifies the purposes the key can be used for and is a bit mask. Bit 0 (value 1) specifies digitalsignature, and bit 2 specifies key encipherment. Note that the MS SCEP server will only issue signature orencryption, not both. =beginpayload_content['CAFingerprint'] = StringIO.new(OpenSSL::Digest::SHA1.new(@@root_cert.to_der).digest)=end SCEP can run over HTTP, as long as the CA cert is verified out of band. This functionality is currently disabled(as shown above) because iPhone does not currently support this. This function supports such operation byadding the fingerprint to the SCEP payload that the phone downloads over HTTPS during enrollment, asshown below: payload['PayloadContent'] = payload_content;payloadendpayload = client_cert_configuration_payload(req)# vpn_configuration_payload(req) 28 Profile Service Handlers 2010-03-24 | © 2010 Apple Inc. All Rights Reserved. CHAPTER 2 Creating a Profile Server for Over-The-Air Enrollment and Configuration
Page 29
This example of a configuration profile payload shown in Listing A-1 contains a webclip that points the userto an intranet site and provides a payload to allow the phone to enroll an SSL client authentication cert thatwill be required to access the protected assets.Listing A-1 client_cert_configuration_payload function def client_cert_configuration_payload(request)webclip_payload = general_payload()webclip_payload['PayloadIdentifier'] = "com.acme.webclip.intranet"webclip_payload['PayloadType'] = "com.apple.webClip.managed" # do not modify# strings that show up in UI, customisablewebclip_payload['PayloadDisplayName'] = "ACME Inc."webclip_payload['PayloadDescription'] = "Creates a link to the ACME intraneton the home screen"# allow user to remove webclipwebclip_payload['IsRemovable'] = true# the linkwebclip_payload['Label'] = "ACME Inc."webclip_payload['URL'] = "https://" + service_address(request).split(":")[0]# + ":4443/" The webclip creates an icon that will take the user to the URL mentioned. In this case we allow the user todelete the webclip. client_cert_payload = scep_cert_payload(request, "Client Authentication", "foo"); The client certificate is enrolled by creating an SCEP payload similar to the one used for decrypting anencrypted payload. In a real-world implementation, you typically add additional parameters to specify keyusage, policies, and subject alternative names to make it easier for the server to match the enrolled identitywith a particular user and that user’s capabilities. Plist::Emit.dump([webclip_payload, client_cert_payload])end This function ends by dumping the raw array of payloads. The caller wraps them in a configuration profileand signs them, as shown in Listing 2-8 (page 24).For more information about the types of payloads that are available, see the iPhoneOSEnterpriseDeploymentGuide at" height="600" width="100%" type="application/x-shockwave-flash" data="http://d1.scribdassets.com/ScribdViewer.swf" style="outline:none;" >

diggFacebookTechnoratiTwitter