Reputation: 2379
I'm trying to use a function that has the following signature to sign a HTTP request:
extern void hmac_sha1(const unsigned char *inText, int inTextLength, unsigned char* inKey, const unsigned int inKeyLength, unsigned char *outDigest);
And this is the method I wrote to use it:
- (NSString *)sign: (NSString *)stringToSign {
NSString *secretKey = @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const unsigned char *inText = (unsigned char *)[stringToSign UTF8String];
int inTextLength = [stringToSign length];
unsigned char *inKey = (unsigned char *)[secretKey UTF8String];
const unsigned int inKeyLength = (unsigned int)[secretKey length];
unsigned char *outDigest;
hmac_sha1(inText, inTextLength, inKey, inKeyLength, outDigest);
NSString *output = [NSString stringWithUTF8String:(const char *)outDigest];
return output;
}
The problem is I'm sure this is not the way I'm supposed to do this casting, as inside this hmac_sha1
function I get a EXC_BAD_ACCESS
exception.
Since I am new to Objective-C and have close to no experience in C (surprise!) I don't really know what to search for. Any tips on how I can start solving this?
Thanks in advance!
BTW, I got the reference for this function here in stackoverflow.
Upvotes: 1
Views: 6009
Reputation: 8823
This wasn't part of your question but it's a bug nonetheless, you shouldn't use -length
to get the byte count of an UTF8 string. That method returns the number of Unicode characters in the string, not the number of bytes. What you want is -lengthOfBytesUsingEncoding:
.
NSUInteger byteCount = [stringToSign lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
Also be aware that the result does not account for a terminating NULL character.
Upvotes: 2
Reputation: 21695
It looks like the problem is not with the casting, but with outDigest
. The fifth argument to hmac_sha1
should point to an already allocated buffer of size 20 bytes (I think).
If you change the line that says
unsigned char *outDigest;
to say
#define HMACSHA1_DIGEST_SIZE 20
void *outDigest = malloc(HMACSHA1_DIGEST_SIZE);
That should get you past the crash inside hmac_sha1
.
Then you've got the problem of converting the data at outDigest
into an NSString
. It looks like hmac_sha1
will put 20 bytes of random-looking data at outDigest
, and not a null terminated UTF-8 string, so stringWithUTF8String:
won't work. You might want to use something like this instead if you have to return an NSString
:
NSString *output = [[NSString alloc] initWithBytesNoCopy:outDigest
length:HMACSHA1_DIGEST_SIZE
encoding:NSASCIIStringEncoding
freeWhenDone:YES];
I don't think NSString
is really the right type for the digest, so it might be worth changing your method to return an NSData
if you can.
Upvotes: 3
Reputation: 52565
Are you sure you don't need to allocate some memory for outDigest
before calling hmac_sha1
? Since you pass in a pointer, rather than a pointer to a pointer, there's no way that the memory can be allocated inside the routine.
Upvotes: 1