mirror of
https://github.com/neon443/ShhShell.git
synced 2026-03-11 13:26:16 +00:00
almost done rewritign import sshprivkey
made these static funcitons made keypair have computed openssh format pub/priv variables that are strings
This commit is contained in:
@@ -187,9 +187,7 @@ class HostsManager: ObservableObject, @unchecked Sendable {
|
||||
for host in hosts {
|
||||
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)
|
||||
let keypair = Keypair(type: .rsa, name: UUID().uuidString, publicKey: publicKey, privateKey: privateKey)
|
||||
if !result.contains(keypair) {
|
||||
result.append(keypair)
|
||||
}
|
||||
|
||||
@@ -27,17 +27,17 @@ class KeyManager: ObservableObject {
|
||||
let privatekeyData = key.rawRepresentation
|
||||
let publickeyData = key.publicKey.rawRepresentation
|
||||
print(publickeyData.base64EncodedString())
|
||||
let pubpem = makeSSHPubkey(pub: publickeyData, comment: "neon443@m")
|
||||
let privpem = makeSSHPrivkey(pub: publickeyData, priv: privatekeyData, comment: "neon443@m")
|
||||
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(importSSHPubkey(pub: String(data: pubpem, encoding: .utf8)!).base64EncodedString())
|
||||
print(KeyManager.importSSHPubkey(pub: String(data: pubpem, encoding: .utf8)!).base64EncodedString())
|
||||
|
||||
print(privatekeyData.base64EncodedString())
|
||||
print(importSSHPrivkey(priv: String(data: privpem, encoding: .utf8)!).base64EncodedString())
|
||||
print(KeyManager.importSSHPrivkey(priv: String(data: privpem, encoding: .utf8)!).privateKey.base64EncodedString())
|
||||
fatalError()
|
||||
}
|
||||
|
||||
@@ -59,14 +59,14 @@ class KeyManager: ObservableObject {
|
||||
//MARK: generate keys
|
||||
func generateKey(type: KeyType, SEPKeyTag: String, comment: String, passphrase: String) -> Keypair? {
|
||||
switch type {
|
||||
case .ecdsa(let inSEP):
|
||||
case .ecdsa:
|
||||
fatalError("unimplemented")
|
||||
case .rsa(let rsaSize):
|
||||
case .rsa:
|
||||
fatalError("unimplemented")
|
||||
}
|
||||
}
|
||||
|
||||
func importSSHPubkey(pub: String) -> Data {
|
||||
static func importSSHPubkey(pub: String) -> Data {
|
||||
let split = pub.split(separator: " ")
|
||||
guard split.count == 3 else { return Data() }
|
||||
|
||||
@@ -78,7 +78,7 @@ class KeyManager: ObservableObject {
|
||||
return pubdata
|
||||
}
|
||||
|
||||
func makeSSHPubkey(pub: Data, comment: String) -> Data {
|
||||
static func makeSSHPubkey(pub: Data, comment: String) -> Data {
|
||||
let header = "ssh-ed25519"
|
||||
var keyBlob: Data = Data()
|
||||
//key type bit
|
||||
@@ -91,7 +91,7 @@ class KeyManager: ObservableObject {
|
||||
return Data(pubkeyline.utf8)
|
||||
}
|
||||
|
||||
func importSSHPrivkey(priv: String) -> Data {
|
||||
static func importSSHPrivkey(priv: String) -> Keypair {
|
||||
var split = priv.replacingOccurrences(of: "-----BEGIN OPENSSH PRIVATE KEY-----\n", with: "")
|
||||
split = split.replacingOccurrences(of: "-----BEGIN OPENSSH PRIVATE KEY-----", with: "")
|
||||
split = split.replacingOccurrences(of: "\n-----END OPENSSH PRIVATE KEY-----\n", with: "")
|
||||
@@ -102,17 +102,38 @@ class KeyManager: ObservableObject {
|
||||
|
||||
var dataBlob = Data(base64Encoded: split.data(using: .utf8)!)!
|
||||
dataBlob.removeFirst(15) //remove magik header
|
||||
dataBlob.removeFirst(16) //remove none noen
|
||||
dataBlob.removeFirst(4) //remove lenght header for empty data
|
||||
dataBlob.removeFirst(8) //remove empty data
|
||||
|
||||
for _ in 0..<2 {
|
||||
removeField(&dataBlob)
|
||||
} //remove the 2 nones fro encryption and kdf
|
||||
removeField(&dataBlob) //remove the empty Data()
|
||||
removeField(&dataBlob) //remove key type for pubkey str
|
||||
|
||||
|
||||
return Data()
|
||||
let pubkeyData = Data((dataBlob as NSData)[0..<Int((dataBlob as NSData)[3])])
|
||||
removeField(&dataBlob) //remove pubkey field
|
||||
|
||||
dataBlob.removeFirst(4) //remove lenght header for the privkey data blob
|
||||
|
||||
guard (dataBlob as NSData).subdata(with: NSRange(0...3)) == (dataBlob as NSData).subdata(with: NSRange(4...7)) else {
|
||||
fatalError("checkints are different")
|
||||
}
|
||||
dataBlob.removeFirst(8) //remove checkints
|
||||
removeField(&dataBlob) // remove pubkey type header
|
||||
removeField(&dataBlob) // remove pubkey
|
||||
|
||||
let privatekeyData = Data((dataBlob as NSData)[0..<32])
|
||||
dataBlob.removeFirst(4 + 32) //remove privkey
|
||||
|
||||
guard (dataBlob as NSData).subdata(with: NSRange(0...31)) == pubkeyData else {
|
||||
fatalError("pubkeys dont match")
|
||||
}
|
||||
dataBlob.removeFirst(32) //remove pubkey
|
||||
|
||||
let comment = String(data: Data((dataBlob as NSData)[0..<Int((dataBlob as NSData)[3])]), encoding: .utf8)!
|
||||
|
||||
return Keypair(type: .ecdsa, name: comment, publicKey: pubkeyData, privateKey: privatekeyData)
|
||||
}
|
||||
|
||||
func makeSSHPrivkey(pub: Data, priv: Data, comment: String) -> Data {
|
||||
static func makeSSHPrivkey(pub: Data, priv: Data, comment: String) -> Data {
|
||||
var content: Data = Data()
|
||||
var blob: Data = Data()
|
||||
|
||||
@@ -167,27 +188,26 @@ class KeyManager: ObservableObject {
|
||||
return SecKeyCopyPublicKey(privateKey)
|
||||
}
|
||||
|
||||
func encode(str: String) -> Data {
|
||||
static func encode(str: String) -> Data {
|
||||
guard let utf8 = str.data(using: .utf8) else {
|
||||
return Data()
|
||||
}
|
||||
return encode(int: utf8.count) + utf8
|
||||
}
|
||||
|
||||
func encode(data: Data) -> Data {
|
||||
static func encode(data: Data) -> Data {
|
||||
return encode(int: data.count) + data
|
||||
}
|
||||
|
||||
func encode(int: Int) -> Data {
|
||||
static func encode(int: Int) -> Data {
|
||||
var bigEndian = UInt32(int).bigEndian
|
||||
return Data(bytes: &bigEndian, count: 4) // 32bits / 8 bitsperbyte
|
||||
}
|
||||
|
||||
func removeField(_ data: inout Data) {
|
||||
static func removeField(_ data: inout Data) {
|
||||
guard data.count >= 4 else { return }
|
||||
|
||||
let lengthBytes = data.subdata(in: 0..<4)
|
||||
let length = lengthBytes.withUnsafeBytes { $0.load(as: UInt32.self).bigEndian }
|
||||
let length = (data as NSData)[3]
|
||||
guard data.count >= 4 + Int(length) else { return }
|
||||
|
||||
data.removeFirst(4)
|
||||
|
||||
@@ -10,13 +10,13 @@ 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:
|
||||
return "ECDSA"
|
||||
case .rsa:
|
||||
return "RSA"
|
||||
}
|
||||
}
|
||||
|
||||
case ecdsa(inSEP: Bool)
|
||||
case rsa(Int)
|
||||
case ecdsa
|
||||
case rsa
|
||||
}
|
||||
|
||||
@@ -11,38 +11,49 @@ 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 publicKey: Data { get set }
|
||||
var privateKey: Data { get set }
|
||||
var passphrase: String { get set }
|
||||
|
||||
var openSshPubkey: String { get }
|
||||
var openSshPrivkey: String { get }
|
||||
}
|
||||
|
||||
struct Keypair: KeypairProtocol {
|
||||
var id = UUID()
|
||||
var type: KeyType = .rsa(4096)
|
||||
var type: KeyType = .ecdsa
|
||||
var name: String = ""
|
||||
var publicKey: Data?
|
||||
var privateKey: Data?
|
||||
var publicKey: Data
|
||||
var privateKey: Data
|
||||
var passphrase: String = ""
|
||||
|
||||
var openSshPubkey: String {
|
||||
String(data: KeyManager.makeSSHPubkey(pub: publicKey, comment: name), encoding: .utf8) ?? "OpenSSH key format error"
|
||||
}
|
||||
|
||||
var openSshPrivkey: String {
|
||||
String(data: KeyManager.makeSSHPrivkey(pub: publicKey, priv: privateKey, comment: name), encoding: .utf8) ?? "OpenSSH key format error"
|
||||
}
|
||||
|
||||
init(
|
||||
id: UUID = UUID(),
|
||||
type: KeyType,
|
||||
name: String,
|
||||
publicKey: String,
|
||||
privateKey: String,
|
||||
publicKey: Data,
|
||||
privateKey: Data,
|
||||
passphrase: String = ""
|
||||
) {
|
||||
self.id = id
|
||||
self.type = type
|
||||
self.name = name
|
||||
self.publicKey = publicKey.data(using: .utf8)
|
||||
self.privateKey = privateKey.data(using: .utf8)
|
||||
self.publicKey = publicKey
|
||||
self.privateKey = privateKey
|
||||
self.passphrase = passphrase
|
||||
}
|
||||
|
||||
static func ==(lhs: Keypair, rhs: Keypair) -> Bool {
|
||||
if lhs.publicKey?.base64EncodedString() == rhs.publicKey?.base64EncodedString()
|
||||
&& lhs.privateKey?.base64EncodedString() == rhs.privateKey?.base64EncodedString() {
|
||||
if lhs.publicKey.base64EncodedString() == rhs.publicKey.base64EncodedString()
|
||||
&& lhs.privateKey.base64EncodedString() == rhs.privateKey.base64EncodedString() {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
|
||||
@@ -85,9 +85,9 @@ struct KeyDetailView: View {
|
||||
KeyDetailView(
|
||||
hostsManager: HostsManager(),
|
||||
keypair: Keypair(
|
||||
type: .rsa(4096),
|
||||
type: .rsa,
|
||||
name: "previewKey",
|
||||
publicKey: "ssh-ed25519 dskjhfajkdhfjkdashfgjkhadsjkgfbhalkjhfjkhdask user@mac",
|
||||
publicKey: "ssh-ed25519 dskjhfajkdhfjkdashfgjkhadsjkgfbhalkjhfjkhdask user@mac".data(using: .utf8)!,
|
||||
privateKey: """
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit
|
||||
@@ -95,7 +95,7 @@ struct KeyDetailView: View {
|
||||
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
|
||||
nisi ut aliquip ex ea commodo consequat
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
"""
|
||||
""".data(using: .utf8)!
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -22,9 +22,7 @@ struct KeyManagerView: View {
|
||||
NavigationLink {
|
||||
KeyDetailView(hostsManager: hostsManager, keypair: keypair)
|
||||
} label: {
|
||||
if let publicKey = keypair.publicKey {
|
||||
Text(String(data: publicKey, encoding: .utf8) ?? "nil")
|
||||
}
|
||||
Text(String(data: keypair.publicKey, encoding: .utf8) ?? "nil")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user