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

📄 sm2read.c

📁 IBE是一种非对称密码技术
💻 C
📖 第 1 页 / 共 4 页
字号:

    /* The headers start with a MIME-style label called
     * "ZDMv2Headers:", so we need to skip past that label to
     * reach the actual XML data.
     */
    labelLength = Z2Strlen(VoltSecureArchiveHeadersName);
    VT_ASSERT(labelLength < sizeof(label));
    Z2Memcpy(label, VoltSecureArchiveHeadersName, labelLength);
    label[labelLength] = ':';
    labelLength++;
    
    if (VoltCaseInsensitiveCompareBuffers(p, labelLength,
      label, labelLength, libCtx) != 0)
    {
      VOLT_SET_FNCT_LINE(fnctLine)
      VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
      status = VT_ERROR_ARCHIVE_READ;
      break;
    }
    
    p += labelLength;

    VOLT_SET_FNCT_LINE(fnctLine)
    status = VtCreateDataNodeObjectFromXML(libCtx, p, &attributesNode);
    if (status != 0)
      break;
    
    /* Obtain the content type attribute */
    VOLT_SET_FNCT_LINE(fnctLine)
    status = VtDataNodeLookupChild(attributesNode,
      VoltZDM2ContentTypeAttributeName, &node);
    if (status == 0)
    {
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtDataNodeGetStringValue(node, &str);
      if (status != 0)
        break;
      
      VOLT_SET_FNCT_LINE(fnctLine)
      status = Z2Strdup(str, &readCtx->contentType);
      if (status != 0)
        break;
    }
    
    /* Obtain the character set attribute */
    VOLT_SET_FNCT_LINE(fnctLine)
    status = VtDataNodeLookupChild(attributesNode,
      VoltZDM2CharacterSetAttributeName, &node);
    if (status == 0)
    {
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtDataNodeGetStringValue(node, &str);
      if (status != 0)
        break;
      
      VOLT_SET_FNCT_LINE(fnctLine)
      status = Z2Strdup(str, &readCtx->characterSet);
      if (status != 0)
        break;
    }
    
    /* Obtain the original character set attribute */
    VOLT_SET_FNCT_LINE(fnctLine)
    status = VtDataNodeLookupChild(attributesNode,
      VoltZDM2OriginalCharacterSetAttributeName, &node);
    if (status == 0)
    {
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtDataNodeGetStringValue(node, &str);
      if (status != 0)
        break;
      
      VOLT_SET_FNCT_LINE(fnctLine)
      status = Z2Strdup(str, &readCtx->originalCharacterSet);
      if (status != 0)
        break;
    }
    
    status = 0;
  }
  while (0);
  
  VtDestroyDataNodeObject(&attributesNode);
  
  VOLT_LOG_ERROR_COMPARE(status, libCtx, status, errorType,
    fnctLine, "VoltSecureMail2ProcessHeaders", (unsigned char*)0)
  
  return status;
}

static int VoltSecureMail2ParseHeaders(
  VtSecureMailObject secureMailObj,
  unsigned char* input,
  unsigned int inputLength,
  unsigned int* inputRead
)
{
  int status = 0;
  VoltSecureMail2ReadCtx* readCtx = (VoltSecureMail2ReadCtx*)0;
  VtLibCtx libCtx = (VtLibCtx)0;
  unsigned char* p;
  unsigned char* end;
  unsigned char c;
  unsigned int eolCount = 0;
  VOLT_DECLARE_FNCT_LINE(fnctLine)
  VOLT_DECLARE_ERROR_TYPE(errorType)
  
  VOLT_SET_ERROR_TYPE(errorType, 0)
  
  VT_ASSERT(secureMailObj != (VtSecureMailObject)0);
  
  readCtx = (VoltSecureMail2ReadCtx*)secureMailObj->localCtx;
  VT_ASSERT(readCtx != (VoltSecureMail2ReadCtx*)0);
  libCtx = secureMailObj->voltObject.libraryCtx;
  VT_ASSERT(libCtx != (VtLibCtx)0);
  
  do
  {
    p = input;
    end = input + inputLength;
    
    while (p < end)
    {
      c = *p++;
      
      if ((c == '\r') || (c == '\n'))
      {
        /* Check for CRLF line endings, so we only treat it as 1 EOL */
        if ((c == '\r') && (p < end) && (*p == '\n'))
          p++;
        eolCount++;
        if (eolCount == 2)
        {
          p[-1] = 0;
          VOLT_SET_FNCT_LINE(fnctLine)
          status = VoltSecureMail2ProcessHeaders(secureMailObj, input);
          if (status != 0)
            break;
            
          *inputRead = p - input;
          readCtx->processedHeaders = 1;
          break;
        }
      }
      else
      {
        eolCount = 0;
      }
    }
  }
  while (0);
  
  VOLT_LOG_ERROR_COMPARE(status, libCtx, status, errorType,
    fnctLine, "VoltSecureMail2ParseHeaders", (unsigned char*)0)
  
  return status;
}

