secretive/SecretKit/Common/OpenSSH/OpenSSHKeyWriter.swift

50 lines
1.6 KiB
Swift
Raw Normal View History

2020-03-04 07:14:38 +00:00
import Foundation
import CryptoKit
2020-03-10 05:12:40 +00:00
// For the moment, only supports ecdsa-sha2-nistp256 and ecdsa-sha2-nistp386 keys
2020-03-04 07:14:38 +00:00
public struct OpenSSHKeyWriter {
public init() {
}
public func data<SecretType: Secret>(secret: SecretType) -> Data {
lengthAndData(of: curveType(for: secret.algorithm, length: secret.keySize).data(using: .utf8)!) +
lengthAndData(of: curveIdentifier(for: secret.algorithm, length: secret.keySize).data(using: .utf8)!) +
2020-03-04 07:14:38 +00:00
lengthAndData(of: secret.publicKey)
}
public func openSSHString<SecretType: Secret>(secret: SecretType) -> String {
"\(curveType(for: secret.algorithm, length: secret.keySize)) \(data(secret: secret).base64EncodedString())"
2020-03-04 07:14:38 +00:00
}
public func openSSHFingerprint<SecretType: Secret>(secret: SecretType) -> String {
Insecure.MD5.hash(data: data(secret: secret))
2020-03-07 03:15:27 +00:00
.compactMap { ("0" + String($0, radix: 16, uppercase: false)).suffix(2) }
2020-03-04 07:14:38 +00:00
.joined(separator: ":")
}
}
extension OpenSSHKeyWriter {
public func lengthAndData(of data: Data) -> Data {
let rawLength = UInt32(data.count)
var endian = rawLength.bigEndian
return Data(bytes: &endian, count: UInt32.bitWidth/8) + data
}
public func curveIdentifier(for algorithm: Algorithm, length: Int) -> String {
switch algorithm {
case .ellipticCurve:
return "nistp" + String(describing: length)
}
2020-03-04 07:14:38 +00:00
}
public func curveType(for algorithm: Algorithm, length: Int) -> String {
switch algorithm {
case .ellipticCurve:
return "ecdsa-sha2-nistp" + String(describing: length)
}
}
2020-03-04 07:14:38 +00:00
}