How to get the Organisation from an EV Certificate on iOS - ios

I've been trying to get the organisation info from an Extended Validation SSL Certificate (EV Certificate) on iOS.
I've a UIWebClient loading an NSURLRequest, but I can't figure out from were should I get the organisation info.
For clarification, I'm trying to get "Banco Santander Chile" from this website when I'm loading the page https://www.santander.cl on my UIWebClient, as show on the image below:

You have to extract it from SecCertificateRef object. have a look into this thread:
SecCertificateRef: How to get the certificate information?

To add to reecon's answer, you will also need a list of OIDs to look for. There is no standard EV OID, so you have to rummage for a matching OID from a list of know OIDs linked to the issuers. An OID that indicates EV for one issuer does not mean its an EV from another issuer.
You can find a list of Chromium's EV OID metadata at http://chromium.googlesource.com/chromium/chromium/+/trunk/net/cert/ev_root_ca_metadata.cc. Wikipedia has a list at Extended Validation certificate identification, but I'm not sure how current it is.
... I'm trying to get "Banco Santander Chile" from this website when I'm loading the page...
Once the EV OID is matched for the issuer, you display the Organizational Name (or other relevant field) from the certificate (/O=Banco Santander Chile below):
$ openssl s_client -connect www.santander.cl:443
CONNECTED(00000003)
depth=2 C = US, O = "VeriSign, Inc.", OU = VeriSign Trust Network, OU = "(c) 2006 VeriSign, Inc. - For authorized use only", CN = VeriSign Class 3 Public Primary Certification Authority - G5
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/1.3.6.1.4.1.311.60.2.1.3=CL/businessCategory=Private Organization/serialNumber=97036000-K/C=CL/ST=Santiago/L=Santiago/O=Banco Santander Chile/OU=Comercio Electronico/OU=Terms of use at www.verisign.com/rpa (c)05/CN=www.santander.cl
i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)06/CN=VeriSign Class 3 Extended Validation SSL SGC CA
1 s:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)06/CN=VeriSign Class 3 Extended Validation SSL SGC CA
i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5
2 s:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5
i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
Parse the certificate. Since the issuer is Verisign, the OID you are looking for is 2.16.840.1.113733.1.7.23.6:
$ openssl x509 -in test.pem -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
2d:fb:a1:be:00:e2:96:99:34:a8:b7:5b:90:c9:85:5d
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=Terms of use at https://www.verisign.com/rpa (c)06, CN=VeriSign Class 3 Extended Validation SSL SGC CA
Validity
Not Before: Aug 27 00:00:00 2013 GMT
Not After : Nov 26 23:59:59 2014 GMT
Subject: 1.3.6.1.4.1.311.60.2.1.3=CL/businessCategory=Private Organization/serialNumber=97036000-K, C=CL, ST=Santiago, L=Santiago, O=Banco Santander Chile, OU=Comercio Electronico, OU=Terms of use at www.verisign.com/rpa (c)05, CN=www.santander.cl
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:af:25:f4:cd:20:3c:ed:6c:e6:83:3e:13:1b:c0:
98:f8:57:2f:57:01:08:bf:22:df:78:22:5a:37:ea:
16:f9:e4:8f:fa:2a:4b:37:2d:57:37:11:8c:29:db:
e5:06:ba:05:56:f6:0b:3f:ee:55:98:69:41:85:a0:
12:df:5d:9f:09:30:26:7b:70:4b:88:51:05:a5:36:
2e:69:c8:28:14:2e:2d:be:7a:13:07:01:9f:eb:23:
ea:52:11:6b:72:3f:4e:ba:1d:33:b1:8c:f5:d4:e7:
51:f5:f8:5b:86:06:6f:04:02:37:63:b4:6d:e6:a9:
4b:34:c4:05:36:8c:7c:e9:f0:71:84:ef:92:38:72:
b9:8e:b2:a4:9a:ca:a6:95:da:73:ce:bd:c8:f9:0c:
b4:a6:88:c9:e3:b9:a3:34:09:4c:55:3b:ad:ce:5f:
2d:35:47:9c:e9:4d:3b:c4:02:1c:22:6b:16:4a:f3:
50:2a:86:b2:bc:bd:08:fd:cb:f8:f7:80:c5:86:55:
e6:59:e4:c8:79:ba:36:e3:c6:a4:d4:f9:8f:15:20:
89:bc:71:64:ab:b4:7c:9e:28:f1:42:f8:16:46:55:
97:09:de:a9:78:58:27:22:aa:60:a7:88:64:03:fb:
4f:8d:36:01:52:11:47:48:d2:82:2b:de:08:3a:ee:
f0:89
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:www.santander.cl
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Certificate Policies:
Policy: 2.16.840.1.113733.1.7.23.6
CPS: https://www.verisign.com/cps
X509v3 CRL Distribution Points:
Full Name:
URI:http://EVIntl-crl.verisign.com/EVIntl2006.crl
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication, Netscape Server Gated Crypto
X509v3 Authority Key Identifier:
keyid:4E:43:C8:1D:76:EF:37:53:7A:4F:F2:58:6F:94:F3:38:E2:D5:BD:DF
Authority Information Access:
OCSP - URI:http://ocsp.verisign.com
CA Issuers - URI:http://EVIntl-aia.verisign.com/EVIntl2006.cer
Signature Algorithm: sha1WithRSAEncryption
5b:77:fb:a5:82:d8:fa:cc:84:b5:5c:48:86:fc:ea:ad:2b:cb:
0f:9e:6e:3b:e6:e5:4a:52:d7:c6:f1:fd:f9:47:a2:2b:b7:32:
95:4d:bf:74:99:9d:8e:30:3b:71:74:00:3d:59:d5:50:7a:08:
be:de:2b:d1:69:89:9f:fc:28:e8:2d:28:04:1b:33:fe:20:52:
84:bd:7a:ad:5b:30:29:41:d1:a2:cd:53:b0:da:50:df:68:12:
b9:94:6a:5f:32:6f:b5:bb:36:ab:15:81:8d:51:99:bf:4b:5d:
ee:10:7b:24:bf:87:50:97:94:b4:fe:ad:dc:61:8e:a9:49:a2:
04:ad:7f:35:a0:4b:0f:ab:7a:a8:86:33:60:e8:12:09:fe:66:
d5:61:da:a7:69:61:85:26:28:92:39:3a:0c:ec:5c:f8:62:bb:
b5:72:8d:1f:44:ef:64:0a:4b:e9:af:cd:6a:29:5f:ec:f5:82:
45:d9:6f:57:2f:ce:51:a4:f9:2c:0e:02:dd:d5:a1:51:ef:45:
6b:d7:93:55:c6:e0:e1:95:46:b0:7b:fa:cd:05:4b:d9:57:3b:
c6:0b:d7:f4:51:7b:cd:19:cf:6e:a7:22:05:b7:cf:a8:50:c9:
20:6f:be:48:85:40:46:61:0f:40:5b:31:49:af:d6:fb:9a:95:
52:d4:88:1b

