Skip to content

Commit

Permalink
Add Expanded CMS Support
Browse files Browse the repository at this point in the history
* Support BER Encoded CMS
* Support Attached CMS
* Support Signed Attributes CMS
  • Loading branch information
davidzech committed Oct 25, 2023
1 parent 3c33085 commit 7eb7421
Show file tree
Hide file tree
Showing 12 changed files with 645 additions and 61 deletions.
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ let package = Package(
if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil {
package.dependencies += [
.package(url: "https://github.com/apple/swift-crypto.git", "2.5.0" ..< "4.0.0"),
.package(url: "https://github.com/apple/swift-asn1.git", from: "1.0.0"),
.package(url: "https://github.com/apple/swift-asn1.git", from: "1.1.0"),
.package(url: "https://github.com/apple/swift-docc-plugin.git", from: "1.0.0"),
]
} else {
Expand Down
1 change: 1 addition & 0 deletions Sources/X509/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ add_library(X509
"CertificatePublicKey.swift"
"CertificateSerialNumber.swift"
"CertificateVersion.swift"
"CryptographicMessageSyntax/CMSAttribute.swift"
"CryptographicMessageSyntax/CMSContentInfo.swift"
"CryptographicMessageSyntax/CMSEncapsulatedContentInfo.swift"
"CryptographicMessageSyntax/CMSIssuerAndSerialNumber.swift"
Expand Down
69 changes: 69 additions & 0 deletions Sources/X509/CryptographicMessageSyntax/CMSAttribute.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftCertificates open source project
//
// Copyright (c) 2023 Apple Inc. and the SwiftCertificates project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftCertificates project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import SwiftASN1

/// ``CMSAttribute`` is defined in ASN.1 as:
/// ```
/// Attribute ::= SEQUENCE {
/// attrType OBJECT IDENTIFIER,
/// attrValues SET OF AttributeValue }
///
/// AttributeValue ::= ANY
/// ```
@usableFromInline
struct CMSAttribute: DERImplicitlyTaggable, BERImplicitlyTaggable, Hashable, Sendable {

@inlinable
static var defaultIdentifier: ASN1Identifier {
.sequence
}

@usableFromInline var attrType: ASN1ObjectIdentifier
@usableFromInline var attrValues: [ASN1Any]

@inlinable
init(derEncoded rootNode: ASN1Node, withIdentifier identifier: ASN1Identifier) throws {
self = try DER.sequence(rootNode, identifier: identifier) { nodes in
let attrType = try ASN1ObjectIdentifier(derEncoded: &nodes)
let attrValues = try DER.set(of: ASN1Any.self, identifier: .set, nodes: &nodes)

return .init(attrType: attrType, attrValues: attrValues)
}
}

@inlinable
init(berEncoded rootNode: ASN1Node, withIdentifier identifier: ASN1Identifier) throws {
self = try BER.sequence(rootNode, identifier: identifier) { nodes in
let attrType = try ASN1ObjectIdentifier(berEncoded: &nodes)
let attrValues = try BER.set(of: ASN1Any.self, identifier: .set, nodes: &nodes)

return .init(attrType: attrType, attrValues: attrValues)
}
}

@inlinable
init(attrType: ASN1ObjectIdentifier, attrValues: [ASN1Any]) {
self.attrType = attrType
self.attrValues = attrValues
}

@inlinable
func serialize(into coder: inout DER.Serializer, withIdentifier identifier: ASN1Identifier) throws {
try coder.appendConstructedNode(identifier: identifier) { coder in
try coder.serialize(self.attrType)
try coder.serializeSetOf(self.attrValues)
}
}
}
14 changes: 13 additions & 1 deletion Sources/X509/CryptographicMessageSyntax/CMSContentInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ extension ASN1ObjectIdentifier {
/// ContentType ::= OBJECT IDENTIFIER
/// ```
@usableFromInline
struct CMSContentInfo: DERImplicitlyTaggable, Hashable, Sendable {
struct CMSContentInfo: DERImplicitlyTaggable, BERImplicitlyTaggable, Hashable, Sendable {
@inlinable
static var defaultIdentifier: ASN1Identifier {
.sequence
Expand Down Expand Up @@ -74,6 +74,18 @@ struct CMSContentInfo: DERImplicitlyTaggable, Hashable, Sendable {
}
}

@inlinable
init(berEncoded rootNode: ASN1Node, withIdentifier identifier: ASN1Identifier) throws {
self = try BER.sequence(rootNode, identifier: identifier) { nodes in
let contentType = try ASN1ObjectIdentifier(derEncoded: &nodes)

let content = try BER.explicitlyTagged(&nodes, tagNumber: 0, tagClass: .contextSpecific) { node in
ASN1Any(berEncoded: node)
}
return .init(contentType: contentType, content: content)
}
}

@inlinable
func serialize(into coder: inout DER.Serializer, withIdentifier identifier: ASN1Identifier) throws {
try coder.appendConstructedNode(identifier: identifier) { coder in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import SwiftASN1
/// ContentType ::= OBJECT IDENTIFIER
/// ```
@usableFromInline
struct CMSEncapsulatedContentInfo: DERImplicitlyTaggable, Hashable, Sendable {
struct CMSEncapsulatedContentInfo: DERImplicitlyTaggable, BERImplicitlyTaggable, Hashable, Sendable {
@inlinable
static var defaultIdentifier: ASN1Identifier {
.sequence
Expand Down Expand Up @@ -52,6 +52,18 @@ struct CMSEncapsulatedContentInfo: DERImplicitlyTaggable, Hashable, Sendable {
}
}

@inlinable
init(berEncoded rootNode: ASN1Node, withIdentifier identifier: ASN1Identifier) throws {
self = try BER.sequence(rootNode, identifier: identifier) { nodes in
let eContentType = try ASN1ObjectIdentifier(derEncoded: &nodes)
let eContent = try BER.optionalExplicitlyTagged(&nodes, tagNumber: 0, tagClass: .contextSpecific) { node in
try ASN1OctetString(berEncoded: node)
}

return .init(eContentType: eContentType, eContent: eContent)
}
}

@inlinable
func serialize(into coder: inout DER.Serializer, withIdentifier identifier: ASN1Identifier) throws {
try coder.appendConstructedNode(
Expand Down
Loading

0 comments on commit 7eb7421

Please sign in to comment.