//---------------------------------------------------------------------
        DocumentPtr IdentityLookupRequest::encode()
        {
          DocumentPtr ret = IMessageHelper::createDocumentWithRoot(*this);
          ElementPtr root = ret->getFirstChildElement();

          ElementPtr providersEl = Element::create("providers");

          for (ProviderList::iterator iter = mProviders.begin(); iter != mProviders.end(); ++iter)
          {
            Provider &info = (*iter);
            ElementPtr providerEl = Element::create("provider");

            if (!info.mBase.isEmpty()) {
              providerEl->adoptAsLastChild(IMessageHelper::createElementWithTextAndJSONEncode("base", info.mBase));
            }
            if (!info.mSeparator.isEmpty()) {
              providerEl->adoptAsLastChild(IMessageHelper::createElementWithTextAndJSONEncode("separator", info.mSeparator));
            }
            if (!info.mIdentities.isEmpty()) {
              providerEl->adoptAsLastChild(IMessageHelper::createElementWithTextAndJSONEncode("identities", info.mIdentities));
            }
            if (providerEl) {
              providersEl->adoptAsLastChild(providerEl);
            }
          }

          if (providersEl->hasChildren()) {
            root->adoptAsLastChild(providersEl);
          }

          return ret;
        }
        //---------------------------------------------------------------------
        DocumentPtr IdentityAccessRolodexCredentialsGetRequest::encode()
        {
          DocumentPtr ret = IMessageHelper::createDocumentWithRoot(*this);
          ElementPtr root = ret->getFirstChildElement();

          String clientNonce = IHelper::randomString(32);

          IdentityInfo identityInfo;

          identityInfo.mURI = mIdentityInfo.mURI;
          identityInfo.mProvider = mIdentityInfo.mProvider;

          identityInfo.mAccessToken = mIdentityInfo.mAccessToken;
          if (mIdentityInfo.mAccessSecret.hasData()) {
            identityInfo.mAccessSecretProofExpires = zsLib::now() + Seconds(OPENPEER_STACK_MESSAGE_IDENTITY_ACCESS_LOCKBOX_UPDATE_EXPIRES_TIME_IN_SECONDS);
            identityInfo.mAccessSecretProof = IHelper::convertToHex(*IHelper::hmac(*IHelper::hmacKeyFromPassphrase(mIdentityInfo.mAccessSecret), "identity-access-validate:" + identityInfo.mURI + ":" + clientNonce + ":" + IHelper::timeToString(identityInfo.mAccessSecretProofExpires) + ":" + identityInfo.mAccessToken + ":rolodex-credentials-get"));
          }

          root->adoptAsLastChild(IMessageHelper::createElementWithText("nonce", clientNonce));
          if (identityInfo.hasData()) {
            root->adoptAsLastChild(MessageHelper::createElement(identityInfo));
          }

          return ret;
        }
        //---------------------------------------------------------------------
        DocumentPtr LockboxContentGetRequest::encode()
        {
          DocumentPtr ret = IMessageHelper::createDocumentWithRoot(*this);
          ElementPtr root = ret->getFirstChildElement();

          String clientNonce = IHelper::randomString(32);

          LockboxInfo lockboxInfo;

          lockboxInfo.mAccessToken = mLockboxInfo.mAccessToken;
          if (mLockboxInfo.mAccessSecret.hasData()) {
            lockboxInfo.mAccessSecretProofExpires = zsLib::now() + Seconds(OPENPEER_STACK_MESSAGE_LOCKBOX_CONTENT_GET_REQUEST_EXPIRES_TIME_IN_SECONDS);
            lockboxInfo.mAccessSecretProof = IHelper::convertToHex(*IHelper::hmac(*IHelper::hmacKeyFromPassphrase(mLockboxInfo.mAccessSecret), "lockbox-access-validate:" + clientNonce + ":" + IHelper::timeToString(lockboxInfo.mAccessSecretProofExpires) + ":" + lockboxInfo.mAccessToken + ":lockbox-content-get"));
          }

          root->adoptAsLastChild(IMessageHelper::createElementWithText("nonce", clientNonce));
          if (lockboxInfo.hasData()) {
            root->adoptAsLastChild(MessageHelper::createElement(lockboxInfo));
          }

          ElementPtr namespacesEl = IMessageHelper::createElement("namespaces");

          for (NamespaceInfoMap::iterator iter = mNamespaceInfos.begin(); iter != mNamespaceInfos.end(); ++iter)
          {
            const NamespaceInfo &namespaceInfo = (*iter).second;
            namespacesEl->adoptAsLastChild(MessageHelper::createElement(namespaceInfo));
          }

          if (namespacesEl->hasChildren()) {
            root->adoptAsLastChild(namespacesEl);
          }

          return ret;
        }
        DocumentPtr PeerToFinderPeerLocationFindRequest::encode(message::PeerToFinderPeerLocationFindRequest &msg)
        {
          DocumentPtr ret = IMessageHelper::createDocumentWithRoot(msg);
          ElementPtr root = ret->getFirstChildElement();
          ElementPtr loc, candidates, locations, exclude, routes;

          if (msg.hasAttribute(message::PeerToFinderPeerLocationFindRequest::AttributeType_RemoteContactID))
          {
            root->adoptAsLastChild(IMessageHelper::createElementWithID("contact", msg.mRemoteContactID));
          }

          if (msg.hasAttribute(message::PeerToFinderPeerLocationFindRequest::AttributeType_ExcludedLocations))
          {
            exclude = IMessageHelper::createElement("exclude");
            locations = IMessageHelper::createElement("locations");
            exclude->adoptAsLastChild(locations);
            root->adoptAsLastChild(exclude);

            message::PeerToFinderPeerLocationFindRequest::ExcludedLocationList::const_iterator it;
            for(it = msg.mExcludedLocations.begin(); it != msg.mExcludedLocations.end(); ++it)
            {
              String location(*it);
              locations->adoptAsLastChild(IMessageHelper::createElementWithID("location", location));
            }
          }

          if (msg.hasAttribute(message::PeerToFinderPeerLocationFindRequest::AttributeType_Location))
          {
            loc = MessageHelper::createElement(msg.mLocation);
            root->adoptAsLastChild(loc);

            if (msg.hasAttribute(message::PeerToFinderPeerLocationFindRequest::AttributeType_LocalContactID))
            {
              loc->adoptAsLastChild(IMessageHelper::createElementWithID("contact", msg.mLocalContactID));
            }
          }

          if (msg.hasAttribute(message::PeerToFinderPeerLocationFindRequest::AttributeType_Routes))
          {
            routes = IMessageHelper::createElement("routes");
            root->adoptAsLastChild(routes);

            RouteList::const_iterator it;
            for(it = msg.mRoutes.begin(); it != msg.mRoutes.end(); ++it)
            {
              String route(*it);
              routes->adoptAsLastChild(IMessageHelper::createElementWithID("route", route));
            }
          }

          return ret;
        }
        //---------------------------------------------------------------------
        DocumentPtr RolodexAccessRequest::encode()
        {
          DocumentPtr ret = IMessageHelper::createDocumentWithRoot(*this);
          ElementPtr rootEl = ret->getFirstChildElement();

          String clientNonce = IHelper::randomString(32);
          IdentityInfo identityInfo;

          identityInfo.mURI = mIdentityInfo.mURI;
          identityInfo.mProvider = mIdentityInfo.mProvider;

          identityInfo.mAccessToken = mIdentityInfo.mAccessToken;
          if (mIdentityInfo.mAccessSecret.hasData()) {
            identityInfo.mAccessSecretProofExpires = zsLib::now() + Seconds(OPENPEER_STACK_MESSAGE_ROLODEX_ACCESS_REQUEST_EXPIRES_TIME_IN_SECONDS);
            identityInfo.mAccessSecretProof = IHelper::convertToHex(*IHelper::hmac(*IHelper::hmacKeyFromPassphrase(mIdentityInfo.mAccessSecret), "identity-access-validate:" + identityInfo.mURI + ":" + clientNonce + ":" + IHelper::timeToString(identityInfo.mAccessSecretProofExpires) + ":" + identityInfo.mAccessToken + ":lockbox-access"));
          }

          rootEl->adoptAsLastChild(IMessageHelper::createElementWithText("nonce", clientNonce));
          if (identityInfo.hasData()) {
            rootEl->adoptAsLastChild(MessageHelper::createElement(identityInfo));
          }

          RolodexInfo rolodexInfo;
          rolodexInfo.mServerToken = mRolodexInfo.mServerToken;
          rolodexInfo.mVersion = mRolodexInfo.mVersion;
          rolodexInfo.mRefreshFlag = mRolodexInfo.mRefreshFlag;

          if (rolodexInfo.hasData()) {
            rootEl->adoptAsLastChild(MessageHelper::createElement(rolodexInfo));
          }

          AgentInfo agentInfo;
          agentInfo = UseStack::agentInfo();
          agentInfo.mergeFrom(mAgentInfo, true);

          if (mAgentInfo.hasData()) {
            rootEl->adoptAsLastChild(MessageHelper::createElement(agentInfo));
          }

          if (mGrantID.hasData()) {
            rootEl->adoptAsLastChild(IMessageHelper::createElementWithID("grant", mGrantID));
          }

          return ret;
        }
