summaryrefslogtreecommitdiff
path: root/ssl/ssl_rsa.c
diff options
context:
space:
mode:
authorTrevor <unsafe@trevp.net>2013-06-13 22:36:45 -0700
committerBen Laurie <ben@links.org>2013-06-18 16:13:08 +0100
commit9cd50f738ff55eae2a64f872492d3a7ce115f18d (patch)
treeff3b9868dd02aa7b632d82a8f9ff9f7c0d8ebc18 /ssl/ssl_rsa.c
parent8ee3c7e676c5edb1d5fbe0d66b7ce307a4f92899 (diff)
downloadopenssl-new-9cd50f738ff55eae2a64f872492d3a7ce115f18d.tar.gz
Cleanup of custom extension stuff.
serverinfo rejects non-empty extensions. Omit extension if no relevant serverinfo data. Improve error-handling in serverinfo callback. Cosmetic cleanups. s_client documentation. s_server documentation. SSL_CTX_serverinfo documentation. Cleaup -1 and NULL callback handling for custom extensions, add tests. Cleanup ssl_rsa.c serverinfo code. Whitespace cleanup. Improve comments in ssl.h for serverinfo. Whitespace. Cosmetic cleanup. Reject non-zero-len serverinfo extensions. Whitespace. Make it build.
Diffstat (limited to 'ssl/ssl_rsa.c')
-rw-r--r--ssl/ssl_rsa.c62
1 files changed, 42 insertions, 20 deletions
diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c
index ac16b8506d..507a3d1773 100644
--- a/ssl/ssl_rsa.c
+++ b/ssl/ssl_rsa.c
@@ -880,58 +880,79 @@ static int serverinfo_find_extension(const unsigned char *serverinfo,
/* end of serverinfo */
if (serverinfo_length == 0)
- return 0;
+ return -1; /* Extension not found */
/* read 2-byte type field */
if (serverinfo_length < 2)
- return 0; /* error */
+ return 0; /* Error */
type = (serverinfo[0] << 8) + serverinfo[1];
serverinfo += 2;
serverinfo_length -= 2;
/* read 2-byte len field */
if (serverinfo_length < 2)
- return 0; /* error */
+ return 0; /* Error */
len = (serverinfo[0] << 8) + serverinfo[1];
serverinfo += 2;
serverinfo_length -= 2;
if (len > serverinfo_length)
- return 0; /* error */
+ return 0; /* Error */
if (type == extension_type)
{
*extension_data = serverinfo;
*extension_length = len;
- return 1;
+ return 1; /* Success */
}
serverinfo += len;
serverinfo_length -= len;
}
- return 0;
+ return 0; /* Error */
}
-static int serverinfo_srv_cb(SSL *s, unsigned short ext_type,
- const unsigned char **out, unsigned short *outlen,
- void *arg)
+static int serverinfo_srv_first_cb(SSL *s, unsigned short ext_type,
+ const unsigned char *in,
+ unsigned short inlen, int *al,
+ void *arg)
+ {
+ if (inlen != 0)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ return 1;
+ }
+
+static int serverinfo_srv_second_cb(SSL *s, unsigned short ext_type,
+ const unsigned char **out, unsigned short *outlen,
+ void *arg)
{
const unsigned char *serverinfo = NULL;
size_t serverinfo_length = 0;
- /* Is there a serverinfo for the chosen server cert? */
+ /* Is there serverinfo data for the chosen server cert? */
if ((ssl_get_server_cert_serverinfo(s, &serverinfo,
&serverinfo_length)) != 0)
{
/* Find the relevant extension from the serverinfo */
- serverinfo_find_extension(serverinfo, serverinfo_length,
- ext_type, out, outlen);
- }
- return 1;
+ int retval = serverinfo_find_extension(serverinfo, serverinfo_length,
+ ext_type, out, outlen);
+ if (retval == 0)
+ return 0; /* Error */
+ if (retval == -1)
+ return -1; /* No extension found, don't send extension */
+ return 1; /* Send extension */
+ }
+ return -1; /* No serverinfo data found, don't send extension */
}
-static int serverinfo_validate(const unsigned char *serverinfo,
- size_t serverinfo_length, SSL_CTX *ctx)
+/* With a NULL context, this function just checks that the serverinfo data
+ parses correctly. With a non-NULL context, it registers callbacks for
+ the included extensions. */
+static int serverinfo_process_buffer(const unsigned char *serverinfo,
+ size_t serverinfo_length, SSL_CTX *ctx)
{
if (serverinfo == NULL || serverinfo_length == 0)
return 0;
@@ -951,8 +972,9 @@ static int serverinfo_validate(const unsigned char *serverinfo,
/* Register callbacks for extensions */
ext_type = (serverinfo[0] << 8) + serverinfo[1];
- if (ctx && !SSL_CTX_set_custom_srv_ext(ctx, ext_type, NULL,
- serverinfo_srv_cb, NULL))
+ if (ctx && !SSL_CTX_set_custom_srv_ext(ctx, ext_type,
+ serverinfo_srv_first_cb,
+ serverinfo_srv_second_cb, NULL))
return 0;
serverinfo += 2;
@@ -1058,7 +1080,7 @@ int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO,ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- if (!serverinfo_validate(serverinfo, serverinfo_length, NULL))
+ if (!serverinfo_process_buffer(serverinfo, serverinfo_length, NULL))
{
SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO,SSL_R_INVALID_SERVERINFO_DATA);
return(0);
@@ -1085,7 +1107,7 @@ int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
/* Now that the serverinfo is validated and stored, go ahead and
* register callbacks. */
- if (!serverinfo_validate(serverinfo, serverinfo_length, ctx))
+ if (!serverinfo_process_buffer(serverinfo, serverinfo_length, ctx))
{
SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO,SSL_R_INVALID_SERVERINFO_DATA);
return(0);