ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/protocol.C
(Generate patch)

Comparing gvpe/src/protocol.C (file contents):
Revision 1.9 by pcg, Fri Mar 21 23:17:01 2003 UTC vs.
Revision 1.10 by pcg, Sat Mar 22 02:35:57 2003 UTC

16 Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17*/ 17*/
18 18
19#include "config.h" 19#include "config.h"
20 20
21#include <list>
22
21#include <cstdlib> 23#include <cstdlib>
22#include <cstring> 24#include <cstring>
23#include <cstdio> 25#include <cstdio>
24 26
25#include <sys/types.h> 27#include <sys/types.h>
71 } 73 }
72 74
73 return challenge; 75 return challenge;
74} 76}
75 77
78// caching of rsa operations really helps slow computers
79struct rsa_entry {
80 tstamp expire;
81 rsachallenge chg;
82 RSA *key; // which key
83 rsaencrdata encr;
84
85 rsa_entry ()
86 {
87 expire = NOW + CHALLENGE_TTL;
88 }
89};
90
91struct rsa_cache : list<rsa_entry>
92{
93 void cleaner_cb (tstamp &ts); time_watcher cleaner;
94
95 const rsaencrdata *public_encrypt (RSA *key, const rsachallenge &chg)
96 {
97 for (iterator i = begin (); i != end (); ++i)
98 {
99 if (i->key == key && !memcmp (&chg, &i->chg, sizeof chg))
100 return &i->encr;
101 }
102
103 if (cleaner.at < NOW)
104 cleaner.start (NOW + CHALLENGE_TTL);
105
106 resize (size () + 1);
107 rsa_entry *e = &(*rbegin ());
108
109 e->key = key;
110 memcpy (&e->chg, &chg, sizeof chg);
111
112 if (0 > RSA_public_encrypt (sizeof chg,
113 (unsigned char *)&chg, (unsigned char *)&e->encr,
114 key, RSA_PKCS1_OAEP_PADDING))
115 fatal ("RSA_public_encrypt error");
116
117 return &e->encr;
118 }
119
120 const rsachallenge *private_decrypt (RSA *key, const rsaencrdata &encr)
121 {
122 for (iterator i = begin (); i != end (); ++i)
123 if (i->key == key && !memcmp (&encr, &i->encr, sizeof encr))
124 return &i->chg;
125
126 if (cleaner.at < NOW)
127 cleaner.start (NOW + CHALLENGE_TTL);
128
129 resize (size () + 1);
130 rsa_entry *e = &(*rbegin ());
131
132 e->key = key;
133 memcpy (&e->encr, &encr, sizeof encr);
134
135 if (0 > RSA_private_decrypt (sizeof encr,
136 (unsigned char *)&encr, (unsigned char *)&e->chg,
137 key, RSA_PKCS1_OAEP_PADDING))
138 {
139 pop_back ();
140 return 0;
141 }
142
143 return &e->chg;
144 }
145
146 rsa_cache ()
147 : cleaner (this, &rsa_cache::cleaner_cb)
148 { }
149
150} rsa_cache;
151
152void rsa_cache::cleaner_cb (tstamp &ts)
153{
154 if (empty ())
155 ts = TSTAMP_CANCEL;
156 else
157 {
158 ts = NOW + 3;
159 for (iterator i = begin (); i != end (); )
160 {
161 if (i->expire >= NOW)
162 i = erase (i);
163 else
164 ++i;
165 }
166 }
167}
168
76// run a script. yes, it's a template function. yes, c++ 169// run a script. yes, it's a template function. yes, c++
77// is not a functional language. yes, this suxx. 170// is not a functional language. yes, this suxx.
78template<class owner> 171template<class owner>
79static void 172static void
80run_script (owner *obj, const char *(owner::*setup)(), bool wait) 173run_script (owner *obj, const char *(owner::*setup)(), bool wait)
112struct crypto_ctx 205struct crypto_ctx
113 { 206 {
114 EVP_CIPHER_CTX cctx; 207 EVP_CIPHER_CTX cctx;
115 HMAC_CTX hctx; 208 HMAC_CTX hctx;
116 209
117 crypto_ctx (rsachallenge &challenge, int enc); 210 crypto_ctx (const rsachallenge &challenge, int enc);
118 ~crypto_ctx (); 211 ~crypto_ctx ();
119 }; 212 };
120 213
121crypto_ctx::crypto_ctx (rsachallenge &challenge, int enc) 214crypto_ctx::crypto_ctx (const rsachallenge &challenge, int enc)
122{ 215{
123 EVP_CIPHER_CTX_init (&cctx); 216 EVP_CIPHER_CTX_init (&cctx);
124 EVP_CipherInit_ex (&cctx, CIPHER, 0, &challenge[CHG_CIPHER_KEY], 0, enc); 217 EVP_CipherInit_ex (&cctx, CIPHER, 0, &challenge[CHG_CIPHER_KEY], 0, enc);
125 HMAC_CTX_init (&hctx); 218 HMAC_CTX_init (&hctx);
126 HMAC_Init_ex (&hctx, &challenge[CHG_HMAC_KEY], HMAC_KEYLEN, DIGEST, 0); 219 HMAC_Init_ex (&hctx, &challenge[CHG_HMAC_KEY], HMAC_KEYLEN, DIGEST, 0);
581void 674void
582connection::send_reset (SOCKADDR *dsa) 675connection::send_reset (SOCKADDR *dsa)
583{ 676{
584 static net_rate_limiter limiter(1); 677 static net_rate_limiter limiter(1);
585 678
586 if (limiter.can (dsa)) 679 if (limiter.can (dsa) && connectmode != conf_node::C_DISABLED)
587 { 680 {
588 config_packet *pkt = new config_packet; 681 config_packet *pkt = new config_packet;
589 682
590 pkt->setup (vpn_packet::PT_RESET, conf->id); 683 pkt->setup (vpn_packet::PT_RESET, conf->id);
591 vpn->send_vpn_packet (pkt, dsa, IPTOS_MINCOST); 684 vpn->send_vpn_packet (pkt, dsa, IPTOS_MINCOST);
593 delete pkt; 686 delete pkt;
594 } 687 }
595} 688}
596 689
597static rsachallenge * 690static rsachallenge *
598gen_challenge (SOCKADDR *sa) 691gen_challenge (u32 seqrand, SOCKADDR *sa)
599{ 692{
600 static rsachallenge k; 693 static rsachallenge k;
601 694
602 memcpy (&k, &challenge_bytes (), sizeof (k)); 695 memcpy (&k, &challenge_bytes (), sizeof (k));
603 RAND_bytes ((unsigned char *)&k[CHG_SEQNO], sizeof (u32)); 696 *(u32 *)&k[CHG_SEQNO] ^= seqrand;
604 xor_sa (k, sa); 697 xor_sa (k, sa);
605 698
606 return &k; 699 return &k;
607} 700}
608 701
609void 702void
610connection::send_auth (auth_subtype subtype, SOCKADDR *sa, rsachallenge *k) 703connection::send_auth (auth_subtype subtype, SOCKADDR *sa, const rsachallenge *k)
611{ 704{
612 static net_rate_limiter limiter(2); 705 static net_rate_limiter limiter(0.2);
613 706
614 if (subtype != AUTH_INIT || limiter.can (sa)) 707 if (subtype != AUTH_INIT || limiter.can (sa))
615 { 708 {
709 if (!k)
710 k = gen_challenge (seqrand, sa);
711
616 auth_packet *pkt = new auth_packet (conf->id, subtype); 712 auth_packet *pkt = new auth_packet (conf->id, subtype);
617 713
618 if (!k) 714 memcpy (pkt->challenge, rsa_cache.public_encrypt (conf->rsa_key, *k), sizeof (rsaencrdata));
619 k = gen_challenge (sa);
620
621 if (0 > RSA_public_encrypt (sizeof (*k),
622 (unsigned char *)k, (unsigned char *)&pkt->challenge,
623 conf->rsa_key, RSA_PKCS1_OAEP_PADDING))
624 fatal ("RSA_public_encrypt error");
625 715
626 slog (L_TRACE, ">>%d PT_AUTH(%d) [%s]", conf->id, subtype, (const char *)sockinfo (sa)); 716 slog (L_TRACE, ">>%d PT_AUTH(%d) [%s]", conf->id, subtype, (const char *)sockinfo (sa));
627 717
628 vpn->send_vpn_packet (pkt, sa, IPTOS_RELIABILITY); 718 vpn->send_vpn_packet (pkt, sa, IPTOS_RELIABILITY);
629 719
672 762
673 if (::conf.script_node_down) 763 if (::conf.script_node_down)
674 run_script (this, &connection::script_node_down, false); 764 run_script (this, &connection::script_node_down, false);
675 } 765 }
676 766
677 delete ictx; 767 delete ictx; ictx = 0;
678 ictx = 0; 768 delete octx; octx = 0;
679 769
680 delete octx; 770 RAND_bytes ((unsigned char *)&seqrand, sizeof (u32));
681 octx = 0;
682 771
683 sa.sin_port = 0; 772 sa.sin_port = 0;
684 sa.sin_addr.s_addr = 0; 773 sa.sin_addr.s_addr = 0;
685 774
686 last_activity = 0; 775 last_activity = 0;
774 reset_connection (); 863 reset_connection ();
775 864
776 config_packet *p = (config_packet *) pkt; 865 config_packet *p = (config_packet *) pkt;
777 if (!p->chk_config ()) 866 if (!p->chk_config ())
778 { 867 {
779 slog (L_WARN, _("disabling node '%s' because of differing protocol"), conf->nodename); 868 slog (L_WARN, _("protocol mismatch, disabling node '%s'"), conf->nodename);
780 connectmode = conf_node::C_NEVER; 869 connectmode = conf_node::C_DISABLED;
781 } 870 }
782 else if (connectmode == conf_node::C_ALWAYS) 871 else if (connectmode == conf_node::C_ALWAYS)
783 establish_connection (); 872 establish_connection ();
784 } 873 }
785 break; 874 break;
798 PROTOCOL_MINOR, conf->nodename, p->prot_minor); 887 PROTOCOL_MINOR, conf->nodename, p->prot_minor);
799 888
800 if (p->subtype == AUTH_INIT) 889 if (p->subtype == AUTH_INIT)
801 send_auth (AUTH_INITREPLY, ssa); 890 send_auth (AUTH_INITREPLY, ssa);
802 891
803 rsachallenge k; 892 const rsachallenge *k = rsa_cache.private_decrypt (::conf.rsa_key, p->challenge);
804 893
805 if (0 > RSA_private_decrypt (sizeof (rsaencrdata), 894 if (!k)
806 (unsigned char *)&p->challenge, (unsigned char *)&k,
807 ::conf.rsa_key, RSA_PKCS1_OAEP_PADDING))
808 { 895 {
809 slog (L_ERR, _("challenge from %s (%s) illegal or corrupted"), 896 slog (L_ERR, _("challenge from %s (%s) illegal or corrupted"),
810 conf->nodename, (const char *)sockinfo (ssa)); 897 conf->nodename, (const char *)sockinfo (ssa));
811 break; 898 break;
812 } 899 }
823 delete ictx; 910 delete ictx;
824 ictx = 0; 911 ictx = 0;
825 912
826 delete octx; 913 delete octx;
827 914
828 octx = new crypto_ctx (k, 1); 915 octx = new crypto_ctx (*k, 1);
829 oseqno = *(u32 *)&k[CHG_SEQNO] & 0x7fffffff; 916 oseqno = *(u32 *)&k[CHG_SEQNO] & 0x7fffffff;
830 917
831 send_auth (AUTH_REPLY, ssa, &k); 918 send_auth (AUTH_REPLY, ssa, k);
832 break; 919 break;
833 920
834 case AUTH_REPLY: 921 case AUTH_REPLY:
835 922
836 if (!memcmp ((u8 *)gen_challenge (ssa) + sizeof (u32), (u8 *)&k + sizeof (u32), 923 if (!memcmp ((u8 *)gen_challenge (seqrand, ssa), (u8 *)k, sizeof (rsachallenge)))
837 sizeof (rsachallenge) - sizeof (u32)))
838 { 924 {
839 delete ictx; 925 delete ictx;
840 926
841 ictx = new crypto_ctx (k, 0); 927 ictx = new crypto_ctx (*k, 0);
842 iseqno.reset (*(u32 *)&k[CHG_SEQNO] & 0x7fffffff); // at least 2**31 sequence numbers are valid 928 iseqno.reset (*(u32 *)&k[CHG_SEQNO] & 0x7fffffff); // at least 2**31 sequence numbers are valid
843 929
844 sa = *ssa; 930 sa = *ssa;
845 931
846 rekey.set (NOW + ::conf.rekey); 932 rekey.set (NOW + ::conf.rekey);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines