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

📄 icserver.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 "icserver.h"
#include "icXmlParser.h"
#include "icutils.h"
#include "icdistrict.h"
#include "errorctx.h"

/* Send server request
 */
int icServerRequest (
   VoltIdentityObject *idObj,
   icServerResponseData *responseData,
   int *responseCode,
   icServerRequestData requestData,
   icHTTPfn httpFn,
   void *httpFnAppData,
   unsigned char *trustStore,
   unsigned long timeOut,
   VoltTransportCtx *transCtx
   )
{
  int status;  
  int max, i, len;
  char *request = (char *)0;
  char *response = (char *)0;
  char *authTokens = (char *)0;
  unsigned char *buf = (unsigned char *)0;
  unsigned char *temp = (unsigned char *)0;
  char *url = (char *)0;
  VoltLibCtx *libCtx = (VoltLibCtx *)0;  
  unsigned char *id64 = (unsigned char *)0;
  unsigned char *certReq64 = (unsigned char *)0;
  unsigned char *request64 = (unsigned char*)0;
  char* escapedStr = (char*)0;
  VoltHttpRequestInfoPost postInfo;
  VoltHttpRequestInfo reqInfo;  
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)  

  libCtx = (VoltLibCtx *)transCtx->voltObject.libraryCtx;

  /* Form request
   */
  max = 1024;

  VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
  VOLT_SET_FNCT_LINE (fnctLine)
  status = VT_ERROR_MEMORY;
  authTokens = (char *)Z3Malloc (256);
  if (authTokens == (char*)0)
    goto cleanup;

  authTokens[0] = 0;

  VOLT_SET_ERROR_TYPE (errorType, 0)
  for (i = 0; i < requestData.authTokensCount; i++)
  {
    VOLT_SET_FNCT_LINE (fnctLine)
    status = icStrcatalloc (
      &authTokens, (unsigned char *)"    <vs:authToken value=\"", libCtx);
    if (status != 0)
      goto cleanup;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = icStringXMLEscapeAlloc(libCtx,
      requestData.authTokens[i], &escapedStr);
    if (status != 0)
      break;
    
    VOLT_SET_FNCT_LINE (fnctLine)
    status = icStrcatalloc (
      &authTokens, (unsigned char *)escapedStr, libCtx);
    Z2Free(escapedStr);
    if (status != 0)
      goto cleanup;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = icStrcatalloc (
      &authTokens, (unsigned char *)"\"/>\n", libCtx);
    if (status != 0)
      goto cleanup;
  }

  VOLT_SET_FNCT_LINE (fnctLine)
  status = icBase64Encode (
    &id64, &len, requestData.id, requestData.idLen, 1, libCtx);
  if (status != 0)
    goto cleanup;

  if (requestData.request != (Asn1P10Request *)0)
  {
    /* Get the length of the expected buffer and allocate sufficient
     * memory.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_ENCODING;
    len = i2d_Asn1P10Request (requestData.request, (unsigned char **)0);
    if (len == 0)
      goto cleanup;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    buf = (unsigned char *) Z2Malloc (len , 0);
    if (buf == (unsigned char *)0) 
      goto cleanup;

    VOLT_SET_FNCT_LINE (fnctLine)
    temp = buf;
    status = VT_ERROR_INVALID_ENCODING;
    len = i2d_Asn1P10Request (requestData.request, &temp);      
    if (len == 0)
      goto cleanup;

    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = icBase64Encode (&certReq64, &len, buf, len, 1, libCtx);
    if (status != 0)
      goto cleanup;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = icBuildServerRequestAlloc (
      libCtx, requestData.components, authTokens, id64, certReq64,
      &request);
    if (status != 0)
      goto cleanup;
  }
  else
  {
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = icBuildServerRequestAlloc (
      libCtx, requestData.components, authTokens, id64, (char *)0,
      &request);
    if (status != 0)
      goto cleanup;
  }

  /* Rather than URL-encode the post data, we just base64 it ...
   */
  VOLT_SET_FNCT_LINE (fnctLine)
  status = icBase64Encode (
    &request64, &len, request, Z2Strlen(request), 1, libCtx);
  if (status != 0)
    goto cleanup;

  /* ...except that we need to escape any +'s and any possible trailing =
   */
  VOLT_SET_FNCT_LINE (fnctLine)
  status = icStrrepl ((char **)&request64, "+", "%2B", libCtx);
  if (status != 0)
    goto cleanup;

  VOLT_SET_FNCT_LINE (fnctLine)
  status = icStrrepl ((char **)&request64, "=", "%3D", libCtx);
  if (status != 0)
    goto cleanup;

  /* Then prepend the "field" name to it
   */
  VOLT_SET_FNCT_LINE (fnctLine)
  status = icStrprependalloc ((char **)&request64, IC_REQUEST_FIELD, libCtx);
  if (status != 0)
    goto cleanup;

  /* Post request to server
   */
  VOLT_SET_ERROR_TYPE (errorType, 0)
  VOLT_SET_FNCT_LINE (fnctLine)
  status = icBuildURLAlloc (
    libCtx, VOLT_IC_URL, "https://", requestData.server,
    IC_SERVER_DEFAULT_URL, &url);
  if (status != 0)
    goto cleanup;

  VOLT_SET_FNCT_LINE (fnctLine)
  postInfo.transCtx = transCtx;
  postInfo.idObj = idObj;
  postInfo.postData = request64;
  reqInfo.requestType = VOLT_REQUEST_TYPE_POST;
  reqInfo.requestData = (Pointer)&postInfo;
  status = httpFn (
    &reqInfo, &response, responseCode, url, 
    0, trustStore, timeOut, httpFnAppData);
  if (status != 0)
    goto cleanup;

  /* response code 401 is Invalid Auth.
   */
  if (*responseCode == 401)
  {
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_AUTHORIZATION_DENIED;
    goto cleanup;
  }
  else if (*responseCode != 200)
  {
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_DOWNLOAD_FAILURE;
    goto cleanup;
  }

  VOLT_SET_FNCT_LINE (fnctLine)
  status = icParseServerResponse (
    responseCode, responseData, response, libCtx);

cleanup:   
  if (buf != (unsigned char *)0 )
    Z2Free (buf);
  if (url != (char *)0 )
    Z2Free (url);
  if (certReq64 != (unsigned char *)0)
    Z2Free (certReq64);
  if (id64 != (unsigned char *)0)
    Z2Free(id64);
  if (request != (char *)0)
    Z2Free (request);
  if (authTokens != (char *) 0)
    Z2Free(authTokens);
  if (request64 != (unsigned char *)0)
    Z2Free (request64);
  if (response != (char *)0)
    Z2Free (response);

  VOLT_LOG_ERROR_COMPARE (
    status, (VtLibCtx)libCtx, status, errorType, fnctLine,
    "icServerRequest", (char *)0)

  return (status);
}

