Skip to content

Commit

Permalink
Merge branch 'jens/bio-multi-protocol'
Browse files Browse the repository at this point in the history
  • Loading branch information
jensutbult committed Jun 25, 2024
2 parents 5cbb858 + 4506b0c commit 3b13e95
Show file tree
Hide file tree
Showing 19 changed files with 578 additions and 89 deletions.
14 changes: 14 additions & 0 deletions YubiKit/YubiKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@
A54DCC0323F2147500E95259 /* YKNSStringAdditionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A54DCC0223F2147500E95259 /* YKNSStringAdditionTests.m */; };
B41B6F9A27A96B760062C377 /* YKFTLVRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = B41B6F9927A96B760062C377 /* YKFTLVRecord.m */; };
B41B6F9C27A97DB40062C377 /* YKFTLVRecordTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B41B6F9B27A97DB40062C377 /* YKFTLVRecordTests.m */; };
B428498C2C22DA730000F8CF /* YKFPIVBioMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = B428498B2C22DA730000F8CF /* YKFPIVBioMetadata.m */; };
B428498F2C2305EA0000F8CF /* YKFInvalidPinError.m in Sources */ = {isa = PBXBuildFile; fileRef = B428498E2C2305EA0000F8CF /* YKFInvalidPinError.m */; };
B4451EBE2757B493002690BB /* YKFConnectionProtocol.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5176559925405FE400819857 /* YKFConnectionProtocol.h */; };
B4451EBF2757B4A9002690BB /* YKFPIVError.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 51ACC34925E7EC910069214B /* YKFPIVError.h */; };
B4451EC02757B4BF002690BB /* YKFPIVSession.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 51ACC2FB25D5860C0069214B /* YKFPIVSession.h */; };
Expand Down Expand Up @@ -633,6 +635,11 @@
B41B6F9827A96B5B0062C377 /* YKFTLVRecord.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = YKFTLVRecord.h; sourceTree = "<group>"; };
B41B6F9927A96B760062C377 /* YKFTLVRecord.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = YKFTLVRecord.m; sourceTree = "<group>"; };
B41B6F9B27A97DB40062C377 /* YKFTLVRecordTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = YKFTLVRecordTests.m; sourceTree = "<group>"; };
B428498A2C22DA730000F8CF /* YKFPIVBioMetadata.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = YKFPIVBioMetadata.h; sourceTree = "<group>"; };
B428498B2C22DA730000F8CF /* YKFPIVBioMetadata.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = YKFPIVBioMetadata.m; sourceTree = "<group>"; };
B428498D2C22DC1B0000F8CF /* YKFPIVBioMetadata+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "YKFPIVBioMetadata+Private.h"; sourceTree = "<group>"; };
B428498E2C2305EA0000F8CF /* YKFInvalidPinError.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = YKFInvalidPinError.m; sourceTree = "<group>"; };
B42849902C23061B0000F8CF /* YKFInvalidPinError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = YKFInvalidPinError.h; sourceTree = "<group>"; };
B4712B6C28DC8412009B270D /* YKFOATHSetAccessKeyAPDU.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YKFOATHSetAccessKeyAPDU.h; sourceTree = "<group>"; };
B4712B6D28DC8413009B270D /* YKFOATHSetAccessKeyAPDU.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YKFOATHSetAccessKeyAPDU.m; sourceTree = "<group>"; };
B4C9BBC92A05547400FFDFD6 /* NSData+GZIP.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSData+GZIP.m"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -699,6 +706,9 @@
5110D6982600D9C800467680 /* YKFPIVPadding.m */,
5110D6AF2603566200467680 /* YKFPIVKeyType.h */,
5110D6B02603568800467680 /* YKFPIVKeyType.m */,
B428498A2C22DA730000F8CF /* YKFPIVBioMetadata.h */,
B428498D2C22DC1B0000F8CF /* YKFPIVBioMetadata+Private.h */,
B428498B2C22DA730000F8CF /* YKFPIVBioMetadata.m */,
);
path = PIV;
sourceTree = "<group>";
Expand Down Expand Up @@ -1302,6 +1312,8 @@
8152341123BAE9D2004D4788 /* YKFChallengeResponseError.m */,
51ACC34925E7EC910069214B /* YKFPIVError.h */,
51ACC34A25E7ECA80069214B /* YKFPIVError.m */,
B42849902C23061B0000F8CF /* YKFInvalidPinError.h */,
B428498E2C2305EA0000F8CF /* YKFInvalidPinError.m */,
);
path = Errors;
sourceTree = "<group>";
Expand Down Expand Up @@ -1483,6 +1495,7 @@
8152340B23B573E4004D4788 /* YKFChalRespRequest.m in Sources */,
5121B2212563DE8200300145 /* YKFSmartCardInterface.m in Sources */,
95DD40872099A86A00363FEE /* YKFU2FSignAPDU.m in Sources */,
B428498C2C22DA730000F8CF /* YKFPIVBioMetadata.m in Sources */,
954E2C542211AA5600720D2B /* YKFFIDO2ClientPinAPDU.m in Sources */,
51ACC32925DC01DA0069214B /* YKFPIVSessionFeatures.m in Sources */,
5110D67625F8FD2F00467680 /* YKFPIVManagementKeyMetadata.m in Sources */,
Expand All @@ -1504,6 +1517,7 @@
9581395421591DE1008558F3 /* YKFSelectOATHApplicationAPDU.m in Sources */,
95BA204521F7483100EED927 /* YKFFIDO2GetAssertionResponse.m in Sources */,
51ACC33625E50C860069214B /* NSArray+YKFTLVRecord.m in Sources */,
B428498F2C2305EA0000F8CF /* YKFInvalidPinError.m in Sources */,
815233FE23B56A6F004D4788 /* YKFChalRespSendRequest.m in Sources */,
95081DEE2214255B006CD08C /* YKFRequest.m in Sources */,
956991F422C224BC00C5EB02 /* YKFWebAuthnClientData.m in Sources */,
Expand Down
1 change: 1 addition & 0 deletions YubiKit/YubiKit/Connections/Shared/Errors/YKFAPDUError.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ typedef NS_ENUM(NSUInteger, YKFAPDUErrorCode) {
YKFAPDUErrorCodeCLANotSupported = 0x6E00,
YKFAPDUErrorCodeCommandAborted = 0x6F00,
YKFAPDUErrorCodeMissingFile = 0x6A82,
YKFAPDUErrorCodeReferencedDataNotFound = 0x6a88,

// Application/Applet short codes

Expand Down
28 changes: 28 additions & 0 deletions YubiKit/YubiKit/Connections/Shared/Errors/YKFInvalidPinError.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2018-2024 Yubico AB
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef YKFInvalidPinError_h
#define YKFInvalidPinError_h

extern NSString* const YKFInvalidPinErrorDomain;
extern NSInteger const YKFInvalidPinErrorCode;

@interface YKFInvalidPinError: NSError

@property (nonatomic, readonly) int retries;

+ (instancetype)invalidPinErrorWithRetries:(int)retries;

@end
#endif /* YKFInvalidPinError_h */
35 changes: 35 additions & 0 deletions YubiKit/YubiKit/Connections/Shared/Errors/YKFInvalidPinError.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2018-2024 Yubico AB
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#import <Foundation/Foundation.h>
#import "YKFInvalidPinError.h"

NSString* const YKFInvalidPinErrorDomain = @"com.yubico.invalid-pin";
NSInteger const YKFInvalidPinErrorCode = 1;

@interface YKFInvalidPinError()

@property (nonatomic, readwrite) int retries;

@end

@implementation YKFInvalidPinError

+ (instancetype)invalidPinErrorWithRetries:(int)retries {
YKFInvalidPinError *error = [[YKFInvalidPinError alloc] initWithDomain:YKFInvalidPinErrorDomain code:YKFInvalidPinErrorCode userInfo:nil];
error.retries = retries;
return error;
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ typedef void (^YKFManagementSessionGetDeviceInfoBlock)
/// parameter is nil.
typedef void (^YKFManagementSessionWriteCompletionBlock) (NSError* _Nullable error);

/// @abstract
/// Response block for [deviceReset:completion:] which will do a device reset on a YubiKey Bio
///
/// @param error
/// In case of a failed request this parameter contains the error. If the request was successful this
/// parameter is nil.
typedef void (^YKFManagementSessionDeviceResetCompletionBlock) (NSError* _Nullable error);

NS_ASSUME_NONNULL_BEGIN

/// @abstract Defines the interface for YKFManagementSessionProtocol.
Expand Down Expand Up @@ -127,6 +135,19 @@ NS_ASSUME_NONNULL_BEGIN
/// The method is thread safe and can be invoked from any thread (main or a background thread).
- (void)writeConfiguration:(YKFManagementInterfaceConfiguration*)configuration reboot:(BOOL)reboot completion:(nonnull YKFManagementSessionWriteCompletionBlock)completion;

/// @abstract
/// Perform a device-wide reset in Bio Multi-protocol Edition devices
///
/// @param completion
/// The response block which is executed after the request was processed by the key. The completion block
/// will be executed on a background thread.
///
/// @note:
/// This method requires support for device reset, available in YubiKey 5.6 or later.
/// The method is thread safe and can be invoked from any thread (main or a background thread).
- (void)deviceReset:(YKFManagementSessionDeviceResetCompletionBlock)completion;


- (instancetype)init NS_UNAVAILABLE;

@end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,17 @@ - (void)writeConfiguration:(YKFManagementInterfaceConfiguration*)configuration r
[self writeConfiguration:configuration reboot:reboot lockCode:nil newLockCode:nil completion:completion];
}

- (void)deviceReset:(YKFManagementSessionDeviceResetCompletionBlock)completion {
if (![self.features.deviceReset isSupportedBySession:self]) {
completion([[NSError alloc] initWithDomain:YKFManagementErrorDomain code:YKFManagementErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: @"Device reset not supported by this YubiKey."}]);
return;
}
YKFAPDU *apdu = [[YKFAPDU alloc] initWithCla:0 ins:0x1f p1:0 p2:0 data:[NSData data] type:YKFAPDUTypeExtended];
[self.smartCardInterface executeCommand:apdu completion:^(NSData * _Nullable data, NSError * _Nullable error) {
completion(error);
}];
}

