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

Duh Crab duhcrab at yahoo.com
Tue Aug 17 09:50:27 PDT 2010


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 <aleksey at aleksey.com>
Date: August 13, 2010 1:13:22 PM CDT
To: Duh Crab <duhcrab at yahoo.com>
Cc: "xmlsec at aleksey.com" <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

xmlsec at aleksey.com

http://www.aleksey.com/mailman/listinfo/xmlsec

 



      
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.aleksey.com/pipermail/xmlsec/attachments/20100817/753d7bab/attachment-0001.html>


More information about the xmlsec mailing list