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

📄 derhelp.c

📁 IBE是一种非对称密码技术
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
 */

#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "derhelp.h"
#include "errorctx.h"

/* Get the tag and length octets into the given buffer. If the buffer
 * is not big enough, realloc so that it is (of course, if it is
 * already big enough, no malloc or realloc is necessary).
 * <p>This function does not check the tag, it just places what is in
 * the tag position into the buffer.
 * <p>This function will not return an error if it encounters
 * indefinite length, it will simply return the tag and len.
 * <p>This function will return an error if the first length octet is
 * not valid (such as 0xC3 or 0x8D).
 * <p>The caller passes the buffer into which the function will place
 * the result, the size of the buffer, and the number of bytes in the
 * buffer. There may have been a previous call that deposited some of
 * the tag and len bytes into the buffer, but not all.
 * <p>The caller passes the address of the size, if this function needs
 * to realloc, it will deposit at the size address the new size.
 * <p>The length arg is also an address. The function will go to that
 * address to get the current length and will deposit at that address
 * the new length.
 * <p>The function will also return the number of bytes read.
 * <p>If the call completes the tag and len, it will set the unsigned
 * int at complete to 1. If not, it will set it to 0.
 * <p>This function will not check encoding and encodingLen, it is the
 * responsibility of the caller to pass in a valid pointer of length
 * not zero.
 * <p>Because the function might realloc, pass the address of the
 * buffer, not the buffer itself.
 */
static int VOLT_CALLING_CONV CollectTagAndLenRealloc VOLT_PROTO_LIST ((
   VoltLibCtx *libCtx,
   unsigned char *encoding,
   unsigned int encodingLen,
   unsigned char **buffer,
   unsigned int *bufferSize,
   unsigned int *bufferLen,
   unsigned int *bytesRead,
   unsigned int *complete
));

/* Store the given data in the element buffer of the derElement struct.
 * If the buffer is big enough already, just store the data and set the
 * elementLen. If the buffer is not big enough, realloc and store.
 * <p>This function will append data. That is, if the elementLen is not
 * 0, the routine will keep the old data, append the new data onto the
 * end and increment elementLen. If elementLen is 0, this routine will
 * store the input as a new element buffer.
 *
 * @param libCtx
 * @param derElement
 * @param dataToStore
 * @param dataToStoreLen
 * @return an int, 0 if the function completed successfully or a
 * non-zero error code.
 */
static int VOLT_CALLING_CONV StoreElementData VOLT_PROTO_LIST ((
   VoltLibCtx *libCtx,
   VoltDerElement *derElement,
   unsigned char *dataToStore,
   unsigned int dataToStoreLen
));

int VoltDecodeTagAndLen (
   VoltLibCtx *libCtx,
   unsigned char *encoding,
   unsigned int encodingLen,
   unsigned int *theTag,
   unsigned int *lengthLen,
   UInt32 *valueLenLo,
   UInt32 *valueLenHi,
   unsigned int sizeofResult
   )
{
  int status;
  unsigned int len, index;
  UInt32 val;
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_ENCODING;
    if (encoding == (unsigned char *)0)
      break;

    /* There must be at least 2 bytes, tag and len.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT_LENGTH;
    if (encodingLen < 2)
      break;

    *theTag = (unsigned int)(encoding[0]);
    len = (unsigned int)(encoding[1]);

    *valueLenHi = (UInt32)0;

    /* If the length octet is <= 0x80, it's the only length octet and it
     * is the return value for valueLenLo.
     */
    if (len <= 0x80)
    {
      status = 0;
      *lengthLen = 1;
      *valueLenLo = (UInt32)len;
      break;
    }

    /* The 1st length octet is > 0x80, it describes how many length octets
     * there are: 0x8i where i is the number of length octets in addition
     * to the 1st length octet.
     * If the first nibble is not 8, error.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_ENCODING;
    if ((len & 0xf0) != 0x80)
      break;

    len &= 0xf;

    /* If the caller put a limit on the size of the result, check to
     * see if the length exceeds that limit.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    if ( ((sizeofResult == 2) || (sizeofResult == 4)) && (len > sizeofResult) )
      break;

    /* Make sure the encoding has that many bytes (plus the tag and 1st
     * length octet).
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT_LENGTH;
    if (encodingLen < (len + 2))
      break;

    /* len now has the number of bytes that make up the actual length,
     * however, the lengthLen is the number of bytes needed to encode
     * the lenght, which includes the 0x8i.
     */
    *lengthLen = len + 1;

    /* Get the value length from the next len octets.
     */
    index = 2;
    val = 0;
    switch (len)
    {
      default:
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VT_ERROR_INVALID_ENCODING;
        break;

      case 8:
        val = (UInt32)(encoding[index]);
        val <<= 8;
        index++;

      case 7:
        val += (UInt32)(encoding[index]);
        val <<= 8;
        index++;

      case 6:
        val += (UInt32)(encoding[index]);
        val <<= 8;
        index++;

      case 5:
        val += (UInt32)(encoding[index]);
        index++;

        *valueLenHi = val;
        val = 0;

      case 4:
        val = (UInt32)(encoding[index]);
        val <<= 8;
        index++;

      case 3:
        val += (UInt32)(encoding[index]);
        val <<= 8;
        index++;

      case 2:
        val += (UInt32)(encoding[index]);
        val <<= 8;
        index++;

      case 1:
        val += (UInt32)(encoding[index]);

        *valueLenLo = val;
        status = 0;
    }

  } while (0);

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, libCtx, 0, status, 0, VT_ERROR_TYPE_PRIMARY,
    (char *)0, "VoltDecodeTagAndLen", fnctLine, (char *)0)

  return (status);
}

