I'm trying to implement the auth-md5 authentication scheme in the  
SyncML spec but have hit a very confusing snag that's been baking my  
noodle.

The digest setup is fairly simple (in theory):
	base64(md5(base64(md5("username:password") + ":" + nonce)))

Here's some PHP code I found on the Horde mailing list that makes  
this happen:
	<?php
	
	function md5_base64($data)
	{
		return base64_encode(pack('H*',md5($data)));
	}
	
	function md5_syncml_new($user,$pass,$nonce)
	{
		return md5_base64(md5_base64($user.":".$pass).":".$nonce);
	}
	
	print base64_encode(pack('H*',md5("Bruce2:OhBehave")));
	print md5_syncml_new("Bruce2","OhBehave","Nonce");
	print "Zz6EivR3yeaaENcRN6lpAQ==";
	
	?>

Works perfectly. The same (at least unless I'm missing something  
truly painfully obvious) in Ruby, doesn't:
   def md5_base64(data)
     Base64.encode64(MD5.digest(data))
   end

   def md5_syncml_new(user,pass,nonce)
       return md5_base64(md5_base64(user+":"+pass)+":"+nonce);
   end

   puts md5_syncml_new("Bruce2","OhBehave","Nonce")

which gives: rBVodJ8RrZ3qC7EksecINA==

Things seem to fall apart in the final step of appending the nonce  
and hashing it again.

PHP's md5() and MD5.hexdigest() come out the same
	print md5("Bruce2:OhBehave");
	=> 3ed11dafc941438e486d3d5b64892b39
	
	>> MD5.hexdigest("Bruce2:OhBehave")
	=> "3ed11dafc941438e486d3d5b64892b39"

Base64 encoding that also works out (Note, php's pack() on the md5()  
output is equivlalent to MD5.digest()):
	print base64_encode(pack('H*',md5("Bruce2:OhBehave")));
	=> PtEdr8lBQ45IbT1bZIkrOQ==
	
	>> Base64.encode64(MD5.digest("Bruce2:OhBehave"))
	=> "PtEdr8lBQ45IbT1bZIkrOQ==\n"


I'm willing to bet there's something horribly wrong with my code, but  
have just been staring at it far too much to see it. Any help would  
be hugely appreciated.

Thanks,
-Dane