apple / swift-certificates Goto Github PK
View Code? Open in Web Editor NEWAn implementation of X.509 for Swift
Home Page: https://swiftpackageindex.com/apple/swift-certificates/main/documentation/x509
License: Apache License 2.0
An implementation of X.509 for Swift
Home Page: https://swiftpackageindex.com/apple/swift-certificates/main/documentation/x509
License: Apache License 2.0
Is it planned to support SignedAttributes and UnsignedAttributes in CMSSignerInfo? Our backend requires SignedAttributes to detect SigningTime for validation.
The Certificate
type conforms to Codable
which is quite helpful...but there seems to be something wrong with the encoding logic, test that repros the problem:
let caPrivateKey = P384.Signing.PrivateKey()
let cert = try Certificate(version: .v3,
serialNumber: .init(),
publicKey: .init(caPrivateKey.publicKey),
notValidBefore: Date().addingTimeInterval(-100),
notValidAfter: Date().addingTimeInterval(100000000),
issuer: try DistinguishedName {
StateOrProvinceName("CA")
OrganizationName("Apple Inc.")
CommonName("Apple App Attestation Root CA")
},
subject: try DistinguishedName {
StateOrProvinceName("CA")
OrganizationName("Apple Inc.")
CommonName("Apple App Attestation Root CA")
},
signatureAlgorithm: .ecdsaWithSHA384,
extensions: try Certificate.Extensions {
Critical(BasicConstraints.isCertificateAuthority(maxPathLength: 0))
SubjectKeyIdentifier(keyIdentifier: Data(SHA384.hash(data: caPrivateKey.publicKey.x963Representation)).map { $0 }.prefix(20))
Critical(KeyUsage(digitalSignature: true, keyCertSign: true, cRLSign: true))
},
issuerPrivateKey: .init(caPrivateKey))
let data = try JSONEncoder().encode(cert)
try JSONDecoder().decode(Certificate.self, from: data)
When you try to decode it you run into random errors, it'll either complain about truncation, difficulty with a UInt, or trailing unparsed data (all ASN1 errors). Given that I've used the decodable conformance successfully I believe the real problem is how it encodes.
I've been trying to trace through to figure out what precisely goes wrong, but given that the failure keeps randomly changing and I don't have a ton of ASN.1 experience, I haven't been able to find the root cause.
Is it possible to generate a SecIdentity
with a PEM cert & key? I tried looking through tests and it seems like you can create a PrivateKey from a PEM but not sure if I can get all the way to a SecIdentity
which is what I need for some mTLS logic.
Thanks in advance.
Would it be possible to add a documentation for the following use case:
Reading a DER-Data
object via SecCertificateCopyData(:)
from the keychain and transforming it into a Certificate
instance to have access to the date values of the X501? I checked the ASN1 documentation but I was not able to find an answer.
Thanks!
I know the title is a mouthful, but that's the simplest one I can come up with that properly describes the issue. Technically this is a regression from Xcode 14.3.1 and therefore I've created a feedback FB13209670 for this. But as it only seems to affect swift-certificates
, I'm opening an issue here as well. Feel free to close this if you think the feedback alone is sufficient.
The error message is the same as in #78:
clang: error: no such file or directory: '/Users/…/Library/Developer/Xcode/DerivedData/Xcode15LinkerProblem-ewdhpfkuiwqkvjewbspactaqojht/Build/Products/Debug-iphonesimulator/PackageFrameworks/Crypto_17A3B1FFC41E47_PackageProduct.framework/Crypto_17A3B1FFC41E47_PackageProduct'
How to reproduce the issue:
swift-certificates
and one the doesn't, but depends on the one that does.The issue can be resolved in a number of ways, at least by:
For our project all of these options have downsides we're not happy with. We've disabled the tests that cause this for now, but it's not a good long term solution.
I've included a sample project in the aforementioned feedback that reproduces this issue.
To build a distributable binary library (aka XCFramework), you should build your library with `BUILD_LIBRARY_FOR_DISTRIBUTION: https://developer.apple.com/documentation/xcode/build-settings-reference#Build-Libraries-for-Distribution
Currently swift-certificate
does not fit to this requirement. To verify it:
xcodebuild build -scheme swift-certificates -destination "generic/platform=macOS" BUILD_LIBRARY_FOR_DISTRIBUTION=YES
Clearly the main issue is the overuse of @inlinable
- removing this compiler hint in many places fix the build.
The big picture is not to only build a binary library from swift-certificates
alone but building my own third-party binary library that depends on swift-certificate
.
But it looks like building my own library with BUILD_LIBRARY_FOR_DISTRIBUTION=YES
requires all its dependencies to be able to build with BUILD_LIBRARY_FOR_DISTRIBUTION=YES
.
An alternative seems to be the non documented option @_implementationOnly
that might keep the benefit from @inlinable
in swift-certificate
but it does not seem to work.
To demonstrate @_implementationOnly
is not working as I would expect is to replace all import SwiftASN1
with @_implementationOnly import SwiftASN1
in swift-certificates
. The build phase also complains about the @inlinable
use in SwiftASN1.
This issue also affects:
xcodebuild build -scheme swift-crypto-Package -destination "generic/platform=macOS" BUILD_LIBRARY_FOR_DISTRIBUTION=YES
xcodebuild build -scheme swift-asn1 -destination "generic/platform=macOS" BUILD_LIBRARY_FOR_DISTRIBUTION=YES
I am using swift-certificate in MacOS project, there is a problem with me .
the detail is
"
clang: error: no such file or directory: '/Users/xx/Library/Developer/Xcode/DerivedData/xx/Build/Products/Debug/PackageFrameworks/Crypto_17A3B1FFC41E47_PackageProduct.framework/Crypto_17A3B1FFC41E47_PackageProduct'
Command Ld failed with a nonzero exit code
"
Hi,
I am using this dependency in my project
but when i want to create cms using CMS.sign() throw Leading or trailing line missing PEM discriminator.
please help me
let data: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
let signatureBytes = try CMS.sign(
data ,
signatureAlgorithm: .ecdsaWithSHA256,
certificate: Certificate.init(pemEncoded: self.globalCertificate),
privateKey: Certificate.PrivateKey(pemEncoded: privateKey.debugDescription)
)
certificate value is
-----BEGIN CERTIFICATE-----
MIIF4DCCBMigAwIBAgIIOrB4pCYzhncwDQYJKoZIhvcNAQELBQAwgakxCzAJBgNV
BAYTAklSMQ8wDQYDVQQIEwZUZWhyYW4xGTAXBgNVBAoTEE5vbi1Hb3Zlcm5tZW50
YWwxEDAOBgNVBAsTB1RlY3Zlc3QxJDAiBgNVBAsTG1NtYXJ0IFRydXN0IEludGVy
bWVkaWF0ZSBDQTE2MDQGA1UEAxMtU21hcnQgdHJ1c3QgcHJpdmF0ZSBpbnRlcm1l
ZGlhdGUgYnJvbnplIENBLUczMB4XDTIzMTAxMjA4NTA0NloXDTI0MTAxMjA4NTA0
NlowdzELMAkGA1UEBhMCSVIxFTATBgNVBAoMDFVuYWZmaWxpYXRlZDERMA8GA1UE
BAwI2KfYrdiv24wxDzANBgNVBCoMBti52YTbjDETMBEGA1UEBRMKMTUyMDI3MDEx
OTEYMBYGA1UEAwwPYWxpIG51bGwgW3NpZ25dMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAp2BLSuEGr47tcrpqpmnarb8/T761IAki++ociXKkovkA4YgB
ozroBJcGxYW79f3vr9UtAATx2DNC8/aV7e38bKomvsGKP5g8yjihiUdh+HNKJo+X
yqe8MOKOMuu+/wiUTDL8XcBFxWnrebDK/RN9cdgXvTl2Sj9wHBqUTdYXCozBSX7j
iWYxyqDLtUjKRq3xIgTNMy5MkBtvB10FV6gnJSFqjeQn2YRZ6cQWrYiGzJOqE6ZB
LxpHoZS921cRfcOzXY7Fk2eUHJ8sVbEXH5US2f91c4yElp8FxIUXJqOBeIHRZXTs
VMgxTh2JndBbZUQPt4Cj3c9Md4VdGNo6dBWVEQIDAQABo4ICOzCCAjcwHwYDVR0j
BBgwFoAUQ8HfQun5vFzQAmXv4e7mj3rPwnswWAYIKwYBBQUHAQEETDBKMEgGCCsG
AQUFBzABhjxodHRwOi8vb2NzcDEuc21hcnR0cnVzdGNvLmlyL2VqYmNhL3JldHJp
ZXZlL2NoZWNrX3N0YXR1cy5qc3AwYwYDVR0gBFwwWjBYBgdggmxlAQEBME0wSwYI
KwYBBQUHAgEWP2h0dHBzOi8vY2Euc21hcnR0cnVzdGNvLmlyL2luZGV4LnBocD9y
ZXNvdXJjZT1wZGYtZGwmcGRmPTAyLnBkZjATBgNVHSUEDDAKBggrBgEFBQcDAjCC
AQ8GA1UdHwSCAQYwggECMIH/oEugSYZHaHR0cHM6Ly9jYS5zbWFydHRydXN0Y28u
aXIvZGwvY3J0L1NtYXJ0dHJ1c3Rwcml2YXRlSW50ZXJtZWRpYXRlQ1JMMS5jcmyi
ga+kgawwgakxNjA0BgNVBAMMLVNtYXJ0IHRydXN0IHByaXZhdGUgaW50ZXJtZWRp
YXRlIHNpbHZlciBDQS1HMzEkMCIGA1UECwwbU21hcnQgVHJ1c3QgSW50ZXJtZWRp
YXRlIENBMRAwDgYDVQQLDAdUZWN2ZXN0MRkwFwYDVQQKDBBOb24tR292ZXJubWVu
dGFsMQ8wDQYDVQQIDAZUZWhyYW4xCzAJBgNVBAYTAklSMB0GA1UdDgQWBBQr8T/7
o/6tUB3Xk88KGvRc+seZJjAOBgNVHQ8BAf8EBAMCBsAwDQYJKoZIhvcNAQELBQAD
ggEBAKe3l+nQ2PuJRuSkiO2d8YxPV0+eAMKvI5fUYwNTrReeIo/kWLtV2p76yAli
l/zOrfeO9PokVXZlbWRxXljVvOkI7oRazzdgcks3vAfU4FFgHdPXGE3LiLNFfd68
SL9l5JdSUxfhR5kDem3A8Agz5OCafbVnE7nS6rkAXy3hcx19W3bPrraKtAkFKPGb
QPwLJfmGF6bNqTgBk7/SIRCsPmuyr7NIGGttQkOBuWcdsapIedQRzhISS1jX7ipO
Tc7v828JeZOT6rlvB/heTXmuwvjxNNmX2e0FPSHHFejqsPN1rsYLYlgJwD6jzv9Z
Jac355Gk2fAfvyfNsS3Q3JUJX5c=
-----END CERTIFICATE-----
Commit hash: d93756b
I'm trying to create a Certificate
that is signed by a (pre-existing, imported) CA certificate.
To make a valid chain, I'm specifying an Authority Key Identifier for the new Certificate
by passing the CA certificate's issuer as a DistinguishedName
into a GeneralName.directoryName
.
The resulting certificate is malformed, which is clearly visible when analyzing it with the following command:
$ openssl x509 -in /path/to/generated/cert.pem -text -noout
Actual output (varies with each generation!):
X509v3 extensions:
X509v3 Authority Key Identifier:
0...../CA......|ob...@...%.....
Expected output:
X509v3 extensions:
X509v3 Authority Key Identifier:
DirName:/C=Some Country/O=Some Org/CN=CA
I suspect the problem could originate in swift-asn1 (maybe here?).
Minimal reproducible example:
import Foundation
import X509
import Crypto
let leafPrivateKey = P256.Signing.PrivateKey()
let now = Date()
let issuer = try DistinguishedName {
CommonName("CA")
OrganizationName("Some Org")
CountryName("Some Country")
}
let leafCertificate = try Certificate(
version: .v3,
serialNumber: Certificate.SerialNumber(),
publicKey: Certificate.PublicKey(leafPrivateKey.publicKey),
notValidBefore: now.addingTimeInterval(-60 * 60 * 24),
notValidAfter: now.addingTimeInterval(60 * 60 * 24 * 395),
issuer: .init(),
subject: .init(),
signatureAlgorithm: .ecdsaWithSHA512,
extensions: try Certificate.Extensions {
AuthorityKeyIdentifier(authorityCertIssuer: [.directoryName(issuer)], authorityCertSerialNumber: Certificate.SerialNumber())
},
issuerPrivateKey: Certificate.PrivateKey(leafPrivateKey)
)
if let certFilePemData = try leafCertificate.serializeAsPEM().pemString.data(using: .ascii) {
let temporaryCertFileURL = URL(string: "/path/to/generated/cert.pem")!
try certFilePemData.write(to: temporaryCertFileURL)
}
Technical details:
$ swift --version
swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
Target: arm64-apple-macosx14.0
Operating system: macOS 14.5
$ uname -a
Darwin Kernel Version 23.5.0: Wed May 1 20:12:58 PDT 2024; root:xnu-10063.121.3~5/RELEASE_ARM64_T6000 arm64
swift-unidoc found an ambiguous codelink in OCSPPolicy.swift:71
. there are two possible link targets.
/swift-certificates/checkouts/swift-certificates/Sources/X509/OCSP/OCSPPolicy.swift:72:161: warning: codelink 'PolicyEvaluationResult.failsToMeetPolicy(reason:)' is ambiguous
The OCSP query is considered unsuccessful and will fail verification in both ``OCSPFailureMode/soft`` and ``OCSPFailureMode/hard`` failure mode.
The certificate is then considered to not meet the ``OCSPVerifierPolicy`` and ``OCSPVerifierPolicy/chainMeetsPolicyRequirements(chain:)`` will return ``PolicyEvaluationResult/failsToMeetPolicy(reason:)`` with the given ``reason``.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
- Parameter reason: the reason why the OCSP query failed
(unknown) note: did you mean 'PolicyEvaluationResult.failsToMeetPolicy(reason:) [3E21]'? (static X509.PolicyEvaluationResult.failsToMeetPolicy(reason: @autoclosure @Sendable () -> Swift.String) -> X509.PolicyEvaluationResult)
(unknown) note: did you mean 'PolicyEvaluationResult.failsToMeetPolicy(reason:) [3TP9A]'? (static X509.PolicyEvaluationResult.failsToMeetPolicy(reason: X509.PolicyFailureReason) -> X509.PolicyEvaluationResult)
In short I would like to be able to use the following code:
let key = try Certificate.PrivateKey(SecureEnclave.P256.Signing.PrivateKey())
or some variation thereof.
I'm trying to use this with vapor to build a micro service capable of handling app attestation. Part of that is:
Create the SHA256 hash of the public key in credCert, and verify that it matches the key identifier from your app.
Problem is the public key exposes no way to do this. It'd be very helpful if Certificate.PublicKey
would conform to DataProtocol
, or expose bytes, or something along those lines.
RFC 5280 states that while uppercase and lowercase letters are allowed in domain names, no significance is attached to the case, meaning the case should be ignored when comparing domain names.
Most certificates don't have any uppercase letter in their domain name. But some do.
swift-certificates converts the server hostname to lowercase but doesn't convert the certificate's CN or SAN. Therefore, the domain name comparison always fails when the certificate has uppercase letters in its domain name.
This issue is similar to apple/swift-nio-ssl#463.
Hi, thanks for making handling certificates easy in Swift with this package!
I am just wondering if it is reasonable to extend the capability of CMS to enable the encryption and decryption capabilities to achieve the similar functionalities to their counterparts in OpenSSL:
CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
const EVP_CIPHER *cipher, unsigned int flags);
int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert,
BIO *dcont, BIO *out, unsigned int flags);
Thanks again.
Hi all,
I would like to create a SSL certificate and sign it by self signed Certificate Authority.
With OpenSSL I would use the following statement:
openssl x509 -req \
-in server.csr \
-CA rootCA.crt -CAkey rootCA.key \
-CAcreateserial -out server.crt \
-days 365 \
-sha256 -extfile cert.conf
Unfortunately, the Certificate struct does not provide parameters to pass the ROOT CA.
I would be very happy if someone could help.
Thanks
How i can enter Certificate, Private Key to URLCredential?
This issue is purely meant as an information, no bug report.
In my attempt to contribute to this repository, I ran all tests CertificateTests.swift
with "On My Mac" (14.4.1 (23E224)) selected.
Xcode (Version 15.3 (15E204a)) told me, that the test testCertificateDescription
failed.
If I select an iPad simulator as target, it finishes successful. That's why I think, I execute the tests in an incorrect manner.
Assertion message
XCTAssertEqual failed: ("Certificate(version: X509v3, serialNumber: 1:2:3:4:5:6:7:8:9:a, issuer: "CN=Swift Certificate Test CA 1,O=Apple,C=US", subject: "CN=Swift Certificate Test CA 1,O=Apple,C=US", notValidBefore: 2022-08-08 2:26:14 PM +0000, notValidAfter: 2033-08-05 2:26:14 PM +0000, publicKey: P384.PublicKey, signature: ECDSA, extensions: [BasicConstraints(CA=TRUE), KeyUsage(keyCertSign), SubjectKeyIdentifier(4e:51:c6:12:55:3d:95:ba:c3:88:c9:11:6:6f:6e:6c:ff:54:a6:1c)])") is not equal to ("Certificate(version: X509v3, serialNumber: 1:2:3:4:5:6:7:8:9:a, issuer: "CN=Swift Certificate Test CA 1,O=Apple,C=US", subject: "CN=Swift Certificate Test CA 1,O=Apple,C=US", notValidBefore: 2022-08-08 14:26:14 +0000, notValidAfter: 2033-08-05 14:26:14 +0000, publicKey: P384.PublicKey, signature: ECDSA, extensions: [BasicConstraints(CA=TRUE), KeyUsage(keyCertSign), SubjectKeyIdentifier(4e:51:c6:12:55:3d:95:ba:c3:88:c9:11:6:6f:6e:6c:ff:54:a6:1c)])")
Thinking of X.509, certificates and keys and ways to transport these at once, one must have ran into the PKCS#12 standard. It's an archive file format used for storing all kinds of cryptography objects. It's often used to, but not limited to:
A quick search reveals that there are some existing server side/native implementations that already have some form of PKCS#12 occurrence already (swift-nio-ssl, Uniform Type Idnetifiers, ...) and I feel like this certificate library is a good fit to have some form of PKCS#12 support too, which may be limited to combining a private key and a related certificate into a container, or combining the certificate chain into a container.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.