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

📄 asn1types.c

📁 IBE是一种非对称密码技术
💻 C
📖 第 1 页 / 共 3 页
字号:
   */
  status = VoltDecodeTagAndLen (
    (VoltLibCtx *)0, encoding, length, &theTag, &lengthLen, &lenLo, &lenHi,
    sizeof (unsigned int));
  if (status != 0)
    return (0);

  valueLen = (unsigned int)lenLo;

  /* Is the encoding big enough for the alleged lengths?
   */
  totalLen = lengthLen + valueLen + 1;
  if (length < (long)totalLen)
    return (0);

  /* Make sure the tag is OCTET STRING or IMPLICIT (if necessary).
   */
  theTag = 4;
  if (tag != -1)
    theTag = aclass | tag;
  if (encoding[0] != (unsigned char)theTag)
    return (0);

  encoding += (1 + lengthLen);

  /* The OpenSSL engine requires moving the input pointer along.
   */
  (*input) += totalLen;

  /* If there is no algorithm object, just copy the data.
   */
  if (value->cipherObj == (VtAlgorithmObject)0)
  {
    /* If copy by ref, copy the addresses, if copy by value, allocate and
     * copy.
     */
    if ((value->vFlags & VOLT_ASN1_COPY_MASK) == VOLT_ASN1_COPY_DATA)
    {
      value->base.data = (unsigned char *)OPENSSL_malloc (valueLen);
      if (value->base.data == (unsigned char *)0)
        return (0);

      Asn1Memcpy (value->base.data, encoding, valueLen);
    }
    else
    {
      value->base.data = encoding;
    }

    value->base.length = (int)valueLen;

    return (1);
  }

  /* How long is the decrypted data.
   */
  status = VtDecryptFinal (
    value->cipherObj, value->random, encoding, valueLen,
    (unsigned char *)0, 0, &decryptLen);
  if (status != VT_ERROR_BUFFER_TOO_SMALL)
    return (0);

  /* At this point we can't copy by reference. Go ahead and allocate.
   * Set the vFlags.
   */
  if ((value->vFlags & VOLT_ASN1_COPY_MASK) != VOLT_ASN1_COPY_DATA)
  {
    value->vFlags ^= VOLT_ASN1_COPY_REFERENCE;
    value->vFlags |= VOLT_ASN1_COPY_DATA;
  }

  value->base.data = (unsigned char *)OPENSSL_malloc (decryptLen);
  if (value->base.data == (unsigned char *)0)
    return (0);

  status = VtDecryptFinal (
    value->cipherObj, value->random, encoding, valueLen,
    value->base.data, decryptLen, &decryptLen);
  if (status != 0)
    return (0);

  value->base.length = (int)decryptLen;

  /* Clear the context.
   */
  ctx->valid = 0;
  ctx->ret = 0;
  ctx->plen = 0;
  ctx->ptag = 0;
  ctx->pclass = 0;
  ctx->hdrlen = 0;

  return (1);
}

int Asn1EncryptedContentEncode (
   ASN1_VALUE **obj,
   unsigned char **output,
   const ASN1_ITEM *asn1Item,
   int tag,
   int aclass
   )
{
  int status;
  unsigned int valueLen, totalLen, theTag;
  Asn1EncryptedContent *value;  
  unsigned char *encoding;

  if (obj == (ASN1_VALUE **)0)
    return (0);
  if (*obj == (ASN1_VALUE *)0)
    return (0);

  value = (Asn1EncryptedContent *)(*obj);

  value->vFlags |= VOLT_ASN1_COPY_FLAG_FIXED;

  /* We can call this if the object is SET or has been initialized for
   * Encryption/Encoding. Use totalLen as a temp variable.
   */
  totalLen = VOLT_ENC_CONTENT_STATE_MASK & value->state;
  if ( (totalLen == VOLT_ENC_CONTENT_STATE_CREATE) ||
       (totalLen == VOLT_ENC_CONTENT_STATE_INIT_D) )
    return (0);

  if (totalLen == VOLT_ENC_CONTENT_STATE_SET)
  {
    status = VtEncryptInit (value->cipherObj, value->keyObj);
    if (status != 0)
      return (0);
    value->state ^= totalLen;
    value->state |= VOLT_ENC_CONTENT_STATE_INIT_E;
  }

  /* How big will the output be?
   */
  status = VtEncryptFinal (
    value->cipherObj, value->random, value->base.data,
    (unsigned int)(value->base.length), (unsigned char *)0, 0, &valueLen);
  if (status != VT_ERROR_BUFFER_TOO_SMALL)
    return (0);

  totalLen =
    valueLen + VoltDetermineDerLengthLen ((UInt32)valueLen, (UInt32)0) + 1;

  /* If there's no pointer to output, just indicate the length.
   */
  if (output == (unsigned char **)0)
    return (totalLen);

  /* If the caller supplied no buffer, don't do anything.
   */
  if (*output == (unsigned char *)0)
    return (0);

  /* If the caller supplied a pointer, but no buffer, don't do anything.
   */
  if (*output == (unsigned char *)0)
    return (0);

  encoding = *output;

  /* Write the tag and len. The tag is OCTET STRING, unless IMPLICIT.
   */
  theTag = 4;
  if (tag != -1)
    theTag = aclass | tag;
  encoding += VoltWriteDerTagAndLen (
    encoding, theTag, (UInt32)valueLen, (UInt32)0);

  /* Encrypt into the buffer.
   */
  status = VtEncryptFinal (
    value->cipherObj, value->random, value->base.data,
    (unsigned int)(value->base.length), encoding, valueLen, &valueLen);
  if (status != 0)
    return (0);

  /* The OpenSSL engine requires moving the output pointer along.
   */
  (*output) += totalLen;
  return (totalLen);
}

int Asn1CommonNew (
   ASN1_VALUE **obj,
   const ASN1_ITEM *asn1Item
   )
{
  VoltAsn1String *retVal = (VoltAsn1String *)0;

  if (obj == (ASN1_VALUE **)0)
    return (0);
  *obj = (ASN1_VALUE *)0;

  /* Build an empty VoltAsn1String struct.
   */
  retVal = (VoltAsn1String *)OPENSSL_malloc (sizeof (VoltAsn1String));
  if (retVal == (VoltAsn1String *)0)
    return (0);

  retVal->base.length = 0;
  retVal->base.type = 0;
  retVal->base.data = (unsigned char *)0;
  retVal->base.flags = 0;
  retVal->vFlags = 0;
  *obj = (ASN1_VALUE *)retVal;

  return (1);
}

void Asn1CommonFree (
   ASN1_VALUE **obj,
   const ASN1_ITEM *asn1Item
   )
{
  VoltAsn1String *value;

  /* Anything to free?
   */
  if (obj == (ASN1_VALUE **)0)
    return;
  if (*obj == (ASN1_VALUE *)0)
    return;

  value = (VoltAsn1String *)(*obj);

  /* If copy by value, overwrite and free.
   */
  if ((value->vFlags & VOLT_ASN1_COPY_MASK) == VOLT_ASN1_COPY_DATA)
  {
    if (value->base.data != (unsigned char *)0)
    {
      Asn1Memset (value->base.data, 0, (unsigned int)(value->base.length));
      OPENSSL_free (value->base.data);
    }
  }
  OPENSSL_free (value);
  *obj = (ASN1_VALUE *)0;
}

void Asn1CommonClear (
   ASN1_VALUE **obj,
   const ASN1_ITEM *asn1Item
   )
{
  VoltAsn1String *value;

  /* Anything to free?
   */
  if (obj == (ASN1_VALUE **)0)
    return;
  if (*obj == (ASN1_VALUE *)0)
    return;

  value = (VoltAsn1String *)(*obj);

  /* If copy by value, overwrite and free.
   */
  if ((value->vFlags & VOLT_ASN1_COPY_MASK) == VOLT_ASN1_COPY_DATA)
  {
    if (value->base.data != (unsigned char *)0)
    {
      Asn1Memset (value->base.data, 0, (unsigned int)(value->base.length));
      OPENSSL_free (value->base.data);
    }
  }
  value->base.data = (unsigned char *)0;
  value->base.length = 0;
}

int Asn1CommonSet (
   VoltAsn1String *value,
   unsigned char *data,
   unsigned int len
   )
{
  if (value == (VoltAsn1String *)0)
    return (0);

  Asn1CommonClear ((ASN1_VALUE **)&value, (const ASN1_ITEM *)0);
  value->vFlags |= VOLT_ASN1_COPY_FLAG_FIXED;

  if ( (data == (unsigned char *)0) || (len == 0) )
    return (1);

  /* If copy by ref, copy the addresses, if copy by value, allocate and
   * copy.
   */
  if ((value->vFlags & VOLT_ASN1_COPY_MASK) == VOLT_ASN1_COPY_DATA)
  {
    value->base.data = (unsigned char *)OPENSSL_malloc (len);
    if (value->base.data == (unsigned char *)0)
      return (0);
    Asn1Memcpy (value->base.data, data, len);
  }
  else
  {
    value->base.data = data;
  }
  value->base.length = len;

  return (1);
}

int Asn1CommonDecode (
   ASN1_VALUE **obj,
   const unsigned char **input,
   long length,
   const ASN1_ITEM *asn1Item,
   int tag,
   int aclass,
   char opt,
   ASN1_TLC *ctx
   )
{
  int status, asn1Ret;
  unsigned int lengthLen, valueLen, totalLen, theTag;
  UInt32 lenLo, lenHi;
  VoltAsn1String *value = (VoltAsn1String *)0;
  unsigned char *encoding = (unsigned char *)(*input);

  if (obj == (ASN1_VALUE **)0)
    return (0);
  if (*obj != (ASN1_VALUE *)0)
    value = (VoltAsn1String *)(*obj);

  Asn1CommonClear (obj, asn1Item);

  /* What are the lengths?
   */
  status = VoltDecodeTagAndLen (
    (VoltLibCtx *)0, encoding, length, &theTag, &lengthLen, &lenLo, &lenHi,
    sizeof (unsigned int));
  if (status != 0)
    return (0);

  valueLen = (unsigned int)lenLo;

  /* Is the encoding big enough for the alleged lengths?
   */
  totalLen = lengthLen + valueLen + 1;
  if (length < (long)totalLen)
    return (0);

  /* The OpenSSL engine requires moving the input pointer along.
   */
  (*input) += totalLen;

  /* If there is an underlying type, copy only the value. If not, copy
   * everything.
   */
  if (asn1Item->utype != 0)
  {
    /* Make sure the tag in the encoding is what we're expecting.
     */
    theTag = (unsigned int)(asn1Item->utype);
    if (tag != -1)
      theTag = aclass | tag;
    if (encoding[0] != (unsigned char)theTag)
      return (0);
    totalLen = valueLen;
    encoding += (1 + lengthLen);
  }

  /* Is there an object? If not, create one.
   */
  if (value == (VoltAsn1String *)0)
  {
    asn1Ret = Asn1CommonNew ((ASN1_VALUE **)&value, asn1Item);
    if (asn1Ret != 1)
      return (0);
    *obj = (ASN1_VALUE *)value;
  }
  value->vFlags |= VOLT_ASN1_COPY_FLAG_FIXED;

  /* If copy by ref, copy the addresses, if copy by value, allocate and
   * copy.
   */
  if ((value->vFlags & VOLT_ASN1_COPY_MASK) == VOLT_ASN1_COPY_DATA)
  {
    /* Copy into the object.
     */
    value->base.data = (unsigned char *)OPENSSL_malloc (totalLen);
    if (value->base.data == (unsigned char *)0)
      return (0);

    Asn1Memcpy (value->base.data, encoding, totalLen);
  }
  else
  {
    value->base.data = encoding;
  }

  value->base.length = (int)totalLen;

  /* Clear the context.
   */
  ctx->valid = 0;
  ctx->ret = 0;
  ctx->plen = 0;
  ctx->ptag = 0;
  ctx->pclass = 0;
  ctx->hdrlen = 0;

  return (1);
}

int Asn1CommonEncode (
   ASN1_VALUE **obj,
   unsigned char **output,
   const ASN1_ITEM *asn1Item,
   int tag,
   int aclass
   )
{
  unsigned int totalLen, theTag;
  VoltAsn1String *value = (VoltAsn1String *)(*obj);  
  unsigned char *encoding;

  value->vFlags |= VOLT_ASN1_COPY_FLAG_FIXED;

  /* If there is an underlying type, encode the tag and length.
   */
  totalLen = (unsigned int)(value->base.length);
  if (asn1Item->utype != 0)
  {
    totalLen += VoltDetermineDerLengthLen ((UInt32)totalLen, (UInt32)0) + 1;
    /* Is this implicit?
     */
    theTag = (unsigned int)(asn1Item->utype);
    if (tag != -1)
      theTag = aclass | tag;
  }

  /* If there's no pointer to output, just indicate the length.
   */
  if (output == (unsigned char **)0)
    return (totalLen);

  /* If the caller supplied no buffer, don't do anything.
   */
  if (*output == (unsigned char *)0)
    return (0);

  encoding = *output;

  /* If there is an underlying type, write the tag and len.
   */
  if (asn1Item->utype != 0)
    encoding += VoltWriteDerTagAndLen (
      encoding, theTag, (UInt32)(value->base.length), (UInt32)0);

  /* Simply copy the data into the buffer.
   */
  if ( (value->base.data != (unsigned char *)0) && (value->base.length != 0) )
    Asn1Memcpy (
      encoding, value->base.data, (unsigned int)(value->base.length));

  /* The OpenSSL engine requires moving the output pointer along.
   */
  (*output) += totalLen;
  return (totalLen);
}

void Asn1SetObjectCopyFlag (
   VoltAsn1String *asn1Obj,
   unsigned int copyFlag
   )
{
  unsigned int theFlag;

  /* Examine only the COPY bits.
   */
  theFlag = copyFlag & VOLT_ASN1_COPY_MASK;

  if (asn1Obj == (VoltAsn1String *)0)
    return;

  /* If the vFlags says the copy flag is FIXED, don't do anything.
   */
  if ((asn1Obj->vFlags & VOLT_ASN1_COPY_FLAG_FIXED) != 0)
    return;

  theFlag = VOLT_ASN1_COPY_DATA;
  if (copyFlag != VOLT_ASN1_COPY_DATA)
    theFlag = VOLT_ASN1_COPY_REFERENCE;

  asn1Obj->vFlags |= theFlag;
}

void Asn1Memcpy (
   unsigned char *dest,
   unsigned char *source,
   unsigned int count
   )
{
  unsigned int index;

  if ( (source == (unsigned char *)0) ||
    (dest == (unsigned char *)0) ||
    (count == 0) )
    return;

  /* Not the most efficient, but portable (no system calls).
   */
  for (index = 0; index < count; ++index)
    dest[index] = source[index];
}

void Asn1Memset (
   unsigned char *dest,
   unsigned int value,
   unsigned int count
   )
{
  unsigned int index;
  unsigned char val;

  if ( (dest == (unsigned char *)0) ||
    (count == 0) )
    return;

  /* Not the most efficient, but portable (no system calls).
   */
  val = (unsigned char)value;
  for (index = 0; index < count; ++index)
    dest[index] = val;
}

⌨️ 快捷键说明

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