I'm trying to implement the putty file format in one of my dart packages. Implementing the actual key loading was ok, but I'm struggeling with the mac validation. I'm not shure what I'm doing wrong here
The putty code is quite clear about how to check it, but something is still wrong here. The putty code generates the validating mac like this:
hash = ssh_hash_new(&ssh_sha1);
put_data(hash, header, sizeof(header)-1);
if (cipher && passphrase)
put_data(hash, passphrase, passlen);
ssh_hash_final(hash, mackey);
mac = ssh2_mac_new(&ssh_hmac_sha1, NULL);
ssh2_mac_setkey(mac, make_ptrlen(mackey, 20));
ssh2_mac_start(mac);
put_data(mac, macdata->s, macdata->len);
ssh2_mac_genresult(mac, binary);
ssh2_mac_free(mac);
my dart code does it like this:
var sha1Hash = SHA1Digest()
..update(Uint8List.fromList("putty-private-key-file-mac-key".codeUnits), 0, "putty-private-key-file-mac-key".codeUnits.length);
if (password != null) {
sha1Hash.update(Uint8List.fromList(password.codeUnits), 0, password.codeUnits.length);
}
var key = Uint8List(20);
sha1Hash.doFinal(key, 0);
var macResult = Uint8List(20);
var mac = HMac(SHA1Digest(), 64);
mac.init(KeyParameter(key));
mac.update(Uint8List.fromList(macData.codeUnits), 0, macData.codeUnits.length);
mac.doFinal(macResult, 0);
I'm pretty sure that the first part of creating the key for the mac is correct, because the same code is used to decrypt the private key and it works as expected. I'm not sure about the second part of creating the actual MAC.
Maybe my algorithm is right an I'm doing something else wrong? To check that in depth it would be nice if someone could provide me with a testvector containing:
- ppkFileContent
- password
- macData
- key