improve getKeys key handling, and will importa key if it is just a string

make pubkey a computed var from the privkey in Keypair
This commit is contained in:
neon443
2025-07-01 16:18:38 +01:00
parent 75ff91d0e4
commit 89cac92d5a
4 changed files with 20 additions and 39 deletions

View File

@@ -185,9 +185,14 @@ class HostsManager: ObservableObject, @unchecked Sendable {
func getKeys() -> [Keypair] { func getKeys() -> [Keypair] {
var result: [Keypair] = [] var result: [Keypair] = []
for host in hosts { for host in hosts {
guard let publicKey = host.publicKey else { continue }
guard let privateKey = host.privateKey else { continue } guard let privateKey = host.privateKey else { continue }
let keypair = Keypair(type: .rsa, name: UUID().uuidString, publicKey: publicKey, privateKey: privateKey) var keypair: Keypair
if let string = String(data: privateKey, encoding: .utf8),
string.contains("-----") {
keypair = KeyManager.importSSHPrivkey(priv: string)
} else {
keypair = Keypair(type: .ecdsa, name: UUID().uuidString, privateKey: privateKey)
}
if !result.contains(keypair) { if !result.contains(keypair) {
result.append(keypair) result.append(keypair)
} }

View File

@@ -22,25 +22,6 @@ class KeyManager: ObservableObject {
var tags: [String] = [] var tags: [String] = []
init() {
let key = Curve25519.Signing.PrivateKey()
let privatekeyData = key.rawRepresentation
let publickeyData = key.publicKey.rawRepresentation
print(publickeyData.base64EncodedString())
let pubpem = KeyManager.makeSSHPubkey(pub: publickeyData, comment: "neon443@m")
let privpem = KeyManager.makeSSHPrivkey(pub: publickeyData, priv: privatekeyData, comment: "neon443@m")
print(String(data: pubpem, encoding: .utf8)!)
print()
print(String(data: privpem, encoding: .utf8)!)
print()
print(KeyManager.importSSHPubkey(pub: String(data: pubpem, encoding: .utf8)!).base64EncodedString())
print(privatekeyData.base64EncodedString())
print(KeyManager.importSSHPrivkey(priv: String(data: privpem, encoding: .utf8)!).privateKey.base64EncodedString())
fatalError()
}
func loadTags() { func loadTags() {
userdefaults.synchronize() userdefaults.synchronize()
let decoder = JSONDecoder() let decoder = JSONDecoder()
@@ -60,7 +41,7 @@ class KeyManager: ObservableObject {
func generateKey(type: KeyType, SEPKeyTag: String, comment: String, passphrase: String) -> Keypair? { func generateKey(type: KeyType, SEPKeyTag: String, comment: String, passphrase: String) -> Keypair? {
switch type { switch type {
case .ecdsa: case .ecdsa:
fatalError("unimplemented") Keypair(type: .ecdsa, name: comment, privateKey: Curve25519.Signing.PrivateKey().rawRepresentation)
case .rsa: case .rsa:
fatalError("unimplemented") fatalError("unimplemented")
} }
@@ -98,6 +79,7 @@ class KeyManager: ObservableObject {
split = split.replacingOccurrences(of: "\n-----END OPENSSH PRIVATE KEY-----", with: "") split = split.replacingOccurrences(of: "\n-----END OPENSSH PRIVATE KEY-----", with: "")
split = split.replacingOccurrences(of: "-----END OPENSSH PRIVATE KEY-----", with: "") split = split.replacingOccurrences(of: "-----END OPENSSH PRIVATE KEY-----", with: "")
split = split.replacingOccurrences(of: "\r\n", with: "") split = split.replacingOccurrences(of: "\r\n", with: "")
split = split.replacingOccurrences(of: " ", with: "\n")
split = split.replacingOccurrences(of: "\n", with: "") split = split.replacingOccurrences(of: "\n", with: "")
var dataBlob = Data(base64Encoded: split.data(using: .utf8)!)! var dataBlob = Data(base64Encoded: split.data(using: .utf8)!)!
@@ -127,7 +109,7 @@ class KeyManager: ObservableObject {
let comment = String(data: extractField(&dataBlob), encoding: .utf8)! let comment = String(data: extractField(&dataBlob), encoding: .utf8)!
return Keypair(type: .ecdsa, name: comment, publicKey: pubkeyData, privateKey: privatekeyData) return Keypair(type: .ecdsa, name: comment, privateKey: privatekeyData)
} }
static func makeSSHPrivkey(pub: Data, priv: Data, comment: String) -> Data { static func makeSSHPrivkey(pub: Data, priv: Data, comment: String) -> Data {

View File

@@ -6,12 +6,13 @@
// //
import Foundation import Foundation
import CryptoKit
protocol KeypairProtocol: Identifiable, Equatable, Codable, Hashable { protocol KeypairProtocol: Identifiable, Equatable, Codable, Hashable {
var id: UUID { get } var id: UUID { get }
var type: KeyType { get set } var type: KeyType { get set }
var name: String { get set } var name: String { get set }
var publicKey: Data { get set } var publicKey: Data { get }
var privateKey: Data { get set } var privateKey: Data { get set }
var passphrase: String { get set } var passphrase: String { get set }
@@ -23,7 +24,9 @@ struct Keypair: KeypairProtocol {
var id = UUID() var id = UUID()
var type: KeyType = .ecdsa var type: KeyType = .ecdsa
var name: String = "" var name: String = ""
var publicKey: Data var publicKey: Data {
(try? Curve25519.Signing.PrivateKey(rawRepresentation: privateKey).publicKey.rawRepresentation) ?? Data()
}
var privateKey: Data var privateKey: Data
var passphrase: String = "" var passphrase: String = ""
@@ -39,14 +42,12 @@ struct Keypair: KeypairProtocol {
id: UUID = UUID(), id: UUID = UUID(),
type: KeyType, type: KeyType,
name: String, name: String,
publicKey: Data,
privateKey: Data, privateKey: Data,
passphrase: String = "" passphrase: String = ""
) { ) {
self.id = id self.id = id
self.type = type self.type = type
self.name = name self.name = name
self.publicKey = publicKey
self.privateKey = privateKey self.privateKey = privateKey
self.passphrase = passphrase self.passphrase = passphrase
} }

View File

@@ -38,14 +38,14 @@ struct KeyDetailView: View {
VStack(alignment: .leading) { VStack(alignment: .leading) {
Text("Public key") Text("Public key")
.bold() .bold()
Text(String(data: publicKey, encoding: .utf8) ?? "nil") Text(keypair.openSshPubkey)
} }
VStack(alignment: .leading) { VStack(alignment: .leading) {
Text("Private key") Text("Private key")
.bold() .bold()
.frame(maxWidth: .infinity) .frame(maxWidth: .infinity)
ZStack(alignment: .center) { ZStack(alignment: .center) {
Text(String(data: privateKey, encoding: .utf8) ?? "nil") Text(keypair.openSshPrivkey)
.blur(radius: reveal ? 0 : 5) .blur(radius: reveal ? 0 : 5)
VStack { VStack {
Image(systemName: "eye.slash.fill") Image(systemName: "eye.slash.fill")
@@ -81,21 +81,14 @@ struct KeyDetailView: View {
} }
} }
import CryptoKit
#Preview { #Preview {
KeyDetailView( KeyDetailView(
hostsManager: HostsManager(), hostsManager: HostsManager(),
keypair: Keypair( keypair: Keypair(
type: .rsa, type: .ecdsa,
name: "previewKey", name: "previewKey",
publicKey: "ssh-ed25519 dskjhfajkdhfjkdashfgjkhadsjkgfbhalkjhfjkhdask user@mac".data(using: .utf8)!, privateKey: Curve25519.Signing.PrivateKey().rawRepresentation
privateKey: """
-----BEGIN OPENSSH PRIVATE KEY-----
Lorem ipsum dolor sit amet, consectetur adipiscing elit
sed do eiusmod tempor incididunt ut labore et dolore magna aliqu
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat
-----END OPENSSH PRIVATE KEY-----
""".data(using: .utf8)!
) )
) )
} }