Little bit of cleanup in agent code (#643)

This commit is contained in:
Max Goedjen 2025-08-27 23:43:33 -07:00 committed by GitHub
parent d967c7de07
commit c5052dd457
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 21 additions and 28 deletions

View File

@ -39,7 +39,7 @@ extension Agent {
public func handle(data: Data, provenance: SigningRequestProvenance) async throws -> Data { public func handle(data: Data, provenance: SigningRequestProvenance) async throws -> Data {
logger.debug("Agent handling new data") logger.debug("Agent handling new data")
guard data.count > 4 else { guard data.count > 4 else {
throw AgentError.couldNotRead throw InvalidDataProvidedError()
} }
let requestTypeInt = data[4] let requestTypeInt = data[4]
guard let requestType = SSHAgent.RequestType(rawValue: requestTypeInt) else { guard let requestType = SSHAgent.RequestType(rawValue: requestTypeInt) else {
@ -84,7 +84,7 @@ extension Agent {
func identities() async -> Data { func identities() async -> Data {
let secrets = await storeList.allSecrets let secrets = await storeList.allSecrets
await certificateHandler.reloadCertificates(for: secrets) await certificateHandler.reloadCertificates(for: secrets)
var count = secrets.count var count = 0
var keyData = Data() var keyData = Data()
for secret in secrets { for secret in secrets {
@ -92,6 +92,7 @@ extension Agent {
let curveData = publicKeyWriter.openSSHIdentifier(for: secret.keyType) let curveData = publicKeyWriter.openSSHIdentifier(for: secret.keyType)
keyData.append(keyBlob.lengthAndData) keyData.append(keyBlob.lengthAndData)
keyData.append(curveData.lengthAndData) keyData.append(curveData.lengthAndData)
count += 1
if let (certificateData, name) = try? await certificateHandler.keyBlobAndName(for: secret) { if let (certificateData, name) = try? await certificateHandler.keyBlobAndName(for: secret) {
keyData.append(certificateData.lengthAndData) keyData.append(certificateData.lengthAndData)
@ -114,6 +115,7 @@ extension Agent {
let reader = OpenSSHReader(data: data) let reader = OpenSSHReader(data: data)
let payloadHash = reader.readNextChunk() let payloadHash = reader.readNextChunk()
let hash: Data let hash: Data
// Check if hash is actually an openssh certificate and reconstruct the public key if it is // Check if hash is actually an openssh certificate and reconstruct the public key if it is
if let certificatePublicKey = await certificateHandler.publicKeyHash(from: payloadHash) { if let certificatePublicKey = await certificateHandler.publicKeyHash(from: payloadHash) {
hash = certificatePublicKey hash = certificatePublicKey
@ -121,22 +123,18 @@ extension Agent {
hash = payloadHash hash = payloadHash
} }
guard let (store, secret) = await secret(matching: hash) else { guard let (secret, store) = await secret(matching: hash) else {
logger.debug("Agent did not have a key matching \(hash as NSData)") logger.debug("Agent did not have a key matching \(hash as NSData)")
throw AgentError.noMatchingKey throw NoMatchingKeyError()
} }
if let witness = witness { try await witness?.speakNowOrForeverHoldYourPeace(forAccessTo: secret, from: store, by: provenance)
try await witness.speakNowOrForeverHoldYourPeace(forAccessTo: secret, from: store, by: provenance)
}
let dataToSign = reader.readNextChunk() let dataToSign = reader.readNextChunk()
let rawRepresentation = try await store.sign(data: dataToSign, with: secret, for: provenance) let rawRepresentation = try await store.sign(data: dataToSign, with: secret, for: provenance)
let signedData = signatureWriter.data(secret: secret, signature: rawRepresentation) let signedData = signatureWriter.data(secret: secret, signature: rawRepresentation)
if let witness = witness { try await witness?.witness(accessTo: secret, from: store, by: provenance)
try await witness.witness(accessTo: secret, from: store, by: provenance)
}
logger.debug("Agent signed request") logger.debug("Agent signed request")
@ -161,16 +159,10 @@ extension Agent {
/// Finds a ``Secret`` matching a specified hash whos signature was requested. /// Finds a ``Secret`` matching a specified hash whos signature was requested.
/// - Parameter hash: The hash to match against. /// - Parameter hash: The hash to match against.
/// - Returns: A ``Secret`` and the ``SecretStore`` containing it, if a match is found. /// - Returns: A ``Secret`` and the ``SecretStore`` containing it, if a match is found.
func secret(matching hash: Data) async -> (AnySecretStore, AnySecret)? { func secret(matching hash: Data) async -> (AnySecret, AnySecretStore)? {
for store in await storeList.stores { await storeList.allSecretsWithStores.first {
let allMatching = await store.secrets.filter { secret in hash == publicKeyWriter.data(secret: $0.0)
hash == publicKeyWriter.data(secret: secret)
}
if let matching = allMatching.first {
return (store, matching)
}
} }
return nil
} }
} }
@ -178,14 +170,8 @@ extension Agent {
extension Agent { extension Agent {
/// An error involving agent operations.. struct InvalidDataProvidedError: Error {}
enum AgentError: Error { struct NoMatchingKeyError: Error {}
case couldNotRead
case unhandledType
case noMatchingKey
case unsupportedKeyType
case notOpenSSHCertificate
}
} }

View File

@ -31,7 +31,6 @@ public actor OpenSSHCertificateHandler: Sendable {
public func publicKeyHash(from hash: Data) -> Data? { public func publicKeyHash(from hash: Data) -> Data? {
let reader = OpenSSHReader(data: hash) let reader = OpenSSHReader(data: hash)
let certType = String(decoding: reader.readNextChunk(), as: UTF8.self) let certType = String(decoding: reader.readNextChunk(), as: UTF8.self)
switch certType { switch certType {
case "ecdsa-sha2-nistp256-cert-v01@openssh.com", case "ecdsa-sha2-nistp256-cert-v01@openssh.com",
"ecdsa-sha2-nistp384-cert-v01@openssh.com", "ecdsa-sha2-nistp384-cert-v01@openssh.com",

View File

@ -36,4 +36,12 @@ import Observation
stores.flatMap(\.secrets) stores.flatMap(\.secrets)
} }
public var allSecretsWithStores: [(AnySecret, AnySecretStore)] {
stores.flatMap { store in
store.secrets.map { secret in
(secret, store)
}
}
}
} }