Commit 5230840f authored by johan's avatar johan

Add dtls-srtp functions to the crypto api

parent 456c332a
......@@ -53,6 +53,10 @@ else()
find_package(PolarSSL)
if (POLARSSL_FOUND)
message("Use polarSSL")
if (HAVE_SSL_GET_DTLS_SRTP_PROTECTION_PROFILE)
message("DTLS SRTP available")
set(HAVE_DTLS_SRTP 1)
endif()
else()
message(FATAL_ERROR " No polarSSL or mbedTLS found")
endif()
......
/*
chrypto.h
crypto.h
Copyright (C) 2016 Belledonne Communications SARL
This program is free software; you can redistribute it and/or
......@@ -36,48 +36,74 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/* Error codes : All error codes are negative and defined on 32 bits on format -0x7XXXXXXX
* in order to be sure to not overlap on crypto librairy (polarssl or mbedtls for now) which are defined on 16 bits 0x[7-0]XXX */
#define BCTOOLBOX_ERROR_UNSPECIFIED_ERROR -0x70000000
#define BCTOOLBOX_ERROR_UNSPECIFIED_ERROR -0x70000000
#define BCTOOLBOX_ERROR_OUTPUT_BUFFER_TOO_SMALL -0x70001000
#define BCTOOLBOX_ERROR_INVALID_BASE64_INPUT -0x70002000
#define BCTOOLBOX_ERROR_INVALID_INPUT_DATA -0x70004000
#define BCTOOLBOX_ERROR_UNAVAILABLE_FUNCTION -0x70008000
/* Public key related */
#define BCTOOLBOX_ERROR_UNABLE_TO_PARSE_KEY -0x70010000
/* Certificate related */
#define BCTOOLBOX_ERROR_INVALID_CERTIFICATE -0x70020000
#define BCTOOLBOX_ERROR_INVALID_CERTIFICATE -0x70020000
#define BCTOOLBOX_ERROR_CERTIFICATE_GENERATION_FAIL -0x70020001
#define BCTOOLBOX_ERROR_CERTIFICATE_WRITE_PEM -0x70020002
#define BCTOOLBOX_ERROR_CERTIFICATE_PARSE_PEM -0x70020003
#define BCTOOLBOX_ERROR_CERTIFICATE_PARSE_PEM -0x70020004
#define BCTOOLBOX_ERROR_UNSUPPORTED_HASH_FUNCTION -0x70020008
/* SSL related */
#define BCTOOLBOX_ERROR_INVALID_SSL_CONFIG -0x70030001
#define BCTOOLBOX_ERROR_INVALID_SSL_TRANSPORT -0x70030002
#define BCTOOLBOX_ERROR_INVALID_SSL_ENDPOINT -0x70030004
#define BCTOOLBOX_ERROR_INVALID_SSL_AUTHMODE -0x70030008
#define BCTOOLBOX_ERROR_INVALID_SSL_TRANSPORT -0x70030002
#define BCTOOLBOX_ERROR_INVALID_SSL_ENDPOINT -0x70030004
#define BCTOOLBOX_ERROR_INVALID_SSL_AUTHMODE -0x70030008
#define BCTOOLBOX_ERROR_INVALID_SSL_CONTEXT -0x70030010
#define BCTOOLBOX_ERROR_NET_WANT_READ -0x70032000
#define BCTOOLBOX_ERROR_NET_WANT_WRITE -0x70034000
#define BCTOOLBOX_ERROR_SSL_PEER_CLOSE_NOTIFY -0x70038000
#define BCTOOLBOX_ERROR_SSL_PEER_CLOSE_NOTIFY -0x70038000
#define BCTOOLBOX_ERROR_NET_CONN_RESET -0x70030000
/* certificate verification flags codes */
#define BCTOOLBOX_CERTIFICATE_VERIFY_ALL_FLAGS 0xFFFFFFFF
#define BCTOOLBOX_CERTIFICATE_VERIFY_ALL_FLAGS 0xFFFFFFFF
#define BCTOOLBOX_CERTIFICATE_VERIFY_BADCERT_EXPIRED 0x01 /**< The certificate validity has expired. */
#define BCTOOLBOX_CERTIFICATE_VERIFY_BADCERT_REVOKED 0x02 /**< The certificate has been revoked (is on a CRL). */
#define BCTOOLBOX_CERTIFICATE_VERIFY_BADCERT_CN_MISMATCH 0x04 /**< The certificate Common Name (CN) does not match with the expected CN. */
#define BCTOOLBOX_CERTIFICATE_VERIFY_BADCERT_NOT_TRUSTED 0x08 /**< The certificate is not correctly signed by the trusted CA. */
#define BCTOOLBOX_CERTIFICATE_VERIFY_BADCRL_NOT_TRUSTED 0x10 /**< CRL is not correctly signed by the trusted CA. */
#define BCTOOLBOX_CERTIFICATE_VERIFY_BADCRL_EXPIRED 0x20 /**< CRL is expired. */
#define BCTOOLBOX_CERTIFICATE_VERIFY_BADCRL_EXPIRED 0x20 /**< CRL is expired. */
#define BCTOOLBOX_CERTIFICATE_VERIFY_BADCERT_MISSING 0x40 /**< Certificate was missing. */
#define BCTOOLBOX_CERTIFICATE_VERIFY_BADCERT_SKIP_VERIFY 0x80 /**< Certificate verification was skipped. */
#define BCTOOLBOX_CERTIFICATE_VERIFY_BADCERT_OTHER 0x0100 /**< Other reason (can be used by verify callback) */
#define BCTOOLBOX_CERTIFICATE_VERIFY_BADCERT_FUTURE 0x0200 /**< The certificate validity starts in the future. */
#define BCTOOLBOX_CERTIFICATE_VERIFY_BADCRL_FUTURE 0x0400 /**< The CRL is from the future */
#define BCTOOLBOX_CERTIFICATE_VERIFY_BADCERT_OTHER 0x0100 /**< Other reason (can be used by verify callback) */
#define BCTOOLBOX_CERTIFICATE_VERIFY_BADCERT_FUTURE 0x0200 /**< The certificate validity starts in the future. */
#define BCTOOLBOX_CERTIFICATE_VERIFY_BADCRL_FUTURE 0x0400 /**< The CRL is from the future */
/* Hash functions type */
typedef enum bctoolbox_md_type {
BCTOOLBOX_MD_UNDEFINED,
BCTOOLBOX_MD_SHA1,
BCTOOLBOX_MD_SHA224,
BCTOOLBOX_MD_SHA256,
BCTOOLBOX_MD_SHA384,
BCTOOLBOX_MD_SHA512} bctoolbox_md_type_t;
/* Dtls srtp protection profile */
typedef enum bctoolbox_srtp_profile {
BCTOOLBOX_SRTP_UNDEFINED,
BCTOOLBOX_SRTP_AES128_CM_HMAC_SHA1_80,
BCTOOLBOX_SRTP_AES128_CM_HMAC_SHA1_32,
BCTOOLBOX_SRTP_NULL_HMAC_SHA1_80,
BCTOOLBOX_SRTP_NULL_HMAC_SHA1_32
} bctoolbox_dtls_srtp_profile_t;
void bctoolbox_strerror(int32_t error_code, char *buffer, size_t buffer_length);
int32_t bctoolbox_base64_encode(unsigned char *output, size_t *output_length, const unsigned char *input, size_t input_length);
int32_t bctoolbox_base64_decode(unsigned char *output, size_t *output_length, const unsigned char *input, size_t input_length);
/* Random Number Generation */
typedef struct bctoolbox_rng_context_struct bctoolbox_rng_context_t;
bctoolbox_rng_context_t *bctoolbox_rng_context_new(void);
int32_t bctoolbox_rng_get(bctoolbox_rng_context_t *context, unsigned char*output, size_t output_length);
void bctoolbox_rng_context_free(bctoolbox_rng_context_t *context);
/* Signing key */
typedef struct bctoolbox_signing_key_struct bctoolbox_signing_key_t;
......@@ -103,7 +129,8 @@ int32_t bctoolbox_x509_certificate_parse_path(bctoolbox_x509_certificate_t *cert
int32_t bctoolbox_x509_certificate_get_der_length(bctoolbox_x509_certificate_t *cert);
int32_t bctoolbox_x509_certificate_get_der(bctoolbox_x509_certificate_t *cert, unsigned char *buffer, size_t buffer_length);
int32_t bctoolbox_x509_certificate_get_subject_dn(bctoolbox_x509_certificate_t *cert, char *dn, size_t dn_length);
int32_t bctoolbox_x509_certificate_get_fingerprint(bctoolbox_x509_certificate_t *cert, char *fingerprint, size_t fingerprint_length);
int32_t bctoolbox_x509_certificate_get_fingerprint(const bctoolbox_x509_certificate_t *cert, char *fingerprint, size_t fingerprint_length, bctoolbox_md_type_t hash_algorithm);
int32_t bctoolbox_x509_certificate_get_signature_hash_function(const bctoolbox_x509_certificate_t *certificate, bctoolbox_md_type_t *hash_algorithm);
int32_t bctoolbox_x509_certificate_generate_selfsigned(const char *subject, bctoolbox_x509_certificate_t *certificate, bctoolbox_signing_key_t *pkey, char *pem, size_t pem_length);
int32_t bctoolbox_x509_certificate_flags_to_string(char *buffer, size_t buffer_size, uint32_t flags);
int32_t bctoolbox_x509_certificate_set_flag(uint32_t *flags, uint32_t flags_to_set);
......@@ -127,14 +154,23 @@ int32_t bctoolbox_ssl_set_hs_own_cert(bctoolbox_ssl_context_t *ssl_ctx, bctoolbo
void bctoolbox_ssl_set_io_callbacks(bctoolbox_ssl_context_t *ssl_ctx, void *callback_data,
int(*callback_send_function)(void *, const unsigned char *, size_t), /* callbacks args are: callback data, data buffer to be send, size of data buffer */
int(*callback_recv_function)(void *, unsigned char *, size_t)); /* args: callback data, data buffer to be read, size of data buffer */
const bctoolbox_x509_certificate_t *bctoolbox_ssl_get_peer_certificate(bctoolbox_ssl_context_t *ssl_ctx);
bctoolbox_ssl_config_t *bctoolbox_ssl_config_new(void);
void bctoolbox_ssl_config_free(bctoolbox_ssl_config_t *ssl_config);
int32_t bctoolbox_ssl_config_init(bctoolbox_ssl_config_t *ssl_config);
int32_t bctoolbox_ssl_config_defaults(bctoolbox_ssl_config_t *ssl_config, int endpoint, int transport);
int32_t bctoolbox_ssl_config_set_endpoint(bctoolbox_ssl_config_t *ssl_config, int endpoint);
int32_t bctoolbox_ssl_config_set_transport (bctoolbox_ssl_config_t *ssl_config, int transport);
int32_t bctoolbox_ssl_config_set_authmode(bctoolbox_ssl_config_t *ssl_config, int authmode);
int32_t bctoolbox_ssl_config_set_rng(bctoolbox_ssl_config_t *ssl_config, int(*rng_function)(void *, unsigned char *, size_t), void *rng_context);
int32_t bctoolbox_ssl_config_set_callback_verify(bctoolbox_ssl_config_t *ssl_config, int(*callback_function)(void *, bctoolbox_x509_certificate_t *, int, uint32_t *), void *callback_data);
int32_t bctoolbox_ssl_config_set_callback_cli_cert(bctoolbox_ssl_config_t *ssl_config, int(*callback_function)(void *, bctoolbox_ssl_context_t *, unsigned char *, size_t), void *callback_data);
int32_t bctoolbox_ssl_config_set_ca_chain(bctoolbox_ssl_config_t *ssl_config, bctoolbox_x509_certificate_t *ca_chain, char *peer_cn);
int32_t bctoolbox_ssl_config_set_own_cert(bctoolbox_ssl_config_t *ssl_config, bctoolbox_x509_certificate_t *cert, bctoolbox_signing_key_t *key);
/* DTLS-SRTP functions */
bctoolbox_dtls_srtp_profile_t bctoolbox_ssl_get_dtls_srtp_protection_profile(bctoolbox_ssl_context_t *ssl_ctx);
int32_t bctoolbox_ssl_config_set_dtls_srtp_protection_profiles(bctoolbox_ssl_config_t *ssl_config, const bctoolbox_dtls_srtp_profile_t *profiles, size_t profiles_number);
int32_t bctoolbox_ssl_get_dtls_srtp_key_material(bctoolbox_ssl_context_t *ssl_ctx, char *output, size_t *output_length);
uint8_t bctoolbox_dtls_srtp_supported(void);
#endif
/*
chrypto.c
crypto.c
Copyright (C) 2016 Belledonne Communications SARL
This program is free software; you can redistribute it and/or
......@@ -17,6 +17,7 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdlib.h>
#include "utils.h"
#include <bctoolbox/crypto.h>
#include <polarssl/ssl.h>
......@@ -58,7 +59,7 @@ void bctoolbox_strerror(int32_t error_code, char *buffer, size_t buffer_length)
return;
}
snprintf(buffer, buffer_length, "%s", "bctoolbox defined error code");
snprintf(buffer, buffer_length, "%s [-0x%x]", "bctoolbox defined error code", -error_code);
return;
}
......@@ -82,22 +83,45 @@ int32_t bctoolbox_base64_decode(unsigned char *output, size_t *output_length, co
return ret;
}
/*** Random Number Generation ***/
struct bctoolbox_rng_context_struct {
entropy_context entropy;
ctr_drbg_context ctr_drbg;
};
bctoolbox_rng_context_t *bctoolbox_rng_context_new(void) {
bctoolbox_rng_context_t *ctx = bctoolbox_malloc0(sizeof(bctoolbox_rng_context_t));
entropy_init(&(ctx->entropy));
ctr_drbg_init(&(ctx->ctr_drbg), entropy_func, &(ctx->entropy), NULL, 0);
return ctx;
}
int32_t bctoolbox_rng_get(bctoolbox_rng_context_t *context, unsigned char*output, size_t output_length) {
return ctr_drbg_random(&(context->ctr_drbg), output, output_length);
}
void bctoolbox_rng_context_free(bctoolbox_rng_context_t *context) {
ctr_drbg_free(&(context->ctr_drbg));
entropy_free(&(context->entropy));
bctoolbox_free(context);
}
/*** signing key ***/
bctoolbox_signing_key_t *bctoolbox_signing_key_new(void) {
pk_context *key = malloc(sizeof(pk_context));
pk_context *key = bctoolbox_malloc0(sizeof(pk_context));
pk_init(key);
return (bctoolbox_signing_key_t *)key;
}
void bctoolbox_signing_key_free(bctoolbox_signing_key_t *key) {
pk_free((pk_context *)key);
free(key);
bctoolbox_free(key);
}
char *bctoolbox_signing_key_get_pem(bctoolbox_signing_key_t *key) {
char *pem_key;
if (key == NULL) return NULL;
pem_key = (char *)malloc(4096);
pem_key = (char *)bctoolbox_malloc0(4096);
pk_write_key_pem( (pk_context *)key, (unsigned char *)pem_key, 4096);
return pem_key;
}
......@@ -139,21 +163,21 @@ char *bctoolbox_x509_certificates_chain_get_pem(bctoolbox_x509_certificate_t *ce
char *pem_certificate = NULL;
size_t olen=0;
pem_certificate = (char *)malloc(4096);
pem_certificate = (char *)bctoolbox_malloc0(4096);
pem_write_buffer("-----BEGIN CERTIFICATE-----\n", "-----END CERTIFICATE-----\n", ((x509_crt *)cert)->raw.p, ((x509_crt *)cert)->raw.len, (unsigned char*)pem_certificate, 4096, &olen );
return pem_certificate;
}
bctoolbox_x509_certificate_t *bctoolbox_x509_certificate_new(void) {
x509_crt *cert = malloc(sizeof(x509_crt));
x509_crt *cert = bctoolbox_malloc0(sizeof(x509_crt));
x509_crt_init(cert);
return (bctoolbox_x509_certificate_t *)cert;
}
void bctoolbox_x509_certificate_free(bctoolbox_x509_certificate_t *cert) {
x509_crt_free((x509_crt *)cert);
free(cert);
bctoolbox_free(cert);
}
int32_t bctoolbox_x509_certificate_get_info_string(char *buf, size_t size, const char *prefix, const bctoolbox_x509_certificate_t *cert) {
......@@ -299,18 +323,80 @@ int32_t bctoolbox_x509_certificate_generate_selfsigned(const char *subject, bcto
}
int32_t bctoolbox_x509_certificate_get_signature_hash_function(const bctoolbox_x509_certificate_t *certificate, bctoolbox_md_type_t *hash_algorithm) {
x509_crt *crt;
if (certificate == NULL) return BCTOOLBOX_ERROR_INVALID_CERTIFICATE;
crt = (x509_crt *)certificate;
switch (crt->sig_md) {
case POLARSSL_MD_SHA1:
*hash_algorithm = BCTOOLBOX_MD_SHA1;
break;
case POLARSSL_MD_SHA224:
*hash_algorithm = BCTOOLBOX_MD_SHA224;
break;
case POLARSSL_MD_SHA256:
*hash_algorithm = BCTOOLBOX_MD_SHA256;
break;
case POLARSSL_MD_SHA384:
*hash_algorithm = BCTOOLBOX_MD_SHA384;
break;
case POLARSSL_MD_SHA512:
*hash_algorithm = BCTOOLBOX_MD_SHA512;
break;
default:
*hash_algorithm = BCTOOLBOX_MD_UNDEFINED;
return BCTOOLBOX_ERROR_UNSUPPORTED_HASH_FUNCTION;
break;
}
return 0;
}
/* maximum length of returned buffer will be 7(SHA-512 string)+3*hash_length(64)+null char = 200 bytes */
int32_t bctoolbox_x509_certificate_get_fingerprint(bctoolbox_x509_certificate_t *certificate, char *fingerprint, size_t fingerprint_length) {
int32_t bctoolbox_x509_certificate_get_fingerprint(const bctoolbox_x509_certificate_t *certificate, char *fingerprint, size_t fingerprint_length, bctoolbox_md_type_t hash_algorithm) {
unsigned char buffer[64]={0}; /* buffer is max length of returned hash, which is 64 in case we use sha-512 */
size_t hash_length = 0;
const char *hash_alg_string=NULL;
size_t fingerprint_size;
x509_crt *crt;
md_type_t hash_id;
if (certificate == NULL) return BCTOOLBOX_ERROR_INVALID_CERTIFICATE;
crt = (x509_crt *)certificate;
/* if there is a specified hash algorithm, use it*/
switch (hash_algorithm) {
case BCTOOLBOX_MD_SHA1:
hash_id = POLARSSL_MD_SHA1;
break;
case BCTOOLBOX_MD_SHA224:
hash_id = POLARSSL_MD_SHA224;
break;
case BCTOOLBOX_MD_SHA256:
hash_id = POLARSSL_MD_SHA256;
break;
case BCTOOLBOX_MD_SHA384:
hash_id = POLARSSL_MD_SHA384;
break;
case BCTOOLBOX_MD_SHA512:
hash_id = POLARSSL_MD_SHA512;
break;
default: /* nothing specified, use the hash algo used in the certificate signature */
hash_id = crt->sig_md;
break;
}
/* fingerprint is a hash of the DER formated certificate (found in crt->raw.p) using the same hash function used by certificate signature */
switch (crt->sig_md) {
switch (hash_id) {
case POLARSSL_MD_SHA1:
sha1(crt->raw.p, crt->raw.len, buffer);
hash_length = 20;
......@@ -342,7 +428,7 @@ int32_t bctoolbox_x509_certificate_get_fingerprint(bctoolbox_x509_certificate_t
break;
default:
return BCTOOLBOX_ERROR_INVALID_CERTIFICATE;
return BCTOOLBOX_ERROR_UNSUPPORTED_HASH_FUNCTION;
break;
}
......@@ -470,16 +556,19 @@ struct bctoolbox_ssl_context_struct {
};
bctoolbox_ssl_context_t *bctoolbox_ssl_context_new(void) {
bctoolbox_ssl_context_t *ssl_ctx = malloc(sizeof(bctoolbox_ssl_context_t));
bctoolbox_ssl_context_t *ssl_ctx = bctoolbox_malloc0(sizeof(bctoolbox_ssl_context_t));
ssl_init(&(ssl_ctx->ssl_ctx));
ssl_ctx->callback_cli_cert_function = NULL;
ssl_ctx->callback_cli_cert_data = NULL;
ssl_ctx->callback_send_function = NULL;
ssl_ctx->callback_recv_function = NULL;
ssl_ctx->callback_sendrecv_data = NULL;
return ssl_ctx;
}
void bctoolbox_ssl_context_free(bctoolbox_ssl_context_t *ssl_ctx) {
ssl_free(&(ssl_ctx->ssl_ctx));
free(ssl_ctx);
bctoolbox_free(ssl_ctx);
}
int32_t bctoolbox_ssl_close_notify(bctoolbox_ssl_context_t *ssl_ctx) {
......@@ -575,6 +664,10 @@ void bctoolbox_ssl_set_io_callbacks(bctoolbox_ssl_context_t *ssl_ctx, void *call
int(*callback_send_function)(void *, const unsigned char *, size_t), /* callbacks args are: callback data, data buffer to be send, size of data buffer */
int(*callback_recv_function)(void *, unsigned char *, size_t)){ /* args: callback data, data buffer to be read, size of data buffer */
if (ssl_ctx==NULL) {
return;
}
ssl_ctx->callback_send_function = callback_send_function;
ssl_ctx->callback_recv_function = callback_recv_function;
ssl_ctx->callback_sendrecv_data = callback_data;
......@@ -582,6 +675,87 @@ void bctoolbox_ssl_set_io_callbacks(bctoolbox_ssl_context_t *ssl_ctx, void *call
ssl_set_bio(&(ssl_ctx->ssl_ctx), bctoolbox_ssl_recv_callback, ssl_ctx, bctoolbox_ssl_send_callback, ssl_ctx);
}
const bctoolbox_x509_certificate_t *bctoolbox_ssl_get_peer_certificate(bctoolbox_ssl_context_t *ssl_ctx) {
return (const bctoolbox_x509_certificate_t *)ssl_get_peer_cert(&(ssl_ctx->ssl_ctx));
}
/** DTLS SRTP functions **/
#ifdef HAVE_DTLS_SRTP
uint8_t bctoolbox_dtls_srtp_supported(void) {
return 1;
}
static bctoolbox_dtls_srtp_profile_t bctoolbox_srtp_profile_polarssl2bctoolbox(enum DTLS_SRTP_protection_profiles polarssl_profile) {
switch (polarssl_profile) {
case SRTP_AES128_CM_HMAC_SHA1_80:
return BCTOOLBOX_SRTP_AES128_CM_HMAC_SHA1_80;
case SRTP_AES128_CM_HMAC_SHA1_32:
return BCTOOLBOX_SRTP_AES128_CM_HMAC_SHA1_32;
case SRTP_NULL_HMAC_SHA1_80:
return BCTOOLBOX_SRTP_NULL_HMAC_SHA1_80;
case SRTP_NULL_HMAC_SHA1_32:
return BCTOOLBOX_SRTP_NULL_HMAC_SHA1_32;
default:
return BCTOOLBOX_SRTP_UNDEFINED;
}
}
static enum DTLS_SRTP_protection_profiles bctoolbox_srtp_profile_bctoolbox2polarssl(bctoolbox_dtls_srtp_profile_t bctoolbox_profile) {
switch (bctoolbox_profile) {
case BCTOOLBOX_SRTP_AES128_CM_HMAC_SHA1_80:
return SRTP_AES128_CM_HMAC_SHA1_80;
case BCTOOLBOX_SRTP_AES128_CM_HMAC_SHA1_32:
return SRTP_AES128_CM_HMAC_SHA1_32;
case BCTOOLBOX_SRTP_NULL_HMAC_SHA1_80:
return SRTP_NULL_HMAC_SHA1_80;
case BCTOOLBOX_SRTP_NULL_HMAC_SHA1_32:
return SRTP_NULL_HMAC_SHA1_32;
default:
return SRTP_UNSET_PROFILE;
}
}
bctoolbox_dtls_srtp_profile_t bctoolbox_ssl_get_dtls_srtp_protection_profile(bctoolbox_ssl_context_t *ssl_ctx) {
if (ssl_ctx==NULL) {
return BCTOOLBOX_ERROR_INVALID_SSL_CONTEXT;
}
return bctoolbox_srtp_profile_polarssl2bctoolbox(ssl_get_dtls_srtp_protection_profile(&(ssl_ctx->ssl_ctx)));
};
int32_t bctoolbox_ssl_get_dtls_srtp_key_material(bctoolbox_ssl_context_t *ssl_ctx, char *output, size_t *output_length) {
if (ssl_ctx==NULL) {
return BCTOOLBOX_ERROR_INVALID_SSL_CONTEXT;
}
/* check output buffer size */
if (*output_length<ssl_ctx->ssl_ctx.dtls_srtp_keys_len) {
return BCTOOLBOX_ERROR_OUTPUT_BUFFER_TOO_SMALL;
}
memcpy(output, ssl_ctx->ssl_ctx.dtls_srtp_keys, ssl_ctx->ssl_ctx.dtls_srtp_keys_len);
*output_length = ssl_ctx->ssl_ctx.dtls_srtp_keys_len;
return 0;
}
#else /* HAVE_DTLS_SRTP */
/* dummy DTLS api when not available */
uint8_t bctoolbox_dtls_srtp_supported(void) {
return 0;
}
bctoolbox_dtls_srtp_profile_t bctoolbox_ssl_get_dtls_srtp_protection_profile(bctoolbox_ssl_context_t *ssl_ctx) {
return BCTOOLBOX_SRTP_UNDEFINED;
}
int32_t bctoolbox_ssl_get_dtls_srtp_key_material(bctoolbox_ssl_context_t *ssl_ctx, char *output, size_t *output_length) {
*output_length = 0;
return BCTOOLBOX_ERROR_UNAVAILABLE_FUNCTION;
}
#endif /* HAVE_DTLS_SRTP */
/** DTLS SRTP functions **/
/** config **/
struct bctoolbox_ssl_config_struct {
......@@ -594,13 +768,18 @@ struct bctoolbox_ssl_config_struct {
void *callback_verify_data; /**< data passed to the verify callback */
x509_crt *ca_chain; /**< trusted CA chain */
char *peer_cn; /**< expected peer Common name */
x509_crt *own_cert;
pk_context *own_cert_pk;
int(*callback_cli_cert_function)(void *, bctoolbox_ssl_context_t *, unsigned char *, size_t); /**< pointer to the callback called to update client certificate during handshake
callback params are user_data, ssl_context, certificate distinguished name, name length */
void *callback_cli_cert_data; /**< data passed to the client cert callback */
enum DTLS_SRTP_protection_profiles dtls_srtp_profiles[4]; /**< Store a maximum of 4 DTLS SRTP profiles to use */
int dtls_srtp_profiles_number; /**< Number of DTLS SRTP profiles in use */
};
bctoolbox_ssl_config_t *bctoolbox_ssl_config_new(void) {
bctoolbox_ssl_config_t *ssl_config = malloc(sizeof(bctoolbox_ssl_config_t));
int i;
bctoolbox_ssl_config_t *ssl_config = bctoolbox_malloc0(sizeof(bctoolbox_ssl_config_t));
/* set all properties to BCTOOLBOX_SSL_UNSET or NULL */
ssl_config->endpoint = BCTOOLBOX_SSL_UNSET;
......@@ -614,12 +793,18 @@ bctoolbox_ssl_config_t *bctoolbox_ssl_config_new(void) {
ssl_config->callback_cli_cert_data = NULL;
ssl_config->ca_chain = NULL;
ssl_config->peer_cn = NULL;
ssl_config->own_cert = NULL;
ssl_config->own_cert_pk = NULL;
for (i=0; i<4; i++) {
ssl_config->dtls_srtp_profiles[i] = SRTP_UNSET_PROFILE;
}
ssl_config->dtls_srtp_profiles_number = 0;
return ssl_config;
}
void bctoolbox_ssl_config_free(bctoolbox_ssl_config_t *ssl_config) {
free(ssl_config);
bctoolbox_free(ssl_config);
}
int32_t bctoolbox_ssl_config_defaults(bctoolbox_ssl_config_t *ssl_config, int endpoint, int transport) {
......@@ -646,6 +831,40 @@ int32_t bctoolbox_ssl_config_defaults(bctoolbox_ssl_config_t *ssl_config, int en
return BCTOOLBOX_ERROR_INVALID_SSL_CONFIG;
}
int32_t bctoolbox_ssl_config_set_endpoint(bctoolbox_ssl_config_t *ssl_config, int endpoint) {
if (ssl_config == NULL) {
return BCTOOLBOX_ERROR_INVALID_SSL_CONFIG;
}
if (endpoint == BCTOOLBOX_SSL_IS_CLIENT) {
ssl_config->endpoint = SSL_IS_CLIENT;
} else if (endpoint == BCTOOLBOX_SSL_IS_SERVER) {
ssl_config->endpoint = SSL_IS_SERVER;
} else {
return BCTOOLBOX_ERROR_INVALID_SSL_ENDPOINT;
}
return 0;
}
int32_t bctoolbox_ssl_config_set_transport (bctoolbox_ssl_config_t *ssl_config, int transport) {
if (ssl_config == NULL) {
return BCTOOLBOX_ERROR_INVALID_SSL_CONFIG;
}
/* useful only for versions of polarssl which have SSL_TRANSPORT_XXX defined */
#ifdef SSL_TRANSPORT_DATAGRAM
if (transport == BCTOOLBOX_SSL_TRANSPORT_STREAM) {
ssl_config->transport = SSL_TRANSPORT_STREAM;
} else if (transport == BCTOOLBOX_SSL_TRANSPORT_DATAGRAM) {
ssl_config->transport = SSL_TRANSPORT_DATAGRAM;
} else {
return BCTOOLBOX_ERROR_INVALID_SSL_TRANSPORT;
}
#endif
return 0;
}
int32_t bctoolbox_ssl_config_set_authmode(bctoolbox_ssl_config_t *ssl_config, int authmode) {
if (ssl_config != NULL) {
switch (authmode) {
......@@ -699,6 +918,44 @@ int32_t bctoolbox_ssl_config_set_ca_chain(bctoolbox_ssl_config_t *ssl_config, bc
return BCTOOLBOX_ERROR_INVALID_SSL_CONFIG;
}
int32_t bctoolbox_ssl_config_set_own_cert(bctoolbox_ssl_config_t *ssl_config, bctoolbox_x509_certificate_t *cert, bctoolbox_signing_key_t *key) {
if (ssl_config != NULL) {
ssl_config->own_cert = (x509_crt *)cert;
ssl_config->own_cert_pk = (pk_context *)key;
}
return BCTOOLBOX_ERROR_INVALID_SSL_CONFIG;
}
/** DTLS SRTP functions **/
#ifdef HAVE_DTLS_SRTP
int32_t bctoolbox_ssl_config_set_dtls_srtp_protection_profiles(bctoolbox_ssl_config_t *ssl_config, const bctoolbox_dtls_srtp_profile_t *profiles, size_t profiles_number) {
int i;
if (ssl_config == NULL) {
return BCTOOLBOX_ERROR_INVALID_SSL_CONFIG;
}
/* convert the profiles array into a polarssl profiles array */
for (i=0; i<profiles_number && i<4; i++) { /* 4 profiles defined max */
ssl_config->dtls_srtp_profiles[i] = bctoolbox_srtp_profile_bctoolbox2polarssl(profiles[i]);
}
for (;i<4; i++) { /* make sure to have harmless values in the rest of the array */
ssl_config->dtls_srtp_profiles[i] = SRTP_UNSET_PROFILE;
}
ssl_config->dtls_srtp_profiles_number = profiles_number;
return 0;
}
#else /* HAVE_DTLS_SRTP */
int32_t bctoolbox_ssl_config_set_dtls_srtp_protection_profiles(bctoolbox_ssl_config_t *ssl_config, const bctoolbox_dtls_srtp_profile_t *profiles, size_t profiles_number) {
return BCTOOLBOX_ERROR_UNAVAILABLE_FUNCTION;
}
#endif /* HAVE_DTLS_SRTP */
/** DTLS SRTP functions **/
int32_t bctoolbox_ssl_context_setup(bctoolbox_ssl_context_t *ssl_ctx, bctoolbox_ssl_config_t *ssl_config) {
/* Check validity of context and config */
if (ssl_config == NULL) {
......@@ -739,6 +996,14 @@ int32_t bctoolbox_ssl_context_setup(bctoolbox_ssl_context_t *ssl_ctx, bctoolbox_
ssl_set_ca_chain(&(ssl_ctx->ssl_ctx), ssl_config->ca_chain, NULL, ssl_config->peer_cn);
}
if (ssl_config->own_cert != NULL && ssl_config->own_cert_pk != NULL) {
ssl_set_own_cert(&(ssl_ctx->ssl_ctx) , ssl_config->own_cert , ssl_config->own_cert_pk);
}
if (ssl_config->dtls_srtp_profiles_number > 0) {
ssl_set_dtls_srtp_protection_profiles(&(ssl_ctx->ssl_ctx), ssl_config->dtls_srtp_profiles, ssl_config->dtls_srtp_profiles_number );
}
return 0;
}
/*
utils.h
Copyright (C) 2016 Belledonne Communications SARL
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define bctoolbox_malloc malloc
#define bctoolbox_malloc0(a) calloc(1,a)
#define bctoolbox_free free
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment