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

📄 smread.c

📁 voltage 公司提供的一个开发Ibe的工具包
💻 C
📖 第 1 页 / 共 4 页
字号:
       * an "extra" block or the second header?
       * Note from the programmer: Notice the goto statement.
       * Normally I don't like them, but in this case it really works.
       */      
      if (readCtx->unprocessedData.len ==
        VOLT_SECURE_MAIL_BEGIN_BLOCK_LEN + newLineLen)
      {
        /* If this is the third header (no second header), skip to the
         * next part of the read.
         */
        if (Z2Memcmp (
          readCtx->unprocessedData.data, beginBlk,
          VOLT_SECURE_MAIL_BEGIN_BLOCK_LEN) == 0) 
        {
          /* Set up for reading the next part.
           */                     
          status = 0;
          readCtx->unprocessedData.len = 0;
          goto VoltSecureMailBase64 ;
        }
      }

      /* This is an "extra" header, just Copy it to the extraHeader
       * field in the context. Copy the NULL-terminating character as
       * well.
       */      
      status = VT_ERROR_MEMORY;
      readCtx->extraHeader.data = (unsigned char *)Z2Realloc (
        readCtx->extraHeader.data, readCtx->unprocessedData.len + readCtx->extraHeader.len);
      if (readCtx->extraHeader.data == (unsigned char *)0)
        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:
      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.
       */
      obj->inputLen = readCtx->unprocessedData.len;

      /* 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.
       */
      status = DoDecodeUpdateOrFinal (
        obj, readCtx, 1, readCtx->unprocessedData.data,
        readCtx->unprocessedData.len);
      if (status != 0)
        break;

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

      /* The length of the entire EnvelopedData is the valueLen plus
       * the lengthLen plus the length of the tag (1).
       */
      valueLen += (lengthLen + 1);

      /* Now determine how long the Base64 encoding of that much data
       * will be. First, how many full blocks of input will there be?
       */
      inBlocks = valueLen / inBlockLen;
      /* How many output bytes will that be? Use lengthLen as a temp
       * variable.
       */
      lengthLen = inBlocks * outBlockLen;
      /* How many bytes in the last line?
       */
      leftovers = inBlocks * inBlockLen;
      leftovers = valueLen - leftovers;

      /* 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)
        obj->dataLen += newLineLen;

      /* How many blocks of 3?
       */
      inBlocks = leftovers / 3;
      /* For each block of three, there is four bytes of output.
       * So far, the total output is the number of full blocks
       * (currently in lengthLen) and the leftover blcoks of 3 expanded
       * to 4.
       */
      valueLen = lengthLen + (inBlocks * 4);

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

      /* Add in the number of bytes for the last line. Include the
       * spaces.
       */
      obj->dataLen += valueLen + preSpaceLen;

      /* 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.
       */
      valueLen = obj->dataLen - obj->inputLen;
      if (valueLen > currentMessageLen)
        valueLen = currentMessageLen;

      /* Decode the data.
       */
      status = DoDecodeUpdateOrFinal (
        obj, readCtx, obj->dataLen - valueLen, currentMessage, valueLen);
      if (status != 0)
        break;

      obj->inputLen += valueLen;
      *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 (obj->dataLen != obj->inputLen)
          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.
       */
      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:
      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 (obj->inputLen == obj->dataLen)
        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;

      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?
       */
      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 SECURE MESSAGE V1-----
       */
      status = VoltSMGetNextBlock (
        obj, &(readCtx->unprocessedData), currentMessage, currentMessageLen,
        24, &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 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 ( (amountRead == newLineLen) &&
           (readCtx->unprocessedData.len == 0) )
      {        
        goto VoltSecureMailStateReadFooter2;
      }

      /* We have the next block in the unprocessedData buffer, is this
       * the block we expect?
       */
      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,

⌨️ 快捷键说明

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