Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

282 строки
7.6KB

  1. #include "rtmp-handshake.h"
  2. #include "rtmp-util.h"
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <assert.h>
  6. #include <math.h>
  7. #if defined(_OPENSSL_)
  8. #include <openssl/sha.h>
  9. #include <openssl/hmac.h>
  10. #define _FLASH_HANDSHAKE_
  11. #elif defined(_IETF_HMAC_)
  12. #include "sha.h"
  13. #define SHA256_DIGEST_LENGTH SHA256HashSize
  14. #define _FLASH_HANDSHAKE_
  15. #endif
  16. #if defined(_FLASH_HANDSHAKE_)
  17. // nginx-rtmp-module / ngx_rtmp_handshake.c
  18. static const uint8_t rtmp_server_key[] = {
  19. 'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
  20. 'F', 'l', 'a', 's', 'h', ' ', 'M', 'e', 'd', 'i', 'a', ' ',
  21. 'S', 'e', 'r', 'v', 'e', 'r', ' ',
  22. '0', '0', '1', /* Genuine Adobe Flash Media Server 001 */
  23. 0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1,
  24. 0x02, 0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB,
  25. 0x93, 0xB8, 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
  26. };
  27. static const uint8_t rtmp_client_key[] = {
  28. 'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
  29. 'F', 'l', 'a', 's', 'h', ' ', 'P', 'l', 'a', 'y', 'e', 'r', ' ',
  30. '0', '0', '1', /* Genuine Adobe Flash Player 001 */
  31. 0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1,
  32. 0x02, 0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB,
  33. 0x93, 0xB8, 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
  34. };
  35. static const uint8_t rtmp_server_version[] = {
  36. 0x0D, 0x0E, 0x0A, 0x0D
  37. };
  38. static const uint8_t rtmp_client_version[] = {
  39. 0x0C, 0x00, 0x0D, 0x0E
  40. };
  41. #if defined(_OPENSSL_)
  42. static int rtmp_handshake_make_digest(const uint8_t* key, size_t len, const uint8_t* ptr, size_t ptrlen, const uint8_t* digest, uint8_t* dst)
  43. {
  44. static HMAC_CTX *hmac;
  45. unsigned int digestlen;
  46. if (hmac == NULL) {
  47. #if OPENSSL_VERSION_NUMBER < 0x10100000L
  48. static HMAC_CTX shmac;
  49. hmac = &shmac;
  50. HMAC_CTX_init(hmac);
  51. #else
  52. hmac = HMAC_CTX_new();
  53. #endif
  54. }
  55. HMAC_Init_ex(hmac, key, len, EVP_sha256(), NULL);
  56. if (digest)
  57. {
  58. assert(digest + SHA256_DIGEST_LENGTH <= ptr + ptrlen);
  59. HMAC_Update(hmac, ptr, digest - ptr);
  60. if (digest + SHA256_DIGEST_LENGTH < ptr + ptrlen)
  61. HMAC_Update(hmac, digest + SHA256_DIGEST_LENGTH, ptrlen - (digest - ptr) - SHA256_DIGEST_LENGTH);
  62. }
  63. else
  64. {
  65. HMAC_Update(hmac, ptr, ptrlen);
  66. }
  67. HMAC_Final(hmac, dst, &digestlen);
  68. assert(digestlen == SHA256_DIGEST_LENGTH);
  69. return 0;
  70. }
  71. #else
  72. static int rtmp_handshake_make_digest(const uint8_t* key, size_t len, const uint8_t* ptr, size_t ptrlen, const uint8_t* digest, uint8_t* dst)
  73. {
  74. HMACContext hmac;
  75. hmacReset(&hmac, SHA256, key, len);
  76. if (digest)
  77. {
  78. assert(digest + SHA256_DIGEST_LENGTH <= ptr + ptrlen);
  79. hmacInput(&hmac, ptr, digest - ptr);
  80. if (digest + SHA256_DIGEST_LENGTH < ptr + ptrlen)
  81. hmacInput(&hmac, digest + SHA256_DIGEST_LENGTH, ptrlen - (digest - ptr) - SHA256_DIGEST_LENGTH);
  82. }
  83. else
  84. {
  85. hmacInput(&hmac, ptr, ptrlen);
  86. }
  87. hmacResult(&hmac, dst);
  88. return 0;
  89. }
  90. #endif
  91. /*
  92. // http://blog.csdn.net/win_lin/article/details/13006803
  93. // 764-bytes key
  94. random-data: (offset)bytes
  95. key-data: 128bytes
  96. random-data: (764-offset-128-4)bytes
  97. offset: 4bytes
  98. // 764-bytes digest
  99. offset: 4bytes
  100. random-data: (offset)bytes
  101. digest-data: 32bytes
  102. random-data: (764-4-offset-32)bytes
  103. */
  104. static const uint8_t* rtmp_handshake_find_digest(const uint8_t* handshake, size_t offset, const uint8_t* key, size_t len)
  105. {
  106. uint32_t bytes;
  107. uint8_t digest[SHA256_DIGEST_LENGTH];
  108. bytes = handshake[offset + 0];
  109. bytes += handshake[offset + 1];
  110. bytes += handshake[offset + 2];
  111. bytes += handshake[offset + 3];
  112. bytes %= 728;/*764 - 4bytesoffset - 32bytesdigest*/
  113. rtmp_handshake_make_digest(key, len, handshake, RTMP_HANDSHAKE_SIZE, handshake + offset + 4 + bytes, digest);
  114. if (0 == memcmp(digest, handshake + offset + 4 + bytes, SHA256_DIGEST_LENGTH))
  115. return handshake + offset + 4 + bytes;
  116. return NULL;
  117. }
  118. static int rtmp_handshake_parse_challenge(const uint8_t* handshake, const uint8_t* key, size_t len, uint8_t digest[SHA256_DIGEST_LENGTH])
  119. {
  120. uint32_t epoch;
  121. uint32_t version;
  122. const uint8_t* p;
  123. be_read_uint32(handshake, &epoch);
  124. be_read_uint32(handshake + 4, &version);
  125. if (0 == version)
  126. {
  127. // simple handshake
  128. return 0;
  129. }
  130. p = rtmp_handshake_find_digest(handshake, 764 + 8, key, len);
  131. if(NULL == p)
  132. p = rtmp_handshake_find_digest(handshake, 8, key, len);
  133. if (p)
  134. memcpy(digest, p, SHA256_DIGEST_LENGTH);
  135. return p ? 1 : 0;
  136. }
  137. static int rtmp_handshake_create_challenge(uint8_t* handshake, const uint8_t* key, size_t len)
  138. {
  139. uint32_t offset;
  140. uint8_t* digest;
  141. offset = handshake[8];
  142. offset += handshake[9];
  143. offset += handshake[10];
  144. offset += handshake[11];
  145. digest = handshake + 12 + (offset % 728/*764 - 4bytesoffset - 32bytesdigest*/);
  146. return rtmp_handshake_make_digest(key, len, handshake, RTMP_HANDSHAKE_SIZE, digest, digest);
  147. }
  148. static int rtmp_handshake_create_response(uint8_t* handshake, const uint8_t* key, size_t len)
  149. {
  150. uint8_t digest[SHA256_DIGEST_LENGTH];
  151. rtmp_handshake_make_digest(key, len, handshake, RTMP_HANDSHAKE_SIZE - SHA256_DIGEST_LENGTH, NULL, digest);
  152. memcpy(handshake + RTMP_HANDSHAKE_SIZE - SHA256_DIGEST_LENGTH, digest, SHA256_DIGEST_LENGTH);
  153. return 0;
  154. }
  155. #endif
  156. static void rtmp_handshake_random(uint8_t* p, uint32_t timestamp)
  157. {
  158. int i;
  159. srand(timestamp);
  160. for (i = 0; i * 4 < RTMP_HANDSHAKE_SIZE - 8; i++)
  161. {
  162. *((int*)p + i) = rand();
  163. }
  164. }
  165. int rtmp_handshake_c0(uint8_t* c0, int version)
  166. {
  167. assert(RTMP_VERSION == version);
  168. *c0 = (uint8_t)version;
  169. return 1;
  170. }
  171. int rtmp_handshake_c1(uint8_t* c1, uint32_t timestamp)
  172. {
  173. be_write_uint32(c1, timestamp);
  174. #if defined(_FLASH_HANDSHAKE_)
  175. memcpy(c1 + 4, rtmp_client_version, 4);
  176. rtmp_handshake_random(c1 + 8, timestamp);
  177. rtmp_handshake_create_challenge(c1, rtmp_client_key, 30);
  178. #else
  179. be_write_uint32(c1 + 4, 0);
  180. rtmp_handshake_random(c1 + 8, timestamp);
  181. #endif
  182. return RTMP_HANDSHAKE_SIZE;
  183. }
  184. int rtmp_handshake_c2(uint8_t* c2, uint32_t timestamp, const uint8_t* s1, size_t bytes)
  185. {
  186. #if defined(_FLASH_HANDSHAKE_)
  187. uint8_t digest[SHA256_DIGEST_LENGTH];
  188. assert(RTMP_HANDSHAKE_SIZE == bytes);
  189. if (1 == rtmp_handshake_parse_challenge(s1, rtmp_server_key, 36, digest))
  190. {
  191. rtmp_handshake_make_digest(rtmp_client_key, sizeof(rtmp_client_key), digest, SHA256_DIGEST_LENGTH, NULL, digest);
  192. rtmp_handshake_random(c2, timestamp);
  193. rtmp_handshake_create_response(c2, digest, SHA256_DIGEST_LENGTH);
  194. }
  195. else
  196. {
  197. memmove(c2, s1, bytes);
  198. //be_write_uint32(c2 + 4, timestamp);
  199. }
  200. #else
  201. assert(RTMP_HANDSHAKE_SIZE == bytes);
  202. memmove(c2, s1, bytes);
  203. be_write_uint32(c2 + 4, timestamp);
  204. #endif
  205. return (int)bytes;
  206. }
  207. int rtmp_handshake_s0(uint8_t* s0, int version)
  208. {
  209. assert(RTMP_VERSION == version);
  210. *s0 = (uint8_t)version;
  211. return 1;
  212. }
  213. int rtmp_handshake_s1(uint8_t* s1, uint32_t timestamp)
  214. {
  215. be_write_uint32(s1, timestamp);
  216. #if defined(_FLASH_HANDSHAKE_)
  217. memcpy(s1 + 4, rtmp_server_version, 4);
  218. rtmp_handshake_random(s1 + 8, timestamp);
  219. rtmp_handshake_create_challenge(s1, rtmp_server_key, 36);
  220. #else
  221. be_write_uint32(s1 + 4, 0);
  222. rtmp_handshake_random(s1 + 8, timestamp);
  223. #endif
  224. return RTMP_HANDSHAKE_SIZE;
  225. }
  226. int rtmp_handshake_s2(uint8_t* s2, uint32_t timestamp, const uint8_t* c1, size_t bytes)
  227. {
  228. #if defined(_FLASH_HANDSHAKE_)
  229. uint8_t digest[SHA256_DIGEST_LENGTH];
  230. assert(RTMP_HANDSHAKE_SIZE == bytes);
  231. if (1 == rtmp_handshake_parse_challenge(c1, rtmp_client_key, 30, digest))
  232. {
  233. rtmp_handshake_make_digest(rtmp_server_key, sizeof(rtmp_server_key), digest, SHA256_DIGEST_LENGTH, NULL, digest);
  234. rtmp_handshake_random(s2, timestamp);
  235. rtmp_handshake_create_response(s2, digest, SHA256_DIGEST_LENGTH);
  236. }
  237. else
  238. {
  239. memmove(s2, c1, bytes);
  240. //be_write_uint32(s2 + 4, timestamp);
  241. }
  242. #else
  243. assert(RTMP_HANDSHAKE_SIZE == bytes);
  244. memmove(s2, c1, bytes);
  245. be_write_uint32(s2 + 4, timestamp);
  246. #endif
  247. return (int)bytes;
  248. }