Merge branch 'master' of github.com:winlinvip/simple-rtmp-server
正在显示
11 个修改的文件
包含
1103 行增加
和
953 行删除
| @@ -167,6 +167,8 @@ See also: [Performance Test Guide](https://github.com/winlinvip/simple-rtmp-serv | @@ -167,6 +167,8 @@ See also: [Performance Test Guide](https://github.com/winlinvip/simple-rtmp-serv | ||
| 167 | * nginx v1.5.0: 139524 lines <br/> | 167 | * nginx v1.5.0: 139524 lines <br/> |
| 168 | 168 | ||
| 169 | ### History | 169 | ### History |
| 170 | +* v1.0, 2014-03-19, add vn/an for FFMPEG to drop video/audio for radio stream. | ||
| 171 | +* v1.0, 2014-03-19, refine handshake, client support coplex handshake, add utest. | ||
| 170 | * v1.0, 2014-03-16, support ARM([debian armhf, v7cpu](https://github.com/winlinvip/simple-rtmp-server/wiki/SrsLinuxArm)) with rtmp/ssl/hls/librtmp. | 172 | * v1.0, 2014-03-16, support ARM([debian armhf, v7cpu](https://github.com/winlinvip/simple-rtmp-server/wiki/SrsLinuxArm)) with rtmp/ssl/hls/librtmp. |
| 171 | * v1.0, 2014-03-12, finish utest for amf0 codec. | 173 | * v1.0, 2014-03-12, finish utest for amf0 codec. |
| 172 | * v1.0, 2014-03-06, add gperftools for mem leak detect, mem/cpu profile. | 174 | * v1.0, 2014-03-06, add gperftools for mem leak detect, mem/cpu profile. |
trunk/conf/full.conf
100644 → 100755
| @@ -291,6 +291,25 @@ vhost audio.transcode.vhost.com { | @@ -291,6 +291,25 @@ vhost audio.transcode.vhost.com { | ||
| 291 | } | 291 | } |
| 292 | } | 292 | } |
| 293 | } | 293 | } |
| 294 | +# disable video, transcode/copy audio. | ||
| 295 | +# for example, publish pure audio stream. | ||
| 296 | +vhost vn.transcode.vhost.com { | ||
| 297 | + transcode { | ||
| 298 | + enabled on; | ||
| 299 | + ffmpeg ./objs/ffmpeg/bin/ffmpeg; | ||
| 300 | + engine vn { | ||
| 301 | + enabled on; | ||
| 302 | + vcodec vn; | ||
| 303 | + acodec libaacplus; | ||
| 304 | + abitrate 45; | ||
| 305 | + asample_rate 44100; | ||
| 306 | + achannels 2; | ||
| 307 | + aparams { | ||
| 308 | + } | ||
| 309 | + output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine]; | ||
| 310 | + } | ||
| 311 | + } | ||
| 312 | +} | ||
| 294 | # ffmpeg-copy(forward implements by ffmpeg). | 313 | # ffmpeg-copy(forward implements by ffmpeg). |
| 295 | # copy the video and audio to a new stream. | 314 | # copy the video and audio to a new stream. |
| 296 | vhost copy.transcode.vhost.com { | 315 | vhost copy.transcode.vhost.com { |
| @@ -333,6 +352,7 @@ vhost all.transcode.vhost.com { | @@ -333,6 +352,7 @@ vhost all.transcode.vhost.com { | ||
| 333 | # video encoder name. can be: | 352 | # video encoder name. can be: |
| 334 | # libx264: use h.264(libx264) video encoder. | 353 | # libx264: use h.264(libx264) video encoder. |
| 335 | # copy: donot encoder the video stream, copy it. | 354 | # copy: donot encoder the video stream, copy it. |
| 355 | + # vn: disable video output. | ||
| 336 | vcodec libx264; | 356 | vcodec libx264; |
| 337 | # video bitrate, in kbps | 357 | # video bitrate, in kbps |
| 338 | vbitrate 1500; | 358 | vbitrate 1500; |
| @@ -364,6 +384,7 @@ vhost all.transcode.vhost.com { | @@ -364,6 +384,7 @@ vhost all.transcode.vhost.com { | ||
| 364 | # audio encoder name. can be: | 384 | # audio encoder name. can be: |
| 365 | # libaacplus: use aac(libaacplus) audio encoder. | 385 | # libaacplus: use aac(libaacplus) audio encoder. |
| 366 | # copy: donot encoder the audio stream, copy it. | 386 | # copy: donot encoder the audio stream, copy it. |
| 387 | + # an: disable audio output. | ||
| 367 | acodec libaacplus; | 388 | acodec libaacplus; |
| 368 | # audio bitrate, in kbps. [16, 72] for libaacplus. | 389 | # audio bitrate, in kbps. [16, 72] for libaacplus. |
| 369 | abitrate 70; | 390 | abitrate 70; |
trunk/conf/srs.conf
100644 → 100755
| @@ -42,6 +42,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -42,6 +42,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 42 | #ifdef SRS_FFMPEG | 42 | #ifdef SRS_FFMPEG |
| 43 | 43 | ||
| 44 | #define SRS_ENCODER_COPY "copy" | 44 | #define SRS_ENCODER_COPY "copy" |
| 45 | +#define SRS_ENCODER_NO_VIDEO "vn" | ||
| 46 | +#define SRS_ENCODER_NO_AUDIO "an" | ||
| 45 | #define SRS_ENCODER_VCODEC "libx264" | 47 | #define SRS_ENCODER_VCODEC "libx264" |
| 46 | #define SRS_ENCODER_ACODEC "libaacplus" | 48 | #define SRS_ENCODER_ACODEC "libaacplus" |
| 47 | 49 | ||
| @@ -138,7 +140,13 @@ int SrsFFMPEG::initialize(SrsRequest* req, SrsConfDirective* engine) | @@ -138,7 +140,13 @@ int SrsFFMPEG::initialize(SrsRequest* req, SrsConfDirective* engine) | ||
| 138 | } | 140 | } |
| 139 | _transcoded_url.push_back(output); | 141 | _transcoded_url.push_back(output); |
| 140 | 142 | ||
| 141 | - if (vcodec != SRS_ENCODER_COPY) { | 143 | + if (vcodec == SRS_ENCODER_NO_VIDEO && acodec == SRS_ENCODER_NO_AUDIO) { |
| 144 | + ret = ERROR_ENCODER_VCODEC; | ||
| 145 | + srs_warn("video and audio disabled. ret=%d", ret); | ||
| 146 | + return ret; | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + if (vcodec != SRS_ENCODER_COPY && vcodec != SRS_ENCODER_NO_VIDEO) { | ||
| 142 | if (vcodec != SRS_ENCODER_VCODEC) { | 150 | if (vcodec != SRS_ENCODER_VCODEC) { |
| 143 | ret = ERROR_ENCODER_VCODEC; | 151 | ret = ERROR_ENCODER_VCODEC; |
| 144 | srs_error("invalid vcodec, must be %s, actual %s, ret=%d", | 152 | srs_error("invalid vcodec, must be %s, actual %s, ret=%d", |
| @@ -182,7 +190,7 @@ int SrsFFMPEG::initialize(SrsRequest* req, SrsConfDirective* engine) | @@ -182,7 +190,7 @@ int SrsFFMPEG::initialize(SrsRequest* req, SrsConfDirective* engine) | ||
| 182 | } | 190 | } |
| 183 | } | 191 | } |
| 184 | 192 | ||
| 185 | - if (acodec != SRS_ENCODER_COPY) { | 193 | + if (acodec != SRS_ENCODER_COPY && acodec != SRS_ENCODER_NO_AUDIO) { |
| 186 | if (acodec != SRS_ENCODER_ACODEC) { | 194 | if (acodec != SRS_ENCODER_ACODEC) { |
| 187 | ret = ERROR_ENCODER_ACODEC; | 195 | ret = ERROR_ENCODER_ACODEC; |
| 188 | srs_error("invalid acodec, must be %s, actual %s, ret=%d", | 196 | srs_error("invalid acodec, must be %s, actual %s, ret=%d", |
| @@ -254,11 +262,15 @@ int SrsFFMPEG::start() | @@ -254,11 +262,15 @@ int SrsFFMPEG::start() | ||
| 254 | } | 262 | } |
| 255 | 263 | ||
| 256 | // video specified. | 264 | // video specified. |
| 257 | - params.push_back("-vcodec"); | ||
| 258 | - params.push_back(vcodec); | 265 | + if (vcodec != SRS_ENCODER_NO_VIDEO) { |
| 266 | + params.push_back("-vcodec"); | ||
| 267 | + params.push_back(vcodec); | ||
| 268 | + } else { | ||
| 269 | + params.push_back("-vn"); | ||
| 270 | + } | ||
| 259 | 271 | ||
| 260 | // the codec params is disabled when copy | 272 | // the codec params is disabled when copy |
| 261 | - if (vcodec != SRS_ENCODER_COPY) { | 273 | + if (vcodec != SRS_ENCODER_COPY && vcodec != SRS_ENCODER_NO_VIDEO) { |
| 262 | params.push_back("-b:v"); | 274 | params.push_back("-b:v"); |
| 263 | snprintf(tmp, sizeof(tmp), "%d", vbitrate * 1000); | 275 | snprintf(tmp, sizeof(tmp), "%d", vbitrate * 1000); |
| 264 | params.push_back(tmp); | 276 | params.push_back(tmp); |
| @@ -299,11 +311,15 @@ int SrsFFMPEG::start() | @@ -299,11 +311,15 @@ int SrsFFMPEG::start() | ||
| 299 | } | 311 | } |
| 300 | 312 | ||
| 301 | // audio specified. | 313 | // audio specified. |
| 302 | - params.push_back("-acodec"); | ||
| 303 | - params.push_back(acodec); | 314 | + if (acodec != SRS_ENCODER_NO_AUDIO) { |
| 315 | + params.push_back("-acodec"); | ||
| 316 | + params.push_back(acodec); | ||
| 317 | + } else { | ||
| 318 | + params.push_back("-an"); | ||
| 319 | + } | ||
| 304 | 320 | ||
| 305 | // the codec params is disabled when copy | 321 | // the codec params is disabled when copy |
| 306 | - if (acodec != SRS_ENCODER_COPY) { | 322 | + if (acodec != SRS_ENCODER_COPY && acodec != SRS_ENCODER_NO_AUDIO) { |
| 307 | params.push_back("-b:a"); | 323 | params.push_back("-b:a"); |
| 308 | snprintf(tmp, sizeof(tmp), "%d", abitrate * 1000); | 324 | snprintf(tmp, sizeof(tmp), "%d", abitrate * 1000); |
| 309 | params.push_back(tmp); | 325 | params.push_back(tmp); |
| @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 31 | // current release version | 31 | // current release version |
| 32 | #define VERSION_MAJOR "0" | 32 | #define VERSION_MAJOR "0" |
| 33 | #define VERSION_MINOR "9" | 33 | #define VERSION_MINOR "9" |
| 34 | -#define VERSION_REVISION "21" | 34 | +#define VERSION_REVISION "22" |
| 35 | #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION | 35 | #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION |
| 36 | // server info. | 36 | // server info. |
| 37 | #define RTMP_SIG_SRS_KEY "srs" | 37 | #define RTMP_SIG_SRS_KEY "srs" |
| @@ -32,924 +32,944 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -32,924 +32,944 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 32 | #include <srs_protocol_utility.hpp> | 32 | #include <srs_protocol_utility.hpp> |
| 33 | #include <srs_protocol_rtmp.hpp> | 33 | #include <srs_protocol_rtmp.hpp> |
| 34 | 34 | ||
| 35 | -using namespace srs; | ||
| 36 | - | ||
| 37 | #ifdef SRS_SSL | 35 | #ifdef SRS_SSL |
| 38 | 36 | ||
| 39 | -// 68bytes FMS key which is used to sign the sever packet. | ||
| 40 | -u_int8_t srs::SrsGenuineFMSKey[] = { | ||
| 41 | - 0x47, 0x65, 0x6e, 0x75, 0x69, 0x6e, 0x65, 0x20, | ||
| 42 | - 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x46, 0x6c, | ||
| 43 | - 0x61, 0x73, 0x68, 0x20, 0x4d, 0x65, 0x64, 0x69, | ||
| 44 | - 0x61, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, | ||
| 45 | - 0x20, 0x30, 0x30, 0x31, // Genuine Adobe Flash Media Server 001 | ||
| 46 | - 0xf0, 0xee, 0xc2, 0x4a, 0x80, 0x68, 0xbe, 0xe8, | ||
| 47 | - 0x2e, 0x00, 0xd0, 0xd1, 0x02, 0x9e, 0x7e, 0x57, | ||
| 48 | - 0x6e, 0xec, 0x5d, 0x2d, 0x29, 0x80, 0x6f, 0xab, | ||
| 49 | - 0x93, 0xb8, 0xe6, 0x36, 0xcf, 0xeb, 0x31, 0xae | ||
| 50 | -}; // 68 | ||
| 51 | - | ||
| 52 | -// 62bytes FP key which is used to sign the client packet. | ||
| 53 | -u_int8_t srs::SrsGenuineFPKey[] = { | ||
| 54 | - 0x47, 0x65, 0x6E, 0x75, 0x69, 0x6E, 0x65, 0x20, | ||
| 55 | - 0x41, 0x64, 0x6F, 0x62, 0x65, 0x20, 0x46, 0x6C, | ||
| 56 | - 0x61, 0x73, 0x68, 0x20, 0x50, 0x6C, 0x61, 0x79, | ||
| 57 | - 0x65, 0x72, 0x20, 0x30, 0x30, 0x31, // Genuine Adobe Flash Player 001 | ||
| 58 | - 0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, | ||
| 59 | - 0x2E, 0x00, 0xD0, 0xD1, 0x02, 0x9E, 0x7E, 0x57, | ||
| 60 | - 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, | ||
| 61 | - 0x93, 0xB8, 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE | ||
| 62 | -}; // 62 | 37 | +using namespace srs; |
| 63 | 38 | ||
| 39 | +// for openssl_HMACsha256 | ||
| 64 | #include <openssl/evp.h> | 40 | #include <openssl/evp.h> |
| 65 | #include <openssl/hmac.h> | 41 | #include <openssl/hmac.h> |
| 66 | -int srs::openssl_HMACsha256(const void* data, int data_size, const void* key, int key_size, void* digest) | ||
| 67 | -{ | ||
| 68 | - HMAC_CTX ctx; | ||
| 69 | - | ||
| 70 | - HMAC_CTX_init(&ctx); | ||
| 71 | - HMAC_Init_ex(&ctx, (unsigned char*) key, key_size, EVP_sha256(), NULL); | ||
| 72 | - HMAC_Update(&ctx, (unsigned char *) data, data_size); | ||
| 73 | - | ||
| 74 | - unsigned int digest_size; | ||
| 75 | - HMAC_Final(&ctx, (unsigned char *) digest, &digest_size); | ||
| 76 | - | ||
| 77 | - HMAC_CTX_cleanup(&ctx); | ||
| 78 | - | ||
| 79 | - if (digest_size != 32) { | ||
| 80 | - return ERROR_OpenSslSha256DigestSize; | ||
| 81 | - } | ||
| 82 | - | ||
| 83 | - return ERROR_SUCCESS; | ||
| 84 | -} | ||
| 85 | - | 42 | +// for __openssl_generate_key |
| 86 | #include <openssl/dh.h> | 43 | #include <openssl/dh.h> |
| 87 | -#define RFC2409_PRIME_1024 \ | ||
| 88 | - "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ | ||
| 89 | - "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ | ||
| 90 | - "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ | ||
| 91 | - "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ | ||
| 92 | - "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" \ | ||
| 93 | - "FFFFFFFFFFFFFFFF" | ||
| 94 | -int __openssl_generate_key( | ||
| 95 | - u_int8_t*& _private_key, u_int8_t*& _public_key, int32_t& size, | ||
| 96 | - DH*& pdh, int32_t& bits_count, u_int8_t*& shared_key, int32_t& shared_key_length, BIGNUM*& peer_public_key | ||
| 97 | -){ | ||
| 98 | - int ret = ERROR_SUCCESS; | ||
| 99 | - | ||
| 100 | - //1. Create the DH | ||
| 101 | - if ((pdh = DH_new()) == NULL) { | ||
| 102 | - ret = ERROR_OpenSslCreateDH; | ||
| 103 | - return ret; | ||
| 104 | - } | ||
| 105 | - | ||
| 106 | - //2. Create his internal p and g | ||
| 107 | - if ((pdh->p = BN_new()) == NULL) { | ||
| 108 | - ret = ERROR_OpenSslCreateP; | ||
| 109 | - return ret; | ||
| 110 | - } | ||
| 111 | - if ((pdh->g = BN_new()) == NULL) { | ||
| 112 | - ret = ERROR_OpenSslCreateG; | ||
| 113 | - return ret; | ||
| 114 | - } | ||
| 115 | - | ||
| 116 | - //3. initialize p, g and key length | ||
| 117 | - if (BN_hex2bn(&pdh->p, RFC2409_PRIME_1024) == 0) { | ||
| 118 | - ret = ERROR_OpenSslParseP1024; | ||
| 119 | - return ret; | ||
| 120 | - } | ||
| 121 | - if (BN_set_word(pdh->g, 2) != 1) { | ||
| 122 | - ret = ERROR_OpenSslSetG; | ||
| 123 | - return ret; | ||
| 124 | - } | ||
| 125 | - | ||
| 126 | - //4. Set the key length | ||
| 127 | - pdh->length = bits_count; | ||
| 128 | - | ||
| 129 | - //5. Generate private and public key | ||
| 130 | - if (DH_generate_key(pdh) != 1) { | ||
| 131 | - ret = ERROR_OpenSslGenerateDHKeys; | ||
| 132 | - return ret; | ||
| 133 | - } | ||
| 134 | - | ||
| 135 | - // CreateSharedKey | ||
| 136 | - if (pdh == NULL) { | ||
| 137 | - ret = ERROR_OpenSslGenerateDHKeys; | ||
| 138 | - return ret; | ||
| 139 | - } | ||
| 140 | - | ||
| 141 | - if (shared_key_length != 0 || shared_key != NULL) { | ||
| 142 | - ret = ERROR_OpenSslShareKeyComputed; | ||
| 143 | - return ret; | ||
| 144 | - } | ||
| 145 | - | ||
| 146 | - shared_key_length = DH_size(pdh); | ||
| 147 | - if (shared_key_length <= 0 || shared_key_length > 1024) { | ||
| 148 | - ret = ERROR_OpenSslGetSharedKeySize; | ||
| 149 | - return ret; | ||
| 150 | - } | ||
| 151 | - shared_key = new u_int8_t[shared_key_length]; | ||
| 152 | - memset(shared_key, 0, shared_key_length); | ||
| 153 | - | ||
| 154 | - peer_public_key = BN_bin2bn(_private_key, size, 0); | ||
| 155 | - if (peer_public_key == NULL) { | ||
| 156 | - ret = ERROR_OpenSslGetPeerPublicKey; | ||
| 157 | - return ret; | ||
| 158 | - } | ||
| 159 | - | ||
| 160 | - if (DH_compute_key(shared_key, peer_public_key, pdh) == -1) { | ||
| 161 | - ret = ERROR_OpenSslComputeSharedKey; | ||
| 162 | - return ret; | ||
| 163 | - } | ||
| 164 | - | ||
| 165 | - // CopyPublicKey | ||
| 166 | - if (pdh == NULL) { | ||
| 167 | - ret = ERROR_OpenSslComputeSharedKey; | ||
| 168 | - return ret; | ||
| 169 | - } | ||
| 170 | - | ||
| 171 | - int32_t keySize = BN_num_bytes(pdh->pub_key); | ||
| 172 | - if ((keySize <= 0) || (size <= 0) || (keySize > size)) { | ||
| 173 | - //("CopyPublicKey failed due to either invalid DH state or invalid call"); return ret; | ||
| 174 | - ret = ERROR_OpenSslInvalidDHState; | ||
| 175 | - return ret; | ||
| 176 | - } | ||
| 177 | - | ||
| 178 | - if (BN_bn2bin(pdh->pub_key, _public_key) != keySize) { | ||
| 179 | - //("Unable to copy key"); return ret; | ||
| 180 | - ret = ERROR_OpenSslCopyKey; | ||
| 181 | - return ret; | ||
| 182 | - } | ||
| 183 | - | ||
| 184 | - return ret; | ||
| 185 | -} | ||
| 186 | -int openssl_generate_key(char* _private_key, char* _public_key, int32_t size) | ||
| 187 | -{ | ||
| 188 | - int ret = ERROR_SUCCESS; | ||
| 189 | - | ||
| 190 | - // Initialize | ||
| 191 | - DH* pdh = NULL; | ||
| 192 | - int32_t bits_count = 1024; | ||
| 193 | - u_int8_t* shared_key = NULL; | ||
| 194 | - int32_t shared_key_length = 0; | ||
| 195 | - BIGNUM* peer_public_key = NULL; | ||
| 196 | - | ||
| 197 | - ret = __openssl_generate_key( | ||
| 198 | - (u_int8_t*&)_private_key, (u_int8_t*&)_public_key, size, | ||
| 199 | - pdh, bits_count, shared_key, shared_key_length, peer_public_key | ||
| 200 | - ); | ||
| 201 | - | ||
| 202 | - if (pdh != NULL) { | ||
| 203 | - if (pdh->p != NULL) { | ||
| 204 | - BN_free(pdh->p); | ||
| 205 | - pdh->p = NULL; | ||
| 206 | - } | ||
| 207 | - if (pdh->g != NULL) { | ||
| 208 | - BN_free(pdh->g); | ||
| 209 | - pdh->g = NULL; | ||
| 210 | - } | ||
| 211 | - DH_free(pdh); | ||
| 212 | - pdh = NULL; | ||
| 213 | - } | ||
| 214 | 44 | ||
| 215 | - if (shared_key != NULL) { | ||
| 216 | - delete[] shared_key; | ||
| 217 | - shared_key = NULL; | ||
| 218 | - } | ||
| 219 | - | ||
| 220 | - if (peer_public_key != NULL) { | ||
| 221 | - BN_free(peer_public_key); | ||
| 222 | - peer_public_key = NULL; | ||
| 223 | - } | ||
| 224 | - | ||
| 225 | - return ret; | ||
| 226 | -} | ||
| 227 | - | ||
| 228 | -// calc the offset of key, | ||
| 229 | -// the key->offset cannot be used as the offset of key. | ||
| 230 | -int srs_key_block_get_offset(key_block* key) | ||
| 231 | -{ | ||
| 232 | - int max_offset_size = 764 - 128 - 4; | ||
| 233 | - | ||
| 234 | - int offset = 0; | ||
| 235 | - u_int8_t* pp = (u_int8_t*)&key->offset; | ||
| 236 | - offset += *pp++; | ||
| 237 | - offset += *pp++; | ||
| 238 | - offset += *pp++; | ||
| 239 | - offset += *pp++; | ||
| 240 | - | ||
| 241 | - return offset % max_offset_size; | ||
| 242 | -} | ||
| 243 | -// create new key block data. | ||
| 244 | -// if created, user must free it by srs_key_block_free | ||
| 245 | -void srs_key_block_init(key_block* key) | 45 | +namespace srs |
| 246 | { | 46 | { |
| 247 | - key->offset = (int32_t)rand(); | ||
| 248 | - key->random0 = NULL; | ||
| 249 | - key->random1 = NULL; | ||
| 250 | - | ||
| 251 | - int offset = srs_key_block_get_offset(key); | ||
| 252 | - srs_assert(offset >= 0); | 47 | + // 68bytes FMS key which is used to sign the sever packet. |
| 48 | + u_int8_t SrsGenuineFMSKey[] = { | ||
| 49 | + 0x47, 0x65, 0x6e, 0x75, 0x69, 0x6e, 0x65, 0x20, | ||
| 50 | + 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x46, 0x6c, | ||
| 51 | + 0x61, 0x73, 0x68, 0x20, 0x4d, 0x65, 0x64, 0x69, | ||
| 52 | + 0x61, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, | ||
| 53 | + 0x20, 0x30, 0x30, 0x31, // Genuine Adobe Flash Media Server 001 | ||
| 54 | + 0xf0, 0xee, 0xc2, 0x4a, 0x80, 0x68, 0xbe, 0xe8, | ||
| 55 | + 0x2e, 0x00, 0xd0, 0xd1, 0x02, 0x9e, 0x7e, 0x57, | ||
| 56 | + 0x6e, 0xec, 0x5d, 0x2d, 0x29, 0x80, 0x6f, 0xab, | ||
| 57 | + 0x93, 0xb8, 0xe6, 0x36, 0xcf, 0xeb, 0x31, 0xae | ||
| 58 | + }; // 68 | ||
| 59 | + | ||
| 60 | + // 62bytes FP key which is used to sign the client packet. | ||
| 61 | + u_int8_t SrsGenuineFPKey[] = { | ||
| 62 | + 0x47, 0x65, 0x6E, 0x75, 0x69, 0x6E, 0x65, 0x20, | ||
| 63 | + 0x41, 0x64, 0x6F, 0x62, 0x65, 0x20, 0x46, 0x6C, | ||
| 64 | + 0x61, 0x73, 0x68, 0x20, 0x50, 0x6C, 0x61, 0x79, | ||
| 65 | + 0x65, 0x72, 0x20, 0x30, 0x30, 0x31, // Genuine Adobe Flash Player 001 | ||
| 66 | + 0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, | ||
| 67 | + 0x2E, 0x00, 0xD0, 0xD1, 0x02, 0x9E, 0x7E, 0x57, | ||
| 68 | + 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, | ||
| 69 | + 0x93, 0xB8, 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE | ||
| 70 | + }; // 62 | ||
| 71 | + | ||
| 72 | + int openssl_HMACsha256(const void* data, int data_size, const void* key, int key_size, void* digest) | ||
| 73 | + { | ||
| 74 | + HMAC_CTX ctx; | ||
| 75 | + | ||
| 76 | + HMAC_CTX_init(&ctx); | ||
| 77 | + HMAC_Init_ex(&ctx, (unsigned char*) key, key_size, EVP_sha256(), NULL); | ||
| 78 | + HMAC_Update(&ctx, (unsigned char *) data, data_size); | ||
| 253 | 79 | ||
| 254 | - key->random0_size = offset; | ||
| 255 | - if (key->random0_size > 0) { | ||
| 256 | - key->random0 = new char[key->random0_size]; | ||
| 257 | - srs_random_generate(key->random0, key->random0_size); | ||
| 258 | - } | 80 | + unsigned int digest_size; |
| 81 | + HMAC_Final(&ctx, (unsigned char *) digest, &digest_size); | ||
| 82 | + | ||
| 83 | + HMAC_CTX_cleanup(&ctx); | ||
| 84 | + | ||
| 85 | + if (digest_size != 32) { | ||
| 86 | + return ERROR_OpenSslSha256DigestSize; | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + return ERROR_SUCCESS; | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + #define RFC2409_PRIME_1024 \ | ||
| 93 | + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ | ||
| 94 | + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ | ||
| 95 | + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ | ||
| 96 | + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ | ||
| 97 | + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" \ | ||
| 98 | + "FFFFFFFFFFFFFFFF" | ||
| 99 | + int __openssl_generate_key( | ||
| 100 | + u_int8_t* _private_key, u_int8_t* _public_key, int32_t& size, | ||
| 101 | + DH*& pdh, int32_t& bits_count, u_int8_t*& shared_key, int32_t& shared_key_length, BIGNUM*& peer_public_key | ||
| 102 | + ){ | ||
| 103 | + int ret = ERROR_SUCCESS; | ||
| 104 | + | ||
| 105 | + //1. Create the DH | ||
| 106 | + if ((pdh = DH_new()) == NULL) { | ||
| 107 | + ret = ERROR_OpenSslCreateDH; | ||
| 108 | + return ret; | ||
| 109 | + } | ||
| 259 | 110 | ||
| 260 | - srs_random_generate(key->key, sizeof(key->key)); | 111 | + //2. Create his internal p and g |
| 112 | + if ((pdh->p = BN_new()) == NULL) { | ||
| 113 | + ret = ERROR_OpenSslCreateP; | ||
| 114 | + return ret; | ||
| 115 | + } | ||
| 116 | + if ((pdh->g = BN_new()) == NULL) { | ||
| 117 | + ret = ERROR_OpenSslCreateG; | ||
| 118 | + return ret; | ||
| 119 | + } | ||
| 261 | 120 | ||
| 262 | - key->random1_size = 764 - offset - 128 - 4; | ||
| 263 | - if (key->random1_size > 0) { | ||
| 264 | - key->random1 = new char[key->random1_size]; | ||
| 265 | - srs_random_generate(key->random1, key->random1_size); | ||
| 266 | - } | ||
| 267 | -} | ||
| 268 | -// parse key block from c1s1. | ||
| 269 | -// if created, user must free it by srs_key_block_free | ||
| 270 | -// @c1s1_key_bytes the key start bytes, maybe c1s1 or c1s1+764 | ||
| 271 | -int srs_key_block_parse(key_block* key, char* c1s1_key_bytes) | ||
| 272 | -{ | ||
| 273 | - int ret = ERROR_SUCCESS; | ||
| 274 | - | ||
| 275 | - char* pp = c1s1_key_bytes + 764; | 121 | + //3. initialize p, g and key length |
| 122 | + if (BN_hex2bn(&pdh->p, RFC2409_PRIME_1024) == 0) { | ||
| 123 | + ret = ERROR_OpenSslParseP1024; | ||
| 124 | + return ret; | ||
| 125 | + } | ||
| 126 | + if (BN_set_word(pdh->g, 2) != 1) { | ||
| 127 | + ret = ERROR_OpenSslSetG; | ||
| 128 | + return ret; | ||
| 129 | + } | ||
| 276 | 130 | ||
| 277 | - pp -= sizeof(int32_t); | ||
| 278 | - key->offset = *(int32_t*)pp; | 131 | + //4. Set the key length |
| 132 | + pdh->length = bits_count; | ||
| 279 | 133 | ||
| 280 | - key->random0 = NULL; | ||
| 281 | - key->random1 = NULL; | 134 | + //5. Generate private and public key |
| 135 | + if (DH_generate_key(pdh) != 1) { | ||
| 136 | + ret = ERROR_OpenSslGenerateDHKeys; | ||
| 137 | + return ret; | ||
| 138 | + } | ||
| 282 | 139 | ||
| 283 | - int offset = srs_key_block_get_offset(key); | ||
| 284 | - srs_assert(offset >= 0); | 140 | + // CreateSharedKey |
| 141 | + if (pdh == NULL) { | ||
| 142 | + ret = ERROR_OpenSslGenerateDHKeys; | ||
| 143 | + return ret; | ||
| 144 | + } | ||
| 285 | 145 | ||
| 286 | - pp = c1s1_key_bytes; | ||
| 287 | - key->random0_size = offset; | ||
| 288 | - if (key->random0_size > 0) { | ||
| 289 | - key->random0 = new char[key->random0_size]; | ||
| 290 | - memcpy(key->random0, pp, key->random0_size); | ||
| 291 | - } | ||
| 292 | - pp += key->random0_size; | 146 | + if (shared_key_length != 0 || shared_key != NULL) { |
| 147 | + ret = ERROR_OpenSslShareKeyComputed; | ||
| 148 | + return ret; | ||
| 149 | + } | ||
| 293 | 150 | ||
| 294 | - memcpy(key->key, pp, sizeof(key->key)); | ||
| 295 | - pp += sizeof(key->key); | 151 | + shared_key_length = DH_size(pdh); |
| 152 | + if (shared_key_length <= 0 || shared_key_length > 1024) { | ||
| 153 | + ret = ERROR_OpenSslGetSharedKeySize; | ||
| 154 | + return ret; | ||
| 155 | + } | ||
| 156 | + shared_key = new u_int8_t[shared_key_length]; | ||
| 157 | + memset(shared_key, 0, shared_key_length); | ||
| 296 | 158 | ||
| 297 | - key->random1_size = 764 - offset - 128 - 4; | ||
| 298 | - if (key->random1_size > 0) { | ||
| 299 | - key->random1 = new char[key->random1_size]; | ||
| 300 | - memcpy(key->random1, pp, key->random1_size); | ||
| 301 | - } | 159 | + peer_public_key = BN_bin2bn(_private_key, size, 0); |
| 160 | + if (peer_public_key == NULL) { | ||
| 161 | + ret = ERROR_OpenSslGetPeerPublicKey; | ||
| 162 | + return ret; | ||
| 163 | + } | ||
| 302 | 164 | ||
| 303 | - return ret; | ||
| 304 | -} | ||
| 305 | -// free the block data create by | ||
| 306 | -// srs_key_block_init or srs_key_block_parse | ||
| 307 | -void srs_key_block_free(key_block* key) | ||
| 308 | -{ | ||
| 309 | - if (key->random0) { | ||
| 310 | - srs_freepa(key->random0); | ||
| 311 | - } | ||
| 312 | - if (key->random1) { | ||
| 313 | - srs_freepa(key->random1); | ||
| 314 | - } | ||
| 315 | -} | ||
| 316 | - | ||
| 317 | -// calc the offset of digest, | ||
| 318 | -// the key->offset cannot be used as the offset of digest. | ||
| 319 | -int srs_digest_block_get_offset(digest_block* digest) | ||
| 320 | -{ | ||
| 321 | - int max_offset_size = 764 - 32 - 4; | ||
| 322 | - | ||
| 323 | - int offset = 0; | ||
| 324 | - u_int8_t* pp = (u_int8_t*)&digest->offset; | ||
| 325 | - offset += *pp++; | ||
| 326 | - offset += *pp++; | ||
| 327 | - offset += *pp++; | ||
| 328 | - offset += *pp++; | ||
| 329 | - | ||
| 330 | - return offset % max_offset_size; | ||
| 331 | -} | ||
| 332 | -// create new digest block data. | ||
| 333 | -// if created, user must free it by srs_digest_block_free | ||
| 334 | -void srs_digest_block_init(digest_block* digest) | ||
| 335 | -{ | ||
| 336 | - digest->offset = (int32_t)rand(); | ||
| 337 | - digest->random0 = NULL; | ||
| 338 | - digest->random1 = NULL; | 165 | + if (DH_compute_key(shared_key, peer_public_key, pdh) == -1) { |
| 166 | + ret = ERROR_OpenSslComputeSharedKey; | ||
| 167 | + return ret; | ||
| 168 | + } | ||
| 339 | 169 | ||
| 340 | - int offset = srs_digest_block_get_offset(digest); | ||
| 341 | - srs_assert(offset >= 0); | 170 | + // CopyPublicKey |
| 171 | + if (pdh == NULL) { | ||
| 172 | + ret = ERROR_OpenSslComputeSharedKey; | ||
| 173 | + return ret; | ||
| 174 | + } | ||
| 175 | + | ||
| 176 | + int32_t keySize = BN_num_bytes(pdh->pub_key); | ||
| 177 | + if ((keySize <= 0) || (size <= 0) || (keySize > size)) { | ||
| 178 | + //("CopyPublicKey failed due to either invalid DH state or invalid call"); return ret; | ||
| 179 | + ret = ERROR_OpenSslInvalidDHState; | ||
| 180 | + return ret; | ||
| 181 | + } | ||
| 342 | 182 | ||
| 343 | - digest->random0_size = offset; | ||
| 344 | - if (digest->random0_size > 0) { | ||
| 345 | - digest->random0 = new char[digest->random0_size]; | ||
| 346 | - srs_random_generate(digest->random0, digest->random0_size); | 183 | + if (BN_bn2bin(pdh->pub_key, _public_key) != keySize) { |
| 184 | + //("Unable to copy key"); return ret; | ||
| 185 | + ret = ERROR_OpenSslCopyKey; | ||
| 186 | + return ret; | ||
| 187 | + } | ||
| 188 | + | ||
| 189 | + return ret; | ||
| 347 | } | 190 | } |
| 191 | + int openssl_generate_key(char* _private_key, char* _public_key, int32_t size) | ||
| 192 | + { | ||
| 193 | + int ret = ERROR_SUCCESS; | ||
| 348 | 194 | ||
| 349 | - srs_random_generate(digest->digest, sizeof(digest->digest)); | ||
| 350 | - | ||
| 351 | - digest->random1_size = 764 - 4 - offset - 32; | ||
| 352 | - if (digest->random1_size > 0) { | ||
| 353 | - digest->random1 = new char[digest->random1_size]; | ||
| 354 | - srs_random_generate(digest->random1, digest->random1_size); | ||
| 355 | - } | ||
| 356 | -} | ||
| 357 | -// parse digest block from c1s1. | ||
| 358 | -// if created, user must free it by srs_digest_block_free | ||
| 359 | -// @c1s1_digest_bytes the digest start bytes, maybe c1s1 or c1s1+764 | ||
| 360 | -int srs_digest_block_parse(digest_block* digest, char* c1s1_digest_bytes) | ||
| 361 | -{ | ||
| 362 | - int ret = ERROR_SUCCESS; | ||
| 363 | - | ||
| 364 | - char* pp = c1s1_digest_bytes; | 195 | + // Initialize |
| 196 | + DH* pdh = NULL; | ||
| 197 | + int32_t bits_count = 1024; | ||
| 198 | + u_int8_t* shared_key = NULL; | ||
| 199 | + int32_t shared_key_length = 0; | ||
| 200 | + BIGNUM* peer_public_key = NULL; | ||
| 201 | + | ||
| 202 | + ret = __openssl_generate_key( | ||
| 203 | + (u_int8_t*)_private_key, (u_int8_t*)_public_key, size, | ||
| 204 | + pdh, bits_count, shared_key, shared_key_length, peer_public_key | ||
| 205 | + ); | ||
| 206 | + | ||
| 207 | + if (pdh != NULL) { | ||
| 208 | + if (pdh->p != NULL) { | ||
| 209 | + BN_free(pdh->p); | ||
| 210 | + pdh->p = NULL; | ||
| 211 | + } | ||
| 212 | + if (pdh->g != NULL) { | ||
| 213 | + BN_free(pdh->g); | ||
| 214 | + pdh->g = NULL; | ||
| 215 | + } | ||
| 216 | + DH_free(pdh); | ||
| 217 | + pdh = NULL; | ||
| 218 | + } | ||
| 365 | 219 | ||
| 366 | - digest->offset = *(int32_t*)pp; | ||
| 367 | - pp += sizeof(int32_t); | 220 | + if (shared_key != NULL) { |
| 221 | + delete[] shared_key; | ||
| 222 | + shared_key = NULL; | ||
| 223 | + } | ||
| 368 | 224 | ||
| 369 | - digest->random0 = NULL; | ||
| 370 | - digest->random1 = NULL; | 225 | + if (peer_public_key != NULL) { |
| 226 | + BN_free(peer_public_key); | ||
| 227 | + peer_public_key = NULL; | ||
| 228 | + } | ||
| 371 | 229 | ||
| 372 | - int offset = srs_digest_block_get_offset(digest); | ||
| 373 | - srs_assert(offset >= 0); | 230 | + return ret; |
| 231 | + } | ||
| 374 | 232 | ||
| 375 | - digest->random0_size = offset; | ||
| 376 | - if (digest->random0_size > 0) { | ||
| 377 | - digest->random0 = new char[digest->random0_size]; | ||
| 378 | - memcpy(digest->random0, pp, digest->random0_size); | 233 | + // calc the offset of key, |
| 234 | + // the key->offset cannot be used as the offset of key. | ||
| 235 | + int srs_key_block_get_offset(key_block* key) | ||
| 236 | + { | ||
| 237 | + int max_offset_size = 764 - 128 - 4; | ||
| 238 | + | ||
| 239 | + int offset = 0; | ||
| 240 | + u_int8_t* pp = (u_int8_t*)&key->offset; | ||
| 241 | + offset += *pp++; | ||
| 242 | + offset += *pp++; | ||
| 243 | + offset += *pp++; | ||
| 244 | + offset += *pp++; | ||
| 245 | + | ||
| 246 | + return offset % max_offset_size; | ||
| 247 | + } | ||
| 248 | + | ||
| 249 | + // create new key block data. | ||
| 250 | + // if created, user must free it by srs_key_block_free | ||
| 251 | + void srs_key_block_init(key_block* key) | ||
| 252 | + { | ||
| 253 | + key->offset = (int32_t)rand(); | ||
| 254 | + key->random0 = NULL; | ||
| 255 | + key->random1 = NULL; | ||
| 256 | + | ||
| 257 | + int offset = srs_key_block_get_offset(key); | ||
| 258 | + srs_assert(offset >= 0); | ||
| 259 | + | ||
| 260 | + key->random0_size = offset; | ||
| 261 | + if (key->random0_size > 0) { | ||
| 262 | + key->random0 = new char[key->random0_size]; | ||
| 263 | + srs_random_generate(key->random0, key->random0_size); | ||
| 264 | + } | ||
| 265 | + | ||
| 266 | + srs_random_generate(key->key, sizeof(key->key)); | ||
| 267 | + | ||
| 268 | + key->random1_size = 764 - offset - 128 - 4; | ||
| 269 | + if (key->random1_size > 0) { | ||
| 270 | + key->random1 = new char[key->random1_size]; | ||
| 271 | + srs_random_generate(key->random1, key->random1_size); | ||
| 272 | + } | ||
| 379 | } | 273 | } |
| 380 | - pp += digest->random0_size; | ||
| 381 | 274 | ||
| 382 | - memcpy(digest->digest, pp, sizeof(digest->digest)); | ||
| 383 | - pp += sizeof(digest->digest); | 275 | + // parse key block from c1s1. |
| 276 | + // if created, user must free it by srs_key_block_free | ||
| 277 | + // @c1s1_key_bytes the key start bytes, maybe c1s1 or c1s1+764 | ||
| 278 | + int srs_key_block_parse(key_block* key, char* c1s1_key_bytes) | ||
| 279 | + { | ||
| 280 | + int ret = ERROR_SUCCESS; | ||
| 384 | 281 | ||
| 385 | - digest->random1_size = 764 - 4 - offset - 32; | ||
| 386 | - if (digest->random1_size > 0) { | ||
| 387 | - digest->random1 = new char[digest->random1_size]; | ||
| 388 | - memcpy(digest->random1, pp, digest->random1_size); | 282 | + char* pp = c1s1_key_bytes + 764; |
| 283 | + | ||
| 284 | + pp -= sizeof(int32_t); | ||
| 285 | + key->offset = *(int32_t*)pp; | ||
| 286 | + | ||
| 287 | + key->random0 = NULL; | ||
| 288 | + key->random1 = NULL; | ||
| 289 | + | ||
| 290 | + int offset = srs_key_block_get_offset(key); | ||
| 291 | + srs_assert(offset >= 0); | ||
| 292 | + | ||
| 293 | + pp = c1s1_key_bytes; | ||
| 294 | + key->random0_size = offset; | ||
| 295 | + if (key->random0_size > 0) { | ||
| 296 | + key->random0 = new char[key->random0_size]; | ||
| 297 | + memcpy(key->random0, pp, key->random0_size); | ||
| 298 | + } | ||
| 299 | + pp += key->random0_size; | ||
| 300 | + | ||
| 301 | + memcpy(key->key, pp, sizeof(key->key)); | ||
| 302 | + pp += sizeof(key->key); | ||
| 303 | + | ||
| 304 | + key->random1_size = 764 - offset - 128 - 4; | ||
| 305 | + if (key->random1_size > 0) { | ||
| 306 | + key->random1 = new char[key->random1_size]; | ||
| 307 | + memcpy(key->random1, pp, key->random1_size); | ||
| 308 | + } | ||
| 309 | + | ||
| 310 | + return ret; | ||
| 389 | } | 311 | } |
| 390 | 312 | ||
| 391 | - return ret; | ||
| 392 | -} | ||
| 393 | -// free the block data create by | ||
| 394 | -// srs_digest_block_init or srs_digest_block_parse | ||
| 395 | -void srs_digest_block_free(digest_block* digest) | ||
| 396 | -{ | ||
| 397 | - if (digest->random0) { | ||
| 398 | - srs_freepa(digest->random0); | ||
| 399 | - } | ||
| 400 | - if (digest->random1) { | ||
| 401 | - srs_freepa(digest->random1); | ||
| 402 | - } | ||
| 403 | -} | ||
| 404 | - | ||
| 405 | -void __srs_time_copy_to(char*& pp, int32_t time) | ||
| 406 | -{ | ||
| 407 | - // 4bytes time | ||
| 408 | - *(int32_t*)pp = time; | ||
| 409 | - pp += 4; | ||
| 410 | -} | ||
| 411 | -void __srs_version_copy_to(char*& pp, int32_t version) | ||
| 412 | -{ | ||
| 413 | - // 4bytes version | ||
| 414 | - *(int32_t*)pp = version; | ||
| 415 | - pp += 4; | ||
| 416 | -} | ||
| 417 | -void __srs_key_copy_to(char*& pp, key_block* key) | ||
| 418 | -{ | ||
| 419 | - // 764bytes key block | ||
| 420 | - if (key->random0_size > 0) { | ||
| 421 | - memcpy(pp, key->random0, key->random0_size); | 313 | + // free the block data create by |
| 314 | + // srs_key_block_init or srs_key_block_parse | ||
| 315 | + void srs_key_block_free(key_block* key) | ||
| 316 | + { | ||
| 317 | + if (key->random0) { | ||
| 318 | + srs_freepa(key->random0); | ||
| 319 | + } | ||
| 320 | + if (key->random1) { | ||
| 321 | + srs_freepa(key->random1); | ||
| 322 | + } | ||
| 422 | } | 323 | } |
| 423 | - pp += key->random0_size; | ||
| 424 | - | ||
| 425 | - memcpy(pp, key->key, sizeof(key->key)); | ||
| 426 | - pp += sizeof(key->key); | ||
| 427 | 324 | ||
| 428 | - if (key->random1_size > 0) { | ||
| 429 | - memcpy(pp, key->random1, key->random1_size); | 325 | + // calc the offset of digest, |
| 326 | + // the key->offset cannot be used as the offset of digest. | ||
| 327 | + int srs_digest_block_get_offset(digest_block* digest) | ||
| 328 | + { | ||
| 329 | + int max_offset_size = 764 - 32 - 4; | ||
| 330 | + | ||
| 331 | + int offset = 0; | ||
| 332 | + u_int8_t* pp = (u_int8_t*)&digest->offset; | ||
| 333 | + offset += *pp++; | ||
| 334 | + offset += *pp++; | ||
| 335 | + offset += *pp++; | ||
| 336 | + offset += *pp++; | ||
| 337 | + | ||
| 338 | + return offset % max_offset_size; | ||
| 339 | + } | ||
| 340 | + | ||
| 341 | + // create new digest block data. | ||
| 342 | + // if created, user must free it by srs_digest_block_free | ||
| 343 | + void srs_digest_block_init(digest_block* digest) | ||
| 344 | + { | ||
| 345 | + digest->offset = (int32_t)rand(); | ||
| 346 | + digest->random0 = NULL; | ||
| 347 | + digest->random1 = NULL; | ||
| 348 | + | ||
| 349 | + int offset = srs_digest_block_get_offset(digest); | ||
| 350 | + srs_assert(offset >= 0); | ||
| 351 | + | ||
| 352 | + digest->random0_size = offset; | ||
| 353 | + if (digest->random0_size > 0) { | ||
| 354 | + digest->random0 = new char[digest->random0_size]; | ||
| 355 | + srs_random_generate(digest->random0, digest->random0_size); | ||
| 356 | + } | ||
| 357 | + | ||
| 358 | + srs_random_generate(digest->digest, sizeof(digest->digest)); | ||
| 359 | + | ||
| 360 | + digest->random1_size = 764 - 4 - offset - 32; | ||
| 361 | + if (digest->random1_size > 0) { | ||
| 362 | + digest->random1 = new char[digest->random1_size]; | ||
| 363 | + srs_random_generate(digest->random1, digest->random1_size); | ||
| 364 | + } | ||
| 430 | } | 365 | } |
| 431 | - pp += key->random1_size; | ||
| 432 | - | ||
| 433 | - *(int32_t*)pp = key->offset; | ||
| 434 | - pp += 4; | ||
| 435 | -} | ||
| 436 | -void __srs_digest_copy_to(char*& pp, digest_block* digest, bool with_digest) | ||
| 437 | -{ | ||
| 438 | - // 732bytes digest block without the 32bytes digest-data | ||
| 439 | - // nbytes digest block part1 | ||
| 440 | - *(int32_t*)pp = digest->offset; | ||
| 441 | - pp += 4; | 366 | + |
| 367 | + // parse digest block from c1s1. | ||
| 368 | + // if created, user must free it by srs_digest_block_free | ||
| 369 | + // @c1s1_digest_bytes the digest start bytes, maybe c1s1 or c1s1+764 | ||
| 370 | + int srs_digest_block_parse(digest_block* digest, char* c1s1_digest_bytes) | ||
| 371 | + { | ||
| 372 | + int ret = ERROR_SUCCESS; | ||
| 442 | 373 | ||
| 443 | - if (digest->random0_size > 0) { | ||
| 444 | - memcpy(pp, digest->random0, digest->random0_size); | 374 | + char* pp = c1s1_digest_bytes; |
| 375 | + | ||
| 376 | + digest->offset = *(int32_t*)pp; | ||
| 377 | + pp += sizeof(int32_t); | ||
| 378 | + | ||
| 379 | + digest->random0 = NULL; | ||
| 380 | + digest->random1 = NULL; | ||
| 381 | + | ||
| 382 | + int offset = srs_digest_block_get_offset(digest); | ||
| 383 | + srs_assert(offset >= 0); | ||
| 384 | + | ||
| 385 | + digest->random0_size = offset; | ||
| 386 | + if (digest->random0_size > 0) { | ||
| 387 | + digest->random0 = new char[digest->random0_size]; | ||
| 388 | + memcpy(digest->random0, pp, digest->random0_size); | ||
| 389 | + } | ||
| 390 | + pp += digest->random0_size; | ||
| 391 | + | ||
| 392 | + memcpy(digest->digest, pp, sizeof(digest->digest)); | ||
| 393 | + pp += sizeof(digest->digest); | ||
| 394 | + | ||
| 395 | + digest->random1_size = 764 - 4 - offset - 32; | ||
| 396 | + if (digest->random1_size > 0) { | ||
| 397 | + digest->random1 = new char[digest->random1_size]; | ||
| 398 | + memcpy(digest->random1, pp, digest->random1_size); | ||
| 399 | + } | ||
| 400 | + | ||
| 401 | + return ret; | ||
| 445 | } | 402 | } |
| 446 | - pp += digest->random0_size; | ||
| 447 | 403 | ||
| 448 | - // digest | ||
| 449 | - if (with_digest) { | ||
| 450 | - memcpy(pp, digest->digest, 32); | ||
| 451 | - pp += 32; | 404 | + // free the block data create by |
| 405 | + // srs_digest_block_init or srs_digest_block_parse | ||
| 406 | + void srs_digest_block_free(digest_block* digest) | ||
| 407 | + { | ||
| 408 | + if (digest->random0) { | ||
| 409 | + srs_freepa(digest->random0); | ||
| 410 | + } | ||
| 411 | + if (digest->random1) { | ||
| 412 | + srs_freepa(digest->random1); | ||
| 413 | + } | ||
| 452 | } | 414 | } |
| 453 | 415 | ||
| 454 | - // nbytes digest block part2 | ||
| 455 | - if (digest->random1_size > 0) { | ||
| 456 | - memcpy(pp, digest->random1, digest->random1_size); | 416 | + void __srs_time_copy_to(char*& pp, int32_t time) |
| 417 | + { | ||
| 418 | + // 4bytes time | ||
| 419 | + *(int32_t*)pp = time; | ||
| 420 | + pp += 4; | ||
| 457 | } | 421 | } |
| 458 | - pp += digest->random1_size; | ||
| 459 | -} | ||
| 460 | - | ||
| 461 | -/** | ||
| 462 | -* copy whole c1s1 to bytes. | ||
| 463 | -*/ | ||
| 464 | -void srs_schema0_copy_to(char* bytes, bool with_digest, | ||
| 465 | - int32_t time, int32_t version, key_block* key, digest_block* digest) | ||
| 466 | -{ | ||
| 467 | - char* pp = bytes; | ||
| 468 | - | ||
| 469 | - __srs_time_copy_to(pp, time); | ||
| 470 | - __srs_version_copy_to(pp, version); | ||
| 471 | - __srs_key_copy_to(pp, key); | ||
| 472 | - __srs_digest_copy_to(pp, digest, with_digest); | ||
| 473 | - | ||
| 474 | - if (with_digest) { | ||
| 475 | - srs_assert(pp - bytes == 1536); | ||
| 476 | - } else { | ||
| 477 | - srs_assert(pp - bytes == 1536 - 32); | 422 | + void __srs_version_copy_to(char*& pp, int32_t version) |
| 423 | + { | ||
| 424 | + // 4bytes version | ||
| 425 | + *(int32_t*)pp = version; | ||
| 426 | + pp += 4; | ||
| 478 | } | 427 | } |
| 479 | -} | ||
| 480 | -void srs_schema1_copy_to(char* bytes, bool with_digest, | ||
| 481 | - int32_t time, int32_t version, digest_block* digest, key_block* key) | ||
| 482 | -{ | ||
| 483 | - char* pp = bytes; | ||
| 484 | - | ||
| 485 | - __srs_time_copy_to(pp, time); | ||
| 486 | - __srs_version_copy_to(pp, version); | ||
| 487 | - __srs_digest_copy_to(pp, digest, with_digest); | ||
| 488 | - __srs_key_copy_to(pp, key); | ||
| 489 | - | ||
| 490 | - if (with_digest) { | ||
| 491 | - srs_assert(pp - bytes == 1536); | ||
| 492 | - } else { | ||
| 493 | - srs_assert(pp - bytes == 1536 - 32); | 428 | + void __srs_key_copy_to(char*& pp, key_block* key) |
| 429 | + { | ||
| 430 | + // 764bytes key block | ||
| 431 | + if (key->random0_size > 0) { | ||
| 432 | + memcpy(pp, key->random0, key->random0_size); | ||
| 433 | + } | ||
| 434 | + pp += key->random0_size; | ||
| 435 | + | ||
| 436 | + memcpy(pp, key->key, sizeof(key->key)); | ||
| 437 | + pp += sizeof(key->key); | ||
| 438 | + | ||
| 439 | + if (key->random1_size > 0) { | ||
| 440 | + memcpy(pp, key->random1, key->random1_size); | ||
| 441 | + } | ||
| 442 | + pp += key->random1_size; | ||
| 443 | + | ||
| 444 | + *(int32_t*)pp = key->offset; | ||
| 445 | + pp += 4; | ||
| 446 | + } | ||
| 447 | + void __srs_digest_copy_to(char*& pp, digest_block* digest, bool with_digest) | ||
| 448 | + { | ||
| 449 | + // 732bytes digest block without the 32bytes digest-data | ||
| 450 | + // nbytes digest block part1 | ||
| 451 | + *(int32_t*)pp = digest->offset; | ||
| 452 | + pp += 4; | ||
| 453 | + | ||
| 454 | + if (digest->random0_size > 0) { | ||
| 455 | + memcpy(pp, digest->random0, digest->random0_size); | ||
| 456 | + } | ||
| 457 | + pp += digest->random0_size; | ||
| 458 | + | ||
| 459 | + // digest | ||
| 460 | + if (with_digest) { | ||
| 461 | + memcpy(pp, digest->digest, 32); | ||
| 462 | + pp += 32; | ||
| 463 | + } | ||
| 464 | + | ||
| 465 | + // nbytes digest block part2 | ||
| 466 | + if (digest->random1_size > 0) { | ||
| 467 | + memcpy(pp, digest->random1, digest->random1_size); | ||
| 468 | + } | ||
| 469 | + pp += digest->random1_size; | ||
| 494 | } | 470 | } |
| 495 | -} | ||
| 496 | - | ||
| 497 | -/** | ||
| 498 | -* c1s1 is splited by digest: | ||
| 499 | -* c1s1-part1: n bytes (time, version, key and digest-part1). | ||
| 500 | -* digest-data: 32bytes | ||
| 501 | -* c1s1-part2: (1536-n-32)bytes (digest-part2) | ||
| 502 | -*/ | ||
| 503 | -char* srs::srs_bytes_join_schema0(int32_t time, int32_t version, key_block* key, digest_block* digest) | ||
| 504 | -{ | ||
| 505 | - char* bytes = new char[1536 -32]; | ||
| 506 | - | ||
| 507 | - srs_schema0_copy_to(bytes, false, time, version, key, digest); | ||
| 508 | - | ||
| 509 | - return bytes; | ||
| 510 | -} | ||
| 511 | - | ||
| 512 | -/** | ||
| 513 | -* c1s1 is splited by digest: | ||
| 514 | -* c1s1-part1: n bytes (time, version and digest-part1). | ||
| 515 | -* digest-data: 32bytes | ||
| 516 | -* c1s1-part2: (1536-n-32)bytes (digest-part2 and key) | ||
| 517 | -*/ | ||
| 518 | -char* srs::srs_bytes_join_schema1(int32_t time, int32_t version, digest_block* digest, key_block* key) | ||
| 519 | -{ | ||
| 520 | - char* bytes = new char[1536 -32]; | ||
| 521 | 471 | ||
| 522 | - srs_schema1_copy_to(bytes, false, time, version, digest, key); | ||
| 523 | - | ||
| 524 | - return bytes; | ||
| 525 | -} | ||
| 526 | - | ||
| 527 | -/** | ||
| 528 | -* compare the memory in bytes. | ||
| 529 | -*/ | ||
| 530 | -bool srs::srs_bytes_equals(void* pa, void* pb, int size) | ||
| 531 | -{ | ||
| 532 | - u_int8_t* a = (u_int8_t*)pa; | ||
| 533 | - u_int8_t* b = (u_int8_t*)pb; | 472 | + /** |
| 473 | + * copy whole c1s1 to bytes. | ||
| 474 | + */ | ||
| 475 | + void srs_schema0_copy_to(char* bytes, bool with_digest, | ||
| 476 | + int32_t time, int32_t version, key_block* key, digest_block* digest) | ||
| 477 | + { | ||
| 478 | + char* pp = bytes; | ||
| 534 | 479 | ||
| 535 | - for(int i = 0; i < size; i++){ | ||
| 536 | - if(a[i] != b[i]){ | ||
| 537 | - return false; | 480 | + __srs_time_copy_to(pp, time); |
| 481 | + __srs_version_copy_to(pp, version); | ||
| 482 | + __srs_key_copy_to(pp, key); | ||
| 483 | + __srs_digest_copy_to(pp, digest, with_digest); | ||
| 484 | + | ||
| 485 | + if (with_digest) { | ||
| 486 | + srs_assert(pp - bytes == 1536); | ||
| 487 | + } else { | ||
| 488 | + srs_assert(pp - bytes == 1536 - 32); | ||
| 538 | } | 489 | } |
| 539 | } | 490 | } |
| 540 | - | ||
| 541 | - return true; | ||
| 542 | -} | ||
| 543 | - | ||
| 544 | -c2s2::c2s2() | ||
| 545 | -{ | ||
| 546 | - srs_random_generate(random, 1504); | ||
| 547 | - srs_random_generate(digest, 32); | ||
| 548 | -} | ||
| 549 | - | ||
| 550 | -c2s2::~c2s2() | ||
| 551 | -{ | ||
| 552 | -} | ||
| 553 | - | ||
| 554 | -void c2s2::dump(char* _c2s2) | ||
| 555 | -{ | ||
| 556 | - memcpy(_c2s2, random, 1504); | ||
| 557 | - memcpy(_c2s2 + 1504, digest, 32); | ||
| 558 | -} | ||
| 559 | - | ||
| 560 | -void c2s2::parse(char* _c2s2) | ||
| 561 | -{ | ||
| 562 | - memcpy(random, _c2s2, 1504); | ||
| 563 | - memcpy(digest, _c2s2 + 1504, 32); | ||
| 564 | -} | ||
| 565 | - | ||
| 566 | -int c2s2::c2_create(c1s1* s1) | ||
| 567 | -{ | ||
| 568 | - int ret = ERROR_SUCCESS; | 491 | + void srs_schema1_copy_to(char* bytes, bool with_digest, |
| 492 | + int32_t time, int32_t version, digest_block* digest, key_block* key) | ||
| 493 | + { | ||
| 494 | + char* pp = bytes; | ||
| 569 | 495 | ||
| 570 | - char temp_key[OpensslHashSize]; | ||
| 571 | - if ((ret = openssl_HMACsha256(s1->get_digest(), 32, SrsGenuineFPKey, 62, temp_key)) != ERROR_SUCCESS) { | ||
| 572 | - srs_error("create c2 temp key failed. ret=%d", ret); | ||
| 573 | - return ret; | 496 | + __srs_time_copy_to(pp, time); |
| 497 | + __srs_version_copy_to(pp, version); | ||
| 498 | + __srs_digest_copy_to(pp, digest, with_digest); | ||
| 499 | + __srs_key_copy_to(pp, key); | ||
| 500 | + | ||
| 501 | + if (with_digest) { | ||
| 502 | + srs_assert(pp - bytes == 1536); | ||
| 503 | + } else { | ||
| 504 | + srs_assert(pp - bytes == 1536 - 32); | ||
| 505 | + } | ||
| 574 | } | 506 | } |
| 575 | - srs_verbose("generate c2 temp key success."); | ||
| 576 | 507 | ||
| 577 | - char _digest[OpensslHashSize]; | ||
| 578 | - if ((ret = openssl_HMACsha256(random, 1504, temp_key, 32, _digest)) != ERROR_SUCCESS) { | ||
| 579 | - srs_error("create c2 digest failed. ret=%d", ret); | ||
| 580 | - return ret; | 508 | + /** |
| 509 | + * c1s1 is splited by digest: | ||
| 510 | + * c1s1-part1: n bytes (time, version, key and digest-part1). | ||
| 511 | + * digest-data: 32bytes | ||
| 512 | + * c1s1-part2: (1536-n-32)bytes (digest-part2) | ||
| 513 | + */ | ||
| 514 | + char* srs_bytes_join_schema0(int32_t time, int32_t version, key_block* key, digest_block* digest) | ||
| 515 | + { | ||
| 516 | + char* bytes = new char[1536 -32]; | ||
| 517 | + | ||
| 518 | + srs_schema0_copy_to(bytes, false, time, version, key, digest); | ||
| 519 | + | ||
| 520 | + return bytes; | ||
| 521 | + } | ||
| 522 | + | ||
| 523 | + /** | ||
| 524 | + * c1s1 is splited by digest: | ||
| 525 | + * c1s1-part1: n bytes (time, version and digest-part1). | ||
| 526 | + * digest-data: 32bytes | ||
| 527 | + * c1s1-part2: (1536-n-32)bytes (digest-part2 and key) | ||
| 528 | + */ | ||
| 529 | + char* srs_bytes_join_schema1(int32_t time, int32_t version, digest_block* digest, key_block* key) | ||
| 530 | + { | ||
| 531 | + char* bytes = new char[1536 -32]; | ||
| 532 | + | ||
| 533 | + srs_schema1_copy_to(bytes, false, time, version, digest, key); | ||
| 534 | + | ||
| 535 | + return bytes; | ||
| 581 | } | 536 | } |
| 582 | - srs_verbose("generate c2 digest success."); | ||
| 583 | - | ||
| 584 | - memcpy(digest, _digest, 32); | ||
| 585 | 537 | ||
| 586 | - return ret; | ||
| 587 | -} | ||
| 588 | - | ||
| 589 | -int c2s2::c2_validate(c1s1* s1, bool& is_valid) | ||
| 590 | -{ | ||
| 591 | - is_valid = false; | ||
| 592 | - int ret = ERROR_SUCCESS; | 538 | + /** |
| 539 | + * compare the memory in bytes. | ||
| 540 | + */ | ||
| 541 | + bool srs_bytes_equals(void* pa, void* pb, int size) | ||
| 542 | + { | ||
| 543 | + u_int8_t* a = (u_int8_t*)pa; | ||
| 544 | + u_int8_t* b = (u_int8_t*)pb; | ||
| 545 | + | ||
| 546 | + if (!a && !b) { | ||
| 547 | + return true; | ||
| 548 | + } | ||
| 549 | + | ||
| 550 | + if (!a || !b) { | ||
| 551 | + return false; | ||
| 552 | + } | ||
| 553 | + | ||
| 554 | + for(int i = 0; i < size; i++){ | ||
| 555 | + if(a[i] != b[i]){ | ||
| 556 | + return false; | ||
| 557 | + } | ||
| 558 | + } | ||
| 593 | 559 | ||
| 594 | - char temp_key[OpensslHashSize]; | ||
| 595 | - if ((ret = openssl_HMACsha256(s1->get_digest(), 32, SrsGenuineFPKey, 62, temp_key)) != ERROR_SUCCESS) { | ||
| 596 | - srs_error("create c2 temp key failed. ret=%d", ret); | ||
| 597 | - return ret; | 560 | + return true; |
| 598 | } | 561 | } |
| 599 | - srs_verbose("generate c2 temp key success."); | ||
| 600 | 562 | ||
| 601 | - char _digest[OpensslHashSize]; | ||
| 602 | - if ((ret = openssl_HMACsha256(random, 1504, temp_key, 32, _digest)) != ERROR_SUCCESS) { | ||
| 603 | - srs_error("create c2 digest failed. ret=%d", ret); | ||
| 604 | - return ret; | 563 | + c2s2::c2s2() |
| 564 | + { | ||
| 565 | + srs_random_generate(random, 1504); | ||
| 566 | + srs_random_generate(digest, 32); | ||
| 605 | } | 567 | } |
| 606 | - srs_verbose("generate c2 digest success."); | ||
| 607 | - | ||
| 608 | - is_valid = srs_bytes_equals(digest, _digest, 32); | ||
| 609 | - | ||
| 610 | - return ret; | ||
| 611 | -} | ||
| 612 | - | ||
| 613 | -int c2s2::s2_create(c1s1* c1) | ||
| 614 | -{ | ||
| 615 | - int ret = ERROR_SUCCESS; | ||
| 616 | 568 | ||
| 617 | - char temp_key[OpensslHashSize]; | ||
| 618 | - if ((ret = openssl_HMACsha256(c1->get_digest(), 32, SrsGenuineFMSKey, 68, temp_key)) != ERROR_SUCCESS) { | ||
| 619 | - srs_error("create s2 temp key failed. ret=%d", ret); | ||
| 620 | - return ret; | 569 | + c2s2::~c2s2() |
| 570 | + { | ||
| 621 | } | 571 | } |
| 622 | - srs_verbose("generate s2 temp key success."); | ||
| 623 | 572 | ||
| 624 | - char _digest[OpensslHashSize]; | ||
| 625 | - if ((ret = openssl_HMACsha256(random, 1504, temp_key, 32, _digest)) != ERROR_SUCCESS) { | ||
| 626 | - srs_error("create s2 digest failed. ret=%d", ret); | ||
| 627 | - return ret; | 573 | + void c2s2::dump(char* _c2s2) |
| 574 | + { | ||
| 575 | + memcpy(_c2s2, random, 1504); | ||
| 576 | + memcpy(_c2s2 + 1504, digest, 32); | ||
| 628 | } | 577 | } |
| 629 | - srs_verbose("generate s2 digest success."); | ||
| 630 | - | ||
| 631 | - memcpy(digest, _digest, 32); | ||
| 632 | - | ||
| 633 | - return ret; | ||
| 634 | -} | ||
| 635 | - | ||
| 636 | -int c2s2::s2_validate(c1s1* c1, bool& is_valid) | ||
| 637 | -{ | ||
| 638 | - is_valid = false; | ||
| 639 | - int ret = ERROR_SUCCESS; | ||
| 640 | 578 | ||
| 641 | - char temp_key[OpensslHashSize]; | ||
| 642 | - if ((ret = openssl_HMACsha256(c1->get_digest(), 32, SrsGenuineFMSKey, 68, temp_key)) != ERROR_SUCCESS) { | ||
| 643 | - srs_error("create s2 temp key failed. ret=%d", ret); | ||
| 644 | - return ret; | 579 | + void c2s2::parse(char* _c2s2) |
| 580 | + { | ||
| 581 | + memcpy(random, _c2s2, 1504); | ||
| 582 | + memcpy(digest, _c2s2 + 1504, 32); | ||
| 645 | } | 583 | } |
| 646 | - srs_verbose("generate s2 temp key success."); | ||
| 647 | 584 | ||
| 648 | - char _digest[OpensslHashSize]; | ||
| 649 | - if ((ret = openssl_HMACsha256(random, 1504, temp_key, 32, _digest)) != ERROR_SUCCESS) { | ||
| 650 | - srs_error("create s2 digest failed. ret=%d", ret); | 585 | + int c2s2::c2_create(c1s1* s1) |
| 586 | + { | ||
| 587 | + int ret = ERROR_SUCCESS; | ||
| 588 | + | ||
| 589 | + char temp_key[OpensslHashSize]; | ||
| 590 | + if ((ret = openssl_HMACsha256(s1->get_digest(), 32, SrsGenuineFPKey, 62, temp_key)) != ERROR_SUCCESS) { | ||
| 591 | + srs_error("create c2 temp key failed. ret=%d", ret); | ||
| 592 | + return ret; | ||
| 593 | + } | ||
| 594 | + srs_verbose("generate c2 temp key success."); | ||
| 595 | + | ||
| 596 | + char _digest[OpensslHashSize]; | ||
| 597 | + if ((ret = openssl_HMACsha256(random, 1504, temp_key, 32, _digest)) != ERROR_SUCCESS) { | ||
| 598 | + srs_error("create c2 digest failed. ret=%d", ret); | ||
| 599 | + return ret; | ||
| 600 | + } | ||
| 601 | + srs_verbose("generate c2 digest success."); | ||
| 602 | + | ||
| 603 | + memcpy(digest, _digest, 32); | ||
| 604 | + | ||
| 651 | return ret; | 605 | return ret; |
| 652 | } | 606 | } |
| 653 | - srs_verbose("generate s2 digest success."); | ||
| 654 | - | ||
| 655 | - is_valid = srs_bytes_equals(digest, _digest, 32); | ||
| 656 | - | ||
| 657 | - return ret; | ||
| 658 | -} | ||
| 659 | - | ||
| 660 | -// TODO: FIXME: move to the right position. | ||
| 661 | -c1s1::c1s1() | ||
| 662 | -{ | ||
| 663 | - schema = srs_schema_invalid; | ||
| 664 | -} | ||
| 665 | -c1s1::~c1s1() | ||
| 666 | -{ | ||
| 667 | - destroy_blocks(); | ||
| 668 | -} | ||
| 669 | - | ||
| 670 | -char* c1s1::get_digest() | ||
| 671 | -{ | ||
| 672 | - srs_assert(schema != srs_schema_invalid); | ||
| 673 | - | ||
| 674 | - if (schema == srs_schema0) { | ||
| 675 | - return block1.digest.digest; | ||
| 676 | - } else { | ||
| 677 | - return block0.digest.digest; | ||
| 678 | - } | ||
| 679 | -} | ||
| 680 | - | ||
| 681 | -void c1s1::dump(char* _c1s1) | ||
| 682 | -{ | ||
| 683 | - srs_assert(schema != srs_schema_invalid); | ||
| 684 | - | ||
| 685 | - if (schema == srs_schema0) { | ||
| 686 | - srs_schema0_copy_to(_c1s1, true, time, version, &block0.key, &block1.digest); | ||
| 687 | - } else { | ||
| 688 | - srs_schema1_copy_to(_c1s1, true, time, version, &block0.digest, &block1.key); | ||
| 689 | - } | ||
| 690 | -} | ||
| 691 | - | ||
| 692 | -int c1s1::parse(char* _c1s1, srs_schema_type _schema) | ||
| 693 | -{ | ||
| 694 | - int ret = ERROR_SUCCESS; | ||
| 695 | 607 | ||
| 696 | - if (_schema == srs_schema_invalid) { | ||
| 697 | - ret = ERROR_RTMP_CH_SCHEMA; | ||
| 698 | - srs_error("parse c1 failed. invalid schema=%d, ret=%d", _schema, ret); | 608 | + int c2s2::c2_validate(c1s1* s1, bool& is_valid) |
| 609 | + { | ||
| 610 | + is_valid = false; | ||
| 611 | + int ret = ERROR_SUCCESS; | ||
| 612 | + | ||
| 613 | + char temp_key[OpensslHashSize]; | ||
| 614 | + if ((ret = openssl_HMACsha256(s1->get_digest(), 32, SrsGenuineFPKey, 62, temp_key)) != ERROR_SUCCESS) { | ||
| 615 | + srs_error("create c2 temp key failed. ret=%d", ret); | ||
| 616 | + return ret; | ||
| 617 | + } | ||
| 618 | + srs_verbose("generate c2 temp key success."); | ||
| 619 | + | ||
| 620 | + char _digest[OpensslHashSize]; | ||
| 621 | + if ((ret = openssl_HMACsha256(random, 1504, temp_key, 32, _digest)) != ERROR_SUCCESS) { | ||
| 622 | + srs_error("create c2 digest failed. ret=%d", ret); | ||
| 623 | + return ret; | ||
| 624 | + } | ||
| 625 | + srs_verbose("generate c2 digest success."); | ||
| 626 | + | ||
| 627 | + is_valid = srs_bytes_equals(digest, _digest, 32); | ||
| 628 | + | ||
| 699 | return ret; | 629 | return ret; |
| 700 | } | 630 | } |
| 701 | 631 | ||
| 702 | - destroy_blocks(); | ||
| 703 | - | ||
| 704 | - time = *(int32_t*)_c1s1; | ||
| 705 | - version = *(int32_t*)(_c1s1 + 4); // client c1 version | ||
| 706 | - | ||
| 707 | - if (_schema == srs_schema0) { | ||
| 708 | - if ((ret = srs_key_block_parse(&block0.key, _c1s1 + 8)) != ERROR_SUCCESS) { | ||
| 709 | - srs_error("parse the c1 key failed. ret=%d", ret); | 632 | + int c2s2::s2_create(c1s1* c1) |
| 633 | + { | ||
| 634 | + int ret = ERROR_SUCCESS; | ||
| 635 | + | ||
| 636 | + char temp_key[OpensslHashSize]; | ||
| 637 | + if ((ret = openssl_HMACsha256(c1->get_digest(), 32, SrsGenuineFMSKey, 68, temp_key)) != ERROR_SUCCESS) { | ||
| 638 | + srs_error("create s2 temp key failed. ret=%d", ret); | ||
| 710 | return ret; | 639 | return ret; |
| 711 | } | 640 | } |
| 712 | - if ((ret = srs_digest_block_parse(&block1.digest, _c1s1 + 8 + 764)) != ERROR_SUCCESS) { | ||
| 713 | - srs_error("parse the c1 digest failed. ret=%d", ret); | 641 | + srs_verbose("generate s2 temp key success."); |
| 642 | + | ||
| 643 | + char _digest[OpensslHashSize]; | ||
| 644 | + if ((ret = openssl_HMACsha256(random, 1504, temp_key, 32, _digest)) != ERROR_SUCCESS) { | ||
| 645 | + srs_error("create s2 digest failed. ret=%d", ret); | ||
| 714 | return ret; | 646 | return ret; |
| 715 | } | 647 | } |
| 716 | - srs_verbose("parse c1 key-digest success"); | ||
| 717 | - } else if (_schema == srs_schema1) { | ||
| 718 | - if ((ret = srs_digest_block_parse(&block0.digest, _c1s1 + 8)) != ERROR_SUCCESS) { | ||
| 719 | - srs_error("parse the c1 key failed. ret=%d", ret); | 648 | + srs_verbose("generate s2 digest success."); |
| 649 | + | ||
| 650 | + memcpy(digest, _digest, 32); | ||
| 651 | + | ||
| 652 | + return ret; | ||
| 653 | + } | ||
| 654 | + | ||
| 655 | + int c2s2::s2_validate(c1s1* c1, bool& is_valid) | ||
| 656 | + { | ||
| 657 | + is_valid = false; | ||
| 658 | + int ret = ERROR_SUCCESS; | ||
| 659 | + | ||
| 660 | + char temp_key[OpensslHashSize]; | ||
| 661 | + if ((ret = openssl_HMACsha256(c1->get_digest(), 32, SrsGenuineFMSKey, 68, temp_key)) != ERROR_SUCCESS) { | ||
| 662 | + srs_error("create s2 temp key failed. ret=%d", ret); | ||
| 720 | return ret; | 663 | return ret; |
| 721 | } | 664 | } |
| 722 | - if ((ret = srs_key_block_parse(&block1.key, _c1s1 + 8 + 764)) != ERROR_SUCCESS) { | ||
| 723 | - srs_error("parse the c1 digest failed. ret=%d", ret); | 665 | + srs_verbose("generate s2 temp key success."); |
| 666 | + | ||
| 667 | + char _digest[OpensslHashSize]; | ||
| 668 | + if ((ret = openssl_HMACsha256(random, 1504, temp_key, 32, _digest)) != ERROR_SUCCESS) { | ||
| 669 | + srs_error("create s2 digest failed. ret=%d", ret); | ||
| 724 | return ret; | 670 | return ret; |
| 725 | } | 671 | } |
| 726 | - srs_verbose("parse c1 digest-key success"); | ||
| 727 | - } else { | ||
| 728 | - ret = ERROR_RTMP_CH_SCHEMA; | ||
| 729 | - srs_error("parse c1 failed. invalid schema=%d, ret=%d", _schema, ret); | 672 | + srs_verbose("generate s2 digest success."); |
| 673 | + | ||
| 674 | + is_valid = srs_bytes_equals(digest, _digest, 32); | ||
| 675 | + | ||
| 730 | return ret; | 676 | return ret; |
| 731 | } | 677 | } |
| 732 | 678 | ||
| 733 | - schema = _schema; | ||
| 734 | - | ||
| 735 | - return ret; | ||
| 736 | -} | ||
| 737 | - | ||
| 738 | -int c1s1::c1_create(srs_schema_type _schema) | ||
| 739 | -{ | ||
| 740 | - int ret = ERROR_SUCCESS; | ||
| 741 | - | ||
| 742 | - if (_schema == srs_schema_invalid) { | ||
| 743 | - ret = ERROR_RTMP_CH_SCHEMA; | ||
| 744 | - srs_error("create c1 failed. invalid schema=%d, ret=%d", _schema, ret); | ||
| 745 | - return ret; | 679 | + // TODO: FIXME: move to the right position. |
| 680 | + c1s1::c1s1() | ||
| 681 | + { | ||
| 682 | + schema = srs_schema_invalid; | ||
| 746 | } | 683 | } |
| 747 | - | ||
| 748 | - destroy_blocks(); | ||
| 749 | - | ||
| 750 | - time = ::time(NULL); | ||
| 751 | - version = 0x02070080; // client c1 version | ||
| 752 | - | ||
| 753 | - if (_schema == srs_schema0) { | ||
| 754 | - srs_key_block_init(&block0.key); | ||
| 755 | - srs_digest_block_init(&block1.digest); | ||
| 756 | - } else { | ||
| 757 | - srs_digest_block_init(&block0.digest); | ||
| 758 | - srs_key_block_init(&block1.key); | 684 | + c1s1::~c1s1() |
| 685 | + { | ||
| 686 | + destroy_blocks(); | ||
| 759 | } | 687 | } |
| 760 | 688 | ||
| 761 | - schema = _schema; | ||
| 762 | - | ||
| 763 | - char* digest = NULL; | ||
| 764 | - | ||
| 765 | - if ((ret = calc_c1_digest(digest)) != ERROR_SUCCESS) { | ||
| 766 | - srs_error("sign c1 error, failed to calc digest. ret=%d", ret); | ||
| 767 | - return ret; | 689 | + char* c1s1::get_digest() |
| 690 | + { | ||
| 691 | + srs_assert(schema != srs_schema_invalid); | ||
| 692 | + | ||
| 693 | + if (schema == srs_schema0) { | ||
| 694 | + return block1.digest.digest; | ||
| 695 | + } else { | ||
| 696 | + return block0.digest.digest; | ||
| 697 | + } | ||
| 768 | } | 698 | } |
| 769 | 699 | ||
| 770 | - srs_assert(digest != NULL); | ||
| 771 | - SrsAutoFree(char, digest, true); | ||
| 772 | - | ||
| 773 | - if (schema == srs_schema0) { | ||
| 774 | - memcpy(block1.digest.digest, digest, 32); | ||
| 775 | - } else { | ||
| 776 | - memcpy(block0.digest.digest, digest, 32); | 700 | + void c1s1::dump(char* _c1s1) |
| 701 | + { | ||
| 702 | + srs_assert(schema != srs_schema_invalid); | ||
| 703 | + | ||
| 704 | + if (schema == srs_schema0) { | ||
| 705 | + srs_schema0_copy_to(_c1s1, true, time, version, &block0.key, &block1.digest); | ||
| 706 | + } else { | ||
| 707 | + srs_schema1_copy_to(_c1s1, true, time, version, &block0.digest, &block1.key); | ||
| 708 | + } | ||
| 777 | } | 709 | } |
| 778 | 710 | ||
| 779 | - return ret; | ||
| 780 | -} | ||
| 781 | - | ||
| 782 | -int c1s1::c1_validate_digest(bool& is_valid) | ||
| 783 | -{ | ||
| 784 | - is_valid = false; | ||
| 785 | - int ret = ERROR_SUCCESS; | ||
| 786 | - | ||
| 787 | - char* c1_digest = NULL; | ||
| 788 | - | ||
| 789 | - if ((ret = calc_c1_digest(c1_digest)) != ERROR_SUCCESS) { | ||
| 790 | - srs_error("validate c1 error, failed to calc digest. ret=%d", ret); | 711 | + int c1s1::parse(char* _c1s1, srs_schema_type _schema) |
| 712 | + { | ||
| 713 | + int ret = ERROR_SUCCESS; | ||
| 714 | + | ||
| 715 | + if (_schema == srs_schema_invalid) { | ||
| 716 | + ret = ERROR_RTMP_CH_SCHEMA; | ||
| 717 | + srs_error("parse c1 failed. invalid schema=%d, ret=%d", _schema, ret); | ||
| 718 | + return ret; | ||
| 719 | + } | ||
| 720 | + | ||
| 721 | + destroy_blocks(); | ||
| 722 | + | ||
| 723 | + time = *(int32_t*)_c1s1; | ||
| 724 | + version = *(int32_t*)(_c1s1 + 4); // client c1 version | ||
| 725 | + | ||
| 726 | + if (_schema == srs_schema0) { | ||
| 727 | + if ((ret = srs_key_block_parse(&block0.key, _c1s1 + 8)) != ERROR_SUCCESS) { | ||
| 728 | + srs_error("parse the c1 key failed. ret=%d", ret); | ||
| 729 | + return ret; | ||
| 730 | + } | ||
| 731 | + if ((ret = srs_digest_block_parse(&block1.digest, _c1s1 + 8 + 764)) != ERROR_SUCCESS) { | ||
| 732 | + srs_error("parse the c1 digest failed. ret=%d", ret); | ||
| 733 | + return ret; | ||
| 734 | + } | ||
| 735 | + srs_verbose("parse c1 key-digest success"); | ||
| 736 | + } else if (_schema == srs_schema1) { | ||
| 737 | + if ((ret = srs_digest_block_parse(&block0.digest, _c1s1 + 8)) != ERROR_SUCCESS) { | ||
| 738 | + srs_error("parse the c1 key failed. ret=%d", ret); | ||
| 739 | + return ret; | ||
| 740 | + } | ||
| 741 | + if ((ret = srs_key_block_parse(&block1.key, _c1s1 + 8 + 764)) != ERROR_SUCCESS) { | ||
| 742 | + srs_error("parse the c1 digest failed. ret=%d", ret); | ||
| 743 | + return ret; | ||
| 744 | + } | ||
| 745 | + srs_verbose("parse c1 digest-key success"); | ||
| 746 | + } else { | ||
| 747 | + ret = ERROR_RTMP_CH_SCHEMA; | ||
| 748 | + srs_error("parse c1 failed. invalid schema=%d, ret=%d", _schema, ret); | ||
| 749 | + return ret; | ||
| 750 | + } | ||
| 751 | + | ||
| 752 | + schema = _schema; | ||
| 753 | + | ||
| 791 | return ret; | 754 | return ret; |
| 792 | } | 755 | } |
| 793 | 756 | ||
| 794 | - srs_assert(c1_digest != NULL); | ||
| 795 | - SrsAutoFree(char, c1_digest, true); | ||
| 796 | - | ||
| 797 | - if (schema == srs_schema0) { | ||
| 798 | - is_valid = srs_bytes_equals(block1.digest.digest, c1_digest, 32); | ||
| 799 | - } else { | ||
| 800 | - is_valid = srs_bytes_equals(block0.digest.digest, c1_digest, 32); | ||
| 801 | - } | ||
| 802 | - | ||
| 803 | - return ret; | ||
| 804 | -} | ||
| 805 | - | ||
| 806 | -int c1s1::s1_validate_digest(bool& is_valid) | ||
| 807 | -{ | ||
| 808 | - is_valid = false; | ||
| 809 | - int ret = ERROR_SUCCESS; | ||
| 810 | - | ||
| 811 | - char* s1_digest = NULL; | ||
| 812 | - | ||
| 813 | - if ((ret = calc_s1_digest(s1_digest)) != ERROR_SUCCESS) { | ||
| 814 | - srs_error("validate s1 error, failed to calc digest. ret=%d", ret); | 757 | + int c1s1::c1_create(srs_schema_type _schema) |
| 758 | + { | ||
| 759 | + int ret = ERROR_SUCCESS; | ||
| 760 | + | ||
| 761 | + if (_schema == srs_schema_invalid) { | ||
| 762 | + ret = ERROR_RTMP_CH_SCHEMA; | ||
| 763 | + srs_error("create c1 failed. invalid schema=%d, ret=%d", _schema, ret); | ||
| 764 | + return ret; | ||
| 765 | + } | ||
| 766 | + | ||
| 767 | + destroy_blocks(); | ||
| 768 | + | ||
| 769 | + time = ::time(NULL); | ||
| 770 | + version = 0x02070080; // client c1 version | ||
| 771 | + | ||
| 772 | + if (_schema == srs_schema0) { | ||
| 773 | + srs_key_block_init(&block0.key); | ||
| 774 | + srs_digest_block_init(&block1.digest); | ||
| 775 | + } else { | ||
| 776 | + srs_digest_block_init(&block0.digest); | ||
| 777 | + srs_key_block_init(&block1.key); | ||
| 778 | + } | ||
| 779 | + | ||
| 780 | + schema = _schema; | ||
| 781 | + | ||
| 782 | + char* digest = NULL; | ||
| 783 | + | ||
| 784 | + if ((ret = calc_c1_digest(digest)) != ERROR_SUCCESS) { | ||
| 785 | + srs_error("sign c1 error, failed to calc digest. ret=%d", ret); | ||
| 786 | + return ret; | ||
| 787 | + } | ||
| 788 | + | ||
| 789 | + srs_assert(digest != NULL); | ||
| 790 | + SrsAutoFree(char, digest, true); | ||
| 791 | + | ||
| 792 | + if (schema == srs_schema0) { | ||
| 793 | + memcpy(block1.digest.digest, digest, 32); | ||
| 794 | + } else { | ||
| 795 | + memcpy(block0.digest.digest, digest, 32); | ||
| 796 | + } | ||
| 797 | + | ||
| 815 | return ret; | 798 | return ret; |
| 816 | } | 799 | } |
| 817 | 800 | ||
| 818 | - srs_assert(s1_digest != NULL); | ||
| 819 | - SrsAutoFree(char, s1_digest, true); | ||
| 820 | - | ||
| 821 | - if (schema == srs_schema0) { | ||
| 822 | - is_valid = srs_bytes_equals(block1.digest.digest, s1_digest, 32); | ||
| 823 | - } else { | ||
| 824 | - is_valid = srs_bytes_equals(block0.digest.digest, s1_digest, 32); | ||
| 825 | - } | ||
| 826 | - | ||
| 827 | - return ret; | ||
| 828 | -} | ||
| 829 | - | ||
| 830 | -int c1s1::s1_create(c1s1* c1) | ||
| 831 | -{ | ||
| 832 | - int ret = ERROR_SUCCESS; | ||
| 833 | - | ||
| 834 | - if (c1->schema == srs_schema_invalid) { | ||
| 835 | - ret = ERROR_RTMP_CH_SCHEMA; | ||
| 836 | - srs_error("create s1 failed. invalid schema=%d, ret=%d", c1->schema, ret); | 801 | + int c1s1::c1_validate_digest(bool& is_valid) |
| 802 | + { | ||
| 803 | + is_valid = false; | ||
| 804 | + int ret = ERROR_SUCCESS; | ||
| 805 | + | ||
| 806 | + char* c1_digest = NULL; | ||
| 807 | + | ||
| 808 | + if ((ret = calc_c1_digest(c1_digest)) != ERROR_SUCCESS) { | ||
| 809 | + srs_error("validate c1 error, failed to calc digest. ret=%d", ret); | ||
| 810 | + return ret; | ||
| 811 | + } | ||
| 812 | + | ||
| 813 | + srs_assert(c1_digest != NULL); | ||
| 814 | + SrsAutoFree(char, c1_digest, true); | ||
| 815 | + | ||
| 816 | + if (schema == srs_schema0) { | ||
| 817 | + is_valid = srs_bytes_equals(block1.digest.digest, c1_digest, 32); | ||
| 818 | + } else { | ||
| 819 | + is_valid = srs_bytes_equals(block0.digest.digest, c1_digest, 32); | ||
| 820 | + } | ||
| 821 | + | ||
| 837 | return ret; | 822 | return ret; |
| 838 | } | 823 | } |
| 839 | 824 | ||
| 840 | - destroy_blocks(); | ||
| 841 | - schema = c1->schema; | ||
| 842 | - | ||
| 843 | - time = ::time(NULL); | ||
| 844 | - version = 0x01000504; // server s1 version | ||
| 845 | - | ||
| 846 | - if (schema == srs_schema0) { | ||
| 847 | - srs_key_block_init(&block0.key); | ||
| 848 | - srs_digest_block_init(&block1.digest); | ||
| 849 | - } else { | ||
| 850 | - srs_digest_block_init(&block0.digest); | ||
| 851 | - srs_key_block_init(&block1.key); | 825 | + int c1s1::s1_validate_digest(bool& is_valid) |
| 826 | + { | ||
| 827 | + is_valid = false; | ||
| 828 | + int ret = ERROR_SUCCESS; | ||
| 829 | + | ||
| 830 | + char* s1_digest = NULL; | ||
| 831 | + | ||
| 832 | + if ((ret = calc_s1_digest(s1_digest)) != ERROR_SUCCESS) { | ||
| 833 | + srs_error("validate s1 error, failed to calc digest. ret=%d", ret); | ||
| 834 | + return ret; | ||
| 835 | + } | ||
| 836 | + | ||
| 837 | + srs_assert(s1_digest != NULL); | ||
| 838 | + SrsAutoFree(char, s1_digest, true); | ||
| 839 | + | ||
| 840 | + if (schema == srs_schema0) { | ||
| 841 | + is_valid = srs_bytes_equals(block1.digest.digest, s1_digest, 32); | ||
| 842 | + } else { | ||
| 843 | + is_valid = srs_bytes_equals(block0.digest.digest, s1_digest, 32); | ||
| 844 | + } | ||
| 845 | + | ||
| 846 | + return ret; | ||
| 852 | } | 847 | } |
| 853 | 848 | ||
| 854 | - if (schema == srs_schema0) { | ||
| 855 | - if ((ret = openssl_generate_key(c1->block0.key.key, block0.key.key, 128)) != ERROR_SUCCESS) { | ||
| 856 | - srs_error("calc s1 key failed. ret=%d", ret); | 849 | + int c1s1::s1_create(c1s1* c1) |
| 850 | + { | ||
| 851 | + int ret = ERROR_SUCCESS; | ||
| 852 | + | ||
| 853 | + if (c1->schema == srs_schema_invalid) { | ||
| 854 | + ret = ERROR_RTMP_CH_SCHEMA; | ||
| 855 | + srs_error("create s1 failed. invalid schema=%d, ret=%d", c1->schema, ret); | ||
| 857 | return ret; | 856 | return ret; |
| 858 | } | 857 | } |
| 859 | - } else { | ||
| 860 | - if ((ret = openssl_generate_key(c1->block1.key.key, block1.key.key, 128)) != ERROR_SUCCESS) { | ||
| 861 | - srs_error("calc s1 key failed. ret=%d", ret); | 858 | + |
| 859 | + destroy_blocks(); | ||
| 860 | + schema = c1->schema; | ||
| 861 | + | ||
| 862 | + time = ::time(NULL); | ||
| 863 | + version = 0x01000504; // server s1 version | ||
| 864 | + | ||
| 865 | + if (schema == srs_schema0) { | ||
| 866 | + srs_key_block_init(&block0.key); | ||
| 867 | + srs_digest_block_init(&block1.digest); | ||
| 868 | + } else { | ||
| 869 | + srs_digest_block_init(&block0.digest); | ||
| 870 | + srs_key_block_init(&block1.key); | ||
| 871 | + } | ||
| 872 | + | ||
| 873 | + if (schema == srs_schema0) { | ||
| 874 | + if ((ret = openssl_generate_key(c1->block0.key.key, block0.key.key, 128)) != ERROR_SUCCESS) { | ||
| 875 | + srs_error("calc s1 key failed. ret=%d", ret); | ||
| 876 | + return ret; | ||
| 877 | + } | ||
| 878 | + } else { | ||
| 879 | + if ((ret = openssl_generate_key(c1->block1.key.key, block1.key.key, 128)) != ERROR_SUCCESS) { | ||
| 880 | + srs_error("calc s1 key failed. ret=%d", ret); | ||
| 881 | + return ret; | ||
| 882 | + } | ||
| 883 | + } | ||
| 884 | + srs_verbose("calc s1 key success."); | ||
| 885 | + | ||
| 886 | + char* s1_digest = NULL; | ||
| 887 | + if ((ret = calc_s1_digest(s1_digest)) != ERROR_SUCCESS) { | ||
| 888 | + srs_error("calc s1 digest failed. ret=%d", ret); | ||
| 862 | return ret; | 889 | return ret; |
| 863 | } | 890 | } |
| 864 | - } | ||
| 865 | - srs_verbose("calc s1 key success."); | 891 | + srs_verbose("calc s1 digest success."); |
| 892 | + | ||
| 893 | + srs_assert(s1_digest != NULL); | ||
| 894 | + SrsAutoFree(char, s1_digest, true); | ||
| 895 | + | ||
| 896 | + if (schema == srs_schema0) { | ||
| 897 | + memcpy(block1.digest.digest, s1_digest, 32); | ||
| 898 | + } else { | ||
| 899 | + memcpy(block0.digest.digest, s1_digest, 32); | ||
| 900 | + } | ||
| 901 | + srs_verbose("copy s1 key success."); | ||
| 866 | 902 | ||
| 867 | - char* s1_digest = NULL; | ||
| 868 | - if ((ret = calc_s1_digest(s1_digest)) != ERROR_SUCCESS) { | ||
| 869 | - srs_error("calc s1 digest failed. ret=%d", ret); | ||
| 870 | return ret; | 903 | return ret; |
| 871 | } | 904 | } |
| 872 | - srs_verbose("calc s1 digest success."); | ||
| 873 | - | ||
| 874 | - srs_assert(s1_digest != NULL); | ||
| 875 | - SrsAutoFree(char, s1_digest, true); | ||
| 876 | - | ||
| 877 | - if (schema == srs_schema0) { | ||
| 878 | - memcpy(block1.digest.digest, s1_digest, 32); | ||
| 879 | - } else { | ||
| 880 | - memcpy(block0.digest.digest, s1_digest, 32); | ||
| 881 | - } | ||
| 882 | - srs_verbose("copy s1 key success."); | ||
| 883 | 905 | ||
| 884 | - return ret; | ||
| 885 | -} | ||
| 886 | - | ||
| 887 | -int c1s1::calc_s1_digest(char*& digest) | ||
| 888 | -{ | ||
| 889 | - int ret = ERROR_SUCCESS; | ||
| 890 | - | ||
| 891 | - srs_assert(schema == srs_schema0 || schema == srs_schema1); | ||
| 892 | - | ||
| 893 | - char* c1s1_joined_bytes = NULL; | ||
| 894 | - | ||
| 895 | - if (schema == srs_schema0) { | ||
| 896 | - c1s1_joined_bytes = srs_bytes_join_schema0(time, version, &block0.key, &block1.digest); | ||
| 897 | - } else { | ||
| 898 | - c1s1_joined_bytes = srs_bytes_join_schema1(time, version, &block0.digest, &block1.key); | ||
| 899 | - } | ||
| 900 | - | ||
| 901 | - srs_assert(c1s1_joined_bytes != NULL); | ||
| 902 | - SrsAutoFree(char, c1s1_joined_bytes, true); | 906 | + int c1s1::calc_s1_digest(char*& digest) |
| 907 | + { | ||
| 908 | + int ret = ERROR_SUCCESS; | ||
| 909 | + | ||
| 910 | + srs_assert(schema == srs_schema0 || schema == srs_schema1); | ||
| 911 | + | ||
| 912 | + char* c1s1_joined_bytes = NULL; | ||
| 903 | 913 | ||
| 904 | - digest = new char[OpensslHashSize]; | ||
| 905 | - if ((ret = openssl_HMACsha256(c1s1_joined_bytes, 1536 - 32, SrsGenuineFMSKey, 36, digest)) != ERROR_SUCCESS) { | ||
| 906 | - srs_error("calc digest for s1 failed. ret=%d", ret); | 914 | + if (schema == srs_schema0) { |
| 915 | + c1s1_joined_bytes = srs_bytes_join_schema0(time, version, &block0.key, &block1.digest); | ||
| 916 | + } else { | ||
| 917 | + c1s1_joined_bytes = srs_bytes_join_schema1(time, version, &block0.digest, &block1.key); | ||
| 918 | + } | ||
| 919 | + | ||
| 920 | + srs_assert(c1s1_joined_bytes != NULL); | ||
| 921 | + SrsAutoFree(char, c1s1_joined_bytes, true); | ||
| 922 | + | ||
| 923 | + digest = new char[OpensslHashSize]; | ||
| 924 | + if ((ret = openssl_HMACsha256(c1s1_joined_bytes, 1536 - 32, SrsGenuineFMSKey, 36, digest)) != ERROR_SUCCESS) { | ||
| 925 | + srs_error("calc digest for s1 failed. ret=%d", ret); | ||
| 926 | + return ret; | ||
| 927 | + } | ||
| 928 | + srs_verbose("digest calculated for s1"); | ||
| 929 | + | ||
| 907 | return ret; | 930 | return ret; |
| 908 | } | 931 | } |
| 909 | - srs_verbose("digest calculated for s1"); | ||
| 910 | 932 | ||
| 911 | - return ret; | ||
| 912 | -} | ||
| 913 | - | ||
| 914 | -int c1s1::calc_c1_digest(char*& digest) | ||
| 915 | -{ | ||
| 916 | - int ret = ERROR_SUCCESS; | ||
| 917 | - | ||
| 918 | - srs_assert(schema == srs_schema0 || schema == srs_schema1); | ||
| 919 | - | ||
| 920 | - char* c1s1_joined_bytes = NULL; | ||
| 921 | - | ||
| 922 | - if (schema == srs_schema0) { | ||
| 923 | - c1s1_joined_bytes = srs_bytes_join_schema0(time, version, &block0.key, &block1.digest); | ||
| 924 | - } else { | ||
| 925 | - c1s1_joined_bytes = srs_bytes_join_schema1(time, version, &block0.digest, &block1.key); | ||
| 926 | - } | ||
| 927 | - | ||
| 928 | - srs_assert(c1s1_joined_bytes != NULL); | ||
| 929 | - SrsAutoFree(char, c1s1_joined_bytes, true); | 933 | + int c1s1::calc_c1_digest(char*& digest) |
| 934 | + { | ||
| 935 | + int ret = ERROR_SUCCESS; | ||
| 936 | + | ||
| 937 | + srs_assert(schema == srs_schema0 || schema == srs_schema1); | ||
| 938 | + | ||
| 939 | + char* c1s1_joined_bytes = NULL; | ||
| 930 | 940 | ||
| 931 | - digest = new char[OpensslHashSize]; | ||
| 932 | - if ((ret = openssl_HMACsha256(c1s1_joined_bytes, 1536 - 32, SrsGenuineFPKey, 30, digest)) != ERROR_SUCCESS) { | ||
| 933 | - srs_error("calc digest for c1 failed. ret=%d", ret); | 941 | + if (schema == srs_schema0) { |
| 942 | + c1s1_joined_bytes = srs_bytes_join_schema0(time, version, &block0.key, &block1.digest); | ||
| 943 | + } else { | ||
| 944 | + c1s1_joined_bytes = srs_bytes_join_schema1(time, version, &block0.digest, &block1.key); | ||
| 945 | + } | ||
| 946 | + | ||
| 947 | + srs_assert(c1s1_joined_bytes != NULL); | ||
| 948 | + SrsAutoFree(char, c1s1_joined_bytes, true); | ||
| 949 | + | ||
| 950 | + digest = new char[OpensslHashSize]; | ||
| 951 | + if ((ret = openssl_HMACsha256(c1s1_joined_bytes, 1536 - 32, SrsGenuineFPKey, 30, digest)) != ERROR_SUCCESS) { | ||
| 952 | + srs_error("calc digest for c1 failed. ret=%d", ret); | ||
| 953 | + return ret; | ||
| 954 | + } | ||
| 955 | + srs_verbose("digest calculated for c1"); | ||
| 956 | + | ||
| 934 | return ret; | 957 | return ret; |
| 935 | } | 958 | } |
| 936 | - srs_verbose("digest calculated for c1"); | ||
| 937 | - | ||
| 938 | - return ret; | ||
| 939 | -} | ||
| 940 | - | ||
| 941 | -void c1s1::destroy_blocks() | ||
| 942 | -{ | ||
| 943 | - if (schema == srs_schema_invalid) { | ||
| 944 | - return; | ||
| 945 | - } | ||
| 946 | 959 | ||
| 947 | - if (schema == srs_schema0) { | ||
| 948 | - srs_key_block_free(&block0.key); | ||
| 949 | - srs_digest_block_free(&block1.digest); | ||
| 950 | - } else { | ||
| 951 | - srs_digest_block_free(&block0.digest); | ||
| 952 | - srs_key_block_free(&block1.key); | 960 | + void c1s1::destroy_blocks() |
| 961 | + { | ||
| 962 | + if (schema == srs_schema_invalid) { | ||
| 963 | + return; | ||
| 964 | + } | ||
| 965 | + | ||
| 966 | + if (schema == srs_schema0) { | ||
| 967 | + srs_key_block_free(&block0.key); | ||
| 968 | + srs_digest_block_free(&block1.digest); | ||
| 969 | + } else { | ||
| 970 | + srs_digest_block_free(&block0.digest); | ||
| 971 | + srs_key_block_free(&block1.key); | ||
| 972 | + } | ||
| 953 | } | 973 | } |
| 954 | } | 974 | } |
| 955 | 975 | ||
| @@ -1144,13 +1164,10 @@ int SrsComplexHandshake::handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrs | @@ -1144,13 +1164,10 @@ int SrsComplexHandshake::handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrs | ||
| 1144 | c2s2 c2; | 1164 | c2s2 c2; |
| 1145 | c2.parse(hs_bytes->c2); | 1165 | c2.parse(hs_bytes->c2); |
| 1146 | srs_verbose("complex handshake read c2 success."); | 1166 | srs_verbose("complex handshake read c2 success."); |
| 1167 | + | ||
| 1147 | // verify c2 | 1168 | // verify c2 |
| 1148 | - if ((ret = c2.c2_validate(&s1, is_valid)) != ERROR_SUCCESS || !is_valid) { | ||
| 1149 | - ret = ERROR_RTMP_HANDSHAKE; | ||
| 1150 | - srs_trace("verify c2 failed. ret=%d", ret); | ||
| 1151 | - return ret; | ||
| 1152 | - } | ||
| 1153 | - srs_verbose("verify c2 success."); | 1169 | + // never verify c2, for ffmpeg will failed. |
| 1170 | + // it's ok for flash. | ||
| 1154 | 1171 | ||
| 1155 | srs_trace("comple handshake with client success"); | 1172 | srs_trace("comple handshake with client success"); |
| 1156 | 1173 |
| @@ -97,6 +97,78 @@ namespace srs | @@ -97,6 +97,78 @@ namespace srs | ||
| 97 | int random1_size; | 97 | int random1_size; |
| 98 | }; | 98 | }; |
| 99 | 99 | ||
| 100 | + // the digest key generate size. | ||
| 101 | + #define OpensslHashSize 512 | ||
| 102 | + extern u_int8_t SrsGenuineFMSKey[]; | ||
| 103 | + extern u_int8_t SrsGenuineFPKey[]; | ||
| 104 | + int openssl_HMACsha256(const void* data, int data_size, const void* key, int key_size, void* digest); | ||
| 105 | + int openssl_generate_key(char* _private_key, char* _public_key, int32_t size); | ||
| 106 | + | ||
| 107 | + // calc the offset of key, | ||
| 108 | + // the key->offset cannot be used as the offset of key. | ||
| 109 | + int srs_key_block_get_offset(key_block* key); | ||
| 110 | + | ||
| 111 | + // create new key block data. | ||
| 112 | + // if created, user must free it by srs_key_block_free | ||
| 113 | + void srs_key_block_init(key_block* key); | ||
| 114 | + | ||
| 115 | + // parse key block from c1s1. | ||
| 116 | + // if created, user must free it by srs_key_block_free | ||
| 117 | + // @c1s1_key_bytes the key start bytes, maybe c1s1 or c1s1+764 | ||
| 118 | + int srs_key_block_parse(key_block* key, char* c1s1_key_bytes); | ||
| 119 | + | ||
| 120 | + // free the block data create by | ||
| 121 | + // srs_key_block_init or srs_key_block_parse | ||
| 122 | + void srs_key_block_free(key_block* key); | ||
| 123 | + | ||
| 124 | + // calc the offset of digest, | ||
| 125 | + // the key->offset cannot be used as the offset of digest. | ||
| 126 | + int srs_digest_block_get_offset(digest_block* digest); | ||
| 127 | + | ||
| 128 | + // create new digest block data. | ||
| 129 | + // if created, user must free it by srs_digest_block_free | ||
| 130 | + void srs_digest_block_init(digest_block* digest); | ||
| 131 | + | ||
| 132 | + // parse digest block from c1s1. | ||
| 133 | + // if created, user must free it by srs_digest_block_free | ||
| 134 | + // @c1s1_digest_bytes the digest start bytes, maybe c1s1 or c1s1+764 | ||
| 135 | + int srs_digest_block_parse(digest_block* digest, char* c1s1_digest_bytes); | ||
| 136 | + | ||
| 137 | + // free the block data create by | ||
| 138 | + // srs_digest_block_init or srs_digest_block_parse | ||
| 139 | + void srs_digest_block_free(digest_block* digest); | ||
| 140 | + | ||
| 141 | + /** | ||
| 142 | + * copy whole c1s1 to bytes. | ||
| 143 | + */ | ||
| 144 | + void srs_schema0_copy_to(char* bytes, bool with_digest, | ||
| 145 | + int32_t time, int32_t version, key_block* key, digest_block* digest); | ||
| 146 | + void srs_schema1_copy_to(char* bytes, bool with_digest, | ||
| 147 | + int32_t time, int32_t version, digest_block* digest, key_block* key); | ||
| 148 | + | ||
| 149 | + /** | ||
| 150 | + * c1s1 is splited by digest: | ||
| 151 | + * c1s1-part1: n bytes (time, version, key and digest-part1). | ||
| 152 | + * digest-data: 32bytes | ||
| 153 | + * c1s1-part2: (1536-n-32)bytes (digest-part2) | ||
| 154 | + * @return a new allocated bytes, user must free it. | ||
| 155 | + */ | ||
| 156 | + char* srs_bytes_join_schema0(int32_t time, int32_t version, key_block* key, digest_block* digest); | ||
| 157 | + | ||
| 158 | + /** | ||
| 159 | + * c1s1 is splited by digest: | ||
| 160 | + * c1s1-part1: n bytes (time, version and digest-part1). | ||
| 161 | + * digest-data: 32bytes | ||
| 162 | + * c1s1-part2: (1536-n-32)bytes (digest-part2 and key) | ||
| 163 | + * @return a new allocated bytes, user must free it. | ||
| 164 | + */ | ||
| 165 | + char* srs_bytes_join_schema1(int32_t time, int32_t version, digest_block* digest, key_block* key); | ||
| 166 | + | ||
| 167 | + /** | ||
| 168 | + * compare the memory in bytes. | ||
| 169 | + */ | ||
| 170 | + bool srs_bytes_equals(void* pa, void* pb, int size); | ||
| 171 | + | ||
| 100 | /** | 172 | /** |
| 101 | * c1s1 schema0 | 173 | * c1s1 schema0 |
| 102 | * time: 4bytes | 174 | * time: 4bytes |
| @@ -236,41 +308,14 @@ namespace srs | @@ -236,41 +308,14 @@ namespace srs | ||
| 236 | */ | 308 | */ |
| 237 | virtual int s2_validate(c1s1* c1, bool& is_valid); | 309 | virtual int s2_validate(c1s1* c1, bool& is_valid); |
| 238 | }; | 310 | }; |
| 239 | - | ||
| 240 | - /** | ||
| 241 | - * compare the memory in bytes. | ||
| 242 | - */ | ||
| 243 | - bool srs_bytes_equals(void* pa, void* pb, int size); | ||
| 244 | - | ||
| 245 | - /** | ||
| 246 | - * c1s1 is splited by digest: | ||
| 247 | - * c1s1-part1: n bytes (time, version, key and digest-part1). | ||
| 248 | - * digest-data: 32bytes | ||
| 249 | - * c1s1-part2: (1536-n-32)bytes (digest-part2) | ||
| 250 | - * @return a new allocated bytes, user must free it. | ||
| 251 | - */ | ||
| 252 | - char* srs_bytes_join_schema0(int32_t time, int32_t version, key_block* key, digest_block* digest); | ||
| 253 | - | ||
| 254 | - /** | ||
| 255 | - * c1s1 is splited by digest: | ||
| 256 | - * c1s1-part1: n bytes (time, version and digest-part1). | ||
| 257 | - * digest-data: 32bytes | ||
| 258 | - * c1s1-part2: (1536-n-32)bytes (digest-part2 and key) | ||
| 259 | - * @return a new allocated bytes, user must free it. | ||
| 260 | - */ | ||
| 261 | - char* srs_bytes_join_schema1(int32_t time, int32_t version, digest_block* digest, key_block* key); | ||
| 262 | - | ||
| 263 | - // the digest key generate size. | ||
| 264 | - #define OpensslHashSize 512 | ||
| 265 | - extern u_int8_t SrsGenuineFMSKey[]; | ||
| 266 | - extern u_int8_t SrsGenuineFPKey[]; | ||
| 267 | - int openssl_HMACsha256(const void* data, int data_size, const void* key, int key_size, void* digest); | ||
| 268 | } | 311 | } |
| 269 | 312 | ||
| 270 | #endif | 313 | #endif |
| 271 | 314 | ||
| 272 | /** | 315 | /** |
| 273 | -* try complex handshake, if failed, fallback to simple handshake. | 316 | +* simple handshake. |
| 317 | +* user can try complex handshake first, | ||
| 318 | +* rollback to simple handshake if error ERROR_RTMP_TRY_SIMPLE_HS | ||
| 274 | */ | 319 | */ |
| 275 | class SrsSimpleHandshake | 320 | class SrsSimpleHandshake |
| 276 | { | 321 | { |
| @@ -36,6 +36,77 @@ ISrsThreadContext* _srs_context = new ISrsThreadContext(); | @@ -36,6 +36,77 @@ ISrsThreadContext* _srs_context = new ISrsThreadContext(); | ||
| 36 | SrsConfig* _srs_config = NULL; | 36 | SrsConfig* _srs_config = NULL; |
| 37 | SrsServer* _srs_server = NULL; | 37 | SrsServer* _srs_server = NULL; |
| 38 | 38 | ||
| 39 | +MockEmptyIO::MockEmptyIO() | ||
| 40 | +{ | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | +MockEmptyIO::~MockEmptyIO() | ||
| 44 | +{ | ||
| 45 | +} | ||
| 46 | + | ||
| 47 | +bool MockEmptyIO::is_never_timeout(int64_t /*timeout_us*/) | ||
| 48 | +{ | ||
| 49 | + return true; | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +int MockEmptyIO::read_fully(const void* /*buf*/, size_t /*size*/, ssize_t* /*nread*/) | ||
| 53 | +{ | ||
| 54 | + return ERROR_SUCCESS; | ||
| 55 | +} | ||
| 56 | + | ||
| 57 | +int MockEmptyIO::write(const void* /*buf*/, size_t /*size*/, ssize_t* /*nwrite*/) | ||
| 58 | +{ | ||
| 59 | + return ERROR_SUCCESS; | ||
| 60 | +} | ||
| 61 | + | ||
| 62 | +void MockEmptyIO::set_recv_timeout(int64_t /*timeout_us*/) | ||
| 63 | +{ | ||
| 64 | +} | ||
| 65 | + | ||
| 66 | +int64_t MockEmptyIO::get_recv_timeout() | ||
| 67 | +{ | ||
| 68 | + return -1; | ||
| 69 | +} | ||
| 70 | + | ||
| 71 | +int64_t MockEmptyIO::get_recv_bytes() | ||
| 72 | +{ | ||
| 73 | + return -1; | ||
| 74 | +} | ||
| 75 | + | ||
| 76 | +int MockEmptyIO::get_recv_kbps() | ||
| 77 | +{ | ||
| 78 | + return 0; | ||
| 79 | +} | ||
| 80 | + | ||
| 81 | +void MockEmptyIO::set_send_timeout(int64_t /*timeout_us*/) | ||
| 82 | +{ | ||
| 83 | +} | ||
| 84 | + | ||
| 85 | +int64_t MockEmptyIO::get_send_timeout() | ||
| 86 | +{ | ||
| 87 | + return 0; | ||
| 88 | +} | ||
| 89 | + | ||
| 90 | +int64_t MockEmptyIO::get_send_bytes() | ||
| 91 | +{ | ||
| 92 | + return 0; | ||
| 93 | +} | ||
| 94 | + | ||
| 95 | +int MockEmptyIO::get_send_kbps() | ||
| 96 | +{ | ||
| 97 | + return 0; | ||
| 98 | +} | ||
| 99 | + | ||
| 100 | +int MockEmptyIO::writev(const iovec */*iov*/, int /*iov_size*/, ssize_t* /*nwrite*/) | ||
| 101 | +{ | ||
| 102 | + return ERROR_SUCCESS; | ||
| 103 | +} | ||
| 104 | + | ||
| 105 | +int MockEmptyIO::read(const void* /*buf*/, size_t /*size*/, ssize_t* /*nread*/) | ||
| 106 | +{ | ||
| 107 | + return ERROR_SUCCESS; | ||
| 108 | +} | ||
| 109 | + | ||
| 39 | // basic test and samples. | 110 | // basic test and samples. |
| 40 | VOID TEST(SampleTest, FastSampleInt64Test) | 111 | VOID TEST(SampleTest, FastSampleInt64Test) |
| 41 | { | 112 | { |
| @@ -34,4 +34,36 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -34,4 +34,36 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 34 | // we add an empty macro for upp to show the smart tips. | 34 | // we add an empty macro for upp to show the smart tips. |
| 35 | #define VOID | 35 | #define VOID |
| 36 | 36 | ||
| 37 | +#include <srs_protocol_io.hpp> | ||
| 38 | + | ||
| 39 | +class MockEmptyIO : public ISrsProtocolReaderWriter | ||
| 40 | +{ | ||
| 41 | +public: | ||
| 42 | + MockEmptyIO(); | ||
| 43 | + virtual ~MockEmptyIO(); | ||
| 44 | +// for protocol | ||
| 45 | +public: | ||
| 46 | + virtual bool is_never_timeout(int64_t timeout_us); | ||
| 47 | +// for handshake. | ||
| 48 | +public: | ||
| 49 | + virtual int read_fully(const void* buf, size_t size, ssize_t* nread); | ||
| 50 | + virtual int write(const void* buf, size_t size, ssize_t* nwrite); | ||
| 51 | +// for protocol | ||
| 52 | +public: | ||
| 53 | + virtual void set_recv_timeout(int64_t timeout_us); | ||
| 54 | + virtual int64_t get_recv_timeout(); | ||
| 55 | + virtual int64_t get_recv_bytes(); | ||
| 56 | + virtual int get_recv_kbps(); | ||
| 57 | +// for protocol | ||
| 58 | +public: | ||
| 59 | + virtual void set_send_timeout(int64_t timeout_us); | ||
| 60 | + virtual int64_t get_send_timeout(); | ||
| 61 | + virtual int64_t get_send_bytes(); | ||
| 62 | + virtual int get_send_kbps(); | ||
| 63 | + virtual int writev(const iovec *iov, int iov_size, ssize_t* nwrite); | ||
| 64 | +// for protocol/amf0/msg-codec | ||
| 65 | +public: | ||
| 66 | + virtual int read(const void* buf, size_t size, ssize_t* nread); | ||
| 67 | +}; | ||
| 68 | + | ||
| 37 | #endif | 69 | #endif |
| @@ -24,77 +24,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -24,77 +24,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 24 | 24 | ||
| 25 | #include <srs_kernel_error.hpp> | 25 | #include <srs_kernel_error.hpp> |
| 26 | #include <srs_core_autofree.hpp> | 26 | #include <srs_core_autofree.hpp> |
| 27 | - | ||
| 28 | -MockEmptyIO::MockEmptyIO() | ||
| 29 | -{ | ||
| 30 | -} | ||
| 31 | - | ||
| 32 | -MockEmptyIO::~MockEmptyIO() | ||
| 33 | -{ | ||
| 34 | -} | ||
| 35 | - | ||
| 36 | -bool MockEmptyIO::is_never_timeout(int64_t /*timeout_us*/) | ||
| 37 | -{ | ||
| 38 | - return true; | ||
| 39 | -} | ||
| 40 | - | ||
| 41 | -int MockEmptyIO::read_fully(const void* /*buf*/, size_t /*size*/, ssize_t* /*nread*/) | ||
| 42 | -{ | ||
| 43 | - return ERROR_SUCCESS; | ||
| 44 | -} | ||
| 45 | - | ||
| 46 | -int MockEmptyIO::write(const void* /*buf*/, size_t /*size*/, ssize_t* /*nwrite*/) | ||
| 47 | -{ | ||
| 48 | - return ERROR_SUCCESS; | ||
| 49 | -} | ||
| 50 | - | ||
| 51 | -void MockEmptyIO::set_recv_timeout(int64_t /*timeout_us*/) | ||
| 52 | -{ | ||
| 53 | -} | ||
| 54 | - | ||
| 55 | -int64_t MockEmptyIO::get_recv_timeout() | ||
| 56 | -{ | ||
| 57 | - return -1; | ||
| 58 | -} | ||
| 59 | - | ||
| 60 | -int64_t MockEmptyIO::get_recv_bytes() | ||
| 61 | -{ | ||
| 62 | - return -1; | ||
| 63 | -} | ||
| 64 | - | ||
| 65 | -int MockEmptyIO::get_recv_kbps() | ||
| 66 | -{ | ||
| 67 | - return 0; | ||
| 68 | -} | ||
| 69 | - | ||
| 70 | -void MockEmptyIO::set_send_timeout(int64_t /*timeout_us*/) | ||
| 71 | -{ | ||
| 72 | -} | ||
| 73 | - | ||
| 74 | -int64_t MockEmptyIO::get_send_timeout() | ||
| 75 | -{ | ||
| 76 | - return 0; | ||
| 77 | -} | ||
| 78 | - | ||
| 79 | -int64_t MockEmptyIO::get_send_bytes() | ||
| 80 | -{ | ||
| 81 | - return 0; | ||
| 82 | -} | ||
| 83 | - | ||
| 84 | -int MockEmptyIO::get_send_kbps() | ||
| 85 | -{ | ||
| 86 | - return 0; | ||
| 87 | -} | ||
| 88 | - | ||
| 89 | -int MockEmptyIO::writev(const iovec */*iov*/, int /*iov_size*/, ssize_t* /*nwrite*/) | ||
| 90 | -{ | ||
| 91 | - return ERROR_SUCCESS; | ||
| 92 | -} | ||
| 93 | - | ||
| 94 | -int MockEmptyIO::read(const void* /*buf*/, size_t /*size*/, ssize_t* /*nread*/) | ||
| 95 | -{ | ||
| 96 | - return ERROR_SUCCESS; | ||
| 97 | -} | 27 | +#include <srs_protocol_utility.hpp> |
| 98 | 28 | ||
| 99 | // verify the sha256 | 29 | // verify the sha256 |
| 100 | VOID TEST(HandshakeTest, OpensslSha256) | 30 | VOID TEST(HandshakeTest, OpensslSha256) |
| @@ -124,6 +54,37 @@ VOID TEST(HandshakeTest, OpensslSha256) | @@ -124,6 +54,37 @@ VOID TEST(HandshakeTest, OpensslSha256) | ||
| 124 | EXPECT_TRUE(srs_bytes_equals(digest, expect_digest, 32)); | 54 | EXPECT_TRUE(srs_bytes_equals(digest, expect_digest, 32)); |
| 125 | } | 55 | } |
| 126 | 56 | ||
| 57 | +// verify the dh key | ||
| 58 | +VOID TEST(HandshakeTest, DHKey) | ||
| 59 | +{ | ||
| 60 | + char pri_key[] = { | ||
| 61 | + 0x6e, 0x65, 0x69, 0x2d, 0x69, 0x2d, 0x69, 0x73, | ||
| 62 | + 0x6e, 0x69, 0x73, 0x6c, 0x65, 0x72, 0x69, 0x72, | ||
| 63 | + 0x76, 0x65, 0x72, 0x69, 0x77, 0x74, 0x2e, 0x6e, | ||
| 64 | + 0x72, 0x76, 0x72, 0x65, 0x72, 0x70, 0x72, 0x69, | ||
| 65 | + 0x69, 0x70, 0x72, 0x73, 0x6e, 0x65, 0x72, 0x72, | ||
| 66 | + 0x6e, 0x2d, 0x65, 0x74, 0x72, 0x6c, 0x69, 0x74, | ||
| 67 | + 0x69, 0x65, 0x40, 0x69, 0x69, 0x76, 0x77, 0x2d, | ||
| 68 | + 0x73, 0x65, 0x72, 0x72, 0x76, 0x73, 0x72, 0x2e, | ||
| 69 | + 0x2d, 0x76, 0x65, 0x31, 0x65, 0x6d, 0x6d, 0x73, | ||
| 70 | + 0x69, 0x73, 0x74, 0x2e, 0x74, 0x72, 0x65, 0x65, | ||
| 71 | + 0x72, 0x65, 0x2d, 0x74, 0x69, 0x31, 0x65, 0x2d, | ||
| 72 | + 0x6f, 0x77, 0x2e, 0x76, 0x77, 0x2d, 0x77, 0x72, | ||
| 73 | + 0x65, 0x65, 0x31, 0x74, 0x73, 0x70, 0x74, 0x6e, | ||
| 74 | + 0x72, 0x6e, 0x73, 0x6d, 0x2e, 0x69, 0x72, 0x2d, | ||
| 75 | + 0x65, 0x69, 0x77, 0x69, 0x76, 0x72, 0x77, 0x72, | ||
| 76 | + 0x32, 0x6e, 0x65, 0x6c, 0x2e, 0x2d, 0x6e, 0x69 | ||
| 77 | + }; | ||
| 78 | + | ||
| 79 | + char pub_key1[128]; | ||
| 80 | + openssl_generate_key(pri_key, pub_key1, 128); | ||
| 81 | + | ||
| 82 | + char pub_key2[128]; | ||
| 83 | + openssl_generate_key(pri_key, pub_key2, 128); | ||
| 84 | + | ||
| 85 | + EXPECT_FALSE(srs_bytes_equals(pub_key1, pub_key2, 128)); | ||
| 86 | +} | ||
| 87 | + | ||
| 127 | // flash will sendout a c0c1 encrypt by ssl. | 88 | // flash will sendout a c0c1 encrypt by ssl. |
| 128 | VOID TEST(HandshakeTest, VerifyFPC0C1) | 89 | VOID TEST(HandshakeTest, VerifyFPC0C1) |
| 129 | { | 90 | { |
| @@ -172,7 +133,7 @@ VOID TEST(HandshakeTest, VerifyFPC0C1) | @@ -172,7 +133,7 @@ VOID TEST(HandshakeTest, VerifyFPC0C1) | ||
| 172 | 0xb1, 0xb5, 0xbc, 0xa6, 0xd6, 0xd6, 0x1d, 0xce, 0x93, 0x78, 0xb3, 0xec, 0xa8, 0x64, 0x19, 0x13 | 133 | 0xb1, 0xb5, 0xbc, 0xa6, 0xd6, 0xd6, 0x1d, 0xce, 0x93, 0x78, 0xb3, 0xec, 0xa8, 0x64, 0x19, 0x13 |
| 173 | }; | 134 | }; |
| 174 | EXPECT_TRUE(srs_bytes_equals(c1.block1.digest.digest, digest, 32)); | 135 | EXPECT_TRUE(srs_bytes_equals(c1.block1.digest.digest, digest, 32)); |
| 175 | -} | 136 | +} |
| 176 | 137 | ||
| 177 | VOID TEST(HandshakeTest, SimpleHandshake) | 138 | VOID TEST(HandshakeTest, SimpleHandshake) |
| 178 | { | 139 | { |
| @@ -260,3 +221,19 @@ VOID TEST(HandshakeTest, ComplexHandshake) | @@ -260,3 +221,19 @@ VOID TEST(HandshakeTest, ComplexHandshake) | ||
| 260 | ASSERT_TRUE(is_valid); | 221 | ASSERT_TRUE(is_valid); |
| 261 | } | 222 | } |
| 262 | } | 223 | } |
| 224 | + | ||
| 225 | +VOID TEST(HandshakeTest, BytesEqual) | ||
| 226 | +{ | ||
| 227 | + char a1[] = { 0x01 }; | ||
| 228 | + char b1[] = { 0x02 }; | ||
| 229 | + char a2[] = { 0x01, 0x02 }; | ||
| 230 | + char b2[] = { 0x02, 0x03 }; | ||
| 231 | + | ||
| 232 | + EXPECT_TRUE(srs_bytes_equals(NULL, NULL, 0)); | ||
| 233 | + EXPECT_FALSE(srs_bytes_equals(a1, NULL, 1)); | ||
| 234 | + EXPECT_FALSE(srs_bytes_equals(NULL, a1, 1)); | ||
| 235 | + EXPECT_FALSE(srs_bytes_equals(a1, b1, 1)); | ||
| 236 | + EXPECT_TRUE(srs_bytes_equals(a1, a1, 1)); | ||
| 237 | + EXPECT_TRUE(srs_bytes_equals(a1, a2, 1)); | ||
| 238 | + EXPECT_FALSE(srs_bytes_equals(a1, b2, 1)); | ||
| 239 | +} |
| @@ -29,39 +29,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -29,39 +29,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 29 | */ | 29 | */ |
| 30 | #include <srs_utest.hpp> | 30 | #include <srs_utest.hpp> |
| 31 | 31 | ||
| 32 | -#include <srs_protocol_io.hpp> | ||
| 33 | #include <srs_protocol_rtmp.hpp> | 32 | #include <srs_protocol_rtmp.hpp> |
| 34 | #include <srs_protocol_handshake.hpp> | 33 | #include <srs_protocol_handshake.hpp> |
| 35 | using namespace srs; | 34 | using namespace srs; |
| 36 | 35 | ||
| 37 | -class MockEmptyIO : public ISrsProtocolReaderWriter | ||
| 38 | -{ | ||
| 39 | -public: | ||
| 40 | - MockEmptyIO(); | ||
| 41 | - virtual ~MockEmptyIO(); | ||
| 42 | -// for protocol | ||
| 43 | -public: | ||
| 44 | - virtual bool is_never_timeout(int64_t timeout_us); | ||
| 45 | -// for handshake. | ||
| 46 | -public: | ||
| 47 | - virtual int read_fully(const void* buf, size_t size, ssize_t* nread); | ||
| 48 | - virtual int write(const void* buf, size_t size, ssize_t* nwrite); | ||
| 49 | -// for protocol | ||
| 50 | -public: | ||
| 51 | - virtual void set_recv_timeout(int64_t timeout_us); | ||
| 52 | - virtual int64_t get_recv_timeout(); | ||
| 53 | - virtual int64_t get_recv_bytes(); | ||
| 54 | - virtual int get_recv_kbps(); | ||
| 55 | -// for protocol | ||
| 56 | -public: | ||
| 57 | - virtual void set_send_timeout(int64_t timeout_us); | ||
| 58 | - virtual int64_t get_send_timeout(); | ||
| 59 | - virtual int64_t get_send_bytes(); | ||
| 60 | - virtual int get_send_kbps(); | ||
| 61 | - virtual int writev(const iovec *iov, int iov_size, ssize_t* nwrite); | ||
| 62 | -// for protocol/amf0/msg-codec | ||
| 63 | -public: | ||
| 64 | - virtual int read(const void* buf, size_t size, ssize_t* nread); | ||
| 65 | -}; | ||
| 66 | - | ||
| 67 | #endif | 36 | #endif |
-
请 注册 或 登录 后发表评论