Skip to content

Commit 9a26bd0

Browse files
committed
Get assertion with prf extension output parsing.
1 parent 9fe2fe9 commit 9a26bd0

File tree

6 files changed

+45
-6
lines changed

6 files changed

+45
-6
lines changed

YubiKit/YubiKit/Connections/Shared/Requests/FIDO2/YKFFIDO2GetAssertionResponse+Private.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ NS_ASSUME_NONNULL_BEGIN
1919

2020
@interface YKFFIDO2GetAssertionResponse()
2121

22-
- (nullable instancetype)initWithCBORData:(NSData *)cborData NS_DESIGNATED_INITIALIZER;
22+
- (nullable instancetype)initWithCBORData:(NSData *)cborData sharedSecret:(NSData * _Nullable)sharedSecret NS_DESIGNATED_INITIALIZER;
23+
- (nullable instancetype)initWithCBORData:(NSData *)cborData;
2324

2425
@end
2526

YubiKit/YubiKit/Connections/Shared/Requests/FIDO2/YKFFIDO2GetAssertionResponse.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ NS_ASSUME_NONNULL_BEGIN
8484
*/
8585
@property (nonatomic, readonly) NSData *rawResponse;
8686

87+
@property (nonatomic, readonly, nullable) NSDictionary *extensionsOutput;
88+
8789
/*
8890
Not available: the response will be created by the library.
8991
*/

YubiKit/YubiKit/Connections/Shared/Requests/FIDO2/YKFFIDO2GetAssertionResponse.m

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
// limitations under the License.
1414

1515
#import "YKFFIDO2GetAssertionResponse.h"
16+
#import "YKFFIDO2MakeCredentialResponse.h"
17+
#import "YKFNSDataAdditions+Private.h"
18+
#import "YKFNSDataAdditions.h"
1619
#import "YKFFIDO2GetAssertionResponse+Private.h"
1720
#import "YKFCBORDecoder.h"
1821
#import "YKFFIDO2Type.h"
@@ -33,14 +36,20 @@ @interface YKFFIDO2GetAssertionResponse()
3336
@property (nonatomic, readwrite) NSData *signature;
3437
@property (nonatomic, readwrite) YKFFIDO2PublicKeyCredentialUserEntity *user;
3538
@property (nonatomic, readwrite) NSInteger numberOfCredentials;
39+
@property (nonatomic, readwrite) NSDictionary *extensionsOutput;
3640

3741
@property (nonatomic, readwrite) NSData *rawResponse;
3842

3943
@end
4044

4145
@implementation YKFFIDO2GetAssertionResponse
4246

47+
4348
- (instancetype)initWithCBORData:(NSData *)cborData {
49+
return [self initWithCBORData:cborData sharedSecret:nil];
50+
}
51+
52+
- (instancetype)initWithCBORData:(NSData *)cborData sharedSecret:(NSData * _Nullable)sharedSecret {
4453
self = [super init];
4554
if (self) {
4655
YKFAssertAbortInit(cborData);
@@ -55,15 +64,19 @@ - (instancetype)initWithCBORData:(NSData *)cborData {
5564

5665
YKFAssertAbortInit(responseMap);
5766

58-
BOOL success = [self parseResponseMap: responseMap];
67+
BOOL success = [self parseResponseMap: responseMap sharedSecret:sharedSecret];
5968
YKFAssertAbortInit(success);
6069
}
6170
return self;
6271
}
6372

6473
#pragma mark - Private
6574

66-
- (BOOL)parseResponseMap:(YKFCBORMap *)map {
75+
//- (BOOL)parseResponseMap:(YKFCBORMap *)map {
76+
// return [self parseResponseMap:map sharedSecret:nil];
77+
//}
78+
79+
- (BOOL)parseResponseMap:(YKFCBORMap *)map sharedSecret:(NSData *)sharedSecret {
6780
id convertedObject = [YKFCBORDecoder convertCBORObjectToFoundationType:map];
6881
if (!convertedObject || ![convertedObject isKindOfClass:NSDictionary.class]) {
6982
return NO;
@@ -97,6 +110,27 @@ - (BOOL)parseResponseMap:(YKFCBORMap *)map {
97110
YKFAssertReturnValue(authData, @"authenticatorGetAssertion authData is required.", NO);
98111
self.authData = authData;
99112

113+
// Extensions output
114+
YKFFIDO2AuthenticatorData *authenticatorData = [[YKFFIDO2AuthenticatorData alloc] initWithData: authData];
115+
YKFCBORByteString *cborSecrect = authenticatorData.extensions.value[YKFCBORTextString(@"hmac-secret")];
116+
NSData *secret = cborSecrect.value;
117+
NSData *decryptedOutputs = [secret ykf_aes256DecryptedDataWithKey: sharedSecret];
118+
NSData *output1 = [decryptedOutputs subdataWithRange: NSMakeRange(0, 32)];
119+
NSData *output2;
120+
if (decryptedOutputs.length == 64) {
121+
output2 = [decryptedOutputs subdataWithRange:NSMakeRange(32, 32)];
122+
}
123+
NSMutableDictionary *outputDict = [NSMutableDictionary new];
124+
outputDict[@"first"] = [output1 ykf_websafeBase64EncodedString];
125+
if (output2) {
126+
outputDict[@"seconde"] = [output2 ykf_websafeBase64EncodedString];
127+
}
128+
NSMutableDictionary *resultsDict = [NSMutableDictionary new];
129+
resultsDict[@"results"] = outputDict;
130+
NSMutableDictionary *prfDict = [NSMutableDictionary new];
131+
prfDict[@"prf"] = resultsDict;
132+
self.extensionsOutput = prfDict;
133+
100134
// Signature
101135
NSData *signature = response[@(YKFFIDO2GetAssertionResponseKeySignature)];
102136
YKFAssertReturnValue(signature, @"authenticatorGetAssertion signature is required.", NO);

YubiKit/YubiKit/Connections/Shared/Requests/FIDO2/YKFFIDO2MakeCredentialResponse.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ NS_ASSUME_NONNULL_BEGIN
157157

158158
@property (nonatomic, readonly, nullable) YKFCBORMap *extensions;
159159

160+
161+
- (instancetype)initWithData:(NSData *)data NS_DESIGNATED_INITIALIZER;
162+
163+
160164
/*
161165
Not available: instances should be created only by the library.
162166
*/

YubiKit/YubiKit/Connections/Shared/Requests/FIDO2/YKFFIDO2MakeCredentialResponse.m

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ @interface YKFFIDO2AuthenticatorData()
4343
@property (nonatomic, readwrite) NSData *coseEncodedCredentialPublicKey;
4444
@property (nonatomic, readwrite) YKFCBORMap *extensions;
4545

46-
- (instancetype)initWithData:(NSData *)data NS_DESIGNATED_INITIALIZER;
47-
4846
@end
4947

5048
@interface YKFFIDO2MakeCredentialResponse()

YubiKit/YubiKit/Connections/Shared/Sessions/FIDO2/YKFFIDO2Session.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ - (void)getAssertionWithClientDataHash:(NSData *)clientDataHash
493493
ykf_safe_strong_self();
494494
NSLog(@"%@", data.ykf_hexadecimalString);
495495
NSData *cborData = [strongSelf cborFromKeyResponseData:data];
496-
YKFFIDO2GetAssertionResponse *getAssertionResponse = [[YKFFIDO2GetAssertionResponse alloc] initWithCBORData:cborData];
496+
YKFFIDO2GetAssertionResponse *getAssertionResponse = [[YKFFIDO2GetAssertionResponse alloc] initWithCBORData:cborData sharedSecret:sharedSecret];
497497

498498
if (getAssertionResponse) {
499499
completion(getAssertionResponse, nil);

0 commit comments

Comments
 (0)