Revision: 77 http://trac.macosforge.org/projects/smartcardservices/changeset/77 Author: ludovic.rousseau@gmail.com Date: 2009-12-18 06:23:24 -0800 (Fri, 18 Dec 2009) Log Message: ----------- merge changes from releases/Apple/Mac OS X 10.6.0/Tokend-36720 Modified Paths: -------------- trunk/Tokend/BELPIC/BELPICError.cpp trunk/Tokend/BELPIC/BELPICError.h trunk/Tokend/BELPIC/BELPICRecord.cpp trunk/Tokend/BELPIC/BELPICRecord.h trunk/Tokend/BELPIC/BELPICSchema.cpp trunk/Tokend/BELPIC/BELPICSchema.h trunk/Tokend/BELPIC/BELPICToken.cpp trunk/Tokend/BELPIC/Info.plist trunk/Tokend/BELPIC/belpic.cpp trunk/Tokend/CAC/CACError.cpp trunk/Tokend/CAC/CACError.h trunk/Tokend/CAC/CACRecord.cpp trunk/Tokend/CAC/CACRecord.h trunk/Tokend/CAC/CACToken.cpp trunk/Tokend/CAC/Info.plist trunk/Tokend/CAC/cac.cpp trunk/Tokend/MuscleCard/Info.plist trunk/Tokend/PIV/Info.plist trunk/Tokend/PIV/PIVAttributeCoder.cpp trunk/Tokend/PIV/PIVAttributeCoder.h trunk/Tokend/PIV/PIVCCC.h trunk/Tokend/PIV/PIVDefines.h trunk/Tokend/PIV/PIVError.cpp trunk/Tokend/PIV/PIVError.h trunk/Tokend/PIV/PIVKeyHandle.cpp trunk/Tokend/PIV/PIVKeyHandle.h trunk/Tokend/PIV/PIVRecord.cpp trunk/Tokend/PIV/PIVRecord.h trunk/Tokend/PIV/PIVSchema.cpp trunk/Tokend/PIV/PIVSchema.h trunk/Tokend/PIV/PIVToken.cpp trunk/Tokend/PIV/PIVToken.h trunk/Tokend/PIV/Padding.cpp trunk/Tokend/PIV/SecureBufferAllocator.h trunk/Tokend/PIV/SecureBufferAllocator.inc trunk/Tokend/PIV/byte_string.h trunk/Tokend/PIV/piv.cpp trunk/Tokend/Tokend/Adornment.h trunk/Tokend/Tokend/Attribute.h trunk/Tokend/Tokend/AttributeCoder.cpp trunk/Tokend/Tokend/AttributeCoder.h trunk/Tokend/Tokend/DbValue.h trunk/Tokend/Tokend/MetaRecord.h trunk/Tokend/Tokend/PKCS11Object.h trunk/Tokend/Tokend/Record.h trunk/Tokend/Tokend/RecordHandle.h trunk/Tokend/Tokend/SCardError.cpp trunk/Tokend/Tokend/SCardError.h trunk/Tokend/Tokend/Schema.cpp trunk/Tokend/Tokend/Schema.h trunk/Tokend/Tokend/SelectionPredicate.h trunk/Tokend/Tokend/Token.cpp trunk/Tokend/Tokend/Token.h trunk/Tokend/Tokend/TokenContext.h trunk/Tokend/Tokend.xcodeproj/project.pbxproj Modified: trunk/Tokend/BELPIC/BELPICError.cpp =================================================================== --- trunk/Tokend/BELPIC/BELPICError.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/BELPIC/BELPICError.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -35,7 +35,11 @@ // BELPICError::BELPICError(uint16_t sw) : SCardError(sw) { +#if MAX_OS_X_VERSION_MIN_REQUIRED <= MAX_OS_X_VERSION_10_5 IFDEBUG(debugDiagnose(this)); +#else + SECURITY_EXCEPTION_THROW_OTHER(this, sw, (char *)"BELPIC"); +#endif } BELPICError::~BELPICError() throw () @@ -48,6 +52,8 @@ void BELPICError::throwMe(uint16_t sw) { throw BELPICError(sw); } +#if MAX_OS_X_VERSION_MIN_REQUIRED <= MAX_OS_X_VERSION_10_5 + #if !defined(NDEBUG) void BELPICError::debugDiagnose(const void *id) const @@ -58,3 +64,4 @@ #endif //NDEBUG +#endif // MAX_OS_X_VERSION_MIN_REQUIRED <= MAX_OS_X_VERSION_10_5 Modified: trunk/Tokend/BELPIC/BELPICError.h =================================================================== --- trunk/Tokend/BELPIC/BELPICError.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/BELPIC/BELPICError.h 2009-12-18 14:23:24 UTC (rev 77) @@ -43,7 +43,9 @@ static void check(uint16_t sw) { if (sw != SCARD_SUCCESS) throwMe(sw); } static void throwMe(uint16_t sw) __attribute__((noreturn)); protected: +#if MAX_OS_X_VERSION_MIN_REQUIRED <= MAX_OS_X_VERSION_10_5 IFDEBUG(void debugDiagnose(const void *id) const;) +#endif }; #endif /* !_BELPICERROR_H_ */ Modified: trunk/Tokend/BELPIC/BELPICRecord.cpp =================================================================== --- trunk/Tokend/BELPIC/BELPICRecord.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/BELPIC/BELPICRecord.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -53,7 +53,11 @@ #define BELPIC_MAXSIZE_CERT 4000 -Tokend::Attribute *BELPICBinaryFileRecord::getDataAttribute( +BELPICCertificateRecord::~BELPICCertificateRecord() +{ +} + +Tokend::Attribute *BELPICCertificateRecord::getDataAttribute( Tokend::TokenContext *tokenContext) { CssmData data; @@ -79,7 +83,44 @@ return new Tokend::Attribute(data.Data, data.Length); } +// +// BELPICProtectedRecord +// +BELPICProtectedRecord::~BELPICProtectedRecord() +{ +} +Tokend::Attribute *BELPICProtectedRecord::getDataAttribute(Tokend::TokenContext *tokenContext) +{ + // no caching + CssmData data; + BELPICToken &belpicToken = static_cast<BELPICToken &>(*tokenContext); + + PCSC::Transaction _(belpicToken); + belpicToken.select(mDF, mEF); + + uint8 certificate[BELPIC_MAXSIZE_CERT]; + size_t certificateLength = sizeof(certificate); + belpicToken.readBinary(certificate, certificateLength); + data.Data = certificate; + data.Length = certificateLength; + + return new Tokend::Attribute(data.Data, data.Length); +} + +void BELPICProtectedRecord::getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls) +{ + if (!mAclEntries) { + mAclEntries.allocator(Allocator::standard()); + // Reading this object's data requires PIN1 + mAclEntries.add(CssmClient::AclFactory::PinSubject( + mAclEntries.allocator(), 1), + AclAuthorizationSet(CSSM_ACL_AUTHORIZATION_DB_READ, 0)); + } + count = mAclEntries.size(); + acls = mAclEntries.entries(); +} + // // BELPICKeyRecord // Modified: trunk/Tokend/BELPIC/BELPICRecord.h =================================================================== --- trunk/Tokend/BELPIC/BELPICRecord.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/BELPIC/BELPICRecord.h 2009-12-18 14:23:24 UTC (rev 77) @@ -41,7 +41,7 @@ public: BELPICRecord(const char *description) : mDescription(description) {} - ~BELPICRecord(); + virtual ~BELPICRecord(); virtual const char *description() { return mDescription; } @@ -55,25 +55,52 @@ NOCOPY(BELPICBinaryFileRecord) public: BELPICBinaryFileRecord(const uint8_t *df, const uint8_t *ef, - const char *description) : - BELPICRecord(description), mDF(df), mEF(ef) {} - ~BELPICBinaryFileRecord(); - - virtual Tokend::Attribute *getDataAttribute( - Tokend::TokenContext *tokenContext); - + const char *description) : + BELPICRecord(description), mDF(df), mEF(ef) {} + virtual ~BELPICBinaryFileRecord(); + + virtual Tokend::Attribute *getDataAttribute(Tokend::TokenContext *tokenContext) = 0; + protected: const uint8_t *mDF; const uint8_t *mEF; }; +class BELPICCertificateRecord : public BELPICBinaryFileRecord +{ + NOCOPY(BELPICCertificateRecord) +public: + BELPICCertificateRecord(const uint8_t *df, const uint8_t *ef, + const char *description) : + BELPICBinaryFileRecord(df, ef, description) {} + virtual ~BELPICCertificateRecord(); + + virtual Tokend::Attribute *getDataAttribute(Tokend::TokenContext *tokenContext); +}; + +class BELPICProtectedRecord : public BELPICBinaryFileRecord +{ + NOCOPY(BELPICProtectedRecord) +public: + BELPICProtectedRecord(const uint8_t *df, const uint8_t *ef, const char *description) : + BELPICBinaryFileRecord(df, ef, description) {} + virtual ~BELPICProtectedRecord(); + + virtual Tokend::Attribute *getDataAttribute(Tokend::TokenContext *tokenContext); + virtual void getAcl(const char *tag, uint32 &count, + AclEntryInfo *&aclList); +private: + AutoAclEntryInfoList mAclEntries; +}; + + class BELPICKeyRecord : public BELPICRecord { NOCOPY(BELPICKeyRecord) public: BELPICKeyRecord(const uint8_t *keyId, const char *description, const Tokend::MetaRecord &metaRecord, bool signOnly); - ~BELPICKeyRecord(); + virtual ~BELPICKeyRecord(); size_t sizeInBits() const { return 1024; } void computeCrypt(BELPICToken &belpicToken, bool sign, Modified: trunk/Tokend/BELPIC/BELPICSchema.cpp =================================================================== --- trunk/Tokend/BELPIC/BELPICSchema.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/BELPIC/BELPICSchema.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -88,6 +88,12 @@ createStandardRelation(CSSM_DL_DB_RECORD_X509_CERTIFICATE); createKeyRelation(CSSM_DL_DB_RECORD_PRIVATE_KEY); - createStandardRelation(CSSM_DL_DB_RECORD_GENERIC); + + Relation *rn_gen = createStandardRelation(CSSM_DL_DB_RECORD_GENERIC); + + // Create the generic table + MetaRecord &mr_gen = rn_gen->metaRecord(); + mr_gen.attributeCoderForData(&mBELPICDataAttributeCoder); + } Modified: trunk/Tokend/BELPIC/BELPICSchema.h =================================================================== --- trunk/Tokend/BELPIC/BELPICSchema.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/BELPIC/BELPICSchema.h 2009-12-18 14:23:24 UTC (rev 77) @@ -31,6 +31,7 @@ #include "Schema.h" #include "BELPICKeyHandle.h" +#include "BELPICAttributeCoder.h" namespace Tokend { @@ -52,6 +53,9 @@ Tokend::Relation *createKeyRelation(CSSM_DB_RECORDTYPE keyType); private: + // Coders we need. + BELPICDataAttributeCoder mBELPICDataAttributeCoder; + Tokend::ConstAttributeCoder mKeyAlgorithmCoder; Tokend::ConstAttributeCoder mKeySizeCoder; Modified: trunk/Tokend/BELPIC/BELPICToken.cpp =================================================================== --- trunk/Tokend/BELPIC/BELPICToken.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/BELPIC/BELPICToken.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -384,18 +384,18 @@ uint32_t offset = 5; apdu[offset++] = 0x20 + oldPinLength; - for (uint32_t ix = 0; ix < oldPinLength;) + for (uint32_t ix = 0; ix < oldPinLength;ix+=2) { - apdu[offset++] = (pinDigit(oldPin[ix++]) << 4) + - (ix < oldPinLength ? pinDigit(oldPin[ix++]) : pinDigit('F')); + apdu[offset++] = (pinDigit(oldPin[ix]) << 4) + + ((ix+1) < oldPinLength ? pinDigit(oldPin[ix+1]) : pinDigit('F')); } offset = 5 + 8; apdu[offset++] = 0x20 + newPinLength; - for (uint32_t ix = 0; ix < newPinLength;) + for (uint32_t ix = 0; ix < newPinLength;ix+=2) { - apdu[offset++] = (pinDigit(newPin[ix++]) << 4) + - (ix < newPinLength ? pinDigit(newPin[ix++]) : pinDigit('F')); + apdu[offset++] = (pinDigit(newPin[ix]) << 4) + + ((ix+1) < newPinLength ? pinDigit(newPin[ix+1]) : pinDigit('F')); } unsigned char result[MAX_BUFFER_SIZE]; @@ -459,10 +459,10 @@ uint32_t offset = 5; apdu[offset++] = 0x20 + pinLength; - for (uint32_t ix = 0; ix < pinLength;) + for (uint32_t ix = 0; ix < pinLength;ix+=2) { - apdu[offset++] = (pinDigit(pin[ix++]) << 4) + - (ix < pinLength ? pinDigit(pin[ix++]) : pinDigit('F')); + apdu[offset++] = (pinDigit(pin[ix]) << 4) + + ((ix+1) < pinLength ? pinDigit(pin[ix+1]) : pinDigit('F')); } #endif @@ -471,6 +471,9 @@ mPinStatus = exchangeAPDU(apdu, sizeof(apdu), result, resultLength); memset(apdu + 5, 0, 8); BELPICError::check(mPinStatus); + // Start a new transaction which we never get rid of until someone calls + // unverifyPIN() + begin(); } void BELPICToken::unverifyPIN(int pinNum) @@ -484,8 +487,12 @@ uint32 BELPICToken::probe(SecTokendProbeFlags flags, char tokenUid[TOKEND_MAX_UID]) { - uint32 score = Tokend::ISO7816Token::probe(flags, tokenUid); - +// uint32 score = Tokend::ISO7816Token::probe(flags, tokenUid); +//SCARD_PROTOCOL_T0 + const SCARD_READERSTATE &readerState = *(*startupReaderInfo)(); + connect(mSession, readerState.szReader, SCARD_PROTOCOL_T0); + uint32 score = 0; + bool doDisconnect = false; /*!(flags & kSecTokendProbeKeepToken); */ try @@ -612,15 +619,15 @@ Tokend::Relation &dataRelation = mSchema->findRelation(CSSM_DL_DB_RECORD_GENERIC); - RefPointer<Tokend::Record> cert2(new BELPICBinaryFileRecord(kDF_BELPIC, + RefPointer<Tokend::Record> cert2(new BELPICCertificateRecord(kDF_BELPIC, kBELPIC_EF_Cert2, "Cert #2 (authentication)")); - RefPointer<Tokend::Record> cert3(new BELPICBinaryFileRecord(kDF_BELPIC, + RefPointer<Tokend::Record> cert3(new BELPICCertificateRecord(kDF_BELPIC, kBELPIC_EF_Cert3, "Cert #3 (signature)")); - RefPointer<Tokend::Record> cert4(new BELPICBinaryFileRecord(kDF_BELPIC, + RefPointer<Tokend::Record> cert4(new BELPICCertificateRecord(kDF_BELPIC, kBELPIC_EF_Cert4, "Cert #4 (CA)")); - RefPointer<Tokend::Record> cert6(new BELPICBinaryFileRecord(kDF_BELPIC, + RefPointer<Tokend::Record> cert6(new BELPICCertificateRecord(kDF_BELPIC, kBELPIC_EF_Cert6, "Cert #6 (root)")); - RefPointer<Tokend::Record> cert8(new BELPICBinaryFileRecord(kDF_BELPIC, + RefPointer<Tokend::Record> cert8(new BELPICCertificateRecord(kDF_BELPIC, kBELPIC_EF_Cert8, "Cert #8 (RN)")); certRelation.insertRecord(cert2); @@ -642,19 +649,19 @@ key3->setAdornment(mSchema->publicKeyHashCoder().certificateKey(), new Tokend::LinkedRecordAdornment(cert3)); - dataRelation.insertRecord(new BELPICBinaryFileRecord(kDF_ID, + dataRelation.insertRecord(new BELPICProtectedRecord(kDF_ID, kID_EF_ID_RN, "ID#RN")); - dataRelation.insertRecord(new BELPICBinaryFileRecord(kDF_ID, + dataRelation.insertRecord(new BELPICProtectedRecord(kDF_ID, kID_EF_SGN_RN, "SGN#RN")); - dataRelation.insertRecord(new BELPICBinaryFileRecord(kDF_ID, + dataRelation.insertRecord(new BELPICProtectedRecord(kDF_ID, kID_EF_ID_ADDRESS, "ID#Address")); - dataRelation.insertRecord(new BELPICBinaryFileRecord(kDF_ID, + dataRelation.insertRecord(new BELPICProtectedRecord(kDF_ID, kID_EF_SGN_ADDRESS, "SGN#Address")); - dataRelation.insertRecord(new BELPICBinaryFileRecord(kDF_ID, + dataRelation.insertRecord(new BELPICProtectedRecord(kDF_ID, kID_EF_ID_PHOTO, "ID#Photo")); - dataRelation.insertRecord(new BELPICBinaryFileRecord(kDF_ID, + dataRelation.insertRecord(new BELPICProtectedRecord(kDF_ID, kID_EF_PuK7_ID, "PuK#7 ID (CA role ID)")); - dataRelation.insertRecord(new BELPICBinaryFileRecord(kDF_ID, + dataRelation.insertRecord(new BELPICProtectedRecord(kDF_ID, kID_EF_Preferences, "Preferences")); secdebug("populate", "BELPICToken::populate() end"); Modified: trunk/Tokend/BELPIC/Info.plist =================================================================== --- trunk/Tokend/BELPIC/Info.plist 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/BELPIC/Info.plist 2009-12-18 14:23:24 UTC (rev 77) @@ -15,10 +15,10 @@ <key>CFBundlePackageType</key> <string>????</string> <key>CFBundleShortVersionString</key> - <string>2.1.1</string> + <string>2.2</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> - <string>1</string> + <string>36720</string> </dict> </plist> Modified: trunk/Tokend/BELPIC/belpic.cpp =================================================================== --- trunk/Tokend/BELPIC/belpic.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/BELPIC/belpic.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -30,7 +30,7 @@ int main(int argc, const char *argv[]) { secdebug("BELPIC.tokend", "main starting with %d arguments", argc); - secdelay("/tmp/delay/BELPIC"); + secdelay((char *)"/tmp/delay/BELPIC"); token = new BELPICToken(); return SecTokendMain(argc, argv, token->callbacks(), token->support()); Modified: trunk/Tokend/CAC/CACError.cpp =================================================================== --- trunk/Tokend/CAC/CACError.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/CAC/CACError.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -35,7 +35,11 @@ // CACError::CACError(uint16_t sw) : SCardError(sw) { +#if MAX_OS_X_VERSION_MIN_REQUIRED <= MAX_OS_X_VERSION_10_5 IFDEBUG(debugDiagnose(this)); +#else + SECURITY_EXCEPTION_THROW_OTHER(this, sw, (char *)"CAC"); +#endif } CACError::~CACError() throw () @@ -64,12 +68,16 @@ #if !defined(NDEBUG) +#if MAX_OS_X_VERSION_MIN_REQUIRED <= MAX_OS_X_VERSION_10_5 + void CACError::debugDiagnose(const void *id) const { secdebug("exception", "%p CACError %s (%04hX)", id, errorstr(statusWord), statusWord); } +#endif // MAX_OS_X_VERSION_MIN_REQUIRED <= MAX_OS_X_VERSION_10_5 + const char *CACError::errorstr(uint16_t sw) const { switch (sw) Modified: trunk/Tokend/CAC/CACError.h =================================================================== --- trunk/Tokend/CAC/CACError.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/CAC/CACError.h 2009-12-18 14:23:24 UTC (rev 77) @@ -53,7 +53,9 @@ static void throwMe(uint16_t sw) __attribute__((noreturn)); protected: +#if MAX_OS_X_VERSION_MIN_REQUIRED <= MAX_OS_X_VERSION_10_5 IFDEBUG(void debugDiagnose(const void *id) const;) +#endif IFDEBUG(const char *errorstr(uint16_t sw) const;) }; Modified: trunk/Tokend/CAC/CACRecord.cpp =================================================================== --- trunk/Tokend/CAC/CACRecord.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/CAC/CACRecord.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -134,17 +134,16 @@ // CACKeyRecord // CACKeyRecord::CACKeyRecord(const unsigned char *application, - const char *description, const Tokend::MetaRecord &metaRecord, - bool signOnly) : - CACRecord(application, description), - mSignOnly(signOnly) + const char *description, const Tokend::MetaRecord &metaRecord) : + CACRecord(application, description) { + // Allow all keys to decrypt, unwrap, sign attributeAtIndex(metaRecord.metaAttribute(kSecKeyDecrypt).attributeIndex(), - new Tokend::Attribute(!signOnly)); + new Tokend::Attribute(true)); attributeAtIndex(metaRecord.metaAttribute(kSecKeyUnwrap).attributeIndex(), - new Tokend::Attribute(!signOnly)); + new Tokend::Attribute(true)); attributeAtIndex(metaRecord.metaAttribute(kSecKeySign).attributeIndex(), - new Tokend::Attribute(signOnly)); + new Tokend::Attribute(true)); } CACKeyRecord::~CACKeyRecord() @@ -158,9 +157,6 @@ if (dataLength > sizeInBits() / 8) CssmError::throwMe(CSSMERR_CSP_BLOCK_SIZE_MISMATCH); - if (sign != mSignOnly) - CssmError::throwMe(CSSMERR_CSP_KEY_USAGE_INCORRECT); - PCSC::Transaction _(cacToken); cacToken.select(mApplication); size_t apduSize = dataLength + 5; @@ -199,18 +195,20 @@ mAclEntries.add(CssmClient::AclFactory::AnySubject( mAclEntries.allocator()), AclAuthorizationSet(CSSM_ACL_AUTHORIZATION_DB_READ, 0)); + // Using this key to sign or decrypt will require PIN1 + char tmptag[20]; + const uint32 slot = 1; // hardwired for now, but... + snprintf(tmptag, sizeof(tmptag), "PIN%d", slot); mAclEntries.add(CssmClient::AclFactory::PinSubject( mAclEntries.allocator(), 1), - AclAuthorizationSet((mSignOnly - ? CSSM_ACL_AUTHORIZATION_SIGN - : CSSM_ACL_AUTHORIZATION_DECRYPT), 0)); + AclAuthorizationSet(CSSM_ACL_AUTHORIZATION_SIGN, CSSM_ACL_AUTHORIZATION_DECRYPT, 0), + tmptag); } count = mAclEntries.size(); acls = mAclEntries.entries(); } - // // CACTBRecord // @@ -260,11 +258,11 @@ #endif /* - See NIST IR 6887 – 2003 EDITION, GSC-IS VERSION 2.1 + See NIST IR 6887 \xD0 2003 EDITION, GSC-IS VERSION 2.1 5.3.4 Generic Container Provider Virtual Machine Card Edge Interface for a description of how this command works - READ BUFFER 0x80 0x52 Off/H Off/L 0x02 <buffer & number bytes to read> – + READ BUFFER 0x80 0x52 Off/H Off/L 0x02 <buffer & number bytes to read> \xD0 */ Tokend::Attribute *CACTBRecord::getDataAttribute(CACToken &cacToken, Modified: trunk/Tokend/CAC/CACRecord.h =================================================================== --- trunk/Tokend/CAC/CACRecord.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/CAC/CACRecord.h 2009-12-18 14:23:24 UTC (rev 77) @@ -39,7 +39,7 @@ public: CACRecord(const unsigned char *application, const char *description) : mApplication(application), mDescription(description) {} - ~CACRecord(); + virtual ~CACRecord(); virtual const char *description() { return mDescription; } @@ -59,7 +59,7 @@ CACCertificateRecord(const unsigned char *application, const char *description) : CACRecord(application, description) {} - ~CACCertificateRecord(); + virtual ~CACCertificateRecord(); virtual Tokend::Attribute *getDataAttribute(Tokend::TokenContext *tokenContext); }; @@ -69,8 +69,8 @@ NOCOPY(CACKeyRecord) public: CACKeyRecord(const unsigned char *application, const char *description, - const Tokend::MetaRecord &metaRecord, bool signOnly); - ~CACKeyRecord(); + const Tokend::MetaRecord &metaRecord); + virtual ~CACKeyRecord(); size_t sizeInBits() const { return 1024; } void computeCrypt(CACToken &cacToken, bool sign, const unsigned char *data, @@ -79,7 +79,6 @@ virtual void getAcl(const char *tag, uint32 &count, AclEntryInfo *&aclList); private: - bool mSignOnly; AutoAclEntryInfoList mAclEntries; }; @@ -90,7 +89,7 @@ public: CACTBRecord(const unsigned char *application, const char *description) : CACRecord(application, description) {} - ~CACTBRecord(); + virtual ~CACTBRecord(); virtual Tokend::Attribute *getDataAttribute(Tokend::TokenContext *tokenContext); @@ -106,7 +105,7 @@ public: CACVBRecord(const unsigned char *application, const char *description) : CACTBRecord(application, description) {} - ~CACVBRecord(); + virtual ~CACVBRecord(); virtual Tokend::Attribute *getDataAttribute(Tokend::TokenContext *tokenContext); virtual void getAcl(const char *tag, uint32 &count, Modified: trunk/Tokend/CAC/CACToken.cpp =================================================================== --- trunk/Tokend/CAC/CACToken.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/CAC/CACToken.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -114,7 +114,8 @@ transmit(applet, applet_length, result, resultLength); // If the select command failed this isn't a cac card, so we are done. - if (resultLength < 2 || result[resultLength - 2] != 0x90 && result[resultLength - 2] != 0x61 /* || result[resultLength - 1] != 0x0D */) + if (resultLength < 2 || result[resultLength - 2] != 0x90 && + result[resultLength - 2] != 0x61 /* || result[resultLength - 1] != 0x0D */) PCSC::Error::throwMe(SCARD_E_PROTO_MISMATCH); if (isInTransaction()) @@ -451,20 +452,20 @@ { unsigned char result[0x2F]; size_t resultLength = sizeof(result); - uint32_t cacreturn = getData(result, resultLength); + /* uint32_t cacreturn = */ getData(result, resultLength); /* Score of 200 to ensure that CAC "wins" for Hybrid CAC/PIV cards */ - score = 200; - // Now stick in the bytes returned by getData into the - // tokenUid. + score = 200; + // Now stick in the bytes returned by getData into the + // tokenUid. if(resultLength > 20) - { - sprintf(tokenUid, - "CAC-%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X", - result[3], result[4], result[5], result[6], result[19], - result[20], result[15], result[16], result[17], - result[18]); - } + { + sprintf(tokenUid, + "CAC-%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X", + result[3], result[4], result[5], result[6], result[19], + result[20], result[15], result[16], result[17], + result[18]); + } else { /* Cannot generated a tokenUid given the returned data. @@ -476,10 +477,10 @@ strftime(reinterpret_cast<char *>(buffer), 80, "%s", timestruct); snprintf(tokenUid, TOKEND_MAX_UID, "CAC-%s", buffer); } - Tokend::ISO7816Token::name(tokenUid); - secdebug("probe", "recognized %s", tokenUid); - } + Tokend::ISO7816Token::name(tokenUid); + secdebug("probe", "recognized %s", tokenUid); } + } catch (...) { doDisconnect = true; @@ -587,13 +588,13 @@ RefPointer<Tokend::Record> idKey(new CACKeyRecord( kSelectCACAppletPKIID, "Identity Private Key", - privateKeyRelation.metaRecord(), true)); + privateKeyRelation.metaRecord())); RefPointer<Tokend::Record> eSigKey(new CACKeyRecord( kSelectCACAppletPKIESig, "Email Signing Private Key", - privateKeyRelation.metaRecord(), true)); + privateKeyRelation.metaRecord())); RefPointer<Tokend::Record> eCryKey(new CACKeyRecord( kSelectCACAppletPKIECry, "Email Encryption Private Key", - privateKeyRelation.metaRecord(), false)); + privateKeyRelation.metaRecord())); privateKeyRelation.insertRecord(idKey); privateKeyRelation.insertRecord(eSigKey); Modified: trunk/Tokend/CAC/Info.plist =================================================================== --- trunk/Tokend/CAC/Info.plist 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/CAC/Info.plist 2009-12-18 14:23:24 UTC (rev 77) @@ -15,10 +15,10 @@ <key>CFBundlePackageType</key> <string>????</string> <key>CFBundleShortVersionString</key> - <string>2.1.1</string> + <string>2.2</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> - <string>1</string> + <string>36720</string> </dict> </plist> Modified: trunk/Tokend/CAC/cac.cpp =================================================================== --- trunk/Tokend/CAC/cac.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/CAC/cac.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -30,7 +30,7 @@ int main(int argc, const char *argv[]) { secdebug("CAC.tokend", "main starting with %d arguments", argc); - secdelay("/tmp/delay/CAC"); + secdelay((char *)"/tmp/delay/CAC"); #if 0 setenv("DEBUGSCOPE", "-mutex,walkers", 0); Modified: trunk/Tokend/MuscleCard/Info.plist =================================================================== --- trunk/Tokend/MuscleCard/Info.plist 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/MuscleCard/Info.plist 2009-12-18 14:23:24 UTC (rev 77) @@ -19,6 +19,6 @@ <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> - <string>1</string> + <string>36720</string> </dict> </plist> Modified: trunk/Tokend/PIV/Info.plist =================================================================== --- trunk/Tokend/PIV/Info.plist 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/PIV/Info.plist 2009-12-18 14:23:24 UTC (rev 77) @@ -15,10 +15,10 @@ <key>CFBundlePackageType</key> <string>????</string> <key>CFBundleShortVersionString</key> - <string>2.1.1</string> + <string>2.2</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> - <string>1234</string> + <string>36720</string> </dict> </plist> Modified: trunk/Tokend/PIV/PIVAttributeCoder.cpp =================================================================== --- trunk/Tokend/PIV/PIVAttributeCoder.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/PIV/PIVAttributeCoder.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -56,3 +56,15 @@ record.attributeAtIndex(metaAttribute.attributeIndex(), pivRecord.getDataAttribute(tokenContext)); } + +// +// PIVKeySizeAttributeCoder +// +PIVKeySizeAttributeCoder::~PIVKeySizeAttributeCoder() {} + +void PIVKeySizeAttributeCoder::decode(Tokend::TokenContext *tokenContext, + const Tokend::MetaAttribute &metaAttribute, Tokend::Record &record) +{ + uint32 keySize = dynamic_cast<PIVKeyRecord &>(record).sizeInBits(); + record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute(keySize)); +} Modified: trunk/Tokend/PIV/PIVAttributeCoder.h =================================================================== --- trunk/Tokend/PIV/PIVAttributeCoder.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/PIV/PIVAttributeCoder.h 2009-12-18 14:23:24 UTC (rev 77) @@ -55,5 +55,20 @@ const Tokend::MetaAttribute &metaAttribute, Tokend::Record &record); }; + +// +// A coder that produces the LogicalKeySizeInBits of a key +// +class PIVKeySizeAttributeCoder : public Tokend::AttributeCoder +{ + NOCOPY(PIVKeySizeAttributeCoder) +public: + PIVKeySizeAttributeCoder() {} + virtual ~PIVKeySizeAttributeCoder(); + + virtual void decode(Tokend::TokenContext *tokenContext, const Tokend::MetaAttribute &metaAttribute, Tokend::Record &record); +}; + + #endif /* !_PIVATTRIBUTECODER_H_ */ Modified: trunk/Tokend/PIV/PIVCCC.h =================================================================== --- trunk/Tokend/PIV/PIVCCC.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/PIV/PIVCCC.h 2009-12-18 14:23:24 UTC (rev 77) @@ -39,7 +39,7 @@ { public: PIVCCC(const byte_string &data) throw(PIVError); - virtual ~PIVCCC(); + virtual ~PIVCCC(); const unsigned char *identifier() const { return mIdentifier; } std::string hexidentifier() const; Modified: trunk/Tokend/PIV/PIVDefines.h =================================================================== --- trunk/Tokend/PIV/PIVDefines.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/PIV/PIVDefines.h 2009-12-18 14:23:24 UTC (rev 77) @@ -29,8 +29,6 @@ #ifndef _PIVDEFINES_H_ #define _PIVDEFINES_H_ -#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h> - /* For the PIV tokend, refer to NIST Specical Publication 800-73-1, "Interfaces for Personal Identity Verification". The define for CLA_STANDARD comes from 2.3.3.1.1. [SP800731] Modified: trunk/Tokend/PIV/PIVError.cpp =================================================================== --- trunk/Tokend/PIV/PIVError.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/PIV/PIVError.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -48,7 +48,11 @@ // PIVError::PIVError(uint16_t sw) : SCardError(sw) { +#if MAX_OS_X_VERSION_MIN_REQUIRED <= MAX_OS_X_VERSION_10_5 IFDEBUG(debugDiagnose(this)); +#else + SECURITY_EXCEPTION_THROW_OTHER(this, sw, (char *)"PIV"); +#endif } PIVError::~PIVError() throw () @@ -78,12 +82,16 @@ #if !defined(NDEBUG) +#if MAX_OS_X_VERSION_MIN_REQUIRED <= MAX_OS_X_VERSION_10_5 + void PIVError::debugDiagnose(const void *id) const { secdebug("exception", "%p PIVError %s (%04hX)", id, errorstr(statusWord), statusWord); } +#endif // MAX_OS_X_VERSION_MIN_REQUIRED <= MAX_OS_X_VERSION_10_5 + const char *PIVError::errorstr(uint16_t sw) const { switch (sw) Modified: trunk/Tokend/PIV/PIVError.h =================================================================== --- trunk/Tokend/PIV/PIVError.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/PIV/PIVError.h 2009-12-18 14:23:24 UTC (rev 77) @@ -53,7 +53,7 @@ { protected: PIVError(uint16_t sw); - virtual ~PIVError() throw (); + virtual ~PIVError() throw (); public: OSStatus osStatus() const; virtual const char *what () const throw (); @@ -62,7 +62,9 @@ static void throwMe(uint16_t sw) __attribute__((noreturn)); protected: +#if MAX_OS_X_VERSION_MIN_REQUIRED <= MAX_OS_X_VERSION_10_5 IFDEBUG(void debugDiagnose(const void *id) const;) +#endif IFDEBUG(const char *errorstr(uint16_t sw) const;) }; Modified: trunk/Tokend/PIV/PIVKeyHandle.cpp =================================================================== --- trunk/Tokend/PIV/PIVKeyHandle.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/PIV/PIVKeyHandle.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -26,16 +26,6 @@ * TokendPIV */ -/* --------------------------------------------------------------------------- - * - * MODIFY - * - It may be that this file does not have to be modified. The heavy - * lifting here is done by computeCrypt, so this might be the only - * place to insert token-specific code. See PIVRecord.cpp for that. - * - * --------------------------------------------------------------------------- -*/ - #include "PIVKeyHandle.h" #include "PIVRecord.h" @@ -78,7 +68,7 @@ { secdebug("crypto", "getOutputSize"); if (encrypting) - CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED); + CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED); return inputSize; //accurate for crypto used on PIV cards } @@ -105,17 +95,19 @@ uint32 padding = CSSM_PADDING_PKCS1; context.getInt(CSSM_ATTRIBUTE_PADDING, padding); - Padding::apply(inputData, mKey.sizeInBits() / 8, alg, padding); + Padding::apply(inputData, mKey.sizeInBits() / 8, padding, alg); // @@@ Switch to using tokend allocators /* Use ref to a new buffer item to keep the data around after the function ends */ - byte_string& outputData = bufferAllocator.getBuffer(); + size_t keyLength = mKey.sizeInBits() / 8; + byte_string outputData; + outputData.reserve(keyLength); const AccessCredentials *cred = context.get<const AccessCredentials>(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS); - // Sign the inputData using the token + // Sign the inputData using the token mKey.computeCrypt(mToken, true, cred, inputData, outputData); - signature.Data = &outputData[0]; + signature.Data = malloc_copy(outputData); signature.Length = outputData.size(); } @@ -172,16 +164,16 @@ // @@@ Use a secure allocator for this. /* Use ref to a new buffer item to keep the data around after the function ends */ - byte_string& outputData = bufferAllocator.getBuffer(); + byte_string outputData; outputData.reserve(cipher.Length); // --- support for multiples of keyLength by doing multiple blocks for(size_t i = 0; i < cipher.Length; i += keyLength) { byte_string inputData(cipher.Data + i, cipher.Data + i + keyLength); byte_string tmpOutput; tmpOutput.reserve(keyLength); - secdebug("crypto", "decrypt: card supports RSA_NOPAD"); + secdebug("crypto", "decrypt: card supports RSA_NOPAD"); const AccessCredentials *cred = context.get<const AccessCredentials>(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS); - // Decrypt the inputData using the token + // Decrypt the inputData using the token mKey.computeCrypt(mToken, false, cred, inputData, tmpOutput); Padding::remove(tmpOutput, padding); outputData += tmpOutput; @@ -189,7 +181,7 @@ secure_zero(tmpOutput); } - clear.Data = &outputData[0]; + clear.Data = malloc_copy(outputData); clear.Length = outputData.size(); } Modified: trunk/Tokend/PIV/PIVKeyHandle.h =================================================================== --- trunk/Tokend/PIV/PIVKeyHandle.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/PIV/PIVKeyHandle.h 2009-12-18 14:23:24 UTC (rev 77) @@ -79,8 +79,8 @@ * TODO: Need spec on how to do this 'right' -- preferred setup would be for * the data buffer be provided */ - static const unsigned MAX_BUFFERS = 2; - SecureBufferAllocator<MAX_BUFFERS> bufferAllocator; +// static const unsigned MAX_BUFFERS = 2; +// SecureBufferAllocator<MAX_BUFFERS> bufferAllocator; }; Modified: trunk/Tokend/PIV/PIVRecord.cpp =================================================================== --- trunk/Tokend/PIV/PIVRecord.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/PIV/PIVRecord.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -89,9 +89,9 @@ PIVToken &pivToken = dynamic_cast<PIVToken &>(*tokenContext); if(mAllowCaching && lastAttribute.get()) return lastAttribute.get(); - + byte_string data; - + pivToken.getDataCore(mApplication, description(), mIsCertificate, mAllowCaching, data); /* Tokend::Attribute creates a copy of data */ lastAttribute.reset(new Tokend::Attribute(&data[0], data.size())); @@ -103,9 +103,9 @@ // PIVKeyRecord::PIVKeyRecord(const unsigned char *application, size_t applicationSize, const char *description, const Tokend::MetaRecord &metaRecord, - unsigned char keyRef) : + unsigned char keyRef, size_t keySize) : PIVRecord(application, applicationSize, description), - keyRef(keyRef) + keyRef(keyRef), keySize(keySize) { /* Allow all keys to decrypt, unwrap, sign */ attributeAtIndex(metaRecord.metaAttribute(kSecKeyDecrypt).attributeIndex(), @@ -120,6 +120,10 @@ { } +size_t PIVKeyRecord::sizeInBits() const { + return keySize; +} + /* MODIFY - This is where most of the crypto functions end up, and this will be the main place to actually talk with the token. @@ -136,10 +140,10 @@ unsigned char algRef; switch (sizeInBits()) { case 1024: - algRef = 0x06; + algRef = PIV_KEYALG_RSA_1024; break; case 2048: - algRef = 0x07; + algRef = PIV_KEYALG_RSA_2048; break; default: /* Cannot use a key ~= 1024 or 2048 bits yet */ @@ -249,20 +253,25 @@ mAclEntries.add(CssmClient::AclFactory::AnySubject( mAclEntries.allocator()), AclAuthorizationSet(CSSM_ACL_AUTHORIZATION_DB_READ, 0)); - + CssmData prompt; - - if(isUserConsent()) { - mAclEntries.add(CssmClient::AclFactory::PromptPWSubject( - mAclEntries.allocator(), prompt), - AclAuthorizationSet(CSSM_ACL_AUTHORIZATION_SIGN, CSSM_ACL_AUTHORIZATION_DECRYPT, 0)); + char tmptag[20]; + const uint32 slot = 1; // hardwired for now, but... + snprintf(tmptag, sizeof(tmptag), "PIN%d", slot); + + if(isUserConsent()) { // PIN1 must be entered every time + mAclEntries.add( + CssmClient::AclFactory::PromptPWSubject(mAclEntries.allocator(), prompt), + AclAuthorizationSet(CSSM_ACL_AUTHORIZATION_SIGN, CSSM_ACL_AUTHORIZATION_DECRYPT, 0), + tmptag); } else { // Using this key to sign or decrypt will require PIN1 - mAclEntries.add(CssmClient::AclFactory::PinSubject( - mAclEntries.allocator(), 1), - AclAuthorizationSet(CSSM_ACL_AUTHORIZATION_SIGN, CSSM_ACL_AUTHORIZATION_DECRYPT, 0)); + mAclEntries.add(CssmClient::AclFactory::PinSubject( + mAclEntries.allocator(), 1), + AclAuthorizationSet(CSSM_ACL_AUTHORIZATION_SIGN, CSSM_ACL_AUTHORIZATION_DECRYPT, 0), + tmptag); + } } - } count = mAclEntries.size(); acls = mAclEntries.entries(); } Modified: trunk/Tokend/PIV/PIVRecord.h =================================================================== --- trunk/Tokend/PIV/PIVRecord.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/PIV/PIVRecord.h 2009-12-18 14:23:24 UTC (rev 77) @@ -41,7 +41,7 @@ public: PIVRecord(const unsigned char *application, size_t applicationSize, const char *description) : mApplication(application, application + applicationSize), mDescription(description) {} - ~PIVRecord(); + virtual ~PIVRecord(); virtual const char *description() { return mDescription.c_str(); } @@ -59,10 +59,10 @@ NOCOPY(PIVKeyRecord) public: PIVKeyRecord(const unsigned char *application, size_t applicationSize, const char *description, - const Tokend::MetaRecord &metaRecord, unsigned char keyRef); - ~PIVKeyRecord(); + const Tokend::MetaRecord &metaRecord, unsigned char keyRef, size_t keySize); + virtual ~PIVKeyRecord(); - size_t sizeInBits() const { return 1024; } + size_t sizeInBits() const; void computeCrypt(PIVToken &pivToken, bool sign, const AccessCredentials *cred, const byte_string& data_type, byte_string &output); @@ -72,6 +72,7 @@ AutoAclEntryInfoList mAclEntries; const unsigned char keyRef; bool isUserConsent() const; + size_t keySize; }; Modified: trunk/Tokend/PIV/PIVSchema.cpp =================================================================== --- trunk/Tokend/PIV/PIVSchema.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/PIV/PIVSchema.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -46,8 +46,7 @@ using namespace Tokend; PIVSchema::PIVSchema() : - mKeyAlgorithmCoder(uint32(CSSM_ALGID_RSA)), - mKeySizeCoder(uint32(1024)) // MODIFY: if you support different size keys + mKeyAlgorithmCoder(uint32(CSSM_ALGID_RSA)) { } Modified: trunk/Tokend/PIV/PIVSchema.h =================================================================== --- trunk/Tokend/PIV/PIVSchema.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/PIV/PIVSchema.h 2009-12-18 14:23:24 UTC (rev 77) @@ -45,7 +45,7 @@ NOCOPY(PIVSchema) public: PIVSchema(); - virtual ~PIVSchema(); + virtual ~PIVSchema(); virtual void create(); @@ -57,7 +57,7 @@ PIVDataAttributeCoder mPIVDataAttributeCoder; Tokend::ConstAttributeCoder mKeyAlgorithmCoder; - Tokend::ConstAttributeCoder mKeySizeCoder; + PIVKeySizeAttributeCoder mKeySizeCoder; PIVKeyHandleFactory mPIVKeyHandleFactory; }; Modified: trunk/Tokend/PIV/PIVToken.cpp =================================================================== --- trunk/Tokend/PIV/PIVToken.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/PIV/PIVToken.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -40,6 +40,8 @@ #include <vector> #include <zlib.h> #include <CoreFoundation/CFString.h> +/* FOR KEYSIZE RETREIVAL */ +#include <Security/Security.h> #include <algorithm> /* min */ @@ -86,6 +88,14 @@ static const unsigned char kUniversalAID[] = { 0xA0, 0x00, 0x00, 0x01, 0x16, 0xDB, 0x00 }; +#pragma mark ---------- Data Description Strings ----------- + +static const char *sDescripCardCapabilityContainer = "CCC"; +static const char *sDescripCardHolderUniqueIdentifier = "CHUID"; +static const char *sDescripCardHolderFingerprints = "FINGERPRINTS"; +static const char *sDescripPrintedInformation = "PRINTDATA"; +static const char *sDescripCardHolderFacialImage = "FACIALIMAGE"; + #pragma mark ---------- Object IDs ---------- static const unsigned char oidCardCapabilityContainer[] = { PIV_OBJECT_ID_CARD_CAPABILITY_CONTAINER }; @@ -141,6 +151,9 @@ const char *workDirectory, char mdsDirectory[PATH_MAX], char printName[PATH_MAX]) { + Tokend::ISO7816Token::establish(guid, subserviceId, flags, + cacheDirectory, workDirectory, mdsDirectory, printName); + #ifdef _USECERTIFICATECOMMONNAME std::string commonName = authCertCommonName(); ::snprintf(printName, 40, "PIV-%s", commonName.c_str()); @@ -154,9 +167,6 @@ Tokend::ISO7816Token::name(printName); secdebug("pivtoken", "name: %s", printName); - Tokend::ISO7816Token::establish(guid, subserviceId, flags, - cacheDirectory, workDirectory, mdsDirectory, printName); - if(mSchema) delete mSchema; mSchema = new PIVSchema(); @@ -254,7 +264,12 @@ #ifndef _USEFALLBACKTOKENUID byte_string cccOid((const unsigned char *)oidCardCapabilityContainer, oidCardCapabilityContainer + sizeof(oidCardCapabilityContainer)); byte_string cccdata; - getDataCore(cccOid, "CCC", false, true, cccdata); + /* + Since probe is called before establish, securityd has not passed us + the cache directory yet, so we don't try to cache anything right now + */ + const bool allowCaching = false; + getDataCore(cccOid, "CCC", false, allowCaching, cccdata); PIVCCC ccc(cccdata); snprintf(tokenUid, TOKEND_MAX_UID, "PIV-%s", ccc.hexidentifier().c_str()); @@ -285,6 +300,30 @@ return score; } +size_t PIVToken::getKeySize(const byte_string &cert) const { + size_t keySize = 0; + SecCertificateRef certRef = 0; + SecKeyRef keyRef = 0; + /* Parse certificate for size */ + CSSM_DATA certData; + certData.Data = (uint8_t*)&cert[0]; + certData.Length = cert.size(); + const CSSM_KEY *cssmKey = NULL; + OSStatus status = SecCertificateCreateFromData(&certData, CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_BER, &certRef); + if(status != noErr) goto done; + status = SecCertificateCopyPublicKey(certRef, &keyRef); + if(status != noErr) goto done; + status = SecKeyGetCSSMKey(keyRef, &cssmKey); + if(status != noErr) goto done; + keySize = cssmKey->KeyHeader.LogicalKeySizeInBits; +done: + if(keyRef) + CFRelease(keyRef); + if(certRef) + CFRelease(certRef); + return keySize; +} + void PIVToken::populate() { /* @@ -303,7 +342,7 @@ mSchema->findRelation(CSSM_DL_DB_RECORD_PRIVATE_KEY); Tokend::Relation &dataRelation = mSchema->findRelation(CSSM_DL_DB_RECORD_GENERIC); - + /* Table 1. SP 800-73 Data Model Containers @@ -324,30 +363,38 @@ const size_t sz = sizeof(oidCardCapabilityContainer); // Card Capability Container 2.16.840.1.101.3.7.1.219.0 '5FC107' [Mandatory] - dataRelation.insertRecord(new PIVDataRecord(oidCardCapabilityContainer, sz, "CCC")); + if (getDataExists(oidCardCapabilityContainer, sz, sDescripCardCapabilityContainer)) + dataRelation.insertRecord(new PIVDataRecord(oidCardCapabilityContainer, sz, sDescripCardCapabilityContainer)); // Card Holder Unique Identifier 2.16.840.1.101.3.7.2.48.0 '5FC102' [Mandatory] [CHUID] - dataRelation.insertRecord(new PIVDataRecord(oidCardHolderUniqueIdentifier, sz, "CHUID")); + if (getDataExists(oidCardHolderUniqueIdentifier, sz, sDescripCardHolderUniqueIdentifier)) + dataRelation.insertRecord(new PIVDataRecord(oidCardHolderUniqueIdentifier, sz, sDescripCardHolderUniqueIdentifier)); // Card Holder Fingerprints 2.16.840.1.101.3.7.2.96.16 '5FC103' [Mandatory] - dataRelation.insertRecord(new PIVProtectedRecord(oidCardHolderFingerprints, sz, "FINGERPRINTS")); + if (getDataExists(oidCardHolderFingerprints, sz, sDescripCardHolderFingerprints)) + dataRelation.insertRecord(new PIVProtectedRecord(oidCardHolderFingerprints, sz, sDescripCardHolderFingerprints)); // Printed Information 2.16.840.1.101.3.7.2.48.1 '5FC109' [Optional] - dataRelation.insertRecord(new PIVProtectedRecord(oidPrintedInformation, sz, "PRINTDATA")); + if (getDataExists(oidPrintedInformation, sz, sDescripPrintedInformation)) + dataRelation.insertRecord(new PIVProtectedRecord(oidPrintedInformation, sz, sDescripPrintedInformation)); // Card Holder Facial Image 2.16.840.1.101.3.7.2.96.48 '5FC108' O - dataRelation.insertRecord(new PIVProtectedRecord(oidCardHolderFacialImage, sz, "FACIALIMAGE")); + if (getDataExists(oidCardHolderFacialImage, sz, sDescripCardHolderFacialImage)) + dataRelation.insertRecord(new PIVProtectedRecord(oidCardHolderFacialImage, sz, sDescripCardHolderFacialImage)); // Now describe the keys and certificates - + + // Note that the "Card Management Key", keyref 0x9B is a symmetric key + // and so is not listed here + const unsigned char *certids[] = { - oidX509CertificatePIVAuthentication, - oidX509CertificateDigitalSignature, - oidX509CertificateKeyManagement, - oidX509CertificateCardAuthentication + oidX509CertificatePIVAuthentication, // 0x9A + oidX509CertificateDigitalSignature, // 0x9C + oidX509CertificateKeyManagement, // 0x9D + oidX509CertificateCardAuthentication // 0x9E }; - + const char *certNames[] = { "PIV Authentication Certificate", @@ -355,15 +402,15 @@ "Key Management Certificate", "Card Authentication Certificate" }; - + const char *keyNames[] = { - "PIV Authentication Private Key", - "Digital Signature Private Key", - "Key Management Private Key", - "Card Authentication Private Key" + "PIV Authentication Private Key", // Keyref 9A + "Digital Signature Private Key", // Keyref 9C + "Key Management Private Key", // Keyref 9D + "Card Authentication Private Key" // Keyref 9E }; - + const unsigned char keyRefs[] = { PIV_KEYREF_PIV_AUTHENTICATION, @@ -371,13 +418,22 @@ PIV_KEYREF_PIV_KEY_MANAGEMENT, PIV_KEYREF_PIV_CARD_AUTHENTICATION }; - + for (unsigned int ix=0;ix<sizeof(certids)/sizeof(certids[0]);++ix) { + byte_string certData; + try { + getDataCore(byte_string(certids[ix], certids[ix] + sz), certNames[ix], true, true, certData); + } catch(PIVError &e) { + continue; + } + int keySize = getKeySize(certData); + if(keySize == 0) continue; + RefPointer<Tokend::Record> cert(new PIVCertificateRecord(certids[ix], sz, certNames[ix])); certRelation.insertRecord(cert); - RefPointer<Tokend::Record> key(new PIVKeyRecord(certids[ix], sz, keyNames[ix], privateKeyRelation.metaRecord(), keyRefs[ix])); + RefPointer<Tokend::Record> key(new PIVKeyRecord(certids[ix], sz, keyNames[ix], privateKeyRelation.metaRecord(), keyRefs[ix], keySize)); privateKeyRelation.insertRecord(key); // The Adornment class links a particular PIVCertificateRecord @@ -613,48 +669,44 @@ select(kSelectPIVApplet, sizeof(kSelectPIVApplet)); } -uint32_t PIVToken::exchangeAPDU(const byte_string &apdu, byte_string &result) +uint16_t PIVToken::simpleExchangeAPDU(const byte_string &apdu, byte_string &result) { + transmit(apdu, result); + if (result.size() < 2) + PCSC::Error::throwMe(SCARD_E_PROTO_MISMATCH); + uint16_t ret = (result[result.size() - 2] << 8) + result[result.size() - 1]; + // Trim off status bytes + result.resize(result.size() - 2); + return ret; +} + +uint16_t PIVToken::exchangeAPDU(const byte_string &apdu, byte_string &result) { static const uint8_t GET_RESULT_TEMPLATE [] = { 0x00, 0xC0, 0x00, 0x00, 0xFF }; byte_string getResult(GET_RESULT_TEMPLATE, GET_RESULT_TEMPLATE + sizeof(GET_RESULT_TEMPLATE)); const int SIZE_INDEX = 4; - transmit(apdu, result); + uint16_t ret = simpleExchangeAPDU(apdu, result); /* Keep pulling more data */ - while (result.size() >= 2 && result[result.size() - 2] == PIV_RESULT_CONTINUATION_SW1) + while ((ret >> 8) == PIV_RESULT_CONTINUATION_SW1) { - size_t expectedLength = result[result.size() - 1]; + size_t expectedLength = ret & 0xFF; if(expectedLength == 0) /* 256-byte case .. */ expectedLength = 256; - getResult[SIZE_INDEX] = expectedLength; - // Trim off status bytes - result.resize(result.size() - 2); - size_t appended = transmit(getResult, result); - if (appended != (expectedLength + 2)) - { - if (appended < 2) - PCSC::Error::throwMe(SCARD_E_PROTO_MISMATCH); - else - PIVError::throwMe((result[result.size() - 2] << 8) - + result[result.size() - 1]); - } + getResult[SIZE_INDEX] = expectedLength & 0xFF; + ret = simpleExchangeAPDU(getResult, result); } - - if (result.size() < 2) - PCSC::Error::throwMe(SCARD_E_PROTO_MISMATCH); - uint16_t ret = (result[result.size() - 2] << 8) + result[result.size() - 1]; - // Trim off status bytes - result.resize(result.size() - 2); - return ret; + return ret; } -uint32_t PIVToken::exchangeChainedAPDU(unsigned char cla, unsigned char ins, +uint16_t PIVToken::exchangeChainedAPDU(unsigned char cla, unsigned char ins, unsigned char p1, unsigned char p2, const byte_string &data, byte_string &result) { + const size_t BASE_CHUNK_LENGTH = 242; /* 242 == reasonably safe data chunk amount well under 256 */ byte_string apdu; - apdu.reserve(5 + data.size()); + uint16_t ret; + apdu.reserve(5 + BASE_CHUNK_LENGTH); apdu.resize(5); apdu[0] = cla; apdu[1] = ins; @@ -662,52 +714,66 @@ apdu[3] = p2; apdu[0] |= 0x10; - apdu += data; - const size_t BASE_CHUNK_LENGTH = 256; + byte_string::iterator apduDataBegin = apdu.begin() + 5; size_t chunkLength; byte_string::const_iterator iter; /* Chain data and skip last chunk since its in the receiving end */ for(iter = data.begin(); (iter + BASE_CHUNK_LENGTH) < data.end(); iter += BASE_CHUNK_LENGTH) { chunkLength = std::min(BASE_CHUNK_LENGTH, (size_t)(data.end() - iter)); - apdu[5] = chunkLength & 0xFF; + apdu.resize(5 + chunkLength); + apdu[4] = chunkLength & 0xFF; + copy(iter, iter + chunkLength, apduDataBegin); /* Don't send Le */ - transmit(apdu.begin(), apdu.begin() + 5 + chunkLength, result); + ret = simpleExchangeAPDU(apdu, result); /* No real data should come back until chaining is complete */ - if(result.size() != 2) - PCSC::Error::throwMe(SCARD_E_PROTO_MISMATCH); - else - PIVError::check(result[result.size() - 2] << 8 | result[result.size() - 1]); - /* Trim off result SW */ - result.resize(result.size() - 2); - // Trim off old data - apdu.erase(apdu.begin() + 5, apdu.begin() + 5 + chunkLength); + PIVError::check(ret); } apdu[0] &= ~0x10; - apdu[4] = (apdu.size() - 5) & 0xFF; + apdu[4] = (data.end() - iter) & 0xFF; + apdu.resize(5 + (data.end() - iter)); + copy(iter, data.end(), apduDataBegin); /* LE BYTE? */ return exchangeAPDU(apdu, result); } +byte_string PIVToken::buildGetData(const byte_string &oid, int limit /* = -1 */) const { + // The APDU only has space for a 3 byte OID + if (oid.size() != 3) + PCSC::Error::throwMe(SCARD_E_PROTO_MISMATCH); + const unsigned char dataFieldLen = 0x05; + static const unsigned char INITIAL_APDU_TEMPLATE[] = { PIV_GETDATA_APDU_TEMPLATE }; + /* TODO: Build from ground-up */ + byte_string initialApdu(INITIAL_APDU_TEMPLATE, INITIAL_APDU_TEMPLATE + sizeof(INITIAL_APDU_TEMPLATE)); + + initialApdu[PIV_GETDATA_APDU_INDEX_LEN] = dataFieldLen; + initialApdu[PIV_GETDATA_APDU_INDEX_OIDLEN] = oid.size(); + copy(oid.begin(), oid.end(), initialApdu.begin() + PIV_GETDATA_APDU_INDEX_OID); + initialApdu.resize(PIV_GETDATA_APDU_INDEX_OID + oid.size()); + if(limit > 255) + PCSC::Error::throwMe(SCARD_E_PROTO_MISMATCH); + if(limit >= 0) + initialApdu.push_back(limit); + return initialApdu; +} + /* This is where the actual data for a certificate or other data is retrieved from the token. - + Here is a sample exchange - APDU: 00 CB 3F FF 05 5C 03 5F C1 05 - APDU: 61 00 + APDU: 00 CB 3F FF 05 5C 03 5F C1 05 + APDU: 61 00 - APDU: 00 C0 00 00 00 + APDU: 00 C0 00 00 00 APDU: 53 82 04 84 70 82 ... 61 00 - APDU: 00 C0 00 00 00 - APDU: 68 82 8C 52 65 ... 61 88 + APDU: 00 C0 00 00 00 + APDU: 68 82 8C 52 65 ... 61 88 - APDU: 00 C0 00 00 88 + APDU: 00 C0 00 00 88 APDU: 50 D0 B2 A2 EF ... 90 00 */ - - void PIVToken::getDataCore(const byte_string &oid, const char *description, bool isCertificate, bool allowCaching, byte_string &data) { @@ -718,53 +784,19 @@ free(cssmData.Data); return; } - - // The APDU only has space for a 3 byte OID - if (oid.size() != 3) - PCSC::Error::throwMe(SCARD_E_PROTO_MISMATCH); - - const unsigned char dataFieldLen = 0x05; // doc says must be 16, but in pratice it is 5 - static const unsigned char INITIAL_APDU_TEMPLATE[] = { PIV_GETDATA_APDU_TEMPLATE }; - /* TODO: Build from ground-up */ - byte_string initialApdu(INITIAL_APDU_TEMPLATE, INITIAL_APDU_TEMPLATE + sizeof(INITIAL_APDU_TEMPLATE)); - - initialApdu[PIV_GETDATA_APDU_INDEX_LEN] = dataFieldLen; - initialApdu[PIV_GETDATA_APDU_INDEX_OIDLEN] = oid.size(); - copy(oid.begin(), oid.end(), initialApdu.begin() + PIV_GETDATA_APDU_INDEX_OID); - initialApdu.resize(PIV_GETDATA_APDU_INDEX_OID + oid.size()); - - static const unsigned char CONTINUATION_APDU_TEMPLATE[] = { PIV_GETDATA_CONT_APDU_TEMPLATE }; - byte_string continuationApdu(CONTINUATION_APDU_TEMPLATE, CONTINUATION_APDU_TEMPLATE + sizeof(CONTINUATION_APDU_TEMPLATE)); - - byte_string *apdu = &initialApdu; - // Talk to token here to get data { + byte_string getDataApdu = buildGetData(oid); PCSC::Transaction _(*this); selectDefault(); - uint32_t rx; - do - { - rx = exchangeAPDU(*apdu, data); - secdebug("pivtokend", "exchangeAPDU result %02X", rx); - - if ((rx & 0xFF00) != SCARD_BYTES_LEFT_IN_SW2 && - (rx & 0xFF00) != SCARD_SUCCESS) - PIVError::check(rx); - - // Switch to the continuation APDU after first exchange - apdu = &continuationApdu; - - // Number of bytes to fetch next time around is in the last byte returned. - // For all except the penultimate read, this is 0, indicating that the - // token should read all bytes. - - apdu->at(PIV_GETDATA_CONT_APDU_INDEX_LEN) = static_cast<unsigned char>(rx & 0xFF); - } while ((rx & 0xFF00) == SCARD_BYTES_LEFT_IN_SW2); + /* Continuation handled by exchangeAPDU */ + uint16_t rx = exchangeAPDU(getDataApdu, data); + secdebug("pivtokend", "exchangeAPDU result %02X", rx); + PIVError::check(rx); + if(data.size() > PIV_MAX_DATA_SIZE) { + PIVError::throwMe(SCARD_RETURNED_DATA_CORRUPTED); + } } - if(data.size() > PIV_MAX_DATA_SIZE) { - PIVError::throwMe(SCARD_RETURNED_DATA_CORRUPTED); - } dumpDataRecord(data, oid); // Start to parse the BER-TLV encoded data. In the end, we only return the @@ -774,9 +806,9 @@ if (data.size()<=0) return; if (data[0] != PIV_GETDATA_RESPONSE_TAG) - PIVError::throwMe(SCARD_RETURNED_DATA_CORRUPTED); + PIVError::throwMe(SCARD_RETURNED_DATA_CORRUPTED); - if (isCertificate) + if (isCertificate) processCertificateRecord(data, oid, description); if (!allowCaching) @@ -784,13 +816,13 @@ cssmData.Data = &data[0]; cssmData.Length = data.size(); cacheObject(0, description, cssmData); - } +} void PIVToken::processCertificateRecord(byte_string &data, const byte_string &oid, const char *description) { bool hasCertificateData = false; bool isCompressed = false; - + // 00000000 53 82 04 84 70 82 04 78 78 da 33 68 62 db 61 d0 TLV_ref tlv; TLVList list; @@ -969,3 +1001,16 @@ return resultLength; } +bool PIVToken::getDataExists(const unsigned char *oid, size_t oidlen, const char *description) +{ + /* Read the data object, limiting it at one byte received to help speed things along */ + byte_string result; + byte_string getDataApdu = buildGetData(byte_string(oid, oid + oidlen), 1); + uint16_t rx = simpleExchangeAPDU(getDataApdu, result); + if(rx == 0x6A82) return false; /* Object certainly doesn't exist */ + if(rx == 0x6982) return true; /* Assume security status not satisified == object exists */ + if(rx & 0xFF00 == SCARD_BYTES_LEFT_IN_SW2) return true; /* More bytes left */ + if((rx >> 8) == PIV_RESULT_CONTINUATION_SW1) return true; /* More data available */ + return result.size() > 0; /* Data has been returned */ +} + Modified: trunk/Tokend/PIV/PIVToken.h =================================================================== --- trunk/Tokend/PIV/PIVToken.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/PIV/PIVToken.h 2009-12-18 14:23:24 UTC (rev 77) @@ -159,22 +159,27 @@ /* NOTE: Using pointers for applet selection rather than byte_strings to permit simple selection detection */ void select(const unsigned char *applet, size_t appletLength); void selectDefault(); - uint32_t exchangeAPDU(const byte_string& apdu, - byte_string &result); - uint32_t exchangeChainedAPDU(unsigned char cla, unsigned char ins, + /* Exchanges APDU without performing data continuation */ + uint16_t simpleExchangeAPDU(const byte_string &apdu, byte_string &result); + /* Exchanges APDU, performing data retreival continuation as needed */ + uint16_t exchangeAPDU(const byte_string& apdu, byte_string &result); + uint16_t exchangeChainedAPDU(unsigned char cla, unsigned char ins, unsigned char p1, unsigned char p2, const byte_string &data, byte_string &result); - uint32_t getData(byte_string &result); + /* Builds the GetData APDU string with a given limit, if limit == -1, no limit */ + byte_string buildGetData(const byte_string &oid, int limit = -1) const; void getDataCore(const byte_string &oid, const char *description, bool isCertificate, bool allowCaching, byte_string &data); + bool getDataExists(const unsigned char *oid, size_t oidlen, const char *description); std::string authCertCommonName(); protected: void populate(); + size_t getKeySize(const byte_string &cert) const; void processCertificateRecord(byte_string &data, const byte_string &oid, const char *description); void dumpDataRecord(const byte_string &data, const byte_string &oid, const char *extraSuffix = NULL); static int compressionType(const byte_string &data); @@ -187,7 +192,7 @@ kCompressionGzip = 2, kCompressionUnknown = 9 }; - + size_t transmit(const byte_string &apdu, byte_string &result) { return transmit(apdu.begin(), apdu.end(), result); } Modified: trunk/Tokend/PIV/Padding.cpp =================================================================== --- trunk/Tokend/PIV/Padding.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/PIV/Padding.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -83,6 +83,7 @@ if(headerLength > 0) { data.insert(data.begin(), header, header + headerLength); } + int markerByteLocation; // Calculate and apply padding switch (padding) { case CSSM_PADDING_NONE: @@ -93,7 +94,7 @@ // Pad using PKCS1 v1.5 signature padding ( 00 01 FF FF.. 00 | M) if(data.size() + 11 > keySize) CssmError::throwMe(CSSMERR_CSP_BLOCK_SIZE_MISMATCH); - int markerByteLocation = keySize - data.size() - 1; + markerByteLocation = keySize - data.size() - 1; data.insert(data.begin(), keySize - data.size(), 0xFF); data[0] = 0; data[1] = 1; Modified: trunk/Tokend/PIV/SecureBufferAllocator.h =================================================================== --- trunk/Tokend/PIV/SecureBufferAllocator.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/PIV/SecureBufferAllocator.h 2009-12-18 14:23:24 UTC (rev 77) @@ -33,7 +33,9 @@ */ template<size_t MAX_SIZE> class SecureBufferAllocator { + NOCOPY(SecureBufferAllocator); public: + SecureBufferAllocator(); ~SecureBufferAllocator(); byte_string &getBuffer(); Modified: trunk/Tokend/PIV/SecureBufferAllocator.inc =================================================================== --- trunk/Tokend/PIV/SecureBufferAllocator.inc 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/PIV/SecureBufferAllocator.inc 2009-12-18 14:23:24 UTC (rev 77) @@ -25,6 +25,11 @@ #include "PIVUtilities.h" template<size_t MAX_SIZE> +SecureBufferAllocator<MAX_SIZE>::SecureBufferAllocator() +: nextFree(0) { +} + +template<size_t MAX_SIZE> SecureBufferAllocator<MAX_SIZE>::~SecureBufferAllocator() { /* Clear out all buffers */ for(size_t i = 0; i < buffers.size(); i++) Modified: trunk/Tokend/PIV/byte_string.h =================================================================== --- trunk/Tokend/PIV/byte_string.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/PIV/byte_string.h 2009-12-18 14:23:24 UTC (rev 77) @@ -23,8 +23,6 @@ #ifndef BYTE_STRING #define BYTE_STRING - -#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h> #include <vector> /** Utility definition and additional operators to make working with Modified: trunk/Tokend/PIV/piv.cpp =================================================================== --- trunk/Tokend/PIV/piv.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/PIV/piv.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -42,11 +42,12 @@ int main(int argc, const char *argv[]) { -#ifdef _USECERTIFICATECOMMONNAME + /* @@@ REQUIRED FOR KEYSIZE RETRIEVAL I THINK */ +#if defined(_USECERTIFICATECOMMONNAME) || 1 SecKeychainSetServerMode(); #endif /* _USECERTIFICATECOMMONNAME */ secdebug("PIV.tokend", "main starting with %d arguments", argc); - secdelay("/tmp/delay/PIV"); + secdelay((char *)"/tmp/delay/PIV"); token = new PIVToken(); try { @@ -56,5 +57,5 @@ } catch(...) { delete token; return -1; + } } -} Modified: trunk/Tokend/Tokend/Adornment.h =================================================================== --- trunk/Tokend/Tokend/Adornment.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/Tokend/Adornment.h 2009-12-18 14:23:24 UTC (rev 77) @@ -29,7 +29,6 @@ #ifndef _TOKEND_ADORNMENT_H_ #define _TOKEND_ADORNMENT_H_ -#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h> #include <security_utilities/adornments.h> #include <security_utilities/refcount.h> #include <Security/SecCertificate.h> Modified: trunk/Tokend/Tokend/Attribute.h =================================================================== --- trunk/Tokend/Tokend/Attribute.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/Tokend/Attribute.h 2009-12-18 14:23:24 UTC (rev 77) @@ -29,7 +29,6 @@ #ifndef _TOKEND_ATTRIBUTE_H_ #define _TOKEND_ATTRIBUTE_H_ -#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h> #include <Security/cssmtype.h> #include <security_cdsa_utilities/cssmdb.h> #include <string> Modified: trunk/Tokend/Tokend/AttributeCoder.cpp =================================================================== --- trunk/Tokend/Tokend/AttributeCoder.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/Tokend/AttributeCoder.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -41,7 +41,6 @@ #include <Security/SecKey.h> #include <Security/SecCertificate.h> #include <Security/SecKeychainItem.h> -#include <Security/SecKeychainItemPriv.h> namespace Tokend { Modified: trunk/Tokend/Tokend/AttributeCoder.h =================================================================== --- trunk/Tokend/Tokend/AttributeCoder.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/Tokend/AttributeCoder.h 2009-12-18 14:23:24 UTC (rev 77) @@ -29,7 +29,6 @@ #ifndef _TOKEND_ATTRIBUTECODER_H_ #define _TOKEND_ATTRIBUTECODER_H_ -#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h> #include <security_utilities/utilities.h> #include <Security/cssmtype.h> Modified: trunk/Tokend/Tokend/DbValue.h =================================================================== --- trunk/Tokend/Tokend/DbValue.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/Tokend/DbValue.h 2009-12-18 14:23:24 UTC (rev 77) @@ -29,7 +29,6 @@ #ifndef _TOKEND_DBVALUE_H_ #define _TOKEND_DBVALUE_H_ -#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h> #include <security_cdsa_utilities/cssmdata.h> #include <security_cdsa_utilities/cssmdb.h> #include <Security/cssmerr.h> Modified: trunk/Tokend/Tokend/MetaRecord.h =================================================================== --- trunk/Tokend/Tokend/MetaRecord.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/Tokend/MetaRecord.h 2009-12-18 14:23:24 UTC (rev 77) @@ -29,7 +29,6 @@ #ifndef _TOKEND_METARECORD_H_ #define _TOKEND_METARECORD_H_ -#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h> #include <security_cdsa_utilities/cssmdata.h> #include <map> #include <string> @@ -86,8 +85,8 @@ const MetaAttribute &metaAttribute( const CSSM_DB_ATTRIBUTE_INFO &inAttributeInfo) const; - const MetaAttribute &MetaRecord::metaAttribute(uint32 name) const; - const MetaAttribute &MetaRecord::metaAttribute( + const MetaAttribute &metaAttribute(uint32 name) const; + const MetaAttribute &metaAttribute( const std::string &name) const; const MetaAttribute &metaAttributeForData() const; Modified: trunk/Tokend/Tokend/PKCS11Object.h =================================================================== --- trunk/Tokend/Tokend/PKCS11Object.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/Tokend/PKCS11Object.h 2009-12-18 14:23:24 UTC (rev 77) @@ -29,7 +29,6 @@ #ifndef _TOKEND_PKCS11OBJECT_H_ #define _TOKEND_PKCS11OBJECT_H_ -#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h> #include <stdint.h> #include <map> #include <security_utilities/debugging.h> Modified: trunk/Tokend/Tokend/Record.h =================================================================== --- trunk/Tokend/Tokend/Record.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/Tokend/Record.h 2009-12-18 14:23:24 UTC (rev 77) @@ -29,7 +29,6 @@ #ifndef _TOKEND_RECORD_H_ #define _TOKEND_RECORD_H_ -#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h> #include "AttributeCoder.h" #include "MetaRecord.h" #include "Attribute.h" Modified: trunk/Tokend/Tokend/RecordHandle.h =================================================================== --- trunk/Tokend/Tokend/RecordHandle.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/Tokend/RecordHandle.h 2009-12-18 14:23:24 UTC (rev 77) @@ -29,7 +29,6 @@ #ifndef _TOKEND_RECORDHANDLE_H_ #define _TOKEND_RECORDHANDLE_H_ -#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h> #include <security_cdsa_utilities/handleobject.h> #include <security_utilities/refcount.h> #include <security_cdsa_utilities/cssmaclpod.h> Modified: trunk/Tokend/Tokend/SCardError.cpp =================================================================== --- trunk/Tokend/Tokend/SCardError.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/Tokend/SCardError.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -202,7 +202,11 @@ // SCardError::SCardError(uint16_t sw) : statusWord(sw) { +#if MAX_OS_X_VERSION_MIN_REQUIRED <= MAX_OS_X_VERSION_10_5 IFDEBUG(debugDiagnose(this)); +#else + SECURITY_EXCEPTION_THROW_OTHER(this, sw, (char *)"SCard"); +#endif } const char *SCardError::what() const throw () @@ -300,12 +304,16 @@ #if !defined(NDEBUG) +#if MAX_OS_X_VERSION_MIN_REQUIRED <= MAX_OS_X_VERSION_10_5 + void SCardError::debugDiagnose(const void *id) const { secdebug("exception", "%p Error %s (%04hX)", id, errorstr(statusWord), statusWord); } +#endif // MAX_OS_X_VERSION_MIN_REQUIRED <= MAX_OS_X_VERSION_10_5 + const char *SCardError::errorstr(uint16_t sw) { switch (sw) Modified: trunk/Tokend/Tokend/SCardError.h =================================================================== --- trunk/Tokend/Tokend/SCardError.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/Tokend/SCardError.h 2009-12-18 14:23:24 UTC (rev 77) @@ -29,7 +29,6 @@ #ifndef _TOKEND_SCARDERROR_H_ #define _TOKEND_SCARDERROR_H_ -#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h> #include <security_utilities/debugging.h> #include <security_utilities/errors.h> @@ -262,7 +261,9 @@ static void throwMe(uint16_t sw) __attribute__((noreturn)); protected: +#if MAX_OS_X_VERSION_MIN_REQUIRED <= MAX_OS_X_VERSION_10_5 IFDEBUG(void debugDiagnose(const void *id) const;) +#endif IFDEBUG(static const char *errorstr(uint16_t sw);) }; Modified: trunk/Tokend/Tokend/Schema.cpp =================================================================== --- trunk/Tokend/Tokend/Schema.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/Tokend/Schema.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -35,9 +35,10 @@ #include <Security/SecKey.h> #include <Security/SecCertificate.h> #include <Security/SecKeychainItem.h> -#include <Security/SecKeychainItemPriv.h> #include <Security/cssmapple.h> +//#define REGISTER_SCHEMA_RELATIONS 1 + namespace Tokend { @@ -140,13 +141,13 @@ #endif #ifdef REGISTER_SCHEMA_RELATIONS - registerRelation("CSSM_DL_DB_SCHEMA_INFO", CSSM_DL_DB_SCHEMA_INFO) + registerRelation("CSSM_DL_DB_SCHEMA_INFO", CSSM_DL_DB_SCHEMA_INFO); registerAttribute(CSSM_DL_DB_SCHEMA_INFO, &an_RelationID, 0, kAF_UINT32, true); registerAttribute(CSSM_DL_DB_SCHEMA_INFO, &an_RelationName, 1, kAF_UINT32, false); registerRelation("CSSM_DL_DB_SCHEMA_ATTRIBUTES", - CSSM_DL_DB_SCHEMA_ATTRIBUTES) + CSSM_DL_DB_SCHEMA_ATTRIBUTES); registerAttribute(CSSM_DL_DB_SCHEMA_ATTRIBUTES, &an_RelationID, 0, kAF_UINT32, true); registerAttribute(CSSM_DL_DB_SCHEMA_ATTRIBUTES, &an_AttributeID, 2, @@ -159,7 +160,7 @@ kAF_BLOB, false); registerAttribute(CSSM_DL_DB_SCHEMA_ATTRIBUTES, &an_AttributeFormat, 6, kAF_UINT32, false); - registerRelation("CSSM_DL_DB_SCHEMA_INDEXES", CSSM_DL_DB_SCHEMA_INDEXES) + registerRelation("CSSM_DL_DB_SCHEMA_INDEXES", CSSM_DL_DB_SCHEMA_INDEXES); registerAttribute(CSSM_DL_DB_SCHEMA_INDEXES, &an_RelationID, 0, kAF_UINT32, true); registerAttribute(CSSM_DL_DB_SCHEMA_INDEXES, &an_IndexID, 1, @@ -177,6 +178,8 @@ // layer expects. Relation *Schema::createStandardRelation(RelationId relationId) { + // avoid include of <Security/SecKeychainItemPriv.h> for definition of kSecProtectedDataItemAttr + const uint32 localkSecProtectedDataItemAttr = 'prot'; /* Item's data is protected (encrypted) (Boolean) */ std::string relationName; // Get the name based on the relation switch (relationId) @@ -191,6 +194,8 @@ relationName = "CSSM_DL_DB_RECORD_X509_CERTIFICATE"; break; case CSSM_DL_DB_RECORD_GENERIC: relationName = "CSSM_DL_DB_RECORD_GENERIC"; break; + case CSSM_DL_DB_RECORD_GENERIC_PASSWORD: + relationName = "CSSM_DL_DB_RECORD_GENERIC_PASSWORD"; break; default: CssmError::throwMe(CSSMERR_DL_INVALID_RECORDTYPE); } @@ -230,7 +235,22 @@ an_SignRecover = "SignRecover", an_VerifyRecover = "VerifyRecover", an_Wrap = "Wrap", - an_Unwrap = "Unwrap"; + an_Unwrap = "Unwrap", + an_CreationDate = "CreationDate", + an_ModDate = "ModDate", + an_Description = "Description", + an_Comment = "Comment", + an_Creator = "Creator", + an_Type = "Type", + an_ScriptCode = "ScriptCode", + an_Invisible = "Invisible", + an_Negative = "Negative", + an_CustomIcon = "CustomIcon", + an_Protected = "Protected", + an_Account = "Account", + an_Service = "Service", + an_Generic = "Generic" + ; // @@@ HARDWIRED Based on what SecKeychain layer expects @@@ switch (relationId) @@ -335,6 +355,39 @@ mPublicKeyHashCoder.setPublicKeyMetaAttribute(&(rt->metaRecord() .metaAttribute(kSecKeyLabel))); break; + case CSSM_DL_DB_RECORD_GENERIC_PASSWORD: + createAttribute(*rt, &an_CreationDate, kSecCreationDateItemAttr, + kAF_TIME_DATE, true).attributeCoder(&mZeroCoder); + createAttribute(*rt, &an_ModDate, kSecModDateItemAttr, + kAF_TIME_DATE, true).attributeCoder(&mZeroCoder); + createAttribute(*rt, &an_Description, kSecDescriptionItemAttr, + kAF_BLOB, false).attributeCoder(&mZeroCoder); + createAttribute(*rt, &an_Comment, kSecCommentItemAttr, + kAF_BLOB, false).attributeCoder(&mZeroCoder); + createAttribute(*rt, &an_Creator, kSecCreatorItemAttr, kAF_UINT32, 0); + createAttribute(*rt, &an_Type, kSecTypeItemAttr, kAF_UINT32, 0); + createAttribute(*rt, &an_ScriptCode, kSecScriptCodeItemAttr, kAF_UINT32, 0); + + createAttribute(*rt, &an_PrintName, kSecLabelItemAttr, kAF_BLOB, false) + .attributeCoder(&mDescriptionCoder); + createAttribute(*rt, &an_Alias, kSecAlias, kAF_BLOB, false) + .attributeCoder(&mZeroCoder); + + createAttribute(*rt, &an_Invisible, kSecInvisibleItemAttr, kAF_UINT32, 0); + createAttribute(*rt, &an_Negative, kSecNegativeItemAttr, kAF_UINT32, 0); + createAttribute(*rt, &an_CustomIcon, kSecCustomIconItemAttr, + kAF_BLOB, false).attributeCoder(&mZeroCoder); + createAttribute(*rt, &an_Protected, localkSecProtectedDataItemAttr, + kAF_BLOB, false).attributeCoder(&mZeroCoder); + createAttribute(*rt, &an_Account, kSecAccountItemAttr, + kAF_BLOB, false).attributeCoder(&mZeroCoder); + createAttribute(*rt, &an_Service, kSecServiceItemAttr, + kAF_BLOB, false).attributeCoder(&mZeroCoder); + createAttribute(*rt, &an_Generic, kSecGenericItemAttr, + kAF_BLOB, false).attributeCoder(&mZeroCoder); + rt->metaRecord().attributeCoderForData(&mDataAttributeCoder); + + break; } return rt; Modified: trunk/Tokend/Tokend/Schema.h =================================================================== --- trunk/Tokend/Tokend/Schema.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/Tokend/Schema.h 2009-12-18 14:23:24 UTC (rev 77) @@ -29,7 +29,6 @@ #ifndef _TOKEND_SCHEMA_H_ #define _TOKEND_SCHEMA_H_ -#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h> #include <security_cdsa_utilities/cssmdata.h> #include <security_cdsa_utilities/cssmdb.h> #include <map> Modified: trunk/Tokend/Tokend/SelectionPredicate.h =================================================================== --- trunk/Tokend/Tokend/SelectionPredicate.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/Tokend/SelectionPredicate.h 2009-12-18 14:23:24 UTC (rev 77) @@ -29,7 +29,6 @@ #ifndef _TOKEND_SELECTIONPREDICATE_H_ #define _TOKEND_SELECTIONPREDICATE_H_ -#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h> #include <security_cdsa_utilities/cssmdata.h> namespace Tokend Modified: trunk/Tokend/Tokend/Token.cpp =================================================================== --- trunk/Tokend/Tokend/Token.cpp 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/Tokend/Token.cpp 2009-12-18 14:23:24 UTC (rev 77) @@ -239,8 +239,9 @@ { BEGIN secdebug("tokend", "releaseSearch(%ld)", hSearch); - Security::HandleObject::findAndKill<Cursor>(hSearch, + Cursor &curs = Security::HandleObject::findAndKill<Cursor>(hSearch, CSSMERR_CSSM_INVALID_ADDIN_HANDLE); + delete &curs; END(DL) } @@ -248,8 +249,9 @@ { BEGIN secdebug("tokend", "releaseRecord(%ld)", hRecord); - Security::HandleObject::findAndKill<RecordHandle>(hRecord, + RecordHandle &rech = Security::HandleObject::findAndKill<RecordHandle>(hRecord, CSSMERR_CSSM_INVALID_ADDIN_HANDLE); + delete &rech; END(DL) } @@ -265,8 +267,9 @@ { BEGIN secdebug("tokend", "releaseKey(%ld)", hKey); - Security::HandleObject::findAndKill<KeyHandle>(hKey, + KeyHandle &keyh = Security::HandleObject::findAndKill<KeyHandle>(hKey, CSSMERR_CSP_INVALID_KEY_REFERENCE); + delete &keyh; END(CSP) } @@ -692,7 +695,7 @@ BEGIN secdebug("tokend", "_isLocked"); Required(locked) = token->isLocked(); - secdebug("tokend", "_isLocked: ", *locked); + secdebug("tokend", "_isLocked: %d", *locked); END(DL) } @@ -842,6 +845,8 @@ case CSSM_SAMPLE_TYPE_PROMPTED_PASSWORD: case CSSM_SAMPLE_TYPE_PROTECTED_PASSWORD: { + if (sample.length() != 2) // not recognized, may have non-existing data + return; CssmData &pin = sample[1].data(); return verifyPIN(pinNum, pin.Data, pin.Length); } Modified: trunk/Tokend/Tokend/Token.h =================================================================== --- trunk/Tokend/Tokend/Token.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/Tokend/Token.h 2009-12-18 14:23:24 UTC (rev 77) @@ -29,7 +29,6 @@ #ifndef _TOKEND_TOKEN_H_ #define _TOKEND_TOKEN_H_ -#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h> #include <SecurityTokend/SecTokend.h> #include <security_utilities/osxcode.h> #include <security_cdsa_utilities/context.h> Modified: trunk/Tokend/Tokend/TokenContext.h =================================================================== --- trunk/Tokend/Tokend/TokenContext.h 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/Tokend/TokenContext.h 2009-12-18 14:23:24 UTC (rev 77) @@ -29,7 +29,6 @@ #ifndef _TOKEND_TOKENCONTEXT_H_ #define _TOKEND_TOKENCONTEXT_H_ -#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h> #include <security_utilities/utilities.h> namespace Tokend Modified: trunk/Tokend/Tokend.xcodeproj/project.pbxproj =================================================================== --- trunk/Tokend/Tokend.xcodeproj/project.pbxproj 2009-12-18 08:22:08 UTC (rev 76) +++ trunk/Tokend/Tokend.xcodeproj/project.pbxproj 2009-12-18 14:23:24 UTC (rev 77) @@ -24,6 +24,7 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 52A683110EEF1FB200F71D5B /* BELPICAttributeCoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52A6830F0EEF1FB200F71D5B /* BELPICAttributeCoder.cpp */; }; 52B260320BC5A864007E00F1 /* Adornment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C1B9B6406DBF99F00014414 /* Adornment.cpp */; }; 52B260330BC5A864007E00F1 /* Attribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C134A9606DBF81800FA17D9 /* Attribute.cpp */; }; 52B260340BC5A864007E00F1 /* AttributeCoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C134A8A06DBF81800FA17D9 /* AttributeCoder.cpp */; }; @@ -118,10 +119,8 @@ 52B260CB0BC5A864007E00F1 /* PIVCCC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 529D9A7B0B867FA900DBFA4B /* PIVCCC.cpp */; }; 52B260CD0BC5A864007E00F1 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBF5CBE0704E76200EEADC2 /* libz.dylib */; }; 52B260CE0BC5A864007E00F1 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CA8C4D606D6D19400F1BCC8 /* CoreFoundation.framework */; }; - 52E66B970E92E78700CDE046 /* Padding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52E66B8F0E92E78700CDE046 /* Padding.cpp */; }; - 52E66B980E92E78700CDE046 /* SecureBufferAllocator.inc in Sources */ = {isa = PBXBuildFile; fileRef = 52E66B930E92E78700CDE046 /* SecureBufferAllocator.inc */; }; - 52E66B990E92E78700CDE046 /* TLV.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52E66B940E92E78700CDE046 /* TLV.cpp */; }; - 52E66B9A0E92E78700CDE046 /* TLV.inc in Sources */ = {isa = PBXBuildFile; fileRef = 52E66B960E92E78700CDE046 /* TLV.inc */; }; + 52CAA8CB0EBF7E40004C1A9E /* Padding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52CAA8C70EBF7E40004C1A9E /* Padding.cpp */; }; + 52CAA8CC0EBF7E40004C1A9E /* TLV.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52CAA8C90EBF7E40004C1A9E /* TLV.cpp */; }; C29914660C441EBB009571C2 /* PCSC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52CA8342067E8175005A1EBA /* PCSC.framework */; }; C29914670C441EBB009571C2 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52CA8343067E8175005A1EBA /* Security.framework */; }; /* End PBXBuildFile section */ @@ -245,7 +244,7 @@ 4C273A200708CE2C00CCB0FA /* CACError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CACError.cpp; sourceTree = "<group>"; }; 4C3C166D06F61D6F00FC8AAC /* KeyHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeyHandle.h; sourceTree = "<group>"; }; 4C3C166E06F61D6F00FC8AAC /* KeyHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KeyHandle.cpp; sourceTree = "<group>"; }; - 4C3FACAC06DBF84400D18D5F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; }; + 4C3FACAC06DBF84400D18D5F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 4C3FACAD06DBF84400D18D5F /* musclecard.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = musclecard.cpp; sourceTree = "<group>"; }; 4C3FACAE06DBF84400D18D5F /* MuscleCardToken.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MuscleCardToken.cpp; sourceTree = "<group>"; }; 4C3FACAF06DBF84400D18D5F /* MuscleCardToken.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MuscleCardToken.h; sourceTree = "<group>"; }; @@ -277,7 +276,7 @@ 4C7BA74F0703990100E5719F /* CACToken.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CACToken.cpp; sourceTree = "<group>"; }; 4C7BA7500703990100E5719F /* CACToken.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CACToken.h; sourceTree = "<group>"; }; 4C7BA7510703990100E5719F /* cac.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cac.cpp; sourceTree = "<group>"; }; - 4C7BA7520703990100E5719F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; }; + 4C7BA7520703990100E5719F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 4C86D3A0070B4122006A0C7F /* belpic.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = belpic.cpp; sourceTree = "<group>"; }; 4C86D3A3070B4122006A0C7F /* BELPICError.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BELPICError.cpp; sourceTree = "<group>"; }; 4C86D3A4070B4122006A0C7F /* BELPICError.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BELPICError.h; sourceTree = "<group>"; }; @@ -289,7 +288,7 @@ 4C86D3AA070B4122006A0C7F /* BELPICSchema.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BELPICSchema.h; sourceTree = "<group>"; }; 4C86D3AB070B4122006A0C7F /* BELPICToken.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BELPICToken.cpp; sourceTree = "<group>"; }; 4C86D3AC070B4122006A0C7F /* BELPICToken.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BELPICToken.h; sourceTree = "<group>"; }; - 4C86D3AD070B4122006A0C7F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; }; + 4C86D3AD070B4122006A0C7F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 4CA858F10654413F0083DED3 /* SecurityTokend.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = SecurityTokend.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4CA8C4D606D6D19400F1BCC8 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; }; 4CBF5C380704CDBF00EEADC2 /* CACRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CACRecord.h; sourceTree = "<group>"; }; @@ -303,7 +302,7 @@ 523F79EC06D5AC27004256A0 /* security_cdsa_client.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = security_cdsa_client.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 523F79ED06D5AC27004256A0 /* security_cdsa_utilities.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = security_cdsa_utilities.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 523F79EE06D5AC27004256A0 /* security_utilities.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = security_utilities.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 5280677F0B78E98600D02C3A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; name = Info.plist; path = PIV/Info.plist; sourceTree = "<group>"; }; + 5280677F0B78E98600D02C3A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; name = Info.plist; path = PIV/Info.plist; sourceTree = "<group>"; }; 528067810B78E98600D02C3A /* piv_csp_capabilities.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = piv_csp_capabilities.mdsinfo; sourceTree = "<group>"; }; 528067820B78E98600D02C3A /* piv_csp_capabilities_common.mds */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = piv_csp_capabilities_common.mds; sourceTree = "<group>"; }; 528067830B78E98600D02C3A /* piv_csp_primary.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = piv_csp_primary.mdsinfo; sourceTree = "<group>"; }; @@ -324,6 +323,8 @@ 528067920B78E98600D02C3A /* PIVToken.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PIVToken.h; path = PIV/PIVToken.h; sourceTree = "<group>"; }; 529D9A7B0B867FA900DBFA4B /* PIVCCC.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PIVCCC.cpp; path = PIV/PIVCCC.cpp; sourceTree = "<group>"; }; 529D9A7C0B867FA900DBFA4B /* PIVCCC.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PIVCCC.h; path = PIV/PIVCCC.h; sourceTree = "<group>"; }; + 52A6830F0EEF1FB200F71D5B /* BELPICAttributeCoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BELPICAttributeCoder.cpp; sourceTree = "<group>"; }; + 52A683100EEF1FB200F71D5B /* BELPICAttributeCoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BELPICAttributeCoder.h; sourceTree = "<group>"; }; 52B2604A0BC5A864007E00F1 /* libtokend.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libtokend.a; sourceTree = BUILT_PRODUCTS_DIR; }; 52B260620BC5A864007E00F1 /* Info-tokend__Upgraded_.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-tokend__Upgraded_.plist"; sourceTree = "<group>"; }; 52B260630BC5A864007E00F1 /* tokend.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = tokend.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -333,17 +334,13 @@ 52B260D40BC5A864007E00F1 /* PIV.tokend */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PIV.tokend; sourceTree = BUILT_PRODUCTS_DIR; }; 52CA8342067E8175005A1EBA /* PCSC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PCSC.framework; path = /System/Library/Frameworks/PCSC.framework; sourceTree = "<absolute>"; }; 52CA8343067E8175005A1EBA /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Security.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 52CAA8C60EBF7E40004C1A9E /* byte_string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = byte_string.h; path = PIV/byte_string.h; sourceTree = "<group>"; }; + 52CAA8C70EBF7E40004C1A9E /* Padding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Padding.cpp; path = PIV/Padding.cpp; sourceTree = "<group>"; }; + 52CAA8C80EBF7E40004C1A9E /* Padding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Padding.h; path = PIV/Padding.h; sourceTree = "<group>"; }; + 52CAA8C90EBF7E40004C1A9E /* TLV.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TLV.cpp; path = PIV/TLV.cpp; sourceTree = "<group>"; }; + 52CAA8CA0EBF7E40004C1A9E /* TLV.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TLV.h; path = PIV/TLV.h; sourceTree = "<group>"; }; 52DE698106E93B870024EA03 /* PKCS11Object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PKCS11Object.h; sourceTree = "<group>"; }; 52DE698206E93B870024EA03 /* PKCS11Object.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PKCS11Object.cpp; sourceTree = "<group>"; }; - 52E66B8E0E92E78700CDE046 /* byte_string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = byte_string.h; path = PIV/byte_string.h; sourceTree = "<group>"; }; - 52E66B8F0E92E78700CDE046 /* Padding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Padding.cpp; path = PIV/Padding.cpp; sourceTree = "<group>"; }; - 52E66B900E92E78700CDE046 /* Padding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Padding.h; path = PIV/Padding.h; sourceTree = "<group>"; }; - 52E66B910E92E78700CDE046 /* PIVUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PIVUtilities.h; path = PIV/PIVUtilities.h; sourceTree = "<group>"; }; - 52E66B920E92E78700CDE046 /* SecureBufferAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecureBufferAllocator.h; path = PIV/SecureBufferAllocator.h; sourceTree = "<group>"; }; - 52E66B930E92E78700CDE046 /* SecureBufferAllocator.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = SecureBufferAllocator.inc; path = PIV/SecureBufferAllocator.inc; sourceTree = "<group>"; }; - 52E66B940E92E78700CDE046 /* TLV.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TLV.cpp; path = PIV/TLV.cpp; sourceTree = "<group>"; }; - 52E66B950E92E78700CDE046 /* TLV.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TLV.h; path = PIV/TLV.h; sourceTree = "<group>"; }; - 52E66B960E92E78700CDE046 /* TLV.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = TLV.inc; path = PIV/TLV.inc; sourceTree = "<group>"; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -574,6 +571,8 @@ 4C86D39F070B4122006A0C7F /* BELPIC */ = { isa = PBXGroup; children = ( + 52A6830F0EEF1FB200F71D5B /* BELPICAttributeCoder.cpp */, + 52A683100EEF1FB200F71D5B /* BELPICAttributeCoder.h */, 4C5C1CE0073065EA00AECB7F /* mds */, 4C86D3A0070B4122006A0C7F /* belpic.cpp */, 4C86D3A3070B4122006A0C7F /* BELPICError.cpp */, @@ -608,15 +607,11 @@ 5280675F0B78E86F00D02C3A /* PIV */ = { isa = PBXGroup; children = ( - 52E66B8E0E92E78700CDE046 /* byte_string.h */, - 52E66B8F0E92E78700CDE046 /* Padding.cpp */, - 52E66B900E92E78700CDE046 /* Padding.h */, - 52E66B910E92E78700CDE046 /* PIVUtilities.h */, - 52E66B920E92E78700CDE046 /* SecureBufferAllocator.h */, - 52E66B930E92E78700CDE046 /* SecureBufferAllocator.inc */, - 52E66B940E92E78700CDE046 /* TLV.cpp */, - 52E66B950E92E78700CDE046 /* TLV.h */, - 52E66B960E92E78700CDE046 /* TLV.inc */, + 52CAA8C60EBF7E40004C1A9E /* byte_string.h */, + 52CAA8C70EBF7E40004C1A9E /* Padding.cpp */, + 52CAA8C80EBF7E40004C1A9E /* Padding.h */, + 52CAA8C90EBF7E40004C1A9E /* TLV.cpp */, + 52CAA8CA0EBF7E40004C1A9E /* TLV.h */, 528067800B78E98600D02C3A /* mds */, 529D9A7B0B867FA900DBFA4B /* PIVCCC.cpp */, 529D9A7C0B867FA900DBFA4B /* PIVCCC.h */, @@ -925,6 +920,7 @@ 52B260710BC5A864007E00F1 /* BELPICRecord.cpp in Sources */, 52B260720BC5A864007E00F1 /* BELPICSchema.cpp in Sources */, 52B260730BC5A864007E00F1 /* BELPICToken.cpp in Sources */, + 52A683110EEF1FB200F71D5B /* BELPICAttributeCoder.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -976,10 +972,8 @@ 52B260C90BC5A864007E00F1 /* PIVSchema.cpp in Sources */, 52B260CA0BC5A864007E00F1 /* PIVToken.cpp in Sources */, 52B260CB0BC5A864007E00F1 /* PIVCCC.cpp in Sources */, - 52E66B970E92E78700CDE046 /* Padding.cpp in Sources */, - 52E66B980E92E78700CDE046 /* SecureBufferAllocator.inc in Sources */, - 52E66B990E92E78700CDE046 /* TLV.cpp in Sources */, - 52E66B9A0E92E78700CDE046 /* TLV.inc in Sources */, + 52CAA8CB0EBF7E40004C1A9E /* Padding.cpp in Sources */, + 52CAA8CC0EBF7E40004C1A9E /* TLV.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1040,7 +1034,6 @@ BUILD_VARIANTS = debug; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; @@ -1070,7 +1063,6 @@ 52B2602A0BC5A864007E00F1 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - GCC_ENABLE_FIX_AND_CONTINUE = NO; PRODUCT_NAME = world; SECTORDER_FLAGS = ""; ZERO_LINK = NO; @@ -1081,13 +1073,12 @@ isa = XCBuildConfiguration; buildSettings = { BUILD_VARIANTS = debug; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 36720; FRAMEWORK_SEARCH_PATHS = ( /usr/local/SecurityPieces/Frameworks, "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", ); GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_PREPROCESSOR_DEFINITIONS = LIMITED_SIGNING; LIBRARY_STYLE = STATIC; @@ -1131,14 +1122,13 @@ nopic, ); COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 36720; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", /usr/local/SecurityPieces/Frameworks, "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", ); GCC_DEBUGGING_SYMBOLS = default; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_PREPROCESSOR_DEFINITIONS = LIMITED_SIGNING; LIBRARY_STYLE = STATIC; OPT_CFLAGS = "-DNDEBUG -Os $(OPT_INLINEFLAGS)"; @@ -1181,7 +1171,6 @@ "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", ); FRAMEWORK_VERSION = A; - GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_SYMBOLS_PRIVATE_EXTERN = NO; INFOPLIST_FILE = "Info-tokend__Upgraded_.plist"; INSTALL_PATH = /usr/local/SecurityPieces/Frameworks; @@ -1196,7 +1185,6 @@ buildSettings = { FRAMEWORK_VERSION = A; GCC_DEBUGGING_SYMBOLS = default; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_SYMBOLS_PRIVATE_EXTERN = NO; INFOPLIST_FILE = "Info-tokend__Upgraded_.plist"; INSTALL_PATH = /usr/local/SecurityPieces/Frameworks; @@ -1212,13 +1200,12 @@ ALWAYS_SEARCH_USER_PATHS = YES; BUILD_VARIANTS = debug; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 36720; FRAMEWORK_SEARCH_PATHS = ( /usr/local/SecurityPieces/Frameworks, "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", ); GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; @@ -1278,13 +1265,12 @@ normal, debug, ); - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 36720; FRAMEWORK_SEARCH_PATHS = ( /usr/local/SecurityPieces/Frameworks, "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", ); GCC_DYNAMIC_NO_PIC = YES; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_MODEL_TUNING = G5; INFOPLIST_FILE = BELPIC/Info.plist; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Security/tokend"; @@ -1322,13 +1308,12 @@ buildSettings = { BUILD_VARIANTS = debug; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 36720; FRAMEWORK_SEARCH_PATHS = ( /usr/local/SecurityPieces/Frameworks, "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", ); GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; @@ -1388,13 +1373,12 @@ normal, debug, ); - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 36720; FRAMEWORK_SEARCH_PATHS = ( /usr/local/SecurityPieces/Frameworks, "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", ); GCC_DYNAMIC_NO_PIC = YES; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_MODEL_TUNING = G5; INFOPLIST_FILE = CAC/Info.plist; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Security/tokend"; @@ -1432,13 +1416,12 @@ buildSettings = { BUILD_VARIANTS = debug; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 36720; FRAMEWORK_SEARCH_PATHS = ( /usr/local/SecurityPieces/Frameworks, "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", ); GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; @@ -1498,13 +1481,12 @@ normal, debug, ); - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 36720; FRAMEWORK_SEARCH_PATHS = ( /usr/local/SecurityPieces/Frameworks, "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", ); GCC_DYNAMIC_NO_PIC = YES; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_MODEL_TUNING = G5; INFOPLIST_FILE = MuscleCard/Info.plist; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Security/tokend"; @@ -1542,13 +1524,12 @@ buildSettings = { BUILD_VARIANTS = debug; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 36720; FRAMEWORK_SEARCH_PATHS = ( /usr/local/SecurityPieces/Frameworks, "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", ); GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; @@ -1608,13 +1589,12 @@ normal, debug, ); - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 36720; FRAMEWORK_SEARCH_PATHS = ( /usr/local/SecurityPieces/Frameworks, "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", ); GCC_DYNAMIC_NO_PIC = YES; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_MODEL_TUNING = G5; INFOPLIST_FILE = PIV/Info.plist; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Security/tokend";
participants (1)
-
source_changes@macosforge.org