I'm trying to implement client certificate authentication in the URLSessionDelegate.urlSession(:didReceive:completionHandler:) by using the URLCredential(identity:certificates:persistence:) and CryptoKit, but it appears this is currently not supported. On my client I generate a key and a CSR and after I sent that to the server, I receive an X.509 certificate which I store in the Keychain.
I used to create the keys as SecKey objects, which were also stored in the Keychain; this works fine. Now I would like to use the CryptoKit keys, preferably the SecureEnclave.P256 ones. It appears that storing these keys, as suggested by Apple (generic passwords), does not create the SecIdentity I'm after that's needed to create the URLCredential, nor have I been able to transform a SecKey created in the Secure Enclave to a CryptoKit.SecureEnclave.P256 key. The SecKeyCopyExternalRepresentation function simply returns an error telling me that I cannot export Secure Enclave keys (which is weird, as CryptoKit's implementation does somewhat allow this).
Also, the URLCredential.init does not allow you to add a private key directly, nor does the SecIdentity provide any way of manually creating it, by supplying the right keys and the right certificates.
How can I use CryptoKit for client certificate authentication or how can I use CryptoKit or the older SecKey implementations to create SecIdentity or URLCredential objects that will work?
Post
Replies
Boosts
Views
Activity
I would like to distribute whitelabel business to business apps to customers of my organisation. We used to be able to do this via the enterprise program of Apple, but they decided that we are no longer eligible for the enterprise program.
We now have multiple existing B2B and MDM customers that are about to lose support from us. What can we do to support these customers and their apps and what are places where we can distribute these apps?
I've written a simple shape container that can be styled using an environment value.
struct CoolShape: Shape {
@Environment(\.coolShapeStyle) var coolShapeStyle
func path(in rect: CGRect) -> Path {
coolShapeStyle.path.path(in: rect)
}
}
I then added some sample styles to style the shape and also created some utility functions to make it easy to add the style.
protocol CoolShapeStyle {
var path: Path { get }
}
struct CoolCircleStyle: CoolShapeStyle {
let path = Path(ellipseIn: CGRect(
x: 0, y: 0,
width: 100, height: 100
))
}
struct CoolSquareStyle: CoolShapeStyle {
let path = Path(CGRect(
x: 0, y: 0,
width: 100, height: 100
))
}
extension CoolShapeStyle where Self == CoolCircleStyle {
static var circle: Self { Self() }
}
extension CoolShapeStyle where Self == CoolSquareStyle {
static var square: Self { Self() }
}
struct CoolShapeStyleEnvironmentKey: EnvironmentKey {
static let defaultValue: CoolShapeStyle = CoolCircleStyle()
}
extension EnvironmentValues {
var coolShapeStyle: CoolShapeStyle {
get { self[CoolShapeStyleEnvironmentKey.self] }
set { self[CoolShapeStyleEnvironmentKey.self] = newValue }
}
}
extension View {
func coolShapeStyle(_ coolShapeStyle: CoolShapeStyle) -> some View {
environment(\.coolShapeStyle, coolShapeStyle)
}
}
I then proceed to create the view as one would do normally, which works fine, all until I also add a fill or stroke to the shape.
// This works fine
CoolShape()
.coolShapeStyle(.circle)
// This creates a warning
CoolShape()
.fill(Color.red)
.coolShapeStyle(.square)
I'll then get the environment value error:
Accessing Environment's value outside of being installed on a View. This will always read the default value and will not update.
This is very odd, as a Shape and also the InsettableShape conform to View, yet the path(in:) function appears to be run at a different time. Is there any way I can fix this?
I have created a custom keyboard using SwiftUI. This is in the app itself, not a keyboard extension, as I don't want it to be part of the system. I would like the buttons of this keyboard to have the audio feedback as with the system keyboard. The way to achieve this would be to implement the UIInputViewAudioFeedback into your view and set the enableInputClicksWhenVisible to true. This allows UIDevice.current.playInputClick() to play the 'click' sound.
However, the UIInputViewAudioFeedback inherits from NSObjectProtocol, which means I cannot add this protocol to a ButtonStyle or any other SwiftUI.View. How would I go about adding the system click sounds to this button?
struct KeyboardButtonStyle: SwiftUI.ButtonStyle {
public func makeBody(configuration: Configuration) -> some View {
configuration.label
.padding()
.font(.title)
.accessibilityAddTraits(.isKeyboardKey)
.onTapGesture {
UIDevice.current.playInputClick()
}
}
}
and then in the body of my keyboard view (example code)
var body: some View {
Button(action: {
// Keyboard button action
}, label: {
Text("Click")
}.buttonStyle(KeyboardButtonStyle())
}
Whilst implementing several HTTP calls, I noticed some strange behaviour on the URLSession. As far as I know, URLSession data tasks used to immediately throw an error when the network connection was unavailable (error -1009 The Internet connection appears to be offline).
I'm now performing network requests too, and while executing a request in flight mode, the request runs for as long as the timeout, before failing. I tried creating a custom configuration that should prevent this, but this does not work. How can I re-enable or configure the behaviour where a request will immediately crash when there is no connection?
The configuration documentation appears to be inconsistent or incorrect.
let url = URL(string: "https://www.google.com/")!
let config = URLSessionConfiguration.default
config.waitsForConnectivity = false
config.timeoutIntervalForRequest = 2
config.timeoutIntervalForResource = 0
URLSession(configuration: config).dataTask(with: url) { d, r, e in
print(d?.count, (r as? HTTPURLResponse)?.statusCode, e?.localizedDescription)
}.resume()
I was wondering if there is a way to determine the curve of an ECC key when/after stored in the KeyChain.
swift
let ed25519 = Curve25519.Signing.PrivateKey().rawRepresentation
let p256 = P256.Signing.PrivateKey().rawRepresentation
As these keys have the same size (256 bits), it's very confusing. I would be able to differentiate between P256, P384 and P521 using the key size, but is there a way to tell the difference between the Curve25519 and P256 variant, or maybe an attribute providing the used curve when stored in the Keychain?
I'm creating a framework for iOS that needs to store files and keys (mostly symmetric keys). I was wondering if I can prevent the parent app from accessing:
Keys/SecItems I create in Keychain
Files I create/store on the device
I have recently used URLSession.shared.dataTask(with:completionHandler:), and it got me wondering:Why are status codes like 400/500 not presented in the Error? object of the completionHandler?Is there a list of errors that have the possibility of ending up in the Error? object of the completionHandler? The 'An error object indicating why the request failed' is quite broad and I am interested in a list of what actually ends up in there.Thanks!Craz1k0ek
During the creation of several key items, I noticed that there are several 'label' or 'tag' options. I did some investigation and I found three different, interesting, values.kSecAttrApplicationTag - A key whose value indicates the item's private tag.kSecAttrApplicationLabel - A key whose value indicates the item's application label.kSecAttrLabel - A key whose value is a string indicating the item's label.I read that the kSecAttrLabel is "human readable data". But what exactly is meant with the description of the kSecAttrApplicationTag? What exactly is the private tag.Another question I have is, how can I uniquely identify a key. Say I want to have a single key to encrypt a specific file, how would I go about doing so? Theoretically, I could set the kSecAttrApplicationLabel, as this has to be a unique value, meaing if I were to set the value to "com.app.appname.someidentifier".data(using: .utf8)! an error would occur if the key would (accidentally) be created again (which is what I want to prevent). However the discussion says "in particular, for keys of class kSecAttrKeyClassPublic and kSecAttrKeyClassPrivate, the value of this attribute is the hash of the public key", and RSA keys do have the public/private class, so the value would no longer be the hash of the public key. Am I actually allowed to overwrite the kSecAttrApplicationLabel? If not, do I have to check if a key for kSecAttrApplicationTag/kSecAttrLabel already exists and delete it first, before adding a new 'unique' key?Thanks in advance!