//--------------------------------------------------------------------- ElementPtr PeerContactProfile::getPrivateProfile() const { AutoRecursiveLock lock(mLock); if (!mDocument) return ElementPtr(); if (!hasContactProfileSecret()) return ElementPtr(); try { ElementPtr contactProfileElement = getContactProfileElement(); if (!contactProfileElement) return ElementPtr(); ElementPtr privateElement = contactProfileElement->findFirstChildElementChecked("private"); ElementPtr profileElement = privateElement->findFirstChildElementChecked("encryptedProfile"); ElementPtr saltElement = privateElement->findFirstChildElementChecked("salt"); String saltAsBase64 = saltElement->getText(true); SecureByteBlock output; decryptAndNulTerminateFromBase64( "profile", mContactProfileSecret, saltAsBase64, profileElement->getText(true), output ); String parseData = (CSTR)((const BYTE *)output); DocumentPtr temp = Document::create(); temp->parse(parseData); ElementPtr result = temp->findFirstChildElementChecked("profile"); result->orphan(); return result; } catch (zsLib::XML::Exceptions::CheckFailed &) { } return ElementPtr(); }
//--------------------------------------------------------------------- bool PeerContactProfile::usesContactProfileSecret(const char *contactProfileSecret) { AutoRecursiveLock lock(mLock); if (NULL == contactProfileSecret) return false; if (!mDocument) return false; try { ElementPtr contactProfileElement = getContactProfileElement(); if (!contactProfileElement) return false; ElementPtr proofElement = contactProfileElement->findFirstChildElementChecked("private")->findFirstChildElementChecked("proof"); String proofAsBase64 = proofElement->getText(true); SecureByteBlock proofHash; convertFromBase64(proofAsBase64, proofHash); SecureByteBlock calculatedProofHash(32); if (calculatedProofHash.size() != proofHash.size()) return false; SHA256 shaProof; shaProof.Update((const BYTE *)"proof:", strlen("proof:")); shaProof.Update((const BYTE *)contactProfileSecret, strlen(contactProfileSecret)); shaProof.Final(calculatedProofHash); if (0 != memcmp(calculatedProofHash, proofHash, proofHash.size())) return false; // this is the secret and it is verified mContactProfileSecret = contactProfileSecret; } catch (zsLib::XML::Exceptions::CheckFailed &) { return false; } return true; }
PeerToPeerPeerIdentifyRequestPtr PeerToPeerPeerIdentifyRequest::create(ElementPtr root) { PeerToPeerPeerIdentifyRequestPtr ret(new message::PeerToPeerPeerIdentifyRequest); if (root) { try { ElementPtr el; ElementPtr proofEl = root->findFirstChildElementChecked("proofBundle")->findFirstChildElementChecked("proof"); ret->mID = IMessageHelper::getAttributeID(root); ret->mProofID = IMessageHelper::getAttributeID(proofEl); ret->mLocationID = IMessageHelper::getAttributeID(proofEl->findFirstChildElement("location")); ret->mFindSecret = IMessageHelper::getElementText(proofEl->findFirstChildElement("findSecret")); ret->mOneTimeKey = IMessageHelper::getAttributeID(proofEl->findFirstChildElement("oneTimeKey")); ret->mExpires = IMessageHelper::stringToTime(IMessageHelper::getElementText(proofEl->findFirstChildElement("expires"))); ret->mUserAgent = IMessageHelper::getElementTextAndEntityDecode(proofEl->findFirstChildElement("userAgent")); ret->mPeerFilePublic = IPeerFilePublic::loadFromXML(proofEl->findFirstChildElement("peer")); } catch (Exceptions::CheckFailed &e) {} } return ret; }
//--------------------------------------------------------------------- void PeerContactProfile::internalTemporaryGetContactProfileSecret() { if (!mDocument) return; try { ElementPtr contactProfileElement = getContactProfileElement(); if (!contactProfileElement) return; ElementPtr privateElement = contactProfileElement->findFirstChildElementChecked("private"); ElementPtr contactProfileSecretElement = privateElement->findFirstChildElementChecked("contactProfileSecret"); String cotactProfileSecret = contactProfileSecretElement->getText(); if (cotactProfileSecret.isEmpty()) return; mContactProfileSecret = cotactProfileSecret; } catch (zsLib::XML::Exceptions::CheckFailed &) { } }
//--------------------------------------------------------------------- IPeerFilePublicPtr PeerContactProfile::getPeerFilePublic() const { AutoRecursiveLock lock(mLock); PeerFilesPtr outer = mPeerFiles.lock(); if (outer) { IPeerFilePublicPtr publicPeer = outer->getPublic(); if (publicPeer) return publicPeer; } if (!mDocument) return IPeerFilePublicPtr(); if (!hasContactProfileSecret()) return IPeerFilePublicPtr(); try { ElementPtr contactProfileElement = getContactProfileElement(); if (!contactProfileElement) return IPeerFilePublicPtr(); ElementPtr privateElement = contactProfileElement->findFirstChildElementChecked("private"); ElementPtr encryptedPeerElement = privateElement->findFirstChildElementChecked("encryptedPeer"); ElementPtr saltElement = privateElement->findFirstChildElementChecked("salt"); String saltAsBase64 = saltElement->getText(true); SecureByteBlock output; decryptAndNulTerminateFromBase64( "peer", mContactProfileSecret, saltAsBase64, encryptedPeerElement->getText(true), output ); String parseData = (CSTR)((const BYTE *)output); DocumentPtr temp = Document::create(); temp->parse(parseData); ElementPtr result = temp->findFirstChildElementChecked("peer"); result->orphan(); PeerFilePublicPtr publicPeer = PeerFilePublic::loadFromXML(result); return publicPeer; } catch (zsLib::XML::Exceptions::CheckFailed &) { } return IPeerFilePublicPtr(); }
//--------------------------------------------------------------------- bool PeerContactProfile::setPublicProfile(ElementPtr newProfileElement) { AutoRecursiveLock lock(mLock); if (!mDocument) return false; PeerFilesPtr outer = mPeerFiles.lock(); if (!outer) return false; IPeerFilePrivatePtr privatePeer = outer->getPrivate(); if (!privatePeer) return false; try { ElementPtr contactProfileElement = getContactProfileElement(); if (!contactProfileElement) return false; ElementPtr publicElement = contactProfileElement->findFirstChildElement("public"); ElementPtr profileElement; if (publicElement) profileElement = publicElement->findFirstChildElementChecked("profile"); if (!newProfileElement) { // erasing the profile element to clean newProfileElement = Element::create(); newProfileElement->setValue("profile"); } if (profileElement) { profileElement->adoptAsNextSibling(newProfileElement); profileElement->orphan(); } else { if (!publicElement) { publicElement = Element::create(); publicElement->setValue("public"); contactProfileElement->adoptAsFirstChild(publicElement); } publicElement->adoptAsLastChild(newProfileElement); } // upgrade the document version number UINT version = getVersionNumber(); ++version; contactProfileElement->setAttribute("version", Stringize<UINT>(version).string()); if (!isExternal()) { // now this this must be signed privatePeer->signElement(contactProfileElement); } } catch (zsLib::XML::Exceptions::CheckFailed &) { return false; } return true; }
//--------------------------------------------------------------------- ElementPtr PeerContactProfile::getPublicProfile() const { AutoRecursiveLock lock(mLock); if (!mDocument) return ElementPtr(); try { ElementPtr contactProfileElement = getContactProfileElement(); if (!contactProfileElement) return ElementPtr(); ElementPtr profileElement = contactProfileElement->findFirstChildElementChecked("public")->findFirstChildElementChecked("profile"); return (profileElement->clone())->toElementChecked(); } catch (zsLib::XML::Exceptions::CheckFailed &) { } return ElementPtr(); }
//--------------------------------------------------------------------- bool PeerContactProfile::setPrivateProfile(ElementPtr newProfileElement) { AutoRecursiveLock lock(mLock); if (!mDocument) return false; PeerFilesPtr outer; IPeerFilePrivatePtr privatePeer; if (!isExternal()) { outer = mPeerFiles.lock(); if (!outer) return false; privatePeer = outer->getPrivate(); if (!privatePeer) return false; } try { ElementPtr contactProfileElement = getContactProfileElement(); if (!contactProfileElement) return false; ElementPtr privateElement = contactProfileElement->findFirstChildElementChecked("private"); ElementPtr encryptedProfileElement = privateElement->findFirstChildElement("encryptedProfile"); ElementPtr saltElement = privateElement->findFirstChildElementChecked("salt"); String saltAsBase64 = saltElement->getText(true); if (!newProfileElement) { // erasing the profile element to clean newProfileElement = Element::create(); newProfileElement->setValue("profile"); } DocumentPtr tempDoc = Document::create(); tempDoc->adoptAsLastChild(newProfileElement->clone()); // write out the new value boost::shared_array<char> output = tempDoc->write(); // encrypt it String encryptedProfileAsBase64 = encryptToBase64( "profile", mContactProfileSecret.c_str(), saltAsBase64, (const BYTE *)(output.get()), strlen(output.get()) ); ElementPtr tempNewEncryptedProfileElement = Element::create(); tempNewEncryptedProfileElement->setValue("encryptedProfile"); TextPtr encryptedProfileText = Text::create(); encryptedProfileText->setValue(encryptedProfileAsBase64); tempNewEncryptedProfileElement->adoptAsLastChild(encryptedProfileText); if (encryptedProfileElement) { encryptedProfileElement->adoptAsNextSibling(tempNewEncryptedProfileElement); encryptedProfileElement->orphan(); } else { privateElement->adoptAsLastChild(tempNewEncryptedProfileElement); } // upgrade the document version number UINT version = getVersionNumber(); ++version; contactProfileElement->setAttribute("version", Stringize<UINT>(version).string()); if (!isExternal()) { // now this this must be signed privatePeer->signElement(contactProfileElement); } } catch (zsLib::XML::Exceptions::CheckFailed &) { return false; } return true; }