예제 #6
0
        //---------------------------------------------------------------------
        DocumentPtr FindersGetRequest::encode()
        {
          DocumentPtr ret = IMessageHelper::createDocumentWithRoot(*this);
          ElementPtr root = ret->getFirstChildElement();

          if (hasAttribute(AttributeType_TotalServers)) {
            root->adoptAsLastChild(IMessageHelper::createElementWithNumber("servers", string(mTotalFinders)));
          }
          return ret;
        }
        //---------------------------------------------------------------------
        DocumentPtr SessionDeleteRequest::encode()
        {
          DocumentPtr ret = IMessageHelper::createDocumentWithRoot(*this);
          ElementPtr root = ret->getFirstChildElement();

          if (hasAttribute(AttributeType_Locations))
          {
            ElementPtr locationsEl = IMessageHelper::createElement("locations");
            root->adoptAsLastChild(locationsEl);

            for(StringList::const_iterator it = mLocations.begin(); it != mLocations.end(); ++it)
            {
              const String &loc = (*it);
              locationsEl->adoptAsLastChild(IMessageHelper::createElementWithID("location", loc));
            }
          }

          return ret;
        }
예제 #8
0
        //---------------------------------------------------------------------
        DocumentPtr SignedSaltGetRequest::encode()
        {
          DocumentPtr ret = IMessageHelper::createDocumentWithRoot(*this);
          ElementPtr root = ret->getFirstChildElement();

          if (hasAttribute(AttributeType_Salts)) {
            root->adoptAsLastChild(IMessageHelper::createElementWithNumber("salts", string(mSalts)));
          }

          return ret;
        }
예제 #9
0
      //-----------------------------------------------------------------------
      DocumentPtr MessageResult::encode(IPeerFilesPtr peerFile)
      {
        DocumentPtr ret = IMessageHelper::createDocumentWithRoot(*this);
        ElementPtr root = ret->getFirstChildElement();

        // <error>
        // <reason id=”301”>Moved Permanently</reason>
        // </error>

        ElementPtr reason = IMessageHelper::createElementWithText("reason", mErrorReason);
        if (0 != mErrorCode) {
          IMessageHelper::setAttributeID(reason, Stringize<WORD>(mErrorCode).string());
        }

        ElementPtr error = IMessageHelper::createElement("error");
        error->adoptAsLastChild(reason);

        root->adoptAsLastChild(error);
        return ret;
      }
예제 #10
0
      //---------------------------------------------------------------------
      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;
      }
        DocumentPtr MultiPartyAPNSPushRequest::encode(message::MultiPartyAPNSPushRequest &msg)
        {
          DocumentPtr ret = IMessageHelper::createDocumentWithRoot(msg);
          ElementPtr root = ret->getFirstChildElement();

          if (msg.hasAttribute(message::MultiPartyAPNSPushRequest::AttributeType_UserID)) {
            root->adoptAsLastChild(IMessageHelper::createElementWithText("userID", msg.mUserID));
          }

          if (msg.hasAttribute(message::MultiPartyAPNSPushRequest::AttributeType_AccessKey)) {
            root->adoptAsLastChild(IMessageHelper::createElementWithText("accessKey", msg.mAccessKey));
          }

          if (msg.hasAttribute(message::MultiPartyAPNSPushRequest::AttributeType_AccessSecret)) {
            root->adoptAsLastChild(IMessageHelper::createElementWithText("accessSecret", msg.mAccessSecret));
          }

          if (msg.hasAttribute(message::MultiPartyAPNSPushRequest::AttributeType_LocationID)) {
            root->adoptAsLastChild(IMessageHelper::createElementWithText("locationID", msg.mLocationID));
          }

          if (msg.hasAttribute(message::MultiPartyAPNSPushRequest::AttributeType_MessageType)) {
            root->adoptAsLastChild(IMessageHelper::createElementWithText("messageType", msg.mMessageType));
          }

          if (msg.hasAttribute(message::MultiPartyAPNSPushRequest::AttributeType_MessageData)) {
            root->adoptAsLastChild(IMessageHelper::createElementWithText("messageData", msg.mMessageData));
          }

          if (msg.hasAttribute(message::MultiPartyAPNSPushRequest::AttributeType_UserIDs)) {
            String usersStr;

            typedef provisioning::IAccount::UserIDList UserIDList;
            for (UserIDList::iterator iter = msg.mUserIDs.begin(); iter != msg.mUserIDs.end(); ++iter)
            {
              const String &userID = (*iter);

              if (!userID.isEmpty()) {
                if (!usersStr.isEmpty()) {
                  usersStr += "," + userID;
                } else {
                  usersStr += userID;
                }
              }
            }

            if (!usersStr.isEmpty()) {
              root->adoptAsLastChild(IMessageHelper::createElementWithText("users", usersStr));
            }
          }

          return ret;
        }
        DocumentPtr ProviderLoginURLGetRequest::encode(message::ProviderLoginURLGetRequest &msg)
        {
          DocumentPtr ret = IMessageHelper::createDocumentWithRoot(msg);
          ElementPtr root = ret->getFirstChildElement();

          if (msg.hasAttribute(message::ProviderLoginURLGetRequest::AttributeType_ProviderType)) {
            root->adoptAsLastChild(IMessageHelper::createElementWithText("providerType", provisioning::IAccount::toCodeString(msg.mProviderType)));
          }

          if (msg.hasAttribute(message::ProviderLoginURLGetRequest::AttributeType_DeviceUUID)) {
            root->adoptAsLastChild(IMessageHelper::createElementWithText("deviceUUID", msg.mDeviceUUID));
          }

          if (msg.hasAttribute(message::ProviderLoginURLGetRequest::AttributeType_DeviceToken)) {
            root->adoptAsLastChild(IMessageHelper::createElementWithText("deviceToken", msg.mDeviceToken));
          }

          if (msg.hasAttribute(message::ProviderLoginURLGetRequest::AttributeType_AccountSalt)) {
            root->adoptAsLastChild(IMessageHelper::createElementWithText("accountSalt", msg.mAccountSalt));
          }

          return ret;
        }
        DocumentPtr ProviderAssociateURLGetRequest::encode(message::ProviderAssociateURLGetRequest &msg)
        {
          DocumentPtr ret = IMessageHelper::createDocumentWithRoot(msg);
          ElementPtr root = ret->getFirstChildElement();

          if (msg.hasAttribute(message::ProviderAssociateURLGetRequest::AttributeType_ProviderType)) {
            root->adoptAsLastChild(IMessageHelper::createElementWithText("providerType", provisioning::IAccount::toCodeString(msg.mProviderType)));
          }

          if (msg.hasAttribute(message::ProviderAssociateURLGetRequest::AttributeType_UserID)) {
            root->adoptAsLastChild(IMessageHelper::createElementWithText("userID", msg.mUserID));
          }

          if (msg.hasAttribute(message::ProviderAssociateURLGetRequest::AttributeType_AccessKey)) {
            root->adoptAsLastChild(IMessageHelper::createElementWithText("accessKey", msg.mAccessKey));
          }

          if (msg.hasAttribute(message::ProviderAssociateURLGetRequest::AttributeType_AccessSecret)) {
            root->adoptAsLastChild(IMessageHelper::createElementWithText("accessSecret", msg.mAccessSecret));
          }

          return ret;
        }
예제 #14
0
      //---------------------------------------------------------------------
      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;
      }
예제 #15
0
      //---------------------------------------------------------------------
      PeerContactProfilePtr PeerContactProfile::createExternalFromPrivateProfile(ElementPtr privateProfileElement)
      {
        if (!privateProfileElement) return PeerContactProfilePtr();

        privateProfileElement = (privateProfileElement->clone())->toElementChecked();

        static const char *contactProfileSkeleton =
        "<contactProfile version=\"0\">\n"
        " <private>\n"
        "  <salt />\n"
        "  <proof cipher=\"sha256/aes256\" />\n"
        "  <encryptedProfile cipher=\"sha256/aes256\" />\n"
        "  <contactProfileSecret cipher=\"sha256/aes256\" />\n"
        " </private>\n"
        "</contactProfile>";

        DocumentPtr contactProfileDoc = Document::create();
        contactProfileDoc->parse(contactProfileSkeleton);

        String contactID = services::IHelper::randomString(32);
        String contactProfileSecret = services::IHelper::randomString(32);

        // generate external profile
        {
          std::string contactSalt;

          // generate salt
          {
            AutoSeededRandomPool rng;

            SecureByteBlock contactSaltRaw(32);
            rng.GenerateBlock(contactSaltRaw, contactSaltRaw.size());
            contactSalt = convertToBase64(contactSaltRaw, contactSaltRaw.size());
          }

          ElementPtr contactProfileElement = contactProfileDoc->getFirstChildElementChecked();
          contactProfileElement->setAttribute("id", contactID);

          ElementPtr privateElement = contactProfileElement->getFirstChildElementChecked();
          ElementPtr saltElement = privateElement->getFirstChildElementChecked();
          TextPtr saltText = Text::create();
          saltText->setValue(contactSalt);
          saltElement->adoptAsLastChild(saltText);

          SecureByteBlock contactProofHash(32);

          SHA256 contactProof;
          contactProof.Update((const BYTE *)"proof:", strlen("proof:"));
          contactProof.Update((const BYTE *)contactProfileSecret.c_str(), contactProfileSecret.size());
          contactProof.Final(contactProofHash);

          String contactProofInBase64 = convertToBase64(contactProofHash, contactProofHash.size());

          ElementPtr proofElement = saltElement->getNextSiblingElementChecked();
          TextPtr proofText = Text::create();
          proofText->setValue(contactProofInBase64);
          proofElement->adoptAsLastChild(proofText);

          DocumentPtr privateProfileDocument = Document::create();
          privateProfileDocument->adoptAsLastChild(privateProfileElement);

          ULONG length = 0;
          boost::shared_array<char> output;
          output = privateProfileDocument->write(&length);

          ElementPtr encryptedProfileElement = proofElement->getNextSiblingElementChecked();
          String encryptedProfileString = encryptToBase64("profile", contactProfileSecret, contactSalt, (const BYTE *)(output.get()), length);
          TextPtr encryptProfileText = Text::create();
          encryptProfileText->setValue(encryptedProfileString);
          encryptedProfileElement->adoptAsLastChild(encryptProfileText);

          ElementPtr contactProfileSecretElement = encryptedProfileElement->getNextSiblingElementChecked();
          TextPtr contactProfileSecretText = Text::create();
          contactProfileSecretText->setValue(contactProfileSecret);
          contactProfileSecretElement->adoptAsLastChild(contactProfileSecretText);
        }

        PeerContactProfilePtr pThis(new PeerContactProfile);
        pThis->mThisWeak = pThis;
        pThis->mDocument = contactProfileDoc;
        pThis->mContactProfileSecret = contactProfileSecret;
        return pThis;
      }
예제 #16
0
        //---------------------------------------------------------------------
        DocumentPtr LockboxIdentitiesUpdateRequest::encode()
        {
          DocumentPtr ret = IMessageHelper::createDocumentWithRoot(*this);
          ElementPtr root = ret->getFirstChildElement();

          String clientNonce = IHelper::randomString(32);

          LockboxInfo lockboxInfo;

          lockboxInfo.mAccessToken = mLockboxInfo.mAccessToken;
          if (mLockboxInfo.mAccessSecret.hasData()) {
            lockboxInfo.mAccessSecretProofExpires = zsLib::now() + Seconds(OPENPEER_STACK_MESSAGE_LOCKBOX_IDENTITIES_UPDATE_REQUEST_EXPIRES_TIME_IN_SECONDS);
            lockboxInfo.mAccessSecretProof = IHelper::convertToHex(*IHelper::hmac(*IHelper::hmacKeyFromPassphrase(mLockboxInfo.mAccessSecret), "lockbox-access-validate:" + clientNonce + ":" + IHelper::timeToString(lockboxInfo.mAccessSecretProofExpires) + ":" + lockboxInfo.mAccessToken + ":lockbox-identities-update"));
          }

          IdentityInfoList identities;

          for (IdentityInfoList::iterator iter = mIdentitiesToUpdate.begin(); iter != mIdentitiesToUpdate.end(); ++iter)
          {
            IdentityInfo &listIdentity = (*iter);

            IdentityInfo identityInfo;
            identityInfo.mURI = listIdentity.mURI;
            identityInfo.mProvider = listIdentity.mProvider;

            identityInfo.mAccessToken = listIdentity.mAccessToken;
            if (listIdentity.mAccessSecret.hasData()) {
              identityInfo.mAccessSecretProofExpires = zsLib::now() + Seconds(OPENPEER_STACK_MESSAGE_LOCKBOX_IDENTITIES_UPDATE_REQUEST_EXPIRES_TIME_IN_SECONDS);
              identityInfo.mAccessSecretProof = IHelper::convertToHex(*IHelper::hmac(*IHelper::hmacKeyFromPassphrase(listIdentity.mAccessSecret), "identity-access-validate:" + identityInfo.mURI + ":" + clientNonce + ":" + IHelper::timeToString(identityInfo.mAccessSecretProofExpires) + ":" + identityInfo.mAccessToken + ":lockbox-access-update"));
            }

            if (identityInfo.hasData()) {
              identityInfo.mDisposition = IdentityInfo::Disposition_Update;
              identities.push_back(identityInfo);
            }
          }

          for (IdentityInfoList::iterator iter = mIdentitiesToRemove.begin(); iter != mIdentitiesToRemove.end(); ++iter)
          {
            IdentityInfo &listIdentity = (*iter);

            IdentityInfo identityInfo;
            identityInfo.mURI = listIdentity.mURI;
            identityInfo.mProvider = listIdentity.mProvider;

            if (identityInfo.hasData()) {
              identityInfo.mDisposition = IdentityInfo::Disposition_Remove;
              identities.push_back(identityInfo);
            }
          }

          root->adoptAsLastChild(IMessageHelper::createElementWithText("nonce", clientNonce));
          if (lockboxInfo.hasData()) {
            root->adoptAsLastChild(MessageHelper::createElement(lockboxInfo));
          }

          ElementPtr identitiesEl = IMessageHelper::createElement("identities");
          for (IdentityInfoList::iterator iter = identities.begin(); iter != identities.end(); ++iter)
          {
            IdentityInfo &listIdentity = (*iter);
            identitiesEl->adoptAsLastChild(MessageHelper::createElement(listIdentity));
          }

          if (identitiesEl->hasChildren()) {
            root->adoptAsLastChild(identitiesEl);
          }

          return ret;
        }