From 34bd4976b650b1b940193b3311c1fa15afe34700 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Fri, 9 Feb 2018 17:40:00 +0200 Subject: [PATCH] Begin/EndSession to lock card after PIN auth IB-5144 Signed-off-by: Raul Metsma --- EstEIDToken/Token.h | 1 - EstEIDToken/Token.m | 23 ++++++++++----------- EstEIDToken/TokenSession.m | 42 +++++++++++++++++++++++--------------- 3 files changed, 36 insertions(+), 30 deletions(-) diff --git a/EstEIDToken/Token.h b/EstEIDToken/Token.h index 5eefd9a..2213224 100644 --- a/EstEIDToken/Token.h +++ b/EstEIDToken/Token.h @@ -17,7 +17,6 @@ * */ -#import #import #import diff --git a/EstEIDToken/Token.m b/EstEIDToken/Token.m index 0521d89..f9e70c0 100644 --- a/EstEIDToken/Token.m +++ b/EstEIDToken/Token.m @@ -113,22 +113,12 @@ - (BOOL)populateIdentity:(NSMutableArray *)items certific } return NO; } -#if ENABLE_RSA == 0 - SecKeyRef pubKey; - SecCertificateCopyPublicKey((__bridge SecCertificateRef)certificate, &pubKey); - NSDictionary *attributes = CFBridgingRelease(SecKeyCopyAttributes(pubKey)); - CFRelease(pubKey); - if ([attributes[(__bridge NSString*)kSecAttrKeyType] caseInsensitiveCompare:(__bridge NSString*)kSecAttrKeyTypeRSA] == NSOrderedSame) { - NSLog(@"EstEIDToken populateIdentityFromSmartCard: RSA support is disabled"); - return NO; - } -#endif + TKTokenKeychainCertificate *certificateItem = [[TKTokenKeychainCertificate alloc] initWithCertificate:(__bridge SecCertificateRef)certificate objectID:certificateID]; if (certificateItem == nil) { return NO; } [certificateItem setName:certificateName]; - [items addObject:certificateItem]; // Create key item. TKTokenKeychainKey *keyItem = [[TKTokenKeychainKey alloc] initWithCertificate:(__bridge SecCertificateRef)certificate objectID:keyID]; @@ -137,6 +127,13 @@ - (BOOL)populateIdentity:(NSMutableArray *)items certific } [keyItem setName:keyName]; +#if ENABLE_RSA == 0 + if ([keyItem.keyType isEqual:(id)kSecAttrKeyTypeRSA]) { + NSLog(@"EstEIDToken populateIdentityFromSmartCard: RSA support is disabled"); + return NO; + } +#endif + keyItem.canSign = YES; keyItem.canDecrypt = NO; //auth; FIXME: implement encryption keyItem.suitableForLogin = NO; //auth; @@ -147,6 +144,8 @@ - (BOOL)populateIdentity:(NSMutableArray *)items certific constraints[@(TKTokenOperationDecryptData)] = EstEIDConstraintPIN; } keyItem.constraints = constraints; + + [items addObject:certificateItem]; [items addObject:keyItem]; return YES; } @@ -173,7 +172,7 @@ - (nullable instancetype)initWithSmartCard:(TKSmartCard *)smartCard AID:(nullabl if (self = [super initWithSmartCard:smartCard AID:AID instanceID:instanceID tokenDriver:tokenDriver]) { // Prepare array with keychain items representing on card objects. - NSMutableArray *items = [NSMutableArray arrayWithCapacity:4]; + NSMutableArray *items = [NSMutableArray arrayWithCapacity:2]; if (![self populateIdentity:items certificateID:@(0xAACE) name:NSLocalizedString(@"AUTH_CERT", nil) certData:auth keyID:@(0x1100) name:NSLocalizedString(@"AUTH_KEY", nil) auth:YES error:error]/* || diff --git a/EstEIDToken/TokenSession.m b/EstEIDToken/TokenSession.m index 669b7f1..3eedde2 100644 --- a/EstEIDToken/TokenSession.m +++ b/EstEIDToken/TokenSession.m @@ -23,6 +23,17 @@ @implementation EstEIDAuthOperation +- (nullable instancetype)initWithSmartCard:(TKSmartCard *)smartCard { + if (self = [super init]) { + self.smartCard = smartCard; + self.APDUTemplate = [NSData dataWithBytes:(const UInt8[]){self.smartCard.cla, 0x20, 0x00, 0x01, 0x00} length:5]; + self.PINByteOffset = 5; + self.PINFormat.maxPINLength = 12; + self.PINFormat.PINBlockByteLength = 0; + } + return self; +} + - (BOOL)finishWithError:(NSError **)error { NSLog(@"EstEIDAuthOperation finishWithError %@", *error); @@ -76,15 +87,15 @@ - (BOOL)finishWithError:(NSError **)error { @implementation EstEIDTokenSession - (TKTokenAuthOperation *)tokenSession:(TKTokenSession *)session beginAuthForOperation:(TKTokenOperation)operation constraint:(TKTokenOperationConstraint)constraint error:(NSError **)error { - NSLog(@"EstEIDTokenSession beginAuthForOperation"); + NSLog(@"EstEIDTokenSession beginAuthForOperation %@ constraint %@", @(operation), constraint); if ([constraint isEqual:EstEIDConstraintPIN]) { - EstEIDAuthOperation *auth = [[EstEIDAuthOperation alloc] init]; - auth.smartCard = self.smartCard; - auth.APDUTemplate = [NSData dataWithBytes:(const UInt8[]){self.smartCard.cla, 0x20, 0x00, 0x01, 0x00} length:5]; - auth.PINByteOffset = 5; - auth.PINFormat.maxPINLength = 12; - auth.PINFormat.PINBlockByteLength = 0; - return auth; + dispatch_semaphore_t sem = dispatch_semaphore_create(0); + [self.smartCard beginSessionWithReply:^(BOOL success, NSError *error) { + NSLog(@"EstEIDTokenSession beginAuthForOperation beginSessionWithReply %@ %@", @(success), error); + dispatch_semaphore_signal(sem); + }]; + dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); + return [[EstEIDAuthOperation alloc] initWithSmartCard:self.smartCard]; } NSLog(@"EstEIDTokenSession beginAuthForOperation attempt to evaluate unsupported constraint %@", constraint); if (error != nil) { @@ -117,9 +128,7 @@ - (BOOL)tokenSession:(TKTokenSession *)session supportsOperation:(TKTokenOperati [algorithm isAlgorithm:kSecKeyAlgorithmECDSASignatureDigestX962SHA512]); break; case TKTokenOperationDecryptData: -#if ENABLE_RSA //supports = keyItem.canDecrypt && [algorithm isAlgorithm:kSecKeyAlgorithmRSAEncryptionRaw]; // FIXME: implement encryption -#endif break; case TKTokenOperationPerformKeyExchange: //supports = keyItem.canPerformKeyExchange && [algorithm isAlgorithm:kSecKeyAlgorithmECDHKeyExchangeStandard]; // FIXME: implement derive @@ -152,8 +161,6 @@ - (NSData *)tokenSession:(TKTokenSession *)session signData:(NSData *)dataToSign } UInt16 sw; - NSData *DEFAULT = [NSData dataWithBytes:(const UInt8[]){ 0x83, 0x00 } length:2]; //Key reference, 8303801100 - [self.smartCard sendIns:0x22 p1:0xF3 p2:0x01 data:nil le:@0 sw:&sw error:error]; if (sw != 0x9000) { NSLog(@"EstEIDTokenSession signData failed to set sec env"); @@ -163,6 +170,7 @@ - (NSData *)tokenSession:(TKTokenSession *)session signData:(NSData *)dataToSign return nil; } + NSData *DEFAULT = [NSData dataWithBytes:(const UInt8[]){ 0x83, 0x00 } length:2]; //Key reference, 8303801100 [self.smartCard sendIns:0x22 p1:0x41 p2:0xB8 data:DEFAULT le:nil sw:&sw error:error]; if (sw != 0x9000) { NSLog(@"EstEIDTokenSession signData failed to select default key"); @@ -193,6 +201,7 @@ - (NSData *)tokenSession:(TKTokenSession *)session signData:(NSData *)dataToSign self.smartCard.sensitive = NO; self.smartCard.context = nil; + [self.smartCard endSession]; if ([algorithm isAlgorithm:kSecKeyAlgorithmECDSASignatureDigestX962] || [algorithm isAlgorithm:kSecKeyAlgorithmECDSASignatureDigestX962SHA1] || [algorithm isAlgorithm:kSecKeyAlgorithmECDSASignatureDigestX962SHA224] || @@ -214,11 +223,10 @@ - (NSData *)tokenSession:(TKTokenSession *)session signData:(NSData *)dataToSign }; uint8 *bytes = (uint8*)response.bytes; - ECDSA ecdsa; - ecdsa.r.Length = response.length / 2; - ecdsa.r.Data = bytes; - ecdsa.s.Length = response.length / 2; - ecdsa.s.Data = &bytes[response.length / 2]; + ECDSA ecdsa = { + { response.length / 2, bytes }, + { response.length / 2, &bytes[response.length / 2] }, + }; SecAsn1CoderRef coder; SecAsn1CoderCreate(&coder);