From cf1db72a6c815b687c6c31f4d12aa80bced158e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Pe=C5=A1ek?= Date: Fri, 7 Nov 2025 18:31:29 +0100 Subject: [PATCH] Fix #784: Crypto4: Move last fetched activation status to session data --- include/PowerAuth/Session.h | 5 +++++ proj-xcode/PowerAuth2/PowerAuthSDK.m | 20 +++++++++---------- .../PowerAuthCore/PowerAuthCoreSession.h | 10 +++++++++- .../PowerAuthCore/PowerAuthCoreSession.mm | 12 +++++++++++ src/PowerAuth/Session.cpp | 6 ++++++ src/PowerAuth/model/SessionData.cpp | 11 ++++++++++ src/PowerAuth/model/SessionData.h | 10 ++++++++++ src/PowerAuth/v3/ActivationServiceV3.cpp | 4 +++- src/PowerAuth/v4/ActivationServiceV4.cpp | 4 +++- 9 files changed, 68 insertions(+), 14 deletions(-) diff --git a/include/PowerAuth/Session.h b/include/PowerAuth/Session.h index cf0e6dc8..f46a5a9f 100644 --- a/include/PowerAuth/Session.h +++ b/include/PowerAuth/Session.h @@ -233,6 +233,11 @@ class Session : public std::enable_shared_from_this /// /// - Returns: Most recently fetched User Info. cc7::json::JsonValue lastUserInfo() const noexcept; + + /// Retrieve the most recently fetched Activation Status stored in the Session Data. + /// + /// - Returns: Most recently fetched Activation Status. + ActivationStatusPtr lastActivationStatus() const noexcept; private: diff --git a/proj-xcode/PowerAuth2/PowerAuthSDK.m b/proj-xcode/PowerAuth2/PowerAuthSDK.m index d9b49e20..9c7ab644 100644 --- a/proj-xcode/PowerAuth2/PowerAuthSDK.m +++ b/proj-xcode/PowerAuth2/PowerAuthSDK.m @@ -76,7 +76,6 @@ @implementation PowerAuthSDK /// Current pending status task. PA2GetActivationStatusTask * _getActivationStatusTask; - PowerAuthActivationStatus * _lastFetchedActivationStatus; // Current pending system status task } @@ -877,9 +876,6 @@ - (void) getActivationStatusTask:(PA2GetActivationStatusTask*)task didFinishedWi // So, we can freely mutate objects in this instance. if (_getActivationStatusTask == task) { _getActivationStatusTask = nil; - if (status) { - _lastFetchedActivationStatus = status; - } // This is the reference to task which is going to finish its execution soon. // The ivar no longer holds the reference to the task, but we should keep that reference // for a little bit longer, to guarantee, that we don't destroy that object during its @@ -895,10 +891,15 @@ - (void) getActivationStatusTask:(PA2GetActivationStatusTask*)task didFinishedWi - (PowerAuthActivationStatus*) lastFetchedActivationStatus { - [_lock lock]; - PowerAuthActivationStatus * status = _lastFetchedActivationStatus; - [_lock unlock]; - return status; + PowerAuthCoreActivationStatus * coreStatus = [_sessionInterface readTaskWithSession:^PowerAuthCoreActivationStatus*(PowerAuthCoreSession *session, NSError **error) { + return [session lastActivationStatus]; + } error:nil]; + + if (!coreStatus) { + return nil; + } + + return [[PowerAuthActivationStatus alloc] initWithCoreStatus:coreStatus]; } #pragma mark Removing an activation @@ -948,9 +949,6 @@ - (void) removeActivationLocal */ - (void) clearCachedData { - [_lock lock]; - _lastFetchedActivationStatus = nil; - [_lock unlock]; } #pragma mark - Authentication codes diff --git a/proj-xcode/PowerAuthCore/PowerAuthCoreSession.h b/proj-xcode/PowerAuthCore/PowerAuthCoreSession.h index 2ffed806..27a8860d 100644 --- a/proj-xcode/PowerAuthCore/PowerAuthCoreSession.h +++ b/proj-xcode/PowerAuthCore/PowerAuthCoreSession.h @@ -21,6 +21,7 @@ #import #import #import +#import /// The `PowerAuthCoreSessionDelegate` provide interface required for interaction @@ -153,7 +154,14 @@ This property accesses user info cached in the session, so read access must be guaranteed. */ @property (nonatomic, strong, readonly, nullable) NSDictionary* lastUserInfo; - +/** + Contains last activation status received from the server. + This property provides the most recent activation status and does not trigger any server communication. + If no such information has been received yet, nil is returned. + + This property accesses activation status cached in the session, so read access must be guaranteed. + */ +@property (nonatomic, strong, readonly, nullable) PowerAuthCoreActivationStatus * lastActivationStatus; #pragma mark - Serialization diff --git a/proj-xcode/PowerAuthCore/PowerAuthCoreSession.mm b/proj-xcode/PowerAuthCore/PowerAuthCoreSession.mm index c27e1c48..fd10bfba 100644 --- a/proj-xcode/PowerAuthCore/PowerAuthCoreSession.mm +++ b/proj-xcode/PowerAuthCore/PowerAuthCoreSession.mm @@ -198,6 +198,18 @@ - (PowerAuthCoreProtocolVersion) protocolVersion return cc7::objc::JsonValueToObjC(_session->lastUserInfo()); } +- (nullable PowerAuthCoreActivationStatus*) lastActivationStatus +{ + [self requireReadAccess:nil]; + + const auto status = _session->lastActivationStatus(); + if (!status) { + return nil; + } + + return [[PowerAuthCoreActivationStatus alloc] initWithActivationStatus:status]; +} + #pragma mark - Serialization - (nullable NSData*) serializedState:(NSError*_Nullable*_Nullable)error diff --git a/src/PowerAuth/Session.cpp b/src/PowerAuth/Session.cpp index 039512c0..3a5820f2 100644 --- a/src/PowerAuth/Session.cpp +++ b/src/PowerAuth/Session.cpp @@ -247,6 +247,12 @@ cc7::json::JsonValue Session::lastUserInfo() const noexcept return _context->sessionData().getUserInfo(); } +ActivationStatusPtr Session::lastActivationStatus() const noexcept +{ + LOCK_GUARD(); + return _context->sessionData().getActivationStatusPtr(); +} + void Session::checkActivationData() const { if (!sessionData().hasPersistentData()) { diff --git a/src/PowerAuth/model/SessionData.cpp b/src/PowerAuth/model/SessionData.cpp index 2e40dbda..4c0769e9 100644 --- a/src/PowerAuth/model/SessionData.cpp +++ b/src/PowerAuth/model/SessionData.cpp @@ -123,6 +123,7 @@ void SessionData::resetSessionData() _rd = nullptr; _pd = nullptr; _user_info = cc7::json::JsonValue(); + _activation_status = nullptr; _ud = nullptr; } @@ -232,4 +233,14 @@ void SessionData::setUserInfo(const cc7::json::JsonValue& userInfo) _user_info = userInfo; } +const ActivationStatusPtr& SessionData::getActivationStatusPtr() const noexcept +{ + return _activation_status; +} + +void SessionData::setActivationStatus(ActivationStatusPtr& ptr) +{ + _activation_status = ptr; +} + } // namespace powerAuth diff --git a/src/PowerAuth/model/SessionData.h b/src/PowerAuth/model/SessionData.h index 26dd0a2c..40501268 100644 --- a/src/PowerAuth/model/SessionData.h +++ b/src/PowerAuth/model/SessionData.h @@ -142,6 +142,14 @@ class SessionData /// - Parameter userInfo: User Info claims. void setUserInfo(const cc7::json::JsonValue& userInfo); + /// Get activation status object pointer + /// - Returns: Activation status object pointer. + const ActivationStatusPtr& getActivationStatusPtr() const noexcept; + + /// Set activation status object. + /// - Parameter ptr: Pointer to activation status object. + void setActivationStatus(ActivationStatusPtr& ptr); + private: ConstPowerAuthSpecPtr _target_specification; RegistrationDataPtr _rd; @@ -149,7 +157,9 @@ class SessionData UpgradeDataPtr _ud; bool _modified; + // Cached data cc7::json::JsonValue _user_info; + ActivationStatusPtr _activation_status; }; CC7_SHARED_PTR(SessionData) diff --git a/src/PowerAuth/v3/ActivationServiceV3.cpp b/src/PowerAuth/v3/ActivationServiceV3.cpp index 189be38c..cee51549 100644 --- a/src/PowerAuth/v3/ActivationServiceV3.cpp +++ b/src/PowerAuth/v3/ActivationServiceV3.cpp @@ -247,7 +247,9 @@ ResponseObjectPtr ActivationServiceV3::processResponseActivationStatus(Context& } // Check counter synchronization - return std::make_shared(Version_V3, local_state, counter_state, binary_data, custom_object); + auto activation_status = std::make_shared(Version_V3, local_state, counter_state, binary_data, custom_object); + _session_data->setActivationStatus(activation_status); + return activation_status; } cc7::ByteArray ActivationServiceV3::decryptActivationStatusBlob(const cc7::json::JsonValue& response, const cc7::ByteRange& challenge, const ISecretKeysPtr& secrets) diff --git a/src/PowerAuth/v4/ActivationServiceV4.cpp b/src/PowerAuth/v4/ActivationServiceV4.cpp index 7708cb71..aecf2f11 100644 --- a/src/PowerAuth/v4/ActivationServiceV4.cpp +++ b/src/PowerAuth/v4/ActivationServiceV4.cpp @@ -282,7 +282,9 @@ ResponseObjectPtr ActivationServiceV4::processResponseActivationStatus(Context & local_state = ActivationState::Deadlock; } // Check counter synchronization - return std::make_shared(Version_V4, local_state, counter_state, binary_data, custom_object); + auto activation_status = std::make_shared(Version_V4, local_state, counter_state, binary_data, custom_object); + _session_data->setActivationStatus(activation_status); + return activation_status; } int ActivationServiceV4::calculateHashCounterDistance(cc7::ByteArray& local_ctr_data,