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

📄 icdistrict.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 "icdistrict.h"
#include "icparams.h"
#include "icutils.h"
#include "stringutil.h"
#include "certobj.h"
#include "errorctx.h"
#include "transport.h"

/* Function takes Asn1 certificate object and fills icDistrictParameter
 * last cert in the chain with a certificate
 */
static int VOLT_CALLING_CONV icDistrictParametersGetDomainCert VOLT_PROTO_LIST ((
   icDistrictParameters *params,
   Asn1X509Cert **getCert,
   VoltLibCtx *libCtx
));

/* Go to the address given and count how many new line characters are
 * there. This counts the number of bytes, not the number of new lines.
 * For example,
 *    0d 0a 0d 0a
 * is 4 chars.
 * <p>This function looks for 0a or 0d 0a.
 */
static unsigned int VOLT_CALLING_CONV CountNewLineChars VOLT_PROTO_LIST ((
   char *buffer
));

#define VOLT_P7_HEADER        "-----BEGIN PKCS7-----"
#define VOLT_P7_HEADER_LEN    21
#define VOLT_P7_FOOTER        "-----END PKCS7-----"
#define VOLT_P7_FOOTER_LEN    19
#define VOLT_CERT_HEADER      "-----BEGIN CERTIFICATE-----"
#define VOLT_CERT_HEADER_LEN  27
#define VOLT_CERT_FOOTER      "-----END CERTIFICATE-----"
#define VOLT_CERT_FOOTER_LEN  25

