loadPrivateKeyFromPpk static method
This helper method takes a ppkFileContent
and its password
and
extracts the private key into a list.
Implementation
static Uint8List loadPrivateKeyFromPpk(String? ppkFileContent,
{String? password}) {
if (ppkFileContent == null) {
throw Exception(
'There is no file content provided to load a private key from!');
}
var encrypted = false;
var endOfHeader = false;
var publicKeyIndex = 0;
var privateKeyIndex = 0;
var publicKey = '';
var privateKey = '';
String? privateMac;
var lines = ppkFileContent.split('\n');
var macData = PpkMacData();
for (var line in lines) {
if (!endOfHeader) {
if (lines.indexOf(line) == 0 &&
!line.startsWith('PuTTY-User-Key-File-')) {
throw Exception('File is no valid putty ssh-2 key file!');
}
if (line.startsWith('PuTTY-User-Key-File-')) {
if (!line.startsWith('PuTTY-User-Key-File-2')) {
throw Exception('Unsupported ssh-2 key file version!');
}
if (!line.trimRight().endsWith('ssh-ed25519')) {
throw Exception(
'The putty key has the wrong encryption method, use ssh-ed25519!');
}
macData.algorithm = 'ssh-ed25519';
}
if (line.startsWith('Encryption')) {
if (!line.trimRight().endsWith('none')) {
if (!line.trimRight().endsWith('aes256-cbc')) {
throw Exception(
'Unknown or unsupported putty file encryption! Supported values are "none" and "aes256-cbc"');
}
encrypted = true;
}
macData.encryption = line.split(': ')[1].trimRight();
}
if (line.startsWith('Comment')) {
macData.comment = line.split(': ')[1].trimRight();
}
if (line.startsWith('Public-Lines')) {
endOfHeader = true;
publicKeyIndex = int.parse(line.split(': ')[1].trimRight());
continue;
}
} else if (line.startsWith('Private-Lines')) {
privateKeyIndex = int.parse(line.split(': ')[1].trimRight());
} else if (publicKeyIndex > 0) {
publicKey += line.trimRight();
publicKeyIndex--;
} else if (privateKeyIndex > 0) {
privateKey += line.trimRight();
privateKeyIndex--;
} else if (line.startsWith('Private-MAC')) {
privateMac = line.split(': ')[1].trimRight();
}
}
macData.publicKey = base64.decode(publicKey);
if (privateKey.isNotEmpty) {
Uint8List privateKeyDecrypted;
if (encrypted) {
if (password == null || password.isEmpty) {
throw Exception('No or empty password provided!');
}
privateKeyDecrypted =
decodePpkPrivateKey(base64.decode(privateKey), password);
} else {
privateKeyDecrypted = base64.decode(privateKey);
}
macData.privateKey = privateKeyDecrypted;
ppkMacCheck(privateMac, macData, password);
return privateKeyDecrypted.sublist(4, 36);
} else {
throw Exception('Wrong file format. Could not extract a private key');
}
}