Mercurial > dovecot > core-2.2
view src/lib-ssl-iostream/iostream-openssl-params.c @ 12616:bd23d4e10fa1
Added lib-ssl-iostream for handling SSL connections more easily.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 31 Jan 2011 18:40:27 +0200 |
parents | |
children | ba770cba5598 |
line wrap: on
line source
/* Copyright (c) 2009 Dovecot authors, see the included COPYING file */ #include "lib.h" #include "buffer.h" #include "iostream-openssl.h" /* 2 or 5. Haven't seen their difference explained anywhere, but 2 is the default.. */ #define DH_GENERATOR 2 static int dh_param_bitsizes[] = { 512, 1024 }; static int generate_dh_parameters(int bitsize, buffer_t *output) { DH *dh; unsigned char *p; int len, len2; dh = DH_generate_parameters(bitsize, DH_GENERATOR, NULL, NULL); if (dh == NULL) { i_error("DH_generate_parameters(bits=%d, gen=%d) failed: %s", bitsize, DH_GENERATOR, ssl_iostream_error()); return -1; } len = i2d_DHparams(dh, NULL); if (len < 0) { i_error("i2d_DHparams() failed: %s", ssl_iostream_error()); DH_free(dh); return -1; } buffer_append(output, &bitsize, sizeof(bitsize)); buffer_append(output, &len, sizeof(len)); p = buffer_append_space_unsafe(output, len); len2 = i2d_DHparams(dh, &p); i_assert(len == len2); DH_free(dh); return 0; } int ssl_iostream_generate_params(buffer_t *output) { unsigned int i; for (i = 0; i < N_ELEMENTS(dh_param_bitsizes); i++) { if (generate_dh_parameters(dh_param_bitsizes[i], output) < 0) return -1; } buffer_append_zero(output, sizeof(int)); return 0; } static int read_int(const unsigned char **data, const unsigned char *end) { unsigned int len = end - *data; int ret; if (len < sizeof(ret)) return -1; memcpy(&ret, *data, sizeof(ret)); *data += sizeof(ret); return ret; } static int read_dh_parameters_next(struct ssl_iostream_context *ctx, const unsigned char **data, const unsigned char *end) { const unsigned char *dbuf; DH *dh; int bits, len, ret = 1; /* get bit size. 0 ends the DH parameters list. */ if ((bits = read_int(data, end)) <= 0) return bits; /* get data size */ if ((len = read_int(data, end)) <= 0 || end - *data < len) return -1; dbuf = *data; dh = d2i_DHparams(NULL, &dbuf, len); *data += len; if (dh == NULL) return -1; switch (bits) { case 512: ctx->dh_512 = dh; break; case 1024: ctx->dh_1024 = dh; break; default: ret = -1; break; } return ret; } int ssl_iostream_context_import_params(struct ssl_iostream_context *ctx, const buffer_t *input) { const unsigned char *data, *end; int ret; ssl_iostream_context_free_params(ctx); data = input->data; end = data + input->used; while ((ret = read_dh_parameters_next(ctx, &data, end)) > 0) ; return ret < 0 || data != end ? -1 : 0; } void ssl_iostream_context_free_params(struct ssl_iostream_context *ctx) { if (ctx->dh_512 != NULL) { DH_free(ctx->dh_512); ctx->dh_512 = NULL; } if (ctx->dh_1024 != NULL) { DH_free(ctx->dh_1024); ctx->dh_1024 = NULL; } }