winlin

for bug #235, use strategy to implements the schema0 and schema1.

@@ -638,261 +638,273 @@ namespace _srs_internal @@ -638,261 +638,273 @@ namespace _srs_internal
638 return bytes; 638 return bytes;
639 } 639 }
640 640
641 - c2s2::c2s2() 641 + c1s1_strategy::c1s1_strategy()
642 { 642 {
643 - srs_random_generate(random, 1504); 643 + }
644 644
645 - int size = snprintf(random, 1504, "%s", RTMP_SIG_SRS_HANDSHAKE);  
646 - srs_assert(++size < 1504);  
647 - snprintf(random + 1504 - size, size, "%s", RTMP_SIG_SRS_HANDSHAKE); 645 + c1s1_strategy::~c1s1_strategy()
  646 + {
  647 + }
648 648
649 - srs_random_generate(digest, 32); 649 + c1s1_strategy_schema0::c1s1_strategy_schema0()
  650 + {
  651 + key.init();
  652 + digest.init();
650 } 653 }
651 654
652 - c2s2::~c2s2() 655 + c1s1_strategy_schema0::~c1s1_strategy_schema0()
653 { 656 {
  657 + key.free();
  658 + digest.free();
654 } 659 }
655 660
656 - void c2s2::dump(char* _c2s2) 661 + srs_schema_type c1s1_strategy_schema0::schema()
657 { 662 {
658 - memcpy(_c2s2, random, 1504);  
659 - memcpy(_c2s2 + 1504, digest, 32); 663 + return srs_schema0;
660 } 664 }
661 665
662 - void c2s2::parse(char* _c2s2) 666 + char* c1s1_strategy_schema0::get_digest()
663 { 667 {
664 - memcpy(random, _c2s2, 1504);  
665 - memcpy(digest, _c2s2 + 1504, 32); 668 + return digest.digest;
666 } 669 }
667 670
668 - int c2s2::c2_create(c1s1* s1) 671 + void c1s1_strategy_schema0::dump(c1s1* owner, char* _c1s1)
  672 + {
  673 + srs_schema0_copy_to(_c1s1, true, owner->time, owner->version, &key, &digest);
  674 + }
  675 +
  676 + int c1s1_strategy_schema0::parse(char* _c1s1)
