Reputation: 4127
How would you pin an SSL certificate (DER format) in iOS by hard coding it?
For example, currently you could use something such as the following:
NSData *mydata = [NSData dataWithContentsOfURL:[[NSBundle mainBundle]
URLForResource:@"mycert" withExtension:@"cer"]];
Then get the certificate bytes
and length
with the methods provided by NSData
.
Could it instead be stored as an char
array?
I ask this because if you store the certificate file in the bundle surely anyone could just swap it out for another certificate.
Upvotes: 2
Views: 2263
Reputation: 764
This is possible. One way to do it would be to temporarily import the certificate as you have done:
NSData *mydata = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"mycert" withExtension:@"cer"]];
Then simply log this out as such:
NSLog(@"%@",myData);
This will output some long string enclosed by < and > symbols.
Example output of NSData object:
<6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8
6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8
6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8
6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8
6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8
6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8
6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8>
Copy this output and hard-code it into the top one of your .m files. This way it will be compiled into non-human-readable code.
Here is a way to accomplish this:
#define CERT_DATA @"<6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8
6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8
6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8
6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8
6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8
6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8
6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8 6j5434 34j320 29dmr4 dj28d8>"
The next piece is the key to making this method work. You have to convert a string representation of NSData back into NSData.
Here is a method that will do exactly that:
-(void)yourMethodThatNeedsCertData
{
NSData *certData = [self dataFromHexString:[[[CERT_DATA stringByReplacingOccurrencesOfString:@"<" withString:@""]stringByReplacingOccurrencesOfString:@">" withString:@""] stringByReplacingOccurrencesOfString:@" " withString:@""]];
}
- (NSData *)dataFromHexString:(NSString *)string
{
// Converts the NSData string representation back into NSData object
const char *chars = [string UTF8String];
int i = 0, len = string.length;
NSMutableData *data = [NSMutableData dataWithCapacity:len / 2];
char byteChars[3] = {'\0','\0','\0'};
unsigned long wholeByte;
while (i < len)
{
byteChars[0] = chars[i++];
byteChars[1] = chars[i++];
wholeByte = strtoul(byteChars, NULL, 16);
[data appendBytes:&wholeByte length:1];
}
return data;
}
Notice that you have to 'clean' the NSData string CERT_DATA by removing all white space and the '<' '>' characters. Good luck to you and I hope this helps!
Upvotes: 3