Skip to content

Conversation

@emaloney
Copy link

@emaloney emaloney commented Dec 4, 2025

Motivation:

We had a need to generate CMS structures with an embedded trusted timestamp that indicates the time at which a signing operation was performed, and discovered that this was not supported by the existing Swift Certificates implementation.

Modifications:

To address this need, we adapted existing functionality, adding several functions allowing the signing time to be embedded in a CMS structure.

In order to make this work, we also needed to add public access to several entities in the code.

Result:

This new CMS SPI allows Swift Certificates to be used for generating trusted timestamp signatures from CMS structures that embed the signing time, such as those for codesigning.

We have been using this exact same code in a high-volume production environment for several months, and can confirm that the CMS structures generated by this are usable for creating valid signatures.

Motivation:

We had a need to generate CMS structures with an embedded
trusted timestamp that indicates the time at which a signing
operation was performed, and discovered that this was not
supported by the existing Swift Certificates implementation.

Modifications:

To address this need, we adapted existing functionality,
adding several functions allowing the signing time to be
embedded in a CMS structure.

In order to make this work, we also needed to add public
access to several entities in the code.

Result:

This new CMS SPI allows Swift Certificates to be used for
generating trusted timestamp signatures from CMS structures
that embed the signing time, such as those for codesigning.

We have been using this exact same code in a high-volume
production environment for several months, and can confirm
that the CMS structures generated by this are usable for
creating valid signatures.
@Lukasa Lukasa added the 🆕 semver/minor Adds new public API. label Dec 15, 2025
/// ```
@usableFromInline
struct CMSEncapsulatedContentInfo: DERImplicitlyTaggable, BERImplicitlyTaggable, Hashable, Sendable {
public struct CMSEncapsulatedContentInfo: DERImplicitlyTaggable, BERImplicitlyTaggable, Hashable, Sendable {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep this type behind the same SPI as the rest of the CMS stuff.

struct CMSVersion: RawRepresentable, Hashable, Sendable {
@usableFromInline
var rawValue: Int
public struct CMSVersion: RawRepresentable, Hashable, Sendable {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep this behind the same SPI as the rest of the CMS stuff.


@usableFromInline
var parameters: ASN1Any?
public private(set) var parameters: ASN1Any?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there's any particular reason to make these private(set).

@usableFromInline
@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *)
enum Digest: Sendable {
public enum Digest: Sendable {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we avoid making this enum public directly? It makes it very hard to evolve. Preferably we'd wrap it in a struct.


@_spi(CMS)
@inlinable
public static func createSigningTimeASN1(signingTime: Date) throws -> Data {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this particular function pulling its weight? It isn't used by anything inside this module, and it does something quite specific, so I'm inclined to want to pull it out of this module and keep it in the code that uses it.

@Lukasa
Copy link
Contributor

Lukasa commented Dec 15, 2025

Can I also ask that we provide some unit tests for new things with public API surface? Just to make sure they're doing what is expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🆕 semver/minor Adds new public API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants