[xmlsec] Sign XML using EVP_PKEY and X509 cert in memory

Aleksey Sanin aleksey at aleksey.com
Tue Aug 17 09:52:37 PDT 2010


You have a problem linking your code. Is it on Windows?

Aleksey

On 8/17/2010 9:50 AM, Duh Crab wrote:
> I used xmlSecOpenSSLAppPkcs12LoadBIO() as a template and loaded EVP_PKEY
> pkey and X509 cert using the code below.
>>
>> data = xmlSecOpenSSLEvpKeyAdopt(pKey);
>>
>> if(data == NULL) {
>>
>> EVP_PKEY_free(pKey);
>>
>> goto done;
>>
>> }
>>
>> x509Data = xmlSecKeyDataCreate(xmlSecOpenSSLKeyDataX509Id);
>>
>> if(x509Data == NULL) {
>>
>> goto done;
>>
>> }
>>
>> /* starting from openssl 1.0.0 the PKCS12_parse() call will not create
>> certs
>>
>> chain object if there is no certificates in the pkcs12 file and it
>> will be null
>>
>> */
>>
>> if(chain == NULL)
>>
>> {
>>
>> chain = sk_X509_new_null();
>>
>> if(chain == NULL)
>>
>> {
>>
>> DEBUGPRINT("chain processing error\n");
>>
>> goto done;
>>
>> }
>>
>> }
>>
>> has_cert = 0;
>>
>> for(i = 0; i < sk_X509_num(chain); ++i) {
>>
>> assert(sk_X509_value(chain, i));
>>
>> if(X509_cmp(sk_X509_value(chain, i), cert) != 0)
>>
>> {
>>
>> has_cert = 1;
>>
>> break;
>>
>> }
>>
>> }
>>
>> if(has_cert != 0)
>>
>> {
>>
>> tmpcert = X509_dup(cert);
>>
>> if(tmpcert == NULL) {
>>
>> DEBUGPRINT("tmpcert == NULL\n");
>>
>> goto done;
>>
>> }
>>
>> ret = sk_X509_push(chain, tmpcert);
>>
>> if(ret < 1)
>>
>> {
>>
>> DEBUGPRINT("sk_X509_push() returned <1\n");
>>
>> X509_free(tmpcert);
>>
>> goto done;
>>
>> }
>>
>> }
>>
>> ret = xmlSecOpenSSLKeyDataX509AdoptKeyCert(x509Data, cert);
>>
>> if(ret < 0)
>>
>> {
>>
>> DEBUGPRINT("xmlSecOpenSSLKeyDataX509AdoptKeyCert() returned <0 \n");
>>
>> goto done;
>>
>> }
>>
>> for(i = 0; i < sk_X509_num(chain); ++i)
>>
>> {
>>
>> assert(sk_X509_value(chain, i));
>>
>> tmpcert = X509_dup(sk_X509_value(chain, i));
>>
>> if(tmpcert == NULL)
>>
>> {
>>
>> DEBUGPRINT("tmpcert == NULL \n");
>>
>> X509_free(tmpcert);
>>
>> goto done;
>>
>> }
>>
>> ret = xmlSecOpenSSLKeyDataX509AdoptCert(x509Data, tmpcert);
>>
>> if(ret < 0)
>>
>> {
>>
>> DEBUGPRINT("xmlSecOpenSSLKeyDataX509AdoptCert ret < 0 \n");
>>
>> goto done;
>>
>> }
>>
>> }
>>
>> key = xmlSecKeyCreate();
>>
>> if(key == NULL)
>>
>> {
>>
>> goto done;
>>
>> }
>>
>> ret = xmlSecKeySetValue(key, data);
>>
>> if(ret < 0) {
>>
>> xmlSecKeyDestroy(key);
>>
>> key = NULL;
>>
>> goto done;
>>
>> }
>>
>> data = NULL;
>>
>> ret = xmlSecKeyAdoptData(key, x509Data);
>>
>> if(ret < 0)
>>
>> {
>>
>> xmlSecKeyDestroy(key);
>>
>> key = NULL;
>>
>> goto done;
>>
>> }
>>
>> x509Data = NULL;
>>
>> dsigCtx->signKey = key;
>>
>> data = xmlSecKeyEnsureData(dsigCtx->signKey, xmlSecOpenSSLKeyDataX509Id);
>>
>> ret = xmlSecOpenSSLKeyDataX509AdoptCert(data, cert);
>>
>> if(ret < 0)
>>
>> {
>>
>> DEBUGPRINT("Processing error\n");
>>
>> goto done;
>>
>> }
>>
>> /* set key name to the file name, this is just an example! */
>>
>> if(xmlSecKeySetName(dsigCtx->signKey, BAD_CAST "BDCKey.pem") < 0)
>>
>> {
>>
>> DEBUGPRINT("Error: failed to set key name for key from BDCKey.pem\n");
>>
>> goto done;
>>
>> }
>>
>> /* sign the template */
>>
>> if(xmlSecDSigCtxSign(dsigCtx, signNode) < 0)
>>
>> {
>>
>> DEBUGPRINT("Error: signature failed\n");
>>
>> goto done;
>>
>> }
>>
>> The final step of signing the xml using xmlSecDSigCtxSign() failed
>> with the following error –
>>
>> func=xmlSecTransformIdListFindByHref:file=..\src\transforms.c:line=2538:obj=unkn
>>
>> own:subj=xmlSecPtrListCheckId(list,
>> xmlSecTransformIdListId):error=100:assertion
>>
>> :
>>
>> func=xmlSecTransformNodeRead:file=..\src\transforms.c:line=1533:obj=unknown:subj
>>
>> =xmlSecTransformIdListFindByHref:error=1:xmlsec library function
>> failed:href=htt
>>
>> p://www.w3.org/2001/10/xml-exc-c14n#
>>
>> func=xmlSecTransformCtxNodeRead:file=..\src\transforms.c:line=684:obj=unknown:su
>>
>> bj=xmlSecTransformNodeRead:error=1:xmlsec library function
>> failed:name=Canonical
>>
>> izationMethod
>>
>> func=xmlSecDSigCtxProcessSignedInfoNode:file=..\src\xmldsig.c:line=689:obj=unkno
>>
>> wn:subj=xmlSecTransformCtxNodeRead:error=1:xmlsec library function
>> failed:node=C
>>
>> anonicalizationMethod
>>
>> func=xmlSecDSigCtxProcessSignatureNode:file=..\src\xmldsig.c:line=547:obj=unknow
>>
>> n:subj=xmlSecDSigCtxProcessSignedInfoNode:error=1:xmlsec library
>> function failed
>>
>> :
>>
>> func=xmlSecDSigCtxSign:file=..\src\xmldsig.c:line=303:obj=unknown:subj=xmlSecDSi
>>
>> gCtxSigantureProcessNode:error=1:xmlsec library function failed:
>>
>> Any suggestions?
>>
>> Thanks,
>>
>> Sri
>>
>>     *From:* Aleksey Sanin <
>>     <mailto:aleksey at aleksey.com>aleksey at aleksey.com
>>     <mailto:aleksey at aleksey.com>>
>>     *Date:* August 13, 2010 1:13:22 PM CDT
>>     *To:* Duh Crab < <mailto:duhcrab at yahoo.com>duhcrab at yahoo.com
>>     <mailto:duhcrab at yahoo.com>>
>>     *Cc:* " <mailto:xmlsec at aleksey.com>xmlsec at aleksey.com
>>     <mailto:xmlsec at aleksey.com>" <
>>     <mailto:xmlsec at aleksey.com>xmlsec at aleksey.com
>>     <mailto:xmlsec at aleksey.com>>
>>     *Subject:* *Re: [xmlsec] Sign XML using EVP_PKEY and X509 cert in
>>     memory*
>>
>>     You can load PKCS12 key+cert directly from xmlsec, take a look
>>     at xmlSecCryptoAppPkcs12Load() and xmlSecCryptoAppPkcs12LoadMemory()
>>     functions. Or xmlsec-openssl specific call
>>     xmlSecOpenSSLAppPkcs12LoadBIO().
>>
>>     Otherwise, if you want to parse PKCS12 container yourself, take
>>     a look at xmlsec-openssl specific functions in
>>     xmlsec/openssl/evp.h and xmlsec/openssl/x509.h. Something like
>>     xmlSecOpenSSLEvpKeyAdopt(), xmlSecOpenSSLKeyDataX509AdoptKeyCert(),
>>     and xmlSecOpenSSLKeyDataX509AdoptCert(). For details on how to use
>>     these functions, best of all study the source code for the
>>     xmlSecOpenSSLAppPkcs12LoadBIO() function. It makes all the right
>>     calls in the right order :)
>>
>>     Aleksey
>>
>>     On 8/13/2010 11:05 AM, Duh Crab wrote:
>>
>>         I am trying to sign XML using the pkey and X509 cert in a
>>         pkcs12 file.
>>
>>         I extracted the pkey and cert from the pkcs12 file using the
>>         following -
>>
>>         EVP_PKEY *pkey;
>>
>>         X509 *cert;
>>
>>         PKCS12 *p12;
>>
>>         p12 = d2i_PKCS12_fp(fp, NULL);
>>
>>         PKCS12_parse(p12, passphrase,&pkey,&cert,&ca);
>>
>>         I now want to use the pkey and cert from above to sign xml
>>         using xmlsec.
>>
>>         How do I use these with the following api's?
>>
>>         xmlSecCryptoAppKeyLoadMemory()
>>
>>         xmlSecOpenSSLAppKeyCertLoadMemory()
>>
>>         If I save the pkey and cert above to the filesystem and then
>>         call -
>>
>>         xmlSecCryptoAppKeyLoad() and xmlSecCryptoAppKeyCertLoad()
>>         (along with other xmlsec api's), everything works well and I
>>
>>         am able to sign the XML.
>>
>>         However, there are cases where I do not have access to the
>>         filesystem and need to use pkey and cert from memory.
>>
>>         Thanks,
>>
>>         Sri
>>
>>         _______________________________________________
>>
>>         xmlsec mailing list
>>
>>         <mailto:xmlsec at aleksey.com>xmlsec at aleksey.com
>>         <mailto:xmlsec at aleksey.com>
>>
>>         <http://www.aleksey.com/mailman/listinfo/xmlsec>http://www.aleksey.com/mailman/listinfo/xmlsec
>>
>
>
>
> _______________________________________________
> xmlsec mailing list
> xmlsec at aleksey.com
> http://www.aleksey.com/mailman/listinfo/xmlsec


More information about the xmlsec mailing list