Coder Social home page Coder Social logo

apple / swift-certificates Goto Github PK

View Code? Open in Web Editor NEW
205.0 105.0 40.0 1.01 MB

An implementation of X.509 for Swift

Home Page: https://swiftpackageindex.com/apple/swift-certificates/main/documentation/x509

License: Apache License 2.0

Swift 97.38% Dockerfile 0.08% Shell 1.36% CMake 1.18%
certificates swift x509

swift-certificates's Issues

Encodable/Decodable issues

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.

SecIdentity from PEM(s)

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.

Linking fails in Xcode 15 when swift-certificates is used in a package that is linked to an application test target

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:

  • Create a Swift package that contains two libraries, one that uses swift-certificates and one the doesn't, but depends on the one that does.
  • Create an application and link the first package to it.
  • Add test target to the application and link the second package to it. Make sure the Host Application API testing is allowed.
  • Run tests

The issue can be resolved in a number of ways, at least by:

  • Disable Host Application API testing.
  • Don't include the package library in the application target.
  • Remove the dependency between package libraries.

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.

swift-certificate does not provide stable ABI

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:

swift-crypto didn't compile result in linker problem

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
"

Throw Leading or trailing line missing PEM discriminator

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-----

Using `GeneralName.directoryName` results in a corrupt 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

ambiguous codelink in OCSPPolicy.swift:71

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)

Get data from public key

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.

Case-insensitive identity verification

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.

API Request: Encryption & Decryption for CMS

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.

Generate SSL certificate that is signed by self signed Certificate Authority

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

Information: Test `testCertificateDescription` fails on Mac platform

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)])")

New API Proposal: PKCS#12 Support

New API Proposal: PKCS#12 Support

Motivation:

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:

  • Combining the private key and X.509 certificate as a container for a digital identity
  • Transporting certificate chains
  • ...

Importance:

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.