unsigned int VoltDetermineDerLengthLen (
   UInt32 valueLenLo,
   UInt32 valueLenHi
   )
{
  unsigned int retVal;
  UInt32 checkVal;

  retVal = 6;
  checkVal = valueLenHi;
  if (valueLenHi == 0)
  {
    if (valueLenLo <= 0x7f)
      return (1);

    retVal = 2;
    checkVal = valueLenLo;
  }

  /* Find the first byte in checkVal with something in it.
   */
  if ((checkVal & 0xffff0000) != 0)
  {
    checkVal >>= 16;
    retVal += 2;
  }
  if ((checkVal & 0xff00) != 0)
    retVal += 1;

  return (retVal);
}

unsigned int VoltWriteDerTagAndLen (
   unsigned char *buf,
   unsigned int tag,
   UInt32 valueLenLo,
   UInt32 valueLenHi
   )
{
  unsigned int count;
  UInt32 checkVal;

  buf[0] = (unsigned char)tag;

  count = 5;
  checkVal = valueLenHi;
  if (valueLenHi == 0)
  {
    if (valueLenLo <= 0x7f)
    {
      buf[1] = (unsigned char)valueLenLo;
      return (2);
    }

    count = 1;
    checkVal = valueLenLo;
  }

  /* Find the first byte in checkVal with something in it.
   */
  if ((checkVal & 0xffff0000) != 0)
  {
    checkVal >>= 16;
    count += 2;
  }
  if ((checkVal & 0xff00) != 0)
    count += 1;

  /* When the length is more than 0x7f, the first octet of length is
   * 0x8i, where i is the number of octets that make up the actual
   * length value.
   */
  buf[1] = (unsigned char)(count + 0x80);
  buf += 2;

  switch (count)
  {
    case 8:
      *buf = (unsigned char)(valueLenHi >> 24);
      buf++;

    case 7:
      *buf = (unsigned char)(valueLenHi >> 16);
      buf++;

    case 6:
      *buf = (unsigned char)(valueLenHi >> 8);
      buf++;

    case 5:
      *buf = (unsigned char)valueLenHi;
      buf++;

    case 4:
      *buf = (unsigned char)(valueLenLo >> 24);
      buf++;

    case 3:
      *buf = (unsigned char)(valueLenLo >> 16);
      buf++;

    case 2:
      *buf = (unsigned char)(valueLenLo >> 8);
      buf++;

    default:
      *buf = (unsigned char)valueLenLo;
  }

  return (count + 2);
}

#if VT_64_BIT_LENGTH == 64
#define VOLT_LEN_LIMIT 8
#else
#define VOLT_LEN_LIMIT 4
#endif

int VoltGetNextDerElement (
   VoltLibCtx *libCtx,
   unsigned char *encoding,
   unsigned  int encodingLen,
   unsigned int explicitTag,
   unsigned int expectedTag,
   unsigned int valueFlag,
   VoltDerElement *derElement,
   unsigned int *bytesRead
   )
{
  int status;
  unsigned int octetsRead, complete, lengthLen;
  UInt32 lenLo, lenHi;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  /* If there's nothing to read, or if it's already captured, there's
   * nothing to do.
   */
  *bytesRead = 0;
  if ( (encodingLen == 0) || (derElement->complete != 0) )
    return (0);

  do
  {
    /* If there's an EXPLICIT tag, and it has not been collected yet,
     * collect it.

⌨️ 快捷键说明

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