diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 7fed580d2e..d464466604 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2812,6 +2812,7 @@ SWITCH_DECLARE(void) switch_sql_queue_manager_execute_sql_event_callback_err(swi SWITCH_DECLARE(pid_t) switch_fork(void); SWITCH_DECLARE(int) switch_core_gen_certs(const char *prefix); +SWITCH_DECLARE(switch_bool_t) switch_core_check_dtls_pem(const char *file); SWITCH_DECLARE(int) switch_core_cert_gen_fingerprint(const char *prefix, dtls_fingerprint_t *fp); SWITCH_DECLARE(int) switch_core_cert_expand_fingerprint(dtls_fingerprint_t *fp, const char *str); SWITCH_DECLARE(int) switch_core_cert_verify(dtls_fingerprint_t *fp); diff --git a/src/switch_core_cert.c b/src/switch_core_cert.c index f91e7cc0ee..565f548e51 100644 --- a/src/switch_core_cert.c +++ b/src/switch_core_cert.c @@ -330,6 +330,67 @@ SWITCH_DECLARE(int) switch_core_gen_certs(const char *prefix) return(0); } +SWITCH_DECLARE(switch_bool_t) switch_core_check_dtls_pem(const char *file) +{ + char *pem = NULL, *old_pem = NULL; + FILE *fp = NULL; + EVP_PKEY *pkey = NULL; + int bits = 0; + + if (switch_is_file_path(file)) { + pem = strdup(file); + } else { + pem = switch_mprintf("%s%s%s", SWITCH_GLOBAL_dirs.certs_dir, SWITCH_PATH_SEPARATOR, file); + } + + if (switch_file_exists(pem, NULL) != SWITCH_STATUS_SUCCESS) { + switch_safe_free(pem); + + return SWITCH_FALSE; + } + + fp = fopen(pem, "r"); + if (!fp) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot open %s: %s\n", pem, strerror(errno)); + goto rename_pem; + } + + pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL); + fclose(fp); + + if (!pkey) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot read key %s: %s\n", pem, ERR_error_string(ERR_get_error(), NULL)); + goto rename_pem; + } + + bits = EVP_PKEY_bits(pkey); + EVP_PKEY_free(pkey); + + if (bits < 4096) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s cryptographic length is too short (%d), it will be regenerated\n", pem, bits); + goto rename_pem; + } + + switch_safe_free(pem); + + return SWITCH_TRUE; + +rename_pem: + + old_pem = switch_mprintf("%s.old", pem); + + if (rename(pem, old_pem) != -1) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Renamed %s to %s\n", pem, old_pem); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not rename %s: %s\n", pem, strerror(errno)); + } + + switch_safe_free(old_pem); + switch_safe_free(pem); + + return SWITCH_FALSE; +} + #if 0 static void callback(int p, int n, void *arg) { diff --git a/src/switch_core_media.c b/src/switch_core_media.c index ca6be2c16d..45468bfb00 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -14042,7 +14042,9 @@ SWITCH_DECLARE (void) switch_core_media_recover_session(switch_core_session_t *s SWITCH_DECLARE(void) switch_core_media_init(void) { - switch_core_gen_certs(DTLS_SRTP_FNAME ".pem"); + if (switch_core_check_dtls_pem(DTLS_SRTP_FNAME ".pem") != SWITCH_TRUE) { + switch_core_gen_certs(DTLS_SRTP_FNAME ".pem"); + } video_globals.cpu_count = switch_core_cpu_count(); video_globals.cur_cpu = 0;