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

📄 readsign.c

📁 voltage 公司提供的一个开发Ibe的工具包
💻 C
📖 第 1 页 / 共 3 页
字号:
      /* How long is the cert list? This is IMPLICIT.
       */
      status = VoltGetNextDerElement (
        libCtx, message, messageLen, 0, 0xA0, 0, derElement, &messageRead);
      if (status != 0)
        break;

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

      readCtx->currentLen = derElement->tlvLen;
      obj->state = VOLT_P7_STATE_SIGN_READ_CERT_D;

      /* Move on to the next element.
       */
      message += messageRead;
      messageLen -= messageRead;
      VoltResetDerElement (derElement);
      if (messageLen == 0)
        break;

VoltP7StateSignReadCertData:
    case VOLT_P7_STATE_SIGN_READ_CERT_D:
      /* The next element is a cert.
       */
      status = VoltGetNextDerElement (
        libCtx, message, messageLen, 0, VOLT_SEQUENCE_TAG, 1,
        derElement, &messageRead);
      if (status != 0)
        break;

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

      /* We kept the total length of all the certs, now that we've read
       * one, subtract its length from the total. If that was the last
       * cert, set the state to indicate we're done reading certs.
       */
      readCtx->currentLen -= derElement->elementLen;
      if (readCtx->currentLen == 0)
        obj->state = VOLT_P7_STATE_SIGN_READ_CERTS;

      /* Add this cert to the list of certs.
       */
      status = AddCertToList (
        libCtx, readCtx, derElement->element, derElement->elementLen);
      if (status != 0)
        break;

      /* Move on to the next element.
       */
      message += messageRead;
      messageLen -= messageRead;
      VoltResetDerElement (derElement);
      if (messageLen == 0)
        break;

      /* There may be more certs, we checked readCtx->currentLen to
       * see, if there are no more the state was set to
       * VOLT_P7_STATE_SIGN_READ_CERTS. If the state is not that value,
       * read another cert. If it is, move on to the CRL's.
       * Note from the programmer: Notice the goto statement.
       * Normally I don't like them, but in this case it really works.
       */
      if (obj->state != VOLT_P7_STATE_SIGN_READ_CERTS)
        goto VoltP7StateSignReadCertData;

    case VOLT_P7_STATE_SIGN_READ_CERTS:
      /* We're done with the certs. There might be some CRL's, but they
       * are OPTIONAL. If they are there, the next byte will be A1. If
       * not, skip the CRL collection code.
       * Note from the programmer: Notice the goto statement.
       * Normally I don't like them, but in this case it really works.
       */
      if (message[0] != 0xA1)
      {
        obj->state = VOLT_P7_STATE_SIGN_READ_CRLS;
        goto VoltP7StateSignReadCrls;
      }
      obj->state = VOLT_P7_STATE_SIGN_READ_CRL_L;

VoltP7StateSignReadCrlLen:
    case VOLT_P7_STATE_SIGN_READ_CRL_L:
      /* This implementation skips the CRL's. Get the length.
       */
      status = VoltGetNextDerElement (
        libCtx, message, messageLen, 0, 0xA1, 0, derElement, &messageRead);
      if (status != 0)
        break;

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

      readCtx->currentLen = derElement->tlvLen;
      obj->state = VOLT_P7_STATE_SIGN_READ_CRL_D;

      /* Move on to the next element.
       */
      message += messageRead;
      messageLen -= messageRead;
      VoltResetDerElement (derElement);
      if (messageLen == 0)
        break;

    case VOLT_P7_STATE_SIGN_READ_CRL_D:
      /* Just skip CRL's. Skip all the CRL data, unless the amount in
       * message is not enough. Then skip all the data in the message.
       */
      length = messageLen;
      if (messageLen >= readCtx->currentLen)
      {
        length = readCtx->currentLen;
        obj->state = VOLT_P7_STATE_SIGN_READ_CRLS;
      }

      readCtx->currentLen -= length;
      message += length;
      messageLen -= length;
      if (messageLen == 0)
        break;

VoltP7StateSignReadCrls:
    case VOLT_P7_STATE_SIGN_READ_CRLS:
      /* We should have a SET OF SignerInfo. How long?
       */
      status = VoltGetNextDerElement (
        libCtx, message, messageLen, 0, VOLT_SET_TAG, 0,
        derElement, &messageRead);
      if (status != 0)
        break;

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

      readCtx->currentLen = derElement->tlvLen;
      obj->state = VOLT_P7_STATE_SIGN_READ_SI;

      /* Move on to the next element.
       */
      message += messageRead;
      messageLen -= messageRead;
      VoltResetDerElement (derElement);
      if (messageLen == 0)
        break;

