Mixe for Privacy and Anonymity in the Internet
CACertStore.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000, The JAP-Team
00003 All rights reserved.
00004 Redistribution and use in source and binary forms, with or without modification,
00005 are permitted provided that the following conditions are met:
00006 
00007   - Redistributions of source code must retain the above copyright notice,
00008     this list of conditions and the following disclaimer.
00009 
00010   - Redistributions in binary form must reproduce the above copyright notice,
00011     this list of conditions and the following disclaimer in the documentation and/or
00012     other materials provided with the distribution.
00013 
00014   - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors
00015     may be used to endorse or promote products derived from this software without specific
00016     prior written permission.
00017 
00018 
00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
00020 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00021 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
00022 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00023 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00025 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00027 */
00028 #include "StdAfx.h"
00029 #ifndef ONLY_LOCAL_PROXY
00030 #include "CACertStore.hpp"
00031 #include "CAUtil.hpp"
00032 #include "CAMsg.hpp"
00033 
00034 CACertStore::CACertStore()
00035   {
00036     m_pCertList=NULL;
00037     m_cCerts=0;
00038     m_pCurrent=NULL;
00039   }
00040 
00041 CACertStore::~CACertStore()
00042   {
00043     LP_CERTSTORE_ENTRY tmp;
00044     while(m_pCertList!=NULL)
00045       {
00046         delete m_pCertList->pCert;
00047         m_pCertList->pCert = NULL;
00048         tmp=m_pCertList;
00049         m_pCertList=m_pCertList->next;
00050         delete tmp;
00051         tmp = NULL;
00052       }
00053   }
00054 
00060 SINT32 CACertStore::add(CACertificate* cert)
00061   {
00062     if(cert==NULL)
00063     {
00064       return E_UNKNOWN;
00065     }
00066     LP_CERTSTORE_ENTRY newEntry=new CERTSTORE_ENTRY;
00067     newEntry->pCert=cert->clone();
00068     newEntry->next=m_pCertList;
00069     m_pCertList=newEntry;
00070     m_cCerts++;
00071     return E_SUCCESS;
00072   }
00073 
00074 CACertificate* CACertStore::getFirst()
00075 {
00076   m_pCurrent = m_pCertList;
00077   return m_pCurrent->pCert;
00078 }
00079 
00080 CACertificate* CACertStore::getNext()
00081 {
00082   if(m_pCurrent != NULL)
00083   {
00084     m_pCurrent = m_pCurrent->next;
00085     if(m_pCurrent != NULL && m_pCurrent != m_pCertList)
00086     {
00087       return m_pCurrent->pCert;
00088     }
00089   }
00090   return NULL;
00091 }
00092 
00110 CACertificate* CACertStore::verifyMixCert(DOMNode* mixNode)
00111 {
00112   UINT32 signatureElementsCount = MAX_SIGNATURE_ELEMENTS;
00113   DOMNode* signatureElements[MAX_SIGNATURE_ELEMENTS];
00114   DOMNode* x509Data;
00115   CACertStore* certPath;
00116   CACertificate* trustedCert;
00117   CACertificate* cert;
00118   CACertificate* mixCert;
00119 
00120   //try to decode the certificates from the Signature elements
00121   if(mixNode == NULL || m_pCertList == NULL)
00122   {
00123     CAMsg::printMsg(LOG_DEBUG , "Error initializing verification.\n");
00124     return NULL;
00125   }
00126   getSignatureElements((DOMElement*)mixNode, signatureElements, &signatureElementsCount);
00127   if(signatureElementsCount < 1)
00128   {
00129     CAMsg::printMsg(LOG_DEBUG , "Error no Signature-Node found!\n");
00130     return NULL;
00131   }
00132   //try to find a valid cert in one of the signature Elements
00133   for(UINT32 i=0; i<signatureElementsCount; i++)
00134   {
00135     getDOMChildByName(signatureElements[i], "X509Data", x509Data, true);
00136     if(x509Data == NULL)
00137     {
00138       CAMsg::printMsg(LOG_DEBUG , "Error X509Data-Node is NULL!\n");
00139       continue;
00140     }
00141     certPath = CACertStore::decode(x509Data, XML_X509DATA);
00142     if(certPath == NULL)
00143     {
00144       continue;
00145     }
00146 
00147     //now try to find a cert that was signed by a trusted CA
00148     trustedCert = getFirst();
00149 
00150     while(trustedCert != NULL)
00151     {
00152       cert = certPath->getFirst();
00153       while(cert != NULL)
00154       {
00155         if(cert->verify(trustedCert) == E_SUCCESS)
00156         {
00157           break;
00158         }
00159         cert = certPath->getNext();
00160       }
00161       if(cert != NULL)
00162       {
00163         break;
00164       }
00165       trustedCert = getNext();
00166     }
00167     if(trustedCert != NULL && cert != NULL)
00168     {
00169       //we found a verified cert
00170       if(certPath->m_cCerts > 1)
00171       {
00172         //try to build a longer certPath
00173         mixCert = certPath->getFirst();
00174         while(mixCert != NULL)
00175         {
00176           if(mixCert->verify(cert) == E_SUCCESS)
00177           {
00178             break;
00179           }
00180           mixCert = certPath->getNext();
00181         }
00182         if(mixCert != NULL)
00183         {
00184           return mixCert;
00185         }
00186       }
00187       else //tricky because there might be a longer certPath in another Signature Element
00188       {
00189         return cert;
00190       }
00191     }
00192   }
00193   return NULL;
00194 }
00195 
00196 SINT32 CACertStore::encode(UINT8* buff,UINT32* bufflen,UINT32 type)
00197   {
00198     switch (type)
00199       {
00200         case XML_X509DATA:
00201           memcpy(buff,"<X509Data>",10);
00202           UINT32 len=10;
00203           LP_CERTSTORE_ENTRY tmp;
00204           tmp=m_pCertList;
00205           UINT32 space=*bufflen-10;
00206           while(tmp!=NULL)
00207             {
00208               *bufflen=space;
00209               tmp->pCert->encode(buff+len,bufflen,CERT_XML_X509CERTIFICATE);
00210               len+=*bufflen;
00211               space-=*bufflen;
00212               tmp=tmp->next;
00213             }
00214           memcpy(buff+len,"</X509Data>",11);
00215           len+=11;
00216           *bufflen=len;
00217         break;
00218       }
00219     return E_SUCCESS;
00220   }
00221 
00230 SINT32 CACertStore::encode(DOMElement* & elemRoot,XERCES_CPP_NAMESPACE::DOMDocument* doc)
00231   {
00232     elemRoot=createDOMElement(doc,"X509Data");
00233     LP_CERTSTORE_ENTRY tmp;
00234     tmp=m_pCertList;
00235     while(tmp!=NULL)
00236       {
00237         DOMElement* tmpElem=NULL;
00238         tmp->pCert->encode(tmpElem,doc);
00239         elemRoot->appendChild(tmpElem);
00240         tmp=tmp->next;
00241       }
00242     return E_SUCCESS;
00243   }
00244 
00245 CACertStore* CACertStore::decode(const DOMNode* node, UINT32 type)
00246 {
00247   switch(type)
00248   {
00249     case XML_X509DATA:
00250       CACertStore* store = new CACertStore();
00251       DOMNodeList* certs = getElementsByTagName((DOMElement*)node, "X509Certificate");
00252 
00253       for(UINT32 i=0; i<certs->getLength(); i++)
00254       {
00255         CACertificate* cert = CACertificate::decode(certs->item(i), CERT_X509CERTIFICATE);
00256         if(cert != NULL)
00257         {
00258           store->add(cert);
00259         }
00260       }
00261       return store;
00262   }
00263   return NULL;
00264 }
00265 #endif //ONLY_LOCAL_PROXY