[rtmpdump] [PATCH 1/2] Add functions for doing server side TLS initialization
Martin Storsjo
martin at martin.st
Sun May 20 22:37:34 CEST 2012
---
librtmp/rtmp.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++
librtmp/rtmp.h | 4 ++
librtmp/rtmp_sys.h | 20 ++++++++++
3 files changed, 130 insertions(+)
diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
index 52d0254..c0d043b 100644
--- a/librtmp/rtmp.c
+++ b/librtmp/rtmp.c
@@ -34,6 +34,19 @@
#ifdef CRYPTO
#ifdef USE_POLARSSL
#include <polarssl/havege.h>
+
+static const char *my_dhm_P =
+ "E4004C1F94182000103D883A448B3F80" \
+ "2CE4B44A83301270002C20D0321CFD00" \
+ "11CCEF784C26A400F43DFB901BCA7538" \
+ "F2C6B176001CF5A0FD16D2C48B1D0C1C" \
+ "F6AC8E1DA6BCC3B4E1F96B0564965300" \
+ "FFA1D0B601EB2800F489AA512C4B248C" \
+ "01F76949A60BB7F00A40B1EAB64BDD48" \
+ "E8A700D60B7F1200FA8E77B0A979DABF";
+
+static const char *my_dhm_G = "4";
+
#elif defined(USE_GNUTLS)
#include <gnutls/gnutls.h>
#else /* USE_OPENSSL */
@@ -227,6 +240,82 @@ RTMP_TLS_Init()
#endif
}
+void *
+RTMP_TLS_AllocServerContext(const char* cert, const char* key)
+{
+ void *ctx = NULL;
+#ifdef CRYPTO
+ if (!RTMP_TLS_ctx)
+ RTMP_TLS_Init();
+#ifdef USE_POLARSSL
+ tls_server_ctx *tc = ctx = calloc(1, sizeof(struct tls_server_ctx));
+ tc->dhm_P = my_dhm_P;
+ tc->dhm_G = my_dhm_G;
+ tc->hs = &RTMP_TLS_ctx->hs;
+ if (x509parse_crtfile(&tc->cert, cert)) {
+ free(tc);
+ return NULL;
+ }
+ if (x509parse_keyfile(&tc->key, key, NULL)) {
+ x509_free(&tc->cert);
+ free(tc);
+ return NULL;
+ }
+#elif defined(USE_GNUTLS) && !defined(NO_SSL)
+ gnutls_certificate_allocate_credentials((gnutls_certificate_credentials*) &ctx);
+ if (gnutls_certificate_set_x509_key_file(ctx, cert, key, GNUTLS_X509_FMT_PEM) != 0) {
+ gnutls_certificate_free_credentials(ctx);
+ return NULL;
+ }
+#elif !defined(NO_SSL) /* USE_OPENSSL */
+ ctx = SSL_CTX_new(SSLv23_server_method());
+ FILE *f = fopen(key, "r");
+ if (!f) {
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
+ EVP_PKEY *k = PEM_read_PrivateKey(f, NULL, NULL, NULL);
+ fclose(f);
+ if (!k) {
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
+ SSL_CTX_use_PrivateKey(ctx, k);
+ EVP_PKEY_free(k);
+ f = fopen(cert, "r");
+ if (!f) {
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
+ X509 *c = PEM_read_X509(f, NULL, NULL, NULL);
+ fclose(f);
+ if (!c) {
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
+ SSL_CTX_use_certificate(ctx, c);
+ X509_free(c);
+#endif
+#endif
+ return ctx;
+}
+
+void
+RTMP_TLS_FreeServerContext(void *ctx)
+{
+#ifdef CRYPTO
+#ifdef USE_POLARSSL
+ x509_free(&((tls_server_ctx*)ctx)->cert);
+ rsa_free(&((tls_server_ctx*)ctx)->key);
+ free(ctx);
+#elif defined(USE_GNUTLS) && !defined(NO_SSL)
+ gnutls_certificate_free_credentials(ctx);
+#elif !defined(NO_SSL) /* USE_OPENSSL */
+ SSL_CTX_free(ctx);
+#endif
+#endif
+}
+
RTMP *
RTMP_Alloc()
{
@@ -859,6 +948,23 @@ RTMP_Connect0(RTMP *r, struct sockaddr * service)
}
int
+RTMP_TLS_Accept(RTMP *r, void *ctx)
+{
+#if defined(CRYPTO) && !defined(NO_SSL)
+ TLS_server(ctx, r->m_sb.sb_ssl);
+ TLS_setfd(r->m_sb.sb_ssl, r->m_sb.sb_socket);
+ if (TLS_accept(r->m_sb.sb_ssl) < 0)
+ {
+ RTMP_Log(RTMP_LOGERROR, "%s, TLS_Connect failed", __FUNCTION__);
+ return FALSE;
+ }
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+int
RTMP_Connect1(RTMP *r, RTMPPacket *cp)
{
if (r->Link.protocol & RTMP_FEATURE_SSL)
diff --git a/librtmp/rtmp.h b/librtmp/rtmp.h
index 6b2ae5b..76e01fd 100644
--- a/librtmp/rtmp.h
+++ b/librtmp/rtmp.h
@@ -307,6 +307,7 @@ extern "C"
int RTMP_Connect0(RTMP *r, struct sockaddr *svc);
int RTMP_Connect1(RTMP *r, RTMPPacket *cp);
int RTMP_Serve(RTMP *r);
+ int RTMP_TLS_Accept(RTMP *r, void *ctx);
int RTMP_ReadPacket(RTMP *r, RTMPPacket *packet);
int RTMP_SendPacket(RTMP *r, RTMPPacket *packet, int queue);
@@ -329,6 +330,9 @@ extern "C"
void RTMP_Free(RTMP *r);
void RTMP_EnableWrite(RTMP *r);
+ void *RTMP_TLS_AllocServerContext(const char* cert, const char* key);
+ void RTMP_TLS_FreeServerContext(void *ctx);
+
int RTMP_LibVersion(void);
void RTMP_UserInterrupt(void); /* user typed Ctrl-C */
diff --git a/librtmp/rtmp_sys.h b/librtmp/rtmp_sys.h
index c3fd4a6..c9c9410 100644
--- a/librtmp/rtmp_sys.h
+++ b/librtmp/rtmp_sys.h
@@ -68,14 +68,30 @@ typedef struct tls_ctx {
havege_state hs;
ssl_session ssn;
} tls_ctx;
+typedef struct tls_server_ctx {
+ havege_state *hs;
+ x509_cert cert;
+ rsa_context key;
+ ssl_session ssn;
+ const char *dhm_P, *dhm_G;
+} tls_server_ctx;
+
#define TLS_CTX tls_ctx *
#define TLS_client(ctx,s) s = malloc(sizeof(ssl_context)); ssl_init(s);\
ssl_set_endpoint(s, SSL_IS_CLIENT); ssl_set_authmode(s, SSL_VERIFY_NONE);\
ssl_set_rng(s, havege_rand, &ctx->hs);\
ssl_set_ciphersuites(s, ssl_default_ciphersuites);\
ssl_set_session(s, 1, 600, &ctx->ssn)
+#define TLS_server(ctx,s) s = malloc(sizeof(ssl_context)); ssl_init(s);\
+ ssl_set_endpoint(s, SSL_IS_SERVER); ssl_set_authmode(s, SSL_VERIFY_NONE);\
+ ssl_set_rng(s, havege_rand, ((tls_server_ctx*)ctx)->hs);\
+ ssl_set_ciphersuites(s, ssl_default_ciphersuites);\
+ ssl_set_session(s, 1, 600, &((tls_server_ctx*)ctx)->ssn);\
+ ssl_set_own_cert(s, &((tls_server_ctx*)ctx)->cert, &((tls_server_ctx*)ctx)->key);\
+ ssl_set_dh_param(s, ((tls_server_ctx*)ctx)->dhm_P, ((tls_server_ctx*)ctx)->dhm_G)
#define TLS_setfd(s,fd) ssl_set_bio(s, net_recv, &fd, net_send, &fd)
#define TLS_connect(s) ssl_handshake(s)
+#define TLS_accept(s) ssl_handshake(s)
#define TLS_read(s,b,l) ssl_read(s,(unsigned char *)b,l)
#define TLS_write(s,b,l) ssl_write(s,(unsigned char *)b,l)
#define TLS_shutdown(s) ssl_close_notify(s)
@@ -89,8 +105,10 @@ typedef struct tls_ctx {
} tls_ctx;
#define TLS_CTX tls_ctx *
#define TLS_client(ctx,s) gnutls_init((gnutls_session_t *)(&s), GNUTLS_CLIENT); gnutls_priority_set(s, ctx->prios); gnutls_credentials_set(s, GNUTLS_CRD_CERTIFICATE, ctx->cred)
+#define TLS_server(ctx,s) gnutls_init((gnutls_session_t *)(&s), GNUTLS_SERVER); gnutls_priority_set_direct(s, "NORMAL", NULL); gnutls_credentials_set(s, GNUTLS_CRD_CERTIFICATE, ctx)
#define TLS_setfd(s,fd) gnutls_transport_set_ptr(s, (gnutls_transport_ptr_t)(long)fd)
#define TLS_connect(s) gnutls_handshake(s)
+#define TLS_accept(s) gnutls_handshake(s)
#define TLS_read(s,b,l) gnutls_record_recv(s,b,l)
#define TLS_write(s,b,l) gnutls_record_send(s,b,l)
#define TLS_shutdown(s) gnutls_bye(s, GNUTLS_SHUT_RDWR)
@@ -99,8 +117,10 @@ typedef struct tls_ctx {
#else /* USE_OPENSSL */
#define TLS_CTX SSL_CTX *
#define TLS_client(ctx,s) s = SSL_new(ctx)
+#define TLS_server(ctx,s) s = SSL_new(ctx)
#define TLS_setfd(s,fd) SSL_set_fd(s,fd)
#define TLS_connect(s) SSL_connect(s)
+#define TLS_accept(s) SSL_accept(s)
#define TLS_read(s,b,l) SSL_read(s,b,l)
#define TLS_write(s,b,l) SSL_write(s,b,l)
#define TLS_shutdown(s) SSL_shutdown(s)
--
1.7.9.4
More information about the rtmpdump
mailing list