VoltP7StateSignReadSi:
    case VOLT_P7_STATE_SIGN_READ_SI:
      /* The next element is a SignerInfo
       */
      status = VoltGetNextDerElement (
        libCtx, message, messageLen, 0, VOLT_SEQUENCE_TAG, 1,
        derElement, &messageRead);
      if (status != 0)
        break;

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

      /* We kept the total length of all the SignerInfo's, now that
       * we've read one, subtract its length from the total. If that
       * was the last SignerInfo, set the state to indicate we're done
       * reading them.
       */
      readCtx->currentLen -= derElement->elementLen;
      if (readCtx->currentLen == 0)
        obj->state = VOLT_P7_STATE_SIGN_READ_COMPLETE;

      /* Add this cert to the list of SingerInfo's.
       */
      status = AddSignerInfoToList (
        libCtx, readCtx, derElement->element, derElement->elementLen);
      if (status != 0)
        break;

      /* There may be more SignerInfo's, we checked readCtx->currentLen
       * to see, if there are no more the state was set to
       * VOLT_P7_STATE_SIGN_READ_COMPLETE. If the state is not that
       * value, read another SignerInfo. If it is, we've read all there
       * is to read, decode the authenticated attributes.
       * Note from the programmer: Notice the goto statement.
       * Normally I don't like them, but in this case it really works.
       */
      if (obj->state == VOLT_P7_STATE_SIGN_READ_COMPLETE)
        break;

      /* Move on to the next element.
       */
      message += messageRead;
      messageLen -= messageRead;
      VoltResetDerElement (derElement);
      if (messageLen == 0)
        break;

      goto VoltP7StateSignReadSi;
  }

  return (status);
}

int VoltP7ReadSignedFinal (
   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_SIGN_READ_COMPLETE) ||
         (obj->state == VOLT_P7_STATE_SIGN_READ_FINAL) )
    {
      obj->state = VOLT_P7_STATE_SIGN_READ_FINAL;
      status = 0;
      break;
    }

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

    status = VoltP7ReadSignedUpdate (
      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_SIGN_READ_COMPLETE)
      break;

    obj->state = VOLT_P7_STATE_SIGN_READ_FINAL;
    status = 0;

  } while (0);

  return (status);
}

