Security

RSS for tag

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

Posts under Security tag

200 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Security Resources
General: Apple Platform Security support document Security Overview Cryptography: DevForums tags: Security, Apple CryptoKit Security framework documentation Apple CryptoKit framework documentation Common Crypto man pages — For the full list of pages, run: % man -k 3cc For more information about man pages, see Reading UNIX Manual Pages. On Cryptographic Key Formats DevForums post SecItem attributes for keys DevForums post CryptoCompatibility sample code Keychain: DevForums tags: Security Security > Keychain Items documentation TN3137 On Mac keychain APIs and implementations SecItem Fundamentals DevForums post SecItem Pitfalls and Best Practices DevForums post Investigating hard-to-reproduce keychain problems DevForums post Smart cards and other secure tokens: DevForums tag: CryptoTokenKit CryptoTokenKit framework documentation Mac-specific frameworks: DevForums tags: Security Foundation, Security Interface Security Foundation framework documentation Security Interface framework documentation Related: Networking Resources — This covers high-level network security, including HTTPS and TLS. Network Extension Resources — This covers low-level network security, including VPN and content filters. Code Signing Resources Notarisation Resources Trusted Execution Resources — This includes Gatekeeper. App Sandbox Resources Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com"
0
0
2.3k
Mar ’24
SecItem: Fundamentals
I regularly help developers with keychain problems, both here on DevForums and for my Day Job™ in DTS. Many of these problems are caused by a fundamental misunderstanding of how the keychain works. This post is my attempt to explain that. I wrote it primarily so that Future Quinn™ can direct folks here rather than explain everything from scratch (-: If you have questions or comments about any of this, put them in a new thread and apply the Security tag so that I see it. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" SecItem: Fundamentals or How I Learned to Stop Worrying and Love the SecItem API The SecItem API seems very simple. After all, it only has four function calls, how hard can it be? In reality, things are not that easy. Various factors contribute to making this API much trickier than it might seem at first glance. This post explains the fundamental underpinnings of the keychain. For information about specific issues, see its companion post, SecItem: Pitfalls and Best Practices. Keychain Documentation Your basic starting point should be Keychain Items. If your code runs on the Mac, also read TN3137 On Mac keychain APIs and implementations. Read the doc comments in <Security/SecItem.h>. In many cases those doc comments contain critical tidbits. When you read keychain documentation [1] and doc comments, keep in mind that statements specific to iOS typically apply to iPadOS, tvOS, and watchOS as well (r. 102786959). Also, they typically apply to macOS when you target the data protection keychain. Conversely, statements specific to macOS may not apply when you target the data protection keychain. [1] Except TN3137, which is very clear about this (-: Caveat Mac Developer macOS supports two different implementations: the original file-based keychain and the iOS-style data protection keychain. If you’re able to use the data protection keychain, do so. It’ll make your life easier. TN3137 On Mac keychain APIs and implementations explains this distinction in depth. The Four Freedoms^H^H^H^H^H^H^H^H Functions The SecItem API contains just four functions: SecItemAdd(_:_:) SecItemCopyMatching(_:_:) SecItemUpdate(_:_:) SecItemDelete(_:) These directly map to standard SQL database operations: SecItemAdd(_:_:) maps to INSERT. SecItemCopyMatching(_:_:) maps to SELECT. SecItemUpdate(_:_:) maps to UPDATE. SecItemDelete(_:) maps to DELETE. You can think of each keychain item class (generic password, certificate, and so on) as a separate SQL table within the database. The rows of that table are the individual keychain items for that class and the columns are the attributes of those items. Note Except for the digital identity class, kSecClassIdentity, where the values are split across the certificate and key tables. See Digital Identities Aren’t Real in SecItem: Pitfalls and Best Practices. This is not an accident. The data protection keychain is actually implemented as an SQLite database. If you’re curious about its structure, examine it on the Mac by pointing your favourite SQLite inspection tool — for example, the sqlite3 command-line tool — at the keychain database in ~/Library/Keychains/UUU/keychain-2.db, where UUU is a UUID. WARNING Do not depend on the location and structure of this file. These have changed in the past and are likely to change again in the future. If you embed knowledge of them into a shipping product, it’s likely that your product will have binary compatibility problems at some point in the future. The only reason I’m mentioning them here is because I find it helpful to poke around in the file to get a better understanding of how the API works. For information about which attributes are supported by each keychain item class — that is, what columns are in each table — see the Note box at the top of Item Attribute Keys and Values. Alternatively, look at the Attribute Key Constants doc comment in <Security/SecItem.h>. Uniqueness A critical part of the keychain model is uniqueness. How does the keychain determine if item A is the same as item B? It turns out that this is class dependent. For each keychain item class there is a set of attributes that form the uniqueness constraint for items of that class. That is, if you try to add item A where all of its attributes are the same as item B, the add fails with errSecDuplicateItem. For more information, see the errSecDuplicateItem page. It has lists of attributes that make up this uniqueness constraint, one for each class. These uniqueness constraints are a major source of confusion, as discussed in the Queries and the Uniqueness Constraints section of SecItem: Pitfalls and Best Practices. Parameter Blocks Understanding The SecItem API is a classic ‘parameter block’ API. All of its inputs are dictionaries, and you have to know which properties to set in each dictionary to achieve your desired result. Likewise for when you read properties in output dictionaries. There are five different property groups: The item class property, kSecClass, determines the class of item you’re operating on: kSecClassGenericPassword, kSecClassCertificate, and so on. The item attribute properties, like kSecAttrAccessGroup, map directly to keychain item attributes. The search properties, like kSecMatchLimit, control how the system runs a query. The return type properties, like kSecReturnAttributes, determine what values the query returns. The value type properties, like kSecValueRef perform multiple duties, as explained below. There are other properties that perform a variety of specific functions. For example, kSecUseDataProtectionKeychain tells macOS to use the data protection keychain instead of the file-based keychain. These properties are hard to describe in general; for the details, see the documentation for each such property. Inputs Each of the four SecItem functions take dictionary input parameters of the same type, CFDictionary, but these dictionaries are not the same. Different dictionaries support different property groups: The first parameter of SecItemAdd(_:_:) is an add dictionary. It supports all property groups except the search properties. The first parameter of SecItemCopyMatching(_:_:) is a query and return dictionary. It supports all property groups. The first parameter of SecItemUpdate(_:_:) is a pure query dictionary. It supports all property groups except the return type properties. Likewise for the only parameter of SecItemDelete(_:). The second parameter of SecItemUpdate(_:_:) is an update dictionary. It supports the item attribute and value type property groups. Outputs Two of the SecItem functions, SecItemAdd(_:_:) and SecItemCopyMatching(_:_:), return values. These output parameters are of type CFTypeRef because the type of value you get back depends on the return type properties you supply in the input dictionary: If you supply a single return type property, except kSecReturnAttributes, you get back a value appropriate for that return type. If you supply multiple return type properties or kSecReturnAttributes, you get back a dictionary. This supports the item attribute and value type property groups. To get a non-attribute value from this dictionary, use the value type property that corresponds to its return type property. For example, if you set kSecReturnPersistentRef in the input dictionary, use kSecValuePersistentRef to get the persistent reference from the output dictionary. In the single item case, the type of value you get back depends on the return type property and the keychain item class: For kSecReturnData you get back the keychain item’s data. This makes most sense for password items, where the data holds the password. It also works for certificate items, where you get back the DER-encoded certificate. Using this for key items is kinda sketchy. If you want to export a key, called SecKeyCopyExternalRepresentation. Using this for digital identity items is nonsensical. For kSecReturnRef you get back an object reference. This only works for keychain item classes that have an object representation, namely certificates, keys, and digital identities. You get back a SecCertificate, a SecKey, or a SecIdentity, respectively. For kSecReturnPersistentRef you get back a data value that holds the persistent reference. Value Type Subtleties There are three properties in the value type property group: kSecValueData kSecValueRef kSecValuePersistentRef Their semantics vary based on the dictionary type. For kSecValueData: In an add dictionary, this is the value of the item to add. For example, when adding a generic password item (kSecClassGenericPassword), the value of this key is a Data value containing the password. This is not supported in a query dictionary. In an update dictionary, this is the new value for the item. For kSecValueRef: In add and query dictionaries, the system infers the class property and attribute properties from the supplied object. For example, if you supply a certificate object (SecCertificate, created using SecCertificateCreateWithData), the system will infer a kSecClass value of kSecClassCertificate and various attribute values, like kSecAttrSerialNumber, from that certificate object. This is not supported in an update dictionary. For kSecValuePersistentRef: For query dictionaries, this uniquely identifies the item to operate on. This is not supported in add and update dictionaries. Revision History 2023-09-12 Fixed various bugs in the revision history. Added a paragraph explaining how to determine which attributes are supported by each keychain item class. 2023-02-22 Made minor editorial changes. 2023-01-28 First posted.
0
0
2.0k
Sep ’23
Multi-User Touch ID
Hi All,Just a quick question regarding the upgraded Touch ID and local authentication capabilities.I want to use the built-in fingerprint scanner on a iPad to allow multiple people to log into a custom application, what i want to do is to try and use the fingerprint scanner to save/recall user info that i want to store within my application.as example, an employee picks up an iPad, and by using the fingerprint scanner, while in the an application, the application should read the fingerprint of the employee and match that to a local database, if successful match, it will log the user into the application and display that user's specific information.Would something like this be possible? any other suggestions would really be appreciated as i have everything else working as needed , except for the biometric side.Thank you.
6
0
3.1k
Jul ’23
TLS for App Developers
Transport Layer Security (TLS) is the most important security protocol on the Internet today. Most notably, TLS puts the S into HTTPS, adding security to the otherwise insecure HTTP protocol. IMPORTANT TLS is the successor to the Secure Sockets Layer (SSL) protocol. SSL is no longer considered secure and it’s now rarely used in practice, although many folks still say SSL when they mean TLS. TLS is a complex protocol. Much of that complexity is hidden from app developers but there are places where it’s important to understand specific details of the protocol in order to meet your requirements. This post explains the fundamentals of TLS, concentrating on the issues that most often confuse app developers. Note If you’re working on TLS in the local environment, for example, to talk to a Wi-Fi based accessory, see TLS For Accessory Developers. Server Certificates For standard TLS to work the server must have a digital identity, that is, the combination of a certificate and the private key matching the public key embedded in that certificate. TLS Crypto Magic™ ensures that: The client gets a copy of the server’s certificate. The client knows that the server holds the private key matching the public key in that certificate. In a typical TLS handshake the server passes the client a list of certificates, where item 0 is the server’s certificate (the leaf certificate), item N is (optionally) the certificate of the certificate authority that ultimately issued that certificate (the root certificate), and items 1 through N-1 are any intermediate certificates required to build a cryptographic chain of trust from 0 to N. Note The cryptographic chain of trust is established by means of digital signatures. Certificate X in the chain is issued by certificate X+1. The owner of certificate X+1 uses their private key to digitally sign certificate X. The client verifies this signature using the public key embedded in certificate X+1. Eventually this chain terminates in a trusted anchor, that is, a certificate that the client trusts by default. Typically this anchor is a self-signed root certificate from a certificate authority. Note Item N is optional for reasons I’ll explain below. Also, the list of intermediate certificates may be empty (in the case where the root certificate directly issued the leaf certificate) but that’s uncommon for servers in the real world. Once the client gets the server’s certificate, it evaluates trust on that certificate to confirm that it’s talking to the right server. There are three levels of trust evaluation here: Basic X.509 trust evaluation checks that there’s a cryptographic chain of trust from the leaf through the intermediates to a trusted root certificate. The client has a set of trusted root certificates built in (these are from well-known certificate authorities, or CAs), and a site admin can add more via a configuration profile. This step also checks that none of the certificates have expired, and various other more technical criteria (like the Basic Constraints extension). Note This explains why the server does not have to include the root certificate in the list of certificates it passes to the client; the client has to have the root certificate installed if trust evaluation is to succeed. In addition, TLS trust evaluation (per RFC 2818) checks that the DNS name that you connected to matches the DNS name in the certificate. Specifically, the DNS name must be listed in the Subject Alternative Name extension. Note The Subject Alternative Name extension can also contain IP addresses, although that’s a much less well-trodden path. Also, historically it was common to accept DNS names in the Common Name element of the Subject but that is no longer the case on Apple platforms. App Transport Security (ATS) adds its own security checks. Basic X.509 and TLS trust evaluation are done for all TLS connections. ATS is only done on TLS connections made by URLSession and things layered on top URLSession (like WKWebView). In many situations you can override trust evaluation; for details, see Technote 2232 HTTPS Server Trust Evaluation). Such overrides can either tighten or loosen security. For example: You might tighten security by checking that the server certificate was issued by a specific CA. That way, if someone manages to convince a poorly-managed CA to issue them a certificate for your server, you can detect that and fail. You might loosen security by adding your own CA’s root certificate as a trusted anchor. IMPORTANT If you rely on loosened security you have to disable ATS. If you leave ATS enabled, it requires that the default server trust evaluation succeeds regardless of any customisations you do. Mutual TLS The previous section discusses server trust evaluation, which is required for all standard TLS connections. That process describes how the client decides whether to trust the server. Mutual TLS (mTLS) is the opposite of that, that is, it’s the process by which the server decides whether to trust the client. Note mTLS is commonly called client certificate authentication. I avoid that term because of the ongoing confusion between certificates and digital identities. While it’s true that, in mTLS, the server authenticates the client certificate, to set this up on the client you need a digital identity, not a certificate. mTLS authentication is optional. The server must request a certificate from the client and the client may choose to supply one or not (although if the server requests a certificate and the client doesn’t supply one it’s likely that the server will then fail the connection). At the TLS protocol level this works much like it does with the server certificate. For the client to provide this certificate it must apply a digital identity, known as the client identity, to the connection. TLS Crypto Magic™ assures the server that, if it gets a certificate from the client, the client holds the private key associated with that certificate. Where things diverge is in trust evaluation. Trust evaluation of the client certificate is done on the server, and the server uses its own rules to decided whether to trust a specific client certificate. For example: Some servers do basic X.509 trust evaluation and then check that the chain of trust leads to one specific root certificate; that is, a client is trusted if it holds a digital identity whose certificate was issued by a specific CA. Some servers just check the certificate against a list of known trusted client certificates. When the client sends its certificate to the server it actually sends a list of certificates, much as I’ve described above for the server’s certificates. In many cases the client only needs to send item 0, that is, its leaf certificate. That’s because: The server already has the intermediate certificates required to build a chain of trust from that leaf to its root. There’s no point sending the root, as I discussed above in the context of server trust evaluation. However, there are no hard and fast rules here; the server does its client trust evaluation using its own internal logic, and it’s possible that this logic might require the client to present intermediates, or indeed present the root certificate even though it’s typically redundant. If you have problems with this, you’ll have to ask the folks running the server to explain its requirements. Note If you need to send additional certificates to the server, pass them to the certificates parameter of the method you use to create your URLCredential (typically init(identity:certificates:persistence:)). One thing that bears repeating is that trust evaluation of the client certificate is done on the server, not the client. The client doesn’t care whether the client certificate is trusted or not. Rather, it simply passes that certificate the server and it’s up to the server to make that decision. When a server requests a certificate from the client, it may supply a list of acceptable certificate authorities [1]. Safari uses this to filter the list of client identities it presents to the user. If you are building an HTTPS server and find that Safari doesn’t show the expected client identity, make sure you have this configured correctly. If you’re building an iOS app and want to implement a filter like Safari’s, get this list using: The distinguishedNames property, if you’re using URLSession The sec_protocol_metadata_access_distinguished_names routine, if you’re using Network framework [1] See the certificate_authorities field in Section 7.4.4 of RFC 5246, and equivalent features in other TLS versions. Self-Signed Certificates Self-signed certificates are an ongoing source of problems with TLS. There’s only one unequivocally correct place to use a self-signed certificate: the trusted anchor provided by a certificate authority. One place where a self-signed certificate might make sense is in a local environment, that is, securing a connection between peers without any centralised infrastructure. However, depending on the specific circumstances there may be a better option. TLS For Accessory Developers discusses this topic in detail. Finally, it’s common for folks to use self-signed certificates for testing. I’m not a fan of that approach. Rather, I recommend the approach described in QA1948 HTTPS and Test Servers. For advice on how to set that up using just your Mac, see TN2326 Creating Certificates for TLS Testing. TLS Standards RFC 6101 The Secure Sockets Layer (SSL) Protocol Version 3.0 (historic) RFC 2246 The TLS Protocol Version 1.0 RFC 4346 The Transport Layer Security (TLS) Protocol Version 1.1 RFC 5246 The Transport Layer Security (TLS) Protocol Version 1.2 RFC 8446 The Transport Layer Security (TLS) Protocol Version 1.3 RFC 4347 Datagram Transport Layer Security RFC 6347 Datagram Transport Layer Security Version 1.2 RFC 9147 The Datagram Transport Layer Security (DTLS) Protocol Version 1.3 Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Revision History: 2024-03-19 Adopted the term mutual TLS in preference to client certificate authentication throughout, because the latter feeds into the ongoing certificate versus digital identity confusion. Defined the term client identity. Added the Self-Signed Certificates section. Made other minor editorial changes. 2023-02-28 Added an explanation mTLS acceptable certificate authorities. 2022-12-02 Added links to the DTLS RFCs. 2022-08-24 Added links to the TLS RFCs. Made other minor editorial changes. 2022-06-03 Added a link to TLS For Accessory Developers. 2021-02-26 Fixed the formatting. Clarified that ATS only applies to URLSession. Minor editorial changes. 2020-04-17 Updated the discussion of Subject Alternative Name to account for changes in the 2019 OS releases. Minor editorial updates. 2018-10-29 Minor editorial updates. 2016-11-11 First posted.
0
0
6.5k
Mar ’24
errSecInvalidOwnerEdit returned from SecItemDelete
Have an app I'm working on that stores an item in the keychain. Everything was was working fine. I have a button in the UI that allows the user to clear out the keychain item:NSDictionary *query = @{(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword, (__bridge id)kSecAttrService: service, (__bridge id)kSecAttrAccount: accountKey}; OSStatus status = SecItemDelete((__bridge CFDictionaryRef)(query));Status is -25244 which is errSecInvalidOwnerEdit. This app created the keychain item to begin with. What would be the appropriate way to handle this type of error?
16
0
3.2k
Nov ’23
How to create an HTTPS server on IOS using cocoaHTTPServer?
I made a javascript cloud app that runs on a webpage in a webview on my iPad app that communicates via WebSocket connection but it only works when im on my http site and not https or else I get an CFNetwork SSLHandshake failed (-9806) error in Xcode and on the website it says time out during handshake.Is this because the webserver on the iPad is running on HTTP instead of HTTPS?JAVASCRIPT CLOUD APPThis part in the cloud is working for HTTP when connecting to the web server on the iPad.var protocol = "ws"; if (this.useSecureConnection) protocol = "wss"; var url = protocol+'://localhost:'+this.port+'/service'; this.connection = new WebSocket(url);Xcode iOS iPad App (Objective-C)I thought that was the issue so I tried to enable HTTPS but I am not sure what to create for the "sslIdentityAndCertificates" method.- (BOOL)isSecureServer { HTTPLogTrace(); // Override me to create an https server... return YES; } /* * This method is expected to returns an array appropriate for use in kCFStreamSSLCertificates SSL Settings. * It should be an array of SecCertificateRefs except for the first element in the array, which is a SecIdentityRef. **/ - (NSArray *)sslIdentityAndCertificates{ HTTPLogTrace(); return nil; }Some of the other posts I have seen use APIs that are only available on Mac and not iOS.I tried several combinations of ATS permissions as well. All resulted in HTTPS not allowing for WebSocket connection.Any help is greatly appreciated! 🙂More Info:The cloud hosted webapp was built to be used on different devices as a webpage but we needed to add support for bluetooth to connect to a 3rd party hardware. To do that we needed to create a native "wrapper" for the webapp that would get bluetooth messages and process/send messages to the webapp in the webview via webSocket. This allows for the web app to use the bluetooth tool.
6
0
6.3k
Aug ’23
Can I delete keychain content when User uninstall App?
I store certificate (as SecIdentity ) in keychain because my application needs clientCertficate.I know when a User uninstall application, keychian content still exist.But in My application, I manage userInformation client certificate and CoreData.So, I want to delete keychain content when user uninstall application for not occering mismatch between Keychain and CoreData.Is it possible to do above ?Or should I delete keychain content when the app re-installed ?
3
0
5.4k
Aug ’23
Integrating Touch ID with Access To Multiple Users in iOS.
I have been working on integrating Touch ID in my iOS application. If the multiple fingerprints are registered at the OS level.Is there anyway to know which fingerprint was scanned. (not the fingerprint infodata just like a unique key)For example :- There are three fingerprint in the iOS DeviceIf fingerprint one is scanned then perform Task A.If fingerprint two is scanned then perform Task C.If fingerprint Three is scanned then perform Task B.
2
0
1k
Jul ’23
NWProtocolTLS.Options init() supported default cipher suites iOS 13 ?
Hello,I have a local WebSocket server running inside an iOS app on iOS 13+. I'm using Swift NIO Transport Services for the server.I'm using NWProtocolTLS.Options from Network framework to specify TLS options for my server.I am providing my server as an XCFramework and want to let users to be able to specify different parameters when launching the server.For specifiying the TLS supported version, everything is working fine by using :public func sec_protocol_options_set_max_tls_protocol_version(_ options: sec_protocol_options_t, _ version: tls_protocol_version_t) public func sec_protocol_options_set_min_tls_protocol_version(_ options: sec_protocol_options_t, _ version: tls_protocol_version_t)But I also want to be able to specify some cipher suites. I saw that I can use :public func sec_protocol_options_append_tls_ciphersuite(_ options: sec_protocol_options_t, _ ciphersuite: tls_ciphersuite_t)But it seems that some cipher suites are enabled by default and I can't restrict the cipher suites just to the ones I want, I can just append others.NWProtocolTLS.Options class has an init() function which states "Initializes a default set of TLS connection options" on Apple documentation.So my question is, is there a way to know what TLS parameters this initialization does ? Especially the list of cipher suites enabled by default ? Because I can't find any information about it from my research. I used a tool to test handshake with my server to discover the cipher suites supported and enabled by default but I don't think it is a good way to be sure about this information.And is there a way to specify only cipher suites I want to be supported by my server by using NWProtocolTLS.Options ?Thank you in advance,Christophe
9
0
1.3k
3w
Security threat due to insecure function "memcpy()" in GCDAsyncSocket.m
Hi, https://opensource.apple.com/source/HTTPServer/HTTPServer-11/CocoaHTTPServer/Vendor/CocoaAsyncSocket/GCDAsyncSocket.m.auto.html I am getting security threat in GCDAsyncSocket.m class file  There are 13 occurrences of memcpy() function which is an insecure function acc to security tool. Below is the issue description and reference links from security team. Issue description : Use of insecure functions/potential dangerous functions Reference link: CWE-676: Use of Potentially Dangerous Function This would explain why SECURITY TEAM is recommending the change of these functions. Please provide solution for this as soon as possible as it is very urgent. Thanks and Regards, Priya Mehndiratta
5
0
3.0k
Sep ’23
Signing with SecKeyCreateSignature and verification with OpenSSL
At my app I have a SecKey which I want to sign some Data with it, and at my sever I need to do the verification process, but this time with openSSL. I didn't find any common key or any steps to achieve this between Apple Security framework and OpenSSL. For example, I've tried the following: Signing (Apple Security): let signedStrCFData = SecKeyCreateSignature(key, .rsaSignatureRaw, plaintextData, &error) Verifying (OpenSSL): ret = RSAverify(NIDrsaSignature, (const unsigned char *)challenge, (unsigned int)strlen(challenge), challengeenc, challengeenc_size, rsa); Which key to choose is not really important to me (as long as it's a reasonable signing key), so I tried multiple types of keys, but I wasn't able to do it. Any idea what I'm missing here?
8
0
1.2k
Nov ’23
how to prompt for and require ADMIN username & password
I'm developing a macOS app that will usually be running in a non-admin user environment. But I have a screen of the app that I would like to secure so as to make it only accessible to admin users (think: parents). I can't figure out what API I'm supposed to use to prompt for specifically an ADMIN user. I've tried googling a ton, but I must be trying the wrong search terms, because I can't find anything. The API for LAContext() is almost what I want, I can get it to prompt for a password, but it seems to ONLY work for the current logged in user. I can't find a policy type that allows me to specify something like .adminUserAuthentication. It seems like LAContext() was not meant for this use case. But then, what is the right API to call to do this? Can someone point me in the right direction? I don't want to limit myself to this only working for supervised users, or users with parental controls turned on, I would like a generic solution. I've seen apps that prompt for admin credentials on regular non-admin users, so it must be possible, right?
14
0
5.2k
Sep ’23
Cryptographic Message Syntax Services for swift
In Swift, I need to create a CMS to input a web service. In Android we used 'spongycastle' https://www.bouncycastle.org/docs/pkixdocs1.4/org/bouncycastle/cms/CMSSignedData.html But I did not find a sample or solution for Swift or objective C. I also read Apple related documents https://developer.apple.com/documentation/security/cryptographic_message_syntax_services#1677736 , but still nothing special. Does anyone have experience working with a specific solution for Swift or objective C code to do this? thank you.
4
0
1.4k
Aug ’23
Authorization Plugin finding user entered FileVault password after Restart
I'm developing an authorization plugin to provide 2 Factor Authentication (2FA) for macOS. When FileVault is enabled, macOS Recovery prompts the user for a password to unlock FileVault FDE (Full Disk Encryption) before macOS can startup. The FDE password entered during Recovery is saved somehow so that after macOS starts up it can be used to log the user in without prompting them to re-enter their password. This feature is configurable with setting 'DisableFDEAutoLogin'. We would like our authorization plugin to implement the same behavior. The first place I thought to look for the FDE password (from within our authorization mechanism) is in Context value kAuthorizationEnvironmentPassword but it's not there. Is it possible for an authorization plugin to obtain this password the same as the standard login mechanism and if so how?
2
0
811
Apr ’24
SecPKCS12Import is failing to import P12 certificate.
Are you able to reproduce the issue? Yes What software version(s) and hardware have you reproduced the issue on? iOS 14, iOS 15 iPhone XR, iPhone 12 simulator (On All iOS devices) Description When trying to import a P12 certificate using the API SecPKCS12Import, it is failing with error errSecDecode = -26275 since 09/23 in production. We tried to figure out the change in our code base (client as well as server side) that might have triggered this failure but there is no change on either side. The same P12 certificate is successfully validated using the below mentioned openssl command on the terminal. openssl pkcs12 -in -passin pass: Please can you tell us how we may debug the API SecPKCS12Import and understand what might be incorrect in P12 certificate format due to which it has started failing. Note: The same code (with zero change) was working fine in production until 09/23. If required, we may share the p12 certificate and associate password with you to debug it further.
9
2
10k
Jan ’24
macOS bundled OpenSSH 8.6p1 seems don't support FIDO keys
Since 8.2p1 OpenSSH support for FIDO/U2F hardware authenticators, add "ed25519-sk" and "ecdsa-sk" key type. macOS Monterey 12.2 bundled OpenSSH (version: 8.6p1) doesn't include built-in security keys support, but it seems that user can specify middle ware library to use FIDO authenticator-hosted keys (see man ssh-add, man ssh_config and man ssh-agent). I try to implement FIDO security key provider library, but bundled ssh-agent seems don't try to load the implemented library and simply return with "unknown or unsupported key type": $ ssh-agent -d -P "/*" SSH_AUTH_SOCK=SOME_VALUE; export SSH_AUTH_SOCK; echo Agent pid SOME_VALUE; debug1: new_socket: type = SOCKET debug2: fd 3 setting O_NONBLOCK debug1: new_socket: type = CONNECTION debug3: fd 4 is O_NONBLOCK debug1: process_message: socket 1 (fd=4) type 25 debug2: process_add_identity: entering debug1: parse_key_constraint_extension: constraint ext sk-provider@openssh.com debug1: process_add_identity: add sk-ssh-ed25519@openssh.com SHA256:KEY_HASH "KEY_COMMENT" (life: 0) (confirm: 0) (provider: /path/to/libsk-libfido2.so) debug1: new_socket: type = CONNECTION debug3: fd 4 is O_NONBLOCK debug1: process_message: socket 1 (fd=4) type 11 debug2: process_request_identities: entering debug1: process_message: socket 1 (fd=4) type 13 debug1: process_sign_request2: entering Confirm user presence for key ED25519-SK SHA256:KEY_HASH process_sign_request2: sshkey_sign: unknown or unsupported key type User presence confirmed Manually install OpenSSH from third-party (such as MacPorts/Homebrew, or simply build it from source code) works, but third-party OpenSSH can't read passwords stored in Keychain. Is bundled OpenSSH disable hardware key support at build time? Advice most appreciated. Thank you!
13
19
6.0k
Oct ’23
Would YOU use ClamXav on an Apple Mac?
Mac users often ask whether they should install "anti-virus" software. The answer usually given on ASC is "no." The answer is right, but it may give the wrong impression that there is no threat from what are loosely called "viruses." There is a threat, and you need to educate yourself about it. This is a comment on what you should—and should not—do to protect yourself from malicious software ("malware") that circulates on the Internet and gets onto a computer as an unintended consequence of the user's actions. It does not apply to software, such as keystroke loggers, that may be installed deliberately by an intruder who has hands-on access to the computer, or who has been able to log in to it remotely. That threat is in a different category, and there's no easy way to defend against it. The comment is long because the issue is complex. The key points are in sections 5, 6, and 10. OS X now implements three layers of built-in protection specifically against malware, not counting runtime protections such as execute disable, sandboxing, system library randomization, and address space layout randomization that may also guard against other kinds of exploits. 2. All versions of OS X since 10.6.7 have been able to detect known Mac malware in downloaded files, and to block insecure web plugins. This feature is transparent to the user. Internally Apple calls it "XProtect." The malware recognition database used by XProtect is automatically updated; however, you shouldn't rely on it, because the attackers are always at least a day ahead of the defenders. The following caveats apply to XProtect: ☞ It can be bypassed by some third-party networking software, such as BitTorrent clients and Java applets. ☞ It only applies to software downloaded from the network. Software installed from a CD or other media is not checked. As new versions of OS X are released, it's not clear whether Apple will indefinitely continue to maintain the XProtect database of older versions such as 10.6. The security of obsolete system versions may eventually be degraded. Security updates to the code of obsolete systems will stop being released at some point, and that may leave them open to other kinds of attack besides malware. 3. Starting with OS X 10.7.5, there has been a second layer of built-in malware protection, designated "Gatekeeper" by Apple. By default, applications and Installer packages downloaded from the network will only run if they're digitally signed by a developer with a certificate issued by Apple. Software certified in this way hasn't necessarily been tested by Apple, but you can be reasonably sure that it hasn't been modified by anyone other than the developer. His identity is known to Apple, so he could be held legally responsible if he distributed malware. That may not mean much if the developer lives in a country with a weak legal system (see below.) Gatekeeper doesn't depend on a database of known malware. It has, however, the same limitations as XProtect, and in addition the following: ☞ It can easily be disabled or overridden by the user. ☞ A malware attacker could get control of a code-signing certificate under false pretenses, or could simply ignore the consequences of distributing codesigned malware. ☞ An App Store developer could find a way to bypass Apple's oversight, or the oversight could fail due to human error. Apple has so far failed to revoke the codesigning certificates of some known abusers, thereby diluting the value of Gatekeeper and the Developer ID program. These failures don't involve App Store products, however. For the reasons given, App Store products, and—to a lesser extent—other applications recognized by Gatekeeper as signed, are safer than others, but they can't be considered absolutely safe. "Sandboxed" applications may prompt for access to private data, such as your contacts, or for access to the network. Think before granting that access. Sandbox security is based on user input. Never click through any request for authorization without thinking. 4. Starting with OS X 10.8.3, a third layer of protection has been added: a "Malware Removal Tool" (MRT). MRT runs automatically in the background when you update the OS. It checks for, and removes, malware that may have evaded the other protections via a Java exploit (see below.) MRT also runs when you install or update the Apple-supplied Java runtime (but not the Oracle runtime.) Like XProtect, MRT is effective against known threats, but not against unknown ones. It notifies you if it finds malware, but otherwise there's no user interface to MRT. 5. The built-in security features of OS X reduce the risk of malware attack, but they are not, and never will be, complete protection. Malware is a problem of human behavior, and a technological fix is not going to solve it. Trusting software to protect you will only make you more vulnerable. The best defense is always going to be your own intelligence. With the possible exception of Java exploits, all known malware circulating on the Internet that affects a fully-updated installation of OS X 10.6 or later takes the form of so-called "****** horses," which can only have an effect if the victim is duped into running them. The threat therefore amounts to a battle of wits between you and the scam artists. If you're smarter than they think you are, you'll win. That means, in practice, that you always stay within a safe harbor of computing practices. Malware defence By Linc Davis - https://discussions.apple.com/thread/6460085
5
1
2.7k
Dec ’23
Calling Security Framework from Swift
I spend way too much time interacting with the Security framework. Most Security framework APIs are kinda clunky to call from Swift, largely because they use Core Foundation conventions. However, I see a lot of folks working much harder than they should to call these APIs. This post contains two tips to make your life easier. Many Security framework APIs work in terms of CFDictionary. I regularly see folks create these dictionaries like so: let query: [String: Any] = [ kSecClass as String: kSecClassKey, kSecMatchLimit as String: kSecMatchLimitAll, kSecReturnRef as String: true, ] var copyResult: CFTypeRef? let status = SecItemCopyMatching(query as CFDictionary, &copyResult) That’s much too hard. Try this instead: let query = [ kSecClass: kSecClassKey, kSecMatchLimit: kSecMatchLimitAll, kSecReturnRef: true, ] as NSDictionary var copyResult: CFTypeRef? let status = SecItemCopyMatching(query, &copyResult) Much nicer. Security framework APIs have a wide variety of ways to indicate an error: Some routines return an OSStatus and that’s it. Some routines return an OSStatus and an ‘out’ value. Some routines return a pointer, where nil indicates an error. Some routines return a pointer, where nil indicates an error, with a CFError ‘out’ value. Some routines return a Boolean, where false indicates an error, with a CFError ‘out’ value. In Swift you really just want to call the API and have it throw. The code pasted in at the end of this post helps with that. It declares a bunch of overloaded secCall(…) functions, one for each of the cases outlined above. It takes code like this: let query = [ kSecClass: kSecClassKey, kSecMatchLimit: kSecMatchLimitAll, kSecReturnRef: true, ] as NSDictionary var copyResult: CFTypeRef? = nil let err = SecItemCopyMatching(query, &copyResult) guard err == errSecSuccess else { throw NSError(domain: NSOSStatusErrorDomain, code: Int(err)) } let keys = copyResult! as! [SecKey] and turns it into this: let query = [ kSecClass: kSecClassKey, kSecMatchLimit: kSecMatchLimitAll, kSecReturnRef: true, ] as NSDictionary let keys = try secCall { SecItemCopyMatching(query, $0) } as! [SecKey] Still not exactly pretty, but definitely an improvement. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Revision History 2023-11-27 Fixed a polarity bug with the Bool routine. As the saying goes “Real programmers can get the branch backwards in any language!” |-: /// Calls a Security framework function, throwing if it returns an error. /// /// For example, the `SecACLRemove` function has a signature like this: /// /// ``` /// func SecACLRemove(…) -> OSStatus /// ``` /// /// and so you call it like this: /// /// ``` /// try secCall { SecACLRemove(acl) } /// ``` /// /// - Parameter body: A function that returns an `OSStatus` value. /// - Throws: If `body` returns anything other than `errSecSuccess`. func secCall(_ body: () -> OSStatus) throws { let err = body() guard err == errSecSuccess else { throw NSError(domain: NSOSStatusErrorDomain, code: Int(err), userInfo: nil) } } /// Calls a Security framework function that returns an error and a value indirectly. /// /// For example, the `SecItemCopyMatching` function has a signature like this: /// /// ``` /// func SecItemCopyMatching(…, _ result: UnsafeMutablePointer<CFTypeRef?>?) -> OSStatus /// ``` /// /// and so you call it like this: /// /// ``` /// let keys = try secCall { SecItemCopyMatching([ /// kSecClass: kSecClassKey, /// kSecMatchLimit: kSecMatchLimitAll, /// kSecReturnRef: true, /// ] as NSDictionary, $0) } /// ``` /// /// - Parameter body: A function that returns an `OSStatus` value and takes a /// ‘out’ pointer to return the result indirectly. /// - Throws: If `body` returns anything other than `errSecSuccess`. /// - Returns: The value returned indirectly by the function. func secCall<Result>(_ body: (_ resultPtr: UnsafeMutablePointer<Result?>) -> OSStatus) throws -> Result { var result: Result? = nil let err = body(&result) guard err == errSecSuccess else { throw NSError(domain: NSOSStatusErrorDomain, code: Int(err), userInfo: nil) } return result! } /// Calls a Security framework function that returns `nil` on error. /// /// For example, the `SecKeyCopyPublicKey` function has a signature like this: /// /// ``` /// func SecKeyCopyPublicKey(…) -> SecKey? /// ``` /// /// and so you call it like this: /// /// ``` /// let publicKey = try secCall { SecKeyCopyPublicKey(privateKey) } /// ``` /// /// - Parameters: /// - code: An `OSStatus` value to throw if there’s an error; defaults to `errSecParam`. /// - body: A function that returns a value, or `nil` if there’s an error. /// - Throws: If `body` returns `nil`. /// - Returns: On success, the non-`nil` value returned by `body`. func secCall<Result>(_ code: Int = Int(errSecParam), _ body: () -> Result?) throws -> Result { guard let result = body() else { throw NSError(domain: NSOSStatusErrorDomain, code: code, userInfo: nil) } return result } /// Calls a Security framework function that returns `nil` on error along with a `CFError` indirectly. /// /// For example, the `SecKeyCreateDecryptedData` function has a signature like this: /// /// ``` /// func SecKeyCreateDecryptedData(…, _ error: UnsafeMutablePointer<Unmanaged<CFError>?>?) -> CFData? /// ``` /// /// and so you call it like this: /// /// ``` /// let plainText = try secCall { SecKeyCreateDecryptedData(privateKey, .rsaEncryptionPKCS1, cypherText, $0) } /// ``` /// /// - Parameter body: A function that returns a value, which returns `nil` if /// there’s an error and, in that case, places a `CFError` value in the ‘out’ parameter. /// - Throws: If `body` returns `nil`. /// - Returns: On success, the non-`nil` value returned by `body`. func secCall<Result>(_ body: (_ resultPtr: UnsafeMutablePointer<Unmanaged<CFError>?>) -> Result?) throws -> Result { var errorQ: Unmanaged<CFError>? = nil guard let result = body(&errorQ) else { throw errorQ!.takeRetainedValue() as Error } return result } /// Calls a Security framework function that returns false on error along with a `CFError` indirectly. /// /// For example, the `SecKeyVerifySignature` function has a signature like this: /// /// ``` /// func SecKeyVerifySignature(…, _ error: UnsafeMutablePointer<Unmanaged<CFError>?>?) -> Bool /// ``` /// /// and so you call it like this: /// /// ``` /// try secCall { SecKeyVerifySignature(publicKey, .ecdsaSignatureMessageX962SHA1, signedData, signature, $0) } /// ``` /// /// - Parameter body: A function that returns a false if there’s an error and, /// in that case, places a `CFError` value in the ‘out’ parameter. /// - Throws: If `body` returns false. func secCall(_ body: (_ resultPtr: UnsafeMutablePointer<Unmanaged<CFError>?>) -> Bool) throws { var errorQ: Unmanaged<CFError>? = nil guard body(&errorQ) else { throw errorQ!.takeRetainedValue() as Error } }
0
0
2.4k
Nov ’23
Getting "Caught Error Domain NSURLErrorDomain Code=-1200 \"An SSL error has occurred and a secure connection to the server cannot be made."?
We've enabled ATS restrictions in our app, and everything works fine, except sometimes, randomly, the CDN download resource fails. In most cases, it happens to users who on iOS 14.* and WiFI (VPN helps solve the problem :thinking_face:) Logs: (ExampleClientErrorLogServlet) :: Client error: {"arguments":["test_resource","Caught Error Domain%3DNSURLErrorDomain Code%3D-1200 \"An SSL error has occurred and a secure connection to the server cannot be made.\" UserInfo%3D{NSErrorFailingURLStringKey%3Dhttps://my-url/reource.bin, NSLocalizedRecoverySuggestion%3DWould you like to connect to the server anyway?, _kCFStreamErrorDomainKey%3D3, _NSURLErrorFailingURLSessionTaskErrorKey%3DLocalDownloadTask &lt;A50DCF0E-38F3-4454-A78A-B4552336561E&gt;.&lt;1&gt;, _NSURLErrorRelatedURLSessionTaskErrorKey%3D(\n \"LocalDownloadTask &lt;A50DCF0E-38F3-4454-A78A-B4552336561E&gt;.&lt;1&gt;\"\n), NSLocalizedDescription%3DAn SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey%3Dhttps://my-url/reource.bin, NSUnderlyingError%3D0x2882e1050 {Error Domain%3DkCFErrorDomainCFNetwork Code%3D-1200 \"(null)\" UserInfo%3D{_kCFStreamPropertySSLClientCertificateState%3D0, _kCFNetworkCFStreamSSLErrorOriginalValue%3D-9816, _kCFStreamErrorDomainKey%3D3, _kCFStreamErrorCodeKey%3D-9816, _NSURLErrorNWPathKey%3Dsatisfied (Path is satisfied), viable, interface: en0, ipv4, dns}}, _kCFStreamErrorCodeKey%3D-9816}"],"format":"Downloading {} file failed: {}","platform":"ios","version":"2.87.1"} 26.07.2022 01:39:55 [DEBUG][9] :: platform: ios, version: 2.87.1. Downloading test_resource file failed: Caught Error Domain%3DNSURLErrorDomain Code%3D-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo%3D{NSErrorFailingURLStringKey%3Dhttps://my-url/reource.bin, NSLocalizedRecoverySuggestion%3DWould you like to connect to the server anyway?, _kCFStreamErrorDomainKey%3D3, _NSURLErrorFailingURLSessionTaskErrorKey%3DLocalDownloadTask &lt;A50DCF0E-38F3-4454-A78A-B4552336561E&gt;.&lt;1&gt;, _NSURLErrorRelatedURLSessionTaskErrorKey%3D( ), NSLocalizedDescription%3DAn SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey%3Dhttps://my-url/reource.bin, NSUnderlyingError%3D0x2882e1050 {Error Domain%3DkCFErrorDomainCFNetwork Code%3D-1200 "(null)" UserInfo%3D{_kCFStreamPropertySSLClientCertificateState%3D0, _kCFNetworkCFStreamSSLErrorOriginalValue%3D-9816, _kCFStreamErrorDomainKey%3D3, _kCFStreamErrorCodeKey%3D-9816, _NSURLErrorNWPathKey%3Dsatisfied (Path is satisfied), viable, interface: en0, ipv4, dns}}, _kCFStreamErrorCodeKey%3D-9816} _kCFNetworkCFStreamSSLErrorOriginalValue=-9816 _kCFStreamErrorDomainKey=3 _kCFStreamErrorCodeKey=-9816 We've tried nscurl --ats-diagnostics on the URL: Configuring ATS Info.plist keys and displaying the result of HTTPS loads to https:/url-path. A test will "PASS" if URLSession:task:didCompleteWithError: returns a nil error. ============================================================== Default ATS Secure Connection --- ATS Default Connection ATS Dictionary: {} Result : PASS --- ============================================================== Allowing Arbitrary Loads --- Allow All Loads ATS Dictionary: {     NSAllowsArbitraryLoads = true; } Result : PASS --- ================================================================================ Configuring TLS exceptions for url --- TLSv1.3 ATS Dictionary: {     NSExceptionDomains =     {         "url" =         {             NSExceptionMinimumTLSVersion = "TLSv1.3";         };     }; } Result : FAIL Error : Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSErrorFailingURLStringKey=url, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask &lt;250D7C7A-A090-41F1-8FED-E73FCB511F41&gt;.&lt;1&gt;, _NSURLErrorRelatedURLSessionTaskErrorKey=(     "LocalDataTask &lt;250D7C7A-A090-41F1-8FED-E73FCB511F41&gt;.&lt;1&gt;" ), NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=url, NSUnderlyingError=0x6000021318f0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9836, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9836, _NSURLErrorNWPathKey=satisfied (Path is satisfied), viable, interface: lo0}}, _kCFStreamErrorCodeKey=-9836} --- ====================================== nsurl --ats-diagnostic show me another error code -9836 and like I know TLSv1.3 not necessary yet Maybe someone can give some suggestions, any help !! :pray: Thx!
2
2
2.5k
Sep ’23