Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use FileHandle for reading base64 secret key from file #2615

Merged
merged 1 commit into from
Aug 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions common_cli/secret.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
11 changes: 7 additions & 4 deletions generate_appcast/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 3 additions & 3 deletions generate_keys/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)")
}

Expand Down
6 changes: 3 additions & 3 deletions sign_update/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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)
Expand Down
Loading