1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

for bug #235, refine schema0 and schema1, extract dup code.

This commit is contained in:
winlin 2014-11-29 17:04:24 +08:00
parent 4b9875e279
commit 646d6f6673
2 changed files with 175 additions and 383 deletions

View file

@ -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()

View file

@ -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