Skeleton for install-ca command

This commit is contained in:
Simon Kågedal Reimer 2019-05-30 14:59:40 +02:00
parent 1908892f0a
commit 173035f063
5 changed files with 32 additions and 4 deletions

View File

@ -4,7 +4,6 @@ A description of this package.
## TODO
* PEM parser
* `install-ca` command
* Filter for os types
* Find out why the argument parsing errors are not printed correctly

View File

@ -1,3 +1,6 @@
disabled_rules:
- identifier_name
- nesting
line_length:
warning: 140

View File

@ -10,13 +10,14 @@ struct InstallCACommand: Command {
let overview = "Install a Certificate Authority"
private let binder = ArgumentBinder<InstallCACommand>()
private var path: String?
func addOptions(to parser: ArgumentParser) {
binder.bind(positional: parser.add(
positional: "path",
kind: String.self
), to: { command, path in
print("Chosen path: \(path)")
command.path = path
})
}
@ -25,6 +26,8 @@ struct InstallCACommand: Command {
}
func run() throws {
print("Running!")
let url = URL(fileURLWithPath: path!)
let certificate = try Certificate.load(from: url)
print(certificate)
}
}

View File

@ -1,7 +1,6 @@
//
// Copyright © 2019 Simon Kågedal Reimer. See LICENSE.
//
// swiftlint:disable line_length
import Foundation

View File

@ -8,12 +8,18 @@ import Security
struct Certificate {
enum Error: LocalizedError {
case invalidDERX509
case importError(OSStatus)
case notACertficate
case unknown
var errorDescription: String? {
switch self {
case .invalidDERX509:
return "Given data was not a valid DER encoded X.509 certificate"
case .importError(let status):
return "Error from SecItemImport: \(status)"
case .notACertficate:
return "SecItemImport gave something else than a certificate"
case .unknown:
return "Operation completed with an unknown error from the Security framework"
}
@ -62,4 +68,22 @@ struct Certificate {
print("<unknown certificate>")
}
}
static func load(from url: URL) throws -> SecCertificate {
let data = try Data(contentsOf: url)
var cfitems: CFArray?
var format = SecExternalFormat.formatUnknown
var type = SecExternalItemType.itemTypeUnknown
let status = SecItemImport(data as CFData, url.lastPathComponent as CFString, &format, &type, [], nil, nil, &cfitems)
guard status == errSecSuccess else {
throw Error.importError(status)
}
guard type == .itemTypeCertificate, let items = cfitems as? [SecCertificate], let item = items.first else {
throw Error.notACertficate
}
return item
}
}