static int 
out_element(struct soap *soap, const struct soap_dom_element *node, const char *prefix, const char *name)
{ if (node->head && soap_send(soap, node->head))
    return soap->error;
  if (node->type && node->node)
  { if (prefix && *prefix)
    { char *s = (char*)SOAP_MALLOC(soap, strlen(prefix) + strlen(name) + 2);
      if (!s)
        return soap->error = SOAP_EOM;
      sprintf(s, "%s:%s", prefix, name);
      soap_putelement(soap, node->node, s, 0, node->type);
      SOAP_FREE(soap, s);
    }
    else
      return soap_putelement(soap, node->node, name, 0, node->type);
  }
  else if (prefix && *prefix)
  { char *s;
    if (strlen(prefix) + strlen(name) < sizeof(soap->msgbuf))
      s = soap->msgbuf;
    else
    { s = (char*)SOAP_MALLOC(soap, strlen(prefix) + strlen(name) + 2);
      if (!s)
        return soap->error = SOAP_EOM;
    }
    sprintf(s, "%s:%s", prefix, name);
    if (soap_element(soap, s, 0, NULL)) /* element() */
      return soap->error;
    if (s != soap->msgbuf)
      SOAP_FREE(soap, s);
  }
  else if (*name != '-')
    return soap_element(soap, name, 0, NULL); /* element() */
  return soap->error;
}
Beispiel #2
0
static void http_md5_delete(struct soap *soap, struct soap_plugin *p)
{ struct http_md5_data *data = (struct http_md5_data*)soap_lookup_plugin(soap, http_md5_id);
  if (data)
  { md5_handler(soap, &data->context, MD5_DELETE, NULL, 0);
    SOAP_FREE(soap, data);
  }
}
Beispiel #3
0
static void http_da_delete(struct soap *soap, struct soap_plugin *p)
{
  if (((struct http_da_data*)p->data)->smd_data.ctx)
    soap_smd_final(soap, &((struct http_da_data*)p->data)->smd_data, NULL, NULL);
  if (p->data)
    SOAP_FREE(soap, p->data);
}
Beispiel #4
0
static void http_da_delete(struct soap *soap, struct soap_plugin *p)
{
  if (((struct http_da_data*)p->data)->context)
    md5_handler(soap, &((struct http_da_data*)p->data)->context, MD5_DELETE, NULL, 0);
  if (p->data)
    SOAP_FREE(soap, p->data);
}
Beispiel #5
0
 static void logging_delete(struct soap *soap, struct soap_plugin *p)
 {
     /* free allocated plugin data. If fcopy() is not set, then this function is
        not called for all copies of the plugin created with soap_copy(). In this
        example, the fcopy() callback is omitted and the plugin data is shared by
        the soap copies created with soap_copy() */
     SOAP_FREE(soap, p->data);
 }