Related

How to get certificate and convert for ESP32 to connect to paid HiveMQ broker?

I am trying to connect to the HiveMQ broker using ESP32, a SIM7020 NB-IoT module and the library Magellan_SIM7020E found at:https://github.com/AIS-DeviceInnovation/Magellan_SIM7020E.
It requires an SSL certificate to be pasted in a header file with this format (here abbreviated), where the lines of XXXXXX are to be replaced with the characters of the certificate:
/= Certificate Authority info =/
/= CA Cert in PEM format =/
const char rootCA[] = {"-----BEGIN CERTIFICATE-----"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
...
...
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
"-----END CERTIFICATE-----"};
const char clientCA[] = {"-----BEGIN CERTIFICATE-----"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
...
...
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
"XXXXXXXXXXXXXXXX"
"-----END CERTIFICATE-----"};
const char clientPrivateKey[] = {"-----BEGIN RSA PRIVATE KEY-----"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
...
...
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
"-----END RSA PRIVATE KEY-----"};
I managed to work with the free service with this setup (using the non SSL client in the library) but the I am failing with the SSL version used to access the paid broker.
By free service I mean broker.hivemq.com and by paid I mean xxxxxxx.s2.eu.hivemq.cloud.
I tried to use the certificate indicated in the FAQ (https://community.hivemq.com/t/frequently-asked-questions/514) which gives me a file called isrgrootx1.pem but it has a different format.
I tried cutting the .pem into sections with length that match each of the three entries required in the header file but the total length does not match.
The downloaded .pem file has a single block of 1856 characters whereas the ESP32 seems to need three blocks for root, client and client private with lengths of 1116, 1232 and 1592 respectively, adding up to much more than the PEM file length.
Is this the right file?
If so, how do I convert it to the format that I need?
If not, where from can I get the certificate?
I tried to follow a previous answer (Can't connect ESP32 to MQTT). That is for WiFi, not NB-IoT but it seems to require a similar format for the certificate. It is suggeseted to install and use OpenSSL but I can't figure out how to install it and I don't even know if it would actually do what I need if I did manage to install it.
As an alternative is there any way I can access the paid broker without SSL as I don't really need that level of security and it is an added complication, especially with regard to keeping the certificates up to date.

Apple Wallet NFC encryptionPublicKey

In Apple's documentation for the keys available for a Wallet pass, there's an option for a dictionary for NFC-related data. I understand that use of this key requires special permission from Apple. Regardless ...
message is straight forward -- it's the data passed to a NFC terminal (usually a unique identifier for the customer).
encryptionPublicKey, however, has me confused. Apple states it is the public encryption key used by the Value Added Services protocol. Use a Base64 encoded X.509 SubjectPublicKeyInfo structure containing a ECDH public key for group P256.
Can anyone explain what this second sentence means and/or what a developer would have to do to generate this? From what would one even generate the public/private keys?
You'll need the following to generate the public and private key. The private key is used by the merchant hardware when reading the pass and decoding the payload.
The compressed public key is what goes into your pass.json.
openssl ecparam -name prime256v1 -genkey -noout -out nfcKey.pem
openssl ec -in nfcKey.pem -pubout -out nfcPubkey.pem -conv_form compressed
cat nfcPubkey.pem
Outputs:
-----BEGIN PUBLIC KEY-----
MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgAC/Bu9nyAtG1DQe7t7jszLb+dZ1GbX
oR8G0rIXoak67NM=
-----END PUBLIC KEY---
You'll need Base64 key (without the newline) for the encryptionPublicKey field.
E.g.
MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgAC/Bu9nyAtG1DQe7t7jszLb+dZ1GbXoR8G0rIXoak67NM=

How can I build the Apple APNS v2 specific OID into the CSR

Apple APNS V2 introduce the "topic" concept, and assign a customized OID for it and give out an example:
https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html#//apple_ref/doc/uid/TP40008194-CH11-SW1
Extension ( 1.2.840.113635.100.6.3.6 )
Critical NO
Data com.yourcompany.yourexampleapp
Data app
Data com.yourcompany.yourexampleapp.voip
Data voip
Data com.yourcompany.yourexampleapp.complication
Data complication
How can I build this extension into the CSR. I know I need to edit the openssl.conf to add it in the "req" section, but what's the specific codes to put all these attributes into CSR? The following command I try can add one line into the CSR, but how can I add the following part? Thanks in advance!!!
[ customized_extension ]
1.2.840.113635.100.6.3.62=Critical NO,ASN1:UTF8String:1.2.840.113635.100.6.3.62
1.2.840.113635.100.6.3.62=ASN1:UTF8String:com.yourcompany.yourexampleapp
???? --How to add the next part?
openssl req -new -sha256 -key ses_lab_20170120.key -out ses_lab_20170120.csr -config openssl.cnf
openssl req -in ses_lab_20170120.csr -text -noout
Certificate Request:
Data:
Version: 0 (0x0)
Subject: C=CN, ST=GD, L=GZ, O=Ericsson, OU=SES, CN=test
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
00:b0:9e:2f:3d:52:da:71:0a:e3:93:13:2b:c4:92:
4b:4b:3c:0c:70:98:d5:6d:3f:a0:af:f4:03:d0:26:
53:6a:d4:7e:82:d7:95:6a:8f:29:eb:88:6c:67:4a:
94:d4:b5:ed:9a:b5:d4:e4:44:8c:1d:21:ec:ba:03:
df:61:3f:6a:5e:c0:ea:13:00:62:e0:df:3c:39:2b:
1a:2b:b0:b5:39:1a:bf:ba:d5:85:0d:37:bd:2a:92:
d1:6e:9b:05:37:bf:bf:c2:83:ca:8f:27:5a:b3:d3:
b5:53:17:7e:b0:d8:ea:ec:51:09:7f:d5:e7:5e:a5:
03:ff:63:28:da:11:5a:ae:10:01:05:46:da:62:02:
b2:20:4d:08:a8:47:ed:95:2a:b9:f3:e9:f5:e6:fb:
b0:29:99:c5:cf:d3:80:98:8b:8a:10:4f:8a:fa:57:
f8:50:31:e7:02:6a:8c:16:13:99:1d:e3:6d:ce:d5:
43:d9:c9:1f:50:b8:55:07:00:88:d6:ab:b1:44:46:
32:62:03:25:91:9a:ae:72:09:b8:a4:07:9c:86:95:
bf:59:0e:0e:65:73:b7:0f:86:d3:d2:7e:ac:7e:82:
9f:61:c8:41:b0:d6:25:2a:4f:09:93:6d:6a:15:b8:
60:22:ba:34:d4:69:dc:b1:6c:98:8a:4a:01:31:71:
b8:0f
Exponent: 65537 (0x10001)
Attributes:
Requested Extensions:
1.2.840.113635.100.6.3.62:
..com.yourcompany.yourexampleapp
Signature Algorithm: sha256WithRSAEncryption
62:53:2f:85:1f:7c:9f:4c:b8:48:c0:df:20:5d:3a:6d:f3:55:
7c:63:90:66:3c:14:d5:e0:c8:4e:f3:21:2d:d8:5b:ed:4c:2d:
38:5b:90:ad:a6:e4:0c:1d:e7:b6:c6:66:1f:41:c9:cf:f1:10:
13:a7:27:bf:f5:74:93:76:dd:e0:1a:64:7e:66:62:87:9b:e4:
88:c2:74:65:fc:90:04:d3:24:51:2b:c3:f0:ef:0d:b3:e9:cb:
d8:23:d6:63:31:0a:93:d6:f3:36:99:8d:1e:33:fd:fd:c3:6d:
a8:38:9d:63:ce:2b:2b:4e:43:93:77:87:05:e7:c5:6d:39:98:
f2:7d:39:3e:bc:a9:9a:59:c4:ce:c2:88:ef:95:67:55:cc:a9:
e4:3a:8a:1d:49:66:77:81:8d:0e:9b:ce:f1:cc:3d:83:62:cc:
86:fe:4a:2d:f0:b9:70:9f:d8:75:9e:52:99:53:4e:ea:32:8d:
af:11:9c:d3:cc:d4:8b:e5:24:c2:10:2b:11:61:52:2d:a3:67:
f0:f6:9c:8e:3e:12:66:0f:14:9e:1c:3d:77:81:3a:26:35:e0:
15:c5:ab:d2:4b:51:c4:2e:7d:7b:0a:92:ae:89:fb:f2:fa:32:
81:52:da:49:16:c3:84:a9:82:e1:2d:b6:9b:03:ae:88:fb:fd:
17:ee:3c:1b

Apple MDM - Profile could not be decrypted (Decryption key for this profile is not installed)

I am implementing Apple MDM Profile Service in C++ using the Apple OTA Profile Delivery example (which is in Ruby). It seems all things work well except the last step (configuration applying).
IPhone Configuration Utility shows the following:
Jul 8 16:38:48 iPhone profiled[1454] : (Note ) profiled: Service starting...
Jul 8 16:38:48 iPhone profiled[1454] : (Note ) MC: Checking for MDM installation...
Jul 8 16:38:48 iPhone profiled[1454] : (Note ) MC: ...finished checking for MDM installation.
Jul 8 16:38:50 iPhone profiled[1454] : (Note ) MC: Enrolling in OTA Profile service...
Jul 8 16:38:51 iPhone profiled[1454] : (Note ) MC: Attempting to retrieve issued certificate...
Jul 8 16:38:51 iPhone profiled[1454] : (Note ) MC: Issued certificate received.
Jul 8 16:38:52 iPhone profiled[1454] : (Note ) MC: Retrieving profile from OTA Profile service...
Jul 8 16:38:52 iPhone profiled[1454] : (Error) MC: Decryption failed: NSError:
Desc : Profile could not be decrypted
Sugg : Decryption key for this profile is not installed.
US Desc: Profile could not be decrypted
US Sugg: Decryption key for this profile is not installed.
Domain : MCProfileErrorDomain
Code : 1006
Type : MCFatalError
It seems like it is a common error, because I found a couple of discussions on discussions.apple.com, but they do not have solutions. Also I have found a comment here, but it is without a solution too.
The Apple Ruby example which is in Over-the-Air Profile Delivery Concepts works well. I have compared outputs (certificate dumps) of my C++ implementation and the Ruby example. They are the same except domain names (I use "TEST" instead of "ACME". I tried to use the original certificates, but they did not work in my implementation either.).
I use the same encryption in the code to send a new certificate to the device side. It works.
In the case of profile encryption I use certificates from the PKCS7 which is received from the device side. So I do not think that the problem is because of an incorrect use of OpenSSL.
Can you suggest me anything?
UPDATE1:
1) Actually when I say that certificates (mine and from the example) are the same I mean that they have the same dependencies and I mean that it seems like my and the example algorithms work similarly. Surely the certificates have different fingerprints, etc.
2) I use the exact algorithm as in the Ruby example from the Over-the-Air Profile Delivery Concepts link. So as far as I understand I use SCEP.
Here is my C++ code (I mainly removed code for logging). Yes, I understand that my code is rough, but on this stage I need only a working algorithm.
C-x509-request-from-device.pem
PKCS #10 Certificate Request (Version 1.0)
Subject: CN=Profile Service (4feea0ef-b586-4c54-a767-5d8160a04952), O=TEST Inc.
Public Key: X.509 format RSA key
Extension Request:
#1: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
DigitalSignature
Key_Encipherment
]
E-pkcs7-degenerated.pem
Owner: CN=Profile Service (4feea0ef-b586-4c54-a767-5d8160a04952), O=TEST Inc.
Issuer: CN=TEST Root CA (314aa3fe-ea1f-4afb-b2f5-ad998f1eddf3), O=None
Serial number: 145
Valid from: Wed Jul 09 22:38:04 NOVT 2014 until: Thu Jul 10 22:38:04 NOVT 2014
Certificate fingerprints:
MD5: B4:F4:78:E3:A1:69:FB:23:49:E8:0D:4C:E5:8F:C5:A6
SHA1: 47:19:8A:9C:9F:91:B2:FC:6B:ED:EE:A8:41:FF:3B:CF:6A:1D:52:F2
SHA256: 59:95:31:66:B8:D8:54:83:B5:23:17:86:1A:7F:94:98:B2:17:58:61:F8:
0A:4C:E8:B0:1C:4D:79:23:B0:32:93
Signature algorithm name: SHA1withRSA
Version: 3
Extensions:
#1: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
DigitalSignature
Key_Encipherment
]
/profile (the second POST; my response on it causes the "Profile could not be decrypted" error)
PKCS7Wrap pkcs7;
pkcs7.InitFromDER(httpData.block_, httpData.blockSize_);
std::string content;
// ...........
SavePKCS7ToFile(pkcs7.pkcs7_, "K-pkcs7-from-device-2.pem");
std::string tmp = appleMDMPList_.GetClientCertConfPayloadPList("foo");
SaveData(tmp, "3-client-cert-conf.xml");
PKCS7Wrap encryptedContent;
PKCS7Wrap::EncryptData(pkcs7.GetCertificates(), tmp, encryptedContent);
if (encryptedContent.IsInited())
{
SavePKCS7ToFile(encryptedContent.pkcs7_, "Q-encrypted_profile.pem");
content =
appleMDMPList_.GetConfigurationPayloadPList(encryptedContent.ToDER());
SaveData(content, "4-configuration.xml");
}
std::string signedProfile;
PKCS7Wrap::SignData(keyStore.GetAppleMDMSSLCrt(),
keyStore.GetAppleMDMSSLKey(), content, signedProfile);
// send to the device with mime = application/x-apple-aspen-config
K-pkcs7-from-device-2.pem
Certificate[1]:
Owner: CN=Profile Service (4feea0ef-b586-4c54-a767-5d8160a04952), O=TEST Inc.
Issuer: CN=TEST Root CA (314aa3fe-ea1f-4afb-b2f5-ad998f1eddf3), O=None
Serial number: 145
Valid from: Wed Jul 09 22:38:04 NOVT 2014 until: Thu Jul 10 22:38:04 NOVT 2014
Certificate fingerprints:
MD5: B4:F4:78:E3:A1:69:FB:23:49:E8:0D:4C:E5:8F:C5:A6
SHA1: 47:19:8A:9C:9F:91:B2:FC:6B:ED:EE:A8:41:FF:3B:CF:6A:1D:52:F2
SHA256: 59:95:31:66:B8:D8:54:83:B5:23:17:86:1A:7F:94:98:B2:17:58:61:F8:
0A:4C:E8:B0:1C:4D:79:23:B0:32:93
Signature algorithm name: SHA1withRSA
Version: 3
Extensions:
#1: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
DigitalSignature
Key_Encipherment
]
Certificate[2]:
Owner: CN=TEST Root CA (314aa3fe-ea1f-4afb-b2f5-ad998f1eddf3), O=None
Issuer: CN=TEST Root CA (314aa3fe-ea1f-4afb-b2f5-ad998f1eddf3), O=None
Serial number: 1
Valid from: Mon Jul 07 19:28:55 NOVT 2014 until: Tue Jul 07 19:28:55 NOVT 2015
Certificate fingerprints:
MD5: 78:20:18:80:9C:09:D9:DA:36:3E:06:CC:F7:61:A9:13
SHA1: 40:61:EA:90:D8:58:20:3C:43:CB:2B:E1:3F:49:DF:A8:5A:7A:01:39
SHA256: AB:F6:5C:A7:23:F1:92:38:12:71:29:2A:C0:F1:04:69:CF:F4:7C:26:FC:
E7:0C:89:B4:10:A4:E5:58:9F:50:39
Signature algorithm name: SHA1withRSA
Version: 3
Extensions:
#1: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:true
PathLen:2147483647
]
#2: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
DigitalSignature
Key_CertSign
Crl_Sign
]
UPDATE2:
I have just regenerated certificates (CA, RA, SSL) and it works. I do no know why :)
#jww is right. It's impossible to troubleshoot such problem without any code.
My guess is that you are encrypting a profile with the wrong certificate.
I have compared outputs (certificate dumps) of my C++ implementation and the Ruby example. >They are the same except domain names (I use "TEST" instead of "ACME".
Frankly. This sentense raised red flags in my mind. There should be more than domain name difference. There should be public key difference, serial number adifference and so on.
Most likely, what happens is that you send one certificate to a device and use another to encrypt profile.
BTW. Do you use PKCS12 or SCEP to provide an identity to your device?
I know this is an old post but I ran into the same thing yesterday and it wound up being a problem with the formatting of the payload that was encrypted, i.e., the "Decryption key for this profile is not installed" error message is a red herring.
The payload that is encrypted has an "array" of "dict", which is different than unencrypted payloads. This is evident in the test Ruby script Apple provides. In the sample Ruby script, the PKCS7.encrypt call encrypts the output from client_cert_configuration_payload. That function emits an array of payloads, as follows: Plist::Emit.dump([webclip_payload, client_cert_payload]). The content that is signed in the /enroll handler is just a "dict", Plist::Emit.dump(payload).
It was very surprising to fix a key not installed problem by changing the contents that the error indicates cannot be decrypted.

iOS connect with self-signed TLS/SSL certificate not working

I would like to encrypt and secure a network connection agains MITM attacks for an iOS application. Since the application will only connect to one server, there is no need to have the certificate signed by a CA like VeriSign. I want to self-sign the certificate and distribute it with the application.
I tried this but end up with kSecTrustResultRecoverableTrustFailure and can not figure out where I went wrong. Can someone look over it and identify the problem or point me into a direction on how to debug this? Is it a problem because I use/test on localhost?
I think it is a problem in the creation of the certificate or setup of the server but I don't know what it is. I tested it with openssl s_client and it seems to work but iOS does not accept it (see below). I could accept kSecTrustResultRecoverableTrustFailure as success but would rather avoid it.
Creation of certificate
My openssl.cnf. The last line specifies subjectAltName and should be the only important one.
[ req ]
default_bits = 2048 # Size of keys
default_keyfile = key.pem # name of generated keys
default_md = sha256 # message digest algorithm
string_mask = nombstr # permitted characters
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
# Variable name Prompt string
# #---------------------- ----------------------------------
0.organizationName = Organization Name (company)
organizationalUnitName = Organizational Unit Name (department, division)
emailAddress = Email Address
emailAddress_max = 40
localityName = Locality Name (city, district)
stateOrProvinceName = State or Province Name (full name)
countryName = Country Name (2 letter code)
countryName_min = 2
countryName_max = 2
commonName = Common Name (hostname, IP, or your name)
commonName_max = 64
# Default values for the above, for consistency and less typing.
# Variable name Value
#------------------------------ ------------------------------
0.organizationName_default = The Sample Company
localityName_default = Metropolis
stateOrProvinceName_default = New York
countryName_default = US
[ server ]
basicConstraints = critical,CA:FALSE
keyUsage = digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
nsCertType = server
subjectAltName = IP:127.0.0.1,DNS:localhost
This is how I create the certificate. I use sha256 since md5 seems not supported. Afterwards I transform the certificate to DER format which iOS needs.
macbook:~/Documents/app/https-test/cert$ openssl req -x509 -sha256 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 356 -nodes -config openssl.cnf
Generating a 2048 bit RSA private key
..+++
............................................................+++
writing new private key to 'key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:DE
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:com
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:
macbook:~/Documents/app/https-test/cert$ ls
cert.der cert.pem key.pem openssl.cnf
macbook:~/Documents/app/https-test/cert$ openssl x509 -in cert.pem -outform der -out cert.der
Server
The server is a node.js server that accepts https requests.
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('../cert/key.pem'),
cert: fs.readFileSync('../cert/cert.pem')
};
https.createServer(options, function (req, res) {
res.writeHead(200);
res.end("test return\n");
}).listen(8443);
I tested this server with the following output:
macbook:~/Documents/app/https-test/server$ openssl s_client -showcerts -host localhost -port 8443 -CAfile ../cert/cert.pem
CONNECTED(00000003)
depth=0 /O=The Sample Company/L=Metropolis/ST=New York/C=US
verify return:1
---
Certificate chain
0 s:/O=The Sample Company/L=Metropolis/ST=New York/C=US
i:/O=The Sample Company/L=Metropolis/ST=New York/C=US
-----BEGIN CERTIFICATE-----
MIIDIDCCAggCCQClnXQ2tGOF1jANBgkqhkiG9w0BAQsFADBSMRswGQYDVQQKExJU
aGUgU2FtcGxlIENvbXBhbnkxEzARBgNVBAcTCk1ldHJvcG9saXMxETAPBgNVBAgT
CE5ldyBZb3JrMQswCQYDVQQGEwJVUzAeFw0xNDAyMjQwMDEwMTJaFw0xNTAyMTUw
MDEwMTJaMFIxGzAZBgNVBAoTElRoZSBTYW1wbGUgQ29tcGFueTETMBEGA1UEBxMK
TWV0cm9wb2xpczERMA8GA1UECBMITmV3IFlvcmsxCzAJBgNVBAYTAlVTMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzudBEZmW78S9EnxQzObf778qIBRf
/pUPVKSC31/8iVLM3w71GtHxI39Gt+WwAhMRRKmO+EhsFWDmQZfg3GNsws4Uj/uO
8I6Xp9rF7IWBIAZ37X2nUPD/qEU4+SFmiNi8POaXPt+5mQQLYFfun5YzpZPoiPpi
wuIkcgY8mOJlNv7Hr4AnyMtMMnscZis+ELVky5Q/mDsiamHzPPGjjKYKDMfwYj8S
yAz0GLKrcHBBm4Re++mefJU0sdapAYEliAJdTs0aBA5lxcRBzkKlFwxgsQrhtwL9
xBY+RC/PbnVWRF/YVrd7o6JvXmWOPFDlbL99v9tGGjoUyFDeLoIMaqaGmwIDAQAB
MA0GCSqGSIb3DQEBCwUAA4IBAQAdnvu4W6GoWkAALpvpEgXBMKq2sApLHib+i8Be
+LrAS/zA1GxlMqswUBUvtGuQq88oGWC/eU3n3PvRE2tuIARg4ZSGo2/KdYfvOFYy
O7hnwdlAYirdj3XKUnomj0sVgeAjJV4xSha7aOzs9mNyLquJvewBEAvQdJnPRYfS
LwSUq5kbbiHyFWHmJnTUfLpfKj0w+LNO4Jrb0GdFs7ZWq3R0Mscig668Htue4xST
jWEh0f/ZcWLK+UVvTvpMb9DTM8oOV94EHt+slaIMEzD2hWjtLcwGfUzX5qYU450v
Kt1b40tBHRHi8ytstg4qdLlwf0NpXejcLQiW1CgNZoEIBtP+
-----END CERTIFICATE-----
---
Server certificate
subject=/O=The Sample Company/L=Metropolis/ST=New York/C=US
issuer=/O=The Sample Company/L=Metropolis/ST=New York/C=US
---
No client certificate CA names sent
---
SSL handshake has read 983 bytes and written 468 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : AES256-SHA
Session-ID: C8901BBE04CB24444E0DDEA60EB7A72A64822E652973AD1D16E27D1E1F29F828
Session-ID-ctx:
Master-Key: D143A0F58C848B0E1BCA7BDF22EEBC326F811961CC10FF3A653715A8D8F96F5825AFC6D200F334D2E1581BFECA940111
Key-Arg : None
Start Time: 1393256956
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
^C
iOS app
The app uses this NSURLConnectionDelegate https://gist.github.com/dhoerl/2051599
The iOS code you linked to expects the server's certificate to be in the device's trusted root certificate store, or at least signed by a trusted root certificate authority. The error you are getting suggests that this is not the case.
That error means the certificate is not trusted. By definition, a self-signed certificate is not trusted because it isn't signed by a trusted root certificate authority (so there's no way to verify that the signer of the certificate is who they say they are).
If you just want the benefits of SSL encryption without the protection from MITM attacks, you can bypass the server check by doing something like the following in the NSURLConnection delegate's didReceiveAuthenticationChallenge method:
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
Note that this will not prevent MITM attacks, since you are now allowing a connection to any SSL host, but if you truly want that kind of protection you shouldn't use a self-signed certificate. If you just want the encryption offered by SSL, a self-signed certificate is fine.
That said, you can do server authentication if you are bundling the server certificate in with your application - this is known as certificate pinning. You would need to add code in the didReceiveAuthenticationChallenge method above to compare the server's certificate with the one that's embedded in your application and have it trust ONLY that specific certificate and no other. This of course means that if the certificate on your server ever expires or changes, your clients will no longer be able to connect (until you rebuild and redistribute your application with the new certificate). It also means that if your server's private key is ever stolen or compromised, you won't be able to revoke it and issue a new one, and the Bad Guys will be able to impersonate your server to any clients that try to connect using the compromised key. Using a certificate issued by a trusted root CA avoids both problems, and is still the recommended way to go if you truly need server authentication. That way you can revoke the certificate if you ever need to, issue a new one, and everything will still work.
#1703536 's solution almost did it, I only had to implement another URLConnection's delegate message :
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
Concerns about security doing that are well explained in the other answer ;-)

Resources