[Live-devel] Live555 support for RTSP over TLS

Gaurav Badhan gbadhan at interfaceinfosoft.com
Thu Oct 6 06:33:42 PDT 2016


Hi Ross,
As per your suggestion, in RTSPServer class, I need to pass the TLS socket
number to RTSPServer constructor.
I am using OpenSSL for creating TLS socket. When I create TLS socket, it
returns SSL type object. How can I pass that SSL type object to RTSPServer
constructor?

I have attached sample code for creating TLS socket using OpenSSL.

Regards,
Gaurav Badhan

On Tue, Jun 24, 2014 at 9:11 PM, Ross Finlayson <finlayson at live555.com>
wrote:

> Do you intend to supply this feature any time soon ?
>
> If you already have a (TCP) TLS socket set up between your client and
> server, then you can use it now, using existing code.
>
> In "RTSPClient::createNew()", note the (optional) "socketNumToServer"
> parameter.  You can set this to specify the (TLS) socket number.
>
> At the server end, note the "ourSocket" parameter to the (protected)
> "RTSPServer" constructor.  You can subclass "RTSPServer", and, in your
> subclass constructor, pass the (TLS) socket number to the "RTSPServer"
> constructor.
>
>
> Ross Finlayson
> Live Networks, Inc.
> http://www.live555.com/
>
>
> _______________________________________________
> live-devel mailing list
> live-devel at lists.live555.com
> http://lists.live555.com/mailman/listinfo/live-devel
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.live555.com/pipermail/live-devel/attachments/20161006/17b46733/attachment.html>
-------------- next part --------------
//SSL-Server.c
#include <errno.h>
#include "stdafx.h"
#include <malloc.h>
#include <string.h>
# include <winsock2.h>
# include <ws2tcpip.h>
#include "openssl/ssl.h"
#include "openssl/err.h"

#define FAIL    -1
#pragma comment(lib, "Ws2_32.lib")


int OpenListener(WORD port)
{  
	SOCKET  m_socket;

	WORD wVersionRequested;
    WSADATA wsaData;
    int err;

/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
    wVersionRequested = MAKEWORD(2, 2);

    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0) {
        /* Tell the user that we could not find a usable */
        /* Winsock DLL.                                  */
        printf("WSAStartup failed with error: %d\n", err);
        return 1;
    }

	m_socket = socket(AF_INET, SOCK_STREAM, 0);

	if (m_socket == INVALID_SOCKET)
	{
		printf("Error at socket(): %ld\n", WSAGetLastError());
		WSACleanup();
		return 0;
	}
	sockaddr_in sain;
	//bzero(&addr, sizeof(addr));
	sain.sin_family = AF_INET;
	sain.sin_port = htons(7080);
	sain.sin_addr.s_addr = inet_addr("127.0.0.1");
	if ( bind(m_socket, (struct sockaddr*)&sain, sizeof(struct sockaddr_in)) == SOCKET_ERROR )
	{
		perror("can't bind port");
		//abort();
	}
	if ( listen(m_socket, 10) != 0 )
	{
		perror("Can't configure listening port");
		//abort();
	}
	return m_socket;
}

SSL_CTX* InitServerCTX(void)
{
	SSL_CTX *ctx = NULL;

    #if OPENSSL_VERSION_NUMBER >= 0x10000000L
           const SSL_METHOD *method;
    #else
            SSL_METHOD *method;
    #endif

    SSL_library_init();
    //OpenSSL_add_all_algorithms();  /* load & register all cryptos, etc. */
    SSL_load_error_strings();   /* load all error messages */
    //method = SSLv23_method(); /* create new server-method instance */
	method =TLSv1_server_method();
    ctx = SSL_CTX_new(method);   /* create new context from method */
    if ( ctx == NULL )
    {
        ERR_print_errors_fp(stderr);
        abort();
    }
    return ctx;
}

void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile)
{
	//New lines
    if (SSL_CTX_load_verify_locations(ctx, CertFile, KeyFile) != 1)
        ERR_print_errors_fp(stderr);

    if (SSL_CTX_set_default_verify_paths(ctx) != 1)
        ERR_print_errors_fp(stderr);
    //End new lines
	/* set the local certificate from CertFile */
	if ( SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM) <= 0 )
	{
		ERR_print_errors_fp(stderr);
		//abort();
	}
	/* set the private key from KeyFile (may be the same as CertFile) */
	if ( SSL_CTX_use_PrivateKey_file(ctx, KeyFile, SSL_FILETYPE_PEM) <= 0 )
	{
		ERR_print_errors_fp(stderr);
		abort();
	}
	/* verify private key */
	if ( !SSL_CTX_check_private_key(ctx) )
	{
		fprintf(stderr, "Private key does not match the public certificate\n");
		abort();
	}
}

void ShowCerts(SSL* ssl)
{   
	X509 *cert;
	char *line;

	cert = SSL_get_peer_certificate(ssl); /* Get certificates (if available) */
	if ( cert != NULL )
	{
		printf("Server certificates:\n");
		line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
		printf("Subject: %s\n", line);
		free(line);
		line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
		printf("Issuer: %s\n", line);
		free(line);
		X509_free(cert);
	}
	else
		printf("No certificates.\n");
}

void Servlet(SSL* ssl,SOCKET client) /* Serve the connection -- threadable */
{   char buf[1024];
	char reply[1024];
	int sd, bytes;
	const char* HTMLecho="hello client";

    ShowCerts(ssl);        /* get any certificates */
	while(1)
	{
		bytes = recv(client, buf, sizeof(buf),0); 
		//bytes = SSL_read(ssl, buf, sizeof(buf)); 
		if ( bytes > 0 )
		{
			buf[bytes] = 0;
			printf("Client msg: \"%s\"\n", buf);
			sprintf(reply, HTMLecho, buf);   /* construct reply */
			SSL_write(ssl, reply, strlen(reply)); /* send reply */
		}
		else
		{
		
		}
	}
}

