Skip to content

Commit

Permalink
Merge branch 'release/0.26.3/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
pixlwave committed Mar 22, 2023
2 parents 941aa44 + b417b6a commit 7b5fc4d
Show file tree
Hide file tree
Showing 38 changed files with 542 additions and 386 deletions.
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## Changes in 0.26.3 (2023-03-22)

No significant changes.


## Changes in 0.26.2 (2023-03-21)

🙌 Improvements
Expand Down
2 changes: 1 addition & 1 deletion MatrixSDK.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|

s.name = "MatrixSDK"
s.version = "0.26.2"
s.version = "0.26.3"
s.summary = "The iOS SDK to build apps compatible with Matrix (https://www.matrix.org)"

s.description = <<-DESC
Expand Down
42 changes: 24 additions & 18 deletions MatrixSDK.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions MatrixSDK/Aggregations/MXAggregatedPollsUpdater.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ public final class MXAggregatedPollsUpdater: NSObject {
// the poll refresh is meant to be done at the end of a poll
guard
event.eventType == .pollEnd,
event.relatesTo.relationType == MXEventRelationTypeReference,
let pollStartEventId = event.relatesTo.eventId
let relatedTo = event.relatesTo,
relatedTo.relationType == MXEventRelationTypeReference,
let pollStartEventId = relatedTo.eventId
else {
return
}
Expand Down
3 changes: 2 additions & 1 deletion MatrixSDK/Crypto/CrossSigning/Data/MXCrossSigningInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#import <Foundation/Foundation.h>

#import "MXCrossSigningKey.h"
#import "MXUserTrustLevel.h"

@class MXCryptoUserIdentityWrapper;

Expand Down Expand Up @@ -55,7 +56,7 @@ extern NSString *const MXCrossSigningInfoTrustLevelDidChangeNotification;

#pragma mark - Additional information

@property (nonatomic, readonly) BOOL isVerified;
@property (nonatomic, readonly) MXUserTrustLevel *trustLevel;

@end

Expand Down
81 changes: 27 additions & 54 deletions MatrixSDK/Crypto/CrossSigning/Data/MXCrossSigningInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,38 +21,6 @@

NSString *const MXCrossSigningInfoTrustLevelDidChangeNotification = @"MXCrossSigningInfoTrustLevelDidChangeNotification";

#pragma mark - Deprecated user trust

/**
Deprecated model of user trust that distinguished local vs cross-signing verification
This model is no longer used and is replaced by a combined `isVerified` property on `MXCrossSigningInfo`.
For backwards compatibility (reading archived values) the model needs to be kept around, albeit as private only.
*/
@interface MXDeprecatedUserTrustLevel : NSObject <NSCoding>
@property (nonatomic, readonly) BOOL isCrossSigningVerified;
@end

@implementation MXDeprecatedUserTrustLevel
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self)
{
// We ignore `isLocallyVerified` field and only consider `isCrossSigningVerified`
_isCrossSigningVerified = [aDecoder decodeBoolForKey:@"isCrossSigningVerified"];
}
return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder
{
MXLogFailure(@"[MXDeprecatedUserTrustLevel] encode: This model should only be used for decoding existing data, not encoding new data");
}
@end

#pragma mark - CrossSigningInfo

@implementation MXCrossSigningInfo

- (instancetype)initWithUserIdentity:(MXCryptoUserIdentityWrapper *)userIdentity
Expand All @@ -75,7 +43,7 @@ - (instancetype)initWithUserIdentity:(MXCryptoUserIdentityWrapper *)userIdentity
keys[MXCrossSigningKeyType.userSigning] = userIdentity.userSignedKeys;
}
_keys = keys.copy;
_isVerified = userIdentity.isVerified;
_trustLevel = userIdentity.trustLevel;
}
return self;
}
Expand Down Expand Up @@ -124,21 +92,18 @@ - (id)initWithCoder:(NSCoder *)aDecoder
{
_userId = [aDecoder decodeObjectForKey:@"userId"];
_keys = [aDecoder decodeObjectForKey:@"keys"];

// Initial version (i.e. version 0) of the model stored user trust via `MXUserTrustLevel` submodel.
// If we are reading this version out we need to decode verification state from this model before
// migrating it over to `isVerified`
NSInteger version = [aDecoder decodeIntegerForKey:@"version"];
if (version == 0)
if (version == 1)
{
[NSKeyedUnarchiver setClass:MXDeprecatedUserTrustLevel.class forClassName:@"MXUserTrustLevel"];
MXDeprecatedUserTrustLevel *trust = [aDecoder decodeObjectForKey:@"trustLevel"];
// Only convert cross-signed verification status, not local verification status
_isVerified = trust.isCrossSigningVerified;
// Version 1 compressed two boolean flags into a single one, when restoring from this version
// we will distribute once again to two booleans as it is important to keep local vs cross-signed
// status for own user as local echo.
BOOL isVerified = [aDecoder decodeBoolForKey:@"isVerified"];
_trustLevel = [MXUserTrustLevel trustLevelWithCrossSigningVerified:isVerified locallyVerified:isVerified];
}
else
{
_isVerified = [aDecoder decodeBoolForKey:@"isVerified"];
_trustLevel = [aDecoder decodeObjectForKey:@"trustLevel"];
}
}
return self;
Expand All @@ -148,8 +113,8 @@ - (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:_userId forKey:@"userId"];
[aCoder encodeObject:_keys forKey:@"keys"];
[aCoder encodeBool:_isVerified forKey:@"isVerified"];
[aCoder encodeInteger:1 forKey:@"version"];
[aCoder encodeObject:_trustLevel forKey:@"trustLevel"];
[aCoder encodeInteger:2 forKey:@"version"];
}


Expand All @@ -161,23 +126,31 @@ - (instancetype)initWithUserId:(NSString *)userId
if (self)
{
_userId = userId;
_isVerified = NO;
_trustLevel = [MXUserTrustLevel new];
}
return self;
}

- (void)setIsVerified:(BOOL)isVerified
- (void)setTrustLevel:(MXUserTrustLevel*)trustLevel
{
if (_isVerified == isVerified)
_trustLevel = trustLevel;
}

- (BOOL)updateTrustLevel:(MXUserTrustLevel*)trustLevel
{
BOOL updated = NO;

if (![_trustLevel isEqual:trustLevel])
{
return;
_trustLevel = trustLevel;
updated = YES;
[self didUpdateTrustLevel];
}

_isVerified = isVerified;
[self didUpdateVerificationState];

return updated;
}

