Esempio n. 1
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)
    { 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;
}
Esempio n. 2
0
/**
@fn int soap_smd_init(struct soap *soap, struct soap_smd_data *data, int alg, const void *key, int keylen)
@brief Initiates a (signed) digest computation.
@param soap context
@param[in,out] data smdevp engine context
@param[in] alg is algorithm to use
@param[in] key is key to use or NULL for digests
@param[in] keylen is length of HMAC key (when provided)
@return SOAP_OK or SOAP_SSL_ERROR
*/
int
soap_smd_init(struct soap *soap, struct soap_smd_data *data, int alg, const void *key, int keylen)
{ static int done = 0;
  int err = 1;
#ifdef WITH_OPENSSL
  /* OpenSSL: make sure we have the digest algorithms, need to call just once */
  if (!done)
  { done = 1;
    OpenSSL_add_all_digests();
    OpenSSL_add_all_algorithms();
  }
#endif
  /* the algorithm to use */
  data->alg = alg;
  /* the key to use */
  data->key = key;
  /* allocate and init the OpenSSL HMAC or EVP_MD context */
  if ((alg & (SOAP_SMD_PASSTHRU-1)) == SOAP_SMD_HMAC_SHA1)
  { data->ctx = (void*)SOAP_MALLOC(soap, sizeof(HMAC_CTX));
    HMAC_CTX_init((HMAC_CTX*)data->ctx);
  }
  else
  { data->ctx = (void*)SOAP_MALLOC(soap, sizeof(EVP_MD_CTX));
    EVP_MD_CTX_init((EVP_MD_CTX*)data->ctx);
  }
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- SMD Init alg=%d (%p) --\n", alg, data->ctx));
  /* init the digest or signature computations */
  switch (alg & (SOAP_SMD_PASSTHRU-1))
  { case SOAP_SMD_DGST_MD5:
      EVP_DigestInit((EVP_MD_CTX*)data->ctx, EVP_md5());
      break;
    case SOAP_SMD_DGST_SHA1:
      EVP_DigestInit((EVP_MD_CTX*)data->ctx, EVP_sha1());
      break;
    case SOAP_SMD_DGST_SHA256:
      EVP_DigestInit((EVP_MD_CTX*)data->ctx, EVP_sha256());
      break;
    case SOAP_SMD_HMAC_SHA1:
      HMAC_Init((HMAC_CTX*)data->ctx, key, keylen, EVP_sha1());
      break;
    case SOAP_SMD_SIGN_DSA_SHA1:
      err = EVP_SignInit((EVP_MD_CTX*)data->ctx, EVP_dss1());
      break;
    case SOAP_SMD_SIGN_RSA_SHA1:
      err = EVP_SignInit((EVP_MD_CTX*)data->ctx, EVP_sha1());
      break;
    case SOAP_SMD_SIGN_RSA_SHA256:
      err = EVP_SignInit((EVP_MD_CTX*)data->ctx, EVP_sha256());
      break;
    case SOAP_SMD_VRFY_DSA_SHA1:
      err = EVP_VerifyInit((EVP_MD_CTX*)data->ctx, EVP_dss1());
      break;
    case SOAP_SMD_VRFY_RSA_SHA1:
      err = EVP_VerifyInit((EVP_MD_CTX*)data->ctx, EVP_sha1());
      break;
  }
  /* check and return */
  return soap_smd_check(soap, data, err, "soap_smd_init() failed");
}
Esempio n. 3
0
/**
@fn int soap_smd_begin(struct soap *soap, int alg, const void *key, int keylen)
@brief Initiates a digest or signature computation.
@param soap context
@param[in] alg is the digest or signature (sign/verification) algorithm used
@param[in] key is a HMAC key or pointer to EVP_PKEY object or NULL for digests
@param[in] keylen is the length of the HMAC key or 0
@return SOAP_OK, SOAP_EOM, or SOAP_SSL_ERROR
*/
int
soap_smd_begin(struct soap *soap, int alg, const void *key, int keylen)
{ struct soap_smd_data *data;
  data = (struct soap_smd_data*)SOAP_MALLOC(soap, sizeof(struct soap_smd_data));
  if (!data)
    return soap->error = SOAP_EOM;
  /* save and set the engine's 'data' field to pass data to the callbacks */
  soap->data[0] = (void*)data;
  /* save and override the send and recv callbacks */
  data->fsend = soap->fsend;
  data->frecv = soap->frecv;
  soap->fsend = soap_smd_send;
  soap->frecv = soap_smd_recv;
  /* save the mode flag */
  data->mode = soap->mode;
  /* clear the IO flags and DOM flag */
  soap->mode &= ~(SOAP_IO | SOAP_IO_LENGTH | SOAP_ENC_ZLIB | SOAP_XML_DOM);
  /* clear the XML attribute store */
  soap_clr_attr(soap);
  /* load the local XML namespaces store */
  soap_set_local_namespaces(soap);
  if (soap->mode & SOAP_XML_CANONICAL)
    soap->ns = 0; /* for in c14n, we must have all xmlns bindings available */
  else if (!(alg & SOAP_SMD_PASSTHRU))
    soap->ns = 2; /* we don't want leading whitespace in serialized XML */
  /* init the soap_smd engine */
  return soap_smd_init(soap, data, alg, key, keylen);
}
Esempio n. 4
0
static int http_md5_copy(struct soap *soap, struct soap_plugin *dst, struct soap_plugin *src)
{ *dst = *src;
  dst->data = (void*)SOAP_MALLOC(soap, sizeof(struct http_md5_data));
  memcpy(dst->data, src->data, sizeof(struct http_md5_data));
  ((struct http_md5_data*)dst->data)->context = NULL;
  return SOAP_OK;
}
Esempio n. 5
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;
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}
Esempio n. 8
0
static int http_da_copy(struct soap *soap, struct soap_plugin *dst, struct soap_plugin *src)
{
  dst->data = (void*)SOAP_MALLOC(soap, sizeof(struct http_da_data));
  memcpy(dst->data, src->data, sizeof(struct http_da_data));
  ((struct http_da_data*)dst->data)->context = NULL;
  memset(((struct http_da_data*)dst->data)->digest, 0, sizeof(((struct http_da_data*)dst->data)->digest));
  ((struct http_da_data*)dst->data)->nonce = NULL;
  ((struct http_da_data*)dst->data)->opaque = NULL;
  ((struct http_da_data*)dst->data)->qop = NULL;
  ((struct http_da_data*)dst->data)->alg = NULL;
  ((struct http_da_data*)dst->data)->nc = 0;
  ((struct http_da_data*)dst->data)->ncount = NULL;
  ((struct http_da_data*)dst->data)->cnonce = NULL;
  ((struct http_da_data*)dst->data)->response = NULL;
  return SOAP_OK;
}
Esempio n. 9
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;
    }
