Login for API does not seem to be working.

I have spent a couple hours trying to debug this but this is not working on a mac. This code is from http://wiki.mikrotik.com/wiki/API_in_C. From what I can tell the issue is in the md5 conversion. I tested the md5 on just my password and that worked correctly according to md5 converters online. I then tested it with the challenge hash in place and it was then wrong. I worked with another piece of code that works in C# to try and figure out where and why it is not working but I cant seem to figure out what is wrong. Any ideas? I attached a log file for the login process to follow as well.

The first login is working fine. The second is failing.

int MikrotikAPI::login(int fdSock, char *username, char *password)
{
	struct Sentence stReadSentence;
	struct Sentence stWriteSentence;
	char *szMD5Challenge;
	char *szMD5ChallengeBinary;
	char *szMD5PasswordToSend;
	char *szLoginUsernameResponseToSend;
	char *szLoginPasswordResponseToSend;
	md5_state_t state;
	md5_byte_t digest[16];
	char cNull[1] = {0};
	
	
	writeWord(fdSock, "/login");
	writeWord(fdSock, "");
	
	stReadSentence = readSentence(fdSock);
	DEBUG ? printSentence (&stReadSentence) : 0;
	
	if (stReadSentence.iReturnValue != DONE)
	{
		printf("error.\n");
		exit(0);
	}
	
	// extract md5 string from the challenge sentence
	szMD5Challenge = strtok(stReadSentence.szSentence[1], "=");
	szMD5Challenge = strtok(NULL, "=");
	
	DEBUG ? printf("MD5 of challenge = %s\n", szMD5Challenge) : 0;
	
	// convert szMD5Challenge to binary
	szMD5ChallengeBinary = md5ToBinary(szMD5Challenge);
	
	// get md5 of the password + challenge concatenation
	md5_init(&state);
	md5_append(&state, (const md5_byte_t *) cNull, 1);
	md5_append(&state, (const md5_byte_t *)password, strlen(password));
	md5_append(&state, (const md5_byte_t *)szMD5ChallengeBinary, strlen(szMD5ChallengeBinary));
	md5_finish(&state, digest);
	
	// convert this digest to a string representation of the hex values
	// digest is the binary format of what we want to send
	// szMD5PasswordToSend is the "string" hex format
	szMD5PasswordToSend = md5DigestToHexString(digest);
	
	DEBUG ? printf("szPasswordToSend = %s\n", szMD5PasswordToSend) : 0;
	
	// put together the login sentence
	initializeSentence(&stWriteSentence);
	
	addWordToSentence(&stWriteSentence, "/login");
	addWordToSentence(&stWriteSentence, "=name=");
	addPartWordToSentence(&stWriteSentence, username);
	addWordToSentence(&stWriteSentence, "=response=00");
	addPartWordToSentence(&stWriteSentence, szMD5PasswordToSend);
	
	DEBUG ? printSentence(&stWriteSentence) : 0;
	writeSentence(fdSock, &stWriteSentence);
	
	
	stReadSentence = readSentence(fdSock);
	DEBUG ? printSentence (&stReadSentence) : 0;
	
	if (stReadSentence.iReturnValue == DONE)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}



[Session started at 2010-02-02 05:44:46 -0800.]
Connecting to 64.126.135.214
Successfully connected to 64.126.135.214
Word to write is /login
length of word is 6
Word to write is
length of word is 0
readSentence
initializeSentence
start readLen()
byte1 = 0x5
1-byte encoded length
readWord iLen=5
word = !done
return sentence contains !done
start readLen()
byte1 = 0x25
1-byte encoded length
readWord iLen=25
word = =ret=7482c02112f004b6cc5685bc1a1563e7
start readLen()
byte1 = 0
1-byte encoded length
readWord iLen=0
stReturnSentence.szSentence[0] = !done
stReturnSentence.szSentence[1] = =ret=7482c02112f004b6cc5685bc1a1563e7
Sentence iLength = 2
Sentence iReturnValue = 1
Sentence iLength = 2
Sentence iReturnValue = 1
>>> !done
>>> =ret=7482c02112f004b6cc5685bc1a1563e7

MD5 of challenge = 7482c02112f004b6cc5685bc1a1563e7
cBinWork = 74
116
cBinWork = 82
130
cBinWork = c0
192
cBinWork = 21
33
cBinWork = 12
18
cBinWork = f0
240
cBinWork = 04
4
cBinWork = b6
182
cBinWork = cc
204
cBinWork = 56
86
cBinWork = 85
133
cBinWork = bc
188
cBinWork = 1a
26
cBinWork = 15
21
cBinWork = 63
99
cBinWork = e7
231
szPasswordToSend = 6047dbf2c1b49e19130e426aee2674f0
initializeSentence
Sentence iLength = 3
Sentence iReturnValue = 0
Sentence iLength = 3
Sentence iReturnValue = 0
>>> /login
>>> =name=test
>>> =response=006047dbf2c1b49e19130e426aee2674f0

Writing sentence
Sentence iLength = 3
Sentence iReturnValue = 0
Sentence iLength = 3
Sentence iReturnValue = 0
>>> /login
>>> =name=test
>>> =response=006047dbf2c1b49e19130e426aee2674f0

Word to write is /login
length of word is 6
Word to write is =name=test
length of word is 10
Word to write is =response=006047dbf2c1b49e19130e426aee2674f0
length of word is 44
Word to write is
length of word is 0
readSentence
initializeSentence
start readLen()
byte1 = 0x5
1-byte encoded length
readWord iLen=5
word = !trap
return sentence contains !trap
start readLen()
byte1 = 0x16
1-byte encoded length
readWord iLen=16
word = =message=cannot log in
start readLen()
byte1 = 0
1-byte encoded length
readWord iLen=0
readSentence
initializeSentence
start readLen()
byte1 = 0x5
1-byte encoded length
readWord iLen=5
word = !done
return sentence contains !done
start readLen()
byte1 = 0
1-byte encoded length
readWord iLen=0
stReturnSentence.szSentence[0] = !done
stReturnSentence.szSentence[0] = !trap
stReturnSentence.szSentence[1] = =message=cannot log in
Sentence iLength = 2
Sentence iReturnValue = 2
Sentence iLength = 2
Sentence iReturnValue = 2
>>> !trap
>>> =message=cannot log in

Closing socket
Invalid username or password.

I figured out the issue…

By changing
md5_append(&state, (const md5_byte_t *)szMD5ChallengeBinary, strlen(szMD5ChallengeBinary));
to
md5_append(&state, (const md5_byte_t *)szMD5ChallengeBinary, 16);