Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
662 views
in Technique[技术] by (71.8m points)

networking - SSL Identity Certificate to run an HTTPS Server on iOS

I'm trying to build an HTTPS server in an iOS app, in order to act as a proxy between my web-app and my external server.

I have managed to make an HTTP server by listening to a socket, either thanks to CFSocketRef or using the GCDAsyncSocket library. I have also succeed to make a Mac app running an HTTPS server, using the GCDAsyncSocket library and thanks to my method "secureSocket:" below which secures the connection:

- (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];
}

The certificate I'm using is a self-signed server SSL certificate I have created with Keychain Access. So I understand that I have to give the system a configuration set with an array containing an identity and a certificate. And it works fine on my Mac app.

The problem is to enable the SSL on the HTTP server of my iOS app. The method "SecIdentityCreateWithCertificate()" which creates the identity doesn't exist on iOS and I don't know how to create an identity another way.

How to create an SecIdentityRef on iOS (to enable SSL server side)? Did I miss something like to store the public/private key in my app, or something else? Thank you so much.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I will post a separate answer, as comments are not suitable for code sharing.
Here is what I use to import my PKCS12:

CFArrayRef keyref = NULL;
OSStatus sanityChesk = SecPKCS12Import((__bridge CFDataRef)p12Data, 
                                       (__bridge CFDictionaryRef)[NSDictionary 
                                                                  dictionaryWithObject:password 
                                                                  forKey:(__bridge id)kSecImportExportPassphrase], 
                                       &keyref);

if (sanityChesk != noErr) {
    NSLog(@"Error while importing pkcs12 [%d]", sanityChesk);
    return nil;
}

NSArray *keystore = (__bridge_transfer NSArray *)keyref;

The complete p12 content will be in the keystore array.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...