Hey there,
Setup: I am writing an app for iOS 7 that implements a Client-Server architecture (one iPhone acts as server the other iPhone acts as client). Therefore I am using CFStream and SSL/TLS to make the connection suitable secure. Problem: Now the connection as well as SSL/TLS are working great but now I want to specify the ciphers that are used by SSL/TLS and here I get stuck. The procedure is as follows: I get the ssl context from the stream before it opens on both server- and client side I read all the enabled ciphers I intersect the enabled ciphers with those I want to have in the end Then I set the enabled ciphers to be exactly that intersection (which is non-zero) Errors? Strange is, that I do not get any return values that could indicate a coding error. The only thing that happens is, that I get a stream error and of course no connection at all. Code: Here is my code. I do set the ssl properties before the stream opens on both client- (Before sending connection request by opening the stream) and server side (handleConnect). ——————8<—————————— - (bool)setSSLpropertiesForStreamsIn:(NSInputStream*)readStream andOut:(NSOutputStream*)writeStream withServerRole:(BOOL)isServer { if (!_ssl) { return YES; } // Setting streams to use TLS [readStream setProperty:NSStreamSocketSecurityLevelNegotiatedSSL forKey:NSStreamSocketSecurityLevelKey]; [writeStream setProperty:NSStreamSocketSecurityLevelNegotiatedSSL forKey:NSStreamSocketSecurityLevelKey]; // Get our identity SecIdentityRef identityRef; SecCertificateRef certificate; BOOL status = [self getP2PConnectionCertificate:&certificate andIdentity:&identityRef]; if (!status) { NSLog(@"Unable to obtain certificate and identity!"); return NO; } // Setting properties. Atm every certificate is accepted and no hostname will be checked NSArray *certificates = [NSArray arrayWithObjects:(__bridge id)identityRef,(__bridge id)certificate, nil]; NSDictionary *settings = @{(NSString *)kCFStreamPropertyShouldCloseNativeSocket: [NSNumber numberWithBool:YES], (NSString *)kCFStreamSSLValidatesCertificateChain: [NSNumber numberWithBool:NO], (NSString *)kCFStreamSSLAllowsExpiredCertificates: [NSNumber numberWithBool:YES], (NSString *)kCFStreamSSLAllowsExpiredRoots: [NSNumber numberWithBool:YES], (NSString *)kCFStreamSSLAllowsAnyRoot: [NSNumber numberWithBool:YES], (NSString *)kCFStreamSSLCertificates: certificates, (NSString *)kCFStreamSSLIsServer: [NSNumber numberWithBool:isServer], (NSString *)kCFStreamSSLLevel: (NSString *)kCFStreamSocketSecurityLevelNegotiatedSSL }; // Apply properties. bool success1 = CFReadStreamSetProperty ((CFReadStreamRef) readStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings); bool success2 = CFWriteStreamSetProperty((CFWriteStreamRef) writeStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings); // Now change the ciphers to those that we want // Get SSLContext to access the ssl properties CFDataRef socketSSLContextData = (CFDataRef) CFReadStreamCopyProperty((CFReadStreamRef) readStream, kCFStreamPropertySocketSSLContext); SSLContextRef sslContext; CFDataGetBytes(socketSSLContextData, CFRangeMake(0, sizeof(SSLContextRef)), (UInt8*)&sslContext); // Get enabled ciphers size_t numCiphers = 0; SSLGetNumberEnabledCiphers(sslContext, &numCiphers); SSLCipherSuite *enabledCiphers = (SSLCipherSuite *)malloc(sizeof(SSLCipherSuite) * numCiphers); SSLGetEnabledCiphers(sslContext, enabledCiphers, &numCiphers); // Converting to NSSet for better performance SSLCipherSuite *targetCiphers[41] = { TLS_ECDH_ECDSA_WITH_NULL_SHA , TLS_ECDH_ECDSA_WITH_RC4_128_SHA , TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA , TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA , TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA , TLS_ECDHE_ECDSA_WITH_NULL_SHA , TLS_ECDHE_ECDSA_WITH_RC4_128_SHA , TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA , TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA , TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA , TLS_ECDH_RSA_WITH_NULL_SHA , TLS_ECDH_RSA_WITH_RC4_128_SHA , TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA , TLS_ECDH_RSA_WITH_AES_128_CBC_SHA , TLS_ECDH_RSA_WITH_AES_256_CBC_SHA , TLS_ECDHE_RSA_WITH_NULL_SHA , TLS_ECDHE_RSA_WITH_RC4_128_SHA , TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA , TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA , TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA , TLS_ECDH_anon_WITH_NULL_SHA , TLS_ECDH_anon_WITH_RC4_128_SHA , TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA , TLS_ECDH_anon_WITH_AES_128_CBC_SHA , TLS_ECDH_anon_WITH_AES_256_CBC_SHA , TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 , TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 , TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 , TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 , TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 , TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 , TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 , TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 , TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 , TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 , TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 , TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 , TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 , TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 , TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 , TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 }; NSMutableSet *setOfTargetCiphers = [[NSMutableSet alloc] init]; for (int i = 0; i < 41; i++) [setOfTargetCiphers addObject:[NSNumber numberWithInt:targetCiphers[i]]]; NSMutableSet *setOfEnabledCiphers = [[NSMutableSet alloc] init]; for (int i = 0; i < numCiphers; i++) [setOfEnabledCiphers addObject:[NSNumber numberWithInt:enabledCiphers[i]]]; // Compute intersection set to get possible values for the connection [setOfEnabledCiphers intersectSet:setOfTargetCiphers]; // Removes from the set of enabled ciphers those that are not in the set of target ciphers // Set the remaining setOfEnabledCiphers to be the only enabled ciphers in the ssl connection int numberOfLeftCiphers = [setOfEnabledCiphers count]; SSLCipherSuite *ciphers = (SSLCipherSuite *)malloc(numberOfLeftCiphers * sizeof(SSLCipherSuite)); for (NSNumber* numberOfCipher in setOfEnabledCiphers) { ciphers[numberOfLeftCiphers-1] = [numberOfCipher intValue]; numberOfLeftCiphers -= 1; } OSStatus osStatus = SSLSetEnabledCiphers(sslContext, ciphers, 1); if (osStatus != noErr) NSLog(@"Unable to set the accepted chiphers to the SSL context!"); // Check for success if ((success1 & success2) && !_invalid) { NSLog(@"SSL/TLS settings for streams are set."); NSLog(@"SSL/TLS settings were set for server: %i", isServer); } return (success1 & success2); } ——————>8—————————— Can anybody help me here please? Any help is very appreciated. Kind regards, Bastian
signature.asc
Description: Message signed with OpenPGP using GPGMail
_______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com