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

266 Posts
Sort by:
Post not yet marked as solved
3 Replies
388 Views
We generated key pair and imported associated cert into keychain. We stored value of kSecAttrPublicKeyHash and use it to find matching certificate and private key later. However we have some legacy code that requests to get SecIdentityRef. We can retrieve SecCertificateRef with matched value of kSecAttrPublicKeyHash and private key with kSecAttrApplicationLabel. But we don't know how to generate/query SecIdentityRef with SecCertificateRef and SecKeyRef. API SecIdentityCreateWithCertificate is only available on macOS. Is there any equivalent API on iOS? Thanks, Ying
Posted
by yingha.
Last updated
.
Post not yet marked as solved
0 Replies
312 Views
My organization is using mutual TLS authentication for HTTPS, with PIV cards storing the certs. We observe that some OS X devices send only the leaf certs when establishing the mTLS connection, whereas others send the entire chain. We cannot validate the leaf cert without the intermediate cert, so those clients are rejected. What drives the decision whether to send the whole chain, vs the leaf cert only? For more details, and some things we observed. The PIV cards are US DoD CAC cards: https://www.cac.mil/common-access-card/ The client cert chain on the card looks like this: Leaf client cert, CN=LastName.Name Intermediate cert, CN=DOD ID CA-70 "Root" cert, CN=DoD Root CA 6 through 8.: Additional interoperability certs. Our system is set up to trust the "root" cert CN=DoD Root CA 6. Neither the leaf cert, nor other certs in the chain are trusted by Apple Keychain Trust Store by default. We find that most laptops will send the entire chain, 1 through 8, when establishing the mTLS connection with our servers. This allows us to validate them correctly. On a subset of OS X devices, Google Chrome will only send the leaf chain. This happens even when we use exact same PIV card, and exact same PIV reader as on working laptops. Safari will not send any cert at all. We found that if we explicitly add the CN=DoD Root CA 6 to the Apple Trust Store, Google Chrome and Safari will start sending a short chain, containing only certs 1 through 3. This allows the server to validate them. When we remove it from Trust Store, Chrome is back to sending only leaf, but Safari will not even send the leaf. Again, this only happens on some laptops; on most of the laptops, both Safari and Google Chrome will send the entire chain, regardless of whatever is set up in Trust Store. My suspicion is that for some reason, on those laptops, Safari will not send the client certs that OS X doesn't trust. This makes sense, but this is not the behavior we want. We want the same behavior on the working laptops, which is to send the whole chain. All of our laptops are on OS X 14.4
Posted Last updated
.
Post not yet marked as solved
14 Replies
2k Views
Hi, An existing app on AppStore have issue with SHA256 Hash only since iOS17.4. And only Pro and Pro Max seems affected by this issue. NSData is read from downloaded file. Hash is calculated with unsigned char *CC_SHA256(const void *data, CC_LONG len, unsigned char *md) And compared with original HASH It appears different only on iOS17.4 and only Pro and Pro Max. But i can't reproduce this issue. Do you have an idea ? Thank you
Posted
by GB_fr.
Last updated
.
Post not yet marked as solved
0 Replies
6.3k Views
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.
Posted
by eskimo.
Last updated
.
Post marked as solved
5 Replies
693 Views
We generate key pair and import cert with access flag kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly in our application. We then have notification extension that access shared keychain to retrieve the identity when device is locked. We use SecItemCopyMatching to get all SecIdentity with its attributes as below: let queryDict: [String: Any] = [ kSecClass as String: kSecClassIdentity, kSecReturnAttributes as String: true, kSecReturnRef as String: true, kSecMatchLimit as String: kSecMatchLimitAll ] var oss = SecItemCopyMatching(queryDict as CFDictionary, &attrs) When the code runs on notification extension with locked device, it failed on some devices (not on all devices) with error -25308. The sysdiagnose shows: default securityd 2024-03-14 10:49:13.844996 -0400 129 0x110115 SecDbKeychainItemV7: cannot decrypt metadata key because the keychain is locked (-25308) default securityd 2024-03-14 10:49:13.845036 -0400 129 0x110091 NSExtension[2222]/1#7 LF=0 copy_matching Error Domain=NSOSStatusErrorDomain Code=-25308 "ks_crypt: e00002e2 failed to 'od' item (class 6, bag: 0) Access to item attempted while keychain is locked." UserInfo={numberOfErrorsDeep=0, NSDescription=ks_crypt: e00002e2 failed to 'od' item (class 6, bag: 0) Access to item attempted while keychain is locked.} We also try to use access flag kSecAttrAccessibleAlwaysThisDeviceOnly, but it doesn't make difference. Since securityd reports "cannot decrypt metadata key because keychain is locked". I wonder if it is because we query attributes for all identity. Is it a bug on Security framework? Thanks, Ying
Posted
by yingha.
Last updated
.
Post not yet marked as solved
1 Replies
227 Views
Hi, I am trying to create a secKey from a .p8 file which I will then use to sign some data. I'm targeting an iOS application. I understand I cannot use the p8 key directly with iOS APIs and will have to unwrap the p8 file before I can feed it to SecKeyCreateWithData I'm unsure how to go about doing it though and any help will be appreciated. For context it is the APNS p8 file.
Posted
by kir4anT.
Last updated
.
Post marked as solved
2 Replies
365 Views
Is it possible? The original key was generated and stored in the Keychain using the following code: func generateSecureEnclaveProtectedSecKey(withTag tag: Data) throws -> SecKey { var error: Unmanaged<CFError>? let accessControl = SecAccessControlCreateWithFlags( kCFAllocatorDefault, kSecAttrAccessibleWhenUnlockedThisDeviceOnly, [.privateKeyUsage], &error )! let attributes = [ kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeySizeInBits as String: 256, kSecAttrTokenID as String: kSecAttrTokenIDSecureEnclave, kSecPrivateKeyAttrs as String: [ kSecAttrCanSign as String: true, kSecAttrIsPermanent as String: true, kSecAttrApplicationTag as String: tag, kSecAttrAccessControl as String: accessControl, ] as [String: Any], ] as [String: Any] let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error)! return privateKey } Then I wanted to use the strongly typed interface of CryptoKit, so I naively tried to get a hold of the existing key as follows (querying for kSecReturnPersistentRef and not kSecReturnRef): func getSecureEnclaveProtectedCryptoKitKey(fromSecureEnclaveProtectedSecKeyWithTag tag: Data) throws -> SecureEnclave.P256.Signing.PrivateKey { let query: [String: Any] = [ kSecClass as String: kSecClassKey, kSecAttrApplicationTag as String: tag, kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom, kSecReturnPersistentRef as String: true, ] var item: CFTypeRef? let status = SecItemCopyMatching(query as CFDictionary, &item) let keyData = item as! CFData return try SecureEnclave.P256.Signing.PrivateKey(dataRepresentation: keyData as Data) } But that resulted in: Error Domain=CryptoTokenKit Code=-3 "corrupted objectID detected" UserInfo={NSLocalizedDescription=corrupted objectID detected} Since this is a Secure Enclave protected key, it is not possible to use SecKeyCopyExternalRepresentation (or query for kSecReturnData), but perhaps there is another way to convert a SecKey object to a SecureEnclave.P256.Signing.PrivateKey? The other way around seem to be possible using the answers to this blog post: https://developer.apple.com/forums/thread/728314
Posted
by Smed1.
Last updated
.
Post marked as solved
3 Replies
475 Views
I am new to iOS development, and recently I was trying to build an application, which will create a key inside the secure element, and after - I will sing something with it. While developing I've encountered an issue: the key generation fails if there is a flag .biometryAny or .biometryCurrentSet The authentication itself is triggered, but the function still throws a mistake. My setup - Xcode iPhone15 simulator, FaceID enrolled and the animation of it is working. Ive created the same post on overflow, in case somebody will have the same issues: https://stackoverflow.com/questions/78175858/secure-enclave-key-generation-failure I've tried deleting the flag, while keeping the manual authorisation, and this approach works, but I still would like have maximum security. THIS WORKS: func authenticateUser(completion: @escaping (Bool, Error?) -> Void) { let context = LAContext() var error: NSError? if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) { let reason = "Biometric authentication is needed to access your secure data." context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) { success, authenticationError in DispatchQueue.main.async { completion(success, authenticationError) } } } else { // Biometry is not available or not enrolled. DispatchQueue.main.async { completion(false, error) } } } @objc func encryptAction() { authenticateUser { [weak self] (success, error) in guard success else { self?.outputLabel.text = "Authentication failed: \(error?.localizedDescription ?? "Unknown error")" return } guard let randomNumber = self?.inputTextField.text, !randomNumber.isEmpty, let dataToSign = randomNumber.data(using: .utf8), let privateKey = self?.generatePrivateKey() else { self?.outputLabel.text = "Error: Could not generate private key." return } if let signature = self?.signData(privateKey: privateKey, data: dataToSign) { self?.outputLabel.text = "Signature: \(signature.base64EncodedString())" } else { self?.outputLabel.text = "Error: Could not sign data." } } } func generatePrivateKey() -> SecKey? { // 1. Create Keys Access Control guard let accessControl = SecAccessControlCreateWithFlags( nil, kSecAttrAccessibleWhenUnlockedThisDeviceOnly, [.privateKeyUsage], nil) else { fatalError("cannot set access control") } // 2. Create Key Attributes guard let tag = "com.example.keys.mykey".data(using: .utf8) else { fatalError("cannot set tag") } let attributes: [String: Any] = [ kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeySizeInBits as String: 256, kSecAttrTokenID as String: kSecAttrTokenIDSecureEnclave, kSecPrivateKeyAttrs as String: [ kSecAttrIsPermanent as String: true, kSecAttrApplicationTag as String: tag, kSecAttrAccessControl as String: accessControl ] ] // 3. Generate Key Pairs var error: Unmanaged<CFError>? guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else { if let error = error?.takeRetainedValue() { print("Error creating a key: \(error)") } return nil } return privateKey } func signData(privateKey: SecKey, data: Data) -> Data? { let digest = sha256(data: data) var error: Unmanaged<CFError>? guard let signature = SecKeyCreateSignature(privateKey, .ecdsaSignatureMessageX962SHA256, digest as CFData, &error) as Data? else { print(error!.takeRetainedValue() as Error) return nil } return signature } } THIS DOESN'T guard let accessControl = SecAccessControlCreateWithFlags( nil, kSecAttrAccessibleWhenUnlockedThisDeviceOnly, [.privateKeyUsage, .biometryCurrentSet], nil) else { info.something file is updated and there is a privacy FaceID field included. the error is triggered at this part: var error: Unmanaged<CFError>? guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else { if let error = error?.takeRetainedValue() { print("Error creating a key: \(error)") } return nil } The error itself: Error creating a key: Error Domain=NSOSStatusErrorDomain Code=-25293 "Key generation failed, error -25293" UserInfo={numberOfErrorsDeep=0, NSDescription=Key generation failed, error -25293}
Posted
by VKrivkov.
Last updated
.
Post not yet marked as solved
0 Replies
300 Views
Keychain is a bit of a ‘call driver’ for DTS. I’ve sent instructions like this to many developers over the years. Today I decided to write it down for everyone’s benefit. If you have questions or comments, put them in a new thread here on DevForums. Tag it with Security so that I see it. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Investigating hard-to-reproduce keychain problems SecItem is the primary API for the keychain on all Apple platforms. If you’re getting started with that API, I have two DevForums posts that you’ll find useful: SecItem: Fundamentals SecItem: Pitfalls and Best Practices Also, if you’re on macOS, make sure to read TN3137 On Mac keychain APIs and implementations. Every now and again folks encounter a hard-to-reproduce keychain problem. For example, you might have code that works most of the time but fails for some users in the field. This failure might be seen regularly by some users, or it might happen sporadically across all your users. Problems like this are often caused by a bug in the system itself, but the SecItem API is sufficiently tricky that I’ve seen cases of this where the actual problem was a bug in the developer’s code. This post outlines a process for investigating such problems. I’ve helped a number of developers use it to good effect, and I figured I should share it for the enjoyment of all (hey hey!). This process depends on the system log. If you’re not best friends with the system log, you should be! See Your Friend the System Log. This process is a special case of the process I describe in Using a Sysdiagnose Log to Debug a Hard-to-Reproduce Problem. Read that before continuing. Unwrap the wrapper Many developers use a wrapper around the SecItem API. Such wrappers make it hard to investigate problems like this. For example, you might call a wrapper routine that returns a password string or nil if there’s a failure. That means you can’t distinguish between an expected nil, where the password hasn’t been saved yet, or a weird error. If you need to debug a hard-to-reproduce keychain problem, look through the wrapper to find the calls to Apple’s SecItem APIs. It’s fine to leave your wrapper in place, but do this debugging at the SecItem level. Add before and after log points The basic strategy here is: Add a log point before the call to the SecItem API, including the parameters that you’ll pass in. Add a log point after the call to the SecItem API, including the returned error code and any response you got. This is trickier than it might seem due to the way that the SecItem API is structured. Consider this example: func copyAccountPassword(_ userName: String) -> String? { var copyResult: CFTypeRef? = nil let err = SecItemCopyMatching([ kSecClass: kSecClassGenericPassword, kSecAttrService: "WaffleVarnish", kSecAttrAccount: userName, kSecReturnData: true, ] as NSDictionary, &copyResult) guard err == errSecSuccess, let result = String(data: copyResult! as! Data, encoding: .utf8) else { return nil } return result } There are a bunch of issues here: The query dictionary is created inline, so it’s not easy to log it. The query dictionary contains the kSecAttrAccount property, which is likely to hold private data. The query can fail, leaving copyResult set to nil. The query can work but return invalid data. In this case the function will return nil but there’s no error. The password is obviously private data. WARNING Be careful when logging keychain data. The whole point of the keychain is to protect the user’s secrets. It would be bad to then go and log those secrets to the system log. Here’s an updated version of that routine: func copyAccountPasswordWithLogging(_ userName: String) -> String? { let query = [ kSecClass: kSecClassGenericPassword, kSecAttrService: "WaffleVarnish", kSecAttrAccount: userName, kSecReturnData: true, ] as NSDictionary var copyResult: CFTypeRef? = nil log.log("will copy account password, query: \(query)") let err = SecItemCopyMatching(query, &copyResult) guard err == errSecSuccess else { log.log("did not copy account password, err: \(err)") return nil } guard let result = String(data: copyResult! as! Data, encoding: .utf8) else { log.log("did not copy account password, malformed") return nil } log.log("did copy account password") return result } This example assumes that log is a value of type Logger. Redact private data This new code isn’t perfect: The query value is considered private data and not recorded in the log. It logs nothing about the resulting password. Addressing the second problem is a challenge. You could do something creative like log a salted hash of the password but, honestly, I think it’s best to err on the side of caution here. You might try to fix the first problem with code like this: !!! DO NOT DO THIS !!! log.log("will copy account password, query: \(query, privacy: .public)") !!! DO NOT DO THIS !!! However, that’s problematic because it logs the account value (kSecAttrAccount) when it should be redacted. What you do about this depends on the scope of your deployment: If you’re targeting an internal test harness, you might choose to leave it as is. The machines on the test harness don’t have any truly private data. If this code is going to be used by actual humans, you must further redact your logging. For example, you might write a helper like this: func redactedQuery(_ query: NSDictionary) -> String { let query = query.mutableCopy() as! NSMutableDictionary if query.object(forKey: kSecAttrAccount as NSString) != nil { query.setObject("REDACTED", forKey: kSecAttrAccount as NSString) } return "\(query)" } You’ll have to customise this code for your specific use case. For example, your code might put information that’s not private into kSecAttrAccount — in many of my projects, I use a fixed string for this — and so redacting that might be pointless. OTOH, your code might put private information into other properties. If you call a SecItem API that returns a dictionary, you’ll need a similar redactedResponse(_:) routine for that response. Test your logging The next step is to test your logging. Make sure that the stuff you want logged is logged and the stuff you don’t want logged is not. Test outside of Xcode, because Xcode automatically captures private data. Look in the log When you get a sysdiagnose log back from a user having this problem, unpack and open the system log snapshot. Find all the log entry pairs created by your before and after log points. Then look for the most recent one that illustrates the problem you’re investigating. To learn more about the cause of this problem, look for other log entries of interest between those two points. When looking at keychain-related log entries, keep in mind that most of the Security framework is open source. If you’re curious what a log entry means, search the source to see the context. Note Darwin open source won’t always exactly match the source in the corresponding OS version. Also, the Security framework is only part of the story here, and some other subsystems that are relevant to the keychain aren’t open source. However, my experience is that looking at the source is super useful. If you find that log entries are missing, remember that the system log purges older log entries to make room for newer ones. That’s why it’s important to take your sysdiagnose as soon as possible after encountering the problem. If you escalate this problem to Apple — via a bug report, a DTS tech support incident, or whatever — make sure to include: Your sysdiagnose log The exact timestamps of your before and after log entries We may not need this level of information, but in many cases it really helps.
Posted
by eskimo.
Last updated
.
Post not yet marked as solved
4 Replies
1.3k Views
I am trying to use SecItemUpdate in order to change the kSecAttrAccessControl value on a private key protected by the Secure Enclave as well as an .applicationPassword - which I want to change. I have been unsuccessful getting the query and attributesToUpdate dictionaries right though, with SecItemUpdate returning either errSecParam, errSecNoSuchAttr or errSecAuthFailed. Am I on the right track here or am I trying to do something that is not possible?
Posted
by jzilske.
Last updated
.
Post not yet marked as solved
0 Replies
237 Views
If on iOS an app protects a keychain item with an access control list that specifies .biometryCurrentSet in its SecAccessControlCreateFlags the app loses access to the item if the set of currently enrolled fingers (for Touch ID) or the currently enrolled user (for Face ID) changes - which corresponds to a change of the evaluatedPolicyDomainState. We have users reporting loss of such items even though - as they assure us - they have not touched (no pun intended) anything under "[Touch|Face] ID & Code" in Preferences.app. Is there another reason why an app may lose access to such items?
Posted
by jzilske.
Last updated
.
Post not yet marked as solved
1 Replies
352 Views
I have an Endpoint system extension that, in theory, receives XProtect alerts. I regularly see XProtectPluginService starting programs like XProtecteRemediatorSheepSwap on my Mac. I would love to be able to put one or more files/bundles on my Mac that triggers the detectors, so I can see the alerts go from the Endpoint system extension through to the UI. Does Apple have or recommend a way (short of being infected) for triggering the XProtect detectors for testing?
Posted Last updated
.
Post not yet marked as solved
0 Replies
300 Views
Can someone share how secure is the communication between iOS app and its safari mobile extension. Is it encrypted? Are there any references to best practices to follow? If a user has opened multiple tabs and has multiple extensions can there be security issues during their communication like one extension able to read other extensions memory?
Posted
by vmvinoth.
Last updated
.
Post not yet marked as solved
3 Replies
435 Views
I am encountering an issue with accessing the system keychain on macOS [macOS 13.6.3]. When running our product, the following error message is logged: [com.apple.securityd:secitemratelimit] Not internal release, disabling SIRL [com.apple.securityd:keychain] System Keychain Always Supported set via feature flag to disabled As a result, our product is unable to access the system keychain, which is impacting functionality. Note: In many other devices this issue is not seen. Steps to Reproduce: The moment pkg is installed it creates a key in keychain. For an affected device SecItemCopyMatching is returning errSecInteractionNotAllowed Question: Is there a way to enable the system keychain access or address the issue with the feature flag being disabled? Are there any suggestions or recommendations for handling this case? Any assistance or guidance on resolving this issue would be greatly appreciated. Thank you in advance for your help.
Posted
by mpatole.
Last updated
.
Post not yet marked as solved
5 Replies
369 Views
I'm working on an app that uses CommonCrypto. The app works perfectly well in my own computer, but when using the very same exe build in another computer it "quit unexpectedly". Suspecting that the issue could be on the said module, I commented out the few lines that requires the module and problem solved!. Now, as I need to use the module at the very beginning of the app, to perform certain security operations, I'm wondering what could I do to assure the module is included in the build, so the app may work in any other computer as well. This sounds weird, because I would had assumed either that the module was to be included in the build or if not, an error claiming the lack of it should have been produced. (within Xcode) what setting should I change when build the app for use in other computers, so to assure the operations that requires this module can be completed? Although this may not be relevant, I'm using swift 5, Xcode 15 (latest versions) and Sonoma 14.2.1
Posted
by Lautarob1.
Last updated
.
Post not yet marked as solved
5 Replies
555 Views
I'm new to Networking, so forgive me if this is a silly question: In the sample code, Building a custom peer-to-peer protocol, TLS is configured as follows: // Create TLS options using a passcode to derive a pre-shared key. private static func tlsOptions(passcode: String) -> NWProtocolTLS.Options { let tlsOptions = NWProtocolTLS.Options() let authenticationKey = SymmetricKey(data: passcode.data(using: .utf8)!) var authenticationCode = HMAC<SHA256>.authenticationCode(for: "TicTacToe".data(using: .utf8)!, using: authenticationKey) let authenticationDispatchData = withUnsafeBytes(of: &authenticationCode) { (ptr: UnsafeRawBufferPointer) in DispatchData(bytes: ptr) } sec_protocol_options_add_pre_shared_key(tlsOptions.securityProtocolOptions, authenticationDispatchData as __DispatchData, stringToDispatchData("TicTacToe")! as __DispatchData) sec_protocol_options_append_tls_ciphersuite(tlsOptions.securityProtocolOptions, tls_ciphersuite_t(rawValue: TLS_PSK_WITH_AES_128_GCM_SHA256)!) return tlsOptions } The sample code touts the connection as secure ("...uses Bonjour and TLS to establish secure connections between nearby devices"), but to my untrained eye it doesn't seem so. My reasoning is as follows: If I adapt this code as-is, so connections between two instances of my app use SymmetricKeys derived from the four-digit passcode, then wouldn't my encryption be easy to break by an adversary who sends 0000...9999 and records corresponding changes in the encryption, exposing my app to all sorts of attacks? The sample uses the passcode to validate the connection (host user shows client user the passcode, which is manually entered), which is a feature I would like to keep in some form or another, which is why this is causing so many headaches. Generally speaking, is there a way to secure a local peer-to-peer connection over Network.framework that doesn't involve certificates? If certificates are the only way, are there good resources you can recommend?
Posted
by wmk.
Last updated
.
Post not yet marked as solved
1 Replies
226 Views
Hello. Here is my Swift code to generate RSA public / private key static func createPrivateKey()-> (SecKey?, SecKey?){ let attributes: [CFString: Any] = [ kSecAttrKeyType: kSecAttrKeyTypeRSA, kSecAttrKeySizeInBits: 2048, kSecPrivateKeyAttrs: [ kSecAttrIsPermanent: true, kSecAttrApplicationTag: "tagData" ] ] var error: Unmanaged<CFError>? guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error), let publicKey = SecKeyCopyPublicKey(privateKey) else { NSLog("\tError generating keypair. %@", "\(error!.takeRetainedValue().localizedDescription)") return (nil, nil) } return (privateKey, publicKey) } static func printRSAPublicKey(_ publicKey: SecKey) { guard let publicKeyData = SecKeyCopyExternalRepresentation(publicKey, nil) as Data? else { print("Failed to get public key data.") return } print("RSA Public Key:") print(publicKeyData.base64EncodedString()) } I got public key but it does not work I got stuck there.
Posted
by iGold.
Last updated
.