PKIFScvpPathBuild.cpp

Go to the documentation of this file.
00001 
00009 #include "PKIFScvpPathBuild.h"
00010 #include "pkif.h"
00011 #include "PKIFSCVP.h"
00012 #include "private/SCVPUtils.h"
00013 #include "private/ScvpState.h"
00014 #include "PKIFCMS.h"
00015 
00016 using namespace std;
00017 
00019 struct CPKIFScvpPathBuildImpl
00020 {
00021     bool m_bValidatedDpd;
00022 };
00024 
00032 CPKIFScvpPathBuild::CPKIFScvpPathBuild(void) : m_impl(new CPKIFScvpPathBuildImpl)
00033 {
00034     m_impl->m_bValidatedDpd = false;
00035 }
00036 
00044 CPKIFScvpPathBuild::~CPKIFScvpPathBuild(void)
00045 {
00046     if(m_impl)delete m_impl;
00047 }
00048 
00056 void CPKIFScvpPathBuild::Initialize()
00057 {
00058 }
00059 
00060 void CPKIFScvpPathBuild::SetUseValidPkcPathCertCheck(bool b)
00061 {
00062     m_impl->m_bValidatedDpd = b;
00063 }
00064 
00065 bool CPKIFScvpPathBuild::GetUseValidPkcPathCertCheck() const
00066 {
00067     return m_impl->m_bValidatedDpd;
00068 }
00069 
00077 bool CPKIFScvpPathBuild::BuildPath(
00079     CPKIFCertificatePath& path)
00080 {
00081     CPKIFCertificatePtr targetCert;
00082     path.GetTarget(targetCert);
00083 
00084     if(!targetCert || !CheckNamespaces(targetCert))
00085         return false;
00086 
00087     //prepare state - first check to see if state was passed in and if it belongs to us
00088     CPKIFCertificatePathStatePtr state;
00089     CPKIFScvpState* scvpState = NULL;
00090     path.GetState(state);
00091 
00092     //if there was state - see if we can cast it to a type that this builder uses
00093     //if(state != (CPKIFScvpState*)NULL)
00094     //  scvpState = dynamic_cast<CPKIFScvpState* >(&(*state));
00095 
00096     //if there was no state or the cast failed create a new state and put it in the path
00097     if(NULL == state)
00098     {
00099         //allocate the new state... (throw bad_alloc)
00100         scvpState = new CPKIFScvpState;     
00101 
00102         //store it in the path
00103         CPKIFCertificatePathStatePtr tmpState(scvpState);
00104         path.SetState(tmpState);
00105     }
00106     else
00107         return false;
00108 
00109     CPKIFCVRequestPtr cvr(new CPKIFCVRequest);  
00110 
00111     CPKIFQueryPtr query;
00112     
00113     if(!m_impl->m_bValidatedDpd)
00114         query = MakeQueryForPath(path, g_id_stc_build_pkc_path, this);
00115     else
00116         query = MakeQueryForPath(path, g_id_stc_build_valid_pkc_path, this);
00117 
00118     cvr->SetQuery(query);
00119     cvr->SetGenerateNonce(GetGenerateNonce());
00120 
00121     //declare variables that will be used to prepare a ContentInfo. 
00122     CPKIFBufferPtr contents = cvr->Encode();
00123     CPKIFOIDPtr contentType = g_id_ct_scvp_certValRequest;
00124 
00125     CPKIFCredentialPtr cred = GetSigningCredential();
00126     if(cred)
00127     {
00128         CPKIFSignedData sd;
00129         CPKIFEncapsulatedContentInfoPtr ecip(new CPKIFEncapsulatedContentInfo);
00130         ecip->SetOID(contentType);
00131         ecip->SetContent(contents);
00132 
00133         CPKIFSignerInfoPtr si(new CPKIFSignerInfo);
00134         si->SetCredential(cred);
00135 
00136         IPKIFScvpClient* thisAsScvpClient = dynamic_cast<IPKIFScvpClient*>(this);
00137 
00138         sd.SetEncapsulatedContent(ecip);
00139         IPKIFMediatorPtr tmpMed = thisAsScvpClient->GetMediator();
00140         sd.AddMediator(tmpMed);
00141         sd.AddSignerInfo(si);
00142         CPKIFCertificatePtr tmpCert = cred->GetCertificate();
00143         sd.AddCertificate(tmpCert);
00144 
00145         contents = sd.Encode();
00146 
00147         contentType = g_signedData;
00148     }
00149 
00150     CPKIFContentInfo ci;
00151     ci.SetContent(contents);
00152     ci.SetContentType(contentType);
00153 
00154     CPKIFBufferPtr encRequest = ci.Encode();
00155     CPKIFBufferPtr resp;
00156     const char* url = GetResponderUrl();
00157     if(PostRequestURL(encRequest, resp, url, PKIF_SCVP)) 
00158     {
00159         CPKIFCVResponsePtr parsedResponse;
00160 
00161         //VerifyResponseSignature parses the response, checks the status, checks the nonce (if necessary) 
00162         //and verifies the signature (if necessary)
00163         if(!VerifyResponseSignature(resp, this, cvr, true, parsedResponse))
00164         {
00165             //if everything checked by VerifyResponseSignature checks out, proceed by getting
00166             //the list of replyObjects
00167             CPKIFCertReplyListPtr replyObjects;
00168             parsedResponse->GetReplyObjects(replyObjects);
00169 
00170             //get the target cert from the path so we can find the correct reply object
00171             CPKIFCertificatePtr targetCert;
00172             path.GetTarget(targetCert);
00173             
00174             CPKIFCertReplyPtr replyObject = GetReplyObject(replyObjects, targetCert);
00175             if(replyObject)
00176             {
00177                 //we found a reply object, get its status.  this will determine what sort of processing is required
00178                 int replyStatus = replyObject->GetReplyStatus();
00179                 if(0 == replyStatus)
00180                 {
00181                     //sanity check the replyChecks and the valErrors.  the former should be all
00182                     //successful and the latter should be absent.
00183                     if(!MakeSureReplyChecksAreSuccessfulAndValErrorsAreAbsent(replyObject))
00184                         return false; //this response was busted, ignore it and let next colleague take a shot
00185                 }
00186 
00187                 //collect information from the wantBacks (the spec indicates these will only be in 
00188                 //successful replies, but....
00189                 CPKIFReplyWantBackListPtr replyWantBackList;
00190                 replyObject->GetReplyWantBacks(replyWantBackList);
00191 
00192                 CPKIFReplyWantBack_ExtDataHandlerPtr emptyWantBacks;
00193                 SetWantBacksFromResponse(emptyWantBacks);
00194                 if(replyWantBackList)
00195                 {
00196                     //There are only two types of wantBacks that we support: best cert path and revocation info.
00197                     //The revocation info type needs to be processed first.  Thus, collect these two below and process
00198                     //them after both are in hand.
00199                     CPKIFBufferPtr bestCertPathWB, revInfoWB;
00200 
00201                     CPKIFReplyWantBack_ExtDataHandlerPtr edh(new CPKIFReplyWantBack_ExtDataHandler);
00202                     edh->m_scvpResponder = GetResponderUrl();
00203 
00204                     CPKIFReplyWantBackList::iterator pos;
00205                     CPKIFReplyWantBackList::iterator end = replyWantBackList->end();
00206                     for(pos = replyWantBackList->begin(); pos != end; ++pos)
00207                     {
00208                         std::pair<CPKIFReplyWantBackPtr, vector<SeqResultsPtr> > pair;
00209                         pair.first = *pos;
00210                         edh->m_wantBacks.push_back(pair);
00211 
00212                         CPKIFOIDPtr posOid = (*pos)->GetWB();
00213                         if(*g_id_swb_pkc_best_cert_path == *posOid)
00214                         {
00215                             bestCertPathWB = (*pos)->GetValue();
00216                         }
00217                         else if(*g_id_swb_pkc_revocation_info == *posOid)
00218                         {
00219                             revInfoWB = (*pos)->GetValue();
00220                         }
00221                         else if(*g_id_swb_pkc_public_key_info == *posOid)
00222                         {
00223                             //Not supported
00224                         }
00225                         else if(*g_id_swb_pkc_relayed_responses == *posOid)
00226                         {
00227                             //Not supported
00228                         }
00229                         else if(*g_id_swb_pkc_cert == *posOid)
00230                         {
00231                             //Not supported (don't need since this API always passed in the cert)
00232                         }
00233                         else if(*g_id_swb_pkc_all_cert_paths == *posOid)
00234                         {
00235                             //Not supported
00236                         }
00237                         else if(*g_id_swb_pkc_ee_revocation_info == *posOid) 
00238                         {
00239                             //Not supported
00240                         }
00241                         else if(*g_id_swb_pkc_CAs_revocation_info == *posOid)
00242                         {
00243                             //Not supported
00244                         }
00245                     }
00246 
00247                     if(!edh->m_wantBacks.empty())
00248                     {
00249                         SetWantBacksFromResponse(edh);
00250                     }
00251 
00252                     if(revInfoWB)
00253                     {
00254                         StickCrlsFromWantBackInCrlStore(revInfoWB, this, this);
00255                     }
00256 
00257                     if(bestCertPathWB)
00258                     {
00259                         return CertPathWantBackToResultsAndStoresForDpd(bestCertPathWB, revInfoWB, path, this, this);
00260                     }
00261                 }
00262             }//if(replyObject)                                                  - If any of these three fail, return false
00263         }//if(!VerifyResponseSignature(resp, this, cvr, false, parsedResponse)) - and let next colleague try to fulfill
00264     }//if(PostRequestURL(encRequest, resp, url, PKIF_SCVP))                     - the request.
00265 
00266     return false;
00267 }

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