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

📄 readenv.c

📁 IBE是一种非对称密码技术
💻 C
📖 第 1 页 / 共 3 页
字号:
      status = VT_ERROR_CHOOSE_RECIPIENT;
      if (readCtx->chosenRecipient < 0)
      {
        VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
        VOLT_SET_FNCT_LINE (fnctLine)
        if (readCtx->priKeyRef == (VtKeyObject)0)
          break;

        /* We have a private key. Which identity belongs to that
         * private key? We have to go through the recipInfos to find
         * the ID matching the one passed in with the private key.
         */
        VOLT_SET_ERROR_TYPE (errorType, 0)
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VoltFindIdInList (
          libCtx, readCtx->specifiedIdentity, readCtx->recipList, &index);
        if (status != 0)
          break;

        /* Set the chosen recipient.
         */
        readCtx->chosenRecipient = (int)index;
      }

      /* Build the symmetric decryption alg object and the symmetric
       * key. This call will need to decrypt the session key in the
       * RecipientInfo of the chosen recipient.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = DecryptSessionKeyData (libCtx, obj, readCtx);
      if (status != 0)
        break;

      /* We have the session key data, set the state so we'll read
       * encrypted content. Then check to see if there's any message to
       * read.
       */
      obj->state = VOLT_P7_STATE_ENV_READ_ENC_CONTENT;
      if (messageLen == 0)
        break;

    case VOLT_P7_STATE_ENV_READ_ENC_CONTENT:
      /* The first part of encrypted content is the SEQUENCE then an
       * OID. "Cheat" by reading the SEQUENCE as the explicitTag.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VoltGetNextDerElement (
        libCtx, message, messageLen, VOLT_SEQUENCE_TAG, VOLT_OID_TAG, 1,
        derElement, &messageRead);
      if (status != 0)
        break;

      *bytesRead += messageRead;
      if (derElement->complete == 0)
        break;

      /* Is this the Data OID?
       * First, set the buffer containing the OID to hold the Data OID.
       */
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_UNSUPPORTED;
      p7Oid[VoltP7SignDataOidBytesLen - 1] = VOLT_P7_OID_BYTE_DATA;
      if (derElement->valueLen != VoltP7EnvDataOidBytesLen)
        break;
      if (Z2Memcmp (
        p7Oid, derElement->element + 2, VoltP7EnvDataOidBytesLen) != 0)
        break;

      /* Move on to the next element.
       */
      status = 0;
      obj->state = VOLT_P7_STATE_ENV_READ_SYM_ALG_ID;

      message += messageRead;
      messageLen -= messageRead;
      VoltResetDerElement (derElement);
      if (messageLen == 0)
        break;

    case VOLT_P7_STATE_ENV_READ_SYM_ALG_ID:
      /* Read the symmetric algID.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VoltGetNextDerElement (
        libCtx, message, messageLen, 0, VOLT_SEQUENCE_TAG, 1,
        derElement, &messageRead);
      if (status != 0)
        break;

      *bytesRead += messageRead;
      if (derElement->complete == 0)
        break;

      /* Build an algorithm object using the algId in the RecipientInfo.
       */
      algIdInfo.derCoders = readCtx->DerCoders;
      algIdInfo.derCoderCount = readCtx->derCoderCount;
      algIdInfo.berEncoding = derElement->element;
      algIdInfo.maxEncodingLen = derElement->elementLen;
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtCreateAlgorithmObject (
        (VtLibCtx)libCtx, VtAlgorithmImplAlgId, (Pointer)&algIdInfo,
        &(readCtx->decryptor));
      if (status != 0)
        break;

      /* Copy the algId into the object in case we need it later.
       */
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_MEMORY;
      readCtx->symAlgID = (unsigned char *)Z2Realloc (
        readCtx->symAlgID, derElement->elementLen);
      if (readCtx->symAlgID == (unsigned char *)0)
        break;

      Z2Memcpy (
        readCtx->symAlgID, derElement->element, derElement->elementLen);
      readCtx->symAlgIDLen = derElement->elementLen;

      /* Get the KeyParam to use when building a key object. Do this by
       * calling the DerCoder's asking for the algorithm.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      offset = derElement->elementLen - (unsigned int)(derElement->valueLen);
      status = VoltDecodeTagAndLen (
        libCtx, derElement->element + offset, derElement->elementLen - offset,
        &theTag, &lengthLen, &lenLo, &lenHi, sizeof (unsigned int));
      if (status != 0)
        break;

      valueLen = (unsigned int)lenLo;
      coderInfo.info.getAlgData.libCtx = libCtx;
      coderInfo.info.getAlgData.oid =
        derElement->element + offset + lengthLen + 1;
      coderInfo.info.getAlgData.oidLen = valueLen;
      coderInfo.info.getAlgData.algorithm = &algorithm;
      coderInfo.info.getAlgData.SymKeyParam = (VtKeyParam *)0;
      coderInfo.info.getAlgData.DigestImpl = (VtAlgorithmImpl *)0;
      for (index = 0; index < readCtx->derCoderCount; ++index)
      {
        /* Call the DerCoder. If successful, we found what we were
         * looking for.
         */
        status = readCtx->DerCoders[index] (
          &coderInfo, (Pointer)0, VOLT_DER_TYPE_GET_ALG_FLAG);
        if (status == 0)
          break;
      }

      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_UNKNOWN_BER;
      if (index >= readCtx->derCoderCount)
        break;

      /* Build a key object using the decrypted key data.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtCreateKeyObject (
        (VtLibCtx)libCtx, VtKeyImplDefault, (Pointer)0, &symKey);
      if (status != 0)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtSetKeyParam (
        symKey, coderInfo.info.getAlgData.SymKeyParam,
        (Pointer)&(readCtx->symKeyData));
      if (status != 0)
        break;

      /* DecryptInit to start the process.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtDecryptInit (readCtx->decryptor, symKey);
      if (status != 0)
        break;

      /* Move on to the next element.
       */
      obj->state = VOLT_P7_STATE_ENV_READ_ENC_DATA_LEN;

      message += messageRead;
      messageLen -= messageRead;
      VoltResetDerElement (derElement);
      if (messageLen == 0)
        break;

    case VOLT_P7_STATE_ENV_READ_ENC_DATA_LEN:
      /* The length of the encrypted data is specified in the IMPLICIT
       * OCTET STRING.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VoltGetNextDerElement (
        libCtx, message, messageLen, 0, 0x80, 0,
        derElement, &messageRead);
      if (status != 0)
        break;

      *bytesRead += messageRead;
      if (derElement->complete == 0)
        break;

      /* Keep the length so we can count off the data as it is input.
       */
      readCtx->dataLen = derElement->valueLen;

      /* Move on to the next element.
       */
      obj->state = VOLT_P7_STATE_ENV_READ_ENC_DATA;

      message += messageRead;
      messageLen -= messageRead;
      VoltResetDerElement (derElement);
      if (messageLen == 0)
        break;

    case VOLT_P7_STATE_ENV_READ_ENC_DATA:
      /* If the length of the message is > the length of the
       * currentLen, ignore the "extra" stuff.
       */
#if VT_64_BIT_LENGTH == 64
      valueLen = 0xffffffff;
      if (readCtx->dataLen < (VtUInt64)0xffffffff)
        valueLen = (unsigned int)(readCtx->dataLen);
#else
      valueLen = readCtx->dataLen;
#endif
      if (messageLen <= valueLen)
        valueLen = messageLen;

      /* If we won't process all the data, call EncryptUpdate. Return
       * all errors, even if BUFFER_TOO_SMALL.
       * If this is the last chunk of data, call DecryptFinal.
       */
#if VT_64_BIT_LENGTH == 64
      if ((readCtx->dataLen - (VtUInt64)valueLen) != 0)
#else
      if ((readCtx->dataLen - valueLen) != 0)
#endif
      {
        VOLT_SET_ERROR_TYPE (errorType, 0)
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VtDecryptUpdate (
          readCtx->decryptor, (VtRandomObject)0, message, valueLen,
          outputData, bufferSize, outputDataLen);
        if (status != 0)
          break;
      }
      else
      {
        VOLT_SET_ERROR_TYPE (errorType, 0)
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VtDecryptFinal (
          readCtx->decryptor, (VtRandomObject)0, message, valueLen,
          outputData, bufferSize, outputDataLen);
        if (status != 0)
          break;
      }

      /* If the Decrypt succeeded, move bytesRead up and currentLen
       * down.
       */
#if VT_64_BIT_LENGTH == 64
      readCtx->dataLen -= (VtUInt64)valueLen;
#else
      readCtx->dataLen -= valueLen;
#endif
      *bytesRead += valueLen;

      /* If there's no more data to read, change the state.
       */
      if (readCtx->dataLen == 0)
        obj->state = VOLT_P7_STATE_ENV_READ_COMPLETE;

      status = 0;
  }

  VtDestroyKeyObject (&symKey);

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, 0, pkcs7Obj, status, 0, errorType,
    (char *)0, "VoltP7ReadEnvelopedUpdate", fnctLine, (char *)0)

  return (status);
}

int VoltP7ReadEnvelopedFinal (
   VtPkcs7Object pkcs7Obj,
   unsigned char *message,
   unsigned int messageLen,
   unsigned int *bytesRead,
   unsigned char *outputData,
   unsigned int bufferSize,
   unsigned int *outputDataLen
   )
{
  int status;
  VoltPkcs7Object *obj = (VoltPkcs7Object *)pkcs7Obj;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  *bytesRead = 0;
  *outputDataLen = 0;

  do
  {
    /* If we're done, there's nothing to do.
     */
    if (obj->state == VOLT_P7_STATE_ENV_READ_COMPLETE)
    {
      obj->state = VOLT_P7_STATE_ENV_READ_FINAL;
      status = 0;
      break;
    }

    /* If we're not done, try to finish.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT_LENGTH;
    if (messageLen == 0)
      break;

    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VoltP7ReadEnvelopedUpdate (
      pkcs7Obj, message, messageLen, bytesRead,
      outputData, bufferSize, outputDataLen);
    if (status != 0)
      break;

    /* Are we finished now?
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT_LENGTH;
    if (obj->state != VOLT_P7_STATE_ENV_READ_COMPLETE)
      break;

    obj->state = VOLT_P7_STATE_ENV_READ_FINAL;
    status = 0;

  } while (0);

⌨️ 快捷键说明

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