|
Mixe for Privacy and Anonymity in the Internet
|
#include <CAMultiSignature.hpp>
Public Member Functions | |
| CAMultiSignature () | |
| virtual | ~CAMultiSignature () |
| SINT32 | addSignature (CASignature *a_signature, CACertStore *a_certs, UINT8 *a_ski, UINT32 a_skiLen) |
| SINT32 | signXML (DOMNode *a_node, bool appendCerts) |
| SINT32 | signXML (UINT8 *in, UINT32 inlen, UINT8 *out, UINT32 *outlen, bool appendCerts) |
| UINT32 | getSignatureCount () |
| SINT32 | sign (UINT8 *in, UINT32 inlen, UINT8 *sig, UINT32 *siglen) |
| Method for producing a single Signature for Key Exchange. | |
| SINT32 | getXORofSKIs (UINT8 *out, UINT32 outlen) |
| SINT32 | findSKI (const UINT8 *a_strSKI) |
Static Public Member Functions | |
| static SINT32 | verifyXML (const UINT8 *const in, UINT32 inlen, CACertificate *a_cert) |
| static SINT32 | verifyXML (DOMNode *a_node, CACertificate *a_cert) |
Private Member Functions | |
| SINT32 | getSKI (UINT8 *in, UINT32 inlen, const UINT8 *a_ski) |
Private Attributes | |
| SIGNATURE * | m_signatures |
| UINT32 | m_sigCount |
| UINT8 * | m_xoredID |
Definition at line 50 of file CAMultiSignature.hpp.
Definition at line 41 of file CAMultiSignature.cpp.
References m_sigCount, m_signatures, and m_xoredID.
{
m_signatures = NULL;
m_sigCount = 0;
m_xoredID = new UINT8[SHA_DIGEST_LENGTH];
for(SINT32 i = 0; i<SHA_DIGEST_LENGTH; i++)
{
m_xoredID[i] = 0;
}
}
| CAMultiSignature::~CAMultiSignature | ( | ) | [virtual] |
Definition at line 52 of file CAMultiSignature.cpp.
References m_signatures, __t_signature::next, __t_signature::pCerts, __t_signature::pSig, and __t_signature::pSKI.
{
SIGNATURE* tmp;
while(m_signatures != NULL)
{
//delete Signer and CertStore
delete m_signatures->pSig;
delete m_signatures->pCerts;
m_signatures->pCerts = NULL;
m_signatures->pSig = NULL;
delete[] m_signatures->pSKI;
m_signatures->pSKI = NULL;
//store current pointer
tmp = m_signatures;
//go to next signature
m_signatures = m_signatures->next;
//delete current signature
delete tmp;
tmp = NULL;
}
}
| SINT32 CAMultiSignature::addSignature | ( | CASignature * | a_signature, |
| CACertStore * | a_certs, | ||
| UINT8 * | a_ski, | ||
| UINT32 | a_skiLen | ||
| ) |
Definition at line 104 of file CAMultiSignature.cpp.
References E_SUCCESS, E_UNKNOWN, m_sigCount, m_signatures, m_xoredID, __t_signature::next, __t_signature::pCerts, __t_signature::pSig, and __t_signature::pSKI.
Referenced by CACmdLnOptions::setOwnCertificate().
{
if(a_signature == NULL || a_certs == NULL || a_ski == NULL || a_skiLen != SHA_DIGEST_LENGTH)
return E_UNKNOWN;
for(SINT32 i=0; i<SHA_DIGEST_LENGTH; i++)
{
m_xoredID[i] = m_xoredID[i] ^ a_ski[i];
}
SIGNATURE* newSignature = new SIGNATURE;
newSignature->pSig = a_signature;
newSignature->pCerts = a_certs;
newSignature->pSKI = new UINT8[a_skiLen];
memcpy(newSignature->pSKI, a_ski, a_skiLen);
newSignature->next = m_signatures;
m_signatures = newSignature;
m_sigCount++;
return E_SUCCESS;
}
| SINT32 CAMultiSignature::findSKI | ( | const UINT8 * | a_strSKI | ) |
Definition at line 75 of file CAMultiSignature.cpp.
References E_NOT_FOUND, E_SUCCESS, E_UNKNOWN, getSKI(), m_signatures, m_xoredID, __t_signature::next, and __t_signature::pSKI.
Referenced by CACmdLnOptions::setOwnCertificate(), and CACmdLnOptions::setPriceCertificate().
{
SIGNATURE* tmp = m_signatures;
UINT8 tmpSKI[200];
if (tmp == NULL)
{
return E_UNKNOWN;
}
while(tmp != NULL)
{
if (getSKI(tmpSKI, 200, tmp->pSKI) == E_SUCCESS &&
strncmp((char*)a_strSKI, (char*)tmpSKI, strlen((char*)tmpSKI) ) == 0)
{
return E_SUCCESS;
}
tmp = tmp->next;
}
if (getSKI(tmpSKI, 200, m_xoredID) == E_SUCCESS &&
strncmp((char*)a_strSKI, (char*)tmpSKI, strlen((char*)tmpSKI) ) == 0)
{
return E_SUCCESS;
}
return E_NOT_FOUND;
}
| UINT32 CAMultiSignature::getSignatureCount | ( | ) | [inline] |
Definition at line 60 of file CAMultiSignature.hpp.
References m_sigCount.
Referenced by CACmdLnOptions::setOwnCertificate().
{ return m_sigCount; }
| SINT32 CAMultiSignature::getSKI | ( | UINT8 * | in, |
| UINT32 | inlen, | ||
| const UINT8 * | a_ski | ||
| ) | [private] |
Definition at line 473 of file CAMultiSignature.cpp.
References E_SUCCESS, E_UNKNOWN, len, CACertificate::removeColons(), and strtrim().
Referenced by findSKI(), and getXORofSKIs().
{
UINT8* tmp = (UINT8*) hex_to_string((unsigned char*)a_ski, SHA_DIGEST_LENGTH);
UINT32 len=outlen;
if (CACertificate::removeColons(tmp, strlen((const char*)tmp), out, &len) != E_SUCCESS)
{
OPENSSL_free(tmp);
return E_UNKNOWN;
}
OPENSSL_free(tmp);
strtrim(out);
return E_SUCCESS;
}
| SINT32 CAMultiSignature::getXORofSKIs | ( | UINT8 * | out, |
| UINT32 | outlen | ||
| ) |
Definition at line 487 of file CAMultiSignature.cpp.
References getSKI(), and m_xoredID.
Referenced by CACmdLnOptions::setOwnCertificate().
Method for producing a single Signature for Key Exchange.
Definition at line 464 of file CAMultiSignature.cpp.
References E_UNKNOWN, m_sigCount, m_signatures, __t_signature::pSig, and CASignature::sign().
Referenced by CAFirstMix::doUserLogin_internal().
{
if(m_sigCount < 1)
{
return E_UNKNOWN;
}
return m_signatures->pSig->sign(in, inlen, sig, siglen);
}
| SINT32 CAMultiSignature::signXML | ( | DOMNode * | a_node, |
| bool | appendCerts | ||
| ) |
Definition at line 137 of file CAMultiSignature.cpp.
References createDOMElement(), DSA_SHA1_REFERENCE, E_SUCCESS, E_UNKNOWN, ECDSA_SHA1_REFERENCE, CABase64::encode(), CACertStore::encode(), getDOMChildByName(), CASignature::getSignatureSize(), CASignature::isDSA(), CASignature::isRSA(), len, m_sigCount, m_signatures, DOM_Output::makeCanonical(), __t_signature::next, __t_signature::pCerts, CAMsg::printMsg(), __t_signature::pSig, RSA_SHA1_REFERENCE, setDOMElementAttribute(), setDOMElementValue(), SHA1_REFERENCE, and CASignature::sign().
Referenced by CAMix::appendTermsAndConditionsExtension(), CAInfoService::getCascadeHeloXMLAsString(), CAInfoService::getStatusXMLAsString(), CAMiddleMix::processKeyExchange(), CAFirstMix::processKeyExchange(), signXML(), CAMix::signXML(), and CAInfoService::xmlDocToStringWithSignature().
{
if(m_sigCount == 0)
{
CAMsg::printMsg(LOG_ERR, "Trying to sign a document with no signature-keys set!");
return E_UNKNOWN;
}
//getting the Document an the Node to sign
XERCES_CPP_NAMESPACE::DOMDocument* doc = NULL;
DOMNode* elemRoot = NULL;
if(node->getNodeType() == DOMNode::DOCUMENT_NODE)
{
doc = (XERCES_CPP_NAMESPACE::DOMDocument*)node;
elemRoot = doc->getDocumentElement();
}
else
{
elemRoot = node;
doc = node->getOwnerDocument();
}
//check if there are already Signatures and if so remove them first...
DOMNode* tmpSignature = NULL;
while(getDOMChildByName(elemRoot, "Signature", tmpSignature, false) == E_SUCCESS)
{
DOMNode* n = elemRoot->removeChild(tmpSignature);
if (n != NULL)
{
n->release();
n = NULL;
}
}
//get SHA1-Digest
UINT32 len = 0;
UINT8* canonicalBuff = DOM_Output::makeCanonical(elemRoot, &len);
if(canonicalBuff == NULL)
{
return E_UNKNOWN;
}
UINT8 dgst[SHA_DIGEST_LENGTH];
SHA1(canonicalBuff, len, dgst);
delete[] canonicalBuff;
canonicalBuff = NULL;
UINT8 digestValue[512];
len = 512;
if(CABase64::encode(dgst, SHA_DIGEST_LENGTH, digestValue, &len) != E_SUCCESS)
{
return E_UNKNOWN;
}
//append a signature for each SIGNATURE element we have
SIGNATURE* currentSignature = m_signatures;
UINT32 sigCount = 0;
for(UINT32 i=0; i<m_sigCount; i++)
{
//Creating the Sig-InfoBlock....
DOMElement* elemSignedInfo = createDOMElement(doc, "SignedInfo");
DOMElement* elemCanonicalizationMethod = createDOMElement(doc, "CanonicalizationMethod");
DOMElement* elemSignatureMethod = createDOMElement(doc, "SignatureMethod");
DOMElement* elemReference = createDOMElement(doc, "Reference");
elemReference->setAttribute(XMLString::transcode("URI"), XMLString::transcode(""));
DOMElement* elemDigestMethod = createDOMElement(doc, "DigestMethod");
if(currentSignature->pSig->isDSA()) //DSA-Signature
{
setDOMElementAttribute(elemSignatureMethod, "Algorithm", (UINT8*)DSA_SHA1_REFERENCE);
}
else if(currentSignature->pSig->isRSA())
{
setDOMElementAttribute(elemSignatureMethod, "Algorithm", (UINT8*)RSA_SHA1_REFERENCE);
}
#ifdef ECC
else if(currentSignature->pSig->isECDSA())
{
setDOMElementAttribute(elemSignatureMethod, "Algorithm", (UINT8*)ECDSA_SHA1_REFERENCE);
}
#endif //ECC
setDOMElementAttribute(elemDigestMethod, "Algorithm", (UINT8*)SHA1_REFERENCE);
DOMElement* elemDigestValue = createDOMElement(doc, "DigestValue");
setDOMElementValue(elemDigestValue, digestValue);
elemSignedInfo->appendChild(elemCanonicalizationMethod);
elemSignedInfo->appendChild(elemSignatureMethod);
elemSignedInfo->appendChild(elemReference);
elemReference->appendChild(elemDigestMethod);
elemReference->appendChild(elemDigestValue);
// Signing the SignInfo block....
canonicalBuff = DOM_Output::makeCanonical(elemSignedInfo,&len);
if(canonicalBuff==NULL)
{
return E_UNKNOWN;
}
UINT32 sigLen = currentSignature->pSig->getSignatureSize();
UINT8* sigBuff=new UINT8[sigLen];
SINT32 ret = currentSignature->pSig->sign(canonicalBuff, len, sigBuff, &sigLen);
delete[] canonicalBuff;
canonicalBuff = NULL;
if(ret != E_SUCCESS)
{
currentSignature = currentSignature->next;
delete[] sigBuff;
continue;
}
UINT sigSize = 255;
UINT8 sig[255];
if(CABase64::encode(sigBuff, sigLen, sig, &sigSize) != E_SUCCESS)
{
currentSignature = currentSignature->next;
delete[] sigBuff;
continue;
}
//Makeing the whole Signature-Block....
DOMElement* elemSignature = createDOMElement(doc,"Signature");
DOMElement* elemSignatureValue = createDOMElement(doc,"SignatureValue");
setDOMElementValue(elemSignatureValue,sig);
elemSignature->appendChild(elemSignedInfo);
elemSignature->appendChild(elemSignatureValue);
//Append KeyInfo if neccassary
if(appendCerts)
{
//Making KeyInfo-Block
DOMElement* tmpElemCerts = NULL;
if(currentSignature->pCerts->encode(tmpElemCerts, doc) == E_SUCCESS && tmpElemCerts != NULL)
{
DOMElement* elemKeyInfo = createDOMElement(doc, "KeyInfo");
elemKeyInfo->appendChild(tmpElemCerts);
elemSignature->appendChild(elemKeyInfo);
}
}
elemRoot->appendChild(elemSignature);
sigCount++;
//goto next Signature
currentSignature = currentSignature->next;
delete[] sigBuff;
}
if(sigCount > 0)
{
//CAMsg::printMsg(LOG_DEBUG, "Appended %d Signature(s) to XML-Structure\n", sigCount);
return E_SUCCESS;
}
return E_UNKNOWN;
}
| SINT32 CAMultiSignature::signXML | ( | UINT8 * | in, |
| UINT32 | inlen, | ||
| UINT8 * | out, | ||
| UINT32 * | outlen, | ||
| bool | appendCerts | ||
| ) |
Definition at line 123 of file CAMultiSignature.cpp.
References DOM_Output::dumpToMem(), E_SUCCESS, E_UNKNOWN, parseDOMDocument(), and signXML().
{
if(in == NULL || inlen < 1 || out == NULL || outlen == NULL)
return E_UNKNOWN;
XERCES_CPP_NAMESPACE::DOMDocument* doc = parseDOMDocument(in, inlen);
if(doc == NULL)
return E_UNKNOWN;
DOMElement* root = doc->getDocumentElement();
if(signXML(root, appendCerts) != E_SUCCESS)
return E_UNKNOWN;
return DOM_Output::dumpToMem(root,out,outlen);
}
| SINT32 CAMultiSignature::verifyXML | ( | const UINT8 *const | in, |
| UINT32 | inlen, | ||
| CACertificate * | a_cert | ||
| ) | [static] |
Definition at line 286 of file CAMultiSignature.cpp.
References E_UNKNOWN, and parseDOMDocument().
Referenced by CAAccountingInstance::handleAccountCertificate_internal(), CAMiddleMix::processKeyExchange(), CALastMix::processKeyExchange(), CAFirstMix::processKeyExchange(), and CACmdLnOptions::setPriceCertificate().
{
XERCES_CPP_NAMESPACE::DOMDocument* doc = parseDOMDocument(in,inlen);
if(doc == NULL)
{
return E_UNKNOWN;
}
DOMElement* root = doc->getDocumentElement();
if(root == NULL)
{
return E_UNKNOWN;
}
return CAMultiSignature::verifyXML(root, a_cert);
}
| SINT32 CAMultiSignature::verifyXML | ( | DOMNode * | a_node, |
| CACertificate * | a_cert | ||
| ) | [static] |
Definition at line 301 of file CAMultiSignature.cpp.
References CABase64::decode(), E_SUCCESS, E_UNKNOWN, getDOMChildByName(), getDOMElementAttribute(), getDOMElementValue(), getSignatureElements(), CASignature::getSignatureMethod(), DOM_Output::makeCanonical(), MAX_SIGNATURE_ELEMENTS, CAMsg::printMsg(), CASignature::setVerifyKey(), and CASignature::verify().
{
CASignature* sigVerifier = new CASignature();
if(sigVerifier->setVerifyKey(a_cert) != E_SUCCESS)
{
CAMsg::printMsg(LOG_ERR, "Failed to set verify Key!");
return E_UNKNOWN;
}
UINT8* signatureMethod = sigVerifier->getSignatureMethod();
UINT32 signatureElementsCount = MAX_SIGNATURE_ELEMENTS;
DOMNode* signatureElements[MAX_SIGNATURE_ELEMENTS];
getSignatureElements((DOMElement*)root, signatureElements, &signatureElementsCount);
CAMsg::printMsg(LOG_DEBUG, "Found %d Signature(s) in XML-Structure\n", signatureElementsCount);
UINT8 dgst[255];
UINT32 dgstlen=255;
UINT8* out = NULL;
UINT32 outlen;
bool verified = false;
//go through all appended Signatures an try to verify them with the given cert
for(UINT32 i=0; i<signatureElementsCount; i++)
{
dgstlen=255;
CAMsg::printMsg(LOG_DEBUG, "Trying to verify signature %d of %d!\n", i+1, signatureElementsCount);
DOMNode* elemSignature = signatureElements[i];
if(elemSignature == NULL)
{
CAMsg::printMsg(LOG_DEBUG, "Error: signature element is NULL\n");
continue;
}
DOMNode* elemSigInfo;
getDOMChildByName(elemSignature, "SignedInfo", elemSigInfo);
if(elemSigInfo == NULL)
{
CAMsg::printMsg(LOG_DEBUG, "Error: signed info is NULL\n");
continue;
}
//check if SignatureMethod fits...
DOMNode* elemSigMethod;
getDOMChildByName(elemSigInfo, "SignatureMethod", elemSigMethod);
UINT32 algLen = 255;
UINT8 algorithm[255];
getDOMElementAttribute(elemSigMethod, (const char*)"Algorithm", algorithm, &algLen);
//if signatureMethod is set check if its equal
if(signatureMethod != NULL &&
strncmp((const char*)algorithm, (const char*)signatureMethod, algLen) != E_SUCCESS)
{
CAMsg::printMsg(LOG_DEBUG, "Did NOT find matching SignatureMethods: %s and %s!\n", signatureMethod, algorithm);
continue;
}
DOMNode* elemSigValue;
getDOMChildByName(elemSignature, "SignatureValue", elemSigValue);
if(elemSigValue == NULL)
{
CAMsg::printMsg(LOG_DEBUG, "Error: signature value is NULL\n");
continue;
}
DOMNode* elemReference;
getDOMChildByName(elemSigInfo, "Reference", elemReference);
if(elemReference == NULL)
{
CAMsg::printMsg(LOG_DEBUG, "Error: signature reference is NULL\n");
continue;
}
DOMNode* elemDigestValue;
getDOMChildByName(elemReference, "DigestValue", elemDigestValue);
if(elemDigestValue == NULL)
{
CAMsg::printMsg(LOG_DEBUG, "Error: digest value is NULL\n");
continue;
}
if(getDOMElementValue(elemDigestValue,dgst,&dgstlen)!=E_SUCCESS)
{
CAMsg::printMsg(LOG_DEBUG, "Error: could not get digest value from XML\n");
continue;
}
if(CABase64::decode(dgst,dgstlen,dgst,&dgstlen)!=E_SUCCESS)
{
CAMsg::printMsg(LOG_DEBUG, "Error: could not decode digest value\n");
continue;
}
if(dgstlen!=SHA_DIGEST_LENGTH)
{
CAMsg::printMsg(LOG_DEBUG, "Error: digest is %d long, should be %d\n", dgstlen, SHA_DIGEST_LENGTH);
continue;
}
UINT32 tmpSiglen = 255;
UINT8 tmpSig[255];
if(getDOMElementValue(elemSigValue,tmpSig,&tmpSiglen)!=E_SUCCESS)
{
CAMsg::printMsg(LOG_DEBUG, "Error: could not get signature value from XML\n");
continue;
}
if(CABase64::decode(tmpSig,tmpSiglen,tmpSig,&tmpSiglen)!=E_SUCCESS)
{
CAMsg::printMsg(LOG_DEBUG, "Error: could not decode signature value\n");
continue;
}
outlen = 5000;
out = new UINT8[outlen];
if(DOM_Output::makeCanonical(elemSigInfo, out, &outlen) == E_SUCCESS)
{
if(sigVerifier->verify(out, outlen, tmpSig, tmpSiglen) == E_SUCCESS)
{
CAMsg::printMsg(LOG_DEBUG, "Signature verification successful!\n");
verified = true;
break;
}
}
CAMsg::printMsg(LOG_WARNING, "Signature verification not successful!\n");
delete[] out;
out = NULL;
continue;
}
if(verified)
{
//the signature could be verified, now check digestValue
//first remove Signature-nodes from root and store them
DOMNode* removedSignatures[MAX_SIGNATURE_ELEMENTS];
for(UINT32 i=0; i<signatureElementsCount; i++)
{
removedSignatures[i] = root->removeChild(signatureElements[i]);
if(removedSignatures[i] == NULL)
{
//TODO do what? Verification will most likely fail, so just log the error for the moment
CAMsg::printMsg(LOG_ERR, "Error removing signature-element %d of %d from Root-Node\n", i+1, signatureElementsCount);
}
}
outlen = 5000;
DOM_Output::makeCanonical(root, out, &outlen);
//append Signature-nodes again
for(UINT32 i=0; i<signatureElementsCount; i++)
{
if(removedSignatures[i] != NULL)
{
root->appendChild(removedSignatures[i]);
}
}
UINT8 newDgst[SHA_DIGEST_LENGTH];
SHA1(out, outlen, newDgst);
delete[] out;
out = NULL;
for(int i=0; i<SHA_DIGEST_LENGTH; i++)
{
if(newDgst[i] != dgst[i])
{
CAMsg::printMsg(LOG_ERR, "Error checking XML-Signature DigestValue!\n");
return E_UNKNOWN;
}
}
return E_SUCCESS;
}
CAMsg::printMsg(LOG_ERR, "XML-Signature could not be verified!\n");
return E_UNKNOWN;
}
UINT32 CAMultiSignature::m_sigCount [private] |
Definition at line 66 of file CAMultiSignature.hpp.
Referenced by addSignature(), CAMultiSignature(), getSignatureCount(), sign(), and signXML().
SIGNATURE* CAMultiSignature::m_signatures [private] |
Definition at line 65 of file CAMultiSignature.hpp.
Referenced by addSignature(), CAMultiSignature(), findSKI(), sign(), signXML(), and ~CAMultiSignature().
UINT8* CAMultiSignature::m_xoredID [private] |
Definition at line 67 of file CAMultiSignature.hpp.
Referenced by addSignature(), CAMultiSignature(), findSKI(), and getXORofSKIs().
1.7.6.1