13
13
// limitations under the License.
14
14
15
15
#import " YKFFIDO2GetAssertionResponse.h"
16
+ #import " YKFFIDO2MakeCredentialResponse.h"
17
+ #import " YKFNSDataAdditions+Private.h"
18
+ #import " YKFNSDataAdditions.h"
16
19
#import " YKFFIDO2GetAssertionResponse+Private.h"
17
20
#import " YKFCBORDecoder.h"
18
21
#import " YKFFIDO2Type.h"
@@ -33,14 +36,20 @@ @interface YKFFIDO2GetAssertionResponse()
33
36
@property (nonatomic , readwrite ) NSData *signature;
34
37
@property (nonatomic , readwrite ) YKFFIDO2PublicKeyCredentialUserEntity *user;
35
38
@property (nonatomic , readwrite ) NSInteger numberOfCredentials;
39
+ @property (nonatomic , readwrite ) NSDictionary *extensionsOutput;
36
40
37
41
@property (nonatomic , readwrite ) NSData *rawResponse;
38
42
39
43
@end
40
44
41
45
@implementation YKFFIDO2GetAssertionResponse
42
46
47
+
43
48
- (instancetype )initWithCBORData : (NSData *)cborData {
49
+ return [self initWithCBORData: cborData sharedSecret: nil ];
50
+ }
51
+
52
+ - (instancetype )initWithCBORData : (NSData *)cborData sharedSecret : (NSData * _Nullable)sharedSecret {
44
53
self = [super init ];
45
54
if (self) {
46
55
YKFAssertAbortInit (cborData);
@@ -55,15 +64,19 @@ - (instancetype)initWithCBORData:(NSData *)cborData {
55
64
56
65
YKFAssertAbortInit (responseMap);
57
66
58
- BOOL success = [self parseResponseMap: responseMap];
67
+ BOOL success = [self parseResponseMap: responseMap sharedSecret: sharedSecret ];
59
68
YKFAssertAbortInit (success);
60
69
}
61
70
return self;
62
71
}
63
72
64
73
#pragma mark - Private
65
74
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 {
67
80
id convertedObject = [YKFCBORDecoder convertCBORObjectToFoundationType: map];
68
81
if (!convertedObject || ![convertedObject isKindOfClass: NSDictionary .class]) {
69
82
return NO ;
@@ -97,6 +110,27 @@ - (BOOL)parseResponseMap:(YKFCBORMap *)map {
97
110
YKFAssertReturnValue (authData, @" authenticatorGetAssertion authData is required." , NO );
98
111
self.authData = authData;
99
112
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
+
100
134
// Signature
101
135
NSData *signature = response[@(YKFFIDO2GetAssertionResponseKeySignature)];
102
136
YKFAssertReturnValue (signature, @" authenticatorGetAssertion signature is required." , NO );
0 commit comments