我正在尝试将 VC 6.0 windows xp 上的 c++ 客户端代码连接到 Web 服务,但出现此错误:
SSL 使用深度 1 的证书验证错误或警告:无法获取本地 iss uer 证书
我生成了所有自动生成的soap文件并编写了我的客户端代码,如下所示。
#include <stdsoap2.h>
#include "WSGetRedemptionSellingPriceListV1ServiceSoapBinding.nsmap"
#include "soapWSGetRedemptionSellingPriceListV1ServiceSoapBindingProxy.h"
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <sys/types.h>
#include <pthread.h>
#include <semaphore.h>
#include <sched.h>
int CRYPTO_thread_setup();
void CRYPTO_thread_cleanup();
void sigpipe_handle(int);
int main()
{
int returnValue=-1;
struct soap *soapObject = new soap;
char *userid = new char[strlen("SID488")+1];
char *password = new char[strlen("lzmyf5hP")+1];
char *transactionID=new char[strlen("1318855997052")+1];
ns1__Transaction *Transaction = new ns1__Transaction;
const char* headerString = "<S:Header> \
<ns1:Security xmlns:ns1= http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd> \
<ns1:UsernameToken> \
<ns1:Username>SID488</ns1:Username>\
<ns1:Password>lzmyf5hP</ns1:Password> \
</ns1:UsernameToken>\
</ns1:Security>\
</S:Header>";
char *ip = new char[strlen("163.166.143.21")+1];
char *header = new char[strlen(headerString)+1];
const char* endPoint = "https://wsgtwy-uat.baplc.com/webservices/gateway/CAPSellingWSLive/BA_GetRedemptionSellingPriceList";
const char* soapAction = "http://www.ba.com/schema/esb/tGetRedemptionSellingPriceListV1/WSGetRedemptionSellingPriceListV1PortType/getRedemptionSellingPriceList";
_ns1__GetRedemptionSellingPriceListRequest requestObject;
_ns1__GetRedemptionSellingPriceListResponse responseObject;
strcpy(ip,"163.166.143.21");
strcpy(header,headerString);
strcpy(userid,"SID488");
strcpy(password,"lzmyf5hP");
soap_ssl_init();
if (CRYPTO_thread_setup())
{
fprintf(stderr, "Cannot setup thread mutex for OpenSSL\n");
exit(1);
}
soap_init(soapObject);
soapObject->header = (struct SOAP_ENV__Header *)soap_malloc(soapObject, sizeof(struct SOAP_ENV__Header));
soapObject->header->authwsns__ip = ip;
soapObject->header->authwsns__token=userid;
soapObject->connect_timeout = 60;
soapObject->send_timeout = soapObject->recv_timeout = 30;
soapObject->userid=userid;
soapObject->password=password;
soapObject->passwd=password;
soapObject->logfile[0] = "F:\\gSOAP\\gsExample\\recv.log";
soapObject->logfile[1] = "F:\\gSOAP\\gsExample\\sent.log";
soapObject->logfile[2] = "F:\\gSOAP\\gsExample\\test.log";
if (soap_ssl_client_context(soapObject,SOAP_SSL_DEFAULT,NULL,NULL,"F:\\gSOAP\\gsExample\\wsgtwy-uat.baplc.com.crt",NULL,NULL))
{
soap_print_fault(soapObject, stderr);
exit(1);
}
WSGetRedemptionSellingPriceListV1ServiceSoapBindingProxy serviceInstance;
requestObject.soap = soapObject;
strcpy(transactionID,"1318855997052");
Transaction->TransactionID=transactionID;
requestObject.Transaction=Transaction;
returnValue = serviceInstance.getRedemptionSellingPriceList(endPoint,soapAction,&requestObject,&responseObject);
if (returnValue == SOAP_OK)
{
fprintf(stdout, "SOAP_OK");
}
else
{
soap_print_fault(soapObject, stderr);
}
CRYPTO_thread_cleanup();
return 0;
}
/******************************************************************************\
*
* OpenSSL
*
\******************************************************************************/
#ifdef WITH_OPENSSL
#if defined(WIN32)
# define MUTEX_TYPE HANDLE
# define MUTEX_SETUP(x) (x) = CreateMutex(NULL, FALSE, NULL)
# define MUTEX_CLEANUP(x) CloseHandle(x)
# define MUTEX_LOCK(x) WaitForSingleObject((x), INFINITE)
# define MUTEX_UNLOCK(x) ReleaseMutex(x)
# define THREAD_ID GetCurrentThreadId()
#elif defined(_POSIX_THREADS) || defined(_SC_THREADS)
# define MUTEX_TYPE pthread_mutex_t
# define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
# define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
# define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
# define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
# define THREAD_ID pthread_self()
#else
# error "You must define mutex operations appropriate for your platform"
# error "See OpenSSL /threads/th-lock.c on how to implement mutex on your platform"
#endif
struct CRYPTO_dynlock_value
{ MUTEX_TYPE mutex;
};
static MUTEX_TYPE *mutex_buf;
static struct CRYPTO_dynlock_value *dyn_create_function(const char *file, int line)
{ struct CRYPTO_dynlock_value *value;
value = (struct CRYPTO_dynlock_value*)malloc(sizeof(struct CRYPTO_dynlock_value));
if (value)
MUTEX_SETUP(value->mutex);
return value;
}
static void dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)
{ if (mode & CRYPTO_LOCK)
MUTEX_LOCK(l->mutex);
else
MUTEX_UNLOCK(l->mutex);
}
static void dyn_destroy_function(struct CRYPTO_dynlock_value *l, const char *file, int line)
{ MUTEX_CLEANUP(l->mutex);
free(l);
}
void locking_function(int mode, int n, const char *file, int line)
{ if (mode & CRYPTO_LOCK)
MUTEX_LOCK(mutex_buf[n]);
else
MUTEX_UNLOCK(mutex_buf[n]);
}
unsigned long id_function()
{ return (unsigned long)THREAD_ID;
}
int CRYPTO_thread_setup()
{ int i;
mutex_buf = (MUTEX_TYPE*)malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
if (!mutex_buf)
return SOAP_EOM;
for (i = 0; i < CRYPTO_num_locks(); i++)
MUTEX_SETUP(mutex_buf[i]);
CRYPTO_set_id_callback(id_function);
CRYPTO_set_locking_callback(locking_function);
CRYPTO_set_dynlock_create_callback(dyn_create_function);
CRYPTO_set_dynlock_lock_callback(dyn_lock_function);
CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function);
return SOAP_OK;
}
void CRYPTO_thread_cleanup()
{ int i;
if (!mutex_buf)
return;
CRYPTO_set_id_callback(NULL);
CRYPTO_set_locking_callback(NULL);
CRYPTO_set_dynlock_create_callback(NULL);
CRYPTO_set_dynlock_lock_callback(NULL);
CRYPTO_set_dynlock_destroy_callback(NULL);
for (i = 0; i < CRYPTO_num_locks(); i++)
MUTEX_CLEANUP(mutex_buf[i]);
free(mutex_buf);
mutex_buf = NULL;
}
#else
/* OpenSSL not used, e.g. GNUTLS is used */
int CRYPTO_thread_setup()
{ return SOAP_OK;
}
void CRYPTO_thread_cleanup()
{ }
#endif
/******************************************************************************\
*
* SIGPIPE
*
\******************************************************************************/
void sigpipe_handle(int x) { }
快速回复会很有帮助。
非常感谢