#include <assert.h>
#include <limits.h>
-#ifdef USE_GNUTLS
+#ifdef USE_POLARSSL
+#include <polarssl/dhm.h>
+typedef mpi * MP_t;
+#define MP_new(m) m = malloc(sizeof(mpi)); mpi_init(m, NULL)
+#define MP_set_w(mpi, w) mpi_lset(mpi, w)
+#define MP_cmp(u, v) mpi_cmp_mpi(u, v)
+#define MP_set(u, v) mpi_copy(u, v)
+#define MP_sub_w(mpi, w) mpi_sub_int(mpi, mpi, w)
+#define MP_cmp_1(mpi) mpi_cmp_int(mpi, 1)
+#define MP_modexp(r, y, q, p) mpi_exp_mod(r, y, q, p, NULL)
+#define MP_free(mpi) mpi_free(mpi, NULL); free(mpi)
+#define MP_gethex(u, hex, res) MP_new(u); res = mpi_read_string(u, 16, hex) == 0
+#define MP_bytes(u) mpi_size(u)
+#define MP_setbin(u,buf,len) mpi_write_binary(u,buf,len)
+#define MP_getbin(u,buf,len) MP_new(u); 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;
+ dhm_context ctx;
+} MDH;
+
+#define MDH_new() calloc(1,sizeof(MDH))
+#define MDH_free(vp) {MDH *dh = vp; 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;
+ dhm_make_public(&dh->ctx, 1024, out, 1, havege_rand, &RTMP_TLS_ctx->hs);
+ 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)
+{
+ int n = len;
+ MP_set(&dh->ctx.GY, pub);
+ dhm_calc_secret(&dh->ctx, secret, &n);
+ return 0;
+}
+
+#elif defined(USE_GNUTLS)
#include <gcrypt.h>
typedef gcry_mpi_t MP_t;
-#define MP_new() gcry_mpi_new(1)
+#define MP_new(m) m = gcry_mpi_new(1)
#define MP_set_w(mpi, w) gcry_mpi_set_ui(mpi, w)
#define MP_cmp(u, v) gcry_mpi_cmp(u, v)
#define MP_set(u, v) gcry_mpi_set(u, v)
#define MP_cmp_1(mpi) gcry_mpi_cmp_ui(mpi, 1)
#define MP_modexp(r, y, q, p) gcry_mpi_powm(r, y, q, p)
#define MP_free(mpi) gcry_mpi_release(mpi)
-#define MP_gethex(u, hex, res) res = (gcry_mpi_scan(u, GCRYMPI_FMT_HEX, hex, 0, 0) == 0)
+#define MP_gethex(u, hex, res) res = (gcry_mpi_scan(&u, GCRYMPI_FMT_HEX, hex, 0, 0) == 0)
#define MP_bytes(u) (gcry_mpi_get_nbits(u) + 7) / 8
#define MP_setbin(u,buf,len) gcry_mpi_print(GCRYMPI_FMT_USG,buf,len,NULL,u)
#define MP_getbin(u,buf,len) gcry_mpi_scan(&u,GCRYMPI_FMT_USG,buf,len,NULL)
extern MP_t gnutls_calc_dh_secret(MP_t *priv, MP_t g, MP_t p);
extern MP_t gnutls_calc_dh_key(MP_t y, MP_t x, MP_t p);
-
#define MDH_generate_key(dh) (dh->pub_key = gnutls_calc_dh_secret(&dh->priv_key, dh->g, dh->p))
static int MDH_compute_key(uint8_t *secret, size_t len, MP_t pub, MDH *dh)
{
return -1;
}
-#else
+#else /* USE_OPENSSL */
#include <openssl/bn.h>
#include <openssl/dh.h>
typedef BIGNUM * MP_t;
-#define MP_new() BN_new()
+#define MP_new(m) m = BN_new()
#define MP_set_w(mpi, w) BN_set_word(mpi, w)
#define MP_cmp(u, v) BN_cmp(u, v)
#define MP_set(u, v) BN_copy(u, v)
#define MP_cmp_1(mpi) BN_cmp(mpi, BN_value_one())
#define MP_modexp(r, y, q, p) do {BN_CTX *ctx = BN_CTX_new(); BN_mod_exp(r, y, q, p, ctx); BN_CTX_free(ctx);} while(0)
#define MP_free(mpi) BN_free(mpi)
-#define MP_gethex(u, hex, res) res = BN_hex2bn(u, hex)
+#define MP_gethex(u, hex, res) res = BN_hex2bn(&u, hex)
#define MP_bytes(u) BN_num_bytes(u)
#define MP_setbin(u,buf,len) BN_bn2bin(u,buf)
#define MP_getbin(u,buf,len) u = BN_bin2bn(buf,len,0)
#include "log.h"
#include "dhgroups.h"
-/*
-MP_t dh_shared_p = 0; // shared prime
-MP_t dh_shared_g = 0; // shared base
-
-void dh_pg_init()
-{
- int res;
- if(dh_shared_p || dh_shared_g)
- return;
-
- dh_shared_p = MP_new();
- dh_shared_g = MP_new();
- assert(dh_shared_p && dh_shared_g);
-
- MP_gethex(&dh_shared_p, P1024, res); // prime P1024, see dhgroups.h
- assert(res);
-
- assert(MP_set_w(dh_shared_g, 2)); // base 2
-}
-*/
-
/* RFC 2631, Section 2.1.5, http://www.ietf.org/rfc/rfc2631.txt */
static bool
isValidPublicKey(MP_t y, MP_t p, MP_t q)
MP_t bn;
assert(y);
- bn = MP_new();
+ MP_new(bn);
assert(bn);
/* y must lie in [2,p-1] */
if (!dh)
goto failed;
- dh->g = MP_new();
+ MP_new(dh->g);
if (!dh->g)
goto failed;
- MP_gethex(&dh->p, P1024, res); /* prime P1024, see dhgroups.h */
+ MP_gethex(dh->p, P1024, res); /* prime P1024, see dhgroups.h */
if (!res)
{
goto failed;
}
- if (!MP_set_w(dh->g, 2)) /* base 2 */
- {
- goto failed;
- }
+ MP_set_w(dh->g, 2); /* base 2 */
dh->length = nKeyBits;
return dh;
if (!MDH_generate_key(dh))
return 0;
- MP_gethex(&q1, Q1024, res);
+ MP_gethex(q1, Q1024, res);
assert(res);
res = isValidPublicKey(dh->pub_key, dh->p, q1);
if (!pubkeyBn)
return -1;
- MP_gethex(&q1, Q1024, len);
+ MP_gethex(q1, Q1024, len);
assert(len);
if (isValidPublicKey(pubkeyBn, dh->p, q1))
/* This file is #included in rtmp.c, it is not meant to be compiled alone */
-#ifdef USE_GNUTLS
+#ifdef USE_POLARSSL
+#include <polarssl/sha2.h>
+#include <polarssl/arc4.h>
+#ifndef SHA256_DIGEST_LENGTH
+#define SHA256_DIGEST_LENGTH 32
+#endif
+#define HMAC_CTX sha2_context
+#define HMAC_setup(ctx, key, len) sha2_hmac_starts(&ctx, (unsigned char *)key, len, 0)
+#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)
+
+typedef arc4_context * RC4_handle;
+#define RC4_setup(h) *h = malloc(sizeof(arc4_context))
+#define RC4_setkey(h,l,k) arc4_setup(h,k,l)
+#define RC4_encrypt(h,l,d) arc4_crypt(h,l,(unsigned char *)d,(unsigned char *)d)
+#define RC4_encrypt2(h,l,s,d) arc4_crypt(h,l,(unsigned char *)s,(unsigned char *)d)
+
+#elif defined(USE_GNUTLS)
#include <gcrypt.h>
#ifndef SHA256_DIGEST_LENGTH
#define SHA256_DIGEST_LENGTH 32
#define RC4_encrypt(h,l,d) gcry_cipher_encrypt(h,(void *)d,l,NULL,0)
#define RC4_encrypt2(h,l,s,d) gcry_cipher_encrypt(h,(void *)d,l,(void *)s,l)
-#else
+#else /* USE_OPENSSL */
#include <openssl/sha.h>
#include <openssl/hmac.h>
#include <openssl/rc4.h>
if (encrypted)
{
/* generate Diffie-Hellmann parameters */
- r->Link.dh = DHInit(128); /* 1024 */
+ r->Link.dh = DHInit(1024);
if (!r->Link.dh)
{
RTMP_Log(RTMP_LOGERROR, "%s: Couldn't initialize Diffie-Hellmann!",
if (encrypted)
{
/* generate Diffie-Hellmann parameters */
- r->Link.dh = DHInit(128);
+ r->Link.dh = DHInit(1024);
if (!r->Link.dh)
{
RTMP_Log(RTMP_LOGERROR, "%s: Couldn't initialize Diffie-Hellmann!",
#include "rtmp.h"
-#ifdef USE_GNUTLS
+#ifdef USE_POLARSSL
+#include <polarssl/net.h>
+#include <polarssl/ssl.h>
+#include <polarssl/havege.h>
+typedef struct tls_ctx {
+ havege_state hs;
+ ssl_session ssn;
+} tls_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_rand, &ctx->hs); ssl_set_ciphers(s, ssl_default_ciphers);\
+ ssl_set_session(s, 1, 600, &ctx->ssn)
+#define TLS_setfd(s,fd) ssl_set_bio(s, net_recv, &fd, net_send, &fd)
+#define TLS_connect(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)
+#define TLS_close(s) ssl_free(s); free(s)
+
+#elif defined(USE_GNUTLS)
#include <gnutls/gnutls.h>
typedef struct tls_ctx {
gnutls_certificate_credentials_t cred;
#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
+
+#else /* USE_OPENSSL */
#define TLS_CTX SSL_CTX *
#define TLS_client(ctx,s) s = SSL_new(ctx)
#define TLS_setfd(s,fd) SSL_set_fd(s,fd)