📄 smdevp.c
字号:
@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*/intsoap_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;}/**@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*/intsoap_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 */ 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_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) { 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_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_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");}/**@fn int soap_smd_update(struct soap *soap, struct soap_smd_data *data, const char *buf, size_t len)@brief Updates (signed) digest computation with message part.@param soap context@param[in,out] data smdevp engine context@param[in] buf contains message part@param[in] len of message part@return SOAP_OK or SOAP_SSL_ERROR*/intsoap_smd_update(struct soap *soap, struct soap_smd_data *data, const char *buf, size_t len){ int err = 1; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- SMD Update alg=%d (%p) --\n", data->alg, data->ctx)); switch (data->alg) { case SOAP_SMD_DGST_MD5: case SOAP_SMD_DGST_SHA1: EVP_DigestUpdate((EVP_MD_CTX*)data->ctx, (const void*)buf, (unsigned int)len); break; case SOAP_SMD_HMAC_SHA1: HMAC_Update((HMAC_CTX*)data->ctx, (const unsigned char*)buf, len); break; case SOAP_SMD_SIGN_DSA_SHA1: case SOAP_SMD_SIGN_RSA_SHA1: err = EVP_SignUpdate((EVP_MD_CTX*)data->ctx, (const void*)buf, (unsigned int)len); break; case SOAP_SMD_VRFY_DSA_SHA1: case SOAP_SMD_VRFY_RSA_SHA1: err = EVP_VerifyUpdate((EVP_MD_CTX*)data->ctx, (const void*)buf, (unsigned int)len); break; } DBGMSG(TEST, buf, len); DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n--")); /* check and return */ return soap_smd_check(soap, data, err, "soap_smd_update() failed");}/**@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*/intsoap_smd_final(struct soap *soap, struct soap_smd_data *data, char *buf, int *len){ unsigned int n = 0; int err = 1; /* finalize the digest or signature computation */ switch (data->alg) { case SOAP_SMD_DGST_MD5: case SOAP_SMD_DGST_SHA1: 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: 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--")); /* cleanup and free the HMAC or EVP_MD context */ if (data->alg == 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 length of digest or signature produced */ if (len) *len = (int)n; /* check and return */ return soap_smd_check(soap, data, err, "soap_smd_final() failed");}/******************************************************************************\ * * Static local functions *\******************************************************************************//**@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 OpenSSL error value@param[in] msg error message@return SOAP_OK or SOAP_SSL_ERROR*/static intsoap_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_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;}/**@fn int soap_smd_send(struct soap *soap, const char *buf, size_t len)@brief Callback to intercept messages for digest or signature computation.@param soap context@param[in] buf message@param[in] len message length@return SOAP_OK or SOAP_SSL_ERROR*/static intsoap_smd_send(struct soap *soap, const char *buf, size_t len){ return soap_smd_update(soap, (struct soap_smd_data*)soap->user, buf, len);}/**@fn size_t soap_smd_recv(struct soap *soap, char *buf, size_t len)@brief Dummy callback to avoid read operations from blocking.@return 0*/static size_tsoap_smd_recv(struct soap *soap, char *buf, size_t len){ return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -