⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zdmwrite.c

📁 IBE是一种非对称密码技术
💻 C
📖 第 1 页 / 共 4 页
字号:
   VtStorageCtx storageCtx,
   VtTransportCtx transportCtx,
   VoltZDRLocationList *locationList,
   char **address,
   unsigned int *addressLen
   )
{
  int status, status2;
  unsigned int index, maxIndex, recipCount, voteCount, sameIdentity;
  UInt32 lenLo, lenHi;
  VoltPolicyCtx *pCtx = (VoltPolicyCtx *)policyCtx;
  VtIdentityObject getId;
  VtItem *getDefLocation = (VtItem *)0;
  VtItem *getDefDomain = (VtItem *)0;
  unsigned char* defaultDomain = (unsigned char*)0;
  VtDistrictObject defaultZDMDistrict = (VtDistrictObject)0;
  VtItem *votedLocation;
  VtItem *location;
  int isSenderLocation;
  unsigned int count;
  unsigned int theTag, lengthLen, valueLen;
  int isSenderRecipient = 0;
  VtItem senderLocation;
  unsigned int recipientCount;
  VtMpIntCtx mpIntCtx = (VtMpIntCtx)0;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)
  
  /* Logic.
   *   1. Does at least one of the recipients use a ZDR location?
   *     yes, move on to step 2.
   *     no, move on to step 6.
   *
   *   2. At least one of the recipients has a ZDR location. Do all
   *   recipients use the same ZDR location?
   *     yes, return that location.
   *     no, move on to step 3.
   *
   *   3. At least one of the recipients has a ZDR location, but not
   *   all share the same location. Do some recipients have no ZDR
   *   location, but all others specify the same location?
   *     yes, use the ZDR location the recipients share.
   *     no, move on to step 4.
   *
   *   4. There are multiple ZDR locations among the recipients. Is
   *   there a default location in the (sender's) policy?
   *     yes, use the default location.
   *     no, move on to step 5.
   *
   *   5. There are multiple ZDR locations among the recipients and no
   *   default location in the policy. Take a "vote". Does one location
   *   appear among the recipients more than any other location?
   *     yes, return that location.
   *     no, return the first location recorded.
   *
   *   6. There are no ZDR locations among the recipients. Is there a
   *   default location in the (sender's) policy?
   *     yes, return that location
   *     no, move on to step 7.
   *
   *   7. There are no ZDR locations among the recipients and there is
   *   no default location in the policy. Does the sender have a ZDR
   *   location?
   *     yes, return that location.
   *     no, return an error, we cannot build a ZDM message.
   */

  do
  {
    Z2Memset(&senderLocation, 0, sizeof(senderLocation));
    
    /* Get the ZDR location of each recipient.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtGetIdentityListCount (
      writeCtx->recipListRef, &recipCount, &maxIndex);
    if (status != 0)
      break;

    for (index = 0; index <= maxIndex; ++index)
    {
      /* To get a ZDR location, get an identity, get the district from
       * that identity, get the district extensions from that district,
       * and get the ZDR location extension from the extension list.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtGetIdentityListIdentity (
        writeCtx->recipListRef, index, &getId);
      if (status == VT_ERROR_NO_ID_AT_INDEX)
        continue;
      if (status != 0)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      status = GetZDRLocationFromIdentity (
        libCtx, getId, policyCtx, storageCtx, transportCtx, &location);
      if (status != 0)
        break;

      /* Is this the sender? If so, set a flag so we know that the
       * sender is also a recipient.
       */
      VoltIsSameIdentity (getId, writeCtx->senderIdRef, &sameIdentity);
      if (sameIdentity != 0)
      {
        isSenderRecipient = 1;
        if (location != (VtItem*)0)
        {
          VOLT_SET_FNCT_LINE (fnctLine)
          status = VoltDecodeTagAndLen (
            libCtx, location->data, location->len, &theTag, &lengthLen,
            &lenLo, &lenHi, sizeof (unsigned int));
          if (status != 0)
            break;

          valueLen = (unsigned int)lenLo;
          
          VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
          VOLT_SET_FNCT_LINE (fnctLine)
          status = VT_ERROR_MEMORY;
          senderLocation.data = (unsigned char *)Z2Malloc (valueLen, 0);
          if (senderLocation.data == (unsigned char *)0)
            break;
          
          Z2Memcpy (senderLocation.data, location->data + lengthLen + 1, valueLen);
          senderLocation.len = valueLen;
        }
      }
      
      if (location != (VtItem *)0)
      {
        VOLT_SET_ERROR_TYPE (errorType, 0)
        VOLT_SET_FNCT_LINE (fnctLine)
        status = AddToLocationList (
          libCtx, getId, location, locationList);
        if (status != 0)
          break;
      }
    }
    if (status != 0)
      break;

    /* If none of the recipients' districts support ZDM, then we
     * shouldn't send a ZDM, since none of them will be able to read it.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_NO_ZDM_LOCATION;
    if (locationList->count == 0)
      break;

    /* If all of the recipients use the same location, then we use that
     * as the ZDM location. We need this to handle the case where all
     * the recipients and the sender have the same location. There's
     * another test below after voting that catches the case where
     * all the recipients (not including the sender) have the same
     * location.
     */
    if (locationList->count == locationList->locationCount[0])
    {
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = CopyZDRLocation (
        libCtx, &locationList->location[0], address, addressLen);
      break;
    }
    
    /* If the sender is also a recipient, we have the sender's ZDR
     * location already. If not, get it now. If there is one, the
     * sender will be included in the Form's Select list.
     */
    if (isSenderRecipient == 0)
    {
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = GetSenderZDRLocationAlloc (
        libCtx, obj, writeCtx, policyCtx, storageCtx, transportCtx,
        &senderLocation);
      if (status != 0)
        break;
    }

    /* Figure out which location is used by the majority of the
     * recipients. We'll use the final vote count to determine
     * if all of the recipients (not including the sender) use
     * the same district. If that's the case we'll use that
     * district (i.e. case 2 in the logic described above).
     * Otherwise we'll continue on to check the default ZDM
     * location. If there's no default location, then we'll
     * use the majority location determined here.
     */
    votedLocation = (VtItem*)0;
    voteCount = 0;
    
    for (index = 0; index < locationList->count; ++index)
    {
      location = &locationList->location[index];
      count = locationList->locationCount[index];
      isSenderLocation = (location->len == senderLocation.len) &&
        (Z2Memcmp(location->data, senderLocation.data, location->len) == 0);
      if (!isSenderLocation && (count > voteCount))
      {
        votedLocation = location;
        voteCount = count;
      }
    }
    
    /* Figure out how many recipients we have (not including the sender)
     */
    recipientCount = locationList->count;
    if (isSenderRecipient)
      recipientCount--;
    
    /* If all the recipients (not including the sender) are using the
     * same district, then use it.
     */
    if ((voteCount > 0) && (voteCount == recipientCount))
    {
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = CopyZDRLocation (
        libCtx, votedLocation, address, addressLen);
      break;
    }
    
    /* We don't have a location yet, get the default location from the
     * policy. The value that's stored in client policy is the domain
     * name of the district whose location we want to use, so we need
     * to translate from the domain name to the district to the ZDM
     * location.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = pCtx->PolicyGetInfoAlloc (
      policyCtx, VOLT_POLICY_GET_DEFAULT_ZDR_LOCATION,
      (Pointer)0, (Pointer *)&getDefDomain);
    if ( (status != 0) && (status != VT_ERROR_POLICY_NOT_SUPPORTED) )
      break;

    if ( (getDefDomain != (VtItem *)0) && (getDefDomain->len > 0) )
    {
      /* Copy the VtItem domain name over to null-terminated string */
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_MEMORY;
      defaultDomain = Z3Malloc(getDefDomain->len + 1);
      if (defaultDomain == (unsigned char*)0)
        break;
      Z2Memcpy(defaultDomain, getDefDomain->data, getDefDomain->len);
      defaultDomain[getDefDomain->len] = 0;
      
      /* If there's a problem retrieving the default ZDM location,
       * we convert the error to the INVALID_ZDM_LOCATION error.
       */
      status = VT_ERROR_INVALID_ZDM_LOCATION;

      if (writeCtx->senderIdRef != (VtIdentityObject)0)
        mpIntCtx = writeCtx->senderIdRef->mpCtx;
      
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status2 = VtCreateDistrictObject (
        libCtx,
        (mpIntCtx != 0) ? VtDistrictImplMpCtx : VtDistrictImplBasic,
        (Pointer)mpIntCtx, &defaultZDMDistrict);
      if (status2 != 0)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      status2 = VtSetDistrictParam (
        defaultZDMDistrict, VtDistrictParamDomainName,
        (Pointer) defaultDomain);
      if (status2 != 0)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      status2 = VtObtainIBEParams(defaultZDMDistrict, policyCtx,
        storageCtx, transportCtx);
      if (status2 != 0)
        break;
      
      VOLT_SET_FNCT_LINE (fnctLine)
      status2 = GetZDRLocationFromDistrict(libCtx, defaultZDMDistrict,
        &getDefLocation);
      if (status2 != 0)
        break;

      if (getDefLocation != (VtItem*)0)
      {
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VoltDecodeTagAndLen (
          libCtx, getDefLocation->data, getDefLocation->len, &theTag, &lengthLen,
          &lenLo, &lenHi, sizeof (unsigned int));
        if (status != 0)
          break;

        valueLen = (unsigned int)lenLo;
          
        VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VT_ERROR_MEMORY;
        *address = (char *)Z2Malloc (valueLen, 0);
        if (*address == (char *)0)
          break;
        Z2Memcpy (*address, getDefLocation->data + lengthLen + 1, valueLen);
        *addressLen = valueLen;
      }
      
      break;
    }

    if (votedLocation != (VtItem*)0)
    {
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = CopyZDRLocation (libCtx, votedLocation, address, addressLen);
      break;
    }

    /* Use the sender's location as the final try. If the sender's district
     * doesn't have ZDM enabled, then we return an error.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_NO_ZDM_LOCATION;
    if (senderLocation.data == (unsigned char *)0)
      break;

    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = CopyZDRLocation (
      libCtx, &senderLocation, address, addressLen);

  } while (0);

  Z2Free (senderLocation.data);
  if (getDefDomain != (VtItem *)0)
    pCtx->PolicyGetInfoFree (policyCtx, (Pointer)getDefDomain);
  Z2Free (defaultDomain);
  VtDestroyDistrictObject(&defaultZDMDistrict);

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, libCtx, obj, status, 0, errorType,
    (char *)0, "GetFormAddressAlloc", fnctLine, (char *)0)

  return (status);
}

static int CopyZDRLocation (
   VoltLibCtx *libCtx,
   VtItem *location,
   char **address,
   unsigned int *addressLen
   )
{
  char *newVal = (char *)0;
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  VOLT_SET_FNCT_LINE (fnctLine)
  newVal = (char *)Z2Malloc (location->len, 0);
  if (newVal != (char *)0)
  {
    Z2Memcpy (newVal, location->data, location->len);

    *address = newVal;
    *addressLen = location->len;

    return (0);
  }

  VOLT_LOG_ERROR_INFO (
    libCtx, 0, VT_ERROR_MEMORY, 0, VT_ERROR_TYPE_PRIMARY,
    (char *)0, "CopyZDRLocation", fnctLine, (char *)0)

  return (VT_ERROR_MEMORY);
}

static int AddToLocationList (
   VoltLibCtx *libCtx,
   VtIdentityObject idToAdd,
   VtItem *location,
   VoltZDRLocationList *locationList
   )
{
  int status;
  unsigned int index, theTag, lengthLen, valueLen;
  UInt32 lenLo, lenHi;
  unsigned char *value;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* Add the id to the list of selections.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    locationList->recipientSelections = (VtIdentityObject *)Z2Realloc (
      locationList->recipientSelections,
      (locationList->count + 1) * sizeof (VtIdentityObject));
    if (locationList->recipientSelections == (VtIdentityObject *)0)
      break;

    locationList->recipientSelections[locationList->count] = idToAdd;

    /* The location returned is TLV of some encoding.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VoltDecodeTagAndLen (
      libCtx, location->data, location->len, &theTag, &lengthLen,
      &lenLo, &lenHi, sizeof (unsigned int));
    if (status != 0)
      break;

    valueLen = (unsigned int)lenLo;
    value = location->data + (lengthLen + 1);

    /* First, is this a location already logged?
     */
    for (index = 0; index < locationList->count; ++index)
    {
      if (valueLen != locationList->location[index].len)
        continue;
      if (Z2Memcmp (
        value, locationList->location[index].data, valueLen) == 0)
        break;
    }
    /* If we broke out before the end, we found a match.
     */
    if (index < locationList->count)
    {
      /* Increment the count of this location.
       */
      locationList->locationCount[index] =
        locationList->locationCount[index] + 1;
    }

    /* Add this location to the list.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    locationList->location = (VtItem *)Z2Realloc (
      locationList->location, (locationList->count + 1) * sizeof (VtItem));
    if (locationList->location == (VtItem *)0)
      break;
    locationList->location[locationList->count].data = value;
    locationList->location[locationList->count].len = valueLen;

    VOLT_SET_FNCT_LINE (fnctLine)
    locationList->locationCount = (unsigned int *)Z2Realloc (
      locationList->locationCount,
      (locationList->count + 1) * sizeof (unsigned int));
    if (locationList->locationCount == (unsigned int *)0)
      break;
    locationList->locationCount[locationList->count] = 1;

    locationList->count = locationList->count + 1;

    status = 0;

  } while (0);

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, libCtx, 0, status, 0, errorType,
    (char *)0, "AddToLocationList", fnctLine, (char *)0)

  return (status);
}

static int GetSenderZDRLocationAlloc (
   VoltLibCtx *libCtx,
   VoltSecureMailObject *obj,
   VoltSecureMailWriteCtx *writeCtx,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -