/* DTLS-SRTP initialization */ gint janus_dtls_srtp_init(const char* server_pem, const char* server_key) { /* FIXME First of all make OpenSSL thread safe (see note above on issue #316) */ janus_dtls_locks = g_malloc0(sizeof(*janus_dtls_locks) * CRYPTO_num_locks()); int l=0; for(l = 0; l < CRYPTO_num_locks(); l++) { janus_mutex_init(&janus_dtls_locks[l]); } CRYPTO_THREADID_set_callback(janus_dtls_cb_openssl_threadid); CRYPTO_set_locking_callback(janus_dtls_cb_openssl_lock); /* Go on and create the DTLS context */ ssl_ctx = SSL_CTX_new(DTLSv1_method()); if(!ssl_ctx) { JANUS_LOG(LOG_FATAL, "Ops, error creating DTLS context?\n"); return -1; } SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, janus_dtls_verify_callback); SSL_CTX_set_tlsext_use_srtp(ssl_ctx, "SRTP_AES128_CM_SHA1_80"); /* FIXME Should we support something else as well? */ if (!server_pem && !server_key) { JANUS_LOG(LOG_WARN, "No cert/key specified, autogenerating some...\n"); if (janus_dtls_generate_keys(&ssl_cert, &ssl_key) != 0) { JANUS_LOG(LOG_FATAL, "Error generating DTLS key/certificate\n"); return -2; } } else if (!server_pem || !server_key) { JANUS_LOG(LOG_FATAL, "DTLS certificate and key must be specified\n"); return -2; } else if (janus_dtls_load_keys(server_pem, server_key, &ssl_cert, &ssl_key) != 0) { return -3; } if(!SSL_CTX_use_certificate(ssl_ctx, ssl_cert)) { JANUS_LOG(LOG_FATAL, "Certificate error (%s)\n", ERR_reason_error_string(ERR_get_error())); return -4; } if(!SSL_CTX_use_PrivateKey(ssl_ctx, ssl_key)) { JANUS_LOG(LOG_FATAL, "Certificate key error (%s)\n", ERR_reason_error_string(ERR_get_error())); return -5; } if(!SSL_CTX_check_private_key(ssl_ctx)) { JANUS_LOG(LOG_FATAL, "Certificate check error (%s)\n", ERR_reason_error_string(ERR_get_error())); return -6; } SSL_CTX_set_read_ahead(ssl_ctx,1); unsigned int size; unsigned char fingerprint[EVP_MAX_MD_SIZE]; if(X509_digest(ssl_cert, EVP_sha256(), (unsigned char *)fingerprint, &size) == 0) { JANUS_LOG(LOG_FATAL, "Error converting X509 structure (%s)\n", ERR_reason_error_string(ERR_get_error())); return -7; } char *lfp = (char *)&local_fingerprint; unsigned int i = 0; for(i = 0; i < size; i++) { g_snprintf(lfp, 4, "%.2X:", fingerprint[i]); lfp += 3; } *(lfp-1) = 0; JANUS_LOG(LOG_INFO, "Fingerprint of our certificate: %s\n", local_fingerprint); SSL_CTX_set_cipher_list(ssl_ctx, DTLS_CIPHERS); /* Initialize libsrtp */ if(srtp_init() != err_status_ok) { JANUS_LOG(LOG_FATAL, "Ops, error setting up libsrtp?\n"); return 5; } return 0; }
/* DTLS-SRTP initialization */ gint janus_dtls_srtp_init(const char *server_pem, const char *server_key, const char *password) { const char *crypto_lib = NULL; #if JANUS_USE_OPENSSL_PRE_1_1_API #if defined(LIBRESSL_VERSION_NUMBER) crypto_lib = "LibreSSL"; #else crypto_lib = "OpenSSL pre-1.1.0"; #endif /* First of all make OpenSSL thread safe (see note above on issue #316) */ janus_dtls_locks = g_malloc0(sizeof(*janus_dtls_locks) * CRYPTO_num_locks()); int l=0; for(l = 0; l < CRYPTO_num_locks(); l++) { janus_mutex_init(&janus_dtls_locks[l]); } CRYPTO_THREADID_set_callback(janus_dtls_cb_openssl_threadid); CRYPTO_set_locking_callback(janus_dtls_cb_openssl_lock); #else crypto_lib = "OpenSSL >= 1.1.0"; #endif #ifdef HAVE_BORINGSSL crypto_lib = "BoringSSL"; #endif JANUS_LOG(LOG_INFO, "Crypto: %s\n", crypto_lib); #ifndef HAVE_SRTP_AESGCM JANUS_LOG(LOG_WARN, "The libsrtp installation does not support AES-GCM profiles\n"); #endif /* Go on and create the DTLS context */ #if JANUS_USE_OPENSSL_PRE_1_1_API ssl_ctx = SSL_CTX_new(DTLSv1_method()); #else ssl_ctx = SSL_CTX_new(DTLS_method()); #endif if(!ssl_ctx) { JANUS_LOG(LOG_FATAL, "Ops, error creating DTLS context?\n"); return -1; } SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, janus_dtls_verify_callback); SSL_CTX_set_tlsext_use_srtp(ssl_ctx, #ifdef HAVE_SRTP_AESGCM "SRTP_AEAD_AES_256_GCM:SRTP_AEAD_AES_128_GCM:SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32"); #else "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32"); #endif if(!server_pem && !server_key) { JANUS_LOG(LOG_WARN, "No cert/key specified, autogenerating some...\n"); if(janus_dtls_generate_keys(&ssl_cert, &ssl_key) != 0) { JANUS_LOG(LOG_FATAL, "Error generating DTLS key/certificate\n"); return -2; } } else if(!server_pem || !server_key) { JANUS_LOG(LOG_FATAL, "DTLS certificate and key must be specified\n"); return -2; } else if(janus_dtls_load_keys(server_pem, server_key, password, &ssl_cert, &ssl_key) != 0) { return -3; } if(!SSL_CTX_use_certificate(ssl_ctx, ssl_cert)) { JANUS_LOG(LOG_FATAL, "Certificate error (%s)\n", ERR_reason_error_string(ERR_get_error())); return -4; } if(!SSL_CTX_use_PrivateKey(ssl_ctx, ssl_key)) { JANUS_LOG(LOG_FATAL, "Certificate key error (%s)\n", ERR_reason_error_string(ERR_get_error())); return -5; } if(!SSL_CTX_check_private_key(ssl_ctx)) { JANUS_LOG(LOG_FATAL, "Certificate check error (%s)\n", ERR_reason_error_string(ERR_get_error())); return -6; } SSL_CTX_set_read_ahead(ssl_ctx,1); unsigned int size; unsigned char fingerprint[EVP_MAX_MD_SIZE]; if(X509_digest(ssl_cert, EVP_sha256(), (unsigned char *)fingerprint, &size) == 0) { JANUS_LOG(LOG_FATAL, "Error converting X509 structure (%s)\n", ERR_reason_error_string(ERR_get_error())); return -7; } char *lfp = (char *)&local_fingerprint; unsigned int i = 0; for(i = 0; i < size; i++) { g_snprintf(lfp, 4, "%.2X:", fingerprint[i]); lfp += 3; } *(lfp-1) = 0; JANUS_LOG(LOG_INFO, "Fingerprint of our certificate: %s\n", local_fingerprint); SSL_CTX_set_cipher_list(ssl_ctx, DTLS_CIPHERS); if(janus_dtls_bio_filter_init() < 0) { JANUS_LOG(LOG_FATAL, "Error initializing BIO filter\n"); return -8; } /* Initialize libsrtp */ if(srtp_init() != srtp_err_status_ok) { JANUS_LOG(LOG_FATAL, "Ops, error setting up libsrtp?\n"); return 5; } return 0; }