3030#import " MSIDEcdhApv.h"
3131#import " MSIDJwtAlgorithm.h"
3232#import " MSIDJWTHelper.h"
33+ #import " MSIDKeyOperationUtil.h"
3334
3435@implementation MSIDBoundRefreshToken (Redemption)
3536
@@ -38,7 +39,7 @@ @implementation MSIDBoundRefreshToken (Redemption)
3839- (NSString *)getTokenRedemptionJwtForTenantId : (nullable NSString *)tenantId
3940 tokenRedemptionParameters : (MSIDBoundRefreshTokenRedemptionParameters *) requestParameters
4041 context : (id <MSIDRequestContext> _Nullable)context
41- jweCrypto : (NSDictionary * __autoreleasing _Nullable *_Nullable )jweCrypto
42+ jweCrypto : (NSDictionary * __autoreleasing __nonnull *__nonnull )jweCrypto
4243 error : (NSError *__autoreleasing _Nullable * _Nullable)error
4344{
4445 if (![self validateRequestParameters: requestParameters context: context error: error])
@@ -53,22 +54,25 @@ - (NSString *)getTokenRedemptionJwtForTenantId:(nullable NSString *)tenantId
5354 return nil ;
5455 }
5556
56- MSIDWPJKeyPairWithCert *workplacejoinData = [self validateAndGetWorkplaceJoinData : tenantId context: context error: error];
57+ MSIDWPJKeyPairWithCert *workplacejoinData = [self getWorkplaceJoinDataAndValidateForTenantId : tenantId context: context error: error];
5758 if (!workplacejoinData)
5859 {
5960 return nil ;
6061 }
6162
62- // TODO: Use new method to query STK private reference
63- SecKeyRef publicSessionTransportKeyRef = NULL ;
64- NSString *apvPrefix = @" MsalClient" ; // TODO: Make this a constant
65- MSIDEcdhApv *ecdhPartyVInfoData = [[MSIDEcdhApv alloc ] initWithKey: publicSessionTransportKeyRef
66- apvPrefix: apvPrefix
63+ SecKeyRef publicTransportKeyRef = SecKeyCopyPublicKey (workplacejoinData.privateTransportKeyRef );
64+ MSIDEcdhApv *ecdhPartyVInfoData = [[MSIDEcdhApv alloc ] initWithKey: publicTransportKeyRef
65+ apvPrefix: MSID_MSAL_CLIENT_APV_PREFIX
6766 context: context
6867 error: error];
6968 if (!ecdhPartyVInfoData)
7069 {
7170 MSID_LOG_WITH_CTX (MSIDLogLevelError, context, @" [Bound Refresh token redemption] Failed to create ECDH APV data for bound RT redemption JWT." );
71+ if (error)
72+ *error = [self createErrorWithDomain: MSIDErrorDomain
73+ code: MSIDErrorInvalidInternalParameter
74+ description: @" Failed to create ECDH APV data for bound RT redemption JWT."
75+ context: context];
7276 return nil ;
7377 }
7478
@@ -80,14 +84,20 @@ - (NSString *)getTokenRedemptionJwtForTenantId:(nullable NSString *)tenantId
8084 if (!jweCryptoObj)
8185 {
8286 MSID_LOG_WITH_CTX (MSIDLogLevelError, context, @" [Bound Refresh token redemption] Failed to create JWE crypto for bound RT redemption JWT." );
87+ if (error)
88+ *error = [self createErrorWithDomain: MSIDErrorDomain
89+ code: MSIDErrorInvalidInternalParameter
90+ description: @" Failed to create JWE crypto for bound RT redemption JWT."
91+ context: context];
8392 return nil ;
8493 }
8594
86- *jweCrypto = [jweCryptoObj.jweCryptoDictionary copy ];
95+ if (jweCrypto)
96+ *jweCrypto = [jweCryptoObj.jweCryptoDictionary copy ];
8797
8898 NSMutableDictionary *jwtPayload = [requestParameters jsonDictionary ];
8999 [jwtPayload setObject: self .refreshToken forKey: MSID_OAUTH2_REFRESH_TOKEN];
90- [jwtPayload setObject: *jweCrypto forKey: @" jwe_crypto" ];
100+ [jwtPayload setObject: jweCryptoObj.jweCryptoDictionary forKey: @" jwe_crypto" ];
91101
92102 NSArray *certificateData = @[[NSString stringWithFormat: @" %@ " , [[workplacejoinData certificateData ] base64EncodedStringWithOptions: kNilOptions ]]];
93103 NSDictionary *header = @{
@@ -145,9 +155,9 @@ - (BOOL)validateBoundDeviceId:(id<MSIDRequestContext>)context
145155 return YES ;
146156}
147157
148- - (MSIDWPJKeyPairWithCert *)validateAndGetWorkplaceJoinData : (NSString *)tenantId
149- context : (id <MSIDRequestContext>)context
150- error : (NSError *__autoreleasing * _Nullable)error
158+ - (MSIDWPJKeyPairWithCert *)getWorkplaceJoinDataAndValidateForTenantId : (NSString *)tenantId
159+ context : (id <MSIDRequestContext>)context
160+ error : (NSError *__autoreleasing * _Nullable)error
151161{
152162 MSIDWPJKeyPairWithCert *workplacejoinData = [MSIDWorkPlaceJoinUtil getWPJKeysWithTenantId: tenantId context: context];
153163 if (!workplacejoinData)
@@ -195,6 +205,60 @@ - (MSIDWPJKeyPairWithCert *)validateAndGetWorkplaceJoinData:(NSString *)tenantId
195205 return nil ;
196206 }
197207
208+ SecKeyRef privateTransportKey = workplacejoinData.privateTransportKeyRef ;
209+ if (!privateTransportKey)
210+ {
211+ MSID_LOG_WITH_CTX (MSIDLogLevelError, context, @" [Bound Refresh token redemption] Failed to obtain private transport key for bound RT redemption JWT." );
212+ if (error)
213+ {
214+ *error = [self createErrorWithDomain: MSIDErrorDomain
215+ code: MSIDErrorWorkplaceJoinRequired
216+ description: @" Failed to obtain private transport key for bound RT redemption JWT."
217+ context: context];
218+ }
219+ return nil ;
220+ }
221+
222+ SecKeyRef publicSessionTransportKeyRef = SecKeyCopyPublicKey (privateTransportKey);
223+ if (!publicSessionTransportKeyRef)
224+ {
225+ MSID_LOG_WITH_CTX (MSIDLogLevelError, context, @" [Bound Refresh token redemption] Failed to calculate public session transport key from private key for bound RT redemption JWT." );
226+ if (error)
227+ {
228+ *error = [self createErrorWithDomain: MSIDErrorDomain
229+ code: MSIDErrorWorkplaceJoinRequired
230+ description: @" [Bound Refresh token redemption] Failed to calculate public session transport key from private key for bound RT redemption JWT."
231+ context: context];
232+ }
233+ return nil ;
234+ }
235+
236+ if (![[MSIDKeyOperationUtil sharedInstance ] isKeyFromSecureEnclave: workplacejoinData.privateKeyRef])
237+ {
238+ MSID_LOG_WITH_CTX (MSIDLogLevelError, context, @" [Bound Refresh token redemption] The private device key for bound RT redemption JWT is not from Secure Enclave. Binding will not be satisfied." );
239+ if (error)
240+ {
241+ *error = [self createErrorWithDomain: MSIDErrorDomain
242+ code: MSIDErrorWorkplaceJoinRequired
243+ description: @" The private device key for bound RT redemption JWT is not from Secure Enclave. Binding will not be satisfied."
244+ context: context];
245+ }
246+ return nil ;
247+ }
248+
249+ if (![[MSIDKeyOperationUtil sharedInstance ] isKeyFromSecureEnclave: workplacejoinData.privateTransportKeyRef])
250+ {
251+ MSID_LOG_WITH_CTX (MSIDLogLevelError, context, @" [Bound Refresh token redemption] The private transport key for bound RT redemption JWT is not from Secure Enclave. Binding will not be satisfied." );
252+ if (error)
253+ {
254+ *error = [self createErrorWithDomain: MSIDErrorDomain
255+ code: MSIDErrorWorkplaceJoinRequired
256+ description: @" The private transport key for bound RT redemption JWT is not from Secure Enclave. Binding will not be satisfied."
257+ context: context];
258+ }
259+ return nil ;
260+ }
261+
198262 return workplacejoinData;
199263}
200264
0 commit comments