gSOAP wsse plugin - какова правильная процедура для подписания запросов? - PullRequest
0 голосов
/ 07 марта 2019

Я использую gSOAP (2.8.16 - да, он старый) для разработки клиента C ++ на RHEL, который общается со службой, для которой сообщения должны иметь цифровую подпись. Сигнатура основана на элементе wsu: Timestamp. Я использую сертификат X509 (PEM) с закрытым ключом RSA. Клиент был сгенерирован с использованием

wsdl2h -g -e -o client-pre.h -t$SOAPHOME/WS/WS-typemap.dat -v $WSDL
sed -f add-imports client-pre.h > client.h # adds import statements for WS-Header.h, dom.h, and wsse.h
soapcpp2 -d ../ -A -L _c -w -j -I $SOAPHOME/import -x -n client.h

На основании документации Genevia следующий код должен быть достаточным (не фактический код, но репрезентативный для него - обработка ошибок опущена для экономии места):

ServiceSOAPProxy client;
...
soap_register_plugin( client.soap, soap_wsse );
...
soap_ssl_client_context( client.soap, SOAP_SSL_DEFAULT, pemfile, pwd, cafile, NULL, NULL );

_ns__RequestType *req = soap_new__ns__RequestType( cpClient.soap );
// set request parameters

RSA *rsakey = PEM_read_RSAPrivateKey( fp, NULL, NULL, (void *) pwd );
...
X509 *cert = PEM_read_X509( fp, NULL, NULL, NULL );
...
soap_wsse_add_Timestamp( client.soap, timeid.c_str(), duration );

if ( soap_wsse_add_BinarySecurityTokenX509( client.soap, tokid.c_str(), cert ) != SOAP_OK || 
     soap_wsse_add_KeyInfo_SecurityTokenReferenceX509( client.soap, ("#" + tokid).c_str()) != SOAP_OK || 
     soap_wsse_sign( client.soap, SOAP_SMD_SIGN_RSA_SHA256, rsakey, 0 ) != SOAP_OK ||
     soap_wsse_sign_only( client.soap, ("#" + timeid).c_str() ) != SOAP_OK )
{
  soap_print_fault( client.soap, ::stderr );
  // handle error
}

ns__ResponseType *rsp = soap_new_ns__ResponseType( client.soap );
cpClient.SendRequest( req, rsp );

К сожалению, подпись не завершена - здесь нет SignatureValue, нет SignedInfo и т. Д., Только SecurityTokenReference:

  <ds:Signature>
    <ds:KeyInfo>
      <wsse:SecurityTokenReference>
        <wsse:Reference URI="#BST-a9ec4d98-41c0-11e9-961e-0e5b675ed876" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
      </wsse:SecurityTokenReference>
    </ds:KeyInfo>
  </ds:Signature>

Ни один из soap_wsse* методов не возвращает ошибку, но я либо пропускаю шаг, либо что-то настроено неправильно. В документации Genevia нет абсолютно ничего, что даже намекает на то, что я делаю неправильно.

Какой шаг я пропускаю?

EDIT

Оказывается, я передал неправильный тег для отметки времени - я использовал ссылочный URI с ведущим # (("#" + time_id).c_str()), поэтому к подписи ничего не добавлялось.

Когда я использую правильный тег (time_id.c_str()), я получаю segfault - как-то, soap->attributes получает неправильное значение. Я установил наблюдение за членом soap-> attribute в сеансе GDB и получил следующее:

Old value = (soap_attribute *) 0x0
New value = (soap_attribute *) 0x9bf1a0
0x00000000005f2d49 in soap_set_attr (soap=0x7ffff7fb7010, name=0x7ffff7fd35d0 "xmlns:SOAP-ENV", value=0x9bf131 "http://schemas.xmlsoap.org/soap/envelope/", flag=1) at stdsoap2.cpp:10456

Old value = (soap_attribute *) 0x9bf1a0
New value = (soap_attribute *) 0xa1aaa0
soap_clr_attr (soap=0x7ffff7fb7010) at stdsoap2.cpp:10510

Old value = (soap_attribute *) 0xa1aaa0
New value = (soap_attribute *) 0x9eca10
soap_clr_attr (soap=0x7ffff7fb7010) at stdsoap2.cpp:10510

Old value = (soap_attribute *) 0x9eca10
New value = (soap_attribute *) 0x9bf3b0
soap_clr_attr (soap=0x7ffff7fb7010) at stdsoap2.cpp:10510

Old value = (soap_attribute *) 0x9bf3b0
New value = (soap_attribute *) 0x9c4570
soap_clr_attr (soap=0x7ffff7fb7010) at stdsoap2.cpp:10510

Old value = (soap_attribute *) 0x9c4570
New value = (soap_attribute *) 0x9ec740
soap_clr_attr (soap=0x7ffff7fb7010) at stdsoap2.cpp:10510

Old value = (soap_attribute *) 0x9ec740
New value = (soap_attribute *) 0xa1a960
soap_clr_attr (soap=0x7ffff7fb7010) at stdsoap2.cpp:10510

Old value = (soap_attribute *) 0xa1a960
New value = (soap_attribute *) 0x9ec690
soap_clr_attr (soap=0x7ffff7fb7010) at stdsoap2.cpp:10510

Old value = (soap_attribute *) 0x9ec690
New value = (soap_attribute *) 0x9b9f30
soap_clr_attr (soap=0x7ffff7fb7010) at stdsoap2.cpp:10510

Old value = (soap_attribute *) 0x9b9f30
New value = (soap_attribute *) 0x9bf300
soap_clr_attr (soap=0x7ffff7fb7010) at stdsoap2.cpp:10510

Old value = (soap_attribute *) 0x9bf300
New value = (soap_attribute *) 0x0
soap_clr_attr (soap=0x7ffff7fb7010) at stdsoap2.cpp:10510

Old value = (soap_attribute *) 0x0
New value = (soap_attribute *) 0x2000000000000
soap_smd_begin (soap=0x7ffff7fb7010, alg=10, key=0x95b150, keylen=0) at smdevp.c:373

Почему в мире это происходит?

...