summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2015-09-19 16:02:17 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2015-09-19 16:02:17 -0500
commita17dfea5e797b9fae31b88e840bb5fa13069ae0d (patch)
tree67a4d24cc8c146eb7faa90a3bd7cb20aa2264c13
parentfa4e775460bf35b655335515cb9b11a4dee9ff1a (diff)
downloadtdelibs-a17dfea5.tar.gz
tdelibs-a17dfea5.zip
Implement autoPIN certificate parsing
-rw-r--r--tdecore/tdehw/tdecryptographiccarddevice.cpp65
-rw-r--r--tdecore/tdehw/tdecryptographiccarddevice_private.h1
2 files changed, 62 insertions, 4 deletions
diff --git a/tdecore/tdehw/tdecryptographiccarddevice.cpp b/tdecore/tdehw/tdecryptographiccarddevice.cpp
index c687643d0..5958e86d7 100644
--- a/tdecore/tdehw/tdecryptographiccarddevice.cpp
+++ b/tdecore/tdehw/tdecryptographiccarddevice.cpp
@@ -571,12 +571,69 @@ void TDECryptographicCardDevice::setProvidedPin(TQString pin) {
}
TQString TDECryptographicCardDevice::autoPIN() {
- // TODO
+ TQString retString = TQString::null;
+
// Use subjAltName field in card certificate to provide the card's PIN,
// in order to support optional pin-less operation.
- // FIXME
- // Disable fully automatic card login support for now...
- return TQString::null;
+ // Parse the TDE autologin extension
+ // Structure:
+ // OID 1.3.6.1.4.1.40364.1.2.1
+ // SEQUENCE
+ // ASN1_CONSTRUCTED [index: 0] (field name: pin)
+ // GeneralString
+
+ // Register custom OID type for TDE autopin data
+ ASN1_OBJECT* tde_autopin_data_object = OBJ_txt2obj("1.3.6.1.4.1.40364.1.2.1", 0);
+
+ int i;
+ X509CertificatePtrListIterator it;
+ for (it = m_cardCertificates.begin(); it != m_cardCertificates.end(); ++it) {
+ X509* x509_cert = *it;
+ GENERAL_NAMES* subjectAltNames = (GENERAL_NAMES*)X509_get_ext_d2i(x509_cert, NID_subject_alt_name, NULL, NULL);
+ int altNameCount = sk_GENERAL_NAME_num(subjectAltNames);
+ for (i=0; i < altNameCount; i++) {
+ GENERAL_NAME* generalName = sk_GENERAL_NAME_value(subjectAltNames, i);
+ if (generalName->type == GEN_OTHERNAME) {
+ OTHERNAME* otherName = generalName->d.otherName;
+ if (!OBJ_cmp(otherName->type_id, tde_autopin_data_object)) {
+ ASN1_TYPE* asnValue = otherName->value;
+ if (asnValue) {
+ // Found autopin structure
+ int index;
+ ASN1_TYPE* asnSeqValue = NULL;
+ ASN1_GENERALSTRING* asnGeneralString = NULL;
+ STACK_OF(ASN1_TYPE) *asnSeqValueStack = NULL;
+ long asn1SeqValueObjectLength;
+ int asn1SeqValueObjectTag;
+ int asn1SeqValueObjectClass;
+ int returnCode;
+
+ index = 0; // Search for the PIN field
+ asnSeqValueStack = ASN1_seq_unpack_ASN1_TYPE(ASN1_STRING_data(asnValue->value.sequence), ASN1_STRING_length(asnValue->value.sequence), d2i_ASN1_TYPE, ASN1_TYPE_free);
+ asnSeqValue = sk_ASN1_TYPE_value(asnSeqValueStack, index);
+ if (asnSeqValue) {
+ if (asnSeqValue->value.octet_string->data[0] == ((V_ASN1_CONSTRUCTED | V_ASN1_CONTEXT_SPECIFIC) + index)) {
+ const unsigned char* asn1SeqValueObjectData = asnSeqValue->value.sequence->data;
+ returnCode = ASN1_get_object(&asn1SeqValueObjectData, &asn1SeqValueObjectLength, &asn1SeqValueObjectTag, &asn1SeqValueObjectClass, asnSeqValue->value.sequence->length);
+ if (!(returnCode & 0x80)) {
+ if (returnCode == (V_ASN1_CONSTRUCTED + index)) {
+ if (d2i_ASN1_GENERALSTRING(&asnGeneralString, &asn1SeqValueObjectData, asn1SeqValueObjectLength) != NULL) {
+ retString = TQString((const char *)ASN1_STRING_data(asnGeneralString));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Clean up
+ OBJ_cleanup();
+
+ return retString;
}
void TDECryptographicCardDevice::workerRequestedPin(TQString prompt) {
diff --git a/tdecore/tdehw/tdecryptographiccarddevice_private.h b/tdecore/tdehw/tdecryptographiccarddevice_private.h
index b7d38fe52..4f21b4bc1 100644
--- a/tdecore/tdehw/tdecryptographiccarddevice_private.h
+++ b/tdecore/tdehw/tdecryptographiccarddevice_private.h
@@ -32,6 +32,7 @@
#ifdef WITH_PKCS
#include <pkcs11-helper-1.0/pkcs11h-certificate.h>
#include <pkcs11-helper-1.0/pkcs11h-openssl.h>
+ #include <openssl/x509v3.h>
#define PKCS11H_PROMPT_MASK_ALLOW_NONE (PKCS11H_PROMPT_MASK_ALLOW_ALL & ~PKCS11H_PROMPT_MASK_ALLOW_ALL)
#endif