blob: cd8dc02fbba085a65b2310c4b1056c79e22ea549 [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>gSOAP WS-Security: The smdevp engine</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.3.8 -->
<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="annotated.html">Class&nbsp;List</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Class&nbsp;Members</a> | <a class="qindex" href="globals.html">File&nbsp;Members</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
<h1><a class="anchor" name="smdevp">The smdevp engine</a></h1>The gSOAP smdevp engine computes (signed) message digests over any type of data using the EVP interface of OpenSSL. It currently supports MD5, SHA1, HMAC_SHA1, DSA_SHA1, and RSA_SHA1.<p>
A digest or signature algorithm is selected with one the following constants:<p>
<ul>
<li><a class="el" href="smdevp_8h.html#a5">SOAP_SMD_DGST_MD5</a> to compute MD5 128-bit digests</li><li><a class="el" href="smdevp_8h.html#a6">SOAP_SMD_DGST_SHA1</a> to compute MD5 160-bit digests</li><li><a class="el" href="smdevp_8h.html#a7">SOAP_SMD_HMAC_SHA1</a> to compute HMAC-SHA1 message authentication code</li><li><a class="el" href="smdevp_8h.html#a8">SOAP_SMD_SIGN_DSA_SHA1</a> to compute DSA-SHA1 signatures</li><li><a class="el" href="smdevp_8h.html#a9">SOAP_SMD_SIGN_RSA_SHA1</a> to compute RSA-SHA1 signatures</li><li><a class="el" href="smdevp_8h.html#a10">SOAP_SMD_VRFY_DSA_SHA1</a> to verify DSA-SHA1 signatures</li><li><a class="el" href="smdevp_8h.html#a11">SOAP_SMD_VRFY_RSA_SHA1</a> to verify RSA-SHA1 signatures</li></ul>
<p>
The smdevp engine wraps the EVP API with three new functions:<p>
<ul>
<li><a class="el" href="smdevp_8h.html#a15">soap_smd_init</a> to initialize the engine</li><li><a class="el" href="smdevp_8h.html#a16">soap_smd_update</a> to update the state with a message part</li><li><a class="el" href="smdevp_8h.html#a17">soap_smd_final</a> to compute the digest, signature, or verify a signature</li></ul>
<p>
A higher-level interface for computing (signed) message digests over messages produced by the gSOAP enginre is defined by two new functions:<p>
<ul>
<li><a class="el" href="smdevp_8h.html#a13">soap_smd_begin</a> to start a digest or signature computation/verification</li><li><a class="el" href="smdevp_8h.html#a14">soap_smd_end</a> to complete a digest/signature computation/verification</li></ul>
<p>
Here is an example to sign an XML serialized C++ object using an RSA private key applied to the SHA1 digest of the serialized object:<p>
<div class="fragment"><pre> ns__Object *object = ...;
<span class="keywordtype">int</span> alg = <a class="code" href="smdevp_8h.html#a9">SOAP_SMD_SIGN_RSA_SHA1</a>;
FILE *fd = fopen(<span class="stringliteral">"key.pem"</span>, <span class="stringliteral">"r"</span>);
EVP_PKEY *key = PEM_read_PrivateKey(fd, NULL, NULL, <span class="stringliteral">"password"</span>);
<span class="keywordtype">char</span> *sig = (<span class="keywordtype">char</span>*)SOAP_MALLOC(soap, <a class="code" href="smdevp_8c.html#a3">soap_smd_size</a>(alg, key));
<span class="keywordtype">int</span> siglen;
fclose(fd);
<span class="keywordflow">if</span> (<a class="code" href="smdevp_8c.html#a4">soap_smd_begin</a>(soap, alg, key, 0)
|| soap_out_ns__Object(soap, <span class="stringliteral">"ns:Object"</span>, 0, object, NULL)
|| <a class="code" href="smdevp_8c.html#a5">soap_smd_end</a>(soap, sig, &amp;siglen))
soap_print_fault(soap, stderr);
<span class="keywordflow">else</span>
... <span class="comment">// sig contains RSA-SHA1 signature of length siglen </span>
</pre></div><p>
To verify the signature, we use the RSA public key and re-run the octet stream (by re-serialization in this example) through the smdevp engine using the SOAP_SMD_VRFY_RSA_SHA1 algorithm. Note that a PEM file may contain both the (encrypted) private and public keys.<p>
<div class="fragment"><pre> <span class="keywordtype">char</span> *sig = ...;
<span class="keywordtype">int</span> siglen = ...;
ns__Object *object = ...;
<span class="keywordtype">int</span> alg = <a class="code" href="smdevp_8h.html#a11">SOAP_SMD_VRFY_RSA_SHA1</a>;
FILE *fd = fopen(<span class="stringliteral">"key.pem"</span>, <span class="stringliteral">"r"</span>);
EVP_PKEY *key = PEM_read_PUBKEY(fd, NULL, NULL, NULL);
fclose(fd);
<span class="keywordflow">if</span> (<a class="code" href="smdevp_8c.html#a4">soap_smd_begin</a>(soap, alg, key, 0)
|| soap_out_ns__Object(soap, <span class="stringliteral">"ns:Object"</span>, 0, object, NULL)
|| <a class="code" href="smdevp_8c.html#a5">soap_smd_end</a>(soap, sig, &amp;siglen))
soap_print_fault(soap, stderr);
<span class="keywordflow">else</span>
... <span class="comment">// sig verified, i.e. signed object was not changed</span>
</pre></div><p>
The HMAC algorithm uses a secret key (which both the sender and receiver must keep secret) to sign and verify a message:<p>
<div class="fragment"><pre> ns__Object *object = ...;
<span class="keywordtype">int</span> alg = <a class="code" href="smdevp_8h.html#a7">SOAP_SMD_HMAC_SHA1</a>;
<span class="keyword">static</span> <span class="keywordtype">char</span> key[16] =
{ 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88,
0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00 };
<span class="keywordtype">char</span> *sig = (<span class="keywordtype">char</span>*)SOAP_MALLOC(soap, <a class="code" href="smdevp_8c.html#a3">soap_smd_size</a>(alg, NULL));
<span class="keywordtype">int</span> siglen;
<span class="keywordflow">if</span> (<a class="code" href="smdevp_8c.html#a4">soap_smd_begin</a>(soap, alg, key, <span class="keyword">sizeof</span>(key))
|| soap_out_ns__Object(soap, <span class="stringliteral">"ns:Object"</span>, 0, object, NULL)
|| <a class="code" href="smdevp_8c.html#a5">soap_smd_end</a>(soap, sig, &amp;siglen))
soap_print_fault(soap, stderr);
<span class="keywordflow">else</span>
... <span class="comment">// sig holds the signature</span>
</pre></div><p>
Note: HMAC signature verification proceeds by recomputing the signature value for comparison.<p>
A digest is a hash value of an octet stream computed using the MD5 or SHA1 algorithms:<p>
<div class="fragment"><pre> ns__Object *object = ...;
<span class="keywordtype">int</span> alg = <a class="code" href="smdevp_8h.html#a6">SOAP_SMD_DGST_SHA1</a>;
<span class="keywordtype">char</span> *digest = (<span class="keywordtype">char</span>*)SOAP_MALLOC(soap, <a class="code" href="smdevp_8c.html#a3">soap_smd_size</a>(alg, NULL));
<span class="keywordtype">int</span> digestlen;
<span class="keywordflow">if</span> (<a class="code" href="smdevp_8c.html#a4">soap_smd_begin</a>(soap, alg, NULL, 0)
|| soap_out_ns__Object(soap, <span class="stringliteral">"ns:Object"</span>, 0, object, NULL)
|| <a class="code" href="smdevp_8c.html#a5">soap_smd_end</a>(soap, digest, &amp;digestlen))
soap_print_fault(soap, stderr);
<span class="keywordflow">else</span>
... <span class="comment">// digest holds hash value of serialized object</span>
</pre></div><p>
Note that indentation (SOAP_XML_INDENT) and exc-c14n canonicalization (SOAP_XML_CANONICAL) affects the XML serialization format and, therefore, the digest or signature produced. <hr size="1"><address style="align: right;"><small>Generated on Fri Aug 19 10:41:46 2005 for gSOAP WS-Security by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border=0 ></a> 1.3.8 </small></address>
</body>
</html>