int icParseServerResponse (
   int *code,
   icServerResponseData *responseData,
   char *responseText,
   VoltLibCtx *libCtx
   )
{
  int status, i, j, len;
  char *responseCode = (char *)0;
  char *tempMessage = (char*)0;
  char *url = (char *)0;
  icXmlNode *node, *privKeyNode, *authTokenNode, *headerNode, *certNode, *root;
  icXmlParser *parser;
  icInputStream *bufStream;
  unsigned char *ptr = (char *)0;
  unsigned char *certDer = (char *)0;
  char *point;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  /* Parse response text
   */
  VOLT_SET_ERROR_TYPE (errorType, 0)
  VOLT_SET_FNCT_LINE (fnctLine)
  status = icInputStreamCreate (
    ICInputStreamImplString, (unsigned char *)responseText,
    Z2Strlen (responseText), VOLT_IC_STREAM_COPY_REFERENCE, &bufStream,
    libCtx);
  if (status != 0)
    goto cleanup1;

  VOLT_SET_FNCT_LINE (fnctLine)
  status = icXmlParserCreate (&parser, libCtx);
  if (status != 0)
    goto cleanup1;

  VOLT_SET_FNCT_LINE (fnctLine)
  status = icXmlParserParse (parser, bufStream, libCtx); 
  if (status != 0)
    goto cleanup1;

  root = parser->main;

  VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
  VOLT_SET_FNCT_LINE (fnctLine)
  status = VT_ERROR_INVALID_INPUT;
  if (root == (icXmlNode *) 0)
    goto cleanup1;

  /* Initialize response struct to empty
   */
  Z2Memset (responseData, 0, sizeof (*responseData));

  VOLT_SET_FNCT_LINE (fnctLine)
  if (root->node_type != IC_XML_NODE_TAG)
    goto cleanup1;

  VOLT_SET_FNCT_LINE (fnctLine)
  if (Z2Strcmp (root->tag_name, "vs:response") != 0)
    goto cleanup1;

  VOLT_SET_FNCT_LINE (fnctLine)
  icTableGet (root->attributes, "code", &responseCode, libCtx);
  if (responseCode == (char *)0)
    goto cleanup1;

  point = responseCode;
  *code = 0;
  while ( (*point != '\0') && (*point != ' ') )
  {
    *code = ((*code) * 10) + (int)(*point) - (int)'0';
    point++;
  }

  icTableGet (root->attributes, "message", &tempMessage, libCtx);
  if (tempMessage != (char *)0)
    icSafeStrncpy (
      responseData->errorMsg, tempMessage, sizeof (responseData->errorMsg),
      libCtx);

  privKeyNode = (icXmlNode *)0;
  authTokenNode = (icXmlNode *)0;
  certNode = (icXmlNode *)0;

  for (i = 0; i < root->num_children; i++)
  {
    node = root->children[i];
    if (node->node_type != IC_XML_NODE_TAG)
      continue;

    if (Z2Strcmp (node->tag_name, "vs:header") == 0)
    {
      for (j = 0; j < node->num_children; j++)
      {
        headerNode = node->children[j];
        if (headerNode->node_type != IC_XML_NODE_TAG)
          continue;

        if (Z2Strcmp(headerNode->tag_name, "vs:id") == 0)
        {
          /* Should have one TEXT child
           */
          VOLT_SET_FNCT_LINE (fnctLine)
          status = VT_ERROR_INVALID_INPUT;
          if ( (headerNode->num_children != 1) ||
               (headerNode->children[0]->node_type != IC_XML_NODE_TEXT) )
            goto cleanup1;

          status = icBase64Decode (
            &(responseData->id), &(responseData->idLen),
            headerNode->children[0]->text, -1, libCtx);
          if (status != 0)
            goto cleanup1;
        }
      }
    }

    if (Z2Strcmp(node->tag_name, "vs:body") == 0)
    {
      for (j = 0; j < node->num_children; j++)
      {

⌨️ 快捷键说明

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