// No application side state that needs clearing but this will be called when another
// session is replacing the YKFManagementSession.
- (void)clearSessionState {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2018-2024 Yubico AB
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef YKFPIVBioMetadata_Private_h
#define YKFPIVBioMetadata_Private_h

#import "YKFPIVBioMetadata.h"

@interface YKFPIVBioMetadata()

- (instancetype)initWithIsConfigured:(bool)isConfigured attemptsRemaining:(int)attemptsRemaining temporaryPin:(bool)temporaryPin NS_DESIGNATED_INITIALIZER;

@end

#endif /* YKFPIVBioMetadata_Private_h */
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2018-2024 Yubico AB
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface YKFPIVBioMetadata : NSObject

@property (nonatomic, readonly) bool isConfigured;
@property (nonatomic, readonly) int attemptsRemaining;
@property (nonatomic, readonly) bool temporaryPin;

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2018-2024 Yubico AB
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#import "YKFPIVBioMetadata.h"

@interface YKFPIVBioMetadata()

@property (nonatomic, readwrite) bool isConfigured;
@property (nonatomic, readwrite) int attemptsRemaining;
@property (nonatomic, readwrite) bool temporaryPin;

@end

@implementation YKFPIVBioMetadata

- (instancetype)initWithIsConfigured:(bool)isConfigured attemptsRemaining:(int)attemptsRemaining temporaryPin:(bool)temporaryPin
{
self = [super init];
if (self) {
self.isConfigured = isConfigured;
self.attemptsRemaining = attemptsRemaining;
self.temporaryPin = temporaryPin;
}
return self;
}

@end
14 changes: 10 additions & 4 deletions YubiKit/YubiKit/Connections/Shared/Sessions/PIV/YKFPIVKeyType.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
// Copyright 2018-2024 Yubico AB
//
// YKFPIVKeyType.h
// YubiKit
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// Created by Jens Utbult on 2021-03-18.
// Copyright © 2021 Yubico. All rights reserved.
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef YKFPIVKeyType_h
#define YKFPIVKeyType_h
Expand Down
14 changes: 10 additions & 4 deletions YubiKit/YubiKit/Connections/Shared/Sessions/PIV/YKFPIVKeyType.m
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
// Copyright 2018-2024 Yubico AB
//
// YKFPIVKeyType.m
// YubiKit
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// Created by Jens Utbult on 2021-03-18.
// Copyright © 2021 Yubico. All rights reserved.
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#import <Foundation/Foundation.h>
#import "YKFPIVKeyType.h"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
// Copyright 2018-2024 Yubico AB
//
// YKFPIVSession+Private.h
// YubiKit
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// Created by Jens Utbult on 2021-02-11.
// Copyright © 2021 Yubico. All rights reserved.
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef YKFPIVSession_Private_h
#define YKFPIVSession_Private_h
Expand Down
Loading

0 comments on commit 3b13e95

Please sign in to comment.