invalidate the HTTPS certificate

What happens when you try to connect to an HTTPS webserver which has an invalid SSL certificate? For example when the hostname of the website is not the same as the one in the SSL certificate.

With a browser (Safari or Firefox), you get an alert like the following:

If you try to connect to this webserver using NSURLConnection (Cocoa) or CFReadStream (Carbon), you get an error. In Cocoa, NSURLConnection fails with an error -1202 (NSURLErrorServerCertificateUntrusted). In Carbon, CFReadStreamRead returns -1, which means no data have been received.

The right way to fix this issue, is of course to create a new SSL certificate with the right hostname inside. But sometimes, it’s not your webserver and you don’t really care if the certificate is valid or not because you don’t send sensitive data. In that case, there is an easy way to just ignore the certificate.

With Carbon

If you are developing with Carbon, you can set some properties to the CFReadStream. To ignore the SSL certificate, you can simply set the property kCFStreamSSLValidatesCertificateChain of the CFReadStream to false. The following sample do a POST request

 

code:

//

// Created by Alexandre Colucci on 23/07/2008.

// Copyright 2008 Alexandre Colucci. All rights reserved.

 

int main(int argc, char * argv[])

{

// The URL of the Webserver

CFURLRef myWebserverURLRef = CFURLCreateWithString (kCFAllocatorDefault , CFSTR ("https://myWebserver.com/" ), NULL );

if (myWebserverURLRef != NULL )

{

// Create the HTTP message

CFHTTPMessageRef theMessageRef = CFHTTPMessageCreateRequest ( kCFAllocatorDefault, CFSTR ( "POST" ), myWebserverURLRef, kCFHTTPVersion1_1);

if (theMessageRef != NULL )

{

// Set useful headers

CFHTTPMessageSetHeaderFieldValue(theMessageRef, CFSTR ( "Accept" ), CFSTR ( "text/xml" ));

CFHTTPMessageSetHeaderFieldValue(theMessageRef, CFSTR ( "Content-type" ), CFSTR ( "application/xml" ));

// The body

char *theDataString = "<?xml version=/"1.0/" encoding=/"UTF-8/"?><something></something>";

CFDataRef dataRef = CFDataCreate (kCFAllocatorDefault , (const UInt8 *)theDataString, strlen (theDataString));

CFHTTPMessageSetBody (theMessageRef, dataRef);

// Create the CFReadStreamRef

CFReadStreamRef streamRef = CFReadStreamCreateForHTTPRequest (kCFAllocatorDefault , theMessageRef);

if (streamRef != NULL )

{

// We don't want to validate the HTTPS certificate.

CFMutableDictionaryRef securityDictRef = CFDictionaryCreateMutable ( kCFAllocatorDefault, 0 , & kCFTypeDictionaryKeyCallBacks, & kCFTypeDictionaryValueCallBacks);

if (securityDictRef != NULL )

{

CFDictionarySetValue (securityDictRef, kCFStreamSSLValidatesCertificateChain, kCFBooleanFalse);

CFReadStreamSetProperty (streamRef, kCFStreamPropertySSLSettings , securityDictRef);

CFRelease (securityDictRef);

}

// Open the stream

CFReadStreamOpen (streamRef);

// Read the data

CFIndex theBufferLength = 1024 ;

UInt8 theBuffer[1024 ];

CFIndex theBytesRead = 0 ;

CFMutableStringRef theMutableStringRef = CFStringCreateMutable ( kCFAllocatorDefault, 0 );

do

{

theBytesRead = CFReadStreamRead (streamRef, theBuffer, theBufferLength);

if (theBufferLength > 0 )

CFStringAppendCString (theMutableStringRef, (const char *)theBuffer, kCFStringEncodingASCII );

}

while (theBytesRead > 0 );

if (theBytesRead < 0 )

fprintf ( stderr , "Host is down?/n");

else

{

fprintf ( stderr , "didReceiveData: /n");

CFShow (theMutableStringRef);

}

CFRelease (theMutableStringRef);

CFRelease (streamRef);

}

CFRelease (dataRef);

CFRelease (theMessageRef);

}

CFRelease (myWebserverURLRef);

}

return 0 ;

}

//

With Cocoa

NSURLRequest has a private method called setAllowsAnyHTTPSCertificate:forHost: which simply ignores the certificate.

The following sample do the same POST request as the Carbon version: 

 

code:

//

@interface NSURLRequest (DummyInterface)

+ (BOOL )allowsAnyHTTPSCertificateForHost:(NSString *)host;

+ (void )setAllowsAnyHTTPSCertificate:(BOOL )allow forHost:(NSString *)host;

@end

 

@implementation MainController

 

-(IBAction )doSomething:(id )sender

{

// The URL of the Webserver

NSURL *myWebserverURL = [ NSURL URLWithString : @"https://myWebserver.com/"];

// Create the request

NSMutableURLRequest *theRequest = [ NSMutableURLRequest requestWithURL:myWebserverURL cachePolicy: NSURLRequestReloadIgnoringCacheData timeoutInterval: 60.0 ];

// Set the HTTP method.

[theRequest setHTTPMethod :@"POST" ];

// Set useful headers

[theRequest setValue: @"text/xml" forHTTPHeaderField: @"Accept" ];

[theRequest setValue : @"application/xml" forHTTPHeaderField : @"Content-type"];

// The body

NSString *theDataString = @"<?xml version=/"1.0/" encoding=/"UTF-8/"?><something></something>";

NSData *theData = [theDataString dataUsingEncoding: NSUTF8StringEncoding];

[theRequest setHTTPBody :theData];

// Use the private method setAllowsAnyHTTPSCertificate:forHost:

// to not validate the HTTPS certificate.

[ NSURLRequest setAllowsAnyHTTPSCertificate: YES forHost:[myWebserverURL host ]];

// Create the NSURLConnection and init the request.

[[ NSURLConnection alloc] initWithRequest:theRequest delegate: self ];

}

//

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值