-
Re: Why SecCertificateCreateWithData is always return nil?
eskimo Dec 2, 2016 2:23 AM (in response to Honda_MW)Three things…
What version of Swift are you using here? Judging by your use of NSBundle (rather than
Bundle
) I presume you’re using Swift 2 of some form. Is that right?You don’t need to create your own CFData here; Swift will automatically go from NSData to CFData like this:
let cert = SecCertificateCreateWithData(nil, data)
If you’re using
Data
(in Swift 3) you’ll need to bounce to NSData.let cert = SecCertificateCreateWithData(nil, data as NSData)
The most common reason for
SecCertificateCreateWithData
to return nil is that the data isn’t a valid certificate. A common problem is that folks try to pass in a PEM format certificate, whereasSecCertificateCreateWithData
requires DER. If you open the certificate with a text editor, do you see Base64? Or do you see binary goo? If you see Base64, you’ll need to convert the certificate to binary (DER) form before passing to toSecCertificateCreateWithData
. For a single certificate that you include in your bundle, you can just pre-convert it using Keychain Access on the Mac.OTOH, if it’s already in binary form, there’s something broken within the certificate itself. If you post a hex dump of that binary data I can take a look.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardwarelet myEmail = "eskimo" + "1" + "@apple.com"
-
Re: Why SecCertificateCreateWithData is always return nil?
Honda_MW Dec 5, 2016 2:11 AM (in response to eskimo)I using Swift2.
I checked my certificate.That's seem Base64 encoded.But extension is DER.
00000000 42 61 67 20 41 74 74 72 69 62 75 74 65 73 0a 20 |Bag Attributes. | 00000010 20 20 20 6c 6f 63 61 6c 4b 65 79 49 44 3a 20 30 | localKeyID: 0| 00000020 31 20 30 30 20 30 30 20 30 30 20 0a 73 75 62 6a |1 00 00 00 .subj| 00000030 65 63 74 3d 2f 43 3d 5c 78 45 36 5c 78 39 37 5c |ect=/C=\xE6\x97\| 00000040 78 41 35 5c 78 45 36 5c 78 39 43 5c 78 41 43 2f |xA5\xE6\x9C\xAC/| 00000050 53 54 3d 5c 78 45 36 5c 78 39 44 5c 78 42 31 5c |ST=\xE6\x9D\xB1\| 00000060 78 45 34 5c 78 42 41 5c 78 41 43 5c 78 45 39 5c |xE4\xBA\xAC\xE9\| 00000070 78 38 33 5c 78 42 44 2f 4f 3d 5c 78 45 36 5c 78 |x83\xBD/O=\xE6\x| 00000080
At first I converted p12 format to DER with openssl. Is this not okay?
-
Re: Why SecCertificateCreateWithData is always return nil?
eskimo Dec 5, 2016 2:00 PM (in response to Honda_MW)I checked my certificate.That's seem Base64 encoded.But extension is DER.
Yeah, that’s a problem. This sort of textual representation is indicative of PEM.
SecCertificateCreateWithData
can’t deal with PEM. You have two choices:If you’re working with a certificate hard-wired into your app, you can just use some tool (like Keychain Utility or the
x509
subcommand ofopenssl
) to convert the certificate to DER and add that to your app.If you have to handle arbitrary certificates at runtime, you’ll need to undo the Base64 encoding.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardwarelet myEmail = "eskimo" + "1" + "@apple.com"
-
Re: Why SecCertificateCreateWithData is always return nil?
Honda_MW Dec 5, 2016 9:12 PM (in response to eskimo)Thanks a lot.I solved problem.
But I got new problem.
When I checked SecTrustResultType.hashValue,that's value was kSecTrustResultRecoverableTrustFailure.
When installing a certificate in General, it was possible to communicate normally.
So I think that there is probably no problem with the certificate.
What kind of problems can be considered?
-
Re: Why SecCertificateCreateWithData is always return nil?
eskimo Dec 6, 2016 12:58 AM (in response to Honda_MW)First up, I moved your thread to Core OS > Security because there’s nothing particularly Swift-specific here.
Secondly, you wrote:
When installing a certificate in General, it was possible to communicate normally.
You mean in Settings > General, right?
Please explain more about what you’re trying to do here. This is the first time you’ve mentioned communication — so far this thread has been about importing a certificate — so it’s hard to understand what’s going on without more context.
Also, are you using TLS? If so, you might want to read my TLS for App Developers post, which provides a bunch of background on that subject.
ps With regards this:
When I checked
SecTrustResultType.hashValue
,that's value waskSecTrustResultRecoverableTrustFailure
.if you want to get the numeric representation of an enum like
SecTrustResultType
, you should use therawValue
property. ThehashValue
property gives you a hash, which in this case just happens to match up but is not guaranteed to do so.Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardwarelet myEmail = "eskimo" + "1" + "@apple.com"
-
Re: Why SecCertificateCreateWithData is always return nil?
Honda_MW Dec 6, 2016 6:14 PM (in response to eskimo)Sorry.I explain what I want to do in the first place.
I connect to server from my application then needs TLS/SSL.
Server certificate is self-signed certificate.
I prepared rootCA certificate and client certificate for TLS/SSL connection.
When I want to got these certificate the first problem occured.
In addition, the following settings are made.
When connecting to the server, it is connected with a port other than 443.
ATS is disabled.
I'm using own wrapper class that was subclass of NSURLConnection.
My code is here.
func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge) { if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { print(challenge.protectionSpace.host) print(ConstStruct.HOST) if challenge.protectionSpace.host == ConstStruct.HOST.stringByReplacingOccurrencesOfString(":PortNo", withString: "") && NSString(string:ConstStruct.HOST).rangeOfString(":PortNo").location != NSNotFound { let protectionSpace = challenge.protectionSpace let trust = protectionSpace.serverTrust let certs: [CFTypeRef] = [HttpPostHelper.sslCertificate() as! CFTypeRef] let certArrayRef : CFArrayRef = CFBridgingRetain(certs as NSArray) as! CFArrayRef var status = SecTrustSetAnchorCertificates(trust!, certArrayRef) if status != errSecSuccess { print("SecTrustSetAnchorCertificates") connection.cancel() return } / let rootCa = "ROOTCA_FILENAME" if let rootCaPath = NSBundle.mainBundle().pathForResource(rootCa, ofType: "der") { if let rootCaData = NSData(contentsOfFile: rootCaPath) { if let rootCert = SecCertificateCreateWithData(nil, rootCaData) { SecTrustSetAnchorCertificates(trust!, CFBridgingRetain([rootCert,HttpPostHelper.sslCertificate() as! CFTypeRef] as NSArray) as! CFArrayRef) SecTrustSetAnchorCertificatesOnly(trust!, false) // also allow regular CAs. } } } */ var trustResult:SecTrustResultType = SecTrustResultType(kSecTrustResultInvalid) status = SecTrustEvaluate(trust!, &trustResult) if status != errSecSuccess { print("SecTrustEvaluate") print("trustResult") connection.cancel() return } switch trustResult.hashValue { case kSecTrustResultProceed,kSecTrustResultUnspecified: challenge.sender?.useCredential(NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!), forAuthenticationChallenge: challenge) return case kSecTrustResultRecoverableTrustFailure: challenge.sender?.cancelAuthenticationChallenge(challenge) connection.cancel() break default: challenge.sender?.cancelAuthenticationChallenge(challenge) connection.cancel() break } challenge.sender?.useCredential(NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!), forAuthenticationChallenge: challenge) challenge.sender?.continueWithoutCredentialForAuthenticationChallenge(challenge) } } }
Running comment lines 19 to 29 did not change the result.
Are there causes in this?
-
Re: Why SecCertificateCreateWithData is always return nil?
Honda_MW Dec 9, 2016 1:00 AM (in response to eskimo)Hi,eskimo.I rewritten my wrapper class with NSURLSession.But that problem was not solved.
I read other articles, but I think whether specifying direct connection by IP address is not good.Is that right?
My test server does'nt have domain name.How do I test it?
-
-
-
-