Skip to content
Snippets Groups Projects
Unverified Commit 8bc4976a authored by Zorg's avatar Zorg Committed by GitHub
Browse files

Use FileHandle for reading base64 secret key from file (#2615)

Fixes process substitution failing to work for providing the private key as file argument (#2605).
parent ed987512
Branches
Tags
No related merge requests found
......@@ -45,3 +45,41 @@ func decodePrivateAndPublicKeys(secret: Data) -> (privateKey: Data, publicKey: D
return (privateKey, publicKey)
}
enum DecodeSecretStringError : LocalizedError {
case unableToReadData
case unableToDecodeDataAsUTF8String
public var errorDescription: String? {
switch self {
case .unableToReadData:
return "Unable to read EdDSA private key data"
case .unableToDecodeDataAsUTF8String:
return "Unable to read EdDSA private key data as UTF-8 string"
}
}
}
// Reads secret base64 string from a file
func decodeSecretString(filePath: String) throws -> String {
let privateKeyString: String
if #available(macOS 10.15.4, *) {
// Prefer to use FileHandle which supports process substitution:
// https://github.com/sparkle-project/Sparkle/issues/2605
let fileHandle = try FileHandle(forReadingFrom: URL(fileURLWithPath: filePath))
guard let data = try fileHandle.readToEnd() else {
throw DecodeSecretStringError.unableToReadData
}
guard let decodedPrivateKeyString = String(data: data, encoding: .utf8) else {
throw DecodeSecretStringError.unableToDecodeDataAsUTF8String
}
privateKeyString = decodedPrivateKeyString
} else {
privateKeyString = try String(contentsOf: URL(fileURLWithPath: filePath))
}
return privateKeyString.trimmingCharacters(in: .whitespacesAndNewlines)
}
......@@ -285,19 +285,22 @@ struct GenerateAppcast: ParsableCommand {
allowNewPrivateKey = false
} else if let privateEdKeyPath = privateEdKeyPath {
do {
let privateKeyString: String
if privateEdKeyPath == "-" && !FileManager.default.fileExists(atPath: privateEdKeyPath) {
if let line = readLine(strippingNewline: true) {
privateKeyString = line
privateEdKeyString = line
} else {
print("Unable to read EdDSA private key from standard input")
throw ExitCode(1)
}
} else {
privateKeyString = try String(contentsOf: URL(fileURLWithPath: privateEdKeyPath))
do {
privateEdKeyString = try decodeSecretString(filePath: privateEdKeyPath)
} catch {
print(error.localizedDescription)
throw ExitCode(1)
}
}
privateEdKeyString = privateKeyString
allowNewPrivateKey = true
} catch {
print("Unable to load EdDSA private key from", privateEdKeyPath, "\n", error)
......
......@@ -235,12 +235,12 @@ struct GenerateKeys: ParsableCommand {
let secretBase64File = importedPrivateKeyFile
let secretBase64: String
do {
secretBase64 = try String(contentsOfFile: secretBase64File)
secretBase64 = try decodeSecretString(filePath: secretBase64File)
} catch {
failure("Failed to read private-key-file: \(error)")
failure("Failed to read private-key-file: \(error.localizedDescription)")
}
guard let secret = Data(base64Encoded: secretBase64.trimmingCharacters(in: .whitespacesAndNewlines), options: .init()) else {
guard let secret = Data(base64Encoded: secretBase64, options: .init()) else {
failure("Failed to decode base64 encoded key data from: \(secretBase64)")
}
......
......@@ -61,13 +61,13 @@ func findKeys(inFile secretFile: String) throws -> (Data, Data) {
throw ExitCode(1)
}
} else {
secretString = try String(contentsOfFile: secretFile)
secretString = try decodeSecretString(filePath: secretFile)
}
return try findKeys(inString: secretString, allowNewFormat: true)
}
func findKeys(inString secretBase64String: String, allowNewFormat: Bool) throws -> (Data, Data) {
guard let secret = Data(base64Encoded: secretBase64String.trimmingCharacters(in: .whitespacesAndNewlines), options: .init()) else {
guard let secret = Data(base64Encoded: secretBase64String, options: .init()) else {
print("ERROR! Failed to decode base64 encoded key data from: \(secretBase64String)")
throw ExitCode.failure
}
......@@ -141,7 +141,7 @@ struct SignUpdate: ParsableCommand {
func run() throws {
let (priv, pub): (Data, Data)
if let privateKey = privateKey {
if let privateKey = privateKey?.trimmingCharacters(in: .whitespacesAndNewlines) {
fputs("Warning: The -s option for passing the private EdDSA key is insecure and deprecated. Please see its help usage for more information.\n", stderr)
(priv, pub) = try findKeys(inString: privateKey, allowNewFormat: false)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment