Security

RSS for tag

Secure the data your app manages and control access to your app using the Security framework.

Security Documentation

Pinned Posts

Posts under Security tag

302 Posts
Sort by:
Post not yet marked as solved
4 Replies
219 Views
I was trying to figure out how to monitor keychain events, and wrote:         dispatch_async(dispatch_get_main_queue(), ^{             OSStatus kr = SecKeychainAddCallback(MyKeychainEventCallback, kSecEveryEventMask, NULL);             printf("Got result %d\n", kr);         });         dispatch_main(); However, the callback never gets called. I put the same code into a simple GUI app (invoked from the didFinishLaunching method), and it does work. So presumably this is something run-loop related. But I can't seem to figure it out -- so what am I doing wrong?
Posted
by
Post marked as solved
3 Replies
296 Views
Apple team I tried to implement the ssl pinning in iOS through info.plist using Pinned Domains Identity Pinning as found in the official apple blog: How to configure server certificates for your app https://developer.apple.com/news/?id=g9ejcf8y news. As of now i have done the following changes something similar in info.plist : And in code i have used simple URLSession as shown: "https://wang.greenhub.example.org/sites/......./logo.png") else { return } // URL session that doesn't cache. let urlSession = URLSession(configuration: URLSessionConfiguration.ephemeral) let task = urlSession.dataTask(with: imageUrl) { imageData, response, error in DispatchQueue.main.async { // Handle client errors if let error = error { self.HandleClientConnectionError(error: error) return } // Handle server errors guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else { self.HandleServerError(response: response!) return } self.AddImageToView(imageData: imageData!) } } task.resume() FYI we have api with multiple subdomains and thus according to the NSIncludesSubdomains documentation here says: it doesn’t apply to the subdomains advanced.math.example.com or ancient.history.example.com because those subdomains have two additional path components. Also it prohibits the use of wild cards so even if i tried to use *.example.org overall the SSL pinning does not seems to work in case of multiple subdomains scenario like mine even if i replace the SHA256-BASE64 pin with wrong ones. Can anyone from apple suggest a solution for this or tell how can we use NSIncludesSubdomains find a solution for pinning against multiple subdomains
Posted
by
Post not yet marked as solved
0 Replies
172 Views
I need to create a script for checking a security posture of a machine using OPSWAT MetaAccess. They have a built-in check, however, according to them, they aren't able to check since macOS 10.13+. This seems to coordinate with a change other people have discussed on other forums where the following commands don't work anymore. OPSWAT does support checks via custom shell script and so I'm figuring out how to write that now. The scripts that don't work anymore: defaults read com.apple.screensaver idleTime defaults -currentHost read com.apple.screensaver idleTime defaults -currentHost read com.apple.screensaver askForPassword defaults read com.apple.screensaver askForPassword
Posted
by
Post not yet marked as solved
2 Replies
215 Views
I can use /usr/bin/security to install a root CA, and to delete it (based on the file)... but how do I check to see if it's installed already? Surely there is a way to do this, other than security find-certificate -a | fgrep my.ca.name? Ideally from the shell level, but if I have to write a program I can (in which case I believe it'd be a relatively easy, albeit annoying because I hate writing certificate code, task)...
Posted
by
Post not yet marked as solved
1 Replies
216 Views
Hi, I have an endpoint security app and I was wondering what is the best way to check if a process was signed by a specific Developer ID certificate. Lets say im subscribed to auth_exec events and wanted to deny execution of processes signed with Developer ID Application: Adobe Inc. Would obtaining the common names of the certificate with SecCertificateCopyCommonName and then comparing strings be the right way or am I missing something?
Posted
by
Post not yet marked as solved
5 Replies
422 Views
I have a certificate + private key in the Apple Keychain on a macOS 12 machine. The access control for the private key has been modified to add my program binary to the "Always allow access by these applications:" list. My program uses this certificate to do mTLS authentication using OpenSSL. Also inside the program I disable the Keychain UI temporarily while accessing items stored in there to disable any prompts. All this was working fine. I could even update this binary from a .pkg file installer to the same path and the access would still be inherited. But that is no longer the case. If I upgrade the binary now at the same path, the Keychain does not allow the program to access that private key. I have to go into the Keychain access application and manually remove the earlier entry and re-add the binary at the same path again into the list. Not sure if this is a macOS issue or by binary has changed somehow. There have been no major code base changes to the program. If this is something by design, is there a command line to add certain binaries to the Access List for the private key? So that I can automate this process somehow and not have to re-add the binary at the same path again every time.
Posted
by
Post not yet marked as solved
2 Replies
174 Views
It's that able to limit my sharing framework only been used by specific applications or not. I would like to know if there's any way to protect the framework's security.
Posted
by
Post marked as solved
6 Replies
463 Views
I'm working on a macOS app that I'd like to sandbox along with a login item that I'd also like to sandbox. Login items implicitly have an XPC Mach service created for them which my app is able to successfully use communicate with the sandboxed login item (because they're in the same application group). The issue is that any non-sandboxed process can also connect to my login item's XPC Mach service, and I'd really rather that wasn't the case. I realize there's no privilege escalation going on, but this feels unnecessarily insecure. My attempts to secure the connection keep failing due to sandboxing. Is there a way to do what I'm attempting or is Apple's intention that any non-sandboxed process on the system ought to be able to successfully communicate with my login item? If I don't sandbox my login item it's trivial for me to secure this connection. Here's what I've tried so far: Path based Retrieve the SecCode using SecCodeCreateWithXPCMessage Retrieve the SecStaticCode using SecCodeCopyStaticCode Retrieve the path of the static code using SecCodeCopyPath Compare this path with my login item's path based on Bundle.main.bundleURL This fails on step 2, the SecCodeCopyStaticCode function gets back a "UNIX error exception: 1". This kind of makes sense to me as it needs to read from the file system in order to get the static code of the running process. Code requirements based Retrieve the SecCode using SecCodeCreateWithXPCMessage Construct a SecRequirement including amongst other things that certificate leaf[subject.OU] = <my team id> Use SecCodeCheckValidity on the code instance from step #1 and the requirement from step #2 This fails on step 3, SecCodeCheckValidity also results in a "UNIX error exception: 1". Looking at the logs generated by sandboxd it looks like under the hood that function calls _CFBundleGetBundleVersionForURL and fails. The violation is: deny(1) file-read-data ~/Library/Developer/Xcode/DerivedData/LoginItemSample-ajfwjiwmyuphdbeyugmssxszdlyq/Build/Products/Debug/LoginItemSample.app Is there perhaps some combination of SecCSFlags values I can pass to prevent any file system access?
Posted
by
Post not yet marked as solved
3 Replies
433 Views
Hello, I'm working with Cryptokit and I'm currently unable to export a P256 ECDSA signature data to base64Encoding and convert it back to derRepresentation. Here is my code: let privateKey = P256.Signing.PrivateKey() //Generated successfully /* For example pemRepresentation: -----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgK+lUhkqFo637XuvJ Q6YiqZx04c33UUyWnLnpwfTwrtChRANCAARy55pVFhjgq3jKnQTx7s1XDIaNm20m 29ZEiBJnvzYfQGUQ+4ldzJYm34z8W2X/waqTqXsY4/oSO1sDFSQ6XwrG -----END PRIVATE KEY----- */ let publicKey = privateKey.publicKey //Picked up successfully /* For example pemRepresentation: -----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEcueaVRYY4Kt4yp0E8e7NVwyGjZtt JtvWRIgSZ782H0BlEPuJXcyWJt+M/Ftl/8Gqk6l7GOP6EjtbAxUkOl8Kxg== -----END PUBLIC KEY----- */ //Basic message to test, "something" here let messageDigest = "something".data(using: .utf8)!                  let signature = try privateKey.signature(for: messageDigest) //Successfully generated                  //Now from the PublicKey, let's check the signature for the message let isValidSignature = publicKey.isValidSignature(signature, for: messageDigest) //Successfully Return true //So far everything works fine //Now lets try to export the derRepresentation of the signature we just created to a base64EncodedString and try to use it later let signDataDerRepresentation = signature.derRepresentation //Here the signDataDerRepresentation is 70 bytes length //Here we get the signature derRepresentation to base64EncodedString, perfect to export let signDataDerRepresentationBase64String = signature.derRepresentation.base64EncodedString() /* "MEQCIGVC/zOGKEauy9AetVViTZiMTtFIeNtW9xALMTu6aIjSAiB+QPz9nGwzy51k3p3osu9OY6oQXkuLHTPoSWxPorg8GA==" */ //Here the signDataDerRepresentationBase64String is 96 bytes length //Now when I try to create a signature from a derRepresentation it works fine when I use the original derRepresentation data: let signature1 = try! P256.Signing.ECDSASignature(derRepresentation: signDataDerRepresentation) //signature1 is created //But when I try to create exactly the same signature from the base64EncodedString, an exception is throw //Convert base64String to Data let signDataDerRepresentationBase64StringData = signDataDerRepresentationBase64String.data(using: .utf8)! do { //Try to create a signature from the base64EncodedData of de the derRepresentation let signature2 = try P256.Signing.ECDSASignature(derRepresentation: signDataDerRepresentationBase64StringData) //Here it fails, signature2 is not created }catch{ //It fails with error: invalidASN1Object print("Signature failed \(error)") /* Signature failed invalidASN1Object */ } So now, I would like to know how to convert de derRepresentation of the signature I created into a base64EncodedString to the derRepresentation the ECDSASignature(derRepresentation:) func is looking for to create a signature from derRepresentation? I don't understand how I can convert my base64 String into that derRepresentation this func is looking for, I can't find the doc : /// An ECDSA (Elliptic Curve Digital Signature Algorithm) Signature @available(iOS 13.0, macOS 10.15, watchOS 6.0, tvOS 13.0, *) extension P256.Signing {     public struct ECDSASignature : ContiguousBytes {         /// Returns the raw signature.         /// The raw signature format for ECDSA is r || s         public var rawRepresentation: Data         /// Initializes ECDSASignature from the raw representation.         /// The raw signature format for ECDSA is r || s         /// As defined in https://tools.ietf.org/html/rfc4754         public init<D>(rawRepresentation: D) throws where D : DataProtocol         /// Initializes ECDSASignature from the DER representation.         public init<D>(derRepresentation: D) throws where D : DataProtocol         /// Calls the given closure with the contents of underlying storage.         ///         /// - note: Calling `withUnsafeBytes` multiple times does not guarantee that         ///         the same buffer pointer will be passed in every time.         /// - warning: The buffer argument to the body should not be stored or used         ///            outside of the lifetime of the call to the closure.         public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R         /// A DER-encoded representation of the signature         public var derRepresentation: Data { get }     } } Thank you for your help. Hélie
Posted
by
Post not yet marked as solved
1 Replies
139 Views
Are we sure this isn’t due to an active exploit of MacOS? This is exactly what you’d expect.
Posted
by
Post not yet marked as solved
5 Replies
274 Views
I have a signed, notarized app that makes use of a privileged helper. In macOS 11 and 12, as noted in several places in the documentation, there was/is an increasing requirement for the user to grant permission for things over prior macOS releases. This is great, I'm on board. I've found that the privileged helper now needs the broad "Full Disk Access". How do I get the Finder to ask the user permission for this? My helper has the special text sections called "__info_plist" and "__launchd_plist" and I tried putting what I think should go into them in those but I didn't have any luck. Is there another section I need to know about or did I just mess something else up? I'm not using Xcode or Swift or ObjectiveC, everything is C++/C and the command line tools. My helper and Application use XPC to communicate with each other. Thanks! (after my helper fails it does show up in the Full Disk Access list, if you check that pref and try again it all works, I don't want my users to ever have to do that)
Posted
by
Post marked as solved
4 Replies
199 Views
We have an application that requires writing to the system keychain and we used SecKeychainOpen like this var keychain: SecKeychain? let path = "/Library/Keychains/System.keychain" SecKeychainOpen(path, &keychain) then in the query baseQuery[kSecUseKeychain as String] = keychain This approach solved my requirements, as we are able to read and write from the system keychain. From macOS 12+ SecKeychainOpen API is getting deprecated. Is there any way to achieve the same now? kSecUseKeychain is still allowed so, I need. a way to get the reference of system keychain am I wrong? Minimum deployment version: 10.15+ Runs in root context , non sandboxed app Thank you
Posted
by
Post marked as solved
6 Replies
362 Views
My little network extension is running out of file descriptors. My suspicion is that something in the Security framework is not being deallocated, although even this doesn't make a great deal of sense: The extension looks at each flow, and gets a SecStaticCodeRef for it, finds the pathname, makes a decision, and stores the result of that decision in an NSCache<NSData, NSNumber> where the key is flow.metaData.sourceAppUniqueIdentifier. This goes through a couple layers of abstractions (the cache is in one Swift class, and it calls another Swift class that gets the security info and then returns the pathname, or throws an error). As an example, after running for a couple of days, it has 1074 open file descriptors for /System/Library/PrivateFrameworks/CloudKitDaemon.framework/Support/cloudd -- and only had 732 three hours ago.
Posted
by
Post marked as solved
1 Replies
278 Views
Hello, I'm using a wrapper from a company call PACE to make a piracy protection for my software. I can wrap and it works, but then, in order to notarize my software with apple, i have to sign it (that is no problem) and apply a "hardened runtime enabled". And that's when I get stuck. I can apply that as apple want but, as soon i apply the hardened runtime enabled, the piracy protection wrapper gets broken and my software doesn't start. it gives me a "Fatal error: 1000000" The Pace company said: You need to add the com.apple.security.cs.allow-unsigned-executable-memory entitlement when signing. To do this, you should create an entitlements file with at least the following contents (add your own required entitlements as needed) xml version="1.0" encoding="UTF-8" DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> plist version="1.0" dict    key com.apple.security.cs.allow-unsigned-executable-memory /key>    true/> /dict> /plist> How I add/create the com.apple.security.cs.allow-unsigned-executable-memory entitlement? Could you help me with the steps to create that in my mac? I'm on 11.6.3 OS. I have xcode but I didn't use it. Also, anybody knows how to notarize a PACE wrapped software applying "hardened runtime enabled" with out this error? Thank you! Javier
Posted
by
Post not yet marked as solved
2 Replies
266 Views
I am building a somewhat-VPN-like system. I have a daemon that handles the networking and a couple of agents that interact with the logged-in user. The daemon and agent communicate via XPC. I am trying to get this to work "smoothly" with fast-user-switching. Empirically, I find that the daemon can correlate XPC connection from different agents in the different login sessions via xpc_connection_get_asid(), which appears to be equivalent to the security session id, though it's not clear this this equivalence is always they case, nor will always be the case in the future. If I had a way to get the security session id for a pid, I would use xpc_connection_get_pid() When the daemon gets a network connection I want to find the pid the connection is coming from (it can only be from the local machine) and figure out which security session that pid belongs to so that I can direct any necessary user interaction and permission checking to the agent in the security session from which the network request is coming. Finding the pid from the TCP port is arduous and inefficient, but doable. However, once I've found the pid, I don't know how to determine the security session id (or audit session id) that that pid is part of. GetSessionInfo appears to permit me to get information about my own session id including my session id, or additional info about another session, if I already have that session id. For my purposes, a viable alternative to being able to get the security session for a pid might be to be able to ask the question "Is this pid part of this security session?" since I expect to have agents in a small number of security sessions. Getting the username of the pid is obviously doable, however this would mean that I would be unable to determine where a sudo'ed process was coming from (at least not without walking up the parent heirarchy). This feels dicey. Am I missing something?
Posted
by
Post not yet marked as solved
5 Replies
527 Views
Hello all, I'm developing IOS Push Notification。 I'll need to generate an AES key and register the key to another backend service so they can encrypt the notification payload using AES-256 cryptography. But based on the official Apple Developer doc (https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/generating_new_cryptographic_keys#2863927), I didn't find a way to generate such a symmetric encryption key. All I found is how to create an asymmetric one. Has Anybody created an AES key in swift before? Your help is much appreciated
Posted
by
Post marked as solved
2 Replies
328 Views
Hello, I've already made a previous similar post but it's getting a bit old so I'm re-launching it. I am currently developing an iOS application using AppCheck with AppAttest. I have read Apple's documentation on AppAttest to understand how it works. However, there is a part I didn't understand. When the public key is to be shared, Apple will create a certificate to attest that this public key belongs to an official instance of my application. Here is what it says about this verification on the official website : How does the Apple server identify that the key comes from an official instance of my application ? I can also rephrase my question as follows: How does the apple server detect an unofficial instance of my application if the data it receives for this check comes from it directly (I assume and I am probably wrong) and can therefore be falsified ? Is this a secret process to which I cannot have access, this answer would also suit me ? Thanks for your attention !
Posted
by
Post not yet marked as solved
0 Replies
207 Views
I often get questions about disabling the HTTPS default server trust evaluation done by NSURLSession. My general advice is “Don’t do that!” However, there is one case where you have to do that, namely when dealing with a hardware accessory on the local network. This post contains my advice on how to deal with that situation. IMPORTANT If you found your way here and you’re not developing a network-based accessory, I have two suggestions for you: If you’re trying to override HTTPS server trust evaluation for testing purposes, see QA1948 HTTPS and Test Servers. If not, post a question here on DevForums and we’ll try to get you heading in the right direction. Tag it with Security, and either CFNetwork or Network depending on which API you’re using. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" TLS For Accessory Developers Communicating securely with a network-based accessory is tricky because the standard network security protocol, TLS, was designed for the wider Internet, where servers have a stable DNS name. A devices on your local network doesn’t have a stable DNS name. The DNS name my-waffle-maker.local. might resolve to your waffle maker today, but tomorrow it might resolve to a different waffle maker or, worse yet, a malicious waffle varnisher. I guarantee that you won’t like them waffles! Note If you’re unfamiliar with TLS in general, I encourage you to read TLS for App Developers first. TLS puts the S into HTTPS. This post focuses on URLSession and HTTPS, because that’s where this most commonly crops up, but similar logic applies to other networking APIs. Doing the Minimum: The SSH Approach Many accessory firmware developers support TLS by generating a self-signed digital identity on the accessory and using that for their HTTPS server. IMO they should do better — the subject of later sections in this post — but sometimes you have to work with what you’ve got. If you’re working with an accessory like this, and you can’t convince the firmware developer to do better, I recommend that you adopt the SSH approach. In this approach you accept the certificate offered by the accessory the first time and then, when you connect again in the future, check the accessory still has the same certificate. Note I call this the SSH approach because that’s how many folks use SSH. To implement the SSH approach, first disable App Transport Security for local networking by setting the NSAllowsLocalNetworking property. On modern systems this isn’t strictly necessary but, as it says in the docs, this is a good “declaration of intent”. Next, override HTTPS server trust evaluation as shown below: var expectedCertificate: SecCertificate? = nil func shouldAllowHTTPSConnection(trust: SecTrust) async -> Bool { guard let chain = SecTrustCopyCertificateChain(trust) as? [SecCertificate], let actual = chain.first else { return false } guard let expected = self.expectedCertificate else { // A. First connection self.expectedCertificate = actual return true } // B. Subsequent connections return CFEqual(expected, actual) } func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { switch challenge.protectionSpace.authenticationMethod { case NSURLAuthenticationMethodServerTrust: let trust = challenge.protectionSpace.serverTrust! guard await self.shouldAllowHTTPSConnection(trust: trust) else { return (.cancelAuthenticationChallenge, nil) } let credential = URLCredential(trust: trust) return (.useCredential, credential) default: return (.performDefaultHandling, nil) } } There are a few things to note here: The snippet uses the new Swift async/await syntax. That simplifies the code and it also avoids a gotcha with the old completion-handler approach, where it was easy to forget to call the completion handler. Having said that, you can achieve the same result without using Swift async/await, or indeed, in Objective-C. The authentication challenge handler only deals with HTTPS server trust challenges (NSURLAuthenticationMethodServerTrust). Critically, if it finds a challenge it doesn’t recognise, it resolves that in the default way (.performDefaultHandling). The shouldAllowHTTPSConnection(trust:) method checks to see if it’s connected to the server before. If not, it defaults to allowing the connection (case A). If so, it checks that the certificate hasn’t changed (case B). In a real app you would persist expectedCertificate so that this logic continues to apply the next time your app is launched. When you do that, store the certificate using a key that uniquely identifies the accessory. Do not use the DNS name or IP address because that can change. The first time you connect (case A) you might take other steps to confirm the identity of the accessory. This is something I’ll cover below. The thing to note here is that this function is async, so you can take your time doing that confirmation. For example, you could bounce over to the main actor and display a UI. Doing Better: Add a Side Channel The above represents the absolute minimum you should do; anything less is doing the user a disservice. Aim to do better! Doing better requires some sort of side channel so that the user can confirm the identity of the accessory. For example: If the accessory has a display, you might present a UI asking the user to confirm that the code in your UI matches the one on the accessory’s display. If the accessory has a LED, it might blink that during this initial setup process. If the accessory has a serial number, you might ask the user to confirm that. Or scan that via a barcode. Note For an example of the barcode approach, see Matt’s Configuring a Wi-Fi Accessory to Join the User’s Network sample. This sample uses a different technique for TLS, namely TLS-PSK. This has some advantages — most notably, it avoids messing around with certificates — but I’m not discussing it here because it’s not supported by URLSession. If you adopt this approach make sure that you present a UI that the user can understand. If your UI contains raw certificate details, most users will just say “Sure, whatever.” and click OK, at which point you might as well have saved everyone’s time by accepting the connection on their behalf. Take care not to blindly trust any information you get from the accessory. After all, the goal here is to check the identity of the accessory, and so you mustn’t trust it before completing that check. Sometimes this can be quite subtle. Consider the accessory-with-a-display example above. In that case the accessory’s self-signed certificate might contain a common name of Acme Waffle Maker CCC, where CCC is the code showing on its display. Don’t display the entire string to the user. The presence of Acme Waffle Maker might lead the user to believe that the accessory is valid, even when it isn’t. After all, a malicious waffle varnisher can just as easily create a self-signed certificate with that common name. Rather, extract the code (CCC) and display just that. That way the user will focus on what’s important. Doing Even Better: Proper Security If the accessory’s firmware and hardware developers are on board, there are steps you can take to properly secure your communication with the accessory: Create a custom certificate authority (CA) for your accessories. At the factory, have that CA issue a certificate to each accessory as its produced, embedding identifying details, like the serial number, in that certificate. Then install that certificate and its associated private key (thus forming a digital identity) on the accessory as it comes off the line. Embed the CA’s certificate in your app. When you connect the accessory, verify that its certificate was issued by your CA. If it was, you can trust the identifying information, like the serial number, embedded in that certificate. With this setup your app will never connect to a malicious accessory. The worst that can happen is that you accidentally connect to the wrong instance of your accessory. IMPORTANT This is just an outline of one approach that I believe offers specific advantages. If you plan to deploy this in practice, hire a security profession to design your process. They can advise you on the details of creating a system that’s secure in practice. For example, they can help you: Create a mechanism that prevents your factory from leaking valid digital identities. Design your hardware to prevent an attacker from extracting an accessory’s digital identity from the accessory itself. To implement the URLSession side of this, change the shouldAllowHTTPSConnection(trust:) method like so: let waffleVarnisherCA: SecCertificate = { let u = Bundle.main.url(forResource: "WaffleVarnisherCA", withExtension: "cer")! let d = try! Data(contentsOf: u) let c = SecCertificateCreateWithData(nil, d as NSData)! return c }() func shouldAllowHTTPSConnection(trust: SecTrust) async -> Bool { var err = SecTrustSetPolicies(trust, SecPolicyCreateBasicX509()) guard err == errSecSuccess else { return false } err = SecTrustSetAnchorCertificates(trust, [self.waffleVarnisherCA] as NSArray) guard err == errSecSuccess else { return false } err = SecTrustSetAnchorCertificatesOnly(trust, true) guard err == errSecSuccess else { return false } let wasIssuedByOurCA = SecTrustEvaluateWithError(trust, nil) guard wasIssuedByOurCA else { return false } guard let chain = SecTrustCopyCertificateChain(trust) as? [SecCertificate], let trustedLeaf = chain.first else { return false } // C. Check the now-trusted leaf certificate return true } There are a few things to note about this code: It changes the trust policy (SecTrustSetPolicies) to the basic X.509 policy (SecPolicyCreateBasicX509) because the standard policy for TLS connections checks the DNS name, and that’s not appropriate for an accessory on the local network. It applies a custom anchor (SecTrustSetAnchorCertificates) and then disables all the other anchors (SecTrustSetAnchorCertificatesOnly) [1]. That prevents someone from impersonating your accessory by getting some other CA to issue a certificate that looks like the accessory’s certificate. It evaluates trust to confirm that the certificate was issued by the accessory’s CA. At point C you can trust the details in the accessory’s certificate (trustedLeaf). Here you might add code to confirm the identity of the accessory, to prevent you from accidentally connecting to the wrong accessory. [1] This is not strictly necessary because calling SecTrustSetAnchorCertificates disables other anchors. However, I’m applying both belt and braces [2] here. [2] I’m using the British idiom because belt and suspenders is so wrong (-:
Posted
by
Post not yet marked as solved
2 Replies
219 Views
i would like to know how to calculate SHA1 fingerprint in ios swift, i am trying to calculate it on runtime to have some potential checking of integrity of my application. I know macos has some direct APIs to get it but i dont know how can we achieve this in iOS as well. P.S. I am new to iOS development , so please bear with me if i ask some naive questions in this thread.
Posted
by