669 { 677 {
670 int ret = ERROR_SUCCESS; 678 int ret = ERROR_SUCCESS;
671 679
672 - char temp_key[__SRS_OpensslHashSize];  
673 - if ((ret = openssl_HMACsha256(SrsGenuineFPKey, 62, s1->get_digest(), 32, temp_key)) != ERROR_SUCCESS) {  
674 - srs_error("create c2 temp key failed. ret=%d", ret); 680 + if ((ret = key.parse(_c1s1 + 8)) != ERROR_SUCCESS) {
  681 + srs_error("parse the c1 key failed. ret=%d", ret);
675 return ret; 682 return ret;
676 } 683 }
677 - srs_verbose("generate c2 temp key success.");  
678 684
679 - char _digest[__SRS_OpensslHashSize];  
680 - if ((ret = openssl_HMACsha256(temp_key, 32, random, 1504, _digest)) != ERROR_SUCCESS) {  
681 - srs_error("create c2 digest failed. ret=%d", ret); 685 + if ((ret = digest.parse(_c1s1 + 8 + 764)) != ERROR_SUCCESS) {
  686 + srs_error("parse the c1 digest failed. ret=%d", ret);
682 return ret; 687 return ret;
683 } 688 }
684 - srs_verbose("generate c2 digest success.");  
685 689
686 - memcpy(digest, _digest, 32); 690 + srs_verbose("parse c1 key-digest success");
687 691
688 return ret; 692 return ret;
689 } 693 }
690 694
691 - int c2s2::c2_validate(c1s1* s1, bool& is_valid) 695 + int c1s1_strategy_schema0::c1_create(c1s1* owner)
692 { 696 {
693 - is_valid = false;  
694 int ret = ERROR_SUCCESS; 697 int ret = ERROR_SUCCESS;
695 698
696 - char temp_key[__SRS_OpensslHashSize];  
697 - if ((ret = openssl_HMACsha256(SrsGenuineFPKey, 62, s1->get_digest(), 32, temp_key)) != ERROR_SUCCESS) {  
698 - srs_error("create c2 temp key failed. ret=%d", ret);  
699 - return ret;  
700 - }  
701 - srs_verbose("generate c2 temp key success."); 699 + // generate digest
  700 + char* c1_digest = NULL;
702 701
703 - char _digest[__SRS_OpensslHashSize];  
704 - if ((ret = openssl_HMACsha256(temp_key, 32, random, 1504, _digest)) != ERROR_SUCCESS) {  
705 - srs_error("create c2 digest failed. ret=%d", ret); 702 + if ((ret = calc_c1_digest(owner, c1_digest)) != ERROR_SUCCESS) {
  703 + srs_error("sign c1 error, failed to calc digest. ret=%d", ret);
706 return ret; 704 return ret;
707 } 705 }
708 - srs_verbose("generate c2 digest success.");  
709 706
710 - is_valid = srs_bytes_equals(digest, _digest, 32); 707 + srs_assert(c1_digest != NULL);
  708 + SrsAutoFree(char, c1_digest);
  709 +
  710 + memcpy(digest.digest, c1_digest, 32);
711 711
712 return ret; 712 return ret;
713 } 713 }
714 714
715 - int c2s2::s2_create(c1s1* c1) 715 + int c1s1_strategy_schema0::c1_validate_digest(c1s1* owner, bool& is_valid)
716 { 716 {
717 int ret = ERROR_SUCCESS; 717 int ret = ERROR_SUCCESS;
718 718
719 - char temp_key[__SRS_OpensslHashSize];  
720 - if ((ret = openssl_HMACsha256(SrsGenuineFMSKey, 68, c1->get_digest(), 32, temp_key)) != ERROR_SUCCESS) {  
721 - srs_error("create s2 temp key failed. ret=%d", ret);  
722 - return ret;  
723 - }  
724 - srs_verbose("generate s2 temp key success."); 719 + char* c1_digest = NULL;
725 720
726 - char _digest[__SRS_OpensslHashSize];  
727 - if ((ret = openssl_HMACsha256(temp_key, 32, random, 1504, _digest)) != ERROR_SUCCESS) {  
728 - srs_error("create s2 digest failed. ret=%d", ret); 721 + if ((ret = calc_c1_digest(owner, c1_digest)) != ERROR_SUCCESS) {
  722 + srs_error("validate c1 error, failed to calc digest. ret=%d", ret);
729 return ret; 723 return ret;
730 } 724 }
731 - srs_verbose("generate s2 digest success.");  
732 725
733 - memcpy(digest, _digest, 32); 726 + srs_assert(c1_digest != NULL);
  727 + SrsAutoFree(char, c1_digest);
  728 +
  729 + is_valid = srs_bytes_equals(digest.digest, c1_digest, 32);
734 730
735 return ret; 731 return ret;
736 } 732 }
737 733
738 - int c2s2::s2_validate(c1s1* c1, bool& is_valid) 734 + int c1s1_strategy_schema0::s1_create(c1s1* owner)
739 { 735 {
740 - is_valid = false;  
741 int ret = ERROR_SUCCESS; 736 int ret = ERROR_SUCCESS;
742 737
743 - char temp_key[__SRS_OpensslHashSize];  
744 - if ((ret = openssl_HMACsha256(SrsGenuineFMSKey, 68, c1->get_digest(), 32, temp_key)) != ERROR_SUCCESS) {  
745 - srs_error("create s2 temp key failed. ret=%d", ret); 738 + SrsDH dh;
  739 +
  740 + // ensure generate 128bytes public key.
  741 + if ((ret = dh.initialize(true)) != ERROR_SUCCESS) {
746 return ret; 742 return ret;
747 } 743 }
748 - srs_verbose("generate s2 temp key success.");  
749 744
750 - char _digest[__SRS_OpensslHashSize];  
751 - if ((ret = openssl_HMACsha256(temp_key, 32, random, 1504, _digest)) != ERROR_SUCCESS) {  
752 - srs_error("create s2 digest failed. ret=%d", ret); 745 + // directly generate the public key.
  746 + // @see: https://github.com/winlinvip/simple-rtmp-server/issues/148
  747 + int pkey_size = 128;
  748 + // TODO: FIXME: use c1 public key to calc the shared key.
  749 + if ((ret = dh.copy_public_key(key.key, pkey_size)) != ERROR_SUCCESS) {
  750 + srs_error("calc s1 key failed. ret=%d", ret);
753 return ret; 751 return ret;
754 } 752 }
755 - srs_verbose("generate s2 digest success.");  
756 -  
757 - is_valid = srs_bytes_equals(digest, _digest, 32); 753 + srs_assert(pkey_size == 128);
  754 + srs_verbose("calc s1 key success.");
758 755
  756 + char* s1_digest = NULL;
  757 + if ((ret = calc_s1_digest(owner, s1_digest)) != ERROR_SUCCESS) {
  758 + srs_error("calc s1 digest failed. ret=%d", ret);
759 return ret; 759 return ret;
760 } 760 }
  761 + srs_verbose("calc s1 digest success.");
761 762
762 - // TODO: FIXME: move to the right position.  
763 - c1s1::c1s1()  
764 - {  
765 - schema = srs_schema_invalid;  
766 - }  
767 - c1s1::~c1s1()  
768 - {  
769 - destroy_blocks();  
770 - } 763 + srs_assert(s1_digest != NULL);
  764 + SrsAutoFree(char, s1_digest);
771 765
772 - char* c1s1::get_digest()  
773 - {  
774 - srs_assert(schema != srs_schema_invalid); 766 + memcpy(digest.digest, s1_digest, 32);
  767 + srs_verbose("copy s1 key success.");
775 768
776 - if (schema == srs_schema0) {  
777 - return block1.digest.digest;  
778 - } else {  
779 - return block0.digest.digest;  
780 - } 769 + return ret;
781 } 770 }
782 771
783 - void c1s1::dump(char* _c1s1) 772 + int c1s1_strategy_schema0::s1_validate_digest(c1s1* owner, bool& is_valid)
784 { 773 {
785 - srs_assert(schema != srs_schema_invalid); 774 + int ret = ERROR_SUCCESS;
786 775
787 - if (schema == srs_schema0) {  
788 - srs_schema0_copy_to(_c1s1, true, time, version, &block0.key, &block1.digest);  
789 - } else {  
790 - srs_schema1_copy_to(_c1s1, true, time, version, &block0.digest, &block1.key); 776 + char* s1_digest = NULL;
  777 +
  778 + if ((ret = calc_s1_digest(owner, s1_digest)) != ERROR_SUCCESS) {
  779 + srs_error("validate s1 error, failed to calc digest. ret=%d", ret);
  780 + return ret;
791 } 781 }
  782 +
  783 + srs_assert(s1_digest != NULL);
  784 + SrsAutoFree(char, s1_digest);
  785 +
  786 + is_valid = srs_bytes_equals(digest.digest, s1_digest, 32);
  787 +
  788 + return ret;
792 } 789 }
793 790
794 - int c1s1::parse(char* _c1s1, srs_schema_type _schema) 791 + int c1s1_strategy_schema0::calc_c1_digest(c1s1* owner, char*& c1_digest)
795 { 792 {
796 int ret = ERROR_SUCCESS; 793 int ret = ERROR_SUCCESS;
797 794
798 - if (_schema == srs_schema_invalid) {  
799 - ret = ERROR_RTMP_CH_SCHEMA;  
800 - srs_error("parse c1 failed. invalid schema=%d, ret=%d", _schema, ret); 795 + char* c1s1_joined_bytes = NULL;
  796 +
  797 + c1s1_joined_bytes = srs_bytes_join_schema0(owner->time, owner->version, &key, &digest);
  798 +
  799 + srs_assert(c1s1_joined_bytes != NULL);
  800 + SrsAutoFree(char, c1s1_joined_bytes);
  801 +
  802 + c1_digest = new char[__SRS_OpensslHashSize];
  803 + if ((ret = openssl_HMACsha256(SrsGenuineFPKey, 30, c1s1_joined_bytes, 1536 - 32, c1_digest)) != ERROR_SUCCESS) {
  804 + srs_freep(c1_digest);
  805 + srs_error("calc digest for c1 failed. ret=%d", ret);
801 return ret; 806 return ret;
802 } 807 }
  808 + srs_verbose("digest calculated for c1");
803 809
804 - destroy_blocks(); 810 + return ret;
  811 + }
  812 +
  813 + int c1s1_strategy_schema0::calc_s1_digest(c1s1* owner, char*& s1_digest)
  814 + {
  815 + int ret = ERROR_SUCCESS;
805 816
  817 + char* c1s1_joined_bytes = NULL;
806 818
807 - time = __srs_stream_read_4bytes(_c1s1);  
808 - version = __srs_stream_read_4bytes(_c1s1 + 4); // client c1 version 819 + c1s1_joined_bytes = srs_bytes_join_schema0(owner->time, owner->version, &key, &digest);
809 820
810 - if (_schema == srs_schema0) {  
811 - if ((ret = block0.key.parse(_c1s1 + 8)) != ERROR_SUCCESS) {  
812 - srs_error("parse the c1 key failed. ret=%d", ret); 821 + srs_assert(c1s1_joined_bytes != NULL);
  822 + SrsAutoFree(char, c1s1_joined_bytes);
  823 +
  824 + s1_digest = new char[__SRS_OpensslHashSize];
  825 + if ((ret = openssl_HMACsha256(SrsGenuineFMSKey, 36, c1s1_joined_bytes, 1536 - 32, s1_digest)) != ERROR_SUCCESS) {
  826 + srs_freep(s1_digest);
  827 + srs_error("calc digest for s1 failed. ret=%d", ret);
813 return ret; 828 return ret;
814 } 829 }
815 - if ((ret = block1.digest.parse(_c1s1 + 8 + 764)) != ERROR_SUCCESS) {  
816 - srs_error("parse the c1 digest failed. ret=%d", ret); 830 + srs_verbose("digest calculated for s1");
  831 +
817 return ret; 832 return ret;
818 } 833 }
819 - srs_verbose("parse c1 key-digest success");  
820 - } else if (_schema == srs_schema1) {  
821 - if ((ret = block0.digest.parse(_c1s1 + 8)) != ERROR_SUCCESS) {  
822 - srs_error("parse the c1 key failed. ret=%d", ret);  
823 - return ret; 834 +
  835 + c1s1_strategy_schema1::c1s1_strategy_schema1()
  836 + {
  837 + key.init();
  838 + digest.init();
824 } 839 }
825 - if ((ret = block1.key.parse(_c1s1 + 8 + 764)) != ERROR_SUCCESS) {  
826 - srs_error("parse the c1 digest failed. ret=%d", ret);  
827 - return ret; 840 +
  841 + c1s1_strategy_schema1::~c1s1_strategy_schema1()
  842 + {
  843 + key.free();
  844 + digest.free();
828 } 845 }
829 - srs_verbose("parse c1 digest-key success");  
830 - } else {  
831 - ret = ERROR_RTMP_CH_SCHEMA;  
832 - srs_error("parse c1 failed. invalid schema=%d, ret=%d", _schema, ret);  
833 - return ret; 846 +
  847 + srs_schema_type c1s1_strategy_schema1::schema()
  848 + {
  849 + return srs_schema1;
834 } 850 }
835 851
836 - schema = _schema; 852 + char* c1s1_strategy_schema1::get_digest()
  853 + {
  854 + return digest.digest;
  855 + }
837 856
838 - return ret; 857 + void c1s1_strategy_schema1::dump(c1s1* owner, char* _c1s1)
  858 + {
  859 + srs_schema0_copy_to(_c1s1, true, owner->time, owner->version, &key, &digest);
839 } 860 }
840 861
841 - int c1s1::c1_create(srs_schema_type _schema) 862 + int c1s1_strategy_schema1::parse(char* _c1s1)
842 { 863 {
843 int ret = ERROR_SUCCESS; 864 int ret = ERROR_SUCCESS;
844 865
845 - if (_schema == srs_schema_invalid) {  
846 - ret = ERROR_RTMP_CH_SCHEMA;  
847 - srs_error("create c1 failed. invalid schema=%d, ret=%d", _schema, ret); 866 + if ((ret = digest.parse(_c1s1 + 8)) != ERROR_SUCCESS) {
  867 + srs_error("parse the c1 digest failed. ret=%d", ret);
848 return ret; 868 return ret;
849 } 869 }
850 870
851 - destroy_blocks(); 871 + if ((ret = key.parse(_c1s1 + 8 + 764)) != ERROR_SUCCESS) {
  872 + srs_error("parse the c1 key failed. ret=%d", ret);
  873 + return ret;
  874 + }
852 875
853 - // client c1 time and version  
854 - time = ::time(NULL);  
855 - version = 0x80000702; // client c1 version 876 + srs_verbose("parse c1 digest-key success");
856 877
857 - // generate signature by schema  
858 - if (_schema == srs_schema0) {  
859 - block0.key.init();  
860 - block1.digest.init();  
861 - } else {  
862 - block0.digest.init();  
863 - block1.key.init(); 878 + return ret;
864 } 879 }
865 880
866 - schema = _schema; 881 + int c1s1_strategy_schema1::c1_create(c1s1* owner)
  882 + {
  883 + int ret = ERROR_SUCCESS;
867 884
868 // generate digest 885 // generate digest
869 - char* digest = NULL; 886 + char* c1_digest = NULL;
870 887
871 - if ((ret = calc_c1_digest(digest)) != ERROR_SUCCESS) { 888 + if ((ret = calc_c1_digest(owner, c1_digest)) != ERROR_SUCCESS) {
872 srs_error("sign c1 error, failed to calc digest. ret=%d", ret); 889 srs_error("sign c1 error, failed to calc digest. ret=%d", ret);
873 return ret; 890 return ret;
874 } 891 }
875 892
876 - srs_assert(digest != NULL);  
877 - SrsAutoFree(char, digest); 893 + srs_assert(c1_digest != NULL);
  894 + SrsAutoFree(char, c1_digest);
878 895
879 - if (schema == srs_schema0) {  
880 - memcpy(block1.digest.digest, digest, 32);  
881 - } else {  
882 - memcpy(block0.digest.digest, digest, 32);  
883 - } 896 + memcpy(digest.digest, c1_digest, 32);
884 897
885 return ret; 898 return ret;
886 } 899 }
887 900
888 - int c1s1::c1_validate_digest(bool& is_valid) 901 + int c1s1_strategy_schema1::c1_validate_digest(c1s1* owner, bool& is_valid)
889 { 902 {
890 - is_valid = false;  
891 int ret = ERROR_SUCCESS; 903 int ret = ERROR_SUCCESS;
892 904
893 char* c1_digest = NULL; 905 char* c1_digest = NULL;
894 906
895 - if ((ret = calc_c1_digest(c1_digest)) != ERROR_SUCCESS) { 907 + if ((ret = calc_c1_digest(owner, c1_digest)) != ERROR_SUCCESS) {
896 srs_error("validate c1 error, failed to calc digest. ret=%d", ret); 908 srs_error("validate c1 error, failed to calc digest. ret=%d", ret);
897 return ret; 909 return ret;
898 } 910 }
@@ -900,163 +912,241 @@ namespace _srs_internal @@ -900,163 +912,241 @@ namespace _srs_internal
900 srs_assert(c1_digest != NULL); 912 srs_assert(c1_digest != NULL);
901 SrsAutoFree(char, c1_digest); 913 SrsAutoFree(char, c1_digest);
902 914
903 - if (schema == srs_schema0) {  
904 - is_valid = srs_bytes_equals(block1.digest.digest, c1_digest, 32);  
905 - } else {  
906 - is_valid = srs_bytes_equals(block0.digest.digest, c1_digest, 32);  
907 - } 915 + is_valid = srs_bytes_equals(digest.digest, c1_digest, 32);
908 916
909 return ret; 917 return ret;
910 } 918 }
911 919
912 - int c1s1::s1_validate_digest(bool& is_valid) 920 + int c1s1_strategy_schema1::s1_create(c1s1* owner)
913 { 921 {
914 - is_valid = false;  
915 int ret = ERROR_SUCCESS; 922 int ret = ERROR_SUCCESS;
916 923
917 - char* s1_digest = NULL; 924 + SrsDH dh;
918 925
919 - if ((ret = calc_s1_digest(s1_digest)) != ERROR_SUCCESS) {  
920 - srs_error("validate s1 error, failed to calc digest. ret=%d", ret); 926 + // ensure generate 128bytes public key.
  927 + if ((ret = dh.initialize(true)) != ERROR_SUCCESS) {
921 return ret; 928 return ret;
922 } 929 }
923 930
  931 + // directly generate the public key.
  932 + // @see: https://github.com/winlinvip/simple-rtmp-server/issues/148
  933 + int pkey_size = 128;
  934 + if ((ret = dh.copy_public_key(key.key, pkey_size)) != ERROR_SUCCESS) {
  935 + srs_error("calc s1 key failed. ret=%d", ret);
  936 + return ret;
  937 + }
  938 + srs_assert(pkey_size == 128);
  939 + srs_verbose("calc s1 key success.");
  940 +
  941 + char* s1_digest = NULL;
  942 + if ((ret = calc_s1_digest(owner, s1_digest)) != ERROR_SUCCESS) {
  943 + srs_error("calc s1 digest failed. ret=%d", ret);
  944 + return ret;
  945 + }
  946 + srs_verbose("calc s1 digest success.");
  947 +
924 srs_assert(s1_digest != NULL); 948 srs_assert(s1_digest != NULL);
925 SrsAutoFree(char, s1_digest); 949 SrsAutoFree(char, s1_digest);
926 950
927 - if (schema == srs_schema0) {  
928 - is_valid = srs_bytes_equals(block1.digest.digest, s1_digest, 32);  
929 - } else {  
930 - is_valid = srs_bytes_equals(block0.digest.digest, s1_digest, 32);  
931 - } 951 + memcpy(digest.digest, s1_digest, 32);
  952 + srs_verbose("copy s1 key success.");
932 953
933 return ret; 954 return ret;
934 } 955 }
935 956
936 - int c1s1::s1_create(c1s1* c1) 957 + int c1s1_strategy_schema1::s1_validate_digest(c1s1* owner, bool& is_valid)
937 { 958 {
938 int ret = ERROR_SUCCESS; 959 int ret = ERROR_SUCCESS;
939 960
940 - if (c1->schema == srs_schema_invalid) {  
941 - ret = ERROR_RTMP_CH_SCHEMA;  
942 - srs_error("create s1 failed. invalid schema=%d, ret=%d", c1->schema, ret); 961 + char* s1_digest = NULL;
  962 +
  963 + if ((ret = calc_s1_digest(owner, s1_digest)) != ERROR_SUCCESS) {
  964 + srs_error("validate s1 error, failed to calc digest. ret=%d", ret);
943 return ret; 965 return ret;
944 } 966 }
945 967
946 - destroy_blocks();  
947 - schema = c1->schema; 968 + srs_assert(s1_digest != NULL);
  969 + SrsAutoFree(char, s1_digest);
948 970
949 - time = ::time(NULL);  
950 - version = 0x01000504; // server s1 version 971 + is_valid = srs_bytes_equals(digest.digest, s1_digest, 32);
951 972
952 - SrsDH dh;  
953 -  
954 - // ensure generate 128bytes public key.  
955 - if ((ret = dh.initialize(true)) != ERROR_SUCCESS) {  
956 return ret; 973 return ret;
957 } 974 }
958 975
959 - if (schema == srs_schema0) {  
960 - block0.key.init();  
961 - block1.digest.init(); 976 + int c1s1_strategy_schema1::calc_c1_digest(c1s1* owner, char*& c1_digest)
  977 + {
  978 + int ret = ERROR_SUCCESS;
962 979
963 - // directly generate the public key.  
964 - // @see: https://github.com/winlinvip/simple-rtmp-server/issues/148  
965 - int pkey_size = 128;  
966 - if ((ret = dh.copy_public_key(block0.key.key, pkey_size)) != ERROR_SUCCESS) {  
967 - srs_error("calc s1 key failed. ret=%d", ret); 980 + char* c1s1_joined_bytes = NULL;
  981 +
  982 + c1s1_joined_bytes = srs_bytes_join_schema1(owner->time, owner->version, &digest, &key);
  983 +
  984 + srs_assert(c1s1_joined_bytes != NULL);
  985 + SrsAutoFree(char, c1s1_joined_bytes);
  986 +
  987 + c1_digest = new char[__SRS_OpensslHashSize];
  988 + if ((ret = openssl_HMACsha256(SrsGenuineFPKey, 30, c1s1_joined_bytes, 1536 - 32, c1_digest)) != ERROR_SUCCESS) {
  989 + srs_freep(c1_digest);
  990 + srs_error("calc digest for c1 failed. ret=%d", ret);
968 return ret; 991 return ret;
969 } 992 }
970 - srs_assert(pkey_size == 128);  
971 - } else {  
972 - block0.digest.init();  
973 - block1.key.init(); 993 + srs_verbose("digest calculated for c1");
974 994
975 - // directly generate the public key.  
976 - // @see: https://github.com/winlinvip/simple-rtmp-server/issues/148  
977 - int pkey_size = 128;  
978 - if ((ret = dh.copy_public_key(block1.key.key, pkey_size)) != ERROR_SUCCESS) {  
979 - srs_error("calc s1 key failed. ret=%d", ret);  
980 return ret; 995 return ret;
981 } 996 }
982 - srs_assert(pkey_size == 128); 997 +
  998 + int c1s1_strategy_schema1::calc_s1_digest(c1s1* owner, char*& s1_digest)
  999 + {
  1000 + int ret = ERROR_SUCCESS;
  1001 +
  1002 + char* c1s1_joined_bytes = NULL;
  1003 +
  1004 + c1s1_joined_bytes = srs_bytes_join_schema1(owner->time, owner->version, &digest, &key);
  1005 +
  1006 + srs_assert(c1s1_joined_bytes != NULL);
  1007 + SrsAutoFree(char, c1s1_joined_bytes);
  1008 +
  1009 + s1_digest = new char[__SRS_OpensslHashSize];
  1010 + if ((ret = openssl_HMACsha256(SrsGenuineFMSKey, 36, c1s1_joined_bytes, 1536 - 32, s1_digest)) != ERROR_SUCCESS) {
  1011 + srs_freep(s1_digest);
  1012 + srs_error("calc digest for s1 failed. ret=%d", ret);
  1013 + return ret;
983 } 1014 }
984 - srs_verbose("calc s1 key success."); 1015 + srs_verbose("digest calculated for s1");
985 1016
986 - char* s1_digest = NULL;  
987 - if ((ret = calc_s1_digest(s1_digest)) != ERROR_SUCCESS) {  
988 - srs_error("calc s1 digest failed. ret=%d", ret);  
989 return ret; 1017 return ret;
990 } 1018 }
991 - srs_verbose("calc s1 digest success.");  
992 1019
993 - srs_assert(s1_digest != NULL);  
994 - SrsAutoFree(char, s1_digest); 1020 + c2s2::c2s2()
  1021 + {
  1022 + srs_random_generate(random, 1504);
995 1023
996 - if (schema == srs_schema0) {  
997 - memcpy(block1.digest.digest, s1_digest, 32);  
998 - } else {  
999 - memcpy(block0.digest.digest, s1_digest, 32); 1024 + int size = snprintf(random, 1504, "%s", RTMP_SIG_SRS_HANDSHAKE);
  1025 + srs_assert(++size < 1504);
  1026 + snprintf(random + 1504 - size, size, "%s", RTMP_SIG_SRS_HANDSHAKE);
  1027 +
  1028 + srs_random_generate(digest, 32);
1000 } 1029 }
1001 - srs_verbose("copy s1 key success.");  
1002 1030
1003 - return ret; 1031 + c2s2::~c2s2()
  1032 + {
  1033 + }
  1034 +
  1035 + void c2s2::dump(char* _c2s2)
  1036 + {
  1037 + memcpy(_c2s2, random, 1504);
  1038 + memcpy(_c2s2 + 1504, digest, 32);
1004 } 1039 }
1005 1040
1006 - int c1s1::calc_s1_digest(char*& digest) 1041 + void c2s2::parse(char* _c2s2)
  1042 + {
  1043 + memcpy(random, _c2s2, 1504);
  1044 + memcpy(digest, _c2s2 + 1504, 32);
  1045 + }
  1046 +
  1047 + int c2s2::c2_create(c1s1* s1)
