Estoy intentando construir un servidor HTTPS en una aplicación iOS, para actuar como un proxy entre mi aplicación web y mi servidor externo.Certificado de identidad SSL para ejecutar un servidor HTTPS en iOS
He logrado hacer un servidor HTTP escuchando un socket, ya sea gracias a CFSocketRef o usando la biblioteca GCDAsyncSocket. tengo también tener éxito al hacer una aplicación de Mac que ejecuta un servidor HTTPS, usando la biblioteca GCDAsyncSocket y gracias a mi método "SecureSocket:" por debajo del cual asegura la conexión:
- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
{
// (...)
// secure the connection
[self secureSocket:newSocket];
// (...)
}
- (void)secureSocket:(GCDAsyncSocket *)sock
{
// The root self-signed certificate I have created
NSString *certificatePath = [[NSBundle mainBundle] pathForResource:@"certificate" ofType:@"cer"];
NSData *certData = [[NSData alloc] initWithContentsOfFile:certificatePath];
CFDataRef certDataRef = (CFDataRef)certData;
SecCertificateRef cert = SecCertificateCreateWithData(NULL, certDataRef);
[certData release];
// the "identity" certificate
SecIdentityRef identityRef;
SecIdentityCreateWithCertificate(NULL, cert, &identityRef);
// the certificates array, containing the identity then the root certificate
NSArray *certs = [[NSArray alloc] initWithObjects:(id)identityRef, (id)cert, nil];
// the SSL configuration
NSMutableDictionary *settings = [NSMutableDictionary dictionaryWithCapacity:3];
[settings setObject:[NSNull null] forKey:(NSString *)kCFStreamSSLPeerName];
[settings setObject:[NSNumber numberWithBool:YES] forKey:(NSString *)kCFStreamSSLAllowsAnyRoot];
[settings setObject:[NSNumber numberWithBool:YES] forKey:(NSString *)kCFStreamSSLAllowsExpiredRoots];
[settings setObject:[NSNumber numberWithBool:YES] forKey:(NSString *)kCFStreamSSLAllowsExpiredCertificates];
[settings setObject:[NSNumber numberWithBool:NO] forKey:(NSString *)kCFStreamSSLValidatesCertificateChain];
[settings setObject:(NSString *)kCFStreamSocketSecurityLevelNegotiatedSSL forKey:(NSString*)kCFStreamSSLLevel];
[settings setObject:certs forKey:(NSString *)kCFStreamSSLCertificates];
[settings setObject:[NSNumber numberWithBool:YES] forKey:(NSString *)kCFStreamSSLIsServer];
[sock startTLS:settings];
[certs release];
}
El certificado que estoy usando es un auto -certificado SSL del servidor firmado que he creado con Keychain Access. Entiendo que tengo que darle al sistema un conjunto de configuración con una matriz que contiene una identidad y un certificado. Y funciona bien en mi aplicación Mac.
El problema es habilitar SSL en el servidor HTTP de mi aplicación iOS. El método "SecIdentityCreateWithCertificate()" que crea la identidad no existe en iOS y no sé cómo crear una identidad de otra manera.
Cómo crear un SecIdentityRef en iOS (para habilitar el lado del servidor SSL)? ¿Perdí algo me gusta almacenar la clave pública/privada en mi aplicación, o alguna otra cosa? Muchas gracias.
Se ha cambiado en CocoaAsyncSocket v7.4, algunas teclas de opción antiguas ahora no están disponibles y arrojarán una excepción. Use GCDAsyncSocketManuallyEvaluateTrust y evalúe en -socket: didReceiveTrust: delegate en su lugar. Ver mi ejemplo en https://gist.github.com/hlung/6432966 – Hlung