0

Trying to take a character arracy (new to C) and encode it in SHA1.

The following bit of code is not working. As its returning '\x10'

char encode[1000];
strcpy(encode, "GET\n\n\n");
strcat(encode, tim);
strcat(encode, "\n");
strcat(encode, uri);

size_t length = sizeof(encode);
unsigned char hash[SHA_DIGEST_LENGTH];
SHA1(encode, length, hash);

return hash;

At the end of the day, I would like to have a base64 representation of the hash. Thanks!!!

Cmag
  • 14,946
  • 25
  • 89
  • 140
  • Show us more code. Show us SHA1's declaration, and show us the full code of this function. – user123 May 14 '13 at 17:21
  • Is SHA1 from openssl/sha.h? Also, can you show use where you declare and set tim, uri, and SHA_DIGEST_LENGTH? – Alex Becker May 14 '13 at 17:22
  • THANKS GUYS! :) http://pastie.org/7907792 – Cmag May 14 '13 at 17:24
  • 1
    Hash is not safe to return since its scope would be limited to the function it is declared in. Either allocate hash via malloc/calloc or pass it into the function. – Dan May 14 '13 at 17:26
  • @Dan not sure how to allocate hash via malloc... – Cmag May 14 '13 at 17:36
  • Are you sure that you want `sizeof()` there and not `strlen()`? The former is always `1000` (because `1000 * sizeof(char)` is the size of whole "encode", regardless of contents), while the latter would be the length of the actual string contained in the array. – Tim Čas May 14 '13 at 17:47

3 Answers3

1

Most likely, your problem is that you're returning locally declared memory with a lifetime equal to your function's scope. It will be non-existent outside of that scope. You should probably allow the user to pass in a buffer of his own to hold the hash:

/* Requires a buffer with a size of at least SHA_DIGEST_LENGTH bytes. */
void do_hash(unsigned char* buffer) {
    /* your code */
    SHA1(encode, length, buffer);
}

Example of usage:

unsigned char* hash = malloc(sizeof(unsigned char) * SHA_DIGEST_LENGTH);
do_hash(hash);

/* do whatever you want */

free(hash);
user123
  • 8,970
  • 2
  • 31
  • 52
  • Well, when you're done with it, you don't need the memory to remain allocated, so you'd free it to save some RAM. – user123 May 14 '13 at 17:49
1

I agree that the return hash is problematic because your array is locally declared and therefore is on the stack and is unreliable after the function returns. It may work, but don't count on it.

Openssl has another behavior that you could use:

strcpy(encode, "GET\n\n\n");
strcat(encode, tim);
strcat(encode, "\n");
strcat(encode, uri);

size_t length = sizeof(encode);
return SHA1(encode, length, NULL);

This will return a static array that SHA1 "manages". However, that array will be overwritten the next time you call SHA1.

Additionally, SHA1 is just calculating the raw digest. You would need to convert it if you want base64. It may be that 0x10 truly is the first byte of the digest.

Chad Barth
  • 528
  • 3
  • 11
0

typo in the code, had to be:

size_t length = sizeof(encode);
unsigned char hash[length];
SHA1(encode, length, hash);

Now, to get this into base64 :)

Cmag
  • 14,946
  • 25
  • 89
  • 140