Esempio n. 10
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;
 }
Esempio n. 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:
      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;
}
Esempio n. 12
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;
}
Esempio n. 13
0
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;
}
Esempio n. 14
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");
}
Esempio n. 15
0
/**
@fn int soap_mec_init(struct soap *soap, struct soap_mec_data *data, int alg, SOAP_MEC_KEY_TYPE *pkey, unsigned char *key, int *keylen)
@brief Initialize mecevp engine state and create context for
encryption/decryption algorithm using a private/public key or symmetric secret
key.
@param soap context
@param[in,out] data mecevp engine context
@param[in] alg encryption/decryption algorithm
@param[in] pkey public/private key or NULL
@param[in,out] key secret key or encrypted ephemeral secret key set with envelope encryption, or NULL
@param[in,out] keylen secret key length
@return SOAP_OK or SOAP_SSL_ERROR
*/
int
soap_mec_init(struct soap *soap, struct soap_mec_data *data, int alg, SOAP_MEC_KEY_TYPE *pkey, unsigned char *key, int *keylen)
{ int ok = 1;
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_mec_init()\n"));
  soap_ssl_init();
  data->ctx = (EVP_CIPHER_CTX*)SOAP_MALLOC(soap, sizeof(EVP_CIPHER_CTX));
  if (!data->ctx)
    return soap->error = SOAP_EOM;
  EVP_CIPHER_CTX_init(data->ctx);
  data->alg = alg;
  data->state = SOAP_MEC_STATE_NONE;
  if (alg & SOAP_MEC_DES_CBC)
    data->type = EVP_des_ede3_cbc(); /* triple DES CBC */
  else if (alg & SOAP_MEC_AES128_CBC)
    data->type = EVP_get_cipherbyname("AES128");
  else if (alg & SOAP_MEC_AES192_CBC)
    data->type = EVP_get_cipherbyname("AES192");
  else if (alg & SOAP_MEC_AES256_CBC)
    data->type = EVP_get_cipherbyname("AES256");
  else if (alg & SOAP_MEC_AES512_CBC)
    data->type = EVP_get_cipherbyname("AES512");
  else
    data->type = EVP_enc_null();
  data->buf = NULL;
  data->rest = NULL;
  data->restlen = 0;
  if (alg & SOAP_MEC_ENC)
  { if (!data->type)
      return soap_mec_check(soap, data, 0, "soap_mec_init() failed: cannot load cipher");
    EVP_EncryptInit_ex(data->ctx, data->type, NULL, NULL, NULL);
  }
  if (alg & SOAP_MEC_OAEP)
    EVP_CIPHER_CTX_set_padding(data->ctx, RSA_PKCS1_OAEP_PADDING);
  else
    EVP_CIPHER_CTX_set_padding(data->ctx, RSA_PKCS1_PADDING);
  switch (alg & SOAP_MEC_MASK)
  { case SOAP_MEC_ENV_ENC_AES128_CBC:
    case SOAP_MEC_ENV_ENC_AES192_CBC:
    case SOAP_MEC_ENV_ENC_AES256_CBC:
    case SOAP_MEC_ENV_ENC_AES512_CBC:
    case SOAP_MEC_ENV_ENC_DES_CBC:
      ok = EVP_CIPHER_CTX_rand_key(data->ctx, data->ekey);
      /* generate ephemeral secret key */
#if (OPENSSL_VERSION_NUMBER >= 0x01000000L)
      *keylen = EVP_PKEY_encrypt_old(key, data->ekey, EVP_CIPHER_CTX_key_length(data->ctx), pkey);
#else
      *keylen = EVP_PKEY_encrypt(key, data->ekey, EVP_CIPHER_CTX_key_length(data->ctx), pkey);
#endif
      key = data->ekey;
      /* fall through to next arm */
    case SOAP_MEC_ENC_DES_CBC:
    case SOAP_MEC_ENC_AES128_CBC:
    case SOAP_MEC_ENC_AES192_CBC:
    case SOAP_MEC_ENC_AES256_CBC:
    case SOAP_MEC_ENC_AES512_CBC:
      data->bufidx = 0;
      data->buflen = 1024; /* > iv in base64 must fit */
      data->buf = (char*)SOAP_MALLOC(soap, data->buflen);
      data->key = key;
      break;
    case SOAP_MEC_ENV_DEC_AES128_CBC:
    case SOAP_MEC_ENV_DEC_AES192_CBC:
    case SOAP_MEC_ENV_DEC_AES256_CBC:
    case SOAP_MEC_ENV_DEC_AES512_CBC:
    case SOAP_MEC_ENV_DEC_DES_CBC:
    case SOAP_MEC_DEC_DES_CBC:
    case SOAP_MEC_DEC_AES128_CBC:
    case SOAP_MEC_DEC_AES192_CBC:
    case SOAP_MEC_DEC_AES256_CBC:
    case SOAP_MEC_DEC_AES512_CBC:
      data->pkey = pkey;
      data->key = key;
      data->keylen = *keylen;
      break;
    default:
      return soap_set_receiver_error(soap, "Unsupported encryption algorithm", NULL, SOAP_SSL_ERROR);
  }
  return soap_mec_check(soap, data, ok, "soap_mec_init() failed");
}
Esempio n. 16
0
/**
@fn int soap_smd_init(struct soap *soap, struct soap_smd_data *data, int alg, const void *key, int keylen)
@brief Initiates a (signed) digest computation.
@param soap context
@param[in,out] data smdevp engine context
@param[in] alg is algorithm to use
@param[in] key is key to use or NULL for digests
@param[in] keylen is length of HMAC key (when provided)
@return SOAP_OK or SOAP_SSL_ERROR
*/
int
soap_smd_init(struct soap *soap, struct soap_smd_data *data, int alg, const void *key, int keylen)
{ int ok = 1;
  const EVP_MD *type;
  soap_ssl_init();
  /* the algorithm to use */
  data->alg = alg;
  /* the key to use */
  data->key = key;
  /* allocate and init the OpenSSL HMAC or EVP_MD context */
  if ((alg & SOAP_SMD_ALGO) == SOAP_SMD_HMAC)
  { data->ctx = (void*)SOAP_MALLOC(soap, sizeof(HMAC_CTX));
    if (!data->ctx)
      return soap_set_receiver_error(soap, "soap_smd_init() failed", "No context", SOAP_SSL_ERROR);
    HMAC_CTX_init((HMAC_CTX*)data->ctx);
  }
  else
  { data->ctx = (void*)SOAP_MALLOC(soap, sizeof(EVP_MD_CTX));
    if (!data->ctx)
      return soap_set_receiver_error(soap, "soap_smd_init() failed", "No context", SOAP_SSL_ERROR);
    EVP_MD_CTX_init((EVP_MD_CTX*)data->ctx);
  }
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- SMD Init alg=%x (%p) --\n", alg, data->ctx));
  /* init the digest or signature computations */
  switch (alg & SOAP_SMD_HASH)
  { case SOAP_SMD_MD5:
      type = EVP_md5();
      break;
    case SOAP_SMD_SHA1:
      type = EVP_sha1();
      break;
#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
    case SOAP_SMD_SHA224:
      type = EVP_sha224();
      break;
    case SOAP_SMD_SHA256:
      type = EVP_sha256();
      break;
    case SOAP_SMD_SHA384:
      type = EVP_sha384();
      break;
    case SOAP_SMD_SHA512:
      type = EVP_sha512();
      break;
#endif
    default:
      return soap_smd_check(soap, data, 0, "soap_smd_init() failed: cannot load digest");
  }
  switch (alg & SOAP_SMD_ALGO)
  { case SOAP_SMD_HMAC:
      HMAC_Init((HMAC_CTX*)data->ctx, key, keylen, type);
      break;
    case SOAP_SMD_DGST:
      EVP_DigestInit((EVP_MD_CTX*)data->ctx, type);
      break;
    case SOAP_SMD_SIGN:
      ok = EVP_SignInit((EVP_MD_CTX*)data->ctx, type);
      break;
    case SOAP_SMD_VRFY:
      ok = EVP_VerifyInit((EVP_MD_CTX*)data->ctx, type);
      break;
    default:
      return soap_set_receiver_error(soap, "Unsupported digest algorithm", NULL, SOAP_SSL_ERROR);
  }
  /* check and return */
  return soap_smd_check(soap, data, ok, "soap_smd_init() failed");
}