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

📄 readenv.c

📁 voltage 公司提供的一个开发Ibe的工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
      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;
      }
      status = VT_ERROR_UNKNOWN_BER;
      if (index >= readCtx->derCoderCount)
        break;

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

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

      /* DecryptInit to start the process.
       */
      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.
       */
      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->currentLen = derElement->tlvLen;

      /* 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.
       */
      valueLen = readCtx->currentLen;
      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 (valueLen != readCtx->currentLen)
      {
        status = VtDecryptUpdate (
          readCtx->decryptor, (VtRandomObject)0, message, valueLen,
          outputData, bufferSize, outputDataLen);
        if (status != 0)
          break;
      }
      else
      {
        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.
       */
      readCtx->currentLen -= valueLen;
      *bytesRead += valueLen;

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

      status = 0;
  }

  VtDestroyKeyObject (&symKey);

  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;

  *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.
     */
    status = VT_ERROR_INVALID_INPUT_LENGTH;
    if (messageLen == 0)
      break;

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

    /* Are we finished now?
     */
    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);

  return (status);
}

static int AddRecipientInfoToList (
   VoltLibCtx *libCtx,
   VoltPkcs7ReadEnvCtx *readCtx,
   unsigned char *recipInfoDer,
   unsigned int recipInfoDerLen
   )
{
  int status;
  unsigned int index, theTag, lengthLen, valueLen, offset, len, count;
  Asn1RecipientInfo *newRi = (Asn1RecipientInfo *)0;
  VtIdentityObject newId = (VtIdentityObject)0;
  Asn1RecipientInfo **newList = (Asn1RecipientInfo **)0;
  unsigned char *temp;
  unsigned char *idString = (unsigned char *)0;

  do
  {
    /* Build a RecipientInfo object out of the encoding.
     */
    status = VT_ERROR_MEMORY;
    newRi = Asn1RecipientInfo_new ();
    if (newRi == (Asn1RecipientInfo *)0)
      break;

    status = VT_ERROR_INVALID_ENCODING;
    temp = recipInfoDer;
    d2i_Asn1RecipientInfo (&newRi, &temp, recipInfoDerLen);
    if (newRi == (Asn1RecipientInfo *)0)
      break;

    /* Isolate the Base64 encoded identity. It will be the element with
     * the VOLT_PRINT_STRING_TAG.
     */
    offset = 0;
    temp = newRi->issuerSerial->base.data;
    len = (unsigned int)(newRi->issuerSerial->base.length);
    do
    {
      /* Keep decoding TL's until reaching 0C.
       */
      status = VoltDecodeTagAndLen (
        temp + offset, len - offset, &theTag, &lengthLen, &valueLen);
      if (status != 0)
        break;

      offset += 1 + lengthLen;

      /* If we found the tag, quit looking.
       */
      if (theTag == VOLT_PRINT_STRING_TAG)
        break;

      /* If we found the OID tag, skip the data.
       */
      if (theTag == VOLT_OID_TAG)
        offset += valueLen;

    } while (1);
    if (status != 0)
      break;

    /* Decode the identity.
     */
    status = VtDecodeInit (readCtx->base64);
    if (status != 0)
      break;

    /* Allocate a buffer to hold the result. There will be 3 characters
     * output for each 4 input. Maybe a little less, so just allocate a
     * buffer 3/4 the size of the input.
     */
    status = VT_ERROR_MEMORY;
    len = (3 * valueLen) / 4;
    idString = (unsigned char *)Z2Malloc (len, 0);
    if (idString == (unsigned char *)0)
      break;

    status = VtDecodeFinal (
      readCtx->base64, (VtRandomObject)0, temp + offset, valueLen,
      idString, len, &len);
    if (status != 0)
      break;

    /* Now build an identity object using that identity.
     */
    status = VtCreateIdentityObject (
      (VtLibCtx)libCtx, VtIdentityImplMpCtx, (Pointer)(readCtx->mpCtx),
      &newId);
    if (status != 0)
      break;

    /* If we can't decode this identity, just ignore it. So if the
     * error is INVALID_ENCODING or UNKNOWN_SCHEMA, skip everithing.
     */
    status = VtDecodeIdentity (
      idString, len, readCtx->Decoders, readCtx->decoderCount, &index,
      newId);
    if (status != 0)
      break;

    /* Add the Asn1RecipientInfo to the list.
     */
    status = VT_ERROR_MEMORY;
    count = readCtx->recipInfoCount + 1;
    newList = (Asn1RecipientInfo **)Z2Malloc (
      count * sizeof (Asn1RecipientInfo *), 0);
    if (newList == (Asn1RecipientInfo **)0)
      break;
    Z2Memset (newList, 0, count * sizeof (Asn1RecipientInfo *));

    /* Copy the old into the new.
     */
    for (index = 0; index < readCtx->recipInfoCount; ++index)
      newList[index] = readCtx->recipInfoList[index];
    newList[index] = newRi;

    /* Add the identity to the identityList.
     */
    status = VtAddIdObjectToIdentityList (readCtx->recipList, newId, &index);
    if (status != 0)
      break;

    /* If everything succeeded, get rid of the old recipInfoList and
     * replace it with the new.
     */
    if (readCtx->recipInfoList != (Asn1RecipientInfo **)0)
      Z2Free (readCtx->recipInfoList);
    readCtx->recipInfoList = newList;
    readCtx->recipInfoCount++;

  } while (0);

  /* We added the identity to the recipient list, so we don't need
   * this object any more.
   */
  VtDestroyIdentityObject (&newId);
  if (idString != (unsigned char *)0)
    Z2Free (idString);

  /* If no error, we're done.
   */
  if (status == 0)
    return (0);

  /* If there was an error, destroy what we created.
   */
  if (newRi != (Asn1RecipientInfo *)0)
    Asn1RecipientInfo_free (newRi);
  if (newList != (Asn1RecipientInfo **)0)
    Z2Free (newList);

  return (status);
}

