diff --git a/trunk/3rdparty/openssl-1.0.1f.zip b/trunk/3rdparty/openssl-1.0.1f.zip deleted file mode 100644 index edcde9dcd..000000000 Binary files a/trunk/3rdparty/openssl-1.0.1f.zip and /dev/null differ diff --git a/trunk/3rdparty/openssl-1.1.0e.zip b/trunk/3rdparty/openssl-1.1.0e.zip new file mode 100644 index 000000000..1361d91cc Binary files /dev/null and b/trunk/3rdparty/openssl-1.1.0e.zip differ diff --git a/trunk/3rdparty/readme.txt b/trunk/3rdparty/readme.txt index 64e5dbe03..ca54471f2 100644 --- a/trunk/3rdparty/readme.txt +++ b/trunk/3rdparty/readme.txt @@ -7,7 +7,7 @@ nginx-1.5.7.zip st-1.9.zip basic framework for srs. -openssl-1.0.1f.zip +openssl-1.1.0e.zip openssl for SRS(with-ssl) RTMP complex handshake to delivery h264+aac stream. CherryPy-3.2.4.zip @@ -60,7 +60,7 @@ links: https://pypi.python.org/pypi/CherryPy/3.2.4 openssl: http://www.openssl.org/ - http://www.openssl.org/source/openssl-1.0.1f.tar.gz + http://www.openssl.org/source/openssl-1.1.0e.tar.gz gtest: https://code.google.com/p/googletest https://code.google.com/p/googletest/downloads/list diff --git a/trunk/auto/depends.sh b/trunk/auto/depends.sh index 9e1f4ff21..8693fde45 100755 --- a/trunk/auto/depends.sh +++ b/trunk/auto/depends.sh @@ -609,7 +609,7 @@ if [ $SRS_OSX = YES ]; then fi OPENSSL_HOTFIX="-DOPENSSL_NO_HEARTBEATS" # @see http://www.openssl.org/news/secadv/20140407.txt -# Affected users should upgrade to OpenSSL 1.0.1g. Users unable to immediately +# Affected users should upgrade to OpenSSL 1.1.0e. Users unable to immediately # upgrade can alternatively recompile OpenSSL with -DOPENSSL_NO_HEARTBEATS. if [ $SRS_SSL = YES ]; then if [ $SRS_USE_SYS_SSL = YES ]; then @@ -619,39 +619,39 @@ if [ $SRS_SSL = YES ]; then if [ $SRS_CROSS_BUILD = YES ]; then # ok, arm specified, if the flag filed does not exists, need to rebuild. if [[ -f ${SRS_OBJS}/_flag.ssl.cross.build.tmp && -f ${SRS_OBJS}/openssl/lib/libssl.a ]]; then - echo "The openssl-1.0.1f for arm is ok."; + echo "The openssl-1.1.0e for arm is ok."; else - echo "Building openssl-1.0.1f for ARM."; + echo "Building openssl-1.1.0e for ARM."; ( - rm -rf ${SRS_OBJS}/openssl-1.0.1f && cd ${SRS_OBJS} && - unzip -q ../3rdparty/openssl-1.0.1f.zip && cd openssl-1.0.1f && + rm -rf ${SRS_OBJS}/openssl-1.1.0e && cd ${SRS_OBJS} && + unzip -q ../3rdparty/openssl-1.1.0e.zip && cd openssl-1.1.0e && $CONFIGURE_TOOL --prefix=`pwd`/_release -no-shared no-asm $OPENSSL_HOTFIX && make CC=${SrsArmCC} GCC=${SrsArmGCC} AR="${SrsArmAR} r" \ LD=${SrsArmLD} LINK=${SrsArmGCC} RANDLIB=${SrsArmRANDLIB} && make install_sw && - cd .. && rm -rf openssl && ln -sf openssl-1.0.1f/_release openssl && + cd .. && rm -rf openssl && ln -sf openssl-1.1.0e/_release openssl && cd .. && touch ${SRS_OBJS}/_flag.ssl.cross.build.tmp ) fi else # cross build not specified, if exists flag, need to rebuild for no-arm platform. if [[ ! -f ${SRS_OBJS}/_flag.ssl.cross.build.tmp && -f ${SRS_OBJS}/openssl/lib/libssl.a ]]; then - echo "Openssl-1.0.1f is ok."; + echo "Openssl-1.1.0e is ok."; else - echo "Building openssl-1.0.1f."; + echo "Building openssl-1.1.0e."; ( - rm -rf ${SRS_OBJS}/openssl-1.0.1f && cd ${SRS_OBJS} && - unzip -q ../3rdparty/openssl-1.0.1f.zip && cd openssl-1.0.1f && + rm -rf ${SRS_OBJS}/openssl-1.1.0e && cd ${SRS_OBJS} && + unzip -q ../3rdparty/openssl-1.1.0e.zip && cd openssl-1.1.0e && $CONFIGURE_TOOL --prefix=`pwd`/_release -no-shared $OPENSSL_HOTFIX && make && make install_sw && - cd .. && rm -rf openssl && ln -sf openssl-1.0.1f/_release openssl && + cd .. && rm -rf openssl && ln -sf openssl-1.1.0e/_release openssl && cd .. && rm -f ${SRS_OBJS}/_flag.ssl.cross.build.tmp ) fi fi # check status - ret=$?; if [[ $ret -ne 0 ]]; then echo "Build openssl-1.0.1f failed, ret=$ret"; exit $ret; fi - if [ ! -f ${SRS_OBJS}/openssl/lib/libssl.a ]; then echo "Build openssl-1.0.1f failed."; exit -1; fi + ret=$?; if [[ $ret -ne 0 ]]; then echo "Build openssl-1.1.0e failed, ret=$ret"; exit $ret; fi + if [ ! -f ${SRS_OBJS}/openssl/lib/libssl.a ]; then echo "Build openssl-1.1.0e failed."; exit -1; fi fi fi diff --git a/trunk/configure b/trunk/configure index df8d863d7..3f6f16a57 100755 --- a/trunk/configure +++ b/trunk/configure @@ -122,7 +122,7 @@ END # # st(state-threads) the basic network library for SRS. LibSTRoot="${SRS_OBJS_DIR}/st"; LibSTfile="${LibSTRoot}/libst.a" -# openssl-1.0.1f, for the RTMP complex handshake. +# openssl-1.1.0e, for the RTMP complex handshake. LibSSLRoot="";LibSSLfile="" if [ $SRS_SSL = YES ]; then if [ $SRS_USE_SYS_SSL = NO ]; then LibSSLRoot="${SRS_OBJS_DIR}/openssl/include"; LibSSLfile="${SRS_OBJS_DIR}/openssl/lib/libssl.a ${SRS_OBJS_DIR}/openssl/lib/libcrypto.a"; fi fi # gperftools-2.1, for mem check and mem/cpu profile @@ -130,7 +130,7 @@ LibGperfRoot=""; LibGperfFile="" if [ $SRS_GPERF = YES ]; then LibGperfRoot="${SRS_OBJS_DIR}/gperf/include"; LibGperfFile="${SRS_OBJS_DIR}/gperf/lib/libtcmalloc_and_profiler.a"; fi if [ $SRS_GPERF_MD = YES ]; then LibGperfFile="${SRS_OBJS_DIR}/gperf/lib/libtcmalloc_debug.a"; fi # the link options, always use static link -SrsLinkOptions="-ldl"; +SrsLinkOptions="-lpthread -ldl"; if [ $SRS_SSL = YES ]; then if [ $SRS_USE_SYS_SSL = YES ]; then SrsLinkOptions="${SrsLinkOptions} -lssl -lcrypto"; fi fi # if static specified, add static # TODO: FIXME: remove static. diff --git a/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj b/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj index e404ce5ab..4f62b8eaf 100644 --- a/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj +++ b/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj @@ -296,8 +296,8 @@ 3C1232D01AAE833300CE8F6C /* stop.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = stop.sh; path = ../../../scripts/stop.sh; sourceTree = ""; }; 3C1232D11AAE833300CE8F6C /* test_configure.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = test_configure.sh; path = ../../../scripts/test_configure.sh; sourceTree = ""; }; 3C1232D21AAEA56B00CE8F6C /* libst.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libst.a; path = "../../objs/st-1.9/DARWIN_14.0.0_DBG/libst.a"; sourceTree = ""; }; - 3C1232E71AAEA5D000CE8F6C /* libcrypto.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcrypto.a; path = "../../objs/openssl-1.0.1f/_release/lib/libcrypto.a"; sourceTree = ""; }; - 3C1232E81AAEA5D000CE8F6C /* libssl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libssl.a; path = "../../objs/openssl-1.0.1f/_release/lib/libssl.a"; sourceTree = ""; }; + 3C1232E71AAEA5D000CE8F6C /* libcrypto.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcrypto.a; path = "../../objs/openssl-1.1.0e/_release/lib/libcrypto.a"; sourceTree = ""; }; + 3C1232E81AAEA5D000CE8F6C /* libssl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libssl.a; path = "../../objs/openssl-1.1.0e/_release/lib/libssl.a"; sourceTree = ""; }; 3C1232EC1AAEA70F00CE8F6C /* libhttp_parser.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libhttp_parser.a; path = "../../objs/http-parser-2.1/libhttp_parser.a"; sourceTree = ""; }; 3C1232F11AAEAC7000CE8F6C /* srs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = srs; path = ../../../etc/init.d/srs; sourceTree = ""; }; 3C1232F21AAEAC7000CE8F6C /* srs-api */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = "srs-api"; path = "../../../etc/init.d/srs-api"; sourceTree = ""; }; diff --git a/trunk/research/librtmp/Makefile b/trunk/research/librtmp/Makefile index 6bdcf976e..e204bf8f4 100755 --- a/trunk/research/librtmp/Makefile +++ b/trunk/research/librtmp/Makefile @@ -69,7 +69,7 @@ ifeq ($(GCC), mipsel-openwrt-linux-gcc) endif # for ssl or nossl ifeq ($(HANDSHAKE), SSL) - SRS_LIBSSL_L = $(SRS_OBJS)/openssl/lib/libssl.a $(SRS_OBJS)/openssl/lib/libcrypto.a + SRS_LIBSSL_L = $(SRS_OBJS)/openssl/lib/libssl.a $(SRS_OBJS)/openssl/lib/libcrypto.a -lpthread endif ifneq ($(shell test -f $(SRS_OBJS)/openssl/lib/libssl.a && echo yes), yes) SRS_LIBSSL_L = -lssl -lcrypto diff --git a/trunk/src/kernel/srs_kernel_error.hpp b/trunk/src/kernel/srs_kernel_error.hpp index 03381af1f..d02bde8bc 100644 --- a/trunk/src/kernel/srs_kernel_error.hpp +++ b/trunk/src/kernel/srs_kernel_error.hpp @@ -159,6 +159,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define ERROR_RTSP_AUDIO_CONFIG 2047 #define ERROR_RTMP_STREAM_NOT_FOUND 2048 #define ERROR_RTMP_CLIENT_NOT_FOUND 2049 +#define ERROR_OpenSslCreateHMAC 2050 // // system control message, // not an error, but special control logic. diff --git a/trunk/src/protocol/srs_rtmp_handshake.cpp b/trunk/src/protocol/srs_rtmp_handshake.cpp index bb0a81bf5..76f006c63 100644 --- a/trunk/src/protocol/srs_rtmp_handshake.cpp +++ b/trunk/src/protocol/srs_rtmp_handshake.cpp @@ -44,6 +44,66 @@ using namespace _srs_internal; // for openssl_generate_key #include +#if OPENSSL_VERSION_NUMBER < 0x10100000L +static HMAC_CTX *HMAC_CTX_new(void) +{ + HMAC_CTX *ctx = (HMAC_CTX *)malloc(sizeof(*ctx)); + if (ctx != NULL) + HMAC_CTX_init(ctx); + return ctx; +} +static void HMAC_CTX_free(HMAC_CTX *ctx) +{ + if (ctx != NULL) { + HMAC_CTX_cleanup(ctx); + free(ctx); + } +} + +static void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) +{ + if (pub_key != NULL) + *pub_key = dh->pub_key; + if (priv_key != NULL) + *priv_key = dh->priv_key; +} + +static int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + /* If the fields p and g in d are NULL, the corresponding input + * parameters MUST be non-NULL. q may remain NULL. + */ + if ((dh->p == NULL && p == NULL) + || (dh->g == NULL && g == NULL)) + return 0; + + if (p != NULL) { + BN_free(dh->p); + dh->p = p; + } + if (q != NULL) { + BN_free(dh->q); + dh->q = q; + } + if (g != NULL) { + BN_free(dh->g); + dh->g = g; + } + + if (q != NULL) { + dh->length = BN_num_bits(q); + } + + return 1; +} + +static int DH_set_length(DH *dh, long length) +{ + dh->length = length; + return 1; +} +#endif + namespace _srs_internal { // 68bytes FMS key which is used to sign the sever packet. @@ -112,18 +172,21 @@ namespace _srs_internal } } else { // use key-data to digest. - HMAC_CTX ctx; - + HMAC_CTX *ctx = HMAC_CTX_new(); + if (ctx == NULL) { + ret = ERROR_OpenSslCreateHMAC; + return ret; + } // @remark, if no key, use EVP_Digest to digest, // for instance, in python, hashlib.sha256(data).digest(). - HMAC_CTX_init(&ctx); - if (HMAC_Init_ex(&ctx, temp_key, key_size, EVP_sha256(), NULL) < 0) { + if (HMAC_Init_ex(ctx, temp_key, key_size, EVP_sha256(), NULL) < 0) { ret = ERROR_OpenSslSha256Init; + HMAC_CTX_free(ctx); return ret; } - ret = do_openssl_HMACsha256(&ctx, data, data_size, temp_digest, &digest_size); - HMAC_CTX_cleanup(&ctx); + ret = do_openssl_HMACsha256(ctx, data, data_size, temp_digest, &digest_size); + HMAC_CTX_free(ctx); if (ret != ERROR_SUCCESS) { return ret; @@ -159,14 +222,6 @@ namespace _srs_internal void SrsDH::close() { if (pdh != NULL) { - if (pdh->p != NULL) { - BN_free(pdh->p); - pdh->p = NULL; - } - if (pdh->g != NULL) { - BN_free(pdh->g); - pdh->g = NULL; - } DH_free(pdh); pdh = NULL; } @@ -182,7 +237,9 @@ namespace _srs_internal } if (ensure_128bytes_public_key) { - int32_t key_size = BN_num_bytes(pdh->pub_key); + const BIGNUM *pub_key = NULL; + DH_get0_key(pdh, &pub_key, NULL); + int32_t key_size = BN_num_bytes(pub_key); if (key_size != 128) { srs_warn("regenerate 128B key, current=%dB", key_size); continue; @@ -201,13 +258,15 @@ namespace _srs_internal // copy public key to bytes. // sometimes, the key_size is 127, seems ok. - int32_t key_size = BN_num_bytes(pdh->pub_key); + const BIGNUM *pub_key = NULL; + DH_get0_key(pdh, &pub_key, NULL); + int32_t key_size = BN_num_bytes(pub_key); srs_assert(key_size > 0); // maybe the key_size is 127, but dh will write all 128bytes pkey, // so, donot need to set/initialize the pkey. // @see https://github.com/ossrs/srs/issues/165 - key_size = BN_bn2bin(pdh->pub_key, (unsigned char*)pkey); + key_size = BN_bn2bin(pub_key, (unsigned char*)pkey); srs_assert(key_size > 0); // output the size of public key. @@ -266,28 +325,31 @@ namespace _srs_internal } //2. Create his internal p and g - if ((pdh->p = BN_new()) == NULL) { + BIGNUM *p, *g; + if ((p = BN_new()) == NULL) { ret = ERROR_OpenSslCreateP; return ret; } - if ((pdh->g = BN_new()) == NULL) { + if ((g = BN_new()) == NULL) { ret = ERROR_OpenSslCreateG; + BN_free(p); return ret; } - + DH_set0_pqg(pdh, p, NULL, g); + //3. initialize p and g, @see ./test/ectest.c:260 - if (!BN_hex2bn(&pdh->p, RFC2409_PRIME_1024)) { + if (!BN_hex2bn(&p, RFC2409_PRIME_1024)) { ret = ERROR_OpenSslParseP1024; return ret; } // @see ./test/bntest.c:1764 - if (!BN_set_word(pdh->g, 2)) { + if (!BN_set_word(g, 2)) { ret = ERROR_OpenSslSetG; return ret; } // 4. Set the key length - pdh->length = bits_count; + DH_set_length(pdh, bits_count); // 5. Generate private and public key // @see ./test/dhtest.c:152