Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions FirebaseMessaging/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# 10.19.0
- [changed] Adopt NSSecureCoding for internal classes. (#12075)

# 10.12.0
- [changed] Removing fiam scoped tokens set by old FIAM SDK(s) from keychain if exists (b/284207019).

Expand Down
2 changes: 1 addition & 1 deletion FirebaseMessaging/Sources/Token/FIRMessagingAPNSInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ NS_ASSUME_NONNULL_BEGIN
* Represents an APNS device token and whether its environment is for sandbox.
* It can read from and write to an NSDictionary for simple serialization.
*/
@interface FIRMessagingAPNSInfo : NSObject <NSCoding, NSCopying>
@interface FIRMessagingAPNSInfo : NSObject <NSSecureCoding, NSCopying>

/// The APNs device token, provided by the OS to the application delegate
@property(nonatomic, readonly, copy) NSData *deviceToken;
Expand Down
4 changes: 4 additions & 0 deletions FirebaseMessaging/Sources/Token/FIRMessagingAPNSInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ - (id)copyWithZone:(NSZone *)zone {

#pragma mark - NSCoding

+ (BOOL)supportsSecureCoding {
return YES;
}

- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
id deviceToken = [aDecoder decodeObjectForKey:kFIRInstanceIDAPNSInfoTokenKey];
if (![deviceToken isKindOfClass:[NSData class]]) {
Expand Down
2 changes: 1 addition & 1 deletion FirebaseMessaging/Sources/Token/FIRMessagingTokenInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN
* associated with it. It can read from and write to an NSDictionary object, for
* simple serialization.
*/
@interface FIRMessagingTokenInfo : NSObject <NSCoding>
@interface FIRMessagingTokenInfo : NSObject <NSSecureCoding>

/// The authorized entity (also known as Sender ID), associated with the token.
@property(nonatomic, readonly, copy) NSString *authorizedEntity;
Expand Down
43 changes: 11 additions & 32 deletions FirebaseMessaging/Sources/Token/FIRMessagingTokenInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,11 @@ - (BOOL)isDefaultToken {
return [self.scope isEqualToString:kFIRMessagingDefaultTokenScope];
}

#pragma mark - NSCoding
#pragma mark - NSSecureCoding

+ (BOOL)supportsSecureCoding {
return YES;
}

- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
// These value cannot be nil
Expand Down Expand Up @@ -164,30 +168,13 @@ - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
if (firebaseAppID && ![firebaseAppID isKindOfClass:[NSString class]]) {
return nil;
}

id rawAPNSInfo = [aDecoder decodeObjectForKey:kFIRInstanceIDAPNSInfoKey];
if (rawAPNSInfo && ![rawAPNSInfo isKindOfClass:[NSData class]]) {
NSSet *classes = [[NSSet alloc] initWithArray:@[ FIRMessagingAPNSInfo.class ]];
FIRMessagingAPNSInfo *rawAPNSInfo = [aDecoder decodeObjectOfClasses:classes
forKey:kFIRInstanceIDAPNSInfoKey];
if (rawAPNSInfo && ![rawAPNSInfo isKindOfClass:[FIRMessagingAPNSInfo class]]) {
return nil;
}

FIRMessagingAPNSInfo *APNSInfo = nil;
if (rawAPNSInfo) {
// TODO(chliangGoogle: Use the new API and secureCoding protocol.
@try {
[NSKeyedUnarchiver setClass:[FIRMessagingAPNSInfo class]
forClassName:@"FIRInstanceIDAPNSInfo"];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
APNSInfo = [NSKeyedUnarchiver unarchiveObjectWithData:rawAPNSInfo];
#pragma clang diagnostic pop
} @catch (NSException *exception) {
FIRMessagingLoggerInfo(kFIRMessagingMessageCodeTokenInfoBadAPNSInfo,
@"Could not parse raw APNS Info while parsing archived token info.");
APNSInfo = nil;
} @finally {
}
}

id cacheTime = [aDecoder decodeObjectForKey:kFIRInstanceIDCacheTimeKey];
if (cacheTime && ![cacheTime isKindOfClass:[NSDate class]]) {
return nil;
Expand All @@ -200,7 +187,7 @@ - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
_token = [token copy];
_appVersion = [appVersion copy];
_firebaseAppID = [firebaseAppID copy];
_APNSInfo = [APNSInfo copy];
_APNSInfo = [rawAPNSInfo copy];
_cacheTime = cacheTime;
}
return self;
Expand All @@ -212,16 +199,8 @@ - (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:self.token forKey:kFIRInstanceIDTokenKey];
[aCoder encodeObject:self.appVersion forKey:kFIRInstanceIDAppVersionKey];
[aCoder encodeObject:self.firebaseAppID forKey:kFIRInstanceIDFirebaseAppIDKey];
NSData *rawAPNSInfo;
if (self.APNSInfo) {
// TODO(chliangGoogle: Use the new API and secureCoding protocol.
[NSKeyedArchiver setClassName:@"FIRInstanceIDAPNSInfo" forClass:[FIRMessagingAPNSInfo class]];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
rawAPNSInfo = [NSKeyedArchiver archivedDataWithRootObject:self.APNSInfo];
#pragma clang diagnostic pop

[aCoder encodeObject:rawAPNSInfo forKey:kFIRInstanceIDAPNSInfoKey];
[aCoder encodeObject:self.APNSInfo forKey:kFIRInstanceIDAPNSInfoKey];
}
[aCoder encodeObject:self.cacheTime forKey:kFIRInstanceIDCacheTimeKey];
}
Expand Down
17 changes: 11 additions & 6 deletions FirebaseMessaging/Tests/UnitTests/FIRMessagingAPNSInfoTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,20 @@ - (void)testAPNSInfoCreationWithInvalidSandboxFormat {
- (void)testAPNSInfoEncodingAndDecoding {
NSDictionary *validDictionary = @{
kFIRMessagingTokenOptionsAPNSKey : [@"tokenData" dataUsingEncoding:NSUTF8StringEncoding],
kFIRMessagingTokenOptionsAPNSIsSandboxKey : @"sandboxValueAsString"
kFIRMessagingTokenOptionsAPNSIsSandboxKey : @1234
};
NSError *error;
FIRMessagingAPNSInfo *info =
[[FIRMessagingAPNSInfo alloc] initWithTokenOptionsDictionary:validDictionary];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
NSData *archive = [NSKeyedArchiver archivedDataWithRootObject:info];
FIRMessagingAPNSInfo *restoredInfo = [NSKeyedUnarchiver unarchiveObjectWithData:archive];
#pragma clang diagnostic pop
NSData *archive = [NSKeyedArchiver archivedDataWithRootObject:info
requiringSecureCoding:YES
error:&error];
XCTAssertNil(error);
NSSet *classes = [[NSSet alloc] initWithArray:@[ FIRMessagingAPNSInfo.class, NSData.class ]];
FIRMessagingAPNSInfo *restoredInfo = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes
fromData:archive
error:&error];
XCTAssertNil(error);
XCTAssertEqualObjects(info.deviceToken, restoredInfo.deviceToken);
XCTAssertEqual(info.sandbox, restoredInfo.sandbox);
}
Expand Down
31 changes: 18 additions & 13 deletions FirebaseMessaging/Tests/UnitTests/FIRMessagingAuthKeychainTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,19 @@ - (void)testKeyChainNoCorruptionWithUniqueAccount {
// Now query the token and compare, they should not corrupt
// each other.
NSData *data1 = [weakKeychain dataForService:service account:account1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
FIRMessagingTokenInfo *tokenInfo1 =
[NSKeyedUnarchiver unarchiveObjectWithData:data1];
[NSKeyedUnarchiver unarchivedObjectOfClass:FIRMessagingTokenInfo.class
fromData:data1
error:&error];
XCTAssertNil(error);
XCTAssertEqualObjects(kToken1, tokenInfo1.token);

NSData *data2 = [weakKeychain dataForService:service account:account2];
FIRMessagingTokenInfo *tokenInfo2 =
[NSKeyedUnarchiver unarchiveObjectWithData:data2];
#pragma clang diagnostic pop
[NSKeyedUnarchiver unarchivedObjectOfClass:FIRMessagingTokenInfo.class
fromData:data2
error:&error];
XCTAssertNil(error);
XCTAssertEqualObjects(kToken2, tokenInfo2.token);
// Also check the cache data.
XCTAssertEqual(weakKeychain.cachedKeychainData.count, 1);
Expand Down Expand Up @@ -175,11 +178,11 @@ - (void)testKeyChainNoCorruptionWithUniqueService {
// Now query the token and compare, they should not corrupt
// each other.
NSData *data1 = [weakKeychain dataForService:service1 account:account];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
FIRMessagingTokenInfo *tokenInfo1 =
[NSKeyedUnarchiver unarchiveObjectWithData:data1];
#pragma clang diagnostic pop
[NSKeyedUnarchiver unarchivedObjectOfClass:FIRMessagingTokenInfo.class
fromData:data1
error:&error];
XCTAssertNil(error);
XCTAssertEqualObjects(kToken1, tokenInfo1.token);

NSData *data2 = [weakKeychain dataForService:service2 account:account];
Expand Down Expand Up @@ -413,10 +416,12 @@ - (NSData *)tokenDataWithAuthorizedEntity:(NSString *)authorizedEntity
token:token
appVersion:@"1.0"
firebaseAppID:kFirebaseAppID];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [NSKeyedArchiver archivedDataWithRootObject:tokenInfo];
#pragma clang diagnostic pop
NSError *error;
NSData *archive = [NSKeyedArchiver archivedDataWithRootObject:tokenInfo
requiringSecureCoding:YES
error:&error];
XCTAssertNil(error);
return archive;
}
@end

Expand Down
30 changes: 20 additions & 10 deletions FirebaseMessaging/Tests/UnitTests/FIRMessagingTokenInfoTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,16 @@ - (void)tearDown {
// yields the same values for all the fields.
- (void)testTokenInfoEncodingAndDecoding {
FIRMessagingTokenInfo *info = self.validTokenInfo;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
NSData *archive = [NSKeyedArchiver archivedDataWithRootObject:info];
FIRMessagingTokenInfo *restoredInfo = [NSKeyedUnarchiver unarchiveObjectWithData:archive];
#pragma clang diagnostic pop
NSError *error;
NSData *archive = [NSKeyedArchiver archivedDataWithRootObject:info
requiringSecureCoding:YES
error:&error];
XCTAssertNil(error);
NSSet *classes = [[NSSet alloc] initWithArray:@[ FIRMessagingTokenInfo.class, NSDate.class ]];
FIRMessagingTokenInfo *restoredInfo = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes
fromData:archive
error:&error];
XCTAssertNil(error);
XCTAssertEqualObjects(restoredInfo.authorizedEntity, info.authorizedEntity);
XCTAssertEqualObjects(restoredInfo.scope, info.scope);
XCTAssertEqualObjects(restoredInfo.token, info.token);
Expand All @@ -101,11 +106,16 @@ - (void)testTokenInfoEncodingAndDecodingWithMissingFields {
token:kToken
appVersion:nil
firebaseAppID:nil];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
NSData *archive = [NSKeyedArchiver archivedDataWithRootObject:sparseInfo];
FIRMessagingTokenInfo *restoredInfo = [NSKeyedUnarchiver unarchiveObjectWithData:archive];
#pragma clang diagnostic pop
NSError *error;
NSData *archive = [NSKeyedArchiver archivedDataWithRootObject:sparseInfo
requiringSecureCoding:YES
error:&error];
XCTAssertNil(error);
NSSet *classes = [[NSSet alloc] initWithArray:@[ FIRMessagingTokenInfo.class, NSDate.class ]];
FIRMessagingTokenInfo *restoredInfo = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes
fromData:archive
error:&error];
XCTAssertNil(error);
XCTAssertEqualObjects(restoredInfo.authorizedEntity, sparseInfo.authorizedEntity);
XCTAssertEqualObjects(restoredInfo.scope, sparseInfo.scope);
XCTAssertEqualObjects(restoredInfo.token, sparseInfo.token);
Expand Down