1007 { 1048 {
1008 int ret = ERROR_SUCCESS; 1049 int ret = ERROR_SUCCESS;
1009 1050
1010 - srs_assert(schema == srs_schema0 || schema == srs_schema1); 1051 + char temp_key[__SRS_OpensslHashSize];
  1052 + if ((ret = openssl_HMACsha256(SrsGenuineFPKey, 62, s1->get_digest(), 32, temp_key)) != ERROR_SUCCESS) {
  1053 + srs_error("create c2 temp key failed. ret=%d", ret);
  1054 + return ret;
  1055 + }
  1056 + srs_verbose("generate c2 temp key success.");
1011 1057
1012 - char* c1s1_joined_bytes = NULL; 1058 + char _digest[__SRS_OpensslHashSize];
  1059 + if ((ret = openssl_HMACsha256(temp_key, 32, random, 1504, _digest)) != ERROR_SUCCESS) {
  1060 + srs_error("create c2 digest failed. ret=%d", ret);
  1061 + return ret;
  1062 + }
  1063 + srs_verbose("generate c2 digest success.");
1013 1064
1014 - if (schema == srs_schema0) {  
1015 - c1s1_joined_bytes = srs_bytes_join_schema0(time, version, &block0.key, &block1.digest);  
1016 - } else {  
1017 - c1s1_joined_bytes = srs_bytes_join_schema1(time, version, &block0.digest, &block1.key); 1065 + memcpy(digest, _digest, 32);
  1066 +
  1067 + return ret;
1018 } 1068 }
1019 1069
1020 - srs_assert(c1s1_joined_bytes != NULL);  
1021 - SrsAutoFree(char, c1s1_joined_bytes); 1070 + int c2s2::c2_validate(c1s1* s1, bool& is_valid)
  1071 + {
  1072 + is_valid = false;
  1073 + int ret = ERROR_SUCCESS;
1022 1074
1023 - digest = new char[__SRS_OpensslHashSize];  
1024 - if ((ret = openssl_HMACsha256(SrsGenuineFMSKey, 36, c1s1_joined_bytes, 1536 - 32, digest)) != ERROR_SUCCESS) {  
1025 - srs_error("calc digest for s1 failed. ret=%d", ret); 1075 + char temp_key[__SRS_OpensslHashSize];
  1076 + if ((ret = openssl_HMACsha256(SrsGenuineFPKey, 62, s1->get_digest(), 32, temp_key)) != ERROR_SUCCESS) {
  1077 + srs_error("create c2 temp key failed. ret=%d", ret);
1026 return ret; 1078 return ret;
1027 } 1079 }
1028 - srs_verbose("digest calculated for s1"); 1080 + srs_verbose("generate c2 temp key success.");
  1081 +
  1082 + char _digest[__SRS_OpensslHashSize];
  1083 + if ((ret = openssl_HMACsha256(temp_key, 32, random, 1504, _digest)) != ERROR_SUCCESS) {
  1084 + srs_error("create c2 digest failed. ret=%d", ret);
  1085 + return ret;
  1086 + }
  1087 + srs_verbose("generate c2 digest success.");
  1088 +
  1089 + is_valid = srs_bytes_equals(digest, _digest, 32);
1029 1090
1030 return ret; 1091 return ret;
1031 } 1092 }
1032 1093
1033 - int c1s1::calc_c1_digest(char*& digest) 1094 + int c2s2::s2_create(c1s1* c1)
1034 { 1095 {
1035 int ret = ERROR_SUCCESS; 1096 int ret = ERROR_SUCCESS;
1036 1097
1037 - srs_assert(schema == srs_schema0 || schema == srs_schema1); 1098 + char temp_key[__SRS_OpensslHashSize];
  1099 + if ((ret = openssl_HMACsha256(SrsGenuineFMSKey, 68, c1->get_digest(), 32, temp_key)) != ERROR_SUCCESS) {
  1100 + srs_error("create s2 temp key failed. ret=%d", ret);
  1101 + return ret;
  1102 + }
  1103 + srs_verbose("generate s2 temp key success.");
  1104 +
  1105 + char _digest[__SRS_OpensslHashSize];
  1106 + if ((ret = openssl_HMACsha256(temp_key, 32, random, 1504, _digest)) != ERROR_SUCCESS) {
  1107 + srs_error("create s2 digest failed. ret=%d", ret);
  1108 + return ret;
  1109 + }
  1110 + srs_verbose("generate s2 digest success.");
1038 1111
1039 - char* c1s1_joined_bytes = NULL; 1112 + memcpy(digest, _digest, 32);
1040 1113
1041 - if (schema == srs_schema0) {  
1042 - c1s1_joined_bytes = srs_bytes_join_schema0(time, version, &block0.key, &block1.digest);  
1043 - } else {  
1044 - c1s1_joined_bytes = srs_bytes_join_schema1(time, version, &block0.digest, &block1.key); 1114 + return ret;
1045 } 1115 }
1046 1116
1047 - srs_assert(c1s1_joined_bytes != NULL);  
1048 - SrsAutoFree(char, c1s1_joined_bytes); 1117 + int c2s2::s2_validate(c1s1* c1, bool& is_valid)
  1118 + {
  1119 + is_valid = false;
  1120 + int ret = ERROR_SUCCESS;
1049 1121
1050 - digest = new char[__SRS_OpensslHashSize];  
1051 - if ((ret = openssl_HMACsha256(SrsGenuineFPKey, 30, c1s1_joined_bytes, 1536 - 32, digest)) != ERROR_SUCCESS) {  
1052 - srs_error("calc digest for c1 failed. ret=%d", ret); 1122 + char temp_key[__SRS_OpensslHashSize];
  1123 + if ((ret = openssl_HMACsha256(SrsGenuineFMSKey, 68, c1->get_digest(), 32, temp_key)) != ERROR_SUCCESS) {
  1124 + srs_error("create s2 temp key failed. ret=%d", ret);
1053 return ret; 1125 return ret;
1054 } 1126 }
1055 - srs_verbose("digest calculated for c1"); 1127 + srs_verbose("generate s2 temp key success.");
  1128 +
  1129 + char _digest[__SRS_OpensslHashSize];
  1130 + if ((ret = openssl_HMACsha256(temp_key, 32, random, 1504, _digest)) != ERROR_SUCCESS) {
  1131 + srs_error("create s2 digest failed. ret=%d", ret);
  1132 + return ret;
  1133 + }
  1134 + srs_verbose("generate s2 digest success.");
  1135 +
  1136 + is_valid = srs_bytes_equals(digest, _digest, 32);
1056 1137
1057 return ret; 1138 return ret;
1058 } 1139 }
1059 1140
  1141 + // TODO: FIXME: move to the right position.
  1142 + c1s1::c1s1()
  1143 + {
  1144 + payload = NULL;
  1145 + }
  1146 + c1s1::~c1s1()
  1147 + {
  1148 + srs_freep(payload);
  1149 + /*
1060 void c1s1::destroy_blocks() 1150 void c1s1::destroy_blocks()
1061 { 1151 {
1062 if (schema == srs_schema_invalid) { 1152 if (schema == srs_schema_invalid) {
@@ -1070,6 +1160,110 @@ namespace _srs_internal @@ -1070,6 +1160,110 @@ namespace _srs_internal
1070 block0.digest.free(); 1160 block0.digest.free();
1071 block1.key.free(); 1161 block1.key.free();
1072 } 1162 }
  1163 + }*/
  1164 + }
  1165 +
  1166 + srs_schema_type c1s1::schema()
  1167 + {
  1168 + srs_assert(payload != NULL);
  1169 + return payload->schema();
  1170 + }
  1171 +
  1172 + char* c1s1::get_digest()
  1173 + {
  1174 + srs_assert(payload != NULL);
  1175 + return payload->get_digest();
  1176 + }
  1177 +
  1178 + void c1s1::dump(char* _c1s1)
  1179 + {
  1180 + srs_assert(payload != NULL);
  1181 + return payload->dump(this, _c1s1);
  1182 + }
  1183 +
  1184 + int c1s1::parse(char* _c1s1, srs_schema_type schema)
  1185 + {
  1186 + int ret = ERROR_SUCCESS;
  1187 +
  1188 + if (schema != srs_schema0 && schema != srs_schema1) {
  1189 + ret = ERROR_RTMP_CH_SCHEMA;
  1190 + srs_error("parse c1 failed. invalid schema=%d, ret=%d", schema, ret);
  1191 + return ret;
  1192 + }
  1193 +
  1194 + time = __srs_stream_read_4bytes(_c1s1);
  1195 + version = __srs_stream_read_4bytes(_c1s1 + 4); // client c1 version
  1196 +
  1197 + srs_freep(payload);
  1198 + if (schema == srs_schema0) {
  1199 + payload = new c1s1_strategy_schema0();
  1200 + } else {
  1201 + payload = new c1s1_strategy_schema1();
  1202 + }
  1203 +
  1204 + return payload->parse(_c1s1);
  1205 + }
  1206 +
  1207 + int c1s1::c1_create(srs_schema_type schema)
  1208 + {
  1209 + int ret = ERROR_SUCCESS;
  1210 +
  1211 + if (schema != srs_schema0 && schema != srs_schema1) {
  1212 + ret = ERROR_RTMP_CH_SCHEMA;
  1213 + srs_error("create c1 failed. invalid schema=%d, ret=%d", schema, ret);
  1214 + return ret;
  1215 + }
  1216 +
  1217 + // client c1 time and version
  1218 + time = ::time(NULL);
  1219 + version = 0x80000702; // client c1 version
  1220 +
  1221 + // generate signature by schema
  1222 + srs_freep(payload);
  1223 + if (schema == srs_schema0) {
  1224 + payload = new c1s1_strategy_schema0();
  1225 + } else {
  1226 + payload = new c1s1_strategy_schema1();
  1227 + }
  1228 +
  1229 + return payload->c1_create(this);
  1230 + }
  1231 +
  1232 + int c1s1::c1_validate_digest(bool& is_valid)
  1233 + {
  1234 + is_valid = false;
  1235 + srs_assert(payload);
  1236 + return payload->c1_validate_digest(this, is_valid);
  1237 + }
  1238 +
  1239 + int c1s1::s1_validate_digest(bool& is_valid)
  1240 + {
  1241 + is_valid = false;
  1242 + srs_assert(payload);
  1243 + return payload->s1_validate_digest(this, is_valid);
  1244 + }
  1245 +
  1246 + int c1s1::s1_create(c1s1* c1)
  1247 + {
  1248 + int ret = ERROR_SUCCESS;
  1249 +
  1250 + if (c1->schema() != srs_schema0 && c1->schema() != srs_schema1) {
  1251 + ret = ERROR_RTMP_CH_SCHEMA;
  1252 + srs_error("create s1 failed. invalid schema=%d, ret=%d", c1->schema(), ret);
  1253 + return ret;
  1254 + }
  1255 +
  1256 + time = ::time(NULL);
  1257 + version = 0x01000504; // server s1 version
  1258 +
  1259 + srs_freep(payload);
  1260 + if (c1->schema() == srs_schema0) {
  1261 + payload = new c1s1_strategy_schema0();
  1262 + } else {
  1263 + payload = new c1s1_strategy_schema1();
  1264 + }
  1265 +
  1266 + return payload->s1_create(this);
1073 } 1267 }
1074 } 1268 }
1075 1269
@@ -1190,6 +1384,7 @@ int SrsComplexHandshake::handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrs @@ -1190,6 +1384,7 @@ int SrsComplexHandshake::handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrs
1190 // decode c1 1384 // decode c1
1191 c1s1 c1; 1385 c1s1 c1;
1192 // try schema0. 1386 // try schema0.
  1387 + // @remark, use schema0 to make flash player happy.
