Mercurial > dropbear
comparison common-kex.c @ 1683:41bf8f216644
merge rsa-sha256
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Tue, 26 May 2020 00:24:02 +0800 |
parents | 3a97f14c0235 435cfb9ec96e |
children | 1051e4eea25a |
comparison
equal
deleted
inserted
replaced
1673:e0871128e61f | 1683:41bf8f216644 |
---|---|
63 | 63 |
64 /* kex algos */ | 64 /* kex algos */ |
65 buf_put_algolist(ses.writepayload, sshkex); | 65 buf_put_algolist(ses.writepayload, sshkex); |
66 | 66 |
67 /* server_host_key_algorithms */ | 67 /* server_host_key_algorithms */ |
68 buf_put_algolist(ses.writepayload, sshhostkey); | 68 buf_put_algolist(ses.writepayload, sigalgs); |
69 | 69 |
70 /* encryption_algorithms_client_to_server */ | 70 /* encryption_algorithms_client_to_server */ |
71 buf_put_algolist(ses.writepayload, sshciphers); | 71 buf_put_algolist(ses.writepayload, sshciphers); |
72 | 72 |
73 /* encryption_algorithms_server_to_client */ | 73 /* encryption_algorithms_server_to_client */ |
108 ses.kexstate.sentkexinit = 1; | 108 ses.kexstate.sentkexinit = 1; |
109 | 109 |
110 ses.newkeys = (struct key_context*)m_malloc(sizeof(struct key_context)); | 110 ses.newkeys = (struct key_context*)m_malloc(sizeof(struct key_context)); |
111 | 111 |
112 if (ses.send_kex_first_guess) { | 112 if (ses.send_kex_first_guess) { |
113 ses.newkeys->algo_kex = sshkex[0].data; | 113 ses.newkeys->algo_kex = first_usable_algo(sshkex)->data; |
114 ses.newkeys->algo_hostkey = sshhostkey[0].val; | 114 ses.newkeys->algo_signature = first_usable_algo(sigalgs)->val; |
115 ses.newkeys->algo_hostkey = signkey_type_from_signature(ses.newkeys->algo_signature); | |
115 ses.send_kex_first_guess(); | 116 ses.send_kex_first_guess(); |
116 } | 117 } |
117 | 118 |
118 TRACE(("DATAALLOWED=0")) | 119 TRACE(("DATAALLOWED=0")) |
119 TRACE(("-> KEXINIT")) | 120 TRACE(("-> KEXINIT")) |
150 if (ses.kexstate.sentnewkeys && ses.kexstate.recvnewkeys) | 151 if (ses.kexstate.sentnewkeys && ses.kexstate.recvnewkeys) |
151 { | 152 { |
152 TRACE(("switch_keys done")) | 153 TRACE(("switch_keys done")) |
153 ses.keys->algo_kex = ses.newkeys->algo_kex; | 154 ses.keys->algo_kex = ses.newkeys->algo_kex; |
154 ses.keys->algo_hostkey = ses.newkeys->algo_hostkey; | 155 ses.keys->algo_hostkey = ses.newkeys->algo_hostkey; |
156 ses.keys->algo_signature = ses.newkeys->algo_signature; | |
155 ses.keys->allow_compress = 0; | 157 ses.keys->allow_compress = 0; |
156 m_free(ses.newkeys); | 158 m_free(ses.newkeys); |
157 ses.newkeys = NULL; | 159 ses.newkeys = NULL; |
158 kexinitialise(); | 160 kexinitialise(); |
159 } | 161 } |
171 encrypt_packet(); | 173 encrypt_packet(); |
172 | 174 |
173 | 175 |
174 /* set up our state */ | 176 /* set up our state */ |
175 ses.kexstate.sentnewkeys = 1; | 177 ses.kexstate.sentnewkeys = 1; |
178 if (ses.kexstate.donefirstkex) { | |
179 ses.kexstate.donesecondkex = 1; | |
180 } | |
176 ses.kexstate.donefirstkex = 1; | 181 ses.kexstate.donefirstkex = 1; |
177 ses.dataallowed = 1; /* we can send other packets again now */ | 182 ses.dataallowed = 1; /* we can send other packets again now */ |
178 gen_new_keys(); | 183 gen_new_keys(); |
179 switch_keys(); | 184 switch_keys(); |
180 | 185 |
193 } | 198 } |
194 | 199 |
195 | 200 |
196 /* Set up the kex for the first time */ | 201 /* Set up the kex for the first time */ |
197 void kexfirstinitialise() { | 202 void kexfirstinitialise() { |
198 ses.kexstate.donefirstkex = 0; | |
199 | |
200 #ifdef DISABLE_ZLIB | 203 #ifdef DISABLE_ZLIB |
201 ses.compress_algos = ssh_nocompress; | 204 ses.compress_algos = ssh_nocompress; |
202 #else | 205 #else |
203 switch (opts.compress_mode) | 206 switch (opts.compress_mode) |
204 { | 207 { |
330 | 333 |
331 if (ses.newkeys->recv.algo_crypt->cipherdesc != NULL) { | 334 if (ses.newkeys->recv.algo_crypt->cipherdesc != NULL) { |
332 int recv_cipher = -1; | 335 int recv_cipher = -1; |
333 if (ses.newkeys->recv.algo_crypt->cipherdesc->name != NULL) { | 336 if (ses.newkeys->recv.algo_crypt->cipherdesc->name != NULL) { |
334 recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name); | 337 recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name); |
335 if (recv_cipher < 0) | 338 if (recv_cipher < 0) |
336 dropbear_exit("Crypto error"); | 339 dropbear_exit("Crypto error"); |
337 } | 340 } |
338 if (ses.newkeys->recv.crypt_mode->start(recv_cipher, | 341 if (ses.newkeys->recv.crypt_mode->start(recv_cipher, |
339 recv_IV, recv_key, | 342 recv_IV, recv_key, |
340 ses.newkeys->recv.algo_crypt->keysize, 0, | 343 ses.newkeys->recv.algo_crypt->keysize, 0, |
341 &ses.newkeys->recv.cipher_state) != CRYPT_OK) { | 344 &ses.newkeys->recv.cipher_state) != CRYPT_OK) { |
345 | 348 |
346 if (ses.newkeys->trans.algo_crypt->cipherdesc != NULL) { | 349 if (ses.newkeys->trans.algo_crypt->cipherdesc != NULL) { |
347 int trans_cipher = -1; | 350 int trans_cipher = -1; |
348 if (ses.newkeys->trans.algo_crypt->cipherdesc->name != NULL) { | 351 if (ses.newkeys->trans.algo_crypt->cipherdesc->name != NULL) { |
349 trans_cipher = find_cipher(ses.newkeys->trans.algo_crypt->cipherdesc->name); | 352 trans_cipher = find_cipher(ses.newkeys->trans.algo_crypt->cipherdesc->name); |
350 if (trans_cipher < 0) | 353 if (trans_cipher < 0) |
351 dropbear_exit("Crypto error"); | 354 dropbear_exit("Crypto error"); |
352 } | 355 } |
353 if (ses.newkeys->trans.crypt_mode->start(trans_cipher, | 356 if (ses.newkeys->trans.crypt_mode->start(trans_cipher, |
354 trans_IV, trans_key, | 357 trans_IV, trans_key, |
355 ses.newkeys->trans.algo_crypt->keysize, 0, | 358 ses.newkeys->trans.algo_crypt->keysize, 0, |
356 &ses.newkeys->trans.cipher_state) != CRYPT_OK) { | 359 &ses.newkeys->trans.cipher_state) != CRYPT_OK) { |
822 char * erralgo = NULL; | 825 char * erralgo = NULL; |
823 | 826 |
824 int goodguess = 0; | 827 int goodguess = 0; |
825 int allgood = 1; /* we AND this with each goodguess and see if its still | 828 int allgood = 1; /* we AND this with each goodguess and see if its still |
826 true after */ | 829 true after */ |
827 | 830 int kexguess2 = 0; |
831 | |
832 buf_incrpos(ses.payload, 16); /* start after the cookie */ | |
833 | |
834 memset(ses.newkeys, 0x0, sizeof(*ses.newkeys)); | |
835 | |
836 /* kex_algorithms */ | |
828 #if DROPBEAR_KEXGUESS2 | 837 #if DROPBEAR_KEXGUESS2 |
829 enum kexguess2_used kexguess2 = KEXGUESS2_LOOK; | 838 if (buf_has_algo(ses.payload, KEXGUESS2_ALGO_NAME) == DROPBEAR_SUCCESS) { |
830 #else | 839 kexguess2 = 1; |
831 enum kexguess2_used kexguess2 = KEXGUESS2_NO; | 840 } |
832 #endif | 841 #endif |
833 | 842 |
834 buf_incrpos(ses.payload, 16); /* start after the cookie */ | 843 #if DROPBEAR_EXT_INFO |
835 | 844 /* Determine if SSH_MSG_EXT_INFO messages should be sent. |
836 memset(ses.newkeys, 0x0, sizeof(*ses.newkeys)); | 845 Should be done for the first key exchange. Only required on server side |
837 | 846 for server-sig-algs */ |
838 /* kex_algorithms */ | 847 if (IS_DROPBEAR_SERVER) { |
839 algo = buf_match_algo(ses.payload, sshkex, &kexguess2, &goodguess); | 848 if (!ses.kexstate.donefirstkex) { |
849 if (buf_has_algo(ses.payload, SSH_EXT_INFO_C) == DROPBEAR_SUCCESS) { | |
850 ses.allow_ext_info = 1; | |
851 } | |
852 } | |
853 } | |
854 #endif | |
855 | |
856 algo = buf_match_algo(ses.payload, sshkex, kexguess2, &goodguess); | |
840 allgood &= goodguess; | 857 allgood &= goodguess; |
841 if (algo == NULL || algo->val == KEXGUESS2_ALGO_ID) { | 858 if (algo == NULL || algo->data == NULL) { |
859 /* kexguess2, ext-info-c, ext-info-s should not match negotiation */ | |
842 erralgo = "kex"; | 860 erralgo = "kex"; |
843 goto error; | 861 goto error; |
844 } | 862 } |
845 TRACE(("kexguess2 %d", kexguess2)) | 863 TRACE(("kexguess2 %d", kexguess2)) |
846 TRACE(("kex algo %s", algo->name)) | 864 TRACE(("kex algo %s", algo->name)) |
847 ses.newkeys->algo_kex = algo->data; | 865 ses.newkeys->algo_kex = algo->data; |
848 | 866 |
849 /* server_host_key_algorithms */ | 867 /* server_host_key_algorithms */ |
850 algo = buf_match_algo(ses.payload, sshhostkey, &kexguess2, &goodguess); | 868 algo = buf_match_algo(ses.payload, sigalgs, kexguess2, &goodguess); |
851 allgood &= goodguess; | 869 allgood &= goodguess; |
852 if (algo == NULL) { | 870 if (algo == NULL) { |
853 erralgo = "hostkey"; | 871 erralgo = "hostkey"; |
854 goto error; | 872 goto error; |
855 } | 873 } |
856 TRACE(("hostkey algo %s", algo->name)) | 874 TRACE(("signature algo %s", algo->name)) |
857 ses.newkeys->algo_hostkey = algo->val; | 875 ses.newkeys->algo_signature = algo->val; |
876 ses.newkeys->algo_hostkey = signkey_type_from_signature(ses.newkeys->algo_signature); | |
858 | 877 |
859 /* encryption_algorithms_client_to_server */ | 878 /* encryption_algorithms_client_to_server */ |
860 c2s_cipher_algo = buf_match_algo(ses.payload, sshciphers, NULL, NULL); | 879 c2s_cipher_algo = buf_match_algo(ses.payload, sshciphers, 0, NULL); |
861 if (c2s_cipher_algo == NULL) { | 880 if (c2s_cipher_algo == NULL) { |
862 erralgo = "enc c->s"; | 881 erralgo = "enc c->s"; |
863 goto error; | 882 goto error; |
864 } | 883 } |
865 TRACE(("enc c2s is %s", c2s_cipher_algo->name)) | 884 TRACE(("enc c2s is %s", c2s_cipher_algo->name)) |
866 | 885 |
867 /* encryption_algorithms_server_to_client */ | 886 /* encryption_algorithms_server_to_client */ |
868 s2c_cipher_algo = buf_match_algo(ses.payload, sshciphers, NULL, NULL); | 887 s2c_cipher_algo = buf_match_algo(ses.payload, sshciphers, 0, NULL); |
869 if (s2c_cipher_algo == NULL) { | 888 if (s2c_cipher_algo == NULL) { |
870 erralgo = "enc s->c"; | 889 erralgo = "enc s->c"; |
871 goto error; | 890 goto error; |
872 } | 891 } |
873 TRACE(("enc s2c is %s", s2c_cipher_algo->name)) | 892 TRACE(("enc s2c is %s", s2c_cipher_algo->name)) |
874 | 893 |
875 /* mac_algorithms_client_to_server */ | 894 /* mac_algorithms_client_to_server */ |
876 c2s_hash_algo = buf_match_algo(ses.payload, sshhashes, NULL, NULL); | 895 c2s_hash_algo = buf_match_algo(ses.payload, sshhashes, 0, NULL); |
877 #if DROPBEAR_AEAD_MODE | 896 #if DROPBEAR_AEAD_MODE |
878 if (((struct dropbear_cipher_mode*)c2s_cipher_algo->mode)->aead_crypt != NULL) { | 897 if (((struct dropbear_cipher_mode*)c2s_cipher_algo->mode)->aead_crypt != NULL) { |
879 c2s_hash_algo = NULL; | 898 c2s_hash_algo = NULL; |
880 } else | 899 } else |
881 #endif | 900 #endif |
884 goto error; | 903 goto error; |
885 } | 904 } |
886 TRACE(("hash c2s is %s", c2s_hash_algo ? c2s_hash_algo->name : "<implicit>")) | 905 TRACE(("hash c2s is %s", c2s_hash_algo ? c2s_hash_algo->name : "<implicit>")) |
887 | 906 |
888 /* mac_algorithms_server_to_client */ | 907 /* mac_algorithms_server_to_client */ |
889 s2c_hash_algo = buf_match_algo(ses.payload, sshhashes, NULL, NULL); | 908 s2c_hash_algo = buf_match_algo(ses.payload, sshhashes, 0, NULL); |
890 #if DROPBEAR_AEAD_MODE | 909 #if DROPBEAR_AEAD_MODE |
891 if (((struct dropbear_cipher_mode*)s2c_cipher_algo->mode)->aead_crypt != NULL) { | 910 if (((struct dropbear_cipher_mode*)s2c_cipher_algo->mode)->aead_crypt != NULL) { |
892 s2c_hash_algo = NULL; | 911 s2c_hash_algo = NULL; |
893 } else | 912 } else |
894 #endif | 913 #endif |
897 goto error; | 916 goto error; |
898 } | 917 } |
899 TRACE(("hash s2c is %s", s2c_hash_algo ? s2c_hash_algo->name : "<implicit>")) | 918 TRACE(("hash s2c is %s", s2c_hash_algo ? s2c_hash_algo->name : "<implicit>")) |
900 | 919 |
901 /* compression_algorithms_client_to_server */ | 920 /* compression_algorithms_client_to_server */ |
902 c2s_comp_algo = buf_match_algo(ses.payload, ses.compress_algos, NULL, NULL); | 921 c2s_comp_algo = buf_match_algo(ses.payload, ses.compress_algos, 0, NULL); |
903 if (c2s_comp_algo == NULL) { | 922 if (c2s_comp_algo == NULL) { |
904 erralgo = "comp c->s"; | 923 erralgo = "comp c->s"; |
905 goto error; | 924 goto error; |
906 } | 925 } |
907 TRACE(("hash c2s is %s", c2s_comp_algo->name)) | 926 TRACE(("hash c2s is %s", c2s_comp_algo->name)) |
908 | 927 |
909 /* compression_algorithms_server_to_client */ | 928 /* compression_algorithms_server_to_client */ |
910 s2c_comp_algo = buf_match_algo(ses.payload, ses.compress_algos, NULL, NULL); | 929 s2c_comp_algo = buf_match_algo(ses.payload, ses.compress_algos, 0, NULL); |
911 if (s2c_comp_algo == NULL) { | 930 if (s2c_comp_algo == NULL) { |
912 erralgo = "comp s->c"; | 931 erralgo = "comp s->c"; |
913 goto error; | 932 goto error; |
914 } | 933 } |
915 TRACE(("hash s2c is %s", s2c_comp_algo->name)) | 934 TRACE(("hash s2c is %s", s2c_comp_algo->name)) |