ppkMacCheck static method
This method performs the mac check against the privateMac
to validate
the files content. It is also capable of testing whether the password
was wrong or not. The macData
is data used to compute the mac and to
compare it to the given privateMac
Implementation
static void ppkMacCheck(
String? privateMac, PpkMacData macData, String? password) {
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([0, 0, 0, macData.algorithm.codeUnits.length]),
0,
4);
mac.update(utf8.encode(macData.algorithm) as Uint8List, 0,
macData.algorithm.codeUnits.length);
mac.update(
Uint8List.fromList([0, 0, 0, macData.encryption.codeUnits.length]),
0,
4);
mac.update(utf8.encode(macData.encryption) as Uint8List, 0,
macData.encryption.length);
mac.update(
Uint8List.fromList([0, 0, 0, macData.comment.codeUnits.length]), 0, 4);
mac.update(
utf8.encode(macData.comment) as Uint8List, 0, macData.comment.length);
mac.update(Uint8List.fromList([0, 0, 0, macData.publicKey.length]), 0, 4);
mac.update(macData.publicKey, 0, macData.publicKey.length);
mac.update(Uint8List.fromList([0, 0, 0, macData.privateKey.length]), 0, 4);
mac.update(macData.privateKey, 0, macData.privateKey.length);
mac.doFinal(macResult, 0);
if (Base16Encoder.instance.encode(ByteList(macResult)) != privateMac) {
if (password == null) {
throw Exception('Mac check failed, file is corrupt!');
} else {
throw Exception('Wrong password!');
}
}
}