[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