Skip to content

Commit 9f465a4

Browse files
committed
Include signing entity in version metadata
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 af783e1 commit 9f465a4

File tree

6 files changed

+79
-2
lines changed

6 files changed

+79
-2
lines changed

Sources/PackageMetadata/PackageMetadata.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import SourceControl
2020
import struct Foundation.URL
2121
import struct TSCBasic.AbsolutePath
2222
import protocol TSCBasic.FileSystem
23+
import var TSCBasic.localFileSystem
2324
import func TSCBasic.withTemporaryDirectory
2425
import struct TSCUtility.Version
2526

@@ -48,6 +49,7 @@ public struct Package {
4849
}
4950

5051
public struct PackageSearchClient {
52+
private let fileSystem: FileSystem
5153
private let registryClient: RegistryClient
5254
private let indexAndCollections: PackageIndexAndCollections
5355
private let observabilityScope: ObservabilityScope
@@ -59,6 +61,7 @@ public struct PackageSearchClient {
5961
) {
6062
self.registryClient = registryClient
6163
self.indexAndCollections = PackageIndexAndCollections(fileSystem: fileSystem, observabilityScope: observabilityScope)
64+
self.fileSystem = fileSystem
6265
self.observabilityScope = observabilityScope
6366
}
6467

@@ -87,6 +90,7 @@ public struct PackageSearchClient {
8790
self.registryClient.getPackageVersionMetadata(
8891
package: package,
8992
version: version,
93+
fileSystem: self.fileSystem,
9094
observabilityScope: observabilityScope,
9195
callbackQueue: DispatchQueue.sharedConcurrent
9296
) { 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)