Generate key on startup or load from keystore.

This commit is contained in:
lemoer 2025-06-20 14:31:37 +02:00
parent 01173b6fd1
commit 3db0026846

View File

@ -1,5 +1,4 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io';
import 'package:dartssh2/dartssh2.dart'; import 'package:dartssh2/dartssh2.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -67,7 +66,6 @@ class _MyHomePageState extends State<MyHomePage> {
OpenSSHEd25519KeyPair? keyPair; OpenSSHEd25519KeyPair? keyPair;
String _output = ''; String _output = '';
String key = ''; String key = '';
Future<void> doSSH() async { Future<void> doSSH() async {
SSHSocket? socket; SSHSocket? socket;
@ -96,14 +94,36 @@ class _MyHomePageState extends State<MyHomePage> {
} }
} }
Future<void> generateKey() async { Future<void> obtainKeyPair({bool regenerate = false}) async {
// Generate a key pair // Generate a key pair
final storage = const FlutterSecureStorage();
final storedKey = await storage.read(key: 'ssh_key_pair');
// Restore the key if we have one stored and regeneration is not requested
if (storedKey != null && !regenerate) {
// If we have a stored key, use it
final keyPairsFromStorage = SSHKeyPair.fromPem(storedKey);
assert(keyPairsFromStorage.length == 1);
assert(keyPairsFromStorage[0] is OpenSSHEd25519KeyPair);
final keyPairFromStorage =
keyPairsFromStorage[0] as OpenSSHEd25519KeyPair;
setState(() {
keyPair = keyPairFromStorage;
key = encodePublicKey(keyPairFromStorage, comment: "leinelab-app-key");
});
return;
}
final generatedKeyPair = final generatedKeyPair =
await generateKeyPair(); // local variable avoids downcast to ? ptr await generateKeyPair(); // local variable avoids downcast to ? ptr
keyPair = generatedKeyPair;
await storage.write(key: 'ssh_key_pair', value: generatedKeyPair.toPem());
setState(() { setState(() {
keyPair = generatedKeyPair;
key = encodePublicKey(generatedKeyPair, comment: "leinelab-app-key"); key = encodePublicKey(generatedKeyPair, comment: "leinelab-app-key");
}); });
@ -113,6 +133,14 @@ class _MyHomePageState extends State<MyHomePage> {
); );
} }
@override
void initState() {
super.initState();
// we do not await generateKey() here, as this is the intended way
obtainKeyPair();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final String outputText = _output.isNotEmpty final String outputText = _output.isNotEmpty
@ -143,7 +171,7 @@ class _MyHomePageState extends State<MyHomePage> {
); );
final actionButtonInfo = FloatingActionButton( final actionButtonInfo = FloatingActionButton(
onPressed: generateKey, onPressed: () => obtainKeyPair(regenerate: true),
tooltip: 'Regenerate Key', tooltip: 'Regenerate Key',
child: const Icon(Icons.refresh), child: const Icon(Icons.refresh),
); );