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.102 by root, Thu Jul 18 13:35:16 2013 UTC vs.
Revision 1.106 by root, Fri Jul 19 21:01:16 2013 UTC

178 178
179 return 1; 179 return 1;
180} 180}
181 181
182static void 182static void
183auth_hash (const auth_data &auth, auth_mac &mac) 183auth_hash (const auth_data &auth, const ecdh_key &b, auth_mac &mac)
184{ 184{
185 HMAC_CTX ctx; 185 hkdf kdf (b, sizeof b, AUTH_DIGEST ()); // use response ecdh b as salt
186 186 kdf.extract (&auth.rsa, sizeof (auth.rsa));
187 HMAC_CTX_init (&ctx); 187 kdf.extract_done ();
188 require (HMAC_Init_ex (&ctx, auth.rsa.auth_key, sizeof (auth.rsa.auth_key), AUTH_DIGEST (), 0)); 188 kdf.expand (mac, sizeof mac, auth.ecdh, sizeof (auth.ecdh)); // use challenge ecdh b as info
189 require (HMAC_Update (&ctx, (const unsigned char *)&auth, sizeof auth));
190 require (HMAC_Final (&ctx, (unsigned char *)&mac, 0));
191 HMAC_CTX_cleanup (&ctx);
192} 189}
193 190
194void 191void
195connection::generate_auth_data () 192connection::generate_auth_data ()
196{ 193{
197 if (auth_expire < ev_now ()) 194 if (auth_expire < ev_now ())
198 { 195 {
199 // request data 196 // request data
200 rand_fill (snd_auth.rsa); 197 rand_fill (snd_auth.rsa);
201 curve25519_generate (snd_ecdh_a, snd_auth.ecdh); 198 curve25519_generate (snd_ecdh_a, snd_auth.ecdh);
202 auth_hash (snd_auth, snd_auth_mac);
203 199
204 // eventual response data 200 // eventual response data
205 curve25519_generate (rcv_ecdh_a, rcv_ecdh_b); 201 curve25519_generate (rcv_ecdh_a, rcv_ecdh_b);
206 } 202 }
207 203
363 } 359 }
364} 360}
365 361
366///////////////////////////////////////////////////////////////////////////// 362/////////////////////////////////////////////////////////////////////////////
367 363
368unsigned char hmac_packet::hmac_digest[EVP_MAX_MD_SIZE];
369
370void 364void
371hmac_packet::hmac_gen (crypto_ctx *ctx) 365hmac_packet::hmac_gen (crypto_ctx *ctx, u8 *hmac_digest)
372{ 366{
373 unsigned int xlen;
374
375 HMAC_CTX *hctx = &ctx->hctx; 367 HMAC_CTX *hctx = &ctx->hctx;
376 368
377 require (HMAC_Init_ex (hctx, 0, 0, 0, 0)); 369 require (HMAC_Init_ex (hctx, 0, 0, 0, 0));
378 require (HMAC_Update (hctx, ((unsigned char *) this) + sizeof (hmac_packet), 370 require (HMAC_Update (hctx, ((unsigned char *) this) + sizeof (hmac_packet), len - sizeof (hmac_packet)));
379 len - sizeof (hmac_packet)));
380 require (HMAC_Final (hctx, (unsigned char *) &hmac_digest, &xlen)); 371 require (HMAC_Final (hctx, hmac_digest, 0));
381} 372}
382 373
383void 374void
384hmac_packet::hmac_set (crypto_ctx *ctx) 375hmac_packet::hmac_set (crypto_ctx *ctx)
385{ 376{
386 hmac_gen (ctx); 377 unsigned char hmac_digest[EVP_MAX_MD_SIZE];
387 378 hmac_gen (ctx, hmac_digest);
388 memcpy (hmac, hmac_digest, HMACLENGTH); 379 memcpy (hmac, hmac_digest, HMACLENGTH);
389} 380}
390 381
391bool 382bool
392hmac_packet::hmac_chk (crypto_ctx *ctx) 383hmac_packet::hmac_chk (crypto_ctx *ctx)
393{ 384{
394 hmac_gen (ctx); 385 unsigned char hmac_digest[EVP_MAX_MD_SIZE];
395 386 hmac_gen (ctx, hmac_digest);
396 return !memcmp (hmac, hmac_digest, HMACLENGTH); 387 return !memcmp (hmac, hmac_digest, HMACLENGTH);
397} 388}
398 389
399void 390void
400vpn_packet::set_hdr (ptype type_, unsigned int dst) 391vpn_packet::set_hdr (ptype type_, unsigned int dst)
552 } 543 }
553}; 544};
554 545
555struct config_packet : vpn_packet 546struct config_packet : vpn_packet
556{ 547{
548 u8 serial[SERIAL_SIZE];
557 u8 prot_major, prot_minor, randsize; 549 u8 prot_major, prot_minor, randsize;
558 u8 flags, features, pad6, pad7, pad8; 550 u8 flags, features, pad6, pad7, pad8;
559 u32 cipher_nid, mac_nid, auth_nid; 551 u32 cipher_nid, mac_nid, auth_nid;
560 552
561 void setup (ptype type, int dst); 553 void setup (ptype type, int dst);
562 bool chk_config () const; 554 bool chk_config (const conf_node *conf, const sockinfo &rsi) const;
563 555
564 static u8 get_features () 556 static u8 get_features ()
565 { 557 {
566 u8 f = 0; 558 u8 f = 0;
567#if ENABLE_COMPRESSION 559#if ENABLE_COMPRESSION
584 prot_minor = PROTOCOL_MINOR; 576 prot_minor = PROTOCOL_MINOR;
585 randsize = RAND_SIZE; 577 randsize = RAND_SIZE;
586 flags = 0; 578 flags = 0;
587 features = get_features (); 579 features = get_features ();
588 580
581 strncpy ((char *)serial, conf.serial, sizeof (serial));
582
589 cipher_nid = htonl (EVP_CIPHER_nid (CIPHER ())); 583 cipher_nid = htonl (EVP_CIPHER_nid (CIPHER ()));
590 mac_nid = htonl (EVP_MD_type (MAC_DIGEST ())); 584 mac_nid = htonl (EVP_MD_type (MAC_DIGEST ()));
591 auth_nid = htonl (EVP_MD_type (AUTH_DIGEST ())); 585 auth_nid = htonl (EVP_MD_type (AUTH_DIGEST ()));
592 586
593 len = sizeof (*this) - sizeof (net_packet); 587 len = sizeof (*this) - sizeof (net_packet);
594 set_hdr (type, dst); 588 set_hdr (type, dst);
595} 589}
596 590
597bool 591bool
598config_packet::chk_config () const 592config_packet::chk_config (const conf_node *conf, const sockinfo &rsi) const
599{ 593{
600 if (prot_major != PROTOCOL_MAJOR) 594 if (prot_major != PROTOCOL_MAJOR)
601 slog (L_WARN, _("major version mismatch (remote %d <=> local %d)"), prot_major, PROTOCOL_MAJOR); 595 slog (L_WARN, _("%s(%s): major version mismatch (remote %d <=> local %d)"),
596 conf->nodename, (const char *)rsi, prot_major, PROTOCOL_MAJOR);
602 else if (randsize != RAND_SIZE) 597 else if (randsize != RAND_SIZE)
603 slog (L_WARN, _("rand size mismatch (remote %d <=> local %d)"), randsize, RAND_SIZE); 598 slog (L_WARN, _("%s(%s): rand size mismatch (remote %d <=> local %d)"),
599 conf->nodename, (const char *)rsi, randsize, RAND_SIZE);
604 else if (cipher_nid != htonl (EVP_CIPHER_nid (CIPHER ()))) 600 else if (cipher_nid != htonl (EVP_CIPHER_nid (CIPHER ())))
605 slog (L_WARN, _("cipher algo mismatch (remote %x <=> local %x)"), ntohl (cipher_nid), EVP_CIPHER_nid (CIPHER ())); 601 slog (L_WARN, _("%s(%s): cipher algo mismatch (remote %x <=> local %x)"),
602 conf->nodename, (const char *)rsi, ntohl (cipher_nid), EVP_CIPHER_nid (CIPHER ()));
606 else if (mac_nid != htonl (EVP_MD_type (MAC_DIGEST ()))) 603 else if (mac_nid != htonl (EVP_MD_type (MAC_DIGEST ())))
607 slog (L_WARN, _("mac algo mismatch (remote %x <=> local %x)"), ntohl (mac_nid), EVP_MD_type (MAC_DIGEST ())); 604 slog (L_WARN, _("%s(%s): mac algo mismatch (remote %x <=> local %x)"),
605 conf->nodename, (const char *)rsi, ntohl (mac_nid), EVP_MD_type (MAC_DIGEST ()));
608 else if (auth_nid != htonl (EVP_MD_type (AUTH_DIGEST ()))) 606 else if (auth_nid != htonl (EVP_MD_type (AUTH_DIGEST ())))
609 slog (L_WARN, _("auth algo mismatch (remote %x <=> local %x)"), ntohl (auth_nid), EVP_MD_type (AUTH_DIGEST ())); 607 slog (L_WARN, _("%s(%s): auth algo mismatch (remote %x <=> local %x)"),
608 conf->nodename, (const char *)rsi, ntohl (auth_nid), EVP_MD_type (AUTH_DIGEST ()));
610 else 609 else
610 {
611 int cmp = memcmp (serial, ::conf.serial, sizeof (serial));
612
613 if (cmp > 0)
614 slog (L_WARN, _("%s(%s): remote serial newer than local serial - outdated config?"),
615 conf->nodename, (const char *)rsi);
616 else if (cmp == 0)
611 return true; 617 return true;
618 }
612 619
613 return false; 620 return false;
614} 621}
615 622
616struct auth_req_packet : config_packet // UNPROTECTED 623struct auth_req_packet : config_packet // UNPROTECTED
630 637
631 len = sizeof (*this) - sizeof (net_packet); 638 len = sizeof (*this) - sizeof (net_packet);
632 } 639 }
633}; 640};
634 641
635struct auth_res_packet : config_packet // UNPROTECTED 642struct auth_res_packet : vpn_packet // UNPROTECTED
636{ 643{
637 auth_response response; 644 auth_response response;
638 645
639 auth_res_packet (int dst) 646 auth_res_packet (int dst)
640 { 647 {
641 config_packet::setup (PT_AUTH_RES, dst); 648 set_hdr (PT_AUTH_RES, dst);
642 649
643 len = sizeof (*this) - sizeof (net_packet); 650 len = sizeof (*this) - sizeof (net_packet);
644 } 651 }
645}; 652};
646 653
820void 827void
821connection::send_auth_response (const sockinfo &si) 828connection::send_auth_response (const sockinfo &si)
822{ 829{
823 auth_res_packet *pkt = new auth_res_packet (conf->id); 830 auth_res_packet *pkt = new auth_res_packet (conf->id);
824 831
825 auth_hash (rcv_auth, pkt->response.mac);
826 memcpy (pkt->response.ecdh, rcv_ecdh_b, sizeof (rcv_ecdh_b)); 832 memcpy (pkt->response.ecdh, rcv_ecdh_b, sizeof rcv_ecdh_b);
833 auth_hash (rcv_auth, rcv_ecdh_b, pkt->response.mac);
827 834
828 slog (L_TRACE, "%s << PT_AUTH_RES [%s]", conf->nodename, (const char *)si); 835 slog (L_TRACE, "%s << PT_AUTH_RES [%s]", conf->nodename, (const char *)si);
829 send_vpn_packet (pkt, si, IPTOS_RELIABILITY); // rsa is very very costly 836 send_vpn_packet (pkt, si, IPTOS_RELIABILITY); // rsa is very very costly
830 837
831 delete pkt; 838 delete pkt;
1056 { 1063 {
1057 reset_connection (); 1064 reset_connection ();
1058 1065
1059 config_packet *p = (config_packet *) pkt; 1066 config_packet *p = (config_packet *) pkt;
1060 1067
1061 if (!p->chk_config ()) 1068 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 (); 1069 establish_connection ();
1069 } 1070 }
1070 break; 1071 break;
1071 1072
1072 case vpn_packet::PT_AUTH_REQ: 1073 case vpn_packet::PT_AUTH_REQ:
1076 1077
1077 slog (L_TRACE, "%s >> PT_AUTH_REQ(%s,p%02x,f%02x)", 1078 slog (L_TRACE, "%s >> PT_AUTH_REQ(%s,p%02x,f%02x)",
1078 conf->nodename, p->initiate ? "initiate" : "reply", 1079 conf->nodename, p->initiate ? "initiate" : "reply",
1079 p->protocols, p->features); 1080 p->protocols, p->features);
1080 1081
1081 if (p->chk_config () && !memcmp (p->magic, MAGIC, 8)) 1082 if (memcmp (p->magic, MAGIC, 8))
1083 {
1084 slog (L_WARN, _("%s(%s): protocol magic mismatch - stray packet?"),
1085 conf->nodename, (const char *)rsi);
1086 }
1087 else if (p->chk_config (conf, rsi))
1082 { 1088 {
1083 if (p->prot_minor != PROTOCOL_MINOR) 1089 if (p->prot_minor != PROTOCOL_MINOR)
1084 slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."), 1090 slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."),
1085 conf->nodename, (const char *)rsi, 1091 conf->nodename, (const char *)rsi,
1086 PROTOCOL_MINOR, conf->nodename, p->prot_minor); 1092 PROTOCOL_MINOR, conf->nodename, p->prot_minor);
1113 } 1119 }
1114 } 1120 }
1115 1121
1116 break; 1122 break;
1117 } 1123 }
1118 else
1119 slog (L_WARN, _("%s(%s): protocol mismatch."),
1120 conf->nodename, (const char *)rsi);
1121 1124
1122 send_reset (rsi); 1125 send_reset (rsi);
1123 } 1126 }
1124 1127
1125 break; 1128 break;
1128 { 1131 {
1129 auth_res_packet *p = (auth_res_packet *)pkt; 1132 auth_res_packet *p = (auth_res_packet *)pkt;
1130 1133
1131 slog (L_TRACE, "%s >> PT_AUTH_RES", conf->nodename); 1134 slog (L_TRACE, "%s >> PT_AUTH_RES", conf->nodename);
1132 1135
1133 if (p->chk_config ()) 1136 auth_mac local_mac;
1137 auth_hash (snd_auth, p->response.ecdh, local_mac);
1138
1139 if (memcmp (&p->response.mac, local_mac, sizeof local_mac))
1134 { 1140 {
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."), 1141 slog (L_ERR, _("%s(%s): unrequested or outdated auth response, ignoring."),
1138 conf->nodename, (const char *)rsi); 1142 conf->nodename, (const char *)rsi);
1139 } 1143 }
1140 else if (!have_snd_auth) 1144 else if (!have_snd_auth)
1141 { 1145 {
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)); 1146 memcpy (snd_ecdh_b, p->response.ecdh, sizeof snd_ecdh_b);
1149 1147
1150 have_snd_auth = true; 1148 have_snd_auth = true;
1151 connection_established (rsi); 1149 connection_established (rsi);
1152 }
1153
1154 break;
1155 } 1150 }
1156 } 1151 }
1157
1158 send_reset (rsi);
1159 break; 1152 break;
1160 1153
1161 case vpn_packet::PT_DATA_COMPRESSED: 1154 case vpn_packet::PT_DATA_COMPRESSED:
1162#if !ENABLE_COMPRESSION 1155#if !ENABLE_COMPRESSION
1163 send_reset (rsi); 1156 send_reset (rsi);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines