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

📄 smread.c

📁 IBE是一种非对称密码技术
💻 C
📖 第 1 页 / 共 4 页
字号:
        break;
      Z2Memcpy (
        readCtx->extraHeader.data + readCtx->extraHeader.len, readCtx->unprocessedData.data,
        readCtx->unprocessedData.len);
      readCtx->extraHeader.len += readCtx->unprocessedData.len;
      readCtx->unprocessedData.len = 0;

      status = 0;
                  
      /* If there's no more message to read, return.
       */
      if (currentMessageLen == 0)
        break;

      /* There's more message to read, but we haven't read the BEGIN
       * BLOCK header yet, so keep performing this part until we have.
       */
      goto VoltSecureMailReadHeader2;      

VoltSecureMailBase64:
      obj->state = VOLT_SECURE_MAIL_STATE_READ_B64_LEN;
      readCtx->unprocessedData.len = 0;

      /* If there's no more message to read, return.
       */
      if (currentMessageLen == 0)
        break;

    case VOLT_SECURE_MAIL_STATE_READ_B64_LEN:
      /* Any data we read now will be regular message data.
       * First, Base64 decode it, then send it to the p7EnvelopedData
       * object to read, then any output is sent to the p7SignedData
       * object to read.
       * Eventually we'll run out of message material and hit the
       * footers. We don't want to pass the footers to the Base64
       * decoder, so we'll have to check input to make sure the line is
       * not a footer.
       * What we need to do is decode the first line of the message,
       * then we'll have the length of the EnvelopedData.
       */
VoltSecureMailStateReadB64Len:
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VoltSMGetNextBlock (
        obj, &(readCtx->unprocessedData), currentMessage, currentMessageLen,
        1, &amountRead, &completeFlag, &newLineLen);
      if (status != 0)
        break;

      *bytesRead += amountRead;
      if (completeFlag == 0)
        break;

      currentMessage = message + *bytesRead;
      currentMessageLen = messageLen - *bytesRead;

      /* this is to handle the situation where there might have been
       * empty new lines either inserted deliberately or by accident
       * between -----BEGIN VOLTAGE SECURE BLOCK V1----- block and
       * the beginning of the base64 encoded data. Skip all those lines.
       */
      if ( (amountRead == newLineLen) &&
           (readCtx->unprocessedData.len == 0) )
      {        
        goto VoltSecureMailStateReadB64Len;
      }

VoltSecureMailBase64A:
      /* Set inputLen to the number of bytes read so far.
       */
#if VT_64_BIT_LENGTH == 64
      obj->inputLen64 = (VtUInt64)(readCtx->unprocessedData.len);
#else
      obj->inputLen = readCtx->unprocessedData.len;
#endif

      /* Determine the input and output block sizes of the message.
       * First, how many spaces are there to lead off a line?
       */
      index = 0;
      preSpaceLen = 0;
      while (readCtx->unprocessedData.data[index++] == ' ')
        preSpaceLen++;

      /* How many actual base64 bytes? Don't count spaces or new lines.
       */
      valueLen = readCtx->unprocessedData.len - preSpaceLen - newLineLen;
      valueLen /= 4;
      inBlockLen = valueLen * 3;

      /* For each block of input, there will be one line of output,
       * which includes space characters and new lines.
       */
      outBlockLen = readCtx->unprocessedData.len;

      /* Decode this line.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = DoDecodeUpdateOrFinal (
        obj, readCtx, 1, readCtx->unprocessedData.data,
        readCtx->unprocessedData.len);
      if (status != 0)
        break;

#if VT_64_BIT_LENGTH == 64
      valueLen = 0;
#else
      valueLen = 4;
#endif

      /* Get the length of the EnvelopedData.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VoltDecodeTagAndLen (
        libCtx, readCtx->unprocessedData.data, readCtx->unprocessedData.len,
        &theTag, &lengthLen, &lenLo, &lenHi, valueLen);
      if (status != 0)
        break;

      /* The length of the entire EnvelopedData is the valueLen plus
       * the lengthLen plus the length of the tag (1).
       */
#if VT_64_BIT_LENGTH == 64
      envelopeLen = (VtUInt64)lenHi;
      envelopeLen <<= 32;
      envelopeLen += (VtUInt64)lenLo;
      envelopeLen += (VtUInt64)(lengthLen + 1);
#else
      envelopeLen = (unsigned int)lenLo + lengthLen + 1;
#endif

      /* Now determine how long the Base64 encoding of that much data
       * will be. First, how many full blocks of input will there be?
       */
#if VT_64_BIT_LENGTH == 64
      inBlocks = envelopeLen / (VtUInt64)inBlockLen;
#else
      inBlocks = envelopeLen / inBlockLen;
#endif

      /* How many bytes in the last line?
       */
#if VT_64_BIT_LENGTH == 64
      outLen = inBlocks * (VtUInt64)inBlockLen;
      leftovers = (UInt32)(envelopeLen - outLen);
#else
      outLen = inBlocks * inBlockLen;
      leftovers = envelopeLen - outLen;
#endif

      /* How many output bytes will that be?
       */
#if VT_64_BIT_LENGTH == 64
      outLen = inBlocks * (VtUInt64)outBlockLen;
#else
      outLen = inBlocks * outBlockLen;
#endif

      /* If there are any leftovers, there will be a new line, but
       * we'll count number of bytes without the new line characters.
       * So if there is going to be another line, add the new line
       * characters now.
       */
      if (leftovers != 0)
#if VT_64_BIT_LENGTH == 64
        obj->dataLen64 += (VtUInt64)newLineLen;
#else
        obj->dataLen += newLineLen;
#endif

      /* How many blocks of 3? Use flag as a temp variable.
       */
      flag = leftovers / 3;
      /* For each block of three, there are four bytes of output.
       * So far, the total output is the number of full blocks
       * and the leftover blocks of 3 expanded to 4.
       */
#if VT_64_BIT_LENGTH == 64
      outLen += (VtUInt64)(flag * 4);
#else
      outLen += (flag * 4);
#endif

      /* How many bytes left over? If there are any bytes left over,
       * the encoder will pad to one more block.
       */
      flag *= 3;
      leftovers -= flag;
      if (leftovers != 0)
        outLen += 4;

      /* Add in the number of bytes for the last line. Include the
       * spaces.
       */
#if VT_64_BIT_LENGTH == 64
      obj->dataLen64 += (outLen + (VtUInt64)(preSpaceLen));
#else
      obj->dataLen += outLen + preSpaceLen;
#endif

      /* Set the state for the next read. We have data in the
       * unprocessedData buffer that needs to go to the Envelope
       * object, so set the state for that.
       */
      obj->state = VOLT_SECURE_MAIL_STATE_READ_ENV;
      goto VoltSecureMailStateReadEnv;

VoltSecureMailStateReadB64:
      /* If there's no more message to read, return.
       */
      if (currentMessageLen == 0)
        break;

    case VOLT_SECURE_MAIL_STATE_READ_B64:
      /* Read the Base64 data. If the caller passed in data beyond the
       * end of the base64 data, don't read it yet.
       */
#if VT_64_BIT_LENGTH == 64
      envelopeLen = obj->dataLen64 - obj->inputLen64;
      flag = 1;
      valueLen = currentMessageLen;
      if (envelopeLen <= (VtUInt64)currentMessageLen)
      {
        valueLen = (unsigned int)envelopeLen;
        flag = 0;
      }
#else
      valueLen = obj->dataLen - obj->inputLen;
      if (valueLen > currentMessageLen)
        valueLen = currentMessageLen;
      flag = obj->dataLen - valueLen;
#endif

      /* Decode the data.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = DoDecodeUpdateOrFinal (
        obj, readCtx, flag, currentMessage, valueLen);
      if (status != 0)
        break;

#if VT_64_BIT_LENGTH == 64
      obj->inputLen64 += (VtUInt64)valueLen;
#else
      obj->inputLen += valueLen;
#endif

      *bytesRead += valueLen;
      currentMessage = message + *bytesRead;
      currentMessageLen = messageLen - *bytesRead;

      /* The state upon return is either READ_ENV or READ_B64. If
       * READ_B64, we've read all the input and there's no more
       * processing on it that we can do.
       */
      if (obj->state != VOLT_SECURE_MAIL_STATE_READ_ENV)
      {
        /* If inputLen and dataLen are equal, that means we've read all
         * the base64 data. Because the Decode did not set the state to
         * READ_ENV, that means there's no more enveloped data (and
         * hence no more signed data) to read. Next up:
         * VOLT_SECURE_MAIL_STATE_READ_FOOTER_1.
         */
#if VT_64_BIT_LENGTH == 64
        if (obj->dataLen64 != obj->inputLen64)
#else
        if (obj->dataLen != obj->inputLen)
#endif
          break;

        obj->state = VOLT_SECURE_MAIL_STATE_READ_FOOTER_1;
        if (currentMessageLen == 0)
          break;

        goto VoltSecureMailStateReadFooter1;
      }

VoltSecureMailStateReadEnv:
    case VOLT_SECURE_MAIL_STATE_READ_ENV:
      /* Read the data in the unprocessedData buffer as EnvelopedData.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = DoEnvelopeRead (obj, readCtx, 1);
      if (status != 0)
        break;

      /* Upon return, the state should be either READ_SIGNED or READ_B64.
       */
      if (obj->state == VOLT_SECURE_MAIL_STATE_READ_B64)
        goto VoltSecureMailStateReadB64;

    case VOLT_SECURE_MAIL_STATE_READ_SIGNED:
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VoltSMDoSignedDataRead (
        obj, readCtx, 1, outputData, bufferSize, outputDataLen);
      if (status != 0)
        break;

      /* If this call read everything in the unprocessedData buffer,
       * then there will need to be some more B64 data to read to get
       * the next bytes.
       */
      obj->state = VOLT_SECURE_MAIL_STATE_READ_B64;

      /* At this point, there is either no more data to process, or the
       * data to process is footer material.
       */
#if VT_64_BIT_LENGTH == 64
      if (obj->dataLen64 == obj->inputLen64)
#else
      if (obj->dataLen == obj->inputLen)
#endif
        obj->state = VOLT_SECURE_MAIL_STATE_READ_FOOTER_1;

      /* If there's no more message to read, return.
       */
      if (currentMessageLen == 0)
        break;

VoltSecureMailStateReadFooter1:
    case VOLT_SECURE_MAIL_STATE_READ_FOOTER_1:
      /* We're expecting to see
       *   -----END VOLTAGE SECURE BLOCK V1-----
       * Unless this is ZDM attachment.
       */
      if (obj->formatType == VOLT_MESSAGE_FORMAT_ZDM_ATTACHMENT)
        goto VoltSecureMailStateReadEnvFinal;

      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VoltSMGetNextBlock (
        obj, &(readCtx->unprocessedData), currentMessage, currentMessageLen,
        8, &amountRead, &completeFlag, &newLineLen);
      if (status != 0)
        break;

      *bytesRead += amountRead;
      if (completeFlag == 0)
        break;

      currentMessage = message + *bytesRead;
      currentMessageLen = messageLen - *bytesRead;

      /* This code is to handle the situation when there are
       * unexpected new lines between the end of the base64 encoded
       * data and the beginning of the block 
       * -----END VOLTAGE SECURE BLOCK V1-----. We don't want to fail
       * if this situation arises accidently. So skip all the extra empty
       * lines until we find something meaningful.
       */
      if ( (amountRead == newLineLen) &&
           (readCtx->unprocessedData.data[0] == 0) )
      {
        readCtx->unprocessedData.len = 0;
        goto VoltSecureMailStateReadFooter1;
      }      

      /* We have the next block in the unprocessedData buffer, is this
       * the block we expect?
       */
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_INVALID_SECURE_MAIL_MSG;
      if (readCtx->unprocessedData.len != VOLT_SECURE_MAIL_END_BLOCK_LEN + newLineLen)
        break;
      if (Z2Memcmp (
        readCtx->unprocessedData.data, endBlk,
        VOLT_SECURE_MAIL_END_BLOCK_LEN) != 0)
        break;

      /* Set up the context for the next block.
       */
      status = 0;
      readCtx->unprocessedData.len = 0;
      obj->state = VOLT_SECURE_MAIL_STATE_READ_FOOTER_2;

      /* If there's no more message to read, return.
       */
      if (currentMessageLen == 0)
        break;

VoltSecureMailStateReadFooter2:
    case VOLT_SECURE_MAIL_STATE_READ_FOOTER_2:
      /* We're expecting to see
       *   -----END VOLTAGE MESSAGE BLOCK V1-----
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VoltSMGetNextBlock (
        obj, &(readCtx->unprocessedData), currentMessage, currentMessageLen,
        24, &amountRead, &completeFlag, &newLineLen);
      if (status != 0)
        break;

      *bytesRead += amountRead;
      currentMessage = message + *bytesRead;
      currentMessageLen = messageLen - *bytesRead;

      /* This check is to handle the situation when there are
       * unexpected new lines between the block  
       * -----END VOLTAGE SECURE BLOCK V1-----. and the block
       * -----END VOLTAGE MESSAGE BLOCK V1-----.
       * We don't want to fail if this situation arises accidently. 
       * So skip all the extra empty lines until we find something 
       * meaningful.
       */
      if ( (completeFlag != 0) && (amountRead == newLineLen) &&
           (readCtx->unprocessedData.len == 0) )
        goto VoltSecureMailStateReadFooter2;

      /* The GetNextBlock function expects a new line character, if
       * there is none, then completeFlag is 0.
       * But it is possible the SecureMail message ends without the new
       * line character.
       * If this was called by ReadFinal, then this is the last block.
       * If there's no new line character, we want to go ahead and
       * read. If the data is the expected footer, who cares if there's
       * a new line character or not. If the problem is something else,
       * then we'll get that error.
       * So if this is ReadFinal and the completeFlag is 0, act as if
       * it is complete (but if this is not ReadFinal and we're
       * incomplete, go ahead and break and wait for more input).
       */
      if ( (completeFlag == 0) && (readCtx->readFinal == 0) )
        break;

      /* We have the next block in the unprocessedData buffer, is this
       * the block we expect?
       */
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_INVALID_SECURE_MAIL_MSG;
      if (readCtx->unprocessedData.len != VOLT_SECURE_MAIL_END_MESSAGE_LEN + newLineLen)
        break;
      if (Z2Memcmp (
        readCtx->unprocessedData.data, endMsg,
        VOLT_SECURE_MAIL_END_MESSAGE_LEN) != 0)
        break;

⌨️ 快捷键说明

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