From: Martin Storsjo Date: Tue, 30 Oct 2012 15:57:43 +0000 (-0700) Subject: Add functions for doing server side TLS initialization X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6df3b1f2015f928d74a675bda542c354b893c2c2;p=rtmpdump Add functions for doing server side TLS initialization --- diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c index 682e3b8..cba8b6c 100644 --- a/librtmp/rtmp.c +++ b/librtmp/rtmp.c @@ -35,6 +35,19 @@ #ifdef USE_POLARSSL #include #include + +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 #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() { @@ -867,6 +956,23 @@ RTMP_Connect0(RTMP *r, struct sockaddr * service) return TRUE; } +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) { 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 1bf0735..2cdb705 100644 --- a/librtmp/rtmp_sys.h +++ b/librtmp/rtmp_sys.h @@ -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)