Re: Peer-to-peer SSL/TLS best practices/strategy
Re: Peer-to-peer SSL/TLS best practices/strategy
- Subject: Re: Peer-to-peer SSL/TLS best practices/strategy
- From: John Pannell <email@hidden>
- Date: Thu, 13 Dec 2012 13:44:54 -0700
Quinn and Jens-
Thanks for your help and input - I'm gaining much better clarity on what I'm trying to achieve! I'll follow up with any other questions, or my eventual results...
Thanks!
John
On Dec 13, 2012, at 3:11 AM, Quinn The Eskimo! <email@hidden> wrote:
>
> On 12 Dec 2012, at 22:30, John Pannell <email@hidden> wrote:
>
>> 0. Prior to app distribution, it sounds like I will be creating a self-signed root certificate for use in my web service and embedding in my app. I plan to do something like what's described here: http://www.eclectica.ca/howto/ssl-cert-howto.php#rootc.
>
> That's the basic idea.
>
>> Per the instructions, this will leave me with a .pem file for the cert, and another .pem file for the private key. I'm confident enough in my Google and OpenSSL skills however to get it packaged however will work best.
>
> Ultimately you'll want to ship the digital identity to the client as PKCS#12 data. OpenSSL has no problem generating that data from a PEM certificate and private key combination. See <x-man-page://1/pkcs12> for details.
>
>> Q: What do I embed in the app, and how do I package it?
>
> The only thing you need to embed in the app is the CA's root certificate. It's easiest to embed this as CER/DER data (see <x-man-page://1/x509>).
>
>> At this point, I will read the root certificate out of the app bundle and add it to my trusted roots - correct?
>
> App's don't have "trusted roots". The system has a set of trusted roots but an app can't modify those (at least on iOS; on OS X there are APIs for this but you get lots of fun authorisation dialogs).
>
> What you want to do here is override trust evaluation and then, when you get the trust object, call SecTrustSetAnchorCertificates (but not SecTrustSetAnchorCertificatesOnly) and then evaluate trust. If that succeeds, you know that the certificate was issued by your own CA.
>
>> Q: a common use case for this app is that it is used to shuttle instances of its documents between devices owned by a single individual. If he installs the same certificate on each device, does this present any issues? (the sending and receiving peers will have identical certs).
>
> That shouldn't be a problem. Remember that the user's email address is embedded securely within the certificate. If the user connects from one device to another, your app will say "do you want to connect to the person with the email address <email@hidden>?" and the user is likely to agree to that (-:
>
> In fact, you could avoid the dialog entirely in that case. If the certificate is issued by your CA and the email addresses in the certificates match, just allow the connection.
>
>> Q: install in keychain = SecItemAdd() correct? With a class of kSecClassIdentity? And I'd send in a persistent reference, write to disk, and pull it back up to refer to this identity in the future?
>
> Yes.
>
>> Q: Now on to usage... imagine the following scenario: peer A initiates a connection to peer B
>
> Yes.
>
>> both peers have already added the embedded root certificate to their trusted roots.
>
> No, as per the above.
>
>> When A initiates and opens streams to B, I would do something like this at A:
>>
>> [inStream setProperty:NSStreamSocketSecurityLevelNegotiatedSSL forKey:NSStreamSocketSecurityLevelKey];
>> [outStream setProperty:NSStreamSocketSecurityLevelNegotiatedSSL forKey:NSStreamSocketSecurityLevelKey];
>>
>> NSDictionary *settings = [[NSDictionary alloc] initWithObjectsAndKeys:
>> [NSNumber numberWithBool:NO], kCFStreamSSLAllowsExpiredCertificates,
>> [NSNumber numberWithBool:NO], kCFStreamSSLAllowsAnyRoot,
>> [NSNumber numberWithBool:YES], kCFStreamSSLValidatesCertificateChain,
>> kCFNull,kCFStreamSSLPeerName,
>> nil];
>
> Dude, learn to love the new Objective-C literal syntax (-:
>
> <http://clang.llvm.org/docs/ObjectiveCLiterals.html>
>
> The /only/ thing you need in this dictionary is kCFStreamSSLValidatesCertificateChain set to kCFBooleanFalse. More on this below.
>
>> CFReadStreamSetProperty((CFReadStreamRef)inStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);
>> CFWriteStreamSetProperty((CFWriteStreamRef)outStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);
>
> Just FYI:
>
> o you can use -[NSStream setProperty:forKey:] for setting the kCFStreamPropertySSLSettings as well
>
> o for socket pairs you only need to the property on one of the streams
>
>> Over at B, I'm doing this when the listener gets streams to the requesting end at A:
>
> Here you only need to have kCFStreamSSLValidatesCertificateChain set to kCFBooleanFalse and kCFStreamSSLIsServer set to kCFBooleanTrue.
>
>> Q: I do *not* override the TLS chain validation, correct? It should all work, if configured as above...
>
> Nope. You need to override trust evaluation for two reasons:
>
> o You want to trust certificates issued by your CA (SecTrustSetAnchorCertificates).
>
> o You want to /not/ trust certificates not issued by your CA (that is, once you've called SecTrustSetAnchorCertificates you want to make sure not to call SecTrustSetAnchorCertificatesOnly).
>
> So, you should disable the default trust evaluation and do your own per the discussed in Technote 2232 "HTTPS Server Trust Evaluation"
>
> <https://developer.apple.com/library/ios/#technotes/tn2232/_index.html>
>
> Share and Enjoy
> --
> Quinn "The Eskimo!" <http://www.apple.com/developer/>
> Apple Developer Relations, Developer Technical Support, Core OS/Hardware
>
>
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Macnetworkprog mailing list (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden