Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CA-signed certificate verification added #399

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Classes/ASIHTTPRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ typedef void (^ASIDataBlock)(NSData *data);

NSOutputStream *inflatedFileDownloadOutputStream;

// True if the certificate verification is done
BOOL certificateVerified;

// When the request fails or completes successfully, complete will be true
BOOL complete;

Expand Down Expand Up @@ -703,6 +706,8 @@ typedef void (^ASIDataBlock)(NSData *data);
- (BOOL)showProxyAuthenticationDialog;
- (BOOL)showAuthenticationDialog;

- (BOOL) VerifyCertificate;

// Construct a basic authentication header from the username and password supplied, and add it to the request headers
// Used when shouldPresentCredentialsBeforeChallenge is YES
- (void)addBasicAuthenticationHeaderWithUsername:(NSString *)theUsername andPassword:(NSString *)thePassword;
Expand Down Expand Up @@ -934,6 +939,7 @@ typedef void (^ASIDataBlock)(NSData *data);
@property (atomic, retain,readonly) NSString *authenticationRealm;
@property (atomic, retain,readonly) NSString *proxyAuthenticationRealm;
@property (atomic, retain) NSError *error;
@property (atomic, assign) BOOL certificateVerified;
@property (atomic, assign,readonly) BOOL complete;
@property (atomic, retain) NSDictionary *responseHeaders;
@property (atomic, retain) NSMutableDictionary *requestHeaders;
Expand Down
66 changes: 64 additions & 2 deletions Classes/ASIHTTPRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -1153,7 +1153,7 @@ - (void)startRequest
if ([self lastBytesSent] > 0) {
[self removeUploadProgressSoFar];
}

[self setCertificateVerified:NO];
[self setLastBytesSent:0];
[self setContentLength:0];
[self setResponseHeaders:nil];
Expand Down Expand Up @@ -1219,13 +1219,26 @@ - (void)startRequest
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
[NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,
kCFNull,kCFStreamSSLPeerName,
@"kCFStreamSocketSecurityLevelTLSv1_0SSLv3", kCFStreamSSLLevel,
nil];

CFReadStreamSetProperty((CFReadStreamRef)[self readStream],
kCFStreamPropertySSLSettings,
(CFTypeRef)sslProperties);
[sslProperties release];
}
} else {
+ NSDictionary *sslProperties = [[NSDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithBool:NO], kCFStreamSSLAllowsExpiredCertificates,
+ [NSNumber numberWithBool:NO], kCFStreamSSLAllowsAnyRoot,
+ [NSNumber numberWithBool:YES], kCFStreamSSLValidatesCertificateChain,
+ @"kCFStreamSocketSecurityLevelTLSv1_0SSLv3", kCFStreamSSLLevel,
+ nil];
+
+ CFReadStreamSetProperty((CFReadStreamRef)[self readStream],
+ kCFStreamPropertySSLSettings,
+ (CFTypeRef)sslProperties);
+ [sslProperties release];
+ }

// Tell CFNetwork to use a client certificate
if (clientCertificateIdentity) {
Expand Down Expand Up @@ -3243,8 +3256,56 @@ - (BOOL)willAskDelegateToConfirmRedirect
return false;
}

-(BOOL) VerifyCertificate
{
NSData *trustedCertData = nil;
BOOL result = NO;
SecTrustRef trustRef = NULL;

NSString *root_certificate_name = @"philips_trusted_cert";
NSString *root_certificate_extension = @"der";

/** Reading root cetificate **/
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
trustedCertData = [NSData dataWithContentsOfFile:[bundle pathForResource: root_certificate_name ofType: root_certificate_extension]];
NS_ASSERT(trustedCertData != nil, @"trustedCertData failed.");

/** Reading server cetificate **/
trustRef = (__bridge SecTrustRef)[readStream propertyForKey:(__bridge id)kCFStreamPropertySSLPeerTrust];
NS_ASSERT(trustRef != NULL, @"Could not create a trust management object!");

/* Check which certificate is identical to root certificate */
NSInteger numCerts = SecTrustGetCertificateCount(trustRef);
for (NSInteger i = 0; i < numCerts; i++) {
SecCertificateRef secCertRef = SecTrustGetCertificateAtIndex(trustRef, i);
NSData *certData = CFBridgingRelease(SecCertificateCopyData(secCertRef));
if ([trustedCertData isEqualToData: certData]) {
result = YES;
break;
}
}

if (!result) {
[self cancelLoad];
[self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIConnectionFailureErrorType
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Certificate verification failed"], NSLocalizedDescriptionKey,nil]]];
}

return result;
}

- (void)handleBytesAvailable
{
if(![self certificateVerified]) {
[self setCertificateVerified:YES];
if([self VerifyCertificate]) {
NSLog(@"Certificate Verification Success.");
} else
{
NSLog(@"Certificate Verification Failed.");
return;
}
}
if (![self responseHeaders]) {
[self readResponseHeaders];
}
Expand Down Expand Up @@ -5037,6 +5098,7 @@ - (void)setRequestRedirectedBlock:(ASIBasicBlock)aRedirectBlock
@synthesize didReceiveDataSelector;
@synthesize authenticationRealm;
@synthesize proxyAuthenticationRealm;
@synthesize certificateVerified;
@synthesize error;
@synthesize complete;
@synthesize requestHeaders;
Expand Down