[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&nbsp;to my=20
problem.</FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</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>&nbsp;</DIV>
<DIV><FONT face=3DCourier><FONT size=3D2>Here is&nbsp;my function which =
does that=20
and returns an xmlSecKeyPtr:</FONT></FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DCourier size=3D2>static xmlSecKeyPtr=20
ReadPublicKeyFromPemCert(const char* certFile){<BR>&nbsp;xmlSecKeyPtr =
retval =3D=20
NULL; </FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DCourier size=3D2>&nbsp;// Load certificate from=20
file<BR>&nbsp;FILE* fid =3D fopen(certFile, "r");<BR>&nbsp;X509* pCert =
=3D=20
PEM_read_X509(fid, NULL, NULL, NULL);<BR>&nbsp;fclose(fid);</FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DCourier size=3D2>&nbsp;// Get the public key from the=20
certificate<BR>&nbsp;EVP_PKEY *pPublicKey =3D =
X509_get_pubkey(pCert);</FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DCourier=20
size=3D2>&nbsp;if(!pPublicKey){<BR>&nbsp;&nbsp;printf("Failed to get =
public key=20
from cert\n");<BR>&nbsp;<BR>&nbsp;&nbsp;return =
NULL;<BR>&nbsp;}</FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DCourier size=3D2>&nbsp;// I only handle RSA=20
keys<BR>&nbsp;if(pPublicKey-&gt;type =3D=3D =
EVP_PKEY_RSA){<BR>&nbsp;&nbsp;retval =3D=20
xmlSecKeyCreate(xmlSecRsaKey,=20
xmlSecKeyOriginX509);<BR>&nbsp;&nbsp;if(xmlSecRsaKeyGenerate(retval,=20
pPublicKey-&gt;pkey.rsa) &lt; 0){<BR>&nbsp;&nbsp;&nbsp;printf("Failed to =

generate public key from RSA=20
key\n");<BR>&nbsp;&nbsp;&nbsp;xmlSecKeyDestroy(retval);<BR>&nbsp;&nbsp;&n=
bsp;EVP_PKEY_free(pPublicKey);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp=
;&nbsp;&nbsp;return=20
NULL;<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;EVP_PKEY_free(pPublicKey);</FONT></=
DIV>
<DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DCourier size=3D2>&nbsp;&nbsp;return=20
retval;<BR>&nbsp;}</FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DCourier =
size=3D2>&nbsp;EVP_PKEY_free(pPublicKey);</FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DCourier size=3D2>&nbsp;printf("Unknown public key type =
in=20
cert");<BR>&nbsp;<BR>&nbsp;return NULL;<BR>}<BR></FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT><FONT face=3DCourier><FONT=20
size=3D2></FONT>&nbsp;</DIV></FONT>
<DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</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>&nbsp;</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>&nbsp;</DIV>
<DIV><FONT face=3DCourier size=3D2>Thanks for all =
help!</FONT></DIV></BODY></HTML>

------=_NextPart_000_0007_01C29549.E3CADFB0--