New upstream version 22.0.3+dfsg1

This commit is contained in:
Sebastian Ramacher 2018-12-16 17:14:58 +01:00
parent 665f64a933
commit cdc9a9fc87
334 changed files with 14525 additions and 2639 deletions

View file

@ -29,6 +29,7 @@
#include "bytes.h"
static const AMFObjectProperty AMFProp_Invalid = { {0, 0}, AMF_INVALID };
static const AMFObject AMFObj_Invalid = { 0, 0 };
static const AVal AV_empty = { 0, 0 };
/* Data is Big-Endian */
@ -336,13 +337,19 @@ AMFProp_GetBoolean(AMFObjectProperty *prop)
void
AMFProp_GetString(AMFObjectProperty *prop, AVal *str)
{
*str = prop->p_vu.p_aval;
if (prop->p_type == AMF_STRING)
*str = prop->p_vu.p_aval;
else
*str = AV_empty;
}
void
AMFProp_GetObject(AMFObjectProperty *prop, AMFObject *obj)
{
*obj = prop->p_vu.p_object;
if (prop->p_type == AMF_OBJECT)
*obj = prop->p_vu.p_object;
else
*obj = AMFObj_Invalid;
}
int
@ -472,6 +479,8 @@ AMF3ReadString(const char *data, AVal *str)
RTMP_Log(RTMP_LOGDEBUG,
"%s, string reference, index: %d, not supported, ignoring!",
__FUNCTION__, refIndex);
str->av_val = NULL;
str->av_len = 0;
return len;
}
else
@ -511,9 +520,12 @@ AMF3Prop_Decode(AMFObjectProperty *prop, const char *pBuffer, int nSize,
if (name.av_len <= 0)
return nRes;
nSize -= nRes;
if (nSize <= 0)
return -1;
prop->p_name = name;
pBuffer += nRes;
nSize -= nRes;
}
/* decode */
@ -601,6 +613,9 @@ AMF3Prop_Decode(AMFObjectProperty *prop, const char *pBuffer, int nSize,
return -1;
}
if (nSize < 0)
return -1;
return nOriginalSize - nSize;
}
@ -994,9 +1009,18 @@ AMF_DecodeArray(AMFObject *obj, const char *pBuffer, int nSize,
int nRes;
nArrayLen--;
if (nSize <= 0)
{
bError = TRUE;
break;
}
nRes = AMFProp_Decode(&prop, pBuffer, nSize, bDecodeName);
if (nRes == -1)
{
bError = TRUE;
break;
}
else
{
nSize -= nRes;
@ -1057,12 +1081,12 @@ AMF3_Decode(AMFObject *obj, const char *pBuffer, int nSize, int bAMFData)
else
{
int32_t classExtRef = (classRef >> 1);
int i;
int i, cdnum;
cd.cd_externalizable = (classExtRef & 0x1) == 1;
cd.cd_dynamic = ((classExtRef >> 1) & 0x1) == 1;
cd.cd_num = classExtRef >> 2;
cdnum = classExtRef >> 2;
/* class name */
@ -1077,9 +1101,16 @@ AMF3_Decode(AMFObject *obj, const char *pBuffer, int nSize, int bAMFData)
cd.cd_name.av_val, cd.cd_externalizable, cd.cd_dynamic,
cd.cd_num);
for (i = 0; i < cd.cd_num; i++)
for (i = 0; i < cdnum; i++)
{
AVal memberName = AV_empty;
if (nSize <= 0)
{
invalid:
RTMP_Log(RTMP_LOGDEBUG, "%s, invalid class encoding!",
__FUNCTION__);
return nOriginalSize;
}
len = AMF3ReadString(pBuffer, &memberName);
RTMP_Log(RTMP_LOGDEBUG, "Member: %s", memberName.av_val);
AMF3CD_AddProp(&cd, &memberName);
@ -1115,6 +1146,8 @@ AMF3_Decode(AMFObject *obj, const char *pBuffer, int nSize, int bAMFData)
int nRes, i;
for (i = 0; i < cd.cd_num; i++) /* non-dynamic */
{
if (nSize <= 0)
goto invalid;
nRes = AMF3Prop_Decode(&prop, pBuffer, nSize, FALSE);
if (nRes == -1)
RTMP_Log(RTMP_LOGDEBUG, "%s, failed to decode AMF3 property!",
@ -1132,6 +1165,8 @@ AMF3_Decode(AMFObject *obj, const char *pBuffer, int nSize, int bAMFData)
do
{
if (nSize <= 0)
goto invalid;
nRes = AMF3Prop_Decode(&prop, pBuffer, nSize, TRUE);
AMF_AddProp(obj, &prop);
@ -1179,10 +1214,18 @@ AMF_Decode(AMFObject *obj, const char *pBuffer, int nSize, int bDecodeName)
nRes = AMFProp_Decode(&prop, pBuffer, nSize, bDecodeName);
if (nRes == -1)
{
bError = TRUE;
break;
}
else
{
nSize -= nRes;
if (nSize < 0)
{
bError = TRUE;
break;
}
pBuffer += nRes;
AMF_AddProp(obj, &prop);
}

View file

@ -21,7 +21,59 @@
* http://www.gnu.org/copyleft/lgpl.html
*/
#ifdef USE_POLARSSL
#if defined(USE_MBEDTLS)
#include <mbedtls/dhm.h>
#include <mbedtls/bignum.h>
typedef mbedtls_mpi* MP_t;
#define MP_new(m) m = malloc(sizeof(mbedtls_mpi)); mbedtls_mpi_init(m)
#define MP_set_w(mpi, w) mbedtls_mpi_lset(mpi, w)
#define MP_cmp(u, v) mbedtls_mpi_cmp_mpi(u, v)
#define MP_set(u, v) mbedtls_mpi_copy(u, v)
#define MP_sub_w(mpi, w) mbedtls_mpi_sub_int(mpi, mpi, w)
#define MP_cmp_1(mpi) mbedtls_mpi_cmp_int(mpi, 1)
#define MP_modexp(r, y, q, p) mbedtls_mpi_exp_mod(r, y, q, p, NULL)
#define MP_free(mpi) mbedtls_mpi_free(mpi); free(mpi)
#define MP_gethex(u, hex, res) MP_new(u); res = mbedtls_mpi_read_string(u, 16, hex) == 0
#define MP_bytes(u) mbedtls_mpi_size(u)
#define MP_setbin(u,buf,len) mbedtls_mpi_write_binary(u,buf,len)
#define MP_getbin(u,buf,len) MP_new(u); mbedtls_mpi_read_binary(u,buf,len)
typedef struct MDH
{
MP_t p;
MP_t g;
MP_t pub_key;
MP_t priv_key;
long length;
mbedtls_dhm_context ctx;
} MDH;
#define MDH_new() calloc(1,sizeof(MDH))
#define MDH_free(vp) {MDH *_dh = vp; mbedtls_dhm_free(&_dh->ctx); MP_free(_dh->p); MP_free(_dh->g); MP_free(_dh->pub_key); MP_free(_dh->priv_key); free(_dh);}
static int MDH_generate_key(MDH *dh)
{
unsigned char out[2];
MP_set(&dh->ctx.P, dh->p);
MP_set(&dh->ctx.G, dh->g);
dh->ctx.len = 128;
mbedtls_dhm_make_public(&dh->ctx, 1024, out, 1, mbedtls_ctr_drbg_random, &RTMP_TLS_ctx->ctr_drbg);
MP_new(dh->pub_key);
MP_new(dh->priv_key);
MP_set(dh->pub_key, &dh->ctx.GX);
MP_set(dh->priv_key, &dh->ctx.X);
return 1;
}
static int MDH_compute_key(uint8_t *secret, size_t len, MP_t pub, MDH *dh)
{
MP_set(&dh->ctx.GY, pub);
size_t olen;
mbedtls_dhm_calc_secret(&dh->ctx, secret, len, &olen, NULL, NULL);
return 0;
}
#elif defined(USE_POLARSSL)
#include <polarssl/dhm.h>
typedef mpi * MP_t;
#define MP_new(m) m = malloc(sizeof(mpi)); mpi_init(m)
@ -271,7 +323,7 @@ DHGetPublicKey(MDH *dh, uint8_t *pubkey, size_t nPubkeyLen)
if (!dh || !dh->pub_key)
return 0;
len = MP_bytes(dh->pub_key);
len = (int)MP_bytes(dh->pub_key);
if (len <= 0 || len > (int) nPubkeyLen)
return 0;

View file

@ -24,7 +24,28 @@
/* This file is #included in rtmp.c, it is not meant to be compiled alone */
#ifdef USE_POLARSSL
#if defined(USE_MBEDTLS)
#include <mbedtls/md.h>
#include <mbedtls/arc4.h>
#ifndef SHA256_DIGEST_LENGTH
#define SHA256_DIGEST_LENGTH 32
#endif
typedef mbedtls_md_context_t *HMAC_CTX;
#define HMAC_setup(ctx, key, len) ctx = malloc(sizeof(mbedtls_md_context_t)); mbedtls_md_init(ctx); \
mbedtls_md_setup(ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1); \
mbedtls_md_hmac_starts(ctx, (const unsigned char *)key, len)
#define HMAC_crunch(ctx, buf, len) mbedtls_md_hmac_update(ctx, buf, len)
#define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; mbedtls_md_hmac_finish(ctx, dig)
#define HMAC_close(ctx) mbedtls_md_free(ctx); free(ctx); ctx = NULL
typedef mbedtls_arc4_context* RC4_handle;
#define RC4_alloc(h) *h = malloc(sizeof(mbedtls_arc4_context)); mbedtls_arc4_init(*h)
#define RC4_setkey(h,l,k) mbedtls_arc4_setup(h,k,l)
#define RC4_encrypt(h,l,d) mbedtls_arc4_crypt(h,l,(unsigned char *)d,(unsigned char *)d)
#define RC4_encrypt2(h,l,s,d) mbedtls_arc4_crypt(h,l,(unsigned char *)s,(unsigned char *)d)
#define RC4_free(h) mbedtls_arc4_free(h); free(h); h = NULL
#elif defined(USE_POLARSSL)
#include <polarssl/sha2.h>
#include <polarssl/arc4.h>
#ifndef SHA256_DIGEST_LENGTH
@ -148,6 +169,8 @@ typedef unsigned int (getoff)(uint8_t *buf, unsigned int len);
static unsigned int
GetDHOffset2(uint8_t *handshake, unsigned int len)
{
(void) len;
unsigned int offset = 0;
uint8_t *ptr = handshake + 768;
unsigned int res;
@ -177,6 +200,8 @@ GetDHOffset2(uint8_t *handshake, unsigned int len)
static unsigned int
GetDigestOffset2(uint8_t *handshake, unsigned int len)
{
(void) len;
unsigned int offset = 0;
uint8_t *ptr = handshake + 772;
unsigned int res;
@ -206,6 +231,8 @@ GetDigestOffset2(uint8_t *handshake, unsigned int len)
static unsigned int
GetDHOffset1(uint8_t *handshake, unsigned int len)
{
(void) len;
unsigned int offset = 0;
uint8_t *ptr = handshake + 1532;
unsigned int res;
@ -235,6 +262,8 @@ GetDHOffset1(uint8_t *handshake, unsigned int len)
static unsigned int
GetDigestOffset1(uint8_t *handshake, unsigned int len)
{
(void) len;
unsigned int offset = 0;
uint8_t *ptr = handshake + 8;
unsigned int res;
@ -1128,6 +1157,7 @@ HandShake(RTMP * r, int FP9HandShake)
__FUNCTION__);
}
}
// TODO(mgoulet): Should this have a HMAC_finish here?
RTMP_Log(RTMP_LOGDEBUG, "%s: Handshaking finished....", __FUNCTION__);
return TRUE;
@ -1482,6 +1512,8 @@ SHandShake(RTMP * r)
}
}
// TODO(mgoulet): Should this have an Rc4_free?
RTMP_Log(RTMP_LOGDEBUG, "%s: Handshaking finished....", __FUNCTION__);
return TRUE;
}

View file

@ -30,7 +30,20 @@
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#ifdef USE_POLARSSL
#if defined(USE_MBEDTLS)
#include <mbedtls/md.h>
#ifndef SHA256_DIGEST_LENGTH
#define SHA256_DIGEST_LENGTH 32
#endif
typedef mbedtls_md_context_t *HMAC_CTX;
#define HMAC_setup(ctx, key, len) ctx = malloc(sizeof(mbedtls_md_context_t)); mbedtls_md_init(ctx); \
mbedtls_md_setup(ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1); \
mbedtls_md_hmac_starts(ctx, (const unsigned char *)key, len)
#define HMAC_crunch(ctx, buf, len) mbedtls_md_hmac_update(ctx, buf, len)
#define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; mbedtls_md_hmac_finish(ctx, dig)
#define HMAC_close(ctx) free(ctx); mbedtls_md_free(ctx); ctx = NULL
#elif defined(USE_POLARSSL)
#include <polarssl/sha2.h>
#ifndef SHA256_DIGEST_LENGTH
#define SHA256_DIGEST_LENGTH 32
@ -40,6 +53,7 @@
#define HMAC_crunch(ctx, buf, len) sha2_hmac_update(&ctx, buf, len)
#define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; sha2_hmac_finish(&ctx, dig)
#define HMAC_close(ctx)
#elif defined(USE_GNUTLS)
#include <nettle/hmac.h>
#ifndef SHA256_DIGEST_LENGTH
@ -51,6 +65,7 @@
#define HMAC_crunch(ctx, buf, len) hmac_sha256_update(&ctx, len, buf)
#define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; hmac_sha256_digest(&ctx, SHA256_DIGEST_LENGTH, dig)
#define HMAC_close(ctx)
#else /* USE_OPENSSL */
#include <openssl/ssl.h>
#include <openssl/sha.h>
@ -161,8 +176,17 @@ HTTP_get(struct HTTP_ctx *http, const char *url, HTTP_read_callback *cb)
goto leave;
#else
TLS_client(RTMP_TLS_ctx, sb.sb_ssl);
#if defined(USE_MBEDTLS)
mbedtls_net_context *server_fd = &RTMP_TLS_ctx->net;
server_fd->fd = sb.sb_socket;
TLS_setfd(sb.sb_ssl, server_fd);
#else
TLS_setfd(sb.sb_ssl, sb.sb_socket);
if (TLS_connect(sb.sb_ssl) < 0)
#endif
int connect_return = TLS_connect(sb.sb_ssl);
if (connect_return < 0)
{
RTMP_Log(RTMP_LOGERROR, "%s, TLS_Connect failed", __FUNCTION__);
ret = HTTPRES_LOST_CONNECTION;
@ -318,21 +342,21 @@ swfcrunch(void *ptr, size_t size, size_t nmemb, void *stream)
{
unsigned char out[CHUNK];
i->zs->next_in = (unsigned char *)p;
i->zs->avail_in = len;
i->zs->avail_in = (uInt)len;
do
{
i->zs->avail_out = CHUNK;
i->zs->next_out = out;
inflate(i->zs, Z_NO_FLUSH);
len = CHUNK - i->zs->avail_out;
i->size += len;
i->size += (int)len;
HMAC_crunch(i->ctx, out, len);
}
while (i->zs->avail_out == 0);
}
else
{
i->size += len;
i->size += (int)len;
HMAC_crunch(i->ctx, (unsigned char *)p, len);
}
return size * nmemb;
@ -469,7 +493,7 @@ RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash,
home.av_val = "\\UserData";
#else
hpre.av_val = getenv("HOMEDRIVE");
hpre.av_len = strlen(hpre.av_val);
hpre.av_len = (int)strlen(hpre.av_val);
home.av_val = getenv("HOMEPATH");
#endif
#define DIRSEP "\\"
@ -482,7 +506,7 @@ RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash,
#endif
if (!home.av_val)
home.av_val = ".";
home.av_len = strlen(home.av_val);
home.av_len = (int)strlen(home.av_val);
/* SWF hash info is cached in a fixed-format file.
* url: <url of SWF file>
@ -528,7 +552,7 @@ RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash,
if (strncmp(buf + 5, url, hlen))
continue;
r1 = strrchr(buf, '/');
i = strlen(r1);
i = (int)strlen(r1);
r1[--i] = '\0';
if (strncmp(r1, file, i))
continue;
@ -543,7 +567,7 @@ RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash,
else if (!strncmp(buf, "hash: ", 6))
{
unsigned char *ptr = hash, *in = (unsigned char *)buf + 6;
int l = strlen((char *)in) - 1;
int l = (int)strlen((char *)in) - 1;
for (i = 0; i < l; i += 2)
*ptr++ = (HEX2BIN(in[i]) << 4) | HEX2BIN(in[i + 1]);
got++;
@ -625,7 +649,7 @@ RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash,
if (q)
i = q - url;
else
i = strlen(url);
i = (int)strlen(url);
fprintf(f, "url: %.*s\n", i, url);
}

View file

@ -40,7 +40,20 @@
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#ifdef USE_POLARSSL
#if defined(USE_MBEDTLS)
#if defined(_WIN32)
#include <windows.h>
#include <wincrypt.h>
#elif defined(__APPLE__)
#include <Security/Security.h>
#endif
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/md5.h>
#include <mbedtls/base64.h>
#define MD5_DIGEST_LENGTH 16
#elif defined(USE_POLARSSL)
#include <polarssl/havege.h>
#include <polarssl/md5.h>
#include <polarssl/base64.h>
@ -57,7 +70,6 @@ static const char *my_dhm_P =
"E8A700D60B7F1200FA8E77B0A979DABF";
static const char *my_dhm_G = "4";
#elif defined(USE_GNUTLS)
#include <gnutls/gnutls.h>
#define MD5_DIGEST_LENGTH 16
@ -70,7 +82,8 @@ static const char *my_dhm_G = "4";
#include <openssl/bio.h>
#include <openssl/buffer.h>
#endif
TLS_CTX RTMP_TLS_ctx;
TLS_CTX RTMP_TLS_ctx = NULL;
#endif
#define RTMP_SIG_SIZE 1536
@ -226,9 +239,13 @@ RTMPPacket_Reset(RTMPPacket *p)
}
int
RTMPPacket_Alloc(RTMPPacket *p, int nSize)
RTMPPacket_Alloc(RTMPPacket *p, uint32_t nSize)
{
char *ptr = calloc(1, nSize + RTMP_MAX_HEADER_SIZE);
char *ptr;
if (nSize > SIZE_MAX - RTMP_MAX_HEADER_SIZE)
return FALSE;
ptr = calloc(1, nSize + RTMP_MAX_HEADER_SIZE);
if (!ptr)
return FALSE;
p->m_body = ptr + RTMP_MAX_HEADER_SIZE;
@ -261,11 +278,101 @@ RTMP_LibVersion()
return RTMP_LIB_VERSION;
}
void
RTMP_TLS_LoadCerts() {
#ifdef USE_MBEDTLS
mbedtls_x509_crt *chain = RTMP_TLS_ctx->cacert = calloc(1, sizeof(struct mbedtls_x509_crt));
mbedtls_x509_crt_init(chain);
#if defined(_WIN32)
HCERTSTORE hCertStore;
PCCERT_CONTEXT pCertContext = NULL;
if (!(hCertStore = CertOpenSystemStore((HCRYPTPROV)NULL, L"ROOT"))) {
goto error;
}
while (pCertContext = CertEnumCertificatesInStore(hCertStore, pCertContext)) {
mbedtls_x509_crt_parse_der(chain,
(unsigned char *)pCertContext->pbCertEncoded,
pCertContext->cbCertEncoded);
}
CertFreeCertificateContext(pCertContext);
CertCloseStore(hCertStore, 0);
#elif defined(__APPLE__)
SecKeychainRef keychain_ref;
CFMutableDictionaryRef search_settings_ref;
CFArrayRef result_ref;
if (SecKeychainOpen("/System/Library/Keychains/SystemRootCertificates.keychain",
&keychain_ref)
!= errSecSuccess) {
goto error;
}
search_settings_ref = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
CFDictionarySetValue(search_settings_ref, kSecClass, kSecClassCertificate);
CFDictionarySetValue(search_settings_ref, kSecMatchLimit, kSecMatchLimitAll);
CFDictionarySetValue(search_settings_ref, kSecReturnRef, kCFBooleanTrue);
CFDictionarySetValue(search_settings_ref, kSecMatchSearchList,
CFArrayCreate(NULL, (const void **)&keychain_ref, 1, NULL));
if (SecItemCopyMatching(search_settings_ref, (CFTypeRef *)&result_ref)
!= errSecSuccess) {
goto error;
}
for (CFIndex i = 0; i < CFArrayGetCount(result_ref); i++) {
SecCertificateRef item_ref = (SecCertificateRef)
CFArrayGetValueAtIndex(result_ref, i);
CFDataRef data_ref;
if ((data_ref = SecCertificateCopyData(item_ref))) {
mbedtls_x509_crt_parse_der(chain,
(unsigned char *)CFDataGetBytePtr(data_ref),
CFDataGetLength(data_ref));
CFRelease(data_ref);
}
}
CFRelease(keychain_ref);
#elif defined(__linux__)
if (mbedtls_x509_crt_parse_path(chain, "/etc/ssl/certs/") != 0) {
goto error;
}
#endif
mbedtls_ssl_conf_ca_chain(&RTMP_TLS_ctx->conf, chain, NULL);
return;
error:
mbedtls_x509_crt_free(chain);
free(chain);
RTMP_TLS_ctx->cacert = NULL;
#endif /* USE_MBEDTLS */
}
void
RTMP_TLS_Init()
{
#ifdef CRYPTO
#ifdef USE_POLARSSL
#if defined(USE_MBEDTLS)
const char * pers = "RTMP_TLS";
RTMP_TLS_ctx = calloc(1,sizeof(struct tls_ctx));
mbedtls_ssl_config_init(&RTMP_TLS_ctx->conf);
mbedtls_ctr_drbg_init(&RTMP_TLS_ctx->ctr_drbg);
mbedtls_entropy_init(&RTMP_TLS_ctx->entropy);
mbedtls_ctr_drbg_seed(&RTMP_TLS_ctx->ctr_drbg,
mbedtls_entropy_func,
&RTMP_TLS_ctx->entropy,
(const unsigned char *)pers,
strlen(pers));
RTMP_TLS_LoadCerts();
#elif defined(USE_POLARSSL)
/* Do this regardless of NO_SSL, we use havege for rtmpe too */
RTMP_TLS_ctx = calloc(1,sizeof(struct tls_ctx));
havege_init(&RTMP_TLS_ctx->hs);
@ -289,6 +396,26 @@ RTMP_TLS_Init()
SSL_CTX_set_options(RTMP_TLS_ctx, SSL_OP_ALL);
SSL_CTX_set_default_verify_paths(RTMP_TLS_ctx);
#endif
#else
#endif
}
void
RTMP_TLS_Free() {
#ifdef USE_MBEDTLS
mbedtls_ssl_config_free(&RTMP_TLS_ctx->conf);
mbedtls_ctr_drbg_free(&RTMP_TLS_ctx->ctr_drbg);
mbedtls_entropy_free(&RTMP_TLS_ctx->entropy);
if (RTMP_TLS_ctx->cacert) {
mbedtls_x509_crt_free(RTMP_TLS_ctx->cacert);
free(RTMP_TLS_ctx->cacert);
RTMP_TLS_ctx->cacert = NULL;
}
// NO mbedtls_net_free() BECAUSE WE SET IT UP BY HAND!
free(RTMP_TLS_ctx);
RTMP_TLS_ctx = NULL;
#endif
}
@ -299,7 +426,27 @@ RTMP_TLS_AllocServerContext(const char* cert, const char* key)
#ifdef CRYPTO
if (!RTMP_TLS_ctx)
RTMP_TLS_Init();
#ifdef USE_POLARSSL
#if defined(USE_MBEDTLS)
tls_server_ctx *tc = ctx = calloc(1, sizeof(struct tls_server_ctx));
tc->conf = &RTMP_TLS_ctx->conf;
tc->ctr_drbg = &RTMP_TLS_ctx->ctr_drbg;
mbedtls_x509_crt_init(&tc->cert);
if (mbedtls_x509_crt_parse_file(&tc->cert, cert))
{
free(tc);
return NULL;
}
mbedtls_pk_init(&tc->key);
if (mbedtls_pk_parse_keyfile(&tc->key, key, NULL))
{
mbedtls_x509_crt_free(&tc->cert);
mbedtls_pk_free(&tc->key);
free(tc);
return NULL;
}
#elif defined(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;
@ -346,7 +493,11 @@ void
RTMP_TLS_FreeServerContext(void *ctx)
{
#ifdef CRYPTO
#ifdef USE_POLARSSL
#if defined(USE_MBEDTLS)
mbedtls_x509_crt_free(&((tls_server_ctx*)ctx)->cert);
mbedtls_pk_free(&((tls_server_ctx*)ctx)->key);
free(ctx);
#elif defined(USE_POLARSSL)
x509_free(&((tls_server_ctx*)ctx)->cert);
rsa_free(&((tls_server_ctx*)ctx)->key);
free(ctx);
@ -370,6 +521,10 @@ RTMP_Alloc()
void
RTMP_Free(RTMP *r)
{
#if defined(CRYPTO) && defined(USE_MBEDTLS)
if (RTMP_TLS_ctx)
RTMP_TLS_Free();
#endif
free(r);
}
@ -846,9 +1001,20 @@ int
RTMP_TLS_Accept(RTMP *r, void *ctx)
{
#if defined(CRYPTO) && !defined(NO_SSL)
TLS_server(ctx, r->m_sb.sb_ssl);
tls_server_ctx *srv_ctx = ctx;
TLS_server(srv_ctx, r->m_sb.sb_ssl);
#if defined(USE_MBEDTLS)
mbedtls_net_context *client_fd = &RTMP_TLS_ctx->net;
mbedtls_net_init(client_fd);
client_fd->fd = r->m_sb.sb_socket;
TLS_setfd(r->m_sb.sb_ssl, client_fd);
#else
TLS_setfd(r->m_sb.sb_ssl, r->m_sb.sb_socket);
if (TLS_accept(r->m_sb.sb_ssl) < 0)
#endif
int connect_return = TLS_connect(r->m_sb.sb_ssl);
if (connect_return < 0)
{
RTMP_Log(RTMP_LOGERROR, "%s, TLS_Connect failed", __FUNCTION__);
return FALSE;
@ -868,10 +1034,59 @@ RTMP_Connect1(RTMP *r, RTMPPacket *cp)
{
#if defined(CRYPTO) && !defined(NO_SSL)
TLS_client(RTMP_TLS_ctx, r->m_sb.sb_ssl);
#if defined(USE_MBEDTLS)
mbedtls_net_context *server_fd = &RTMP_TLS_ctx->net;
server_fd->fd = r->m_sb.sb_socket;
TLS_setfd(r->m_sb.sb_ssl, server_fd);
// make sure we verify the certificate hostname
char hostname[MBEDTLS_SSL_MAX_HOST_NAME_LEN + 1];
if (r->Link.hostname.av_len >= MBEDTLS_SSL_MAX_HOST_NAME_LEN)
return FALSE;
memcpy(hostname, r->Link.hostname.av_val, r->Link.hostname.av_len);
hostname[r->Link.hostname.av_len] = 0;
if (mbedtls_ssl_set_hostname(r->m_sb.sb_ssl, hostname))
return FALSE;
#else
TLS_setfd(r->m_sb.sb_ssl, r->m_sb.sb_socket);
if (TLS_connect(r->m_sb.sb_ssl) < 0)
#endif
int connect_return = TLS_connect(r->m_sb.sb_ssl);
if (connect_return < 0)
{
RTMP_Log(RTMP_LOGERROR, "%s, TLS_Connect failed", __FUNCTION__);
#if defined(USE_MBEDTLS)
if (connect_return == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED)
{
r->last_error_code = connect_return;
// show a more detailed error in the log if possible
int verify_result = mbedtls_ssl_get_verify_result(r->m_sb.sb_ssl);
if (verify_result)
{
char err[256], *e;
if (mbedtls_x509_crt_verify_info(err, sizeof(err), "", verify_result) > 0)
{
e = strchr(err, '\n');
if (e)
*e = '\0';
}
else
{
strcpy(err, "unknown error");
}
RTMP_Log(RTMP_LOGERROR, "%s, Cert verify failed: %d (%s)", __FUNCTION__, verify_result, err);
RTMP_Close(r);
return FALSE;
}
}
#endif
// output the error in a format that matches mbedTLS
connect_return = abs(connect_return);
RTMP_Log(RTMP_LOGERROR, "%s, TLS_Connect failed: -0x%x", __FUNCTION__, connect_return);
RTMP_Close(r);
return FALSE;
}
@ -879,7 +1094,6 @@ RTMP_Connect1(RTMP *r, RTMPPacket *cp)
RTMP_Log(RTMP_LOGERROR, "%s, no SSL/TLS support", __FUNCTION__);
RTMP_Close(r);
return FALSE;
#endif
}
if (r->Link.protocol & RTMP_FEATURE_HTTP)
@ -1108,7 +1322,7 @@ RTMP_GetNextMediaPacket(RTMP *r, RTMPPacket *packet)
while (!bHasMediaPacket && RTMP_IsConnected(r)
&& RTMP_ReadPacket(r, packet))
{
if (!RTMPPacket_IsReady(packet))
if (!RTMPPacket_IsReady(packet) || !packet->m_nBodySize)
{
continue;
}
@ -2398,7 +2612,19 @@ b64enc(const unsigned char *input, int length, char *output, int maxsize)
{
(void)maxsize;
#ifdef USE_POLARSSL
#if defined(USE_MBEDTLS)
size_t osize;
if(mbedtls_base64_encode((unsigned char *) output, maxsize, &osize, input, length) == 0)
{
output[osize] = '\0';
return 1;
}
else
{
RTMP_Log(RTMP_LOGDEBUG, "%s, error", __FUNCTION__);
return 0;
}
#elif defined(USE_POLARSSL)
size_t buf_size = maxsize;
if(base64_encode((unsigned char *) output, &buf_size, input, length) == 0)
{
@ -2457,7 +2683,13 @@ b64enc(const unsigned char *input, int length, char *output, int maxsize)
return 1;
}
#ifdef USE_POLARSSL
#if defined(USE_MBEDTLS)
typedef mbedtls_md5_context MD5_CTX;
#define MD5_Init(ctx) mbedtls_md5_init(ctx); mbedtls_md5_starts(ctx)
#define MD5_Update(ctx,data,len) mbedtls_md5_update(ctx,(unsigned char *)data,len)
#define MD5_Final(dig,ctx) mbedtls_md5_finish(ctx,dig); mbedtls_md5_free(ctx)
#elif defined(USE_POLARSSL)
#define MD5_CTX md5_context
#define MD5_Init(ctx) md5_starts(ctx)
#define MD5_Update(ctx,data,len) md5_update(ctx,(unsigned char *)data,len)
@ -3713,7 +3945,6 @@ RTMP_ReadPacket(RTMP *r, RTMPPacket *packet)
{
packet->m_nBodySize = AMF_DecodeInt24(header + 3);
packet->m_nBytesRead = 0;
RTMPPacket_Free(packet);
if (nSize > 6)
{

View file

@ -150,7 +150,7 @@ extern "C"
void RTMPPacket_Reset(RTMPPacket *p);
void RTMPPacket_Dump(RTMPPacket *p);
int RTMPPacket_Alloc(RTMPPacket *p, int nSize);
int RTMPPacket_Alloc(RTMPPacket *p, uint32_t nSize);
void RTMPPacket_Free(RTMPPacket *p);
#define RTMPPacket_IsReady(a) ((a)->m_nBytesRead == (a)->m_nBodySize)

View file

@ -80,7 +80,76 @@
#include "rtmp.h"
#ifdef USE_POLARSSL
#if defined(USE_MBEDTLS)
#include <mbedtls/version.h>
#include <mbedtls/net.h>
#include <mbedtls/ssl.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/entropy.h>
#define my_dhm_P \
"E4004C1F94182000103D883A448B3F80" \
"2CE4B44A83301270002C20D0321CFD00" \
"11CCEF784C26A400F43DFB901BCA7538" \
"F2C6B176001CF5A0FD16D2C48B1D0C1C" \
"F6AC8E1DA6BCC3B4E1F96B0564965300" \
"FFA1D0B601EB2800F489AA512C4B248C" \
"01F76949A60BB7F00A40B1EAB64BDD48" \
"E8A700D60B7F1200FA8E77B0A979DABF"
#define my_dhm_G "4"
#define SSL_SET_SESSION(S,resume,timeout,ctx) mbedtls_ssl_set_session(S,ctx)
typedef struct tls_ctx
{
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ssl_config conf;
mbedtls_ssl_session ssn;
mbedtls_x509_crt *cacert;
mbedtls_net_context net;
} tls_ctx;
typedef struct tls_server_ctx
{
mbedtls_ssl_config *conf;
mbedtls_ctr_drbg_context *ctr_drbg;
mbedtls_pk_context key;
mbedtls_x509_crt cert;
} tls_server_ctx;
typedef tls_ctx *TLS_CTX;
#define TLS_client(ctx,s) \
s = malloc(sizeof(mbedtls_ssl_context));\
mbedtls_ssl_init(s);\
mbedtls_ssl_setup(s, &ctx->conf);\
mbedtls_ssl_config_defaults(&ctx->conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);\
mbedtls_ssl_conf_authmode(&ctx->conf, MBEDTLS_SSL_VERIFY_REQUIRED);\
mbedtls_ssl_conf_rng(&ctx->conf, mbedtls_ctr_drbg_random, &ctx->ctr_drbg)
#define TLS_server(ctx,s)\
s = malloc(sizeof(mbedtls_ssl_context));\
mbedtls_ssl_init(s);\
mbedtls_ssl_setup(s, ctx->conf);\
mbedtls_ssl_conf_endpoint(ctx->conf, MBEDTLS_SSL_IS_SERVER);\
mbedtls_ssl_conf_authmode(ctx->conf, MBEDTLS_SSL_VERIFY_REQUIRED);\
mbedtls_ssl_conf_rng(ctx->conf, mbedtls_ctr_drbg_random, ctx->ctr_drbg);\
mbedtls_ssl_conf_own_cert(ctx->conf, &ctx->cert, &ctx->key);\
mbedtls_ssl_conf_dh_param_bin(ctx->conf,\
(const unsigned char *)my_dhm_P, strlen(my_dhm_P),\
(const unsigned char *)my_dhm_G, strlen(my_dhm_G))
#define TLS_setfd(s,fd) mbedtls_ssl_set_bio(s, fd, mbedtls_net_send, mbedtls_net_recv, NULL)
#define TLS_connect(s) mbedtls_ssl_handshake(s)
#define TLS_accept(s) mbedtls_ssl_handshake(s)
#define TLS_read(s,b,l) mbedtls_ssl_read(s,(unsigned char *)b,l)
#define TLS_write(s,b,l) mbedtls_ssl_write(s,(unsigned char *)b,l)
#define TLS_shutdown(s) mbedtls_ssl_close_notify(s)
#define TLS_close(s) mbedtls_ssl_free(s); free(s)
#elif defined(USE_POLARSSL)
#include <polarssl/version.h>
#include <polarssl/net.h>
#include <polarssl/ssl.h>
@ -128,6 +197,7 @@ typedef struct tls_server_ctx
#define TLS_shutdown(s) ssl_close_notify(s)
#define TLS_close(s) ssl_free(s); free(s)
#elif defined(USE_GNUTLS)
#include <gnutls/gnutls.h>
typedef struct tls_ctx