diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7c8c150
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,12 @@
+## Build directory
+.build/
+
+## Xcode ser settings
+xcuserdata/
+.swiftpm/xcode
+
+## macOS files
+.DS_Store
+
+## Resolved package dependencies
+Package.resolved
diff --git a/Package.swift b/Package.swift
index 81c7bf8..187b0cd 100644
--- a/Package.swift
+++ b/Package.swift
@@ -16,8 +16,8 @@ let package = Package(
.package(url: "https://github.com/swift-server/async-http-client.git", from: "1.10.0"),
.package(url: "https://github.com/apple/swift-crypto.git", from: "2.1.0"),
.package(url: "https://github.com/vapor/jwt-kit.git", branch: "main"),
- // x509
- .package(url: "https://github.com/outfoxx/PotentCodables.git", from: "2.2.0"),
+ .package(url: "https://github.com/apple/swift-certificates.git", from: "1.0.0-beta.1"),
+ .package(url: "https://github.com/apple/swift-asn1.git", from: "1.0.0-beta.1")
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
@@ -29,7 +29,8 @@ let package = Package(
.product(name: "Crypto", package: "swift-crypto"),
.product(name: "_CryptoExtras", package: "swift-crypto"),
.product(name: "JWTKit", package: "jwt-kit"),
- "PotentCodables"
+ .product(name: "X509", package: "swift-certificates"),
+ .product(name: "SwiftASN1", package: "swift-asn1")
]),
.testTarget(
name: "AcmeSwiftTests",
diff --git a/README.md b/README.md
index ebf60ac..ad2a93b 100644
--- a/README.md
+++ b/README.md
@@ -168,13 +168,12 @@ let finalizedOrder = try await acme.orders.finalize(order: order, withPemCsr: ".
If you want AcmeSwift to generate one for you:
```swift
// ECDSA key and certificate
-let csr = try AcmeX509Csr.ecdsa(domains: ["mydomain.com", "www.mydomain.com"])
+let (privateKey, csr, finalizedOrder) = try await acme.orders.finalizeWithEcdsa(order: order, domains: ["mydomain.com", "www.mydomain.com"])
// .. or, good old RSA
-let csr = try AcmeX509Csr.rsa(domains: ["mydomain.com", "www.mydomain.com"])
+let (privateKey, csr, finalizedOrder) = try await acme.orders.finalizeWithRsa(order: order, domains: ["mydomain.com", "www.mydomain.com"])
-let finalizedOrder = try await acme.orders.finalize(order: order, withCsr: csr)
// You can access the private key used to generate the CSR (and to use once you get the certificate)
-print("\n• Private key: \(csr.privateKeyPem)")
+print("\n• Private key: \(try privateKey.serializeAsPEM().pemString)")
```
@@ -255,10 +254,8 @@ guard failed.count == 0 else {
}
// Let's create a private key and CSR using the rudimentary feature provided by AcmeSwift
-let csr = try AcmeX509Csr.ecdsa(domains: domains)
-
// If the validation didn't throw any error, we can now send our Certificate Signing Request...
-let finalized = try await acme.orders.finalize(order: order, withCsr: csr)
+let (privateKey, csr, finalized) = try await acme.orders.finalizeWithRsa(order: order, domains: domains)
// ... and the certificate is ready to download!
let certs = try await acme.certificates.download(for: finalized)
@@ -268,7 +265,7 @@ try certs.joined(separator: "\n").write(to: URL(fileURLWithPath: "cert.pem"), at
// Now we also need to export the private key, encoded as PEM
// If your server doesn't accept it, append a line return to it.
-try csr.privateKeyPem.write(to: URL(fileURLWithPath: "key.pem"), atomically: true, encoding: .utf8)
+try privateKey.serializeAsPEM().pemString.write(to: URL(fileURLWithPath: "key.pem"), atomically: true, encoding: .utf8)
```
diff --git a/Sources/AcmeSwift/APIs/AcmeSwift+Orders.swift b/Sources/AcmeSwift/APIs/AcmeSwift+Orders.swift
index 44fd844..d157795 100644
--- a/Sources/AcmeSwift/APIs/AcmeSwift+Orders.swift
+++ b/Sources/AcmeSwift/APIs/AcmeSwift+Orders.swift
@@ -1,6 +1,9 @@
import Foundation
import Crypto
+import _CryptoExtras
import JWTKit
+import SwiftASN1
+import X509
extension AcmeSwift {
@@ -33,6 +36,8 @@ extension AcmeSwift {
/// - Parameters:
/// - url: The URL of the Order.
public func get(url: URL) async throws -> AcmeOrderInfo {
+ try await self.client.ensureLoggedIn()
+
let ep = GetOrderEndpoint(url: url)
var (info, headers) = try await self.client.run(ep, privateKey: self.client.login!.key, accountURL: client.accountURL!)
info.url = URL(string: headers["Location"].first ?? "")
@@ -96,17 +101,96 @@ extension AcmeSwift {
let (info, _) = try await self.client.run(ep, privateKey: self.client.login!.key, accountURL: client.accountURL!)
return info
}
+
+ /// Finalizes an Order and send the ECDSA CSR.
+ /// - Parameters:
+ /// - order: The `AcmeOrderInfo` returned by the call to `.create()`
+ /// - subject: Subject of certificate
+ /// - domains: Domains for certificate
+ /// - Throws: Errors that can occur when executing the request.
+ /// - Returns: Returns `Certificate.PrivateKey`, `CertificateSigningRequest` and `Account`.
+ public func finalizeWithEcdsa(order: AcmeOrderInfo, subject: String? = nil, domains: [String]) async throws -> (Certificate.PrivateKey, CertificateSigningRequest, AcmeOrderInfo) {
+ guard domains.count > 0 else {
+ throw AcmeError.noDomains("At least 1 DNS name is required")
+ }
+
+ let p256 = P256.Signing.PrivateKey()
+ let privateKey = Certificate.PrivateKey(p256)
+ let commonName = subject ?? domains[0]
+ let name = try DistinguishedName {
+ CommonName(commonName)
+ }
+ let extensions = try Certificate.Extensions {
+ SubjectAlternativeNames(domains.map({ GeneralName.dnsName($0) }))
+ }
+ let extensionRequest = ExtensionRequest(extensions: extensions)
+ let attributes = try CertificateSigningRequest.Attributes(
+ [.init(extensionRequest)]
+ )
+ let csr = try CertificateSigningRequest(
+ version: .v1,
+ subject: name,
+ privateKey: privateKey,
+ attributes: attributes,
+ signatureAlgorithm: .ecdsaWithSHA256
+ )
+
+ let account = try await finalize(order: order, withCsr: csr)
+
+ return (privateKey, csr, account)
+ }
+
+ /// Finalizes an Order and send the RSA CSR.
+ /// - Parameters:
+ /// - order: The `AcmeOrderInfo` returned by the call to `.create()`
+ /// - subject: Subject of certificate
+ /// - domains: Domains for certificate
+ /// - Throws: Errors that can occur when executing the request.
+ /// - Returns: Returns `Certificate.PrivateKey`, `CertificateSigningRequest` and `Account`.
+ public func finalizeWithRsa(order: AcmeOrderInfo, subject: String? = nil, domains: [String]) async throws -> (Certificate.PrivateKey, CertificateSigningRequest, AcmeOrderInfo) {
+ guard domains.count > 0 else {
+ throw AcmeError.noDomains("At least 1 DNS name is required")
+ }
+
+ let p256 = try _CryptoExtras._RSA.Signing.PrivateKey(keySize: .bits2048)
+ let privateKey = Certificate.PrivateKey(p256)
+ let commonName = subject ?? domains[0]
+ let name = try DistinguishedName {
+ CommonName(commonName)
+ }
+ let extensions = try Certificate.Extensions {
+ SubjectAlternativeNames(domains.map({ GeneralName.dnsName($0) }))
+ }
+ let extensionRequest = ExtensionRequest(extensions: extensions)
+ let attributes = try CertificateSigningRequest.Attributes(
+ [.init(extensionRequest)]
+ )
+ let csr = try CertificateSigningRequest(
+ version: .v1,
+ subject: name,
+ privateKey: privateKey,
+ attributes: attributes,
+ signatureAlgorithm: .sha256WithRSAEncryption
+ )
+
+ let account = try await finalize(order: order, withCsr: csr)
+
+ return (privateKey, csr, account)
+ }
/// Finalizes an Order and send the CSR.
/// - Parameters:
/// - order: The `AcmeOrderInfo` returned by the call to `.create()`
- /// - withCsr: An instance of an `AcmeX509Csr`.
+ /// - withCsr: An instance of an `Certificate`.
/// - Throws: Errors that can occur when executing the request.
/// - Returns: Returns the `Account`.
- public func finalize(order: AcmeOrderInfo, withCsr: AcmeX509Csr) async throws -> AcmeOrderInfo {
+ public func finalize(order: AcmeOrderInfo, withCsr csr: CertificateSigningRequest) async throws -> AcmeOrderInfo {
try await self.client.ensureLoggedIn()
-
- let csrBytes = try withCsr.derEncoded()
+
+ var serializer = DER.Serializer()
+ try serializer.serialize(csr)
+
+ let csrBytes = Data(serializer.serializedBytes)
let pemStr = csrBytes.toBase64UrlString()
let ep = FinalizeOrderEndpoint(orderURL: order.finalize, spec: .init(csr: pemStr))
diff --git a/Sources/AcmeSwift/Models/AcmeError.swift b/Sources/AcmeSwift/Models/AcmeError.swift
index 72e083b..202e6e7 100644
--- a/Sources/AcmeSwift/Models/AcmeError.swift
+++ b/Sources/AcmeSwift/Models/AcmeError.swift
@@ -26,6 +26,8 @@ public enum AcmeError: Error {
/// A resource should have a URL, returned in a response "Location" header, but couldn't find or parse the header.
case noResourceUrl
+
+ case noDomains(String)
}
public struct AcmeResponseError: Codable, Error {
diff --git a/Sources/AcmeSwift/x509/AcmeX509Csr.swift b/Sources/AcmeSwift/x509/AcmeX509Csr.swift
deleted file mode 100644
index 7424582..0000000
--- a/Sources/AcmeSwift/x509/AcmeX509Csr.swift
+++ /dev/null
@@ -1,176 +0,0 @@
-import Foundation
-import Crypto
-import _CryptoExtras
-import PotentASN1
-import CryptoKit
-
-public struct AcmeX509Csr {
-
- /// The private key used to generate the CSR, in DER format
- private(set) public var privateKey: Data
-
- /// The private key used to generate the CSR, in PEM format with headers
- private(set) public var privateKeyPem: String
-
- private var asn1Csr: Asn1CertificateSigningRequest
-
- public static func rsa(key: _CryptoExtras._RSA.Signing.PrivateKey = try! .init(keySize: .bits2048), subject: X509Subject? = nil, domains: [String], keyUsage: X509KeyUsage? = nil, extendedKeyUsage: [X509ExtendedKeyUsageOID]? = nil) throws -> AcmeX509Csr {
- guard domains.count > 0 else {
- throw X509Error.noDomains("At least 1 DNS name is required")
- }
- let rsa = try RsaCSR.init(key: key, subject: subject, domains: domains, keyUsage: keyUsage, extendedKeyUsage: extendedKeyUsage)
- let csr = self.init(privateKey: rsa.key.derRepresentation, privateKeyPem: rsa.key.pemEncoded(), asn1Csr: rsa.asn1Csr)
-
- return csr
- }
-
- public static func rsa(key: _CryptoExtras._RSA.Signing.PrivateKey = try! .init(keySize: .bits2048), subject: X509Subject? = nil, order: AcmeOrderInfo, keyUsage: X509KeyUsage? = nil, extendedKeyUsage: [X509ExtendedKeyUsageOID]? = nil) throws -> AcmeX509Csr {
- guard order.identifiers.count > 0 else {
- throw X509Error.noDomains("At least 1 DNS name is required")
- }
- let domains = order.identifiers.map{$0.value}
- let rsa = try RsaCSR.init(key: key, subject: subject, domains: domains, keyUsage: keyUsage, extendedKeyUsage: extendedKeyUsage)
- let csr = self.init(privateKey: rsa.key.derRepresentation, privateKeyPem: rsa.key.pemEncoded(), asn1Csr: rsa.asn1Csr)
-
- return csr
- }
-
- public static func rsa(keyPem: String, subject: X509Subject? = nil, domains: [String]) throws -> AcmeX509Csr {
- let key = try _CryptoExtras._RSA.Signing.PrivateKey.init(pemRepresentation: keyPem)
- return try rsa(key: key, subject: subject, domains: domains)
- }
-
- public static func rsa(keyPem: String, subject: X509Subject? = nil, order: AcmeOrderInfo) throws -> AcmeX509Csr {
- let key = try _CryptoExtras._RSA.Signing.PrivateKey.init(pemRepresentation: keyPem)
- let domains = order.identifiers.map{$0.value}
- return try rsa(key: key, subject: subject, domains: domains)
- }
-
- /// A CSR using a P256 private key
- public static func ecdsa(key: Crypto.P256.Signing.PrivateKey = .init(), subject: X509Subject? = nil, domains: [String], keyUsage: X509KeyUsage? = nil, extendedKeyUsage: [X509ExtendedKeyUsageOID]? = nil) throws -> AcmeX509Csr {
- guard domains.count > 0 else {
- throw X509Error.noDomains("At least 1 DNS name is required")
- }
- let ecdsa = try EcdsaCSR.init(key: key, subject: subject, domains: domains, keyUsage: keyUsage, extendedKeyUsage: extendedKeyUsage)
- return self.init(privateKey: ecdsa.key.derRepresentation, privateKeyPem: ecdsa.key.pemEncoded(), asn1Csr: ecdsa.asn1Csr)
- }
-
- /// A CSR using a P256 private key
- public static func ecdsa(key: Crypto.P256.Signing.PrivateKey = .init(), subject: X509Subject? = nil, order: AcmeOrderInfo, keyUsage: X509KeyUsage? = nil, extendedKeyUsage: [X509ExtendedKeyUsageOID]? = nil) throws -> AcmeX509Csr {
- guard order.identifiers.count > 0 else {
- throw X509Error.noDomains("At least 1 DNS name is required")
- }
- let domains = order.identifiers.map{$0.value}
- let ecdsa = try EcdsaCSR.init(key: key, subject: subject, domains: domains, keyUsage: keyUsage, extendedKeyUsage: extendedKeyUsage)
- return self.init(privateKey: ecdsa.key.derRepresentation, privateKeyPem: ecdsa.key.pemEncoded(), asn1Csr: ecdsa.asn1Csr)
- }
-
- /// A CSR using a P256 private key
- public static func ecdsa(keyPem: String, subject: X509Subject? = nil, domains: [String]) throws -> AcmeX509Csr {
- let key = try Crypto.P256.Signing.PrivateKey.init(pemRepresentation: keyPem)
- return try ecdsa(key: key, subject: subject, domains: domains)
- }
-
- /// A CSR using a P256 private key
- public static func ecdsa(keyPem: String, subject: X509Subject? = nil, order: AcmeOrderInfo) throws -> AcmeX509Csr {
- let key = try Crypto.P256.Signing.PrivateKey.init(pemRepresentation: keyPem)
- let domains = order.identifiers.map{$0.value}
- return try ecdsa(key: key, subject: subject, domains: domains)
- }
-
- /// Returns the CSR as DER Data
- public func derEncoded() throws -> Data {
- let encoder = ASN1Encoder(schema: Asn1CertificateSigningRequest.schema)
- return try encoder.encode(self.asn1Csr)
- }
-
- /// Returns the CSR as a PEM encoded string with headers.
- public func pemEncoded() throws -> String {
- let data = try self.derEncoded().base64EncodedString(options: .lineLength64Characters)
- return """
- -----BEGIN CERTIFICATE REQUEST-----
- \(data)
- -----END CERTIFICATE REQUEST-----
- """
- }
-}
-
-
-/// A CSR using an ECDSA key
-struct EcdsaCSR {
- var key: Crypto.P256.Signing.PrivateKey
- var subject: X509Subject
- var domains: [String]
- var asn1Csr: Asn1CertificateSigningRequest
-
- init(key: Crypto.P256.Signing.PrivateKey = .init(), subject: X509Subject? = nil, domains: [String], keyUsage: X509KeyUsage?, extendedKeyUsage: [X509ExtendedKeyUsageOID]?) throws {
-
- self.domains = domains
- self.subject = subject ?? .init(commonName: domains.first!)
- self.key = key
-
- let crInfo = Asn1CertificateRequestInfo(
- subject: .init(subject: subject ?? .init(commonName: domains.first!)),
- subjectPKInfo: .init(
- algorithm: Asn1AlgorithmIdentifier(
- algorithm: X509PublicKeyAlgorithmOID.idEcPublicKey.value,
- parameters: ECCurve.prime256v1.value
- ),
- publicKey: self.key.publicKey.x963Representation
- ),
- extensions: .init(
- san: .init(dnsNames: domains),
- keyUsage: keyUsage != nil ? .init(keyUsage!) : nil,
- extendedKeyUsage: extendedKeyUsage != nil ? .init(usages: extendedKeyUsage!) : nil
- )
- )
- let crInfoEncoder = ASN1Encoder(schema: Asn1CertificateRequestInfo.schema)
- let crInfoEncoded = try crInfoEncoder.encode(crInfo)
-
- let digest = Crypto.SHA256.hash(data: crInfoEncoded)
- let signature = try self.key.signature(for: digest)
-
- self.asn1Csr = .init(
- certificationRequestInfo: crInfo,
- signatureAlgorithm: .init(algorithm: OID(X509SignatureAlgorithmOID.ecdsaWithSHA256.value)),
- signature: signature.derRepresentation
- )
- }
-}
-
-/// A CSR using an RSA key
-struct RsaCSR {
- var key: _CryptoExtras._RSA.Signing.PrivateKey
- public var subject: X509Subject
- var domains: [String]
- var asn1Csr: Asn1CertificateSigningRequest
-
- init(key: _CryptoExtras._RSA.Signing.PrivateKey = try! .init(keySize: .bits2048), subject: X509Subject? = nil, domains: [String], keyUsage: X509KeyUsage?, extendedKeyUsage: [X509ExtendedKeyUsageOID]?) throws {
- self.domains = domains
- self.subject = subject ?? .init(commonName: domains.first!)
- self.key = key
-
- let crInfo = Asn1CertificateRequestInfo(
- subject: .init(subject: subject ?? .init(commonName: domains.first!)),
- subjectPKInfo: .init(
- algorithm: .rsaEncryption,
- publicKey: self.key.publicKey.derRepresentation
- ),
- extensions: .init(
- san: .init(dnsNames: domains),
- keyUsage: keyUsage != nil ? .init(keyUsage!) : nil,
- extendedKeyUsage: extendedKeyUsage != nil ? .init(usages: extendedKeyUsage!) : nil
- )
- )
- let crInfoEncoder = ASN1Encoder(schema: Asn1CertificateRequestInfo.schema)
- let crInfoEncoded = try crInfoEncoder.encode(crInfo)
- let digest = Crypto.SHA256.hash(data: crInfoEncoded)
- let signature = try self.key.signature(for: digest, padding: .insecurePKCS1v1_5)
-
- self.asn1Csr = .init(
- certificationRequestInfo: crInfo,
- signatureAlgorithm: .init(algorithm: OID(X509SignatureAlgorithmOID.sha256WithRSAEncryption.value)),
- signature: signature.rawRepresentation
- )
- }
-}
diff --git a/Sources/AcmeSwift/x509/Asn1CertificateRequestInfo.swift b/Sources/AcmeSwift/x509/Asn1CertificateRequestInfo.swift
deleted file mode 100644
index e9ab86c..0000000
--- a/Sources/AcmeSwift/x509/Asn1CertificateRequestInfo.swift
+++ /dev/null
@@ -1,77 +0,0 @@
-import Foundation
-import PotentASN1
-
-/*struct X509CertificateRequestInfo {
- public var version: CSRVersion = .v1
- public var subject: X509Subject
- public var subjectPKInfo: Asn1SubjectPublicKeyInfo
- public var attributes: [Asn1Extension]
-
- enum CSRVersion: Int, Codable {
- case v1 = 0
- }
-}*/
-
- struct Asn1CertificateRequestInfo: HasSchemaProtocol {
- init(version: Int = 0, subject: Asn1Subject, subjectPKInfo: Asn1SubjectPublicKeyInfo, extensions: Asn1CertificateRequestInfo.Extensions) {
- self.version = version
- self.subject = subject
- self.subjectPKInfo = subjectPKInfo
- self.extensions = [extensions]
- }
-
- var version: Int = 0
- var subject: Asn1Subject
- var subjectPKInfo: Asn1SubjectPublicKeyInfo
- var extensions: [Extensions]
-
- static var schema: Schema {
- .sequence([
- "version": .version(.integer(allowed: 0 ..< 1)),
- "subject": Asn1Subject.schema,
- "subjectPKInfo": Asn1SubjectPublicKeyInfo.schema,
- "extensions": .implicit(
- 0,
- .setOf(Extensions.schema)
- )
- ])
- }
-
- struct Extensions: HasSchemaProtocol {
- private(set) var oid: OID = CsrExtension.extensionRequest.value
- var value: [ExtensionValue]
-
- init(san: Asn1SubjectAltName, keyUsage: Asn1KeyUsage? = nil, extendedKeyUsage: Asn1ExtendedKeyUsage? = nil) {
- self.value = [
- .init(san: san, keyUsage: keyUsage, extendedKeyUsage: extendedKeyUsage, basicConstraints: nil)
- ]
- }
-
- static var schema: Schema {
- .sequence([
- "oid": .objectIdentifier(),
- "value": .setOf(
- ExtensionValue.schema,
- size: .is(1)
- )
- ])
- }
-
- struct ExtensionValue: HasSchemaProtocol {
- var san: Asn1SubjectAltName
- var keyUsage: Asn1KeyUsage? = nil
- var extendedKeyUsage: Asn1ExtendedKeyUsage? = nil
- var basicConstraints: Asn1BasicConstraints? = nil
-
- static var schema: Schema {
- .sequence([
- "san": Asn1SubjectAltName.schema,
- "keyUsage": .optional(Asn1KeyUsage.schema),
- "extendedKeyUsage": .optional(Asn1ExtendedKeyUsage.schema),
- "basicConstraints": .optional(Asn1BasicConstraints.schema)
- ])
- }
- }
-
- }
-}
diff --git a/Sources/AcmeSwift/x509/Asn1CertificateSigningRequest.swift b/Sources/AcmeSwift/x509/Asn1CertificateSigningRequest.swift
deleted file mode 100644
index fe78597..0000000
--- a/Sources/AcmeSwift/x509/Asn1CertificateSigningRequest.swift
+++ /dev/null
@@ -1,18 +0,0 @@
-import Foundation
-import PotentASN1
-
-struct Asn1CertificateSigningRequest: HasSchemaProtocol {
- var certificationRequestInfo: Asn1CertificateRequestInfo
- var signatureAlgorithm: Asn1AlgorithmIdentifier
- var signature: Data
-
- static var schema: Schema {
- .sequence([
- "certificationRequestInfo": Asn1CertificateRequestInfo.schema,
- "signatureAlgorithm": Asn1AlgorithmIdentifier.schema,
- "signature": .bitString(),
- ])
- }
-}
-
-
diff --git a/Sources/AcmeSwift/x509/Asn1Subject.swift b/Sources/AcmeSwift/x509/Asn1Subject.swift
deleted file mode 100644
index 4c34abf..0000000
--- a/Sources/AcmeSwift/x509/Asn1Subject.swift
+++ /dev/null
@@ -1,43 +0,0 @@
-import Foundation
-import PotentASN1
-
-struct Asn1Subject: HasSchemaProtocol {
- var values: [X509Item] = []
-
- init(subject: X509Subject) {
- if let c = subject.countryName {
- self.values.append(.init(oid: [2,5,4,6], value: c))
- }
- if let s = subject.stateOrProvinceName {
- self.values.append(.init(oid: [2,5,4,8], value: s))
- }
- if let l = subject.localityName {
- self.values.append(.init(oid: [2,5,4,7], value: l))
- }
- if let o = subject.organizationName {
- self.values.append(.init(oid: [2,5,4,10], value: o))
- }
- if let ou = subject.organizationalUnitName {
- self.values.append(.init(oid: [2,5,4,11], value: ou))
- }
- if let cn = subject.commonName {
- self.values.append(.init(oid: [2,5,4,3], value: cn))
- }
- }
-
- static var schema: Schema {
- .sequence(
- ["values": .setOf(X509Kind.schema())]
- )
- // TODO: set proper kind and range for each field, or at least check spec
- /*.sequence([
- "countryName": X509Kind.schema(),
- "stateOrProvinceName": X509Kind.schema(),
- "localityName": X509Kind.schema(),
- "organizationName": X509Kind.schema(),
- "organizationalUnitName": X509Kind.schema(),
- "commonName": X509Kind.schema(),
- "emailAddress": X509Kind.schema()
- ])*/
- }
-}
diff --git a/Sources/AcmeSwift/x509/Asn1SubjectPublicKeyInfo.swift b/Sources/AcmeSwift/x509/Asn1SubjectPublicKeyInfo.swift
deleted file mode 100644
index 3daaadf..0000000
--- a/Sources/AcmeSwift/x509/Asn1SubjectPublicKeyInfo.swift
+++ /dev/null
@@ -1,41 +0,0 @@
-import Foundation
-import PotentASN1
-
-struct Asn1SubjectPublicKeyInfo: HasSchemaProtocol {
-
- var algorithm: Asn1AlgorithmIdentifier
-
- /// The Subject public key
- var publicKey: Data
-
- init(algorithm: X509PublicKeyAlgorithmOID, publicKey: Data) {
- self.algorithm = Asn1AlgorithmIdentifier(algorithm: algorithm.value)
- self.publicKey = publicKey
- }
-
- init(algorithm: Asn1AlgorithmIdentifier, publicKey: Data) {
- self.algorithm = algorithm
- self.publicKey = publicKey
- }
-
- static var schema: Schema {
- .sequence([
- //"algorithm": .sequenceOf(.objectIdentifier(), .none),
- "algorithm": Asn1AlgorithmIdentifier.schema,
- "publicKey": .bitString(),
- ])
- }
-}
-
-struct Asn1AlgorithmIdentifier: HasSchemaProtocol {
- var algorithm: OID
- var parameters: OID? = nil
-
- static var schema: Schema {
- .sequence([
- "algorithm": .objectIdentifier(),
- "parameters": .objectIdentifier()
- ])
- }
-
-}
diff --git a/Sources/AcmeSwift/x509/Extensions/Asn1BasicConstraints.swift b/Sources/AcmeSwift/x509/Extensions/Asn1BasicConstraints.swift
deleted file mode 100644
index 3c655a2..0000000
--- a/Sources/AcmeSwift/x509/Extensions/Asn1BasicConstraints.swift
+++ /dev/null
@@ -1,26 +0,0 @@
-import Foundation
-import PotentASN1
-
-struct Asn1BasicConstraints: X509ExtensionProtocol {
- private(set) var oid: OID = CsrExtensionsOID.basicConstraints.value
- var critical: Bool = true
- var data: Data
-
- init(isCa: Bool = false, pathLen: UInt? = nil) {
- let constraints = Constraints(isCa: isCa, pathLen: pathLen)
- let asn1Encoder = ASN1Encoder(schema: Constraints.schema)
- self.data = try! asn1Encoder.encode(constraints)
- }
-
- struct Constraints: HasSchemaProtocol {
- var isCa: Bool = false
- var pathLen: UInt? = nil
-
- static var schema: Schema {
- .sequence([
- "isCa": .boolean(),
- "pathLen": .optional(.integer())
- ])
- }
- }
-}
diff --git a/Sources/AcmeSwift/x509/Extensions/Asn1ExtendedKeyUsage.swift b/Sources/AcmeSwift/x509/Extensions/Asn1ExtendedKeyUsage.swift
deleted file mode 100644
index 570147e..0000000
--- a/Sources/AcmeSwift/x509/Extensions/Asn1ExtendedKeyUsage.swift
+++ /dev/null
@@ -1,17 +0,0 @@
-import Foundation
-import PotentASN1
-
-struct Asn1ExtendedKeyUsage: X509ExtensionProtocol {
- private(set) var oid: OID = CsrExtensionsOID.extendedKeyUsage.value
- var critical: Bool = true
- var data: Data = Data()
-
- init(usages: [X509ExtendedKeyUsageOID]) {
- var extKeyUsages: [OID] = []
- for usage in usages {
- extKeyUsages.append(usage.value)
- }
- let asn1Encoder = ASN1Encoder(schema: .sequenceOf(.objectIdentifier(), size: .min(1)))
- self.data = try! asn1Encoder.encode(extKeyUsages)
- }
-}
diff --git a/Sources/AcmeSwift/x509/Extensions/Asn1KeyUsage.swift b/Sources/AcmeSwift/x509/Extensions/Asn1KeyUsage.swift
deleted file mode 100644
index 2e16307..0000000
--- a/Sources/AcmeSwift/x509/Extensions/Asn1KeyUsage.swift
+++ /dev/null
@@ -1,13 +0,0 @@
-import Foundation
-import PotentASN1
-
-struct Asn1KeyUsage: X509ExtensionProtocol {
- private(set) var oid: OID = CsrExtensionsOID.keyUsage.value
- var critical: Bool = true
- var data: Data
-
- init(_ value: X509KeyUsage) {
- let asn1Encoder = ASN1Encoder(schema: .bitString())
- self.data = try! asn1Encoder.encode(value.rawValue)
- }
-}
diff --git a/Sources/AcmeSwift/x509/Extensions/Asn1SubjectAltName.swift b/Sources/AcmeSwift/x509/Extensions/Asn1SubjectAltName.swift
deleted file mode 100644
index 4757ad6..0000000
--- a/Sources/AcmeSwift/x509/Extensions/Asn1SubjectAltName.swift
+++ /dev/null
@@ -1,18 +0,0 @@
-import Foundation
-import PotentASN1
-
-struct Asn1SubjectAltName: X509ExtensionProtocol {
- private(set) var oid: OID = CsrExtensionsOID.subjectAltName.value
- var critical: Bool = true
- var data: Data
-
- init(dnsNames: [String]) {
- var generalNames: GeneralNames = []
- for name in dnsNames {
- generalNames.append(X509GeneralName.dnsName(name))
- }
- // The actual value of an extension must be passed as an ASN.1 Octet String
- let asn1Encoder = ASN1Encoder(schema: GeneralNames.schema)
- self.data = try! asn1Encoder.encode(generalNames)
- }
-}
diff --git a/Sources/AcmeSwift/x509/Extensions/X509ExtensionProtocol.swift b/Sources/AcmeSwift/x509/Extensions/X509ExtensionProtocol.swift
deleted file mode 100644
index a625bc7..0000000
--- a/Sources/AcmeSwift/x509/Extensions/X509ExtensionProtocol.swift
+++ /dev/null
@@ -1,18 +0,0 @@
-import Foundation
-import PotentASN1
-
-protocol X509ExtensionProtocol: HasSchemaProtocol {
- var oid: OID {get}
- var critical: Bool {get set}
- var data: Data {get set}
-}
-
-extension X509ExtensionProtocol {
- static var schema: Schema {
- .sequence([
- "oid": .objectIdentifier(),
- "critical": .boolean(),
- "data": .octetString()
- ])
- }
-}
diff --git a/Sources/AcmeSwift/x509/GeneralName.swift b/Sources/AcmeSwift/x509/GeneralName.swift
deleted file mode 100644
index 108da0d..0000000
--- a/Sources/AcmeSwift/x509/GeneralName.swift
+++ /dev/null
@@ -1,229 +0,0 @@
-// From the excellent https://github.com/outfoxx/Shield
-
-// GeneralName.swift
-// Shield
-//
-// Copyright © 2019 Outfox, inc.
-//
-//
-// Distributed under the MIT License, See LICENSE for details.
-//
-
-import Foundation
-import PotentASN1
-
-
-typealias GeneralNames = [X509GeneralName]
-extension GeneralNames {
- static var schema: Schema {
- .sequenceOf(X509GeneralName.schema, size: .min(1))
- }
-}
-
-public enum X509GeneralName: HasSchemaProtocol, TaggedValue {
- //case otherName(OtherName)
- case rfc822Name(String)
- case dnsName(String)
- case x400Address(ASN1)
- //case directoryName(Name)
- //case ediPartyName(EDIPartyName)
- case uniformResourceIdentifier(String)
- case ipAddress(Data)
- case registeredID(ObjectIdentifier)
-
- public init?(tag: ASN1.AnyTag, value: Any?) {
- switch ASN1.Tag.value(from: tag, in: .contextSpecific) {
- /*case 0:
- guard
- let values = value as? [ASN1],
- let name = try? ASN1Decoder(schema: Schemas.OtherName).decodeTree(OtherName.self, from: .sequence(values))
- else {
- return nil
- }
- self = .otherName(name)*/
- case 1:
- guard let value = value as? AnyString else { return nil }
- self = .rfc822Name(value.storage)
- case 2:
- guard let value = value as? AnyString else { return nil }
- self = .dnsName(value.storage)
- case 3:
- guard let value = value as? ASN1 else { return nil }
- self = .x400Address(value)
- /*case 4:
- guard
- let values = value as? [ASN1],
- let name = try? ASN1Decoder(schema: Schemas.Name).decodeTree(Name.self, from: .sequence(values))
- else {
- return nil
- }
- self = .directoryName(name)
- case 5:
- guard
- let values = value as? [ASN1],
- let name = try? ASN1Decoder(schema: Schemas.EDIPartyName).decodeTree(EDIPartyName.self, from: .sequence(values))
- else {
- return nil
- }
- self = .ediPartyName(name)*/
- case 6:
- guard let value = value as? AnyString else { return nil }
- self = .uniformResourceIdentifier(value.storage)
- case 7:
- guard let value = value as? Data else { return nil }
- self = .ipAddress(value)
- case 8:
- guard let value = value as? ObjectIdentifier else { return nil }
- self = .registeredID(value)
- default:
- return nil
- }
- }
-
- public var tag: ASN1.AnyTag {
- switch self {
- //case .otherName: return 0
- case .rfc822Name: return 1
- case .dnsName: return 2
- case .x400Address: return 3
- //case .directoryName: return 4
- //case .ediPartyName: return 5
- case .uniformResourceIdentifier: return 6
- case .ipAddress: return 7
- case .registeredID: return 8
- }
- }
-
- public var value: Any? {
- switch self {
- //case .otherName(let value): return value
- case .rfc822Name(let value): return value
- case .dnsName(let value): return value
- case .x400Address(let value): return value
- //case .directoryName(let value): return value
- //case .ediPartyName(let value): return value
- case .uniformResourceIdentifier(let value): return value
- case .ipAddress(let value): return value
- case .registeredID(let value): return value
- }
- }
-
- public func encode(schema: Schema) throws -> ASN1 {
- let encoder = ASN1Encoder(schema: schema)
- switch self {
- //case .otherName(let value): return try encoder.encodeTree(value)
- case .rfc822Name(let value): return try encoder.encodeTree(value)
- case .dnsName(let value): return try encoder.encodeTree(value)
- case .x400Address(let value): return value
- //case .directoryName(let value): return try encoder.encodeTree(value)
- //case .ediPartyName(let value): return try encoder.encodeTree(value)
- case .uniformResourceIdentifier(let value): return try encoder.encodeTree(value)
- case .ipAddress(let value): return try encoder.encodeTree(value)
- case .registeredID(let value): return try encoder.encodeTree(value)
- }
- }
-
- static let schema: Schema =
- .choiceOf([
- //.implicit(0, OtherName),
- .implicit(1, .string(kind: .ia5)),
- .implicit(2, .string(kind: .ia5)),
- .implicit(3, .any),
- //.explicit(4, Name),
- //.implicit(5, EDIPartyName),
- .implicit(6, .string(kind: .ia5)),
- .implicit(7, .octetString()),
- .implicit(8, .objectIdentifier()),
- ])
-}
-
-
-extension X509GeneralName: Codable {
-
- public init(from decoder: Swift.Decoder) throws {
- var container = try decoder.unkeyedContainer()
- let tag = try container.decode(UInt8.self)
- switch ASN1.Tag.value(from: tag, in: .contextSpecific) {
- //case 0:
- // self = .otherName(try container.decode(OtherName.self))
-
- case 1:
- self = .rfc822Name(try container.decode(String.self))
-
- case 2:
- self = .dnsName(try container.decode(String.self))
-
- case 3:
- self = .x400Address(try container.decode(ASN1.self))
-
- /*case 4:
- self = .directoryName(try container.decode(Name.self))
-
- case 5:
- self = .ediPartyName(try container.decode(EDIPartyName.self))
- */
- case 6:
- self = .uniformResourceIdentifier(try container.decode(String.self))
-
- case 7:
- self = .ipAddress(try container.decode(Data.self))
-
- case 8:
- self = .registeredID(try container.decode(ObjectIdentifier.self))
-
- default:
- throw DecodingError.dataCorruptedError(in: container, debugDescription: "No matching tag")
- }
- }
-
- public func encode(to encoder: Encoder) throws {
- var container = encoder.unkeyedContainer()
- switch self {
- /*case .otherName(let value):
- try container.encode(ASN1.Tag.tag(from: 0, in: .contextSpecific, constructed: true))
- try container.encode(value)
- */
- case .rfc822Name(let value):
- try container.encode(ASN1.Tag.tag(from: 1, in: .contextSpecific, constructed: false))
- try container.encode(value)
-
- case .dnsName(let value):
- try container.encode(ASN1.Tag.tag(from: 2, in: .contextSpecific, constructed: false))
- try container.encode(value)
-
- case .x400Address(let value):
- try container.encode(ASN1.Tag.tag(from: 3, in: .contextSpecific, constructed: true))
- try container.encode(value)
-
- /*case .directoryName(let value):
- try container.encode(ASN1.Tag.tag(from: 4, in: .contextSpecific, constructed: true))
- try container.encode(value)
-
- case .ediPartyName(let value):
- try container.encode(ASN1.Tag.tag(from: 5, in: .contextSpecific, constructed: true))
- try container.encode(value)
- */
- case .uniformResourceIdentifier(let value):
- try container.encode(ASN1.Tag.tag(from: 6, in: .contextSpecific, constructed: false))
- try container.encode(value)
-
- case .ipAddress(let value):
- try container.encode(ASN1.Tag.tag(from: 7, in: .contextSpecific, constructed: false))
- try container.encode(value)
-
- case .registeredID(let value):
- try container.encode(ASN1.Tag.tag(from: 8, in: .contextSpecific, constructed: false))
- try container.encode(value)
- }
- }
-
-}
-
-private func encodeToSequence(_ value: T, using schema: Schema) throws -> [ASN1]? {
- return try ASN1Encoder(schema: schema).encodeTree(value).sequenceValue
-}
-
-private func decodeFromSequence(_ type: T.Type, from value: Any?, using schema: Schema) -> T? {
- guard let values = value as? [ASN1] else { return nil }
- return try? ASN1Decoder(schema: schema).decodeTree(type, from: .sequence(values))
-}
diff --git a/Sources/AcmeSwift/x509/HasSchemaProtocol.swift b/Sources/AcmeSwift/x509/HasSchemaProtocol.swift
deleted file mode 100644
index d5c4192..0000000
--- a/Sources/AcmeSwift/x509/HasSchemaProtocol.swift
+++ /dev/null
@@ -1,6 +0,0 @@
-import Foundation
-import PotentASN1
-
-protocol HasSchemaProtocol: Codable {
- static var schema: Schema {get}
-}
diff --git a/Sources/AcmeSwift/x509/OIDs.swift b/Sources/AcmeSwift/x509/OIDs.swift
deleted file mode 100644
index 7f78ef3..0000000
--- a/Sources/AcmeSwift/x509/OIDs.swift
+++ /dev/null
@@ -1,135 +0,0 @@
-import Foundation
-import PotentASN1
-
-public enum X509SignatureAlgorithmOID {
- case sha256WithRSAEncryption
- case ecdsaWithSHA256
- case ecdsaWithSHA512
-
- var value: [UInt64] {
- switch self {
- case .sha256WithRSAEncryption: return [1,2,840,113549,1,1,11]
- case .ecdsaWithSHA256: return [1,2,840,10045,4,3,2]
- case .ecdsaWithSHA512: return [1,2,840,10045,4,3,4]
- }
- }
-}
-
-enum X509PublicKeyAlgorithmOID {
- case rsaEncryption
- case sha256WithRSAEncryption
- case sha512WithRSAEncryption
- case idEcDH
- case idEcPublicKey
-
- var value: OID {
- switch self {
- case .rsaEncryption: return [1,2,840,113549,1,1,1]
- case .sha256WithRSAEncryption: return [1,2,840,113549,1,1,11]
- case .sha512WithRSAEncryption: return [1,2,840,113549,1,1,13]
- case .idEcDH: return [1,3,132,1,12]
- case .idEcPublicKey: return [1,2,840,10045,2,1]
- }
- }
-}
-
-enum ECCurve {
- case prime256v1
-
- var value: OID {
- switch self {
- case .prime256v1: return [1,2,840,10045,3,1,7]
- }
- }
-}
-
-enum CsrExtension {
- case extensionRequest
-
- var value: OID {
- switch self {
- case .extensionRequest: return [1,2,840,113549,1,9,14]
- }
- }
-}
-
-enum CsrExtensionsOID {
- case basicConstraints
- case keyUsage
- case extendedKeyUsage
- case subjectAltName
-
- var value: OID {
- switch self {
- case .basicConstraints: return [2,5,29,19]
- case .keyUsage: return [2,5,29,15]
- case .extendedKeyUsage: return [2,5,29,37]
- case .subjectAltName: return [2,5,29,17]
- }
- }
-}
-
-enum KeyUsageOID {
- case digitalSignature
- case nonRepudiation
- case keyEncipherment
- case dataEncipherment
- case keyAgreement
- case keyCertSign
- case cRLSign
- case encipherOnly
- case decipherOnly
-
- var value: OID {
- switch self {
- case .digitalSignature: return [2,5,29,15,0]
- case .nonRepudiation: return [2,5,29,15,1]
- case .keyEncipherment: return [2,5,29,15,2]
- case .dataEncipherment: return [2,5,29,15,3]
- case .keyAgreement: return [2,5,29,15,4]
- case .keyCertSign: return [2,5,29,15,5]
- case .cRLSign: return [2,5,29,15,6]
- case .encipherOnly: return [2,5,29,15,7]
- case .decipherOnly: return [2,5,29,15,8]
- }
- }
-}
-
-public enum X509ExtendedKeyUsageOID: Codable {
- /// The most common type. A certificate for a server (web...)
- case serverAuth
- /// A certificate for client authentication (mutual TLS)
- case clientAuth
-
- case codesigning
-
- case ocspSigning
-
- var value: OID {
- switch self {
- case .serverAuth: return [1,3,6,1,5,5,7,3,1]
- case .clientAuth: return [1,3,6,1,5,5,7,3,2]
- case .codesigning: return [1,3,6,1,5,5,7,3,3]
- case .ocspSigning: return [1,3,6,1,5,5,7,3,9]
- }
- }
-}
-
-enum GeneralNameOID {
- /// Email address
- case rfc822Name
-
- /// DNS name
- case dNSName
-
- // URI
- case uniformResourceIdentifier
-
- var value: OID {
- switch self {
- case .rfc822Name: return [2,5,29,17,1]
- case .dNSName: return [2,5,29,17,2]
- case .uniformResourceIdentifier: return [2,5,29,17,6]
- }
- }
-}
diff --git a/Sources/AcmeSwift/x509/PrivateKey+pemEncoded.swift b/Sources/AcmeSwift/x509/PrivateKey+pemEncoded.swift
deleted file mode 100644
index 0997fca..0000000
--- a/Sources/AcmeSwift/x509/PrivateKey+pemEncoded.swift
+++ /dev/null
@@ -1,39 +0,0 @@
-import Foundation
-import Crypto
-import _CryptoExtras
-
-public extension Crypto.P256.Signing.PrivateKey {
- /// A PEM encoded representation of the private key.
- /// If `withHeaders` is set to `true`, the returned value can be used as-is by most software using PEM keys.
- func pemEncoded(withHeaders: Bool = true) -> String {
- let privateKeyData = self.derRepresentation.base64EncodedString(options: .lineLength64Characters)
- if !withHeaders {
- return privateKeyData
- }
- else {
- return """
- -----BEGIN EC PRIVATE KEY-----
- \(privateKeyData)
- -----END EC PRIVATE KEY----
- """
- }
- }
-}
-
-public extension _CryptoExtras._RSA.Signing.PrivateKey {
- /// A PEM encoded representation of the private key.
- /// If `withHeaders` is set to `true`, the returned value can be used as-is by most software using PEM keys.
- func pemEncoded(withHeaders: Bool = true) -> String {
- let privateKeyData = self.derRepresentation.base64EncodedString(options: .lineLength64Characters)
- if !withHeaders {
- return privateKeyData
- }
- else {
- return """
- -----BEGIN PRIVATE KEY-----
- \(privateKeyData)
- -----END PRIVATE KEY----
- """
- }
- }
-}
diff --git a/Sources/AcmeSwift/x509/X509Error.swift b/Sources/AcmeSwift/x509/X509Error.swift
deleted file mode 100644
index 7417ce1..0000000
--- a/Sources/AcmeSwift/x509/X509Error.swift
+++ /dev/null
@@ -1,5 +0,0 @@
-import Foundation
-
-public enum X509Error: Error {
- case noDomains(String)
-}
diff --git a/Sources/AcmeSwift/x509/X509KeyUsage.swift b/Sources/AcmeSwift/x509/X509KeyUsage.swift
deleted file mode 100644
index ef914e5..0000000
--- a/Sources/AcmeSwift/x509/X509KeyUsage.swift
+++ /dev/null
@@ -1,20 +0,0 @@
-import Foundation
-
-public struct X509KeyUsage: OptionSet {
- public let rawValue: UInt16
-
- public init(rawValue: UInt16) {
- self.rawValue = rawValue
- }
-
- public static let digitalSignature = X509KeyUsage(rawValue: 1 << 0)
- public static let nonRepudiation = X509KeyUsage(rawValue: 1 << 1)
- public static let keyEncipherment = X509KeyUsage(rawValue: 1 << 2)
- public static let dataEncipherment = X509KeyUsage(rawValue: 1 << 3)
- public static let keyAgreement = X509KeyUsage(rawValue: 1 << 4)
- public static let keyCertSign = X509KeyUsage(rawValue: 1 << 5)
- public static let cRLSign = X509KeyUsage(rawValue: 1 << 6)
- public static let encipherOnly = X509KeyUsage(rawValue: 1 << 7)
- public static let decipherOnly = X509KeyUsage(rawValue: 1 << 8)
- public static let contentCommitment = nonRepudiation
-}
diff --git a/Sources/AcmeSwift/x509/X509Kind.swift b/Sources/AcmeSwift/x509/X509Kind.swift
deleted file mode 100644
index 040957e..0000000
--- a/Sources/AcmeSwift/x509/X509Kind.swift
+++ /dev/null
@@ -1,16 +0,0 @@
-import Foundation
-import PotentASN1
-
-struct X509Kind {
- static func schema(_ valueKind: Schema = .string(kind: .ia5, size: .range(1, 64))) -> Schema {
- .sequence([
- "oid": .objectIdentifier(),
- "value": valueKind
- ])
- }
-}
-
-struct X509Item: Codable {
- var oid: OID
- var value: T?
-}
diff --git a/Sources/AcmeSwift/x509/X509SignatureAlgorithm.swift b/Sources/AcmeSwift/x509/X509SignatureAlgorithm.swift
deleted file mode 100644
index 3fb4ef2..0000000
--- a/Sources/AcmeSwift/x509/X509SignatureAlgorithm.swift
+++ /dev/null
@@ -1,15 +0,0 @@
-import Foundation
-import PotentASN1
-
-public struct X509SignatureAlgorithm: HasSchemaProtocol {
- var oid: OID
-
- public init(_ kind: X509SignatureAlgorithmOID) {
- self.oid = .init(kind.value)
- }
-
- static var schema: Schema {
- .sequence(["oid": .objectIdentifier()])
- }
-
-}
diff --git a/Sources/AcmeSwift/x509/X509Subject.swift b/Sources/AcmeSwift/x509/X509Subject.swift
deleted file mode 100644
index 440b3a4..0000000
--- a/Sources/AcmeSwift/x509/X509Subject.swift
+++ /dev/null
@@ -1,26 +0,0 @@
-import Foundation
-import PotentASN1
-
-public struct X509Subject {
- /// C
- public var countryName: String?
-
- /// S
- public var stateOrProvinceName: String?
-
- /// L
- public var localityName: String?
-
- /// O
- public var organizationName: String?
-
- /// OU
- public var organizationalUnitName: String?
-
- /// CN
- public var commonName: String?
-
- /// E (deprecated)
- //public var emailAddress: String?
-}
-
diff --git a/Tests/AcmeSwiftTests/MiscTemp.swift b/Tests/AcmeSwiftTests/MiscTemp.swift
index 26da067..d6505ab 100644
--- a/Tests/AcmeSwiftTests/MiscTemp.swift
+++ b/Tests/AcmeSwiftTests/MiscTemp.swift
@@ -2,29 +2,53 @@ import XCTest
import AsyncHTTPClient
import NIO
import Logging
-import PotentASN1
import Crypto
import _CryptoExtras
+import SwiftASN1
+import X509
@testable import AcmeSwift
final class MiscTempTests: XCTestCase {
func testHahi() throws {
- let privateKey = Crypto.P256.Signing.PrivateKey.init()
- let rsaPrivate = try _RSA.Signing.PrivateKey.init(keySize: .bits2048)
- //privateKey.publicKey.
- //try rsaPrivate.signature(for: Data()).rawRepresentation
-
- let csr = try AcmeX509Csr.ecdsa(
- domains: ["www.nuw.run", "nuw.run"],
- keyUsage: [.dataEncipherment, .digitalSignature],
- extendedKeyUsage: [.clientAuth, .serverAuth]
+ let domains = ["www.nuw.run", "nuw.run"]
+
+ let p256 = P256.Signing.PrivateKey()
+ let privateKey = Certificate.PrivateKey(p256)
+ let commonName = domains[0]
+ let name = try DistinguishedName {
+ CommonName(commonName)
+ }
+ let extensions = try Certificate.Extensions {
+ SubjectAlternativeNames(domains.map({ GeneralName.dnsName($0) }))
+ }
+ let extensionRequest = ExtensionRequest(extensions: extensions)
+ let attributes = try CertificateSigningRequest.Attributes(
+ [.init(extensionRequest)]
+ )
+ let csr = try CertificateSigningRequest(
+ version: .v1,
+ subject: name,
+ privateKey: privateKey,
+ attributes: attributes,
+ signatureAlgorithm: .ecdsaWithSHA256
+ )
+
+ print("\n ECDSA CSR='\(try! csr.serializeAsPEM().pemString)'")
+ print("\n ECDSA private key = '\(try! privateKey.serializeAsPEM().pemString)'")
+
+ let p256RSA = try _CryptoExtras._RSA.Signing.PrivateKey(keySize: .bits2048)
+ let privateKeyRSA = Certificate.PrivateKey(p256RSA)
+ let csr2 = try CertificateSigningRequest(
+ version: .v1,
+ subject: name,
+ privateKey: privateKeyRSA,
+ attributes: attributes,
+ signatureAlgorithm: .sha256WithRSAEncryption
)
- print("\n ECDSA CSR='\(try! csr.pemEncoded())'")
- print("\n ECDSA private key = \(csr.privateKeyPem)")
- let csr2 = try AcmeX509Csr.rsa(domains: ["www.nuw.run", "nuw.run"])
- print("\n RSA CSR='\(try! csr2.pemEncoded())'")
- print("\n RSA private key = \(csr2.privateKeyPem)")
+
+ print("\n RSA CSR='\(try! csr2.serializeAsPEM().pemString)'")
+ print("\n RSA private key = '\(try! privateKeyRSA.serializeAsPEM().pemString)'")
}
diff --git a/Tests/AcmeSwiftTests/OrderTests.swift b/Tests/AcmeSwiftTests/OrderTests.swift
index f8eebdf..562aa60 100644
--- a/Tests/AcmeSwiftTests/OrderTests.swift
+++ b/Tests/AcmeSwiftTests/OrderTests.swift
@@ -2,6 +2,9 @@ import XCTest
import AsyncHTTPClient
import NIO
import Logging
+import SwiftASN1
+import X509
+import Crypto
@testable import AcmeSwift
@@ -100,14 +103,11 @@ final class OrderTests: XCTestCase {
try await acme.orders.refresh(&order)
print("\n => order: \(toJson(order))")
- //let csr = try AcmeX509Csr.ecdsa(domains: domains)
- let csr = try AcmeX509Csr.ecdsa(order: order)
-
- let finalized = try await acme.orders.finalize(order: order, withCsr: csr)
+ let (key, _, finalized) = try await acme.orders.finalizeWithEcdsa(order: order, domains: domains)
let certs = try await acme.certificates.download(for: finalized)
try certs.joined(separator: "\n").write(to: URL(fileURLWithPath: "cert.pem"), atomically: true, encoding: .utf8)
- try csr.privateKeyPem.write(to: URL(fileURLWithPath: "key.pem"), atomically: true, encoding: .utf8)
+ try key.serializeAsPEM().pemString.write(to: URL(fileURLWithPath: "key.pem"), atomically: true, encoding: .utf8)
}
catch(let error) {
print("\n•••• BOOM! \(error)")