[xmlsec] Verifying a signature against a PEM certificate, SOLUTION!
Asbjørn Oskal
asbjorn.oskal@welldiagnostics.com
Tue, 26 Nov 2002 12:46:50 +0100
This is a multi-part message in MIME format.
------=_NextPart_000_0007_01C29549.E3CADFB0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Hi!
I seem to have found a solution to my problem.
I wanted to use a X509 pem certificate to validate a signature but I did =
not
find a straightforward solution to load a public key from a certificate.
I have struggled a bit to work this out but it turned out wasn't so bad =
afterall.=20
Since I could not load a PEM certificate directly I have to get the (in =
my case)=20
RSA public key from the certificate and turn it into a xmlSecKeyPtr.
Here is my function which does that and returns an xmlSecKeyPtr:
static xmlSecKeyPtr ReadPublicKeyFromPemCert(const char* certFile){
xmlSecKeyPtr retval =3D NULL;=20
// Load certificate from file
FILE* fid =3D fopen(certFile, "r");
X509* pCert =3D PEM_read_X509(fid, NULL, NULL, NULL);
fclose(fid);
// Get the public key from the certificate
EVP_PKEY *pPublicKey =3D X509_get_pubkey(pCert);
if(!pPublicKey){
printf("Failed to get public key from cert\n");
=20
return NULL;
}
// I only handle RSA keys
if(pPublicKey->type =3D=3D EVP_PKEY_RSA){
retval =3D xmlSecKeyCreate(xmlSecRsaKey, xmlSecKeyOriginX509);
if(xmlSecRsaKeyGenerate(retval, pPublicKey->pkey.rsa) < 0){
printf("Failed to generate public key from RSA key\n");
xmlSecKeyDestroy(retval);
EVP_PKEY_free(pPublicKey);
=20
return NULL;
}
EVP_PKEY_free(pPublicKey);
return retval;
}
EVP_PKEY_free(pPublicKey);
printf("Unknown public key type in cert");
=20
return NULL;
}
I then use this public key together with xmlSecDSigValidate and it seems =
to work Ok.
Please comment if you see something bad about this.
Thanks for all help!
------=_NextPart_000_0007_01C29549.E3CADFB0
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.2800.1106" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3DCourier size=3D2>Hi!<BR></FONT></DIV>
<DIV><FONT face=3DCourier size=3D2>I seem to have found a =
solution to my=20
problem.</FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>I wanted to use a X509 pem =
certificate to=20
validate a signature but I did not</FONT></DIV>
<DIV><FONT face=3DCourier><FONT size=3D2>find a straightforward solution =
to load a=20
public key from a certificate.</FONT></FONT></DIV>
<DIV><FONT face=3DCourier><FONT size=3D2>I have struggled a bit to work =
this out but=20
</FONT></FONT><FONT face=3DCourier><FONT size=3D2>it turned out wasn't =
so bad=20
afterall. </FONT></FONT></DIV>
<DIV><FONT face=3DCourier><FONT size=3D2>Since I could not load a PEM =
certificate=20
directly I have to </FONT></FONT><FONT face=3DCourier><FONT size=3D2>get =
the (in my=20
case) </FONT></FONT></DIV>
<DIV><FONT face=3DCourier><FONT size=3D2>RSA public key from the =
certificate and=20
turn it into a xmlSecKeyPtr.</FONT></FONT></DIV>
<DIV><FONT face=3DCourier><FONT size=3D2></FONT></FONT> </DIV>
<DIV><FONT face=3DCourier><FONT size=3D2>Here is my function which =
does that=20
and returns an xmlSecKeyPtr:</FONT></FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>static xmlSecKeyPtr=20
ReadPublicKeyFromPemCert(const char* certFile){<BR> xmlSecKeyPtr =
retval =3D=20
NULL; </FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2> // Load certificate from=20
file<BR> FILE* fid =3D fopen(certFile, "r");<BR> X509* pCert =
=3D=20
PEM_read_X509(fid, NULL, NULL, NULL);<BR> fclose(fid);</FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2> // Get the public key from the=20
certificate<BR> EVP_PKEY *pPublicKey =3D =
X509_get_pubkey(pCert);</FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier=20
size=3D2> if(!pPublicKey){<BR> printf("Failed to get =
public key=20
from cert\n");<BR> <BR> return =
NULL;<BR> }</FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2> // I only handle RSA=20
keys<BR> if(pPublicKey->type =3D=3D =
EVP_PKEY_RSA){<BR> retval =3D=20
xmlSecKeyCreate(xmlSecRsaKey,=20
xmlSecKeyOriginX509);<BR> if(xmlSecRsaKeyGenerate(retval,=20
pPublicKey->pkey.rsa) < 0){<BR> printf("Failed to =
generate public key from RSA=20
key\n");<BR> xmlSecKeyDestroy(retval);<BR> &n=
bsp;EVP_PKEY_free(pPublicKey);<BR> <BR> =
; return=20
NULL;<BR> }<BR> EVP_PKEY_free(pPublicKey);</FONT></=
DIV>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2> return=20
retval;<BR> }</FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier =
size=3D2> EVP_PKEY_free(pPublicKey);</FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2> printf("Unknown public key type =
in=20
cert");<BR> <BR> return NULL;<BR>}<BR></FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT><FONT face=3DCourier><FONT=20
size=3D2></FONT> </DIV></FONT>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>I then use this public key together =
with=20
</FONT><FONT face=3DCourier size=3D2>xmlSecDSigValidate and it seems to =
work=20
Ok.</FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>Please comment if you see something =
bad about=20
this.</FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>Thanks for all =
help!</FONT></DIV></BODY></HTML>
------=_NextPart_000_0007_01C29549.E3CADFB0--