static int VoltSecureMail2ReadBody(
  VtSecureMailObject secureMailObj,
  unsigned char *input,
  unsigned int inputLength,
  unsigned int* inputRead,
  unsigned char* output,
  unsigned int outputBufferSize,
  unsigned int* outputLength
)
{
  int status = 0;
  VoltSecureMail2ReadCtx* readCtx = (VoltSecureMail2ReadCtx*)0;
  VtLibCtx libCtx = (VtLibCtx)0;
  unsigned char* p;
  unsigned char* end;
  int final = 0;
  unsigned int decodedLength;
  unsigned char* envelopedData = (unsigned char*)0;
  unsigned char* signedData = (unsigned char*)0;
  unsigned char* data = (unsigned char*)0;
  unsigned int envelopedDataLength;
  unsigned int signedDataLength;
  unsigned int dataLength;
  unsigned int newDataLength;
  unsigned int dataRead, dataRead2, dataWritten;
  VoltEncodeDecodeSizeInfo encodeDecodeSizeInfo;
  VOLT_DECLARE_FNCT_LINE(fnctLine)
  VOLT_DECLARE_ERROR_TYPE(errorType)
  
  VOLT_SET_ERROR_TYPE(errorType, 0)
  
  VT_ASSERT(secureMailObj != (VtSecureMailObject)0);
  
  readCtx = (VoltSecureMail2ReadCtx*)secureMailObj->localCtx;
  VT_ASSERT(readCtx != (VoltSecureMail2ReadCtx*)0);
  libCtx = secureMailObj->voltObject.libraryCtx;
  VT_ASSERT(libCtx != (VtLibCtx)0);
  
  do
  {
    *outputLength = 0;
    
    /* Find the end of the base64-encoded data. We look for the
     * first character of the secure block end tag, which must
     * be an invalid base 64 character (or else it would be
     * interpreted as data.
     */
    p = input;
    end = input + inputLength;
    
    while (p < end)
    {
      if (*p == VoltZDM2SecureBlockEndTagPrefix[0])
      {
        final = 1;
        break;
      }
      p++;
    }
    
    /* We're going to consume all the input (or else hit an
     * error we can't recover from, so we can set the inputRead param
     */
    *inputRead = p - input;
    decodedLength = 0;
    
    if (final)
    {
      if (!readCtx->decodedFinal)
      {
        encodeDecodeSizeInfo.dataToProcess = input;
#if VT_64_BIT_LENGTH == 64
        encodeDecodeSizeInfo.dataToProcessLen = (VtUInt64)(p - input);
#else
        encodeDecodeSizeInfo.dataToProcessLen = (unsigned int)(p - input);
#endif
        VOLT_SET_FNCT_LINE(fnctLine)
        status = VoltBase64GetEncodeDecodeSize (
          secureMailObj->base64, (VtRandomObject)0, VOLT_CALLER_DECODE_FINAL,
          &encodeDecodeSizeInfo);
#if VT_64_BIT_LENGTH == 64
        decodedLength = (unsigned int)(encodeDecodeSizeInfo.processedDataLen);
#else
        decodedLength = encodeDecodeSizeInfo.processedDataLen;
#endif
      }
    }
    else if (p > input)
    {
      encodeDecodeSizeInfo.dataToProcess = input;
#if VT_64_BIT_LENGTH == 64
      encodeDecodeSizeInfo.dataToProcessLen = (VtUInt64)(p - input);
#else
      encodeDecodeSizeInfo.dataToProcessLen = (unsigned int)(p - input);
#endif
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VoltBase64GetEncodeDecodeSize (
        secureMailObj->base64, (VtRandomObject)0, VOLT_CALLER_DECODE_UPDATE,
        &encodeDecodeSizeInfo);
#if VT_64_BIT_LENGTH == 64
      decodedLength = (unsigned int)(encodeDecodeSizeInfo.processedDataLen);
#else
      decodedLength = encodeDecodeSizeInfo.processedDataLen;
#endif
    }
    
    if ((status != 0) && (status != VT_ERROR_BUFFER_TOO_SMALL))
        break;
    
    envelopedDataLength = readCtx->pendingDataLength + decodedLength;
    
    envelopedData = (unsigned char*) Z3Malloc(envelopedDataLength);
    if (envelopedData == (unsigned char*)0)
    {
      VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VT_ERROR_MEMORY;
      break;
    }
    
    Z2Memcpy(envelopedData, readCtx->pendingData, readCtx->pendingDataLength);
    
    if (status == VT_ERROR_BUFFER_TOO_SMALL)
    {
      if (final)
      {
        VOLT_SET_FNCT_LINE(fnctLine)
        status = VtDecodeFinal(secureMailObj->base64, (VtRandomObject)0,
          input, p - input, envelopedData + readCtx->pendingDataLength,
          decodedLength, &dataWritten);
        if (status == 0)
          readCtx->decodedFinal = 1;
      }
      else
      {
        VOLT_SET_FNCT_LINE(fnctLine)
        status = VtDecodeUpdate(secureMailObj->base64, (VtRandomObject)0,
          input, p - input, envelopedData + readCtx->pendingDataLength,
          decodedLength, &dataWritten);
      }
      
      if (status != 0)
        break;

      envelopedDataLength = readCtx->pendingDataLength + dataWritten;
    }
    
    Z2Free(readCtx->pendingData);
    readCtx->pendingData = (unsigned char*)0;
    readCtx->pendingDataLength = 0;
    
    /* At this point we've decoded the input data up until the end of
     * the base 64 data and merged it with any pending enveloped data.
     * Now we extract the signed data from the enveloped data.
     */
     
    if (final)
    {
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtPkcs7ReadFinal(secureMailObj->p7EnvelopedData, envelopedData,
        envelopedDataLength, &dataRead, (unsigned char*)0, 0, &signedDataLength);
    }
    else if (envelopedDataLength > 0)
    {
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtPkcs7ReadUpdate(secureMailObj->p7EnvelopedData, envelopedData,
        envelopedDataLength, &dataRead, (unsigned char*)0, 0, &signedDataLength);
    }
    else
    {
      dataRead = 0;
      signedDataLength = 0;
      status = 0;
    }
    
    if (status == VT_ERROR_CHOOSE_RECIPIENT)
    {
      if (dataRead < envelopedDataLength)
      {
        VT_ASSERT(readCtx->pendingData == (unsigned char*)0);
        readCtx->pendingDataLength = envelopedDataLength - dataRead;
        readCtx->pendingData = (unsigned char*)
          Z3Malloc(readCtx->pendingDataLength);
        if (readCtx->pendingData == (unsigned char*)0)
        {
          VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
          VOLT_SET_FNCT_LINE(fnctLine)
          status = VT_ERROR_MEMORY;
          break;
        }
        Z2Memcpy(readCtx->pendingData, envelopedData + dataRead,
          readCtx->pendingDataLength);
      }
      break;
    }
    
    if (status == VT_ERROR_BUFFER_TOO_SMALL)
    {
      VT_ASSERT(signedDataLength > 0);
      
      signedData = (unsigned char*) Z3Malloc(signedDataLength);
      if (signedData == (unsigned char*)0)
      {
        VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
        VOLT_SET_FNCT_LINE(fnctLine)
        status = VT_ERROR_MEMORY;
        break;
      }
      
      if (final)
      {
        VOLT_SET_FNCT_LINE(fnctLine)
        status = VtPkcs7ReadFinal(secureMailObj->p7EnvelopedData,
          envelopedData + dataRead, envelopedDataLength - dataRead,
          &dataRead2, signedData, signedDataLength, &signedDataLength);
      }
      else
      {
        VOLT_SET_FNCT_LINE(fnctLine)
        status = VtPkcs7ReadUpdate(secureMailObj->p7EnvelopedData,
          envelopedData + dataRead, envelopedDataLength - dataRead,
          &dataRead2, signedData, signedDataLength, &signedDataLength);
      }
      
      VT_ASSERT(dataRead + dataRead2 == envelopedDataLength);
    }
    
    if (status != 0)
      break;
      
    /* At this point we've extracted the signed data from the
     * envelope. Now we extract the meesage data from the signed data.
     */
     
    if (final)
    {
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtPkcs7ReadFinal(secureMailObj->p7SignedData,
        signedData, signedDataLength, &dataRead,
        (unsigned char*)0, 0, &newDataLength);
    }
    else if (signedDataLength > 0)
    {
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtPkcs7ReadUpdate(secureMailObj->p7SignedData,
        signedData, signedDataLength, &dataRead,
        (unsigned char*)0, 0, &newDataLength);
    }
    else
    {
      newDataLength = 0;
      dataRead = 0;
      status = 0;
    }
    
    if (status == VT_ERROR_BUFFER_TOO_SMALL)
    {
      data = (unsigned char*)
        Z3Malloc(readCtx->pendingHeadersLength + newDataLength);
      if (data == (unsigned char*)0)
      {
        VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
        VOLT_SET_FNCT_LINE(fnctLine)
        status = VT_ERROR_MEMORY;
        break;
      }
      
      if (readCtx->pendingHeadersLength > 0)
      {
        VT_ASSERT(readCtx->pendingHeaders != (unsigned char*)0);
        Z2Memcpy(data, readCtx->pendingHeaders, readCtx->pendingHeadersLength);
      }

      if (final)
      {
        VOLT_SET_FNCT_LINE(fnctLine)
        status = VtPkcs7ReadFinal(secureMailObj->p7SignedData,
          signedData + dataRead, signedDataLength - dataRead, &dataRead,
          data + readCtx->pendingHeadersLength, newDataLength, &newDataLength);
      }

⌨️ 快捷键说明

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