Skip to content

Commit

Permalink
Get assertion with prf extension output parsing.
Browse files Browse the repository at this point in the history
  • Loading branch information
jensutbult committed Nov 6, 2024
1 parent 9fe2fe9 commit 9a26bd0
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ NS_ASSUME_NONNULL_BEGIN

@interface YKFFIDO2GetAssertionResponse()

- (nullable instancetype)initWithCBORData:(NSData *)cborData NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCBORData:(NSData *)cborData sharedSecret:(NSData * _Nullable)sharedSecret NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCBORData:(NSData *)cborData;

@end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (nonatomic, readonly) NSData *rawResponse;

@property (nonatomic, readonly, nullable) NSDictionary *extensionsOutput;

/*
Not available: the response will be created by the library.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
// limitations under the License.

#import "YKFFIDO2GetAssertionResponse.h"
#import "YKFFIDO2MakeCredentialResponse.h"
#import "YKFNSDataAdditions+Private.h"
#import "YKFNSDataAdditions.h"
#import "YKFFIDO2GetAssertionResponse+Private.h"
#import "YKFCBORDecoder.h"
#import "YKFFIDO2Type.h"
Expand All @@ -33,14 +36,20 @@ @interface YKFFIDO2GetAssertionResponse()
@property (nonatomic, readwrite) NSData *signature;
@property (nonatomic, readwrite) YKFFIDO2PublicKeyCredentialUserEntity *user;
@property (nonatomic, readwrite) NSInteger numberOfCredentials;
@property (nonatomic, readwrite) NSDictionary *extensionsOutput;

@property (nonatomic, readwrite) NSData *rawResponse;

@end

@implementation YKFFIDO2GetAssertionResponse


- (instancetype)initWithCBORData:(NSData *)cborData {
return [self initWithCBORData:cborData sharedSecret:nil];
}

- (instancetype)initWithCBORData:(NSData *)cborData sharedSecret:(NSData * _Nullable)sharedSecret {
self = [super init];
if (self) {
YKFAssertAbortInit(cborData);
Expand All @@ -55,15 +64,19 @@ - (instancetype)initWithCBORData:(NSData *)cborData {

YKFAssertAbortInit(responseMap);

BOOL success = [self parseResponseMap: responseMap];
BOOL success = [self parseResponseMap: responseMap sharedSecret:sharedSecret];
YKFAssertAbortInit(success);
}
return self;
}

#pragma mark - Private

- (BOOL)parseResponseMap:(YKFCBORMap *)map {
//- (BOOL)parseResponseMap:(YKFCBORMap *)map {
// return [self parseResponseMap:map sharedSecret:nil];
//}

- (BOOL)parseResponseMap:(YKFCBORMap *)map sharedSecret:(NSData *)sharedSecret {
id convertedObject = [YKFCBORDecoder convertCBORObjectToFoundationType:map];
if (!convertedObject || ![convertedObject isKindOfClass:NSDictionary.class]) {
return NO;
Expand Down Expand Up @@ -97,6 +110,27 @@ - (BOOL)parseResponseMap:(YKFCBORMap *)map {
YKFAssertReturnValue(authData, @"authenticatorGetAssertion authData is required.", NO);
self.authData = authData;

// Extensions output
YKFFIDO2AuthenticatorData *authenticatorData = [[YKFFIDO2AuthenticatorData alloc] initWithData: authData];
YKFCBORByteString *cborSecrect = authenticatorData.extensions.value[YKFCBORTextString(@"hmac-secret")];
NSData *secret = cborSecrect.value;
NSData *decryptedOutputs = [secret ykf_aes256DecryptedDataWithKey: sharedSecret];
NSData *output1 = [decryptedOutputs subdataWithRange: NSMakeRange(0, 32)];
NSData *output2;
if (decryptedOutputs.length == 64) {
output2 = [decryptedOutputs subdataWithRange:NSMakeRange(32, 32)];
}
NSMutableDictionary *outputDict = [NSMutableDictionary new];
outputDict[@"first"] = [output1 ykf_websafeBase64EncodedString];
if (output2) {
outputDict[@"seconde"] = [output2 ykf_websafeBase64EncodedString];
}
NSMutableDictionary *resultsDict = [NSMutableDictionary new];
resultsDict[@"results"] = outputDict;
NSMutableDictionary *prfDict = [NSMutableDictionary new];
prfDict[@"prf"] = resultsDict;
self.extensionsOutput = prfDict;

// Signature
NSData *signature = response[@(YKFFIDO2GetAssertionResponseKeySignature)];
YKFAssertReturnValue(signature, @"authenticatorGetAssertion signature is required.", NO);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ NS_ASSUME_NONNULL_BEGIN

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


- (instancetype)initWithData:(NSData *)data NS_DESIGNATED_INITIALIZER;


/*
Not available: instances should be created only by the library.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ @interface YKFFIDO2AuthenticatorData()
@property (nonatomic, readwrite) NSData *coseEncodedCredentialPublicKey;
@property (nonatomic, readwrite) YKFCBORMap *extensions;

- (instancetype)initWithData:(NSData *)data NS_DESIGNATED_INITIALIZER;

@end

@interface YKFFIDO2MakeCredentialResponse()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ - (void)getAssertionWithClientDataHash:(NSData *)clientDataHash
ykf_safe_strong_self();
NSLog(@"%@", data.ykf_hexadecimalString);
NSData *cborData = [strongSelf cborFromKeyResponseData:data];
YKFFIDO2GetAssertionResponse *getAssertionResponse = [[YKFFIDO2GetAssertionResponse alloc] initWithCBORData:cborData];
YKFFIDO2GetAssertionResponse *getAssertionResponse = [[YKFFIDO2GetAssertionResponse alloc] initWithCBORData:cborData sharedSecret:sharedSecret];

if (getAssertionResponse) {
completion(getAssertionResponse, nil);
Expand Down

0 comments on commit 9a26bd0

Please sign in to comment.