Add functions for doing server side TLS initialization
authorMartin Storsjo <martin@martin.st>
Tue, 30 Oct 2012 15:57:43 +0000 (08:57 -0700)
committerHoward Chu <hyc@highlandsun.com>
Tue, 30 Oct 2012 15:57:43 +0000 (08:57 -0700)
librtmp/rtmp.c
librtmp/rtmp.h
librtmp/rtmp_sys.h

index 682e3b8..cba8b6c 100644 (file)
 #ifdef USE_POLARSSL
 #include <polarssl/version.h>
 #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 */
@@ -228,6 +241,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()
 {
@@ -868,6 +957,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)
index 6b2ae5b..76e01fd 100644 (file)
@@ -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 */
 
index 1bf0735..2cdb705 100644 (file)
@@ -72,14 +72,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_random, &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)
@@ -93,8 +109,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)
@@ -103,8 +121,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)