int main(int count, char *strings[])
{   SSL_CTX *ctx;
	SOCKET server;
	char *portnum;
	server = OpenListener(1030);    /* create server socket */

	SSL_library_init();

	portnum = strings[1];
	ctx = InitServerCTX();        /* initialize SSL */
	LoadCertificates(ctx, "cert.pem", "key.pem");  /* load certs */


	while (1)
	{   struct sockaddr_in addr;
		socklen_t len = sizeof(addr);
		SSL *ssl;

		SOCKET client = accept(server, (struct sockaddr*)&addr, &len);  /* accept connection   as usual */

				socklen_t len1;
				struct sockaddr_storage addr1;
				//add1.sin_family = AF_INET;
				char ipstr[INET6_ADDRSTRLEN];
				int port;

				len1 = sizeof addr;
				int r;

				r=getpeername(client, (struct sockaddr*)&addr1, &len1);

				// deal with both IPv4 and IPv6:
				if (addr1.ss_family == AF_INET) 
				{
					struct sockaddr_in *s = (struct sockaddr_in *)&addr1;
					port = ntohs(s->sin_port);
					inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr);
				} 
				else 
				{ // AF_INET6
					struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr1;
					port = ntohs(s->sin6_port);
					inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr);
				}

				printf("Peer IP address: %s\n", ipstr);
				printf("Peer port      : %d\n", port);
		printf("Connection: %s:%d\n",inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
		ssl = SSL_new(ctx);              /* get new SSL state with context */
		SSL_set_fd(ssl, client);      /* set connection socket to SSL state */
		Servlet(ssl,client);         /* service connection */
	}
SSL_CTX_free(ctx);         /* release context */
}

//SSL-Client.c
#include <stdio.h>
#include <errno.h>
#include <StdAfx.h>
#include <malloc.h>
#include <string.h>
# include <winsock2.h>
#include <ws2tcpip.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

#define FAIL    -1
#pragma comment(lib, "Ws2_32.lib")
    //Added the LoadCertificates how in the server-side makes.    
int OpenConnection(const char *hostname, int port)
{   
	SOCKET sd;
	struct hostent *host;
	struct sockaddr_in addr;

	WORD wVersionRequested;
    WSADATA wsaData;
    int err;

	/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
    wVersionRequested = MAKEWORD(2, 2);

    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0) 
	{
        /* Tell the user that we could not find a usable */
        /* Winsock DLL.                                  */
        printf("WSAStartup failed with error: %d\n", err);
        return 1;
    }

	sd = socket(PF_INET, SOCK_STREAM, 0);
	/////////////bzero(&addr, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(1020);
	addr.sin_addr.s_addr = inet_addr("127.0.0.1");
	if ( connect(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 )
	{
		//close(sd);
		perror(hostname);
		abort();
	}
	return sd;
}

SSL_CTX* InitCTX(void)
{   SSL_METHOD *method;
	SSL_CTX *ctx;

	//OpenSSL_add_all_algorithms();  /* Load cryptos, et.al. */
	SSL_load_error_strings();   /* Bring in and register error messages */
	//method = SSLv2_client_method();  /* Create new client-method instance */
	method =TLSv1_method();
	ctx = SSL_CTX_new(method);   /* Create new context */
	if ( ctx == NULL )
	{
		ERR_print_errors_fp(stderr);
		printf("Eroor: %s\n",stderr);
		abort();
	}
	return ctx;
}

void ShowCerts(SSL* ssl)
 {   X509 *cert;
    char *line1,*line2;

    cert = SSL_get_peer_certificate(ssl); /* get the server's certificate */
    if ( cert != NULL )
    {
		printf("Server certificates:\n");
		line1 = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
		printf("Subject: %s\n", line1);
		//free(line);       /* free the malloc'ed string */
		line2 = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
		printf("Issuer: %s\n", line2);
		//free(line);       /* free the malloc'ed string */
		//X509_free(cert);     /* free the malloc'ed certificate copy */
	}
	else
		printf("No certificates.\n");
}

int main(int count, char *strings[])
{   SSL_CTX *ctx;
	SOCKET server;
	SSL *ssl;
	char buf[1024];
	int bytes;
	char *hostname, *portnum;

	SSL_library_init();
	hostname="127.0.0.1";
	portnum="1020";

	ctx = InitCTX();
	server = OpenConnection(hostname, atoi(portnum));
	ssl = SSL_new(ctx);      /* create new SSL connection state */
	SSL_set_fd(ssl, server);    /* attach the socket descriptor */
	if ( SSL_connect(ssl) == FAIL )   /* perform the connection */
	{
		printf("Eroor: %s\n",stderr);
		ERR_print_errors_fp(stderr);
	}
	else
	{  
		printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
		ShowCerts(ssl);  /* get any certs */
		while(1)
		{
			char *msg = "Hello???";
			char p[10];
			scanf("%s",&p);		      
			SSL_write(ssl, msg, strlen(msg));   /* encrypt & send message */
			bytes = SSL_read(ssl, buf, sizeof(buf)); /* get reply & decrypt */
			buf[bytes] = 0;
			printf("Received: \"%s\"\n", buf);
		}
		SSL_free(ssl);        /* release connection state */
	}
	//close(server);         /* close socket */
	SSL_CTX_free(ctx);        /* release context */
	return 0;
}


More information about the live-devel mailing list