Skip to content

Commit 828ffa4

Browse files
authored
chore: Update the keychain attribute to AccessibleAfterFirstUnlockThisDeviceOnly (#4159)
1 parent ea2cdeb commit 828ffa4

File tree

9 files changed

+92
-9
lines changed

9 files changed

+92
-9
lines changed

AWSCognitoAuth/Internal/UICKeyChainStore/AWSCognitoAuthUICKeyChainStore.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ - (instancetype)initWithServer:(NSURL *)server protocolType:(AWSCognitoAuthUICKe
116116

117117
- (void)commonInit
118118
{
119-
_accessibility = AWSCognitoAuthUICKeyChainStoreAccessibilityAfterFirstUnlock;
119+
_accessibility = AWSCognitoAuthUICKeyChainStoreAccessibilityAfterFirstUnlockThisDeviceOnly;
120120
}
121121

122122
#pragma mark -

AWSCore/UICKeyChainStore/AWSUICKeyChainStore.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ - (instancetype)initWithServer:(NSURL *)server protocolType:(AWSUICKeyChainStore
116116

117117
- (void)commonInit
118118
{
119-
_accessibility = AWSUICKeyChainStoreAccessibilityAfterFirstUnlock;
119+
_accessibility = AWSUICKeyChainStoreAccessibilityAfterFirstUnlockThisDeviceOnly;
120120
}
121121

122122
#pragma mark -

AWSIoT/AWSIoTKeyChainTypes.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//
2+
// Copyright 2010-2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License").
5+
// You may not use this file except in compliance with the License.
6+
// A copy of the License is located at
7+
//
8+
// http://aws.amazon.com/apache2.0
9+
//
10+
// or in the "license" file accompanying this file. This file is distributed
11+
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
// express or implied. See the License for the specific language governing
13+
// permissions and limitations under the License.
14+
//
15+
16+
#import <Foundation/Foundation.h>
17+
18+
@class AWSIoTMessage;
19+
20+
NS_ASSUME_NONNULL_BEGIN
21+
22+
typedef NS_ENUM(NSInteger, AWSIoTKeyChainAccessibility) {
23+
AWSIoTKeyChainAccessibilityWhenUnlocked = 1,
24+
AWSIoTKeyChainAccessibilityAfterFirstUnlock,
25+
AWSIoTKeyChainAccessibilityAlways,
26+
AWSIoTKeyChainAccessibilityWhenPasscodeSetThisDeviceOnly,
27+
AWSIoTKeyChainAccessibilityWhenUnlockedThisDeviceOnly,
28+
AWSIoTKeyChainAccessibilityAfterFirstUnlockThisDeviceOnly,
29+
AWSIoTKeyChainAccessibilityAlwaysThisDeviceOnly,
30+
};
31+
32+
NS_ASSUME_NONNULL_END

AWSIoT/AWSIoTManager.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
//
1515

1616
#import "AWSIoTService.h"
17+
#import "AWSIoTKeyChainTypes.h"
1718

1819
//CreateCertificateWithResponse
1920
@interface AWSIoTCreateCertificateResponse : AWSModel
@@ -217,4 +218,6 @@
217218
*/
218219
+ (BOOL)deleteCertificate;
219220

221+
+ (void)setKeyChainAccessibility:(AWSIoTKeyChainAccessibility)accessibility;
222+
220223
@end

AWSIoT/AWSIoTManager.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,4 +382,8 @@ + (BOOL)isValidCertificate:(NSString *)certificateId {
382382
return [AWSIoTKeychain isValidCertificate:[NSString stringWithFormat:@"%@%@",[AWSIoTKeychain privateKeyTag], certificateId ]];
383383
}
384384

385+
+ (void)setKeyChainAccessibility:(AWSIoTKeyChainAccessibility)accessibility {
386+
[AWSIoTKeychain setKeyChainAccessibility:accessibility];
387+
}
388+
385389
@end

AWSIoT/Internal/AWSIoTKeychain.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#import <Security/Security.h>
1919
#import <CommonCrypto/CommonDigest.h>
2020
#import <CommonCrypto/CommonCryptor.h>
21+
#import "AWSIoTKeyChainTypes.h"
2122

2223
FOUNDATION_EXPORT NSString *const AWSIoTKeychainStartPrivateKeyTag;
2324
FOUNDATION_EXPORT NSString *const AWSIoTKeychainEndPrivateKeyTag;
@@ -59,4 +60,6 @@ FOUNDATION_EXPORT NSString *const AWSIoTKeychainEndCertKeyTag;
5960
+ (BOOL)addPrivateKey:(NSData *)privkey tag:(NSString *)tag;
6061
+ (BOOL)deletePrivateKeyWithTag:(NSString*)tag;
6162

63+
+ (void)setKeyChainAccessibility:(AWSIoTKeyChainAccessibility)accessibility;
64+
6265
@end

AWSIoT/Internal/AWSIoTKeychain.m

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
NSString *const AWSIoTKeychainStartCertKeyTag = @"-----BEGIN CERTIFICATE-----\n";
2323
NSString *const AWSIoTKeychainEndCertKeyTag = @"\n-----END CERTIFICATE-----";
2424

25+
static AWSIoTKeyChainAccessibility _accessibility = AWSIoTKeyChainAccessibilityAfterFirstUnlockThisDeviceOnly;
26+
2527
@implementation AWSIoTKeychain
2628

2729
+ (NSString*)publicKeyTag {
@@ -205,6 +207,7 @@ + (BOOL)addCertificateRef:(SecCertificateRef)certRef {
205207
[queryCertificate setObject:(id)kSecClassCertificate forKey:(id)kSecClass];
206208
[queryCertificate setObject:[AWSIoTKeychain certTag] forKey:(id)kSecAttrLabel];
207209
[queryCertificate setObject:(__bridge id)certRef forKey:(id)kSecValueRef];
210+
[queryCertificate setObject:(__bridge id)[AWSIoTKeychain accessibilityType] forKey:(id)kSecAttrAccessible];
208211

209212
OSStatus sanityCheck = SecItemAdd((CFDictionaryRef)queryCertificate, nil);
210213
if ((sanityCheck != noErr) && (sanityCheck != errSecDuplicateItem)) {
@@ -226,7 +229,8 @@ + (BOOL)addCertificate:(NSData*)cert withTag:(NSString*)tag {
226229
[queryCertificate setObject:(id)kSecClassCertificate forKey:(id)kSecClass];
227230
[queryCertificate setObject:tag forKey:(id)kSecAttrLabel];
228231
[queryCertificate setObject:(__bridge id)certRef forKey:(id)kSecValueRef];
229-
232+
[queryCertificate setObject:(__bridge id)[AWSIoTKeychain accessibilityType] forKey:(id)kSecAttrAccessible];
233+
230234
OSStatus sanityCheck = SecItemAdd((CFDictionaryRef)queryCertificate, nil);
231235
if ((sanityCheck != noErr) && (sanityCheck != errSecDuplicateItem)) {
232236
AWSDDLogError(@"add certificate to keychain with error: %d", (int)sanityCheck);
@@ -394,7 +398,8 @@ + (BOOL)addPublicKeyRef:(SecKeyRef)pubkeyRef tag:(NSString*)tag {
394398
[publicKeyAttr setObject:(__bridge id _Nonnull)(pubkeyRef) forKey:(id)kSecValueRef];
395399
[publicKeyAttr setObject:(id)kSecAttrKeyClassPublic forKey:(id)kSecAttrKeyClass];
396400
[publicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnPersistentRef];
397-
401+
[publicKeyAttr setObject:(__bridge id)[AWSIoTKeychain accessibilityType] forKey:(id)kSecAttrAccessible];
402+
398403
sanityCheck = SecItemAdd((CFDictionaryRef) publicKeyAttr, (CFTypeRef *)&persistPeer);
399404
if ((sanityCheck != noErr) && (sanityCheck != errSecDuplicateItem)){
400405
AWSDDLogError(@"addPublicKeyRef error: %d",(int)sanityCheck);
@@ -417,7 +422,8 @@ + (BOOL)addPublicKey:(NSData*)pubkey tag:(NSString*)tag {
417422
[publicKeyAttr setObject:pubkey forKey:(id)kSecValueData];
418423
[publicKeyAttr setObject:(id)kSecAttrKeyClassPublic forKey:(id)kSecAttrKeyClass];
419424
[publicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnPersistentRef];
420-
425+
[publicKeyAttr setObject:(__bridge id)[AWSIoTKeychain accessibilityType] forKey:(id)kSecAttrAccessible];
426+
421427
sanityCheck = SecItemAdd((CFDictionaryRef) publicKeyAttr, (CFTypeRef *)&persistPeer);
422428
if ((sanityCheck != noErr) && (sanityCheck != errSecDuplicateItem)){
423429
AWSDDLogError(@"addPublicKey error: %d",(int)sanityCheck);
@@ -440,7 +446,8 @@ + (BOOL)addPrivateKeyRef:(SecKeyRef)privkeyRef tag:(NSString*)tag {
440446
[privateKeyAttr setObject:(__bridge id _Nonnull)(privkeyRef) forKey:(id)kSecValueRef];
441447
[privateKeyAttr setObject:(id)kSecAttrKeyClassPrivate forKey:(id)kSecAttrKeyClass];
442448
[privateKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnPersistentRef];
443-
449+
[privateKeyAttr setObject:(__bridge id)[AWSIoTKeychain accessibilityType] forKey:(id)kSecAttrAccessible];
450+
444451
sanityCheck = SecItemAdd((CFDictionaryRef) privateKeyAttr, (CFTypeRef *)&persistPeer);
445452
if ((sanityCheck != noErr) && (sanityCheck != errSecDuplicateItem)){
446453
AWSDDLogError(@"addPrivateKeyRef error: %d",(int)sanityCheck);
@@ -463,7 +470,8 @@ + (BOOL)addPrivateKey:(NSData*)privkey tag:(NSString*)tag {
463470
[privateKeyAttr setObject:privkey forKey:(id)kSecValueData];
464471
[privateKeyAttr setObject:(id)kSecAttrKeyClassPrivate forKey:(id)kSecAttrKeyClass];
465472
[privateKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnPersistentRef];
466-
473+
[privateKeyAttr setObject:(__bridge id)[AWSIoTKeychain accessibilityType] forKey:(id)kSecAttrAccessible];
474+
467475
sanityCheck = SecItemAdd((CFDictionaryRef) privateKeyAttr, (CFTypeRef *)&persistPeer);
468476
if ((sanityCheck != noErr) && (sanityCheck != errSecDuplicateItem)){
469477
AWSDDLogError(@"addPrivateKey error: %d",(int)sanityCheck);
@@ -524,4 +532,29 @@ + (BOOL)deletePrivateKeyWithTag:(NSString*)tag {
524532
return YES;
525533
}
526534

535+
+ (void)setKeyChainAccessibility:(AWSIoTKeyChainAccessibility)accessibility {
536+
_accessibility = accessibility;
537+
}
538+
539+
+ (CFTypeRef)accessibilityType {
540+
switch (_accessibility) {
541+
case AWSIoTKeyChainAccessibilityWhenUnlocked:
542+
return kSecAttrAccessibleWhenUnlocked;
543+
case AWSIoTKeyChainAccessibilityAfterFirstUnlock:
544+
return kSecAttrAccessibleAfterFirstUnlock;
545+
case AWSIoTKeyChainAccessibilityAlways:
546+
return kSecAttrAccessibleAlways;
547+
case AWSIoTKeyChainAccessibilityWhenPasscodeSetThisDeviceOnly:
548+
return kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly;
549+
case AWSIoTKeyChainAccessibilityWhenUnlockedThisDeviceOnly:
550+
return kSecAttrAccessibleWhenUnlockedThisDeviceOnly;
551+
case AWSIoTKeyChainAccessibilityAfterFirstUnlockThisDeviceOnly:
552+
return kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;
553+
case AWSIoTKeyChainAccessibilityAlwaysThisDeviceOnly:
554+
return kSecAttrAccessibleAlwaysThisDeviceOnly;
555+
default:
556+
return nil;
557+
}
558+
}
559+
527560
@end

AWSiOSSDKv2.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,7 @@
628628
B4B8C4BF25ACC10F0054E723 /* AWSLexConfig.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = B4B8C4BE25ACC10E0054E723 /* AWSLexConfig.xcconfig */; };
629629
B4B8C61325ACC1270054E723 /* AWSLexConfig.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = B4B8C4BE25ACC10E0054E723 /* AWSLexConfig.xcconfig */; };
630630
B4B8C9B62845CAB3009E0865 /* AWSCognitoIdentityUserPoolTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B4B8C9B52845CAB3009E0865 /* AWSCognitoIdentityUserPoolTests.m */; };
631+
B4B8C9B7284698D8009E0865 /* AWSIoTKeyChainTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = B4932E1D283D4AB100993CBC /* AWSIoTKeyChainTypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
631632
B4D61CCC23285D8C007E7A12 /* AWSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE0D416D1C6A66E5006B91B5 /* AWSCore.framework */; };
632633
B4D61CD523285DF5007E7A12 /* AWSConnectParticipant.h in Headers */ = {isa = PBXBuildFile; fileRef = B4D61CCD23285DF3007E7A12 /* AWSConnectParticipant.h */; settings = {ATTRIBUTES = (Public, ); }; };
633634
B4D61CD623285DF5007E7A12 /* AWSConnectParticipantService.h in Headers */ = {isa = PBXBuildFile; fileRef = B4D61CCE23285DF4007E7A12 /* AWSConnectParticipantService.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -3142,6 +3143,7 @@
31423143
B47FAF4222C577CE00014548 /* AWSS3TransferUtilityUnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AWSS3TransferUtilityUnitTests.m; sourceTree = "<group>"; };
31433144
B482E84522EEA9F10075A0A3 /* AWSS3TestHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AWSS3TestHelper.h; sourceTree = "<group>"; };
31443145
B482E84622EEA9F20075A0A3 /* AWSS3TestHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AWSS3TestHelper.m; sourceTree = "<group>"; };
3146+
B4932E1D283D4AB100993CBC /* AWSIoTKeyChainTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AWSIoTKeyChainTypes.h; sourceTree = "<group>"; };
31453147
B4A4DFF522B4201300379396 /* AWSSageMakerRuntime.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AWSSageMakerRuntime.framework; sourceTree = BUILT_PRODUCTS_DIR; };
31463148
B4A4DFF822B4201400379396 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
31473149
B4A4E01422B4212900379396 /* AWSSageMakerRuntimeService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSSageMakerRuntimeService.h; sourceTree = "<group>"; };
@@ -6918,6 +6920,7 @@
69186920
CE9DE6351C6A78D70060793F /* Internal */,
69196921
CE9DE6101C6A78A60060793F /* Info.plist */,
69206922
174F80A62108066F00775D0D /* AWSIoTMQTTTypes.h */,
6923+
B4932E1D283D4AB100993CBC /* AWSIoTKeyChainTypes.h */,
69216924
);
69226925
path = AWSIoT;
69236926
sourceTree = "<group>";
@@ -8168,6 +8171,7 @@
81688171
CE9DE66A1C6A78D70060793F /* AWSMQTTMessage.h in Headers */,
81698172
03427769269D185200379263 /* AWSIoTMessage+AWSMQTTMessage.h in Headers */,
81708173
174F80A72108066F00775D0D /* AWSIoTMQTTTypes.h in Headers */,
8174+
B4B8C9B7284698D8009E0865 /* AWSIoTKeyChainTypes.h in Headers */,
81718175
CE9DE6681C6A78D70060793F /* AWSMQTTEncoder.h in Headers */,
81728176
CE9DE6701C6A78D70060793F /* AWSSRWebSocket.h in Headers */,
81738177
CE9DE6641C6A78D70060793F /* AWSIoTWebSocketOutputStream.h in Headers */,

CHANGELOG.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
# AWS Mobile SDK for iOS CHANGELOG
22

33
## Unreleased
4-
54
-Features for next release
65

76
### Bug Fixes
87

98
- **AWSCognito**
10-
- Fix the parsing of providerName used in the loginMap to use the right value in case of customer endpoint is configured. (See [PR #4162](https://github.com/aws-amplify/aws-sdk-ios/pull/4162))
9+
- Fix the parsing of providerName used in the loginMap to use the right value in case of customer endpoint is configured. (See [PR #4162](https://github.com/aws-amplify/aws-sdk-ios/pull/4162))
10+
11+
### Misc. Updates
12+
13+
- **Core**
14+
- Update keychain accessibility level to `kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly` as default to keep the keychain value in the device. (See [PR #4159](https://github.com/aws-amplify/aws-sdk-ios/pull/4159))
1115

1216
## 2.27.9
1317

0 commit comments

Comments
 (0)