<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.openssl.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Richmoore</id>
	<title>OpenSSLWiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.openssl.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Richmoore"/>
	<link rel="alternate" type="text/html" href="https://wiki.openssl.org/index.php/Special:Contributions/Richmoore"/>
	<updated>2026-05-12T15:22:37Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.13</generator>
	<entry>
		<id>https://wiki.openssl.org/index.php?title=EVP_Signing_and_Verifying&amp;diff=2238</id>
		<title>EVP Signing and Verifying</title>
		<link rel="alternate" type="text/html" href="https://wiki.openssl.org/index.php?title=EVP_Signing_and_Verifying&amp;diff=2238"/>
		<updated>2015-06-21T21:37:09Z</updated>

		<summary type="html">&lt;p&gt;Richmoore: /* Signing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There are two APIs available to perform sign and verify operations. The first are the older &amp;lt;tt&amp;gt;EVP_Sign*&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;EVP_Verify*&amp;lt;/tt&amp;gt; functions; and the second are the newer and more flexible &amp;lt;tt&amp;gt;EVP_DigestSign*&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;EVP_DigestVerify*&amp;lt;/tt&amp;gt; functions. Though the APIs are similar, new applications should use the &amp;lt;tt&amp;gt;EVP_DigestSign*&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;EVP_DigestVerify*&amp;lt;/tt&amp;gt; functions.&lt;br /&gt;
&lt;br /&gt;
The examples below use the new &amp;lt;tt&amp;gt;EVP_DigestSign*&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;EVP_DigestVerify*&amp;lt;/tt&amp;gt; functions to demonstarte signing and verification. The first example uses an HMAC, and the second example uses RSA key pairs. Additionally, the code for the examples are available for download.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
In general, signing a message is a three stage process:&lt;br /&gt;
&lt;br /&gt;
* Initialize the context with a message digest/hash function and &amp;lt;tt&amp;gt;EVP_PKEY&amp;lt;/tt&amp;gt; key&lt;br /&gt;
* Add the message data (this step can be repeated as many times as necessary)&lt;br /&gt;
* Finalize the context to create the signature&lt;br /&gt;
&lt;br /&gt;
In order to initialize, you first need to select a message digest algorithm (refer to [[EVP#Working with Algorithms and Modes|Working with Algorithms and Modes]]). Second, you need to provide a &amp;lt;tt&amp;gt;EVP_PKEY&amp;lt;/tt&amp;gt; containing a key for an algorithm that supports signing (refer to [[EVP#Working with EVP_PKEYs|Working with EVP_PKEYs]]). Both the digest and the key are provided to &amp;lt;tt&amp;gt;EVP_DigestSignInit&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To add the message data, you call &amp;lt;tt&amp;gt;EVP_DigestSignUpdate&amp;lt;/tt&amp;gt; one or more times.&lt;br /&gt;
&lt;br /&gt;
To finalize the operation and retrieve the signature, you call &amp;lt;tt&amp;gt;EVP_DigestSignFinal&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In general, verification follows the same steps. The key difference is the finalization:&lt;br /&gt;
&lt;br /&gt;
* Initialize the context with a message digest/hash function and &amp;lt;tt&amp;gt;EVP_PKEY&amp;lt;/tt&amp;gt; key&lt;br /&gt;
* Add the message data (this step can be repeated as many times as necessary)&lt;br /&gt;
* Finalize the context '''''with''''' the previous signature to verify the message&lt;br /&gt;
&lt;br /&gt;
When finalizing during verification, you add the signature in the call. &amp;lt;tt&amp;gt;EVP_DigestVerifyFinal&amp;lt;/tt&amp;gt; will then perform the validate the signature on the message.&lt;br /&gt;
&lt;br /&gt;
==HMAC==&lt;br /&gt;
&lt;br /&gt;
The first example shows how to create a signature over a message using an HMAC with &amp;lt;tt&amp;gt;EVP_DigestSignInit&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;EVP_DigestSignUpdate&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;EVP_DigestSignFinal&amp;lt;/tt&amp;gt;. The second part shows how to verify a signature over the message using using the same &amp;lt;tt&amp;gt;EVP_DigestSign&amp;lt;/tt&amp;gt; functions. You do not use the &amp;lt;tt&amp;gt;EVP_DigestVerify&amp;lt;/tt&amp;gt; functions to verify.&lt;br /&gt;
&lt;br /&gt;
'''''Note well''''': you do not use &amp;lt;tt&amp;gt;EVP_DigestVerify&amp;lt;/tt&amp;gt; to verify an HMAC. &amp;lt;tt&amp;gt;EVP_DigestVerifyInit&amp;lt;/tt&amp;gt; will fail with an error 0x608f096: &amp;lt;tt&amp;gt;error:0608F096:digital envelope routines:EVP_PKEY_verify_init:operation not supported for this keytype&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Signing===&lt;br /&gt;
&lt;br /&gt;
The code below signs a string using an HMAC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;int sign_it(const byte* msg, size_t mlen, byte** sig, size_t* slen, EVP_PKEY* pkey)&lt;br /&gt;
{&lt;br /&gt;
    /* Returned to caller */&lt;br /&gt;
    int result = -1;&lt;br /&gt;
    &lt;br /&gt;
    if(!msg || !mlen || !sig || !pkey) {&lt;br /&gt;
        assert(0);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if(*sig)&lt;br /&gt;
        OPENSSL_free(*sig);&lt;br /&gt;
    &lt;br /&gt;
    *sig = NULL;&lt;br /&gt;
    *slen = 0;&lt;br /&gt;
    &lt;br /&gt;
    EVP_MD_CTX* ctx = NULL;&lt;br /&gt;
    &lt;br /&gt;
    do&lt;br /&gt;
    {&lt;br /&gt;
        ctx = EVP_MD_CTX_create();&lt;br /&gt;
        assert(ctx != NULL);&lt;br /&gt;
        if(ctx == NULL) {&lt;br /&gt;
            printf(&amp;quot;EVP_MD_CTX_create failed, error 0x%lx\n&amp;quot;, ERR_get_error());&lt;br /&gt;
            break; /* failed */&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        const EVP_MD* md = EVP_get_digestbyname(&amp;quot;SHA256&amp;quot;);&lt;br /&gt;
        assert(md != NULL);&lt;br /&gt;
        if(md == NULL) {&lt;br /&gt;
            printf(&amp;quot;EVP_get_digestbyname failed, error 0x%lx\n&amp;quot;, ERR_get_error());&lt;br /&gt;
            break; /* failed */&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        int rc = EVP_DigestInit_ex(ctx, md, NULL);&lt;br /&gt;
        assert(rc == 1);&lt;br /&gt;
        if(rc != 1) {&lt;br /&gt;
            printf(&amp;quot;EVP_DigestInit_ex failed, error 0x%lx\n&amp;quot;, ERR_get_error());&lt;br /&gt;
            break; /* failed */&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        rc = EVP_DigestSignInit(ctx, NULL, md, NULL, pkey);&lt;br /&gt;
        assert(rc == 1);&lt;br /&gt;
        if(rc != 1) {&lt;br /&gt;
            printf(&amp;quot;EVP_DigestSignInit failed, error 0x%lx\n&amp;quot;, ERR_get_error());&lt;br /&gt;
            break; /* failed */&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        rc = EVP_DigestSignUpdate(ctx, msg, mlen);&lt;br /&gt;
        assert(rc == 1);&lt;br /&gt;
        if(rc != 1) {&lt;br /&gt;
            printf(&amp;quot;EVP_DigestSignUpdate failed, error 0x%lx\n&amp;quot;, ERR_get_error());&lt;br /&gt;
            break; /* failed */&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        size_t req = 0;&lt;br /&gt;
        rc = EVP_DigestSignFinal(ctx, NULL, &amp;amp;req);&lt;br /&gt;
        assert(rc == 1);&lt;br /&gt;
        if(rc != 1) {&lt;br /&gt;
            printf(&amp;quot;EVP_DigestSignFinal failed (1), error 0x%lx\n&amp;quot;, ERR_get_error());&lt;br /&gt;
            break; /* failed */&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        assert(req &amp;gt; 0);&lt;br /&gt;
        if(!(req &amp;gt; 0)) {&lt;br /&gt;
            printf(&amp;quot;EVP_DigestSignFinal failed (2), error 0x%lx\n&amp;quot;, ERR_get_error());&lt;br /&gt;
            break; /* failed */&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        *sig = OPENSSL_malloc(req);&lt;br /&gt;
        assert(*sig != NULL);&lt;br /&gt;
        if(*sig == NULL) {&lt;br /&gt;
            printf(&amp;quot;OPENSSL_malloc failed, error 0x%lx\n&amp;quot;, ERR_get_error());&lt;br /&gt;
            break; /* failed */&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        *slen = req;&lt;br /&gt;
        rc = EVP_DigestSignFinal(ctx, *sig, slen);&lt;br /&gt;
        assert(rc == 1);&lt;br /&gt;
        if(rc != 1) {&lt;br /&gt;
            printf(&amp;quot;EVP_DigestSignFinal failed (3), return code %d, error 0x%lx\n&amp;quot;, rc, ERR_get_error());&lt;br /&gt;
            break; /* failed */&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        assert(req == *slen);&lt;br /&gt;
        if(rc != 1) {&lt;br /&gt;
            printf(&amp;quot;EVP_DigestSignFinal failed, mismatched signature sizes %ld, %ld&amp;quot;, req, *slen);&lt;br /&gt;
            break; /* failed */&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        result = 0;&lt;br /&gt;
        &lt;br /&gt;
    } while(0);&lt;br /&gt;
    &lt;br /&gt;
    if(ctx) {&lt;br /&gt;
        EVP_MD_CTX_destroy(ctx);&lt;br /&gt;
        ctx = NULL;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Convert to 0/1 result */&lt;br /&gt;
    return !!result;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Verifying===&lt;br /&gt;
&lt;br /&gt;
The code below performs verification of a string using an HMAC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;int verify_it(const byte* msg, size_t mlen, const byte* sig, size_t slen, EVP_PKEY* pkey)&lt;br /&gt;
{&lt;br /&gt;
    /* Returned to caller */&lt;br /&gt;
    int result = -1;&lt;br /&gt;
    &lt;br /&gt;
    if(!msg || !mlen || !sig || !slen || !pkey) {&lt;br /&gt;
        assert(0);&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    EVP_MD_CTX* ctx = NULL;&lt;br /&gt;
    &lt;br /&gt;
    do&lt;br /&gt;
    {&lt;br /&gt;
        ctx = EVP_MD_CTX_create();&lt;br /&gt;
        assert(ctx != NULL);&lt;br /&gt;
        if(ctx == NULL) {&lt;br /&gt;
            printf(&amp;quot;EVP_MD_CTX_create failed, error 0x%lx\n&amp;quot;, ERR_get_error());&lt;br /&gt;
            break; /* failed */&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        const EVP_MD* md = EVP_get_digestbyname(&amp;quot;SHA256&amp;quot;);&lt;br /&gt;
        assert(md != NULL);&lt;br /&gt;
        if(md == NULL) {&lt;br /&gt;
            printf(&amp;quot;EVP_get_digestbyname failed, error 0x%lx\n&amp;quot;, ERR_get_error());&lt;br /&gt;
            break; /* failed */&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        int rc = EVP_DigestInit_ex(ctx, md, NULL);&lt;br /&gt;
        assert(rc == 1);&lt;br /&gt;
        if(rc != 1) {&lt;br /&gt;
            printf(&amp;quot;EVP_DigestInit_ex failed, error 0x%lx\n&amp;quot;, ERR_get_error());&lt;br /&gt;
            break; /* failed */&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        rc = EVP_DigestSignInit(ctx, NULL, md, NULL, pkey);&lt;br /&gt;
        assert(rc == 1);&lt;br /&gt;
        if(rc != 1) {&lt;br /&gt;
            printf(&amp;quot;EVP_DigestSignInit failed, error 0x%lx\n&amp;quot;, ERR_get_error());&lt;br /&gt;
            break; /* failed */&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        rc = EVP_DigestSignUpdate(ctx, msg, mlen);&lt;br /&gt;
        assert(rc == 1);&lt;br /&gt;
        if(rc != 1) {&lt;br /&gt;
            printf(&amp;quot;EVP_DigestSignUpdate failed, error 0x%lx\n&amp;quot;, ERR_get_error());&lt;br /&gt;
            break; /* failed */&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        byte buff[EVP_MAX_MD_SIZE];&lt;br /&gt;
        size_t size = sizeof(buff);&lt;br /&gt;
        &lt;br /&gt;
        rc = EVP_DigestSignFinal(ctx, buff, &amp;amp;size);&lt;br /&gt;
        assert(rc == 1);&lt;br /&gt;
        if(rc != 1) {&lt;br /&gt;
            printf(&amp;quot;EVP_DigestVerifyFinal failed, error 0x%lx\n&amp;quot;, ERR_get_error());&lt;br /&gt;
            break; /* failed */&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        assert(size &amp;gt; 0);&lt;br /&gt;
        if(!(size &amp;gt; 0)) {&lt;br /&gt;
            printf(&amp;quot;EVP_DigestSignFinal failed (2)\n&amp;quot;);&lt;br /&gt;
            break; /* failed */&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        const size_t m = (slen &amp;lt; size ? slen : size);&lt;br /&gt;
        result = !!CRYPTO_memcmp(sig, buff, m);&lt;br /&gt;
        &lt;br /&gt;
        OPENSSL_cleanse(buff, sizeof(buff));&lt;br /&gt;
        &lt;br /&gt;
    } while(0);&lt;br /&gt;
    &lt;br /&gt;
    if(ctx) {&lt;br /&gt;
        EVP_MD_CTX_destroy(ctx);&lt;br /&gt;
        ctx = NULL;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Convert to 0/1 result */&lt;br /&gt;
    return !!result;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Public Key==&lt;br /&gt;
&lt;br /&gt;
The second example shows how to create a signature over a message using public keys with &amp;lt;tt&amp;gt;EVP_DigestSignInit&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;EVP_DigestSignUpdate&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;EVP_DigestSignFinal&amp;lt;/tt&amp;gt;. The second example shows how to verify a signature over the message using &amp;lt;tt&amp;gt;EVP_DigestVerifyInit&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;EVP_DigestVerifyUpdate&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;EVP_DigestVerifyFinal&amp;lt;/tt&amp;gt;. Unlike HMACs, you do use the &amp;lt;tt&amp;gt;EVP_DigestVerify&amp;lt;/tt&amp;gt; functions to verify.&lt;br /&gt;
&lt;br /&gt;
===Signing===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;EVP_MD_CTX *mdctx = NULL;&lt;br /&gt;
int ret = 0;&lt;br /&gt;
 &lt;br /&gt;
*sig = NULL;&lt;br /&gt;
 &lt;br /&gt;
/* Create the Message Digest Context */&lt;br /&gt;
if(!(mdctx = EVP_MD_CTX_create())) goto err;&lt;br /&gt;
 &lt;br /&gt;
/* Initialise the DigestSign operation - SHA-256 has been selected as the message digest function in this example */&lt;br /&gt;
 if(1 != EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, key)) goto err;&lt;br /&gt;
 &lt;br /&gt;
 /* Call update with the message */&lt;br /&gt;
 if(1 != EVP_DigestSignUpdate(mdctx, msg, strlen(msg))) goto err;&lt;br /&gt;
 &lt;br /&gt;
 /* Finalise the DigestSign operation */&lt;br /&gt;
 /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the&lt;br /&gt;
  * signature. Length is returned in slen */&lt;br /&gt;
 if(1 != EVP_DigestSignFinal(mdctx, NULL, slen)) goto err;&lt;br /&gt;
 /* Allocate memory for the signature based on size in slen */&lt;br /&gt;
 if(!(*sig = OPENSSL_malloc(sizeof(unsigned char) * (*slen)))) goto err;&lt;br /&gt;
 /* Obtain the signature */&lt;br /&gt;
 if(1 != EVP_DigestSignFinal(mdctx, *sig, slen)) goto err;&lt;br /&gt;
 &lt;br /&gt;
 /* Success */&lt;br /&gt;
 ret = 1;&lt;br /&gt;
 &lt;br /&gt;
 err:&lt;br /&gt;
 if(ret != 1)&lt;br /&gt;
 {&lt;br /&gt;
   /* Do some error handling */&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 /* Clean up */&lt;br /&gt;
 if(*sig &amp;amp;&amp;amp; !ret) OPENSSL_free(*sig);&lt;br /&gt;
 if(mdctx) EVP_MD_CTX_destroy(mdctx);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: There is no difference in the API between signing using an asymmetric algorithm, and generating a MAC code. In the case of CMAC no message digest function is required (NULL can be passed). Signing using the EVP_Sign* functions is very similar to the above example, except there is no support for MAC codes. Note that CMAC is only supported in the (as yet unreleased) version 1.1.0 of OpenSSL.&lt;br /&gt;
&lt;br /&gt;
One gotcha to be aware of is that the first call to EVP_DigestSignFinal simply returns the maximum size of the buffer required. This will not always be the same as the size of the generated signature (specifically in the case of DSA and ECDSA). This means that you should also take account of the value of the length returned on the second call (in the slen variable in this example) when making use of the signature.&lt;br /&gt;
&lt;br /&gt;
Refer to [[Manual:EVP_DigestSignInit(3)]] for further details on the EVP_DigestSign* functions, and [[Manual:EVP_SignInit(3)]] for the EVP_Sign* functions.&lt;br /&gt;
&lt;br /&gt;
===Verifying===&lt;br /&gt;
&lt;br /&gt;
Verifying a message is very similar to signing except the EVP_DigestVerify* functions (or EVP_Verify* functions) are used instead. Clearly only a public key is required for a verify operation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;/* Initialize `key` with a public key */&lt;br /&gt;
if(1 != EVP_DigestVerifyInit(mdctx, NULL, EVP_sha256(), NULL, key)) goto err;&lt;br /&gt;
&lt;br /&gt;
/* Initialize `key` with a public key */&lt;br /&gt;
if(1 != EVP_DigestVerifyUpdate(mdctx, msg, strlen(msg))) goto err;&lt;br /&gt;
&lt;br /&gt;
if(1 == EVP_DigestVerifyFinal(mdctx, sig, slen))&lt;br /&gt;
{&lt;br /&gt;
    /* Success */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
    /* Failure */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that MAC operations do not support the verify operation. Verifying a MAC code is done by calling the sign operations and confirming that the generated code is identical to the one provided. It is important that when comparing a supplied MAC with an expected MAC that the comparison takes a constant time whether the comparison returns a match or not. Failure to do this can expose your code to timing attacks, which could (for example) enable an attacker to forge MAC codes. To do this use the CRYPTO_memcmp function as shown in the code example below. '''Never''' use memcmp for this test:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	if(!(mdctx = EVP_MD_CTX_create())) goto err;&lt;br /&gt;
&lt;br /&gt;
	/* Create a buffer to store the MAC for the received message */&lt;br /&gt;
	if(!(sigtmp = OPENSSL_malloc(sizeof(unsigned char) * EVP_PKEY_size(key)))) goto err;&lt;br /&gt;
	sigtmplen = EVP_PKEY_size(key);&lt;br /&gt;
&lt;br /&gt;
	/* Calculate the MAC for the received message */&lt;br /&gt;
	if(1 != EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, key)) goto err;&lt;br /&gt;
	if(1 != EVP_DigestSignUpdate(mdctx, msg, strlen(msg))) goto err;&lt;br /&gt;
	if(1 != EVP_DigestSignFinal(mdctx, sigtmp, &amp;amp;sigtmplen)) goto err;&lt;br /&gt;
&lt;br /&gt;
	/* Check the lengths of the calculated and supplied MACs are the same */ &lt;br /&gt;
	if(sigtmplen != slen) goto err;&lt;br /&gt;
&lt;br /&gt;
	/* Calculated MAC is in sigtmp. Supplied MAC is in sig. Compare the two */&lt;br /&gt;
	if(CRYPTO_memcmp(sig, sigtmp, slen))	&lt;br /&gt;
		/* Verify failure */ goto failure;&lt;br /&gt;
	else&lt;br /&gt;
		/* Verify success */;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Refer to [[Manual:EVP_DigestVerifyInit(3)]] and [[Manual:EVP_VerifyInit(3)]] for further information on the verify functions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Downloads==&lt;br /&gt;
&lt;br /&gt;
[[Media:t-hmac.c.tar.gz|t-hmac.c.tar.gz]] - sample program to sign and verify a string using an HMAC with the &amp;lt;tt&amp;gt;EVP_DigestSign*&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;EVP_DigestVerify*&amp;lt;/tt&amp;gt; functions.&lt;br /&gt;
&lt;br /&gt;
[[Media:t-rsa.c.tar.gz|t-rsa.c.tar.gz]] - sample program to sign and verify a string using RSA with the &amp;lt;tt&amp;gt;EVP_DigestSign*&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;EVP_DigestVerify*&amp;lt;/tt&amp;gt; functions.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[EVP]]&lt;br /&gt;
* [[Libcrypto API]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Crypto API]]&lt;br /&gt;
[[Category:C level]]&lt;br /&gt;
[[Category:Examples]]&lt;/div&gt;</summary>
		<author><name>Richmoore</name></author>
	</entry>
	<entry>
		<id>https://wiki.openssl.org/index.php?title=Simple_TLS_Server&amp;diff=2222</id>
		<title>Simple TLS Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.openssl.org/index.php?title=Simple_TLS_Server&amp;diff=2222"/>
		<updated>2015-05-18T20:38:05Z</updated>

		<summary type="html">&lt;p&gt;Richmoore: Fix missing error check on accept&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The code below is a complete implementation of a minimal TLS server. The first thing we do is initialise openssl in the ''init_openssl()'' function  by loading the strings used for error messages, and setting up the algorithms needed for TLS. We then create an ''SSL_CTX'' or SSL context. This is created using the ''SSLv23_server_method'' which despite its name actually creates a server that will negotiate the highest version of SSL/TLS supported by the client it is connecting to. The context is then configured - we use ''SSL_CTX_set_ecdh_auto'' to tell openssl to handle selecting the right elliptic curves for us (this function isn't available in older versions of openssl which required this to be done manually). The final step of configuring the context is to specify the certificate and private key to use.&lt;br /&gt;
&lt;br /&gt;
Next we perform some normal socket programming and create a new server socket, there's nothing openssl specific about this code. Whenever we get a new connection we call ''accept'' as normal. To handle the TLS we create a new ''SSL'' structure, this holds the information related to this particular connection. We use ''SSL_set_fd'' to tell openssl the file descriptor to use for the communication. In this example, we call ''SSL_accept'' to handle the server side of the TLS handshake, then use ''SSL_write()'' to send our message. Finally we clean up the various structures.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/socket.h&amp;gt;&lt;br /&gt;
#include &amp;lt;arpa/inet.h&amp;gt;&lt;br /&gt;
#include &amp;lt;openssl/ssl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;openssl/err.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int create_socket(int port)&lt;br /&gt;
{&lt;br /&gt;
    int s;&lt;br /&gt;
    struct sockaddr_in addr;&lt;br /&gt;
&lt;br /&gt;
    addr.sin_family = AF_INET;&lt;br /&gt;
    addr.sin_port = htons(port);&lt;br /&gt;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);&lt;br /&gt;
&lt;br /&gt;
    s = socket(AF_INET, SOCK_STREAM, 0);&lt;br /&gt;
    if (s &amp;lt; 0) {&lt;br /&gt;
	perror(&amp;quot;Unable to create socket&amp;quot;);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (bind(s, (struct sockaddr*)&amp;amp;addr, sizeof(addr)) &amp;lt; 0) {&lt;br /&gt;
	perror(&amp;quot;Unable to bind&amp;quot;);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen(s, 1) &amp;lt; 0) {&lt;br /&gt;
	perror(&amp;quot;Unable to listen&amp;quot;);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void init_openssl()&lt;br /&gt;
{ &lt;br /&gt;
    SSL_load_error_strings();	&lt;br /&gt;
    OpenSSL_add_ssl_algorithms();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void cleanup_openssl()&lt;br /&gt;
{&lt;br /&gt;
    EVP_cleanup();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
SSL_CTX *create_context()&lt;br /&gt;
{&lt;br /&gt;
    const SSL_METHOD *method;&lt;br /&gt;
    SSL_CTX *ctx;&lt;br /&gt;
&lt;br /&gt;
    method = SSLv23_server_method();&lt;br /&gt;
&lt;br /&gt;
    ctx = SSL_CTX_new(method);&lt;br /&gt;
    if (!ctx) {&lt;br /&gt;
	perror(&amp;quot;Unable to create SSL context&amp;quot;);&lt;br /&gt;
	ERR_print_errors_fp(stderr);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return ctx;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void configure_context(SSL_CTX *ctx)&lt;br /&gt;
{&lt;br /&gt;
    SSL_CTX_set_ecdh_auto(ctx, 1);&lt;br /&gt;
&lt;br /&gt;
    /* Set the key and cert */&lt;br /&gt;
    if (SSL_CTX_use_certificate_file(ctx, &amp;quot;cert.pem&amp;quot;, SSL_FILETYPE_PEM) &amp;lt; 0) {&lt;br /&gt;
        ERR_print_errors_fp(stderr);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (SSL_CTX_use_PrivateKey_file(ctx, &amp;quot;key.pem&amp;quot;, SSL_FILETYPE_PEM) &amp;lt; 0 ) {&lt;br /&gt;
        ERR_print_errors_fp(stderr);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
    int sock;&lt;br /&gt;
    SSL_CTX *ctx;&lt;br /&gt;
&lt;br /&gt;
    init_openssl();&lt;br /&gt;
    ctx = create_context();&lt;br /&gt;
&lt;br /&gt;
    configure_context(ctx);&lt;br /&gt;
&lt;br /&gt;
    sock = create_socket(4433);&lt;br /&gt;
&lt;br /&gt;
    /* Handle connections */&lt;br /&gt;
    while(1) {&lt;br /&gt;
        struct sockaddr_in addr;&lt;br /&gt;
        uint len = sizeof(addr);&lt;br /&gt;
        SSL *ssl;&lt;br /&gt;
        const char reply[] = &amp;quot;test\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        int client = accept(sock, (struct sockaddr*)&amp;amp;addr, &amp;amp;len);&lt;br /&gt;
        if (client &amp;lt; 0) {&lt;br /&gt;
            perror(&amp;quot;Unable to accept&amp;quot;);&lt;br /&gt;
            exit(EXIT_FAILURE);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        ssl = SSL_new(ctx);&lt;br /&gt;
        SSL_set_fd(ssl, client);&lt;br /&gt;
&lt;br /&gt;
        if (SSL_accept(ssl) &amp;lt;= 0) {&lt;br /&gt;
            ERR_print_errors_fp(stderr);&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
            SSL_write(ssl, reply, strlen(reply));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        SSL_free(ssl);&lt;br /&gt;
        close(client);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    close(sock);&lt;br /&gt;
    SSL_CTX_free(ctx);&lt;br /&gt;
    cleanup_openssl();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Richmoore</name></author>
	</entry>
	<entry>
		<id>https://wiki.openssl.org/index.php?title=Simple_TLS_Server&amp;diff=2221</id>
		<title>Simple TLS Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.openssl.org/index.php?title=Simple_TLS_Server&amp;diff=2221"/>
		<updated>2015-05-17T19:49:44Z</updated>

		<summary type="html">&lt;p&gt;Richmoore: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The code below is a complete implementation of a minimal TLS server. The first thing we do is initialise openssl in the ''init_openssl()'' function  by loading the strings used for error messages, and setting up the algorithms needed for TLS. We then create an ''SSL_CTX'' or SSL context. This is created using the ''SSLv23_server_method'' which despite its name actually creates a server that will negotiate the highest version of SSL/TLS supported by the client it is connecting to. The context is then configured - we use ''SSL_CTX_set_ecdh_auto'' to tell openssl to handle selecting the right elliptic curves for us (this function isn't available in older versions of openssl which required this to be done manually). The final step of configuring the context is to specify the certificate and private key to use.&lt;br /&gt;
&lt;br /&gt;
Next we perform some normal socket programming and create a new server socket, there's nothing openssl specific about this code. Whenever we get a new connection we call ''accept'' as normal. To handle the TLS we create a new ''SSL'' structure, this holds the information related to this particular connection. We use ''SSL_set_fd'' to tell openssl the file descriptor to use for the communication. In this example, we call ''SSL_accept'' to handle the server side of the TLS handshake, then use ''SSL_write()'' to send our message. Finally we clean up the various structures.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/socket.h&amp;gt;&lt;br /&gt;
#include &amp;lt;arpa/inet.h&amp;gt;&lt;br /&gt;
#include &amp;lt;openssl/ssl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;openssl/err.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int create_socket(int port)&lt;br /&gt;
{&lt;br /&gt;
    int s;&lt;br /&gt;
    struct sockaddr_in addr;&lt;br /&gt;
&lt;br /&gt;
    addr.sin_family = AF_INET;&lt;br /&gt;
    addr.sin_port = htons(port);&lt;br /&gt;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);&lt;br /&gt;
&lt;br /&gt;
    s = socket(AF_INET, SOCK_STREAM, 0);&lt;br /&gt;
    if (s &amp;lt; 0) {&lt;br /&gt;
	perror(&amp;quot;Unable to create socket&amp;quot;);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (bind(s, (struct sockaddr*)&amp;amp;addr, sizeof(addr)) &amp;lt; 0) {&lt;br /&gt;
	perror(&amp;quot;Unable to bind&amp;quot;);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen(s, 1) &amp;lt; 0) {&lt;br /&gt;
	perror(&amp;quot;Unable to listen&amp;quot;);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void init_openssl()&lt;br /&gt;
{ &lt;br /&gt;
    SSL_load_error_strings();	&lt;br /&gt;
    OpenSSL_add_ssl_algorithms();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void cleanup_openssl()&lt;br /&gt;
{&lt;br /&gt;
    EVP_cleanup();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
SSL_CTX *create_context()&lt;br /&gt;
{&lt;br /&gt;
    const SSL_METHOD *method;&lt;br /&gt;
    SSL_CTX *ctx;&lt;br /&gt;
&lt;br /&gt;
    method = SSLv23_server_method();&lt;br /&gt;
&lt;br /&gt;
    ctx = SSL_CTX_new(method);&lt;br /&gt;
    if (!ctx) {&lt;br /&gt;
	perror(&amp;quot;Unable to create SSL context&amp;quot;);&lt;br /&gt;
	ERR_print_errors_fp(stderr);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return ctx;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void configure_context(SSL_CTX *ctx)&lt;br /&gt;
{&lt;br /&gt;
    SSL_CTX_set_ecdh_auto(ctx, 1);&lt;br /&gt;
&lt;br /&gt;
    /* Set the key and cert */&lt;br /&gt;
    if (SSL_CTX_use_certificate_file(ctx, &amp;quot;cert.pem&amp;quot;, SSL_FILETYPE_PEM) &amp;lt; 0) {&lt;br /&gt;
        ERR_print_errors_fp(stderr);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (SSL_CTX_use_PrivateKey_file(ctx, &amp;quot;key.pem&amp;quot;, SSL_FILETYPE_PEM) &amp;lt; 0 ) {&lt;br /&gt;
        ERR_print_errors_fp(stderr);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
    int sock;&lt;br /&gt;
    SSL_CTX *ctx;&lt;br /&gt;
&lt;br /&gt;
    init_openssl();&lt;br /&gt;
    ctx = create_context();&lt;br /&gt;
&lt;br /&gt;
    configure_context(ctx);&lt;br /&gt;
&lt;br /&gt;
    sock = create_socket(4433);&lt;br /&gt;
&lt;br /&gt;
    /* Handle connections */&lt;br /&gt;
    while(1) {&lt;br /&gt;
        struct sockaddr_in addr;&lt;br /&gt;
        uint len = sizeof(addr);&lt;br /&gt;
        SSL *ssl;&lt;br /&gt;
        const char reply[] = &amp;quot;test\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        uint client = accept(sock, (struct sockaddr*)&amp;amp;addr, &amp;amp;len);&lt;br /&gt;
        ssl = SSL_new(ctx);&lt;br /&gt;
        SSL_set_fd(ssl, client);&lt;br /&gt;
&lt;br /&gt;
        if (SSL_accept(ssl) &amp;lt;= 0) {&lt;br /&gt;
            ERR_print_errors_fp(stderr);&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
            SSL_write(ssl, reply, strlen(reply));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        SSL_free(ssl);&lt;br /&gt;
        close(client);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    close(sock);&lt;br /&gt;
    SSL_CTX_free(ctx);&lt;br /&gt;
    cleanup_openssl();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Richmoore</name></author>
	</entry>
	<entry>
		<id>https://wiki.openssl.org/index.php?title=Simple_TLS_Server&amp;diff=2220</id>
		<title>Simple TLS Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.openssl.org/index.php?title=Simple_TLS_Server&amp;diff=2220"/>
		<updated>2015-05-17T16:49:36Z</updated>

		<summary type="html">&lt;p&gt;Richmoore: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The code below is a complete implementation of a minimal TLS server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/socket.h&amp;gt;&lt;br /&gt;
#include &amp;lt;arpa/inet.h&amp;gt;&lt;br /&gt;
#include &amp;lt;openssl/ssl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;openssl/err.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int create_socket(int port)&lt;br /&gt;
{&lt;br /&gt;
    int s;&lt;br /&gt;
    struct sockaddr_in addr;&lt;br /&gt;
&lt;br /&gt;
    addr.sin_family = AF_INET;&lt;br /&gt;
    addr.sin_port = htons(port);&lt;br /&gt;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);&lt;br /&gt;
&lt;br /&gt;
    s = socket(AF_INET, SOCK_STREAM, 0);&lt;br /&gt;
    if (s &amp;lt; 0) {&lt;br /&gt;
	perror(&amp;quot;Unable to create socket&amp;quot;);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (bind(s, (struct sockaddr*)&amp;amp;addr, sizeof(addr)) &amp;lt; 0) {&lt;br /&gt;
	perror(&amp;quot;Unable to bind&amp;quot;);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen(s, 1) &amp;lt; 0) {&lt;br /&gt;
	perror(&amp;quot;Unable to listen&amp;quot;);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void init_openssl()&lt;br /&gt;
{ &lt;br /&gt;
    SSL_load_error_strings();	&lt;br /&gt;
    OpenSSL_add_ssl_algorithms();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void cleanup_openssl()&lt;br /&gt;
{&lt;br /&gt;
    EVP_cleanup();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
SSL_CTX *create_context()&lt;br /&gt;
{&lt;br /&gt;
    const SSL_METHOD *method;&lt;br /&gt;
    SSL_CTX *ctx;&lt;br /&gt;
&lt;br /&gt;
    method = SSLv23_server_method();&lt;br /&gt;
&lt;br /&gt;
    ctx = SSL_CTX_new(method);&lt;br /&gt;
    if (!ctx) {&lt;br /&gt;
	perror(&amp;quot;Unable to create SSL context&amp;quot;);&lt;br /&gt;
	ERR_print_errors_fp(stderr);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return ctx;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void configure_context(SSL_CTX *ctx)&lt;br /&gt;
{&lt;br /&gt;
    SSL_CTX_set_ecdh_auto(ctx, 1);&lt;br /&gt;
&lt;br /&gt;
    /* Set the key and cert */&lt;br /&gt;
    if (SSL_CTX_use_certificate_file(ctx, &amp;quot;cert.pem&amp;quot;, SSL_FILETYPE_PEM) &amp;lt; 0) {&lt;br /&gt;
        ERR_print_errors_fp(stderr);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (SSL_CTX_use_PrivateKey_file(ctx, &amp;quot;key.pem&amp;quot;, SSL_FILETYPE_PEM) &amp;lt; 0 ) {&lt;br /&gt;
        ERR_print_errors_fp(stderr);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
    int sock;&lt;br /&gt;
    SSL_CTX *ctx;&lt;br /&gt;
&lt;br /&gt;
    init_openssl();&lt;br /&gt;
    ctx = create_context();&lt;br /&gt;
&lt;br /&gt;
    configure_context(ctx);&lt;br /&gt;
&lt;br /&gt;
    sock = create_socket(4433);&lt;br /&gt;
&lt;br /&gt;
    /* Handle connections */&lt;br /&gt;
    while(1) {&lt;br /&gt;
        struct sockaddr_in addr;&lt;br /&gt;
        uint len = sizeof(addr);&lt;br /&gt;
        SSL *ssl;&lt;br /&gt;
        const char reply[] = &amp;quot;test\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        uint client = accept(sock, (struct sockaddr*)&amp;amp;addr, &amp;amp;len);&lt;br /&gt;
        ssl = SSL_new(ctx);&lt;br /&gt;
        SSL_set_fd(ssl, client);&lt;br /&gt;
&lt;br /&gt;
        if (SSL_accept(ssl) &amp;lt;= 0) {&lt;br /&gt;
            ERR_print_errors_fp(stderr);&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
            SSL_write(ssl, reply, strlen(reply));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        SSL_free(ssl);&lt;br /&gt;
        close(client);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    close(sock);&lt;br /&gt;
    SSL_CTX_free(ctx);&lt;br /&gt;
    cleanup_openssl();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Richmoore</name></author>
	</entry>
	<entry>
		<id>https://wiki.openssl.org/index.php?title=Simple_TLS_Server&amp;diff=2219</id>
		<title>Simple TLS Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.openssl.org/index.php?title=Simple_TLS_Server&amp;diff=2219"/>
		<updated>2015-05-17T12:04:17Z</updated>

		<summary type="html">&lt;p&gt;Richmoore: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The code below is a complete implementation of a minimal TLS server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/socket.h&amp;gt;&lt;br /&gt;
#include &amp;lt;arpa/inet.h&amp;gt;&lt;br /&gt;
#include &amp;lt;openssl/ssl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;openssl/err.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int create_socket(int port)&lt;br /&gt;
{&lt;br /&gt;
    int s;&lt;br /&gt;
    struct sockaddr_in addr;&lt;br /&gt;
&lt;br /&gt;
    addr.sin_family = AF_INET;&lt;br /&gt;
    addr.sin_port = htons(port);&lt;br /&gt;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);&lt;br /&gt;
&lt;br /&gt;
    s = socket(AF_INET, SOCK_STREAM, 0);&lt;br /&gt;
    if (s &amp;lt; 0) {&lt;br /&gt;
	perror(&amp;quot;Unable to create socket&amp;quot;);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (bind(s, (struct sockaddr*)&amp;amp;addr, sizeof(addr)) &amp;lt; 0) {&lt;br /&gt;
	perror(&amp;quot;Unable to bind&amp;quot;);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen(s, 1) &amp;lt; 0) {&lt;br /&gt;
	perror(&amp;quot;Unable to listen&amp;quot;);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void init_openssl()&lt;br /&gt;
{ &lt;br /&gt;
    SSL_load_error_strings();	&lt;br /&gt;
    OpenSSL_add_ssl_algorithms();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void cleanup_openssl()&lt;br /&gt;
{&lt;br /&gt;
    EVP_cleanup();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
SSL_CTX *create_context()&lt;br /&gt;
{&lt;br /&gt;
    const SSL_METHOD *method;&lt;br /&gt;
    SSL_CTX *ctx;&lt;br /&gt;
&lt;br /&gt;
    method = TLSv1_server_method();&lt;br /&gt;
&lt;br /&gt;
    ctx = SSL_CTX_new(method);&lt;br /&gt;
    if (!ctx) {&lt;br /&gt;
	perror(&amp;quot;Unable to create SSL context&amp;quot;);&lt;br /&gt;
	ERR_print_errors_fp(stderr);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return ctx;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
    int sock;&lt;br /&gt;
    SSL_CTX *ctx;&lt;br /&gt;
&lt;br /&gt;
    init_openssl();&lt;br /&gt;
    ctx = create_context();&lt;br /&gt;
&lt;br /&gt;
    /* Set the key and cert */&lt;br /&gt;
    if (SSL_CTX_use_certificate_file(ctx, &amp;quot;cert.pem&amp;quot;, SSL_FILETYPE_PEM) &amp;lt; 0) {&lt;br /&gt;
        ERR_print_errors_fp(stderr);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (SSL_CTX_use_PrivateKey_file(ctx, &amp;quot;key.pem&amp;quot;, SSL_FILETYPE_PEM) &amp;lt; 0 ) {&lt;br /&gt;
        ERR_print_errors_fp(stderr);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    sock = create_socket(4433);&lt;br /&gt;
&lt;br /&gt;
    /* Handle connections */&lt;br /&gt;
    while(1) {&lt;br /&gt;
        struct sockaddr_in addr;&lt;br /&gt;
        uint len = sizeof(addr);&lt;br /&gt;
        SSL *ssl;&lt;br /&gt;
        const char reply[] = &amp;quot;test\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        uint client = accept(sock, (struct sockaddr*)&amp;amp;addr, &amp;amp;len);&lt;br /&gt;
        ssl = SSL_new(ctx);&lt;br /&gt;
        SSL_set_fd(ssl, client);&lt;br /&gt;
&lt;br /&gt;
        if (SSL_accept(ssl) &amp;lt;= 0) {&lt;br /&gt;
            ERR_print_errors_fp(stderr);&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
            SSL_write(ssl, reply, strlen(reply));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        SSL_free(ssl);&lt;br /&gt;
        close(client);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    close(sock);&lt;br /&gt;
    SSL_CTX_free(ctx);&lt;br /&gt;
    cleanup_openssl();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Richmoore</name></author>
	</entry>
	<entry>
		<id>https://wiki.openssl.org/index.php?title=Simple_TLS_Server&amp;diff=2218</id>
		<title>Simple TLS Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.openssl.org/index.php?title=Simple_TLS_Server&amp;diff=2218"/>
		<updated>2015-05-16T09:39:02Z</updated>

		<summary type="html">&lt;p&gt;Richmoore: /* Simple TLS Server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The code below is a complete implementation of a minimal TLS server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/socket.h&amp;gt;&lt;br /&gt;
#include &amp;lt;arpa/inet.h&amp;gt;&lt;br /&gt;
#include &amp;lt;openssl/ssl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;openssl/err.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int create_socket(int port)&lt;br /&gt;
{&lt;br /&gt;
    int s;&lt;br /&gt;
    struct sockaddr_in addr;&lt;br /&gt;
&lt;br /&gt;
    addr.sin_family = AF_INET;&lt;br /&gt;
    addr.sin_port = htons(port);&lt;br /&gt;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);&lt;br /&gt;
&lt;br /&gt;
    s = socket(AF_INET, SOCK_STREAM, 0);&lt;br /&gt;
&lt;br /&gt;
    if (bind(s, (struct sockaddr*)&amp;amp;addr, sizeof(addr)) &amp;lt; 0) {&lt;br /&gt;
	perror(&amp;quot;Unable to bind&amp;quot;);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen(s, 1) &amp;lt; 0) {&lt;br /&gt;
	perror(&amp;quot;Unable to listen&amp;quot;);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void init_openssl()&lt;br /&gt;
{ &lt;br /&gt;
    SSL_load_error_strings();	&lt;br /&gt;
    OpenSSL_add_ssl_algorithms();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void cleanup_openssl()&lt;br /&gt;
{&lt;br /&gt;
    EVP_cleanup();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
SSL_CTX *create_context()&lt;br /&gt;
{&lt;br /&gt;
    const SSL_METHOD *method;&lt;br /&gt;
    SSL_CTX *ctx;&lt;br /&gt;
&lt;br /&gt;
    method = TLSv1_server_method();&lt;br /&gt;
&lt;br /&gt;
    ctx = SSL_CTX_new(method);&lt;br /&gt;
    if (!ctx) {&lt;br /&gt;
	perror(&amp;quot;Unable to create SSL context&amp;quot;);&lt;br /&gt;
	ERR_print_errors_fp(stderr);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return ctx;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
    int sock;&lt;br /&gt;
    SSL_CTX *ctx;&lt;br /&gt;
&lt;br /&gt;
    init_openssl();&lt;br /&gt;
    ctx = create_context();&lt;br /&gt;
&lt;br /&gt;
    /* Set the key and cert */&lt;br /&gt;
    if (SSL_CTX_use_certificate_file(ctx, &amp;quot;cert.pem&amp;quot;, SSL_FILETYPE_PEM) &amp;lt; 0) {&lt;br /&gt;
        ERR_print_errors_fp(stderr);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (SSL_CTX_use_PrivateKey_file(ctx, &amp;quot;key.pem&amp;quot;, SSL_FILETYPE_PEM) &amp;lt; 0 ) {&lt;br /&gt;
        ERR_print_errors_fp(stderr);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    sock = create_socket(4433);&lt;br /&gt;
&lt;br /&gt;
    /* Handle connections */&lt;br /&gt;
    while(1) {&lt;br /&gt;
        struct sockaddr_in addr;&lt;br /&gt;
        uint len = sizeof(addr);&lt;br /&gt;
        SSL *ssl;&lt;br /&gt;
        const char reply[] = &amp;quot;test\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        uint client = accept(sock, (struct sockaddr*)&amp;amp;addr, &amp;amp;len);&lt;br /&gt;
        ssl = SSL_new(ctx);&lt;br /&gt;
        SSL_set_fd(ssl, client);&lt;br /&gt;
&lt;br /&gt;
        if (SSL_accept(ssl) &amp;lt;= 0) {&lt;br /&gt;
            ERR_print_errors_fp(stderr);&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
            SSL_write(ssl, reply, strlen(reply));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        SSL_free(ssl);&lt;br /&gt;
        close(client);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    close(sock);&lt;br /&gt;
    SSL_CTX_free(ctx);&lt;br /&gt;
    cleanup_openssl();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Richmoore</name></author>
	</entry>
	<entry>
		<id>https://wiki.openssl.org/index.php?title=Simple_TLS_Server&amp;diff=2217</id>
		<title>Simple TLS Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.openssl.org/index.php?title=Simple_TLS_Server&amp;diff=2217"/>
		<updated>2015-05-16T09:38:49Z</updated>

		<summary type="html">&lt;p&gt;Richmoore: Created page with &amp;quot;= Simple TLS Server =  The code below is a complete implementation of a minimal TLS server.  &amp;lt;pre&amp;gt;  #include &amp;lt;stdio.h&amp;gt; #include &amp;lt;unistd.h&amp;gt; #include &amp;lt;sys/socket.h&amp;gt; #include &amp;lt;ar...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Simple TLS Server =&lt;br /&gt;
&lt;br /&gt;
The code below is a complete implementation of a minimal TLS server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/socket.h&amp;gt;&lt;br /&gt;
#include &amp;lt;arpa/inet.h&amp;gt;&lt;br /&gt;
#include &amp;lt;openssl/ssl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;openssl/err.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int create_socket(int port)&lt;br /&gt;
{&lt;br /&gt;
    int s;&lt;br /&gt;
    struct sockaddr_in addr;&lt;br /&gt;
&lt;br /&gt;
    addr.sin_family = AF_INET;&lt;br /&gt;
    addr.sin_port = htons(port);&lt;br /&gt;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);&lt;br /&gt;
&lt;br /&gt;
    s = socket(AF_INET, SOCK_STREAM, 0);&lt;br /&gt;
&lt;br /&gt;
    if (bind(s, (struct sockaddr*)&amp;amp;addr, sizeof(addr)) &amp;lt; 0) {&lt;br /&gt;
	perror(&amp;quot;Unable to bind&amp;quot;);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen(s, 1) &amp;lt; 0) {&lt;br /&gt;
	perror(&amp;quot;Unable to listen&amp;quot;);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void init_openssl()&lt;br /&gt;
{ &lt;br /&gt;
    SSL_load_error_strings();	&lt;br /&gt;
    OpenSSL_add_ssl_algorithms();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void cleanup_openssl()&lt;br /&gt;
{&lt;br /&gt;
    EVP_cleanup();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
SSL_CTX *create_context()&lt;br /&gt;
{&lt;br /&gt;
    const SSL_METHOD *method;&lt;br /&gt;
    SSL_CTX *ctx;&lt;br /&gt;
&lt;br /&gt;
    method = TLSv1_server_method();&lt;br /&gt;
&lt;br /&gt;
    ctx = SSL_CTX_new(method);&lt;br /&gt;
    if (!ctx) {&lt;br /&gt;
	perror(&amp;quot;Unable to create SSL context&amp;quot;);&lt;br /&gt;
	ERR_print_errors_fp(stderr);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return ctx;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
    int sock;&lt;br /&gt;
    SSL_CTX *ctx;&lt;br /&gt;
&lt;br /&gt;
    init_openssl();&lt;br /&gt;
    ctx = create_context();&lt;br /&gt;
&lt;br /&gt;
    /* Set the key and cert */&lt;br /&gt;
    if (SSL_CTX_use_certificate_file(ctx, &amp;quot;cert.pem&amp;quot;, SSL_FILETYPE_PEM) &amp;lt; 0) {&lt;br /&gt;
        ERR_print_errors_fp(stderr);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (SSL_CTX_use_PrivateKey_file(ctx, &amp;quot;key.pem&amp;quot;, SSL_FILETYPE_PEM) &amp;lt; 0 ) {&lt;br /&gt;
        ERR_print_errors_fp(stderr);&lt;br /&gt;
	exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    sock = create_socket(4433);&lt;br /&gt;
&lt;br /&gt;
    /* Handle connections */&lt;br /&gt;
    while(1) {&lt;br /&gt;
        struct sockaddr_in addr;&lt;br /&gt;
        uint len = sizeof(addr);&lt;br /&gt;
        SSL *ssl;&lt;br /&gt;
        const char reply[] = &amp;quot;test\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        uint client = accept(sock, (struct sockaddr*)&amp;amp;addr, &amp;amp;len);&lt;br /&gt;
        ssl = SSL_new(ctx);&lt;br /&gt;
        SSL_set_fd(ssl, client);&lt;br /&gt;
&lt;br /&gt;
        if (SSL_accept(ssl) &amp;lt;= 0) {&lt;br /&gt;
            ERR_print_errors_fp(stderr);&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
            SSL_write(ssl, reply, strlen(reply));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        SSL_free(ssl);&lt;br /&gt;
        close(client);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    close(sock);&lt;br /&gt;
    SSL_CTX_free(ctx);&lt;br /&gt;
    cleanup_openssl();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Richmoore</name></author>
	</entry>
	<entry>
		<id>https://wiki.openssl.org/index.php?title=Main_Page&amp;diff=2216</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.openssl.org/index.php?title=Main_Page&amp;diff=2216"/>
		<updated>2015-05-16T09:35:46Z</updated>

		<summary type="html">&lt;p&gt;Richmoore: /* Usage and Programming */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If this is your first visit or to get an account please see the [[Welcome]] page. Your participation and [[Contributions]] are valued.&lt;br /&gt;
&lt;br /&gt;
This wiki is intended as a place for collecting, organizing, and refining useful information about OpenSSL that is currently strewn among multiple locations and formats.&lt;br /&gt;
&lt;br /&gt;
== OpenSSL Quick Links ==&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;TABLE border=0&amp;gt;&lt;br /&gt;
     &amp;lt;TR&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[OpenSSL Overview]]&amp;lt;/TD&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[Image:HTAB.png]][[Image:HTAB.png]]&amp;lt;/TD&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[Compilation and Installation]]&amp;lt;/TD&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[Image:HTAB.png]][[Image:HTAB.png]]&amp;lt;/TD&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[Internals]]&amp;lt;/TD&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[Image:HTAB.png]][[Image:HTAB.png]]&amp;lt;/TD&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[Mailing Lists]] &amp;lt;/TD&amp;gt;&lt;br /&gt;
      &amp;lt;/TR&amp;gt;&lt;br /&gt;
      &amp;lt;TR&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[libcrypto API]]&amp;lt;/TD&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[Image:HTAB.png]][[Image:HTAB.png]]&amp;lt;/TD&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[libssl API]]&amp;lt;/TD&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[Image:HTAB.png]][[Image:HTAB.png]]&amp;lt;/TD&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[Examples]] &amp;lt;/TD&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[Image:HTAB.png]][[Image:HTAB.png]]&amp;lt;/TD&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[Documentation Index|Index of all API functions]]&amp;lt;/TD&amp;gt;&lt;br /&gt;
      &amp;lt;/TR&amp;gt;&lt;br /&gt;
      &amp;lt;TR&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[License]] &amp;lt;/TD&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[Image:HTAB.png]][[Image:HTAB.png]]&amp;lt;/TD&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[Command Line Utilities]]&amp;lt;/TD&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[Image:HTAB.png]][[Image:HTAB.png]]&amp;lt;/TD&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[Related Links]]&amp;lt;/TD&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[Image:HTAB.png]][[Image:HTAB.png]]&amp;lt;/TD&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[SSL and TLS Protocols]]&amp;lt;/TD&amp;gt;&lt;br /&gt;
      &amp;lt;/TR&amp;gt;&lt;br /&gt;
      &amp;lt;TR&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[1.1 API Changes]]&amp;lt;/TD&amp;gt;&lt;br /&gt;
        &amp;lt;TD&amp;gt;[[Image:HTAB.png]][[Image:HTAB.png]]&amp;lt;/TD&amp;gt;&lt;br /&gt;
      &amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/TABLE&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Administrivia ==&lt;br /&gt;
Site guidelines, legal and admininstrative issues.&lt;br /&gt;
:* [[Basic rules]], [[Commercial Product Disclaimer]], [[Contributions]], [[Copyright]], [[License]]&lt;br /&gt;
:* Using This Wiki&lt;br /&gt;
:: [http://meta.wikimedia.org/wiki/Help:Contents Wiki User's Guide], [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list], [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ], [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki Mailing List]&lt;br /&gt;
&lt;br /&gt;
== Reference ==&lt;br /&gt;
This section contains the automagically generated man pages from the OpenSSL git repository, and similar &amp;quot;man&amp;quot; style reference documentation. The man pages are automatically imported from the OpenSSL git repository and local wiki modifications are submitted as patches.&lt;br /&gt;
:* OpenSSL Manual Pages&lt;br /&gt;
::* [[Manual:Openssl(1)]], [[Manual:Ssl(3)]], [[Manual:Crypto(3)]], [[Documentation Index]]&lt;br /&gt;
:: If you wish to edit any of the Manual page content please refer to the [[Guidelines for Manual Page Authors]] page.&lt;br /&gt;
:* [[API]], [[Libcrypto API]], [[Libssl API]]&lt;br /&gt;
:* [[FIPS mode()]], [[FIPS_mode_set()]]&lt;br /&gt;
&lt;br /&gt;
== Usage and Programming ==&lt;br /&gt;
This section has discussions of practical issues in using OpenSSL&lt;br /&gt;
:* Building from Source&lt;br /&gt;
:: Where to find it, the different versions, how to build and install it.&lt;br /&gt;
:* [[OpenSSL Overview]]&lt;br /&gt;
:* [[Versioning]]&lt;br /&gt;
:* [[Compilation and Installation]]&lt;br /&gt;
:* [[EVP]]&lt;br /&gt;
:: Programming techniques and example code&lt;br /&gt;
:: Use of EVP is preferred for most applications and circumstances&lt;br /&gt;
::* [[EVP Asymmetric Encryption and Decryption of an Envelope]]&lt;br /&gt;
::* [[EVP Authenticated Encryption and Decryption]]&lt;br /&gt;
::* [[EVP Symmetric Encryption and Decryption]]&lt;br /&gt;
::* [[EVP Key and Parameter Generation]]&lt;br /&gt;
::* [[EVP Key Agreement]]&lt;br /&gt;
::* [[EVP Message Digests]]&lt;br /&gt;
::* [[EVP Key Derivation]]&lt;br /&gt;
::* [[EVP Signing and Verifying|EVP Signing and Verifying (including MAC codes)]]&lt;br /&gt;
:* [[STACK API]]&lt;br /&gt;
:* Low Level APIs&lt;br /&gt;
:: More specialized non-EVP usage&lt;br /&gt;
::* [[Diffie-Hellman parameters]]&lt;br /&gt;
:* [[FIPS Mode]]&lt;br /&gt;
:* [[Simple TLS Server]]&lt;br /&gt;
&lt;br /&gt;
== Concepts and Theory ==&lt;br /&gt;
Discussions of basic cryptographic theory and concepts&lt;br /&gt;
Discussions of common operational issues&lt;br /&gt;
:* [[Base64]]&lt;br /&gt;
:* [http://wiki.openssl.org/index.php/Category:FIPS_140 FIPS 140-2]&lt;br /&gt;
:* [[Random Numbers]]&lt;br /&gt;
:* [[Diffie Hellman]]&lt;br /&gt;
:* [[Elliptic Curve Diffie Hellman]]&lt;br /&gt;
:* [[Elliptic Curve Cryptography]]&lt;br /&gt;
&lt;br /&gt;
== Security Advisories ==&lt;br /&gt;
:* [https://www.openssl.org/about/secpolicy.html OpenSSL Security Policy]&lt;br /&gt;
:* [https://www.openssl.org/news/vulnerabilities.html OpenSSL Vulnerabilities List]&lt;br /&gt;
:* [[Security_Advisories|Security Advisories Additional Information]]&lt;br /&gt;
&lt;br /&gt;
== Feedback and Contributions ==&lt;br /&gt;
:* [https://www.openssl.org/support/faq.html#BUILD18 Notification of suspected security vulnerabilities]&lt;br /&gt;
:* [https://www.openssl.org/support/rt.html Contributing bug reports, other than for suspected vulnerabilities]&lt;br /&gt;
:* [[Contributions|General background on source and documentation contributions - '''must read''']]&lt;br /&gt;
:* Contributing code fixes, other than for suspected vulnerabilities, as well as fixes and other improvements to manual pages&lt;br /&gt;
::* Follow the [[Use of Git#Use_of_Git_with_OpenSSL_source_tree|instructions for accessing source code]] in the appropriate branches&lt;br /&gt;
:::* Note that manual pages and the FAQ are maintained with the source code.&lt;br /&gt;
::* If you are unsure as to whether a feature will be useful for the general OpenSSL community please discuss it on the [https://www.openssl.org/support/community.html openssl-dev mailing list] first.  Someone may be already working on the same thing or there may be a good reason as to why that feature isn't implemented.&lt;br /&gt;
::* Submit a pull request for each separate fix (also documented [[Use of Git#Use_of_Git_with_OpenSSL_source_tree|there]])&lt;br /&gt;
::* Submit a bug report for the issue and reference the pull request&lt;br /&gt;
:* Contributing fixes and other improvements to the web site&lt;br /&gt;
::* Follow the [[Use_of_Git#Use_of_Git_with_the_OpenSSL_web_site|instructions for accessing web site sources]]&lt;br /&gt;
::* Create a patch (also documented [[Use_of_Git#Use_of_Git_with_the_OpenSSL_web_site|there]])&lt;br /&gt;
::* Submit a bug report and add the patch as an attachment&lt;br /&gt;
:* [[Developing For OpenSSL]]&lt;br /&gt;
:* [[KnownPatches|Known patches not part of OpenSSL]]&lt;br /&gt;
:* [[Welcome|Contributing to this wiki]]&lt;br /&gt;
&lt;br /&gt;
== Internals and Development ==&lt;br /&gt;
This section is for internal details of primary interest to OpenSSL maintainers and power users&lt;br /&gt;
:* [[Code reformatting]]&lt;br /&gt;
&lt;br /&gt;
:* [[Internals]]&lt;br /&gt;
:* [[Code Quality]]&lt;br /&gt;
:* [[Static and Dynamic Analysis]]&lt;br /&gt;
:* [[OCB|OCB Licence details]]&lt;br /&gt;
:* [[Defect and Feature Review Process]]&lt;br /&gt;
:* [[Unit Testing]] (includes other automated testing information)&lt;/div&gt;</summary>
		<author><name>Richmoore</name></author>
	</entry>
	<entry>
		<id>https://wiki.openssl.org/index.php?title=OpenSSL_1.1.0_Changes&amp;diff=2174</id>
		<title>OpenSSL 1.1.0 Changes</title>
		<link rel="alternate" type="text/html" href="https://wiki.openssl.org/index.php?title=OpenSSL_1.1.0_Changes&amp;diff=2174"/>
		<updated>2015-02-10T18:21:30Z</updated>

		<summary type="html">&lt;p&gt;Richmoore: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a parent page for discussion about API changes being done for OpenSSL version 1.1&lt;br /&gt;
&lt;br /&gt;
The overall goal of this project is to make most data structures opaque to applications.  This provides us with a number of benefits:&lt;br /&gt;
* We can add fields without breaking binary compatibility&lt;br /&gt;
* Applications are more robust and can be more assured about correctness&lt;br /&gt;
* It helps us determine which (new) accessors and settors, for example, are needed&lt;br /&gt;
&lt;br /&gt;
Please add sub-pages to discuss particular parts of the library has work progresses.&lt;br /&gt;
&lt;br /&gt;
So far, the SSL library has mostly been made opaque. The old DES API has been removed.&lt;br /&gt;
&lt;br /&gt;
== Things that Broke in Qt ==&lt;br /&gt;
&lt;br /&gt;
Here's what's broken in the dev branch of Qt when building openssl master as of 6 Feb 2015.&lt;br /&gt;
&lt;br /&gt;
* DH - we were directly accessing p and q to set the DH params to primes embedded in Qt. We can probably replace this with SSL_CTX_set_dh_auto(ctx, 1). Another option suggested by Steve Henson is to save the DHparams we're using at the moment then use d2i_DHparams to load them in. This is compatible with openssl versions that don't have the dh_auto option.&lt;br /&gt;
&lt;br /&gt;
* ctx-&amp;gt;cert_store - we were directly accessing the cert_store field of SSL_CTX. We can probably replace this with X509_STORE *SSL_CTX_get_cert_store(SSL_CTX *ctx) [Fixed in dev]&lt;br /&gt;
&lt;br /&gt;
* session-&amp;gt;tlsext_tick_lifetime_hint - we were directly accessing the lifetime hint of the session. No replacement found.&lt;br /&gt;
&lt;br /&gt;
* cipher-&amp;gt;valid - we were directly accessing the valid field of SSL_CIPHER. No replacement found. [This turned out not to be needed and so will be removed].&lt;br /&gt;
&lt;br /&gt;
== Things that Broke in Curl ==&lt;br /&gt;
&lt;br /&gt;
* SSL_SESSION-&amp;gt;ssl_version. Replaced with SSL_version(SSL *)&lt;br /&gt;
&lt;br /&gt;
== Things that Broke in wget ==&lt;br /&gt;
&lt;br /&gt;
* SSL-&amp;gt;state. Replaced with SSL_state(SSL *)&lt;/div&gt;</summary>
		<author><name>Richmoore</name></author>
	</entry>
	<entry>
		<id>https://wiki.openssl.org/index.php?title=OpenSSL_1.1.0_Changes&amp;diff=2173</id>
		<title>OpenSSL 1.1.0 Changes</title>
		<link rel="alternate" type="text/html" href="https://wiki.openssl.org/index.php?title=OpenSSL_1.1.0_Changes&amp;diff=2173"/>
		<updated>2015-02-10T18:17:30Z</updated>

		<summary type="html">&lt;p&gt;Richmoore: /* Things that Broke in Curl */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a parent page for discussion about API changes being done for OpenSSL version 1.1&lt;br /&gt;
&lt;br /&gt;
The overall goal of this project is to make most data structures opaque to applications.  This provides us with a number of benefits:&lt;br /&gt;
* We can add fields without breaking binary compatibility&lt;br /&gt;
* Applications are more robust and can be more assured about correctness&lt;br /&gt;
* It helps us determine which (new) accessors and settors, for example, are needed&lt;br /&gt;
&lt;br /&gt;
Please add sub-pages to discuss particular parts of the library has work progresses.&lt;br /&gt;
&lt;br /&gt;
So far, the SSL library has mostly been made opaque. The old DES API has been removed.&lt;br /&gt;
&lt;br /&gt;
== Things that Broke in Qt ==&lt;br /&gt;
&lt;br /&gt;
Here's what's broken in the dev branch of Qt when building openssl master as of 6 Feb 2015.&lt;br /&gt;
&lt;br /&gt;
* DH - we were directly accessing p and q to set the DH params to primes embedded in Qt. We can probably replace this with SSL_CTX_set_dh_auto(ctx, 1). Another option suggested by Steve Henson is to save the DHparams we're using at the moment then use d2i_DHparams to load them in. This is compatible with openssl versions that don't have the dh_auto option.&lt;br /&gt;
&lt;br /&gt;
* ctx-&amp;gt;cert_store - we were directly accessing the cert_store field of SSL_CTX. We can probably replace this with X509_STORE *SSL_CTX_get_cert_store(SSL_CTX *ctx) [Fixed in dev]&lt;br /&gt;
&lt;br /&gt;
* session-&amp;gt;tlsext_tick_lifetime_hint - we were directly accessing the lifetime hint of the session. No replacement found.&lt;br /&gt;
&lt;br /&gt;
* cipher-&amp;gt;valid - we were directly accessing the valid field of SSL_CIPHER. No replacement found. [This turned out not to be needed and so will be removed].&lt;br /&gt;
&lt;br /&gt;
== Things that Broke in Curl ==&lt;br /&gt;
&lt;br /&gt;
* SSL_SESSION-&amp;gt;ssl_version. Replaced with SSL_version(SSL *)&lt;br /&gt;
* SSL-&amp;gt;state. Replaced with SSL_state(SSL *)&lt;/div&gt;</summary>
		<author><name>Richmoore</name></author>
	</entry>
	<entry>
		<id>https://wiki.openssl.org/index.php?title=OpenSSL_1.1.0_Changes&amp;diff=2171</id>
		<title>OpenSSL 1.1.0 Changes</title>
		<link rel="alternate" type="text/html" href="https://wiki.openssl.org/index.php?title=OpenSSL_1.1.0_Changes&amp;diff=2171"/>
		<updated>2015-02-08T11:47:28Z</updated>

		<summary type="html">&lt;p&gt;Richmoore: /* Things that Broke in Qt */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a parent page for discussion about API changes being done for OpenSSL version 1.1&lt;br /&gt;
&lt;br /&gt;
The overall goal of this project is to make most data structures opaque to applications.  This provides us with a number of benefits:&lt;br /&gt;
* We can add fields without breaking binary compatibility&lt;br /&gt;
* Applications are more robust and can be more assured about correctness&lt;br /&gt;
* It helps us determine which (new) accessors and settors, for example, are needed&lt;br /&gt;
&lt;br /&gt;
Please add sub-pages to discuss particular parts of the library has work progresses.&lt;br /&gt;
&lt;br /&gt;
So far, the SSL library has mostly been made opaque. The old DES API has been removed.&lt;br /&gt;
&lt;br /&gt;
== Things that Broke in Qt ==&lt;br /&gt;
&lt;br /&gt;
Here's what's broken in the dev branch of Qt when building openssl master as of 6 Feb 2015.&lt;br /&gt;
&lt;br /&gt;
* DH - we were directly accessing p and q to set the DH params to primes embedded in Qt. We can probably replace this with SSL_CTX_set_dh_auto(ctx, 1). Another option suggested by Steve Henson is to save the DHparams we're using at the moment then use d2i_DHparams to load them in. This is compatible with openssl versions that don't have the dh_auto option.&lt;br /&gt;
&lt;br /&gt;
* ctx-&amp;gt;cert_store - we were directly accessing the cert_store field of SSL_CTX. We can probably replace this with X509_STORE *SSL_CTX_get_cert_store(SSL_CTX *ctx) [Fixed in dev]&lt;br /&gt;
&lt;br /&gt;
* session-&amp;gt;tlsext_tick_lifetime_hint - we were directly accessing the lifetime hint of the session. No replacement found.&lt;br /&gt;
&lt;br /&gt;
* cipher-&amp;gt;valid - we were directly accessing the valid field of SSL_CIPHER. No replacement found. [This turned out not to be needed and so will be removed].&lt;br /&gt;
&lt;br /&gt;
== Things that Broke in Curl ==&lt;br /&gt;
&lt;br /&gt;
* SSL_SESSION-&amp;gt;ssl_version. Replaced with SSL_version(SSL *)&lt;/div&gt;</summary>
		<author><name>Richmoore</name></author>
	</entry>
	<entry>
		<id>https://wiki.openssl.org/index.php?title=OpenSSL_1.1.0_Changes&amp;diff=2160</id>
		<title>OpenSSL 1.1.0 Changes</title>
		<link rel="alternate" type="text/html" href="https://wiki.openssl.org/index.php?title=OpenSSL_1.1.0_Changes&amp;diff=2160"/>
		<updated>2015-02-07T21:58:25Z</updated>

		<summary type="html">&lt;p&gt;Richmoore: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a parent page for discussion about API changes being done for OpenSSL version 1.1&lt;br /&gt;
&lt;br /&gt;
The overall goal of this project is to make most data structures opaque to applications.  This provides us with a number of benefits:&lt;br /&gt;
* We can add fields without breaking binary compatibility&lt;br /&gt;
* Applications are more robust and can be more assured about correctness&lt;br /&gt;
* It helps us determine which (new) accessors and settors, for example, are needed&lt;br /&gt;
&lt;br /&gt;
Please add sub-pages to discuss particular parts of the library has work progresses.&lt;br /&gt;
&lt;br /&gt;
So far, the SSL library has mostly been made opaque. The old DES API has been removed.&lt;br /&gt;
&lt;br /&gt;
== Things that Broke in Qt ==&lt;br /&gt;
&lt;br /&gt;
Here's what's broken in the dev branch of Qt when building openssl master as of 6 Feb 2015.&lt;br /&gt;
&lt;br /&gt;
* DH - we were directly accessing p and q to set the DH params to primes embedded in Qt. We can probably replace this with SSL_CTX_set_dh_auto(ctx, 1). Another option suggested by Steve Henson is to save the DHparams we're using at the moment then use d2i_DHparams to load them in. This is compatible with openssl versions that don't have the dh_auto option.&lt;br /&gt;
&lt;br /&gt;
* ctx-&amp;gt;cert_store - we were directly accessing the cert_store field of SSL_CTX. We can probably replace this with X509_STORE *SSL_CTX_get_cert_store(SSL_CTX *ctx)&lt;br /&gt;
&lt;br /&gt;
* session-&amp;gt;tlsext_tick_lifetime_hint - we were directly accessing the lifetime hint of the session. No replacement found.&lt;br /&gt;
&lt;br /&gt;
* cipher-&amp;gt;valid - we were directly accessing the valid field of SSL_CIPHER. No replacement found.&lt;br /&gt;
&lt;br /&gt;
== Things that Broke in Curl ==&lt;br /&gt;
&lt;br /&gt;
* SSL_SESSION-&amp;gt;ssl_version. Replaced with SSL_version(SSL *)&lt;/div&gt;</summary>
		<author><name>Richmoore</name></author>
	</entry>
	<entry>
		<id>https://wiki.openssl.org/index.php?title=OpenSSL_1.1.0_Changes&amp;diff=2159</id>
		<title>OpenSSL 1.1.0 Changes</title>
		<link rel="alternate" type="text/html" href="https://wiki.openssl.org/index.php?title=OpenSSL_1.1.0_Changes&amp;diff=2159"/>
		<updated>2015-02-07T20:01:50Z</updated>

		<summary type="html">&lt;p&gt;Richmoore: /* Things that Broke in Qt */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a parent page for discussion about API changes being done for OpenSSL version 1.1&lt;br /&gt;
&lt;br /&gt;
The overall goal of this project is to make most data structures opaque to applications.  This provides us with a number of benefits:&lt;br /&gt;
* We can add fields without breaking binary compatibility&lt;br /&gt;
* Applications are more robust and can be more assured about correctness&lt;br /&gt;
* It helps us determine which (new) accessors and settors, for example, are needed&lt;br /&gt;
&lt;br /&gt;
Please add sub-pages to discuss particular parts of the library has work progresses.&lt;br /&gt;
&lt;br /&gt;
So far, the SSL library has mostly been made opaque. The old DES API has been removed.&lt;br /&gt;
&lt;br /&gt;
== Things that Broke in Qt ==&lt;br /&gt;
&lt;br /&gt;
Here's what's broken in the dev branch of Qt when building openssl master as of 6 Feb 2015.&lt;br /&gt;
&lt;br /&gt;
* DH - we were directly accessing p and q to set the DH params to primes embedded in Qt. We can probably replace this with SSL_CTX_set_dh_auto(ctx, 1). Another option suggested by Steve Henson is to save the DHparams we're using at the moment then use d2i_DHparams to load them in. This is compatible with openssl versions that don't have the dh_auto option.&lt;br /&gt;
&lt;br /&gt;
* ctx-&amp;gt;cert_store - we were directly accessing the cert_store field of SSL_CTX. We can probably replace this with X509_STORE *SSL_CTX_get_cert_store(SSL_CTX *ctx)&lt;br /&gt;
&lt;br /&gt;
* session-&amp;gt;tlsext_tick_lifetime_hint - we were directly accessing the lifetime hint of the session. No replacement found.&lt;br /&gt;
&lt;br /&gt;
* cipher-&amp;gt;valid - we were directly accessing the valid field of SSL_CIPHER. No replacement found.&lt;/div&gt;</summary>
		<author><name>Richmoore</name></author>
	</entry>
	<entry>
		<id>https://wiki.openssl.org/index.php?title=OpenSSL_1.1.0_Changes&amp;diff=2158</id>
		<title>OpenSSL 1.1.0 Changes</title>
		<link rel="alternate" type="text/html" href="https://wiki.openssl.org/index.php?title=OpenSSL_1.1.0_Changes&amp;diff=2158"/>
		<updated>2015-02-07T14:36:47Z</updated>

		<summary type="html">&lt;p&gt;Richmoore: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a parent page for discussion about API changes being done for OpenSSL version 1.1&lt;br /&gt;
&lt;br /&gt;
The overall goal of this project is to make most data structures opaque to applications.  This provides us with a number of benefits:&lt;br /&gt;
* We can add fields without breaking binary compatibility&lt;br /&gt;
* Applications are more robust and can be more assured about correctness&lt;br /&gt;
* It helps us determine which (new) accessors and settors, for example, are needed&lt;br /&gt;
&lt;br /&gt;
Please add sub-pages to discuss particular parts of the library has work progresses.&lt;br /&gt;
&lt;br /&gt;
So far, the SSL library has mostly been made opaque. The old DES API has been removed.&lt;br /&gt;
&lt;br /&gt;
== Things that Broke in Qt ==&lt;br /&gt;
&lt;br /&gt;
Here's what's broken in the dev branch of Qt when building openssl master as of 6 Feb 2015.&lt;br /&gt;
&lt;br /&gt;
* DH - we were directly accessing p and q to set the DH params to primes embedded in Qt. We can probably replace this with SSL_CTX_set_dh_auto(ctx, 1)&lt;br /&gt;
&lt;br /&gt;
* ctx-&amp;gt;cert_store - we were directly accessing the cert_store field of SSL_CTX. We can probably replace this with X509_STORE *SSL_CTX_get_cert_store(SSL_CTX *ctx)&lt;br /&gt;
&lt;br /&gt;
* session-&amp;gt;tlsext_tick_lifetime_hint - we were directly accessing the lifetime hint of the session. No replacement found.&lt;br /&gt;
&lt;br /&gt;
* cipher-&amp;gt;valid - we were directly accessing the valid field of SSL_CIPHER. No replacement found.&lt;/div&gt;</summary>
		<author><name>Richmoore</name></author>
	</entry>
</feed>