mirror of
https://github.com/neon443/ShhShell.git
synced 2026-03-11 13:26:16 +00:00
updated keypair data structure to have an name, passphrase and type
added generateKy to generate a key, currently only rsa update generateRSA to return the Data for pub and priv, and take a custom size bell animation better, slightly longer in total and easeinout added new generate button hardcoded to a rsa 4096 added keytype to define key types (duh) update getKeys to use the new keypair structure
This commit is contained in:
@@ -48,6 +48,7 @@
|
||||
A96C6B002E0C45FE00F377FE /* KeyDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A96C6AFF2E0C45FE00F377FE /* KeyDetailView.swift */; };
|
||||
A96C6B022E0C49E800F377FE /* CenteredLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A96C6B012E0C49E800F377FE /* CenteredLabel.swift */; };
|
||||
A96C90A12E12B87A00724253 /* TextBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = A96C90A02E12B87900724253 /* TextBox.swift */; };
|
||||
A96C90A32E12D53B00724253 /* KeyType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A96C90A22E12D53900724253 /* KeyType.swift */; };
|
||||
A98554552E05535F009051BD /* KeyManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98554542E05535F009051BD /* KeyManagerView.swift */; };
|
||||
A98554592E0553AA009051BD /* KeyManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98554582E0553AA009051BD /* KeyManager.swift */; };
|
||||
A985545D2E055D4D009051BD /* ConnectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A985545C2E055D4D009051BD /* ConnectionView.swift */; };
|
||||
@@ -145,6 +146,7 @@
|
||||
A96C6AFF2E0C45FE00F377FE /* KeyDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyDetailView.swift; sourceTree = "<group>"; };
|
||||
A96C6B012E0C49E800F377FE /* CenteredLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CenteredLabel.swift; sourceTree = "<group>"; };
|
||||
A96C90A02E12B87900724253 /* TextBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextBox.swift; sourceTree = "<group>"; };
|
||||
A96C90A22E12D53900724253 /* KeyType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyType.swift; sourceTree = "<group>"; };
|
||||
A98554542E05535F009051BD /* KeyManagerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyManagerView.swift; sourceTree = "<group>"; };
|
||||
A98554582E0553AA009051BD /* KeyManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyManager.swift; sourceTree = "<group>"; };
|
||||
A985545C2E055D4D009051BD /* ConnectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionView.swift; sourceTree = "<group>"; };
|
||||
@@ -374,6 +376,7 @@
|
||||
A98554572E055398009051BD /* Keys */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A96C90A22E12D53900724253 /* KeyType.swift */,
|
||||
A98554582E0553AA009051BD /* KeyManager.swift */,
|
||||
A985545E2E056EDD009051BD /* KeychainLayer.swift */,
|
||||
A96C6AFD2E0C43B600F377FE /* Keypair.swift */,
|
||||
@@ -587,6 +590,7 @@
|
||||
A9DA97712E0D30ED00142DDC /* HostSymbol.swift in Sources */,
|
||||
A96C90A12E12B87A00724253 /* TextBox.swift in Sources */,
|
||||
A96BE6A82E116E2B00C0FEE9 /* SessionsListView.swift in Sources */,
|
||||
A96C90A32E12D53B00724253 /* KeyType.swift in Sources */,
|
||||
A98554612E058433009051BD /* HostsManager.swift in Sources */,
|
||||
A985545D2E055D4D009051BD /* ConnectionView.swift in Sources */,
|
||||
A98554592E0553AA009051BD /* KeyManager.swift in Sources */,
|
||||
|
||||
@@ -185,8 +185,11 @@ class HostsManager: ObservableObject, @unchecked Sendable {
|
||||
func getKeys() -> [Keypair] {
|
||||
var result: [Keypair] = []
|
||||
for host in hosts {
|
||||
guard host.privateKey != nil && host.publicKey != nil else { continue }
|
||||
let keypair = Keypair(publicKey: host.publicKey, privateKey: host.privateKey)
|
||||
guard let publicKey = host.publicKey else { continue }
|
||||
guard let privateKey = host.privateKey else { continue }
|
||||
guard let privKeyStr = String(data: privateKey, encoding: .utf8),
|
||||
let pubKeyStr = String(data: publicKey, encoding: .utf8) else { continue }
|
||||
let keypair = Keypair(type: .rsa(1), name: UUID().uuidString, publicKey: pubKeyStr, privateKey: privKeyStr)
|
||||
if !result.contains(keypair) {
|
||||
result.append(keypair)
|
||||
}
|
||||
|
||||
@@ -38,6 +38,22 @@ class KeyManager: ObservableObject {
|
||||
}
|
||||
|
||||
//MARK: generate keys
|
||||
func generateKey(type: KeyType, SEPKeyTag: String, comment: String, passphrase: String) -> Keypair? {
|
||||
switch type {
|
||||
case .ecdsa(let inSEP):
|
||||
fatalError()
|
||||
case .rsa(let rsaSize):
|
||||
guard let keyData = try? generateRSA(size: rsaSize) else { return nil }
|
||||
return Keypair(
|
||||
type: .rsa(rsaSize),
|
||||
name: comment,
|
||||
publicKey: String(data: keyData.pub, encoding: .utf8) ?? "",
|
||||
privateKey: String(data: keyData.priv, encoding: .utf8) ?? "",
|
||||
passphrase: ""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func generateEd25519() {
|
||||
let privateKey = Curve25519.Signing.PrivateKey()
|
||||
let publicKeyData = privateKey.publicKey
|
||||
@@ -45,13 +61,13 @@ class KeyManager: ObservableObject {
|
||||
print(publicKeyData.rawRepresentation)
|
||||
}
|
||||
|
||||
func generateRSA() throws {
|
||||
func generateRSA(size: Int) throws -> (priv: Data, pub: Data) {
|
||||
let type = kSecAttrKeyTypeRSA
|
||||
let label = Date().ISO8601Format()
|
||||
let tag = label.data(using: .utf8)!
|
||||
let attributes: [String: Any] =
|
||||
[kSecAttrKeyType as String: type,
|
||||
kSecAttrKeySizeInBits as String: 4096,
|
||||
kSecAttrKeySizeInBits as String: size,
|
||||
kSecPrivateKeyAttrs as String:
|
||||
[kSecAttrIsPermanent as String: true,
|
||||
kSecAttrApplicationTag as String: tag]
|
||||
@@ -61,15 +77,23 @@ class KeyManager: ObservableObject {
|
||||
guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
|
||||
throw error!.takeRetainedValue() as Error
|
||||
}
|
||||
guard let pubkey = getPubkey(privateKey) else {
|
||||
throw error!.takeRetainedValue() as Error
|
||||
}
|
||||
print(privateKey)
|
||||
|
||||
print(SecKeyCopyPublicKey(privateKey) ?? "")
|
||||
print(SecKeyCopyExternalRepresentation(privateKey, nil) as Any)
|
||||
// do {
|
||||
// try storeKey(privateKey, label: label)
|
||||
// } catch {
|
||||
// print(error.localizedDescription)
|
||||
// }
|
||||
guard let privKeyData = SecKeyCopyExternalRepresentation(privateKey, &error) else {
|
||||
throw error!.takeRetainedValue() as Error
|
||||
}
|
||||
guard let pubKeyData = SecKeyCopyExternalRepresentation(pubkey, &error) else {
|
||||
throw error!.takeRetainedValue() as Error
|
||||
}
|
||||
return (privKeyData as Data, pubKeyData as Data)
|
||||
}
|
||||
|
||||
func getPubkey(_ privateKey: SecKey) -> SecKey? {
|
||||
|
||||
22
ShhShell/Keys/KeyType.swift
Normal file
22
ShhShell/Keys/KeyType.swift
Normal file
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// KeyType.swift
|
||||
// ShhShell
|
||||
//
|
||||
// Created by neon443 on 30/06/2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum KeyType: Codable, Equatable, Hashable, CustomStringConvertible {
|
||||
var description: String {
|
||||
switch self {
|
||||
case .ecdsa(let inSEP):
|
||||
return inSEP ? "ECDSA Secure Enclave" : "ECDSA"
|
||||
case .rsa(let bits):
|
||||
return "RSA \(bits)"
|
||||
}
|
||||
}
|
||||
|
||||
case ecdsa(inSEP: Bool)
|
||||
case rsa(Int)
|
||||
}
|
||||
@@ -8,21 +8,36 @@
|
||||
import Foundation
|
||||
|
||||
protocol KeypairProtocol: Identifiable, Equatable, Codable, Hashable {
|
||||
var id: UUID { get }
|
||||
var type: KeyType { get set }
|
||||
var name: String { get set }
|
||||
var publicKey: Data? { get set }
|
||||
var privateKey: Data? { get set }
|
||||
var passphrase: String { get set }
|
||||
}
|
||||
|
||||
struct Keypair: KeypairProtocol {
|
||||
var id = UUID()
|
||||
var type: KeyType = .rsa(4096)
|
||||
var name: String = ""
|
||||
var publicKey: Data?
|
||||
var privateKey: Data?
|
||||
var passphrase: String = ""
|
||||
|
||||
init(
|
||||
publicKey: Data?,
|
||||
privateKey: Data?
|
||||
id: UUID = UUID(),
|
||||
type: KeyType,
|
||||
name: String,
|
||||
publicKey: String,
|
||||
privateKey: String,
|
||||
passphrase: String = ""
|
||||
) {
|
||||
self.publicKey = publicKey
|
||||
self.privateKey = privateKey
|
||||
self.id = id
|
||||
self.type = type
|
||||
self.name = name
|
||||
self.publicKey = publicKey.data(using: .utf8)
|
||||
self.privateKey = privateKey.data(using: .utf8)
|
||||
self.passphrase = passphrase
|
||||
}
|
||||
|
||||
static func ==(lhs: Keypair, rhs: Keypair) -> Bool {
|
||||
|
||||
@@ -184,9 +184,9 @@ class SSHHandler: @unchecked Sendable, ObservableObject {
|
||||
|
||||
func ring() {
|
||||
Task { @MainActor in
|
||||
withAnimation { self.bell = true }
|
||||
try? await Task.sleep(nanoseconds: 250_000_000) // 250ms
|
||||
withAnimation { self.bell = false }
|
||||
withAnimation(.easeIn(duration: 0.1)) { self.bell = true }
|
||||
try? await Task.sleep(nanoseconds: 300_000_000) // 250ms
|
||||
withAnimation(.easeOut(duration: 0.1)) { self.bell = false }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,9 @@ struct KeyDetailView: View {
|
||||
KeyDetailView(
|
||||
hostsManager: HostsManager(),
|
||||
keypair: Keypair(
|
||||
publicKey: "ssh-ed25519 dskjhfajkdhfjkdashfgjkhadsjkgfbhalkjhfjkhdask user@mac".data(using: .utf8),
|
||||
type: .rsa(4096),
|
||||
name: "previewKey",
|
||||
publicKey: "ssh-ed25519 dskjhfajkdhfjkdashfgjkhadsjkgfbhalkjhfjkhdask user@mac",
|
||||
privateKey: """
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit
|
||||
@@ -94,7 +96,6 @@ struct KeyDetailView: View {
|
||||
nisi ut aliquip ex ea commodo consequat
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
"""
|
||||
.data(using: .utf8)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -29,15 +29,8 @@ struct KeyManagerView: View {
|
||||
}
|
||||
}
|
||||
|
||||
Button("ed25519") {
|
||||
keyManager.generateEd25519()
|
||||
}
|
||||
Button("rsa") {
|
||||
do {
|
||||
try keyManager.generateRSA()
|
||||
} catch {
|
||||
print(error.localizedDescription)
|
||||
}
|
||||
Button("genereate rsa") {
|
||||
keyManager.generateKey(type: .rsa(4096), SEPKeyTag: "", comment: "jaklsd", passphrase: "")
|
||||
}
|
||||
}
|
||||
.scrollContentBackground(.hidden)
|
||||
|
||||
Reference in New Issue
Block a user