aws-amplify / aws-sdk-ios

AWS SDK for iOS. For more information, see our web site:
https://aws-amplify.github.io/docs
Other
1.68k stars 885 forks source link

AWSIoT uses incorrect certificate if there are multiple with the same private key in KeyChain #4613

Closed eddieSullivan closed 1 year ago

eddieSullivan commented 1 year ago

Describe the bug

In AWSIoTManager.importIdentity, the SDK uses Apple Keychain to store a certificate "Identity" (defined as the combination of a certificate and the private key used to generate it). Later in AWSIoTDataManager.connectUsingALPN it looks the Identity up using a Keychain query operation.

The parameters to the query operation (in AWSIoTKeychain.getIdentityRef) only include attributes set on the private key. But if other parts of the app store multiple certificates generated from that same private key (a reasonable thing to do), the query can return more than one Identity -- one for each certificate.

The query is set up to only return the first result. So if the correct one is not first, the SDK tries to connect to MQTT using the wrong certificate, causing an immediate disconnect.

To Reproduce Steps to reproduce the behavior:

  1. Generate a private key
  2. Generate two certificates based on that same private key
  3. Store the private key and the first certificate in the keychain
  4. Pass the private key and the second certificate to AWSIoTManager.importIdentity (after converting them to p12 format)
  5. Try to connect to MQTT in the normal way
  6. Observe MQTT fail to connect

If you reverse steps 3 and 4, MQTT successfully connects. Keychain seems to return items in the order they were inserted.

Observed Behavior MQTT uses the wrong certificate

Expected Behavior MQTT should include the certificate tag in the kSecAttrLabel parameter when doing the lookup, so as to use the right certificate

Stack Trace N/A

Code Snippet I don't have a simplified code snippet to share, but the reproduction steps above describe the issue.

Unique Configuration The unique aspect of our configuration is our use of multiple certificates with the same private key. There are many reasons an app might want to do this and it would be difficult for us to change this behavior.

Areas of the SDK you are using (AWSMobileClient, Cognito, Pinpoint, IoT, etc)? AWSIoT

Screenshots N/A

Environment(please complete the following information):

Device Information (please complete the following information):

Additional context I have a patch to fix it, which we're applying using cocoapods patch. I plan to open a PR, but there is some work involved in getting unit tests working, so it may take some time. I'll add the patch to this issue in case someone else already has a development environment set up and wants to do the fix.

eddieSullivan commented 1 year ago

AWSIoT+2.30.2.diff.patch

atierian commented 1 year ago

Thanks for opening this issue @eddieSullivan. Let us know if there's anything we can do to help move the patch along. If you open a PR with your fix, we can help with testing.

eddieSullivan commented 1 year ago

@atierian thanks for the quick response. I opened a PR here: https://github.com/aws-amplify/aws-sdk-ios/pull/4614

I marked it as draft because I haven't gotten unit tests set up yet. I welcome any testing help.

harsh62 commented 1 year ago

The fix has been released. Please use the latest version of the SDK.