[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