diff options
author | Trevor <unsafe@trevp.net> | 2013-06-13 22:36:45 -0700 |
---|---|---|
committer | Ben Laurie <ben@links.org> | 2013-06-18 16:13:08 +0100 |
commit | 9cd50f738ff55eae2a64f872492d3a7ce115f18d (patch) | |
tree | ff3b9868dd02aa7b632d82a8f9ff9f7c0d8ebc18 /ssl/ssl_rsa.c | |
parent | 8ee3c7e676c5edb1d5fbe0d66b7ce307a4f92899 (diff) | |
download | openssl-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.c | 62 |
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); |