Beispiel #6
0
/**
@fn void soap_mec_cleanup(struct soap *soap, struct soap_mec_data *data)
@brief Clean up mecevp engine and deallocate cipher context and buffers.
@param soap context
@param[in,out] data mecevp engine context
@return SOAP_OK or SOAP_SSL_ERROR
*/
void
soap_mec_cleanup(struct soap *soap, struct soap_mec_data *data)
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_mec_cleanup()\n"));
  if (data->ctx)
  { EVP_CIPHER_CTX_cleanup(data->ctx);
    SOAP_FREE(soap, data->ctx);
    data->ctx = NULL;
  }
  if (data->buf)
  { SOAP_FREE(soap, data->buf);
    data->buf = NULL;
  }
  if (data->rest)
  { SOAP_FREE(soap, data->rest);
    data->rest = NULL;
  }
}
Beispiel #7
0
static int 
out_element(struct soap *soap, const struct soap_dom_element *node, const char *prefix, const char *name)
{ if (node->head && soap_send(soap, node->head))
    return soap->error;
  if (node->type && node->node)
  { if (prefix && *prefix)
    { size_t l = strlen(prefix) + strlen(name);
      char *s = (char*)SOAP_MALLOC(soap, l + 2);
      if (!s)
        return soap->error = SOAP_EOM;
      (SOAP_SNPRINTF(s, l + 2, l + 1), "%s:%s", prefix, name);
      soap_putelement(soap, node->node, s, 0, node->type);
      SOAP_FREE(soap, s);
    }
    else
      return soap_putelement(soap, node->node, name, 0, node->type);
  }
  else if (prefix && *prefix)
  { size_t l = strlen(prefix) + strlen(name);
    char *s;
    if (l + 1 < sizeof(soap->msgbuf))
      s = soap->msgbuf;
    else
    { s = (char*)SOAP_MALLOC(soap, l + 2);
      if (!s)
        return soap->error = SOAP_EOM;
    }
    (SOAP_SNPRINTF(s, l + 2, l + 1), "%s:%s", prefix, name);
    soap_element(soap, s, 0, NULL); /* element() */
    if (s != soap->msgbuf)
      SOAP_FREE(soap, s);
  }
  else if (*name != '-')
  { soap_mode m = soap->mode;
    if ((soap->mode & SOAP_DOM_ASIS))
      soap->mode &= ~SOAP_XML_INDENT;
    soap_element(soap, name, 0, NULL); /* element() */
    soap->mode = m;
  }
  return soap->error;
}
Beispiel #8
0
int http_md5(struct soap *soap, struct soap_plugin *p, void *arg)
{ p->id = http_md5_id;
  p->data = (void*)SOAP_MALLOC(soap, sizeof(struct http_md5_data));
  p->fcopy = http_md5_copy;
  p->fdelete = http_md5_delete;
  if (p->data)
    if (http_md5_init(soap, (struct http_md5_data*)p->data))
    { SOAP_FREE(soap, p->data); /* error: could not init */
      return SOAP_EOM; /* return error */
    }
  return SOAP_OK;
}
Beispiel #9
0
int http_da(struct soap *soap, struct soap_plugin *p, void *arg)
{
  p->id = http_da_id;
  p->data = (void*)SOAP_MALLOC(soap, sizeof(struct http_da_data));
  p->fcopy = http_da_copy;
  p->fdelete = http_da_delete;
  if (p->data)
  {
    if (http_da_init(soap, (struct http_da_data*)p->data))
    {
      SOAP_FREE(soap, p->data);
      return SOAP_EOM;
    }
  }
  return SOAP_OK;
}
Beispiel #10
0
/**
@fn int soap_smd_final(struct soap *soap, struct soap_smd_data *data, char *buf, int *len)
@brief Finalizes (signed) digest computation and returns digest or signature.
@param soap context
@param[in,out] data smdevp engine context
@param[in] buf contains signature for verification (SOAP_SMD_VRFY algorithms)
@param[out] buf is populated with the digest or signature
@param[in] len points to length of signature to verify (SOAP_SMD_VRFY algorithms)
@param[out] len points to length of stored digest or signature (pass NULL if you are not interested in this value)
@return SOAP_OK or SOAP_SSL_ERROR
*/
int
soap_smd_final(struct soap *soap, struct soap_smd_data *data, char *buf, int *len)
{ unsigned int n = 0;
  int err = 1;
  if (buf)
  { /* finalize the digest or signature computation */
    switch (data->alg & (SOAP_SMD_PASSTHRU-1))
    { case SOAP_SMD_DGST_MD5:
      case SOAP_SMD_DGST_SHA1:
      case SOAP_SMD_DGST_SHA256:
        EVP_DigestFinal((EVP_MD_CTX*)data->ctx, (unsigned char*)buf, &n);
        break;
      case SOAP_SMD_HMAC_SHA1:
        HMAC_Final((HMAC_CTX*)data->ctx, (unsigned char*)buf, &n);
        break;
      case SOAP_SMD_SIGN_DSA_SHA1:
      case SOAP_SMD_SIGN_RSA_SHA1:
      case SOAP_SMD_SIGN_RSA_SHA256:
        err = EVP_SignFinal((EVP_MD_CTX*)data->ctx, (unsigned char*)buf, &n, (EVP_PKEY*)data->key);
        break;
      case SOAP_SMD_VRFY_DSA_SHA1:
      case SOAP_SMD_VRFY_RSA_SHA1:
        if (len)
        { n = (unsigned int)*len;
          err = EVP_VerifyFinal((EVP_MD_CTX*)data->ctx, (unsigned char*)buf, n, (EVP_PKEY*)data->key);
        }
        else
          err = 0;
        break;
    }
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- SMD Final alg=%d (%p) %d bytes--\n", data->alg, data->ctx, n));
    DBGHEX(TEST, buf, n);
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n--"));
    /* return length of digest or signature produced */
    if (len)
      *len = (int)n;
  }
  /* cleanup and free the HMAC or EVP_MD context */
  if ((data->alg & (SOAP_SMD_PASSTHRU-1)) == SOAP_SMD_HMAC_SHA1)
    HMAC_CTX_cleanup((HMAC_CTX*)data->ctx);
  else
    EVP_MD_CTX_cleanup((EVP_MD_CTX*)data->ctx);
  SOAP_FREE(soap, data->ctx);
  data->ctx = NULL;
  /* check and return */
  return soap_smd_check(soap, data, err, "soap_smd_final() failed");
}
Beispiel #11
0
    int md5_handler(struct soap *soap, void **context, enum md5_action action, char *buf, size_t len)
    {
        EVP_MD_CTX *ctx;
        unsigned char hash[EVP_MAX_MD_SIZE];
        unsigned int size;
        switch (action)
        {
        case MD5_INIT:
#ifdef WITH_OPENSSL
            OpenSSL_add_all_digests();
#endif
            if (!*context)
            {
                *context = (void*)SOAP_MALLOC(soap, sizeof(EVP_MD_CTX));
                EVP_MD_CTX_init((EVP_MD_CTX*)*context);
            }
            ctx = (EVP_MD_CTX*)*context;
            DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- MD5 Init %p\n", ctx));
            EVP_DigestInit(ctx, EVP_md5());
            break;
        case MD5_UPDATE:
            ctx = (EVP_MD_CTX*)*context;
            DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- MD5 Update %p --\n", ctx));
            DBGMSG(TEST, buf, len);
            DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n--"));
            EVP_DigestUpdate(ctx, (const void*)buf, (unsigned int)len);
            break;
        case MD5_FINAL:
            ctx = (EVP_MD_CTX*)*context;
            DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- MD5 Final %p --\n", ctx));
            EVP_DigestFinal(ctx, (unsigned char*)hash, &size);
            memcpy(buf, hash, 16);
            break;
        case MD5_DELETE:
            ctx = (EVP_MD_CTX*)*context;
            DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- MD5 Delete %p --\n", ctx));
            if (ctx)
            {
                EVP_MD_CTX_cleanup(ctx);
                SOAP_FREE(soap, ctx);
            }
            *context = NULL;
        }
        return SOAP_OK;
    }
Beispiel #12
0
 /* plugin registry function, invoked by soap_register_plugin */
 int logging(struct soap *soap, struct soap_plugin *p, void *arg)
 {
     p->id = logging_id;
     /* create local plugin data */
     p->data = (void*)SOAP_MALLOC(soap, sizeof(struct logging_data));
     /* register the destructor */
     p->fdelete = logging_delete;
     /* if OK then initialize */
     if (p->data)
     {
         if (logging_init(soap, (struct logging_data*)p->data))
         {
             SOAP_FREE(soap, p->data); /* error: could not init */
             return SOAP_EOM; /* return error */
         }
     }
     return SOAP_OK;
 }
Beispiel #13
0
/**
@fn int soap_smd_final(struct soap *soap, struct soap_smd_data *data, char *buf, int *len)
@brief Finalizes (signed) digest computation and returns digest or signature.
@param soap context
@param[in,out] data smdevp engine context
@param[in] buf contains signature for verification (SOAP_SMD_VRFY algorithms)
@param[out] buf is populated with the digest or signature
@param[in] len points to length of signature to verify (SOAP_SMD_VRFY algorithms)
@param[out] len points to length of stored digest or signature (pass NULL if you are not interested in this value)
@return SOAP_OK or SOAP_SSL_ERROR
*/
int
soap_smd_final(struct soap *soap, struct soap_smd_data *data, char *buf, int *len)
{ unsigned int n = 0;
  int ok = 1;
  if (!data->ctx)
    return soap_set_receiver_error(soap, "soap_smd_final() failed", "No context", SOAP_SSL_ERROR);
  if (buf)
  { /* finalize the digest or signature computation */
    switch (data->alg & SOAP_SMD_ALGO)
    { case SOAP_SMD_HMAC:
        HMAC_Final((HMAC_CTX*)data->ctx, (unsigned char*)buf, &n);
        break;
      case SOAP_SMD_DGST:
        EVP_DigestFinal_ex((EVP_MD_CTX*)data->ctx, (unsigned char*)buf, &n);
        break;
      case SOAP_SMD_SIGN:
        ok = EVP_SignFinal((EVP_MD_CTX*)data->ctx, (unsigned char*)buf, &n, (EVP_PKEY*)data->key);
        break;
      case SOAP_SMD_VRFY:
        if (len)
        { n = (unsigned int)*len;
          ok = EVP_VerifyFinal((EVP_MD_CTX*)data->ctx, (unsigned char*)buf, n, (EVP_PKEY*)data->key);
        }
        else
          ok = 0;
        break;
    }
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- SMD Final alg=%x (%p) %d bytes--\n", data->alg, data->ctx, n));
    DBGHEX(TEST, buf, n);
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n--"));
    /* pass back length of digest or signature produced */
    if (len)
      *len = (int)n;
  }
  /* cleanup */
  if ((data->alg & SOAP_SMD_ALGO) == SOAP_SMD_HMAC)
    HMAC_CTX_cleanup((HMAC_CTX*)data->ctx);
  else
    EVP_MD_CTX_cleanup((EVP_MD_CTX*)data->ctx);
  SOAP_FREE(soap, data->ctx);
  data->ctx = NULL;
  /* check and return */
  return soap_smd_check(soap, data, ok, "soap_smd_final() failed");
}
Beispiel #14
0
/**
@fn int soap_smd_check(struct soap *soap, struct soap_smd_data *data, int err, const char *msg)
@brief Check result of init/update/final smdevp engine operations.
@param soap context
@param[in,out] data smdevp engine context
@param[in] err EVP error value
@param[in] msg error message
@return SOAP_OK or SOAP_SSL_ERROR
*/
static int
soap_smd_check(struct soap *soap, struct soap_smd_data *data, int err, const char *msg)
{ if (err <= 0)
  { unsigned long r;
    while ((r = ERR_get_error()))
    { ERR_error_string_n(r, soap->msgbuf, sizeof(soap->msgbuf));
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- SMD Error (%d) %s: %s\n", err, msg, soap->msgbuf));
    }
    if (data->ctx)
    { if ((data->alg & (SOAP_SMD_PASSTHRU-1)) == SOAP_SMD_HMAC_SHA1)
        HMAC_CTX_cleanup((HMAC_CTX*)data->ctx);
      else
        EVP_MD_CTX_cleanup((EVP_MD_CTX*)data->ctx);
      SOAP_FREE(soap, data->ctx);
      data->ctx = NULL;
    }
    return soap_set_receiver_error(soap, msg, soap->msgbuf, SOAP_SSL_ERROR);
  }
  return SOAP_OK;
}
Beispiel #15
0
int md5_handler(struct soap *soap, void **context, enum md5_action action, char *buf, size_t len)
{ EVP_MD_CTX *ctx;
  unsigned char hash[EVP_MAX_MD_SIZE];
  unsigned int size;
  switch (action)
  { case MD5_INIT:
      soap_ssl_init();
      if (!*context)
      { *context = (void*)SOAP_MALLOC(soap, sizeof(EVP_MD_CTX));
        EVP_MD_CTX_init((EVP_MD_CTX*)*context);
      }
      ctx = (EVP_MD_CTX*)*context;
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- MD5 Init %p\n", ctx));
      EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
      break;
    case MD5_UPDATE:
      ctx = (EVP_MD_CTX*)*context;
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- MD5 Update %p (%lu) --\n", ctx, (unsigned long)len));
      DBGMSG(TEST, buf, len);
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n--"));
      EVP_DigestUpdate(ctx, (const void*)buf, (unsigned int)len);
      break;
    case MD5_FINAL:
      ctx = (EVP_MD_CTX*)*context;
      EVP_DigestFinal_ex(ctx, (unsigned char*)hash, &size);
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- MD5 Final %p --\n", ctx));
      DBGHEX(TEST, hash, size);
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n--"));
      soap_memcpy((void*)buf, 16, (const void*)hash, 16);
      break;
    case MD5_DELETE:
      ctx = (EVP_MD_CTX*)*context;
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- MD5 Delete %p --\n", ctx));
      if (ctx)
      { EVP_MD_CTX_cleanup(ctx);
        SOAP_FREE(soap, ctx);
      }
      *context = NULL;
  }
  return SOAP_OK;
}
/**
@fn int soap_smd_end(struct soap *soap, char *buf, int *len)
@brief Completes a digest or signature computation.
@param soap context
@param[in] buf contains signature for verification (when using a SOAP_SMD_VRFY algorithm)
@param[out] buf is populated with the digest or signature
@param[in] len points to length of signature to verify (when using a SOAP_SMD_VRFY algorithm)
@param[out] len points to length of stored digest or signature (when not NULL)
@return SOAP_OK, SOAP_USER_ERROR, or SOAP_SSL_ERROR
*/
int
soap_smd_end(struct soap *soap, char *buf, int *len)
{ struct soap_smd_data *data;
  int err;
  data = (struct soap_smd_data*)soap->user;
  if (!data)
    return SOAP_USER_ERROR;
  /* finalize the digest/signature computation and store data in buf + len */
  /* for signature verification, buf + len contain the signature */
  err = soap_smd_final(soap, data, buf, len);
  /* restore the callbacks */
  soap->fsend = data->fsend;
  soap->frecv = data->frecv;
  /* restore the mode flag */
  soap->mode = data->mode;
  /* restore the 'user' data */
  soap->user = data->user;
  /* free data */
  SOAP_FREE(soap, data);
  /* return SOAP_OK or error */
  return err;
}
Beispiel #17
0
static int
out_attribute(struct soap *soap, const char *prefix, const char *name, const char *data, const wchar_t *wide, int flag)
{ char *s;
  const char *t;
  size_t l;
  int err;
  if (wide)
    data = soap_wchar2s(soap, wide);
  if (!prefix || !*prefix)
  { if (wide)
      return soap_set_attr(soap, name, data, 2);
    if (flag)
      return soap_set_attr(soap, name, data, 1);
    return soap_attribute(soap, name, data);
  }
  t = strchr(name, ':');
  if (t)
    t++;
  else
    t = name;
  l = strlen(prefix) + strlen(t);
  if (l + 1 < sizeof(soap->msgbuf))
    s = soap->msgbuf;
  else
  { s = (char*)SOAP_MALLOC(soap, l + 2);
    if (!s)
      return soap->error = SOAP_EOM;
  } 
  (SOAP_SNPRINTF(s, l + 2, l + 1), "%s:%s", prefix, t);
  if (wide)
    err = soap_set_attr(soap, s, data, 2);
  else if (flag)
    err = soap_set_attr(soap, s, data, 1);
  else
    err = soap_attribute(soap, s, data);
  if (s != soap->msgbuf)
    SOAP_FREE(soap, s);
  return err;
}
SOAP_FMAC1
int
SOAP_FMAC2
soap_out_xsd__anyType(struct soap *soap, const char *tag, int id, const struct soap_dom_element *node, const char *type)
{ if (node)
  { const char *prefix; /* namespace prefix, if namespace is present */
    size_t colon;
    if (!(soap->mode & SOAP_DOM_ASIS))
    { const struct soap_dom_attribute *att;
      for (att = node->atts; att; att = att->next)
      { if (att->name && att->data && !strncmp(att->name, "xmlns:", 6))
	{ if (soap_push_namespace(soap, att->name + 6, att->data) == NULL)
            return soap->error;
	}
        else if (att->name && att->data && !strcmp(att->name, "xmlns"))
	{ if (soap_push_namespace(soap, "", att->data) == NULL)
            return soap->error;
	}
      }
    }
    if (node->name)
      tag = node->name;
    else if (!tag)
      tag = "-";
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' output at level %u\n", tag, soap->level));
    if ((prefix = strchr(tag, ':')))
    { colon = prefix - tag + 1;
      if (colon > sizeof(soap->tag))
        colon = sizeof(soap->tag);
    }
    else
      colon = 0;
    prefix = NULL;
    if (node->nstr && *node->nstr && !(soap->mode & SOAP_DOM_ASIS))
    { if (colon)
      { strncpy(soap->tag, tag, colon - 1);
        soap->tag[colon - 1] = '\0';
        if ((prefix = soap_push_ns_prefix(soap, soap->tag, node->nstr, 1)) == NULL
         || out_element(soap, node, prefix, tag + colon))
          return soap->error;
      }
      else
      { if ((prefix = soap_lookup_ns_prefix(soap, node->nstr)))
        { if (out_element(soap, node, prefix, tag + colon))
            return soap->error;
        }
        else
	{ if ((prefix = soap_push_ns_prefix(soap, NULL, node->nstr, 1)) == NULL
           || out_element(soap, node, prefix, tag + colon))
            return soap->error;
        }
      }
    }
    else
    { colon = 0;
      if (out_element(soap, node, NULL, tag))
        return soap->error;
    }
    if (!node->type || !node->node)
    { struct soap_dom_attribute *att;
      struct soap_dom_element *elt;
      for (att = node->atts; att; att = att->next)
      { if (att->name)
        { if (att->nstr && !(soap->mode & SOAP_DOM_ASIS))
          { const char *p;
            if ((att->nstr == node->nstr || (node->nstr && !strcmp(att->nstr, node->nstr))) && prefix)
	    { if (out_attribute(soap, prefix, att->name, att->data, att->wide, 0))
	        return soap->error;
	    }
	    else if ((p = soap_lookup_ns_prefix(soap, att->nstr)))
	    { if (out_attribute(soap, p, att->name, att->data, att->wide, 0))
	        return soap->error;
	    }
	    else if (!strncmp(att->name, "xml", 3))
	    { if (out_attribute(soap, NULL, att->name, att->data, att->wide, 0))
                return soap->error;
	    }
	    else if ((p = soap_push_ns_prefix(soap, NULL, att->nstr, 0)) == NULL
	          || out_attribute(soap, p, att->name, att->data, att->wide, 0))
              return soap->error;
          }
	  else if (soap_attribute(soap, att->name, att->wide ? soap_wchar2s(soap, att->wide) : att->data))
            return soap->error;
        }
      }
      if ((soap->mode & SOAP_DOM_ASIS) && !node->data && !node->wide && !node->elts && !node->tail)
      { if (*tag != '-' && soap_element_start_end_out(soap, tag))
          return soap->error;
      }
      else
      { if (*tag != '-' && soap_element_start_end_out(soap, NULL))
          return soap->error;
        if (node->data)
        { if (soap_string_out(soap, node->data, 0))
            return soap->error;
        }
        else if (node->wide)
        { if (soap_wstring_out(soap, node->wide, 0))
            return soap->error;
        }
        for (elt = node->elts; elt; elt = elt->next)
        { if (soap_out_xsd__anyType(soap, tag, 0, elt, NULL))
            return soap->error;
        }
        if (node->tail && soap_send(soap, node->tail))
          return soap->error;
        if (!prefix || !*prefix)
        { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of DOM node '%s'\n", tag + colon));
          if (soap_element_end_out(soap, tag + colon))
            return soap->error;
        }
        else
        { char *s;
          if (strlen(prefix) + strlen(tag + colon) < sizeof(soap->msgbuf))
	    s = soap->msgbuf;
	  else
	  { s = (char*)SOAP_MALLOC(soap, strlen(prefix) + strlen(tag + colon) + 2);
            if (!s)
              return soap->error = SOAP_EOM;
	  }
          DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of DOM node '%s'\n", tag));
	  sprintf(s, "%s:%s", prefix, tag + colon);
	  soap_pop_namespace(soap);
          if (soap_element_end_out(soap, s))
            return soap->error;
          if (s != soap->msgbuf)
	    SOAP_FREE(soap, s);
        }
      }
    }
  }
  return SOAP_OK;
}
Beispiel #19
0
/**
@fn int soap_mec_start_alg(struct soap *soap, int alg, const unsigned char *key)
@brief Start encryption or decryption of current message. If key is non-NULL,
use the symmetric triple DES key. Use soap_mec_start only after soap_mec_begin.
The soap_mec_start should be followed by a soap_mec_stop call.
@param soap context
@param[in] alg algorithm
@param[in] key secret triple DES key or NULL
@return SOAP_OK or error code
*/
int
soap_mec_start_alg(struct soap *soap, int alg, const unsigned char *key)
{ struct soap_mec_data *data;
  int ok = 1;
  data = (struct soap_mec_data*)soap->data[1];
  if (!data)
    return soap->error = SOAP_USER_ERROR;
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "MEC Start alg=%x\n", data->alg));
  if (key)
    data->key = key;
  if (alg != SOAP_MEC_NONE)
    data->alg = alg;
  if (data->alg & SOAP_MEC_ENC)
  { unsigned char iv[EVP_MAX_IV_LENGTH];
    int ivlen;
    /* save and override the callbacks */
    data->ffiltersend = soap->ffiltersend;
    soap->ffiltersend = soap_mec_filtersend;
    data->bufidx = 0;
    data->i = 0;
    data->m = 0;
    ivlen = EVP_CIPHER_iv_length(data->type);
    if (ivlen)
    { RAND_pseudo_bytes(iv, ivlen);
      soap_mec_put_base64(soap, data, (unsigned char*)iv, ivlen);
    }
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "IV = "));
    DBGHEX(TEST, iv, ivlen);
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n--\n"));
    ok = EVP_EncryptInit_ex(data->ctx, NULL, NULL, data->key, iv);
  }
  else
  { size_t len;
    /* algorithm */
    if (data->alg & SOAP_MEC_DES_CBC)
      data->type = EVP_des_ede3_cbc(); /* triple DES CBC */
    else if (data->alg & SOAP_MEC_AES128_CBC)
      data->type = EVP_get_cipherbyname("AES128");
    else if (data->alg & SOAP_MEC_AES192_CBC)
      data->type = EVP_get_cipherbyname("AES192");
    else if (data->alg & SOAP_MEC_AES256_CBC)
      data->type = EVP_get_cipherbyname("AES256");
    else if (data->alg & SOAP_MEC_AES512_CBC)
      data->type = EVP_get_cipherbyname("AES512");
    else
      data->type = EVP_enc_null();
    len = 2 * sizeof(soap->buf) + EVP_CIPHER_block_size(data->type);
    if (!data->buf || data->buflen < len)
    { if (data->buf)
        SOAP_FREE(soap, data->buf);
      data->buflen = len;
      data->buf = (char*)SOAP_MALLOC(soap, data->buflen);
    }
    data->bufidx = soap->buflen - soap->bufidx;
    /* copy buf[bufidx..buflen-1] to data buf */
    memcpy(data->buf, soap->buf + soap->bufidx, data->bufidx);
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Alloc buf=%lu, copy %lu message bytes\n", (unsigned long)data->buflen, (unsigned long)data->bufidx));
    /* trigger ffilterrecv() */
    soap->bufidx = soap->buflen;
    /* INIT state */
    data->i = 0;
    data->m = 0;
    data->state = SOAP_MEC_STATE_INIT;
  }
  return soap_mec_check(soap, data, ok, "soap_mec_start() failed");
}