List certificates
This commit is contained in:
parent
a0e2298e69
commit
9082c86d02
|
@ -34,7 +34,11 @@ struct ListDevicesCommand: Command {
|
|||
print(" - \(device.name)")
|
||||
let trustStore = TrustStore(uuid: device.udid)
|
||||
if trustStore.exists {
|
||||
print(" - Trust store exists at \(trustStore.path)")
|
||||
if let store = try? trustStore.open(), store.isValid() {
|
||||
try? store.listCertificates()
|
||||
} else {
|
||||
print(" - Invalid trust store exists at \(trustStore.path)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
//
|
||||
// Copyright © 2019 Simon Kågedal Reimer. See LICENSE.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Security
|
||||
|
||||
enum SecurityError: LocalizedError {
|
||||
case invalidDERX509
|
||||
case unknown
|
||||
|
||||
var errorDescription: String? {
|
||||
switch self {
|
||||
case .invalidDERX509:
|
||||
return "Given data was not a valid DER encoded X.509 certificate"
|
||||
case .unknown:
|
||||
return "Operation completed with an unknown error from the Security framework"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension SecCertificate {
|
||||
static func read(data: Data) throws -> SecCertificate {
|
||||
guard let certificate = SecCertificateCreateWithData(nil, data as CFData) else {
|
||||
throw SecurityError.invalidDERX509
|
||||
}
|
||||
return certificate
|
||||
}
|
||||
|
||||
var subjectSummary: String? {
|
||||
return SecCertificateCopySubjectSummary(self) as String?
|
||||
}
|
||||
|
||||
func normalizedSubjectSequence() throws -> Data {
|
||||
var error: Unmanaged<CFError>?
|
||||
guard let data = SecCertificateCopyNormalizedSubjectContent(self, &error) else {
|
||||
guard let error = error else {
|
||||
throw SecurityError.unknown
|
||||
}
|
||||
throw error.takeRetainedValue()
|
||||
}
|
||||
return data as Data
|
||||
}
|
||||
|
||||
func printInfo() {
|
||||
if let summary = subjectSummary {
|
||||
print(summary)
|
||||
} else {
|
||||
print("<unknown certificate>")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,4 +14,46 @@ struct TrustStore {
|
|||
var exists: Bool {
|
||||
return localFileSystem.exists(path)
|
||||
}
|
||||
|
||||
func open() throws -> Connection {
|
||||
return try Connection(openingPath: path.pathString)
|
||||
}
|
||||
|
||||
class Connection {
|
||||
private let connection: SQLite.Connection
|
||||
private let sqliteMaster = Table("sqlite_master")
|
||||
private let tsettings = Table("tsettings")
|
||||
private let dataColumn = Expression<Blob?>("data")
|
||||
|
||||
fileprivate init(openingPath path: String) throws {
|
||||
connection = try SQLite.Connection(path)
|
||||
}
|
||||
|
||||
func isValid() -> Bool {
|
||||
do {
|
||||
guard let count = try connection.scalar(
|
||||
"SELECT count(*) FROM sqlite_master WHERE type='table' AND name='tsettings'"
|
||||
) as? Int64 else {
|
||||
return false
|
||||
}
|
||||
return count > 0
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func listCertificates() throws {
|
||||
for certificate in try connection.prepare(tsettings) {
|
||||
guard let blob = certificate[dataColumn] else {
|
||||
print("Couldn't get data blob from row...")
|
||||
continue
|
||||
}
|
||||
let data = Data(blob.bytes)
|
||||
let cert = try SecCertificate.read(data: data)
|
||||
cert.printInfo()
|
||||
let count = blob.bytes.count
|
||||
print(" - \(count) bytes")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue