|
Mixe for Privacy and Anonymity in the Internet
|
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
1.7.6.1