CFLAGS=-Wall $(XCFLAGS) $(INC) $(DEF) $(OPT)
LDFLAGS=-Wall $(XLDFLAGS)
LIBS=-lssl -lcrypto -lz
+#LIBS=-lgnutls -lz
THREADLIB=-lpthread
LIBRTMP=librtmp/librtmp.a
SLIBS=$(THREADLIB) $(LIBS)
CC=$(CROSS_COMPILE)gcc
LD=$(CROSS_COMPILE)ld
-DEF=-DRTMPDUMP_VERSION=\"v2.2a\"
+DEF=-DRTMPDUMP_VERSION=\"v2.2a\" # -DUSE_GNUTLS
OPT=-O2
CFLAGS=-Wall $(XCFLAGS) $(INC) $(DEF) $(OPT)
$(AR) rs $@ $?
log.o: log.c log.h Makefile
-rtmp.o: rtmp.c rtmp.h handshake.h dh.h log.h amf.h Makefile
+rtmp.o: rtmp.c rtmp.h rtmp_sys.h handshake.h dh.h log.h amf.h Makefile
amf.o: amf.c amf.h bytes.h log.h Makefile
-hashswf.o: hashswf.c http.h rtmp.h
+hashswf.o: hashswf.c http.h rtmp.h rtmp_sys.h
parseurl.o: parseurl.c
#include "log.h"
#include "http.h"
+#ifdef USE_GNUTLS
+#include <gnutls/gnutls.h>
+#include <gcrypt.h>
+#ifndef SHA256_DIGEST_LENGTH
+#define SHA256_DIGEST_LENGTH 32
+#endif
+#define HMAC_CTX gcry_md_hd_t
+#define HMAC_setup(ctx, key, len) gcry_md_open(&ctx, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); gcry_md_setkey(ctx, key, len)
+#define HMAC_crunch(ctx, buf, len) gcry_md_write(ctx, buf, len)
+#define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; memcpy(dig, gcry_md_read(ctx, 0), dlen)
+#define HMAC_close(ctx) gcry_md_close(ctx)
+#else
#include <openssl/ssl.h>
#include <openssl/sha.h>
#include <openssl/hmac.h>
+#include <openssl/rc4.h>
+#define HMAC_setup(ctx, key, len) HMAC_CTX_init(&ctx); HMAC_Init_ex(&ctx, (unsigned char *)key, len, EVP_sha256(), 0)
+#define HMAC_crunch(ctx, buf, len) HMAC_Update(&ctx, (unsigned char *)buf, len)
+#define HMAC_finish(ctx, dig, dlen) HMAC_Final(&ctx, (unsigned char *)dig, &dlen);
+#define HMAC_close(ctx) HMAC_CTX_cleanup(&ctx)
+#endif
#include <zlib.h>
struct info
{
- HMAC_CTX *ctx;
z_stream *zs;
+ HMAC_CTX ctx;
int first;
int zlib;
int size;
};
-extern void RTMP_SSL_Init();
-extern SSL_CTX *RTMP_ssl_ctx;
+extern void RTMP_TLS_Init();
+extern TLS_CTX RTMP_TLS_ctx;
#define CHUNK 16384
*p = 'F';
i->zlib = 1;
}
- HMAC_Update(i->ctx, (unsigned char *)p, 8);
+ HMAC_crunch(i->ctx, (unsigned char *)p, 8);
p += 8;
len -= 8;
i->size = 8;
inflate(i->zs, Z_NO_FLUSH);
len = CHUNK - i->zs->avail_out;
i->size += len;
- HMAC_Update(i->ctx, out, len);
+ HMAC_crunch(i->ctx, out, len);
}
while (i->zs->avail_out == 0);
}
else
{
i->size += len;
- HMAC_Update(i->ctx, (unsigned char *)p, len);
+ HMAC_crunch(i->ctx, (unsigned char *)p, len);
}
return size * nmemb;
}
{
ssl = 1;
port = 443;
- if (!RTMP_ssl_ctx)
- RTMP_SSL_Init();
+ if (!RTMP_TLS_ctx)
+ RTMP_TLS_Init();
}
p1 = strchr(url + 4, ':');
}
if (ssl)
{
- sb.sb_ssl = SSL_new(RTMP_ssl_ctx);
- SSL_set_fd(sb.sb_ssl, sb.sb_socket);
- if (SSL_connect(sb.sb_ssl) < 0)
+ TLS_client(RTMP_TLS_ctx, sb.sb_ssl);
+ TLS_setfd(sb.sb_ssl, sb.sb_socket);
+ if ((i = TLS_connect(sb.sb_ssl)) < 0)
{
- Log(LOGERROR, "%s, SSL_Connect failed", __FUNCTION__);
+ Log(LOGERROR, "%s, TLS_Connect failed", __FUNCTION__);
ret = HTTPRES_LOST_CONNECTION;
goto leave;
}
struct HTTP_ctx http = { 0 };
HTTPResult httpres;
z_stream zs = { 0 };
- HMAC_CTX ctx;
date[0] = '\0';
home = getenv(ENV_HOME);
}
in.first = 1;
- HMAC_CTX_init(&ctx);
- HMAC_Init_ex(&ctx, "Genuine Adobe Flash Player 001", 30, EVP_sha256(),
- NULL);
+ HMAC_setup(in.ctx, "Genuine Adobe Flash Player 001", 30);
inflateInit(&zs);
- in.ctx = &ctx;
in.zs = &zs;
http.date = date;
if (!in.first)
{
- HMAC_Final(&ctx, (unsigned char *)hash, &hlen);
+ HMAC_finish(in.ctx, hash, hlen);
*size = in.size;
fprintf(f, "date: %s\n", date);
fprintf(f, "\n");
}
}
- HMAC_CTX_cleanup(&ctx);
+ HMAC_close(in.ctx);
out:
free(path);
if (f)
#define RTMP_SIG_SIZE 1536
#define RTMP_LARGE_HEADER_SIZE 12
-SSL_CTX *RTMP_ssl_ctx;
+TLS_CTX RTMP_TLS_ctx;
static const int packetSize[] = { 12, 8, 4, 1 };
bool RTMP_ctrlC;
}
void
-RTMP_SSL_Init()
+RTMP_TLS_Init()
{
#ifdef USE_GNUTLS
gnutls_global_init();
+ RTMP_TLS_ctx = malloc(sizeof(struct tls_ctx));
+ gnutls_certificate_allocate_credentials(&RTMP_TLS_ctx->cred);
+ gnutls_priority_init(&RTMP_TLS_ctx->prios, "NORMAL", NULL);
+ gnutls_certificate_set_x509_trust_file(RTMP_TLS_ctx->cred,
+ "ca.pem", GNUTLS_X509_FMT_PEM);
#else
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_digests();
- RTMP_ssl_ctx = SSL_CTX_new(SSLv23_method());
- SSL_CTX_set_options(RTMP_ssl_ctx, SSL_OP_ALL);
- SSL_CTX_set_default_verify_paths(RTMP_ssl_ctx);
+ RTMP_TLS_ctx = SSL_CTX_new(SSLv23_method());
+ SSL_CTX_set_options(RTMP_TLS_ctx, SSL_OP_ALL);
+ SSL_CTX_set_default_verify_paths(RTMP_TLS_ctx);
#endif
}
{
int i;
- if (!RTMP_ssl_ctx)
- RTMP_SSL_Init();
+ if (!RTMP_TLS_ctx)
+ RTMP_TLS_Init();
for (i = 0; i < RTMP_CHANNELS; i++)
{
{
if (r->Link.protocol & RTMP_FEATURE_SSL)
{
- r->m_sb.sb_ssl = SSL_new(RTMP_ssl_ctx);
- SSL_set_fd(r->m_sb.sb_ssl, r->m_sb.sb_socket);
- if (SSL_connect(r->m_sb.sb_ssl) < 0)
+ TLS_client(RTMP_TLS_ctx, r->m_sb.sb_ssl);
+ TLS_setfd(r->m_sb.sb_ssl, r->m_sb.sb_socket);
+ if (TLS_connect(r->m_sb.sb_ssl) < 0)
{
- Log(LOGERROR, "%s, SSL_Connect failed", __FUNCTION__);
+ Log(LOGERROR, "%s, TLS_Connect failed", __FUNCTION__);
RTMP_Close(r);
return false;
}
nBytes = sizeof(sb->sb_buf) - sb->sb_size - (sb->sb_start - sb->sb_buf);
if (sb->sb_ssl)
{
- nBytes = SSL_read(sb->sb_ssl, sb->sb_start + sb->sb_size, nBytes);
+ nBytes = TLS_read(sb->sb_ssl, sb->sb_start + sb->sb_size, nBytes);
}
else
{
if (sb->sb_ssl)
{
- rc = SSL_write(sb->sb_ssl, buf, len);
+ rc = TLS_write(sb->sb_ssl, buf, len);
}
else
{
{
if (sb->sb_ssl)
{
- SSL_shutdown(sb->sb_ssl);
- SSL_free(sb->sb_ssl);
+ TLS_shutdown(sb->sb_ssl);
+ TLS_close(sb->sb_ssl);
sb->sb_ssl = NULL;
}
return closesocket(sb->sb_socket);
#include "rtmp.h"
+#ifdef USE_GNUTLS
+#include <gnutls/gnutls.h>
+typedef struct tls_ctx {
+ gnutls_certificate_credentials_t cred;
+ gnutls_priority_t prios;
+} 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_setfd(s,fd) gnutls_transport_set_ptr(s, (gnutls_transport_ptr_t)(long)fd)
+#define TLS_connect(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)
+#define TLS_close(s) gnutls_deinit(s)
+#else
+#define TLS_CTX SSL_CTX *
+#define TLS_client(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_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)
+#define TLS_close(s) SSL_free(s)
+
+#endif
#endif