Refactor listing of certificates

This commit is contained in:
Simon Kågedal Reimer 2019-05-11 18:28:50 +02:00
parent 9082c86d02
commit af72a890da
4 changed files with 41 additions and 33 deletions

View File

@ -64,7 +64,7 @@ struct CommandLineOptions {
binder.bind( binder.bind(
parser: parser, parser: parser,
to: { _, subcommand in to: { _, subcommand in
print("Parsed subcommand: \(subcommand)") // print("Parsed subcommand: \(subcommand)")
} }
) )

View File

@ -34,15 +34,27 @@ struct ListDevicesCommand: Command {
print(" - \(device.name)") print(" - \(device.name)")
let trustStore = TrustStore(uuid: device.udid) let trustStore = TrustStore(uuid: device.udid)
if trustStore.exists { if trustStore.exists {
if let store = try? trustStore.open(), store.isValid() { try listCertificates(in: trustStore)
try? store.listCertificates()
} else {
print(" - Invalid trust store exists at \(trustStore.path)")
}
} }
} }
} }
} }
private func listCertificates(in trustStore: TrustStore) throws {
let store = try trustStore.open()
guard store.isValid() else {
return print(" Invalid trust store at \(trustStore.path)")
}
var didPrintHeader = false
for certificate in try store.certificates() {
if !didPrintHeader {
print(" Certificates:")
didPrintHeader = true
}
print(" - \(certificate.subjectSummary ?? "<unknown certificate>")")
}
}
} }
extension FilteringOptions.Availability { extension FilteringOptions.Availability {

View File

@ -5,37 +5,39 @@
import Foundation import Foundation
import Security import Security
enum SecurityError: LocalizedError { struct Certificate {
case invalidDERX509 enum Error: LocalizedError {
case unknown case invalidDERX509
case unknown
var errorDescription: String? { var errorDescription: String? {
switch self { switch self {
case .invalidDERX509: case .invalidDERX509:
return "Given data was not a valid DER encoded X.509 certificate" return "Given data was not a valid DER encoded X.509 certificate"
case .unknown: case .unknown:
return "Operation completed with an unknown error from the Security framework" return "Operation completed with an unknown error from the Security framework"
}
} }
} }
}
extension SecCertificate { private let certificate: SecCertificate
static func read(data: Data) throws -> SecCertificate {
init(_ data: Data) throws {
guard let certificate = SecCertificateCreateWithData(nil, data as CFData) else { guard let certificate = SecCertificateCreateWithData(nil, data as CFData) else {
throw SecurityError.invalidDERX509 throw Error.invalidDERX509
} }
return certificate self.certificate = certificate
} }
var subjectSummary: String? { var subjectSummary: String? {
return SecCertificateCopySubjectSummary(self) as String? return SecCertificateCopySubjectSummary(certificate) as String?
} }
func normalizedSubjectSequence() throws -> Data { func normalizedSubjectSequence() throws -> Data {
var error: Unmanaged<CFError>? var error: Unmanaged<CFError>?
guard let data = SecCertificateCopyNormalizedSubjectContent(self, &error) else { guard let data = SecCertificateCopyNormalizedSubjectContent(certificate, &error) else {
guard let error = error else { guard let error = error else {
throw SecurityError.unknown throw Error.unknown
} }
throw error.takeRetainedValue() throw error.takeRetainedValue()
} }

View File

@ -42,17 +42,11 @@ struct TrustStore {
} }
} }
func listCertificates() throws { func certificates() throws -> [Certificate] {
for certificate in try connection.prepare(tsettings) { return try connection.prepare(tsettings).compactMap { row in
guard let blob = certificate[dataColumn] else { try row[dataColumn].map { blob in
print("Couldn't get data blob from row...") try Certificate(Data(blob.bytes))
continue
} }
let data = Data(blob.bytes)
let cert = try SecCertificate.read(data: data)
cert.printInfo()
let count = blob.bytes.count
print(" - \(count) bytes")
} }
} }
} }