static int DecryptSessionKeyData (
   VoltLibCtx *libCtx,
   VoltPkcs7Object *obj,
   VoltPkcs7ReadEnvCtx *readCtx
   )
{
  int status;
  unsigned int bufferSize;
  Asn1RecipientInfo *recipInfo;
  VtAlgorithmObject decryptor = (VtAlgorithmObject)0;
  VoltSurrenderCtx *surrCtx = (VoltSurrenderCtx *)0;
  VtSurrenderCallback surrenderCtx;
  VtSetAlgIdInfo algIdInfo;

  recipInfo = readCtx->recipInfoList[readCtx->chosenRecipient];

  do
  {
    /* Build an algorithm object using the algId in the RecipientInfo.
     */
    algIdInfo.derCoders = readCtx->DerCoders;
    algIdInfo.derCoderCount = readCtx->derCoderCount;
    algIdInfo.berEncoding = recipInfo->keyEncAlg->base.data;
    algIdInfo.maxEncodingLen =
      (unsigned int)(recipInfo->keyEncAlg->base.length);
    status = VtCreateAlgorithmObject (
      (VtLibCtx)libCtx, VtAlgorithmImplAlgId, (Pointer)&algIdInfo,
      &decryptor);
    if (status != 0)
      break;

    /* If there's a surrender ctx, pass it on to the decryptor.
     */
    if ( ((obj->voltObject.objectType & VOLT_OBJECT_TYPE_SURRENDER) != 0) &&
         (obj->voltObject.surrenderCtx != (Pointer)0) )
    {
      surrCtx = (VoltSurrenderCtx *)(obj->voltObject.surrenderCtx);
      /* Set the decryption object with the surrender ctx, but don't copy
       * the appData, just copy a reference, so we're still using the
       * P7 object's appData.
       */
      surrenderCtx.Surrender = surrCtx->Surrender;
      surrenderCtx.appData = surrCtx->appData;
      surrenderCtx.AppDataCopy = (VtSurrenderAppDataCopy)0;
      surrenderCtx.AppDataFree = (VtSurrenderAppDataFree)0;
      status = VtSetAlgorithmParam (
        decryptor, VtAlgorithmParamSurrenderCallback, (Pointer)&surrenderCtx);
      if (status != 0)
        break;
    }

    /* Init with the key we have.
     */
    status = VtDecryptInit (decryptor, readCtx->priKeyRef);
    if (status != 0)
      break;

    /* How big does the output buffer need to be?
     * Don't call this routine, it will decrypt to get the appropriate
     * size. Compute "by hand". The length will be encryptedKeyLen -
     * primeLen - SHA-1 len. So the max len will be encryptedKeyLen -
     * minPrimeLen - SHA-1 len,
     */
/*    status = VtDecryptFinal (
      decryptor, (VtRandomObject)0, recipInfo->encryptedKey->data,
      (unsigned int)(recipInfo->encryptedKey->length),
      (unsigned char *)0, 0, &bufferSize);
    if (status == 0)
      status = VT_ERROR_GENERAL;
    if (status != VT_ERROR_BUFFER_TOO_SMALL)
      break;
*/
    bufferSize = (unsigned int)(recipInfo->encryptedKey->length) - 20;

    status = VT_ERROR_MEMORY;
    readCtx->symKeyData.data = (unsigned char *)Z2Realloc (
      readCtx->symKeyData.data, bufferSize);
    if (readCtx->symKeyData.data == (unsigned char *)0)
      break;

    /* Now decrypt into the buffer.
     */
    status = VtDecryptFinal (
      decryptor, (VtRandomObject)0, recipInfo->encryptedKey->data,
      (unsigned int)(recipInfo->encryptedKey->length),
      readCtx->symKeyData.data, bufferSize, &(readCtx->symKeyData.len));
    if (status != 0)
      break;

  } while (0);

  VtDestroyAlgorithmObject (&decryptor);

  return (status);
}

⌨️ 快捷键说明

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