I'm developing an ACME server to issue identity certificates to macOS/iOS devices for MDM attestation, following RFC 8555. Per RFC, the client creates an order, performs authorization, verifies the challenge, and finalizes the order by submitting a CSR to the CA.
In my setup, the CA sometimes takes longer to issue the certificate (around 50 seconds). According to RFC 8555, if certificate issuance isn’t complete after the /finalize call, the server should respond with an "order" object with a "processing" status. The client should then send a POST-as-GET request to the order resource (e.g., /order/<order_id>) to check the current state. If the CA still hasn’t issued the certificate, the server should return the order object with the same "processing" status and include a "Retry-After" header, indicating when the client should retry. The client is expected to poll the order resource at this specified interval with POST-as-GET requests.
However, it seems the Apple ACME client ignores the "Retry-After" header and instead returns the error: "Profile failed - Order status is processing, not yet valid" immediately upon the first poll response with "processing." Apple ACME client deviating from the RFC documentation.
Has anyone found a reliable solution to this issue? Or does Apple supports asynchronous order finalization?
Ref -https://datatracker.ietf.org/doc/html/rfc8555#:~:text=A%20request%20to%20finalize%20an%20order%20will%20result%20in%20error,to%20the%20%22certificate%22%20field%20of%20the%20order.%20%20Download%20the%0A%20%20%20%20%20%20certificate.
To work around this, I’m holding the /finalize call until the CA issues the certificate. This works when issuance is quick (under 20 seconds), but if it takes more than that , the client times out. Interestingly, the Apple ACME client’s timeout appears shorter than the usual 60-second URLSession default.
WWDC22
RSS for tagDiscuss the latest Apple technologies announced at WWDC22.
Posts under WWDC22 tag
7 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Current Apple ACME Profile does not support EAB. Do you have any plan to support it?
When using the sample code included on the Running macOS in a virtual machine on Apple silicon. I am adding the following changes to the swift files:
Added to 'MacOSVirtualMachineConfigurationHelper' file:
static func createAutomountSingleDirectoryShareDeviceConfiguration() -> VZVirtioFileSystemDeviceConfiguration {
let sharedDirectory = VZSharedDirectory(url: directoryURL, readOnly: false)
let singleDirectoryShare = VZSingleDirectoryShare(directory: sharedDirectory)
// Assign the automount tag to this share. macOS shares automounted directories automatically under /Volumes in the guest.
let sharingConfiguration = VZVirtioFileSystemDeviceConfiguration(tag: VZVirtioFileSystemDeviceConfiguration.macOSGuestAutomountTag)
sharingConfiguration.share = singleDirectoryShare
return sharingConfiguration
}
Added to 'path' file:
let directoryURL = URL(fileURLWithPath: NSHomeDirectory() + "Projects")
Added to the 'AppDelegate' file:
virtualMachineConfiguration.directorySharingDevices = [MacOSVirtualMachineConfigurationHelper.createAutomountSingleDirectoryShareDeviceConfiguration()]
When the above is added and the sample app is run, the following error is shown:
macOSVirtualMachineSampleApp/AppDelegate.swift:95: Fatal error: Virtual machine failed to start with Error Domain=VZErrorDomain Code=2 "A directory sharing device configuration is invalid." UserInfo={NSLocalizedFailure=Invalid virtual machine configuration., NSLocalizedFailureReason=A directory sharing device configuration is invalid., NSUnderlyingError=0x600000c343c0 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
On the host device the directory that is being shared is ~/Projects and it does exist.
What do I need to change to create the shared directory and have it work?
Is there a sample code project for the same configuration that was shown in the demo?
Hi, I'm looking into ACME Managed Deice Attestation and was wondering about one of the values in the payload - AllowAllAppsAccess.
From the documentation: "If true, all apps have access to the private key" but what is the case that you would have this set to true? seems like it opens up the device to potentially malicious software.
Also, if this were set to true, how would an app access this private key when it is stored in the Secure Enclave? is there a specific tag that it is stored with?
I'm trying to implement ACME managed device attestation, I have ACME server code written in C# and I've been able to get all of the steps working except for the very last one - issuing the certificate.
I so far have not been able to get the device to accept the certificate, the device logs show:
Got certificate {length = ......}
ACME request flow failed at step 9: Error Domain=NSOSStatusErrorDomain Code=-67673 "failed to obtain certificate" UserInfo={NSLocalizedDescription=failed to obtain certificate}
The certificate is issued by an internal CA and the correct root certificate is in the device's trusted certs.
I have tried returning the certificate chain as a file response or content response to the device as a "application/pem-certificate-chain" mime type (as outlined as the default in the ACME RFC), returning just the leaf certificate as PEM, returning the leaf certificate as DER with mime type "application/pkix-cert", "application/pkcs7-mime", "application/x-pkcs12" or "application/x-x509-ca-cert", but none of this has worked.
Can anyone point me in the right direction to figure out what the issue is?
Hello,
I am reading up on the documentation and seems to have some discrepancies but wanted to double check.
In Overview for PTChannelManager, it states "Multiple calls to channelManager(delegate:restorationDelegate:completionHandler:) result in the system returning the same shared instance, so store the channel manager in an instance variable." https://developer.apple.com/documentation/pushtotalk/ptchannelmanager
However if we look at the documentation for creation of a channel manager,
in the completionHandler, it states that it will return "A new channel manager instance."
https://developer.apple.com/documentation/pushtotalk/ptchannelmanager/4031737-channelmanager
So is it a shared instance that gets returned or will a new instance be created? Need to know if we will need to implement a multiDelegate Pattern or not for this scenario for example if someone else called this function, would they take over the callbacks or would they get their own instance?
Thank you.
I'm building a UIKit app that reads user's Apple Music library and displays it. In MusicKit there is the Artwork structure which I need to use to display artwork images in the app. Since I'm not using SwiftUI I cannot use the ArtworkImage view that is recommended way of displaying those images but the Artwork structure has a method that returns url for the image which can be used to read the image.
The way I have it setup is really simple:
extension MusicKit.Song {
func imageURL(for cgSize: CGSize) -> URL? {
return artwork?.url(
width: Int(cgSize.width),
height: Int(cgSize.height)
)
}
func localImage(for cgSize: CGSize) -> UIImage? {
guard let url = imageURL(for: cgSize),
url.scheme == "musicKit",
let data = try? Data(contentsOf: url) else {
return nil
}
return .init(data: data)
}
}
Now, everytime I access .artwork property (so a lot of times) the main thread gets blocked and the console output gets bombared with messages like these:
2023-07-26 11:49:47.317195+0200 Plum[998:297199] [Artwork] Failed to create color analysis for artwork: <MPMediaLibraryArtwork: 0x289591590> with error; Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named com.apple.mediaartworkd.xpc was invalidated: failed at lookup with error 159 - Sandbox restriction." UserInfo={NSDebugDescription=The connection to service named com.apple.mediaartworkd.xpc was invalidated: failed at lookup with error 159 - Sandbox restriction.}
2023-07-26 11:49:47.317262+0200 Plum[998:297199] [Artwork] Failed to create color analysis for artwork: file:///var/mobile/Media/iTunes_Control/iTunes/Artwork/Originals/4b/48d7b8d349d2de858413ae4561b6ba1b294dc7
2023-07-26 11:49:47.323099+0200 Plum[998:297013] [Plum] IIOImageWriteSession:121: cannot create: '/var/mobile/Media/iTunes_Control/iTunes/Artwork/Caches/320x320/4b/48d7b8d349d2de858413ae4561b6ba1b294dc7.sb-f9c7943d-6ciLNp'error = 1 (Operation not permitted)
My guess is that the most performance-heavy task here is performing the color analysis for each artwork but IMO the property backgroundColor should not be a stored property if that's the case. I am not planning to use it anywhere and if so it should be a computed async property so it doesn't block the caller.
I know I can move the call to a background thread and that fixes the issue of blocking main thread but still the loading times for each artwork are terribly slow and that impacts the UX.
SwiftUI's ArtworkImage loads the artworks much quicker and without the errors so there must be a better way to do it.