From e231a14fc463f3ee5d423c78cb48d1d2118467d8 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Wed, 5 Aug 2015 14:58:35 +0900 Subject: [PATCH] Add method in SignatureValidator for cert-checker Change-Id: I89888472754accdde4632692c80b40dca9713710 Signed-off-by: Kyungwook Tak --- vcore/vcore/SignatureValidator.cpp | 102 +++++++++++++++++++++++++------------ vcore/vcore/SignatureValidator.h | 13 +++++ 2 files changed, 82 insertions(+), 33 deletions(-) diff --git a/vcore/vcore/SignatureValidator.cpp b/vcore/vcore/SignatureValidator.cpp index 52f04b5..c366fd8 100644 --- a/vcore/vcore/SignatureValidator.cpp +++ b/vcore/vcore/SignatureValidator.cpp @@ -174,7 +174,7 @@ static struct tm getMidTime(const struct tm &tb, const struct tm &ta) return tMid; } -} // namespace anonymouse +} // namespace anonymous @@ -183,14 +183,10 @@ namespace ValidationCore { /* * Prepare to check / checklist. parse xml and save info to signature data. * - * [in] fileInfo : signature file information to check. file path should be absolute path - * which is made by SignatureFinder. * [out] outData : signature data for validating and will be finally returned to client. */ -int prepareToCheck(const SignatureFileInfo &fileInfo, SignatureData &outData) +int prepareToCheck(SignatureData &outData) { - outData = SignatureData(fileInfo.getFileName(), fileInfo.getFileNumber()); - try { SignatureReader xml; xml.initialize(outData, SIGNATURE_SCHEMA_PATH); @@ -204,14 +200,61 @@ int prepareToCheck(const SignatureFileInfo &fileInfo, SignatureData &outData) } /* + * Make SignatureData by parsing signature file. + * and get certificate chain with attached certificate in signature + */ +static int makeDataBySignature( + const SignatureFileInfo &fileInfo, + bool completeWithSystemCert, + SignatureData &data) +{ + data = SignatureData(fileInfo.getFileName(), fileInfo.getFileNumber()); + + if (prepareToCheck(data)) { + LogError("Failed to prepare to check."); + return -1; + } + + if (!checkRoleURI(data) || !checkProfileURI(data)) + return -1; + + try { + CertificateCollection collection; + collection.load(data.getCertList()); + + if (!collection.sort() || collection.empty()) { + LogError("Certificates do not form valid chain."); + return -1; + } + + if (completeWithSystemCert && !collection.completeCertificateChain()) { + LogError("Failed to complete cert chain with system cert"); + return -1; + } + + data.setSortedCertificateList(collection.getChain()); + return 0; + + } catch (const CertificateCollection::Exception::Base &e) { + LogError("CertificateCollection exception : " << e.DumpToString()); + return -1; + } catch (...) { + LogError("Unknown exception in SignatureValidator::makeChainBySignature"); + return -1; + } +} + +/* * Same logic (check, checkList) is functionalized here. * + * [in] fileInfo : file info of signature to check * [in] checkOcsp : If on, check ocsp. * [out] disregard : distributor signature disregard flag. * [out] context : xml sec for validating. * [out] data : signature data for validationg and will be finally returned to client. */ static SignatureValidator::Result checkInternal( + const SignatureFileInfo &fileInfo, bool checkOcsp, bool &disregard, XmlSec::XmlSecContext &context, @@ -220,22 +263,11 @@ static SignatureValidator::Result checkInternal( // TODO: impl ocsp check (void) checkOcsp; - if (!checkRoleURI(data) || !checkProfileURI(data)) + if (makeDataBySignature(fileInfo, true, data)) return SignatureValidator::SIGNATURE_INVALID; - CertificateCollection collection; - collection.load(data.getCertList()); - - if (!collection.sort() || collection.empty() || !collection.completeCertificateChain()) { - LogWarning("Certificates do not form valid chain."); - return SignatureValidator::SIGNATURE_INVALID; - } - - CertificateList sortedCertificateList = collection.getChain(); - CertificatePtr root = sortedCertificateList.back(); - // Is Root CA certificate trusted? - CertStoreId::Set storeIdSet = createCertificateIdentifier().find(root); + CertStoreId::Set storeIdSet = createCertificateIdentifier().find(data.getCertList().back()); LogDebug("root certificate from " << storeIdSet.typeToString() << " domain"); if (data.isAuthorSignature()) { @@ -259,14 +291,13 @@ static SignatureValidator::Result checkInternal( } data.setStorageType(storeIdSet); - data.setSortedCertificateList(sortedCertificateList); /* * We add only Root CA certificate because the rest * of certificates are present in signature files ;-) */ context.signatureFile = data.getSignatureFileName(); - context.certificatePtr = root; + context.certificatePtr = data.getCertList().back(); /* certificate time check */ ASN1_TIME* notAfterTime = data.getEndEntityCertificatePtr()->getNotAfterTime(); @@ -295,16 +326,11 @@ SignatureValidator::Result SignatureValidator::check( bool checkReferences, SignatureData &outData) { - if (prepareToCheck(fileInfo, outData)) { - LogError("Failed to prepare to check."); - return SIGNATURE_INVALID; - } - bool disregard = false; try { XmlSec::XmlSecContext context; - Result result = checkInternal(checkOcsp, disregard, context, outData); + Result result = checkInternal(fileInfo, checkOcsp, disregard, context, outData); if (result != SIGNATURE_VERIFIED) return result; @@ -350,15 +376,11 @@ SignatureValidator::Result SignatureValidator::checkList( bool checkReferences, SignatureData &outData) { - if (prepareToCheck(fileInfo, outData)) { - LogError("Failed to prepare to check."); - return SIGNATURE_INVALID; - } - bool disregard = false; + try { XmlSec::XmlSecContext context; - Result result = checkInternal(checkOcsp, disregard, context, outData); + Result result = checkInternal(fileInfo, checkOcsp, disregard, context, outData); if (result != SIGNATURE_VERIFIED) return result; @@ -404,6 +426,20 @@ SignatureValidator::Result SignatureValidator::checkList( return disregard ? SIGNATURE_DISREGARD : SIGNATURE_VERIFIED; } +SignatureValidator::Result SignatureValidator::makeChainBySignature( + const SignatureFileInfo &fileInfo, + bool completeWithSystemCert, + CertificateList &certList) +{ + SignatureData data; + if (makeDataBySignature(fileInfo, completeWithSystemCert, data)) + return SIGNATURE_INVALID; + + certList = data.getCertList(); + + return SIGNATURE_VALID; +} + } // namespace ValidationCore diff --git a/vcore/vcore/SignatureValidator.h b/vcore/vcore/SignatureValidator.h index 8154f8c..60afb27 100644 --- a/vcore/vcore/SignatureValidator.h +++ b/vcore/vcore/SignatureValidator.h @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -60,6 +61,18 @@ public: bool checkOcsp, bool checkReferences, SignatureData &outData); + + /* + * @Remarks : cert list isn't completed with self-signed root CA system cert + * if completeWithSystemCert is false. + * + * return Result::SIGNATURE_VALID if success + * return Result::SIGNATURE_INVALID otherwise + */ + static Result makeChainBySignature( + const SignatureFileInfo &fileInfo, + bool completeWithSystemCert, + CertificateList &certList); }; } // namespace ValidationCore -- 2.7.4