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; }
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); } }
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); }
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); }
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); }
/** @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; } }
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; }
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; }
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; }
/** @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"); }
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; }
/* 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; }
/** @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"); }
/** @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; }
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; }
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; }
/** @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"); }