Automated merge with http://gredler.at/hg/olsrd
[olsrd.git] / lib / secure / src / olsrd_secure.c
1
2 /*
3  * Secure OLSR plugin
4  * http://www.olsr.org
5  *
6  * Copyright (c) 2004, Andreas T√łnnesen(andreto@olsr.org)
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or 
10  * without modification, are permitted provided that the following 
11  * conditions are met:
12  *
13  * * Redistributions of source code must retain the above copyright 
14  *   notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above copyright 
16  *   notice, this list of conditions and the following disclaimer in 
17  *   the documentation and/or other materials provided with the 
18  *   distribution.
19  * * Neither the name of olsrd, olsr.org nor the names of its 
20  *   contributors may be used to endorse or promote products derived 
21  *   from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  */
37
38
39 /*
40  * Dynamic linked library for the olsr.org olsr daemon
41  */
42
43 #include "olsrd_secure.h"
44
45 #include <stdio.h>
46 #include <string.h>
47 #include <stdlib.h>
48 #ifdef linux
49 #include <linux/in_route.h>
50 #endif
51 #include <unistd.h>
52 #include <errno.h>
53 #include <signal.h>
54
55 #include "defs.h"
56 #include "ipcalc.h"
57 #include "olsr.h"
58 #include "socket_parser.h"
59 #include "parser.h"
60 #include "scheduler.h"
61 #include "net_olsr.h"
62 #include "common/string.h"
63
64 #ifdef USE_OPENSSL
65 /* OpenSSL stuff */
66 #include <openssl/sha.h>
67
68 #define CHECKSUM SHA1
69 #define SCHEME   SHA1_INCLUDING_KEY
70
71 #else
72 /* Homebrewn checksuming */
73 #include "md5.h"
74
75 static void
76 MD5_checksum(const olsr_u8_t *data, const olsr_u16_t data_len, olsr_u8_t *hashbuf)
77 {
78   MD5_CTX context;
79
80   MD5Init(&context);
81   MD5Update(&context, data, data_len);
82   MD5Final(hashbuf, &context);
83 }
84
85 #define CHECKSUM MD5_checksum
86 #define SCHEME   MD5_INCLUDING_KEY
87
88 #endif
89
90 #ifdef OS
91 #undef OS
92 #endif
93
94 #ifdef WIN32
95 #define close(x) closesocket(x)
96 #undef EWOULDBLOCK
97 #define EWOULDBLOCK WSAEWOULDBLOCK
98 #define OS "Windows"
99 #endif
100 #ifdef linux
101 #define OS "GNU/Linux"
102 #endif
103 #ifdef __FreeBSD__
104 #define OS "FreeBSD"
105 #endif
106
107 #ifndef OS
108 #define OS "Undefined"
109 #endif
110
111 static struct timeval now;
112
113 /* Timestamp node */
114 struct stamp
115 {
116   union olsr_ip_addr addr;
117   /* Timestamp difference */
118   int diff;
119   olsr_u32_t challenge;
120   olsr_u8_t validated;
121   clock_t valtime; /* Validity time */
122   clock_t conftime; /* Reconfiguration time */
123   struct stamp *prev;
124   struct stamp *next;
125 };
126
127 /* Seconds to cache a valid timestamp entry */
128 #define TIMESTAMP_HOLD_TIME 30
129 /* Seconds to cache a not verified timestamp entry */
130 #define EXCHANGE_HOLD_TIME 5
131
132 static struct stamp timestamps[HASHSIZE];
133
134
135 char keyfile[FILENAME_MAX+1];
136 char aes_key[16];
137
138 /* Event function to register with the sceduler */
139 #if 0
140 static void olsr_event(void);
141 #endif
142 static int send_challenge(struct interface *olsr_if, const union olsr_ip_addr *);
143 static int send_cres(struct interface *olsr_if, union olsr_ip_addr *, union olsr_ip_addr *, olsr_u32_t, struct stamp *);
144 static int send_rres(struct interface *olsr_if, union olsr_ip_addr *, union olsr_ip_addr *, olsr_u32_t);
145 static int parse_challenge(struct interface *olsr_if, char *);
146 static int parse_cres(struct interface *olsr_if, char *);
147 static int parse_rres(char *);
148 static int check_auth(struct interface *olsr_if, char *, int *);
149 #if 0
150 static int ipc_send(char *, int);
151 #endif
152 static int add_signature(olsr_u8_t *, int*);
153 static int validate_packet(struct interface *olsr_if, const char *, int*);
154 static char *secure_preprocessor(char *packet, struct interface *olsr_if, union olsr_ip_addr *from_addr, int *length);
155 static void timeout_timestamps(void*);
156 static int check_timestamp(struct interface *olsr_if, const union olsr_ip_addr *, time_t);
157 static struct stamp *lookup_timestamp_entry(const union olsr_ip_addr *);
158 static int read_key_from_file(const char *);
159
160 /**
161  *Do initialization here
162  *
163  *This function is called by the my_init
164  *function in uolsrd_plugin.c
165  */
166
167 int
168 secure_plugin_init(void)
169 {
170   int i;
171
172
173   /* Initialize the timestamp database */
174   for(i = 0; i < HASHSIZE; i++)
175     {
176       timestamps[i].next = &timestamps[i];
177       timestamps[i].prev = &timestamps[i];
178     }
179   olsr_printf(1, "Timestamp database initialized\n");
180
181   if(!strlen(keyfile))
182     strscpy(keyfile, KEYFILE, sizeof(keyfile));
183
184   i = read_key_from_file(keyfile);
185
186   if(i < 0)
187     {
188       olsr_printf(1, "[ENC]Could not read key from file %s!\nExitting!\n\n", keyfile);
189       exit(1);
190     }
191   if(i == 0)
192     {
193       olsr_printf(1, "[ENC]There was a problem reading key from file %s. Is the key long enough?\nExitting!\n\n", keyfile);
194       exit(1);
195     }
196
197   /* Register the packet transform function */
198   add_ptf(&add_signature);
199
200   olsr_preprocessor_add_function(&secure_preprocessor);
201   
202   /* Register timeout - poll every 2 seconds */
203   olsr_start_timer(2 * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC,
204                    &timeout_timestamps, NULL, 0);
205
206
207   return 1;
208 }
209
210 int
211 plugin_ipc_init(void)
212 {
213   return 1;
214 }
215
216 /*
217  * destructor - called at unload
218  */
219 void
220 secure_plugin_exit(void)
221 {
222   olsr_preprocessor_remove_function(&secure_preprocessor);
223 }
224
225
226 #if 0
227 /**
228  *Scheduled event
229  */
230 static void
231 olsr_event(void)
232 {
233
234 }
235 #endif
236
237 #if 0
238 static int
239 ipc_send(char *data __attribute__((unused)), int size __attribute__((unused)))
240 {
241   return 1;
242 }
243 #endif
244
245 static char *
246 secure_preprocessor(char *packet, struct interface *olsr_if, union olsr_ip_addr *from_addr, int *length)
247 {
248   struct olsr *olsr = (struct olsr *)packet;
249   struct ipaddr_str buf;
250   
251   /*
252    * Check for challenge/response messages
253    */
254   check_auth(olsr_if, packet, length);
255
256   /*
257    * Check signature
258    */
259
260   if(!validate_packet(olsr_if, packet, length))
261   {
262     olsr_printf(1, "[ENC]Rejecting packet from %s\n", olsr_ip_to_string(&buf, from_addr));
263     return NULL;
264   }
265
266   olsr_printf(1, "[ENC]Packet from %s OK size %d\n", olsr_ip_to_string(&buf, from_addr), *length);
267
268   /* Fix OLSR packet header */
269   olsr->olsr_packlen = htons(*length);
270   return packet;
271 }
272
273
274
275 /**
276  * Check a incoming OLSR packet for
277  * challenge/responses.
278  * They need not be verified as they
279  * are signed in the message.
280  *
281  */
282 static int
283 check_auth(struct interface *olsr_if, char *pck, int *size __attribute__((unused)))
284 {
285
286   olsr_printf(3, "[ENC]Checking packet for challenge response message...\n");
287
288   switch(pck[4])
289     {
290     case(TYPE_CHALLENGE):
291       parse_challenge(olsr_if, &pck[4]);
292       break;
293
294     case(TYPE_CRESPONSE):
295       parse_cres(olsr_if, &pck[4]);
296       break;
297
298     case(TYPE_RRESPONSE):
299       parse_rres(&pck[4]);
300       break;
301
302     default:
303       return 0;
304     }
305
306   return 1;
307 }
308
309
310
311 /**
312  * Packet transform function
313  * Build a SHA-1/MD5 hash of the original message
314  * + the signature message(-digest) + key
315  *
316  * Then add the signature message to the packet and
317  * increase the size
318  */
319 int
320 add_signature(olsr_u8_t *pck, int *size)
321 {
322   struct s_olsrmsg *msg;
323 #ifdef DEBUG
324   unsigned int i;
325   int j;
326   const olsr_u8_t *sigmsg;                                                                                        
327 #endif
328   
329   olsr_printf(2, "[ENC]Adding signature for packet size %d\n", *size);
330   fflush(stdout);
331   
332   msg = (struct s_olsrmsg *)&pck[*size];
333   /* Update size */
334   ((struct olsr*)pck)->olsr_packlen = htons(*size + sizeof(struct s_olsrmsg));
335   
336   /* Fill packet header */
337   msg->olsr_msgtype = MESSAGE_TYPE;
338   msg->olsr_vtime = 0;
339   msg->olsr_msgsize = htons(sizeof(struct s_olsrmsg));
340   memcpy(&msg->originator, &olsr_cnf->main_addr, olsr_cnf->ipsize);
341   msg->ttl = 1;
342   msg->hopcnt = 0;
343   msg->seqno = htons(get_msg_seqno());
344   
345   /* Fill subheader */
346   msg->sig.type = ONE_CHECKSUM;
347   msg->sig.algorithm = SCHEME;
348   memset(&msg->sig.reserved, 0, 2);
349   
350   /* Add timestamp */
351   msg->sig.timestamp = htonl(now.tv_sec);
352   olsr_printf(3, "[ENC]timestamp: %ld\n", now.tv_sec);
353   
354   /* Set the new size */
355   *size += sizeof(struct s_olsrmsg);
356   
357   {
358   olsr_u8_t checksum_cache[512 + KEYLENGTH];
359   /* Create packet + key cache */
360   /* First the OLSR packet + signature message - digest */
361   memcpy(checksum_cache, pck, *size - SIGNATURE_SIZE);
362   /* Then the key */
363   memcpy(&checksum_cache[*size - SIGNATURE_SIZE], aes_key, KEYLENGTH);
364   
365   /* Create the hash */
366   CHECKSUM(checksum_cache, (*size - SIGNATURE_SIZE) + KEYLENGTH, &pck[*size - SIGNATURE_SIZE]);
367   } 
368
369 #ifdef DEBUG
370   olsr_printf(1, "Signature message:\n");
371
372   j = 0;
373   sigmsg = (olsr_u8_t *)msg;
374
375   for(i = 0; i < sizeof(struct s_olsrmsg); i++)
376     {
377       olsr_printf(1, "  %3i", sigmsg[i]);
378       j++;
379       if(j == 4)
380         {
381           olsr_printf(1, "\n");
382           j = 0;
383         }
384     }
385 #endif
386
387   olsr_printf(3, "[ENC] Message signed\n");
388
389   return 1;
390 }
391
392
393
394 static int
395 validate_packet(struct interface *olsr_if, const char *pck, int *size)
396 {
397   int packetsize;
398   olsr_u8_t sha1_hash[SIGNATURE_SIZE];
399   const struct s_olsrmsg *sig;
400   time_t rec_time;
401
402 #ifdef DEBUG
403   unsigned int i;
404   int j;
405   const olsr_u8_t *sigmsg;
406 #endif
407
408   /* Find size - signature message */
409   packetsize = *size - sizeof(struct s_olsrmsg);
410
411   if(packetsize < 4)
412     return 0;
413
414   sig = (const struct s_olsrmsg *)&pck[packetsize];
415
416   //olsr_printf(1, "Size: %d\n", packetsize);
417
418 #ifdef DEBUG
419   olsr_printf(1, "Input message:\n");
420   
421   j = 0;
422   sigmsg = (const olsr_u8_t *)sig;
423
424   for(i = 0; i < sizeof(struct s_olsrmsg); i++)
425     {
426       olsr_printf(1, "  %3i", sigmsg[i]);
427       j++;
428       if(j == 4)
429         {
430           olsr_printf(1, "\n");
431           j = 0;
432         }
433     }
434 #endif
435
436   /* Sanity check first */
437   if((sig->olsr_msgtype != MESSAGE_TYPE) || 
438      (sig->olsr_vtime != 0) ||
439      (sig->olsr_msgsize != ntohs(sizeof(struct s_olsrmsg))) ||
440      (sig->ttl != 1) ||
441      (sig->hopcnt != 0))
442     {
443       olsr_printf(1, "[ENC]Packet not sane!\n");
444       return 0;
445     }
446
447   /* Check scheme and type */
448   switch(sig->sig.type)
449     {
450     case(ONE_CHECKSUM):
451       switch(sig->sig.algorithm)
452         {
453         case(SCHEME):
454           goto one_checksum_SHA; /* Ahhh... fix this */
455           break;
456           
457         }
458       break;
459
460     default:
461       olsr_printf(1, "[ENC]Unsupported sceme: %d enc: %d!\n", sig->sig.type, sig->sig.algorithm);
462       return 0;
463     }
464   //olsr_printf(1, "Packet sane...\n");
465
466  one_checksum_SHA:
467  
468  {
469   olsr_u8_t checksum_cache[512 + KEYLENGTH];
470   /* Create packet + key cache */
471   /* First the OLSR packet + signature message - digest */
472   memcpy(checksum_cache, pck, *size - SIGNATURE_SIZE);
473   /* Then the key */
474   memcpy(&checksum_cache[*size - SIGNATURE_SIZE], aes_key, KEYLENGTH);
475
476   /* generate SHA-1 */
477   CHECKSUM(checksum_cache, *size - SIGNATURE_SIZE + KEYLENGTH, sha1_hash);
478  }
479
480 #ifdef DEBUG
481   olsr_printf(1, "Recevied hash:\n");
482   
483   sigmsg = (const olsr_u8_t *)sig->sig.signature;
484
485   for(i = 0; i < SIGNATURE_SIZE; i++)
486     {
487       olsr_printf(1, " %3i", sigmsg[i]);
488     }
489   olsr_printf(1, "\n");
490
491   olsr_printf(1, "Calculated hash:\n");
492   
493   sigmsg = sha1_hash;
494
495   for(i = 0; i < SIGNATURE_SIZE; i++)
496     {
497       olsr_printf(1, " %3i", sigmsg[i]);
498     }
499   olsr_printf(1, "\n");
500 #endif
501
502   if(memcmp(sha1_hash, sig->sig.signature, SIGNATURE_SIZE) != 0)
503     {
504       olsr_printf(1, "[ENC]Signature missmatch\n");
505       return 0;
506     }
507
508   /* Check timestamp */
509   rec_time = ntohl(sig->sig.timestamp);
510
511   if(!check_timestamp(olsr_if, (const union olsr_ip_addr *)&sig->originator, rec_time))
512     {
513       struct ipaddr_str buf;
514       olsr_printf(1, "[ENC]Timestamp missmatch in packet from %s!\n",
515                   olsr_ip_to_string(&buf, (const union olsr_ip_addr *)&sig->originator));
516       return 0;
517     }
518
519   olsr_printf(1, "[ENC]Received timestamp %ld diff: %ld\n", rec_time, now.tv_sec - rec_time);
520
521   /* Remove signature message */
522   *size = packetsize;
523   return 1;
524 }
525
526
527 int
528 check_timestamp(struct interface *olsr_if, const union olsr_ip_addr *originator, time_t tstamp)
529 {
530   struct stamp *entry;
531   int diff;
532
533   entry = lookup_timestamp_entry(originator);
534
535   if(!entry)
536     {
537       /* Initiate timestamp negotiation */
538
539       send_challenge(olsr_if, originator);
540
541       return 0;
542     }
543
544   if(!entry->validated)
545     {
546       olsr_printf(1, "[ENC]Message from non-validated host!\n");
547       return 0;
548     }
549
550   diff = entry->diff - (now.tv_sec - tstamp);
551
552   olsr_printf(3, "[ENC]Timestamp slack: %d\n", diff);
553
554   if((diff > UPPER_DIFF) || (diff < LOWER_DIFF))
555     {
556       olsr_printf(1, "[ENC]Timestamp scew detected!!\n");
557       return 0;
558     }
559
560   /* ok - update diff */
561   entry->diff = ((now.tv_sec - tstamp) + entry->diff) ?
562     ((now.tv_sec - tstamp) + entry->diff) / 2 : 0;
563
564   olsr_printf(3, "[ENC]Diff set to : %d\n", entry->diff);
565
566   /* update validtime */
567
568   entry->valtime = GET_TIMESTAMP(TIMESTAMP_HOLD_TIME * 1000);
569
570   return 1;
571 }
572
573
574 /**
575  * Create and send a timestamp
576  * challenge message to new_host
577  *
578  * The host is registered in the timestamps
579  * repository with valid=0
580  */
581
582 int
583 send_challenge(struct interface *olsr_if, const union olsr_ip_addr *new_host)
584 {
585   struct challengemsg cmsg;
586   struct stamp *entry;
587   olsr_u32_t challenge, hash;
588   struct ipaddr_str buf;
589
590   olsr_printf(1, "[ENC]Building CHALLENGE message\n");
591
592   /* Set the size including OLSR packet size */
593
594
595   challenge = rand() << 16;
596   challenge |= rand();
597
598   /* Fill challengemessage */
599   cmsg.olsr_msgtype = TYPE_CHALLENGE;
600   cmsg.olsr_vtime = 0;
601   cmsg.olsr_msgsize = htons(sizeof(struct challengemsg));
602   memcpy(&cmsg.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize);
603   cmsg.ttl = 1;
604   cmsg.hopcnt = 0;
605   cmsg.seqno = htons(get_msg_seqno());
606
607   /* Fill subheader */
608   memcpy(&cmsg.destination, new_host, olsr_cnf->ipsize);
609   cmsg.challenge = htonl(challenge);
610
611   olsr_printf(3, "[ENC]Size: %lu\n", (unsigned long)sizeof(struct challengemsg));
612
613   {
614   olsr_u8_t checksum_cache[512 + KEYLENGTH];
615   /* Create packet + key cache */
616   /* First the OLSR packet + signature message - digest */
617   memcpy(checksum_cache, &cmsg, sizeof(struct challengemsg) - SIGNATURE_SIZE);
618   /* Then the key */
619   memcpy(&checksum_cache[sizeof(struct challengemsg) - SIGNATURE_SIZE], aes_key, KEYLENGTH);
620
621   /* Create the hash */
622   CHECKSUM(checksum_cache, 
623            (sizeof(struct challengemsg) - SIGNATURE_SIZE) + KEYLENGTH, 
624            cmsg.signature);
625   }
626   olsr_printf(3, "[ENC]Sending timestamp request to %s challenge 0x%x\n", 
627               olsr_ip_to_string(&buf, new_host),
628               challenge);
629
630   /* Add to buffer */
631   net_outbuffer_push(olsr_if, &cmsg, sizeof(struct challengemsg));
632
633   /* Send the request */
634   net_output(olsr_if);
635
636   /* Create new entry */
637   entry = malloc(sizeof(struct stamp));
638   
639   entry->diff = 0;
640   entry->validated = 0;
641   entry->challenge = challenge;
642
643   memcpy(&entry->addr, new_host, olsr_cnf->ipsize);
644
645   /* update validtime - not validated */
646   entry->conftime = GET_TIMESTAMP(EXCHANGE_HOLD_TIME * 1000);
647
648   hash = olsr_ip_hashing(new_host);
649   
650   /* Queue */
651   timestamps[hash].next->prev = entry;
652   entry->next = timestamps[hash].next;
653   timestamps[hash].next = entry;
654   entry->prev = &timestamps[hash];
655
656
657   return 1;
658
659 }
660
661 int
662 parse_cres(struct interface *olsr_if, char *in_msg)
663 {
664   struct c_respmsg *msg;
665   olsr_u8_t sha1_hash[SIGNATURE_SIZE];
666   struct stamp *entry;
667   struct ipaddr_str buf;
668
669   msg = (struct c_respmsg *)in_msg;
670
671   olsr_printf(1, "[ENC]Challenge-response message received\n");
672   olsr_printf(3, "[ENC]To: %s\n", olsr_ip_to_string(&buf, (union olsr_ip_addr *)&msg->destination));
673
674   if(if_ifwithaddr((union olsr_ip_addr *)&msg->destination) == NULL)
675     {
676       olsr_printf(3, "[ENC]Not for us...\n");
677       return 0;
678     }
679
680   olsr_printf(3, "[ENC]Challenge: 0x%lx\n", (unsigned long)ntohl(msg->challenge)); /* ntohl() returns a unsignedlong onwin32 */
681
682   /* Check signature */
683
684   {
685   olsr_u8_t checksum_cache[512 + KEYLENGTH];
686   /* Create packet + key cache */
687   /* First the OLSR packet + signature message - digest */
688   memcpy(checksum_cache, msg, sizeof(struct c_respmsg) - SIGNATURE_SIZE);
689   /* Then the key */
690   memcpy(&checksum_cache[sizeof(struct c_respmsg) - SIGNATURE_SIZE], aes_key, KEYLENGTH);
691   
692   /* Create the hash */
693   CHECKSUM(checksum_cache, 
694            (sizeof(struct c_respmsg) - SIGNATURE_SIZE) + KEYLENGTH, 
695            sha1_hash);
696   }
697   
698   if(memcmp(sha1_hash, &msg->signature, SIGNATURE_SIZE) != 0)
699     {
700       olsr_printf(1, "[ENC]Signature missmatch in challenge-response!\n");
701       return 0;
702     }
703
704   olsr_printf(3, "[ENC]Signature verified\n");
705
706
707   /* Now to check the digest from the emitted challenge */
708   if((entry = lookup_timestamp_entry((const union olsr_ip_addr *)&msg->originator)) == NULL)
709     {
710       olsr_printf(1, "[ENC]Received challenge-response from non-registered node %s!\n",
711                   olsr_ip_to_string(&buf, (union olsr_ip_addr *)&msg->originator));
712       return 0;
713     }
714
715   /* Generate the digest */
716   olsr_printf(3, "[ENC]Entry-challenge 0x%x\n", entry->challenge);
717
718   {
719   olsr_u8_t checksum_cache[512 + KEYLENGTH];
720   /* First the challenge received */
721   memcpy(checksum_cache, &entry->challenge, 4);
722   /* Then the local IP */
723   memcpy(&checksum_cache[sizeof(olsr_u32_t)], &msg->originator, olsr_cnf->ipsize);
724
725   /* Create the hash */
726   CHECKSUM(checksum_cache, 
727            sizeof(olsr_u32_t) + olsr_cnf->ipsize, 
728            sha1_hash);
729   }
730
731   if(memcmp(msg->res_sig, sha1_hash, SIGNATURE_SIZE) != 0)
732     {
733       olsr_printf(1, "[ENC]Error in challenge signature from %s!\n",
734                   olsr_ip_to_string(&buf, (union olsr_ip_addr *)&msg->originator));
735       
736       return 0;
737     }
738
739   olsr_printf(3, "[ENC]Challenge-response signature ok\n");
740
741   /* Update entry! */
742
743
744   entry->challenge = 0;
745   entry->validated = 1;
746   entry->diff = now.tv_sec - msg->timestamp;
747
748   /* update validtime - validated entry */
749   entry->valtime = GET_TIMESTAMP(TIMESTAMP_HOLD_TIME * 1000);
750
751   olsr_printf(1, "[ENC]%s registered with diff %d!\n",
752               olsr_ip_to_string(&buf, (union olsr_ip_addr *)&msg->originator),
753               entry->diff);
754
755   /* Send response-response */
756   send_rres(olsr_if, (union olsr_ip_addr *)&msg->originator, 
757             (union olsr_ip_addr *)&msg->destination, 
758             ntohl(msg->challenge));
759
760   return 1;
761 }
762
763
764 int
765 parse_rres(char *in_msg)
766 {
767   struct r_respmsg *msg;
768   olsr_u8_t sha1_hash[SIGNATURE_SIZE];
769   struct stamp *entry;
770   struct ipaddr_str buf;
771
772   msg = (struct r_respmsg *)in_msg;
773
774   olsr_printf(1, "[ENC]Response-response message received\n");
775   olsr_printf(3, "[ENC]To: %s\n", olsr_ip_to_string(&buf, (union olsr_ip_addr *)&msg->destination));
776
777   if(if_ifwithaddr((union olsr_ip_addr *)&msg->destination) == NULL)
778     {
779       olsr_printf(1, "[ENC]Not for us...\n");
780       return 0;
781     }
782
783   /* Check signature */
784
785   {
786   olsr_u8_t checksum_cache[512 + KEYLENGTH];
787   /* Create packet + key cache */
788   /* First the OLSR packet + signature message - digest */
789   memcpy(checksum_cache, msg, sizeof(struct r_respmsg) - SIGNATURE_SIZE);
790   /* Then the key */
791   memcpy(&checksum_cache[sizeof(struct r_respmsg) - SIGNATURE_SIZE], aes_key, KEYLENGTH);
792   
793   /* Create the hash */
794   CHECKSUM(checksum_cache, 
795            (sizeof(struct r_respmsg) - SIGNATURE_SIZE) + KEYLENGTH, 
796            sha1_hash);
797   }
798   
799   if(memcmp(sha1_hash, &msg->signature, SIGNATURE_SIZE) != 0)
800     {
801       olsr_printf(1, "[ENC]Signature missmatch in response-response!\n");
802       return 0;
803     }
804
805   olsr_printf(3, "[ENC]Signature verified\n");
806
807
808   /* Now to check the digest from the emitted challenge */
809   if((entry = lookup_timestamp_entry((const union olsr_ip_addr *)&msg->originator)) == NULL)
810     {
811       olsr_printf(1, "[ENC]Received response-response from non-registered node %s!\n",
812                   olsr_ip_to_string(&buf, (union olsr_ip_addr *)&msg->originator));
813       return 0;
814     }
815
816   /* Generate the digest */
817   olsr_printf(3, "[ENC]Entry-challenge 0x%x\n", entry->challenge);
818
819   {
820   olsr_u8_t checksum_cache[512 + KEYLENGTH];
821   /* First the challenge received */
822   memcpy(checksum_cache, &entry->challenge, 4);
823   /* Then the local IP */
824   memcpy(&checksum_cache[sizeof(olsr_u32_t)], &msg->originator, olsr_cnf->ipsize);
825
826   /* Create the hash */
827   CHECKSUM(checksum_cache, 
828            sizeof(olsr_u32_t) + olsr_cnf->ipsize, 
829            sha1_hash);
830   }
831
832   if(memcmp(msg->res_sig, sha1_hash, SIGNATURE_SIZE) != 0)
833     {
834       olsr_printf(1, "[ENC]Error in response signature from %s!\n",
835                   olsr_ip_to_string(&buf, (union olsr_ip_addr *)&msg->originator));
836       
837       return 0;
838     }
839
840   olsr_printf(3, "[ENC]Challenge-response signature ok\n");
841
842   /* Update entry! */
843
844
845   entry->challenge = 0;
846   entry->validated = 1;
847   entry->diff = now.tv_sec - msg->timestamp;
848
849   /* update validtime - validated entry */
850   entry->valtime = GET_TIMESTAMP(TIMESTAMP_HOLD_TIME * 1000);
851
852   olsr_printf(1, "[ENC]%s registered with diff %d!\n",
853               olsr_ip_to_string(&buf, (union olsr_ip_addr *)&msg->originator),
854               entry->diff);
855
856   return 1;
857 }
858
859
860 int
861 parse_challenge(struct interface *olsr_if, char *in_msg)
862 {
863   struct challengemsg *msg;
864   olsr_u8_t sha1_hash[SIGNATURE_SIZE];
865   struct stamp *entry;
866   olsr_u32_t hash;
867   struct ipaddr_str buf;
868           
869   msg = (struct challengemsg *)in_msg;
870
871   olsr_printf(1, "[ENC]Challenge message received\n");
872   olsr_printf(3, "[ENC]To: %s\n", olsr_ip_to_string(&buf, (union olsr_ip_addr *)&msg->destination));
873
874   if(if_ifwithaddr((union olsr_ip_addr *)&msg->destination) == NULL)
875     {
876       olsr_printf(1, "[ENC]Not for us...\n");
877       return 0;
878     }
879
880   /* Create entry if not registered */
881   if((entry = lookup_timestamp_entry((const union olsr_ip_addr *)&msg->originator)) == NULL)
882     {
883       entry = malloc(sizeof(struct stamp));
884       memcpy(&entry->addr, &msg->originator, olsr_cnf->ipsize);
885
886       hash = olsr_ip_hashing((union olsr_ip_addr *)&msg->originator);
887   
888       /* Queue */
889       timestamps[hash].next->prev = entry;
890       entry->next = timestamps[hash].next;
891       timestamps[hash].next = entry;
892       entry->prev = &timestamps[hash];
893     }
894   else
895     {
896       /* Check configuration timeout */
897       if(!TIMED_OUT(entry->conftime))
898         {
899           /* If registered - do not accept! */
900           olsr_printf(1, "[ENC]Challenge from registered node...dropping!\n");
901           return 0;
902         }
903       else
904         {
905           olsr_printf(1, "[ENC]Challenge from registered node...accepted!\n");
906         }
907     }
908
909   olsr_printf(3, "[ENC]Challenge: 0x%lx\n", (unsigned long)ntohl(msg->challenge)); /* ntohl() returns a unsignedlong onwin32 */
910
911   /* Check signature */
912
913   {
914   olsr_u8_t checksum_cache[512 + KEYLENGTH];
915   /* Create packet + key cache */
916   /* First the OLSR packet + signature message - digest */
917   memcpy(checksum_cache, msg, sizeof(struct challengemsg) - SIGNATURE_SIZE);
918   /* Then the key */
919   memcpy(&checksum_cache[sizeof(struct challengemsg) - SIGNATURE_SIZE], aes_key, KEYLENGTH);
920   
921   /* Create the hash */
922   CHECKSUM(checksum_cache, 
923            (sizeof(struct challengemsg) - SIGNATURE_SIZE) + KEYLENGTH, 
924            sha1_hash);
925   }  
926   if(memcmp(sha1_hash, &msg->signature, SIGNATURE_SIZE) != 0)
927     {
928       olsr_printf(1, "[ENC]Signature missmatch in challenge!\n");
929       return 0;
930     }
931
932   olsr_printf(3, "[ENC]Signature verified\n");
933
934   
935   entry->diff = 0;
936   entry->validated = 0;
937
938   /* update validtime - not validated */
939   entry->conftime = GET_TIMESTAMP(EXCHANGE_HOLD_TIME * 1000);
940
941   /* Build and send response */
942
943   send_cres(olsr_if, (union olsr_ip_addr *)&msg->originator, 
944             (union olsr_ip_addr *)&msg->destination, 
945             ntohl(msg->challenge),
946             entry);
947
948   return 1;
949 }
950
951
952
953
954
955 /**
956  * Build and transmit a challenge response
957  * message.
958  *
959  */
960 int
961 send_cres(struct interface *olsr_if, union olsr_ip_addr *to, union olsr_ip_addr *from, olsr_u32_t chal_in, struct stamp *entry)
962 {
963   struct c_respmsg crmsg;
964   olsr_u32_t challenge;
965   struct ipaddr_str buf;
966
967   olsr_printf(1, "[ENC]Building CRESPONSE message\n");
968
969   challenge = rand() << 16;
970   challenge |= rand();
971
972   entry->challenge = challenge;
973
974   olsr_printf(3, "[ENC]Challenge-response: 0x%x\n", challenge);
975
976   /* Fill challengemessage */
977   crmsg.olsr_msgtype = TYPE_CRESPONSE;
978   crmsg.olsr_vtime = 0;
979   crmsg.olsr_msgsize = htons(sizeof(struct c_respmsg));
980   memcpy(&crmsg.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize);
981   crmsg.ttl = 1;
982   crmsg.hopcnt = 0;
983   crmsg.seqno = htons(get_msg_seqno());
984
985   /* set timestamp */
986   crmsg.timestamp = now.tv_sec;
987   olsr_printf(3, "[ENC]Timestamp %ld\n", crmsg.timestamp);
988
989   /* Fill subheader */
990   memcpy(&crmsg.destination, to, olsr_cnf->ipsize);
991   crmsg.challenge = htonl(challenge);
992
993   /* Create digest of received challenge + IP */
994
995   {
996   olsr_u8_t checksum_cache[512 + KEYLENGTH];
997   /* Create packet + key cache */
998   /* First the challenge received */
999   memcpy(checksum_cache, &chal_in, 4);
1000   /* Then the local IP */
1001   memcpy(&checksum_cache[sizeof(olsr_u32_t)], from, olsr_cnf->ipsize);
1002
1003   /* Create the hash */
1004   CHECKSUM(checksum_cache, 
1005            sizeof(olsr_u32_t) + olsr_cnf->ipsize, 
1006            crmsg.res_sig);
1007   }
1008
1009   /* Now create the digest of the message and the key */
1010
1011   {
1012   olsr_u8_t checksum_cache[512 + KEYLENGTH];
1013   /* Create packet + key cache */
1014   /* First the OLSR packet + signature message - digest */
1015   memcpy(checksum_cache, &crmsg, sizeof(struct c_respmsg) - SIGNATURE_SIZE);
1016   /* Then the key */
1017   memcpy(&checksum_cache[sizeof(struct c_respmsg) - SIGNATURE_SIZE], aes_key, KEYLENGTH);
1018
1019   /* Create the hash */
1020   CHECKSUM(checksum_cache, 
1021            (sizeof(struct c_respmsg) - SIGNATURE_SIZE) + KEYLENGTH, 
1022            crmsg.signature);
1023   }
1024
1025   olsr_printf(3, "[ENC]Sending challenge response to %s challenge 0x%x\n", 
1026               olsr_ip_to_string(&buf, to),
1027               challenge);
1028
1029   /* Add to buffer */
1030   net_outbuffer_push(olsr_if, &crmsg, sizeof(struct c_respmsg));
1031   /* Send the request */
1032   net_output(olsr_if);
1033
1034   return 1;
1035 }
1036
1037
1038
1039
1040
1041
1042 /**
1043  * Build and transmit a response response
1044  * message.
1045  *
1046  */
1047 static int
1048 send_rres(struct interface *olsr_if, union olsr_ip_addr *to, union olsr_ip_addr *from, olsr_u32_t chal_in)
1049 {
1050   struct r_respmsg rrmsg;
1051   struct ipaddr_str buf;
1052
1053   olsr_printf(1, "[ENC]Building RRESPONSE message\n");
1054
1055
1056   /* Fill challengemessage */
1057   rrmsg.olsr_msgtype = TYPE_RRESPONSE;
1058   rrmsg.olsr_vtime = 0;
1059   rrmsg.olsr_msgsize = htons(sizeof(struct r_respmsg));
1060   memcpy(&rrmsg.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize);
1061   rrmsg.ttl = 1;
1062   rrmsg.hopcnt = 0;
1063   rrmsg.seqno = htons(get_msg_seqno());
1064
1065   /* set timestamp */
1066   rrmsg.timestamp = now.tv_sec;
1067   olsr_printf(3, "[ENC]Timestamp %ld\n", rrmsg.timestamp);
1068
1069   /* Fill subheader */
1070   memcpy(&rrmsg.destination, to, olsr_cnf->ipsize);
1071
1072   /* Create digest of received challenge + IP */
1073
1074   {
1075   olsr_u8_t checksum_cache[512 + KEYLENGTH];
1076   /* Create packet + key cache */
1077   /* First the challenge received */
1078   memcpy(checksum_cache, &chal_in, 4);
1079   /* Then the local IP */
1080   memcpy(&checksum_cache[sizeof(olsr_u32_t)], from, olsr_cnf->ipsize);
1081
1082   /* Create the hash */
1083   CHECKSUM(checksum_cache, 
1084            sizeof(olsr_u32_t) + olsr_cnf->ipsize, 
1085            rrmsg.res_sig);
1086   }
1087
1088   /* Now create the digest of the message and the key */
1089
1090   {
1091   olsr_u8_t checksum_cache[512 + KEYLENGTH];
1092   /* Create packet + key cache */
1093   /* First the OLSR packet + signature message - digest */
1094   memcpy(checksum_cache, &rrmsg, sizeof(struct r_respmsg) - SIGNATURE_SIZE);
1095   /* Then the key */
1096   memcpy(&checksum_cache[sizeof(struct r_respmsg) - SIGNATURE_SIZE], aes_key, KEYLENGTH);
1097
1098   /* Create the hash */
1099   CHECKSUM(checksum_cache, 
1100            (sizeof(struct r_respmsg) - SIGNATURE_SIZE) + KEYLENGTH, 
1101            rrmsg.signature);
1102   }
1103
1104   olsr_printf(3, "[ENC]Sending response response to %s\n", 
1105               olsr_ip_to_string(&buf, to));
1106
1107   /* add to buffer */
1108   net_outbuffer_push(olsr_if, &rrmsg, sizeof(struct r_respmsg));
1109
1110   /* Send the request */
1111   net_output(olsr_if);
1112
1113   return 1;
1114 }
1115
1116
1117
1118 static struct stamp *
1119 lookup_timestamp_entry(const union olsr_ip_addr *adr)
1120 {
1121   olsr_u32_t hash;
1122   struct stamp *entry;
1123   struct ipaddr_str buf;
1124
1125   hash = olsr_ip_hashing(adr);
1126
1127   for(entry = timestamps[hash].next;
1128       entry != &timestamps[hash];
1129       entry = entry->next)
1130     {
1131       if(memcmp(&entry->addr, adr, olsr_cnf->ipsize) == 0)
1132         {
1133           olsr_printf(3, "[ENC]Match for %s\n", olsr_ip_to_string(&buf, adr));
1134           return entry;
1135         }
1136     }
1137
1138   olsr_printf(1, "[ENC]No match for %s\n", olsr_ip_to_string(&buf, adr));
1139
1140   return NULL;
1141 }
1142
1143
1144
1145 /**
1146  *Find timed out entries and delete them
1147  *
1148  *@return nada
1149  */
1150 void
1151 timeout_timestamps(void* foo __attribute__((unused)))
1152 {
1153   struct stamp *tmp_list;
1154   struct stamp *entry_to_delete;
1155   int idx;
1156
1157   /* Update our local timestamp */
1158   gettimeofday(&now, NULL);
1159
1160   for(idx=0;idx<HASHSIZE;idx++)
1161     {
1162       tmp_list = timestamps[idx].next;
1163       /*Traverse MID list*/
1164       while(tmp_list != &timestamps[idx])
1165         {
1166           /*Check if the entry is timed out*/
1167           if((TIMED_OUT(tmp_list->valtime)) && (TIMED_OUT(tmp_list->conftime)))
1168             {
1169               struct ipaddr_str buf;
1170               entry_to_delete = tmp_list;
1171               tmp_list = tmp_list->next;
1172
1173               olsr_printf(1, "[ENC]timestamp info for %s timed out.. deleting it\n", 
1174                           olsr_ip_to_string(&buf, &entry_to_delete->addr));
1175
1176               /*Delete it*/
1177               entry_to_delete->next->prev = entry_to_delete->prev;
1178               entry_to_delete->prev->next = entry_to_delete->next;
1179
1180               free(entry_to_delete);
1181             }
1182           else
1183               tmp_list = tmp_list->next;
1184         }
1185     }
1186
1187   return;
1188 }
1189
1190
1191
1192 static int
1193 read_key_from_file(const char *file)
1194 {
1195   FILE *kf;
1196   size_t keylen;
1197
1198   keylen = 16;
1199   kf = fopen(file, "r");
1200
1201   olsr_printf(1, "[ENC]Reading key from file \"%s\"\n", file);
1202
1203   if(kf == NULL)
1204     {
1205       olsr_printf(1, "[ENC]Could not open keyfile %s!\nError: %s\n", file, strerror(errno));
1206       return -1;
1207     }
1208
1209   if(fread(aes_key, 1, keylen, kf) != keylen)
1210     {
1211       olsr_printf(1, "[ENC]Could not read key from keyfile %s!\nError: %s\n", file, strerror(errno));
1212       fclose(kf);
1213       return 0;
1214     }
1215
1216
1217   fclose(kf);
1218   return 1;
1219 }
1220