- (void)didUpdateVerificationState
- (void)didUpdateTrustLevel
{
dispatch_async(dispatch_get_main_queue(),^{
[[NSNotificationCenter defaultCenter] postNotificationName:MXCrossSigningInfoTrustLevelDidChangeNotification object:self userInfo:nil];
Expand All @@ -198,7 +171,7 @@ - (void)addCrossSigningKey:(MXCrossSigningKey*)crossSigningKey type:(NSString*)t

- (NSString *)description
{
return [NSString stringWithFormat:@"<MXCrossSigningInfo: %p> Verified: %@\nMSK: %@\nSSK: %@\nUSK: %@", self, @(self.isVerified), self.masterKeys, self.selfSignedKeys, self.userSignedKeys];
return [NSString stringWithFormat:@"<MXCrossSigningInfo: %p> Trusted: %@\nMSK: %@\nSSK: %@\nUSK: %@", self, @(self.trustLevel.isCrossSigningVerified), self.masterKeys, self.selfSignedKeys, self.userSignedKeys];
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ NS_ASSUME_NONNULL_BEGIN

- (instancetype)initWithUserId:(NSString *)userId;

- (void)setIsVerified:(BOOL)isVerified;
- (void)setTrustLevel:(MXUserTrustLevel*)trustLevel;
- (BOOL)updateTrustLevel:(MXUserTrustLevel*)trustLevel;
- (void)addCrossSigningKey:(MXCrossSigningKey*)crossSigningKey type:(NSString*)type;

@end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import MatrixSDKCrypto
public let masterKeys: MXCrossSigningKey?
public let selfSignedKeys: MXCrossSigningKey?
public let userSignedKeys: MXCrossSigningKey?
public let isVerified: Bool
public let trustLevel: MXUserTrustLevel

internal init(identity: UserIdentity, isVerified: Bool) {
switch identity {
Expand All @@ -43,7 +43,13 @@ import MatrixSDKCrypto
self.selfSignedKeys = .init(jsonString: selfSigningKey)
self.userSignedKeys = nil
}
self.isVerified = isVerified

// `MatrixSDKCrypto` does not distinguish local and cross-signed
// verification status for users
trustLevel = MXUserTrustLevel(
crossSigningVerified: isVerified,
locallyVerified: isVerified
)
}
}

Expand Down
76 changes: 55 additions & 21 deletions MatrixSDK/Crypto/CrossSigning/MXCrossSigning.m
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ - (void)setupWithAuthParams:(NSDictionary*)authParams
[self.crypto.matrixRestClient uploadDeviceSigningKeys:signingKeys authParams:authParams success:^{

// Store our user's keys
[keys setIsVerified:YES];
[keys updateTrustLevel:[MXUserTrustLevel trustLevelWithCrossSigningVerified:YES locallyVerified:YES]];
[self.crypto.store storeCrossSigningKeys:keys];

// Cross-signing is bootstrapped
Expand Down Expand Up @@ -585,7 +585,7 @@ - (BOOL)isDeviceVerified:(MXDeviceInfo*)device
BOOL isDeviceVerified = NO;

MXCrossSigningInfo *userCrossSigning = [self.crypto.store crossSigningKeysForUser:device.userId];
BOOL isUserVerified = [self.crypto isUserVerified:device.userId];
MXUserTrustLevel *userTrustLevel = [self.crypto trustLevelForUser:device.userId];

MXCrossSigningKey *userSSK = userCrossSigning.selfSignedKeys;
if (!userSSK)
Expand All @@ -610,7 +610,7 @@ - (BOOL)isDeviceVerified:(MXDeviceInfo*)device
// ...then we trust this device as much as far as we trust the user
if (userSSKVerify && deviceVerify)
{
isDeviceVerified = isUserVerified;
isDeviceVerified = userTrustLevel.isCrossSigningVerified;
}

return isDeviceVerified;
Expand Down Expand Up @@ -685,14 +685,17 @@ - (void)resetTrust
for (MXCrossSigningInfo *crossSigningInfo in self.crypto.store.crossSigningKeys)
{
BOOL isCrossSigningVerified = [self isUserWithCrossSigningKeysVerified:crossSigningInfo];
if (crossSigningInfo.isVerified != isCrossSigningVerified)
if (crossSigningInfo.trustLevel.isCrossSigningVerified != isCrossSigningVerified)
{
MXLogDebug(@"[MXCrossSigning] resetTrust: Change trust for %@: %@ -> %@", crossSigningInfo.userId,
@(crossSigningInfo.isVerified),
@(crossSigningInfo.trustLevel.isCrossSigningVerified),
@(isCrossSigningVerified));

[crossSigningInfo setIsVerified:isCrossSigningVerified];
[self.crypto.store storeCrossSigningKeys:crossSigningInfo];
MXUserTrustLevel *newTrustLevel = [MXUserTrustLevel trustLevelWithCrossSigningVerified:isCrossSigningVerified locallyVerified:crossSigningInfo.trustLevel.isLocallyVerified];
if ([crossSigningInfo updateTrustLevel:newTrustLevel])
{
[self.crypto.store storeCrossSigningKeys:crossSigningInfo];
}

// Update trust on associated devices
[self checkTrustLevelForDevicesOfUser:crossSigningInfo.userId];
Expand Down Expand Up @@ -742,32 +745,46 @@ - (BOOL)isSelfTrusted

NSString *myUserId = _crypto.mxSession.myUserId;

// Is it signed by a locally trusted device?
NSDictionary<NSString*, NSString*> *myUserSignatures = myMasterKey.signatures.map[myUserId];
for (NSString *publicKeyId in myUserSignatures)
// Is the master key trusted?
MXCrossSigningInfo *myCrossSigningInfo = [_crypto.store crossSigningKeysForUser:myUserId];
if (myCrossSigningInfo && myCrossSigningInfo.trustLevel.isLocallyVerified)
{
isMasterKeyTrusted = YES;
}
else if ([self hasMatchingMasterPrivateKeyInCryptoStore:myCrossSigningInfo.masterKeys])
{
MXKey *key = [[MXKey alloc] initWithKeyFullId:publicKeyId value:myUserSignatures[publicKeyId]];
if ([key.type isEqualToString:kMXKeyEd25519Type])
isMasterKeyTrusted = YES;
}
else
{
// Is it signed by a locally trusted device?
NSDictionary<NSString*, NSString*> *myUserSignatures = myMasterKey.signatures.map[myUserId];
for (NSString *publicKeyId in myUserSignatures)
{
MXDeviceInfo *device = [self.crypto.store deviceWithDeviceId:key.keyId forUser:myUserId];
if (device && device.trustLevel.isLocallyVerified)
MXKey *key = [[MXKey alloc] initWithKeyFullId:publicKeyId value:myUserSignatures[publicKeyId]];
if ([key.type isEqualToString:kMXKeyEd25519Type])
{
// Check signature validity
NSError *error;
isMasterKeyTrusted = [_crypto.olmDevice verifySignature:device.fingerprint JSON:myMasterKey.signalableJSONDictionary signature:key.value error:&error];

if (isMasterKeyTrusted)
MXDeviceInfo *device = [self.crypto.store deviceWithDeviceId:key.keyId forUser:myUserId];
if (device && device.trustLevel.isLocallyVerified)
{
break;
// Check signature validity
NSError *error;
isMasterKeyTrusted = [_crypto.olmDevice verifySignature:device.fingerprint JSON:myMasterKey.signalableJSONDictionary signature:key.value error:&error];

if (isMasterKeyTrusted)
{
break;
}
}
}
}
}


if (!isMasterKeyTrusted)
{
MXLogDebug(@"[MXCrossSigning] isSelfTrusted: NO (MSK not trusted). MSK: %@", myMasterKey);
MXLogDebug(@"[MXCrossSigning] isSelfTrusted: My cross-signing info: %@", [self.crypto.store crossSigningKeysForUser:myUserId]);
MXLogDebug(@"[MXCrossSigning] isSelfTrusted: My cross-signing info: %@", myCrossSigningInfo);
MXLogDebug(@"[MXCrossSigning] isSelfTrusted: My user devices: %@", [self.crypto.store devicesForUser:myUserId]);

return NO;
Expand Down Expand Up @@ -956,6 +973,23 @@ - (void)signObject:(NSDictionary*)object withKeyType:(NSString*)keyType

#pragma mark - Private keys storage

- (BOOL)hasMatchingMasterPrivateKeyInCryptoStore:(MXCrossSigningKey *)masterKey
{
NSString *mskPrivateKeyBase64 = [self.crypto.store secretWithSecretId:MXSecretId.crossSigningMaster];
// Check it is valid and corresponds to our current master keys
if (mskPrivateKeyBase64 && masterKey)
{
OLMPkSigning *mskPkSigning = [self.crossSigningTools pkSigningFromBase64PrivateKey:mskPrivateKeyBase64
withExpectedPublicKey:masterKey.keys];
if (mskPkSigning)
{
return YES;
}
}

return NO;
}

- (BOOL)haveCrossSigningPrivateKeysInCryptoStore
{
NSString *uskPrivateKeyBase64 = [self.crypto.store secretWithSecretId:MXSecretId.crossSigningUserSigning];
Expand Down
12 changes: 9 additions & 3 deletions MatrixSDK/Crypto/CrossSigning/MXCrossSigningV2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class MXCrossSigningV2: NSObject, MXCrossSigning {
return .notBootstrapped
}

if info.isVerified {
if info.trustLevel.isVerified {
return hasAllPrivateKeys ? .canCrossSign : .trustCrossSigning
} else {
return .crossSigningExists
Expand Down Expand Up @@ -217,11 +217,17 @@ class MXCrossSigningV2: NSObject, MXCrossSigning {
}

extension MXCrossSigningV2: MXRecoveryServiceDelegate {
func setUserVerificationForUserId(
_ userId: String,
func setUserVerification(
_ verificationStatus: Bool,
forUser userId: String,
success: @escaping () -> Void,
failure: @escaping (Swift.Error?) -> Void
) {
guard verificationStatus else {
log.failure("Cannot unset user trust")
failure(Error.cannotUnsetTrust)
return
}
signUser(withUserId: userId, success: success, failure: failure)
}
}
Loading

0 comments on commit 7b5fc4d

Please sign in to comment.