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

Comparing gvpe/src/connection.C (file contents):
Revision 1.99 by root, Wed Jul 17 04:36:03 2013 UTC vs.
Revision 1.103 by root, Thu Jul 18 17:35:10 2013 UTC

48#include "hkdf.h" 48#include "hkdf.h"
49 49
50#include "netcompat.h" 50#include "netcompat.h"
51 51
52#define MAGIC "gvpe\xbd\xc6\xdb\x82" // 8 bytes of magic 52#define MAGIC "gvpe\xbd\xc6\xdb\x82" // 8 bytes of magic
53#define MAGIC "HUHN\xbd\xc6\xdb\x82" // 8 bytes of magic//D
53 54
54#define ULTRA_FAST 1 55#define ULTRA_FAST 1
55#define HLOG 15 56#define HLOG 15
56#include "lzf/lzf.h" 57#include "lzf/lzf.h"
57#include "lzf/lzf_c.c" 58#include "lzf/lzf_c.c"
119 { 120 {
120 u8 mac_key[MAC_KEYSIZE]; 121 u8 mac_key[MAC_KEYSIZE];
121 static const unsigned char mac_info[] = "gvpe mac key"; 122 static const unsigned char mac_info[] = "gvpe mac key";
122 123
123 hkdf kdf (auth2.rsa.hkdf_salt, sizeof (auth2.rsa.hkdf_salt), HKDF_XTR_HASH ()); 124 hkdf kdf (auth2.rsa.hkdf_salt, sizeof (auth2.rsa.hkdf_salt), HKDF_XTR_HASH ());
124 kdf.extract (auth2.rsa.ikm, sizeof (auth2.rsa.ikm));
125 kdf.extract (auth1.rsa.mac_key, sizeof (auth1.rsa.mac_key)); 125 kdf.extract (auth1.rsa.mac_key, sizeof (auth1.rsa.mac_key));
126 kdf.extract (s, sizeof (s)); 126 kdf.extract (s, sizeof (s));
127 kdf.extract_done (HKDF_PRF_HASH ()); 127 kdf.extract_done (HKDF_PRF_HASH ());
128 kdf.expand (mac_key, sizeof (mac_key), mac_info, sizeof (mac_info)); 128 kdf.expand (mac_key, sizeof (mac_key), mac_info, sizeof (mac_info));
129 129
134 { 134 {
135 u8 cipher_key[CIPHER_KEYSIZE]; 135 u8 cipher_key[CIPHER_KEYSIZE];
136 static const unsigned char cipher_info[] = "gvpe cipher key"; 136 static const unsigned char cipher_info[] = "gvpe cipher key";
137 137
138 hkdf kdf (auth2.rsa.hkdf_salt, sizeof (auth2.rsa.hkdf_salt), HKDF_XTR_HASH ()); 138 hkdf kdf (auth2.rsa.hkdf_salt, sizeof (auth2.rsa.hkdf_salt), HKDF_XTR_HASH ());
139 kdf.extract (auth2.rsa.ikm, sizeof (auth2.rsa.ikm));
140 kdf.extract (auth1.rsa.cipher_key, sizeof (auth1.rsa.cipher_key)); 139 kdf.extract (auth1.rsa.cipher_key, sizeof (auth1.rsa.cipher_key));
141 kdf.extract (s, sizeof (s)); 140 kdf.extract (s, sizeof (s));
142 kdf.extract_done (HKDF_PRF_HASH ()); 141 kdf.extract_done (HKDF_PRF_HASH ());
143 kdf.expand (cipher_key, sizeof (cipher_key), cipher_info, sizeof (cipher_info)); 142 kdf.expand (cipher_key, sizeof (cipher_key), cipher_info, sizeof (cipher_info));
144 143
158{ 157{
159 if (RSA_public_encrypt (sizeof (auth.rsa), 158 if (RSA_public_encrypt (sizeof (auth.rsa),
160 (unsigned char *)&auth.rsa, (unsigned char *)&encr.rsa, 159 (unsigned char *)&auth.rsa, (unsigned char *)&encr.rsa,
161 key, RSA_PKCS1_OAEP_PADDING) < 0) 160 key, RSA_PKCS1_OAEP_PADDING) < 0)
162 fatal ("RSA_public_encrypt error"); 161 fatal ("RSA_public_encrypt error");
162
163 memcpy (&encr.ecdh, &auth.ecdh, sizeof (encr.ecdh));
163} 164}
164 165
165static inline bool 166static inline bool
166auth_decrypt (RSA *key, const auth_encr &encr, auth_data &auth) 167auth_decrypt (RSA *key, const auth_encr &encr, auth_data &auth)
167{ 168{
171 (const unsigned char *)&encr.rsa, (unsigned char *)rsa_decrypt, 172 (const unsigned char *)&encr.rsa, (unsigned char *)rsa_decrypt,
172 key, RSA_PKCS1_OAEP_PADDING) != sizeof (auth.rsa)) 173 key, RSA_PKCS1_OAEP_PADDING) != sizeof (auth.rsa))
173 return 0; 174 return 0;
174 175
175 memcpy (&auth.rsa, rsa_decrypt, sizeof (auth.rsa)); 176 memcpy (&auth.rsa, rsa_decrypt, sizeof (auth.rsa));
177 memcpy (&auth.ecdh, &encr.ecdh, sizeof (auth.ecdh));
176 178
177 return 1; 179 return 1;
178} 180}
179 181
180static void 182static void
193connection::generate_auth_data () 195connection::generate_auth_data ()
194{ 196{
195 if (auth_expire < ev_now ()) 197 if (auth_expire < ev_now ())
196 { 198 {
197 // request data 199 // request data
198 RAND_bytes ((unsigned char *)&snd_auth.rsa, sizeof snd_auth.rsa); 200 rand_fill (snd_auth.rsa);
199 curve25519_generate (snd_ecdh_a, snd_auth.ecdh); 201 curve25519_generate (snd_ecdh_a, snd_auth.ecdh);
200 auth_hash (snd_auth, snd_auth_mac); 202 auth_hash (snd_auth, snd_auth_mac);
201 203
202 // eventual response data 204 // eventual response data
203 curve25519_generate (rcv_ecdh_a, rcv_ecdh_b); 205 curve25519_generate (rcv_ecdh_a, rcv_ecdh_b);
458 u32 seqno; 460 u32 seqno;
459 } datahdr; 461 } datahdr;
460 462
461 datahdr.seqno = ntohl (seqno); 463 datahdr.seqno = ntohl (seqno);
462#if RAND_SIZE 464#if RAND_SIZE
463 RAND_bytes ((unsigned char *) datahdr.rnd, RAND_SIZE); 465 // NB: a constant (per session) random prefix
466 // is likely enough, but we don't take any chances.
467 conn->oiv.get (datahdr.rnd, RAND_SIZE);
464#endif 468#endif
465 469
466 require (EVP_EncryptUpdate (cctx, 470 require (EVP_EncryptUpdate (cctx,
467 (unsigned char *) data + outl, &outl2, 471 (unsigned char *) data + outl, &outl2,
468 (unsigned char *) &datahdr, DATAHDR)); 472 (unsigned char *) &datahdr, DATAHDR));
499 503
500 if (type == PT_DATA_COMPRESSED) 504 if (type == PT_DATA_COMPRESSED)
501 d = cdata; 505 d = cdata;
502 else 506 else
503#endif 507#endif
504 d = &(*p)[6 + 6 - DATAHDR]; 508 d = &(*p)[6 + 6] - DATAHDR;
505 509
506 /* this overwrites part of the src mac, but we fix that later */ 510 // we play do evil games with the struct layout atm.
511 // pending better solutions, we at least do some verification.
512 // this is fine, as we left ISO territory long ago.
513 require (DATAHDR <= 16);
514 require ((u8 *)(&p->len + 1) == &(*p)[0]);
515
516 // this can overwrite the len/dst/src fields
507 require (EVP_DecryptUpdate (cctx, 517 require (EVP_DecryptUpdate (cctx,
508 d, &outl2, 518 d, &outl2,
509 (unsigned char *)&data, len - data_hdr_size ())); 519 (unsigned char *)&data, len - data_hdr_size ()));
510 outl += outl2; 520 outl += outl2;
511 521
542 } 552 }
543}; 553};
544 554
545struct config_packet : vpn_packet 555struct config_packet : vpn_packet
546{ 556{
557 u8 serial[SERIAL_SIZE];
547 u8 prot_major, prot_minor, randsize; 558 u8 prot_major, prot_minor, randsize;
548 u8 flags, features, pad6, pad7, pad8; 559 u8 flags, features, pad6, pad7, pad8;
549 u32 cipher_nid, mac_nid, auth_nid; 560 u32 cipher_nid, mac_nid, auth_nid;
550 561
551 void setup (ptype type, int dst); 562 void setup (ptype type, int dst);
552 bool chk_config () const; 563 bool chk_config (const conf_node *conf, const sockinfo &rsi) const;
553 564
554 static u8 get_features () 565 static u8 get_features ()
555 { 566 {
556 u8 f = 0; 567 u8 f = 0;
557#if ENABLE_COMPRESSION 568#if ENABLE_COMPRESSION
574 prot_minor = PROTOCOL_MINOR; 585 prot_minor = PROTOCOL_MINOR;
575 randsize = RAND_SIZE; 586 randsize = RAND_SIZE;
576 flags = 0; 587 flags = 0;
577 features = get_features (); 588 features = get_features ();
578 589
590 strncpy ((char *)serial, conf.serial, sizeof (serial));
591
579 cipher_nid = htonl (EVP_CIPHER_nid (CIPHER ())); 592 cipher_nid = htonl (EVP_CIPHER_nid (CIPHER ()));
580 mac_nid = htonl (EVP_MD_type (MAC_DIGEST ())); 593 mac_nid = htonl (EVP_MD_type (MAC_DIGEST ()));
581 auth_nid = htonl (EVP_MD_type (AUTH_DIGEST ())); 594 auth_nid = htonl (EVP_MD_type (AUTH_DIGEST ()));
582 595
583 len = sizeof (*this) - sizeof (net_packet); 596 len = sizeof (*this) - sizeof (net_packet);
584 set_hdr (type, dst); 597 set_hdr (type, dst);
585} 598}
586 599
587bool 600bool
588config_packet::chk_config () const 601config_packet::chk_config (const conf_node *conf, const sockinfo &rsi) const
589{ 602{
590 if (prot_major != PROTOCOL_MAJOR) 603 if (prot_major != PROTOCOL_MAJOR)
591 slog (L_WARN, _("major version mismatch (remote %d <=> local %d)"), prot_major, PROTOCOL_MAJOR); 604 slog (L_WARN, _("%s(%s): major version mismatch (remote %d <=> local %d)"),
605 conf->nodename, (const char *)rsi, prot_major, PROTOCOL_MAJOR);
592 else if (randsize != RAND_SIZE) 606 else if (randsize != RAND_SIZE)
593 slog (L_WARN, _("rand size mismatch (remote %d <=> local %d)"), randsize, RAND_SIZE); 607 slog (L_WARN, _("%s(%s): rand size mismatch (remote %d <=> local %d)"),
608 conf->nodename, (const char *)rsi, randsize, RAND_SIZE);
594 else if (cipher_nid != htonl (EVP_CIPHER_nid (CIPHER ()))) 609 else if (cipher_nid != htonl (EVP_CIPHER_nid (CIPHER ())))
595 slog (L_WARN, _("cipher algo mismatch (remote %x <=> local %x)"), ntohl (cipher_nid), EVP_CIPHER_nid (CIPHER ())); 610 slog (L_WARN, _("%s(%s): cipher algo mismatch (remote %x <=> local %x)"),
611 conf->nodename, (const char *)rsi, ntohl (cipher_nid), EVP_CIPHER_nid (CIPHER ()));
596 else if (mac_nid != htonl (EVP_MD_type (MAC_DIGEST ()))) 612 else if (mac_nid != htonl (EVP_MD_type (MAC_DIGEST ())))
597 slog (L_WARN, _("mac algo mismatch (remote %x <=> local %x)"), ntohl (mac_nid), EVP_MD_type (MAC_DIGEST ())); 613 slog (L_WARN, _("%s(%s): mac algo mismatch (remote %x <=> local %x)"),
614 conf->nodename, (const char *)rsi, ntohl (mac_nid), EVP_MD_type (MAC_DIGEST ()));
598 else if (auth_nid != htonl (EVP_MD_type (AUTH_DIGEST ()))) 615 else if (auth_nid != htonl (EVP_MD_type (AUTH_DIGEST ())))
599 slog (L_WARN, _("auth algo mismatch (remote %x <=> local %x)"), ntohl (auth_nid), EVP_MD_type (AUTH_DIGEST ())); 616 slog (L_WARN, _("%s(%s): auth algo mismatch (remote %x <=> local %x)"),
617 conf->nodename, (const char *)rsi, ntohl (auth_nid), EVP_MD_type (AUTH_DIGEST ()));
600 else 618 else
619 {
620 int cmp = memcmp (serial, ::conf.serial, sizeof (serial));
621
622 if (cmp > 0)
623 slog (L_WARN, _("%s(%s): remote serial newer than local serial - outdated config?"),
624 conf->nodename, (const char *)rsi);
625 else if (cmp == 0)
601 return true; 626 return true;
627 }
602 628
603 return false; 629 return false;
604} 630}
605 631
606struct auth_req_packet : config_packet // UNPROTECTED 632struct auth_req_packet : config_packet // UNPROTECTED
620 646
621 len = sizeof (*this) - sizeof (net_packet); 647 len = sizeof (*this) - sizeof (net_packet);
622 } 648 }
623}; 649};
624 650
625struct auth_res_packet : config_packet // UNPROTECTED 651struct auth_res_packet : vpn_packet // UNPROTECTED
626{ 652{
627 auth_response response; 653 auth_response response;
628 654
629 auth_res_packet (int dst) 655 auth_res_packet (int dst)
630 { 656 {
631 config_packet::setup (PT_AUTH_RES, dst); 657 set_hdr (PT_AUTH_RES, dst);
632 658
633 len = sizeof (*this) - sizeof (net_packet); 659 len = sizeof (*this) - sizeof (net_packet);
634 } 660 }
635}; 661};
636 662
692 iseqno.reset (ntohl (rcv_auth.rsa.seqno) & 0x7fffffff); 718 iseqno.reset (ntohl (rcv_auth.rsa.seqno) & 0x7fffffff);
693 719
694 delete octx; octx = new crypto_ctx (snd_auth, rcv_auth, snd_ecdh_a, snd_ecdh_b , 1); 720 delete octx; octx = new crypto_ctx (snd_auth, rcv_auth, snd_ecdh_a, snd_ecdh_b , 1);
695 oseqno = ntohl (snd_auth.rsa.seqno) & 0x7fffffff; 721 oseqno = ntohl (snd_auth.rsa.seqno) & 0x7fffffff;
696 722
723 oiv.reset ();
724
725 // make sure rekeying timeouts are slightly asymmetric
726 ev::tstamp rekey_interval = ::conf.rekey + (conf->id > THISNODE->id ? 10 : 0);
727 rekey.start (rekey_interval, rekey_interval);
728
729 keepalive.start (::conf.keepalive);
730
731 // send queued packets
697 if (ictx && octx) 732 if (ictx && octx)
698 { 733 {
699 // make sure rekeying timeouts are slightly asymmetric 734 while (tap_packet *p = (tap_packet *)data_queue.get ())
700 ev::tstamp rekey_interval = ::conf.rekey + (conf->id > THISNODE->id ? 10 : 0);
701 rekey.start (rekey_interval, rekey_interval);
702
703 keepalive.start (::conf.keepalive);
704
705 // send queued packets
706 if (ictx && octx)
707 { 735 {
708 while (tap_packet *p = (tap_packet *)data_queue.get ())
709 {
710 if (p->len) send_data_packet (p); 736 if (p->len) send_data_packet (p);
711 delete p; 737 delete p;
712 }
713
714 while (vpn_packet *p = (vpn_packet *)vpn_queue.get ())
715 {
716 if (p->len) send_vpn_packet (p, si, IPTOS_RELIABILITY);
717 delete p;
718 }
719 } 738 }
720 739
740 while (vpn_packet *p = (vpn_packet *)vpn_queue.get ())
741 {
742 if (p->len) send_vpn_packet (p, si, IPTOS_RELIABILITY);
743 delete p;
744 }
745 }
746
721 vpn->connection_established (this); 747 vpn->connection_established (this);
722 }
723#if 0
724 else
725 {
726 retry_cnt = 0;
727 establish_connection.start (5);
728 keepalive.stop ();
729 rekey.stop ();
730 }
731#endif
732} 748}
733 749
734void 750void
735connection::reset_si () 751connection::reset_si ()
736{ 752{
1056 { 1072 {
1057 reset_connection (); 1073 reset_connection ();
1058 1074
1059 config_packet *p = (config_packet *) pkt; 1075 config_packet *p = (config_packet *) pkt;
1060 1076
1061 if (!p->chk_config ()) 1077 if (p->chk_config (conf, rsi) && connectmode == conf_node::C_ALWAYS)
1062 {
1063 slog (L_WARN, _("%s(%s): protocol mismatch, disabling node."),
1064 conf->nodename, (const char *)rsi);
1065 connectmode = conf_node::C_DISABLED;
1066 }
1067 else if (connectmode == conf_node::C_ALWAYS)
1068 establish_connection (); 1078 establish_connection ();
1069 } 1079 }
1070 break; 1080 break;
1071 1081
1072 case vpn_packet::PT_AUTH_REQ: 1082 case vpn_packet::PT_AUTH_REQ:
1076 1086
1077 slog (L_TRACE, "%s >> PT_AUTH_REQ(%s,p%02x,f%02x)", 1087 slog (L_TRACE, "%s >> PT_AUTH_REQ(%s,p%02x,f%02x)",
1078 conf->nodename, p->initiate ? "initiate" : "reply", 1088 conf->nodename, p->initiate ? "initiate" : "reply",
1079 p->protocols, p->features); 1089 p->protocols, p->features);
1080 1090
1081 if (p->chk_config () && !memcmp (p->magic, MAGIC, 8)) 1091 if (memcmp (p->magic, MAGIC, 8))
1092 {
1093 slog (L_WARN, _("%s(%s): protocol magic mismatch - stray packet?"),
1094 conf->nodename, (const char *)rsi);
1095 }
1096 else if (p->chk_config (conf, rsi))
1082 { 1097 {
1083 if (p->prot_minor != PROTOCOL_MINOR) 1098 if (p->prot_minor != PROTOCOL_MINOR)
1084 slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."), 1099 slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."),
1085 conf->nodename, (const char *)rsi, 1100 conf->nodename, (const char *)rsi,
1086 PROTOCOL_MINOR, conf->nodename, p->prot_minor); 1101 PROTOCOL_MINOR, conf->nodename, p->prot_minor);
1113 } 1128 }
1114 } 1129 }
1115 1130
1116 break; 1131 break;
1117 } 1132 }
1118 else
1119 slog (L_WARN, _("%s(%s): protocol mismatch."),
1120 conf->nodename, (const char *)rsi);
1121 1133
1122 send_reset (rsi); 1134 send_reset (rsi);
1123 } 1135 }
1124 1136
1125 break; 1137 break;
1128 { 1140 {
1129 auth_res_packet *p = (auth_res_packet *)pkt; 1141 auth_res_packet *p = (auth_res_packet *)pkt;
1130 1142
1131 slog (L_TRACE, "%s >> PT_AUTH_RES", conf->nodename); 1143 slog (L_TRACE, "%s >> PT_AUTH_RES", conf->nodename);
1132 1144
1133 if (p->chk_config ()) 1145 if (memcmp (&p->response.mac, snd_auth_mac, sizeof (snd_auth_mac)))
1134 { 1146 {
1135 if (memcmp (&p->response.mac, snd_auth_mac, sizeof (snd_auth_mac)))
1136 {
1137 slog (L_ERR, _("%s(%s): unrequested or outdated auth response, ignoring."), 1147 slog (L_ERR, _("%s(%s): unrequested or outdated auth response, ignoring."),
1138 conf->nodename, (const char *)rsi); 1148 conf->nodename, (const char *)rsi);
1139 }
1140 else if (!have_snd_auth)
1141 {
1142 if (p->prot_minor != PROTOCOL_MINOR)
1143 slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."),
1144 conf->nodename, (const char *)rsi,
1145 PROTOCOL_MINOR, conf->nodename, p->prot_minor);
1146
1147 prot_minor = p->prot_minor;
1148 memcpy (snd_ecdh_b, p->response.ecdh, sizeof (snd_ecdh_b));
1149
1150 have_snd_auth = true;
1151 connection_established (rsi);
1152 }
1153
1154 break;
1155 } 1149 }
1150 else if (!have_snd_auth)
1151 {
1152 memcpy (snd_ecdh_b, p->response.ecdh, sizeof (snd_ecdh_b));
1153
1154 have_snd_auth = true;
1155 connection_established (rsi);
1156 }
1157
1158 break;
1156 } 1159 }
1157 1160
1158 send_reset (rsi); 1161 send_reset (rsi);
1159 break; 1162 break;
1160 1163

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines