Mixe for Privacy and Anonymity in the Internet
CASignature.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 "CASignature.hpp"
00031 #include "CABase64.hpp"
00032 #include "CAUtil.hpp"
00033 #include "xml/DOM_Output.hpp"
00034 
00035 CASignature::CASignature()
00036   {
00037     m_pDSA = NULL;
00038     m_pRSA = NULL;
00039 #ifdef ECC
00040     m_pEC = NULL;
00041 #endif //ECC
00042   }
00043 
00044 CASignature::~CASignature()
00045   {
00046     if(m_pDSA != NULL)
00047     {
00048       DSA_free(m_pDSA);
00049       m_pDSA = NULL;
00050     }
00051     if(m_pRSA != NULL)
00052     {
00053       RSA_free(m_pRSA);
00054       m_pRSA = NULL;
00055     }
00056 #ifdef ECC
00057     if(m_pEC != NULL)
00058     {
00059       EC_KEY_free(m_pEC);
00060       m_pEC = NULL;
00061     }
00062 #endif //ECC
00063   }
00064 
00065 
00066 CASignature* CASignature::clone()
00067   {
00068     CASignature* tmpSig=new CASignature();
00069     if(m_pDSA!=NULL)
00070     {
00071       DSA* tmpDSA=DSA_clone(m_pDSA);
00072       tmpSig->m_pDSA=tmpDSA;
00073     }
00074     else if(m_pRSA != NULL)
00075     {
00076       RSA* tmpRSA = RSA_clone(m_pRSA);
00077       tmpSig->m_pRSA = tmpRSA;
00078     }
00079 #ifdef ECC
00080     else if(m_pEC != NULL)
00081     {
00082       EC_KEY* tmpEC = EC_KEY_dup(m_pEC);
00083       tmpSig->m_pEC = tmpEC;
00084     }
00085 #endif //ECC
00086     return tmpSig;
00087 
00088   }
00089 
00090 SINT32 CASignature::generateSignKey(UINT32 size)
00091   {
00092     if(m_pDSA!=NULL)
00093       DSA_free(m_pDSA);
00094     m_pDSA=NULL;
00095     m_pDSA=DSA_generate_parameters(size,NULL,0,NULL,NULL,NULL,NULL);
00096     if(m_pDSA==NULL)
00097       return E_UNKNOWN;
00098     if(DSA_generate_key(m_pDSA)!=1)
00099       {
00100         DSA_free(m_pDSA);
00101         m_pDSA=NULL;
00102         return E_UNKNOWN;
00103       }
00104     return E_SUCCESS;
00105   }
00106 
00107 SINT32 CASignature::getSignKey(DOMElement* & elem,XERCES_CPP_NAMESPACE::DOMDocument* doc)
00108   {
00109     CACertificate* pCert=NULL;
00110     getVerifyKey(&pCert);
00111     EVP_PKEY* pPKey=EVP_PKEY_new();
00112     EVP_PKEY_set1_DSA(pPKey,m_pDSA);
00113     PKCS12* pPKCS12=PKCS12_create(NULL,NULL, pPKey,pCert->m_pCert,NULL,0,0,0,0,0);
00114     delete pCert;
00115     pCert = NULL;
00116     EVP_PKEY_free(pPKey);
00117     UINT8* buff=NULL;
00118     SINT32 len=i2d_PKCS12(pPKCS12,&buff);
00119     UINT32 outlen=2*len;
00120     UINT8* outbuff=new UINT8[outlen];
00121     CABase64::encode(buff,len,outbuff,&outlen);
00122     outbuff[outlen]=0;
00123     OPENSSL_free(buff);
00124     elem=createDOMElement(doc,"X509PKCS12");
00125     setDOMElementValue(elem,outbuff);
00126     return E_SUCCESS;
00127   }
00128 
00129 SINT32 CASignature::setSignKey(const DOMNode* n,UINT32 type,const char* passwd)
00130   {
00131     const DOMNode* node=n;
00132     switch(type)
00133     {
00134       case SIGKEY_PKCS12:
00135         while(node!=NULL)
00136         {
00137           if(equals(node->getNodeName(),"X509PKCS12"))
00138           {
00139             UINT32 strLen=4096;
00140             UINT8* tmpStr=new UINT8[strLen];
00141             if(getDOMElementValue(node,tmpStr,&strLen)!=E_SUCCESS)
00142             {
00143               delete[] tmpStr;
00144               tmpStr = NULL;
00145               return E_UNKNOWN;
00146             }
00147             UINT32 decLen=4096;
00148             UINT8* decBuff=new UINT8[decLen];
00149             CABase64::decode((UINT8*)tmpStr,strLen,decBuff,&decLen);
00150             delete [] tmpStr;
00151             tmpStr = NULL;
00152             SINT32 ret=setSignKey(decBuff,decLen,SIGKEY_PKCS12,passwd);
00153             delete[] decBuff;
00154             decBuff = NULL;
00155             return ret;
00156           }
00157           node=node->getNextSibling();
00158         }
00159     }
00160     return E_UNKNOWN;
00161   }
00162 
00163 SINT32 CASignature::setSignKey(const UINT8* buff,UINT32 len,UINT32 type,const char* passwd)
00164   {
00165     if(buff==NULL||len<1)
00166     {
00167       return E_UNKNOWN;
00168     }
00169     switch (type)
00170     {
00171       case SIGKEY_XML:
00172         return parseSignKeyXML(buff,len);
00173 
00174       case SIGKEY_PKCS12:
00175         #if OPENSSL_VERSION_NUMBER  > 0x009070CfL
00176           PKCS12* tmpPKCS12=d2i_PKCS12(NULL,(const UINT8**)&buff,len);
00177         #else
00178           PKCS12* tmpPKCS12=d2i_PKCS12(NULL,(UINT8**)&buff,len);
00179         #endif
00180 
00181         EVP_PKEY* key=NULL;
00182         if(PKCS12_parse(tmpPKCS12,passwd,&key,NULL,NULL)!=1)
00183         {
00184           PKCS12_free(tmpPKCS12);
00185           return E_UNKNOWN;
00186         }
00187         PKCS12_free(tmpPKCS12);
00188         if(EVP_PKEY_type(key->type) == EVP_PKEY_DSA)
00189         {
00190           // found DSA key
00191           DSA* tmpDSA = DSA_clone(key->pkey.dsa);
00192           EVP_PKEY_free(key);
00193           if(DSA_sign_setup(tmpDSA,NULL,&tmpDSA->kinv,&tmpDSA->r)!=1)
00194           {
00195             DSA_free(tmpDSA);
00196             return E_UNKNOWN;
00197           }
00198           DSA_free(m_pDSA);
00199           m_pDSA = tmpDSA;
00200           return E_SUCCESS;
00201         }
00202         else if(EVP_PKEY_type(key->type) == EVP_PKEY_RSA)
00203         {
00204           // found RSA key
00205           RSA* tmpRSA = RSA_clone(key->pkey.rsa);
00206           EVP_PKEY_free(key);
00207           key = NULL;
00208           tmpRSA->flags |= RSA_FLAG_THREAD_SAFE;
00209           tmpRSA->flags |= RSA_FLAG_SIGN_VER;
00210           #ifdef RSA_FLAG_NO_BLINDING
00211             tmpRSA->flags |= RSA_FLAG_NO_BLINDING;
00212           #endif
00213           #if OPENSSL_VERSION_NUMBER  > 0x0090707fL
00214             tmpRSA->flags |= RSA_FLAG_NO_EXP_CONSTTIME;
00215           #endif
00216           RSA_free(m_pRSA);
00217           m_pRSA=tmpRSA;
00218           return E_SUCCESS;
00219         }
00220         else if(EVP_PKEY_type(key->type) == EVP_PKEY_EC)
00221         {
00222 #ifdef ECC
00223           // found EC key
00224           EC_KEY* tmpECKey = EC_KEY_dup(key->pkey.ec);
00225           EVP_PKEY_free(key);
00226           key = NULL;
00227           EC_KEY_free(m_pEC);
00228           m_pEC = tmpECKey;
00229           return E_SUCCESS;
00230 #else
00231           CAMsg::printMsg(LOG_ERR, "Found EC-Key but OpenSSL was built without ECC support!\n");
00232           return E_UNKNOWN;
00233 #endif //ECC
00234 
00235         }
00236         else
00237         {
00238           EVP_PKEY_free(key);
00239         }
00240       }
00241       return E_UNKNOWN;
00242   }
00243 
00244 
00245 //XML Decode...
00246 SINT32 CASignature::parseSignKeyXML(const UINT8* buff,UINT32 len)
00247   {
00248 
00249     XERCES_CPP_NAMESPACE::DOMDocument* doc=parseDOMDocument(buff,len);
00250     if(doc == NULL)
00251     {
00252       return E_UNKNOWN;
00253     }
00254     DOMElement* rootKeyInfo=doc->getDocumentElement();
00255     if(rootKeyInfo == NULL)
00256     {
00257       return E_UNKNOWN;
00258     }
00259     if(!equals(rootKeyInfo->getNodeName(),"KeyInfo"))
00260     {
00261       return E_UNKNOWN;
00262     }
00263     DOMNode* elemKeyValue;
00264     if(getDOMChildByName(rootKeyInfo,"KeyValue",elemKeyValue)!=E_SUCCESS)
00265       return E_UNKNOWN;
00266     if(getDOMChildByName(elemKeyValue,"DSAKeyValue",elemKeyValue)!=E_SUCCESS)
00267       return E_UNKNOWN;
00268     UINT8 tbuff[4096];
00269     UINT32 tlen=4096;
00270     DSA* tmpDSA=DSA_new();
00271     DOMNode* child=elemKeyValue->getFirstChild();
00272     while(child!=NULL)
00273       {
00274         char* name=XMLString::transcode(child->getNodeName());
00275         DOMNode* text=child->getFirstChild();
00276         if(text!=NULL)
00277           {
00278             char* tmpStr=XMLString::transcode(text->getNodeValue());
00279             tlen=4096;
00280             CABase64::decode((UINT8*)tmpStr,strlen(tmpStr),tbuff,&tlen);
00281             XMLString::release(&tmpStr);
00282             if(strcmp(name,"P")==0)
00283               {
00284                 if(tmpDSA->p!=NULL)
00285                   BN_free(tmpDSA->p);
00286                 tmpDSA->p=BN_bin2bn(tbuff,tlen,NULL);
00287               }
00288             else if(strcmp(name,"Q")==0)
00289               {
00290                 if(tmpDSA->q!=NULL)
00291                   BN_free(tmpDSA->q);
00292                 tmpDSA->q=BN_bin2bn(tbuff,tlen,NULL);
00293               }
00294             else if(strcmp(name,"G")==0)
00295               {
00296                 if(tmpDSA->g!=NULL)
00297                     BN_free(tmpDSA->g);
00298                   tmpDSA->g=BN_bin2bn(tbuff,tlen,NULL);
00299               }
00300             else if(strcmp(name,"X")==0)
00301               {
00302                 if(tmpDSA->priv_key!=NULL)
00303                   BN_free(tmpDSA->priv_key);
00304                 tmpDSA->priv_key=BN_bin2bn(tbuff,tlen,NULL);
00305 
00306               }
00307             else if(strcmp(name,"Y")==0)
00308               {
00309                 if(tmpDSA->pub_key!=NULL)
00310                   BN_free(tmpDSA->pub_key);
00311                 tmpDSA->pub_key=BN_bin2bn(tbuff,tlen,NULL);
00312               }
00313           }
00314         XMLString::release(&name);
00315         child=child->getNextSibling();
00316       }
00317     if(DSA_sign_setup(tmpDSA,NULL,&tmpDSA->kinv,&tmpDSA->r)!=1)
00318       {
00319         DSA_free(tmpDSA);
00320         return E_UNKNOWN;
00321       }
00322     if(m_pDSA!=NULL)
00323       DSA_free(m_pDSA);
00324     m_pDSA=tmpDSA;
00325     return E_SUCCESS;
00326   }
00327 
00331 SINT32 CASignature::sign(const UINT8* in,UINT32 inlen,UINT8* sig,UINT32* siglen) const
00332   {
00333     if(m_pDSA != NULL)
00334     {
00335       DSA_SIG* signature = NULL;
00336       if( sign(in,inlen,&signature) != E_SUCCESS)
00337       {
00338         return E_UNKNOWN;
00339       }
00340       if(encodeRS(sig,siglen,signature) != E_SUCCESS)
00341       {
00342         DSA_SIG_free(signature);
00343         return E_UNKNOWN;
00344       }
00345       DSA_SIG_free(signature);
00346       return E_SUCCESS;
00347     }
00348     else if(m_pRSA != NULL)
00349     {
00350       UINT8 dgst[SHA_DIGEST_LENGTH];
00351       SHA1(in,inlen,dgst);
00352       return signRSA(dgst, SHA_DIGEST_LENGTH, sig, siglen);
00353     }
00354 #ifdef ECC
00355     else if(m_pEC != NULL)
00356     {
00357       UINT8 dgst[SHA_DIGEST_LENGTH];
00358       SHA1(in,inlen,dgst);
00359       return signECDSA(dgst, SHA_DIGEST_LENGTH, sig, siglen);
00360     }
00361 #endif //ECC
00362     return E_UNKNOWN;
00363   }
00364 
00365 // TODO integrate this function to the one above!
00366 SINT32 CASignature::sign(const UINT8* in,UINT32 inlen,DSA_SIG** pdsaSig) const
00367   {
00368     UINT8* dgst=new UINT8[SHA_DIGEST_LENGTH];
00369     SHA1(in,inlen,dgst);
00370     *pdsaSig=DSA_do_sign(dgst,SHA_DIGEST_LENGTH,m_pDSA);
00371     delete []dgst;
00372     if(*pdsaSig!=NULL)
00373      return E_SUCCESS;
00374     return E_UNKNOWN;
00375   }
00376 
00377 SINT32 CASignature::getSignatureSize() const
00378   {
00379     if(isDSA())
00380     {
00381       return DSA_size(m_pDSA);
00382     }
00383     if(isRSA())
00384     {
00385       return RSA_size(m_pRSA);
00386     }
00387 #ifdef ECC
00388     if(isECDSA())
00389     {
00390       const EC_GROUP* tmpGroup = EC_KEY_get0_group(m_pEC);
00391 
00392       BIGNUM* order = BN_new();
00393       EC_GROUP_get_order(tmpGroup, order, NULL);
00394       SINT32 size = BN_num_bytes(order) * 2;
00395       return size;
00396     }
00397 #endif //ECC
00398     return E_UNKNOWN;
00399   }
00400 
00413 /*SINT32 CASignature::signXML(UINT8* in,UINT32 inlen,UINT8* out,UINT32* outlen,CACertStore* pIncludeCerts)
00414   {
00415     if(in==NULL||inlen<1||out==NULL||outlen==NULL)
00416       return E_UNKNOWN;
00417 
00418     XERCES_CPP_NAMESPACE::DOMDocument* doc=parseDOMDocument(in,inlen);
00419     if(doc==NULL)
00420       return E_UNKNOWN;
00421     DOMElement* root=doc->getDocumentElement();
00422     SINT32 ret=signXML(root,pIncludeCerts);
00423     if(ret!=E_SUCCESS)
00424       {
00425         doc->release();
00426         return E_UNKNOWN;
00427       }
00428     ret=DOM_Output::dumpToMem(root,out,outlen);
00429     doc->release();
00430     return ret;
00431   }
00432 */
00442 /*SINT32 CASignature::signXML(DOMNode* node,CACertStore* pIncludeCerts)
00443   {
00444     //getting the Document an the Node to sign
00445     XERCES_CPP_NAMESPACE::DOMDocument* doc=NULL;
00446     DOMNode* elemRoot=NULL;
00447     if(node->getNodeType()==DOMNode::DOCUMENT_NODE)
00448       {
00449         doc=(XERCES_CPP_NAMESPACE::DOMDocument*)node;
00450         elemRoot=doc->getDocumentElement();
00451       }
00452     else
00453       {
00454         elemRoot=node;
00455         doc=node->getOwnerDocument();
00456       }
00457 
00458     //check if there is already a Signature and if so remove it first...
00459     DOMNode* tmpSignature=NULL;
00460     if(getDOMChildByName(elemRoot,"Signature",tmpSignature,false)==E_SUCCESS)
00461       {
00462         DOMNode* n=elemRoot->removeChild(tmpSignature);
00463         if (n != NULL)
00464         {
00465           n->release();
00466           n = NULL;
00467         }
00468       }
00469 
00470     //Calculating the Digest...
00471     UINT32 len=0;
00472     UINT8* canonicalBuff=DOM_Output::makeCanonical(elemRoot,&len);
00473     if(canonicalBuff==NULL)
00474       return E_UNKNOWN;
00475 
00476     UINT8 dgst[SHA_DIGEST_LENGTH];
00477     SHA1(canonicalBuff,len,dgst);
00478     delete[]canonicalBuff;
00479     canonicalBuff = NULL;
00480 
00481     UINT8 tmpBuff[1024];
00482     len=1024;
00483     if(CABase64::encode(dgst,SHA_DIGEST_LENGTH,tmpBuff,&len)!=E_SUCCESS)
00484       return E_UNKNOWN;
00485     tmpBuff[len]=0;
00486 
00487 
00488     //Creating the Sig-InfoBlock....
00489     DOMElement* elemSignedInfo=createDOMElement(doc,"SignedInfo");
00490     DOMElement* elemCanonicalizationMethod=createDOMElement(doc,"CanonicalizationMethod");
00491     DOMElement* elemSignatureMethod=createDOMElement(doc,"SignatureMethod");
00492     if(isDSA())
00493     {
00494       setDOMElementAttribute(elemSignatureMethod, "Algorithm", (UINT8*)DSA_SHA1_REFERENCE);
00495     }
00496     else if(isRSA())
00497     {
00498       setDOMElementAttribute(elemSignatureMethod, "Algorithm", (UINT8*)RSA_SHA1_REFERENCE);
00499     }
00500     else if(isECDSA())
00501     {
00502       setDOMElementAttribute(elemSignatureMethod, "Algorithm", (UINT8*)ECDSA_SHA1_REFERENCE);
00503     }
00504     DOMElement* elemReference=createDOMElement(doc,"Reference");
00505     //setDOMElementAttribute(elemReference,"URI",(UINT8*)"");
00506     DOMElement* elemDigestMethod=createDOMElement(doc, "DigestMethod");
00507     setDOMElementAttribute(elemDigestMethod, "Algorithm", (UINT8*)SHA1_REFERENCE);
00508     DOMElement* elemDigestValue=createDOMElement(doc,"DigestValue");
00509     setDOMElementValue(elemDigestValue,tmpBuff);
00510 
00511     elemSignedInfo->appendChild(elemCanonicalizationMethod);
00512     elemSignedInfo->appendChild(elemSignatureMethod);
00513     elemSignedInfo->appendChild(elemReference);
00514     elemReference->appendChild(elemDigestMethod);
00515     elemReference->appendChild(elemDigestValue);
00516 
00517     // Signing the SignInfo block....
00518     canonicalBuff=DOM_Output::makeCanonical(elemSignedInfo,&len);
00519     if(canonicalBuff==NULL)
00520     {
00521       return E_UNKNOWN;
00522     }
00523     if(isDSA())
00524     {
00525       DSA_SIG* pdsaSig=NULL;
00526       SINT32 ret=sign(canonicalBuff,len,&pdsaSig);
00527       delete[] canonicalBuff;
00528       canonicalBuff = NULL;
00529       if(ret!=E_SUCCESS)
00530       {
00531         DSA_SIG_free(pdsaSig);
00532         return E_UNKNOWN;
00533       }
00534       len=1024;
00535       encodeRS(tmpBuff,&len,pdsaSig);
00536       //memset(tmpBuff,0,40); //make first 40 bytes '0' --> if r or s is less then 20 bytes long!
00537                           //(Due to be compatible to the standarad r and s must be 20 bytes each)
00538       //BN_bn2bin(pdsaSig->r,tmpBuff+20-BN_num_bytes(pdsaSig->r)); //so r is 20 bytes with leading '0'...
00539       //BN_bn2bin(pdsaSig->s,tmpBuff+40-BN_num_bytes(pdsaSig->s));
00540       DSA_SIG_free(pdsaSig);
00541     }
00542     else if(isRSA() || isECDSA())
00543     {
00544       UINT32 sigLen = getSignatureSize();
00545       SINT32 ret = sign(canonicalBuff, len, tmpBuff, &sigLen);
00546       delete[] canonicalBuff;
00547       canonicalBuff = NULL;
00548 
00549       if(ret != E_SUCCESS)
00550       {
00551         return E_UNKNOWN;
00552       }
00553       len = sigLen;
00554     }
00555     else
00556     {
00557       return E_UNKNOWN;
00558     }
00559     UINT sigSize=255;
00560     UINT8 sig[255];
00561     if(CABase64::encode(tmpBuff,len,sig,&sigSize)!=E_SUCCESS)
00562       return E_UNKNOWN;
00563     sig[sigSize]=0;
00564 
00565     //Makeing the whole Signature-Block....
00566     DOMElement* elemSignature=createDOMElement(doc,"Signature");
00567     DOMElement* elemSignatureValue=createDOMElement(doc,"SignatureValue");
00568     setDOMElementValue(elemSignatureValue,sig);
00569     elemSignature->appendChild(elemSignedInfo);
00570     elemSignature->appendChild(elemSignatureValue);
00571 
00572     if(pIncludeCerts!=NULL)
00573       {
00574         //Making KeyInfo-Block
00575         DOMElement* tmpElemCerts=NULL;
00576         if(pIncludeCerts->encode(tmpElemCerts,doc)==E_SUCCESS && tmpElemCerts!=NULL)
00577           {
00578             DOMElement* elemKeyInfo=createDOMElement(doc,"KeyInfo");
00579             elemKeyInfo->appendChild(tmpElemCerts);
00580             elemSignature->appendChild(elemKeyInfo);
00581           }
00582       }
00583     elemRoot->appendChild(elemSignature);
00584     return E_SUCCESS;
00585   }*/
00586 
00587 
00588 SINT32 CASignature::getVerifyKey(CACertificate** ppCert)
00589   {
00590     //We need this DAS key as EVP key...
00591     EVP_PKEY* pPKey=EVP_PKEY_new();
00592     EVP_PKEY_set1_DSA(pPKey,m_pDSA);
00593     *ppCert=new CACertificate();
00594     (*ppCert)->m_pCert=X509_new();
00595     // LERNGRUPPE
00596     // We nned to use Version 3 to use extensions
00597 //    X509_set_version((*ppCert)->m_pCert,2);
00598     X509_set_version((*ppCert)->m_pCert,3);
00599     ASN1_TIME* pTime=ASN1_TIME_new();
00600     ASN1_TIME_set(pTime,time(NULL));
00601     X509_set_notBefore((*ppCert)->m_pCert,pTime);
00602     X509_set_notAfter((*ppCert)->m_pCert,pTime);
00603     X509_set_pubkey((*ppCert)->m_pCert,pPKey);
00604 // LERNGRUPPE
00605 // Add the subjectKeyIdentifier-Extension to the certificate
00606                 if( (*ppCert)->setSubjectKeyIdentifier() != E_SUCCESS )
00607                 {
00608                     CAMsg::printMsg( LOG_ERR, "Couldn't add the SKI to the certificate!\n");
00609                     return E_UNKNOWN;
00610                 }
00611 
00612     X509_sign((*ppCert)->m_pCert,pPKey,EVP_sha1());
00613     EVP_PKEY_free(pPKey);
00614     return E_SUCCESS;
00615   }
00616 
00619 SINT32 CASignature::getVerifyKeyHash(UINT8* buff,UINT32* len)
00620   {
00621      UINT8* tmpBuff=NULL;
00622      int l=i2d_DSA_PUBKEY(m_pDSA,&tmpBuff);
00623      SHA1(tmpBuff,l,buff);
00624      *len=SHA_DIGEST_LENGTH;
00625      OPENSSL_free(tmpBuff);
00626      return E_SUCCESS;
00627   }
00628 
00635 SINT32 CASignature::setVerifyKey(CACertificate* pCert)
00636   {
00637     if(pCert==NULL)
00638     {
00639       if(isDSA())
00640       {
00641         DSA_free(m_pDSA);
00642         m_pDSA = NULL;
00643       }
00644       else if (isRSA())
00645       {
00646         RSA_free(m_pRSA);
00647         m_pRSA = NULL;
00648       }
00649 #ifdef ECC
00650       else if (isECDSA());
00651       {
00652         EC_KEY_free(m_pEC);
00653         m_pEC = NULL;
00654       }
00655 #endif //ECC
00656       return E_SUCCESS;
00657     }
00658 
00659     EVP_PKEY *key=X509_get_pubkey(pCert->m_pCert);
00660     if(EVP_PKEY_type(key->type) == EVP_PKEY_DSA)
00661     {
00662       DSA* tmpDSA=DSA_clone(key->pkey.dsa);
00663       EVP_PKEY_free(key);
00664       DSA_free(m_pDSA);
00665       m_pDSA=tmpDSA;
00666       return E_SUCCESS;
00667     }
00668     if(EVP_PKEY_type(key->type) == EVP_PKEY_RSA)
00669     {
00670       RSA* tmpRSA = RSA_clone(key->pkey.rsa);
00671       EVP_PKEY_free(key);
00672       RSA_free(m_pRSA);
00673       m_pRSA = tmpRSA;
00674       return E_SUCCESS;
00675     }
00676     if(EVP_PKEY_type(key->type) == EVP_PKEY_EC)
00677     {
00678 #ifdef ECC
00679       EC_KEY* tmpEC = EC_KEY_dup(key->pkey.ec);
00680       EVP_PKEY_free(key);
00681       EC_KEY_free(m_pEC);
00682       m_pEC = tmpEC;
00683       return E_SUCCESS;
00684 #else
00685       CAMsg::printMsg(LOG_ERR, "Found EC-Key but OpenSSL was built without ECC support!\n");
00686       return E_UNKNOWN;
00687 #endif //ECC
00688     }
00689     //key-type is unknown
00690     EVP_PKEY_free(key);
00691     return E_UNKNOWN;
00692   }
00693 
00697 SINT32 CASignature::setVerifyKey(const DOMElement* xmlKey)
00698 {
00699   UINT8 decodeBuffer[4096];
00700   UINT32 len = 4096;
00701   UINT32 encodedLen = 0;
00702   DSA * tmpDSA = NULL;
00703 
00704   if(xmlKey==NULL)
00705   {
00706     DSA_free(m_pDSA);
00707     m_pDSA = NULL;
00708     return E_SUCCESS;
00709   }
00710   if(!equals(xmlKey->getTagName(), "JapPublicKey")!=0)
00711   {
00712     char* tmpStr=XMLString::transcode(xmlKey->getTagName());
00713     CAMsg::printMsg(LOG_DEBUG, "CASignature::setVerifyKey(): no JapPublicKey! -- Tagname is %s\n", tmpStr);
00714     XMLString::release(&tmpStr);
00715     return E_UNKNOWN;
00716   }
00717 
00718   decodeBuffer[0]=0;
00719   if( getDOMElementAttribute(xmlKey,"version",decodeBuffer,&len)!=E_SUCCESS ||
00720     strcmp((char*)decodeBuffer, "1.0")!=0 )
00721   {
00722     CAMsg::printMsg(LOG_DEBUG,
00723         "CASignature::setVerifyKey(): JapPublicKey has unknown version %s. "
00724         "Version 1.0 expected!",decodeBuffer);
00725     return E_UNKNOWN;
00726   }
00727 
00728   DOMNode* elemDsaKey;
00729   if(getDOMChildByName(xmlKey, "DSAKeyValue", elemDsaKey, false)
00730       !=E_SUCCESS)
00731     {
00732       CAMsg::printMsg(LOG_DEBUG,
00733           "CASignature::setVerifyKey(): DSAKeyValue not found!");
00734       return E_UNKNOWN;
00735     }
00736 
00737   tmpDSA=DSA_new();
00738 
00739   // parse "Y"
00740   DOMNode* elem;
00741   if(getDOMChildByName(elemDsaKey, "Y", elem, false)
00742       !=E_SUCCESS)
00743     {
00744       return E_UNKNOWN;
00745     }
00746   len=4096;
00747   if(getDOMElementValue(elem, decodeBuffer, &len)!=E_SUCCESS)
00748   {
00749     DSA_free(tmpDSA);
00750     return E_UNKNOWN;
00751   }
00752   encodedLen = len; len = 4096;
00753   if(CABase64::decode(decodeBuffer, encodedLen, decodeBuffer, &len)!=E_SUCCESS)
00754   {
00755     DSA_free(tmpDSA);
00756     return E_UNKNOWN;
00757   }
00758   tmpDSA->pub_key = BN_bin2bn(decodeBuffer,len,NULL);
00759 
00760 
00761   // parse "G"
00762   len = 4096;
00763   if(getDOMChildByName(elemDsaKey, "G", elem, false)
00764       !=E_SUCCESS)
00765     {
00766       DSA_free(tmpDSA);
00767       return E_UNKNOWN;
00768     }
00769   if(getDOMElementValue(elem, decodeBuffer, &len)!=E_SUCCESS)
00770   {
00771     DSA_free(tmpDSA);
00772     return E_UNKNOWN;
00773   }
00774   encodedLen = len; len = 4096;
00775   if(CABase64::decode(decodeBuffer, encodedLen, decodeBuffer, &len)!=E_SUCCESS)
00776   {
00777     DSA_free(tmpDSA);
00778     return E_UNKNOWN;
00779   }
00780   tmpDSA->g=BN_bin2bn(decodeBuffer,len,NULL);
00781 
00782 
00783   // parse "P"
00784   len = 4096;
00785   if(getDOMChildByName(elemDsaKey,"P", elem, false)
00786       !=E_SUCCESS)
00787     {
00788       DSA_free(tmpDSA);
00789       return E_UNKNOWN;
00790     }
00791   if(getDOMElementValue(elem, decodeBuffer, &len)!=E_SUCCESS)
00792   {
00793     DSA_free(tmpDSA);
00794     return E_UNKNOWN;
00795   }
00796   encodedLen = len; len = 4096;
00797   if(CABase64::decode(decodeBuffer, encodedLen, decodeBuffer, &len)!=E_SUCCESS)
00798   {
00799     DSA_free(tmpDSA);
00800     return E_UNKNOWN;
00801   }
00802   tmpDSA->p=BN_bin2bn(decodeBuffer,len,NULL);
00803 
00804 
00805   // parse "Q"
00806   len = 4096;
00807   if(getDOMChildByName(elemDsaKey, "Q", elem, false)
00808       !=E_SUCCESS)
00809     {
00810       DSA_free(tmpDSA);
00811       return E_UNKNOWN;
00812     }
00813   if(getDOMElementValue(elem, decodeBuffer, &len)!=E_SUCCESS)
00814   {
00815     DSA_free(tmpDSA);
00816     return E_UNKNOWN;
00817   }
00818   encodedLen = len;
00819   len = 1024;
00820   if(CABase64::decode(decodeBuffer, encodedLen, decodeBuffer, &len)!=E_SUCCESS)
00821   {
00822     DSA_free(tmpDSA);
00823     return E_UNKNOWN;
00824   }
00825   tmpDSA->q=BN_bin2bn(decodeBuffer,len,NULL);
00826 
00827   if( tmpDSA->pub_key!=NULL && tmpDSA->g!=NULL && tmpDSA->p!=NULL && tmpDSA->q!=NULL)
00828   {
00829     if(m_pDSA!=NULL)
00830     {
00831       DSA_free(m_pDSA);
00832     }
00833     m_pDSA = tmpDSA;
00834     return E_SUCCESS;
00835   }
00836   DSA_free(tmpDSA);
00837   return E_UNKNOWN;
00838 }
00839 
00840 
00841 SINT32 CASignature::verify(const UINT8* const in,UINT32 inlen,DSA_SIG* const dsaSig) const
00842   {
00843     if(m_pDSA==NULL||dsaSig==NULL||dsaSig->r==NULL||dsaSig->s==NULL)
00844       return E_UNKNOWN;
00845     SINT32 ret=E_UNKNOWN;
00846     UINT8* dgst=new UINT8[SHA_DIGEST_LENGTH];
00847     SHA1(in,inlen,dgst);
00848     if(DSA_do_verify(dgst,SHA_DIGEST_LENGTH,dsaSig,m_pDSA)==1)
00849       {
00850         ret=E_SUCCESS;
00851       }
00852     delete [] dgst;
00853     return ret;
00854   }
00855 
00856 
00869 SINT32 CASignature::verifyDER(UINT8* in, UINT32 inlen, const UINT8 * dsaSig, const UINT32 sigLen)
00870   {
00871     UINT8 dgst[SHA_DIGEST_LENGTH];
00872     UINT32 rc;
00873 
00874     if(m_pDSA==NULL||dsaSig==NULL)
00875       return E_UNKNOWN;
00876     SHA1(in,inlen,dgst);
00877     if((rc=DSA_verify(0, dgst, SHA_DIGEST_LENGTH, dsaSig, sigLen, m_pDSA))==1)
00878       return E_SUCCESS;
00879     else if(rc==0)
00880       return E_INVALID; // wrong signature
00881     return E_UNKNOWN;
00882   }
00883 
00884 
00885 /*SINT32 CASignature::verifyXML(const UINT8* const in,UINT32 inlen)
00886   {
00887     XERCES_CPP_NAMESPACE::DOMDocument* doc=parseDOMDocument(in,inlen);
00888     if(doc == NULL)
00889     {
00890       return E_UNKNOWN;
00891     }
00892     DOMElement* root=doc->getDocumentElement();
00893     if(root == NULL)
00894     {
00895       return E_UNKNOWN;
00896     }
00897     //CAMsg::printMsg(LOG_DEBUG,"verified document 0x%x doesn't clean up itself!\n",
00898               //doc);
00899     return verifyXML(root,NULL);
00900   }*/
00901 
00902 
00904 SINT32 CASignature::verifyXML(DOMNode* root,CACertStore* trustedCerts)
00905   {
00906     DOMNode* elemSignature;
00907     getDOMChildByName(root,"Signature",elemSignature);
00908     if(elemSignature==NULL)
00909       return E_UNKNOWN;
00910     DOMNode* elemSigValue;
00911     getDOMChildByName(elemSignature,"SignatureValue",elemSigValue);
00912     if(elemSigValue==NULL)
00913       return E_UNKNOWN;
00914     DOMNode* elemSigInfo;
00915     getDOMChildByName(elemSignature,"SignedInfo",elemSigInfo);
00916     if(elemSigInfo==NULL)
00917       return E_UNKNOWN;
00918     DOMNode* elemReference;
00919     getDOMChildByName(elemSigInfo,"Reference",elemReference);
00920     if(elemReference==NULL)
00921       return E_UNKNOWN;
00922     DOMNode* elemDigestValue;
00923     getDOMChildByName(elemReference,"DigestValue",elemDigestValue);
00924     if(elemDigestValue==NULL)
00925       return E_UNKNOWN;
00926 
00927     UINT8 dgst[255];
00928     UINT32 dgstlen=255;
00929     if(getDOMElementValue(elemDigestValue,dgst,&dgstlen)!=E_SUCCESS)
00930       return E_UNKNOWN;
00931     if(CABase64::decode(dgst,dgstlen,dgst,&dgstlen)!=E_SUCCESS)
00932       return E_UNKNOWN;
00933     if(dgstlen!=SHA_DIGEST_LENGTH)
00934       return E_UNKNOWN;
00935     UINT8 tmpSig[255];
00936     UINT32 tmpSiglen=255;
00937     if(getDOMElementValue(elemSigValue,tmpSig,&tmpSiglen)!=E_SUCCESS)
00938       return E_UNKNOWN;
00939     if(CABase64::decode(tmpSig,tmpSiglen,tmpSig,&tmpSiglen)!=E_SUCCESS)
00940       return E_UNKNOWN;
00941 
00942     UINT8* out=new UINT8[5000];
00943     UINT32 outlen=5000;
00944     if(DOM_Output::makeCanonical(elemSigInfo, out, &outlen) != E_SUCCESS)
00945     {
00946       delete[] out;
00947       out = NULL;
00948       return E_UNKNOWN;
00949     }
00950     if(isDSA())
00951     {
00952       if(tmpSiglen!=40)
00953       {
00954         delete[] out;
00955         out = NULL;
00956         return E_UNKNOWN;
00957       }
00958       DSA_SIG* dsaSig=DSA_SIG_new();
00959         dsaSig->r=BN_bin2bn(tmpSig,20,dsaSig->r);
00960       dsaSig->s=BN_bin2bn(tmpSig+20,20,dsaSig->s);
00961       if(verify(out,outlen,dsaSig)!=E_SUCCESS)
00962       {
00963         DSA_SIG_free(dsaSig);
00964         delete[] out;
00965         out = NULL;
00966         return E_UNKNOWN;
00967       }
00968       DSA_SIG_free(dsaSig);
00969     }
00970     else
00971     {
00972       UINT8 sha1[SHA_DIGEST_LENGTH];
00973       SHA1(out, outlen, sha1);
00974       SINT32 ret = 0;
00975       if(isRSA())
00976       {
00977         ret = RSA_verify(NID_sha1, sha1, SHA_DIGEST_LENGTH, tmpSig, tmpSiglen, m_pRSA);
00978       }
00979 #ifdef ECC
00980       else if(isECDSA())
00981       {
00982         ret = ECDSA_verify(NID_sha1, sha1, SHA_DIGEST_LENGTH, tmpSig, tmpSiglen, m_pEC);
00983       }
00984 #endif //ECC
00985       if(ret != 1)
00986       {
00987         delete[] out;
00988         out = NULL;
00989         return E_UNKNOWN;
00990       }
00991     }
00992 
00993     DOMNode* tmpNode=root->removeChild(elemSignature);
00994     outlen=5000;
00995     DOM_Output::makeCanonical(root,out,&outlen);
00996     root->appendChild(tmpNode);
00997     UINT8 dgst1[SHA_DIGEST_LENGTH];
00998     SHA1(out,outlen,dgst1);
00999     delete[] out;
01000     out = NULL;
01001     for(int i=0;i<SHA_DIGEST_LENGTH;i++)
01002     {
01003       if(dgst1[i]!=dgst[i])
01004       {
01005         return E_UNKNOWN;
01006       }
01007     }
01008     return E_SUCCESS;
01009   }
01010 
01011 SINT32 CASignature::encodeRS(UINT8* out,UINT32* outLen,const DSA_SIG* const pdsaSig) const
01012   {
01013     UINT32 rSize, sSize;
01014     memset(out,0,40); //make first 40 bytes '0' --> if r or s is less then 20 bytes long!
01015                       //(Due to be compatible to the standarad r and s must be 20 bytes each)
01016     rSize = BN_num_bytes(pdsaSig->r);
01017     sSize = BN_num_bytes(pdsaSig->s);
01018     BN_bn2bin(pdsaSig->r,out+20-rSize); //so r is 20 bytes with leading '0'...
01019     BN_bn2bin(pdsaSig->s,out+40-sSize);
01020     *outLen=40;
01021     return E_SUCCESS;
01022   }
01023 
01024 
01025 SINT32 CASignature::decodeRS(const UINT8* const in, const UINT32 inLen, DSA_SIG* pDsaSig) const
01026 {
01027   ASSERT(pDsaSig!=NULL, "DSA_SIG is null");
01028   ASSERT(inLen>20, "Inbuffer is <=20 bytes");
01029   pDsaSig->r = BN_bin2bn(in, 20, NULL);
01030   pDsaSig->s = BN_bin2bn(in+20, inLen-20, NULL);
01031   return E_SUCCESS;
01032 }
01033 
01034 SINT32 CASignature::signRSA(const UINT8* dgst, UINT32 dgstLen, UINT8* sig, UINT32* sigLen) const
01035 {
01036   if(RSA_sign(NID_sha1, dgst, dgstLen, sig, sigLen, m_pRSA) != 1)
01037   {
01038     return E_UNKNOWN;
01039   }
01040 
01041   return E_SUCCESS;
01042 }
01043 #ifdef ECC
01044 SINT32 CASignature::signECDSA(const UINT8* dgst, UINT32 dgstLen, UINT8* sig, UINT32* sigLen) const
01045 {
01046 
01047   UINT32 len = getSignatureSize();
01048   if(len > *sigLen)
01049   {
01050     return E_UNKNOWN;
01051   }
01052   ECDSA_SIG* ecdsaSig = ECDSA_do_sign(dgst, dgstLen, m_pEC);
01053   if(ecdsaSig == NULL)
01054   {
01055     return E_UNKNOWN;
01056   }
01057   memset(sig, 0, *sigLen);
01058   UINT32 rSize, sSize;
01059   rSize = BN_num_bytes(ecdsaSig->r);
01060   sSize = BN_num_bytes(ecdsaSig->s);
01061 
01062   UINT32 rPos = (len/2)-rSize;
01063   UINT32 sPos = len-sSize;
01064 
01065   //CAMsg::printMsg(LOG_DEBUG, "Sig-Positions r: %d(size=%d), s: %d(size=%d)\n", rPos, rSize, sPos, sSize);
01066   BN_bn2bin(ecdsaSig->r, sig + rPos);
01067   BN_bn2bin(ecdsaSig->s, sig + sPos);
01068   *sigLen = len;
01069 
01070   UINT32 tmplen = 255;
01071   UINT8 tmpbuff[tmplen];
01072   CABase64::encode(sig, *sigLen, tmpbuff, &tmplen);
01073   ECDSA_SIG_free(ecdsaSig);
01074 
01075   return E_SUCCESS;
01076 
01077 }
01078 #endif //ECC
01079 SINT32 CASignature::verify(UINT8* in, UINT32 inLen, UINT8* sig, const UINT32 sigLen)
01080 {
01081   UINT8 sha1[SHA_DIGEST_LENGTH];
01082   SHA1(in, inLen, sha1);
01083   SINT32 ret = -1;
01084   if(isDSA())
01085   {
01086     ret = verifyDSA(sha1, SHA_DIGEST_LENGTH, sig, sigLen);
01087   }
01088   else if(isRSA())
01089   {
01090     ret = verifyRSA(sha1, SHA_DIGEST_LENGTH, sig, sigLen);
01091   }
01092 #ifdef ECC
01093   else if(isECDSA())
01094   {
01095     ret = verifyECDSA(sha1, SHA_DIGEST_LENGTH, sig, sigLen);
01096   }
01097 #endif //ECC
01098   if(ret == 1)
01099   {
01100     return E_SUCCESS;
01101   }
01102   return E_UNKNOWN;
01103 }
01104 
01105 SINT32 CASignature::verifyRSA(const UINT8* dgst, const UINT32 dgstLen, UINT8* sig, UINT32 sigLen) const
01106 {
01107   if(sigLen != (UINT32)getSignatureSize())
01108   {
01109     return E_UNKNOWN;
01110   }
01111   return RSA_verify(NID_sha1, dgst, dgstLen, sig, sigLen, m_pRSA);
01112 }
01113 
01114 SINT32 CASignature::verifyDSA(const UINT8* dgst, const UINT32 dgstLen, UINT8* sig, UINT32 sigLen) const
01115 {
01116   if(sigLen != 40)
01117   {
01118     return E_UNKNOWN;
01119   }
01120   DSA_SIG* dsaSig = DSA_SIG_new();
01121   dsaSig->r = BN_bin2bn(sig, 20, dsaSig->r);
01122   dsaSig->s = BN_bin2bn(sig+20, 20, dsaSig->s);
01123 
01124   SINT32 ret = DSA_do_verify(dgst, dgstLen, dsaSig, m_pDSA);
01125   DSA_SIG_free(dsaSig);
01126 
01127   return ret;
01128 }
01129 
01130 #ifdef ECC
01131 SINT32 CASignature::verifyECDSA(const UINT8* dgst, const UINT32 dgstLen, UINT8* sig, UINT32 sigLen) const
01132 {
01133   SINT32 len = sigLen / 2;
01134   ECDSA_SIG* ecdsaSig = ECDSA_SIG_new();
01135   ecdsaSig->r = BN_bin2bn(sig, len, ecdsaSig->r);
01136   ecdsaSig->s = BN_bin2bn(sig+len, len, ecdsaSig->s);
01137 
01138   SINT32 ret = ECDSA_do_verify(dgst, dgstLen, ecdsaSig, m_pEC);
01139   ECDSA_SIG_free(ecdsaSig);
01140 
01141   return ret;
01142 
01143 }
01144 #endif //ECC
01145 
01146 bool CASignature::isDSA() const
01147 {
01148   if(m_pDSA != NULL)
01149   {
01150     return true;
01151   }
01152   return false;
01153 }
01154 
01155 bool CASignature::isRSA() const
01156 {
01157   if(m_pRSA != NULL)
01158   {
01159     return true;
01160   }
01161   return false;
01162 }
01163 
01164 #ifdef ECC
01165 bool CASignature::isECDSA() const
01166 {
01167   if(m_pEC != NULL)
01168   {
01169     return true;
01170   }
01171   return false;
01172 }
01173 #endif //ECC
01174 
01175 UINT8* CASignature::getSignatureMethod()
01176 {
01177   if(m_pDSA != NULL)
01178   {
01179     return (UINT8*)DSA_SHA1_REFERENCE;
01180   }
01181   if(m_pRSA != NULL)
01182   {
01183     return (UINT8*)RSA_SHA1_REFERENCE;
01184   }
01185 #ifdef ECC
01186   if(m_pEC != NULL)
01187   {
01188     return (UINT8*)ECDSA_SHA1_REFERENCE;
01189   }
01190 #endif //ECC
01191   return NULL;
01192 }
01193 
01194 #endif //ONLY_LOCAL_PROXY