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 // These need to be defined explicitly.
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                     // this is just being used as a convenient way to get the certificate into
00157                     // the right format
00158                     PKIFXSECCryptoX509 * x509 = new PKIFXSECCryptoX509();
00159                     x509->SetMediator(m_impl->m_med);
00160                     Janitor<PKIFXSECCryptoX509> j_x509(x509);
00161                     // get the base64-encoded certificate
00162                     x509Str = ((DSIGKeyInfoX509 *) lst->item(i))->getCertificateItem(0);
00163                     if (x509Str != 0) {
00164                         safeBuffer transX509(XMLString::transcode(x509Str));
00165                         // decode it
00166                         x509->loadX509Base64Bin(transX509.rawCharBuffer(), (unsigned int) strlen(transX509.rawCharBuffer()));
00167                         // get the DER back
00168                         transX509 = x509->getDEREncodingSB();
00169 
00170                         // now build and validate the path
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                                     // if the caller wanted revocation status make sure it's not revoked
00188                                     if(NOT_REVOKED != m_impl->m_lastPVR->GetRevocationStatusMostSevere()) break;
00189                                 } else {
00190                                     // else just make sure there was no REVOKED result and the path is otherwise
00191                                     // valid
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                                 // if we haven't broken out by now, it's good
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                             // need to do this instead of clonePublicKey()
00215                             // to make sure inherited parameters come through if needed
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                 // The PKIF resolver can only do anything with certificates. 
00244                 // this structure is a little funky but here in case we want to
00245                 // expand PKIFXML processing to non-cert keys.
00246                 // For now, Use the default resolver for other cases
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 }

Generated on Mon Nov 15 11:15:55 2010 for PublicKeyInfrastructureFramework(PKIF) by  doxygen 1.5.6