int icDistrictParametersNew (
   icDistrictParameters **distParams,
   char *paramsText,
   unsigned int paramsTextLen,
   VtMpIntCtx mpCtx,
   VoltLibCtx *libCtx)
{
  int status;
  unsigned int p7Len, certLen, newLineLen, certCount, index;
  unsigned int signDataLen, theDataLen, certDataLen, bufferSize, bytesRead;
  unsigned int derCoderCount, decoderCount;
  VtPkcs7Object p7SignReader = (VtPkcs7Object)0;
  VtCertObject *newList = (VtCertObject *)0;
  VtCertObject *certList = (VtCertObject *)0;
  icDistrictParameters *params = (icDistrictParameters *)0;
  unsigned char *signData = (unsigned char *)0;
  unsigned char *theData = (unsigned char *)0;
  unsigned char *certData = (unsigned char *)0;
  unsigned char *temp;
  char *foundAddress, *p7, *cert;
  char *p7Header = VOLT_P7_HEADER;
  char *p7Footer = VOLT_P7_FOOTER;
  char *certHeader = VOLT_CERT_HEADER;
  char *certFooter = VOLT_CERT_FOOTER;
  VtReadPkcs7Info p7Info;
  VtCertInfo certInfo;
  VtDerCoder *DerCoders[3] =
  {
    VtDerCoderSHA1,
    VtDerCoderDSAPublicKey,
    VtDerCoderDSAwSHA1
  };
  VtIdentitySchemaDecode *Decoders[1] =
  {
    VtIdentitySchemaDecode822Email
  };
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  derCoderCount = 3;
  decoderCount = 1;
  certCount = 0;

  certInfo.derCoders = DerCoders;
  certInfo.derCoderCount = derCoderCount;

  do
  {
    /* We're expecting the following.
     *    -----BEGIN PKCS7-----
     *      <params in base64>
     *    -----END PKCS7-----
     *    -----BEGIN CERTIFICATE-----
     *      <a cert in base64>
     *    -----END CERTIFICATE-----
     *    -----BEGIN CERTIFICATE-----
     *      <another cert in base64>
     *    -----END CERTIFICATE-----
     * Make sure they are there.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_DIST_PARAMS;
    if (paramsTextLen < VOLT_P7_HEADER_LEN)
      break;
    if (Z2Memcmp (paramsText, p7Header, VOLT_P7_HEADER_LEN) != 0)
      break;

    p7 = paramsText + VOLT_P7_HEADER_LEN;
    newLineLen = CountNewLineChars (p7);
    p7 += newLineLen;

    VOLT_SET_FNCT_LINE (fnctLine)
    foundAddress = Strstr (p7, p7Footer, libCtx);
    if (foundAddress == (char *)0)
      break;

    p7Len = foundAddress - p7;

    /* Point to what follows the P7 message, it should be a cert. We'll
     * get to it later.
     */
    cert = p7 + p7Len + VOLT_P7_FOOTER_LEN;
    newLineLen = CountNewLineChars (cert);
    cert += newLineLen;
    certLen = paramsTextLen - (cert - paramsText);

    /* Before we actually get to the certs, read the P7 message.
     * Base64 decode what we have, it should be the actual P7
     * SignedData.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = icBase64Decode (
      &signData, &signDataLen, (unsigned char *)p7, p7Len, libCtx);
    if (status != 0)
      break;

    /* Decode the P7 SignedData message.
     */
    p7Info.derCoders = DerCoders;
    p7Info.derCoderCount = derCoderCount;
    p7Info.decoders = Decoders;
    p7Info.decoderCount = decoderCount;
    p7Info.mpCtx = mpCtx;
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtCreatePkcs7Object (
      (VtLibCtx)libCtx, VtPkcs7ImplReadSignedData, (Pointer)&p7Info,
      &p7SignReader);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtPkcs7ReadInit (p7SignReader);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtPkcs7ReadFinal (
      p7SignReader, signData, signDataLen, &bytesRead,
      (unsigned char *)0, 0, &bufferSize);
    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;
    theData = (unsigned char *)Z2Malloc (bufferSize, VOLT_MEMORY_SENSITIVE);
    if (theData == (unsigned char *)0)
      break;

    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtPkcs7ReadFinal (
      p7SignReader, signData + bytesRead, signDataLen - bytesRead, &bytesRead,
      theData, bufferSize, &theDataLen);
    if (status != 0)
      break;

    /* We are expecting certs, keep reading data as long as we have
     * certs to read.
     */
    do
    {
      if (certLen < VOLT_CERT_HEADER_LEN)
        break;
      if (Z2Memcmp (cert, certHeader, VOLT_CERT_HEADER_LEN) != 0)
        break;

      cert += VOLT_CERT_HEADER_LEN;
      newLineLen = CountNewLineChars (cert);
      cert += newLineLen;

      foundAddress = Strstr (cert, certFooter, libCtx);
      if (foundAddress == (char *)0)
        break;

      certLen = foundAddress - cert;

      /* Expand the certList array.
       */
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_MEMORY;
      newList = (VtCertObject *)Z2Malloc (
        (certCount + 1) * sizeof (VtCertObject), 0);
      if (newList == (VtCertObject *)0)
        break;
      status = 0;

      /* Copy the old into the new.
       */
      for (index = 0; index < certCount; ++index)
        newList[index] = certList[index];

      newList[certCount] = (VtCertObject)0;

      /* Free the old.
       */
      if (certList != (VtCertObject *)0)
        Z2Free (certList);

      certList = newList;
      index = certCount;
      certCount++;
      newList = (VtCertObject *)0;

      /* Base64 decode the cert data.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = icBase64Decode (
        &certData, &certDataLen, cert, certLen, libCtx);
      if (status != 0)
        break;

      /* Build a cert object from this data.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtCreateCertObject (
        (VtLibCtx)libCtx, VtCertImplMpCtx, (Pointer)mpCtx,
        &(certList[index]));
      if (status != 0)
        break;

      certInfo.cert = certData;
      certInfo.certLen = certDataLen;
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtSetCertParam (
        certList[index], VtCertParamX509Der, (Pointer)&certInfo);
      if (status != 0)
        break;

      /* Free this buffer because on the next loop we're going to use
       * this variable again.
       */
      Z2Free (certData);
      certData = (unsigned char *)0;

      /* Move the pointer to the next cert.
       */
      cert += (certLen + VOLT_CERT_FOOTER_LEN);
      newLineLen = CountNewLineChars (cert);
      cert += newLineLen;

      certLen = paramsTextLen - (cert - paramsText);

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

    /* Allocate space for new icDistricParameter shell.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    params = (icDistrictParameters *)Z2Malloc (
      sizeof (icDistrictParameters), 0);
    if (params == (icDistrictParameters *)0)
      break;
    Z2Memset (params, 0, sizeof (icDistrictParameters));

    /* Decode the public params.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    params->pubParams = icPublicParameters_new ();
    if (params->pubParams == (icPublicParameters *)0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_DIST_PARAMS;
    temp = theData;
    d2i_icPublicParameters (&(params->pubParams), &temp, theDataLen);
    if (params->pubParams == (icPublicParameters *)0)
      break;

    params->certList = certList;
    params->certCount = certCount;
    params->p7SignedData = p7SignReader;
    *distParams = params;

    status = 0;

  } while (0);

  if (newList != (VtCertObject *)0)
    Z2Free (newList);

  if (signData != (unsigned char *)0)
    Z2Free (signData);
  if (theData != (unsigned char *)0)
    Z2Free (theData);
  if (certData != (unsigned char *)0)
    Z2Free (certData);

  if (status == 0)
    return (0);

  /* If there was an error, free buffers we would have returned, but
   * didn't.
   */
  if (certCount != 0)
  {
    for (index = 0; index < certCount; ++index)
      VtDestroyCertObject (&(certList[index]));

    Z2Free (certList);
  }

  VtDestroyPkcs7Object (&p7SignReader);

  if (params != (icDistrictParameters *)0)
    Z2Free (params);

  VOLT_LOG_ERROR (
    (VtLibCtx)libCtx, status, errorType, fnctLine,
    "icDistrictParametersNew", (char *)0)

  return (status);
}

static unsigned int CountNewLineChars (
   char *buffer
   )
{
  unsigned int count;

  count = 0;

  if (buffer == (char *)0)
    return (count);

  while ( (buffer[count] == 0x0d) || (buffer[count] == 0x0a) )
    count++;

  return (count);
}

void icDistrictParametersFree (
   icDistrictParameters *params,

⌨️ 快捷键说明

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