1193 if ((ret = c1.parse(hs_bytes->c0c1 + 1, srs_schema0)) != ERROR_SUCCESS) { 1388 if ((ret = c1.parse(hs_bytes->c0c1 + 1, srs_schema0)) != ERROR_SUCCESS) {
1194 srs_error("parse c1 schema%d error. ret=%d", srs_schema0, ret); 1389 srs_error("parse c1 schema%d error. ret=%d", srs_schema0, ret);
1195 return ret; 1390 return ret;
@@ -1197,6 +1392,7 @@ int SrsComplexHandshake::handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrs @@ -1197,6 +1392,7 @@ int SrsComplexHandshake::handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrs
1197 // try schema1 1392 // try schema1
1198 bool is_valid = false; 1393 bool is_valid = false;
1199 if ((ret = c1.c1_validate_digest(is_valid)) != ERROR_SUCCESS || !is_valid) { 1394 if ((ret = c1.c1_validate_digest(is_valid)) != ERROR_SUCCESS || !is_valid) {
  1395 + srs_info("schema0 failed, try schema1.");
1200 if ((ret = c1.parse(hs_bytes->c0c1 + 1, srs_schema1)) != ERROR_SUCCESS) { 1396 if ((ret = c1.parse(hs_bytes->c0c1 + 1, srs_schema1)) != ERROR_SUCCESS) {
1201 srs_error("parse c1 schema%d error. ret=%d", srs_schema1, ret); 1397 srs_error("parse c1 schema%d error. ret=%d", srs_schema1, ret);
1202 return ret; 1398 return ret;
@@ -1207,6 +1403,8 @@ int SrsComplexHandshake::handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrs @@ -1207,6 +1403,8 @@ int SrsComplexHandshake::handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrs
1207 srs_info("all schema valid failed, try simple handshake. ret=%d", ret); 1403 srs_info("all schema valid failed, try simple handshake. ret=%d", ret);
1208 return ret; 1404 return ret;
1209 } 1405 }
  1406 + } else {
  1407 + srs_info("schema0 is ok.");
1210 } 1408 }
1211 srs_verbose("decode c1 success."); 1409 srs_verbose("decode c1 success.");
1212 1410
@@ -1321,7 +1519,7 @@ int SrsComplexHandshake::handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrs @@ -1321,7 +1519,7 @@ int SrsComplexHandshake::handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrs
1321 1519
1322 // verify s1s2 1520 // verify s1s2
1323 c1s1 s1; 1521 c1s1 s1;
1324 - if ((ret = s1.parse(hs_bytes->s0s1s2 + 1, c1.schema)) != ERROR_SUCCESS) { 1522 + if ((ret = s1.parse(hs_bytes->s0s1s2 + 1, c1.schema())) != ERROR_SUCCESS) {
1325 return ret; 1523 return ret;
1326 } 1524 }
1327 1525
@@ -219,6 +219,121 @@ namespace _srs_internal @@ -219,6 +219,121 @@ namespace _srs_internal
219 */ 219 */
220 char* srs_bytes_join_schema1(int32_t time, int32_t version, digest_block* digest, key_block* key); 220 char* srs_bytes_join_schema1(int32_t time, int32_t version, digest_block* digest, key_block* key);
221 221
  222 + class c1s1;
  223 +
  224 + /**
  225 + * the c1s1 strategy, use schema0 or schema1.
  226 + * the template method class to defines common behaviors,
  227 + * while the concrete class to implements in schema0 or schema1.
  228 + */
  229 + class c1s1_strategy
  230 + {
  231 + public:
  232 + c1s1_strategy();
  233 + virtual ~c1s1_strategy();
  234 + public:
  235 + /**
  236 + * get the scema.
  237 + */
  238 + virtual srs_schema_type schema() = 0;
  239 + /**
  240 + * get the digest key.
  241 + */
  242 + virtual char* get_digest() = 0;
  243 + /**
  244 + * copy to bytes.
  245 + */
  246 + virtual void dump(c1s1* owner, char* _c1s1) = 0;
  247 + /**
  248 + * server: parse the c1s1, discovery the key and digest by schema.
  249 + * use the c1_validate_digest() to valid the digest of c1.
  250 + */
  251 + virtual int parse(char* _c1s1) = 0;
  252 + public:
  253 + /**
  254 + * client: create and sign c1 by schema.
  255 + * sign the c1, generate the digest.
  256 + * calc_c1_digest(c1, schema) {
  257 + * get c1s1-joined from c1 by specified schema
  258 + * digest-data = HMACsha256(c1s1-joined, FPKey, 30)
  259 + * return digest-data;
  260 + * }
  261 + * random fill 1536bytes c1 // also fill the c1-128bytes-key
  262 + * time = time() // c1[0-3]
  263 + * version = [0x80, 0x00, 0x07, 0x02] // c1[4-7]
  264 + * schema = choose schema0 or schema1
  265 + * digest-data = calc_c1_digest(c1, schema)
  266 + * copy digest-data to c1
  267 + */
  268 + virtual int c1_create(c1s1* owner) = 0;
  269 + /**
  270 + * server: validate the parsed c1 schema
  271 + */
  272 + virtual int c1_validate_digest(c1s1* owner, bool& is_valid) = 0;
  273 + /**
  274 + * server: create and sign the s1 from c1.
  275 + */
  276 + virtual int s1_create(c1s1* owner) = 0;
  277 + /**
  278 + * server: validate the parsed s1 schema
  279 + */
  280 + virtual int s1_validate_digest(c1s1* owner, bool& is_valid) = 0;
  281 + };
  282 +
  283 + /**
  284 + * c1s1 schema0
  285 + * key: 764bytes
  286 + * digest: 764bytes
  287 + */
  288 + class c1s1_strategy_schema0 : public c1s1_strategy
  289 + {
  290 + private:
  291 + key_block key;
  292 + digest_block digest;
  293 + public:
  294 + c1s1_strategy_schema0();
  295 + virtual ~c1s1_strategy_schema0();
  296 + public:
  297 + virtual srs_schema_type schema();
  298 + virtual char* get_digest();
  299 + virtual void dump(c1s1* owner, char* _c1s1);
  300 + virtual int parse(char* _c1s1);
  301 + virtual int c1_create(c1s1* owner);
  302 + virtual int c1_validate_digest(c1s1* owner, bool& is_valid);
  303 + virtual int s1_create(c1s1* owner);
  304 + virtual int s1_validate_digest(c1s1* owner, bool& is_valid);
  305 + private:
  306 + virtual int calc_c1_digest(c1s1* owner, char*& c1_digest);
  307 + virtual int calc_s1_digest(c1s1* owner, char*& s1_digest);
  308 + };
  309 +
  310 + /**
  311 + * c1s1 schema1
  312 + * digest: 764bytes
  313 + * key: 764bytes
  314 + */
  315 + class c1s1_strategy_schema1 : public c1s1_strategy
  316 + {
  317 + private:
  318 + digest_block digest;
  319 + key_block key;
  320 + public:
  321 + c1s1_strategy_schema1();
  322 + virtual ~c1s1_strategy_schema1();
  323 + public:
  324 + virtual srs_schema_type schema();
  325 + virtual char* get_digest();
  326 + virtual void dump(c1s1* owner, char* _c1s1);
  327 + virtual int parse(char* _c1s1);
  328 + virtual int c1_create(c1s1* owner);
  329 + virtual int c1_validate_digest(c1s1* owner, bool& is_valid);
  330 + virtual int s1_create(c1s1* owner);
  331 + virtual int s1_validate_digest(c1s1* owner, bool& is_valid);
  332 + private:
  333 + virtual int calc_c1_digest(c1s1* owner, char*& c1_digest);
  334 + virtual int calc_s1_digest(c1s1* owner, char*& s1_digest);
  335 + };
  336 +
222 /** 337 /**
223 * c1s1 schema0 338 * c1s1 schema0
224 * time: 4bytes 339 * time: 4bytes
@@ -235,30 +350,20 @@ namespace _srs_internal @@ -235,30 +350,20 @@ namespace _srs_internal
235 class c1s1 350 class c1s1
236 { 351 {
237 public: 352 public:
238 - union block {  
239 - key_block key;  
240 - digest_block digest;  
241 - };  
242 -  
243 // 4bytes 353 // 4bytes
244 int32_t time; 354 int32_t time;
245 // 4bytes 355 // 4bytes
246 int32_t version; 356 int32_t version;
247 - // 764bytes  
248 - // if schema0, use key  
249 - // if schema1, use digest  
250 - block block0;  
251 - // 764bytes  
252 - // if schema0, use digest  
253 - // if schema1, use key  
254 - block block1;  
255 -  
256 - // the logic schema  
257 - srs_schema_type schema; 357 + // 764bytes+764bytes
  358 + c1s1_strategy* payload;
258 359
259 c1s1(); 360 c1s1();
260 virtual ~c1s1(); 361 virtual ~c1s1();
261 /** 362 /**
  363 + * get the scema.
  364 + */
  365 + virtual srs_schema_type schema();
  366 + /**
262 * get the digest key. 367 * get the digest key.
263 */ 368 */
264 virtual char* get_digest(); 369 virtual char* get_digest();
@@ -269,6 +374,7 @@ namespace _srs_internal @@ -269,6 +374,7 @@ namespace _srs_internal
269 /** 374 /**
270 * server: parse the c1s1, discovery the key and digest by schema. 375 * server: parse the c1s1, discovery the key and digest by schema.
271 * use the c1_validate_digest() to valid the digest of c1. 376 * use the c1_validate_digest() to valid the digest of c1.
  377 + * use the s1_validate_digest() to valid the digest of s1.
272 */ 378 */
273 virtual int parse(char* _c1s1, srs_schema_type _schema); 379 virtual int parse(char* _c1s1, srs_schema_type _schema);
274 380
@@ -294,16 +400,35 @@ namespace _srs_internal @@ -294,16 +400,35 @@ namespace _srs_internal
294 virtual int c1_validate_digest(bool& is_valid); 400 virtual int c1_validate_digest(bool& is_valid);
295 /** 401 /**
296 * server: create and sign the s1 from c1. 402 * server: create and sign the s1 from c1.
  403 + * // decode c1 try schema0 then schema1
  404 + * c1-digest-data = get-c1-digest-data(schema0)
  405 + * if c1-digest-data equals to calc_c1_digest(c1, schema0) {
  406 + * c1-key-data = get-c1-key-data(schema0)
  407 + * schema = schema0
  408 + * } else {
  409 + * c1-digest-data = get-c1-digest-data(schema1)
  410 + * if c1-digest-data not equals to calc_c1_digest(c1, schema1) {
  411 + * switch to simple handshake.
  412 + * return
  413 + * }
  414 + * c1-key-data = get-c1-key-data(schema1)
  415 + * schema = schema1
  416 + * }
  417 + *
  418 + * // generate s1
  419 + * random fill 1536bytes s1
  420 + * time = time() // c1[0-3]
  421 + * version = [0x04, 0x05, 0x00, 0x01] // s1[4-7]
  422 + * s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data)
  423 + * get c1s1-joined by specified schema
  424 + * s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36)
  425 + * copy s1-digest-data and s1-key-data to s1.
297 */ 426 */
298 virtual int s1_create(c1s1* c1); 427 virtual int s1_create(c1s1* c1);
299 /** 428 /**
300 * server: validate the parsed s1 schema 429 * server: validate the parsed s1 schema
301 */ 430 */
302 virtual int s1_validate_digest(bool& is_valid); 431 virtual int s1_validate_digest(bool& is_valid);
303 - private:  
304 - virtual int calc_s1_digest(char*& digest);  
305 - virtual int calc_c1_digest(char*& digest);  
306 - virtual void destroy_blocks();  
307 }; 432 };
308 433
309 /** 434 /**