PKIFXSECKeyInfoResolver.cpp
Go to the documentation of this file.00001
00010 #include "PKIFXSECKeyInfoResolver.h"
00011 #include "PKIFXSECCrypto.h"
00012 #include "PKIFXSECCryptoX509.h"
00013 #include "PKIFXSECCryptoKeyDSA.h"
00014 #include "PKIFXSECCryptoKeyRSA.h"
00015
00016 #include <xsec/dsig/DSIGKeyInfoX509.hpp>
00017 #include <xsec/enc/XSCrypt/XSCryptCryptoBase64.hpp>
00018 #include <xsec/enc/XSECCryptoException.hpp>
00019 #include <xsec/enc/XSECCryptoUtils.hpp>
00020 #include <xsec/framework/XSECError.hpp>
00021
00022 #include <xercesc/util/Janitor.hpp>
00023 XERCES_CPP_NAMESPACE_USE;
00024
00026 struct PKIFXSECKeyInfoResolverImpl
00027 {
00028 IPKIFMediatorPtr m_med;
00029 CPKIFPathSettingsPtr m_ps;
00030 CPKIFFuncStoragePtr m_checker;
00031 IPKIFXSECNotificationCallback * m_cb;
00032 CPKIFCertificatePathPtr m_lastPath;
00033 CPKIFPathValidationResultsPtr m_lastPVR;
00034 };
00035
00036
00037
00045 IPKIFXSECNotificationCallback::IPKIFXSECNotificationCallback() {}
00053 IPKIFXSECNotificationCallback::~IPKIFXSECNotificationCallback() {}
00054
00062 void xmlKeyUsageChecker_Any(
00065 const CPKIFCertificateNodeEntryPtr& certNode,
00067 CPKIFPathValidationResults& results,
00069 CertificateType type)
00070 {
00071 if(EE == type)
00072 {
00073 CPKIFCertificatePtr curCert = certNode->GetCert();
00074 CPKIFKeyUsagePtr keyUsage = curCert->GetExtension<CPKIFKeyUsage>();
00075 if(keyUsage != (CPKIFKeyUsage*)NULL)
00076 {
00077 CPKIFX509ExtensionPtr keyUsage2 = keyUsage;
00078 certNode->MarkExtensionAsProcessed(keyUsage2);
00079 }
00080 }
00081 }
00082
00084
00093 PKIFXSECKeyInfoResolver::PKIFXSECKeyInfoResolver(
00095 IPKIFMediatorPtr & med,
00097 CPKIFPathSettingsPtr & ps,
00099 CPKIFFuncStoragePtr & kuChecker
00100 )
00101 :m_impl(new PKIFXSECKeyInfoResolverImpl())
00102 {
00103 m_impl->m_med = med;
00104 m_impl->m_ps = ps;
00105 m_impl->m_checker = kuChecker;
00106 m_impl->m_cb = 0;
00107 }
00108
00116 PKIFXSECKeyInfoResolver::~PKIFXSECKeyInfoResolver()
00117 {
00118 if(m_impl) {
00119 delete m_impl;
00120 m_impl = 0;
00121 }
00122 }
00123
00132 XSECCryptoKey * PKIFXSECKeyInfoResolver::resolveKey(
00134 DSIGKeyInfoList * lst)
00135 {
00136 XSECCryptoKey * ret = 0;
00137
00138 IPKIFPathBuild * pb = m_impl->m_med->GetMediator<IPKIFPathBuild>();
00139 IPKIFPathValidate * pv = m_impl->m_med->GetMediator<IPKIFPathValidate>();
00140 if(!m_impl->m_checker) {
00141 m_impl->m_checker = CPKIFFuncStoragePtr(new CPKIFFuncStorage(xmlKeyUsageChecker_Any));
00142 }
00143
00144 if(!pb || !pv) return 0;
00145
00146 DSIGKeyInfoList::size_type sz = lst->getSize();
00147
00148 for (DSIGKeyInfoList::size_type i = 0; i < sz; ++i) {
00149
00150 switch (lst->item(i)->getKeyInfoType()) {
00151 case (DSIGKeyInfo::KEYINFO_X509) :
00152 {
00153 ret = NULL;
00154 const XMLCh * x509Str;
00155
00156
00157
00158 PKIFXSECCryptoX509 * x509 = new PKIFXSECCryptoX509();
00159 x509->SetMediator(m_impl->m_med);
00160 Janitor<PKIFXSECCryptoX509> j_x509(x509);
00161
00162 x509Str = ((DSIGKeyInfoX509 *) lst->item(i))->getCertificateItem(0);
00163 if (x509Str != 0) {
00164 safeBuffer transX509(XMLString::transcode(x509Str));
00165
00166 x509->loadX509Base64Bin(transX509.rawCharBuffer(), (unsigned int) strlen(transX509.rawCharBuffer()));
00167
00168 transX509 = x509->getDEREncodingSB();
00169
00170
00171 CPKIFCertificatePtr cert(new CPKIFCertificate());
00172 cert->Decode(transX509.rawBuffer(), transX509.sbRawBufferSize());
00173 CPKIFPathValidationResultsPtr emptyres;
00174 m_impl->m_lastPVR = emptyres;
00175 m_impl->m_lastPath = CPKIFCertificatePathPtr(new CPKIFCertificatePath());
00176 m_impl->m_lastPath->SetTarget(cert);
00177
00178 if(m_impl->m_ps) m_impl->m_lastPath->SetPathSettings(m_impl->m_ps);
00179 bool goodCert = false;
00180 while(pb->BuildPath(*m_impl->m_lastPath) && !goodCert) {
00181 m_impl->m_lastPVR = CPKIFPathValidationResultsPtr(new CPKIFPathValidationResults());
00182 if(pv->ValidatePath(*m_impl->m_lastPath,*m_impl->m_lastPVR,m_impl->m_checker))
00183 {
00184 CPKIFPathSettingsPtr tmpPS;
00185 m_impl->m_lastPath->GetPathSettings(tmpPS);
00186 if(tmpPS->GetCheckRevocationStatus()) {
00187
00188 if(NOT_REVOKED != m_impl->m_lastPVR->GetRevocationStatusMostSevere()) break;
00189 } else {
00190
00191
00192 if(NOT_CHECKED > m_impl->m_lastPVR->GetRevocationStatusMostSevere()) break;
00193 if(!m_impl->m_lastPVR->GetBasicChecksSuccessfullyPerformed() ||
00194 !m_impl->m_lastPVR->GetCertSignaturesVerified()) break;
00195 }
00196
00197 goodCert = m_impl->m_lastPVR->PathSuccessfullyValidated();
00198
00199 }
00200 }
00201 if(m_impl->m_cb) {
00202 bool acceptPKIF = (*(m_impl->m_cb))(m_impl->m_lastPath,
00203 m_impl->m_lastPVR,goodCert);
00204 if(!acceptPKIF) goodCert = !goodCert;
00205 }
00206 if(goodCert) {
00207 CPKIFKeyMaterialPtr km(new CPKIFKeyMaterial());
00208 CPKIFBufferPtr pecert = cert->Encoded();
00209 km->SetCertificate(pecert->GetBuffer(), pecert->GetLength());
00210 CPKIFAlgorithmIdentifierPtr params = m_impl->m_lastPVR->GetWorkingParams();
00211 if(params) {
00212 km->SetWorkingParameters(params);
00213 }
00214
00215
00216 switch(x509->getPublicKeyType()) {
00217 case XSECCryptoKey::KEY_RSA_PUBLIC:
00218 {
00219 PKIFXSECCryptoKeyRSA * rsaKey = new PKIFXSECCryptoKeyRSA();
00220 rsaKey->SetMediator(m_impl->m_med);
00221 rsaKey->SetKeyMaterial(km);
00222 ret = rsaKey;
00223 break;
00224 }
00225 case XSECCryptoKey::KEY_DSA_PUBLIC:
00226 {
00227 PKIFXSECCryptoKeyDSA * dsaKey = new PKIFXSECCryptoKeyDSA();
00228 dsaKey->SetMediator(m_impl->m_med);
00229 dsaKey->SetKeyMaterial(km);
00230 ret = dsaKey;
00231 break;
00232 }
00233 }
00234 }
00235 }
00236
00237 if (ret != NULL)
00238 return ret;
00239
00240 }
00241 break;
00242 default:
00243
00244
00245
00246
00247 break;
00248 }
00249 }
00250 return ret;
00251 }
00252
00260 XSECKeyInfoResolver * PKIFXSECKeyInfoResolver::clone(void) const
00261 {
00262 PKIFXSECKeyInfoResolver * rv = new PKIFXSECKeyInfoResolver(m_impl->m_med, m_impl->m_ps, m_impl->m_checker);
00263 rv->m_impl->m_cb = m_impl->m_cb;
00264 return rv;
00265 }
00266
00275 void PKIFXSECKeyInfoResolver::SetCallback(IPKIFXSECNotificationCallback * cb)
00276 {
00277 m_impl->m_cb = cb;
00278 }