I have few questions regarding Identity certificate in Profile Payload.
Forgive the ignorance, if some questions are basic.
1.) I found that, we can either use SCEP standard or PKCS12 certificate directly for device identification. SCEP is recommended, since private key will be known only to the device. So in case If I am going to implement SCEP server, do I need to maintain the list of Public key of Identity certificates mapped to the device, so that I can use it later for encrypting?
2.) What is the best possible way to implement SCEP server.? Is there any reliable robust methods available to adopt it instead of writing everything on our own?
3.) What if the identity certificate is expired?
As a basic version while playing around, I tried to add my own p12 certificate to the Payload without using SCEP.
I tried to add the base64 encoded p12 certificate in the identity payloadcontent key,as mentioned in some link reference. I got an error
The identity certificate for “Test MDM Profile” could not be found
while installing profile.
identity_payload['PayloadType'] = 'com.apple.security.pkcs12'
identity_payload['PayloadUUID'] = "RANDOM-UUID-STRING"
identity_payload['PayloadVersion'] = 1
identity_payload['PayloadContent'] = Base64.encode64(File.read "identity.p12")
identity_payload['Password'] = 'p12Secret'
When I checked 'Configuration Profile key reference', it was mentioned that I should send Binary representation of Payload in Data.
So I tried,
identity_payload['PayloadContent'] = ConvertToBinary(File.read "identity.p12")
I got,
The password for the certificate “IdentityCertificate” is incorrect
I am supplying valid password for exporting the p12 certificate.
What am I doing wrong?
Answering your question:
1) Do I need to maintain the list of Public key of Identity certificates mapped to the device, so that I can use it later for encrypting?
Yes. You need some kind of mapping. You can do couple of ways:
Just store it in DB a mapping between certificate common name and device UDID.
Make CN contain UDID (I like this method, because it simplifies initial checks)
And as you pointed out you will need public key to encrypt payloads for this device.
2) What is the best possible way to implement SCEP server.? Is there any reliable robust methods available to adopt it instead of writing everything on our own?
There are open source implementation of SCEP. As example jSCEP have it (I used it) and EJBCA have it (I used it too). I saw other implementation (in Ruby and so on). So, you can find an choose something which works with your stack.
3) You need to renew identity certificate before it expeires (the same way as for any other certificates).
4) If your profile doesn't work, I would recommend you to create the same profile in iPhone Configuration Utility and compare with yours. Most of the time, you missed just one tag or something like that (it will take a lot to figure it out without comparing it with working one).
Related
I'm debating and need to know the implications of not using the SCEP protocol for the mdm enrolment, more precisely the Identity certificate (the certificate credential used for authentication). I'm talking about the certificate in the Identity section on IPCU, as shown in the image below, with the red arrow.
I wont be pushing down profiles with sensitive informations (like vpn, email, etc configurations and/or passwords).
My use case will be 99%:
Block/unblock apps by rating
Lock/unlock device
Block/unlock web domains
From reading around StackOverflow (here and here) the following scenarios can happen.
If someone get access to the certificate he will be able to impersonate an enrolled device, but he will only be able to receive commands/profiles and not initiate commands/profiles. Am I right?
A man in the middle attack can get access to the certificate
The advantage of using the PKCS12 embedded within the profile is that it is faster to implement and no external dependencies (SCEP server) but I'm not so sure about the disadvantages. So my questions and doubts is:
What can a malicious person do with the private key from the Identity certificate?
Can it be a security breach going with the PKCS12 embedded approach?
This is mostly a question of SCEP vs PKCS12 embedded within the profile, pros and cons.
Here my thought on that:
1) If you are building a prototype or a small not critical service then go with PKCS12.
2) If you are building a serious product (production and touching devices of people with sensitive info) then go with SCEP (you can get a free SCEP servers. It's not that complex).
Frankly, If I was on the dark side (trying to hack it) I don't think that I would attack PKCS12 vs SCEP (it's not the weakest link)
However, let say, I say I decided to try to hack it
I would try to do man in the middle. I will try to capture communicarion, save PKCS12 and password for it
I will use it to authenticate to MDM server.
You are right, I can't trigger any commands, but I can start probing your code to find where you skipped some security checks. Maybe you don't check that a certificate matches a device UUID and so on.
Hopefully, I will find enough security holes to do something (let say trigger actions for other users). Maybe I will send them Wipe command or may be I will try to install a root CA + HTTP proxy configuration to see all their traffic.
Anyhow. I don't think that it's that weakest link and it requires a lot of additional step to get to some interesting stuff. However, if you get there, you can do A LOT.
As a result for a serious product, it will make sense to invest several additional weeks in SCEP.
I'm trying to figure out what exactly means the status code errSecDuplicateItem for the SecItemAdd method when trying to add a certificate identity to the iOS keychain.
Reading the iOS documentation, it only says that this status code means the item is duplicated in the keychain, but what is the criteria to determine if an identity is a duplicate? Issuer name? Expiration date? Both?
If you read to the Mac OSX documentation, the discussion section for a similar method says the following:
If the certificate has already been added to the specified keychain,
the function returns errSecDuplicateItem and does not add another copy
to the keychain. The function looks at the certificate data, not at
the certificate object, to determine whether the certificate is a
duplicate. It considers two certificates to be duplicates if they have
the same primary key attributes.
I know there is a difference, I'm trying to save the certificate identity in the keychain, and this discussion is for the SecCertificateAddToKeychain method which saves the certificate; but I believe there is a connection.
What's the meaning of "primary keys attributes"?
I tried adding the same identity twice and of course I get the errSecDuplicateItem, but I'm afraid that users may get an error if they want to update the certificate in someway I'm not considering.
Any thoughts?
Thanks in advance
As far as I know, the keychain's primary key attributes aren't documented. However, according to a message from Ken McLeod, certificates are identified by their certificate type, issuer, and serial number. The keychain will refuse to accept more than one certificate that has the exact same values for these attributes.
Certificate authorities are required not to issue two certificates with the same serial number, so this error is unlikely to happen for your users. If you're generating certificates yourself, you must also make sure you do not accidentally reuse serials.
For one of my iOS apps I need to check two things:
Is there an active device lock (pass code)
Has the device lock been triggered by the correct authority / certificate (e.g. my own certificate). This is required to assure specific security guidelines.
For the first part of my question I found this answer - which is sufficient for me. How would you accomplish the second part?
Answering my own question.
First of all the correct question is not about validation of a certificate. It's about validation of meta information placed within a configuration profile (which in my case provides security guidelines for the device lock).
You have to create a custom CA and issue one certificate. The issued certificate has to be placed within your app, the custom CA's certificate goes into the configuration profile.
If the configuration profile is installed it is possible to check whether the certificate within the app binary was signed with the root certificate placed in the configuration profile.
It's not the most secure solution, but definitely a way to go.
--
This post put me into the right direction (Apple Developer Account required).
I am implementing SSL client authentication for our iPhone app and am using the app keychain to store the client identity (certificate + private key). After adding the items to the keychain, I am getting some unexpected results when using SecItemCopyMatching. Quick summary: I add exactly one SecIdentityRef to the keychain, but SecItemCopyMatching finds two afterwards. Let me start with the facts.
I am running my app on an iPod with iOS 4.3.5.
I have an empty app keychain to start with.
My certificates are all created using openssl and deployed to the iPod via a PKCS#12 file as an email attachment.
The PKCS#12 file contains:
Client certificate
Client CA certificate (issuer of the Client certificate)
Root CA certificate (issuer of the Client CA certificate)
RSA private key of the client certificate
SecPKCS12Import successfully imports the file and the resulting dictionary has the following content:
one "identity"
one "trust"
one "chain" (CFArray which holds the three certificates mentioned above)
Using SecItemAdd, I successfully add the "identity" to the keychain.
Next, I retrieve the "chain" array from the dictionary and attempt to add the certificates. In doing so, the first one fails with error errSecDuplicateItem. I assume this is because the first certificate is the client certificate and that it was already added to the keychain when I added the identity. The other two certificates are added without error.
Now, if I go back and use SecItemCopyMatching with these key/value pairs...
keys = {kSecClass, kSecReturnRef, kSecMatchLimit}
values = {kSecClassIdentity, kCFBooleanTrue, kSecMatchLimitAll}
...two identities are returned! Furthermore, if I retrieve the certificate for each (SecIdentityCopyCertificate) and then the summary (SecCertificateCopySubjectSummary), I see the both identities have the same certificate!
Lastly, when I try to clear the identities from the keychain (SecItemDelete), the first attempt is successful but the second fails with errSecItemNotFound.
It is clear from all the googling I have been doing that there are "issues" with the iOS keychain. However, I have not seen this reported; nor have I seen anything even remotely related.
So, my questions:
Am I using SecItemCopyMatching correctly?
When using SecItemCopyMatching to find identities in the keychain, how does it determine the identities that are present? Is this dynamic, or strictly based on how many SecIdentityRef items were added?
could this problem possibly be related to the certificates themselves? Note that despite this issue, I am still able to retrieve the first identity and certificates in order to respond to didReceiveAuthenticationChallenge.
I can post code and/or certificate dump, if needed.
Thanks in advance,
Ken Cross
Siemens Enterprise Networks.
As far as I can tell, you're using SecItemCopyMatching correctly.
SecIdentityRef items are not actually stored on the keychain; they are generated dynamically for certificates that have an associated private key available. Duplicate identities are indeed strange, and probably indicate a framework issue -- perhaps the framework gets confused by the duplicate in the second set of certificates? (Please do file a bug at bugreport.apple.com!) Does the duplicate identity go away when you restart the app?
On the other hand, duplicate identities won't necessarily lead to any actual problem. If you are worried that you might be using the wrong identity, simply ask SecItemAdd to provide a persistent reference to the one it "creates" and use that to retrieve the SecIdentityRef when needed.
I am working on an Apple MDM server, and actually it is working fine. I have a signature problem, that makes the client complain about the certificate, so now I am interested in how others sign their configuration profiles.
I use java, but any kind of help is welcome, since this is not a particular question on how to implement the code in java, but more on how to correctly sign the configuration profile.
This is how we do it currently:
byte[] data = ...
X509Certificate cert = ...
KeyPair keyPair = ...
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
gen.addSigner(keyPair.getPrivate(), cert, CMSSignedGenerator.DIGEST_SHA1, new AttributeTable(new Hashtable<DERObjectIdentifier, Attribute>()), null);
CMSSignedData signedData = gen.generate(new CMSProcessableByteArray(data), true, "BC");
response.setContentType("application/x-apple-aspen-config");
response.getOutputStream().write(signedData.getEncoded());
We are using a self signed certificate created with the algorithm SHA1withRSA and the key is with RSA and the size is 2048.
Does anyone see a problem with this way of doing it, or are you just doing it differently which maes it work?
And please feel free to post code in other languages than java - it might still help.
I did two things to fix this.
First I changed the certificate to x509 v3 - it was v1. Then I added KeyUsage and BasicConstraints to make iOS accept it as trusted.
The second I did was to add the certificate itself as a CertStore.
These two steps makes the certificate similar to the certificate iPhone Configuration Utility uses.