int c1s1::calc_c1_digest(char *&digest) { int ret = ERROR_SUCCESS; mAssert(schema == srs_schema0 || schema == srs_schema1); char *c1s1_joined_bytes = NULL; if (schema == srs_schema0) { c1s1_joined_bytes = srs_bytes_join_schema0(time, version, &block0.key, &block1.digest); } else { c1s1_joined_bytes = srs_bytes_join_schema1(time, version, &block0.digest, &block1.key); } mAssert(c1s1_joined_bytes != NULL); mAutoFreeArray(char, c1s1_joined_bytes); digest = new char[OpensslHashSize]; if ((ret = openssl_HMACsha256(c1s1_joined_bytes, 1536 - 32, SrsGenuineFPKey, 30, digest)) != ERROR_SUCCESS) { log_error("calc digest for c1 failed. ret=%d", ret); return ret; } log_verbose("digest calculated for c1"); return ret; }
MAMF0Any *MAMFObject::value(int index) { mAssert(index < (int)values.size()); pair<MString, MAMF0Any *> &p = values.at(index); return p.second; }
MString MAMFObject::key(int index) { mAssert(index < (int)values.size()); pair<MString, MAMF0Any *> &p = values.at(index); return p.first; }
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) { mAssert(pp - bytes == 1536); } else { mAssert(pp - bytes == 1536 - 32); } }
// parse digest block from c1s1. // if created, user must free it by srs_digest_block_free // @c1s1_digest_bytes the digest start bytes, maybe c1s1 or c1s1+764 int srs_digest_block_parse(digest_block *digest, char *c1s1_digest_bytes) { int ret = ERROR_SUCCESS; char *pp = c1s1_digest_bytes; digest->offset = *(int32_t *)pp; pp += sizeof(int32_t); digest->random0 = NULL; digest->random1 = NULL; int offset = srs_digest_block_get_offset(digest); mAssert(offset >= 0); digest->random0_size = offset; if (digest->random0_size > 0) { digest->random0 = new char[digest->random0_size]; memcpy(digest->random0, pp, digest->random0_size); } pp += digest->random0_size; memcpy(digest->digest, pp, sizeof(digest->digest)); pp += sizeof(digest->digest); digest->random1_size = 764 - 4 - offset - 32; if (digest->random1_size > 0) { digest->random1 = new char[digest->random1_size]; memcpy(digest->random1, pp, digest->random1_size); } return ret; }
// parse key block from c1s1. // if created, user must free it by srs_key_block_free // @c1s1_key_bytes the key start bytes, maybe c1s1 or c1s1+764 int srs_key_block_parse(key_block *key, char *c1s1_key_bytes) { int ret = ERROR_SUCCESS; char *pp = c1s1_key_bytes + 764; pp -= sizeof(int32_t); key->offset = *(int32_t *)pp; key->random0 = NULL; key->random1 = NULL; int offset = srs_key_block_get_offset(key); mAssert(offset >= 0); pp = c1s1_key_bytes; key->random0_size = offset; if (key->random0_size > 0) { key->random0 = new char[key->random0_size]; memcpy(key->random0, pp, key->random0_size); } pp += key->random0_size; memcpy(key->key, pp, sizeof(key->key)); pp += sizeof(key->key); key->random1_size = 764 - offset - 128 - 4; if (key->random1_size > 0) { key->random1 = new char[key->random1_size]; memcpy(key->random1, pp, key->random1_size); } return ret; }
int c1s1::s1_create(c1s1* c1,u_int8_t *&shared_key) { int ret = ERROR_SUCCESS; if (c1->schema == srs_schema_invalid) { ret = ERROR_RTMP_CH_SCHEMA; log_error("create s1 failed. invalid schema=%d, ret=%d", c1->schema, ret); return ret; } destroy_blocks(); schema = c1->schema; time = ::time(NULL); version = 0x01000504; // server s1 version if (schema == srs_schema0) { srs_key_block_init(&block0.key); srs_digest_block_init(&block1.digest); } else { srs_digest_block_init(&block0.digest); srs_key_block_init(&block1.key); } if (schema == srs_schema0) { if ((ret = openssl_generate_key(c1->block0.key.key, block0.key.key, 128,shared_key)) != ERROR_SUCCESS) { log_error("calc s1 key failed. ret=%d", ret); return ret; } } else { if ((ret = openssl_generate_key(c1->block1.key.key, block1.key.key, 128,shared_key)) != ERROR_SUCCESS) { log_error("calc s1 key failed. ret=%d", ret); return ret; } } log_verbose("calc s1 key success."); char *s1_digest = NULL; if ((ret = calc_s1_digest(s1_digest)) != ERROR_SUCCESS) { log_error("calc s1 digest failed. ret=%d", ret); return ret; } log_verbose("calc s1 digest success."); mAssert(s1_digest != NULL); mAutoFreeArray(char, s1_digest); if (schema == srs_schema0) { memcpy(block1.digest.digest, s1_digest, 32); } else { memcpy(block0.digest.digest, s1_digest, 32); } log_verbose("copy s1 key success."); return ret; }
void c1s1::dump(char *_c1s1) { mAssert(schema != srs_schema_invalid); if (schema == srs_schema0) { srs_schema0_copy_to(_c1s1, true, time, version, &block0.key, &block1.digest); } else { srs_schema1_copy_to(_c1s1, true, time, version, &block0.digest, &block1.key); } }
char *c1s1::get_digest() { mAssert(schema != srs_schema_invalid); if (schema == srs_schema0) { return block1.digest.digest; } else { return block0.digest.digest; } }
int c1s1::c1_create(srs_schema_type _schema) { int ret = ERROR_SUCCESS; if (_schema == srs_schema_invalid) { ret = ERROR_RTMP_CH_SCHEMA; log_error("create c1 failed. invalid schema=%d, ret=%d", _schema, ret); return ret; } destroy_blocks(); time = ::time(NULL); // client c1 version char *_version = (char *)&version; _version[0] = 10; _version[1] = 0; _version[2] = 45; _version[3] = 2; if (_schema == srs_schema0) { srs_key_block_init(&block0.key); srs_digest_block_init(&block1.digest); } else { srs_digest_block_init(&block0.digest); srs_key_block_init(&block1.key); } schema = _schema; char *digest = NULL; if ((ret = calc_c1_digest(digest)) != ERROR_SUCCESS) { log_error("sign c1 error, failed to calc digest. ret=%d", ret); return ret; } mAssert(digest != NULL); mAutoFreeArray(char, digest); if (schema == srs_schema0) { memcpy(block1.digest.digest, digest, 32); } else { memcpy(block0.digest.digest, digest, 32); } return ret; }
int c1s1::s1_validate_digest(bool& is_valid) { int ret = ERROR_SUCCESS; char* c1_digest = NULL; if ((ret = calc_s1_digest(c1_digest)) != ERROR_SUCCESS) { log_error("validate c1 error, failed to calc digest. ret=%d", ret); return ret; } mAssert(c1_digest != NULL); mAutoFreeArray(char, c1_digest); if (schema == srs_schema0) { is_valid = srs_bytes_equals(block1.digest.digest, c1_digest, 32); } else { is_valid = srs_bytes_equals(block0.digest.digest, c1_digest, 32); } return ret; }
// create new digest block data. // if created, user must free it by srs_digest_block_free void srs_digest_block_init(digest_block *digest) { digest->offset = (int32_t)rand(); digest->random0 = NULL; digest->random1 = NULL; int offset = srs_digest_block_get_offset(digest); mAssert(offset >= 0); digest->random0_size = offset; if (digest->random0_size > 0) { digest->random0 = new char[digest->random0_size]; srs_random_generate(digest->random0, digest->random0_size); } srs_random_generate(digest->digest, sizeof(digest->digest)); digest->random1_size = 764 - 4 - offset - 32; if (digest->random1_size > 0) { digest->random1 = new char[digest->random1_size]; srs_random_generate(digest->random1, digest->random1_size); } }
// create new key block data. // if created, user must free it by srs_key_block_free void srs_key_block_init(key_block *key) { key->offset = (int32_t)rand(); key->random0 = NULL; key->random1 = NULL; int offset = srs_key_block_get_offset(key); mAssert(offset >= 0); key->random0_size = offset; if (key->random0_size > 0) { key->random0 = new char[key->random0_size]; srs_random_generate(key->random0, key->random0_size); } srs_random_generate(key->key, sizeof(key->key)); key->random1_size = 764 - offset - 128 - 4; if (key->random1_size > 0) { key->random1 = new char[key->random1_size]; srs_random_generate(key->random1, key->random1_size); } }