int VoltP7VerifySignerInfo (
   VtPkcs7Object pkcs7Obj,
   unsigned int index,
   VtPolicyCtx policyCtx,
   VtStorageCtx storageCtx,
   VtTransportCtx transportCtx,
   VtCertVerifyCtx certVerifyCtx,
   Pointer verifyCtxInfo,
   VtVerifyStack verifyStack,
   unsigned int *verifyResult
   )
{
  int status;
  unsigned int digestLen, newDigestLen, indexC;
  unsigned int attrCount, contentOidLen, sigResult;
  VoltPkcs7Object *obj = (VoltPkcs7Object *)pkcs7Obj;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VoltPkcs7ReadSignCtx *readCtx;
  VoltDigestClassCtx *digestCtx;
  VtMpIntCtx mpCtx;
  VtAlgorithmObject digestObj;
  VtDistrictObject district = (VtDistrictObject)0;
  Asn1SignerInfo *signerInfo;
  unsigned char *digest;
  unsigned char *contentOid;
  VoltCertObject *signerCert;
  VtCertObjectList *getCerts = (VtCertObjectList *)0;
  VtCertObjectList trustedCerts;
  VtCertObjectList untrustedCerts;
  VtCertInfo certInfo;
  VtSetAlgIdInfo algIdInfo;
  VtKeyObject pubKey = (VtKeyObject)0;
  VtAlgorithmObject verifier = (VtAlgorithmObject)0;
  VoltSurrenderCtx *surrCtx = (VoltSurrenderCtx *)0;
  unsigned char *newDigest = (unsigned char *)0;
  Asn1P9Attribute **authAttrs;
  VtSurrenderCallback surrenderCtx;

  *verifyResult = 0;
  do
  {
    /* We can do this only after all the data has been read.
     */
    status = VT_ERROR_INVALID_P7_OBJ;
    if (obj->contentType != VOLT_PKCS7_SIGNED_DATA_READ)
      break;

    readCtx = (VoltPkcs7ReadSignCtx *)(obj->localCtx);
    digestCtx = (VoltDigestClassCtx *)
      (((VoltAlgorithmObject *)(readCtx->digestObj))->classCtx);

    /* Get the requested SignerInfo.
     */
    status = VT_ERROR_INVALID_P7_OBJ;
    if (readCtx->signerInfosCount <= index)
      break;
    signerInfo = readCtx->signerInfos[index].signerInfo;

    /* We'll need a digest object and MpCtx.
     */
    digestObj = readCtx->digestObj;
    mpCtx = readCtx->mpCtx;

    /* Get the buffer that holds the digest of the data and the one
     * that holds the contentOid.
     */
    digest = readCtx->digest;
    digestLen = readCtx->digestLen;
    contentOid = readCtx->contentOid;
    contentOidLen = readCtx->contentOidLen;

    /* Put together a VtCertList of the untrusted certs (msgCerts).
     */
    untrustedCerts.certObjects = readCtx->msgCerts;
    untrustedCerts.count = readCtx->msgCertsCount;
    trustedCerts.certObjects = (VtCertObject *)0;
    trustedCerts.count = 0;

    /* Get the DerCoders array.
     */
    certInfo.derCoders = readCtx->DerCoders;
    certInfo.derCoderCount = readCtx->derCoderCount;

    /* Get the cert associated with this signer.
     */
    indexC = 0;
    status = VoltFindCertByReference (
      libCtx, VOLT_FIND_CERT_BY_ISSUER_SERIAL,
      signerInfo->issuerSerial->issuerName->base.data,
      (unsigned int)(signerInfo->issuerSerial->issuerName->base.length),
      signerInfo->issuerSerial->serialNumber->data,
      (unsigned int)(signerInfo->issuerSerial->serialNumber->length),
      &indexC, &untrustedCerts, (VtCertObject *)&signerCert);
    if (status != 0)
    {
      if (status != VT_ERROR_ENTRY_NOT_FOUND)
        break;

      /* Couldn't find the signer cert, id does not verify, but no
       * error.
       */
      status = 0;
      break;
    }

    /* Build a key object from this cert.
     */
    status = VtCreateKeyObject (
      (VtLibCtx)libCtx, VtKeyImplMpCtx, (Pointer)mpCtx, &pubKey);
    if (status != 0)
      break;

    certInfo.cert = signerCert->certificate.data;
    certInfo.certLen = signerCert->certificate.len;
    status = VtSetKeyParam (pubKey, VtKeyParamX509Cert, (Pointer)&certInfo);
    if (status != 0)
      break;

    /* Build an object that verifies.
     */
    algIdInfo.derCoders = certInfo.derCoders;
    algIdInfo.derCoderCount = certInfo.derCoderCount;
    algIdInfo.berEncoding = signerInfo->signatureAlg->base.data;
    algIdInfo.maxEncodingLen =
      (unsigned int)(signerInfo->signatureAlg->base.length);
    status = VtCreateAlgorithmObject (
      (VtLibCtx)libCtx, VtAlgorithmImplAlgId, (Pointer)&algIdInfo,
      &verifier);
    if (status != 0)
      break;

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

    /* Digest. First, get a buffer.
     */
    status = VT_ERROR_MEMORY;
    newDigestLen = digestLen;
    newDigest = (unsigned char *)Z2Malloc (newDigestLen, 0);
    if (newDigest == (unsigned char *)0)
      break;

    status = VtDigestInit (digestObj);
    if (status != 0)
      break;

    /* The authenticatedAttributes are IMPLICIT, but the standard
     * specifies digesting the regular tag (0x31) instead.
     */
    newDigest[0] = 0x31;
    status = VtDigestUpdate (digestObj, newDigest, 1);
    if (status != 0)
      break;

    /* Digest the rest, without the leading IMPLICIT (0xA0) tag.
     */
    status = VtDigestFinal (
      digestObj, signerInfo->authAttributes->base.data + 1,
      (unsigned int)(signerInfo->authAttributes->base.length - 1),
      newDigest, newDigestLen, &newDigestLen);
    if (status != 0)
      break;

    authAttrs = readCtx->signerInfos[index].authAttrs;
    attrCount =  readCtx->signerInfos[index].authAttrsCount;

    /* Verify that the authenticated attribute contentType matches
     * the contentType of the message.
     */
    status = VerifyAuthAttribute (
      libCtx, VOLT_P9_ATTRIBUTE_CONTENT_TYPE, authAttrs, attrCount,
      contentOid, contentOidLen);
    if (status != 0)
      break;

    /* Verify that the authenticated attribute messageDigest matches
     * the messageDigest of the regular message.
     */
    status = VerifyAuthAttribute (
      libCtx, VOLT_P9_ATTRIBUTE_DIGEST, authAttrs, attrCount,
      digest, digestLen);
    if (status != 0)
      break;

    /* Now that we have the algorithm and key objects, perform the
     * verification.
     */
    status = VtVerifySignature (
      verifier, pubKey, (VtRandomObject)0, digestCtx->algorithm,
      newDigest, newDigestLen, signerInfo->signature->data,
      (unsigned int)(signerInfo->signature->length), &sigResult);
    if (status != 0)
      break;

    /* If sigResult is not verified, we're done, no need to look
     * further.
     */
    if (sigResult == 0)
      break;

    /* Now verify the cert. In order to do that, get the trusted certs
     * from the district object. Get the district object based on the
     * district name in the signer cert.
     */
    status = VoltDistrictObjectFromCert (
      libCtx, (VtCertObject)signerCert, policyCtx, storageCtx, transportCtx,
      &district);

    /* If the above function failed, continue without the certs. But if
     * there is a district object, get the trusted certs out of it.
     */

    if (district != (VtDistrictObject)0)
    {

⌨️ 快捷键说明

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