diff --git a/trunk/src/rtmp/srs_protocol_handshake.cpp b/trunk/src/rtmp/srs_protocol_handshake.cpp index a26ce2fa0..807208c99 100644 --- a/trunk/src/rtmp/srs_protocol_handshake.cpp +++ b/trunk/src/rtmp/srs_protocol_handshake.cpp @@ -515,184 +515,29 @@ namespace _srs_internal } } - void __srs_time_copy_to(char*& pp, int32_t time) - { - // 4bytes time - __srs_stream_write_4bytes(pp, time); - pp += 4; - } - void __srs_version_copy_to(char*& pp, int32_t version) - { - // 4bytes version - __srs_stream_write_4bytes(pp, version); - pp += 4; - } - void __srs_key_copy_to(char*& pp, key_block* key) - { - // 764bytes key block - if (key->random0_size > 0) { - memcpy(pp, key->random0, key->random0_size); - } - pp += key->random0_size; - - memcpy(pp, key->key, sizeof(key->key)); - pp += sizeof(key->key); - - if (key->random1_size > 0) { - memcpy(pp, key->random1, key->random1_size); - } - pp += key->random1_size; - - __srs_stream_write_4bytes(pp, key->offset); - pp += 4; - } - void __srs_digest_copy_to(char*& pp, digest_block* digest, bool with_digest) - { - // 732bytes digest block without the 32bytes digest-data - // nbytes digest block part1 - __srs_stream_write_4bytes(pp, digest->offset); - pp += 4; - - // digest random padding. - if (digest->random0_size > 0) { - memcpy(pp, digest->random0, digest->random0_size); - } - pp += digest->random0_size; - - // digest - if (with_digest) { - memcpy(pp, digest->digest, 32); - pp += 32; - } - - // nbytes digest block part2 - if (digest->random1_size > 0) { - memcpy(pp, digest->random1, digest->random1_size); - } - pp += digest->random1_size; - } - - /** - * copy whole c1s1 to bytes. - */ - void srs_schema0_copy_to(char* bytes, bool with_digest, - int32_t time, int32_t version, key_block* key, digest_block* digest) - { - char* pp = bytes; - - __srs_time_copy_to(pp, time); - __srs_version_copy_to(pp, version); - __srs_key_copy_to(pp, key); - __srs_digest_copy_to(pp, digest, with_digest); - - if (with_digest) { - srs_assert(pp - bytes == 1536); - } else { - srs_assert(pp - bytes == 1536 - 32); - } - } - void srs_schema1_copy_to(char* bytes, bool with_digest, - int32_t time, int32_t version, digest_block* digest, key_block* key) - { - char* pp = bytes; - - __srs_time_copy_to(pp, time); - __srs_version_copy_to(pp, version); - __srs_digest_copy_to(pp, digest, with_digest); - __srs_key_copy_to(pp, key); - - if (with_digest) { - srs_assert(pp - bytes == 1536); - } else { - srs_assert(pp - bytes == 1536 - 32); - } - } - - /** - * c1s1 is splited by digest: - * c1s1-part1: n bytes (time, version, key and digest-part1). - * digest-data: 32bytes - * c1s1-part2: (1536-n-32)bytes (digest-part2) - */ - char* srs_bytes_join_schema0(int32_t time, int32_t version, key_block* key, digest_block* digest) - { - char* bytes = new char[1536 -32]; - - srs_schema0_copy_to(bytes, false, time, version, key, digest); - - return bytes; - } - - /** - * c1s1 is splited by digest: - * c1s1-part1: n bytes (time, version and digest-part1). - * digest-data: 32bytes - * c1s1-part2: (1536-n-32)bytes (digest-part2 and key) - */ - char* srs_bytes_join_schema1(int32_t time, int32_t version, digest_block* digest, key_block* key) - { - char* bytes = new char[1536 -32]; - - srs_schema1_copy_to(bytes, false, time, version, digest, key); - - return bytes; - } - c1s1_strategy::c1s1_strategy() - { - } - - c1s1_strategy::~c1s1_strategy() - { - } - - c1s1_strategy_schema0::c1s1_strategy_schema0() { key.init(); digest.init(); } - c1s1_strategy_schema0::~c1s1_strategy_schema0() + c1s1_strategy::~c1s1_strategy() { key.free(); digest.free(); } - srs_schema_type c1s1_strategy_schema0::schema() - { - return srs_schema0; - } - - char* c1s1_strategy_schema0::get_digest() + char* c1s1_strategy::get_digest() { return digest.digest; } - void c1s1_strategy_schema0::dump(c1s1* owner, char* _c1s1) + void c1s1_strategy::dump(c1s1* owner, char* _c1s1) { - srs_schema0_copy_to(_c1s1, true, owner->time, owner->version, &key, &digest); + copy_to(owner, _c1s1, true); } - int c1s1_strategy_schema0::parse(char* _c1s1) - { - int ret = ERROR_SUCCESS; - - if ((ret = key.parse(_c1s1 + 8)) != ERROR_SUCCESS) { - srs_error("parse the c1 key failed. ret=%d", ret); - return ret; - } - - if ((ret = digest.parse(_c1s1 + 8 + 764)) != ERROR_SUCCESS) { - srs_error("parse the c1 digest failed. ret=%d", ret); - return ret; - } - - srs_verbose("parse c1 key-digest success"); - - return ret; - } - - int c1s1_strategy_schema0::c1_create(c1s1* owner) + int c1s1_strategy::c1_create(c1s1* owner) { int ret = ERROR_SUCCESS; @@ -712,7 +557,7 @@ namespace _srs_internal return ret; } - int c1s1_strategy_schema0::c1_validate_digest(c1s1* owner, bool& is_valid) + int c1s1_strategy::c1_validate_digest(c1s1* owner, bool& is_valid) { int ret = ERROR_SUCCESS; @@ -731,7 +576,7 @@ namespace _srs_internal return ret; } - int c1s1_strategy_schema0::s1_create(c1s1* owner) + int c1s1_strategy::s1_create(c1s1* owner) { int ret = ERROR_SUCCESS; @@ -769,7 +614,7 @@ namespace _srs_internal return ret; } - int c1s1_strategy_schema0::s1_validate_digest(c1s1* owner, bool& is_valid) + int c1s1_strategy::s1_validate_digest(c1s1* owner, bool& is_valid) { int ret = ERROR_SUCCESS; @@ -788,16 +633,20 @@ namespace _srs_internal return ret; } - int c1s1_strategy_schema0::calc_c1_digest(c1s1* owner, char*& c1_digest) + int c1s1_strategy::calc_c1_digest(c1s1* owner, char*& c1_digest) { int ret = ERROR_SUCCESS; - char* c1s1_joined_bytes = NULL; - - c1s1_joined_bytes = srs_bytes_join_schema0(owner->time, owner->version, &key, &digest); - - srs_assert(c1s1_joined_bytes != NULL); + /** + * c1s1 is splited by digest: + * c1s1-part1: n bytes (time, version, key and digest-part1). + * digest-data: 32bytes + * c1s1-part2: (1536-n-32)bytes (digest-part2) + * @return a new allocated bytes, user must free it. + */ + char* c1s1_joined_bytes = new char[1536 -32]; SrsAutoFree(char, c1s1_joined_bytes); + copy_to(owner, c1s1_joined_bytes, false); c1_digest = new char[__SRS_OpensslHashSize]; if ((ret = openssl_HMACsha256(SrsGenuineFPKey, 30, c1s1_joined_bytes, 1536 - 32, c1_digest)) != ERROR_SUCCESS) { @@ -810,16 +659,20 @@ namespace _srs_internal return ret; } - int c1s1_strategy_schema0::calc_s1_digest(c1s1* owner, char*& s1_digest) + int c1s1_strategy::calc_s1_digest(c1s1* owner, char*& s1_digest) { int ret = ERROR_SUCCESS; - - char* c1s1_joined_bytes = NULL; - - c1s1_joined_bytes = srs_bytes_join_schema0(owner->time, owner->version, &key, &digest); - - srs_assert(c1s1_joined_bytes != NULL); + + /** + * c1s1 is splited by digest: + * c1s1-part1: n bytes (time, version, key and digest-part1). + * digest-data: 32bytes + * c1s1-part2: (1536-n-32)bytes (digest-part2) + * @return a new allocated bytes, user must free it. + */ + char* c1s1_joined_bytes = new char[1536 -32]; SrsAutoFree(char, c1s1_joined_bytes); + copy_to(owner, c1s1_joined_bytes, false); s1_digest = new char[__SRS_OpensslHashSize]; if ((ret = openssl_HMACsha256(SrsGenuineFMSKey, 36, c1s1_joined_bytes, 1536 - 32, s1_digest)) != ERROR_SUCCESS) { @@ -832,16 +685,113 @@ namespace _srs_internal return ret; } + void c1s1_strategy::copy_time_version(char*& pp, c1s1* owner) + { + // 4bytes time + __srs_stream_write_4bytes(pp, owner->time); + pp += 4; + // 4bytes version + __srs_stream_write_4bytes(pp, owner->version); + pp += 4; + } + void c1s1_strategy::copy_key(char*& pp) + { + // 764bytes key block + if (key.random0_size > 0) { + memcpy(pp, key.random0, key.random0_size); + } + pp += key.random0_size; + + memcpy(pp, key.key, sizeof(key.key)); + pp += sizeof(key.key); + + if (key.random1_size > 0) { + memcpy(pp, key.random1, key.random1_size); + } + pp += key.random1_size; + + __srs_stream_write_4bytes(pp, key.offset); + pp += 4; + } + void c1s1_strategy::digest_key(char*& pp, bool with_digest) + { + // 732bytes digest block without the 32bytes digest-data + // nbytes digest block part1 + __srs_stream_write_4bytes(pp, digest.offset); + pp += 4; + + // digest random padding. + if (digest.random0_size > 0) { + memcpy(pp, digest.random0, digest.random0_size); + } + pp += digest.random0_size; + + // digest + if (with_digest) { + memcpy(pp, digest.digest, 32); + pp += 32; + } + + // nbytes digest block part2 + if (digest.random1_size > 0) { + memcpy(pp, digest.random1, digest.random1_size); + } + pp += digest.random1_size; + } + + c1s1_strategy_schema0::c1s1_strategy_schema0() + { + } + + c1s1_strategy_schema0::~c1s1_strategy_schema0() + { + } + + srs_schema_type c1s1_strategy_schema0::schema() + { + return srs_schema0; + } + + int c1s1_strategy_schema0::parse(char* _c1s1) + { + int ret = ERROR_SUCCESS; + + if ((ret = key.parse(_c1s1 + 8)) != ERROR_SUCCESS) { + srs_error("parse the c1 key failed. ret=%d", ret); + return ret; + } + + if ((ret = digest.parse(_c1s1 + 8 + 764)) != ERROR_SUCCESS) { + srs_error("parse the c1 digest failed. ret=%d", ret); + return ret; + } + + srs_verbose("parse c1 key-digest success"); + + return ret; + } + + void c1s1_strategy_schema0::copy_to(c1s1* owner, char* bytes, bool with_digest) + { + char* pp = bytes; + + copy_time_version(pp, owner); + copy_key(pp); + digest_key(pp, with_digest); + + if (with_digest) { + srs_assert(pp - bytes == 1536); + } else { + srs_assert(pp - bytes == 1536 - 32); + } + } + c1s1_strategy_schema1::c1s1_strategy_schema1() { - key.init(); - digest.init(); } c1s1_strategy_schema1::~c1s1_strategy_schema1() { - key.free(); - digest.free(); } srs_schema_type c1s1_strategy_schema1::schema() @@ -849,16 +799,6 @@ namespace _srs_internal return srs_schema1; } - char* c1s1_strategy_schema1::get_digest() - { - return digest.digest; - } - - void c1s1_strategy_schema1::dump(c1s1* owner, char* _c1s1) - { - srs_schema0_copy_to(_c1s1, true, owner->time, owner->version, &key, &digest); - } - int c1s1_strategy_schema1::parse(char* _c1s1) { int ret = ERROR_SUCCESS; @@ -878,143 +818,19 @@ namespace _srs_internal return ret; } - int c1s1_strategy_schema1::c1_create(c1s1* owner) + void c1s1_strategy_schema1::copy_to(c1s1* owner, char* bytes, bool with_digest) { - int ret = ERROR_SUCCESS; - - // generate digest - char* c1_digest = NULL; - - if ((ret = calc_c1_digest(owner, c1_digest)) != ERROR_SUCCESS) { - srs_error("sign c1 error, failed to calc digest. ret=%d", ret); - return ret; - } - - srs_assert(c1_digest != NULL); - SrsAutoFree(char, c1_digest); - - memcpy(digest.digest, c1_digest, 32); - - return ret; - } + char* pp = bytes; - int c1s1_strategy_schema1::c1_validate_digest(c1s1* owner, bool& is_valid) - { - int ret = ERROR_SUCCESS; + copy_time_version(pp, owner); + digest_key(pp, with_digest); + copy_key(pp); - char* c1_digest = NULL; - - if ((ret = calc_c1_digest(owner, c1_digest)) != ERROR_SUCCESS) { - srs_error("validate c1 error, failed to calc digest. ret=%d", ret); - return ret; + if (with_digest) { + srs_assert(pp - bytes == 1536); + } else { + srs_assert(pp - bytes == 1536 - 32); } - - srs_assert(c1_digest != NULL); - SrsAutoFree(char, c1_digest); - - is_valid = srs_bytes_equals(digest.digest, c1_digest, 32); - - return ret; - } - - int c1s1_strategy_schema1::s1_create(c1s1* owner) - { - int ret = ERROR_SUCCESS; - - SrsDH dh; - - // ensure generate 128bytes public key. - if ((ret = dh.initialize(true)) != ERROR_SUCCESS) { - return ret; - } - - // directly generate the public key. - // @see: https://github.com/winlinvip/simple-rtmp-server/issues/148 - int pkey_size = 128; - if ((ret = dh.copy_public_key(key.key, pkey_size)) != ERROR_SUCCESS) { - srs_error("calc s1 key failed. ret=%d", ret); - return ret; - } - srs_assert(pkey_size == 128); - srs_verbose("calc s1 key success."); - - char* s1_digest = NULL; - if ((ret = calc_s1_digest(owner, s1_digest)) != ERROR_SUCCESS) { - srs_error("calc s1 digest failed. ret=%d", ret); - return ret; - } - srs_verbose("calc s1 digest success."); - - srs_assert(s1_digest != NULL); - SrsAutoFree(char, s1_digest); - - memcpy(digest.digest, s1_digest, 32); - srs_verbose("copy s1 key success."); - - return ret; - } - - int c1s1_strategy_schema1::s1_validate_digest(c1s1* owner, bool& is_valid) - { - int ret = ERROR_SUCCESS; - - char* s1_digest = NULL; - - if ((ret = calc_s1_digest(owner, s1_digest)) != ERROR_SUCCESS) { - srs_error("validate s1 error, failed to calc digest. ret=%d", ret); - return ret; - } - - srs_assert(s1_digest != NULL); - SrsAutoFree(char, s1_digest); - - is_valid = srs_bytes_equals(digest.digest, s1_digest, 32); - - return ret; - } - - int c1s1_strategy_schema1::calc_c1_digest(c1s1* owner, char*& c1_digest) - { - int ret = ERROR_SUCCESS; - - char* c1s1_joined_bytes = NULL; - - c1s1_joined_bytes = srs_bytes_join_schema1(owner->time, owner->version, &digest, &key); - - srs_assert(c1s1_joined_bytes != NULL); - SrsAutoFree(char, c1s1_joined_bytes); - - c1_digest = new char[__SRS_OpensslHashSize]; - if ((ret = openssl_HMACsha256(SrsGenuineFPKey, 30, c1s1_joined_bytes, 1536 - 32, c1_digest)) != ERROR_SUCCESS) { - srs_freep(c1_digest); - srs_error("calc digest for c1 failed. ret=%d", ret); - return ret; - } - srs_verbose("digest calculated for c1"); - - return ret; - } - - int c1s1_strategy_schema1::calc_s1_digest(c1s1* owner, char*& s1_digest) - { - int ret = ERROR_SUCCESS; - - char* c1s1_joined_bytes = NULL; - - c1s1_joined_bytes = srs_bytes_join_schema1(owner->time, owner->version, &digest, &key); - - srs_assert(c1s1_joined_bytes != NULL); - SrsAutoFree(char, c1s1_joined_bytes); - - s1_digest = new char[__SRS_OpensslHashSize]; - if ((ret = openssl_HMACsha256(SrsGenuineFMSKey, 36, c1s1_joined_bytes, 1536 - 32, s1_digest)) != ERROR_SUCCESS) { - srs_freep(s1_digest); - srs_error("calc digest for s1 failed. ret=%d", ret); - return ret; - } - srs_verbose("digest calculated for s1"); - - return ret; } c2s2::c2s2() diff --git a/trunk/src/rtmp/srs_protocol_handshake.hpp b/trunk/src/rtmp/srs_protocol_handshake.hpp index ad72486bf..871723298 100644 --- a/trunk/src/rtmp/srs_protocol_handshake.hpp +++ b/trunk/src/rtmp/srs_protocol_handshake.hpp @@ -193,32 +193,6 @@ namespace _srs_internal void free(); }; - /** - * copy whole c1s1 to bytes. - */ - void srs_schema0_copy_to(char* bytes, bool with_digest, - int32_t time, int32_t version, key_block* key, digest_block* digest); - void srs_schema1_copy_to(char* bytes, bool with_digest, - int32_t time, int32_t version, digest_block* digest, key_block* key); - - /** - * c1s1 is splited by digest: - * c1s1-part1: n bytes (time, version, key and digest-part1). - * digest-data: 32bytes - * c1s1-part2: (1536-n-32)bytes (digest-part2) - * @return a new allocated bytes, user must free it. - */ - char* srs_bytes_join_schema0(int32_t time, int32_t version, key_block* key, digest_block* digest); - - /** - * c1s1 is splited by digest: - * c1s1-part1: n bytes (time, version and digest-part1). - * digest-data: 32bytes - * c1s1-part2: (1536-n-32)bytes (digest-part2 and key) - * @return a new allocated bytes, user must free it. - */ - char* srs_bytes_join_schema1(int32_t time, int32_t version, digest_block* digest, key_block* key); - class c1s1; /** @@ -228,6 +202,9 @@ namespace _srs_internal */ class c1s1_strategy { + protected: + key_block key; + digest_block digest; public: c1s1_strategy(); virtual ~c1s1_strategy(); @@ -239,11 +216,11 @@ namespace _srs_internal /** * get the digest key. */ - virtual char* get_digest() = 0; + virtual char* get_digest(); /** * copy to bytes. */ - virtual void dump(c1s1* owner, char* _c1s1) = 0; + virtual void dump(c1s1* owner, char* _c1s1); /** * server: parse the c1s1, discovery the key and digest by schema. * use the c1_validate_digest() to valid the digest of c1. @@ -265,19 +242,29 @@ namespace _srs_internal * digest-data = calc_c1_digest(c1, schema) * copy digest-data to c1 */ - virtual int c1_create(c1s1* owner) = 0; + virtual int c1_create(c1s1* owner); /** * server: validate the parsed c1 schema */ - virtual int c1_validate_digest(c1s1* owner, bool& is_valid) = 0; + virtual int c1_validate_digest(c1s1* owner, bool& is_valid); /** * server: create and sign the s1 from c1. */ - virtual int s1_create(c1s1* owner) = 0; + virtual int s1_create(c1s1* owner); /** * server: validate the parsed s1 schema */ - virtual int s1_validate_digest(c1s1* owner, bool& is_valid) = 0; + virtual int s1_validate_digest(c1s1* owner, bool& is_valid); + protected: + virtual int calc_c1_digest(c1s1* owner, char*& c1_digest); + virtual int calc_s1_digest(c1s1* owner, char*& s1_digest); + /** + * copy whole c1s1 to bytes. + */ + virtual void copy_to(c1s1* owner, char* bytes, bool with_digest) = 0; + virtual void copy_time_version(char*& pp, c1s1* owner); + virtual void copy_key(char*& pp); + virtual void digest_key(char*& pp, bool with_digest); }; /** @@ -287,24 +274,17 @@ namespace _srs_internal */ class c1s1_strategy_schema0 : public c1s1_strategy { - private: - key_block key; - digest_block digest; public: c1s1_strategy_schema0(); virtual ~c1s1_strategy_schema0(); public: virtual srs_schema_type schema(); - virtual char* get_digest(); - virtual void dump(c1s1* owner, char* _c1s1); virtual int parse(char* _c1s1); - virtual int c1_create(c1s1* owner); - virtual int c1_validate_digest(c1s1* owner, bool& is_valid); - virtual int s1_create(c1s1* owner); - virtual int s1_validate_digest(c1s1* owner, bool& is_valid); private: - virtual int calc_c1_digest(c1s1* owner, char*& c1_digest); - virtual int calc_s1_digest(c1s1* owner, char*& s1_digest); + /** + * copy whole c1s1 to bytes. + */ + virtual void copy_to(c1s1* owner, char* bytes, bool with_digest); }; /** @@ -314,24 +294,17 @@ namespace _srs_internal */ class c1s1_strategy_schema1 : public c1s1_strategy { - private: - digest_block digest; - key_block key; public: c1s1_strategy_schema1(); virtual ~c1s1_strategy_schema1(); public: virtual srs_schema_type schema(); - virtual char* get_digest(); - virtual void dump(c1s1* owner, char* _c1s1); virtual int parse(char* _c1s1); - virtual int c1_create(c1s1* owner); - virtual int c1_validate_digest(c1s1* owner, bool& is_valid); - virtual int s1_create(c1s1* owner); - virtual int s1_validate_digest(c1s1* owner, bool& is_valid); private: - virtual int calc_c1_digest(c1s1* owner, char*& c1_digest); - virtual int calc_s1_digest(c1s1* owner, char*& s1_digest); + /** + * copy whole c1s1 to bytes. + */ + virtual void copy_to(c1s1* owner, char* bytes, bool with_digest); }; /** @@ -356,9 +329,10 @@ namespace _srs_internal int32_t version; // 764bytes+764bytes c1s1_strategy* payload; - + public: c1s1(); virtual ~c1s1(); + public: /** * get the scema. */ @@ -367,6 +341,7 @@ namespace _srs_internal * get the digest key. */ virtual char* get_digest(); + public: /** * copy to bytes. */ @@ -377,7 +352,7 @@ namespace _srs_internal * use the s1_validate_digest() to valid the digest of s1. */ virtual int parse(char* _c1s1, srs_schema_type _schema); - + public: /** * client: create and sign c1 by schema. * sign the c1, generate the digest. @@ -398,6 +373,7 @@ namespace _srs_internal * server: validate the parsed c1 schema */ virtual int c1_validate_digest(bool& is_valid); + public: /** * server: create and sign the s1 from c1. * // decode c1 try schema0 then schema1 @@ -442,10 +418,10 @@ namespace _srs_internal public: char random[1504]; char digest[32]; - + public: c2s2(); virtual ~c2s2(); - + public: /** * copy to bytes. */ @@ -454,7 +430,7 @@ namespace _srs_internal * parse the c2s2 */ virtual void parse(char* _c2s2); - + public: /** * create c2. * random fill c2s2 1536 bytes @@ -469,7 +445,7 @@ namespace _srs_internal * validate the c2 from client. */ virtual int c2_validate(c1s1* s1, bool& is_valid); - + public: /** * create s2. * random fill c2s2 1536 bytes