Skip to content

Commit 638cc86

Browse files
authored
Include signing entity in version metadata (#6363)
Clients who are asking for metadata prior to download an archive from the registry may still want to display information from the signature which is non-trivial to extract. This includes it if possible.
1 parent f7cab11 commit 638cc86

File tree

6 files changed

+78
-2
lines changed

6 files changed

+78
-2
lines changed

Sources/PackageMetadata/PackageMetadata.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public struct Package {
4848
}
4949

5050
public struct PackageSearchClient {
51+
private let fileSystem: FileSystem
5152
private let registryClient: RegistryClient
5253
private let indexAndCollections: PackageIndexAndCollections
5354
private let observabilityScope: ObservabilityScope
@@ -59,6 +60,7 @@ public struct PackageSearchClient {
5960
) {
6061
self.registryClient = registryClient
6162
self.indexAndCollections = PackageIndexAndCollections(fileSystem: fileSystem, observabilityScope: observabilityScope)
63+
self.fileSystem = fileSystem
6264
self.observabilityScope = observabilityScope
6365
}
6466

@@ -87,6 +89,7 @@ public struct PackageSearchClient {
8789
self.registryClient.getPackageVersionMetadata(
8890
package: package,
8991
version: version,
92+
fileSystem: self.fileSystem,
9093
observabilityScope: observabilityScope,
9194
callbackQueue: DispatchQueue.sharedConcurrent
9295
) { result in

Sources/PackageRegistry/RegistryClient.swift

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ public final class RegistryClient: Cancellable {
266266
package: PackageIdentity,
267267
version: Version,
268268
timeout: DispatchTimeInterval? = .none,
269+
fileSystem: FileSystem,
269270
observabilityScope: ObservabilityScope,
270271
callbackQueue: DispatchQueue,
271272
completion: @escaping (Result<PackageVersionMetadata, Error>) -> Void
@@ -286,6 +287,7 @@ public final class RegistryClient: Cancellable {
286287
package: registryIdentity,
287288
version: version,
288289
timeout: timeout,
290+
fileSystem: fileSystem,
289291
observabilityScope: observabilityScope,
290292
callbackQueue: callbackQueue,
291293
completion: completion
@@ -314,6 +316,7 @@ public final class RegistryClient: Cancellable {
314316
package: PackageIdentity.RegistryIdentity,
315317
version: Version,
316318
timeout: DispatchTimeInterval?,
319+
fileSystem: FileSystem,
317320
observabilityScope: ObservabilityScope,
318321
callbackQueue: DispatchQueue,
319322
completion: @escaping (Result<PackageVersionMetadata, Error>) -> Void
@@ -343,6 +346,22 @@ public final class RegistryClient: Cancellable {
343346
signatureBase64Encoded: $0.signatureBase64Encoded,
344347
signatureFormat: $0.signatureFormat
345348
)
349+
},
350+
signingEntity: $0.signing.flatMap {
351+
guard let signatureData = Data(base64Encoded: $0.signatureBase64Encoded) else {
352+
return nil
353+
}
354+
guard let signatureFormat = SignatureFormat(rawValue: $0.signatureFormat) else {
355+
return nil
356+
}
357+
let configuration = self.configuration.signing(for: package, registry: registry)
358+
return try? tsc_await { SignatureValidation.extractSigningEntity(
359+
signature: [UInt8](signatureData),
360+
signatureFormat: signatureFormat,
361+
configuration: configuration,
362+
fileSystem: fileSystem,
363+
completion: $0
364+
) }
346365
}
347366
)
348367
},
@@ -501,6 +520,7 @@ public final class RegistryClient: Cancellable {
501520
package: package,
502521
version: version,
503522
timeout: timeout,
523+
fileSystem: localFileSystem,
504524
observabilityScope: observabilityScope,
505525
callbackQueue: callbackQueue
506526
) { result in
@@ -733,6 +753,7 @@ public final class RegistryClient: Cancellable {
733753
package: package,
734754
version: version,
735755
timeout: timeout,
756+
fileSystem: localFileSystem,
736757
observabilityScope: observabilityScope,
737758
callbackQueue: callbackQueue
738759
) { result in
@@ -950,6 +971,7 @@ public final class RegistryClient: Cancellable {
950971
package: package,
951972
version: version,
952973
timeout: timeout,
974+
fileSystem: fileSystem,
953975
observabilityScope: observabilityScope,
954976
callbackQueue: callbackQueue
955977
) { result in
@@ -1839,12 +1861,14 @@ extension RegistryClient {
18391861
public let type: String
18401862
public let checksum: String?
18411863
public let signing: Signing?
1864+
public let signingEntity: SigningEntity?
18421865

1843-
public init(name: String, type: String, checksum: String?, signing: Signing?) {
1866+
public init(name: String, type: String, checksum: String?, signing: Signing?, signingEntity: SigningEntity?) {
18441867
self.name = name
18451868
self.type = type
18461869
self.checksum = checksum
18471870
self.signing = signing
1871+
self.signingEntity = signingEntity
18481872
}
18491873
}
18501874

Sources/PackageRegistry/SignatureValidation.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,30 @@ struct SignatureValidation {
513513
}
514514
}
515515
}
516+
517+
// MARK: - signing entity
518+
519+
static func extractSigningEntity(
520+
signature: [UInt8],
521+
signatureFormat: SignatureFormat,
522+
configuration: RegistryConfiguration.Security.Signing,
523+
fileSystem: FileSystem,
524+
completion: @Sendable @escaping (Result<SigningEntity?, Error>) -> Void
525+
) {
526+
Task {
527+
do {
528+
let verifierConfiguration = try VerifierConfiguration.from(configuration, fileSystem: fileSystem)
529+
let signingEntity = try await SignatureProvider.extractSigningEntity(
530+
signature: signature,
531+
format: signatureFormat,
532+
verifierConfiguration: verifierConfiguration
533+
)
534+
return completion(.success(signingEntity))
535+
} catch {
536+
return completion(.failure(error))
537+
}
538+
}
539+
}
516540
}
517541

518542
extension VerifierConfiguration {

Sources/PackageSigning/SignatureProvider.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@ public enum SignatureProvider {
5555
observabilityScope: observabilityScope
5656
)
5757
}
58+
59+
public static func extractSigningEntity(
60+
signature: [UInt8],
61+
format: SignatureFormat,
62+
verifierConfiguration: VerifierConfiguration
63+
) async throws -> SigningEntity {
64+
let provider = format.provider
65+
return try await provider.extractSigningEntity(
66+
signature: signature,
67+
verifierConfiguration: verifierConfiguration
68+
)
69+
}
5870
}
5971

6072
public struct VerifierConfiguration {
@@ -162,6 +174,11 @@ protocol SignatureProviderProtocol {
162174
verifierConfiguration: VerifierConfiguration,
163175
observabilityScope: ObservabilityScope
164176
) async throws -> SignatureStatus
177+
178+
func extractSigningEntity(
179+
signature: [UInt8],
180+
verifierConfiguration: VerifierConfiguration
181+
) async throws -> SigningEntity
165182
}
166183

167184
// MARK: - CMS signature provider
@@ -232,6 +249,13 @@ struct CMSSignatureProvider: SignatureProviderProtocol {
232249
}
233250
}
234251

252+
func extractSigningEntity(
253+
signature: [UInt8],
254+
verifierConfiguration: VerifierConfiguration
255+
) async throws -> SigningEntity {
256+
throw StringError("not implemented")
257+
}
258+
235259
func status(
236260
signature: [UInt8],
237261
content: [UInt8],

Sources/PackageSigning/SigningEntity/SigningEntity.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
// MARK: - SigningEntity is the entity that generated the signature
1717

18-
public enum SigningEntity: Hashable, Codable, CustomStringConvertible {
18+
public enum SigningEntity: Hashable, Codable, CustomStringConvertible, Sendable {
1919
case recognized(type: SigningEntityType, name: String, organizationalUnit: String, organization: String)
2020
case unrecognized(name: String?, organizationalUnit: String?, organization: String?)
2121

Tests/PackageRegistryTests/RegistryClientTests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3837,6 +3837,7 @@ extension RegistryClient {
38373837
self.getPackageVersionMetadata(
38383838
package: package,
38393839
version: version,
3840+
fileSystem: InMemoryFileSystem(),
38403841
observabilityScope: ObservabilitySystem.NOOP,
38413842
callbackQueue: .sharedConcurrent,
38423843
completion: $0

0 commit comments

Comments
 (0)