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

📄 writesign.c

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

    /* Extract the issuerName and serialNum from the signingCert.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VoltDecodeX509CertCreate (
      libCtx, signerInfo->cert.data, signerInfo->cert.len, &x509Cert);
    if (status != 0)
      break;

    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    if (Asn1Encoded_set (
      newObj->issuerSerial->issuerName, x509Cert->innerCert->issuer->base.data,
      (unsigned int)(x509Cert->innerCert->issuer->base.length)) != 1)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    if (ASN1_STRING_set (
      newObj->issuerSerial->serialNumber,
      x509Cert->innerCert->serialNum->data,
      (unsigned int)(x509Cert->innerCert->serialNum->length)) != 1)
      break;

    /* We don't have the authenticated attributes or the signature yet,
     * but we can put some placeholders there.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = BuildAuthAttributes (
      p7Obj, VT_PKCS7_DATA, digestBuf, digestLen, &(signCtx->signingTime),
      (unsigned char *)0, 0, &authAttrsLen);
    if (status == 0)
      status = VT_ERROR_GENERAL;
    if (status != VT_ERROR_BUFFER_TOO_SMALL)
      break;

    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    authAttrs = (unsigned char *)Z2Malloc (authAttrsLen, 0);
    if (authAttrs == (unsigned char *)0)
      break;

    /* Because authenticated attributes is OPTIONAL, the OpenSSL ASN.1
     * engine did not create the Asn1Encoded object.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    newObj->authAttributes = Asn1Encoded_new ();
    if (newObj->authAttributes == (Asn1Encoded *)0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    if (Asn1Encoded_set (
      newObj->authAttributes, authAttrs, authAttrsLen) != 1)
      break;

    /* Build the signer object, use signatureLen as a temp
     * variable to pass in the format.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    signatureLen = VT_DSA_SIGNATURE_DER_ENCODED;
    status = VtCreateAlgorithmObject (
      (VtLibCtx)libCtx, VtAlgorithmImplDSASign, (Pointer)&signatureLen,
      &(signerInfo->signObj));
    if (status != 0)
      break;

    /* If there's a surrender ctx, get it to pass along to signers.
     */
    if (surrCtx != (VoltSurrenderCtx *)0)
    {
      /* Set the signing 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;
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtSetAlgorithmParam (
        signerInfo->signObj, VtAlgorithmParamSurrenderCallback,
        (Pointer)&surrenderCtx);
      if (status != 0)
        break;
    }

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtSign (
      signerInfo->signObj, signerInfo->priKeyRef, random,
      digestCtx->algorithm, (unsigned char *)signCtx, signCtx->digestSize,
      (unsigned char *)0, 0, &signatureLen);
    if (status == 0)
      status = VT_ERROR_GENERAL;
    if (status != VT_ERROR_BUFFER_TOO_SMALL)
      break;

    /* Allocate the signature buffer.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    signerInfo->signature = (unsigned char *)Z2Realloc (
      signerInfo->signature, signatureLen);
    if (signerInfo->signature == (unsigned char *)0)
      break;
    signerInfo->sigBufSize = signatureLen;

    VOLT_SET_FNCT_LINE (fnctLine)
    if (ASN1_OCTET_STRING_set (
      newObj->signature, signerInfo->signature, (int)signatureLen) != 1)
      break;

    /* Encode with a NULL output buffer to get the length.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT;
    signerInfo->signerInfoLen = i2d_Asn1SignerInfo (
      newObj, (unsigned char **)0);
    if (signerInfo->signerInfoLen == 0)
      break;

    signerInfo->asn1SignerInfo = newObj;

    status = 0;

  } while (0);

  if (x509Cert != (Asn1X509Cert *)0)
    Asn1X509Cert_free (x509Cert);
  if (authAttrs != (unsigned char *)0)
    Z2Free (authAttrs);

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

  /* If error, destroy what we created.
   */
  if (newObj != (Asn1SignerInfo *)0)
    Asn1SignerInfo_free (newObj);

  VOLT_LOG_ERROR_INFO (
    0, p7Obj, status, 0, errorType,
    (char *)0, "BuildSignerInfoCreate", fnctLine, (char *)0)

  return (status);
}

#define VOLT_CONTENT_TYPE_ATTR_LEN \
    VoltP9AtContentTypeOidBytesLen+VoltP7DataOidBytesLen+8

static int BuildAuthAttributes (
   VoltPkcs7Object *p7Obj,
   unsigned int contentType,
   unsigned char *contentDigest,
   unsigned int contentDigestLen,
   VtTime *theTime,
   unsigned char *authAttrs,
   unsigned int bufferSize,
   unsigned int *authAttrsLen
   )
{
  int status;
  unsigned int contentAttrLen, timeAttrLen, digestAttrLen;
  unsigned int encodingLen, lengthLen;
  VoltLibCtx *libCtx = (VoltLibCtx *)(p7Obj->voltObject.libraryCtx);
  unsigned char *temp;
  unsigned char contentTypeAttr[VOLT_CONTENT_TYPE_ATTR_LEN] =
  {
    0x30, VoltP9AtContentTypeOidBytesLen + VoltP7DataOidBytesLen + 6,
    0x06, VoltP9AtContentTypeOidBytesLen,
    VoltP9AtContentTypeOidBytes,
    0x31, VoltP7DataOidBytesLen + 2, 0x06, VoltP7DataOidBytesLen,
    VoltP7DataOidBytes
  };
  unsigned char signTimeOid[VoltP9AtSignTimeOidBytesLen] =
    { VoltP9AtSignTimeOidBytes };
  unsigned char digestAttrOid[VoltP9AtDigestOidBytesLen] =
    { VoltP9AtDigestOidBytes };
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* We're going to build
     *
     *    31 len
     *       30 len -- contentType attribute
     *       30 len -- signingTime attribute
     *       30 len -- digest attribute
     *
     * First, figure out how long each of the attributes will be. The
     * contentType attribute is a fixed size, the signingTime attribute
     * is one of two sizes depending on whether we use UTCTime or
     * GeneralizedTime, and the digest attribute size depends on the
     * incoming digest len.
     */
    contentAttrLen = VOLT_CONTENT_TYPE_ATTR_LEN;
    timeAttrLen = VoltP9AtSignTimeOidBytesLen + VOLT_UTC_LEN + 8;
    if (theTime->year >= 2050)
      timeAttrLen += (VOLT_GEN_LEN - VOLT_UTC_LEN);

    /* Assume the digestLen is not > 0x70 (112 bytes = 896 bits). If
     * the toolkit ever supports such a digest (at the time of the
     * first release, the largest possible digest it might support is
     * 512 bits: SHA-512), this code will have to change.
     * If there is a digest > 0x70, the SEQUENCE len will be more than
     * 0x7f and will need a 2-byte length.
     * The length is 2 bytes for the 30 len, 11 bytes for the
     * 06 09 <pkcs-9-at-messageDigset>, 4 bytes for the
     * 31 len 04 len in front of the digest, plus the digestLen bytes
     */
    digestAttrLen = VoltP9AtDigestOidBytesLen + contentDigestLen + 8;
    encodingLen = contentAttrLen + timeAttrLen + digestAttrLen;

    /* Determine the lengthLen of the outer SET OF.
     */
    lengthLen = VoltDetermineDerLengthLen ((UInt32)encodingLen, (UInt32)0);

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_BUFFER_TOO_SMALL;
    *authAttrsLen = 1 + lengthLen + encodingLen;
    if (bufferSize < *authAttrsLen)
      break;

    /* Write out the encoding.
     * First, the outer SET OF (IMPLICIT).
     */
    temp = authAttrs;
    temp += VoltWriteDerTagAndLen (temp, 0xa0, (UInt32)encodingLen, (UInt32)0);
    Z2Memcpy (temp, contentTypeAttr, sizeof (contentTypeAttr));
    temp += (sizeof (contentTypeAttr) - 1);
    /* The contentTypeAttr buffer contains the OID for P7 Data. If the
     * contentType flag passed in is not Data, change it.
     */
    *temp = (unsigned char)contentType;
    temp++;

    /* Write the signingTime attribute. Lengths are different depending
     * on the year.
     */
    temp += VoltWriteDerTagAndLen (
      temp, 0x30, (UInt32)(timeAttrLen - 2), (UInt32)0);
    temp += VoltWriteDerTagAndLen (
      temp, 0x06, (UInt32)VoltP9AtSignTimeOidBytesLen, (UInt32)0);
    Z2Memcpy (temp, signTimeOid, VoltP9AtSignTimeOidBytesLen);
    temp += VoltP9AtSignTimeOidBytesLen;
    if (theTime->year < 2050)
    {
      temp += VoltWriteDerTagAndLen (
        temp, 0x31, (UInt32)(VOLT_UTC_LEN + 2), (UInt32)0);
      temp += VoltWriteDerTagAndLen (
        temp, 0x17, (UInt32)VOLT_UTC_LEN, (UInt32)0);
      temp += VoltConvertVtTimeToUTC (theTime, temp);
    }
    else
    {
      temp += VoltWriteDerTagAndLen (
        temp, 0x31, (UInt32)(VOLT_GEN_LEN + 2), (UInt32)0);
      temp += VoltWriteDerTagAndLen (
        temp, 0x18, (UInt32)VOLT_GEN_LEN, (UInt32)0);
      temp += VoltConvertVtTimeToGen (theTime, temp);
    }

    /* Write out the digest attribute.
     */
    temp += VoltWriteDerTagAndLen (
      temp, 0x30, (UInt32)(digestAttrLen - 2), (UInt32)0);
    temp += VoltWriteDerTagAndLen (
      temp, 0x06, (UInt32)VoltP9AtDigestOidBytesLen, (UInt32)0);
    Z2Memcpy (temp, digestAttrOid, VoltP9AtDigestOidBytesLen);
    temp += VoltP9AtDigestOidBytesLen;
    temp += VoltWriteDerTagAndLen (
      temp, 0x31, (UInt32)(contentDigestLen + 2), (UInt32)0);
    temp += VoltWriteDerTagAndLen (
      temp, 0x04, (UInt32)contentDigestLen, (UInt32)0);
    Z2Memcpy (temp, contentDigest, contentDigestLen);

    status = 0;

  } while (0);

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, 0, p7Obj, status, 0, VT_ERROR_TYPE_PRIMARY,
    (char *)0, "BuildAuthAttributes", fnctLine, (char *)0)

  return (status);
}

static void FixDsaSignature (
   VoltLibCtx *libCtx,
   unsigned char *signature,
   unsigned int sigBufSize,
   unsigned int *signatureLen
   )
{
  unsigned char *rVal, *sVal;
  unsigned int rLen, sLen, offset;
  unsigned char tempBuf[48] =
  {
    0x30, 0x2e, 0x02, 0x15, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x02, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  };

  /* The rLen will be the 4th byte (index 3) always.
   * rVal will always begin on the 5th byte (index 4).
   */
  rLen = signature[3];
  rVal = signature + 4;

  /* Now move rLen bytes from rVal to find sLen and sVal.
   */
  sLen = signature[rLen + 5];
  sVal = signature + rLen + 6;

  /* Build a signature with appropriate lengths and leading 00 octets.
   */
  offset = 4;
  offset += (21 - rLen);
  Z2Memcpy (tempBuf + offset, rVal, rLen);
  offset = 27;
  offset += (21 - sLen);
  Z2Memcpy (tempBuf + offset, sVal, sLen);
  Z2Memcpy (signature, tempBuf, 48);
  *signatureLen = 48;
}

⌨️ 快捷键说明

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