CHUID - Card Holder Unique Identifier
The CHUID is defined to provide the basis for interoperable identification of individuals and to extend capabilities over magnetic stripe technology for Physical Access Control System applications. It contains a series of mandatory and optional tagged objects. Some of these include the Federal Agency Smart Credential Number (FASC-N), the Global Unique ID (GUID), and the Asymmetric Signature.
FASC-N
Let's dive deeper into grabbing FASC-N data. First step is to get CHUID data.
// CHUID
TSS_PKI_Data *CHUID = [TSS_PKI_Data dataObjectWithName:@"CHUID"];
Next step is to get NSData of FASC-N.
if (CHUID) {
// FASC-N
NSData *FASCN = [CHUID dataWithBerTlvTag:0x30];
...
}
1) Convert FASC-N NSData to binary string. It should looks like this: "110101001110011....."
2) Divide this binary string into parts each 5 characters long.
3) Replace with corresponding character due to this part of code:
// The 40-character FASC-N credential is encoded as a 200 bit (25-byte) record
// Packed BCD 4-Bit Decimal Format with Odd Parity.
if ([bits isEqualToString:@"00001"]) return @"0";
else if ([bits isEqualToString:@"10000"]) return @"1";
else if ([bits isEqualToString:@"01000"]) return @"2";
else if ([bits isEqualToString:@"11001"]) return @"3";
else if ([bits isEqualToString:@"00100"]) return @"4";
else if ([bits isEqualToString:@"10101"]) return @"5";
else if ([bits isEqualToString:@"01101"]) return @"6";
else if ([bits isEqualToString:@"11100"]) return @"7";
else if ([bits isEqualToString:@"00010"]) return @"8";
else if ([bits isEqualToString:@"10011"]) return @"9";
else if ([bits isEqualToString:@"11010"]) return @"S"; // Start Sentinel
else if ([bits isEqualToString:@"10110"]) return @"F"; // Field Separator
else if ([bits isEqualToString:@"11111"]) return @"E"; // End Sentinel
Final string format of FASC-N should looks like this: "S9999F9999F999999F1F1F1234567890199991E8". But how to interpret this string? I found all important informations in documentation in TIG SCEPACS v2.3 by the Physical Access Interagency Interoperability Working Group, December 20, 2005. - Refer to section 6.1
You will find all informations about FASC-N in the documentation. Here we have FASC-N description:
and here we have FASC-N field description:
GIUD
Extending our code we can start grabbing GUID data.
// CHUID
TSS_PKI_Data *CHUID = [TSS_PKI_Data dataObjectWithName:@"CHUID"];
NSUUID *UUID = nil;
VLFASCNData *FASCNData = nil;
if (CHUID) {
NSData *FASCN = [CHUID dataWithBerTlvTag:0x30];
if (FASCN) {
FASCNData = [[VLFASCNData alloc] initWithFASCNData:FASCN];
}
// GUID
NSData *GUID = [CHUID dataWithBerTlvTag:0x34];
if (GUID) {
// RFC 4122 - conformant UUID value
UUID = [[NSUUID alloc]initWithUUIDBytes:GUID.bytes];
}
}
X.509 / X.509 Extension
At the end of this tutorial, here is example code how to grab subject name, email or Authority Key Identifier (AKI) / Subject Key Identifier (SKI) from X.509 extension.
NSArray *certs = [TSS_PKI_Identity currentIdentitiesWithAssertion:kAssertCertificateKeyUsageDigitalSignature];
NSString *subjectName;
NSString *emailAddress;
NSData *dataAKI;
NSData *dataSKI;
if ( certs.count > 0 ) {
TSS_PKI_Identity *signatureCert = certs[0];
subjectName = signatureCert.certificate.subjectName;
emailAddress = signatureCert.certificate.subjectAltNames[X509SubjectAltNameRFC822];
// Authority Key Identifier & Subject Key Identifier
X509 *inCert = signatureCert.certificate.nativeX509;
X509_EXTENSION *authorityKeyIdentifier = getExtensionFromCert(inCert, NID_authority_key_identifier);
X509_EXTENSION *subjectKeyIdentifier = getExtensionFromCert(inCert, NID_subject_key_identifier);
if (authorityKeyIdentifier) {
dataAKI = [NSData dataWithBytes:authorityKeyIdentifier->value->data length:authorityKeyIdentifier->value->length];
}
if (subjectKeyIdentifier) {
dataSKI = [NSData dataWithBytes:subjectKeyIdentifier->value->data length:subjectKeyIdentifier->value->length];
}
}
It takes a time to get all the informations about reading specific data from smart card. I hope these tutorials will help you with development for iOS devices which needs to grab data from smart cards.