Skip to content

Commit

Permalink
Fixed type that lead to confusing error code naming for PIVSession.
Browse files Browse the repository at this point in the history
  • Loading branch information
jensutbult committed Jun 10, 2024
1 parent 910be36 commit be96b7e
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 45 deletions.
8 changes: 0 additions & 8 deletions YubiKit/YubiKit/Connections/Shared/Errors/YKFPIVError.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,6 @@

#import "YKFSessionError.h"

typedef NS_ENUM(NSUInteger, YKFPIVErrorCode) {

/*! Unexpected reply from the YubiKey.
*/
YKFPIVErrorCodeBadResponse = 0x01,
YKFPIVErrorCodeBadKeyLength = 0x02
};


NS_ASSUME_NONNULL_BEGIN
/*!
Expand Down
5 changes: 3 additions & 2 deletions YubiKit/YubiKit/Connections/Shared/Errors/YKFPIVError.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@
// limitations under the License.

#import "YKFPIVError.h"
#import "YKFPIVSession.h"
#import "YKFSessionError+Private.h"

@implementation YKFPIVError

+ (instancetype)errorWithCode:(NSUInteger)code {
NSString *message;
switch (code) {
case YKFPIVErrorCodeBadResponse:
case YKFPIVErrorCodeInvalidResponse:
message = @"Bad response";
break;
default:
Expand All @@ -31,7 +32,7 @@ + (instancetype)errorWithCode:(NSUInteger)code {
}

+ (instancetype)errorUnpackingTLVExpected:(NSUInteger)expected got:(NSUInteger)got {
return [[self alloc] initWithCode:YKFPIVErrorCodeBadResponse message:[[NSString alloc] initWithFormat:@"Exptected tag: %02lx, got %02lx", (unsigned long)expected, (unsigned long)got]];
return [[self alloc] initWithCode:YKFPIVErrorCodeInvalidResponse message:[[NSString alloc] initWithFormat:@"Exptected tag: %02lx, got %02lx", (unsigned long)expected, (unsigned long)got]];
}

@end
18 changes: 9 additions & 9 deletions YubiKit/YubiKit/Connections/Shared/Sessions/PIV/YKFPIVSession.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ typedef NS_ENUM(NSUInteger, YKFPIVSlot) {
extern NSString* _Nonnull const YKFPIVFErrorDomain;

/// PIV error codes.
typedef NS_ENUM(NSUInteger, YKFPIVFErrorCode) {
YKFPIVFErrorCodeInvalidCipherTextLength = 1,
YKFPIVFErrorCodeUnsupportedOperation = 2,
YKFPIVFErrorCodeDataParseError = 3,
YKFPIVFErrorCodeUnknownKeyType = 4,
YKFPIVFErrorCodeInvalidPin = 5,
YKFPIVFErrorCodePinLocked = 6,
YKFPIVFErrorCodeInvalidResponse = 7,
YKFPIVFErrorCodeAuthenticationFailed = 8,
typedef NS_ENUM(NSUInteger, YKFPIVErrorCode) {
YKFPIVErrorCodeInvalidCipherTextLength = 1,
YKFPIVErrorCodeUnsupportedOperation = 2,
YKFPIVErrorCodeDataParseError = 3,
YKFPIVErrorCodeUnknownKeyType = 4,
YKFPIVErrorCodeInvalidPin = 5,
YKFPIVErrorCodePinLocked = 6,
YKFPIVErrorCodeInvalidResponse = 7,
YKFPIVErrorCodeAuthenticationFailed = 8,
YKFPIVErrorCodeIllegalArgument = 9
};

Expand Down
42 changes: 21 additions & 21 deletions YubiKit/YubiKit/Connections/Shared/Sessions/PIV/YKFPIVSession.m
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ + (void)sessionWithConnectionController:(nonnull id<YKFConnectionControllerProto
completion(nil, error);
} else {
if ([data length] < 3) {
completion(nil, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVFErrorCodeInvalidResponse userInfo:@{NSLocalizedDescriptionKey: @"Invalid response when retrieving PIV version."}]);
completion(nil, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVErrorCodeInvalidResponse userInfo:@{NSLocalizedDescriptionKey: @"Invalid response when retrieving PIV version."}]);
return;
}
UInt8 *versionBytes = (UInt8 *)data.bytes;
Expand Down Expand Up @@ -181,7 +181,7 @@ - (void)decryptWithKeyInSlot:(YKFPIVSlot)slot algorithm:(SecKeyAlgorithm)algorit
keyType = YKFPIVKeyTypeRSA4096;
break;
default:
completion(nil, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVFErrorCodeInvalidCipherTextLength userInfo:@{NSLocalizedDescriptionKey: @"Invalid lenght of cipher text."}]);
completion(nil, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVErrorCodeInvalidCipherTextLength userInfo:@{NSLocalizedDescriptionKey: @"Invalid lenght of cipher text."}]);
return;
}
[self usePrivateKeyInSlot:slot type:keyType message:encrypted exponentiation:false completion:^(NSData * _Nullable data, NSError * _Nullable error) {
Expand Down Expand Up @@ -228,7 +228,7 @@ - (void)usePrivateKeyInSlot:(YKFPIVSlot)slot type:(YKFPIVKeyType)type message:(N
- (void)calculateSecretKeyInSlot:(YKFPIVSlot)slot peerPublicKey:(SecKeyRef)peerPublicKey completion:(nonnull YKFPIVSessionCalculateSecretCompletionBlock)completion {
YKFPIVKeyType keyType = YKFPIVKeyTypeFromKey(peerPublicKey);
if (keyType != YKFPIVKeyTypeECCP256 && keyType != YKFPIVKeyTypeECCP384) {
completion(nil, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVFErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: @"Calculate secret only supported for EC keys."}]);
completion(nil, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: @"Calculate secret only supported for EC keys."}]);
return;
}
CFErrorRef cfError = nil;
Expand All @@ -247,7 +247,7 @@ - (void)calculateSecretKeyInSlot:(YKFPIVSlot)slot peerPublicKey:(SecKeyRef)peerP

- (void)attestKeyInSlot:(YKFPIVSlot)slot completion:(nonnull YKFPIVSessionAttestKeyCompletionBlock)completion {
if (![self.features.attestation isSupportedBySession:self]) {
completion(nil, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVFErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: @"Attestation not supported by this YubiKey."}]);
completion(nil, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: @"Attestation not supported by this YubiKey."}]);
return;
}
YKFAPDU *apdu = [[YKFAPDU alloc] initWithCla:0 ins:YKFPIVInsAttest p1:slot p2:0 data:[NSData data] type:YKFAPDUTypeExtended];
Expand All @@ -261,7 +261,7 @@ - (void)attestKeyInSlot:(YKFPIVSlot)slot completion:(nonnull YKFPIVSessionAttest
if (certificate) {
completion(certificate, nil);
} else {
completion(nil, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVFErrorCodeDataParseError userInfo:@{NSLocalizedDescriptionKey: @"Failed to parse certificate."}]); }
completion(nil, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVErrorCodeDataParseError userInfo:@{NSLocalizedDescriptionKey: @"Failed to parse certificate."}]); }
}];
}

Expand Down Expand Up @@ -352,7 +352,7 @@ - (NSError * _Nullable)checkKeySupport:(YKFPIVKeyType)keyType pinPolicy:(YKFPIVP
}

if (errorMessage) {
return [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVFErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"%@ not supported by this YubiKey.", errorMessage]}];
return [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"%@ not supported by this YubiKey.", errorMessage]}];
}

return nil;
Expand Down Expand Up @@ -404,7 +404,7 @@ - (void)putKey:(SecKeyRef)key inSlot:(YKFPIVSlot)slot pinPolicy:(YKFPIVPinPolicy
break;
}
default:
completion(YKFPIVKeyTypeUnknown, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVFErrorCodeUnknownKeyType userInfo:@{NSLocalizedDescriptionKey: @"Unknown key type."}]);
completion(YKFPIVKeyTypeUnknown, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVErrorCodeUnknownKeyType userInfo:@{NSLocalizedDescriptionKey: @"Unknown key type."}]);
return;
}

Expand All @@ -427,7 +427,7 @@ - (void)putKey:(SecKeyRef)key inSlot:(YKFPIVSlot)slot completion:(nonnull YKFPIV

- (void)moveKey:(YKFPIVSlot)sourceSlot destinationSlot:(YKFPIVSlot)destinationSlot completion:(nonnull YKFPIVSessionGenericCompletionBlock)completion {
if (![self.features.moveDelete isSupportedBySession:self]) {
completion([[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVFErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: @"Move keys not supported by this YubiKey."}]);
completion([[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: @"Move keys not supported by this YubiKey."}]);
return;
}
if (sourceSlot == YKFPIVSlotAttestation) {
Expand Down Expand Up @@ -494,7 +494,7 @@ - (void)getCertificateInSlot:(YKFPIVSlot)slot completion:(nonnull YKFPIVSessionR
if (certificate != nil) {
completion(certificate, nil);
} else {
completion(nil, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVFErrorCodeDataParseError userInfo:@{NSLocalizedDescriptionKey: @"Failed to parse certificate."}]);
completion(nil, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVErrorCodeDataParseError userInfo:@{NSLocalizedDescriptionKey: @"Failed to parse certificate."}]);
}
}
}];
Expand All @@ -508,11 +508,11 @@ - (void)deleteCertificateInSlot:(YKFPIVSlot)slot completion:(nonnull YKFPIVSessi

- (void)setManagementKey:(nonnull NSData *)managementKey type:(nonnull YKFPIVManagementKeyType *)type requiresTouch:(BOOL)requiresTouch completion:(nonnull YKFPIVSessionGenericCompletionBlock)completion {
if (requiresTouch && ![self.features.usagePolicy isSupportedBySession:self]) {
completion([[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVFErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: @"PIN/Touch policy not supported by this YubiKey."}]);
completion([[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: @"PIN/Touch policy not supported by this YubiKey."}]);
return;
}
if (type.name != YKFPIVManagementKeyTypeTripleDES && ![self.features.aesKey isSupportedBySession:self]) {
completion([[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVFErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: @"AES management key not supported by this YubiKey."}]);
completion([[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: @"AES management key not supported by this YubiKey."}]);
return;
}
YKFTLVRecord *tlv = [[YKFTLVRecord alloc] initWithTag:YKFPIVSlotCardManagement value:managementKey];
Expand All @@ -529,7 +529,7 @@ - (void)setManagementKey:(nonnull NSData *)managementKey type:(nonnull YKFPIVMan

- (void)authenticateWithManagementKey:(nonnull NSData *)managementKey type:(nonnull YKFPIVManagementKeyType *)keyType completion:(nonnull YKFPIVSessionGenericCompletionBlock)completion {
if (keyType.keyLenght != managementKey.length) {
YKFPIVError *error = [[YKFPIVError alloc] initWithCode:YKFPIVErrorCodeBadKeyLength message:[NSString stringWithFormat: @"Magagement key must be %i bytes in length. Used key is %lu long.", keyType.keyLenght, (unsigned long)managementKey.length]];
YKFPIVError *error = [[YKFPIVError alloc] initWithCode:YKFPIVErrorCodeInvalidCipherTextLength message:[NSString stringWithFormat: @"Magagement key must be %i bytes in length. Used key is %lu long.", keyType.keyLenght, (unsigned long)managementKey.length]];
completion(error);
return;
}
Expand Down Expand Up @@ -584,7 +584,7 @@ - (void)authenticateWithManagementKey:(nonnull NSData *)managementKey type:(nonn
NSData *encryptedData = encryptedRecord.value;
NSData *expectedData = [challenge ykf_encryptDataWithAlgorithm:[keyType.name ykfCCAlgorithm] key:managementKey];
if (![encryptedData isEqual:expectedData]) {
completion([[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVFErrorCodeAuthenticationFailed userInfo:@{NSLocalizedDescriptionKey: @"Authentication failed."}]);
completion([[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVErrorCodeAuthenticationFailed userInfo:@{NSLocalizedDescriptionKey: @"Authentication failed."}]);
return;
}
completion(nil);
Expand Down Expand Up @@ -613,15 +613,15 @@ - (void)resetWithCompletion:(YKFPIVSessionGenericCompletionBlock)completion {

- (void)getSerialNumberWithCompletion:(YKFPIVSessionSerialNumberCompletionBlock)completion {
if (![self.features.serial isSupportedBySession:self]) {
completion(-1, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVFErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: @"Read serial number not supported by this YubiKey."}]);
completion(-1, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: @"Read serial number not supported by this YubiKey."}]);
return;
}

YKFAPDU *apdu = [[YKFAPDU alloc] initWithCla:0 ins:YKFPIVInsGetSerial p1:0 p2:0 data:[NSData data] type:YKFAPDUTypeShort];
[self.smartCardInterface executeCommand:apdu completion:^(NSData * _Nullable data, NSError * _Nullable error) {
if (data != nil) {
if ([data length] != 4) {
completion(-1, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVFErrorCodeInvalidResponse userInfo:@{NSLocalizedDescriptionKey: @"Invalid response when reading serial number."}]);
completion(-1, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVErrorCodeInvalidResponse userInfo:@{NSLocalizedDescriptionKey: @"Invalid response when reading serial number."}]);
return;
}
UInt32 serialNumber = CFSwapInt32BigToHost(*(UInt32*)([data bytes]));
Expand All @@ -646,11 +646,11 @@ - (void)verifyPin:(nonnull NSString *)pin completion:(nonnull YKFPIVSessionVerif
int retries = [self getRetriesFromStatusCode:(int)sessionError.code];
if (retries > 0) {
currentPinAttempts = retries;
completion(currentPinAttempts, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVFErrorCodeInvalidPin userInfo:@{NSLocalizedDescriptionKey: @"Invalid PIN code."}]);
completion(currentPinAttempts, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVErrorCodeInvalidPin userInfo:@{NSLocalizedDescriptionKey: @"Invalid PIN code."}]);
return;

} else if (retries == 0) {
completion(retries, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVFErrorCodePinLocked userInfo:@{NSLocalizedDescriptionKey: @"PIN code entry locked."}]);
completion(retries, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVErrorCodePinLocked userInfo:@{NSLocalizedDescriptionKey: @"PIN code entry locked."}]);
return;
}
}
Expand Down Expand Up @@ -681,7 +681,7 @@ - (void)unblockPinWithPuk:(nonnull NSString *)puk newPin:(nonnull NSString *)new
- (void)getPinPukMetadata:(UInt8)p2 completion:(nonnull YKFPIVSessionPinPukMetadataCompletionBlock)completion {
YKFAPDU *apdu = [[YKFAPDU alloc] initWithCla:0 ins:YKFPIVInsGetMetadata p1:0 p2:p2 data:[NSData data] type:YKFAPDUTypeShort];
if (![self.features.metadata isSupportedBySession:self]) {
completion(0, 0, 0, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVFErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: @"Read metadata not supported by this YubiKey."}]);
completion(0, 0, 0, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: @"Read metadata not supported by this YubiKey."}]);
return;
}

Expand All @@ -700,7 +700,7 @@ - (void)getPinPukMetadata:(UInt8)p2 completion:(nonnull YKFPIVSessionPinPukMetad

- (void)getMetadataForSlot:(YKFPIVSlot)slot completion:(nonnull YKFPIVSessionSlotMetadataCompletionBlock)completion {
if (![self.features.metadata isSupportedBySession:self]) {
completion(nil, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVFErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: @"Read metadata not supported by this YubiKey."}]);
completion(nil, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: @"Read metadata not supported by this YubiKey."}]);
return;
}
YKFAPDU *apdu = [[YKFAPDU alloc] initWithCla:0 ins:YKFPIVInsGetMetadata p1:0 p2:slot data:[NSData data] type:YKFAPDUTypeShort];
Expand Down Expand Up @@ -728,14 +728,14 @@ - (void)getMetadataForSlot:(YKFPIVSlot)slot completion:(nonnull YKFPIVSessionSlo
YKFPIVSlotMetadata *metadata = [[YKFPIVSlotMetadata alloc] initWithKeyType:keyType publicKey:publicKey pinPolicy:pinPolicy touchPolicy:touchPolicy generated:origin];
completion(metadata, nil);
} else {
completion(nil, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVFErrorCodeDataParseError userInfo:@{NSLocalizedDescriptionKey: @"Failed parsing data returned from YubiKey."}]);
completion(nil, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVErrorCodeDataParseError userInfo:@{NSLocalizedDescriptionKey: @"Failed parsing data returned from YubiKey."}]);
}
}];
}

- (void)getManagementKeyMetadataWithCompletion:(nonnull YKFPIVSessionManagementKeyMetadataCompletionBlock)completion {
if (![self.features.metadata isSupportedBySession:self]) {
completion(nil, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVFErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: @"Read metadata not supported by this YubiKey."}]);
completion(nil, [[NSError alloc] initWithDomain:YKFPIVErrorDomain code:YKFPIVErrorCodeUnsupportedOperation userInfo:@{NSLocalizedDescriptionKey: @"Read metadata not supported by this YubiKey."}]);
return;
}
YKFAPDU *apdu = [[YKFAPDU alloc] initWithCla:0 ins:YKFPIVInsGetMetadata p1:0 p2:YKFPIVSlotCardManagement data:[NSData data] type:YKFAPDUTypeShort];
Expand Down
Loading

0 comments on commit be96b7e

Please sign in to comment.