conversion from 8 spaces to 4 spaces per tab

This commit is contained in:
Andreas Steffen
2009-04-19 19:16:09 +00:00
parent d940c7638c
commit 3d7a244b54
138 changed files with 47306 additions and 47306 deletions
+692 -692
View File
File diff suppressed because it is too large Load Diff
+27 -27
View File
@@ -1,7 +1,7 @@
/* Support of X.509 attribute certificates /* Support of X.509 attribute certificates
* Copyright (C) 2002 Ueli Galizzi, Ariane Seiler * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
* Copyright (C) 2003 Martin Berner, Lukas Suter * Copyright (C) 2003 Martin Berner, Lukas Suter
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public License as published by the
@@ -22,9 +22,9 @@
/* definition of ietfAttribute kinds */ /* definition of ietfAttribute kinds */
typedef enum { typedef enum {
IETF_ATTRIBUTE_OCTETS = 0, IETF_ATTRIBUTE_OCTETS = 0,
IETF_ATTRIBUTE_OID = 1, IETF_ATTRIBUTE_OID = 1,
IETF_ATTRIBUTE_STRING = 2 IETF_ATTRIBUTE_STRING = 2
} ietfAttribute_t; } ietfAttribute_t;
/* access structure for an ietfAttribute */ /* access structure for an ietfAttribute */
@@ -32,17 +32,17 @@ typedef enum {
typedef struct ietfAttr ietfAttr_t; typedef struct ietfAttr ietfAttr_t;
struct ietfAttr { struct ietfAttr {
time_t installed; time_t installed;
int count; int count;
ietfAttribute_t kind; ietfAttribute_t kind;
chunk_t value; chunk_t value;
}; };
typedef struct ietfAttrList ietfAttrList_t; typedef struct ietfAttrList ietfAttrList_t;
struct ietfAttrList { struct ietfAttrList {
ietfAttrList_t *next; ietfAttrList_t *next;
ietfAttr_t *attr; ietfAttr_t *attr;
}; };
@@ -52,31 +52,31 @@ typedef struct x509acert x509acert_t;
struct x509acert { struct x509acert {
x509acert_t *next; x509acert_t *next;
time_t installed; time_t installed;
chunk_t certificate; chunk_t certificate;
chunk_t certificateInfo; chunk_t certificateInfo;
u_int version; u_int version;
/* holder */ /* holder */
/* baseCertificateID */ /* baseCertificateID */
chunk_t holderIssuer; chunk_t holderIssuer;
chunk_t holderSerial; chunk_t holderSerial;
chunk_t entityName; chunk_t entityName;
/* v2Form */ /* v2Form */
chunk_t issuerName; chunk_t issuerName;
/* signature */ /* signature */
int sigAlg; int sigAlg;
chunk_t serialNumber; chunk_t serialNumber;
/* attrCertValidityPeriod */ /* attrCertValidityPeriod */
time_t notBefore; time_t notBefore;
time_t notAfter; time_t notAfter;
/* attributes */ /* attributes */
ietfAttrList_t *charging; ietfAttrList_t *charging;
ietfAttrList_t *groups; ietfAttrList_t *groups;
/* extensions */ /* extensions */
chunk_t authKeyID; chunk_t authKeyID;
chunk_t authKeySerialNumber; chunk_t authKeySerialNumber;
bool noRevAvail; bool noRevAvail;
/* signatureAlgorithm */ /* signatureAlgorithm */
int algorithm; int algorithm;
chunk_t signature; chunk_t signature;
}; };
@@ -88,7 +88,7 @@ extern void unshare_ietfAttrList(ietfAttrList_t **listp);
extern void free_ietfAttrList(ietfAttrList_t *list); extern void free_ietfAttrList(ietfAttrList_t *list);
extern void decode_groups(char *groups, ietfAttrList_t **listp); extern void decode_groups(char *groups, ietfAttrList_t **listp);
extern bool group_membership(const ietfAttrList_t *my_list extern bool group_membership(const ietfAttrList_t *my_list
, const char *conn, const ietfAttrList_t *conn_list); , const char *conn, const ietfAttrList_t *conn_list);
extern bool parse_ac(chunk_t blob, x509acert_t *ac); extern bool parse_ac(chunk_t blob, x509acert_t *ac);
extern bool verify_x509acert(x509acert_t *ac, bool strict); extern bool verify_x509acert(x509acert_t *ac, bool strict);
extern x509acert_t* get_x509acert(chunk_t issuer, chunk_t serial); extern x509acert_t* get_x509acert(chunk_t issuer, chunk_t serial);
+359 -359
View File
@@ -14,7 +14,7 @@
* RCSID $Id$ * RCSID $Id$
*/ */
#ifndef USE_LWRES /* whole file! */ #ifndef USE_LWRES /* whole file! */
/* This program executes as multiple processes. The Master process /* This program executes as multiple processes. The Master process
* receives queries (struct adns_query messages) from Pluto and distributes * receives queries (struct adns_query messages) from Pluto and distributes
@@ -58,7 +58,7 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/nameser.h> #include <arpa/nameser.h>
#include <resolv.h> #include <resolv.h>
#include <netdb.h> /* ??? for h_errno */ #include <netdb.h> /* ??? for h_errno */
#include <freeswan.h> #include <freeswan.h>
@@ -70,11 +70,11 @@
#endif #endif
#include "constants.h" #include "constants.h"
#include "adns.h" /* needs <resolv.h> */ #include "adns.h" /* needs <resolv.h> */
/* shared by all processes */ /* shared by all processes */
static const char *name; /* program name, for messages */ static const char *name; /* program name, for messages */
static bool debug = FALSE; static bool debug = FALSE;
@@ -88,43 +88,43 @@ static bool debug = FALSE;
static enum helper_exit_status static enum helper_exit_status
read_pipe(int fd, unsigned char *stuff, size_t minlen, size_t maxlen) read_pipe(int fd, unsigned char *stuff, size_t minlen, size_t maxlen)
{ {
size_t n = 0; size_t n = 0;
size_t goal = minlen; size_t goal = minlen;
do { do {
ssize_t m = read(fd, stuff + n, goal - n); ssize_t m = read(fd, stuff + n, goal - n);
if (m == -1) if (m == -1)
{
if (errno != EINTR)
{
syslog(LOG_ERR, "Input error on pipe: %s", strerror(errno));
return HES_IO_ERROR_IN;
}
}
else if (m == 0)
{
return HES_OK; /* treat empty message as EOF */
}
else
{
n += m;
if (n >= sizeof(size_t))
{
goal = *(size_t *)(void *)stuff;
if (goal < minlen || maxlen < goal)
{ {
if (debug) if (errno != EINTR)
fprintf(stderr, "%lu : [%lu, %lu]\n" {
, (unsigned long)goal syslog(LOG_ERR, "Input error on pipe: %s", strerror(errno));
, (unsigned long)minlen, (unsigned long)maxlen); return HES_IO_ERROR_IN;
return HES_BAD_LEN; }
} }
} else if (m == 0)
} {
} while (n < goal); return HES_OK; /* treat empty message as EOF */
}
else
{
n += m;
if (n >= sizeof(size_t))
{
goal = *(size_t *)(void *)stuff;
if (goal < minlen || maxlen < goal)
{
if (debug)
fprintf(stderr, "%lu : [%lu, %lu]\n"
, (unsigned long)goal
, (unsigned long)minlen, (unsigned long)maxlen);
return HES_BAD_LEN;
}
}
}
} while (n < goal);
return HES_CONTINUE; return HES_CONTINUE;
} }
/* Write a variable-length record to a pipe. /* Write a variable-length record to a pipe.
@@ -135,27 +135,27 @@ read_pipe(int fd, unsigned char *stuff, size_t minlen, size_t maxlen)
static enum helper_exit_status static enum helper_exit_status
write_pipe(int fd, const unsigned char *stuff) write_pipe(int fd, const unsigned char *stuff)
{ {
size_t len = *(const size_t *)(const void *)stuff; size_t len = *(const size_t *)(const void *)stuff;
size_t n = 0; size_t n = 0;
do { do {
ssize_t m = write(fd, stuff + n, len - n); ssize_t m = write(fd, stuff + n, len - n);
if (m == -1) if (m == -1)
{ {
/* error, but ignore and retry if EINTR */ /* error, but ignore and retry if EINTR */
if (errno != EINTR) if (errno != EINTR)
{ {
syslog(LOG_ERR, "Output error from master: %s", strerror(errno)); syslog(LOG_ERR, "Output error from master: %s", strerror(errno));
return HES_IO_ERROR_OUT; return HES_IO_ERROR_OUT;
} }
} }
else else
{ {
n += m; n += m;
} }
} while (n != len); } while (n != len);
return HES_CONTINUE; return HES_CONTINUE;
} }
/**************** worker process ****************/ /**************** worker process ****************/
@@ -171,14 +171,14 @@ write_pipe(int fd, const unsigned char *stuff)
*/ */
#if (__RES) <= 19960801 #if (__RES) <= 19960801
# define OLD_RESOLVER 1 # define OLD_RESOLVER 1
#endif #endif
#ifdef OLD_RESOLVER #ifdef OLD_RESOLVER
# define res_ninit(statp) res_init() # define res_ninit(statp) res_init()
# define res_nquery(statp, dname, class, type, answer, anslen) \ # define res_nquery(statp, dname, class, type, answer, anslen) \
res_query(dname, class, type, answer, anslen) res_query(dname, class, type, answer, anslen)
# define res_nclose(statp) res_close() # define res_nclose(statp) res_close()
static struct __res_state *statp = &_res; static struct __res_state *statp = &_res;
@@ -193,75 +193,75 @@ static res_state statp = &my_res_state;
static int static int
worker(int qfd, int afd) worker(int qfd, int afd)
{ {
{
int r = res_ninit(statp);
if (r != 0)
{ {
syslog(LOG_ERR, "cannot initialize resolver"); int r = res_ninit(statp);
return HES_RES_INIT;
} if (r != 0)
{
syslog(LOG_ERR, "cannot initialize resolver");
return HES_RES_INIT;
}
#ifndef OLD_RESOLVER #ifndef OLD_RESOLVER
statp->options |= RES_ROTATE; statp->options |= RES_ROTATE;
#endif #endif
statp->options |= RES_DEBUG; statp->options |= RES_DEBUG;
}
for (;;)
{
struct adns_query q;
struct adns_answer a;
enum helper_exit_status r = read_pipe(qfd, (unsigned char *)&q
, sizeof(q), sizeof(q));
if (r != HES_CONTINUE)
return r; /* some kind of exit */
if (q.qmagic != ADNS_Q_MAGIC)
{
syslog(LOG_ERR, "error in input from master: bad magic");
return HES_BAD_MAGIC;
} }
a.amagic = ADNS_A_MAGIC; for (;;)
a.serial = q.serial; {
struct adns_query q;
struct adns_answer a;
a.result = res_nquery(statp, q.name_buf, C_IN, q.type, a.ans, sizeof(a.ans)); enum helper_exit_status r = read_pipe(qfd, (unsigned char *)&q
a.h_errno_val = h_errno; , sizeof(q), sizeof(q));
a.len = offsetof(struct adns_answer, ans) + (a.result < 0? 0 : a.result); if (r != HES_CONTINUE)
return r; /* some kind of exit */
if (q.qmagic != ADNS_Q_MAGIC)
{
syslog(LOG_ERR, "error in input from master: bad magic");
return HES_BAD_MAGIC;
}
a.amagic = ADNS_A_MAGIC;
a.serial = q.serial;
a.result = res_nquery(statp, q.name_buf, C_IN, q.type, a.ans, sizeof(a.ans));
a.h_errno_val = h_errno;
a.len = offsetof(struct adns_answer, ans) + (a.result < 0? 0 : a.result);
#ifdef DEBUG #ifdef DEBUG
if (((q.debugging & IMPAIR_DELAY_ADNS_KEY_ANSWER) && q.type == T_KEY) if (((q.debugging & IMPAIR_DELAY_ADNS_KEY_ANSWER) && q.type == T_KEY)
|| ((q.debugging & IMPAIR_DELAY_ADNS_TXT_ANSWER) && q.type == T_TXT)) || ((q.debugging & IMPAIR_DELAY_ADNS_TXT_ANSWER) && q.type == T_TXT))
sleep(30); /* delay the answer */ sleep(30); /* delay the answer */
#endif #endif
/* write answer, possibly a bit at a time */ /* write answer, possibly a bit at a time */
r = write_pipe(afd, (const unsigned char *)&a); r = write_pipe(afd, (const unsigned char *)&a);
if (r != HES_CONTINUE) if (r != HES_CONTINUE)
return r; /* some kind of exit */ return r; /* some kind of exit */
} }
} }
/**************** master process ****************/ /**************** master process ****************/
bool eof_from_pluto = FALSE; bool eof_from_pluto = FALSE;
#define PLUTO_QFD 0 /* queries come on stdin */ #define PLUTO_QFD 0 /* queries come on stdin */
#define PLUTO_AFD 1 /* answers go out on stdout */ #define PLUTO_AFD 1 /* answers go out on stdout */
#ifndef MAX_WORKERS #ifndef MAX_WORKERS
# define MAX_WORKERS 10 /* number of in-flight queries */ # define MAX_WORKERS 10 /* number of in-flight queries */
#endif #endif
struct worker_info { struct worker_info {
int qfd; /* query pipe's file descriptor */ int qfd; /* query pipe's file descriptor */
int afd; /* answer pipe's file descriptor */ int afd; /* answer pipe's file descriptor */
pid_t pid; pid_t pid;
bool busy; bool busy;
void *continuation; /* of outstanding request */ void *continuation; /* of outstanding request */
}; };
static struct worker_info wi[MAX_WORKERS]; static struct worker_info wi[MAX_WORKERS];
@@ -270,300 +270,300 @@ static struct worker_info *wi_roof = wi;
/* request FIFO */ /* request FIFO */
struct query_list { struct query_list {
struct query_list *next; struct query_list *next;
struct adns_query aq; struct adns_query aq;
}; };
static struct query_list *oldest_query = NULL; static struct query_list *oldest_query = NULL;
static struct query_list *newest_query; /* undefined when oldest == NULL */ static struct query_list *newest_query; /* undefined when oldest == NULL */
static struct query_list *free_queries = NULL; static struct query_list *free_queries = NULL;
static bool static bool
spawn_worker(void) spawn_worker(void)
{ {
int qfds[2]; int qfds[2];
int afds[2]; int afds[2];
pid_t p; pid_t p;
if (pipe(qfds) != 0 || pipe(afds) != 0) if (pipe(qfds) != 0 || pipe(afds) != 0)
{
syslog(LOG_ERR, "pipe(2) failed: %s", strerror(errno));
exit(HES_PIPE);
}
wi_roof->qfd = qfds[1]; /* write end of query pipe */
wi_roof->afd = afds[0]; /* read end of answer pipe */
p = fork();
if (p == -1)
{
/* fork failed: ignore if at least one worker exists */
if (wi_roof == wi)
{ {
syslog(LOG_ERR, "fork(2) error creating first worker: %s", strerror(errno)); syslog(LOG_ERR, "pipe(2) failed: %s", strerror(errno));
exit(HES_FORK); exit(HES_PIPE);
} }
close(qfds[0]);
close(qfds[1]);
close(afds[0]);
close(afds[1]);
return FALSE;
}
else if (p == 0)
{
/* child */
struct worker_info *w;
close(PLUTO_QFD); wi_roof->qfd = qfds[1]; /* write end of query pipe */
close(PLUTO_AFD); wi_roof->afd = afds[0]; /* read end of answer pipe */
/* close all master pipes, including ours */
for (w = wi; w <= wi_roof; w++) p = fork();
if (p == -1)
{ {
close(w->qfd); /* fork failed: ignore if at least one worker exists */
close(w->afd); if (wi_roof == wi)
{
syslog(LOG_ERR, "fork(2) error creating first worker: %s", strerror(errno));
exit(HES_FORK);
}
close(qfds[0]);
close(qfds[1]);
close(afds[0]);
close(afds[1]);
return FALSE;
} }
exit(worker(qfds[0], afds[1])); else if (p == 0)
} {
else /* child */
{ struct worker_info *w;
/* parent */
struct worker_info *w = wi_roof++;
w->pid = p; close(PLUTO_QFD);
w->busy = FALSE; close(PLUTO_AFD);
close(qfds[0]); /* close all master pipes, including ours */
close(afds[1]); for (w = wi; w <= wi_roof; w++)
return TRUE; {
} close(w->qfd);
close(w->afd);
}
exit(worker(qfds[0], afds[1]));
}
else
{
/* parent */
struct worker_info *w = wi_roof++;
w->pid = p;
w->busy = FALSE;
close(qfds[0]);
close(afds[1]);
return TRUE;
}
} }
static void static void
send_eof(struct worker_info *w) send_eof(struct worker_info *w)
{ {
pid_t p; pid_t p;
int status; int status;
close(w->qfd); close(w->qfd);
w->qfd = NULL_FD; w->qfd = NULL_FD;
close(w->afd); close(w->afd);
w->afd = NULL_FD; w->afd = NULL_FD;
/* reap child */ /* reap child */
p = waitpid(w->pid, &status, 0); p = waitpid(w->pid, &status, 0);
/* ignore result -- what could we do with it? */ /* ignore result -- what could we do with it? */
} }
static void static void
forward_query(struct worker_info *w) forward_query(struct worker_info *w)
{ {
struct query_list *q = oldest_query; struct query_list *q = oldest_query;
if (q == NULL) if (q == NULL)
{ {
if (eof_from_pluto) if (eof_from_pluto)
send_eof(w); send_eof(w);
} }
else else
{ {
enum helper_exit_status r enum helper_exit_status r
= write_pipe(w->qfd, (const unsigned char *) &q->aq); = write_pipe(w->qfd, (const unsigned char *) &q->aq);
if (r != HES_CONTINUE) if (r != HES_CONTINUE)
exit(r); exit(r);
w->busy = TRUE; w->busy = TRUE;
oldest_query = q->next; oldest_query = q->next;
q->next = free_queries; q->next = free_queries;
free_queries = q; free_queries = q;
} }
} }
static void static void
query(void) query(void)
{ {
struct query_list *q = free_queries; struct query_list *q = free_queries;
enum helper_exit_status r; enum helper_exit_status r;
/* find an unused queue entry */ /* find an unused queue entry */
if (q == NULL)
{
q = malloc(sizeof(*q));
if (q == NULL) if (q == NULL)
{ {
syslog(LOG_ERR, "malloc(3) failed"); q = malloc(sizeof(*q));
exit(HES_MALLOC); if (q == NULL)
{
syslog(LOG_ERR, "malloc(3) failed");
exit(HES_MALLOC);
}
} }
}
else
{
free_queries = q->next;
}
r = read_pipe(PLUTO_QFD, (unsigned char *)&q->aq
, sizeof(q->aq), sizeof(q->aq));
if (r == HES_OK)
{
/* EOF: we're done, except for unanswered queries */
struct worker_info *w;
eof_from_pluto = TRUE;
q->next = free_queries;
free_queries = q;
/* Send bye-bye to unbusy processes.
* Note that if there are queued queries, there won't be
* any non-busy workers.
*/
for (w = wi; w != wi_roof; w++)
if (!w->busy)
send_eof(w);
}
else if (r != HES_CONTINUE)
{
exit(r);
}
else if (q->aq.qmagic != ADNS_Q_MAGIC)
{
syslog(LOG_ERR, "error in query from Pluto: bad magic");
exit(HES_BAD_MAGIC);
}
else
{
struct worker_info *w;
/* got a query */
/* add it to FIFO */
q->next = NULL;
if (oldest_query == NULL)
oldest_query = q;
else else
newest_query->next = q;
newest_query = q;
/* See if any worker available */
for (w = wi; ; w++)
{ {
if (w == wi_roof) free_queries = q->next;
{
/* no free worker */
if (w == wi + MAX_WORKERS)
break; /* no more to be created */
/* make a new one */
if (!spawn_worker())
break; /* cannot create one at this time */
}
if (!w->busy)
{
/* assign first to free worker */
forward_query(w);
break;
}
} }
}
return; r = read_pipe(PLUTO_QFD, (unsigned char *)&q->aq
, sizeof(q->aq), sizeof(q->aq));
if (r == HES_OK)
{
/* EOF: we're done, except for unanswered queries */
struct worker_info *w;
eof_from_pluto = TRUE;
q->next = free_queries;
free_queries = q;
/* Send bye-bye to unbusy processes.
* Note that if there are queued queries, there won't be
* any non-busy workers.
*/
for (w = wi; w != wi_roof; w++)
if (!w->busy)
send_eof(w);
}
else if (r != HES_CONTINUE)
{
exit(r);
}
else if (q->aq.qmagic != ADNS_Q_MAGIC)
{
syslog(LOG_ERR, "error in query from Pluto: bad magic");
exit(HES_BAD_MAGIC);
}
else
{
struct worker_info *w;
/* got a query */
/* add it to FIFO */
q->next = NULL;
if (oldest_query == NULL)
oldest_query = q;
else
newest_query->next = q;
newest_query = q;
/* See if any worker available */
for (w = wi; ; w++)
{
if (w == wi_roof)
{
/* no free worker */
if (w == wi + MAX_WORKERS)
break; /* no more to be created */
/* make a new one */
if (!spawn_worker())
break; /* cannot create one at this time */
}
if (!w->busy)
{
/* assign first to free worker */
forward_query(w);
break;
}
}
}
return;
} }
static void static void
answer(struct worker_info *w) answer(struct worker_info *w)
{ {
struct adns_answer a; struct adns_answer a;
enum helper_exit_status r = read_pipe(w->afd, (unsigned char *)&a enum helper_exit_status r = read_pipe(w->afd, (unsigned char *)&a
, offsetof(struct adns_answer, ans), sizeof(a)); , offsetof(struct adns_answer, ans), sizeof(a));
if (r == HES_OK) if (r == HES_OK)
{ {
/* unexpected EOF */ /* unexpected EOF */
syslog(LOG_ERR, "unexpected EOF from worker"); syslog(LOG_ERR, "unexpected EOF from worker");
exit(HES_IO_ERROR_IN); exit(HES_IO_ERROR_IN);
} }
else if (r != HES_CONTINUE) else if (r != HES_CONTINUE)
{ {
exit(r); exit(r);
} }
else if (a.amagic != ADNS_A_MAGIC) else if (a.amagic != ADNS_A_MAGIC)
{ {
syslog(LOG_ERR, "Input from worker error: bad magic"); syslog(LOG_ERR, "Input from worker error: bad magic");
exit(HES_BAD_MAGIC); exit(HES_BAD_MAGIC);
} }
else if (a.continuation != w->continuation) else if (a.continuation != w->continuation)
{ {
/* answer doesn't match query */ /* answer doesn't match query */
syslog(LOG_ERR, "Input from worker error: continuation mismatch"); syslog(LOG_ERR, "Input from worker error: continuation mismatch");
exit(HES_SYNC); exit(HES_SYNC);
} }
else else
{ {
/* pass the answer on to Pluto */ /* pass the answer on to Pluto */
enum helper_exit_status r enum helper_exit_status r
= write_pipe(PLUTO_AFD, (const unsigned char *) &a); = write_pipe(PLUTO_AFD, (const unsigned char *) &a);
if (r != HES_CONTINUE) if (r != HES_CONTINUE)
exit(r); exit(r);
w->busy = FALSE; w->busy = FALSE;
forward_query(w); forward_query(w);
} }
} }
/* assumption: input limited; accept blocking on output */ /* assumption: input limited; accept blocking on output */
static int static int
master(void) master(void)
{ {
for (;;) for (;;)
{ {
fd_set readfds; fd_set readfds;
int maxfd = PLUTO_QFD; /* approximate lower bound */ int maxfd = PLUTO_QFD; /* approximate lower bound */
int ndes = 0; int ndes = 0;
struct worker_info *w; struct worker_info *w;
FD_ZERO(&readfds); FD_ZERO(&readfds);
if (!eof_from_pluto) if (!eof_from_pluto)
{
FD_SET(PLUTO_QFD, &readfds);
ndes++;
}
for (w = wi; w != wi_roof; w++)
{
if (w->busy)
{
FD_SET(w->afd, &readfds);
ndes++;
if (maxfd < w->afd)
maxfd = w->afd;
}
}
if (ndes == 0)
return HES_OK; /* done! */
do {
ndes = select(maxfd + 1, &readfds, NULL, NULL, NULL);
} while (ndes == -1 && errno == EINTR);
if (ndes == -1)
{
syslog(LOG_ERR, "select(2) error: %s", strerror(errno));
exit(HES_IO_ERROR_SELECT);
}
else if (ndes > 0)
{
if (FD_ISSET(PLUTO_QFD, &readfds))
{
query();
ndes--;
}
for (w = wi; ndes > 0 && w != wi_roof; w++)
{
if (w->busy && FD_ISSET(w->afd, &readfds))
{ {
answer(w); FD_SET(PLUTO_QFD, &readfds);
ndes--; ndes++;
}
for (w = wi; w != wi_roof; w++)
{
if (w->busy)
{
FD_SET(w->afd, &readfds);
ndes++;
if (maxfd < w->afd)
maxfd = w->afd;
}
}
if (ndes == 0)
return HES_OK; /* done! */
do {
ndes = select(maxfd + 1, &readfds, NULL, NULL, NULL);
} while (ndes == -1 && errno == EINTR);
if (ndes == -1)
{
syslog(LOG_ERR, "select(2) error: %s", strerror(errno));
exit(HES_IO_ERROR_SELECT);
}
else if (ndes > 0)
{
if (FD_ISSET(PLUTO_QFD, &readfds))
{
query();
ndes--;
}
for (w = wi; ndes > 0 && w != wi_roof; w++)
{
if (w->busy && FD_ISSET(w->afd, &readfds))
{
answer(w);
ndes--;
}
}
} }
}
} }
}
} }
/* Not to be invoked by strangers -- user hostile. /* Not to be invoked by strangers -- user hostile.
@@ -574,42 +574,42 @@ master(void)
static void static void
adns_usage(const char *fmt, const char *arg) adns_usage(const char *fmt, const char *arg)
{ {
const char **sp = ipsec_copyright_notice(); const char **sp = ipsec_copyright_notice();
fprintf(stderr, "INTERNAL TO PLUTO: DO NOT EXECUTE\n"); fprintf(stderr, "INTERNAL TO PLUTO: DO NOT EXECUTE\n");
fprintf(stderr, fmt, arg); fprintf(stderr, fmt, arg);
fprintf(stderr, "\n%s\n", ipsec_version_string()); fprintf(stderr, "\n%s\n", ipsec_version_string());
for (; *sp != NULL; sp++) for (; *sp != NULL; sp++)
fprintf(stderr, "%s\n", *sp); fprintf(stderr, "%s\n", *sp);
syslog(LOG_ERR, fmt, arg); syslog(LOG_ERR, fmt, arg);
exit(HES_INVOCATION); exit(HES_INVOCATION);
} }
int int
main(int argc UNUSED, char **argv) main(int argc UNUSED, char **argv)
{ {
int i = 1; int i = 1;
name = argv[0]; name = argv[0];
while (i < argc) while (i < argc)
{
if (streq(argv[i], "-d"))
{ {
i++; if (streq(argv[i], "-d"))
debug = TRUE; {
i++;
debug = TRUE;
}
else
{
adns_usage("unexpected argument \"%s\"", argv[i]);
/*NOTREACHED*/
}
} }
else
{
adns_usage("unexpected argument \"%s\"", argv[i]);
/*NOTREACHED*/
}
}
return master(); return master();
} }
#endif /* !USE_LWRES */ #endif /* !USE_LWRES */
+27 -27
View File
@@ -14,7 +14,7 @@
* RCSID $Id$ * RCSID $Id$
*/ */
#ifndef USE_LWRES /* whole file! */ #ifndef USE_LWRES /* whole file! */
/* The interface in RHL6.x and BIND distribution 8.2.2 are different, /* The interface in RHL6.x and BIND distribution 8.2.2 are different,
* so we build some of our own :-( * so we build some of our own :-(
@@ -38,38 +38,38 @@
*/ */
struct adns_query { struct adns_query {
size_t len; size_t len;
unsigned int qmagic; unsigned int qmagic;
unsigned long serial; unsigned long serial;
lset_t debugging; /* only used #ifdef DEBUG, but don't want layout to change */ lset_t debugging; /* only used #ifdef DEBUG, but don't want layout to change */
u_char name_buf[NS_MAXDNAME + 2]; u_char name_buf[NS_MAXDNAME + 2];
int type; /* T_KEY or T_TXT */ int type; /* T_KEY or T_TXT */
}; };
struct adns_answer { struct adns_answer {
size_t len; size_t len;
unsigned int amagic; unsigned int amagic;
unsigned long serial; unsigned long serial;
struct adns_continuation *continuation; struct adns_continuation *continuation;
int result; int result;
int h_errno_val; int h_errno_val;
u_char ans[NS_PACKETSZ * 10]; /* very probably bigger than necessary */ u_char ans[NS_PACKETSZ * 10]; /* very probably bigger than necessary */
}; };
enum helper_exit_status { enum helper_exit_status {
HES_CONTINUE = -1, /* not an exit */ HES_CONTINUE = -1, /* not an exit */
HES_OK = 0, /* all's well that ends well (perhaps EOF) */ HES_OK = 0, /* all's well that ends well (perhaps EOF) */
HES_INVOCATION, /* improper invocation */ HES_INVOCATION, /* improper invocation */
HES_IO_ERROR_SELECT, /* IO error in select() */ HES_IO_ERROR_SELECT, /* IO error in select() */
HES_MALLOC, /* malloc failed */ HES_MALLOC, /* malloc failed */
HES_IO_ERROR_IN, /* error reading pipe */ HES_IO_ERROR_IN, /* error reading pipe */
HES_IO_ERROR_OUT, /* error reading pipe */ HES_IO_ERROR_OUT, /* error reading pipe */
HES_PIPE, /* pipe(2) failed */ HES_PIPE, /* pipe(2) failed */
HES_SYNC, /* answer from worker doesn't match query */ HES_SYNC, /* answer from worker doesn't match query */
HES_FORK, /* fork(2) failed */ HES_FORK, /* fork(2) failed */
HES_RES_INIT, /* resolver initialization failed */ HES_RES_INIT, /* resolver initialization failed */
HES_BAD_LEN, /* implausible .len field */ HES_BAD_LEN, /* implausible .len field */
HES_BAD_MAGIC, /* .magic field wrong */ HES_BAD_MAGIC, /* .magic field wrong */
}; };
#endif /* !USE_LWRES */ #endif /* !USE_LWRES */
+832 -832
View File
File diff suppressed because it is too large Load Diff
+32 -32
View File
@@ -18,49 +18,49 @@
#define ALG_INFO_H #define ALG_INFO_H
struct esp_info { struct esp_info {
u_int8_t transid; /* ESP transform */ u_int8_t transid; /* ESP transform */
u_int16_t auth; /* AUTH */ u_int16_t auth; /* AUTH */
size_t enckeylen; /* keylength for ESP transform */ size_t enckeylen; /* keylength for ESP transform */
size_t authkeylen; /* keylength for AUTH */ size_t authkeylen; /* keylength for AUTH */
u_int8_t encryptalg; /* normally encryptalg=transid */ u_int8_t encryptalg; /* normally encryptalg=transid */
u_int8_t authalg; /* normally authalg=auth+1 */ u_int8_t authalg; /* normally authalg=auth+1 */
}; };
struct ike_info { struct ike_info {
u_int16_t ike_ealg; /* high 16 bit nums for reserved */ u_int16_t ike_ealg; /* high 16 bit nums for reserved */
u_int8_t ike_halg; u_int8_t ike_halg;
size_t ike_eklen; size_t ike_eklen;
size_t ike_hklen; size_t ike_hklen;
u_int16_t ike_modp; u_int16_t ike_modp;
}; };
#define ALG_INFO_COMMON \ #define ALG_INFO_COMMON \
int alg_info_cnt; \ int alg_info_cnt; \
int ref_cnt; \ int ref_cnt; \
unsigned alg_info_flags; \ unsigned alg_info_flags; \
unsigned alg_info_protoid unsigned alg_info_protoid
struct alg_info { struct alg_info {
ALG_INFO_COMMON; ALG_INFO_COMMON;
}; };
struct alg_info_esp { struct alg_info_esp {
ALG_INFO_COMMON; ALG_INFO_COMMON;
struct esp_info esp[64]; struct esp_info esp[64];
int esp_pfsgroup; int esp_pfsgroup;
}; };
struct alg_info_ike { struct alg_info_ike {
ALG_INFO_COMMON; ALG_INFO_COMMON;
struct ike_info ike[64]; struct ike_info ike[64];
}; };
#define esp_ealg_id transid #define esp_ealg_id transid
#define esp_aalg_id auth #define esp_aalg_id auth
#define esp_ealg_keylen enckeylen /* bits */ #define esp_ealg_keylen enckeylen /* bits */
#define esp_aalg_keylen authkeylen /* bits */ #define esp_aalg_keylen authkeylen /* bits */
/* alg_info_flags bits */ /* alg_info_flags bits */
#define ALG_INFO_F_STRICT 0x01 #define ALG_INFO_F_STRICT 0x01
extern int alg_info_esp_aa2sadb(int auth); extern int alg_info_esp_aa2sadb(int auth);
extern int alg_info_esp_sadb2aa(int sadb_aalg); extern int alg_info_esp_sadb2aa(int sadb_aalg);
@@ -68,18 +68,18 @@ extern void alg_info_free(struct alg_info *alg_info);
extern void alg_info_addref(struct alg_info *alg_info); extern void alg_info_addref(struct alg_info *alg_info);
extern void alg_info_delref(struct alg_info **alg_info); extern void alg_info_delref(struct alg_info **alg_info);
extern struct alg_info_esp* alg_info_esp_create_from_str(const char *alg_str extern struct alg_info_esp* alg_info_esp_create_from_str(const char *alg_str
, const char **err_p); , const char **err_p);
extern struct alg_info_ike* alg_info_ike_create_from_str(const char *alg_str extern struct alg_info_ike* alg_info_ike_create_from_str(const char *alg_str
, const char **err_p); , const char **err_p);
extern int alg_info_parse(const char *str); extern int alg_info_parse(const char *str);
extern int alg_info_snprint(char *buf, int buflen extern int alg_info_snprint(char *buf, int buflen
, struct alg_info *alg_info); , struct alg_info *alg_info);
extern int alg_info_snprint_esp(char *buf, int buflen extern int alg_info_snprint_esp(char *buf, int buflen
, struct alg_info_esp *alg_info); , struct alg_info_esp *alg_info);
extern int alg_info_snprint_ike(char *buf, int buflen extern int alg_info_snprint_ike(char *buf, int buflen
, struct alg_info_ike *alg_info); , struct alg_info_ike *alg_info);
#define ALG_INFO_ESP_FOREACH(ai, ai_esp, i) \ #define ALG_INFO_ESP_FOREACH(ai, ai_esp, i) \
for (i=(ai)->alg_info_cnt,ai_esp=(ai)->esp; i--; ai_esp++) for (i=(ai)->alg_info_cnt,ai_esp=(ai)->esp; i--; ai_esp++)
#define ALG_INFO_IKE_FOREACH(ai, ai_ike, i) \ #define ALG_INFO_IKE_FOREACH(ai, ai_ike, i) \
for (i=(ai)->alg_info_cnt,ai_ike=(ai)->ike; i--; ai_ike++) for (i=(ai)->alg_info_cnt,ai_ike=(ai)->ike; i--; ai_ike++)
#endif /* ALG_INFO_H */ #endif /* ALG_INFO_H */
+548 -548
View File
File diff suppressed because it is too large Load Diff
+62 -62
View File
@@ -25,82 +25,82 @@
/* Defines some primitive ASN1 types */ /* Defines some primitive ASN1 types */
typedef enum { typedef enum {
ASN1_EOC = 0x00, ASN1_EOC = 0x00,
ASN1_BOOLEAN = 0x01, ASN1_BOOLEAN = 0x01,
ASN1_INTEGER = 0x02, ASN1_INTEGER = 0x02,
ASN1_BIT_STRING = 0x03, ASN1_BIT_STRING = 0x03,
ASN1_OCTET_STRING = 0x04, ASN1_OCTET_STRING = 0x04,
ASN1_NULL = 0x05, ASN1_NULL = 0x05,
ASN1_OID = 0x06, ASN1_OID = 0x06,
ASN1_ENUMERATED = 0x0A, ASN1_ENUMERATED = 0x0A,
ASN1_UTF8STRING = 0x0C, ASN1_UTF8STRING = 0x0C,
ASN1_NUMERICSTRING = 0x12, ASN1_NUMERICSTRING = 0x12,
ASN1_PRINTABLESTRING = 0x13, ASN1_PRINTABLESTRING = 0x13,
ASN1_T61STRING = 0x14, ASN1_T61STRING = 0x14,
ASN1_VIDEOTEXSTRING = 0x15, ASN1_VIDEOTEXSTRING = 0x15,
ASN1_IA5STRING = 0x16, ASN1_IA5STRING = 0x16,
ASN1_UTCTIME = 0x17, ASN1_UTCTIME = 0x17,
ASN1_GENERALIZEDTIME = 0x18, ASN1_GENERALIZEDTIME = 0x18,
ASN1_GRAPHICSTRING = 0x19, ASN1_GRAPHICSTRING = 0x19,
ASN1_VISIBLESTRING = 0x1A, ASN1_VISIBLESTRING = 0x1A,
ASN1_GENERALSTRING = 0x1B, ASN1_GENERALSTRING = 0x1B,
ASN1_UNIVERSALSTRING = 0x1C, ASN1_UNIVERSALSTRING = 0x1C,
ASN1_BMPSTRING = 0x1E, ASN1_BMPSTRING = 0x1E,
ASN1_CONSTRUCTED = 0x20, ASN1_CONSTRUCTED = 0x20,
ASN1_SEQUENCE = 0x30, ASN1_SEQUENCE = 0x30,
ASN1_SET = 0x31, ASN1_SET = 0x31,
ASN1_CONTEXT_S_0 = 0x80, ASN1_CONTEXT_S_0 = 0x80,
ASN1_CONTEXT_S_1 = 0x81, ASN1_CONTEXT_S_1 = 0x81,
ASN1_CONTEXT_S_2 = 0x82, ASN1_CONTEXT_S_2 = 0x82,
ASN1_CONTEXT_S_3 = 0x83, ASN1_CONTEXT_S_3 = 0x83,
ASN1_CONTEXT_S_4 = 0x84, ASN1_CONTEXT_S_4 = 0x84,
ASN1_CONTEXT_S_5 = 0x85, ASN1_CONTEXT_S_5 = 0x85,
ASN1_CONTEXT_S_6 = 0x86, ASN1_CONTEXT_S_6 = 0x86,
ASN1_CONTEXT_S_7 = 0x87, ASN1_CONTEXT_S_7 = 0x87,
ASN1_CONTEXT_S_8 = 0x88, ASN1_CONTEXT_S_8 = 0x88,
ASN1_CONTEXT_C_0 = 0xA0, ASN1_CONTEXT_C_0 = 0xA0,
ASN1_CONTEXT_C_1 = 0xA1, ASN1_CONTEXT_C_1 = 0xA1,
ASN1_CONTEXT_C_2 = 0xA2, ASN1_CONTEXT_C_2 = 0xA2,
ASN1_CONTEXT_C_3 = 0xA3, ASN1_CONTEXT_C_3 = 0xA3,
ASN1_CONTEXT_C_4 = 0xA4, ASN1_CONTEXT_C_4 = 0xA4,
ASN1_CONTEXT_C_5 = 0xA5 ASN1_CONTEXT_C_5 = 0xA5
} asn1_t; } asn1_t;
/* Definition of ASN1 flags */ /* Definition of ASN1 flags */
#define ASN1_NONE 0x00 #define ASN1_NONE 0x00
#define ASN1_DEF 0x01 #define ASN1_DEF 0x01
#define ASN1_OPT 0x02 #define ASN1_OPT 0x02
#define ASN1_LOOP 0x04 #define ASN1_LOOP 0x04
#define ASN1_END 0x08 #define ASN1_END 0x08
#define ASN1_OBJ 0x10 #define ASN1_OBJ 0x10
#define ASN1_BODY 0x20 #define ASN1_BODY 0x20
#define ASN1_RAW 0x40 #define ASN1_RAW 0x40
#define ASN1_INVALID_LENGTH 0xffffffff #define ASN1_INVALID_LENGTH 0xffffffff
/* definition of an ASN.1 object */ /* definition of an ASN.1 object */
typedef struct { typedef struct {
u_int level; u_int level;
const u_char *name; const u_char *name;
asn1_t type; asn1_t type;
u_char flags; u_char flags;
} asn1Object_t; } asn1Object_t;
#define ASN1_MAX_LEVEL 10 #define ASN1_MAX_LEVEL 10
typedef struct { typedef struct {
bool implicit; bool implicit;
u_int cond; u_int cond;
u_int level0; u_int level0;
u_int loopAddr[ASN1_MAX_LEVEL+1]; u_int loopAddr[ASN1_MAX_LEVEL+1];
chunk_t blobs[ASN1_MAX_LEVEL+2]; chunk_t blobs[ASN1_MAX_LEVEL+2];
} asn1_ctx_t; } asn1_ctx_t;
/* some common prefabricated ASN.1 constants */ /* some common prefabricated ASN.1 constants */
@@ -129,13 +129,13 @@ extern bool is_printablestring(chunk_t str);
extern time_t asn1totime(const chunk_t *utctime, asn1_t type); extern time_t asn1totime(const chunk_t *utctime, asn1_t type);
extern chunk_t timetoasn1(const time_t *time, asn1_t type); extern chunk_t timetoasn1(const time_t *time, asn1_t type);
extern void asn1_init(asn1_ctx_t *ctx, chunk_t blob extern void asn1_init(asn1_ctx_t *ctx, chunk_t blob
, u_int level0, bool implicit, u_int cond); , u_int level0, bool implicit, u_int cond);
extern bool extract_object(asn1Object_t const *objects extern bool extract_object(asn1Object_t const *objects
, u_int *objectID, chunk_t *object, u_int *level, asn1_ctx_t *ctx); , u_int *objectID, chunk_t *object, u_int *level, asn1_ctx_t *ctx);
extern bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level extern bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level
, const char* name); , const char* name);
extern int parse_algorithmIdentifier(chunk_t blob, int level0 extern int parse_algorithmIdentifier(chunk_t blob, int level0
, chunk_t *parameters); , chunk_t *parameters);
extern bool is_asn1(chunk_t blob); extern bool is_asn1(chunk_t blob);
#endif /* _ASN1_H */ #endif /* _ASN1_H */
+452 -452
View File
File diff suppressed because it is too large Load Diff
+20 -20
View File
@@ -20,45 +20,45 @@
#include "x509.h" #include "x509.h"
#include "whack.h" #include "whack.h"
#define MAX_CA_PATH_LEN 7 #define MAX_CA_PATH_LEN 7
/* authority flags */ /* authority flags */
#define AUTH_NONE 0x00 /* no authorities */ #define AUTH_NONE 0x00 /* no authorities */
#define AUTH_CA 0x01 /* certification authority */ #define AUTH_CA 0x01 /* certification authority */
#define AUTH_AA 0x02 /* authorization authority */ #define AUTH_AA 0x02 /* authorization authority */
#define AUTH_OCSP 0x04 /* ocsp signing authority */ #define AUTH_OCSP 0x04 /* ocsp signing authority */
/* CA info structures */ /* CA info structures */
typedef struct ca_info ca_info_t; typedef struct ca_info ca_info_t;
struct ca_info { struct ca_info {
ca_info_t *next; ca_info_t *next;
char *name; char *name;
time_t installed; time_t installed;
chunk_t authName; chunk_t authName;
chunk_t authKeyID; chunk_t authKeyID;
chunk_t authKeySerialNumber; chunk_t authKeySerialNumber;
char *ldaphost; char *ldaphost;
char *ldapbase; char *ldapbase;
char *ocspuri; char *ocspuri;
generalName_t *crluri; generalName_t *crluri;
bool strictcrlpolicy; bool strictcrlpolicy;
}; };
extern bool trusted_ca(chunk_t a, chunk_t b, int *pathlen); extern bool trusted_ca(chunk_t a, chunk_t b, int *pathlen);
extern bool match_requested_ca(generalName_t *requested_ca extern bool match_requested_ca(generalName_t *requested_ca
, chunk_t our_ca, int *our_pathlen); , chunk_t our_ca, int *our_pathlen);
extern x509cert_t* get_authcert(chunk_t subject, chunk_t serial, chunk_t keyid extern x509cert_t* get_authcert(chunk_t subject, chunk_t serial, chunk_t keyid
, u_char auth_flags); , u_char auth_flags);
extern void load_authcerts(const char *type, const char *path extern void load_authcerts(const char *type, const char *path
, u_char auth_flags); , u_char auth_flags);
extern x509cert_t* add_authcert(x509cert_t *cert, u_char auth_flags); extern x509cert_t* add_authcert(x509cert_t *cert, u_char auth_flags);
extern void free_authcerts(void); extern void free_authcerts(void);
extern void list_authcerts(const char *caption, u_char auth_flags, bool utc); extern void list_authcerts(const char *caption, u_char auth_flags, bool utc);
extern bool trust_authcert_candidate(const x509cert_t *cert extern bool trust_authcert_candidate(const x509cert_t *cert
, const x509cert_t *alt_chain); , const x509cert_t *alt_chain);
extern ca_info_t* get_ca_info(chunk_t name, chunk_t serial, chunk_t keyid); extern ca_info_t* get_ca_info(chunk_t name, chunk_t serial, chunk_t keyid);
extern bool find_ca_info_by_name(const char *name, bool delete); extern bool find_ca_info_by_name(const char *name, bool delete);
extern void add_ca_info(const whack_message_t *msg); extern void add_ca_info(const whack_message_t *msg);
+148 -148
View File
@@ -43,15 +43,15 @@ const cert_t empty_cert = {CERT_NONE, {NULL}};
chunk_t chunk_t
get_mycert(cert_t cert) get_mycert(cert_t cert)
{ {
switch (cert.type) switch (cert.type)
{ {
case CERT_PGP: case CERT_PGP:
return cert.u.pgp->certificate; return cert.u.pgp->certificate;
case CERT_X509_SIGNATURE: case CERT_X509_SIGNATURE:
return cert.u.x509->certificate; return cert.u.x509->certificate;
default: default:
return chunk_empty; return chunk_empty;
} }
} }
/* load a coded key or certificate file with autodetection /* load a coded key or certificate file with autodetection
@@ -61,64 +61,64 @@ bool
load_coded_file(const char *filename, prompt_pass_t *pass, const char *type load_coded_file(const char *filename, prompt_pass_t *pass, const char *type
, chunk_t *blob, bool *pgp) , chunk_t *blob, bool *pgp)
{ {
err_t ugh = NULL; err_t ugh = NULL;
FILE *fd = fopen(filename, "r"); FILE *fd = fopen(filename, "r");
if (fd) if (fd)
{
int bytes;
fseek(fd, 0, SEEK_END );
blob->len = ftell(fd);
rewind(fd);
blob->ptr = malloc(blob->len);
bytes = fread(blob->ptr, 1, blob->len, fd);
fclose(fd);
plog(" loaded %s file '%s' (%d bytes)", type, filename, bytes);
*pgp = FALSE;
/* try DER format */
if (is_asn1(*blob))
{ {
DBG(DBG_PARSING, int bytes;
DBG_log(" file coded in DER format"); fseek(fd, 0, SEEK_END );
) blob->len = ftell(fd);
return TRUE; rewind(fd);
blob->ptr = malloc(blob->len);
bytes = fread(blob->ptr, 1, blob->len, fd);
fclose(fd);
plog(" loaded %s file '%s' (%d bytes)", type, filename, bytes);
*pgp = FALSE;
/* try DER format */
if (is_asn1(*blob))
{
DBG(DBG_PARSING,
DBG_log(" file coded in DER format");
)
return TRUE;
}
/* try PEM format */
ugh = pemtobin(blob, pass, filename, pgp);
if (ugh == NULL)
{
if (*pgp)
{
DBG(DBG_PARSING,
DBG_log(" file coded in armored PGP format");
)
return TRUE;
}
if (is_asn1(*blob))
{
DBG(DBG_PARSING,
DBG_log(" file coded in PEM format");
)
return TRUE;
}
ugh = "file coded in unknown format, discarded";
}
/* a conversion error has occured */
plog(" %s", ugh);
free(blob->ptr);
*blob = chunk_empty;
} }
else
/* try PEM format */
ugh = pemtobin(blob, pass, filename, pgp);
if (ugh == NULL)
{ {
if (*pgp) plog(" could not open %s file '%s'", type, filename);
{
DBG(DBG_PARSING,
DBG_log(" file coded in armored PGP format");
)
return TRUE;
}
if (is_asn1(*blob))
{
DBG(DBG_PARSING,
DBG_log(" file coded in PEM format");
)
return TRUE;
}
ugh = "file coded in unknown format, discarded";
} }
return FALSE;
/* a conversion error has occured */
plog(" %s", ugh);
free(blob->ptr);
*blob = chunk_empty;
}
else
{
plog(" could not open %s file '%s'", type, filename);
}
return FALSE;
} }
/* /*
@@ -128,30 +128,30 @@ err_t
load_rsa_private_key(const char* filename, prompt_pass_t *pass load_rsa_private_key(const char* filename, prompt_pass_t *pass
, RSA_private_key_t *key) , RSA_private_key_t *key)
{ {
err_t ugh = NULL; err_t ugh = NULL;
bool pgp = FALSE; bool pgp = FALSE;
chunk_t blob = chunk_empty; chunk_t blob = chunk_empty;
const char *path = concatenate_paths(PRIVATE_KEY_PATH, filename); const char *path = concatenate_paths(PRIVATE_KEY_PATH, filename);
if (load_coded_file(path, pass, "private key", &blob, &pgp)) if (load_coded_file(path, pass, "private key", &blob, &pgp))
{
if (pgp)
{ {
if (!parse_pgp(blob, NULL, key)) if (pgp)
ugh = "syntax error in PGP private key file"; {
if (!parse_pgp(blob, NULL, key))
ugh = "syntax error in PGP private key file";
}
else
{
if (!pkcs1_parse_private_key(blob, key))
ugh = "syntax error in PKCS#1 private key file";
}
free(blob.ptr);
} }
else else
{ ugh = "error loading RSA private key file";
if (!pkcs1_parse_private_key(blob, key))
ugh = "syntax error in PKCS#1 private key file";
}
free(blob.ptr);
}
else
ugh = "error loading RSA private key file";
return ugh; return ugh;
} }
/* /*
* Loads a X.509 or OpenPGP certificate * Loads a X.509 or OpenPGP certificate
@@ -159,51 +159,51 @@ load_rsa_private_key(const char* filename, prompt_pass_t *pass
bool bool
load_cert(const char *filename, const char *label, cert_t *cert) load_cert(const char *filename, const char *label, cert_t *cert)
{ {
bool pgp = FALSE; bool pgp = FALSE;
chunk_t blob = chunk_empty; chunk_t blob = chunk_empty;
/* initialize cert struct */ /* initialize cert struct */
cert->type = CERT_NONE; cert->type = CERT_NONE;
cert->u.x509 = NULL; cert->u.x509 = NULL;
if (load_coded_file(filename, NULL, label, &blob, &pgp)) if (load_coded_file(filename, NULL, label, &blob, &pgp))
{
if (pgp)
{ {
pgpcert_t *pgpcert = malloc_thing(pgpcert_t); if (pgp)
*pgpcert = empty_pgpcert; {
if (parse_pgp(blob, pgpcert, NULL)) pgpcert_t *pgpcert = malloc_thing(pgpcert_t);
{ *pgpcert = empty_pgpcert;
cert->type = CERT_PGP; if (parse_pgp(blob, pgpcert, NULL))
cert->u.pgp = pgpcert; {
return TRUE; cert->type = CERT_PGP;
} cert->u.pgp = pgpcert;
else return TRUE;
{ }
plog(" error in OpenPGP certificate"); else
free_pgpcert(pgpcert); {
return FALSE; plog(" error in OpenPGP certificate");
} free_pgpcert(pgpcert);
return FALSE;
}
}
else
{
x509cert_t *x509cert = malloc_thing(x509cert_t);
*x509cert = empty_x509cert;
if (parse_x509cert(blob, 0, x509cert))
{
cert->type = CERT_X509_SIGNATURE;
cert->u.x509 = x509cert;
return TRUE;
}
else
{
plog(" error in X.509 certificate");
free_x509cert(x509cert);
return FALSE;
}
}
} }
else return FALSE;
{
x509cert_t *x509cert = malloc_thing(x509cert_t);
*x509cert = empty_x509cert;
if (parse_x509cert(blob, 0, x509cert))
{
cert->type = CERT_X509_SIGNATURE;
cert->u.x509 = x509cert;
return TRUE;
}
else
{
plog(" error in X.509 certificate");
free_x509cert(x509cert);
return FALSE;
}
}
}
return FALSE;
} }
/* /*
@@ -212,9 +212,9 @@ load_cert(const char *filename, const char *label, cert_t *cert)
bool bool
load_host_cert(const char *filename, cert_t *cert) load_host_cert(const char *filename, cert_t *cert)
{ {
const char *path = concatenate_paths(HOST_CERT_PATH, filename); const char *path = concatenate_paths(HOST_CERT_PATH, filename);
return load_cert(path, "host cert", cert); return load_cert(path, "host cert", cert);
} }
/* /*
@@ -223,9 +223,9 @@ load_host_cert(const char *filename, cert_t *cert)
bool bool
load_ca_cert(const char *filename, cert_t *cert) load_ca_cert(const char *filename, cert_t *cert)
{ {
const char *path = concatenate_paths(CA_CERT_PATH, filename); const char *path = concatenate_paths(CA_CERT_PATH, filename);
return load_cert(path, "CA cert", cert); return load_cert(path, "CA cert", cert);
} }
/* /*
@@ -234,7 +234,7 @@ load_ca_cert(const char *filename, cert_t *cert)
bool bool
same_cert(const cert_t *a, const cert_t *b) same_cert(const cert_t *a, const cert_t *b)
{ {
return a->type == b->type && a->u.x509 == b->u.x509; return a->type == b->type && a->u.x509 == b->u.x509;
} }
/* for each link pointing to the certif icate /* for each link pointing to the certif icate
@@ -243,17 +243,17 @@ same_cert(const cert_t *a, const cert_t *b)
void void
share_cert(cert_t cert) share_cert(cert_t cert)
{ {
switch (cert.type) switch (cert.type)
{ {
case CERT_PGP: case CERT_PGP:
share_pgpcert(cert.u.pgp); share_pgpcert(cert.u.pgp);
break; break;
case CERT_X509_SIGNATURE: case CERT_X509_SIGNATURE:
share_x509cert(cert.u.x509); share_x509cert(cert.u.x509);
break; break;
default: default:
break; break;
} }
} }
/* release of a certificate decreases the count by one /* release of a certificate decreases the count by one
@@ -263,16 +263,16 @@ void
release_cert(cert_t cert) release_cert(cert_t cert)
{ {
switch (cert.type) switch (cert.type)
{ {
case CERT_PGP: case CERT_PGP:
release_pgpcert(cert.u.pgp); release_pgpcert(cert.u.pgp);
break; break;
case CERT_X509_SIGNATURE: case CERT_X509_SIGNATURE:
release_x509cert(cert.u.x509); release_x509cert(cert.u.x509);
break; break;
default: default:
break; break;
} }
} }
/* /*
@@ -281,7 +281,7 @@ release_cert(cert_t cert)
void void
list_certs(bool utc) list_certs(bool utc)
{ {
list_x509_end_certs(utc); list_x509_end_certs(utc);
list_pgp_end_certs(utc); list_pgp_end_certs(utc);
} }
+19 -19
View File
@@ -26,31 +26,31 @@
*/ */
#define PRIVATE_KEY_PATH IPSEC_CONFDIR "/ipsec.d/private" #define PRIVATE_KEY_PATH IPSEC_CONFDIR "/ipsec.d/private"
#define HOST_CERT_PATH IPSEC_CONFDIR "/ipsec.d/certs" #define HOST_CERT_PATH IPSEC_CONFDIR "/ipsec.d/certs"
#define CA_CERT_PATH IPSEC_CONFDIR "/ipsec.d/cacerts" #define CA_CERT_PATH IPSEC_CONFDIR "/ipsec.d/cacerts"
#define A_CERT_PATH IPSEC_CONFDIR "/ipsec.d/acerts" #define A_CERT_PATH IPSEC_CONFDIR "/ipsec.d/acerts"
#define AA_CERT_PATH IPSEC_CONFDIR "/ipsec.d/aacerts" #define AA_CERT_PATH IPSEC_CONFDIR "/ipsec.d/aacerts"
#define OCSP_CERT_PATH IPSEC_CONFDIR "/ipsec.d/ocspcerts" #define OCSP_CERT_PATH IPSEC_CONFDIR "/ipsec.d/ocspcerts"
#define CRL_PATH IPSEC_CONFDIR "/ipsec.d/crls" #define CRL_PATH IPSEC_CONFDIR "/ipsec.d/crls"
#define REQ_PATH IPSEC_CONFDIR "/ipsec.d/reqs" #define REQ_PATH IPSEC_CONFDIR "/ipsec.d/reqs"
/* advance warning of imminent expiry of /* advance warning of imminent expiry of
* cacerts, public keys, and crls * cacerts, public keys, and crls
*/ */
#define CA_CERT_WARNING_INTERVAL 30 /* days */ #define CA_CERT_WARNING_INTERVAL 30 /* days */
#define OCSP_CERT_WARNING_INTERVAL 30 /* days */ #define OCSP_CERT_WARNING_INTERVAL 30 /* days */
#define PUBKEY_WARNING_INTERVAL 7 /* days */ #define PUBKEY_WARNING_INTERVAL 7 /* days */
#define CRL_WARNING_INTERVAL 7 /* days */ #define CRL_WARNING_INTERVAL 7 /* days */
#define ACERT_WARNING_INTERVAL 1 /* day */ #define ACERT_WARNING_INTERVAL 1 /* day */
/* certificate access structure /* certificate access structure
* currently X.509 and OpenPGP certificates are supported * currently X.509 and OpenPGP certificates are supported
*/ */
typedef struct { typedef struct {
u_char type; u_char type;
union { union {
x509cert_t *x509; x509cert_t *x509;
pgpcert_t *pgp; pgpcert_t *pgp;
} u; } u;
} cert_t; } cert_t;
/* used for initialization */ /* used for initialization */
@@ -62,12 +62,12 @@ extern const cert_t empty_cert;
extern bool no_cr_send; extern bool no_cr_send;
extern err_t load_rsa_private_key(const char* filename, prompt_pass_t *pass extern err_t load_rsa_private_key(const char* filename, prompt_pass_t *pass
, RSA_private_key_t *key); , RSA_private_key_t *key);
extern chunk_t get_mycert(cert_t cert); extern chunk_t get_mycert(cert_t cert);
extern bool load_coded_file(const char *filename, prompt_pass_t *pass extern bool load_coded_file(const char *filename, prompt_pass_t *pass
, const char *type, chunk_t *blob, bool *pgp); , const char *type, chunk_t *blob, bool *pgp);
extern bool load_cert(const char *filename, const char *label extern bool load_cert(const char *filename, const char *label
, cert_t *cert); , cert_t *cert);
extern bool load_host_cert(const char *filename, cert_t *cert); extern bool load_host_cert(const char *filename, cert_t *cert);
extern bool load_ca_cert(const char *filename, cert_t *cert); extern bool load_ca_cert(const char *filename, cert_t *cert);
extern bool same_cert(const cert_t *a, const cert_t *b); extern bool same_cert(const cert_t *a, const cert_t *b);
+3280 -3280
View File
File diff suppressed because it is too large Load Diff
+133 -133
View File
@@ -118,135 +118,135 @@
* - display format: n,m * - display format: n,m
*/ */
typedef unsigned long policy_prio_t; typedef unsigned long policy_prio_t;
#define BOTTOM_PRIO ((policy_prio_t)0) /* smaller than any real prio */ #define BOTTOM_PRIO ((policy_prio_t)0) /* smaller than any real prio */
#define set_policy_prio(c) { (c)->prio = \ #define set_policy_prio(c) { (c)->prio = \
((policy_prio_t)(c)->spd.this.client.maskbits << 16) \ ((policy_prio_t)(c)->spd.this.client.maskbits << 16) \
| ((policy_prio_t)(c)->spd.that.client.maskbits << 8) \ | ((policy_prio_t)(c)->spd.that.client.maskbits << 8) \
| (policy_prio_t)1; } | (policy_prio_t)1; }
#define POLICY_PRIO_BUF (3+1+3+1) #define POLICY_PRIO_BUF (3+1+3+1)
extern void fmt_policy_prio(policy_prio_t pp, char buf[POLICY_PRIO_BUF]); extern void fmt_policy_prio(policy_prio_t pp, char buf[POLICY_PRIO_BUF]);
struct virtual_t; struct virtual_t;
struct end { struct end {
struct id id; struct id id;
ip_address ip_address
host_addr, host_addr,
host_nexthop, host_nexthop,
host_srcip; host_srcip;
ip_subnet client; ip_subnet client;
bool key_from_DNS_on_demand; bool key_from_DNS_on_demand;
bool has_client; bool has_client;
bool has_client_wildcard; bool has_client_wildcard;
bool has_port_wildcard; bool has_port_wildcard;
bool has_id_wildcards; bool has_id_wildcards;
bool has_natip; bool has_natip;
char *updown; char *updown;
u_int16_t host_port; /* host order */ u_int16_t host_port; /* host order */
u_int16_t port; /* host order */ u_int16_t port; /* host order */
u_int8_t protocol; u_int8_t protocol;
cert_t cert; /* end certificate */ cert_t cert; /* end certificate */
chunk_t ca; /* CA distinguished name */ chunk_t ca; /* CA distinguished name */
struct ietfAttrList *groups;/* access control groups */ struct ietfAttrList *groups;/* access control groups */
smartcard_t *sc; /* smartcard reader and key info */ smartcard_t *sc; /* smartcard reader and key info */
struct virtual_t *virt; struct virtual_t *virt;
bool modecfg; /* this end: request local address from server */ bool modecfg; /* this end: request local address from server */
/* that end: give local addresses to clients */ /* that end: give local addresses to clients */
bool hostaccess; /* allow access to host via iptables INPUT/OUTPUT */ bool hostaccess; /* allow access to host via iptables INPUT/OUTPUT */
/* rules if client behind host is a subnet */ /* rules if client behind host is a subnet */
bool allow_any; /* IP address is subject to change */ bool allow_any; /* IP address is subject to change */
certpolicy_t sendcert; /* whether or not to send the certificate */ certpolicy_t sendcert; /* whether or not to send the certificate */
}; };
struct spd_route { struct spd_route {
struct spd_route *next; struct spd_route *next;
struct end this; struct end this;
struct end that; struct end that;
so_serial_t eroute_owner; so_serial_t eroute_owner;
enum routing_t routing; /* level of routing in place */ enum routing_t routing; /* level of routing in place */
uint32_t reqid; uint32_t reqid;
}; };
struct connection { struct connection {
char *name; char *name;
bool ikev1; bool ikev1;
lset_t policy; lset_t policy;
time_t sa_ike_life_seconds; time_t sa_ike_life_seconds;
time_t sa_ipsec_life_seconds; time_t sa_ipsec_life_seconds;
time_t sa_rekey_margin; time_t sa_rekey_margin;
unsigned long sa_rekey_fuzz; unsigned long sa_rekey_fuzz;
unsigned long sa_keying_tries; unsigned long sa_keying_tries;
/* RFC 3706 DPD */ /* RFC 3706 DPD */
time_t dpd_delay; time_t dpd_delay;
time_t dpd_timeout; time_t dpd_timeout;
dpd_action_t dpd_action; dpd_action_t dpd_action;
char *log_file_name; /* name of log file */ char *log_file_name; /* name of log file */
FILE *log_file; /* possibly open FILE */ FILE *log_file; /* possibly open FILE */
TAILQ_ENTRY(connection) log_link; /* linked list of open conns */ TAILQ_ENTRY(connection) log_link; /* linked list of open conns */
bool log_file_err; /* only bitch once */ bool log_file_err; /* only bitch once */
struct spd_route spd; struct spd_route spd;
/* internal fields: */ /* internal fields: */
unsigned long instance_serial; unsigned long instance_serial;
policy_prio_t prio; policy_prio_t prio;
bool instance_initiation_ok; /* this is an instance of a policy that mandates initiate */ bool instance_initiation_ok; /* this is an instance of a policy that mandates initiate */
enum connection_kind kind; enum connection_kind kind;
const struct iface *interface; /* filled in iff oriented */ const struct iface *interface; /* filled in iff oriented */
so_serial_t /* state object serial number */ so_serial_t /* state object serial number */
newest_isakmp_sa, newest_isakmp_sa,
newest_ipsec_sa; newest_ipsec_sa;
#ifdef DEBUG #ifdef DEBUG
lset_t extra_debugging; lset_t extra_debugging;
#endif #endif
/* note: if the client is the gateway, the following must be equal */ /* note: if the client is the gateway, the following must be equal */
sa_family_t addr_family; /* between gateways */ sa_family_t addr_family; /* between gateways */
sa_family_t tunnel_addr_family; /* between clients */ sa_family_t tunnel_addr_family; /* between clients */
struct connection *policy_next; /* if multiple policies, struct connection *policy_next; /* if multiple policies,
next one to apply */ next one to apply */
struct gw_info *gw_info; struct gw_info *gw_info;
struct alg_info_esp *alg_info_esp; struct alg_info_esp *alg_info_esp;
struct alg_info_ike *alg_info_ike; struct alg_info_ike *alg_info_ike;
struct host_pair *host_pair; struct host_pair *host_pair;
struct connection *hp_next; /* host pair list link */ struct connection *hp_next; /* host pair list link */
struct connection *ac_next; /* all connections list link */ struct connection *ac_next; /* all connections list link */
generalName_t *requested_ca; /* collected certificate requests */ generalName_t *requested_ca; /* collected certificate requests */
bool got_certrequest; bool got_certrequest;
}; };
#define oriented(c) ((c).interface != NULL) #define oriented(c) ((c).interface != NULL)
extern bool orient(struct connection *c); extern bool orient(struct connection *c);
extern bool same_peer_ids(const struct connection *c extern bool same_peer_ids(const struct connection *c
, const struct connection *d, const struct id *his_id); , const struct connection *d, const struct id *his_id);
/* Format the topology of a connection end, leaving out defaults. /* Format the topology of a connection end, leaving out defaults.
* Largest left end looks like: client === host : port [ host_id ] --- hop * Largest left end looks like: client === host : port [ host_id ] --- hop
* Note: if that==NULL, skip nexthop * Note: if that==NULL, skip nexthop
*/ */
#define END_BUF (SUBNETTOT_BUF + ADDRTOT_BUF + IDTOA_BUF + ADDRTOT_BUF + 10) #define END_BUF (SUBNETTOT_BUF + ADDRTOT_BUF + IDTOA_BUF + ADDRTOT_BUF + 10)
extern size_t format_end(char *buf, size_t buf_len extern size_t format_end(char *buf, size_t buf_len
, const struct end *this, const struct end *that , const struct end *this, const struct end *that
, bool is_left, lset_t policy); , bool is_left, lset_t policy);
extern void add_connection(const whack_message_t *wm); extern void add_connection(const whack_message_t *wm);
extern void initiate_connection(const char *name, int whackfd); extern void initiate_connection(const char *name, int whackfd);
extern void initiate_opportunistic(const ip_address *our_client extern void initiate_opportunistic(const ip_address *our_client
, const ip_address *peer_client, int transport_proto, bool held, int whackfd); , const ip_address *peer_client, int transport_proto, bool held, int whackfd);
extern void terminate_connection(const char *nm); extern void terminate_connection(const char *nm);
extern void release_connection(struct connection *c, bool relations); extern void release_connection(struct connection *c, bool relations);
extern void delete_connection(struct connection *c, bool relations); extern void delete_connection(struct connection *c, bool relations);
@@ -257,87 +257,87 @@ extern void remove_group_instance(const struct connection *group, const char *na
extern void release_dead_interfaces(void); extern void release_dead_interfaces(void);
extern void check_orientations(void); extern void check_orientations(void);
extern struct connection *route_owner(struct connection *c extern struct connection *route_owner(struct connection *c
, struct spd_route **srp , struct spd_route **srp
, struct connection **erop , struct connection **erop
, struct spd_route **esrp); , struct spd_route **esrp);
extern struct connection *shunt_owner(const ip_subnet *ours extern struct connection *shunt_owner(const ip_subnet *ours
, const ip_subnet *his); , const ip_subnet *his);
extern bool uniqueIDs; /* --uniqueids? */ extern bool uniqueIDs; /* --uniqueids? */
extern void ISAKMP_SA_established(struct connection *c, so_serial_t serial); extern void ISAKMP_SA_established(struct connection *c, so_serial_t serial);
#define his_id_was_instantiated(c) ((c)->kind == CK_INSTANCE \ #define his_id_was_instantiated(c) ((c)->kind == CK_INSTANCE \
&& (id_is_ipaddr(&(c)->spd.that.id)? \ && (id_is_ipaddr(&(c)->spd.that.id)? \
sameaddr(&(c)->spd.that.id.ip_addr, &(c)->spd.that.host_addr) : TRUE)) sameaddr(&(c)->spd.that.id.ip_addr, &(c)->spd.that.host_addr) : TRUE))
struct state; /* forward declaration of tag (defined in state.h) */ struct state; /* forward declaration of tag (defined in state.h) */
extern struct connection extern struct connection
*con_by_name(const char *nm, bool strict), *con_by_name(const char *nm, bool strict),
*find_host_connection(const ip_address *me, u_int16_t my_port *find_host_connection(const ip_address *me, u_int16_t my_port
, const ip_address *him, u_int16_t his_port, lset_t policy), , const ip_address *him, u_int16_t his_port, lset_t policy),
*refine_host_connection(const struct state *st, const struct id *id *refine_host_connection(const struct state *st, const struct id *id
, chunk_t peer_ca), , chunk_t peer_ca),
*find_client_connection(struct connection *c *find_client_connection(struct connection *c
, const ip_subnet *our_net , const ip_subnet *our_net
, const ip_subnet *peer_net , const ip_subnet *peer_net
, const u_int8_t our_protocol , const u_int8_t our_protocol
, const u_int16_t out_port , const u_int16_t out_port
, const u_int8_t peer_protocol , const u_int8_t peer_protocol
, const u_int16_t peer_port), , const u_int16_t peer_port),
*find_connection_by_reqid(uint32_t reqid); *find_connection_by_reqid(uint32_t reqid);
extern struct connection * extern struct connection *
find_connection_for_clients(struct spd_route **srp find_connection_for_clients(struct spd_route **srp
, const ip_address *our_client , const ip_address *our_client
, const ip_address *peer_client , const ip_address *peer_client
, int transport_proto); , int transport_proto);
extern chunk_t get_peer_ca_and_groups(struct connection *c extern chunk_t get_peer_ca_and_groups(struct connection *c
, const ietfAttrList_t **peer_list); , const ietfAttrList_t **peer_list);
/* instantiating routines /* instantiating routines
* Note: connection_discard() is in state.h because all its work * Note: connection_discard() is in state.h because all its work
* is looking through state objects. * is looking through state objects.
*/ */
struct gw_info; /* forward declaration of tag (defined in dnskey.h) */ struct gw_info; /* forward declaration of tag (defined in dnskey.h) */
struct alg_info; /* forward declaration of tag (defined in alg_info.h) */ struct alg_info; /* forward declaration of tag (defined in alg_info.h) */
extern struct connection *rw_instantiate(struct connection *c extern struct connection *rw_instantiate(struct connection *c
, const ip_address *him , const ip_address *him
, u_int16_t his_port , u_int16_t his_port
, const ip_subnet *his_net , const ip_subnet *his_net
, const struct id *his_id); , const struct id *his_id);
extern struct connection *oppo_instantiate(struct connection *c extern struct connection *oppo_instantiate(struct connection *c
, const ip_address *him , const ip_address *him
, const struct id *his_id , const struct id *his_id
, struct gw_info *gw , struct gw_info *gw
, const ip_address *our_client , const ip_address *our_client
, const ip_address *peer_client); , const ip_address *peer_client);
extern struct connection extern struct connection
*build_outgoing_opportunistic_connection(struct gw_info *gw *build_outgoing_opportunistic_connection(struct gw_info *gw
, const ip_address *our_client , const ip_address *our_client
, const ip_address *peer_client); , const ip_address *peer_client);
/* worst case: "[" serial "] " myclient "=== ..." peer "===" hisclient '\0' */ /* worst case: "[" serial "] " myclient "=== ..." peer "===" hisclient '\0' */
#define CONN_INST_BUF \ #define CONN_INST_BUF \
(2 + 10 + 1 + SUBNETTOT_BUF + 7 + ADDRTOT_BUF + 3 + SUBNETTOT_BUF + 1) (2 + 10 + 1 + SUBNETTOT_BUF + 7 + ADDRTOT_BUF + 3 + SUBNETTOT_BUF + 1)
extern void fmt_conn_instance(const struct connection *c extern void fmt_conn_instance(const struct connection *c
, char buf[CONN_INST_BUF]); , char buf[CONN_INST_BUF]);
/* operations on "pending", the structure representing Quick Mode /* operations on "pending", the structure representing Quick Mode
* negotiations delayed until a Keying Channel has been negotiated. * negotiations delayed until a Keying Channel has been negotiated.
*/ */
struct pending; /* forward declaration (opaque outside connections.c) */ struct pending; /* forward declaration (opaque outside connections.c) */
extern void add_pending(int whack_sock extern void add_pending(int whack_sock
, struct state *isakmp_sa , struct state *isakmp_sa
, struct connection *c , struct connection *c
, lset_t policy , lset_t policy
, unsigned long try , unsigned long try
, so_serial_t replacing); , so_serial_t replacing);
extern void release_pending_whacks(struct state *st, err_t story); extern void release_pending_whacks(struct state *st, err_t story);
extern void unpend(struct state *st); extern void unpend(struct state *st);
@@ -360,9 +360,9 @@ extern struct connection *eclipsed(struct connection *c, struct spd_route **);
extern void show_connections_status(bool all, const char *name); extern void show_connections_status(bool all, const char *name);
extern int connection_compare(const struct connection *ca extern int connection_compare(const struct connection *ca
, const struct connection *cb); , const struct connection *cb);
extern void update_host_pair(const char *why, struct connection *c extern void update_host_pair(const char *why, struct connection *c
, const ip_address *myaddr, u_int16_t myport , const ip_address *myaddr, u_int16_t myport
, const ip_address *hisaddr, u_int16_t hisport); , const ip_address *hisaddr, u_int16_t hisport);
#endif /* _CONNECTIONS_H */ #endif /* _CONNECTIONS_H */
+825 -825
View File
File diff suppressed because it is too large Load Diff
+488 -488
View File
File diff suppressed because it is too large Load Diff
+25 -25
View File
@@ -29,7 +29,7 @@
#include "rnd.h" #include "rnd.h"
#include "cookie.h" #include "cookie.h"
const u_char zero_cookie[COOKIE_SIZE]; /* guaranteed 0 */ const u_char zero_cookie[COOKIE_SIZE]; /* guaranteed 0 */
/* Generate a cookie. /* Generate a cookie.
* First argument is true if we're to create an Initiator cookie. * First argument is true if we're to create an Initiator cookie.
@@ -38,30 +38,30 @@ const u_char zero_cookie[COOKIE_SIZE]; /* guaranteed 0 */
void void
get_cookie(bool initiator, u_int8_t *cookie, int length, const ip_address *addr) get_cookie(bool initiator, u_int8_t *cookie, int length, const ip_address *addr)
{ {
u_char buffer[SHA1_DIGEST_SIZE]; u_char buffer[SHA1_DIGEST_SIZE];
SHA1_CTX ctx; SHA1_CTX ctx;
do { do {
if (initiator) if (initiator)
{ {
get_rnd_bytes(cookie, length); get_rnd_bytes(cookie, length);
} }
else /* Responder cookie */ else /* Responder cookie */
{ {
/* This looks as good as any way */ /* This looks as good as any way */
size_t addr_length; size_t addr_length;
static u_int32_t counter = 0; static u_int32_t counter = 0;
unsigned char addr_buff[ unsigned char addr_buff[
sizeof(union {struct in_addr A; struct in6_addr B;})]; sizeof(union {struct in_addr A; struct in6_addr B;})];
addr_length = addrbytesof(addr, addr_buff, sizeof(addr_buff)); addr_length = addrbytesof(addr, addr_buff, sizeof(addr_buff));
SHA1Init(&ctx); SHA1Init(&ctx);
SHA1Update(&ctx, addr_buff, addr_length); SHA1Update(&ctx, addr_buff, addr_length);
SHA1Update(&ctx, secret_of_the_day, sizeof(secret_of_the_day)); SHA1Update(&ctx, secret_of_the_day, sizeof(secret_of_the_day));
counter++; counter++;
SHA1Update(&ctx, (const void *) &counter, sizeof(counter)); SHA1Update(&ctx, (const void *) &counter, sizeof(counter));
SHA1Final(buffer, &ctx); SHA1Final(buffer, &ctx);
memcpy(cookie, buffer, length); memcpy(cookie, buffer, length);
} }
} while (is_zero_cookie(cookie)); /* probably never loops */ } while (is_zero_cookie(cookie)); /* probably never loops */
} }
+2 -2
View File
@@ -16,9 +16,9 @@
#include <freeswan.h> #include <freeswan.h>
extern const u_char zero_cookie[COOKIE_SIZE]; /* guaranteed 0 */ extern const u_char zero_cookie[COOKIE_SIZE]; /* guaranteed 0 */
extern void get_cookie(bool initiator, u_int8_t *cookie, int length extern void get_cookie(bool initiator, u_int8_t *cookie, int length
, const ip_address *addr); , const ip_address *addr);
#define is_zero_cookie(cookie) all_zero((cookie), COOKIE_SIZE) #define is_zero_cookie(cookie) all_zero((cookie), COOKIE_SIZE)
+553 -553
View File
File diff suppressed because it is too large Load Diff
+16 -16
View File
@@ -22,9 +22,9 @@ typedef struct revokedCert revokedCert_t;
struct revokedCert{ struct revokedCert{
revokedCert_t *next; revokedCert_t *next;
chunk_t userCertificate; chunk_t userCertificate;
time_t revocationDate; time_t revocationDate;
crl_reason_t revocationReason; crl_reason_t revocationReason;
}; };
/* storage structure for an X.509 CRL */ /* storage structure for an X.509 CRL */
@@ -33,28 +33,28 @@ typedef struct x509crl x509crl_t;
struct x509crl { struct x509crl {
x509crl_t *next; x509crl_t *next;
time_t installed; time_t installed;
generalName_t *distributionPoints; generalName_t *distributionPoints;
chunk_t certificateList; chunk_t certificateList;
chunk_t tbsCertList; chunk_t tbsCertList;
u_int version; u_int version;
/* signature */ /* signature */
int sigAlg; int sigAlg;
chunk_t issuer; chunk_t issuer;
time_t thisUpdate; time_t thisUpdate;
time_t nextUpdate; time_t nextUpdate;
revokedCert_t *revokedCertificates; revokedCert_t *revokedCertificates;
/* v2 extensions */ /* v2 extensions */
/* crlExtensions */ /* crlExtensions */
/* extension */ /* extension */
/* extnID */ /* extnID */
/* critical */ /* critical */
/* extnValue */ /* extnValue */
chunk_t authKeyID; chunk_t authKeyID;
chunk_t authKeySerialNumber; chunk_t authKeySerialNumber;
chunk_t crlNumber; chunk_t crlNumber;
/* signatureAlgorithm */ /* signatureAlgorithm */
int algorithm; int algorithm;
chunk_t signature; chunk_t signature;
}; };
@@ -82,7 +82,7 @@ extern void load_crls(void);
extern void check_crls(void); extern void check_crls(void);
extern bool insert_crl(chunk_t blob, chunk_t crl_uri, bool cache_crl); extern bool insert_crl(chunk_t blob, chunk_t crl_uri, bool cache_crl);
extern cert_status_t verify_by_crl(const x509cert_t *cert, time_t *until extern cert_status_t verify_by_crl(const x509cert_t *cert, time_t *until
, time_t *revocationDate, crl_reason_t *revocationReason); , time_t *revocationDate, crl_reason_t *revocationReason);
extern void list_crls(bool utc, bool strict); extern void list_crls(bool utc, bool strict);
extern void free_crls(void); extern void free_crls(void);
extern void free_crl(x509crl_t *crl); extern void free_crl(x509crl_t *crl);
+323 -323
View File
@@ -40,29 +40,29 @@
/* moduli and generator. */ /* moduli and generator. */
static MP_INT static MP_INT
modp1024_modulus, modp1024_modulus,
modp1536_modulus, modp1536_modulus,
modp2048_modulus, modp2048_modulus,
modp3072_modulus, modp3072_modulus,
modp4096_modulus, modp4096_modulus,
modp6144_modulus, modp6144_modulus,
modp8192_modulus; modp8192_modulus;
MP_INT groupgenerator; /* MODP group generator (2) */ MP_INT groupgenerator; /* MODP group generator (2) */
static void do_3des(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc); static void do_3des(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc);
static struct encrypt_desc crypto_encryptor_3des = static struct encrypt_desc crypto_encryptor_3des =
{ {
algo_type: IKE_ALG_ENCRYPT, algo_type: IKE_ALG_ENCRYPT,
algo_id: OAKLEY_3DES_CBC, algo_id: OAKLEY_3DES_CBC,
algo_next: NULL, algo_next: NULL,
enc_ctxsize: sizeof(des_key_schedule) * 3, enc_ctxsize: sizeof(des_key_schedule) * 3,
enc_blocksize: DES_CBC_BLOCK_SIZE, enc_blocksize: DES_CBC_BLOCK_SIZE,
keydeflen: DES_CBC_BLOCK_SIZE * 3 * BITS_PER_BYTE, keydeflen: DES_CBC_BLOCK_SIZE * 3 * BITS_PER_BYTE,
keyminlen: DES_CBC_BLOCK_SIZE * 3 * BITS_PER_BYTE, keyminlen: DES_CBC_BLOCK_SIZE * 3 * BITS_PER_BYTE,
keymaxlen: DES_CBC_BLOCK_SIZE * 3 * BITS_PER_BYTE, keymaxlen: DES_CBC_BLOCK_SIZE * 3 * BITS_PER_BYTE,
do_crypt: do_3des, do_crypt: do_3des,
}; };
/* MD5 hash test vectors /* MD5 hash test vectors
@@ -75,93 +75,93 @@ static const u_char md5_test0_msg[] = {
}; };
static const u_char md5_test0_msg_digest[] = { static const u_char md5_test0_msg_digest[] = {
0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e
}; };
static const u_char md5_test1_msg[] = { static const u_char md5_test1_msg[] = {
0x61 0x61
}; };
static const u_char md5_test1_msg_digest[] = { static const u_char md5_test1_msg_digest[] = {
0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61
}; };
static const u_char md5_test2_msg[] = { static const u_char md5_test2_msg[] = {
0x61, 0x62, 0x63 0x61, 0x62, 0x63
}; };
static const u_char md5_test2_msg_digest[] = { static const u_char md5_test2_msg_digest[] = {
0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72
}; };
static const u_char md5_test3_msg[] = { static const u_char md5_test3_msg[] = {
0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20,
0x64, 0x69, 0x67, 0x65, 0x73, 0x74 0x64, 0x69, 0x67, 0x65, 0x73, 0x74
}; };
static const u_char md5_test3_msg_digest[] = { static const u_char md5_test3_msg_digest[] = {
0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0
}; };
static const u_char md5_test4_msg[] = { static const u_char md5_test4_msg[] = {
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
0x79, 0x7a 0x79, 0x7a
}; };
static const u_char md5_test4_msg_digest[] = { static const u_char md5_test4_msg_digest[] = {
0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b
}; };
static const u_char md5_test5_msg[] = { static const u_char md5_test5_msg[] = {
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, 0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39 0x34, 0x35, 0x36, 0x37, 0x38, 0x39
}; };
static const u_char md5_test5_msg_digest[] = { static const u_char md5_test5_msg_digest[] = {
0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f
}; };
static const u_char md5_test6_msg[] = { static const u_char md5_test6_msg[] = {
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34,
0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32,
0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34,
0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32,
0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30
}; };
static const u_char md5_test6_msg_digest[] = { static const u_char md5_test6_msg_digest[] = {
0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a
}; };
static const hash_testvector_t md5_hash_testvectors[] = { static const hash_testvector_t md5_hash_testvectors[] = {
{ sizeof(md5_test0_msg), md5_test0_msg, md5_test0_msg_digest }, { sizeof(md5_test0_msg), md5_test0_msg, md5_test0_msg_digest },
{ sizeof(md5_test1_msg), md5_test1_msg, md5_test1_msg_digest }, { sizeof(md5_test1_msg), md5_test1_msg, md5_test1_msg_digest },
{ sizeof(md5_test2_msg), md5_test2_msg, md5_test2_msg_digest }, { sizeof(md5_test2_msg), md5_test2_msg, md5_test2_msg_digest },
{ sizeof(md5_test3_msg), md5_test3_msg, md5_test3_msg_digest }, { sizeof(md5_test3_msg), md5_test3_msg, md5_test3_msg_digest },
{ sizeof(md5_test4_msg), md5_test4_msg, md5_test4_msg_digest }, { sizeof(md5_test4_msg), md5_test4_msg, md5_test4_msg_digest },
{ sizeof(md5_test5_msg), md5_test5_msg, md5_test5_msg_digest }, { sizeof(md5_test5_msg), md5_test5_msg, md5_test5_msg_digest },
{ sizeof(md5_test6_msg), md5_test6_msg, md5_test6_msg_digest }, { sizeof(md5_test6_msg), md5_test6_msg, md5_test6_msg_digest },
{ 0, NULL, NULL } { 0, NULL, NULL }
}; };
/* MD5 hmac test vectors /* MD5 hmac test vectors
@@ -170,146 +170,146 @@ static const hash_testvector_t md5_hash_testvectors[] = {
*/ */
static const u_char md5_hmac1_key[] = { static const u_char md5_hmac1_key[] = {
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b
}; };
static const u_char md5_hmac1_msg[] = { static const u_char md5_hmac1_msg[] = {
0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65
}; };
static const u_char md5_hmac1[] = { static const u_char md5_hmac1[] = {
0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d
}; };
static const u_char md5_hmac2_key[] = { static const u_char md5_hmac2_key[] = {
0x4a, 0x65, 0x66, 0x65 0x4a, 0x65, 0x66, 0x65
}; };
static const u_char md5_hmac2_msg[] = { static const u_char md5_hmac2_msg[] = {
0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20, 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20,
0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20, 0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20,
0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68, 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68,
0x69, 0x6e, 0x67, 0x3f 0x69, 0x6e, 0x67, 0x3f
}; };
static const u_char md5_hmac2[] = { static const u_char md5_hmac2[] = {
0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38
}; };
static const u_char md5_hmac3_key[] = { static const u_char md5_hmac3_key[] = {
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
}; };
static const u_char md5_hmac3_msg[] = { static const u_char md5_hmac3_msg[] = {
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd 0xdd, 0xdd
}; };
static const u_char md5_hmac3[] = { static const u_char md5_hmac3[] = {
0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88, 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6
}; };
static const u_char md5_hmac4_key[] = { static const u_char md5_hmac4_key[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x19 0x19
}; };
static const u_char md5_hmac4_msg[] = { static const u_char md5_hmac4_msg[] = {
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd 0xcd, 0xcd
}; };
static const u_char md5_hmac4[] = { static const u_char md5_hmac4[] = {
0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea, 0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea,
0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79 0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79
}; };
static const u_char md5_hmac6_key[] = { static const u_char md5_hmac6_key[] = {
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
}; };
static const u_char md5_hmac6_msg[] = { static const u_char md5_hmac6_msg[] = {
0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69, 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69,
0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65, 0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65,
0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42, 0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a, 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a,
0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x2d, 0x20, 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x2d, 0x20,
0x48, 0x61, 0x73, 0x68, 0x20, 0x4b, 0x65, 0x79, 0x48, 0x61, 0x73, 0x68, 0x20, 0x4b, 0x65, 0x79,
0x20, 0x46, 0x69, 0x72, 0x73, 0x74 0x20, 0x46, 0x69, 0x72, 0x73, 0x74
}; };
static const u_char md5_hmac6[] = { static const u_char md5_hmac6[] = {
0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f, 0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f,
0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd 0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd
}; };
static const u_char md5_hmac7_msg[] = { static const u_char md5_hmac7_msg[] = {
0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69, 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69,
0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65, 0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65,
0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42, 0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a, 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a,
0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x61, 0x6e, 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x61, 0x6e,
0x64, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x64, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65, 0x72,
0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x4f, 0x6e, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x4f, 0x6e,
0x65, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x65, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x2d,
0x53, 0x69, 0x7a, 0x65, 0x20, 0x44, 0x61, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x20, 0x44, 0x61, 0x74,
0x61 0x61
}; };
static const u_char md5_hmac7[] = { static const u_char md5_hmac7[] = {
0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee, 0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee,
0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e 0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e
}; };
static const hmac_testvector_t md5_hmac_testvectors[] = { static const hmac_testvector_t md5_hmac_testvectors[] = {
{ sizeof(md5_hmac1_key), md5_hmac1_key, sizeof(md5_hmac1_msg), md5_hmac1_msg, md5_hmac1 }, { sizeof(md5_hmac1_key), md5_hmac1_key, sizeof(md5_hmac1_msg), md5_hmac1_msg, md5_hmac1 },
{ sizeof(md5_hmac2_key), md5_hmac2_key, sizeof(md5_hmac2_msg), md5_hmac2_msg, md5_hmac2 }, { sizeof(md5_hmac2_key), md5_hmac2_key, sizeof(md5_hmac2_msg), md5_hmac2_msg, md5_hmac2 },
{ sizeof(md5_hmac3_key), md5_hmac3_key, sizeof(md5_hmac3_msg), md5_hmac3_msg, md5_hmac3 }, { sizeof(md5_hmac3_key), md5_hmac3_key, sizeof(md5_hmac3_msg), md5_hmac3_msg, md5_hmac3 },
{ sizeof(md5_hmac4_key), md5_hmac4_key, sizeof(md5_hmac4_msg), md5_hmac4_msg, md5_hmac4 }, { sizeof(md5_hmac4_key), md5_hmac4_key, sizeof(md5_hmac4_msg), md5_hmac4_msg, md5_hmac4 },
{ sizeof(md5_hmac6_key), md5_hmac6_key, sizeof(md5_hmac6_msg), md5_hmac6_msg, md5_hmac6 }, { sizeof(md5_hmac6_key), md5_hmac6_key, sizeof(md5_hmac6_msg), md5_hmac6_msg, md5_hmac6 },
{ sizeof(md5_hmac6_key), md5_hmac6_key, sizeof(md5_hmac7_msg), md5_hmac7_msg, md5_hmac7 }, { sizeof(md5_hmac6_key), md5_hmac6_key, sizeof(md5_hmac7_msg), md5_hmac7_msg, md5_hmac7 },
{ 0, NULL, 0, NULL, NULL } { 0, NULL, 0, NULL, NULL }
}; };
static struct hash_desc crypto_hasher_md5 = static struct hash_desc crypto_hasher_md5 =
{ {
algo_type: IKE_ALG_HASH, algo_type: IKE_ALG_HASH,
algo_id: OAKLEY_MD5, algo_id: OAKLEY_MD5,
algo_next: NULL, algo_next: NULL,
hash_ctx_size: sizeof(MD5_CTX), hash_ctx_size: sizeof(MD5_CTX),
hash_block_size: MD5_BLOCK_SIZE, hash_block_size: MD5_BLOCK_SIZE,
hash_digest_size: MD5_DIGEST_SIZE, hash_digest_size: MD5_DIGEST_SIZE,
hash_testvectors: md5_hash_testvectors, hash_testvectors: md5_hash_testvectors,
hmac_testvectors: md5_hmac_testvectors, hmac_testvectors: md5_hmac_testvectors,
hash_init: (void (*)(void *)) MD5Init, hash_init: (void (*)(void *)) MD5Init,
hash_update: (void (*)(void *, const u_int8_t *, size_t)) MD5Update, hash_update: (void (*)(void *, const u_int8_t *, size_t)) MD5Update,
hash_final: (void (*)(u_char *, void *)) MD5Final hash_final: (void (*)(u_char *, void *)) MD5Final
}; };
/* SHA-1 test vectors /* SHA-1 test vectors
@@ -318,61 +318,61 @@ static struct hash_desc crypto_hasher_md5 =
*/ */
static const u_char sha1_short2_msg[] = { static const u_char sha1_short2_msg[] = {
0x5e 0x5e
}; };
static const u_char sha1_short2_msg_digest[] = { static const u_char sha1_short2_msg_digest[] = {
0x5e, 0x6f, 0x80, 0xa3, 0x4a, 0x97, 0x98, 0xca, 0x5e, 0x6f, 0x80, 0xa3, 0x4a, 0x97, 0x98, 0xca,
0xfc, 0x6a, 0x5d, 0xb9, 0x6c, 0xc5, 0x7b, 0xa4, 0xfc, 0x6a, 0x5d, 0xb9, 0x6c, 0xc5, 0x7b, 0xa4,
0xc4, 0xdb, 0x59, 0xc2 0xc4, 0xdb, 0x59, 0xc2
}; };
static const u_char sha1_short4_msg[] = { static const u_char sha1_short4_msg[] = {
0x9a, 0x7d, 0xfd, 0xf1, 0xec, 0xea, 0xd0, 0x6e, 0x9a, 0x7d, 0xfd, 0xf1, 0xec, 0xea, 0xd0, 0x6e,
0xd6, 0x46, 0xaa, 0x55, 0xfe, 0x75, 0x71, 0x46 0xd6, 0x46, 0xaa, 0x55, 0xfe, 0x75, 0x71, 0x46
}; };
static const u_char sha1_short4_msg_digest[] = { static const u_char sha1_short4_msg_digest[] = {
0x82, 0xab, 0xff, 0x66, 0x05, 0xdb, 0xe1, 0xc1, 0x82, 0xab, 0xff, 0x66, 0x05, 0xdb, 0xe1, 0xc1,
0x7d, 0xef, 0x12, 0xa3, 0x94, 0xfa, 0x22, 0xa8, 0x7d, 0xef, 0x12, 0xa3, 0x94, 0xfa, 0x22, 0xa8,
0x2b, 0x54, 0x4a, 0x35 0x2b, 0x54, 0x4a, 0x35
}; };
static const u_char sha1_long2_msg[] = { static const u_char sha1_long2_msg[] = {
0xf7, 0x8f, 0x92, 0x14, 0x1b, 0xcd, 0x17, 0x0a, 0xf7, 0x8f, 0x92, 0x14, 0x1b, 0xcd, 0x17, 0x0a,
0xe8, 0x9b, 0x4f, 0xba, 0x15, 0xa1, 0xd5, 0x9f, 0xe8, 0x9b, 0x4f, 0xba, 0x15, 0xa1, 0xd5, 0x9f,
0x3f, 0xd8, 0x4d, 0x22, 0x3c, 0x92, 0x51, 0xbd, 0x3f, 0xd8, 0x4d, 0x22, 0x3c, 0x92, 0x51, 0xbd,
0xac, 0xbb, 0xae, 0x61, 0xd0, 0x5e, 0xd1, 0x15, 0xac, 0xbb, 0xae, 0x61, 0xd0, 0x5e, 0xd1, 0x15,
0xa0, 0x6a, 0x7c, 0xe1, 0x17, 0xb7, 0xbe, 0xea, 0xa0, 0x6a, 0x7c, 0xe1, 0x17, 0xb7, 0xbe, 0xea,
0xd2, 0x44, 0x21, 0xde, 0xd9, 0xc3, 0x25, 0x92, 0xd2, 0x44, 0x21, 0xde, 0xd9, 0xc3, 0x25, 0x92,
0xbd, 0x57, 0xed, 0xea, 0xe3, 0x9c, 0x39, 0xfa, 0xbd, 0x57, 0xed, 0xea, 0xe3, 0x9c, 0x39, 0xfa,
0x1f, 0xe8, 0x94, 0x6a, 0x84, 0xd0, 0xcf, 0x1f, 0x1f, 0xe8, 0x94, 0x6a, 0x84, 0xd0, 0xcf, 0x1f,
0x7b, 0xee, 0xad, 0x17, 0x13, 0xe2, 0xe0, 0x95, 0x7b, 0xee, 0xad, 0x17, 0x13, 0xe2, 0xe0, 0x95,
0x98, 0x97, 0x34, 0x7f, 0x67, 0xc8, 0x0b, 0x04, 0x98, 0x97, 0x34, 0x7f, 0x67, 0xc8, 0x0b, 0x04,
0x00, 0xc2, 0x09, 0x81, 0x5d, 0x6b, 0x10, 0xa6, 0x00, 0xc2, 0x09, 0x81, 0x5d, 0x6b, 0x10, 0xa6,
0x83, 0x83, 0x6f, 0xd5, 0x56, 0x2a, 0x56, 0xca, 0x83, 0x83, 0x6f, 0xd5, 0x56, 0x2a, 0x56, 0xca,
0xb1, 0xa2, 0x8e, 0x81, 0xb6, 0x57, 0x66, 0x54, 0xb1, 0xa2, 0x8e, 0x81, 0xb6, 0x57, 0x66, 0x54,
0x63, 0x1c, 0xf1, 0x65, 0x66, 0xb8, 0x6e, 0x3b, 0x63, 0x1c, 0xf1, 0x65, 0x66, 0xb8, 0x6e, 0x3b,
0x33, 0xa1, 0x08, 0xb0, 0x53, 0x07, 0xc0, 0x0a, 0x33, 0xa1, 0x08, 0xb0, 0x53, 0x07, 0xc0, 0x0a,
0xff, 0x14, 0xa7, 0x68, 0xed, 0x73, 0x50, 0x60, 0xff, 0x14, 0xa7, 0x68, 0xed, 0x73, 0x50, 0x60,
0x6a, 0x0f, 0x85, 0xe6, 0xa9, 0x1d, 0x39, 0x6f, 0x6a, 0x0f, 0x85, 0xe6, 0xa9, 0x1d, 0x39, 0x6f,
0x5b, 0x5c, 0xbe, 0x57, 0x7f, 0x9b, 0x38, 0x80, 0x5b, 0x5c, 0xbe, 0x57, 0x7f, 0x9b, 0x38, 0x80,
0x7c, 0x7d, 0x52, 0x3d, 0x6d, 0x79, 0x2f, 0x6e, 0x7c, 0x7d, 0x52, 0x3d, 0x6d, 0x79, 0x2f, 0x6e,
0xbc, 0x24, 0xa4, 0xec, 0xf2, 0xb3, 0xa4, 0x27, 0xbc, 0x24, 0xa4, 0xec, 0xf2, 0xb3, 0xa4, 0x27,
0xcd, 0xbb, 0xfb 0xcd, 0xbb, 0xfb
}; };
static const u_char sha1_long2_msg_digest[] = { static const u_char sha1_long2_msg_digest[] = {
0xcb, 0x00, 0x82, 0xc8, 0xf1, 0x97, 0xd2, 0x60, 0xcb, 0x00, 0x82, 0xc8, 0xf1, 0x97, 0xd2, 0x60,
0x99, 0x1b, 0xa6, 0xa4, 0x60, 0xe7, 0x6e, 0x20, 0x99, 0x1b, 0xa6, 0xa4, 0x60, 0xe7, 0x6e, 0x20,
0x2b, 0xad, 0x27, 0xb3 0x2b, 0xad, 0x27, 0xb3
}; };
static const hash_testvector_t sha1_hash_testvectors[] = { static const hash_testvector_t sha1_hash_testvectors[] = {
{ sizeof(sha1_short2_msg), sha1_short2_msg, sha1_short2_msg_digest }, { sizeof(sha1_short2_msg), sha1_short2_msg, sha1_short2_msg_digest },
{ sizeof(sha1_short4_msg), sha1_short4_msg, sha1_short4_msg_digest }, { sizeof(sha1_short4_msg), sha1_short4_msg, sha1_short4_msg_digest },
{ sizeof(sha1_long2_msg), sha1_long2_msg, sha1_long2_msg_digest }, { sizeof(sha1_long2_msg), sha1_long2_msg, sha1_long2_msg_digest },
{ 0, NULL, NULL } { 0, NULL, NULL }
}; };
/* SHA-1 hmac test vectors /* SHA-1 hmac test vectors
@@ -381,109 +381,109 @@ static const hash_testvector_t sha1_hash_testvectors[] = {
*/ */
static const u_char sha1_hmac1_key[] = { static const u_char sha1_hmac1_key[] = {
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b 0x0b, 0x0b, 0x0b, 0x0b
}; };
static const u_char sha1_hmac1[] = { static const u_char sha1_hmac1[] = {
0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e, 0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
0xf1, 0x46, 0xbe, 0x00 0xf1, 0x46, 0xbe, 0x00
}; };
static const u_char sha1_hmac2[] = { static const u_char sha1_hmac2[] = {
0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2, 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2,
0xd2, 0x74, 0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c, 0xd2, 0x74, 0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c,
0x25, 0x9a, 0x7c, 0x79 0x25, 0x9a, 0x7c, 0x79
}; };
static const u_char sha1_hmac3_key[] = { static const u_char sha1_hmac3_key[] = {
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa 0xaa, 0xaa, 0xaa, 0xaa
}; };
static const u_char sha1_hmac3[] = { static const u_char sha1_hmac3[] = {
0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd, 0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd,
0x91, 0xa3, 0x9a, 0xf4, 0x8a, 0xa1, 0x7b, 0x4f, 0x91, 0xa3, 0x9a, 0xf4, 0x8a, 0xa1, 0x7b, 0x4f,
0x63, 0xf1, 0x75, 0xd3 0x63, 0xf1, 0x75, 0xd3
}; };
static const u_char sha1_hmac4[] = { static const u_char sha1_hmac4[] = {
0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6, 0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6,
0xbc, 0x84, 0x14, 0xf9, 0xbf, 0x50, 0xc8, 0x6c, 0xbc, 0x84, 0x14, 0xf9, 0xbf, 0x50, 0xc8, 0x6c,
0x2d, 0x72, 0x35, 0xda 0x2d, 0x72, 0x35, 0xda
}; };
static const u_char sha1_hmac6[] = { static const u_char sha1_hmac6[] = {
0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e, 0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e,
0x95, 0x70, 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55, 0x95, 0x70, 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55,
0xed, 0x40, 0x21, 0x12 0xed, 0x40, 0x21, 0x12
}; };
static const u_char sha1_hmac7[] = { static const u_char sha1_hmac7[] = {
0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78, 0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78,
0x6d, 0x6b, 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08, 0x6d, 0x6b, 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08,
0xbb, 0xff, 0x1a, 0x91 0xbb, 0xff, 0x1a, 0x91
}; };
static const hmac_testvector_t sha1_hmac_testvectors[] = { static const hmac_testvector_t sha1_hmac_testvectors[] = {
{ sizeof(sha1_hmac1_key), sha1_hmac1_key, sizeof(md5_hmac1_msg), md5_hmac1_msg, sha1_hmac1 }, { sizeof(sha1_hmac1_key), sha1_hmac1_key, sizeof(md5_hmac1_msg), md5_hmac1_msg, sha1_hmac1 },
{ sizeof(md5_hmac2_key), md5_hmac2_key, sizeof(md5_hmac2_msg), md5_hmac2_msg, sha1_hmac2 }, { sizeof(md5_hmac2_key), md5_hmac2_key, sizeof(md5_hmac2_msg), md5_hmac2_msg, sha1_hmac2 },
{ sizeof(sha1_hmac3_key), sha1_hmac3_key, sizeof(md5_hmac3_msg), md5_hmac3_msg, sha1_hmac3 }, { sizeof(sha1_hmac3_key), sha1_hmac3_key, sizeof(md5_hmac3_msg), md5_hmac3_msg, sha1_hmac3 },
{ sizeof(md5_hmac4_key), md5_hmac4_key, sizeof(md5_hmac4_msg), md5_hmac4_msg, sha1_hmac4 }, { sizeof(md5_hmac4_key), md5_hmac4_key, sizeof(md5_hmac4_msg), md5_hmac4_msg, sha1_hmac4 },
{ sizeof(md5_hmac6_key), md5_hmac6_key, sizeof(md5_hmac6_msg), md5_hmac6_msg, sha1_hmac6 }, { sizeof(md5_hmac6_key), md5_hmac6_key, sizeof(md5_hmac6_msg), md5_hmac6_msg, sha1_hmac6 },
{ sizeof(md5_hmac6_key), md5_hmac6_key, sizeof(md5_hmac7_msg), md5_hmac7_msg, sha1_hmac7 }, { sizeof(md5_hmac6_key), md5_hmac6_key, sizeof(md5_hmac7_msg), md5_hmac7_msg, sha1_hmac7 },
{ 0, NULL, 0, NULL, NULL } { 0, NULL, 0, NULL, NULL }
}; };
static struct hash_desc crypto_hasher_sha1 = static struct hash_desc crypto_hasher_sha1 =
{ {
algo_type: IKE_ALG_HASH, algo_type: IKE_ALG_HASH,
algo_id: OAKLEY_SHA, algo_id: OAKLEY_SHA,
algo_next: NULL, algo_next: NULL,
hash_ctx_size: sizeof(SHA1_CTX), hash_ctx_size: sizeof(SHA1_CTX),
hash_block_size: SHA1_BLOCK_SIZE, hash_block_size: SHA1_BLOCK_SIZE,
hash_digest_size: SHA1_DIGEST_SIZE, hash_digest_size: SHA1_DIGEST_SIZE,
hash_testvectors: sha1_hash_testvectors, hash_testvectors: sha1_hash_testvectors,
hmac_testvectors: sha1_hmac_testvectors, hmac_testvectors: sha1_hmac_testvectors,
hash_init: (void (*)(void *)) SHA1Init, hash_init: (void (*)(void *)) SHA1Init,
hash_update: (void (*)(void *, const u_int8_t *, size_t)) SHA1Update, hash_update: (void (*)(void *, const u_int8_t *, size_t)) SHA1Update,
hash_final: (void (*)(u_char *, void *)) SHA1Final hash_final: (void (*)(u_char *, void *)) SHA1Final
}; };
void void
init_crypto(void) init_crypto(void)
{ {
if (mpz_init_set_str(&groupgenerator, MODP_GENERATOR, 10) != 0 if (mpz_init_set_str(&groupgenerator, MODP_GENERATOR, 10) != 0
|| mpz_init_set_str(&modp1024_modulus, MODP1024_MODULUS, 16) != 0 || mpz_init_set_str(&modp1024_modulus, MODP1024_MODULUS, 16) != 0
|| mpz_init_set_str(&modp1536_modulus, MODP1536_MODULUS, 16) != 0 || mpz_init_set_str(&modp1536_modulus, MODP1536_MODULUS, 16) != 0
|| mpz_init_set_str(&modp2048_modulus, MODP2048_MODULUS, 16) != 0 || mpz_init_set_str(&modp2048_modulus, MODP2048_MODULUS, 16) != 0
|| mpz_init_set_str(&modp3072_modulus, MODP3072_MODULUS, 16) != 0 || mpz_init_set_str(&modp3072_modulus, MODP3072_MODULUS, 16) != 0
|| mpz_init_set_str(&modp4096_modulus, MODP4096_MODULUS, 16) != 0 || mpz_init_set_str(&modp4096_modulus, MODP4096_MODULUS, 16) != 0
|| mpz_init_set_str(&modp6144_modulus, MODP6144_MODULUS, 16) != 0 || mpz_init_set_str(&modp6144_modulus, MODP6144_MODULUS, 16) != 0
|| mpz_init_set_str(&modp8192_modulus, MODP8192_MODULUS, 16) != 0) || mpz_init_set_str(&modp8192_modulus, MODP8192_MODULUS, 16) != 0)
exit_log("mpz_init_set_str() failed in init_crypto()"); exit_log("mpz_init_set_str() failed in init_crypto()");
ike_alg_add((struct ike_alg *) &crypto_encryptor_3des); ike_alg_add((struct ike_alg *) &crypto_encryptor_3des);
ike_alg_add((struct ike_alg *) &crypto_hasher_sha1); ike_alg_add((struct ike_alg *) &crypto_hasher_sha1);
ike_alg_add((struct ike_alg *) &crypto_hasher_md5); ike_alg_add((struct ike_alg *) &crypto_hasher_md5);
ike_alg_init(); ike_alg_init();
ike_alg_test(); ike_alg_test();
} }
void void
free_crypto(void) free_crypto(void)
{ {
mpz_clear(&groupgenerator); mpz_clear(&groupgenerator);
mpz_clear(&modp1024_modulus); mpz_clear(&modp1024_modulus);
mpz_clear(&modp1536_modulus); mpz_clear(&modp1536_modulus);
mpz_clear(&modp2048_modulus); mpz_clear(&modp2048_modulus);
mpz_clear(&modp3072_modulus); mpz_clear(&modp3072_modulus);
mpz_clear(&modp4096_modulus); mpz_clear(&modp4096_modulus);
mpz_clear(&modp6144_modulus); mpz_clear(&modp6144_modulus);
mpz_clear(&modp8192_modulus); mpz_clear(&modp8192_modulus);
} }
/* Oakley group description /* Oakley group description
@@ -491,29 +491,29 @@ free_crypto(void)
* See RFC2409 "The Internet key exchange (IKE)" 6. * See RFC2409 "The Internet key exchange (IKE)" 6.
*/ */
const struct oakley_group_desc unset_group = {0, NULL, 0}; /* magic signifier */ const struct oakley_group_desc unset_group = {0, NULL, 0}; /* magic signifier */
const struct oakley_group_desc oakley_group[OAKLEY_GROUP_SIZE] = { const struct oakley_group_desc oakley_group[OAKLEY_GROUP_SIZE] = {
# define BYTES(bits) (((bits) + BITS_PER_BYTE - 1) / BITS_PER_BYTE) # define BYTES(bits) (((bits) + BITS_PER_BYTE - 1) / BITS_PER_BYTE)
{ OAKLEY_GROUP_MODP1024, &modp1024_modulus, BYTES(1024) }, { OAKLEY_GROUP_MODP1024, &modp1024_modulus, BYTES(1024) },
{ OAKLEY_GROUP_MODP1536, &modp1536_modulus, BYTES(1536) }, { OAKLEY_GROUP_MODP1536, &modp1536_modulus, BYTES(1536) },
{ OAKLEY_GROUP_MODP2048, &modp2048_modulus, BYTES(2048) }, { OAKLEY_GROUP_MODP2048, &modp2048_modulus, BYTES(2048) },
{ OAKLEY_GROUP_MODP3072, &modp3072_modulus, BYTES(3072) }, { OAKLEY_GROUP_MODP3072, &modp3072_modulus, BYTES(3072) },
{ OAKLEY_GROUP_MODP4096, &modp4096_modulus, BYTES(4096) }, { OAKLEY_GROUP_MODP4096, &modp4096_modulus, BYTES(4096) },
{ OAKLEY_GROUP_MODP6144, &modp6144_modulus, BYTES(6144) }, { OAKLEY_GROUP_MODP6144, &modp6144_modulus, BYTES(6144) },
{ OAKLEY_GROUP_MODP8192, &modp8192_modulus, BYTES(8192) }, { OAKLEY_GROUP_MODP8192, &modp8192_modulus, BYTES(8192) },
# undef BYTES # undef BYTES
}; };
const struct oakley_group_desc * const struct oakley_group_desc *
lookup_group(u_int16_t group) lookup_group(u_int16_t group)
{ {
int i; int i;
for (i = 0; i != countof(oakley_group); i++) for (i = 0; i != countof(oakley_group); i++)
if (group == oakley_group[i].group) if (group == oakley_group[i].group)
return &oakley_group[i]; return &oakley_group[i];
return NULL; return NULL;
} }
/* Encryption Routines /* Encryption Routines
@@ -528,16 +528,16 @@ lookup_group(u_int16_t group)
static void __attribute__ ((unused)) static void __attribute__ ((unused))
do_des(bool enc, void *buf, size_t buf_len, struct state *st) do_des(bool enc, void *buf, size_t buf_len, struct state *st)
{ {
des_key_schedule ks; des_key_schedule ks;
(void) des_set_key((des_cblock *)st->st_enc_key.ptr, ks); (void) des_set_key((des_cblock *)st->st_enc_key.ptr, ks);
passert(st->st_new_iv_len >= DES_CBC_BLOCK_SIZE); passert(st->st_new_iv_len >= DES_CBC_BLOCK_SIZE);
st->st_new_iv_len = DES_CBC_BLOCK_SIZE; /* truncate */ st->st_new_iv_len = DES_CBC_BLOCK_SIZE; /* truncate */
des_ncbc_encrypt((des_cblock *)buf, (des_cblock *)buf, buf_len, des_ncbc_encrypt((des_cblock *)buf, (des_cblock *)buf, buf_len,
ks, ks,
(des_cblock *)st->st_new_iv, enc); (des_cblock *)st->st_new_iv, enc);
} }
/* encrypt or decrypt part of an IKE message using 3DES /* encrypt or decrypt part of an IKE message using 3DES
@@ -546,30 +546,30 @@ do_des(bool enc, void *buf, size_t buf_len, struct state *st)
static void static void
do_3des(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc) do_3des(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
{ {
des_key_schedule ks[3]; des_key_schedule ks[3];
passert (!key_size || (key_size==(DES_CBC_BLOCK_SIZE * 3))) passert (!key_size || (key_size==(DES_CBC_BLOCK_SIZE * 3)))
(void) des_set_key((des_cblock *)key + 0, ks[0]); (void) des_set_key((des_cblock *)key + 0, ks[0]);
(void) des_set_key((des_cblock *)key + 1, ks[1]); (void) des_set_key((des_cblock *)key + 1, ks[1]);
(void) des_set_key((des_cblock *)key + 2, ks[2]); (void) des_set_key((des_cblock *)key + 2, ks[2]);
des_ede3_cbc_encrypt((des_cblock *)buf, (des_cblock *)buf, buf_len, des_ede3_cbc_encrypt((des_cblock *)buf, (des_cblock *)buf, buf_len,
ks[0], ks[1], ks[2], ks[0], ks[1], ks[2],
(des_cblock *)iv, enc); (des_cblock *)iv, enc);
} }
/* hash and prf routines */ /* hash and prf routines */
void void
crypto_cbc_encrypt(const struct encrypt_desc *e, bool enc, u_int8_t *buf, size_t size, struct state *st) crypto_cbc_encrypt(const struct encrypt_desc *e, bool enc, u_int8_t *buf, size_t size, struct state *st)
{ {
passert(st->st_new_iv_len >= e->enc_blocksize); passert(st->st_new_iv_len >= e->enc_blocksize);
st->st_new_iv_len = e->enc_blocksize; /* truncate */ st->st_new_iv_len = e->enc_blocksize; /* truncate */
e->do_crypt(buf, size, st->st_enc_key.ptr, st->st_enc_key.len, st->st_new_iv, enc); e->do_crypt(buf, size, st->st_enc_key.ptr, st->st_enc_key.len, st->st_new_iv, enc);
/* /*
e->set_key(&ctx, st->st_enc_key.ptr, st->st_enc_key.len); e->set_key(&ctx, st->st_enc_key.ptr, st->st_enc_key.len);
e->cbc_crypt(&ctx, buf, size, st->st_new_iv, enc); e->cbc_crypt(&ctx, buf, size, st->st_new_iv, enc);
*/ */
} }
/* HMAC package /* HMAC package
@@ -578,63 +578,63 @@ crypto_cbc_encrypt(const struct encrypt_desc *e, bool enc, u_int8_t *buf, size_t
void void
hmac_init(struct hmac_ctx *ctx, hmac_init(struct hmac_ctx *ctx,
const struct hash_desc *h, const struct hash_desc *h,
const u_char *key, size_t key_len) const u_char *key, size_t key_len)
{ {
int k; int k;
ctx->h = h; ctx->h = h;
ctx->hmac_digest_size = h->hash_digest_size; ctx->hmac_digest_size = h->hash_digest_size;
/* Prepare the two pads for the HMAC */ /* Prepare the two pads for the HMAC */
memset(ctx->buf1, '\0', h->hash_block_size); memset(ctx->buf1, '\0', h->hash_block_size);
if (key_len <= h->hash_block_size) if (key_len <= h->hash_block_size)
{ {
memcpy(ctx->buf1, key, key_len); memcpy(ctx->buf1, key, key_len);
} }
else else
{ {
h->hash_init(&ctx->hash_ctx); h->hash_init(&ctx->hash_ctx);
h->hash_update(&ctx->hash_ctx, key, key_len); h->hash_update(&ctx->hash_ctx, key, key_len);
h->hash_final(ctx->buf1, &ctx->hash_ctx); h->hash_final(ctx->buf1, &ctx->hash_ctx);
} }
memcpy(ctx->buf2, ctx->buf1, h->hash_block_size); memcpy(ctx->buf2, ctx->buf1, h->hash_block_size);
for (k = 0; k < h->hash_block_size; k++) for (k = 0; k < h->hash_block_size; k++)
{ {
ctx->buf1[k] ^= HMAC_IPAD; ctx->buf1[k] ^= HMAC_IPAD;
ctx->buf2[k] ^= HMAC_OPAD; ctx->buf2[k] ^= HMAC_OPAD;
} }
hmac_reinit(ctx); hmac_reinit(ctx);
} }
void void
hmac_reinit(struct hmac_ctx *ctx) hmac_reinit(struct hmac_ctx *ctx)
{ {
ctx->h->hash_init(&ctx->hash_ctx); ctx->h->hash_init(&ctx->hash_ctx);
ctx->h->hash_update(&ctx->hash_ctx, ctx->buf1, ctx->h->hash_block_size); ctx->h->hash_update(&ctx->hash_ctx, ctx->buf1, ctx->h->hash_block_size);
} }
void void
hmac_update(struct hmac_ctx *ctx, hmac_update(struct hmac_ctx *ctx,
const u_char *data, size_t data_len) const u_char *data, size_t data_len)
{ {
ctx->h->hash_update(&ctx->hash_ctx, data, data_len); ctx->h->hash_update(&ctx->hash_ctx, data, data_len);
} }
void void
hmac_final(u_char *output, struct hmac_ctx *ctx) hmac_final(u_char *output, struct hmac_ctx *ctx)
{ {
const struct hash_desc *h = ctx->h; const struct hash_desc *h = ctx->h;
h->hash_final(output, &ctx->hash_ctx); h->hash_final(output, &ctx->hash_ctx);
h->hash_init(&ctx->hash_ctx); h->hash_init(&ctx->hash_ctx);
h->hash_update(&ctx->hash_ctx, ctx->buf2, h->hash_block_size); h->hash_update(&ctx->hash_ctx, ctx->buf2, h->hash_block_size);
h->hash_update(&ctx->hash_ctx, output, h->hash_digest_size); h->hash_update(&ctx->hash_ctx, output, h->hash_digest_size);
h->hash_final(output, &ctx->hash_ctx); h->hash_final(output, &ctx->hash_ctx);
} }
+34 -34
View File
@@ -24,15 +24,15 @@ extern void free_crypto(void);
/* Oakley group descriptions */ /* Oakley group descriptions */
extern MP_INT groupgenerator; /* MODP group generator (2) */ extern MP_INT groupgenerator; /* MODP group generator (2) */
struct oakley_group_desc { struct oakley_group_desc {
u_int16_t group; u_int16_t group;
MP_INT *modulus; MP_INT *modulus;
size_t bytes; size_t bytes;
}; };
extern const struct oakley_group_desc unset_group; /* magic signifier */ extern const struct oakley_group_desc unset_group; /* magic signifier */
extern const struct oakley_group_desc *lookup_group(u_int16_t group); extern const struct oakley_group_desc *lookup_group(u_int16_t group);
#define OAKLEY_GROUP_SIZE 7 #define OAKLEY_GROUP_SIZE 7
extern const struct oakley_group_desc oakley_group[OAKLEY_GROUP_SIZE]; extern const struct oakley_group_desc oakley_group[OAKLEY_GROUP_SIZE];
@@ -47,26 +47,26 @@ extern const struct oakley_group_desc oakley_group[OAKLEY_GROUP_SIZE];
#define MAX_OAKLEY_KEY_LEN0 (3 * DES_CBC_BLOCK_SIZE) #define MAX_OAKLEY_KEY_LEN0 (3 * DES_CBC_BLOCK_SIZE)
#define MAX_OAKLEY_KEY_LEN (256/BITS_PER_BYTE) #define MAX_OAKLEY_KEY_LEN (256/BITS_PER_BYTE)
struct state; /* forward declaration, dammit */ struct state; /* forward declaration, dammit */
void crypto_cbc_encrypt(const struct encrypt_desc *e, bool enc, u_int8_t *buf, size_t size, struct state *st); void crypto_cbc_encrypt(const struct encrypt_desc *e, bool enc, u_int8_t *buf, size_t size, struct state *st);
#define update_iv(st) memcpy((st)->st_iv, (st)->st_new_iv \ #define update_iv(st) memcpy((st)->st_iv, (st)->st_new_iv \
, (st)->st_iv_len = (st)->st_new_iv_len) , (st)->st_iv_len = (st)->st_new_iv_len)
#define set_ph1_iv(st, iv) \ #define set_ph1_iv(st, iv) \
passert((st)->st_ph1_iv_len <= sizeof((st)->st_ph1_iv)); \ passert((st)->st_ph1_iv_len <= sizeof((st)->st_ph1_iv)); \
memcpy((st)->st_ph1_iv, (iv), (st)->st_ph1_iv_len); memcpy((st)->st_ph1_iv, (iv), (st)->st_ph1_iv_len);
/* unification of cryptographic hashing mechanisms */ /* unification of cryptographic hashing mechanisms */
#ifndef NO_HASH_CTX #ifndef NO_HASH_CTX
union hash_ctx { union hash_ctx {
MD5_CTX ctx_md5; MD5_CTX ctx_md5;
SHA1_CTX ctx_sha1; SHA1_CTX ctx_sha1;
sha256_context ctx_sha256; sha256_context ctx_sha256;
sha512_context ctx_sha512; sha512_context ctx_sha512;
}; };
/* HMAC package /* HMAC package
* Note that hmac_ctx can be (and is) copied since there are * Note that hmac_ctx can be (and is) copied since there are
@@ -74,36 +74,36 @@ union hash_ctx {
*/ */
struct hmac_ctx { struct hmac_ctx {
const struct hash_desc *h; /* underlying hash function */ const struct hash_desc *h; /* underlying hash function */
size_t hmac_digest_size; /* copy of h->hash_digest_size */ size_t hmac_digest_size; /* copy of h->hash_digest_size */
union hash_ctx hash_ctx; /* ctx for hash function */ union hash_ctx hash_ctx; /* ctx for hash function */
u_char buf1[MAX_HASH_BLOCK_SIZE]; u_char buf1[MAX_HASH_BLOCK_SIZE];
u_char buf2[MAX_HASH_BLOCK_SIZE]; u_char buf2[MAX_HASH_BLOCK_SIZE];
}; };
extern void hmac_init( extern void hmac_init(
struct hmac_ctx *ctx, struct hmac_ctx *ctx,
const struct hash_desc *h, const struct hash_desc *h,
const u_char *key, const u_char *key,
size_t key_len); size_t key_len);
#define hmac_init_chunk(ctx, h, ch) hmac_init((ctx), (h), (ch).ptr, (ch).len) #define hmac_init_chunk(ctx, h, ch) hmac_init((ctx), (h), (ch).ptr, (ch).len)
extern void hmac_reinit(struct hmac_ctx *ctx); /* saves recreating pads */ extern void hmac_reinit(struct hmac_ctx *ctx); /* saves recreating pads */
extern void hmac_update( extern void hmac_update(
struct hmac_ctx *ctx, struct hmac_ctx *ctx,
const u_char *data, const u_char *data,
size_t data_len); size_t data_len);
#define hmac_update_chunk(ctx, ch) hmac_update((ctx), (ch).ptr, (ch).len) #define hmac_update_chunk(ctx, ch) hmac_update((ctx), (ch).ptr, (ch).len)
extern void hmac_final(u_char *output, struct hmac_ctx *ctx); extern void hmac_final(u_char *output, struct hmac_ctx *ctx);
#define hmac_final_chunk(ch, name, ctx) { \ #define hmac_final_chunk(ch, name, ctx) { \
free((ch).ptr); \ free((ch).ptr); \
(ch).len = (ctx)->hmac_digest_size; \ (ch).len = (ctx)->hmac_digest_size; \
(ch).ptr = malloc((ch).len); \ (ch).ptr = malloc((ch).len); \
hmac_final((ch).ptr, (ctx)); \ hmac_final((ch).ptr, (ctx)); \
} }
#endif #endif
+260 -260
View File
@@ -31,22 +31,22 @@
* also update attrs_cur (by offset) * also update attrs_cur (by offset)
* *
* db_context structure: * db_context structure:
* +---------------------+ * +---------------------+
* | prop | * | prop |
* | .protoid | * | .protoid |
* | .trans | --+ * | .trans | --+
* | .trans_cnt | | * | .trans_cnt | |
* +---------------------+ <-+ * +---------------------+ <-+
* | trans0 | ----> { trans#1 | ... | trans#i | ... } * | trans0 | ----> { trans#1 | ... | trans#i | ... }
* +---------------------+ ^ * +---------------------+ ^
* | trans_cur | ----------------------' current transf. * | trans_cur | ----------------------' current transf.
* +---------------------+ * +---------------------+
* | attrs0 | ----> { attr#1 | ... | attr#j | ... } * | attrs0 | ----> { attr#1 | ... | attr#j | ... }
* +---------------------+ ^ * +---------------------+ ^
* | attrs_cur | ---------------------' current attr. * | attrs_cur | ---------------------' current attr.
* +---------------------+ * +---------------------+
* | max_trans,max_attrs | max_trans/attrs: number of elem. of each vector * | max_trans,max_attrs | max_trans/attrs: number of elem. of each vector
* +---------------------+ * +---------------------+
* *
* See testing examples at end for interface usage. * See testing examples at end for interface usage.
*/ */
@@ -71,29 +71,29 @@
#ifdef NOT_YET #ifdef NOT_YET
/* /*
* Allocator cache: * Allocator cache:
* Because of the single-threaded nature of pluto/spdb.c, * Because of the single-threaded nature of pluto/spdb.c,
* alloc()/free() is exercised many times with very small * alloc()/free() is exercised many times with very small
* lifetime objects. * lifetime objects.
* Just caching last object (currently it will select the * Just caching last object (currently it will select the
* largest) will avoid this allocation mas^Wperturbations * largest) will avoid this allocation mas^Wperturbations
* *
*/ */
struct db_ops_alloc_cache { struct db_ops_alloc_cache {
void *ptr; void *ptr;
int size; int size;
}; };
#endif #endif
#ifndef NO_DB_OPS_STATS #ifndef NO_DB_OPS_STATS
/* /*
* stats: do account for allocations * stats: do account for allocations
* displayed in db_ops_show_status() * displayed in db_ops_show_status()
*/ */
struct db_ops_stats { struct db_ops_stats {
int st_curr_cnt; /* current number of allocations */ int st_curr_cnt; /* current number of allocations */
int st_total_cnt; /* total allocations so far */ int st_total_cnt; /* total allocations so far */
size_t st_maxsz; /* max. size requested */ size_t st_maxsz; /* max. size requested */
}; };
#define DB_OPS_ZERO { 0, 0, 0}; #define DB_OPS_ZERO { 0, 0, 0};
#define DB_OPS_STATS_DESC "{curr_cnt, total_cnt, maxsz}" #define DB_OPS_STATS_DESC "{curr_cnt, total_cnt, maxsz}"
@@ -104,14 +104,14 @@ static struct db_ops_stats db_trans_st = DB_OPS_ZERO;
static struct db_ops_stats db_attrs_st = DB_OPS_ZERO; static struct db_ops_stats db_attrs_st = DB_OPS_ZERO;
static __inline__ void *malloc_bytes_st(size_t size, struct db_ops_stats *st) static __inline__ void *malloc_bytes_st(size_t size, struct db_ops_stats *st)
{ {
void *ptr = malloc(size); void *ptr = malloc(size);
if (ptr) if (ptr)
{ {
st->st_curr_cnt++; st->st_curr_cnt++;
st->st_total_cnt++; st->st_total_cnt++;
if (size > st->st_maxsz) st->st_maxsz=size; if (size > st->st_maxsz) st->st_maxsz=size;
} }
return ptr; return ptr;
} }
#define ALLOC_BYTES_ST(z,st) malloc_bytes_st(z, &st); #define ALLOC_BYTES_ST(z,st) malloc_bytes_st(z, &st);
#define PFREE_ST(p,st) do { st.st_curr_cnt--; free(p); } while (0); #define PFREE_ST(p,st) do { st.st_curr_cnt--; free(p); } while (0);
@@ -122,220 +122,220 @@ static __inline__ void *malloc_bytes_st(size_t size, struct db_ops_stats *st)
#define PFREE_ST(p,n) free(p); #define PFREE_ST(p,n) free(p);
#endif /* NO_DB_OPS_STATS */ #endif /* NO_DB_OPS_STATS */
/* Initialize db object /* Initialize db object
* max_trans and max_attrs can be 0, will be dynamically expanded * max_trans and max_attrs can be 0, will be dynamically expanded
* as a result of "add" operations * as a result of "add" operations
*/ */
int int
db_prop_init(struct db_context *ctx, u_int8_t protoid, int max_trans, int max_attrs) db_prop_init(struct db_context *ctx, u_int8_t protoid, int max_trans, int max_attrs)
{ {
int ret=-1; int ret=-1;
ctx->trans0 = NULL;
ctx->attrs0 = NULL;
if (max_trans > 0) { /* quite silly if not */
ctx->trans0 = ALLOC_BYTES_ST ( sizeof(struct db_trans) * max_trans,
db_trans_st);
memset(ctx->trans0, '\0', sizeof(struct db_trans) * max_trans);
}
if (max_attrs > 0) { /* quite silly if not */
ctx->attrs0 = ALLOC_BYTES_ST (sizeof(struct db_attr) * max_attrs,
db_attrs_st);
memset(ctx->attrs0, '\0', sizeof(struct db_attr) * max_attrs);
}
ret = 0;
out:
if (ret < 0 && ctx->trans0) {
PFREE_ST(ctx->trans0, db_trans_st);
ctx->trans0 = NULL; ctx->trans0 = NULL;
} ctx->attrs0 = NULL;
ctx->max_trans = max_trans;
ctx->max_attrs = max_attrs; if (max_trans > 0) { /* quite silly if not */
ctx->trans_cur = ctx->trans0; ctx->trans0 = ALLOC_BYTES_ST ( sizeof(struct db_trans) * max_trans,
ctx->attrs_cur = ctx->attrs0; db_trans_st);
ctx->prop.protoid = protoid; memset(ctx->trans0, '\0', sizeof(struct db_trans) * max_trans);
ctx->prop.trans = ctx->trans0; }
ctx->prop.trans_cnt = 0;
return ret; if (max_attrs > 0) { /* quite silly if not */
ctx->attrs0 = ALLOC_BYTES_ST (sizeof(struct db_attr) * max_attrs,
db_attrs_st);
memset(ctx->attrs0, '\0', sizeof(struct db_attr) * max_attrs);
}
ret = 0;
out:
if (ret < 0 && ctx->trans0) {
PFREE_ST(ctx->trans0, db_trans_st);
ctx->trans0 = NULL;
}
ctx->max_trans = max_trans;
ctx->max_attrs = max_attrs;
ctx->trans_cur = ctx->trans0;
ctx->attrs_cur = ctx->attrs0;
ctx->prop.protoid = protoid;
ctx->prop.trans = ctx->trans0;
ctx->prop.trans_cnt = 0;
return ret;
} }
/* Expand storage for transforms by number delta_trans */ /* Expand storage for transforms by number delta_trans */
static int static int
db_trans_expand(struct db_context *ctx, int delta_trans) db_trans_expand(struct db_context *ctx, int delta_trans)
{ {
int ret = -1; int ret = -1;
struct db_trans *new_trans, *old_trans; struct db_trans *new_trans, *old_trans;
int max_trans = ctx->max_trans + delta_trans; int max_trans = ctx->max_trans + delta_trans;
int offset; int offset;
old_trans = ctx->trans0; old_trans = ctx->trans0;
new_trans = ALLOC_BYTES_ST ( sizeof (struct db_trans) * max_trans, new_trans = ALLOC_BYTES_ST ( sizeof (struct db_trans) * max_trans,
db_trans_st); db_trans_st);
if (!new_trans) if (!new_trans)
goto out; goto out;
memcpy(new_trans, old_trans, ctx->max_trans * sizeof(struct db_trans)); memcpy(new_trans, old_trans, ctx->max_trans * sizeof(struct db_trans));
/* update trans0 (obviously) */ /* update trans0 (obviously) */
ctx->trans0 = ctx->prop.trans = new_trans; ctx->trans0 = ctx->prop.trans = new_trans;
/* update trans_cur (by offset) */ /* update trans_cur (by offset) */
offset = (char *)(new_trans) - (char *)(old_trans); offset = (char *)(new_trans) - (char *)(old_trans);
{ {
char *cctx = (char *)(ctx->trans_cur); char *cctx = (char *)(ctx->trans_cur);
cctx += offset; cctx += offset;
ctx->trans_cur = (struct db_trans *)cctx; ctx->trans_cur = (struct db_trans *)cctx;
} }
/* update elem count */ /* update elem count */
ctx->max_trans = max_trans; ctx->max_trans = max_trans;
PFREE_ST(old_trans, db_trans_st); PFREE_ST(old_trans, db_trans_st);
ret = 0; ret = 0;
out: out:
return ret; return ret;
} }
/* /*
* Expand storage for attributes by delta_attrs number AND * Expand storage for attributes by delta_attrs number AND
* rewrite trans->attr pointers * rewrite trans->attr pointers
*/ */
static int static int
db_attrs_expand(struct db_context *ctx, int delta_attrs) db_attrs_expand(struct db_context *ctx, int delta_attrs)
{ {
int ret = -1; int ret = -1;
struct db_attr *new_attrs, *old_attrs; struct db_attr *new_attrs, *old_attrs;
struct db_trans *t; struct db_trans *t;
int ti; int ti;
int max_attrs = ctx->max_attrs + delta_attrs; int max_attrs = ctx->max_attrs + delta_attrs;
int offset; int offset;
old_attrs = ctx->attrs0; old_attrs = ctx->attrs0;
new_attrs = ALLOC_BYTES_ST ( sizeof (struct db_attr) * max_attrs, new_attrs = ALLOC_BYTES_ST ( sizeof (struct db_attr) * max_attrs,
db_attrs_st); db_attrs_st);
if (!new_attrs) if (!new_attrs)
goto out; goto out;
memcpy(new_attrs, old_attrs, ctx->max_attrs * sizeof(struct db_attr)); memcpy(new_attrs, old_attrs, ctx->max_attrs * sizeof(struct db_attr));
/* update attrs0 and attrs_cur (obviously) */ /* update attrs0 and attrs_cur (obviously) */
offset = (char *)(new_attrs) - (char *)(old_attrs); offset = (char *)(new_attrs) - (char *)(old_attrs);
{ {
char *actx = (char *)(ctx->attrs0); char *actx = (char *)(ctx->attrs0);
actx += offset; actx += offset;
ctx->attrs0 = (struct db_attr *)actx; ctx->attrs0 = (struct db_attr *)actx;
actx = (char *)ctx->attrs_cur; actx = (char *)ctx->attrs_cur;
actx += offset; actx += offset;
ctx->attrs_cur = (struct db_attr *)actx; ctx->attrs_cur = (struct db_attr *)actx;
} }
/* for each transform, rewrite attrs pointer by offsetting it */ /* for each transform, rewrite attrs pointer by offsetting it */
for (t=ctx->prop.trans, ti=0; ti < ctx->prop.trans_cnt; t++, ti++) { for (t=ctx->prop.trans, ti=0; ti < ctx->prop.trans_cnt; t++, ti++) {
char *actx = (char *)(t->attrs); char *actx = (char *)(t->attrs);
actx += offset; actx += offset;
t->attrs = (struct db_attr *)actx; t->attrs = (struct db_attr *)actx;
} }
/* update elem count */ /* update elem count */
ctx->max_attrs = max_attrs; ctx->max_attrs = max_attrs;
PFREE_ST(old_attrs, db_attrs_st); PFREE_ST(old_attrs, db_attrs_st);
ret = 0; ret = 0;
out: out:
return ret; return ret;
} }
/* Allocate a new db object */ /* Allocate a new db object */
struct db_context * struct db_context *
db_prop_new(u_int8_t protoid, int max_trans, int max_attrs) db_prop_new(u_int8_t protoid, int max_trans, int max_attrs)
{ {
struct db_context *ctx; struct db_context *ctx;
ctx = ALLOC_BYTES_ST ( sizeof (struct db_context), db_context_st); ctx = ALLOC_BYTES_ST ( sizeof (struct db_context), db_context_st);
if (!ctx) goto out; if (!ctx) goto out;
if (db_prop_init(ctx, protoid, max_trans, max_attrs) < 0) { if (db_prop_init(ctx, protoid, max_trans, max_attrs) < 0) {
PFREE_ST(ctx, db_context_st); PFREE_ST(ctx, db_context_st);
ctx=NULL; ctx=NULL;
} }
out: out:
return ctx; return ctx;
} }
/* Free a db object */ /* Free a db object */
void void
db_destroy(struct db_context *ctx) db_destroy(struct db_context *ctx)
{ {
if (ctx->trans0) PFREE_ST(ctx->trans0, db_trans_st); if (ctx->trans0) PFREE_ST(ctx->trans0, db_trans_st);
if (ctx->attrs0) PFREE_ST(ctx->attrs0, db_attrs_st); if (ctx->attrs0) PFREE_ST(ctx->attrs0, db_attrs_st);
PFREE_ST(ctx, db_context_st); PFREE_ST(ctx, db_context_st);
} }
/* Start a new transform, expand trans0 is needed */ /* Start a new transform, expand trans0 is needed */
int int
db_trans_add(struct db_context *ctx, u_int8_t transid) db_trans_add(struct db_context *ctx, u_int8_t transid)
{ {
/* skip incrementing current trans pointer the 1st time*/ /* skip incrementing current trans pointer the 1st time*/
if (ctx->trans_cur && ctx->trans_cur->attr_cnt) if (ctx->trans_cur && ctx->trans_cur->attr_cnt)
ctx->trans_cur++; ctx->trans_cur++;
/* /*
* Strategy: if more space is needed, expand by * Strategy: if more space is needed, expand by
* <current_size>/2 + 1 * <current_size>/2 + 1
* *
* This happens to produce a "reasonable" sequence * This happens to produce a "reasonable" sequence
* after few allocations, eg.: * after few allocations, eg.:
* 0,1,2,4,8,13,20,31,47 * 0,1,2,4,8,13,20,31,47
*/ */
if ((ctx->trans_cur - ctx->trans0) >= ctx->max_trans) { if ((ctx->trans_cur - ctx->trans0) >= ctx->max_trans) {
/* XXX:jjo if fails should shout and flag it */ /* XXX:jjo if fails should shout and flag it */
if (db_trans_expand(ctx, ctx->max_trans/2 + 1)<0) if (db_trans_expand(ctx, ctx->max_trans/2 + 1)<0)
return -1; return -1;
} }
ctx->trans_cur->transid = transid; ctx->trans_cur->transid = transid;
ctx->trans_cur->attrs=ctx->attrs_cur; ctx->trans_cur->attrs=ctx->attrs_cur;
ctx->trans_cur->attr_cnt = 0; ctx->trans_cur->attr_cnt = 0;
ctx->prop.trans_cnt++; ctx->prop.trans_cnt++;
return 0; return 0;
} }
/* Add attr copy to current transform, expanding attrs0 if needed */ /* Add attr copy to current transform, expanding attrs0 if needed */
int int
db_attr_add(struct db_context *ctx, const struct db_attr *a) db_attr_add(struct db_context *ctx, const struct db_attr *a)
{ {
/* /*
* Strategy: if more space is needed, expand by * Strategy: if more space is needed, expand by
* <current_size>/2 + 1 * <current_size>/2 + 1
*/ */
if ((ctx->attrs_cur - ctx->attrs0) >= ctx->max_attrs) { if ((ctx->attrs_cur - ctx->attrs0) >= ctx->max_attrs) {
/* XXX:jjo if fails should shout and flag it */ /* XXX:jjo if fails should shout and flag it */
if (db_attrs_expand(ctx, ctx->max_attrs/2 + 1) < 0) if (db_attrs_expand(ctx, ctx->max_attrs/2 + 1) < 0)
return -1; return -1;
} }
*ctx->attrs_cur++=*a; *ctx->attrs_cur++=*a;
ctx->trans_cur->attr_cnt++; ctx->trans_cur->attr_cnt++;
return 0; return 0;
} }
/* Add attr copy (by value) to current transform, /* Add attr copy (by value) to current transform,
* expanding attrs0 if needed, just calls db_attr_add(). * expanding attrs0 if needed, just calls db_attr_add().
*/ */
int int
db_attr_add_values(struct db_context *ctx, u_int16_t type, u_int16_t val) db_attr_add_values(struct db_context *ctx, u_int16_t type, u_int16_t val)
{ {
struct db_attr attr; struct db_attr attr;
attr.type = type; attr.type = type;
attr.val = val; attr.val = val;
return db_attr_add (ctx, &attr); return db_attr_add (ctx, &attr);
} }
#ifndef NO_DB_OPS_STATS #ifndef NO_DB_OPS_STATS
int int
db_ops_show_status(void) db_ops_show_status(void)
{ {
whack_log(RC_COMMENT, "stats " __FILE__ ": " whack_log(RC_COMMENT, "stats " __FILE__ ": "
DB_OPS_STATS_DESC " :" DB_OPS_STATS_DESC " :"
DB_OPS_STATS_STR("context") DB_OPS_STATS_STR("context")
DB_OPS_STATS_STR("trans") DB_OPS_STATS_STR("trans")
DB_OPS_STATS_STR("attrs"), DB_OPS_STATS_STR("attrs"),
DB_OPS_STATS_F(db_context_st), DB_OPS_STATS_F(db_context_st),
DB_OPS_STATS_F(db_trans_st), DB_OPS_STATS_F(db_trans_st),
DB_OPS_STATS_F(db_attrs_st) DB_OPS_STATS_F(db_attrs_st)
); );
return 0; return 0;
} }
#endif /* NO_DB_OPS_STATS */ #endif /* NO_DB_OPS_STATS */
/* /*
@@ -344,51 +344,51 @@ db_ops_show_status(void)
#ifdef TEST #ifdef TEST
static void db_prop_print(struct db_prop *p) static void db_prop_print(struct db_prop *p)
{ {
struct db_trans *t; struct db_trans *t;
struct db_attr *a; struct db_attr *a;
int ti, ai; int ti, ai;
enum_names *n, *n_at, *n_av; enum_names *n, *n_at, *n_av;
printf("protoid=\"%s\"\n", enum_name(&protocol_names, p->protoid)); printf("protoid=\"%s\"\n", enum_name(&protocol_names, p->protoid));
for (ti=0, t=p->trans; ti< p->trans_cnt; ti++, t++) { for (ti=0, t=p->trans; ti< p->trans_cnt; ti++, t++) {
switch( t->transid) { switch( t->transid) {
case PROTO_ISAKMP: case PROTO_ISAKMP:
n=&isakmp_transformid_names;break; n=&isakmp_transformid_names;break;
case PROTO_IPSEC_ESP: case PROTO_IPSEC_ESP:
n=&esp_transformid_names;break; n=&esp_transformid_names;break;
default: default:
continue; continue;
}
printf(" transid=\"%s\"\n",
enum_name(n, t->transid));
for (ai=0, a=t->attrs; ai < t->attr_cnt; ai++, a++) {
int i;
switch( t->transid) {
case PROTO_ISAKMP:
n_at=&oakley_attr_names;
i=a->type|ISAKMP_ATTR_AF_TV;
n_av=oakley_attr_val_descs[(i)&ISAKMP_ATTR_RTYPE_MASK];
break;
case PROTO_IPSEC_ESP:
n_at=&ipsec_attr_names;
i=a->type|ISAKMP_ATTR_AF_TV;
n_av=ipsec_attr_val_descs[(i)&ISAKMP_ATTR_RTYPE_MASK];
break;
default:
continue;
}
printf(" type=\"%s\" value=\"%s\"\n",
enum_name(n_at, i),
enum_name(n_av, a->val));
}
} }
printf(" transid=\"%s\"\n",
enum_name(n, t->transid));
for (ai=0, a=t->attrs; ai < t->attr_cnt; ai++, a++) {
int i;
switch( t->transid) {
case PROTO_ISAKMP:
n_at=&oakley_attr_names;
i=a->type|ISAKMP_ATTR_AF_TV;
n_av=oakley_attr_val_descs[(i)&ISAKMP_ATTR_RTYPE_MASK];
break;
case PROTO_IPSEC_ESP:
n_at=&ipsec_attr_names;
i=a->type|ISAKMP_ATTR_AF_TV;
n_av=ipsec_attr_val_descs[(i)&ISAKMP_ATTR_RTYPE_MASK];
break;
default:
continue;
}
printf(" type=\"%s\" value=\"%s\"\n",
enum_name(n_at, i),
enum_name(n_av, a->val));
}
}
} }
static void db_print(struct db_context *ctx) static void db_print(struct db_context *ctx)
{ {
printf("trans_cur diff=%d, attrs_cur diff=%d\n", printf("trans_cur diff=%d, attrs_cur diff=%d\n",
ctx->trans_cur - ctx->trans0, ctx->trans_cur - ctx->trans0,
ctx->attrs_cur - ctx->attrs0); ctx->attrs_cur - ctx->attrs0);
db_prop_print(&ctx->prop); db_prop_print(&ctx->prop);
} }
void void
@@ -397,25 +397,25 @@ void abort(void);
void void
passert_fail(const char *pred_str, const char *file_str, unsigned long line_no) passert_fail(const char *pred_str, const char *file_str, unsigned long line_no)
{ {
fprintf(stderr, "ASSERTION FAILED at %s:%lu: %s", file_str, line_no, pred_str); fprintf(stderr, "ASSERTION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
abort(); /* exiting correctly doesn't always work */ abort(); /* exiting correctly doesn't always work */
} }
int main(void) { int main(void) {
struct db_context *ctx=db_prop_new(PROTO_ISAKMP, 0, 0); struct db_context *ctx=db_prop_new(PROTO_ISAKMP, 0, 0);
db_trans_add(ctx, KEY_IKE); db_trans_add(ctx, KEY_IKE);
db_attr_add_values(ctx, OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC); db_attr_add_values(ctx, OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC);
db_attr_add_values(ctx, OAKLEY_HASH_ALGORITHM, OAKLEY_MD5); db_attr_add_values(ctx, OAKLEY_HASH_ALGORITHM, OAKLEY_MD5);
db_attr_add_values(ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG); db_attr_add_values(ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG);
db_attr_add_values(ctx, OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024); db_attr_add_values(ctx, OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024);
db_trans_add(ctx, KEY_IKE); db_trans_add(ctx, KEY_IKE);
db_attr_add_values(ctx, OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_AES_CBC); db_attr_add_values(ctx, OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_AES_CBC);
db_attr_add_values(ctx, OAKLEY_HASH_ALGORITHM, OAKLEY_MD5); db_attr_add_values(ctx, OAKLEY_HASH_ALGORITHM, OAKLEY_MD5);
db_attr_add_values(ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY); db_attr_add_values(ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY);
db_attr_add_values(ctx, OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536); db_attr_add_values(ctx, OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536);
db_trans_add(ctx, ESP_3DES); db_trans_add(ctx, ESP_3DES);
db_attr_add_values(ctx, AUTH_ALGORITHM, AUTH_ALGORITHM_HMAC_SHA1); db_attr_add_values(ctx, AUTH_ALGORITHM, AUTH_ALGORITHM_HMAC_SHA1);
db_print(ctx); db_print(ctx);
db_destroy(ctx); db_destroy(ctx);
return 0; return 0;
} }
#endif #endif
+17 -17
View File
@@ -18,39 +18,39 @@
#define _DB_OPS_H #define _DB_OPS_H
/* /*
* Main db object, (quite proposal "oriented") * Main db object, (quite proposal "oriented")
*/ */
#ifndef NO_DB_CONTEXT #ifndef NO_DB_CONTEXT
struct db_context { struct db_context {
struct db_prop prop; /* proposal buffer (not pointer) */ struct db_prop prop; /* proposal buffer (not pointer) */
struct db_trans *trans0; /* transf. list, dynamically sized */ struct db_trans *trans0; /* transf. list, dynamically sized */
struct db_trans *trans_cur; /* current transform ptr */ struct db_trans *trans_cur; /* current transform ptr */
struct db_attr *attrs0; /* attr. list, dynamically sized */ struct db_attr *attrs0; /* attr. list, dynamically sized */
struct db_attr *attrs_cur; /* current attribute ptr */ struct db_attr *attrs_cur; /* current attribute ptr */
int max_trans; /* size of trans list */ int max_trans; /* size of trans list */
int max_attrs; /* size of attrs list */ int max_attrs; /* size of attrs list */
}; };
/* /*
* Allocate a new db object * Allocate a new db object
*/ */
struct db_context * db_prop_new(u_int8_t protoid, int max_trans, int max_attrs); struct db_context * db_prop_new(u_int8_t protoid, int max_trans, int max_attrs);
/* Initialize object for proposal building */ /* Initialize object for proposal building */
int db_prop_init(struct db_context *ctx, u_int8_t protoid, int max_trans, int max_attrs); int db_prop_init(struct db_context *ctx, u_int8_t protoid, int max_trans, int max_attrs);
/* Free all resourses for this db */ /* Free all resourses for this db */
void db_destroy(struct db_context *ctx); void db_destroy(struct db_context *ctx);
/* Start a new transform */ /* Start a new transform */
int db_trans_add(struct db_context *ctx, u_int8_t transid); int db_trans_add(struct db_context *ctx, u_int8_t transid);
/* Add a new attribute by copying db_attr content */ /* Add a new attribute by copying db_attr content */
int db_attr_add(struct db_context *db_ctx, const struct db_attr *attr); int db_attr_add(struct db_context *db_ctx, const struct db_attr *attr);
/* Add a new attribute by value */ /* Add a new attribute by value */
int db_attr_add_values(struct db_context *ctx, u_int16_t type, u_int16_t val); int db_attr_add_values(struct db_context *ctx, u_int16_t type, u_int16_t val);
/* Get proposal from db object */ /* Get proposal from db object */
static __inline__ struct db_prop *db_prop_get(struct db_context *ctx) { static __inline__ struct db_prop *db_prop_get(struct db_context *ctx) {
return &ctx->prop; return &ctx->prop;
} }
/* Show stats (allocation, etc) */ /* Show stats (allocation, etc) */
#endif /* NO_DB_CONTEXT */ #endif /* NO_DB_CONTEXT */
int db_ops_show_status(void); int db_ops_show_status(void);
#endif /* _DB_OPS_H */ #endif /* _DB_OPS_H */
+93 -93
View File
@@ -27,25 +27,25 @@
#include "constants.h" #include "constants.h"
#include "defs.h" #include "defs.h"
#include "log.h" #include "log.h"
#include "whack.h" /* for RC_LOG_SERIOUS */ #include "whack.h" /* for RC_LOG_SERIOUS */
bool bool
all_zero(const unsigned char *m, size_t len) all_zero(const unsigned char *m, size_t len)
{ {
size_t i; size_t i;
for (i = 0; i != len; i++) for (i = 0; i != len; i++)
if (m[i] != '\0') if (m[i] != '\0')
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
void *clone_bytes(const void *orig, size_t size) void *clone_bytes(const void *orig, size_t size)
{ {
void *p = malloc(size); void *p = malloc(size);
memcpy(p, orig, size); memcpy(p, orig, size);
return p; return p;
} }
/* Note that there may be as many as six IDs that are temporary at /* Note that there may be as many as six IDs that are temporary at
@@ -53,16 +53,16 @@ void *clone_bytes(const void *orig, size_t size)
* at least six temporary buffers for DER_ASN1_DN IDs. * at least six temporary buffers for DER_ASN1_DN IDs.
* We rotate them. Be careful! * We rotate them. Be careful!
*/ */
#define MAX_BUF 10 #define MAX_BUF 10
char* char*
temporary_cyclic_buffer(void) temporary_cyclic_buffer(void)
{ {
static char buf[MAX_BUF][BUF_LEN]; /* MAX_BUF internal buffers */ static char buf[MAX_BUF][BUF_LEN]; /* MAX_BUF internal buffers */
static int counter = 0; /* cyclic counter */ static int counter = 0; /* cyclic counter */
if (++counter == MAX_BUF) counter = 0; /* next internal buffer */ if (++counter == MAX_BUF) counter = 0; /* next internal buffer */
return buf[counter]; /* assign temporary buffer */ return buf[counter]; /* assign temporary buffer */
} }
/* concatenates two sub paths into a string with a maximum size of BUF_LEN /* concatenates two sub paths into a string with a maximum size of BUF_LEN
@@ -71,14 +71,14 @@ temporary_cyclic_buffer(void)
const char* const char*
concatenate_paths(const char *a, const char *b) concatenate_paths(const char *a, const char *b)
{ {
char *c; char *c;
if (*b == '/' || *b == '.') if (*b == '/' || *b == '.')
return b; return b;
c = temporary_cyclic_buffer(); c = temporary_cyclic_buffer();
snprintf(c, BUF_LEN, "%s/%s", a, b); snprintf(c, BUF_LEN, "%s/%s", a, b);
return c; return c;
} }
/* moves a chunk to a memory position, chunk is freed afterwards /* moves a chunk to a memory position, chunk is freed afterwards
@@ -87,11 +87,11 @@ concatenate_paths(const char *a, const char *b)
void void
mv_chunk(u_char **pos, chunk_t content) mv_chunk(u_char **pos, chunk_t content)
{ {
if (content.len > 0) if (content.len > 0)
{ {
chunkcpy(*pos, content); chunkcpy(*pos, content);
free(content.ptr); free(content.ptr);
} }
} }
/* /*
@@ -101,46 +101,46 @@ bool
write_chunk(const char *filename, const char *label, chunk_t ch write_chunk(const char *filename, const char *label, chunk_t ch
, mode_t mask, bool force) , mode_t mask, bool force)
{ {
mode_t oldmask; mode_t oldmask;
FILE *fd; FILE *fd;
size_t written; size_t written;
if (!force)
{
fd = fopen(filename, "r");
if (fd)
{
fclose(fd);
plog(" %s file '%s' already exists", label, filename);
return FALSE;
}
}
/* set umask */
oldmask = umask(mask);
fd = fopen(filename, "w");
if (!force)
{
fd = fopen(filename, "r");
if (fd) if (fd)
{ {
fclose(fd); written = fwrite(ch.ptr, sizeof(u_char), ch.len, fd);
plog(" %s file '%s' already exists", label, filename); fclose(fd);
return FALSE; if (written != ch.len)
{
plog(" writing to %s file '%s' failed", label, filename);
umask(oldmask);
return FALSE;
}
plog(" written %s file '%s' (%d bytes)", label, filename, (int)ch.len);
umask(oldmask);
return TRUE;
} }
} else
/* set umask */
oldmask = umask(mask);
fd = fopen(filename, "w");
if (fd)
{
written = fwrite(ch.ptr, sizeof(u_char), ch.len, fd);
fclose(fd);
if (written != ch.len)
{ {
plog(" writing to %s file '%s' failed", label, filename); plog(" could not open %s file '%s' for writing", label, filename);
umask(oldmask); umask(oldmask);
return FALSE; return FALSE;
} }
plog(" written %s file '%s' (%d bytes)", label, filename, (int)ch.len);
umask(oldmask);
return TRUE;
}
else
{
plog(" could not open %s file '%s' for writing", label, filename);
umask(oldmask);
return FALSE;
}
} }
/* checks if the expiration date has been reached and /* checks if the expiration date has been reached and
@@ -151,44 +151,44 @@ write_chunk(const char *filename, const char *label, chunk_t ch
const char* const char*
check_expiry(time_t expiration_date, int warning_interval, bool strict) check_expiry(time_t expiration_date, int warning_interval, bool strict)
{ {
time_t now; time_t now;
int time_left; int time_left;
if (expiration_date == UNDEFINED_TIME) if (expiration_date == UNDEFINED_TIME)
return "ok (expires never)"; return "ok (expires never)";
/* determine the current time */ /* determine the current time */
time(&now); time(&now);
time_left = (expiration_date - now); time_left = (expiration_date - now);
if (time_left < 0) if (time_left < 0)
return strict? "fatal (expired)" : "warning (expired)"; return strict? "fatal (expired)" : "warning (expired)";
if (time_left > 86400*warning_interval) if (time_left > 86400*warning_interval)
return "ok"; return "ok";
{
static char buf[35]; /* temporary storage */
const char* unit = "second";
if (time_left > 172800)
{ {
time_left /= 86400; static char buf[35]; /* temporary storage */
unit = "day"; const char* unit = "second";
if (time_left > 172800)
{
time_left /= 86400;
unit = "day";
}
else if (time_left > 7200)
{
time_left /= 3600;
unit = "hour";
}
else if (time_left > 120)
{
time_left /= 60;
unit = "minute";
}
snprintf(buf, 35, "warning (expires in %d %s%s)", time_left,
unit, (time_left == 1)?"":"s");
return buf;
} }
else if (time_left > 7200)
{
time_left /= 3600;
unit = "hour";
}
else if (time_left > 120)
{
time_left /= 60;
unit = "minute";
}
snprintf(buf, 35, "warning (expires in %d %s%s)", time_left,
unit, (time_left == 1)?"":"s");
return buf;
}
} }
@@ -198,8 +198,8 @@ check_expiry(time_t expiration_date, int warning_interval, bool strict)
int int
file_select(const struct dirent *entry) file_select(const struct dirent *entry)
{ {
return strcmp(entry->d_name, "." ) && return strcmp(entry->d_name, "." ) &&
strcmp(entry->d_name, ".."); strcmp(entry->d_name, "..");
} }
+17 -17
View File
@@ -24,23 +24,23 @@
#include <chunk.h> #include <chunk.h>
#ifdef KLIPS #ifdef KLIPS
# define USED_BY_KLIPS /* ignore */ # define USED_BY_KLIPS /* ignore */
#else #else
# define USED_BY_KLIPS UNUSED # define USED_BY_KLIPS UNUSED
#endif #endif
#ifdef DEBUG #ifdef DEBUG
# define USED_BY_DEBUG /* ignore */ # define USED_BY_DEBUG /* ignore */
#else #else
# define USED_BY_DEBUG UNUSED # define USED_BY_DEBUG UNUSED
#endif #endif
/* type of serial number of a state object /* type of serial number of a state object
* Needed in connections.h and state.h; here to simplify dependencies. * Needed in connections.h and state.h; here to simplify dependencies.
*/ */
typedef unsigned long so_serial_t; typedef unsigned long so_serial_t;
#define SOS_NOBODY 0 /* null serial number */ #define SOS_NOBODY 0 /* null serial number */
#define SOS_FIRST 1 /* first normal serial number */ #define SOS_FIRST 1 /* first normal serial number */
/* memory allocation */ /* memory allocation */
@@ -49,13 +49,13 @@ extern void *clone_bytes(const void *orig, size_t size);
#define clone_thing(orig) clone_bytes((const void *)&(orig), sizeof(orig)) #define clone_thing(orig) clone_bytes((const void *)&(orig), sizeof(orig))
#define clone_str(str) \ #define clone_str(str) \
((str) == NULL? NULL : strdup(str)) ((str) == NULL? NULL : strdup(str))
#define replace(p, q) \ #define replace(p, q) \
{ free(p); (p) = (q); } { free(p); (p) = (q); }
#define chunkcpy(dst, chunk) \ #define chunkcpy(dst, chunk) \
{ memcpy(dst, chunk.ptr, chunk.len); dst += chunk.len;} { memcpy(dst, chunk.ptr, chunk.len); dst += chunk.len;}
extern char* temporary_cyclic_buffer(void); extern char* temporary_cyclic_buffer(void);
extern const char* concatenate_paths(const char *a, const char *b); extern const char* concatenate_paths(const char *a, const char *b);
@@ -65,26 +65,26 @@ extern void mv_chunk(u_char **pos, chunk_t content);
/* write the binary contents of a chunk_t to a file */ /* write the binary contents of a chunk_t to a file */
extern bool write_chunk(const char *filename, const char *label, chunk_t ch extern bool write_chunk(const char *filename, const char *label, chunk_t ch
,mode_t mask, bool force); ,mode_t mask, bool force);
/* warns a predefined interval before expiry */ /* warns a predefined interval before expiry */
extern const char* check_expiry(time_t expiration_date, extern const char* check_expiry(time_t expiration_date,
int warning_interval, bool strict); int warning_interval, bool strict);
#define MAX_PROMPT_PASS_TRIALS 5 #define MAX_PROMPT_PASS_TRIALS 5
#define PROMPT_PASS_LEN 64 #define PROMPT_PASS_LEN 64
/* struct used to prompt for a secret passphrase /* struct used to prompt for a secret passphrase
* from a console with file descriptor fd * from a console with file descriptor fd
*/ */
typedef struct { typedef struct {
char secret[PROMPT_PASS_LEN+1]; char secret[PROMPT_PASS_LEN+1];
bool prompt; bool prompt;
int fd; int fd;
} prompt_pass_t; } prompt_pass_t;
/* size of timetoa string buffer */ /* size of timetoa string buffer */
#define TIMETOA_BUF 30 #define TIMETOA_BUF 30
/* filter eliminating the directory entries '.' and '..' */ /* filter eliminating the directory entries '.' and '..' */
typedef struct dirent dirent_t; typedef struct dirent dirent_t;
+1930 -1930
View File
File diff suppressed because it is too large Load Diff
+31 -31
View File
@@ -16,7 +16,7 @@
#include "packet.h" #include "packet.h"
struct state; /* forward declaration of tag */ struct state; /* forward declaration of tag */
extern void init_demux(void); extern void init_demux(void);
extern bool send_packet(struct state *st, const char *where); extern bool send_packet(struct state *st, const char *where);
extern void comm_handle(const struct iface *ifp); extern void comm_handle(const struct iface *ifp);
@@ -36,9 +36,9 @@ extern u_int8_t reply_buffer[MAX_OUTPUT_UDP_SIZE];
*/ */
struct payload_digest { struct payload_digest {
pb_stream pbs; pb_stream pbs;
union payload payload; union payload payload;
struct payload_digest *next; /* of same kind */ struct payload_digest *next; /* of same kind */
}; };
/* message digest /* message digest
@@ -46,30 +46,30 @@ struct payload_digest {
*/ */
struct msg_digest { struct msg_digest {
struct msg_digest *next; /* for free list */ struct msg_digest *next; /* for free list */
chunk_t raw_packet; /* if encrypted, received packet before decryption */ chunk_t raw_packet; /* if encrypted, received packet before decryption */
const struct iface *iface; /* interface on which message arrived */ const struct iface *iface; /* interface on which message arrived */
ip_address sender; /* where message came from */ ip_address sender; /* where message came from */
u_int16_t sender_port; /* host order */ u_int16_t sender_port; /* host order */
pb_stream packet_pbs; /* whole packet */ pb_stream packet_pbs; /* whole packet */
pb_stream message_pbs; /* message to be processed */ pb_stream message_pbs; /* message to be processed */
struct isakmp_hdr hdr; /* message's header */ struct isakmp_hdr hdr; /* message's header */
bool encrypted; /* was it encrypted? */ bool encrypted; /* was it encrypted? */
enum state_kind from_state; /* state we started in */ enum state_kind from_state; /* state we started in */
const struct state_microcode *smc; /* microcode for initial state */ const struct state_microcode *smc; /* microcode for initial state */
struct state *st; /* current state object */ struct state *st; /* current state object */
pb_stream reply; /* room for reply */ pb_stream reply; /* room for reply */
pb_stream rbody; /* room for reply body (after header) */ pb_stream rbody; /* room for reply body (after header) */
notification_t note; /* reason for failure */ notification_t note; /* reason for failure */
bool dpd; /* peer supports RFC 3706 DPD */ bool dpd; /* peer supports RFC 3706 DPD */
bool openpgp; /* peer supports OpenPGP certificates */ bool openpgp; /* peer supports OpenPGP certificates */
# define PAYLIMIT 40 # define PAYLIMIT 40
struct payload_digest struct payload_digest
digest[PAYLIMIT], digest[PAYLIMIT],
*digest_roof, *digest_roof,
*chain[ISAKMP_NEXT_ROOF]; *chain[ISAKMP_NEXT_ROOF];
unsigned short nat_traversal_vid; unsigned short nat_traversal_vid;
}; };
extern void release_md(struct msg_digest *md); extern void release_md(struct msg_digest *md);
@@ -79,11 +79,11 @@ extern void release_md(struct msg_digest *md);
*/ */
typedef enum { typedef enum {
STF_IGNORE, /* don't respond */ STF_IGNORE, /* don't respond */
STF_SUSPEND, /* unfinished -- don't release resources */ STF_SUSPEND, /* unfinished -- don't release resources */
STF_OK, /* success */ STF_OK, /* success */
STF_INTERNAL_ERROR, /* discard everything, we failed */ STF_INTERNAL_ERROR, /* discard everything, we failed */
STF_FAIL /* discard everything, something failed. notification_t added. */ STF_FAIL /* discard everything, something failed. notification_t added. */
} stf_status; } stf_status;
typedef stf_status state_transition_fn(struct msg_digest *md); typedef stf_status state_transition_fn(struct msg_digest *md);
+1257 -1257
View File
File diff suppressed because it is too large Load Diff
+34 -34
View File
@@ -15,9 +15,9 @@
*/ */
extern int extern int
adns_qfd, /* file descriptor for sending queries to adns */ adns_qfd, /* file descriptor for sending queries to adns */
adns_afd; /* file descriptor for receiving answers from adns */ adns_afd; /* file descriptor for receiving answers from adns */
extern const char *pluto_adns_option; /* path from --pluto_adns */ extern const char *pluto_adns_option; /* path from --pluto_adns */
extern void init_adns(void); extern void init_adns(void);
extern void stop_adns(void); extern void stop_adns(void);
extern void handle_adns_answer(void); extern void handle_adns_answer(void);
@@ -30,55 +30,55 @@ extern void send_unsent_ADNS_queries(void);
* Freed by call to release_adns_continuation. * Freed by call to release_adns_continuation.
*/ */
struct adns_continuation; /* forward declaration (not far!) */ struct adns_continuation; /* forward declaration (not far!) */
typedef void (*cont_fn_t)(struct adns_continuation *cr, err_t ugh); typedef void (*cont_fn_t)(struct adns_continuation *cr, err_t ugh);
struct adns_continuation { struct adns_continuation {
unsigned long qtid; /* query transaction id number */ unsigned long qtid; /* query transaction id number */
int type; /* T_TXT or T_KEY, selecting rr type of interest */ int type; /* T_TXT or T_KEY, selecting rr type of interest */
cont_fn_t cont_fn; /* function to carry on suspended work */ cont_fn_t cont_fn; /* function to carry on suspended work */
struct id id; /* subject of query */ struct id id; /* subject of query */
bool sgw_specified; bool sgw_specified;
struct id sgw_id; /* peer, if constrained */ struct id sgw_id; /* peer, if constrained */
lset_t debugging; /* only used #ifdef DEBUG, but don't want layout to change */ lset_t debugging; /* only used #ifdef DEBUG, but don't want layout to change */
struct gw_info *gateways_from_dns; /* answer, if looking for our TXT rrs */ struct gw_info *gateways_from_dns; /* answer, if looking for our TXT rrs */
#ifdef USE_KEYRR #ifdef USE_KEYRR
struct pubkey_list *keys_from_dns; /* answer, if looking for KEY rrs */ struct pubkey_list *keys_from_dns; /* answer, if looking for KEY rrs */
#endif #endif
struct adns_continuation *previous, *next; struct adns_continuation *previous, *next;
struct pubkey *last_info; /* the last structure we accumulated */ struct pubkey *last_info; /* the last structure we accumulated */
#ifdef USE_LWRES #ifdef USE_LWRES
bool used; /* have we called the cont_fn yet? */ bool used; /* have we called the cont_fn yet? */
struct { struct {
u_char name_buf[NS_MAXDNAME + 2]; u_char name_buf[NS_MAXDNAME + 2];
} query; } query;
#else /* ! USE_LWRES */ #else /* ! USE_LWRES */
struct adns_query query; struct adns_query query;
#endif /* ! USE_LWRES */ #endif /* ! USE_LWRES */
}; };
extern err_t start_adns_query(const struct id *id /* domain to query */ extern err_t start_adns_query(const struct id *id /* domain to query */
, const struct id *sgw_id /* if non-null, any accepted gw_info must match */ , const struct id *sgw_id /* if non-null, any accepted gw_info must match */
, int type /* T_TXT or T_KEY, selecting rr type of interest */ , int type /* T_TXT or T_KEY, selecting rr type of interest */
, cont_fn_t cont_fn /* continuation function */ , cont_fn_t cont_fn /* continuation function */
, struct adns_continuation *cr); , struct adns_continuation *cr);
/* Gateway info gleaned from reverse DNS of client */ /* Gateway info gleaned from reverse DNS of client */
struct gw_info { struct gw_info {
unsigned refcnt; /* reference counted! */ unsigned refcnt; /* reference counted! */
unsigned pref; /* preference: lower is better */ unsigned pref; /* preference: lower is better */
#define NO_TIME ((time_t) -2) /* time_t value meaning "not_yet" */ #define NO_TIME ((time_t) -2) /* time_t value meaning "not_yet" */
struct id client_id; /* id of client of peer */ struct id client_id; /* id of client of peer */
struct id gw_id; /* id of peer (if id_is_ipaddr, .ip_addr is address) */ struct id gw_id; /* id of peer (if id_is_ipaddr, .ip_addr is address) */
bool gw_key_present; bool gw_key_present;
struct pubkey *key; struct pubkey *key;
struct gw_info *next; struct gw_info *next;
}; };
extern void gw_addref(struct gw_info *gw) extern void gw_addref(struct gw_info *gw)
, gw_delref(struct gw_info **gwp); , gw_delref(struct gw_info **gwp);
extern void reset_adns_restart_count(void); extern void reset_adns_restart_count(void);
+265 -265
View File
@@ -1,5 +1,5 @@
/* dsa.c - DSA signature scheme /* dsa.c - DSA signature scheme
* Copyright (C) 1998 Free Software Foundation, Inc. * Copyright (C) 1998 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@@ -44,19 +44,19 @@
#include "dsa.h" #include "dsa.h"
typedef struct { typedef struct {
MPI p; /* prime */ MPI p; /* prime */
MPI q; /* group order */ MPI q; /* group order */
MPI g; /* group generator */ MPI g; /* group generator */
MPI y; /* g^x mod p */ MPI y; /* g^x mod p */
} DSA_public_key; } DSA_public_key;
typedef struct { typedef struct {
MPI p; /* prime */ MPI p; /* prime */
MPI q; /* group order */ MPI q; /* group order */
MPI g; /* group generator */ MPI g; /* group generator */
MPI y; /* g^x mod p */ MPI y; /* g^x mod p */
MPI x; /* secret exponent */ MPI x; /* secret exponent */
} DSA_secret_key; } DSA_secret_key;
@@ -70,7 +70,7 @@ static int verify(MPI r, MPI s, MPI input, DSA_public_key *pkey);
static void static void
progress( int c ) progress( int c )
{ {
fputc( c, stderr ); fputc( c, stderr );
} }
@@ -80,82 +80,82 @@ progress( int c )
static MPI static MPI
gen_k( MPI q ) gen_k( MPI q )
{ {
MPI k = mpi_alloc_secure( mpi_get_nlimbs(q) ); MPI k = mpi_alloc_secure( mpi_get_nlimbs(q) );
unsigned int nbits = mpi_get_nbits(q); unsigned int nbits = mpi_get_nbits(q);
unsigned int nbytes = (nbits+7)/8; unsigned int nbytes = (nbits+7)/8;
char *rndbuf = NULL; char *rndbuf = NULL;
if( DBG_CIPHER )
log_debug("choosing a random k ");
for(;;) {
if( DBG_CIPHER ) if( DBG_CIPHER )
progress('.'); log_debug("choosing a random k ");
for(;;) {
if( DBG_CIPHER )
progress('.');
if( !rndbuf || nbits < 32 ) { if( !rndbuf || nbits < 32 ) {
m_free(rndbuf); m_free(rndbuf);
rndbuf = get_random_bits( nbits, 1, 1 ); rndbuf = get_random_bits( nbits, 1, 1 );
} }
else { /* change only some of the higher bits */ else { /* change only some of the higher bits */
/* we could imporove this by directly requesting more memory /* we could imporove this by directly requesting more memory
* at the first call to get_random_bits() and use this the here * at the first call to get_random_bits() and use this the here
* maybe it is easier to do this directly in random.c */ * maybe it is easier to do this directly in random.c */
char *pp = get_random_bits( 32, 1, 1 ); char *pp = get_random_bits( 32, 1, 1 );
memcpy( rndbuf,pp, 4 ); memcpy( rndbuf,pp, 4 );
m_free(pp); m_free(pp);
} }
mpi_set_buffer( k, rndbuf, nbytes, 0 ); mpi_set_buffer( k, rndbuf, nbytes, 0 );
if( mpi_test_bit( k, nbits-1 ) ) if( mpi_test_bit( k, nbits-1 ) )
mpi_set_highbit( k, nbits-1 ); mpi_set_highbit( k, nbits-1 );
else { else {
mpi_set_highbit( k, nbits-1 ); mpi_set_highbit( k, nbits-1 );
mpi_clear_bit( k, nbits-1 ); mpi_clear_bit( k, nbits-1 );
} }
if( !(mpi_cmp( k, q ) < 0) ) { /* check: k < q */ if( !(mpi_cmp( k, q ) < 0) ) { /* check: k < q */
if( DBG_CIPHER ) if( DBG_CIPHER )
progress('+'); progress('+');
continue; /* no */ continue; /* no */
}
if( !(mpi_cmp_ui( k, 0 ) > 0) ) { /* check: k > 0 */
if( DBG_CIPHER )
progress('-');
continue; /* no */
}
break; /* okay */
} }
if( !(mpi_cmp_ui( k, 0 ) > 0) ) { /* check: k > 0 */ m_free(rndbuf);
if( DBG_CIPHER ) if( DBG_CIPHER )
progress('-'); progress('\n');
continue; /* no */
}
break; /* okay */
}
m_free(rndbuf);
if( DBG_CIPHER )
progress('\n');
return k; return k;
} }
static void static void
test_keys( DSA_secret_key *sk, unsigned qbits ) test_keys( DSA_secret_key *sk, unsigned qbits )
{ {
DSA_public_key pk; DSA_public_key pk;
MPI test = mpi_alloc( qbits / BITS_PER_MPI_LIMB ); MPI test = mpi_alloc( qbits / BITS_PER_MPI_LIMB );
MPI out1_a = mpi_alloc( qbits / BITS_PER_MPI_LIMB ); MPI out1_a = mpi_alloc( qbits / BITS_PER_MPI_LIMB );
MPI out1_b = mpi_alloc( qbits / BITS_PER_MPI_LIMB ); MPI out1_b = mpi_alloc( qbits / BITS_PER_MPI_LIMB );
pk.p = sk->p; pk.p = sk->p;
pk.q = sk->q; pk.q = sk->q;
pk.g = sk->g; pk.g = sk->g;
pk.y = sk->y; pk.y = sk->y;
/*mpi_set_bytes( test, qbits, get_random_byte, 0 );*/ /*mpi_set_bytes( test, qbits, get_random_byte, 0 );*/
{ char *p = get_random_bits( qbits, 0, 0 ); { char *p = get_random_bits( qbits, 0, 0 );
mpi_set_buffer( test, p, (qbits+7)/8, 0 ); mpi_set_buffer( test, p, (qbits+7)/8, 0 );
m_free(p); m_free(p);
} }
sign( out1_a, out1_b, test, sk ); sign( out1_a, out1_b, test, sk );
if( !verify( out1_a, out1_b, test, &pk ) ) if( !verify( out1_a, out1_b, test, &pk ) )
log_fatal("DSA:: sign, verify failed\n"); log_fatal("DSA:: sign, verify failed\n");
mpi_free( test ); mpi_free( test );
mpi_free( out1_a ); mpi_free( out1_a );
mpi_free( out1_b ); mpi_free( out1_b );
} }
@@ -163,91 +163,91 @@ test_keys( DSA_secret_key *sk, unsigned qbits )
/**************** /****************
* Generate a DSA key pair with a key of size NBITS * Generate a DSA key pair with a key of size NBITS
* Returns: 2 structures filled with all needed values * Returns: 2 structures filled with all needed values
* and an array with the n-1 factors of (p-1) * and an array with the n-1 factors of (p-1)
*/ */
static void static void
generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors ) generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors )
{ {
MPI p; /* the prime */ MPI p; /* the prime */
MPI q; /* the 160 bit prime factor */ MPI q; /* the 160 bit prime factor */
MPI g; /* the generator */ MPI g; /* the generator */
MPI y; /* g^x mod p */ MPI y; /* g^x mod p */
MPI x; /* the secret exponent */ MPI x; /* the secret exponent */
MPI h, e; /* helper */ MPI h, e; /* helper */
unsigned qbits; unsigned qbits;
byte *rndbuf; byte *rndbuf;
assert( nbits >= 512 && nbits <= 1024 ); assert( nbits >= 512 && nbits <= 1024 );
qbits = 160; qbits = 160;
p = generate_elg_prime( 1, nbits, qbits, NULL, ret_factors ); p = generate_elg_prime( 1, nbits, qbits, NULL, ret_factors );
/* get q out of factors */ /* get q out of factors */
q = mpi_copy((*ret_factors)[0]); q = mpi_copy((*ret_factors)[0]);
if( mpi_get_nbits(q) != qbits ) if( mpi_get_nbits(q) != qbits )
BUG(); BUG();
/* find a generator g (h and e are helpers)*/ /* find a generator g (h and e are helpers)*/
/* e = (p-1)/q */ /* e = (p-1)/q */
e = mpi_alloc( mpi_get_nlimbs(p) ); e = mpi_alloc( mpi_get_nlimbs(p) );
mpi_sub_ui( e, p, 1 ); mpi_sub_ui( e, p, 1 );
mpi_fdiv_q( e, e, q ); mpi_fdiv_q( e, e, q );
g = mpi_alloc( mpi_get_nlimbs(p) ); g = mpi_alloc( mpi_get_nlimbs(p) );
h = mpi_alloc_set_ui( 1 ); /* we start with 2 */ h = mpi_alloc_set_ui( 1 ); /* we start with 2 */
do { do {
mpi_add_ui( h, h, 1 ); mpi_add_ui( h, h, 1 );
/* g = h^e mod p */ /* g = h^e mod p */
mpi_powm( g, h, e, p ); mpi_powm( g, h, e, p );
} while( !mpi_cmp_ui( g, 1 ) ); /* continue until g != 1 */ } while( !mpi_cmp_ui( g, 1 ) ); /* continue until g != 1 */
/* select a random number which has these properties: /* select a random number which has these properties:
* 0 < x < q-1 * 0 < x < q-1
* This must be a very good random number because this * This must be a very good random number because this
* is the secret part. */ * is the secret part. */
if( DBG_CIPHER )
log_debug("choosing a random x ");
assert( qbits >= 160 );
x = mpi_alloc_secure( mpi_get_nlimbs(q) );
mpi_sub_ui( h, q, 1 ); /* put q-1 into h */
rndbuf = NULL;
do {
if( DBG_CIPHER ) if( DBG_CIPHER )
progress('.'); log_debug("choosing a random x ");
if( !rndbuf ) assert( qbits >= 160 );
rndbuf = get_random_bits( qbits, 2, 1 ); x = mpi_alloc_secure( mpi_get_nlimbs(q) );
else { /* change only some of the higher bits (= 2 bytes)*/ mpi_sub_ui( h, q, 1 ); /* put q-1 into h */
char *r = get_random_bits( 16, 2, 1 ); rndbuf = NULL;
memcpy(rndbuf, r, 16/8 ); do {
m_free(r); if( DBG_CIPHER )
progress('.');
if( !rndbuf )
rndbuf = get_random_bits( qbits, 2, 1 );
else { /* change only some of the higher bits (= 2 bytes)*/
char *r = get_random_bits( 16, 2, 1 );
memcpy(rndbuf, r, 16/8 );
m_free(r);
}
mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 );
mpi_clear_highbit( x, qbits+1 );
} while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) );
m_free(rndbuf);
mpi_free( e );
mpi_free( h );
/* y = g^x mod p */
y = mpi_alloc( mpi_get_nlimbs(p) );
mpi_powm( y, g, x, p );
if( DBG_CIPHER ) {
progress('\n');
log_mpidump("dsa p= ", p );
log_mpidump("dsa q= ", q );
log_mpidump("dsa g= ", g );
log_mpidump("dsa y= ", y );
log_mpidump("dsa x= ", x );
} }
mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 );
mpi_clear_highbit( x, qbits+1 );
} while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) );
m_free(rndbuf);
mpi_free( e );
mpi_free( h );
/* y = g^x mod p */ /* copy the stuff to the key structures */
y = mpi_alloc( mpi_get_nlimbs(p) ); sk->p = p;
mpi_powm( y, g, x, p ); sk->q = q;
sk->g = g;
sk->y = y;
sk->x = x;
if( DBG_CIPHER ) { /* now we can test our keys (this should never fail!) */
progress('\n'); test_keys( sk, qbits );
log_mpidump("dsa p= ", p );
log_mpidump("dsa q= ", q );
log_mpidump("dsa g= ", g );
log_mpidump("dsa y= ", y );
log_mpidump("dsa x= ", x );
}
/* copy the stuff to the key structures */
sk->p = p;
sk->q = q;
sk->g = g;
sk->y = y;
sk->x = x;
/* now we can test our keys (this should never fail!) */
test_keys( sk, qbits );
} }
@@ -259,13 +259,13 @@ generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors )
static int static int
check_secret_key( DSA_secret_key *sk ) check_secret_key( DSA_secret_key *sk )
{ {
int rc; int rc;
MPI y = mpi_alloc( mpi_get_nlimbs(sk->y) ); MPI y = mpi_alloc( mpi_get_nlimbs(sk->y) );
mpi_powm( y, sk->g, sk->x, sk->p ); mpi_powm( y, sk->g, sk->x, sk->p );
rc = !mpi_cmp( y, sk->y ); rc = !mpi_cmp( y, sk->y );
mpi_free( y ); mpi_free( y );
return rc; return rc;
} }
@@ -277,30 +277,30 @@ check_secret_key( DSA_secret_key *sk )
static void static void
sign(MPI r, MPI s, MPI hash, DSA_secret_key *skey ) sign(MPI r, MPI s, MPI hash, DSA_secret_key *skey )
{ {
MPI k; MPI k;
MPI kinv; MPI kinv;
MPI tmp; MPI tmp;
/* select a random k with 0 < k < q */ /* select a random k with 0 < k < q */
k = gen_k( skey->q ); k = gen_k( skey->q );
/* r = (a^k mod p) mod q */ /* r = (a^k mod p) mod q */
mpi_powm( r, skey->g, k, skey->p ); mpi_powm( r, skey->g, k, skey->p );
mpi_fdiv_r( r, r, skey->q ); mpi_fdiv_r( r, r, skey->q );
/* kinv = k^(-1) mod q */ /* kinv = k^(-1) mod q */
kinv = mpi_alloc( mpi_get_nlimbs(k) ); kinv = mpi_alloc( mpi_get_nlimbs(k) );
mpi_invm(kinv, k, skey->q ); mpi_invm(kinv, k, skey->q );
/* s = (kinv * ( hash + x * r)) mod q */ /* s = (kinv * ( hash + x * r)) mod q */
tmp = mpi_alloc( mpi_get_nlimbs(skey->p) ); tmp = mpi_alloc( mpi_get_nlimbs(skey->p) );
mpi_mul( tmp, skey->x, r ); mpi_mul( tmp, skey->x, r );
mpi_add( tmp, tmp, hash ); mpi_add( tmp, tmp, hash );
mpi_mulm( s , kinv, tmp, skey->q ); mpi_mulm( s , kinv, tmp, skey->q );
mpi_free(k); mpi_free(k);
mpi_free(kinv); mpi_free(kinv);
mpi_free(tmp); mpi_free(tmp);
} }
@@ -310,45 +310,45 @@ sign(MPI r, MPI s, MPI hash, DSA_secret_key *skey )
static int static int
verify(MPI r, MPI s, MPI hash, DSA_public_key *pkey ) verify(MPI r, MPI s, MPI hash, DSA_public_key *pkey )
{ {
int rc; int rc;
MPI w, u1, u2, v; MPI w, u1, u2, v;
MPI base[3]; MPI base[3];
MPI exp[3]; MPI exp[3];
if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) ) if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) )
return 0; /* assertion 0 < r < q failed */ return 0; /* assertion 0 < r < q failed */
if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) ) if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) )
return 0; /* assertion 0 < s < q failed */ return 0; /* assertion 0 < s < q failed */
w = mpi_alloc( mpi_get_nlimbs(pkey->q) ); w = mpi_alloc( mpi_get_nlimbs(pkey->q) );
u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) ); u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
u2 = mpi_alloc( mpi_get_nlimbs(pkey->q) ); u2 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
v = mpi_alloc( mpi_get_nlimbs(pkey->p) ); v = mpi_alloc( mpi_get_nlimbs(pkey->p) );
/* w = s^(-1) mod q */ /* w = s^(-1) mod q */
mpi_invm( w, s, pkey->q ); mpi_invm( w, s, pkey->q );
/* u1 = (hash * w) mod q */ /* u1 = (hash * w) mod q */
mpi_mulm( u1, hash, w, pkey->q ); mpi_mulm( u1, hash, w, pkey->q );
/* u2 = r * w mod q */ /* u2 = r * w mod q */
mpi_mulm( u2, r, w, pkey->q ); mpi_mulm( u2, r, w, pkey->q );
/* v = g^u1 * y^u2 mod p mod q */ /* v = g^u1 * y^u2 mod p mod q */
base[0] = pkey->g; exp[0] = u1; base[0] = pkey->g; exp[0] = u1;
base[1] = pkey->y; exp[1] = u2; base[1] = pkey->y; exp[1] = u2;
base[2] = NULL; exp[2] = NULL; base[2] = NULL; exp[2] = NULL;
mpi_mulpowm( v, base, exp, pkey->p ); mpi_mulpowm( v, base, exp, pkey->p );
mpi_fdiv_r( v, v, pkey->q ); mpi_fdiv_r( v, v, pkey->q );
rc = !mpi_cmp( v, r ); rc = !mpi_cmp( v, r );
mpi_free(w); mpi_free(w);
mpi_free(u1); mpi_free(u1);
mpi_free(u2); mpi_free(u2);
mpi_free(v); mpi_free(v);
return rc; return rc;
} }
@@ -359,40 +359,40 @@ verify(MPI r, MPI s, MPI hash, DSA_public_key *pkey )
int int
dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ) dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
{ {
DSA_secret_key sk; DSA_secret_key sk;
if( algo != PUBKEY_ALGO_DSA ) if( algo != PUBKEY_ALGO_DSA )
return G10ERR_PUBKEY_ALGO; return G10ERR_PUBKEY_ALGO;
generate( &sk, nbits, retfactors ); generate( &sk, nbits, retfactors );
skey[0] = sk.p; skey[0] = sk.p;
skey[1] = sk.q; skey[1] = sk.q;
skey[2] = sk.g; skey[2] = sk.g;
skey[3] = sk.y; skey[3] = sk.y;
skey[4] = sk.x; skey[4] = sk.x;
return 0; return 0;
} }
int int
dsa_check_secret_key( int algo, MPI *skey ) dsa_check_secret_key( int algo, MPI *skey )
{ {
DSA_secret_key sk; DSA_secret_key sk;
if( algo != PUBKEY_ALGO_DSA ) if( algo != PUBKEY_ALGO_DSA )
return G10ERR_PUBKEY_ALGO; return G10ERR_PUBKEY_ALGO;
if( !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] ) if( !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] )
return G10ERR_BAD_MPI; return G10ERR_BAD_MPI;
sk.p = skey[0]; sk.p = skey[0];
sk.q = skey[1]; sk.q = skey[1];
sk.g = skey[2]; sk.g = skey[2];
sk.y = skey[3]; sk.y = skey[3];
sk.x = skey[4]; sk.x = skey[4];
if( !check_secret_key( &sk ) ) if( !check_secret_key( &sk ) )
return G10ERR_BAD_SECKEY; return G10ERR_BAD_SECKEY;
return 0; return 0;
} }
@@ -400,43 +400,43 @@ dsa_check_secret_key( int algo, MPI *skey )
int int
dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey ) dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey )
{ {
DSA_secret_key sk; DSA_secret_key sk;
if( algo != PUBKEY_ALGO_DSA ) if( algo != PUBKEY_ALGO_DSA )
return G10ERR_PUBKEY_ALGO; return G10ERR_PUBKEY_ALGO;
if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] ) if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] )
return G10ERR_BAD_MPI; return G10ERR_BAD_MPI;
sk.p = skey[0]; sk.p = skey[0];
sk.q = skey[1]; sk.q = skey[1];
sk.g = skey[2]; sk.g = skey[2];
sk.y = skey[3]; sk.y = skey[3];
sk.x = skey[4]; sk.x = skey[4];
resarr[0] = mpi_alloc( mpi_get_nlimbs( sk.p ) ); resarr[0] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
resarr[1] = mpi_alloc( mpi_get_nlimbs( sk.p ) ); resarr[1] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
sign( resarr[0], resarr[1], data, &sk ); sign( resarr[0], resarr[1], data, &sk );
return 0; return 0;
} }
int int
dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey, dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
int (*cmp)(void *, MPI) UNUSED, void *opaquev UNUSED) int (*cmp)(void *, MPI) UNUSED, void *opaquev UNUSED)
{ {
DSA_public_key pk; DSA_public_key pk;
if( algo != PUBKEY_ALGO_DSA ) if( algo != PUBKEY_ALGO_DSA )
return G10ERR_PUBKEY_ALGO; return G10ERR_PUBKEY_ALGO;
if( !data[0] || !data[1] || !hash if( !data[0] || !data[1] || !hash
|| !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] ) || !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] )
return G10ERR_BAD_MPI; return G10ERR_BAD_MPI;
pk.p = pkey[0]; pk.p = pkey[0];
pk.q = pkey[1]; pk.q = pkey[1];
pk.g = pkey[2]; pk.g = pkey[2];
pk.y = pkey[3]; pk.y = pkey[3];
if( !verify( data[0], data[1], hash, &pk ) ) if( !verify( data[0], data[1], hash, &pk ) )
return G10ERR_BAD_SIGN; return G10ERR_BAD_SIGN;
return 0; return 0;
} }
@@ -444,9 +444,9 @@ dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
unsigned unsigned
dsa_get_nbits( int algo, MPI *pkey ) dsa_get_nbits( int algo, MPI *pkey )
{ {
if( algo != PUBKEY_ALGO_DSA ) if( algo != PUBKEY_ALGO_DSA )
return 0; return 0;
return mpi_get_nbits( pkey[0] ); return mpi_get_nbits( pkey[0] );
} }
@@ -454,23 +454,23 @@ dsa_get_nbits( int algo, MPI *pkey )
* Return some information about the algorithm. We need algo here to * Return some information about the algorithm. We need algo here to
* distinguish different flavors of the algorithm. * distinguish different flavors of the algorithm.
* Returns: A pointer to string describing the algorithm or NULL if * Returns: A pointer to string describing the algorithm or NULL if
* the ALGO is invalid. * the ALGO is invalid.
* Usage: Bit 0 set : allows signing * Usage: Bit 0 set : allows signing
* 1 set : allows encryption * 1 set : allows encryption
*/ */
const char * const char *
dsa_get_info( int algo, int *npkey, int *nskey, int *nenc, int *nsig, dsa_get_info( int algo, int *npkey, int *nskey, int *nenc, int *nsig,
int *use ) int *use )
{ {
*npkey = 4; *npkey = 4;
*nskey = 5; *nskey = 5;
*nenc = 0; *nenc = 0;
*nsig = 2; *nsig = 2;
switch( algo ) { switch( algo ) {
case PUBKEY_ALGO_DSA: *use = PUBKEY_USAGE_SIG; return "DSA"; case PUBKEY_ALGO_DSA: *use = PUBKEY_USAGE_SIG; return "DSA";
default: *use = 0; return NULL; default: *use = 0; return NULL;
} }
} }
+3 -3
View File
@@ -1,5 +1,5 @@
/* dsa.h - DSA signature scheme /* dsa.h - DSA signature scheme
* Copyright (C) 1998 Free Software Foundation, Inc. * Copyright (C) 1998 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@@ -24,9 +24,9 @@ int dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors );
int dsa_check_secret_key( int algo, MPI *skey ); int dsa_check_secret_key( int algo, MPI *skey );
int dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey ); int dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey );
int dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey, int dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
int (*cmp)(void *, MPI), void *opaquev ); int (*cmp)(void *, MPI), void *opaquev );
unsigned dsa_get_nbits( int algo, MPI *pkey ); unsigned dsa_get_nbits( int algo, MPI *pkey );
const char *dsa_get_info( int algo, int *npkey, int *nskey, const char *dsa_get_info( int algo, int *npkey, int *nskey,
int *nenc, int *nsig, int *use ); int *nenc, int *nsig, int *use );
#endif /*G10_DSA_H*/ #endif /*G10_DSA_H*/
+357 -357
View File
@@ -1,5 +1,5 @@
/* elgamal.c - ElGamal Public Key encryption /* elgamal.c - ElGamal Public Key encryption
* Copyright (C) 1998 Free Software Foundation, Inc. * Copyright (C) 1998 Free Software Foundation, Inc.
* *
* For a description of the algorithm, see: * For a description of the algorithm, see:
* Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996. * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
@@ -47,17 +47,17 @@
#include "elgamal.h" #include "elgamal.h"
typedef struct { typedef struct {
MPI p; /* prime */ MPI p; /* prime */
MPI g; /* group generator */ MPI g; /* group generator */
MPI y; /* g^x mod p */ MPI y; /* g^x mod p */
} ELG_public_key; } ELG_public_key;
typedef struct { typedef struct {
MPI p; /* prime */ MPI p; /* prime */
MPI g; /* group generator */ MPI g; /* group generator */
MPI y; /* g^x mod p */ MPI y; /* g^x mod p */
MPI x; /* secret exponent */ MPI x; /* secret exponent */
} ELG_secret_key; } ELG_secret_key;
@@ -74,42 +74,42 @@ static int verify(MPI a, MPI b, MPI input, ELG_public_key *pkey);
static void static void
progress( int c ) progress( int c )
{ {
fputc( c, stderr ); fputc( c, stderr );
} }
static void static void
test_keys( ELG_secret_key *sk, unsigned nbits ) test_keys( ELG_secret_key *sk, unsigned nbits )
{ {
ELG_public_key pk; ELG_public_key pk;
MPI test = mpi_alloc( 0 ); MPI test = mpi_alloc( 0 );
MPI out1_a = mpi_alloc( nbits / BITS_PER_MPI_LIMB ); MPI out1_a = mpi_alloc( nbits / BITS_PER_MPI_LIMB );
MPI out1_b = mpi_alloc( nbits / BITS_PER_MPI_LIMB ); MPI out1_b = mpi_alloc( nbits / BITS_PER_MPI_LIMB );
MPI out2 = mpi_alloc( nbits / BITS_PER_MPI_LIMB ); MPI out2 = mpi_alloc( nbits / BITS_PER_MPI_LIMB );
pk.p = sk->p; pk.p = sk->p;
pk.g = sk->g; pk.g = sk->g;
pk.y = sk->y; pk.y = sk->y;
/*mpi_set_bytes( test, nbits, get_random_byte, 0 );*/ /*mpi_set_bytes( test, nbits, get_random_byte, 0 );*/
{ char *p = get_random_bits( nbits, 0, 0 ); { char *p = get_random_bits( nbits, 0, 0 );
mpi_set_buffer( test, p, (nbits+7)/8, 0 ); mpi_set_buffer( test, p, (nbits+7)/8, 0 );
m_free(p); m_free(p);
} }
encrypt( out1_a, out1_b, test, &pk ); encrypt( out1_a, out1_b, test, &pk );
decrypt( out2, out1_a, out1_b, sk ); decrypt( out2, out1_a, out1_b, sk );
if( mpi_cmp( test, out2 ) ) if( mpi_cmp( test, out2 ) )
log_fatal("ElGamal operation: encrypt, decrypt failed\n"); log_fatal("ElGamal operation: encrypt, decrypt failed\n");
sign( out1_a, out1_b, test, sk ); sign( out1_a, out1_b, test, sk );
if( !verify( out1_a, out1_b, test, &pk ) ) if( !verify( out1_a, out1_b, test, &pk ) )
log_fatal("ElGamal operation: sign, verify failed\n"); log_fatal("ElGamal operation: sign, verify failed\n");
mpi_free( test ); mpi_free( test );
mpi_free( out1_a ); mpi_free( out1_a );
mpi_free( out1_b ); mpi_free( out1_b );
mpi_free( out2 ); mpi_free( out2 );
} }
@@ -120,151 +120,151 @@ test_keys( ELG_secret_key *sk, unsigned nbits )
static MPI static MPI
gen_k( MPI p ) gen_k( MPI p )
{ {
MPI k = mpi_alloc_secure( 0 ); MPI k = mpi_alloc_secure( 0 );
MPI temp = mpi_alloc( mpi_get_nlimbs(p) ); MPI temp = mpi_alloc( mpi_get_nlimbs(p) );
MPI p_1 = mpi_copy(p); MPI p_1 = mpi_copy(p);
unsigned int nbits = mpi_get_nbits(p); unsigned int nbits = mpi_get_nbits(p);
unsigned int nbytes = (nbits+7)/8; unsigned int nbytes = (nbits+7)/8;
char *rndbuf = NULL; char *rndbuf = NULL;
if( DBG_CIPHER )
log_debug("choosing a random k ");
mpi_sub_ui( p_1, p, 1);
for(;;) {
if( DBG_CIPHER ) if( DBG_CIPHER )
progress('.'); log_debug("choosing a random k ");
if( !rndbuf || nbits < 32 ) { mpi_sub_ui( p_1, p, 1);
m_free(rndbuf);
rndbuf = get_random_bits( nbits, 1, 1 );
}
else { /* change only some of the higher bits */
/* we could imporove this by directly requesting more memory
* at the first call to get_random_bits() and use this the here
* maybe it is easier to do this directly in random.c */
char *pp = get_random_bits( 32, 1, 1 );
memcpy( rndbuf,pp, 4 );
m_free(pp);
}
mpi_set_buffer( k, rndbuf, nbytes, 0 );
for(;;) { for(;;) {
/* make sure that the number is of the exact lenght */
if( mpi_test_bit( k, nbits-1 ) )
mpi_set_highbit( k, nbits-1 );
else {
mpi_set_highbit( k, nbits-1 );
mpi_clear_bit( k, nbits-1 );
}
if( !(mpi_cmp( k, p_1 ) < 0) ) { /* check: k < (p-1) */
if( DBG_CIPHER ) if( DBG_CIPHER )
progress('+'); progress('.');
break; /* no */ if( !rndbuf || nbits < 32 ) {
} m_free(rndbuf);
if( !(mpi_cmp_ui( k, 0 ) > 0) ) { /* check: k > 0 */ rndbuf = get_random_bits( nbits, 1, 1 );
if( DBG_CIPHER ) }
progress('-'); else { /* change only some of the higher bits */
break; /* no */ /* we could imporove this by directly requesting more memory
} * at the first call to get_random_bits() and use this the here
if( mpi_gcd( temp, k, p_1 ) ) * maybe it is easier to do this directly in random.c */
goto found; /* okay, k is relatively prime to (p-1) */ char *pp = get_random_bits( 32, 1, 1 );
mpi_add_ui( k, k, 1 ); memcpy( rndbuf,pp, 4 );
} m_free(pp);
} }
found: mpi_set_buffer( k, rndbuf, nbytes, 0 );
m_free(rndbuf);
if( DBG_CIPHER )
progress('\n');
mpi_free(p_1);
mpi_free(temp);
return k; for(;;) {
/* make sure that the number is of the exact lenght */
if( mpi_test_bit( k, nbits-1 ) )
mpi_set_highbit( k, nbits-1 );
else {
mpi_set_highbit( k, nbits-1 );
mpi_clear_bit( k, nbits-1 );
}
if( !(mpi_cmp( k, p_1 ) < 0) ) { /* check: k < (p-1) */
if( DBG_CIPHER )
progress('+');
break; /* no */
}
if( !(mpi_cmp_ui( k, 0 ) > 0) ) { /* check: k > 0 */
if( DBG_CIPHER )
progress('-');
break; /* no */
}
if( mpi_gcd( temp, k, p_1 ) )
goto found; /* okay, k is relatively prime to (p-1) */
mpi_add_ui( k, k, 1 );
}
}
found:
m_free(rndbuf);
if( DBG_CIPHER )
progress('\n');
mpi_free(p_1);
mpi_free(temp);
return k;
} }
/**************** /****************
* Generate a key pair with a key of size NBITS * Generate a key pair with a key of size NBITS
* Returns: 2 structures filles with all needed values * Returns: 2 structures filles with all needed values
* and an array with n-1 factors of (p-1) * and an array with n-1 factors of (p-1)
*/ */
static void static void
generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors ) generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
{ {
MPI p; /* the prime */ MPI p; /* the prime */
MPI p_min1; MPI p_min1;
MPI g; MPI g;
MPI x; /* the secret exponent */ MPI x; /* the secret exponent */
MPI y; MPI y;
MPI temp; MPI temp;
unsigned qbits; unsigned qbits;
byte *rndbuf; byte *rndbuf;
p_min1 = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB ); p_min1 = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
temp = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB ); temp = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
if( nbits < 512 ) if( nbits < 512 )
qbits = 120; qbits = 120;
else if( nbits <= 1024 ) else if( nbits <= 1024 )
qbits = 160; qbits = 160;
else if( nbits <= 2048 ) else if( nbits <= 2048 )
qbits = 200; qbits = 200;
else
qbits = 240;
g = mpi_alloc(1);
p = generate_elg_prime( 0, nbits, qbits, g, ret_factors );
mpi_sub_ui(p_min1, p, 1);
/* select a random number which has these properties:
* 0 < x < p-1
* This must be a very good random number because this is the
* secret part. The prime is public and may be shared anyway,
* so a random generator level of 1 is used for the prime.
*/
x = mpi_alloc_secure( nbits/BITS_PER_MPI_LIMB );
if( DBG_CIPHER )
log_debug("choosing a random x ");
rndbuf = NULL;
do {
if( DBG_CIPHER )
progress('.');
if( rndbuf ) { /* change only some of the higher bits */
if( nbits < 16 ) {/* should never happen ... */
m_free(rndbuf);
rndbuf = get_random_bits( nbits, 2, 1 );
}
else {
char *r = get_random_bits( 16, 2, 1 );
memcpy(rndbuf, r, 16/8 );
m_free(r);
}
}
else else
rndbuf = get_random_bits( nbits, 2, 1 ); qbits = 240;
mpi_set_buffer( x, rndbuf, (nbits+7)/8, 0 ); g = mpi_alloc(1);
mpi_clear_highbit( x, nbits+1 ); p = generate_elg_prime( 0, nbits, qbits, g, ret_factors );
} while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) ); mpi_sub_ui(p_min1, p, 1);
m_free(rndbuf);
y = mpi_alloc(nbits/BITS_PER_MPI_LIMB);
mpi_powm( y, g, x, p );
if( DBG_CIPHER ) { /* select a random number which has these properties:
progress('\n'); * 0 < x < p-1
log_mpidump("elg p= ", p ); * This must be a very good random number because this is the
log_mpidump("elg g= ", g ); * secret part. The prime is public and may be shared anyway,
log_mpidump("elg y= ", y ); * so a random generator level of 1 is used for the prime.
log_mpidump("elg x= ", x ); */
} x = mpi_alloc_secure( nbits/BITS_PER_MPI_LIMB );
if( DBG_CIPHER )
log_debug("choosing a random x ");
rndbuf = NULL;
do {
if( DBG_CIPHER )
progress('.');
if( rndbuf ) { /* change only some of the higher bits */
if( nbits < 16 ) {/* should never happen ... */
m_free(rndbuf);
rndbuf = get_random_bits( nbits, 2, 1 );
}
else {
char *r = get_random_bits( 16, 2, 1 );
memcpy(rndbuf, r, 16/8 );
m_free(r);
}
}
else
rndbuf = get_random_bits( nbits, 2, 1 );
mpi_set_buffer( x, rndbuf, (nbits+7)/8, 0 );
mpi_clear_highbit( x, nbits+1 );
} while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) );
m_free(rndbuf);
/* copy the stuff to the key structures */ y = mpi_alloc(nbits/BITS_PER_MPI_LIMB);
sk->p = p; mpi_powm( y, g, x, p );
sk->g = g;
sk->y = y;
sk->x = x;
/* now we can test our keys (this should never fail!) */ if( DBG_CIPHER ) {
test_keys( sk, nbits - 64 ); progress('\n');
log_mpidump("elg p= ", p );
log_mpidump("elg g= ", g );
log_mpidump("elg y= ", y );
log_mpidump("elg x= ", x );
}
mpi_free( p_min1 ); /* copy the stuff to the key structures */
mpi_free( temp ); sk->p = p;
sk->g = g;
sk->y = y;
sk->x = x;
/* now we can test our keys (this should never fail!) */
test_keys( sk, nbits - 64 );
mpi_free( p_min1 );
mpi_free( temp );
} }
@@ -275,46 +275,46 @@ generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
static int static int
check_secret_key( ELG_secret_key *sk ) check_secret_key( ELG_secret_key *sk )
{ {
int rc; int rc;
MPI y = mpi_alloc( mpi_get_nlimbs(sk->y) ); MPI y = mpi_alloc( mpi_get_nlimbs(sk->y) );
mpi_powm( y, sk->g, sk->x, sk->p ); mpi_powm( y, sk->g, sk->x, sk->p );
rc = !mpi_cmp( y, sk->y ); rc = !mpi_cmp( y, sk->y );
mpi_free( y ); mpi_free( y );
return rc; return rc;
} }
static void static void
encrypt(MPI a, MPI b, MPI input, ELG_public_key *pkey ) encrypt(MPI a, MPI b, MPI input, ELG_public_key *pkey )
{ {
MPI k; MPI k;
/* Note: maybe we should change the interface, so that it /* Note: maybe we should change the interface, so that it
* is possible to check that input is < p and return an * is possible to check that input is < p and return an
* error code. * error code.
*/ */
k = gen_k( pkey->p ); k = gen_k( pkey->p );
mpi_powm( a, pkey->g, k, pkey->p ); mpi_powm( a, pkey->g, k, pkey->p );
/* b = (y^k * input) mod p /* b = (y^k * input) mod p
* = ((y^k mod p) * (input mod p)) mod p * = ((y^k mod p) * (input mod p)) mod p
* and because input is < p * and because input is < p
* = ((y^k mod p) * input) mod p * = ((y^k mod p) * input) mod p
*/ */
mpi_powm( b, pkey->y, k, pkey->p ); mpi_powm( b, pkey->y, k, pkey->p );
mpi_mulm( b, b, input, pkey->p ); mpi_mulm( b, b, input, pkey->p );
#if 0 #if 0
if( DBG_CIPHER ) { if( DBG_CIPHER ) {
log_mpidump("elg encrypted y= ", pkey->y); log_mpidump("elg encrypted y= ", pkey->y);
log_mpidump("elg encrypted p= ", pkey->p); log_mpidump("elg encrypted p= ", pkey->p);
log_mpidump("elg encrypted k= ", k); log_mpidump("elg encrypted k= ", k);
log_mpidump("elg encrypted M= ", input); log_mpidump("elg encrypted M= ", input);
log_mpidump("elg encrypted a= ", a); log_mpidump("elg encrypted a= ", a);
log_mpidump("elg encrypted b= ", b); log_mpidump("elg encrypted b= ", b);
} }
#endif #endif
mpi_free(k); mpi_free(k);
} }
@@ -323,23 +323,23 @@ encrypt(MPI a, MPI b, MPI input, ELG_public_key *pkey )
static void static void
decrypt(MPI output, MPI a, MPI b, ELG_secret_key *skey ) decrypt(MPI output, MPI a, MPI b, ELG_secret_key *skey )
{ {
MPI t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) ); MPI t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) );
/* output = b/(a^x) mod p */ /* output = b/(a^x) mod p */
mpi_powm( t1, a, skey->x, skey->p ); mpi_powm( t1, a, skey->x, skey->p );
mpi_invm( t1, t1, skey->p ); mpi_invm( t1, t1, skey->p );
mpi_mulm( output, b, t1, skey->p ); mpi_mulm( output, b, t1, skey->p );
#if 0 #if 0
if( DBG_CIPHER ) { if( DBG_CIPHER ) {
log_mpidump("elg decrypted x= ", skey->x); log_mpidump("elg decrypted x= ", skey->x);
log_mpidump("elg decrypted p= ", skey->p); log_mpidump("elg decrypted p= ", skey->p);
log_mpidump("elg decrypted a= ", a); log_mpidump("elg decrypted a= ", a);
log_mpidump("elg decrypted b= ", b); log_mpidump("elg decrypted b= ", b);
log_mpidump("elg decrypted M= ", output); log_mpidump("elg decrypted M= ", output);
} }
#endif #endif
mpi_free(t1); mpi_free(t1);
} }
@@ -350,43 +350,43 @@ decrypt(MPI output, MPI a, MPI b, ELG_secret_key *skey )
static void static void
sign(MPI a, MPI b, MPI input, ELG_secret_key *skey ) sign(MPI a, MPI b, MPI input, ELG_secret_key *skey )
{ {
MPI k; MPI k;
MPI t = mpi_alloc( mpi_get_nlimbs(a) ); MPI t = mpi_alloc( mpi_get_nlimbs(a) );
MPI inv = mpi_alloc( mpi_get_nlimbs(a) ); MPI inv = mpi_alloc( mpi_get_nlimbs(a) );
MPI p_1 = mpi_copy(skey->p); MPI p_1 = mpi_copy(skey->p);
/* /*
* b = (t * inv) mod (p-1) * b = (t * inv) mod (p-1)
* b = (t * inv(k,(p-1),(p-1)) mod (p-1) * b = (t * inv(k,(p-1),(p-1)) mod (p-1)
* b = (((M-x*a) mod (p-1)) * inv(k,(p-1),(p-1))) mod (p-1) * b = (((M-x*a) mod (p-1)) * inv(k,(p-1),(p-1))) mod (p-1)
* *
*/ */
mpi_sub_ui(p_1, p_1, 1); mpi_sub_ui(p_1, p_1, 1);
k = gen_k( skey->p ); k = gen_k( skey->p );
mpi_powm( a, skey->g, k, skey->p ); mpi_powm( a, skey->g, k, skey->p );
mpi_mul(t, skey->x, a ); mpi_mul(t, skey->x, a );
mpi_subm(t, input, t, p_1 ); mpi_subm(t, input, t, p_1 );
while( mpi_is_neg(t) ) while( mpi_is_neg(t) )
mpi_add(t, t, p_1); mpi_add(t, t, p_1);
mpi_invm(inv, k, p_1 ); mpi_invm(inv, k, p_1 );
mpi_mulm(b, t, inv, p_1 ); mpi_mulm(b, t, inv, p_1 );
#if 0 #if 0
if( DBG_CIPHER ) { if( DBG_CIPHER ) {
log_mpidump("elg sign p= ", skey->p); log_mpidump("elg sign p= ", skey->p);
log_mpidump("elg sign g= ", skey->g); log_mpidump("elg sign g= ", skey->g);
log_mpidump("elg sign y= ", skey->y); log_mpidump("elg sign y= ", skey->y);
log_mpidump("elg sign x= ", skey->x); log_mpidump("elg sign x= ", skey->x);
log_mpidump("elg sign k= ", k); log_mpidump("elg sign k= ", k);
log_mpidump("elg sign M= ", input); log_mpidump("elg sign M= ", input);
log_mpidump("elg sign a= ", a); log_mpidump("elg sign a= ", a);
log_mpidump("elg sign b= ", b); log_mpidump("elg sign b= ", b);
} }
#endif #endif
mpi_free(k); mpi_free(k);
mpi_free(t); mpi_free(t);
mpi_free(inv); mpi_free(inv);
mpi_free(p_1); mpi_free(p_1);
} }
@@ -396,54 +396,54 @@ sign(MPI a, MPI b, MPI input, ELG_secret_key *skey )
static int static int
verify(MPI a, MPI b, MPI input, ELG_public_key *pkey ) verify(MPI a, MPI b, MPI input, ELG_public_key *pkey )
{ {
int rc; int rc;
MPI t1; MPI t1;
MPI t2; MPI t2;
MPI base[4]; MPI base[4];
MPI exp[4]; MPI exp[4];
if( !(mpi_cmp_ui( a, 0 ) > 0 && mpi_cmp( a, pkey->p ) < 0) ) if( !(mpi_cmp_ui( a, 0 ) > 0 && mpi_cmp( a, pkey->p ) < 0) )
return 0; /* assertion 0 < a < p failed */ return 0; /* assertion 0 < a < p failed */
t1 = mpi_alloc( mpi_get_nlimbs(a) ); t1 = mpi_alloc( mpi_get_nlimbs(a) );
t2 = mpi_alloc( mpi_get_nlimbs(a) ); t2 = mpi_alloc( mpi_get_nlimbs(a) );
#if 0 #if 0
/* t1 = (y^a mod p) * (a^b mod p) mod p */ /* t1 = (y^a mod p) * (a^b mod p) mod p */
mpi_powm( t1, pkey->y, a, pkey->p ); mpi_powm( t1, pkey->y, a, pkey->p );
mpi_powm( t2, a, b, pkey->p ); mpi_powm( t2, a, b, pkey->p );
mpi_mulm( t1, t1, t2, pkey->p ); mpi_mulm( t1, t1, t2, pkey->p );
/* t2 = g ^ input mod p */ /* t2 = g ^ input mod p */
mpi_powm( t2, pkey->g, input, pkey->p ); mpi_powm( t2, pkey->g, input, pkey->p );
rc = !mpi_cmp( t1, t2 ); rc = !mpi_cmp( t1, t2 );
#elif 0 #elif 0
/* t1 = (y^a mod p) * (a^b mod p) mod p */ /* t1 = (y^a mod p) * (a^b mod p) mod p */
base[0] = pkey->y; exp[0] = a; base[0] = pkey->y; exp[0] = a;
base[1] = a; exp[1] = b; base[1] = a; exp[1] = b;
base[2] = NULL; exp[2] = NULL; base[2] = NULL; exp[2] = NULL;
mpi_mulpowm( t1, base, exp, pkey->p ); mpi_mulpowm( t1, base, exp, pkey->p );
/* t2 = g ^ input mod p */ /* t2 = g ^ input mod p */
mpi_powm( t2, pkey->g, input, pkey->p ); mpi_powm( t2, pkey->g, input, pkey->p );
rc = !mpi_cmp( t1, t2 ); rc = !mpi_cmp( t1, t2 );
#else #else
/* t1 = g ^ - input * y ^ a * a ^ b mod p */ /* t1 = g ^ - input * y ^ a * a ^ b mod p */
mpi_invm(t2, pkey->g, pkey->p ); mpi_invm(t2, pkey->g, pkey->p );
base[0] = t2 ; exp[0] = input; base[0] = t2 ; exp[0] = input;
base[1] = pkey->y; exp[1] = a; base[1] = pkey->y; exp[1] = a;
base[2] = a; exp[2] = b; base[2] = a; exp[2] = b;
base[3] = NULL; exp[3] = NULL; base[3] = NULL; exp[3] = NULL;
mpi_mulpowm( t1, base, exp, pkey->p ); mpi_mulpowm( t1, base, exp, pkey->p );
rc = !mpi_cmp_ui( t1, 1 ); rc = !mpi_cmp_ui( t1, 1 );
#endif #endif
mpi_free(t1); mpi_free(t1);
mpi_free(t2); mpi_free(t2);
return rc; return rc;
} }
/********************************************* /*********************************************
@@ -453,38 +453,38 @@ verify(MPI a, MPI b, MPI input, ELG_public_key *pkey )
int int
elg_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ) elg_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
{ {
ELG_secret_key sk; ELG_secret_key sk;
if( !is_ELGAMAL(algo) ) if( !is_ELGAMAL(algo) )
return G10ERR_PUBKEY_ALGO; return G10ERR_PUBKEY_ALGO;
generate( &sk, nbits, retfactors ); generate( &sk, nbits, retfactors );
skey[0] = sk.p; skey[0] = sk.p;
skey[1] = sk.g; skey[1] = sk.g;
skey[2] = sk.y; skey[2] = sk.y;
skey[3] = sk.x; skey[3] = sk.x;
return 0; return 0;
} }
int int
elg_check_secret_key( int algo, MPI *skey ) elg_check_secret_key( int algo, MPI *skey )
{ {
ELG_secret_key sk; ELG_secret_key sk;
if( !is_ELGAMAL(algo) ) if( !is_ELGAMAL(algo) )
return G10ERR_PUBKEY_ALGO; return G10ERR_PUBKEY_ALGO;
if( !skey[0] || !skey[1] || !skey[2] || !skey[3] ) if( !skey[0] || !skey[1] || !skey[2] || !skey[3] )
return G10ERR_BAD_MPI; return G10ERR_BAD_MPI;
sk.p = skey[0]; sk.p = skey[0];
sk.g = skey[1]; sk.g = skey[1];
sk.y = skey[2]; sk.y = skey[2];
sk.x = skey[3]; sk.x = skey[3];
if( !check_secret_key( &sk ) ) if( !check_secret_key( &sk ) )
return G10ERR_BAD_SECKEY; return G10ERR_BAD_SECKEY;
return 0; return 0;
} }
@@ -492,80 +492,80 @@ elg_check_secret_key( int algo, MPI *skey )
int int
elg_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey ) elg_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
{ {
ELG_public_key pk; ELG_public_key pk;
if( !is_ELGAMAL(algo) ) if( !is_ELGAMAL(algo) )
return G10ERR_PUBKEY_ALGO; return G10ERR_PUBKEY_ALGO;
if( !data || !pkey[0] || !pkey[1] || !pkey[2] ) if( !data || !pkey[0] || !pkey[1] || !pkey[2] )
return G10ERR_BAD_MPI; return G10ERR_BAD_MPI;
pk.p = pkey[0]; pk.p = pkey[0];
pk.g = pkey[1]; pk.g = pkey[1];
pk.y = pkey[2]; pk.y = pkey[2];
resarr[0] = mpi_alloc( mpi_get_nlimbs( pk.p ) ); resarr[0] = mpi_alloc( mpi_get_nlimbs( pk.p ) );
resarr[1] = mpi_alloc( mpi_get_nlimbs( pk.p ) ); resarr[1] = mpi_alloc( mpi_get_nlimbs( pk.p ) );
encrypt( resarr[0], resarr[1], data, &pk ); encrypt( resarr[0], resarr[1], data, &pk );
return 0; return 0;
} }
int int
elg_decrypt( int algo, MPI *result, MPI *data, MPI *skey ) elg_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
{ {
ELG_secret_key sk; ELG_secret_key sk;
if( !is_ELGAMAL(algo) ) if( !is_ELGAMAL(algo) )
return G10ERR_PUBKEY_ALGO; return G10ERR_PUBKEY_ALGO;
if( !data[0] || !data[1] if( !data[0] || !data[1]
|| !skey[0] || !skey[1] || !skey[2] || !skey[3] ) || !skey[0] || !skey[1] || !skey[2] || !skey[3] )
return G10ERR_BAD_MPI; return G10ERR_BAD_MPI;
sk.p = skey[0]; sk.p = skey[0];
sk.g = skey[1]; sk.g = skey[1];
sk.y = skey[2]; sk.y = skey[2];
sk.x = skey[3]; sk.x = skey[3];
*result = mpi_alloc_secure( mpi_get_nlimbs( sk.p ) ); *result = mpi_alloc_secure( mpi_get_nlimbs( sk.p ) );
decrypt( *result, data[0], data[1], &sk ); decrypt( *result, data[0], data[1], &sk );
return 0; return 0;
} }
int int
elg_sign( int algo, MPI *resarr, MPI data, MPI *skey ) elg_sign( int algo, MPI *resarr, MPI data, MPI *skey )
{ {
ELG_secret_key sk; ELG_secret_key sk;
if( !is_ELGAMAL(algo) ) if( !is_ELGAMAL(algo) )
return G10ERR_PUBKEY_ALGO; return G10ERR_PUBKEY_ALGO;
if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] ) if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] )
return G10ERR_BAD_MPI; return G10ERR_BAD_MPI;
sk.p = skey[0]; sk.p = skey[0];
sk.g = skey[1]; sk.g = skey[1];
sk.y = skey[2]; sk.y = skey[2];
sk.x = skey[3]; sk.x = skey[3];
resarr[0] = mpi_alloc( mpi_get_nlimbs( sk.p ) ); resarr[0] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
resarr[1] = mpi_alloc( mpi_get_nlimbs( sk.p ) ); resarr[1] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
sign( resarr[0], resarr[1], data, &sk ); sign( resarr[0], resarr[1], data, &sk );
return 0; return 0;
} }
int int
elg_verify( int algo, MPI hash, MPI *data, MPI *pkey, elg_verify( int algo, MPI hash, MPI *data, MPI *pkey,
int (*cmp)(void *, MPI) UNUSED, void *opaquev UNUSED) int (*cmp)(void *, MPI) UNUSED, void *opaquev UNUSED)
{ {
ELG_public_key pk; ELG_public_key pk;
if( !is_ELGAMAL(algo) ) if( !is_ELGAMAL(algo) )
return G10ERR_PUBKEY_ALGO; return G10ERR_PUBKEY_ALGO;
if( !data[0] || !data[1] || !hash if( !data[0] || !data[1] || !hash
|| !pkey[0] || !pkey[1] || !pkey[2] ) || !pkey[0] || !pkey[1] || !pkey[2] )
return G10ERR_BAD_MPI; return G10ERR_BAD_MPI;
pk.p = pkey[0]; pk.p = pkey[0];
pk.g = pkey[1]; pk.g = pkey[1];
pk.y = pkey[2]; pk.y = pkey[2];
if( !verify( data[0], data[1], hash, &pk ) ) if( !verify( data[0], data[1], hash, &pk ) )
return G10ERR_BAD_SIGN; return G10ERR_BAD_SIGN;
return 0; return 0;
} }
@@ -573,9 +573,9 @@ elg_verify( int algo, MPI hash, MPI *data, MPI *pkey,
unsigned unsigned
elg_get_nbits( int algo, MPI *pkey ) elg_get_nbits( int algo, MPI *pkey )
{ {
if( !is_ELGAMAL(algo) ) if( !is_ELGAMAL(algo) )
return 0; return 0;
return mpi_get_nbits( pkey[0] ); return mpi_get_nbits( pkey[0] );
} }
@@ -583,31 +583,31 @@ elg_get_nbits( int algo, MPI *pkey )
* Return some information about the algorithm. We need algo here to * Return some information about the algorithm. We need algo here to
* distinguish different flavors of the algorithm. * distinguish different flavors of the algorithm.
* Returns: A pointer to string describing the algorithm or NULL if * Returns: A pointer to string describing the algorithm or NULL if
* the ALGO is invalid. * the ALGO is invalid.
* Usage: Bit 0 set : allows signing * Usage: Bit 0 set : allows signing
* 1 set : allows encryption * 1 set : allows encryption
* NOTE: This function allows signing also for ELG-E, which is not * NOTE: This function allows signing also for ELG-E, which is not
* okay but a bad hack to allow to work with old gpg keys. The real check * okay but a bad hack to allow to work with old gpg keys. The real check
* is done in the gnupg ocde depending on the packet version. * is done in the gnupg ocde depending on the packet version.
*/ */
const char * const char *
elg_get_info( int algo, int *npkey, int *nskey, int *nenc, int *nsig, elg_get_info( int algo, int *npkey, int *nskey, int *nenc, int *nsig,
int *use ) int *use )
{ {
*npkey = 3; *npkey = 3;
*nskey = 4; *nskey = 4;
*nenc = 2; *nenc = 2;
*nsig = 2; *nsig = 2;
switch( algo ) { switch( algo ) {
case PUBKEY_ALGO_ELGAMAL: case PUBKEY_ALGO_ELGAMAL:
*use = PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC; *use = PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC;
return "ELG"; return "ELG";
case PUBKEY_ALGO_ELGAMAL_E: case PUBKEY_ALGO_ELGAMAL_E:
*use = PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC; *use = PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC;
return "ELG-E"; return "ELG-E";
default: *use = 0; return NULL; default: *use = 0; return NULL;
} }
} }
+3 -3
View File
@@ -1,5 +1,5 @@
/* elgamal.h /* elgamal.h
* Copyright (C) 1998 Free Software Foundation, Inc. * Copyright (C) 1998 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@@ -26,10 +26,10 @@ int elg_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey );
int elg_decrypt( int algo, MPI *result, MPI *data, MPI *skey ); int elg_decrypt( int algo, MPI *result, MPI *data, MPI *skey );
int elg_sign( int algo, MPI *resarr, MPI data, MPI *skey ); int elg_sign( int algo, MPI *resarr, MPI data, MPI *skey );
int elg_verify( int algo, MPI hash, MPI *data, MPI *pkey, int elg_verify( int algo, MPI hash, MPI *data, MPI *pkey,
int (*cmp)(void *, MPI), void *opaquev ); int (*cmp)(void *, MPI), void *opaquev );
unsigned elg_get_nbits( int algo, MPI *pkey ); unsigned elg_get_nbits( int algo, MPI *pkey );
const char *elg_get_info( int algo, int *npkey, int *nskey, const char *elg_get_info( int algo, int *npkey, int *nskey,
int *nenc, int *nsig, int *use ); int *nenc, int *nsig, int *use );
#endif /*G10_ELGAMAL_H*/ #endif /*G10_ELGAMAL_H*/
+590 -590
View File
File diff suppressed because it is too large Load Diff
+13 -13
View File
@@ -17,25 +17,25 @@
#include "x509.h" #include "x509.h"
#define FETCH_CMD_TIMEOUT 10 /* seconds */ #define FETCH_CMD_TIMEOUT 10 /* seconds */
struct ocsp_location; /* forward declaration of ocsp_location defined in ocsp.h */ struct ocsp_location; /* forward declaration of ocsp_location defined in ocsp.h */
typedef enum { typedef enum {
FETCH_GET = 1, FETCH_GET = 1,
FETCH_POST = 2 FETCH_POST = 2
} fetch_request_t; } fetch_request_t;
typedef struct fetch_req fetch_req_t; typedef struct fetch_req fetch_req_t;
struct fetch_req { struct fetch_req {
fetch_req_t *next; fetch_req_t *next;
time_t installed; time_t installed;
int trials; int trials;
chunk_t issuer; chunk_t issuer;
chunk_t authKeyID; chunk_t authKeyID;
chunk_t authKeySerialNumber; chunk_t authKeySerialNumber;
generalName_t *distributionPoints; generalName_t *distributionPoints;
}; };
#ifdef THREADS #ifdef THREADS
@@ -67,9 +67,9 @@ extern void init_fetch(void);
extern void free_crl_fetch(void); extern void free_crl_fetch(void);
extern void free_ocsp_fetch(void); extern void free_ocsp_fetch(void);
extern void add_distribution_points(const generalName_t *newPoints extern void add_distribution_points(const generalName_t *newPoints
, generalName_t **distributionPoints); , generalName_t **distributionPoints);
extern fetch_req_t* build_crl_fetch_request(chunk_t issuer, chunk_t authKeySerialNumber extern fetch_req_t* build_crl_fetch_request(chunk_t issuer, chunk_t authKeySerialNumber
, chunk_t authKeyID, const generalName_t *gn); , chunk_t authKeyID, const generalName_t *gn);
extern void add_crl_fetch_request(fetch_req_t *req); extern void add_crl_fetch_request(fetch_req_t *req);
extern void add_ocsp_fetch_request(struct ocsp_location *location, chunk_t serialNumber); extern void add_ocsp_fetch_request(struct ocsp_location *location, chunk_t serialNumber);
extern void list_distribution_points(const generalName_t *gn); extern void list_distribution_points(const generalName_t *gn);
+294 -294
View File
@@ -49,8 +49,8 @@ static size_t fg_path_space = 0;
*/ */
struct fg_groups { struct fg_groups {
struct fg_groups *next; struct fg_groups *next;
struct connection *connection; struct connection *connection;
}; };
static struct fg_groups *groups = NULL; static struct fg_groups *groups = NULL;
@@ -66,10 +66,10 @@ static struct fg_groups *groups = NULL;
*/ */
struct fg_targets { struct fg_targets {
struct fg_targets *next; struct fg_targets *next;
struct fg_groups *group; struct fg_groups *group;
ip_subnet subnet; ip_subnet subnet;
char *name; /* name of instance of group conn */ char *name; /* name of instance of group conn */
}; };
static struct fg_targets *targets = NULL; static struct fg_targets *targets = NULL;
@@ -83,24 +83,24 @@ struct fg_targets *new_targets;
static int static int
ipcmp(ip_address *a, ip_address *b) ipcmp(ip_address *a, ip_address *b)
{ {
if (addrtypeof(a) != addrtypeof(b)) if (addrtypeof(a) != addrtypeof(b))
{ {
return addrtypeof(a) < addrtypeof(b)? -1 : 1; return addrtypeof(a) < addrtypeof(b)? -1 : 1;
} }
else if (sameaddr(a, b)) else if (sameaddr(a, b))
{ {
return 0; return 0;
} }
else else
{ {
const struct sockaddr *sa = sockaddrof(a) const struct sockaddr *sa = sockaddrof(a)
, *sb = sockaddrof(b); , *sb = sockaddrof(b);
passert(addrtypeof(a) == AF_INET); /* not yet implemented IPv6 version :-( */ passert(addrtypeof(a) == AF_INET); /* not yet implemented IPv6 version :-( */
return (ntohl(((const struct sockaddr_in *)sa)->sin_addr.s_addr) return (ntohl(((const struct sockaddr_in *)sa)->sin_addr.s_addr)
< ntohl(((const struct sockaddr_in *)sb)->sin_addr.s_addr)) < ntohl(((const struct sockaddr_in *)sb)->sin_addr.s_addr))
? -1 : 1; ? -1 : 1;
} }
} }
/* subnetcmp compares the two ip_subnet values a and b. /* subnetcmp compares the two ip_subnet values a and b.
@@ -110,353 +110,353 @@ ipcmp(ip_address *a, ip_address *b)
static int static int
subnetcmp(const ip_subnet *a, const ip_subnet *b) subnetcmp(const ip_subnet *a, const ip_subnet *b)
{ {
ip_address neta, maska, netb, maskb; ip_address neta, maska, netb, maskb;
int r; int r;
networkof(a, &neta); networkof(a, &neta);
maskof(a, &maska); maskof(a, &maska);
networkof(b, &netb); networkof(b, &netb);
maskof(b, &maskb); maskof(b, &maskb);
r = ipcmp(&neta, &netb); r = ipcmp(&neta, &netb);
if (r == 0) if (r == 0)
r = ipcmp(&maska, &maskb); r = ipcmp(&maska, &maskb);
return r; return r;
} }
static void static void
read_foodgroup(struct fg_groups *g) read_foodgroup(struct fg_groups *g)
{ {
const char *fgn = g->connection->name; const char *fgn = g->connection->name;
const ip_subnet *lsn = &g->connection->spd.this.client; const ip_subnet *lsn = &g->connection->spd.this.client;
size_t plen = strlen(policygroups_dir) + 1 + strlen(fgn) + 1; size_t plen = strlen(policygroups_dir) + 1 + strlen(fgn) + 1;
struct file_lex_position flp_space; struct file_lex_position flp_space;
if (plen > fg_path_space) if (plen > fg_path_space)
{
free(fg_path);
fg_path_space = plen + 10;
fg_path = malloc(fg_path_space);
}
snprintf(fg_path, fg_path_space, "%s/%s", policygroups_dir, fgn);
if (!lexopen(&flp_space, fg_path, TRUE))
{
DBG(DBG_CONTROL, DBG_log("no group file \"%s\"", fg_path));
}
else
{
plog("loading group \"%s\"", fg_path);
for (;;)
{ {
switch (flp->bdry) free(fg_path);
{ fg_path_space = plen + 10;
case B_none: fg_path = malloc(fg_path_space);
}
snprintf(fg_path, fg_path_space, "%s/%s", policygroups_dir, fgn);
if (!lexopen(&flp_space, fg_path, TRUE))
{
DBG(DBG_CONTROL, DBG_log("no group file \"%s\"", fg_path));
}
else
{
plog("loading group \"%s\"", fg_path);
for (;;)
{ {
/* !!! this test is not sufficient for distinguishing address families. switch (flp->bdry)
* We need a notation to specify that a FQDN is to be resolved to IPv6. {
*/ case B_none:
const struct af_info *afi = strchr(tok, ':') == NULL {
? &af_inet4_info: &af_inet6_info; /* !!! this test is not sufficient for distinguishing address families.
ip_subnet sn; * We need a notation to specify that a FQDN is to be resolved to IPv6.
err_t ugh; */
const struct af_info *afi = strchr(tok, ':') == NULL
? &af_inet4_info: &af_inet6_info;
ip_subnet sn;
err_t ugh;
if (strchr(tok, '/') == NULL)
{
/* no /, so treat as /32 or V6 equivalent */
ip_address t;
ugh = ttoaddr(tok, 0, afi->af, &t);
if (ugh == NULL)
ugh = addrtosubnet(&t, &sn);
}
else
{
ugh = ttosubnet(tok, 0, afi->af, &sn);
}
if (strchr(tok, '/') == NULL) if (ugh != NULL)
{ {
/* no /, so treat as /32 or V6 equivalent */ loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s \"%s\""
ip_address t; , flp->filename, flp->lino, ugh, tok);
}
else if (afi->af != AF_INET)
{
loglog(RC_LOG_SERIOUS
, "\"%s\" line %d: unsupported Address Family \"%s\""
, flp->filename, flp->lino, tok);
}
else
{
/* Find where new entry ought to go in new_targets. */
struct fg_targets **pp;
int r;
ugh = ttoaddr(tok, 0, afi->af, &t); for (pp = &new_targets; ; pp = &(*pp)->next)
if (ugh == NULL) {
ugh = addrtosubnet(&t, &sn); if (*pp == NULL)
} {
else r = -1; /* end of list is infinite */
{ break;
ugh = ttosubnet(tok, 0, afi->af, &sn); }
} r = subnetcmp(lsn, &(*pp)->group->connection->spd.this.client);
if (r == 0)
r = subnetcmp(&sn, &(*pp)->subnet);
if (r <= 0)
break;
}
if (ugh != NULL) if (r == 0)
{ {
loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s \"%s\"" char source[SUBNETTOT_BUF];
, flp->filename, flp->lino, ugh, tok);
}
else if (afi->af != AF_INET)
{
loglog(RC_LOG_SERIOUS
, "\"%s\" line %d: unsupported Address Family \"%s\""
, flp->filename, flp->lino, tok);
}
else
{
/* Find where new entry ought to go in new_targets. */
struct fg_targets **pp;
int r;
for (pp = &new_targets; ; pp = &(*pp)->next) subnettot(lsn, 0, source, sizeof(source));
{ loglog(RC_LOG_SERIOUS
if (*pp == NULL) , "\"%s\" line %d: subnet \"%s\", source %s, already \"%s\""
{ , flp->filename
r = -1; /* end of list is infinite */ , flp->lino
break; , tok
} , source
r = subnetcmp(lsn, &(*pp)->group->connection->spd.this.client); , (*pp)->group->connection->name);
if (r == 0) }
r = subnetcmp(&sn, &(*pp)->subnet); else
if (r <= 0) {
break; struct fg_targets *f = malloc_thing(struct fg_targets);
}
if (r == 0) f->next = *pp;
{ f->group = g;
char source[SUBNETTOT_BUF]; f->subnet = sn;
f->name = NULL;
*pp = f;
}
}
}
(void)shift(); /* next */
continue;
subnettot(lsn, 0, source, sizeof(source)); case B_record:
loglog(RC_LOG_SERIOUS flp->bdry = B_none; /* eat the Record Boundary */
, "\"%s\" line %d: subnet \"%s\", source %s, already \"%s\"" (void)shift(); /* get real first token */
, flp->filename continue;
, flp->lino
, tok
, source
, (*pp)->group->connection->name);
}
else
{
struct fg_targets *f = malloc_thing(struct fg_targets);
f->next = *pp; case B_file:
f->group = g; break; /* done */
f->subnet = sn;
f->name = NULL;
*pp = f;
} }
} break; /* if we reach here, out of loop */
} }
(void)shift(); /* next */ lexclose();
continue;
case B_record:
flp->bdry = B_none; /* eat the Record Boundary */
(void)shift(); /* get real first token */
continue;
case B_file:
break; /* done */
}
break; /* if we reach here, out of loop */
} }
lexclose();
}
} }
static void static void
free_targets(void) free_targets(void)
{ {
while (targets != NULL) while (targets != NULL)
{ {
struct fg_targets *t = targets; struct fg_targets *t = targets;
targets = t->next; targets = t->next;
free(t->name); free(t->name);
free(t); free(t);
} }
} }
void void
load_groups(void) load_groups(void)
{ {
passert(new_targets == NULL); passert(new_targets == NULL);
/* for each group, add config file targets into new_targets */ /* for each group, add config file targets into new_targets */
{
struct fg_groups *g;
for (g = groups; g != NULL; g = g->next)
if (oriented(*g->connection))
read_foodgroup(g);
}
/* dump new_targets */
DBG(DBG_CONTROL,
{ {
struct fg_targets *t; struct fg_groups *g;
for (t = new_targets; t != NULL; t = t->next) for (g = groups; g != NULL; g = g->next)
{ if (oriented(*g->connection))
char asource[SUBNETTOT_BUF]; read_foodgroup(g);
char atarget[SUBNETTOT_BUF];
subnettot(&t->group->connection->spd.this.client
, 0, asource, sizeof(asource));
subnettot(&t->subnet, 0, atarget, sizeof(atarget));
DBG_log("%s->%s %s"
, asource, atarget
, t->group->connection->name);
}
});
/* determine and deal with differences between targets and new_targets.
* structured like a merge.
*/
{
struct fg_targets *op = targets
, *np = new_targets;
while (op != NULL && np != NULL)
{
int r = subnetcmp(&op->group->connection->spd.this.client
, &np->group->connection->spd.this.client);
if (r == 0)
r = subnetcmp(&op->subnet, &np->subnet);
if (r == 0 && op->group == np->group)
{
/* unchanged -- steal name & skip over */
np->name = op->name;
op->name = NULL;
op = op->next;
np = np->next;
}
else
{
/* note: following cases overlap! */
if (r <= 0)
{
remove_group_instance(op->group->connection, op->name);
op = op->next;
}
if (r >= 0)
{
np->name = add_group_instance(np->group->connection, &np->subnet);
np = np->next;
}
}
} }
for (; op != NULL; op = op->next)
remove_group_instance(op->group->connection, op->name);
for (; np != NULL; np = np->next)
np->name = add_group_instance(np->group->connection, &np->subnet);
/* update: new_targets replaces targets */ /* dump new_targets */
free_targets(); DBG(DBG_CONTROL,
targets = new_targets; {
new_targets = NULL; struct fg_targets *t;
}
for (t = new_targets; t != NULL; t = t->next)
{
char asource[SUBNETTOT_BUF];
char atarget[SUBNETTOT_BUF];
subnettot(&t->group->connection->spd.this.client
, 0, asource, sizeof(asource));
subnettot(&t->subnet, 0, atarget, sizeof(atarget));
DBG_log("%s->%s %s"
, asource, atarget
, t->group->connection->name);
}
});
/* determine and deal with differences between targets and new_targets.
* structured like a merge.
*/
{
struct fg_targets *op = targets
, *np = new_targets;
while (op != NULL && np != NULL)
{
int r = subnetcmp(&op->group->connection->spd.this.client
, &np->group->connection->spd.this.client);
if (r == 0)
r = subnetcmp(&op->subnet, &np->subnet);
if (r == 0 && op->group == np->group)
{
/* unchanged -- steal name & skip over */
np->name = op->name;
op->name = NULL;
op = op->next;
np = np->next;
}
else
{
/* note: following cases overlap! */
if (r <= 0)
{
remove_group_instance(op->group->connection, op->name);
op = op->next;
}
if (r >= 0)
{
np->name = add_group_instance(np->group->connection, &np->subnet);
np = np->next;
}
}
}
for (; op != NULL; op = op->next)
remove_group_instance(op->group->connection, op->name);
for (; np != NULL; np = np->next)
np->name = add_group_instance(np->group->connection, &np->subnet);
/* update: new_targets replaces targets */
free_targets();
targets = new_targets;
new_targets = NULL;
}
} }
void void
add_group(struct connection *c) add_group(struct connection *c)
{ {
struct fg_groups *g = malloc_thing(struct fg_groups); struct fg_groups *g = malloc_thing(struct fg_groups);
g->next = groups; g->next = groups;
groups = g; groups = g;
g->connection = c; g->connection = c;
} }
static struct fg_groups * static struct fg_groups *
find_group(const struct connection *c) find_group(const struct connection *c)
{ {
struct fg_groups *g; struct fg_groups *g;
for (g = groups; g != NULL && g->connection != c; g = g->next) for (g = groups; g != NULL && g->connection != c; g = g->next)
; ;
return g; return g;
} }
void void
route_group(struct connection *c) route_group(struct connection *c)
{ {
/* it makes no sense to route a connection that is ISAKMP-only */ /* it makes no sense to route a connection that is ISAKMP-only */
if (!NEVER_NEGOTIATE(c->policy) && !HAS_IPSEC_POLICY(c->policy)) if (!NEVER_NEGOTIATE(c->policy) && !HAS_IPSEC_POLICY(c->policy))
{
loglog(RC_ROUTE, "cannot route an ISAKMP-only group connection");
}
else
{
struct fg_groups *g = find_group(c);
struct fg_targets *t;
passert(g != NULL);
g->connection->policy |= POLICY_GROUTED;
for (t = targets; t != NULL; t = t->next)
{ {
if (t->group == g) loglog(RC_ROUTE, "cannot route an ISAKMP-only group connection");
{ }
struct connection *ci = con_by_name(t->name, FALSE); else
{
struct fg_groups *g = find_group(c);
struct fg_targets *t;
if (ci != NULL) passert(g != NULL);
g->connection->policy |= POLICY_GROUTED;
for (t = targets; t != NULL; t = t->next)
{ {
set_cur_connection(ci); if (t->group == g)
if (!trap_connection(ci)) {
whack_log(RC_ROUTE, "could not route"); struct connection *ci = con_by_name(t->name, FALSE);
set_cur_connection(c);
if (ci != NULL)
{
set_cur_connection(ci);
if (!trap_connection(ci))
whack_log(RC_ROUTE, "could not route");
set_cur_connection(c);
}
}
} }
}
} }
}
} }
void void
unroute_group(struct connection *c) unroute_group(struct connection *c)
{ {
struct fg_groups *g = find_group(c); struct fg_groups *g = find_group(c);
struct fg_targets *t; struct fg_targets *t;
passert(g != NULL); passert(g != NULL);
g->connection->policy &= ~POLICY_GROUTED; g->connection->policy &= ~POLICY_GROUTED;
for (t = targets; t != NULL; t = t->next) for (t = targets; t != NULL; t = t->next)
{
if (t->group == g)
{ {
struct connection *ci = con_by_name(t->name, FALSE); if (t->group == g)
{
struct connection *ci = con_by_name(t->name, FALSE);
if (ci != NULL) if (ci != NULL)
{ {
set_cur_connection(ci); set_cur_connection(ci);
unroute_connection(ci); unroute_connection(ci);
set_cur_connection(c); set_cur_connection(c);
} }
}
} }
}
} }
void void
delete_group(const struct connection *c) delete_group(const struct connection *c)
{ {
struct fg_groups *g; struct fg_groups *g;
/* find and remove from groups */ /* find and remove from groups */
{
struct fg_groups **pp;
for (pp = &groups; (g = *pp)->connection != c; pp = &(*pp)->next)
;
*pp = g->next;
}
/* find and remove from targets */
{
struct fg_targets **pp;
for (pp = &targets; *pp != NULL; )
{ {
struct fg_targets *t = *pp; struct fg_groups **pp;
if (t->group == g) for (pp = &groups; (g = *pp)->connection != c; pp = &(*pp)->next)
{ ;
*pp = t->next;
remove_group_instance(t->group->connection, t->name); *pp = g->next;
free(t);
/* pp is ready for next iteration */
}
else
{
pp = &t->next;
}
} }
}
free(g); /* find and remove from targets */
{
struct fg_targets **pp;
for (pp = &targets; *pp != NULL; )
{
struct fg_targets *t = *pp;
if (t->group == g)
{
*pp = t->next;
remove_group_instance(t->group->connection, t->name);
free(t);
/* pp is ready for next iteration */
}
else
{
pp = &t->next;
}
}
}
free(g);
} }
+1 -1
View File
@@ -14,7 +14,7 @@
* RCSID $Id$ * RCSID $Id$
*/ */
struct connection; /* forward declaration */ struct connection; /* forward declaration */
extern void add_group(struct connection *c); extern void add_group(struct connection *c);
extern void route_group(struct connection *c); extern void route_group(struct connection *c);
extern void unroute_group(struct connection *c); extern void unroute_group(struct connection *c);
+133 -133
View File
@@ -22,134 +22,134 @@
#include "defs.h" #include "defs.h"
#include "log.h" #include "log.h"
#include "rnd.h" #include "rnd.h"
#include "gcryptfix.h" /* includes <gmp.h> "defs.h" "rnd.h" */ #include "gcryptfix.h" /* includes <gmp.h> "defs.h" "rnd.h" */
MPI MPI
mpi_alloc( unsigned nlimbs UNUSED ) mpi_alloc( unsigned nlimbs UNUSED )
{ {
MPI n = malloc(sizeof *n); MPI n = malloc(sizeof *n);
mpz_init(n); mpz_init(n);
return n; return n;
} }
MPI MPI
mpi_alloc_secure( unsigned nlimbs ) mpi_alloc_secure( unsigned nlimbs )
{ {
return mpi_alloc(nlimbs); return mpi_alloc(nlimbs);
} }
MPI MPI
mpi_alloc_set_ui( unsigned long u) mpi_alloc_set_ui( unsigned long u)
{ {
MPI n = malloc(sizeof *n); MPI n = malloc(sizeof *n);
mpz_init_set_ui(n, u); mpz_init_set_ui(n, u);
return n; return n;
} }
MPI MPI
mpi_copy( MPI a ) mpi_copy( MPI a )
{ {
MPI n = malloc(sizeof *n); MPI n = malloc(sizeof *n);
mpz_init_set(n, a); mpz_init_set(n, a);
return n; return n;
} }
void void
mpi_free( MPI a ) mpi_free( MPI a )
{ {
mpz_clear(a); mpz_clear(a);
free(a); free(a);
} }
int int
mpi_divisible_ui(MPI dividend, ulong divisor ) mpi_divisible_ui(MPI dividend, ulong divisor )
{ {
ulong rem; ulong rem;
mpz_t remtoo; mpz_t remtoo;
mpz_init(remtoo); mpz_init(remtoo);
rem = mpz_mod_ui(remtoo, dividend, divisor); rem = mpz_mod_ui(remtoo, dividend, divisor);
mpz_clear(remtoo); mpz_clear(remtoo);
return rem == 0; return rem == 0;
} }
unsigned unsigned
mpi_trailing_zeros( MPI a ) mpi_trailing_zeros( MPI a )
{ {
return mpz_scan1(a, 0); return mpz_scan1(a, 0);
} }
unsigned unsigned
mpi_get_nbits( MPI a ) mpi_get_nbits( MPI a )
{ {
return mpz_sizeinbase(a, 2); return mpz_sizeinbase(a, 2);
} }
int int
mpi_test_bit( MPI a, unsigned n ) mpi_test_bit( MPI a, unsigned n )
{ {
/* inspired by gmp/mpz/clrbit.c */ /* inspired by gmp/mpz/clrbit.c */
mp_size_t li = n / mp_bits_per_limb; mp_size_t li = n / mp_bits_per_limb;
if (li >= a->_mp_size) if (li >= a->_mp_size)
return 0; return 0;
return (a->_mp_d[li] & ((mp_limb_t) 1 << (n % mp_bits_per_limb))) != 0; return (a->_mp_d[li] & ((mp_limb_t) 1 << (n % mp_bits_per_limb))) != 0;
} }
void void
mpi_set_bit( MPI a, unsigned n ) mpi_set_bit( MPI a, unsigned n )
{ {
mpz_setbit(a, n); mpz_setbit(a, n);
} }
void void
mpi_clear_bit( MPI a, unsigned n ) mpi_clear_bit( MPI a, unsigned n )
{ {
mpz_clrbit(a, n); mpz_clrbit(a, n);
} }
void void
mpi_clear_highbit( MPI a, unsigned n ) mpi_clear_highbit( MPI a, unsigned n )
{ {
/* This seems whacky, but what do I know. */ /* This seems whacky, but what do I know. */
mpz_fdiv_r_2exp(a, a, n); mpz_fdiv_r_2exp(a, a, n);
} }
void void
mpi_set_highbit( MPI a, unsigned n ) mpi_set_highbit( MPI a, unsigned n )
{ {
/* This seems whacky, but what do I know. */ /* This seems whacky, but what do I know. */
mpz_fdiv_r_2exp(a, a, n+1); mpz_fdiv_r_2exp(a, a, n+1);
mpz_setbit(a, n); mpz_setbit(a, n);
} }
void void
mpi_set_buffer( MPI a, const u_char *buffer, unsigned nbytes, int sign ) mpi_set_buffer( MPI a, const u_char *buffer, unsigned nbytes, int sign )
{ {
/* this is a lot like n_to_mpz */ /* this is a lot like n_to_mpz */
size_t i; size_t i;
passert(sign == 0); /* we won't hit any negative numbers */ passert(sign == 0); /* we won't hit any negative numbers */
mpz_init_set_ui(a, 0); mpz_init_set_ui(a, 0);
for (i = 0; i != nbytes; i++) for (i = 0; i != nbytes; i++)
{ {
mpz_mul_ui(a, a, 1 << BITS_PER_BYTE); mpz_mul_ui(a, a, 1 << BITS_PER_BYTE);
mpz_add_ui(a, a, buffer[i]); mpz_add_ui(a, a, buffer[i]);
} }
} }
u_char * u_char *
get_random_bits(size_t nbits, int level UNUSED, int secure UNUSED) get_random_bits(size_t nbits, int level UNUSED, int secure UNUSED)
{ {
size_t nbytes = (nbits+7)/8; size_t nbytes = (nbits+7)/8;
u_char *b = malloc(nbytes); u_char *b = malloc(nbytes);
get_rnd_bytes(b, nbytes); get_rnd_bytes(b, nbytes);
return b; return b;
} }
/**************** from gnupg-1.0.0/mpi/mpi-mpow.c /**************** from gnupg-1.0.0/mpi/mpi-mpow.c
* RES = (BASE[0] ^ EXP[0]) * (BASE[1] ^ EXP[1]) * ... * mod M * RES = (BASE[0] ^ EXP[0]) * (BASE[1] ^ EXP[1]) * ... * mod M
@@ -159,125 +159,125 @@ get_random_bits(size_t nbits, int level UNUSED, int secure UNUSED)
static int static int
build_index( MPI *exparray, int k, int i, int t ) build_index( MPI *exparray, int k, int i, int t )
{ {
int j, bitno; int j, bitno;
int index = 0; int index = 0;
bitno = t-i; bitno = t-i;
for(j=k-1; j >= 0; j-- ) { for(j=k-1; j >= 0; j-- ) {
index <<= 1; index <<= 1;
if( mpi_test_bit( exparray[j], bitno ) ) if( mpi_test_bit( exparray[j], bitno ) )
index |= 1; index |= 1;
} }
/*log_debug("t=%d i=%d index=%d\n", t, i, index );*/ /*log_debug("t=%d i=%d index=%d\n", t, i, index );*/
return index; return index;
} }
void void
mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI m) mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI m)
{ {
int k; /* number of elements */ int k; /* number of elements */
int t; /* bit size of largest exponent */ int t; /* bit size of largest exponent */
int i, j, idx; int i, j, idx;
MPI *G; /* table with precomputed values of size 2^k */ MPI *G; /* table with precomputed values of size 2^k */
MPI tmp; MPI tmp;
#ifdef USE_BARRETT #ifdef USE_BARRETT
MPI barrett_y, barrett_r1, barrett_r2; MPI barrett_y, barrett_r1, barrett_r2;
int barrett_k; int barrett_k;
#endif #endif
for(k=0; basearray[k]; k++ ) for(k=0; basearray[k]; k++ )
; ;
passert(k); passert(k);
for(t=0, i=0; (tmp=exparray[i]); i++ ) { for(t=0, i=0; (tmp=exparray[i]); i++ ) {
/*log_mpidump("exp: ", tmp );*/ /*log_mpidump("exp: ", tmp );*/
j = mpi_get_nbits(tmp); j = mpi_get_nbits(tmp);
if( j > t ) if( j > t )
t = j; t = j;
} }
/*log_mpidump("mod: ", m );*/ /*log_mpidump("mod: ", m );*/
passert(i==k); passert(i==k);
passert(t); passert(t);
passert( k < 10 ); passert( k < 10 );
#ifdef PLUTO #ifdef PLUTO
m_alloc_ptrs_clear(G, 1<<k); m_alloc_ptrs_clear(G, 1<<k);
#else #else
G = m_alloc_clear( (1<<k) * sizeof *G ); G = m_alloc_clear( (1<<k) * sizeof *G );
#endif #endif
#ifdef USE_BARRETT #ifdef USE_BARRETT
barrett_y = init_barrett( m, &barrett_k, &barrett_r1, &barrett_r2 ); barrett_y = init_barrett( m, &barrett_k, &barrett_r1, &barrett_r2 );
#endif #endif
/* and calculate */ /* and calculate */
tmp = mpi_alloc( mpi_get_nlimbs(m)+1 ); tmp = mpi_alloc( mpi_get_nlimbs(m)+1 );
mpi_set_ui( res, 1 ); mpi_set_ui( res, 1 );
for(i = 1; i <= t; i++ ) { for(i = 1; i <= t; i++ ) {
barrett_mulm(tmp, res, res, m, barrett_y, barrett_k, barrett_mulm(tmp, res, res, m, barrett_y, barrett_k,
barrett_r1, barrett_r2 ); barrett_r1, barrett_r2 );
idx = build_index( exparray, k, i, t ); idx = build_index( exparray, k, i, t );
passert( idx >= 0 && idx < (1<<k) ); passert( idx >= 0 && idx < (1<<k) );
if( !G[idx] ) { if( !G[idx] ) {
if( !idx ) if( !idx )
G[0] = mpi_alloc_set_ui( 1 ); G[0] = mpi_alloc_set_ui( 1 );
else { else {
for(j=0; j < k; j++ ) { for(j=0; j < k; j++ ) {
if( (idx & (1<<j) ) ) { if( (idx & (1<<j) ) ) {
if( !G[idx] ) if( !G[idx] )
G[idx] = mpi_copy( basearray[j] ); G[idx] = mpi_copy( basearray[j] );
else else
barrett_mulm( G[idx], G[idx], basearray[j], barrett_mulm( G[idx], G[idx], basearray[j],
m, barrett_y, barrett_k, barrett_r1, barrett_r2 ); m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
} }
}
if( !G[idx] )
G[idx] = mpi_alloc(0);
}
} }
if( !G[idx] ) barrett_mulm(res, tmp, G[idx], m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
G[idx] = mpi_alloc(0);
}
} }
barrett_mulm(res, tmp, G[idx], m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
}
/* cleanup */ /* cleanup */
mpi_free(tmp); mpi_free(tmp);
#ifdef USE_BARRETT #ifdef USE_BARRETT
mpi_free(barrett_y); mpi_free(barrett_y);
mpi_free(barrett_r1); mpi_free(barrett_r1);
mpi_free(barrett_r2); mpi_free(barrett_r2);
#endif #endif
for(i=0; i < (1<<k); i++ ) for(i=0; i < (1<<k); i++ )
mpi_free(G[i]); mpi_free(G[i]);
m_free(G); m_free(G);
} }
void void
log_mpidump( const char *text UNUSED, MPI a ) log_mpidump( const char *text UNUSED, MPI a )
{ {
/* Print number in hex -- helpful to see if they match bytes. /* Print number in hex -- helpful to see if they match bytes.
* Humans are not going to do arithmetic with the large numbers! * Humans are not going to do arithmetic with the large numbers!
* Much code adapted from mpz_to_n. * Much code adapted from mpz_to_n.
*/ */
u_char buf[8048]; /* this ought to be big enough */ u_char buf[8048]; /* this ought to be big enough */
size_t len = (mpz_sizeinbase(a, 16) + 1) / 2; /* bytes */ size_t len = (mpz_sizeinbase(a, 16) + 1) / 2; /* bytes */
MP_INT temp1, temp2; MP_INT temp1, temp2;
int i; int i;
passert(len <= sizeof(buf)); passert(len <= sizeof(buf));
mpz_init(&temp1); mpz_init(&temp1);
mpz_init(&temp2); mpz_init(&temp2);
mpz_set(&temp1, a); mpz_set(&temp1, a);
for (i = len-1; i >= 0; i--) for (i = len-1; i >= 0; i--)
{ {
buf[i] = mpz_mdivmod_ui(&temp2, NULL, &temp1, 1 << BITS_PER_BYTE); buf[i] = mpz_mdivmod_ui(&temp2, NULL, &temp1, 1 << BITS_PER_BYTE);
mpz_set(&temp1, &temp2); mpz_set(&temp1, &temp2);
} }
passert(mpz_sgn(&temp1) == 0); /* we must have done all the bits */ passert(mpz_sgn(&temp1) == 0); /* we must have done all the bits */
mpz_clear(&temp1); mpz_clear(&temp1);
mpz_clear(&temp2); mpz_clear(&temp2);
#ifdef DEBUG #ifdef DEBUG
DBG_dump(text, buf, len); DBG_dump(text, buf, len);
#endif /* DEBUG */ #endif /* DEBUG */
} }
+13 -13
View File
@@ -14,7 +14,7 @@
* RCSID $Id$ * RCSID $Id$
*/ */
#define DBG_CIPHER 1 /* some day we'll do this right */ #define DBG_CIPHER 1 /* some day we'll do this right */
/* Simulate MPI routines with gmp routines. /* Simulate MPI routines with gmp routines.
* gmp's MP_INT is a stuct; MPI's MPI is a pointer to an analogous struct. * gmp's MP_INT is a stuct; MPI's MPI is a pointer to an analogous struct.
@@ -35,7 +35,7 @@ extern MPI mpi_alloc_set_ui( unsigned long u);
extern void mpi_free( MPI a ); extern void mpi_free( MPI a );
extern MPI mpi_copy( MPI a ); extern MPI mpi_copy( MPI a );
extern unsigned mpi_get_nbits( MPI a ); extern unsigned mpi_get_nbits( MPI a );
#define mpi_get_nlimbs(a) ((a)->_mp_alloc) /* dirty, but useless */ #define mpi_get_nlimbs(a) ((a)->_mp_alloc) /* dirty, but useless */
extern void mpi_set_buffer( MPI a, const u_char *buffer, unsigned nbytes, int sign ); extern void mpi_set_buffer( MPI a, const u_char *buffer, unsigned nbytes, int sign );
extern unsigned mpi_trailing_zeros( MPI a ); extern unsigned mpi_trailing_zeros( MPI a );
extern int mpi_test_bit( MPI a, unsigned n ); extern int mpi_test_bit( MPI a, unsigned n );
@@ -66,22 +66,22 @@ extern void mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI mod);
#ifdef DEBUG #ifdef DEBUG
# define log_debug(f...) DBG_log(f) # define log_debug(f...) DBG_log(f)
#else #else
# define log_debug(f...) do ; while (0) /* do nothing, carefully */ # define log_debug(f...) do ; while (0) /* do nothing, carefully */
#endif #endif
#define log_fatal(f...) exit_log(f) /* overreaction? */ #define log_fatal(f...) exit_log(f) /* overreaction? */
extern void log_mpidump( const char *text, MPI a ); extern void log_mpidump( const char *text, MPI a );
#define assert(p) passert(p) #define assert(p) passert(p)
#define BUG() passert(FALSE) #define BUG() passert(FALSE)
#define m_alloc_ptrs_clear(pp, n) { \ #define m_alloc_ptrs_clear(pp, n) { \
int c = (n); \ int c = (n); \
(pp) = malloc((n) * sizeof(*(pp))); \ (pp) = malloc((n) * sizeof(*(pp))); \
while (c > 0) (pp)[--c] = NULL; \ while (c > 0) (pp)[--c] = NULL; \
} }
extern u_char *get_random_bits(size_t nbits, int level, int secure); extern u_char *get_random_bits(size_t nbits, int level, int secure);
#define m_alloc(sz) malloc((sz)) /* not initialized */ #define m_alloc(sz) malloc((sz)) /* not initialized */
#define m_free(n) free(n) /* always freeing something from get_random_bits */ #define m_free(n) free(n) /* always freeing something from get_random_bits */
/* declarations from gnupg-1.0.0/include/cipher.h */ /* declarations from gnupg-1.0.0/include/cipher.h */
@@ -89,7 +89,7 @@ extern u_char *get_random_bits(size_t nbits, int level, int secure);
MPI generate_secret_prime( unsigned nbits ); MPI generate_secret_prime( unsigned nbits );
MPI generate_public_prime( unsigned nbits ); MPI generate_public_prime( unsigned nbits );
MPI generate_elg_prime( int mode, unsigned pbits, unsigned qbits, MPI generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
MPI g, MPI **factors ); MPI g, MPI **factors );
#define PUBKEY_ALGO_ELGAMAL_E 16 /* encrypt only ElGamal (but not for v3)*/ #define PUBKEY_ALGO_ELGAMAL_E 16 /* encrypt only ElGamal (but not for v3)*/
#define PUBKEY_ALGO_DSA 17 #define PUBKEY_ALGO_DSA 17
@@ -97,15 +97,15 @@ MPI generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
#define is_ELGAMAL(a) ((a)==PUBKEY_ALGO_ELGAMAL || (a)==PUBKEY_ALGO_ELGAMAL_E) #define is_ELGAMAL(a) ((a)==PUBKEY_ALGO_ELGAMAL || (a)==PUBKEY_ALGO_ELGAMAL_E)
#define PUBKEY_USAGE_SIG 1 /* key is good for signatures */ #define PUBKEY_USAGE_SIG 1 /* key is good for signatures */
#define PUBKEY_USAGE_ENC 2 /* key is good for encryption */ #define PUBKEY_USAGE_ENC 2 /* key is good for encryption */
/* from gnupg-1.0.0/include/errors.h */ /* from gnupg-1.0.0/include/errors.h */
#define G10ERR_PUBKEY_ALGO 4 /* Unknown pubkey algorithm */ #define G10ERR_PUBKEY_ALGO 4 /* Unknown pubkey algorithm */
#define G10ERR_BAD_SECKEY 7 /* Bad secret key */ #define G10ERR_BAD_SECKEY 7 /* Bad secret key */
#define G10ERR_BAD_SIGN 8 /* Bad signature */ #define G10ERR_BAD_SIGN 8 /* Bad signature */
#define G10ERR_BAD_MPI 30 #define G10ERR_BAD_MPI 30
/*-- smallprime.c --*/ /*-- smallprime.c --*/
extern ushort small_prime_numbers[]; extern ushort small_prime_numbers[];
+330 -330
View File
@@ -22,8 +22,8 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <unistd.h> #include <unistd.h>
#ifndef HOST_NAME_MAX /* POSIX 1003.1-2001 says <unistd.h> defines this */ #ifndef HOST_NAME_MAX /* POSIX 1003.1-2001 says <unistd.h> defines this */
# define HOST_NAME_MAX 255 /* upper bound, according to SUSv2 */ # define HOST_NAME_MAX 255 /* upper bound, according to SUSv2 */
#endif #endif
#include <sys/queue.h> #include <sys/queue.h>
@@ -38,10 +38,10 @@
#include "packet.h" #include "packet.h"
#include "whack.h" #include "whack.h"
const struct id empty_id; /* ID_NONE */ const struct id empty_id; /* ID_NONE */
enum myid_state myid_state = MYID_UNKNOWN; enum myid_state myid_state = MYID_UNKNOWN;
struct id myids[MYID_SPECIFIED+1]; /* %myid */ struct id myids[MYID_SPECIFIED+1]; /* %myid */
char *myid_str[MYID_SPECIFIED+1]; /* string form of IDs */ char *myid_str[MYID_SPECIFIED+1]; /* string form of IDs */
/* initialize id module /* initialize id module
@@ -50,20 +50,20 @@ char *myid_str[MYID_SPECIFIED+1]; /* string form of IDs */
void void
init_id(void) init_id(void)
{ {
passert(empty_id.kind == ID_NONE); passert(empty_id.kind == ID_NONE);
myid_state = MYID_UNKNOWN; myid_state = MYID_UNKNOWN;
{
enum myid_state s;
for (s = MYID_UNKNOWN; s <= MYID_SPECIFIED; s++)
{ {
myids[s] = empty_id; enum myid_state s;
myid_str[s] = NULL;
for (s = MYID_UNKNOWN; s <= MYID_SPECIFIED; s++)
{
myids[s] = empty_id;
myid_str[s] = NULL;
}
} }
} set_myid(MYID_SPECIFIED, getenv("IPSECmyid"));
set_myid(MYID_SPECIFIED, getenv("IPSECmyid")); set_myid(MYID_IP, getenv("defaultrouteaddr"));
set_myid(MYID_IP, getenv("defaultrouteaddr")); set_myFQDN();
set_myFQDN();
} }
/* /*
@@ -72,95 +72,95 @@ init_id(void)
void void
free_id(void) free_id(void)
{ {
enum myid_state s; enum myid_state s;
for (s = MYID_UNKNOWN; s <= MYID_SPECIFIED; s++) for (s = MYID_UNKNOWN; s <= MYID_SPECIFIED; s++)
{ {
free_id_content(&myids[s]); free_id_content(&myids[s]);
free(myid_str[s]); free(myid_str[s]);
} }
} }
static void static void
calc_myid_str(enum myid_state s) calc_myid_str(enum myid_state s)
{ {
/* preformat the ID name */ /* preformat the ID name */
char buf[BUF_LEN]; char buf[BUF_LEN];
idtoa(&myids[s], buf, BUF_LEN); idtoa(&myids[s], buf, BUF_LEN);
replace(myid_str[s], clone_str(buf)); replace(myid_str[s], clone_str(buf));
} }
void void
set_myid(enum myid_state s, char *idstr) set_myid(enum myid_state s, char *idstr)
{ {
if (idstr != NULL) if (idstr != NULL)
{
struct id id;
err_t ugh = atoid(idstr, &id, FALSE);
if (ugh != NULL)
{ {
loglog(RC_BADID, "myid malformed: %s \"%s\"", ugh, idstr); struct id id;
} err_t ugh = atoid(idstr, &id, FALSE);
else
{
free_id_content(&myids[s]);
unshare_id_content(&id);
myids[s] = id;
if (s == MYID_SPECIFIED)
myid_state = MYID_SPECIFIED;
calc_myid_str(s); if (ugh != NULL)
{
loglog(RC_BADID, "myid malformed: %s \"%s\"", ugh, idstr);
}
else
{
free_id_content(&myids[s]);
unshare_id_content(&id);
myids[s] = id;
if (s == MYID_SPECIFIED)
myid_state = MYID_SPECIFIED;
calc_myid_str(s);
}
} }
}
} }
void void
set_myFQDN(void) set_myFQDN(void)
{ {
char FQDN[HOST_NAME_MAX + 1]; char FQDN[HOST_NAME_MAX + 1];
int r = gethostname(FQDN, sizeof(FQDN)); int r = gethostname(FQDN, sizeof(FQDN));
free_id_content(&myids[MYID_HOSTNAME]);
myids[MYID_HOSTNAME] = empty_id;
if (r != 0)
{
log_errno((e, "gethostname() failed in set_myFQDN"));
}
else
{
FQDN[sizeof(FQDN) - 1] = '\0'; /* insurance */
free_id_content(&myids[MYID_HOSTNAME]);
myids[MYID_HOSTNAME] = empty_id;
if (r != 0)
{ {
size_t len = strlen(FQDN); log_errno((e, "gethostname() failed in set_myFQDN"));
if (len > 0 && FQDN[len-1] == '.')
{
/* nuke trailing . */
FQDN[len-1]='\0';
}
} }
else
if (!strcaseeq(FQDN, "localhost.localdomain"))
{ {
chunk_t myid_name = { FQDN, strlen(FQDN) }; FQDN[sizeof(FQDN) - 1] = '\0'; /* insurance */
myids[MYID_HOSTNAME].name = chunk_clone(myid_name); {
myids[MYID_HOSTNAME].kind = ID_FQDN; size_t len = strlen(FQDN);
calc_myid_str(MYID_HOSTNAME);
if (len > 0 && FQDN[len-1] == '.')
{
/* nuke trailing . */
FQDN[len-1]='\0';
}
}
if (!strcaseeq(FQDN, "localhost.localdomain"))
{
chunk_t myid_name = { FQDN, strlen(FQDN) };
myids[MYID_HOSTNAME].name = chunk_clone(myid_name);
myids[MYID_HOSTNAME].kind = ID_FQDN;
calc_myid_str(MYID_HOSTNAME);
}
} }
}
} }
void void
show_myid_status(void) show_myid_status(void)
{ {
char idstr[BUF_LEN]; char idstr[BUF_LEN];
(void)idtoa(&myids[myid_state], idstr, sizeof(idstr)); (void)idtoa(&myids[myid_state], idstr, sizeof(idstr));
whack_log(RC_COMMENT, "%%myid = %s", idstr); whack_log(RC_COMMENT, "%%myid = %s", idstr);
} }
/* Convert textual form of id into a (temporary) struct id. /* Convert textual form of id into a (temporary) struct id.
@@ -169,86 +169,86 @@ show_myid_status(void)
err_t err_t
atoid(char *src, struct id *id, bool myid_ok) atoid(char *src, struct id *id, bool myid_ok)
{ {
err_t ugh = NULL; err_t ugh = NULL;
*id = empty_id; *id = empty_id;
if (myid_ok && streq("%myid", src)) if (myid_ok && streq("%myid", src))
{
id->kind = ID_MYID;
}
else if (strchr(src, '=') != NULL)
{
/* we interpret this as an ASCII X.501 ID_DER_ASN1_DN */
id->kind = ID_DER_ASN1_DN;
id->name.ptr = temporary_cyclic_buffer(); /* assign temporary buffer */
id->name.len = 0;
/* convert from LDAP style or openssl x509 -subject style to ASN.1 DN
* discard optional @ character in front of DN
*/
ugh = atodn((*src == '@')?src+1:src, &id->name);
}
else if (strchr(src, '@') == NULL)
{
if (streq(src, "%any") || streq(src, "0.0.0.0"))
{ {
/* any ID will be accepted */ id->kind = ID_MYID;
id->kind = ID_NONE;
} }
else else if (strchr(src, '=') != NULL)
{ {
/* !!! this test is not sufficient for distinguishing address families. /* we interpret this as an ASCII X.501 ID_DER_ASN1_DN */
* We need a notation to specify that a FQDN is to be resolved to IPv6.
*/
const struct af_info *afi = strchr(src, ':') == NULL
? &af_inet4_info: &af_inet6_info;
id->kind = afi->id_addr;
ugh = ttoaddr(src, 0, afi->af, &id->ip_addr);
}
}
else
{
if (*src == '@')
{
if (*(src+1) == '#')
{
/* if there is a second specifier (#) on the line
* we interprete this as ID_KEY_ID
*/
id->kind = ID_KEY_ID;
id->name.ptr = src;
/* discard @~, convert from hex to bin */
ugh = ttodata(src+2, 0, 16, id->name.ptr, strlen(src), &id->name.len);
}
else if (*(src+1) == '~')
{
/* if there is a second specifier (~) on the line
* we interprete this as a binary ID_DER_ASN1_DN
*/
id->kind = ID_DER_ASN1_DN; id->kind = ID_DER_ASN1_DN;
id->name.ptr = src; id->name.ptr = temporary_cyclic_buffer(); /* assign temporary buffer */
/* discard @~, convert from hex to bin */ id->name.len = 0;
ugh = ttodata(src+2, 0, 16, id->name.ptr, strlen(src), &id->name.len); /* convert from LDAP style or openssl x509 -subject style to ASN.1 DN
} * discard optional @ character in front of DN
else */
{ ugh = atodn((*src == '@')?src+1:src, &id->name);
id->kind = ID_FQDN; }
id->name.ptr = src+1; /* discard @ */ else if (strchr(src, '@') == NULL)
id->name.len = strlen(src)-1; {
} if (streq(src, "%any") || streq(src, "0.0.0.0"))
{
/* any ID will be accepted */
id->kind = ID_NONE;
}
else
{
/* !!! this test is not sufficient for distinguishing address families.
* We need a notation to specify that a FQDN is to be resolved to IPv6.
*/
const struct af_info *afi = strchr(src, ':') == NULL
? &af_inet4_info: &af_inet6_info;
id->kind = afi->id_addr;
ugh = ttoaddr(src, 0, afi->af, &id->ip_addr);
}
} }
else else
{ {
/* We leave in @, as per DOI 4.6.2.4 if (*src == '@')
* (but DNS wants . instead). {
*/ if (*(src+1) == '#')
id->kind = ID_USER_FQDN; {
id->name.ptr = src; /* if there is a second specifier (#) on the line
id->name.len = strlen(src); * we interprete this as ID_KEY_ID
*/
id->kind = ID_KEY_ID;
id->name.ptr = src;
/* discard @~, convert from hex to bin */
ugh = ttodata(src+2, 0, 16, id->name.ptr, strlen(src), &id->name.len);
}
else if (*(src+1) == '~')
{
/* if there is a second specifier (~) on the line
* we interprete this as a binary ID_DER_ASN1_DN
*/
id->kind = ID_DER_ASN1_DN;
id->name.ptr = src;
/* discard @~, convert from hex to bin */
ugh = ttodata(src+2, 0, 16, id->name.ptr, strlen(src), &id->name.len);
}
else
{
id->kind = ID_FQDN;
id->name.ptr = src+1; /* discard @ */
id->name.len = strlen(src)-1;
}
}
else
{
/* We leave in @, as per DOI 4.6.2.4
* (but DNS wants . instead).
*/
id->kind = ID_USER_FQDN;
id->name.ptr = src;
id->name.len = strlen(src);
}
} }
} return ugh;
return ugh;
} }
@@ -258,72 +258,72 @@ atoid(char *src, struct id *id, bool myid_ok)
int int
keyidtoa(char *dst, size_t dstlen, chunk_t keyid) keyidtoa(char *dst, size_t dstlen, chunk_t keyid)
{ {
int n = datatot(keyid.ptr, keyid.len, 'x', dst, dstlen); int n = datatot(keyid.ptr, keyid.len, 'x', dst, dstlen);
return (((size_t)n < dstlen)? n : dstlen) - 1; return (((size_t)n < dstlen)? n : dstlen) - 1;
} }
void void
iptoid(const ip_address *ip, struct id *id) iptoid(const ip_address *ip, struct id *id)
{ {
*id = empty_id; *id = empty_id;
switch (addrtypeof(ip)) switch (addrtypeof(ip))
{ {
case AF_INET: case AF_INET:
id->kind = ID_IPV4_ADDR; id->kind = ID_IPV4_ADDR;
break; break;
case AF_INET6: case AF_INET6:
id->kind = ID_IPV6_ADDR; id->kind = ID_IPV6_ADDR;
break; break;
default: default:
bad_case(addrtypeof(ip)); bad_case(addrtypeof(ip));
} }
id->ip_addr = *ip; id->ip_addr = *ip;
} }
int int
idtoa(const struct id *id, char *dst, size_t dstlen) idtoa(const struct id *id, char *dst, size_t dstlen)
{ {
int n; int n;
id = resolve_myid(id); id = resolve_myid(id);
switch (id->kind) switch (id->kind)
{ {
case ID_NONE: case ID_NONE:
n = snprintf(dst, dstlen, "(none)"); n = snprintf(dst, dstlen, "(none)");
break; break;
case ID_IPV4_ADDR: case ID_IPV4_ADDR:
case ID_IPV6_ADDR: case ID_IPV6_ADDR:
n = (int)addrtot(&id->ip_addr, 0, dst, dstlen) - 1; n = (int)addrtot(&id->ip_addr, 0, dst, dstlen) - 1;
break; break;
case ID_FQDN: case ID_FQDN:
n = snprintf(dst, dstlen, "@%.*s", (int)id->name.len, id->name.ptr); n = snprintf(dst, dstlen, "@%.*s", (int)id->name.len, id->name.ptr);
break; break;
case ID_USER_FQDN: case ID_USER_FQDN:
n = snprintf(dst, dstlen, "%.*s", (int)id->name.len, id->name.ptr); n = snprintf(dst, dstlen, "%.*s", (int)id->name.len, id->name.ptr);
break; break;
case ID_DER_ASN1_DN: case ID_DER_ASN1_DN:
n = dntoa(dst, dstlen, id->name); n = dntoa(dst, dstlen, id->name);
break; break;
case ID_KEY_ID: case ID_KEY_ID:
n = keyidtoa(dst, dstlen, id->name); n = keyidtoa(dst, dstlen, id->name);
break; break;
default: default:
n = snprintf(dst, dstlen, "unknown id kind %d", id->kind); n = snprintf(dst, dstlen, "unknown id kind %d", id->kind);
break; break;
} }
/* "Sanitize" string so that log isn't endangered: /* "Sanitize" string so that log isn't endangered:
* replace unprintable characters with '?'. * replace unprintable characters with '?'.
*/ */
if (n > 0) if (n > 0)
{ {
for ( ; *dst != '\0'; dst++) for ( ; *dst != '\0'; dst++)
if (!isprint(*dst)) if (!isprint(*dst))
*dst = '?'; *dst = '?';
} }
return n; return n;
} }
/* Replace the shell metacharacters ', \, ", `, and $ in a character string /* Replace the shell metacharacters ', \, ", `, and $ in a character string
@@ -332,26 +332,26 @@ idtoa(const struct id *id, char *dst, size_t dstlen)
void void
escape_metachar(const char *src, char *dst, size_t dstlen) escape_metachar(const char *src, char *dst, size_t dstlen)
{ {
while (*src != '\0' && dstlen > 4) while (*src != '\0' && dstlen > 4)
{
switch (*src)
{ {
case '\'': switch (*src)
case '\\': {
case '"': case '\'':
case '`': case '\\':
case '$': case '"':
sprintf(dst,"\\%s%o", (*src < 64)?"0":"", *src); case '`':
dst += 4; case '$':
dstlen -= 4; sprintf(dst,"\\%s%o", (*src < 64)?"0":"", *src);
break; dst += 4;
default: dstlen -= 4;
*dst++ = *src; break;
dstlen--; default:
*dst++ = *src;
dstlen--;
}
src++;
} }
src++; *dst = '\0';
}
*dst = '\0';
} }
@@ -361,126 +361,126 @@ escape_metachar(const char *src, char *dst, size_t dstlen)
void void
unshare_id_content(struct id *id) unshare_id_content(struct id *id)
{ {
switch (id->kind) switch (id->kind)
{ {
case ID_FQDN: case ID_FQDN:
case ID_USER_FQDN: case ID_USER_FQDN:
case ID_DER_ASN1_DN: case ID_DER_ASN1_DN:
case ID_KEY_ID: case ID_KEY_ID:
id->name = chunk_clone(id->name); id->name = chunk_clone(id->name);
break; break;
case ID_MYID: case ID_MYID:
case ID_NONE: case ID_NONE:
case ID_IPV4_ADDR: case ID_IPV4_ADDR:
case ID_IPV6_ADDR: case ID_IPV6_ADDR:
break; break;
default: default:
bad_case(id->kind); bad_case(id->kind);
} }
} }
void void
free_id_content(struct id *id) free_id_content(struct id *id)
{ {
switch (id->kind) switch (id->kind)
{ {
case ID_FQDN: case ID_FQDN:
case ID_USER_FQDN: case ID_USER_FQDN:
case ID_DER_ASN1_DN: case ID_DER_ASN1_DN:
case ID_KEY_ID: case ID_KEY_ID:
free(id->name.ptr); free(id->name.ptr);
break; break;
case ID_MYID: case ID_MYID:
case ID_NONE: case ID_NONE:
case ID_IPV4_ADDR: case ID_IPV4_ADDR:
case ID_IPV6_ADDR: case ID_IPV6_ADDR:
break; break;
default: default:
bad_case(id->kind); bad_case(id->kind);
} }
} }
/* compare two struct id values */ /* compare two struct id values */
bool bool
same_id(const struct id *a, const struct id *b) same_id(const struct id *a, const struct id *b)
{ {
a = resolve_myid(a); a = resolve_myid(a);
b = resolve_myid(b); b = resolve_myid(b);
if (a->kind != b->kind) if (a->kind != b->kind)
return FALSE; return FALSE;
switch (a->kind) switch (a->kind)
{
case ID_NONE:
return TRUE; /* kind of vacuous */
case ID_IPV4_ADDR:
case ID_IPV6_ADDR:
return sameaddr(&a->ip_addr, &b->ip_addr);
case ID_FQDN:
case ID_USER_FQDN:
/* assumptions:
* - case should be ignored
* - trailing "." should be ignored (even if the only character?)
*/
{ {
size_t al = a->name.len case ID_NONE:
, bl = b->name.len; return TRUE; /* kind of vacuous */
while (al > 0 && a->name.ptr[al - 1] == '.') case ID_IPV4_ADDR:
al--; case ID_IPV6_ADDR:
while (bl > 0 && b->name.ptr[bl - 1] == '.') return sameaddr(&a->ip_addr, &b->ip_addr);
bl--;
return al == bl case ID_FQDN:
&& strncasecmp(a->name.ptr, b->name.ptr, al) == 0; case ID_USER_FQDN:
/* assumptions:
* - case should be ignored
* - trailing "." should be ignored (even if the only character?)
*/
{
size_t al = a->name.len
, bl = b->name.len;
while (al > 0 && a->name.ptr[al - 1] == '.')
al--;
while (bl > 0 && b->name.ptr[bl - 1] == '.')
bl--;
return al == bl
&& strncasecmp(a->name.ptr, b->name.ptr, al) == 0;
}
case ID_DER_ASN1_DN:
return same_dn(a->name, b->name);
case ID_KEY_ID:
return a->name.len == b->name.len
&& memeq(a->name.ptr, b->name.ptr, a->name.len);
default:
bad_case(a->kind);
} }
return FALSE;
case ID_DER_ASN1_DN:
return same_dn(a->name, b->name);
case ID_KEY_ID:
return a->name.len == b->name.len
&& memeq(a->name.ptr, b->name.ptr, a->name.len);
default:
bad_case(a->kind);
}
return FALSE;
} }
/* compare two struct id values, DNs can contain wildcards */ /* compare two struct id values, DNs can contain wildcards */
bool bool
match_id(const struct id *a, const struct id *b, int *wildcards) match_id(const struct id *a, const struct id *b, int *wildcards)
{ {
if (b->kind == ID_NONE) if (b->kind == ID_NONE)
{ {
*wildcards = MAX_WILDCARDS; *wildcards = MAX_WILDCARDS;
return TRUE; return TRUE;
} }
if (a->kind != b->kind) if (a->kind != b->kind)
return FALSE; return FALSE;
if (a->kind == ID_DER_ASN1_DN) if (a->kind == ID_DER_ASN1_DN)
return match_dn(a->name, b->name, wildcards); return match_dn(a->name, b->name, wildcards);
else else
{ {
*wildcards = 0; *wildcards = 0;
return same_id(a, b); return same_id(a, b);
} }
} }
/* count the numer of wildcards in an id */ /* count the numer of wildcards in an id */
int int
id_count_wildcards(const struct id *id) id_count_wildcards(const struct id *id)
{ {
switch (id->kind) switch (id->kind)
{ {
case ID_NONE: case ID_NONE:
return MAX_WILDCARDS; return MAX_WILDCARDS;
case ID_DER_ASN1_DN: case ID_DER_ASN1_DN:
return dn_count_wildcards(id->name); return dn_count_wildcards(id->name);
default: default:
return 0; return 0;
} }
} }
/* build an ID payload /* build an ID payload
@@ -491,31 +491,31 @@ id_count_wildcards(const struct id *id)
void void
build_id_payload(struct isakmp_ipsec_id *hd, chunk_t *tl, struct end *end) build_id_payload(struct isakmp_ipsec_id *hd, chunk_t *tl, struct end *end)
{ {
const struct id *id = resolve_myid(&end->id); const struct id *id = resolve_myid(&end->id);
zero(hd); zero(hd);
hd->isaiid_idtype = id->kind; hd->isaiid_idtype = id->kind;
switch (id->kind) switch (id->kind)
{ {
case ID_NONE: case ID_NONE:
hd->isaiid_idtype = aftoinfo(addrtypeof(&end->host_addr))->id_addr; hd->isaiid_idtype = aftoinfo(addrtypeof(&end->host_addr))->id_addr;
tl->len = addrbytesptr(&end->host_addr tl->len = addrbytesptr(&end->host_addr
, (const unsigned char **)&tl->ptr); /* sets tl->ptr too */ , (const unsigned char **)&tl->ptr); /* sets tl->ptr too */
break; break;
case ID_FQDN: case ID_FQDN:
case ID_USER_FQDN: case ID_USER_FQDN:
case ID_DER_ASN1_DN: case ID_DER_ASN1_DN:
case ID_KEY_ID: case ID_KEY_ID:
*tl = id->name; *tl = id->name;
break; break;
case ID_IPV4_ADDR: case ID_IPV4_ADDR:
case ID_IPV6_ADDR: case ID_IPV6_ADDR:
tl->len = addrbytesptr(&id->ip_addr tl->len = addrbytesptr(&id->ip_addr
, (const unsigned char **)&tl->ptr); /* sets tl->ptr too */ , (const unsigned char **)&tl->ptr); /* sets tl->ptr too */
break; break;
default: default:
bad_case(id->kind); bad_case(id->kind);
} }
} }
/* /*
+15 -15
View File
@@ -20,25 +20,25 @@
#include "defs.h" #include "defs.h"
struct id { struct id {
int kind; /* ID_* value */ int kind; /* ID_* value */
ip_address ip_addr; /* ID_IPV4_ADDR, ID_IPV6_ADDR */ ip_address ip_addr; /* ID_IPV4_ADDR, ID_IPV6_ADDR */
chunk_t name; /* ID_FQDN, ID_USER_FQDN (with @) */ chunk_t name; /* ID_FQDN, ID_USER_FQDN (with @) */
/* ID_KEY_ID, ID_DER_ASN_DN */ /* ID_KEY_ID, ID_DER_ASN_DN */
}; };
extern void init_id(void); extern void init_id(void);
extern void free_id(void); extern void free_id(void);
extern const struct id empty_id; /* ID_NONE */ extern const struct id empty_id; /* ID_NONE */
enum myid_state { enum myid_state {
MYID_UNKNOWN, /* not yet figured out */ MYID_UNKNOWN, /* not yet figured out */
MYID_HOSTNAME, /* our current hostname */ MYID_HOSTNAME, /* our current hostname */
MYID_IP, /* our default IP address */ MYID_IP, /* our default IP address */
MYID_SPECIFIED /* as specified by ipsec.conf */ MYID_SPECIFIED /* as specified by ipsec.conf */
}; };
extern enum myid_state myid_state; extern enum myid_state myid_state;
extern struct id myids[MYID_SPECIFIED+1]; /* %myid */ extern struct id myids[MYID_SPECIFIED+1]; /* %myid */
extern char *myid_str[MYID_SPECIFIED+1]; /* strings */ extern char *myid_str[MYID_SPECIFIED+1]; /* strings */
extern void set_myid(enum myid_state s, char *); extern void set_myid(enum myid_state s, char *);
extern void show_myid_status(void); extern void show_myid_status(void);
@@ -49,19 +49,19 @@ extern err_t atoid(char *src, struct id *id, bool myid_ok);
extern int keyidtoa(char *dst, size_t dstlen, chunk_t keyid); extern int keyidtoa(char *dst, size_t dstlen, chunk_t keyid);
extern void iptoid(const ip_address *ip, struct id *id); extern void iptoid(const ip_address *ip, struct id *id);
extern int idtoa(const struct id *id, char *dst, size_t dstlen); extern int idtoa(const struct id *id, char *dst, size_t dstlen);
#define IDTOA_BUF 512 #define IDTOA_BUF 512
extern void escape_metachar(const char *src, char *dst, size_t dstlen); extern void escape_metachar(const char *src, char *dst, size_t dstlen);
struct end; /* forward declaration of tag (defined in connections.h) */ struct end; /* forward declaration of tag (defined in connections.h) */
extern void unshare_id_content(struct id *id); extern void unshare_id_content(struct id *id);
extern void free_id_content(struct id *id); extern void free_id_content(struct id *id);
extern bool same_id(const struct id *a, const struct id *b); extern bool same_id(const struct id *a, const struct id *b);
#define MAX_WILDCARDS 15 #define MAX_WILDCARDS 15
extern bool match_id(const struct id *a, const struct id *b, int *wildcards); extern bool match_id(const struct id *a, const struct id *b, int *wildcards);
extern int id_count_wildcards(const struct id *id); extern int id_count_wildcards(const struct id *id);
#define id_is_ipaddr(id) ((id)->kind == ID_IPV4_ADDR || (id)->kind == ID_IPV6_ADDR) #define id_is_ipaddr(id) ((id)->kind == ID_IPV4_ADDR || (id)->kind == ID_IPV6_ADDR)
struct isakmp_ipsec_id; /* forward declaration of tag (defined in packet.h) */ struct isakmp_ipsec_id; /* forward declaration of tag (defined in packet.h) */
extern void extern void
build_id_payload(struct isakmp_ipsec_id *hd, chunk_t *tl, struct end *end); build_id_payload(struct isakmp_ipsec_id *hd, chunk_t *tl, struct end *end);
#endif /* _ID_H */ #endif /* _ID_H */
+359 -359
View File
@@ -56,13 +56,13 @@ static struct ike_alg *ike_alg_base[IKE_ALG_MAX+1] = {NULL, NULL};
static struct ike_alg * static struct ike_alg *
ike_alg_find(u_int algo_type, u_int algo_id, u_int keysize __attribute__((unused))) ike_alg_find(u_int algo_type, u_int algo_id, u_int keysize __attribute__((unused)))
{ {
struct ike_alg *e = ike_alg_base[algo_type]; struct ike_alg *e = ike_alg_base[algo_type];
while (e != NULL && algo_id > e->algo_id) while (e != NULL && algo_id > e->algo_id)
{ {
e = e->algo_next; e = e->algo_next;
} }
return (e != NULL && e->algo_id == algo_id) ? e : NULL; return (e != NULL && e->algo_id == algo_id) ? e : NULL;
} }
/* /*
@@ -71,31 +71,31 @@ ike_alg_find(u_int algo_type, u_int algo_id, u_int keysize __attribute__((unused
int int
ike_alg_add(struct ike_alg* a) ike_alg_add(struct ike_alg* a)
{ {
if (a->algo_type > IKE_ALG_MAX) if (a->algo_type > IKE_ALG_MAX)
{
plog("ike_alg: Not added, invalid algorithm type");
return -EINVAL;
}
if (ike_alg_find(a->algo_type, a->algo_id, 0) != NULL)
{
plog("ike_alg: Not added, algorithm already exists");
return -EEXIST;
}
{
struct ike_alg **ep = &ike_alg_base[a->algo_type];
struct ike_alg *e = *ep;
while (e != NULL && a->algo_id > e->algo_id)
{ {
ep = &e->algo_next; plog("ike_alg: Not added, invalid algorithm type");
e = *ep; return -EINVAL;
}
if (ike_alg_find(a->algo_type, a->algo_id, 0) != NULL)
{
plog("ike_alg: Not added, algorithm already exists");
return -EEXIST;
}
{
struct ike_alg **ep = &ike_alg_base[a->algo_type];
struct ike_alg *e = *ep;
while (e != NULL && a->algo_id > e->algo_id)
{
ep = &e->algo_next;
e = *ep;
}
*ep = a;
a->algo_next = e;
return 0;
} }
*ep = a;
a->algo_next = e;
return 0;
}
} }
/* /*
@@ -103,7 +103,7 @@ ike_alg_add(struct ike_alg* a)
*/ */
struct hash_desc *ike_alg_get_hasher(u_int alg) struct hash_desc *ike_alg_get_hasher(u_int alg)
{ {
return (struct hash_desc *) ike_alg_find(IKE_ALG_HASH, alg, 0); return (struct hash_desc *) ike_alg_find(IKE_ALG_HASH, alg, 0);
} }
/* /*
@@ -111,7 +111,7 @@ struct hash_desc *ike_alg_get_hasher(u_int alg)
*/ */
struct encrypt_desc *ike_alg_get_encrypter(u_int alg) struct encrypt_desc *ike_alg_get_encrypter(u_int alg)
{ {
return (struct encrypt_desc *) ike_alg_find(IKE_ALG_ENCRYPT, alg, 0); return (struct encrypt_desc *) ike_alg_find(IKE_ALG_ENCRYPT, alg, 0);
} }
/* /*
@@ -120,7 +120,7 @@ struct encrypt_desc *ike_alg_get_encrypter(u_int alg)
bool bool
ike_alg_hash_present(u_int halg) ike_alg_hash_present(u_int halg)
{ {
return ike_alg_get_hasher(halg) != NULL; return ike_alg_get_hasher(halg) != NULL;
} }
/* /*
@@ -129,7 +129,7 @@ ike_alg_hash_present(u_int halg)
bool bool
ike_alg_enc_present(u_int ealg) ike_alg_enc_present(u_int ealg)
{ {
return ike_alg_get_encrypter(ealg) != NULL; return ike_alg_get_encrypter(ealg) != NULL;
} }
/* /*
@@ -138,48 +138,48 @@ ike_alg_enc_present(u_int ealg)
int int
ike_alg_register_hash(struct hash_desc *hash_desc) ike_alg_register_hash(struct hash_desc *hash_desc)
{ {
const char *alg_name = NULL; const char *alg_name = NULL;
int ret = 0; int ret = 0;
if (hash_desc->algo_id > OAKLEY_HASH_MAX) if (hash_desc->algo_id > OAKLEY_HASH_MAX)
{ {
plog ("ike_alg: hash alg=%d > max=%d" plog ("ike_alg: hash alg=%d > max=%d"
, hash_desc->algo_id, OAKLEY_HASH_MAX); , hash_desc->algo_id, OAKLEY_HASH_MAX);
return_on(ret,-EINVAL); return_on(ret,-EINVAL);
} }
if (hash_desc->hash_ctx_size > sizeof (union hash_ctx)) if (hash_desc->hash_ctx_size > sizeof (union hash_ctx))
{ {
plog ("ike_alg: hash alg=%d has ctx_size=%d > hash_ctx=%d" plog ("ike_alg: hash alg=%d has ctx_size=%d > hash_ctx=%d"
, hash_desc->algo_id , hash_desc->algo_id
, (int)hash_desc->hash_ctx_size , (int)hash_desc->hash_ctx_size
, (int)sizeof (union hash_ctx)); , (int)sizeof (union hash_ctx));
return_on(ret,-EOVERFLOW); return_on(ret,-EOVERFLOW);
} }
if (!(hash_desc->hash_init && hash_desc->hash_update && hash_desc->hash_final)) if (!(hash_desc->hash_init && hash_desc->hash_update && hash_desc->hash_final))
{ {
plog ("ike_alg: hash alg=%d needs hash_init(), hash_update() and hash_final()" plog ("ike_alg: hash alg=%d needs hash_init(), hash_update() and hash_final()"
, hash_desc->algo_id); , hash_desc->algo_id);
return_on(ret,-EINVAL); return_on(ret,-EINVAL);
} }
alg_name = enum_name(&oakley_hash_names, hash_desc->algo_id); alg_name = enum_name(&oakley_hash_names, hash_desc->algo_id);
if (!alg_name) if (!alg_name)
{ {
plog ("ike_alg: hash alg=%d not found in constants.c:oakley_hash_names" plog ("ike_alg: hash alg=%d not found in constants.c:oakley_hash_names"
, hash_desc->algo_id); , hash_desc->algo_id);
alg_name = "<NULL>"; alg_name = "<NULL>";
} }
return_out: return_out:
if (ret == 0) if (ret == 0)
ret = ike_alg_add((struct ike_alg *)hash_desc); ret = ike_alg_add((struct ike_alg *)hash_desc);
plog("ike_alg: Activating %s hash: %s" plog("ike_alg: Activating %s hash: %s"
,alg_name, ret == 0 ? "Ok" : "FAILED"); ,alg_name, ret == 0 ? "Ok" : "FAILED");
return ret; return ret;
} }
/* /*
@@ -188,24 +188,24 @@ return_out:
int int
ike_alg_register_enc(struct encrypt_desc *enc_desc) ike_alg_register_enc(struct encrypt_desc *enc_desc)
{ {
int ret = ike_alg_add((struct ike_alg *)enc_desc); int ret = ike_alg_add((struct ike_alg *)enc_desc);
const char *alg_name = enum_name(&oakley_enc_names, enc_desc->algo_id); const char *alg_name = enum_name(&oakley_enc_names, enc_desc->algo_id);
char alg_number[20]; char alg_number[20];
/* algorithm is not listed in oakley_enc_names */ /* algorithm is not listed in oakley_enc_names */
if (alg_name == NULL) if (alg_name == NULL)
{ {
snprintf(alg_number, sizeof(alg_number), "OAKLEY_ID_%d" snprintf(alg_number, sizeof(alg_number), "OAKLEY_ID_%d"
, enc_desc->algo_id); , enc_desc->algo_id);
alg_name = alg_number; alg_name = alg_number;
} }
plog("ike_alg: Activating %s encryption: %s" plog("ike_alg: Activating %s encryption: %s"
, alg_name, ret == 0 ? "Ok" : "FAILED"); , alg_name, ret == 0 ? "Ok" : "FAILED");
return ret; return ret;
} }
/* /*
@@ -214,13 +214,13 @@ ike_alg_register_enc(struct encrypt_desc *enc_desc)
const struct oakley_group_desc * const struct oakley_group_desc *
ike_alg_pfsgroup(struct connection *c, lset_t policy) ike_alg_pfsgroup(struct connection *c, lset_t policy)
{ {
const struct oakley_group_desc * ret = NULL; const struct oakley_group_desc * ret = NULL;
if ((policy & POLICY_PFS) if ((policy & POLICY_PFS)
&& c->alg_info_esp && c->alg_info_esp
&& c->alg_info_esp->esp_pfsgroup) && c->alg_info_esp->esp_pfsgroup)
ret = lookup_group(c->alg_info_esp->esp_pfsgroup); ret = lookup_group(c->alg_info_esp->esp_pfsgroup);
return ret; return ret;
} }
/* /*
@@ -229,109 +229,109 @@ ike_alg_pfsgroup(struct connection *c, lset_t policy)
struct db_context * struct db_context *
ike_alg_db_new(struct alg_info_ike *ai , lset_t policy) ike_alg_db_new(struct alg_info_ike *ai , lset_t policy)
{ {
struct db_context *db_ctx = NULL; struct db_context *db_ctx = NULL;
struct ike_info *ike_info; struct ike_info *ike_info;
struct encrypt_desc *enc_desc; struct encrypt_desc *enc_desc;
u_int ealg, halg, modp, eklen = 0; u_int ealg, halg, modp, eklen = 0;
int i; int i;
bool is_xauth_server = (policy & POLICY_XAUTH_SERVER) != LEMPTY; bool is_xauth_server = (policy & POLICY_XAUTH_SERVER) != LEMPTY;
if (!ai) if (!ai)
{
whack_log(RC_LOG_SERIOUS, "no IKE algorithms "
"for this connection "
"(check ike algorithm string)");
goto fail;
}
policy &= POLICY_ID_AUTH_MASK;
db_ctx = db_prop_new(PROTO_ISAKMP, 8, 8 * 5);
/* for each group */
ALG_INFO_IKE_FOREACH(ai, ike_info, i)
{
ealg = ike_info->ike_ealg;
halg = ike_info->ike_halg;
modp = ike_info->ike_modp;
eklen= ike_info->ike_eklen;
if (!ike_alg_enc_present(ealg))
{ {
DBG_log("ike_alg: ike enc ealg=%d not present" whack_log(RC_LOG_SERIOUS, "no IKE algorithms "
, ealg); "for this connection "
continue; "(check ike algorithm string)");
goto fail;
} }
policy &= POLICY_ID_AUTH_MASK;
db_ctx = db_prop_new(PROTO_ISAKMP, 8, 8 * 5);
if (!ike_alg_hash_present(halg)) /* for each group */
ALG_INFO_IKE_FOREACH(ai, ike_info, i)
{ {
DBG_log("ike_alg: ike hash halg=%d not present" ealg = ike_info->ike_ealg;
, halg); halg = ike_info->ike_halg;
continue; modp = ike_info->ike_modp;
} eklen= ike_info->ike_eklen;
enc_desc = ike_alg_get_encrypter(ealg); if (!ike_alg_enc_present(ealg))
passert(enc_desc != NULL); {
DBG_log("ike_alg: ike enc ealg=%d not present"
, ealg);
continue;
}
if (eklen if (!ike_alg_hash_present(halg))
&& (eklen < enc_desc->keyminlen || eklen > enc_desc->keymaxlen)) {
{ DBG_log("ike_alg: ike hash halg=%d not present"
DBG_log("ike_alg: ealg=%d (specified) keylen:%d, not valid min=%d, max=%d" , halg);
, ealg continue;
, eklen }
, enc_desc->keyminlen
, enc_desc->keymaxlen
);
continue;
}
if (policy & POLICY_RSASIG) enc_desc = ike_alg_get_encrypter(ealg);
{ passert(enc_desc != NULL);
db_trans_add(db_ctx, KEY_IKE);
db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
if (eklen)
db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG);
db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
}
if (policy & POLICY_PSK) if (eklen
{ && (eklen < enc_desc->keyminlen || eklen > enc_desc->keymaxlen))
db_trans_add(db_ctx, KEY_IKE); {
db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg); DBG_log("ike_alg: ealg=%d (specified) keylen:%d, not valid min=%d, max=%d"
db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg); , ealg
if (eklen) , eklen
db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen); , enc_desc->keyminlen
db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY); , enc_desc->keymaxlen
db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp); );
} continue;
}
if (policy & POLICY_XAUTH_RSASIG) if (policy & POLICY_RSASIG)
{ {
db_trans_add(db_ctx, KEY_IKE); db_trans_add(db_ctx, KEY_IKE);
db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg); db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg); db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
if (eklen) if (eklen)
db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen); db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG);
, is_xauth_server ? XAUTHRespRSA : XAUTHInitRSA); db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp); }
}
if (policy & POLICY_XAUTH_PSK) if (policy & POLICY_PSK)
{ {
db_trans_add(db_ctx, KEY_IKE); db_trans_add(db_ctx, KEY_IKE);
db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg); db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg); db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
if (eklen) if (eklen)
db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen); db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY);
, is_xauth_server ? XAUTHRespPreShared : XAUTHInitPreShared); db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp); }
if (policy & POLICY_XAUTH_RSASIG)
{
db_trans_add(db_ctx, KEY_IKE);
db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
if (eklen)
db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD
, is_xauth_server ? XAUTHRespRSA : XAUTHInitRSA);
db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
}
if (policy & POLICY_XAUTH_PSK)
{
db_trans_add(db_ctx, KEY_IKE);
db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
if (eklen)
db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD
, is_xauth_server ? XAUTHRespPreShared : XAUTHInitPreShared);
db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
}
} }
}
fail: fail:
return db_ctx; return db_ctx;
} }
/* /*
@@ -340,54 +340,54 @@ fail:
void void
ike_alg_list(void) ike_alg_list(void)
{ {
u_int i; u_int i;
struct ike_alg *a; struct ike_alg *a;
whack_log(RC_COMMENT, " "); whack_log(RC_COMMENT, " ");
whack_log(RC_COMMENT, "List of registered IKE Encryption Algorithms:"); whack_log(RC_COMMENT, "List of registered IKE Encryption Algorithms:");
whack_log(RC_COMMENT, " "); whack_log(RC_COMMENT, " ");
for (a = ike_alg_base[IKE_ALG_ENCRYPT]; a != NULL; a = a->algo_next) for (a = ike_alg_base[IKE_ALG_ENCRYPT]; a != NULL; a = a->algo_next)
{ {
struct encrypt_desc *desc = (struct encrypt_desc*)a; struct encrypt_desc *desc = (struct encrypt_desc*)a;
whack_log(RC_COMMENT, "#%-5d %s, blocksize: %d, keylen: %d-%d-%d" whack_log(RC_COMMENT, "#%-5d %s, blocksize: %d, keylen: %d-%d-%d"
, a->algo_id , a->algo_id
, enum_name(&oakley_enc_names, a->algo_id) , enum_name(&oakley_enc_names, a->algo_id)
, (int)desc->enc_blocksize*BITS_PER_BYTE , (int)desc->enc_blocksize*BITS_PER_BYTE
, desc->keyminlen , desc->keyminlen
, desc->keydeflen , desc->keydeflen
, desc->keymaxlen , desc->keymaxlen
); );
} }
whack_log(RC_COMMENT, " "); whack_log(RC_COMMENT, " ");
whack_log(RC_COMMENT, "List of registered IKE Hash Algorithms:"); whack_log(RC_COMMENT, "List of registered IKE Hash Algorithms:");
whack_log(RC_COMMENT, " "); whack_log(RC_COMMENT, " ");
for (a = ike_alg_base[IKE_ALG_HASH]; a != NULL; a = a->algo_next) for (a = ike_alg_base[IKE_ALG_HASH]; a != NULL; a = a->algo_next)
{ {
whack_log(RC_COMMENT, "#%-5d %s, hashsize: %d" whack_log(RC_COMMENT, "#%-5d %s, hashsize: %d"
, a->algo_id , a->algo_id
, enum_name(&oakley_hash_names, a->algo_id) , enum_name(&oakley_hash_names, a->algo_id)
, (int)((struct hash_desc *)a)->hash_digest_size*BITS_PER_BYTE , (int)((struct hash_desc *)a)->hash_digest_size*BITS_PER_BYTE
); );
} }
whack_log(RC_COMMENT, " "); whack_log(RC_COMMENT, " ");
whack_log(RC_COMMENT, "List of registered IKE DH Groups:"); whack_log(RC_COMMENT, "List of registered IKE DH Groups:");
whack_log(RC_COMMENT, " "); whack_log(RC_COMMENT, " ");
for (i = 0; i < countof(oakley_group); i++) for (i = 0; i < countof(oakley_group); i++)
{ {
const struct oakley_group_desc *gdesc=oakley_group + i; const struct oakley_group_desc *gdesc=oakley_group + i;
whack_log(RC_COMMENT, "#%-5d %s, groupsize: %d" whack_log(RC_COMMENT, "#%-5d %s, groupsize: %d"
, gdesc->group , gdesc->group
, enum_name(&oakley_group_names, gdesc->group) , enum_name(&oakley_group_names, gdesc->group)
, (int)gdesc->bytes*BITS_PER_BYTE , (int)gdesc->bytes*BITS_PER_BYTE
); );
} }
} }
/* Show IKE algorithms for /* Show IKE algorithms for
@@ -397,43 +397,43 @@ ike_alg_list(void)
void void
ike_alg_show_connection(struct connection *c, const char *instance) ike_alg_show_connection(struct connection *c, const char *instance)
{ {
char buf[256]; char buf[256];
struct state *st; struct state *st;
if (c->alg_info_ike) if (c->alg_info_ike)
{ {
alg_info_snprint(buf, sizeof(buf)-1, (struct alg_info *)c->alg_info_ike); alg_info_snprint(buf, sizeof(buf)-1, (struct alg_info *)c->alg_info_ike);
whack_log(RC_COMMENT whack_log(RC_COMMENT
, "\"%s\"%s: IKE algorithms wanted: %s" , "\"%s\"%s: IKE algorithms wanted: %s"
, c->name , c->name
, instance , instance
, buf , buf
); );
alg_info_snprint_ike(buf, sizeof(buf)-1, c->alg_info_ike); alg_info_snprint_ike(buf, sizeof(buf)-1, c->alg_info_ike);
whack_log(RC_COMMENT whack_log(RC_COMMENT
, "\"%s\"%s: IKE algorithms found: %s" , "\"%s\"%s: IKE algorithms found: %s"
, c->name , c->name
, instance , instance
, buf , buf
); );
} }
st = state_with_serialno(c->newest_isakmp_sa); st = state_with_serialno(c->newest_isakmp_sa);
if (st) if (st)
whack_log(RC_COMMENT whack_log(RC_COMMENT
, "\"%s\"%s: IKE algorithm newest: %s_%d-%s-%s" , "\"%s\"%s: IKE algorithm newest: %s_%d-%s-%s"
, c->name , c->name
, instance , instance
, enum_show(&oakley_enc_names, st->st_oakley.encrypt) , enum_show(&oakley_enc_names, st->st_oakley.encrypt)
+7 /* strlen("OAKLEY_") */ +7 /* strlen("OAKLEY_") */
/* , st->st_oakley.encrypter->keydeflen */ /* , st->st_oakley.encrypter->keydeflen */
, st->st_oakley.enckeylen , st->st_oakley.enckeylen
, enum_show(&oakley_hash_names, st->st_oakley.hash) , enum_show(&oakley_hash_names, st->st_oakley.hash)
+7 /* strlen("OAKLEY_") */ +7 /* strlen("OAKLEY_") */
, enum_show(&oakley_group_names, st->st_oakley.group->group) , enum_show(&oakley_group_names, st->st_oakley.group->group)
+13 /* strlen("OAKLEY_GROUP_") */ +13 /* strlen("OAKLEY_GROUP_") */
); );
} }
/* /*
@@ -442,70 +442,70 @@ ike_alg_show_connection(struct connection *c, const char *instance)
static bool static bool
ike_hash_test(const struct hash_desc *desc) ike_hash_test(const struct hash_desc *desc)
{ {
bool hash_results = TRUE; bool hash_results = TRUE;
bool hmac_results = TRUE; bool hmac_results = TRUE;
if (desc->hash_testvectors == NULL) if (desc->hash_testvectors == NULL)
{
plog(" %s hash self-test not available", enum_name(&oakley_hash_names, desc->algo_id));
}
else
{
int i;
for (i = 0; desc->hash_testvectors[i].msg_digest != NULL; i++)
{ {
u_char digest[MAX_DIGEST_LEN]; plog(" %s hash self-test not available", enum_name(&oakley_hash_names, desc->algo_id));
bool result;
union hash_ctx ctx;
desc->hash_init(&ctx);
desc->hash_update(&ctx, desc->hash_testvectors[i].msg
,desc->hash_testvectors[i].msg_size);
desc->hash_final(digest, &ctx);
result = memeq(digest, desc->hash_testvectors[i].msg_digest
, desc->hash_digest_size);
DBG(DBG_CRYPT,
DBG_log(" hash testvector %d: %s", i, result ? "ok":"failed")
)
hash_results &= result;
} }
plog(" %s hash self-test %s", enum_name(&oakley_hash_names, desc->algo_id) else
, hash_results ? "passed":"failed");
}
if (desc->hmac_testvectors == NULL)
{
plog(" %s hmac self-test not available", enum_name(&oakley_hash_names, desc->algo_id));
}
else
{
int i;
for (i = 0; desc->hmac_testvectors[i].hmac != NULL; i++)
{ {
u_char digest[MAX_DIGEST_LEN]; int i;
bool result;
struct hmac_ctx ctx; for (i = 0; desc->hash_testvectors[i].msg_digest != NULL; i++)
{
u_char digest[MAX_DIGEST_LEN];
bool result;
hmac_init(&ctx, desc, desc->hmac_testvectors[i].key union hash_ctx ctx;
, desc->hmac_testvectors[i].key_size);
hmac_update(&ctx, desc->hmac_testvectors[i].msg desc->hash_init(&ctx);
,desc->hmac_testvectors[i].msg_size); desc->hash_update(&ctx, desc->hash_testvectors[i].msg
hmac_final(digest, &ctx); ,desc->hash_testvectors[i].msg_size);
result = memeq(digest, desc->hmac_testvectors[i].hmac desc->hash_final(digest, &ctx);
, desc->hash_digest_size); result = memeq(digest, desc->hash_testvectors[i].msg_digest
DBG(DBG_CRYPT, , desc->hash_digest_size);
DBG_log(" hmac testvector %d: %s", i, result ? "ok":"failed") DBG(DBG_CRYPT,
) DBG_log(" hash testvector %d: %s", i, result ? "ok":"failed")
hmac_results &= result; )
hash_results &= result;
}
plog(" %s hash self-test %s", enum_name(&oakley_hash_names, desc->algo_id)
, hash_results ? "passed":"failed");
} }
plog(" %s hmac self-test %s", enum_name(&oakley_hash_names, desc->algo_id)
, hmac_results ? "passed":"failed"); if (desc->hmac_testvectors == NULL)
} {
return hash_results && hmac_results; plog(" %s hmac self-test not available", enum_name(&oakley_hash_names, desc->algo_id));
}
else
{
int i;
for (i = 0; desc->hmac_testvectors[i].hmac != NULL; i++)
{
u_char digest[MAX_DIGEST_LEN];
bool result;
struct hmac_ctx ctx;
hmac_init(&ctx, desc, desc->hmac_testvectors[i].key
, desc->hmac_testvectors[i].key_size);
hmac_update(&ctx, desc->hmac_testvectors[i].msg
,desc->hmac_testvectors[i].msg_size);
hmac_final(digest, &ctx);
result = memeq(digest, desc->hmac_testvectors[i].hmac
, desc->hash_digest_size);
DBG(DBG_CRYPT,
DBG_log(" hmac testvector %d: %s", i, result ? "ok":"failed")
)
hmac_results &= result;
}
plog(" %s hmac self-test %s", enum_name(&oakley_hash_names, desc->algo_id)
, hmac_results ? "passed":"failed");
}
return hash_results && hmac_results;
} }
/* /*
@@ -514,30 +514,30 @@ ike_hash_test(const struct hash_desc *desc)
bool bool
ike_alg_test(void) ike_alg_test(void)
{ {
bool all_results = TRUE; bool all_results = TRUE;
struct ike_alg *a; struct ike_alg *a;
plog("Testing registered IKE encryption algorithms:"); plog("Testing registered IKE encryption algorithms:");
for (a = ike_alg_base[IKE_ALG_ENCRYPT]; a != NULL; a = a->algo_next) for (a = ike_alg_base[IKE_ALG_ENCRYPT]; a != NULL; a = a->algo_next)
{ {
plog(" %s self-test not available", enum_name(&oakley_enc_names, a->algo_id)); plog(" %s self-test not available", enum_name(&oakley_enc_names, a->algo_id));
} }
plog("Testing registered IKE hash algorithms:"); plog("Testing registered IKE hash algorithms:");
for (a = ike_alg_base[IKE_ALG_HASH]; a != NULL; a = a->algo_next) for (a = ike_alg_base[IKE_ALG_HASH]; a != NULL; a = a->algo_next)
{ {
struct hash_desc *desc = (struct hash_desc*)a; struct hash_desc *desc = (struct hash_desc*)a;
all_results &= ike_hash_test(desc); all_results &= ike_hash_test(desc);
} }
if (all_results) if (all_results)
plog("All crypto self-tests passed"); plog("All crypto self-tests passed");
else else
plog("Some crypto self-tests failed"); plog("Some crypto self-tests failed");
return all_results; return all_results;
} }
/* /*
@@ -547,43 +547,43 @@ bool
ike_alg_ok_final(u_int ealg, u_int key_len, u_int aalg, u_int group ike_alg_ok_final(u_int ealg, u_int key_len, u_int aalg, u_int group
, struct alg_info_ike *alg_info_ike) , struct alg_info_ike *alg_info_ike)
{ {
/* /*
* simple test to discard low key_len, will accept it only * simple test to discard low key_len, will accept it only
* if specified in "esp" string * if specified in "esp" string
*/ */
bool ealg_insecure = (key_len < 128); bool ealg_insecure = (key_len < 128);
if (ealg_insecure if (ealg_insecure
|| (alg_info_ike && alg_info_ike->alg_info_flags & ALG_INFO_F_STRICT)) || (alg_info_ike && alg_info_ike->alg_info_flags & ALG_INFO_F_STRICT))
{
int i;
struct ike_info *ike_info;
if (alg_info_ike)
{ {
ALG_INFO_IKE_FOREACH(alg_info_ike, ike_info, i) int i;
{ struct ike_info *ike_info;
if (ike_info->ike_ealg == ealg
&& (ike_info->ike_eklen == 0 || key_len == 0 || ike_info->ike_eklen == key_len) if (alg_info_ike)
&& ike_info->ike_halg == aalg
&& ike_info->ike_modp == group)
{ {
if (ealg_insecure) ALG_INFO_IKE_FOREACH(alg_info_ike, ike_info, i)
loglog(RC_LOG_SERIOUS, "You should NOT use insecure IKE algorithms (%s)!" {
, enum_name(&oakley_enc_names, ealg)); if (ike_info->ike_ealg == ealg
return TRUE; && (ike_info->ike_eklen == 0 || key_len == 0 || ike_info->ike_eklen == key_len)
&& ike_info->ike_halg == aalg
&& ike_info->ike_modp == group)
{
if (ealg_insecure)
loglog(RC_LOG_SERIOUS, "You should NOT use insecure IKE algorithms (%s)!"
, enum_name(&oakley_enc_names, ealg));
return TRUE;
}
}
} }
} plog("Oakley Transform [%s (%d), %s, %s] refused due to %s"
, enum_name(&oakley_enc_names, ealg), key_len
, enum_name(&oakley_hash_names, aalg)
, enum_name(&oakley_group_names, group)
, ealg_insecure ?
"insecure key_len and enc. alg. not listed in \"ike\" string" : "strict flag"
);
return FALSE;
} }
plog("Oakley Transform [%s (%d), %s, %s] refused due to %s" return TRUE;
, enum_name(&oakley_enc_names, ealg), key_len
, enum_name(&oakley_hash_names, aalg)
, enum_name(&oakley_group_names, group)
, ealg_insecure ?
"insecure key_len and enc. alg. not listed in \"ike\" string" : "strict flag"
);
return FALSE;
}
return TRUE;
} }
+37 -37
View File
@@ -13,66 +13,66 @@
* *
* RCSID $Id$ * RCSID $Id$
*/ */
#ifndef _IKE_ALG_H #ifndef _IKE_ALG_H
#define _IKE_ALG_H #define _IKE_ALG_H
#include "connections.h" #include "connections.h"
struct ike_alg { struct ike_alg {
u_int16_t algo_type; u_int16_t algo_type;
u_int16_t algo_id; u_int16_t algo_id;
struct ike_alg *algo_next; struct ike_alg *algo_next;
}; };
struct encrypt_desc { struct encrypt_desc {
u_int16_t algo_type; u_int16_t algo_type;
u_int16_t algo_id; u_int16_t algo_id;
struct ike_alg *algo_next; struct ike_alg *algo_next;
size_t enc_ctxsize; size_t enc_ctxsize;
size_t enc_blocksize; size_t enc_blocksize;
u_int keydeflen; u_int keydeflen;
u_int keymaxlen; u_int keymaxlen;
u_int keyminlen; u_int keyminlen;
void (*do_crypt)(u_int8_t *dat, size_t datasize, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc); void (*do_crypt)(u_int8_t *dat, size_t datasize, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc);
}; };
typedef struct hash_testvector hash_testvector_t; typedef struct hash_testvector hash_testvector_t;
struct hash_testvector { struct hash_testvector {
const size_t msg_size; const size_t msg_size;
const u_char *msg; const u_char *msg;
const u_char *msg_digest; const u_char *msg_digest;
}; };
typedef struct hmac_testvector hmac_testvector_t; typedef struct hmac_testvector hmac_testvector_t;
struct hmac_testvector { struct hmac_testvector {
const size_t key_size; const size_t key_size;
const u_char *key; const u_char *key;
const size_t msg_size; const size_t msg_size;
const u_char *msg; const u_char *msg;
const u_char *hmac; const u_char *hmac;
}; };
struct hash_desc { struct hash_desc {
u_int16_t algo_type; u_int16_t algo_type;
u_int16_t algo_id; u_int16_t algo_id;
struct ike_alg *algo_next; struct ike_alg *algo_next;
size_t hash_ctx_size; size_t hash_ctx_size;
size_t hash_block_size; size_t hash_block_size;
size_t hash_digest_size; size_t hash_digest_size;
const hash_testvector_t *hash_testvectors; const hash_testvector_t *hash_testvectors;
const hmac_testvector_t *hmac_testvectors; const hmac_testvector_t *hmac_testvectors;
void (*hash_init)(void *ctx); void (*hash_init)(void *ctx);
void (*hash_update)(void *ctx, const u_int8_t *in, size_t datasize); void (*hash_update)(void *ctx, const u_int8_t *in, size_t datasize);
void (*hash_final)(u_int8_t *out, void *ctx); void (*hash_final)(u_int8_t *out, void *ctx);
}; };
#define IKE_ALG_ENCRYPT 0 #define IKE_ALG_ENCRYPT 0
#define IKE_ALG_HASH 1 #define IKE_ALG_HASH 1
#define IKE_ALG_MAX IKE_ALG_HASH #define IKE_ALG_MAX IKE_ALG_HASH
extern int ike_alg_add(struct ike_alg *a); extern int ike_alg_add(struct ike_alg *a);
extern struct hash_desc *ike_alg_get_hasher(u_int alg); extern struct hash_desc *ike_alg_get_hasher(u_int alg);
@@ -82,13 +82,13 @@ extern bool ike_alg_hash_present(u_int halg);
extern int ike_alg_register_hash(struct hash_desc *a); extern int ike_alg_register_hash(struct hash_desc *a);
extern int ike_alg_register_enc(struct encrypt_desc *e); extern int ike_alg_register_enc(struct encrypt_desc *e);
extern const struct oakley_group_desc* ike_alg_pfsgroup(struct connection *c extern const struct oakley_group_desc* ike_alg_pfsgroup(struct connection *c
, lset_t policy); , lset_t policy);
extern struct db_context * ike_alg_db_new(struct alg_info_ike *ai, lset_t policy); extern struct db_context * ike_alg_db_new(struct alg_info_ike *ai, lset_t policy);
extern void ike_alg_list(void); extern void ike_alg_list(void);
extern void ike_alg_show_connection(struct connection *c, const char *instance); extern void ike_alg_show_connection(struct connection *c, const char *instance);
extern bool ike_alg_test(void); extern bool ike_alg_test(void);
extern bool ike_alg_ok_final(u_int ealg, u_int key_len, u_int aalg, u_int group extern bool ike_alg_ok_final(u_int ealg, u_int key_len, u_int aalg, u_int group
, struct alg_info_ike *alg_info_ike); , struct alg_info_ike *alg_info_ike);
extern int ike_alg_init(void); extern int ike_alg_init(void);
#endif /* _IKE_ALG_H */ #endif /* _IKE_ALG_H */
+4177 -4177
View File
File diff suppressed because it is too large Load Diff
+39 -39
View File
@@ -17,48 +17,48 @@
extern void echo_hdr(struct msg_digest *md, bool enc, u_int8_t np); extern void echo_hdr(struct msg_digest *md, bool enc, u_int8_t np);
extern void ipsecdoi_initiate(int whack_sock, struct connection *c extern void ipsecdoi_initiate(int whack_sock, struct connection *c
, lset_t policy, unsigned long try, so_serial_t replacing); , lset_t policy, unsigned long try, so_serial_t replacing);
extern void ipsecdoi_replace(struct state *st, unsigned long try); extern void ipsecdoi_replace(struct state *st, unsigned long try);
extern void init_phase2_iv(struct state *st, const msgid_t *msgid); extern void init_phase2_iv(struct state *st, const msgid_t *msgid);
extern stf_status quick_outI1(int whack_sock extern stf_status quick_outI1(int whack_sock
, struct state *isakmp_sa , struct state *isakmp_sa
, struct connection *c , struct connection *c
, lset_t policy , lset_t policy
, unsigned long try , unsigned long try
, so_serial_t replacing); , so_serial_t replacing);
extern state_transition_fn extern state_transition_fn
main_inI1_outR1, main_inI1_outR1,
main_inR1_outI2, main_inR1_outI2,
main_inI2_outR2, main_inI2_outR2,
main_inR2_outI3, main_inR2_outI3,
main_inI3_outR3, main_inI3_outR3,
main_inR3, main_inR3,
quick_inI1_outR1, quick_inI1_outR1,
quick_inR1_outI2, quick_inR1_outI2,
quick_inI2; quick_inI2;
extern void send_delete(struct state *st); extern void send_delete(struct state *st);
extern void accept_delete(struct state *st, struct msg_digest *md extern void accept_delete(struct state *st, struct msg_digest *md
, struct payload_digest *p); , struct payload_digest *p);
extern void close_message(pb_stream *pbs); extern void close_message(pb_stream *pbs);
extern bool encrypt_message(pb_stream *pbs, struct state *st); extern bool encrypt_message(pb_stream *pbs, struct state *st);
extern void send_notification_from_state(struct state *st, extern void send_notification_from_state(struct state *st,
enum state_kind state, u_int16_t type); enum state_kind state, u_int16_t type);
extern void send_notification_from_md(struct msg_digest *md, u_int16_t type); extern void send_notification_from_md(struct msg_digest *md, u_int16_t type);
extern const char *init_pluto_vendorid(void); extern const char *init_pluto_vendorid(void);
extern void dpd_outI(struct state *st); extern void dpd_outI(struct state *st);
extern stf_status dpd_inI_outR(struct state *st extern stf_status dpd_inI_outR(struct state *st
, struct isakmp_notification *const n, pb_stream *n_pbs); , struct isakmp_notification *const n, pb_stream *n_pbs);
extern stf_status dpd_inR(struct state *st extern stf_status dpd_inR(struct state *st
, struct isakmp_notification *const n, pb_stream *n_pbs); , struct isakmp_notification *const n, pb_stream *n_pbs);
extern void dpd_timeout(struct state *st); extern void dpd_timeout(struct state *st);
/* START_HASH_PAYLOAD /* START_HASH_PAYLOAD
@@ -70,14 +70,14 @@ extern void dpd_timeout(struct state *st);
* - it references variables local to the caller (r_hashval, r_hash_start, st) * - it references variables local to the caller (r_hashval, r_hash_start, st)
*/ */
#define START_HASH_PAYLOAD(rbody, np) { \ #define START_HASH_PAYLOAD(rbody, np) { \
pb_stream hash_pbs; \ pb_stream hash_pbs; \
if (!out_generic(np, &isakmp_hash_desc, &(rbody), &hash_pbs)) \ if (!out_generic(np, &isakmp_hash_desc, &(rbody), &hash_pbs)) \
return STF_INTERNAL_ERROR; \ return STF_INTERNAL_ERROR; \
r_hashval = hash_pbs.cur; /* remember where to plant value */ \ r_hashval = hash_pbs.cur; /* remember where to plant value */ \
if (!out_zero(st->st_oakley.hasher->hash_digest_size, &hash_pbs, "HASH")) \ if (!out_zero(st->st_oakley.hasher->hash_digest_size, &hash_pbs, "HASH")) \
return STF_INTERNAL_ERROR; \ return STF_INTERNAL_ERROR; \
close_output_pbs(&hash_pbs); \ close_output_pbs(&hash_pbs); \
r_hash_start = (rbody).cur; /* hash from after HASH payload */ \ r_hash_start = (rbody).cur; /* hash from after HASH payload */ \
} }
/* CHECK_QUICK_HASH /* CHECK_QUICK_HASH
@@ -88,17 +88,17 @@ extern void dpd_timeout(struct state *st);
* expression to reference them (hash_val, hash_pbs) * expression to reference them (hash_val, hash_pbs)
*/ */
#define CHECK_QUICK_HASH(md, do_hash, hash_name, msg_name) { \ #define CHECK_QUICK_HASH(md, do_hash, hash_name, msg_name) { \
pb_stream *const hash_pbs = &md->chain[ISAKMP_NEXT_HASH]->pbs; \ pb_stream *const hash_pbs = &md->chain[ISAKMP_NEXT_HASH]->pbs; \
u_char hash_val[MAX_DIGEST_LEN]; \ u_char hash_val[MAX_DIGEST_LEN]; \
size_t hash_len = do_hash; \ size_t hash_len = do_hash; \
if (pbs_left(hash_pbs) != hash_len \ if (pbs_left(hash_pbs) != hash_len \
|| memcmp(hash_pbs->cur, hash_val, hash_len) != 0) \ || memcmp(hash_pbs->cur, hash_val, hash_len) != 0) \
{ \ { \
DBG_cond_dump(DBG_CRYPT, "received " hash_name ":", hash_pbs->cur, pbs_left(hash_pbs)); \ DBG_cond_dump(DBG_CRYPT, "received " hash_name ":", hash_pbs->cur, pbs_left(hash_pbs)); \
loglog(RC_LOG_SERIOUS, "received " hash_name " does not match computed value in " msg_name); \ loglog(RC_LOG_SERIOUS, "received " hash_name " does not match computed value in " msg_name); \
/* XXX Could send notification back */ \ /* XXX Could send notification back */ \
return STF_FAIL + INVALID_HASH_INFORMATION; \ return STF_FAIL + INVALID_HASH_INFORMATION; \
} \ } \
} }
+23 -23
View File
@@ -3,45 +3,45 @@
/* The definitions, required to talk to KAME racoon IKE. */ /* The definitions, required to talk to KAME racoon IKE. */
#define IPSEC_PORT_ANY 0 #define IPSEC_PORT_ANY 0
#define IPSEC_ULPROTO_ANY 255 #define IPSEC_ULPROTO_ANY 255
#define IPSEC_PROTO_ANY 255 #define IPSEC_PROTO_ANY 255
enum { enum {
IPSEC_MODE_ANY = 0, /* We do not support this for SA */ IPSEC_MODE_ANY = 0, /* We do not support this for SA */
IPSEC_MODE_TRANSPORT = 1, IPSEC_MODE_TRANSPORT = 1,
IPSEC_MODE_TUNNEL = 2 IPSEC_MODE_TUNNEL = 2
}; };
enum { enum {
IPSEC_DIR_ANY = 0, IPSEC_DIR_ANY = 0,
IPSEC_DIR_INBOUND = 1, IPSEC_DIR_INBOUND = 1,
IPSEC_DIR_OUTBOUND = 2, IPSEC_DIR_OUTBOUND = 2,
IPSEC_DIR_FWD = 3, /* It is our own */ IPSEC_DIR_FWD = 3, /* It is our own */
IPSEC_DIR_MAX = 4, IPSEC_DIR_MAX = 4,
IPSEC_DIR_INVALID = 5 IPSEC_DIR_INVALID = 5
}; };
enum { enum {
IPSEC_POLICY_DISCARD = 0, IPSEC_POLICY_DISCARD = 0,
IPSEC_POLICY_NONE = 1, IPSEC_POLICY_NONE = 1,
IPSEC_POLICY_IPSEC = 2, IPSEC_POLICY_IPSEC = 2,
IPSEC_POLICY_ENTRUST = 3, IPSEC_POLICY_ENTRUST = 3,
IPSEC_POLICY_BYPASS = 4 IPSEC_POLICY_BYPASS = 4
}; };
enum { enum {
IPSEC_LEVEL_DEFAULT = 0, IPSEC_LEVEL_DEFAULT = 0,
IPSEC_LEVEL_USE = 1, IPSEC_LEVEL_USE = 1,
IPSEC_LEVEL_REQUIRE = 2, IPSEC_LEVEL_REQUIRE = 2,
IPSEC_LEVEL_UNIQUE = 3 IPSEC_LEVEL_UNIQUE = 3
}; };
#define IPSEC_MANUAL_REQID_MAX 0x3fff #define IPSEC_MANUAL_REQID_MAX 0x3fff
#define IPSEC_REPLAYWSIZE 32 #define IPSEC_REPLAYWSIZE 32
#define IP_IPSEC_POLICY 16 #define IP_IPSEC_POLICY 16
#define IPV6_IPSEC_POLICY 34 #define IPV6_IPSEC_POLICY 34
#endif /* __IPSEC_H */ #endif /* __IPSEC_H */
+2251 -2251
View File
File diff suppressed because it is too large Load Diff
+100 -100
View File
@@ -16,7 +16,7 @@
#include "connections.h" #include "connections.h"
extern bool no_klips; /* don't actually use KLIPS */ extern bool no_klips; /* don't actually use KLIPS */
extern bool can_do_IPcomp; /* can system actually perform IPCOMP? */ extern bool can_do_IPcomp; /* can system actually perform IPCOMP? */
#ifdef KLIPS #ifdef KLIPS
@@ -28,96 +28,96 @@ extern bool can_do_IPcomp; /* can system actually perform IPCOMP? */
* limited to appropriate source and destination addresses. * limited to appropriate source and destination addresses.
*/ */
#define ERO_MASK 0xFF #define ERO_MASK 0xFF
#define ERO_FLAG_SHIFT 8 #define ERO_FLAG_SHIFT 8
#define ERO_DELETE SADB_X_DELFLOW #define ERO_DELETE SADB_X_DELFLOW
#define ERO_ADD SADB_X_ADDFLOW #define ERO_ADD SADB_X_ADDFLOW
#define ERO_REPLACE (SADB_X_ADDFLOW | (SADB_X_SAFLAGS_REPLACEFLOW << ERO_FLAG_SHIFT)) #define ERO_REPLACE (SADB_X_ADDFLOW | (SADB_X_SAFLAGS_REPLACEFLOW << ERO_FLAG_SHIFT))
#define ERO_ADD_INBOUND (SADB_X_ADDFLOW | (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT)) #define ERO_ADD_INBOUND (SADB_X_ADDFLOW | (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
#define ERO_DEL_INBOUND (SADB_X_DELFLOW | (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT)) #define ERO_DEL_INBOUND (SADB_X_DELFLOW | (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
struct pfkey_proto_info { struct pfkey_proto_info {
int proto; int proto;
int encapsulation; int encapsulation;
unsigned reqid; unsigned reqid;
}; };
struct sadb_msg; struct sadb_msg;
struct kernel_sa { struct kernel_sa {
const ip_address *src; const ip_address *src;
const ip_address *dst; const ip_address *dst;
const ip_subnet *src_client; const ip_subnet *src_client;
const ip_subnet *dst_client; const ip_subnet *dst_client;
ipsec_spi_t spi; ipsec_spi_t spi;
unsigned proto; unsigned proto;
unsigned satype; unsigned satype;
unsigned transport_proto; unsigned transport_proto;
unsigned replay_window; unsigned replay_window;
unsigned reqid; unsigned reqid;
unsigned authalg; unsigned authalg;
unsigned authkeylen; unsigned authkeylen;
char *authkey; char *authkey;
unsigned encalg; unsigned encalg;
unsigned enckeylen; unsigned enckeylen;
char *enckey; char *enckey;
unsigned compalg; unsigned compalg;
int encapsulation; int encapsulation;
u_int16_t natt_sport, natt_dport; u_int16_t natt_sport, natt_dport;
u_int8_t transid, natt_type; u_int8_t transid, natt_type;
ip_address *natt_oa; ip_address *natt_oa;
const char *text_said; const char *text_said;
}; };
struct kernel_ops { struct kernel_ops {
enum { enum {
KERNEL_TYPE_NONE, KERNEL_TYPE_NONE,
KERNEL_TYPE_KLIPS, KERNEL_TYPE_KLIPS,
KERNEL_TYPE_LINUX, KERNEL_TYPE_LINUX,
} type; } type;
bool inbound_eroute; bool inbound_eroute;
bool policy_lifetime; bool policy_lifetime;
int *async_fdp; int *async_fdp;
void (*init)(void); void (*init)(void);
void (*pfkey_register)(void); void (*pfkey_register)(void);
void (*pfkey_register_response)(const struct sadb_msg *msg); void (*pfkey_register_response)(const struct sadb_msg *msg);
void (*process_queue)(void); void (*process_queue)(void);
void (*process_msg)(void); void (*process_msg)(void);
bool (*raw_eroute)(const ip_address *this_host, bool (*raw_eroute)(const ip_address *this_host,
const ip_subnet *this_client, const ip_subnet *this_client,
const ip_address *that_host, const ip_address *that_host,
const ip_subnet *that_client, const ip_subnet *that_client,
ipsec_spi_t spi, ipsec_spi_t spi,
unsigned int satype, unsigned int satype,
unsigned int transport_proto, unsigned int transport_proto,
const struct pfkey_proto_info *proto_info, const struct pfkey_proto_info *proto_info,
time_t use_lifetime, time_t use_lifetime,
unsigned int op, unsigned int op,
const char *text_said); const char *text_said);
bool (*get_policy)(const struct kernel_sa *sa, bool inbound, bool (*get_policy)(const struct kernel_sa *sa, bool inbound,
time_t *use_time); time_t *use_time);
bool (*add_sa)(const struct kernel_sa *sa, bool replace); bool (*add_sa)(const struct kernel_sa *sa, bool replace);
bool (*grp_sa)(const struct kernel_sa *sa_outer, bool (*grp_sa)(const struct kernel_sa *sa_outer,
const struct kernel_sa *sa_inner); const struct kernel_sa *sa_inner);
bool (*del_sa)(const struct kernel_sa *sa); bool (*del_sa)(const struct kernel_sa *sa);
bool (*get_sa)(const struct kernel_sa *sa, u_int *bytes); bool (*get_sa)(const struct kernel_sa *sa, u_int *bytes);
ipsec_spi_t (*get_spi)(const ip_address *src, ipsec_spi_t (*get_spi)(const ip_address *src,
const ip_address *dst, const ip_address *dst,
int proto, int proto,
bool tunnel_mode, bool tunnel_mode,
unsigned reqid, unsigned reqid,
ipsec_spi_t min, ipsec_spi_t min,
ipsec_spi_t max, ipsec_spi_t max,
const char *text_said); const char *text_said);
}; };
@@ -126,13 +126,13 @@ extern const struct kernel_ops *kernel_ops;
/* information from /proc/net/ipsec_eroute */ /* information from /proc/net/ipsec_eroute */
struct eroute_info { struct eroute_info {
unsigned long count; unsigned long count;
ip_subnet ours; ip_subnet ours;
ip_subnet his; ip_subnet his;
ip_address dst; ip_address dst;
ip_said said; ip_said said;
int transport_proto; int transport_proto;
struct eroute_info *next; struct eroute_info *next;
}; };
extern struct eroute_info *orphaned_holds; extern struct eroute_info *orphaned_holds;
@@ -144,13 +144,13 @@ extern void show_shunt_status(void);
* Is there a PF_KEY equivalent? * Is there a PF_KEY equivalent?
*/ */
#ifndef EM_MAXRELSPIS #ifndef EM_MAXRELSPIS
# define EM_MAXRELSPIS 4 /* AH ESP IPCOMP IPIP */ # define EM_MAXRELSPIS 4 /* AH ESP IPCOMP IPIP */
#endif #endif
extern void record_and_initiate_opportunistic(const ip_subnet * extern void record_and_initiate_opportunistic(const ip_subnet *
, const ip_subnet * , const ip_subnet *
, int transport_proto , int transport_proto
, const char *why); , const char *why);
extern void init_kernel(void); extern void init_kernel(void);
@@ -160,39 +160,39 @@ extern bool trap_connection(struct connection *c);
extern void unroute_connection(struct connection *c); extern void unroute_connection(struct connection *c);
extern bool has_bare_hold(const ip_address *src, const ip_address *dst extern bool has_bare_hold(const ip_address *src, const ip_address *dst
, int transport_proto); , int transport_proto);
extern bool replace_bare_shunt(const ip_address *src, const ip_address *dst extern bool replace_bare_shunt(const ip_address *src, const ip_address *dst
, policy_prio_t policy_prio , policy_prio_t policy_prio
, ipsec_spi_t shunt_spi /* in host order! */ , ipsec_spi_t shunt_spi /* in host order! */
, bool repl , bool repl
, unsigned int transport_proto , unsigned int transport_proto
, const char *why); , const char *why);
extern bool assign_hold(struct connection *c extern bool assign_hold(struct connection *c
, struct spd_route *sr , struct spd_route *sr
, int transport_proto , int transport_proto
, const ip_address *src, const ip_address *dst); , const ip_address *src, const ip_address *dst);
extern ipsec_spi_t shunt_policy_spi(struct connection *c, bool prospective); extern ipsec_spi_t shunt_policy_spi(struct connection *c, bool prospective);
struct state; /* forward declaration of tag */ struct state; /* forward declaration of tag */
extern ipsec_spi_t get_ipsec_spi(ipsec_spi_t avoid extern ipsec_spi_t get_ipsec_spi(ipsec_spi_t avoid
, int proto , int proto
, struct spd_route *sr , struct spd_route *sr
, bool tunnel_mode); , bool tunnel_mode);
extern ipsec_spi_t get_my_cpi(struct spd_route *sr, bool tunnel_mode); extern ipsec_spi_t get_my_cpi(struct spd_route *sr, bool tunnel_mode);
extern bool install_inbound_ipsec_sa(struct state *st); extern bool install_inbound_ipsec_sa(struct state *st);
extern bool install_ipsec_sa(struct state *st, bool inbound_also); extern bool install_ipsec_sa(struct state *st, bool inbound_also);
extern void delete_ipsec_sa(struct state *st, bool inbound_only); extern void delete_ipsec_sa(struct state *st, bool inbound_only);
extern bool route_and_eroute(struct connection *c extern bool route_and_eroute(struct connection *c
, struct spd_route *sr , struct spd_route *sr
, struct state *st); , struct state *st);
extern bool was_eroute_idle(struct state *st, time_t idle_max extern bool was_eroute_idle(struct state *st, time_t idle_max
, time_t *idle_time); , time_t *idle_time);
extern bool get_sa_info(struct state *st, bool inbound, u_int *bytes extern bool get_sa_info(struct state *st, bool inbound, u_int *bytes
, time_t *use_time); , time_t *use_time);
extern bool update_ipsec_sa(struct state *st); extern bool update_ipsec_sa(struct state *st);
+539 -539
View File
File diff suppressed because it is too large Load Diff
+840 -840
View File
File diff suppressed because it is too large Load Diff
+29 -29
View File
@@ -39,7 +39,7 @@
#include "kernel.h" #include "kernel.h"
#include "kernel_noklips.h" #include "kernel_noklips.h"
#include "log.h" #include "log.h"
#include "whack.h" /* for RC_LOG_SERIOUS */ #include "whack.h" /* for RC_LOG_SERIOUS */
void void
init_noklips(void) init_noklips(void)
@@ -71,30 +71,30 @@ noklips_register(void)
static bool static bool
noklips_raw_eroute(const ip_address *this_host UNUSED noklips_raw_eroute(const ip_address *this_host UNUSED
, const ip_subnet *this_client UNUSED , const ip_subnet *this_client UNUSED
, const ip_address *that_host UNUSED , const ip_address *that_host UNUSED
, const ip_subnet *that_client UNUSED , const ip_subnet *that_client UNUSED
, ipsec_spi_t spi UNUSED , ipsec_spi_t spi UNUSED
, unsigned int satype UNUSED , unsigned int satype UNUSED
, unsigned int transport_proto UNUSED , unsigned int transport_proto UNUSED
, const struct pfkey_proto_info *proto_info UNUSED , const struct pfkey_proto_info *proto_info UNUSED
, time_t use_lifetime UNUSED , time_t use_lifetime UNUSED
, unsigned int op UNUSED , unsigned int op UNUSED
, const char *text_said UNUSED) , const char *text_said UNUSED)
{ {
return TRUE; return TRUE;
} }
static bool static bool
noklips_add_sa(const struct kernel_sa *sa UNUSED noklips_add_sa(const struct kernel_sa *sa UNUSED
, bool replace UNUSED) , bool replace UNUSED)
{ {
return TRUE; return TRUE;
} }
static bool static bool
noklips_grp_sa(const struct kernel_sa *sa0 UNUSED noklips_grp_sa(const struct kernel_sa *sa0 UNUSED
, const struct kernel_sa *sa1 UNUSED) , const struct kernel_sa *sa1 UNUSED)
{ {
return TRUE; return TRUE;
} }
@@ -107,20 +107,20 @@ noklips_del_sa(const struct kernel_sa *sa UNUSED)
const struct kernel_ops noklips_kernel_ops = { const struct kernel_ops noklips_kernel_ops = {
type: KERNEL_TYPE_NONE, type: KERNEL_TYPE_NONE,
async_fdp: NULL, async_fdp: NULL,
init: init_noklips, init: init_noklips,
pfkey_register: noklips_register, pfkey_register: noklips_register,
pfkey_register_response: noklips_register_response, pfkey_register_response: noklips_register_response,
process_queue: noklips_dequeue, process_queue: noklips_dequeue,
process_msg: noklips_event, process_msg: noklips_event,
raw_eroute: noklips_raw_eroute, raw_eroute: noklips_raw_eroute,
add_sa: noklips_add_sa, add_sa: noklips_add_sa,
grp_sa: noklips_grp_sa, grp_sa: noklips_grp_sa,
del_sa: noklips_del_sa, del_sa: noklips_del_sa,
get_sa: NULL, get_sa: NULL,
get_spi: NULL, get_spi: NULL,
inbound_eroute: FALSE, inbound_eroute: FALSE,
policy_lifetime: FALSE policy_lifetime: FALSE
}; };
+589 -589
View File
File diff suppressed because it is too large Load Diff
+1023 -1023
View File
File diff suppressed because it is too large Load Diff
+32 -32
View File
@@ -32,11 +32,11 @@ extern void load_preshared_secrets(int whackfd);
extern void free_preshared_secrets(void); extern void free_preshared_secrets(void);
enum PrivateKeyKind { enum PrivateKeyKind {
PPK_PSK, PPK_PSK,
/* PPK_DSS, */ /* not implemented */ /* PPK_DSS, */ /* not implemented */
PPK_RSA, PPK_RSA,
PPK_XAUTH, PPK_XAUTH,
PPK_PIN PPK_PIN
}; };
extern void xauth_defaults(void); extern void xauth_defaults(void);
@@ -54,60 +54,60 @@ extern const RSA_private_key_t *get_x509_private_key(const x509cert_t *cert);
typedef struct pubkey pubkey_t; typedef struct pubkey pubkey_t;
struct pubkey { struct pubkey {
struct id id; struct id id;
unsigned refcnt; /* reference counted! */ unsigned refcnt; /* reference counted! */
enum dns_auth_level dns_auth_level; enum dns_auth_level dns_auth_level;
char *dns_sig; char *dns_sig;
time_t installed_time time_t installed_time
, last_tried_time , last_tried_time
, last_worked_time , last_worked_time
, until_time; , until_time;
chunk_t issuer; chunk_t issuer;
chunk_t serial; chunk_t serial;
enum pubkey_alg alg; enum pubkey_alg alg;
union { union {
RSA_public_key_t rsa; RSA_public_key_t rsa;
} u; } u;
}; };
typedef struct pubkey_list pubkey_list_t; typedef struct pubkey_list pubkey_list_t;
struct pubkey_list { struct pubkey_list {
pubkey_t *key; pubkey_t *key;
pubkey_list_t *next; pubkey_list_t *next;
}; };
extern pubkey_list_t *pubkeys; /* keys from ipsec.conf or from certs */ extern pubkey_list_t *pubkeys; /* keys from ipsec.conf or from certs */
extern pubkey_t *public_key_from_rsa(const RSA_public_key_t *k); extern pubkey_t *public_key_from_rsa(const RSA_public_key_t *k);
extern pubkey_list_t *free_public_keyentry(pubkey_list_t *p); extern pubkey_list_t *free_public_keyentry(pubkey_list_t *p);
extern void free_public_keys(pubkey_list_t **keys); extern void free_public_keys(pubkey_list_t **keys);
extern void free_remembered_public_keys(void); extern void free_remembered_public_keys(void);
extern void delete_public_keys(const struct id *id, enum pubkey_alg alg extern void delete_public_keys(const struct id *id, enum pubkey_alg alg
, chunk_t issuer, chunk_t serial); , chunk_t issuer, chunk_t serial);
extern pubkey_t *reference_key(pubkey_t *pk); extern pubkey_t *reference_key(pubkey_t *pk);
extern void unreference_key(pubkey_t **pkp); extern void unreference_key(pubkey_t **pkp);
extern err_t add_public_key(const struct id *id extern err_t add_public_key(const struct id *id
, enum dns_auth_level dns_auth_level , enum dns_auth_level dns_auth_level
, enum pubkey_alg alg , enum pubkey_alg alg
, const chunk_t *key , const chunk_t *key
, pubkey_list_t **head); , pubkey_list_t **head);
extern bool has_private_key(cert_t cert); extern bool has_private_key(cert_t cert);
extern void add_x509_public_key(x509cert_t *cert, time_t until extern void add_x509_public_key(x509cert_t *cert, time_t until
, enum dns_auth_level dns_auth_level); , enum dns_auth_level dns_auth_level);
extern void add_pgp_public_key(pgpcert_t *cert, time_t until extern void add_pgp_public_key(pgpcert_t *cert, time_t until
, enum dns_auth_level dns_auth_level); , enum dns_auth_level dns_auth_level);
extern void remove_x509_public_key(const x509cert_t *cert); extern void remove_x509_public_key(const x509cert_t *cert);
extern void list_public_keys(bool utc); extern void list_public_keys(bool utc);
struct gw_info; /* forward declaration of tag (defined in dnskey.h) */ struct gw_info; /* forward declaration of tag (defined in dnskey.h) */
extern void transfer_to_public_keys(struct gw_info *gateways_from_dns extern void transfer_to_public_keys(struct gw_info *gateways_from_dns
#ifdef USE_KEYRR #ifdef USE_KEYRR
, pubkey_list_t **keys , pubkey_list_t **keys
#endif /* USE_KEYRR */ #endif /* USE_KEYRR */
); );
#endif /* _KEYS_H */ #endif /* _KEYS_H */
+127 -127
View File
@@ -27,7 +27,7 @@
#include "constants.h" #include "constants.h"
#include "defs.h" #include "defs.h"
#include "log.h" #include "log.h"
#include "whack.h" /* for RC_LOG_SERIOUS */ #include "whack.h" /* for RC_LOG_SERIOUS */
#include "lex.h" #include "lex.h"
struct file_lex_position *flp = NULL; struct file_lex_position *flp = NULL;
@@ -39,36 +39,36 @@ struct file_lex_position *flp = NULL;
bool bool
lexopen(struct file_lex_position *new_flp, const char *name, bool optional) lexopen(struct file_lex_position *new_flp, const char *name, bool optional)
{ {
FILE *f = fopen(name, "r"); FILE *f = fopen(name, "r");
if (f == NULL) if (f == NULL)
{ {
if (!optional || errno != ENOENT) if (!optional || errno != ENOENT)
log_errno((e, "could not open \"%s\"", name)); log_errno((e, "could not open \"%s\"", name));
return FALSE; return FALSE;
} }
else else
{ {
new_flp->previous = flp; new_flp->previous = flp;
flp = new_flp; flp = new_flp;
flp->filename = name; flp->filename = name;
flp->fp = f; flp->fp = f;
flp->lino = 0; flp->lino = 0;
flp->bdry = B_none; flp->bdry = B_none;
flp->cur = flp->buffer; /* nothing loaded yet */ flp->cur = flp->buffer; /* nothing loaded yet */
flp->under = *flp->cur = '\0'; flp->under = *flp->cur = '\0';
(void) shift(); /* prime tok */ (void) shift(); /* prime tok */
return TRUE; return TRUE;
} }
} }
void void
lexclose(void) lexclose(void)
{ {
fclose(flp->fp); fclose(flp->fp);
flp = flp->previous; flp = flp->previous;
} }
/* Token decoding: shift() loads the next token into tok. /* Token decoding: shift() loads the next token into tok.
@@ -88,110 +88,110 @@ char *tok;
bool bool
shift(void) shift(void)
{ {
char *p = flp->cur; char *p = flp->cur;
char *sor = NULL; /* start of record for any new lines */ char *sor = NULL; /* start of record for any new lines */
passert(flp->bdry == B_none); passert(flp->bdry == B_none);
*p = flp->under; *p = flp->under;
flp->under = '\0'; flp->under = '\0';
for (;;) for (;;)
{
switch (*p)
{ {
case '\0': /* end of line */ switch (*p)
case '#': /* comment to end of line: treat as end of line */
/* get the next line */
if (fgets(flp->buffer, sizeof(flp->buffer)-1, flp->fp) == NULL)
{
flp->bdry = B_file;
tok = flp->cur = NULL;
return FALSE;
}
else
{
/* strip trailing whitespace, including \n */
for (p = flp->buffer+strlen(flp->buffer)-1
; p>flp->buffer && isspace(p[-1]); p--)
;
*p = '\0';
flp->lino++;
sor = p = flp->buffer;
}
break; /* try again for a token */
case ' ': /* whitespace */
case '\t':
p++;
break; /* try again for a token */
case '"': /* quoted token */
case '\'':
if (p != sor)
{
/* we have a quoted token: note and advance to its end */
tok = p;
p = strchr(p+1, *p);
if (p == NULL)
{ {
loglog(RC_LOG_SERIOUS, "\"%s\" line %d: unterminated string" case '\0': /* end of line */
, flp->filename, flp->lino); case '#': /* comment to end of line: treat as end of line */
p = tok + strlen(tok); /* get the next line */
} if (fgets(flp->buffer, sizeof(flp->buffer)-1, flp->fp) == NULL)
else {
{ flp->bdry = B_file;
p++; /* include delimiter in token */ tok = flp->cur = NULL;
} return FALSE;
}
else
{
/* strip trailing whitespace, including \n */
/* remember token delimiter and replace with '\0' */ for (p = flp->buffer+strlen(flp->buffer)-1
flp->under = *p; ; p>flp->buffer && isspace(p[-1]); p--)
*p = '\0'; ;
flp->cur = p; *p = '\0';
return TRUE;
}
/* FALL THROUGH */
default:
if (p != sor)
{
/* we seem to have a token: note and advance to its end */
tok = p;
if (p[0] == '0' && p[1] == 't') flp->lino++;
{ sor = p = flp->buffer;
/* 0t... token goes to end of line */ }
p += strlen(p); break; /* try again for a token */
}
else case ' ': /* whitespace */
{ case '\t':
/* "ordinary" token: up to whitespace or end of line */
do {
p++; p++;
} while (*p != '\0' && !isspace(*p)) break; /* try again for a token */
;
/* fudge to separate ':' from a preceding adjacent token */ case '"': /* quoted token */
if (p-1 > tok && p[-1] == ':') case '\'':
p--; if (p != sor)
{
/* we have a quoted token: note and advance to its end */
tok = p;
p = strchr(p+1, *p);
if (p == NULL)
{
loglog(RC_LOG_SERIOUS, "\"%s\" line %d: unterminated string"
, flp->filename, flp->lino);
p = tok + strlen(tok);
}
else
{
p++; /* include delimiter in token */
}
/* remember token delimiter and replace with '\0' */
flp->under = *p;
*p = '\0';
flp->cur = p;
return TRUE;
}
/* FALL THROUGH */
default:
if (p != sor)
{
/* we seem to have a token: note and advance to its end */
tok = p;
if (p[0] == '0' && p[1] == 't')
{
/* 0t... token goes to end of line */
p += strlen(p);
}
else
{
/* "ordinary" token: up to whitespace or end of line */
do {
p++;
} while (*p != '\0' && !isspace(*p))
;
/* fudge to separate ':' from a preceding adjacent token */
if (p-1 > tok && p[-1] == ':')
p--;
}
/* remember token delimiter and replace with '\0' */
flp->under = *p;
*p = '\0';
flp->cur = p;
return TRUE;
}
/* we have a start-of-record: return it, deferring "real" token */
flp->bdry = B_record;
tok = NULL;
flp->under = *p;
flp->cur = p;
return FALSE;
} }
/* remember token delimiter and replace with '\0' */
flp->under = *p;
*p = '\0';
flp->cur = p;
return TRUE;
}
/* we have a start-of-record: return it, deferring "real" token */
flp->bdry = B_record;
tok = NULL;
flp->under = *p;
flp->cur = p;
return FALSE;
} }
}
} }
/* ensures we are at a Record (or File) boundary, optionally warning if not */ /* ensures we are at a Record (or File) boundary, optionally warning if not */
@@ -199,15 +199,15 @@ shift(void)
bool bool
flushline(const char *m) flushline(const char *m)
{ {
if (flp->bdry != B_none) if (flp->bdry != B_none)
{ {
return TRUE; return TRUE;
} }
else else
{ {
if (m != NULL) if (m != NULL)
loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s", flp->filename, flp->lino, m); loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s", flp->filename, flp->lino, m);
do ; while (shift()); do ; while (shift());
return FALSE; return FALSE;
} }
} }
+9 -9
View File
@@ -17,15 +17,15 @@
#define MAX_TOK_LEN 2048 /* includes terminal '\0' */ #define MAX_TOK_LEN 2048 /* includes terminal '\0' */
struct file_lex_position struct file_lex_position
{ {
int depth; /* how deeply we are nested */ int depth; /* how deeply we are nested */
const char *filename; const char *filename;
FILE *fp; FILE *fp;
enum { B_none, B_record, B_file } bdry; /* current boundary */ enum { B_none, B_record, B_file } bdry; /* current boundary */
int lino; /* line number in file */ int lino; /* line number in file */
char buffer[MAX_TOK_LEN + 1]; /* note: one extra char for our use (jamming '"') */ char buffer[MAX_TOK_LEN + 1]; /* note: one extra char for our use (jamming '"') */
char *cur; /* cursor */ char *cur; /* cursor */
char under; /* except in shift(): character orignally at *cur */ char under; /* except in shift(): character orignally at *cur */
struct file_lex_position *previous; struct file_lex_position *previous;
}; };
extern struct file_lex_position *flp; extern struct file_lex_position *flp;
+40 -40
View File
@@ -33,16 +33,16 @@ typedef struct private_library_t private_library_t;
*/ */
struct private_library_t { struct private_library_t {
/** /**
* public functions * public functions
*/ */
library_t public; library_t public;
#ifdef LEAK_DETECTIVE #ifdef LEAK_DETECTIVE
/** /**
* Memory leak detective, if enabled * Memory leak detective, if enabled
*/ */
leak_detective_t *detective; leak_detective_t *detective;
#endif /* LEAK_DETECTIVE */ #endif /* LEAK_DETECTIVE */
}; };
@@ -56,19 +56,19 @@ library_t *lib;
*/ */
void library_deinit() void library_deinit()
{ {
private_library_t *this = (private_library_t*)lib; private_library_t *this = (private_library_t*)lib;
this->public.settings->destroy(this->public.settings); this->public.settings->destroy(this->public.settings);
this->public.printf_hook->destroy(this->public.printf_hook); this->public.printf_hook->destroy(this->public.printf_hook);
#ifdef LEAK_DETECTIVE #ifdef LEAK_DETECTIVE
if (this->detective) if (this->detective)
{ {
this->detective->destroy(this->detective); this->detective->destroy(this->detective);
} }
#endif /* LEAK_DETECTIVE */ #endif /* LEAK_DETECTIVE */
free(this); free(this);
lib = NULL; lib = NULL;
} }
/* /*
@@ -76,31 +76,31 @@ void library_deinit()
*/ */
void library_init(char *settings) void library_init(char *settings)
{ {
printf_hook_t *pfh; printf_hook_t *pfh;
private_library_t *this = malloc_thing(private_library_t); private_library_t *this = malloc_thing(private_library_t);
lib = &this->public; lib = &this->public;
lib->leak_detective = FALSE; lib->leak_detective = FALSE;
#ifdef LEAK_DETECTIVE #ifdef LEAK_DETECTIVE
this->detective = leak_detective_create(); this->detective = leak_detective_create();
#endif /* LEAK_DETECTIVE */ #endif /* LEAK_DETECTIVE */
pfh = printf_hook_create(); pfh = printf_hook_create();
this->public.printf_hook = pfh; this->public.printf_hook = pfh;
pfh->add_handler(pfh, 'b', mem_printf_hook, pfh->add_handler(pfh, 'b', mem_printf_hook,
PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_INT, PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_INT,
PRINTF_HOOK_ARGTYPE_END); PRINTF_HOOK_ARGTYPE_END);
pfh->add_handler(pfh, 'B', chunk_printf_hook, pfh->add_handler(pfh, 'B', chunk_printf_hook,
PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_END); PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_END);
pfh->add_handler(pfh, 'T', time_printf_hook, pfh->add_handler(pfh, 'T', time_printf_hook,
PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_INT, PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_INT,
PRINTF_HOOK_ARGTYPE_END); PRINTF_HOOK_ARGTYPE_END);
pfh->add_handler(pfh, 'V', time_delta_printf_hook, pfh->add_handler(pfh, 'V', time_delta_printf_hook,
PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_POINTER,
PRINTF_HOOK_ARGTYPE_END); PRINTF_HOOK_ARGTYPE_END);
this->public.settings = settings_create(settings); this->public.settings = settings_create(settings);
} }
+15 -15
View File
@@ -28,26 +28,26 @@ typedef struct library_t library_t;
*/ */
struct library_t { struct library_t {
/** /**
* Printf hook registering facility * Printf hook registering facility
*/ */
printf_hook_t *printf_hook; printf_hook_t *printf_hook;
/** /**
* various settings loaded from settings file * various settings loaded from settings file
*/ */
settings_t *settings; settings_t *settings;
/** /**
* is leak detective running? * is leak detective running?
*/ */
bool leak_detective; bool leak_detective;
}; };
/** /**
* Initialize library, creates "lib" instance. * Initialize library, creates "lib" instance.
* *
* @param settings file to read settings from, may be NULL for none * @param settings file to read settings from, may be NULL for none
*/ */
void library_init(char *settings); void library_init(char *settings);
+493 -493
View File
File diff suppressed because it is too large Load Diff
+51 -51
View File
@@ -27,49 +27,49 @@
#ifdef DEBUG #ifdef DEBUG
extern void passert_fail(const char *pred_str extern void passert_fail(const char *pred_str
, const char *file_str, unsigned long line_no) NEVER_RETURNS; , const char *file_str, unsigned long line_no) NEVER_RETURNS;
extern void pexpect_log(const char *pred_str extern void pexpect_log(const char *pred_str
, const char *file_str, unsigned long line_no); , const char *file_str, unsigned long line_no);
# define impossible() passert_fail("impossible", __FILE__, __LINE__) # define impossible() passert_fail("impossible", __FILE__, __LINE__)
extern void switch_fail(int n extern void switch_fail(int n
, const char *file_str, unsigned long line_no) NEVER_RETURNS; , const char *file_str, unsigned long line_no) NEVER_RETURNS;
# define bad_case(n) switch_fail((int) n, __FILE__, __LINE__) # define bad_case(n) switch_fail((int) n, __FILE__, __LINE__)
# define passert(pred) { \ # define passert(pred) { \
if (!(pred)) \ if (!(pred)) \
passert_fail(#pred, __FILE__, __LINE__); \ passert_fail(#pred, __FILE__, __LINE__); \
} }
# define pexpect(pred) { \ # define pexpect(pred) { \
if (!(pred)) \ if (!(pred)) \
pexpect_log(#pred, __FILE__, __LINE__); \ pexpect_log(#pred, __FILE__, __LINE__); \
} }
/* assert that an err_t is NULL; evaluate exactly once */ /* assert that an err_t is NULL; evaluate exactly once */
# define happy(x) { \ # define happy(x) { \
err_t ugh = x; \ err_t ugh = x; \
if (ugh != NULL) \ if (ugh != NULL) \
passert_fail(ugh, __FILE__, __LINE__); \ passert_fail(ugh, __FILE__, __LINE__); \
} }
#else /*!DEBUG*/ #else /*!DEBUG*/
# define impossible() abort() # define impossible() abort()
# define bad_case(n) abort() # define bad_case(n) abort()
# define passert(pred) { } /* do nothing */ # define passert(pred) { } /* do nothing */
# define happy(x) { (void) x; } /* evaluate non-judgementally */ # define happy(x) { (void) x; } /* evaluate non-judgementally */
#endif /*!DEBUG*/ #endif /*!DEBUG*/
extern bool extern bool
log_to_stderr, /* should log go to stderr? */ log_to_stderr, /* should log go to stderr? */
log_to_syslog, /* should log go to syslog? */ log_to_syslog, /* should log go to syslog? */
log_to_perpeer; /* should log go to per-IP file? */ log_to_perpeer; /* should log go to per-IP file? */
extern const char *base_perpeer_logdir; extern const char *base_perpeer_logdir;
@@ -84,25 +84,25 @@ extern const char *base_perpeer_logdir;
* If the context provides a whack file descriptor, messages * If the context provides a whack file descriptor, messages
* should be copied to it -- see whack_log() * should be copied to it -- see whack_log()
*/ */
extern int whack_log_fd; /* only set during whack_handle() */ extern int whack_log_fd; /* only set during whack_handle() */
extern struct state *cur_state; /* current state, for diagnostics */ extern struct state *cur_state; /* current state, for diagnostics */
extern struct connection *cur_connection; /* current connection, for diagnostics */ extern struct connection *cur_connection; /* current connection, for diagnostics */
extern const ip_address *cur_from; /* source of current current message */ extern const ip_address *cur_from; /* source of current current message */
extern u_int16_t cur_from_port; /* host order */ extern u_int16_t cur_from_port; /* host order */
#ifdef DEBUG #ifdef DEBUG
extern lset_t cur_debugging; /* current debugging level */ extern lset_t cur_debugging; /* current debugging level */
extern void extra_debugging(const struct connection *c); extern void extra_debugging(const struct connection *c);
# define reset_debugging() { cur_debugging = base_debugging; } # define reset_debugging() { cur_debugging = base_debugging; }
# define GLOBALS_ARE_RESET() (whack_log_fd == NULL_FD \ # define GLOBALS_ARE_RESET() (whack_log_fd == NULL_FD \
&& cur_state == NULL \ && cur_state == NULL \
&& cur_connection == NULL \ && cur_connection == NULL \
&& cur_from == NULL \ && cur_from == NULL \
&& cur_debugging == base_debugging) && cur_debugging == base_debugging)
#else /*!DEBUG*/ #else /*!DEBUG*/
@@ -111,40 +111,40 @@ extern u_int16_t cur_from_port; /* host order */
# define reset_debugging() { } # define reset_debugging() { }
# define GLOBALS_ARE_RESET() (whack_log_fd == NULL_FD \ # define GLOBALS_ARE_RESET() (whack_log_fd == NULL_FD \
&& cur_state == NULL \ && cur_state == NULL \
&& cur_connection == NULL \ && cur_connection == NULL \
&& cur_from == NULL) && cur_from == NULL)
#endif /*!DEBUG*/ #endif /*!DEBUG*/
#define reset_globals() { \ #define reset_globals() { \
whack_log_fd = NULL_FD; \ whack_log_fd = NULL_FD; \
cur_state = NULL; \ cur_state = NULL; \
cur_from = NULL; \ cur_from = NULL; \
reset_cur_connection(); \ reset_cur_connection(); \
} }
#define set_cur_connection(c) { \ #define set_cur_connection(c) { \
cur_connection = (c); \ cur_connection = (c); \
extra_debugging(c); \ extra_debugging(c); \
} }
#define reset_cur_connection() { \ #define reset_cur_connection() { \
cur_connection = NULL; \ cur_connection = NULL; \
reset_debugging(); \ reset_debugging(); \
} }
#define set_cur_state(s) { \ #define set_cur_state(s) { \
cur_state = (s); \ cur_state = (s); \
extra_debugging((s)->st_connection); \ extra_debugging((s)->st_connection); \
} }
#define reset_cur_state() { \ #define reset_cur_state() { \
cur_state = NULL; \ cur_state = NULL; \
reset_debugging(); \ reset_debugging(); \
} }
extern void init_log(const char *program); extern void init_log(const char *program);
extern void close_log(void); extern void close_log(void);
@@ -188,12 +188,12 @@ extern void show_status(bool all, const char *name);
* restriction is not checked in any way: violators will produce * restriction is not checked in any way: violators will produce
* confusing results (without crashing!). * confusing results (without crashing!).
*/ */
extern char diag_space[LOG_WIDTH]; /* output buffer, but can be occupied at call */ extern char diag_space[LOG_WIDTH]; /* output buffer, but can be occupied at call */
extern err_t builddiag(const char *fmt, ...) PRINTF_LIKE(1); extern err_t builddiag(const char *fmt, ...) PRINTF_LIKE(1);
#ifdef DEBUG #ifdef DEBUG
extern lset_t base_debugging; /* bits selecting what to report */ extern lset_t base_debugging; /* bits selecting what to report */
#define DBGP(cond) (cur_debugging & (cond)) #define DBGP(cond) (cur_debugging & (cond))
#define DBG(cond, action) { if (DBGP(cond)) { action ; } } #define DBG(cond, action) { if (DBGP(cond)) { action ; } }
@@ -204,7 +204,7 @@ extern void DBG_dump(const char *label, const void *p, size_t len);
#else /*!DEBUG*/ #else /*!DEBUG*/
#define DBG(cond, action) { } /* do nothing */ #define DBG(cond, action) { } /* do nothing */
#endif /*!DEBUG*/ #endif /*!DEBUG*/
+29 -29
View File
@@ -21,15 +21,15 @@
#include "md2.h" #include "md2.h"
#define HAVEMEMCOPY 1 /* use ISO C's memcpy and memset */ #define HAVEMEMCOPY 1 /* use ISO C's memcpy and memset */
static void MD2Transform PROTO_LIST static void MD2Transform PROTO_LIST
((unsigned char [16], unsigned char [16], const unsigned char [16])); ((unsigned char [16], unsigned char [16], const unsigned char [16]));
#ifdef HAVEMEMCOPY #ifdef HAVEMEMCOPY
#include <memory.h> #include <memory.h>
#define MD2_memcpy memcpy #define MD2_memcpy memcpy
#define MD2_memset memset #define MD2_memset memset
#else #else
#ifdef HAVEBCOPY #ifdef HAVEBCOPY
#define MD2_memcpy(_a,_b,_c) memcpy((_a), (_b),(_c)) #define MD2_memcpy(_a,_b,_c) memcpy((_a), (_b),(_c))
@@ -79,13 +79,13 @@ static const unsigned char *PADDING[] = {
(const unsigned char *)"\013\013\013\013\013\013\013\013\013\013\013", (const unsigned char *)"\013\013\013\013\013\013\013\013\013\013\013",
(const unsigned char *)"\014\014\014\014\014\014\014\014\014\014\014\014", (const unsigned char *)"\014\014\014\014\014\014\014\014\014\014\014\014",
(const unsigned char *) (const unsigned char *)
"\015\015\015\015\015\015\015\015\015\015\015\015\015", "\015\015\015\015\015\015\015\015\015\015\015\015\015",
(const unsigned char *) (const unsigned char *)
"\016\016\016\016\016\016\016\016\016\016\016\016\016\016", "\016\016\016\016\016\016\016\016\016\016\016\016\016\016",
(const unsigned char *) (const unsigned char *)
"\017\017\017\017\017\017\017\017\017\017\017\017\017\017\017", "\017\017\017\017\017\017\017\017\017\017\017\017\017\017\017",
(const unsigned char *) (const unsigned char *)
"\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020" "\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020"
}; };
/* MD2 initialization. Begins an MD2 operation, writing a new context. /* MD2 initialization. Begins an MD2 operation, writing a new context.
@@ -96,12 +96,12 @@ MD2_CTX *context; /* context */
context->count = 0; context->count = 0;
MD2_memset ((POINTER)context->state, 0, sizeof (context->state)); MD2_memset ((POINTER)context->state, 0, sizeof (context->state));
MD2_memset MD2_memset
((POINTER)context->checksum, 0, sizeof (context->checksum)); ((POINTER)context->checksum, 0, sizeof (context->checksum));
} }
/* MD2 block update operation. Continues an MD2 message-digest /* MD2 block update operation. Continues an MD2 message-digest
operation, processing another message block, and updating the operation, processing another message block, and updating the
context. context.
*/ */
void MD2Update (context, input, inputLen) void MD2Update (context, input, inputLen)
MD2_CTX *context; /* context */ MD2_CTX *context; /* context */
@@ -117,28 +117,28 @@ unsigned int inputLen; /* length of input block */
partLen = 16 - index; partLen = 16 - index;
/* Transform as many times as possible. /* Transform as many times as possible.
*/ */
if (inputLen >= partLen) { if (inputLen >= partLen) {
MD2_memcpy MD2_memcpy
((POINTER)&context->buffer[index], (CONST_POINTER)input, partLen); ((POINTER)&context->buffer[index], (CONST_POINTER)input, partLen);
MD2Transform (context->state, context->checksum, context->buffer); MD2Transform (context->state, context->checksum, context->buffer);
for (i = partLen; i + 15 < inputLen; i += 16) for (i = partLen; i + 15 < inputLen; i += 16)
MD2Transform (context->state, context->checksum, &input[i]); MD2Transform (context->state, context->checksum, &input[i]);
index = 0; index = 0;
} }
else else
i = 0; i = 0;
/* Buffer remaining input */ /* Buffer remaining input */
MD2_memcpy MD2_memcpy
((POINTER)&context->buffer[index], (CONST_POINTER)&input[i], ((POINTER)&context->buffer[index], (CONST_POINTER)&input[i],
inputLen-i); inputLen-i);
} }
/* MD2 finalization. Ends an MD2 message-digest operation, writing the /* MD2 finalization. Ends an MD2 message-digest operation, writing the
message digest and zeroizing the context. message digest and zeroizing the context.
*/ */
void MD2Final (digest, context) void MD2Final (digest, context)
@@ -165,7 +165,7 @@ MD2_CTX *context; /* context */
} }
/* MD2 basic transformation. Transforms state and updates checksum /* MD2 basic transformation. Transforms state and updates checksum
based on block. based on block.
*/ */
static void MD2Transform (state, checksum, block) static void MD2Transform (state, checksum, block)
unsigned char state[16]; unsigned char state[16];
@@ -180,15 +180,15 @@ const unsigned char block[16];
MD2_memcpy ((POINTER)x, (CONST_POINTER)state, 16); MD2_memcpy ((POINTER)x, (CONST_POINTER)state, 16);
MD2_memcpy ((POINTER)x+16, (CONST_POINTER)block, 16); MD2_memcpy ((POINTER)x+16, (CONST_POINTER)block, 16);
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
x[i+32] = state[i] ^ block[i]; x[i+32] = state[i] ^ block[i];
/* Encrypt block (18 rounds). /* Encrypt block (18 rounds).
*/ */
t = 0; t = 0;
for (i = 0; i < 18; i++) { for (i = 0; i < 18; i++) {
for (j = 0; j < 48; j++) for (j = 0; j < 48; j++)
t = x[j] ^= PI_SUBST[t]; t = x[j] ^= PI_SUBST[t];
t = (t + i) & 0xff; t = (t + i) & 0xff;
} }
/* Save new state */ /* Save new state */
@@ -198,7 +198,7 @@ const unsigned char block[16];
*/ */
t = checksum[15]; t = checksum[15];
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
t = checksum[i] ^= PI_SUBST[block[i] ^ t]; t = checksum[i] ^= PI_SUBST[block[i] ^ t];
/* Zeroize sensitive information. /* Zeroize sensitive information.
*/ */
@@ -217,7 +217,7 @@ unsigned int len;
unsigned int i; unsigned int i;
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
output[i] = input[i]; output[i] = input[i];
} }
/* Note: Replace "for loop" with standard memset if possible. /* Note: Replace "for loop" with standard memset if possible.
@@ -230,7 +230,7 @@ unsigned int len;
unsigned int i; unsigned int i;
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
((char *)output)[i] = (char)value; ((char *)output)[i] = (char)value;
} }
#endif #endif
#endif #endif
+3 -3
View File
@@ -4,9 +4,9 @@
*/ */
/* PROTOTYPES should be set to one if and only if the compiler supports /* PROTOTYPES should be set to one if and only if the compiler supports
function argument prototyping. function argument prototyping.
The following makes PROTOTYPES default to 0 if it has not already The following makes PROTOTYPES default to 0 if it has not already
been defined with C compiler flags. been defined with C compiler flags.
*/ */
#ifndef PROTOTYPES #ifndef PROTOTYPES
#define PROTOTYPES 1 #define PROTOTYPES 1
@@ -24,7 +24,7 @@ typedef unsigned long int UINT4;
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above. /* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
returns an empty list. returns an empty list.
*/ */
#if PROTOTYPES #if PROTOTYPES
+18 -18
View File
@@ -41,12 +41,12 @@ documentation and/or software.
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>
#include <sys/types.h> /* for u_int*_t */ #include <sys/types.h> /* for u_int*_t */
#include <endian.h> /* sets BYTE_ORDER, LITTLE_ENDIAN, and BIG_ENDIAN */ #include <endian.h> /* sets BYTE_ORDER, LITTLE_ENDIAN, and BIG_ENDIAN */
#include "md5.h" #include "md5.h"
#define HAVEMEMCOPY 1 /* use ISO C's memcpy and memset */ #define HAVEMEMCOPY 1 /* use ISO C's memcpy and memset */
/* Constants for MD5Transform routine. /* Constants for MD5Transform routine.
*/ */
@@ -84,8 +84,8 @@ static void Decode PROTO_LIST
#ifdef HAVEMEMCOPY #ifdef HAVEMEMCOPY
#include <memory.h> #include <memory.h>
#define MD5_memcpy memcpy #define MD5_memcpy memcpy
#define MD5_memset memset #define MD5_memset memset
#else #else
#ifdef HAVEBCOPY #ifdef HAVEBCOPY
#define MD5_memcpy(_a,_b,_c) memcpy((_a), (_b),(_c)) #define MD5_memcpy(_a,_b,_c) memcpy((_a), (_b),(_c))
@@ -167,23 +167,23 @@ UINT4 inputLen; /* length of input block */
/* Update number of bits */ /* Update number of bits */
if ((context->count[0] += (inputLen << 3)) < (inputLen << 3)) if ((context->count[0] += (inputLen << 3)) < (inputLen << 3))
context->count[1]++; context->count[1]++;
context->count[1] += (inputLen >> 29); context->count[1] += (inputLen >> 29);
partLen = 64 - index; partLen = 64 - index;
/* Transform as many times as possible. */ /* Transform as many times as possible. */
if (inputLen >= partLen) { if (inputLen >= partLen) {
MD5_memcpy((POINTER)&context->buffer[index], (CONSTPOINTER)input, partLen); MD5_memcpy((POINTER)&context->buffer[index], (CONSTPOINTER)input, partLen);
MD5Transform (context->state, context->buffer); MD5Transform (context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64) for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform (context->state, &input[i]); MD5Transform (context->state, &input[i]);
index = 0; index = 0;
} }
else else
i = 0; i = 0;
/* Buffer remaining input */ /* Buffer remaining input */
MD5_memcpy((POINTER)&context->buffer[index], (CONSTPOINTER)&input[i], inputLen-i); MD5_memcpy((POINTER)&context->buffer[index], (CONSTPOINTER)&input[i], inputLen-i);
@@ -211,14 +211,14 @@ MD5_CTX *context; /* context */
/* Append length (before padding) */ /* Append length (before padding) */
MD5Update (context, bits, 8); MD5Update (context, bits, 8);
if (digest != NULL) /* Bill Simpson's padding */ if (digest != NULL) /* Bill Simpson's padding */
{ {
/* store state in digest */ /* store state in digest */
Encode (digest, context->state, 16); Encode (digest, context->state, 16);
/* Zeroize sensitive information. /* Zeroize sensitive information.
*/ */
MD5_memset ((POINTER)context, 0, sizeof (*context)); MD5_memset ((POINTER)context, 0, sizeof (*context));
} }
} }
+3 -3
View File
@@ -4,9 +4,9 @@
*/ */
/* PROTOTYPES should be set to one if and only if the compiler supports /* PROTOTYPES should be set to one if and only if the compiler supports
function argument prototyping. function argument prototyping.
The following makes PROTOTYPES default to 0 if it has not already The following makes PROTOTYPES default to 0 if it has not already
been defined with C compiler flags. been defined with C compiler flags.
*/ */
#ifndef PROTOTYPES #ifndef PROTOTYPES
#define PROTOTYPES 1 #define PROTOTYPES 1
@@ -24,7 +24,7 @@ typedef u_int32_t UINT4;
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above. /* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
returns an empty list. returns an empty list.
*/ */
#if PROTOTYPES #if PROTOTYPES
+929 -929
View File
File diff suppressed because it is too large Load Diff
+24 -24
View File
@@ -27,29 +27,29 @@
chunk_t chunk_t
mpz_to_n(const MP_INT *mp, size_t bytes) mpz_to_n(const MP_INT *mp, size_t bytes)
{ {
chunk_t r; chunk_t r;
MP_INT temp1, temp2; MP_INT temp1, temp2;
int i; int i;
r.len = bytes; r.len = bytes;
r.ptr = malloc(r.len); r.ptr = malloc(r.len);
mpz_init(&temp1); mpz_init(&temp1);
mpz_init(&temp2); mpz_init(&temp2);
mpz_set(&temp1, mp); mpz_set(&temp1, mp);
for (i = r.len-1; i >= 0; i--) for (i = r.len-1; i >= 0; i--)
{ {
r.ptr[i] = mpz_mdivmod_ui(&temp2, NULL, &temp1, 1 << BITS_PER_BYTE); r.ptr[i] = mpz_mdivmod_ui(&temp2, NULL, &temp1, 1 << BITS_PER_BYTE);
mpz_set(&temp1, &temp2); mpz_set(&temp1, &temp2);
} }
passert(mpz_sgn(&temp1) == 0); /* we must have done all the bits */ passert(mpz_sgn(&temp1) == 0); /* we must have done all the bits */
mpz_clear(&temp1); mpz_clear(&temp1);
mpz_clear(&temp2); mpz_clear(&temp2);
return r; return r;
} }
/* Convert network form (binary bytes, big-endian) to MP_INT. /* Convert network form (binary bytes, big-endian) to MP_INT.
@@ -58,13 +58,13 @@ mpz_to_n(const MP_INT *mp, size_t bytes)
void void
n_to_mpz(MP_INT *mp, const u_char *nbytes, size_t nlen) n_to_mpz(MP_INT *mp, const u_char *nbytes, size_t nlen)
{ {
size_t i; size_t i;
mpz_init_set_ui(mp, 0); mpz_init_set_ui(mp, 0);
for (i = 0; i != nlen; i++) for (i = 0; i != nlen; i++)
{ {
mpz_mul_ui(mp, mp, 1 << BITS_PER_BYTE); mpz_mul_ui(mp, mp, 1 << BITS_PER_BYTE);
mpz_add_ui(mp, mp, nbytes[i]); mpz_add_ui(mp, mp, nbytes[i]);
} }
} }
+5 -5
View File
@@ -27,10 +27,10 @@ extern chunk_t mpz_to_n(const MP_INT *mp, size_t bytes);
/* var := mod(base ** exp, mod), ensuring var is mpz_inited */ /* var := mod(base ** exp, mod), ensuring var is mpz_inited */
#define mpz_init_powm(flag, var, base, exp, mod) { \ #define mpz_init_powm(flag, var, base, exp, mod) { \
if (!(flag)) \ if (!(flag)) \
mpz_init(&(var)); \ mpz_init(&(var)); \
(flag) = TRUE; \ (flag) = TRUE; \
mpz_powm(&(var), &(base), &(exp), (mod)); \ mpz_powm(&(var), &(base), &(exp), (mod)); \
} }
#endif /* _MP_DEFS_H */ #endif /* _MP_DEFS_H */
+608 -608
View File
File diff suppressed because it is too large Load Diff
+30 -30
View File
@@ -32,37 +32,37 @@
* NAT-Traversal methods which need NAT-D * NAT-Traversal methods which need NAT-D
*/ */
#define NAT_T_WITH_NATD \ #define NAT_T_WITH_NATD \
( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \ ( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
LELEM(NAT_TRAVERSAL_RFC) ) LELEM(NAT_TRAVERSAL_RFC) )
/** /**
* NAT-Traversal methods which need NAT-OA * NAT-Traversal methods which need NAT-OA
*/ */
#define NAT_T_WITH_NATOA \ #define NAT_T_WITH_NATOA \
( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \ ( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
LELEM(NAT_TRAVERSAL_RFC) ) LELEM(NAT_TRAVERSAL_RFC) )
/** /**
* NAT-Traversal methods which use NAT-KeepAlive * NAT-Traversal methods which use NAT-KeepAlive
*/ */
#define NAT_T_WITH_KA \ #define NAT_T_WITH_KA \
( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \ ( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
LELEM(NAT_TRAVERSAL_RFC) ) LELEM(NAT_TRAVERSAL_RFC) )
/** /**
* NAT-Traversal methods which use floating port * NAT-Traversal methods which use floating port
*/ */
#define NAT_T_WITH_PORT_FLOATING \ #define NAT_T_WITH_PORT_FLOATING \
( LELEM(NAT_TRAVERSAL_IETF_02_03) | LELEM(NAT_TRAVERSAL_RFC) ) ( LELEM(NAT_TRAVERSAL_IETF_02_03) | LELEM(NAT_TRAVERSAL_RFC) )
/** /**
* NAT-Traversal methods which use officials values (RFC) * NAT-Traversal methods which use officials values (RFC)
*/ */
#define NAT_T_WITH_RFC_VALUES \ #define NAT_T_WITH_RFC_VALUES \
( LELEM(NAT_TRAVERSAL_RFC) ) ( LELEM(NAT_TRAVERSAL_RFC) )
/** /**
* NAT-Traversal detected * NAT-Traversal detected
*/ */
#define NAT_T_DETECTED \ #define NAT_T_DETECTED \
( LELEM(NAT_TRAVERSAL_NAT_BHND_ME) | LELEM(NAT_TRAVERSAL_NAT_BHND_PEER) ) ( LELEM(NAT_TRAVERSAL_NAT_BHND_ME) | LELEM(NAT_TRAVERSAL_NAT_BHND_PEER) )
/** /**
* NAT-T Port Floating * NAT-T Port Floating
@@ -70,7 +70,7 @@
#define NAT_T_IKE_FLOAT_PORT 4500 #define NAT_T_IKE_FLOAT_PORT 4500
void init_nat_traversal (bool activate, unsigned int keep_alive_period, void init_nat_traversal (bool activate, unsigned int keep_alive_period,
bool fka, bool spf); bool fka, bool spf);
extern bool nat_traversal_enabled; extern bool nat_traversal_enabled;
extern bool nat_traversal_support_non_ike; extern bool nat_traversal_support_non_ike;
@@ -82,7 +82,7 @@ extern bool nat_traversal_support_port_floating;
void nat_traversal_natd_lookup(struct msg_digest *md); void nat_traversal_natd_lookup(struct msg_digest *md);
#ifndef PB_STREAM_UNDEFINED #ifndef PB_STREAM_UNDEFINED
bool nat_traversal_add_natd(u_int8_t np, pb_stream *outs, bool nat_traversal_add_natd(u_int8_t np, pb_stream *outs,
struct msg_digest *md); struct msg_digest *md);
#endif #endif
/** /**
@@ -91,7 +91,7 @@ bool nat_traversal_add_natd(u_int8_t np, pb_stream *outs,
void nat_traversal_natoa_lookup(struct msg_digest *md); void nat_traversal_natoa_lookup(struct msg_digest *md);
#ifndef PB_STREAM_UNDEFINED #ifndef PB_STREAM_UNDEFINED
bool nat_traversal_add_natoa(u_int8_t np, pb_stream *outs, bool nat_traversal_add_natoa(u_int8_t np, pb_stream *outs,
struct state *st); struct state *st);
#endif #endif
/** /**
@@ -119,8 +119,8 @@ void nat_traversal_change_port_lookup(struct msg_digest *md, struct state *st);
*/ */
#ifdef __PFKEY_V2_H #ifdef __PFKEY_V2_H
void process_pfkey_nat_t_new_mapping( void process_pfkey_nat_t_new_mapping(
struct sadb_msg *, struct sadb_msg *,
struct sadb_ext *[SADB_EXT_MAX + 1]); struct sadb_ext *[SADB_EXT_MAX + 1]);
#endif #endif
/** /**
@@ -133,22 +133,22 @@ nat_traversal_port_float(struct state *st, struct msg_digest *md, bool in);
* Encapsulation mode macro (see demux.c) * Encapsulation mode macro (see demux.c)
*/ */
#define NAT_T_ENCAPSULATION_MODE(st,nat_t_policy) ( \ #define NAT_T_ENCAPSULATION_MODE(st,nat_t_policy) ( \
((st)->nat_traversal & NAT_T_DETECTED) \ ((st)->nat_traversal & NAT_T_DETECTED) \
? ( ((nat_t_policy) & POLICY_TUNNEL) \ ? ( ((nat_t_policy) & POLICY_TUNNEL) \
? ( ((st)->nat_traversal & NAT_T_WITH_RFC_VALUES) \ ? ( ((st)->nat_traversal & NAT_T_WITH_RFC_VALUES) \
? (ENCAPSULATION_MODE_UDP_TUNNEL_RFC) \ ? (ENCAPSULATION_MODE_UDP_TUNNEL_RFC) \
: (ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS) \ : (ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS) \
) \ ) \
: ( ((st)->nat_traversal & NAT_T_WITH_RFC_VALUES) \ : ( ((st)->nat_traversal & NAT_T_WITH_RFC_VALUES) \
? (ENCAPSULATION_MODE_UDP_TRANSPORT_RFC) \ ? (ENCAPSULATION_MODE_UDP_TRANSPORT_RFC) \
: (ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS) \ : (ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS) \
) \ ) \
) \ ) \
: ( ((st)->st_policy & POLICY_TUNNEL) \ : ( ((st)->st_policy & POLICY_TUNNEL) \
? (ENCAPSULATION_MODE_TUNNEL) \ ? (ENCAPSULATION_MODE_TUNNEL) \
: (ENCAPSULATION_MODE_TRANSPORT) \ : (ENCAPSULATION_MODE_TRANSPORT) \
) \ ) \
) )
#endif /* _NAT_TRAVERSAL_H */ #endif /* _NAT_TRAVERSAL_H */
+982 -982
View File
File diff suppressed because it is too large Load Diff
+31 -31
View File
@@ -19,19 +19,19 @@
/* constants */ /* constants */
#define OCSP_BASIC_RESPONSE_VERSION 1 #define OCSP_BASIC_RESPONSE_VERSION 1
#define OCSP_DEFAULT_VALID_TIME 120 /* validity of one-time response in seconds */ #define OCSP_DEFAULT_VALID_TIME 120 /* validity of one-time response in seconds */
#define OCSP_WARNING_INTERVAL 2 /* days */ #define OCSP_WARNING_INTERVAL 2 /* days */
/* OCSP response status */ /* OCSP response status */
typedef enum { typedef enum {
STATUS_SUCCESSFUL = 0, STATUS_SUCCESSFUL = 0,
STATUS_MALFORMEDREQUEST = 1, STATUS_MALFORMEDREQUEST = 1,
STATUS_INTERNALERROR = 2, STATUS_INTERNALERROR = 2,
STATUS_TRYLATER = 3, STATUS_TRYLATER = 3,
STATUS_SIGREQUIRED = 5, STATUS_SIGREQUIRED = 5,
STATUS_UNAUTHORIZED= 6 STATUS_UNAUTHORIZED= 6
} response_status; } response_status;
/* OCSP access structures */ /* OCSP access structures */
@@ -39,46 +39,46 @@ typedef enum {
typedef struct ocsp_certinfo ocsp_certinfo_t; typedef struct ocsp_certinfo ocsp_certinfo_t;
struct ocsp_certinfo { struct ocsp_certinfo {
ocsp_certinfo_t *next; ocsp_certinfo_t *next;
int trials; int trials;
chunk_t serialNumber; chunk_t serialNumber;
cert_status_t status; cert_status_t status;
bool once; bool once;
crl_reason_t revocationReason; crl_reason_t revocationReason;
time_t revocationTime; time_t revocationTime;
time_t thisUpdate; time_t thisUpdate;
time_t nextUpdate; time_t nextUpdate;
}; };
typedef struct ocsp_location ocsp_location_t; typedef struct ocsp_location ocsp_location_t;
struct ocsp_location { struct ocsp_location {
ocsp_location_t *next; ocsp_location_t *next;
chunk_t issuer; chunk_t issuer;
chunk_t authNameID; chunk_t authNameID;
chunk_t authKeyID; chunk_t authKeyID;
chunk_t authKeySerialNumber; chunk_t authKeySerialNumber;
chunk_t uri; chunk_t uri;
chunk_t nonce; chunk_t nonce;
ocsp_certinfo_t *certinfo; ocsp_certinfo_t *certinfo;
}; };
extern ocsp_location_t* get_ocsp_location(const ocsp_location_t *loc extern ocsp_location_t* get_ocsp_location(const ocsp_location_t *loc
, ocsp_location_t *chain); , ocsp_location_t *chain);
extern ocsp_location_t* add_ocsp_location(const ocsp_location_t *loc extern ocsp_location_t* add_ocsp_location(const ocsp_location_t *loc
, ocsp_location_t **chain); , ocsp_location_t **chain);
extern void add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info extern void add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info
, ocsp_location_t **chain, bool request); , ocsp_location_t **chain, bool request);
extern void check_ocsp(void); extern void check_ocsp(void);
extern cert_status_t verify_by_ocsp(const x509cert_t *cert, time_t *until extern cert_status_t verify_by_ocsp(const x509cert_t *cert, time_t *until
, time_t *revocationTime, crl_reason_t *revocationReason); , time_t *revocationTime, crl_reason_t *revocationReason);
extern bool ocsp_set_request_cert(char* path); extern bool ocsp_set_request_cert(char* path);
extern void ocsp_set_default_uri(char* uri); extern void ocsp_set_default_uri(char* uri);
extern void ocsp_cache_add_cert(const x509cert_t* cert); extern void ocsp_cache_add_cert(const x509cert_t* cert);
extern chunk_t build_ocsp_request(ocsp_location_t* location); extern chunk_t build_ocsp_request(ocsp_location_t* location);
extern void parse_ocsp(ocsp_location_t* location, chunk_t blob); extern void parse_ocsp(ocsp_location_t* location, chunk_t blob);
extern void list_ocsp_locations(ocsp_location_t *location, bool requests extern void list_ocsp_locations(ocsp_location_t *location, bool requests
, bool utc, bool strict); , bool utc, bool strict);
extern void list_ocsp_cache(bool utc, bool strict); extern void list_ocsp_cache(bool utc, bool strict);
extern void free_ocsp_locations(ocsp_location_t **chain); extern void free_ocsp_locations(ocsp_location_t **chain);
extern void free_ocsp_cache(void); extern void free_ocsp_cache(void);
+639 -639
View File
File diff suppressed because it is too large Load Diff
+155 -155
View File
@@ -23,9 +23,9 @@
*/ */
typedef const struct struct_desc { typedef const struct struct_desc {
const char *name; const char *name;
const struct field_desc *fields; const struct field_desc *fields;
size_t size; size_t size;
} struct_desc; } struct_desc;
/* Note: if an ft_af_enum field has the ISAKMP_ATTR_AF_TV bit set, /* Note: if an ft_af_enum field has the ISAKMP_ATTR_AF_TV bit set,
@@ -35,24 +35,24 @@ typedef const struct struct_desc {
*/ */
enum field_type { enum field_type {
ft_mbz, /* must be zero */ ft_mbz, /* must be zero */
ft_nat, /* natural number (may be 0) */ ft_nat, /* natural number (may be 0) */
ft_len, /* length of this struct and any following crud */ ft_len, /* length of this struct and any following crud */
ft_lv, /* length/value field of attribute */ ft_lv, /* length/value field of attribute */
ft_enum, /* value from an enumeration */ ft_enum, /* value from an enumeration */
ft_loose_enum, /* value from an enumeration with only some names known */ ft_loose_enum, /* value from an enumeration with only some names known */
ft_af_loose_enum, /* Attribute Format + enumeration, some names known */ ft_af_loose_enum, /* Attribute Format + enumeration, some names known */
ft_af_enum, /* Attribute Format + value from an enumeration */ ft_af_enum, /* Attribute Format + value from an enumeration */
ft_set, /* bits representing set */ ft_set, /* bits representing set */
ft_raw, /* bytes to be left in network-order */ ft_raw, /* bytes to be left in network-order */
ft_end, /* end of field list */ ft_end, /* end of field list */
}; };
typedef const struct field_desc { typedef const struct field_desc {
enum field_type field_type; enum field_type field_type;
int size; /* size, in bytes, of field */ int size; /* size, in bytes, of field */
const char *name; const char *name;
const void *desc; /* enum_names for enum or char *[] for bits */ const void *desc; /* enum_names for enum or char *[] for bits */
} field_desc; } field_desc;
/* The formatting of input and output of packets is done /* The formatting of input and output of packets is done
@@ -62,18 +62,18 @@ typedef const struct field_desc {
* Actual packet transfer is done elsewhere. * Actual packet transfer is done elsewhere.
*/ */
typedef struct packet_byte_stream { typedef struct packet_byte_stream {
struct packet_byte_stream *container; /* PBS of which we are part */ struct packet_byte_stream *container; /* PBS of which we are part */
struct_desc *desc; struct_desc *desc;
const char *name; /* what does this PBS represent? */ const char *name; /* what does this PBS represent? */
u_int8_t u_int8_t
*start, *start,
*cur, /* current position in stream */ *cur, /* current position in stream */
*roof; /* byte after last in PBS (actually just a limit on output) */ *roof; /* byte after last in PBS (actually just a limit on output) */
/* For an output PBS, the length field will be filled in later so /* For an output PBS, the length field will be filled in later so
* we need to record its particulars. Note: it may not be aligned. * we need to record its particulars. Note: it may not be aligned.
*/ */
u_int8_t *lenfld; u_int8_t *lenfld;
field_desc *lenfld_desc; field_desc *lenfld_desc;
} pb_stream; } pb_stream;
/* For an input PBS, pbs_offset is amount of stream processed. /* For an input PBS, pbs_offset is amount of stream processed.
@@ -88,17 +88,17 @@ typedef struct packet_byte_stream {
extern void init_pbs(pb_stream *pbs, u_int8_t *start, size_t len, const char *name); extern void init_pbs(pb_stream *pbs, u_int8_t *start, size_t len, const char *name);
extern bool in_struct(void *struct_ptr, struct_desc *sd, extern bool in_struct(void *struct_ptr, struct_desc *sd,
pb_stream *ins, pb_stream *obj_pbs); pb_stream *ins, pb_stream *obj_pbs);
extern bool in_raw(void *bytes, size_t len, pb_stream *ins, const char *name); extern bool in_raw(void *bytes, size_t len, pb_stream *ins, const char *name);
extern bool out_struct(const void *struct_ptr, struct_desc *sd, extern bool out_struct(const void *struct_ptr, struct_desc *sd,
pb_stream *outs, pb_stream *obj_pbs); pb_stream *outs, pb_stream *obj_pbs);
extern bool out_generic(u_int8_t np, struct_desc *sd, extern bool out_generic(u_int8_t np, struct_desc *sd,
pb_stream *outs, pb_stream *obj_pbs); pb_stream *outs, pb_stream *obj_pbs);
extern bool out_generic_raw(u_int8_t np, struct_desc *sd, extern bool out_generic_raw(u_int8_t np, struct_desc *sd,
pb_stream *outs, const void *bytes, size_t len, const char *name); pb_stream *outs, const void *bytes, size_t len, const char *name);
#define out_generic_chunk(np, sd, outs, ch, name) \ #define out_generic_chunk(np, sd, outs, ch, name) \
out_generic_raw(np, sd, outs, (ch).ptr, (ch).len, name) out_generic_raw(np, sd, outs, (ch).ptr, (ch).len, name)
extern bool out_zero(size_t len, pb_stream *outs, const char *name); extern bool out_zero(size_t len, pb_stream *outs, const char *name);
extern bool out_raw(const void *bytes, size_t len, pb_stream *outs, const char *name); extern bool out_raw(const void *bytes, size_t len, pb_stream *outs, const char *name);
#define out_chunk(ch, outs, name) out_raw((ch).ptr, (ch).len, (outs), (name)) #define out_chunk(ch, outs, name) out_raw((ch).ptr, (ch).len, (outs), (name))
@@ -106,7 +106,7 @@ extern void close_output_pbs(pb_stream *pbs);
#ifdef DEBUG #ifdef DEBUG
extern void DBG_print_struct(const char *label, const void *struct_ptr, extern void DBG_print_struct(const char *label, const void *struct_ptr,
struct_desc *sd, bool len_meaningful); struct_desc *sd, bool len_meaningful);
#endif #endif
/* ISAKMP Header: for all messages /* ISAKMP Header: for all messages
@@ -160,16 +160,16 @@ extern void DBG_print_struct(const char *label, const void *struct_ptr,
struct isakmp_hdr struct isakmp_hdr
{ {
u_int8_t isa_icookie[COOKIE_SIZE]; u_int8_t isa_icookie[COOKIE_SIZE];
u_int8_t isa_rcookie[COOKIE_SIZE]; u_int8_t isa_rcookie[COOKIE_SIZE];
u_int8_t isa_np; /* Next payload */ u_int8_t isa_np; /* Next payload */
u_int8_t isa_version; /* high-order 4 bits: Major; low order 4: Minor */ u_int8_t isa_version; /* high-order 4 bits: Major; low order 4: Minor */
#define ISA_MAJ_SHIFT 4 #define ISA_MAJ_SHIFT 4
#define ISA_MIN_MASK (~((~0u) << ISA_MAJ_SHIFT)) #define ISA_MIN_MASK (~((~0u) << ISA_MAJ_SHIFT))
u_int8_t isa_xchg; /* Exchange type */ u_int8_t isa_xchg; /* Exchange type */
u_int8_t isa_flags; u_int8_t isa_flags;
u_int32_t isa_msgid; /* Message ID (RAW) */ u_int32_t isa_msgid; /* Message ID (RAW) */
u_int32_t isa_length; /* Length of message */ u_int32_t isa_length; /* Length of message */
}; };
extern struct_desc isakmp_hdr_desc; extern struct_desc isakmp_hdr_desc;
@@ -186,9 +186,9 @@ extern struct_desc isakmp_hdr_desc;
*/ */
struct isakmp_generic struct isakmp_generic
{ {
u_int8_t isag_np; u_int8_t isag_np;
u_int8_t isag_reserved; u_int8_t isag_reserved;
u_int16_t isag_length; u_int16_t isag_length;
}; };
extern struct_desc isakmp_generic_desc; extern struct_desc isakmp_generic_desc;
@@ -209,17 +209,17 @@ extern struct_desc isakmp_generic_desc;
*/ */
struct isakmp_attribute struct isakmp_attribute
{ {
/* The high order bit of isaat_af_type is the Attribute Format /* The high order bit of isaat_af_type is the Attribute Format
* If it is off, the format is TLV: lv is the length of the following * If it is off, the format is TLV: lv is the length of the following
* attribute value. * attribute value.
* If it is on, the format is TV: lv is the value of the attribute. * If it is on, the format is TV: lv is the value of the attribute.
* ISAKMP_ATTR_AF_MASK is the mask in host form. * ISAKMP_ATTR_AF_MASK is the mask in host form.
* *
* The low order 15 bits of isaat_af_type is the Attribute Type. * The low order 15 bits of isaat_af_type is the Attribute Type.
* ISAKMP_ATTR_RTYPE_MASK is the mask in host form. * ISAKMP_ATTR_RTYPE_MASK is the mask in host form.
*/ */
u_int16_t isaat_af_type; /* high order bit: AF; lower 15: rtype */ u_int16_t isaat_af_type; /* high order bit: AF; lower 15: rtype */
u_int16_t isaat_lv; /* Length or value */ u_int16_t isaat_lv; /* Length or value */
}; };
#define ISAKMP_ATTR_AF_MASK 0x8000 #define ISAKMP_ATTR_AF_MASK 0x8000
@@ -229,8 +229,8 @@ struct isakmp_attribute
#define ISAKMP_ATTR_RTYPE_MASK 0x7FFF #define ISAKMP_ATTR_RTYPE_MASK 0x7FFF
extern struct_desc extern struct_desc
isakmp_oakley_attribute_desc, isakmp_oakley_attribute_desc,
isakmp_ipsec_attribute_desc; isakmp_ipsec_attribute_desc;
/* ISAKMP Security Association Payload /* ISAKMP Security Association Payload
* layout from RFC 2408 "ISAKMP" section 3.4 * layout from RFC 2408 "ISAKMP" section 3.4
@@ -250,10 +250,10 @@ extern struct_desc
*/ */
struct isakmp_sa struct isakmp_sa
{ {
u_int8_t isasa_np; /* Next payload */ u_int8_t isasa_np; /* Next payload */
u_int8_t isasa_reserved; u_int8_t isasa_reserved;
u_int16_t isasa_length; /* Payload length */ u_int16_t isasa_length; /* Payload length */
u_int32_t isasa_doi; /* DOI */ u_int32_t isasa_doi; /* DOI */
}; };
extern struct_desc isakmp_sa_desc; extern struct_desc isakmp_sa_desc;
@@ -276,13 +276,13 @@ extern struct_desc ipsec_sit_desc;
*/ */
struct isakmp_proposal struct isakmp_proposal
{ {
u_int8_t isap_np; u_int8_t isap_np;
u_int8_t isap_reserved; u_int8_t isap_reserved;
u_int16_t isap_length; u_int16_t isap_length;
u_int8_t isap_proposal; u_int8_t isap_proposal;
u_int8_t isap_protoid; u_int8_t isap_protoid;
u_int8_t isap_spisize; u_int8_t isap_spisize;
u_int8_t isap_notrans; /* Number of transforms */ u_int8_t isap_notrans; /* Number of transforms */
}; };
extern struct_desc isakmp_proposal_desc; extern struct_desc isakmp_proposal_desc;
@@ -305,19 +305,19 @@ extern struct_desc isakmp_proposal_desc;
*/ */
struct isakmp_transform struct isakmp_transform
{ {
u_int8_t isat_np; u_int8_t isat_np;
u_int8_t isat_reserved; u_int8_t isat_reserved;
u_int16_t isat_length; u_int16_t isat_length;
u_int8_t isat_transnum; /* Number of the transform */ u_int8_t isat_transnum; /* Number of the transform */
u_int8_t isat_transid; u_int8_t isat_transid;
u_int16_t isat_reserved2; u_int16_t isat_reserved2;
}; };
extern struct_desc extern struct_desc
isakmp_isakmp_transform_desc, isakmp_isakmp_transform_desc,
isakmp_ah_transform_desc, isakmp_ah_transform_desc,
isakmp_esp_transform_desc, isakmp_esp_transform_desc,
isakmp_ipcomp_transform_desc; isakmp_ipcomp_transform_desc;
/* ISAKMP Key Exchange Payload: no fixed fields beyond the generic ones. /* ISAKMP Key Exchange Payload: no fixed fields beyond the generic ones.
* layout from RFC 2408 "ISAKMP" section 3.7 * layout from RFC 2408 "ISAKMP" section 3.7
@@ -354,12 +354,12 @@ extern struct_desc isakmp_keyex_desc;
*/ */
struct isakmp_id struct isakmp_id
{ {
u_int8_t isaid_np; u_int8_t isaid_np;
u_int8_t isaid_reserved; u_int8_t isaid_reserved;
u_int16_t isaid_length; u_int16_t isaid_length;
u_int8_t isaid_idtype; u_int8_t isaid_idtype;
u_int8_t isaid_doi_specific_a; u_int8_t isaid_doi_specific_a;
u_int16_t isaid_doi_specific_b; u_int16_t isaid_doi_specific_b;
}; };
extern struct_desc isakmp_identification_desc; extern struct_desc isakmp_identification_desc;
@@ -381,12 +381,12 @@ extern struct_desc isakmp_identification_desc;
*/ */
struct isakmp_ipsec_id struct isakmp_ipsec_id
{ {
u_int8_t isaiid_np; u_int8_t isaiid_np;
u_int8_t isaiid_reserved; u_int8_t isaiid_reserved;
u_int16_t isaiid_length; u_int16_t isaiid_length;
u_int8_t isaiid_idtype; u_int8_t isaiid_idtype;
u_int8_t isaiid_protoid; u_int8_t isaiid_protoid;
u_int16_t isaiid_port; u_int16_t isaiid_port;
}; };
extern struct_desc isakmp_ipsec_identification_desc; extern struct_desc isakmp_ipsec_identification_desc;
@@ -408,17 +408,17 @@ extern struct_desc isakmp_ipsec_identification_desc;
*/ */
struct isakmp_cert struct isakmp_cert
{ {
u_int8_t isacert_np; u_int8_t isacert_np;
u_int8_t isacert_reserved; u_int8_t isacert_reserved;
u_int16_t isacert_length; u_int16_t isacert_length;
u_int8_t isacert_type; u_int8_t isacert_type;
}; };
/* NOTE: this packet type has a fixed portion that is not a /* NOTE: this packet type has a fixed portion that is not a
* multiple of 4 octets. This means that sizeof(struct isakmp_cert) * multiple of 4 octets. This means that sizeof(struct isakmp_cert)
* yields the wrong value for the length. * yields the wrong value for the length.
*/ */
#define ISAKMP_CERT_SIZE 5 #define ISAKMP_CERT_SIZE 5
extern struct_desc isakmp_ipsec_certificate_desc; extern struct_desc isakmp_ipsec_certificate_desc;
@@ -439,17 +439,17 @@ extern struct_desc isakmp_ipsec_certificate_desc;
*/ */
struct isakmp_cr struct isakmp_cr
{ {
u_int8_t isacr_np; u_int8_t isacr_np;
u_int8_t isacr_reserved; u_int8_t isacr_reserved;
u_int16_t isacr_length; u_int16_t isacr_length;
u_int8_t isacr_type; u_int8_t isacr_type;
}; };
/* NOTE: this packet type has a fixed portion that is not a /* NOTE: this packet type has a fixed portion that is not a
* multiple of 4 octets. This means that sizeof(struct isakmp_cr) * multiple of 4 octets. This means that sizeof(struct isakmp_cr)
* yields the wrong value for the length. * yields the wrong value for the length.
*/ */
#define ISAKMP_CR_SIZE 5 #define ISAKMP_CR_SIZE 5
extern struct_desc isakmp_ipsec_cert_req_desc; extern struct_desc isakmp_ipsec_cert_req_desc;
@@ -526,13 +526,13 @@ extern struct_desc isakmp_nonce_desc;
*/ */
struct isakmp_notification struct isakmp_notification
{ {
u_int8_t isan_np; u_int8_t isan_np;
u_int8_t isan_reserved; u_int8_t isan_reserved;
u_int16_t isan_length; u_int16_t isan_length;
u_int32_t isan_doi; u_int32_t isan_doi;
u_int8_t isan_protoid; u_int8_t isan_protoid;
u_int8_t isan_spisize; u_int8_t isan_spisize;
u_int16_t isan_type; u_int16_t isan_type;
}; };
extern struct_desc isakmp_notification_desc; extern struct_desc isakmp_notification_desc;
@@ -557,40 +557,40 @@ extern struct_desc isakmp_notification_desc;
*/ */
struct isakmp_delete struct isakmp_delete
{ {
u_int8_t isad_np; u_int8_t isad_np;
u_int8_t isad_reserved; u_int8_t isad_reserved;
u_int16_t isad_length; u_int16_t isad_length;
u_int32_t isad_doi; u_int32_t isad_doi;
u_int8_t isad_protoid; u_int8_t isad_protoid;
u_int8_t isad_spisize; u_int8_t isad_spisize;
u_int16_t isad_nospi; u_int16_t isad_nospi;
}; };
extern struct_desc isakmp_delete_desc; extern struct_desc isakmp_delete_desc;
/* From draft-dukes-ike-mode-cfg /* From draft-dukes-ike-mode-cfg
3.2. Attribute Payload 3.2. Attribute Payload
1 2 3 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! Next Payload ! RESERVED ! Payload Length ! ! Next Payload ! RESERVED ! Payload Length !
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! Type ! RESERVED ! Identifier ! ! Type ! RESERVED ! Identifier !
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! ! ! !
! ! ! !
~ Attributes ~ ~ Attributes ~
! ! ! !
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/ */
struct isakmp_mode_attr struct isakmp_mode_attr
{ {
u_int8_t isama_np; u_int8_t isama_np;
u_int8_t isama_reserved; u_int8_t isama_reserved;
u_int16_t isama_length; u_int16_t isama_length;
u_int8_t isama_type; u_int8_t isama_type;
u_int8_t isama_reserved2; u_int8_t isama_reserved2;
u_int16_t isama_identifier; u_int16_t isama_identifier;
}; };
extern struct_desc isakmp_attr_desc; extern struct_desc isakmp_attr_desc;
@@ -614,12 +614,12 @@ extern struct_desc isakmp_vendor_id_desc;
struct isakmp_nat_oa struct isakmp_nat_oa
{ {
u_int8_t isanoa_np; u_int8_t isanoa_np;
u_int8_t isanoa_reserved_1; u_int8_t isanoa_reserved_1;
u_int16_t isanoa_length; u_int16_t isanoa_length;
u_int8_t isanoa_idtype; u_int8_t isanoa_idtype;
u_int8_t isanoa_reserved_2; u_int8_t isanoa_reserved_2;
u_int16_t isanoa_reserved_3; u_int16_t isanoa_reserved_3;
}; };
extern struct_desc isakmp_nat_d; extern struct_desc isakmp_nat_d;
@@ -628,18 +628,18 @@ extern struct_desc isakmp_nat_oa;
/* union of all payloads */ /* union of all payloads */
union payload { union payload {
struct isakmp_generic generic; struct isakmp_generic generic;
struct isakmp_sa sa; struct isakmp_sa sa;
struct isakmp_proposal proposal; struct isakmp_proposal proposal;
struct isakmp_transform transform; struct isakmp_transform transform;
struct isakmp_id id; /* Main Mode */ struct isakmp_id id; /* Main Mode */
struct isakmp_cert cert; struct isakmp_cert cert;
struct isakmp_cr cr; struct isakmp_cr cr;
struct isakmp_ipsec_id ipsec_id; /* Quick Mode */ struct isakmp_ipsec_id ipsec_id; /* Quick Mode */
struct isakmp_notification notification; struct isakmp_notification notification;
struct isakmp_delete delete; struct isakmp_delete delete;
struct isakmp_nat_oa nat_oa; struct isakmp_nat_oa nat_oa;
struct isakmp_mode_attr attribute; struct isakmp_mode_attr attribute;
}; };
/* descriptor for each payload type /* descriptor for each payload type
+288 -288
View File
@@ -43,15 +43,15 @@
static bool static bool
present(const char* pattern, chunk_t* ch) present(const char* pattern, chunk_t* ch)
{ {
u_int pattern_len = strlen(pattern); u_int pattern_len = strlen(pattern);
if (ch->len >= pattern_len && strneq(ch->ptr, pattern, pattern_len)) if (ch->len >= pattern_len && strneq(ch->ptr, pattern, pattern_len))
{ {
ch->ptr += pattern_len; ch->ptr += pattern_len;
ch->len -= pattern_len; ch->len -= pattern_len;
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
} }
/* /*
@@ -60,7 +60,7 @@ present(const char* pattern, chunk_t* ch)
static bool static bool
match(const char *pattern, const chunk_t *ch) match(const char *pattern, const chunk_t *ch)
{ {
return ch->len == strlen(pattern) && strneq(pattern, ch->ptr, ch->len); return ch->len == strlen(pattern) && strneq(pattern, ch->ptr, ch->len);
} }
/* /*
@@ -69,31 +69,31 @@ match(const char *pattern, const chunk_t *ch)
static bool static bool
find_boundary(const char* tag, chunk_t *line) find_boundary(const char* tag, chunk_t *line)
{ {
chunk_t name = chunk_empty; chunk_t name = chunk_empty;
if (!present("-----", line)) if (!present("-----", line))
return FALSE; return FALSE;
if (!present(tag, line)) if (!present(tag, line))
return FALSE; return FALSE;
if (*line->ptr != ' ') if (*line->ptr != ' ')
return FALSE; return FALSE;
line->ptr++; line->len--; line->ptr++; line->len--;
/* extract name */ /* extract name */
name.ptr = line->ptr; name.ptr = line->ptr;
while (line->len > 0) while (line->len > 0)
{
if (present("-----", line))
{ {
DBG(DBG_PARSING, if (present("-----", line))
DBG_log(" -----%s %.*s-----", {
tag, (int)name.len, name.ptr); DBG(DBG_PARSING,
) DBG_log(" -----%s %.*s-----",
return TRUE; tag, (int)name.len, name.ptr);
)
return TRUE;
}
line->ptr++; line->len--; name.len++;
} }
line->ptr++; line->len--; name.len++; return FALSE;
}
return FALSE;
} }
/* /*
@@ -102,10 +102,10 @@ find_boundary(const char* tag, chunk_t *line)
static void static void
eat_whitespace(chunk_t *src) eat_whitespace(chunk_t *src)
{ {
while (src->len > 0 && (*src->ptr == ' ' || *src->ptr == '\t')) while (src->len > 0 && (*src->ptr == ' ' || *src->ptr == '\t'))
{ {
src->ptr++; src->len--; src->ptr++; src->len--;
} }
} }
/* /*
@@ -114,21 +114,21 @@ eat_whitespace(chunk_t *src)
static bool static bool
extract_token(chunk_t *token, char termination, chunk_t *src) extract_token(chunk_t *token, char termination, chunk_t *src)
{ {
u_char *eot = memchr(src->ptr, termination, src->len); u_char *eot = memchr(src->ptr, termination, src->len);
/* initialize empty token */ /* initialize empty token */
*token = chunk_empty; *token = chunk_empty;
if (eot == NULL) /* termination symbol not found */ if (eot == NULL) /* termination symbol not found */
return FALSE; return FALSE;
/* extract token */ /* extract token */
token->ptr = src->ptr; token->ptr = src->ptr;
token->len = (u_int)(eot - src->ptr); token->len = (u_int)(eot - src->ptr);
/* advance src pointer after termination symbol */ /* advance src pointer after termination symbol */
src->ptr = eot + 1; src->ptr = eot + 1;
src->len -= (token->len + 1); src->len -= (token->len + 1);
return TRUE; return TRUE;
} }
@@ -139,19 +139,19 @@ extract_token(chunk_t *token, char termination, chunk_t *src)
static bool static bool
extract_parameter(chunk_t *name, chunk_t *value, chunk_t *line) extract_parameter(chunk_t *name, chunk_t *value, chunk_t *line)
{ {
DBG(DBG_PARSING, DBG(DBG_PARSING,
DBG_log(" %.*s", (int)line->len, line->ptr); DBG_log(" %.*s", (int)line->len, line->ptr);
) )
/* extract name */ /* extract name */
if (!extract_token(name,':', line)) if (!extract_token(name,':', line))
return FALSE; return FALSE;
eat_whitespace(line); eat_whitespace(line);
/* extract value */ /* extract value */
*value = *line; *value = *line;
return TRUE; return TRUE;
} }
/* /*
@@ -160,21 +160,21 @@ extract_parameter(chunk_t *name, chunk_t *value, chunk_t *line)
static bool static bool
fetchline(chunk_t *src, chunk_t *line) fetchline(chunk_t *src, chunk_t *line)
{ {
if (src->len == 0) /* end of src reached */ if (src->len == 0) /* end of src reached */
return FALSE; return FALSE;
if (extract_token(line, '\n', src)) if (extract_token(line, '\n', src))
{ {
if (line->len > 0 && *(line->ptr + line->len -1) == '\r') if (line->len > 0 && *(line->ptr + line->len -1) == '\r')
line->len--; /* remove optional \r */ line->len--; /* remove optional \r */
} }
else /*last line ends without newline */ else /*last line ends without newline */
{ {
*line = *src; *line = *src;
src->ptr += src->len; src->ptr += src->len;
src->len = 0; src->len = 0;
} }
return TRUE; return TRUE;
} }
/* /*
@@ -183,55 +183,55 @@ fetchline(chunk_t *src, chunk_t *line)
static bool static bool
pem_decrypt_3des(chunk_t *blob, chunk_t *iv, const char *passphrase) pem_decrypt_3des(chunk_t *blob, chunk_t *iv, const char *passphrase)
{ {
MD5_CTX context; MD5_CTX context;
u_char digest[MD5_DIGEST_SIZE]; u_char digest[MD5_DIGEST_SIZE];
u_char des_iv[DES_CBC_BLOCK_SIZE]; u_char des_iv[DES_CBC_BLOCK_SIZE];
u_char key[24]; u_char key[24];
des_cblock *deskey = (des_cblock *)key; des_cblock *deskey = (des_cblock *)key;
des_key_schedule ks[3]; des_key_schedule ks[3];
u_char padding, *last_padding_pos, *first_padding_pos; u_char padding, *last_padding_pos, *first_padding_pos;
/* Convert passphrase to 3des key */ /* Convert passphrase to 3des key */
MD5Init(&context); MD5Init(&context);
MD5Update(&context, passphrase, strlen(passphrase)); MD5Update(&context, passphrase, strlen(passphrase));
MD5Update(&context, iv->ptr, iv->len); MD5Update(&context, iv->ptr, iv->len);
MD5Final(digest, &context); MD5Final(digest, &context);
memcpy(key, digest, MD5_DIGEST_SIZE); memcpy(key, digest, MD5_DIGEST_SIZE);
MD5Init(&context); MD5Init(&context);
MD5Update(&context, digest, MD5_DIGEST_SIZE); MD5Update(&context, digest, MD5_DIGEST_SIZE);
MD5Update(&context, passphrase, strlen(passphrase)); MD5Update(&context, passphrase, strlen(passphrase));
MD5Update(&context, iv->ptr, iv->len); MD5Update(&context, iv->ptr, iv->len);
MD5Final(digest, &context); MD5Final(digest, &context);
memcpy(key + MD5_DIGEST_SIZE, digest, 24 - MD5_DIGEST_SIZE); memcpy(key + MD5_DIGEST_SIZE, digest, 24 - MD5_DIGEST_SIZE);
(void) des_set_key(&deskey[0], ks[0]); (void) des_set_key(&deskey[0], ks[0]);
(void) des_set_key(&deskey[1], ks[1]); (void) des_set_key(&deskey[1], ks[1]);
(void) des_set_key(&deskey[2], ks[2]); (void) des_set_key(&deskey[2], ks[2]);
/* decrypt data block */ /* decrypt data block */
memcpy(des_iv, iv->ptr, DES_CBC_BLOCK_SIZE); memcpy(des_iv, iv->ptr, DES_CBC_BLOCK_SIZE);
des_ede3_cbc_encrypt((des_cblock *)blob->ptr, (des_cblock *)blob->ptr, des_ede3_cbc_encrypt((des_cblock *)blob->ptr, (des_cblock *)blob->ptr,
blob->len, ks[0], ks[1], ks[2], (des_cblock *)des_iv, FALSE); blob->len, ks[0], ks[1], ks[2], (des_cblock *)des_iv, FALSE);
/* determine amount of padding */ /* determine amount of padding */
last_padding_pos = blob->ptr + blob->len - 1; last_padding_pos = blob->ptr + blob->len - 1;
padding = *last_padding_pos; padding = *last_padding_pos;
first_padding_pos = (padding > blob->len)? first_padding_pos = (padding > blob->len)?
blob->ptr : last_padding_pos - padding; blob->ptr : last_padding_pos - padding;
/* check the padding pattern */ /* check the padding pattern */
while (--last_padding_pos > first_padding_pos) while (--last_padding_pos > first_padding_pos)
{ {
if (*last_padding_pos != padding) if (*last_padding_pos != padding)
return FALSE; return FALSE;
} }
/* remove padding */ /* remove padding */
blob->len -= padding; blob->len -= padding;
return TRUE; return TRUE;
} }
/* /*
@@ -241,74 +241,74 @@ pem_decrypt_3des(chunk_t *blob, chunk_t *iv, const char *passphrase)
static err_t static err_t
pem_decrypt(chunk_t *blob, chunk_t *iv, prompt_pass_t *pass, const char* label) pem_decrypt(chunk_t *blob, chunk_t *iv, prompt_pass_t *pass, const char* label)
{ {
DBG(DBG_CRYPT, DBG(DBG_CRYPT,
DBG_log(" decrypting file using 'DES-EDE3-CBC'"); DBG_log(" decrypting file using 'DES-EDE3-CBC'");
) )
if (iv->len != DES_CBC_BLOCK_SIZE) if (iv->len != DES_CBC_BLOCK_SIZE)
return "size of DES-EDE3-CBC IV is not 8 bytes"; return "size of DES-EDE3-CBC IV is not 8 bytes";
if (pass == NULL) if (pass == NULL)
return "no passphrase available"; return "no passphrase available";
/* do we prompt for the passphrase? */ /* do we prompt for the passphrase? */
if (pass->prompt && pass->fd != NULL_FD) if (pass->prompt && pass->fd != NULL_FD)
{
int i;
chunk_t blob_copy;
err_t ugh = "invalid passphrase, too many trials";
whack_log(RC_ENTERSECRET, "need passphrase for '%s'", label);
for (i = 0; i < MAX_PROMPT_PASS_TRIALS; i++)
{ {
int n; int i;
chunk_t blob_copy;
err_t ugh = "invalid passphrase, too many trials";
if (i > 0) whack_log(RC_ENTERSECRET, "need passphrase for '%s'", label);
whack_log(RC_ENTERSECRET, "invalid passphrase, please try again");
n = read(pass->fd, pass->secret, PROMPT_PASS_LEN); for (i = 0; i < MAX_PROMPT_PASS_TRIALS; i++)
{
int n;
if (n == -1) if (i > 0)
{ whack_log(RC_ENTERSECRET, "invalid passphrase, please try again");
err_t ugh = "read(whackfd) failed";
whack_log(RC_LOG_SERIOUS,ugh); n = read(pass->fd, pass->secret, PROMPT_PASS_LEN);
return ugh;
}
pass->secret[n-1] = '\0'; if (n == -1)
{
if (strlen(pass->secret) == 0) err_t ugh = "read(whackfd) failed";
{
err_t ugh = "no passphrase entered, aborted";
whack_log(RC_LOG_SERIOUS,ugh);
return ugh;
}
pass->secret[n-1] = '\0';
if (strlen(pass->secret) == 0)
{
err_t ugh = "no passphrase entered, aborted";
whack_log(RC_LOG_SERIOUS, ugh);
return ugh;
}
blob_copy = chunk_clone(*blob);
if (pem_decrypt_3des(blob, iv, pass->secret))
{
whack_log(RC_SUCCESS, "valid passphrase");
free(blob_copy.ptr);
return NULL;
}
/* blob is useless after wrong decryption, restore the original */
free(blob->ptr);
*blob = blob_copy;
}
whack_log(RC_LOG_SERIOUS, ugh); whack_log(RC_LOG_SERIOUS, ugh);
return ugh; return ugh;
}
blob_copy = chunk_clone(*blob);
if (pem_decrypt_3des(blob, iv, pass->secret))
{
whack_log(RC_SUCCESS, "valid passphrase");
free(blob_copy.ptr);
return NULL;
}
/* blob is useless after wrong decryption, restore the original */
free(blob->ptr);
*blob = blob_copy;
} }
whack_log(RC_LOG_SERIOUS, ugh);
return ugh;
}
else
{
if (pem_decrypt_3des(blob, iv, pass->secret))
return NULL;
else else
return "invalid passphrase"; {
} if (pem_decrypt_3des(blob, iv, pass->secret))
return NULL;
else
return "invalid passphrase";
}
} }
/* Converts a PEM encoded file into its binary form /* Converts a PEM encoded file into its binary form
@@ -319,144 +319,144 @@ pem_decrypt(chunk_t *blob, chunk_t *iv, prompt_pass_t *pass, const char* label)
err_t err_t
pemtobin(chunk_t *blob, prompt_pass_t *pass, const char* label, bool *pgp) pemtobin(chunk_t *blob, prompt_pass_t *pass, const char* label, bool *pgp)
{ {
typedef enum { typedef enum {
PEM_PRE = 0, PEM_PRE = 0,
PEM_MSG = 1, PEM_MSG = 1,
PEM_HEADER = 2, PEM_HEADER = 2,
PEM_BODY = 3, PEM_BODY = 3,
PEM_POST = 4, PEM_POST = 4,
PEM_ABORT = 5 PEM_ABORT = 5
} state_t; } state_t;
bool encrypted = FALSE; bool encrypted = FALSE;
state_t state = PEM_PRE; state_t state = PEM_PRE;
chunk_t src = *blob; chunk_t src = *blob;
chunk_t dst = *blob; chunk_t dst = *blob;
chunk_t line = chunk_empty; chunk_t line = chunk_empty;
chunk_t iv = chunk_empty; chunk_t iv = chunk_empty;
u_char iv_buf[MAX_DIGEST_LEN]; u_char iv_buf[MAX_DIGEST_LEN];
/* zero size of converted blob */ /* zero size of converted blob */
dst.len = 0; dst.len = 0;
/* zero size of IV */ /* zero size of IV */
iv.ptr = iv_buf; iv.ptr = iv_buf;
iv.len = 0; iv.len = 0;
while (fetchline(&src, &line)) while (fetchline(&src, &line))
{
if (state == PEM_PRE)
{ {
if (find_boundary("BEGIN", &line)) if (state == PEM_PRE)
{
*pgp = FALSE;
state = PEM_MSG;
}
continue;
}
else
{
if (find_boundary("END", &line))
{
state = PEM_POST;
break;
}
if (state == PEM_MSG)
{
state = (memchr(line.ptr, ':', line.len) == NULL)?
PEM_BODY : PEM_HEADER;
}
if (state == PEM_HEADER)
{
chunk_t name = chunk_empty;
chunk_t value = chunk_empty;
/* an empty line separates HEADER and BODY */
if (line.len == 0)
{ {
state = PEM_BODY; if (find_boundary("BEGIN", &line))
continue; {
} *pgp = FALSE;
state = PEM_MSG;
/* we are looking for a name: value pair */ }
if (!extract_parameter(&name, &value, &line)) continue;
continue;
if (match("Proc-Type", &name) && *value.ptr == '4')
encrypted = TRUE;
else if (match("DEK-Info", &name))
{
const char *ugh = NULL;
size_t len = 0;
chunk_t dek;
if (!extract_token(&dek, ',', &value))
dek = value;
/* we support DES-EDE3-CBC encrypted files, only */
if (!match("DES-EDE3-CBC", &dek))
return "we support DES-EDE3-CBC encrypted files, only";
eat_whitespace(&value);
ugh = ttodata(value.ptr, value.len, 16,
iv.ptr, MAX_DIGEST_LEN, &len);
if (ugh)
return "error in IV";
iv.len = len;
}
}
else /* state is PEM_BODY */
{
const char *ugh = NULL;
size_t len = 0;
chunk_t data;
/* remove any trailing whitespace */
if (!extract_token(&data ,' ', &line))
data = line;
/* check for PGP armor checksum */
if (*data.ptr == '=')
{
*pgp = TRUE;
data.ptr++;
data.len--;
DBG(DBG_PARSING,
DBG_log(" Armor checksum: %.*s", (int)data.len, data.ptr);
)
continue;
}
ugh = ttodata(data.ptr, data.len, 64,
dst.ptr, blob->len - dst.len, &len);
if (ugh)
{
DBG(DBG_PARSING,
DBG_log(" %s", ugh);
)
state = PEM_ABORT;
break;
} }
else else
{ {
dst.ptr += len; if (find_boundary("END", &line))
dst.len += len; {
state = PEM_POST;
break;
}
if (state == PEM_MSG)
{
state = (memchr(line.ptr, ':', line.len) == NULL)?
PEM_BODY : PEM_HEADER;
}
if (state == PEM_HEADER)
{
chunk_t name = chunk_empty;
chunk_t value = chunk_empty;
/* an empty line separates HEADER and BODY */
if (line.len == 0)
{
state = PEM_BODY;
continue;
}
/* we are looking for a name: value pair */
if (!extract_parameter(&name, &value, &line))
continue;
if (match("Proc-Type", &name) && *value.ptr == '4')
encrypted = TRUE;
else if (match("DEK-Info", &name))
{
const char *ugh = NULL;
size_t len = 0;
chunk_t dek;
if (!extract_token(&dek, ',', &value))
dek = value;
/* we support DES-EDE3-CBC encrypted files, only */
if (!match("DES-EDE3-CBC", &dek))
return "we support DES-EDE3-CBC encrypted files, only";
eat_whitespace(&value);
ugh = ttodata(value.ptr, value.len, 16,
iv.ptr, MAX_DIGEST_LEN, &len);
if (ugh)
return "error in IV";
iv.len = len;
}
}
else /* state is PEM_BODY */
{
const char *ugh = NULL;
size_t len = 0;
chunk_t data;
/* remove any trailing whitespace */
if (!extract_token(&data ,' ', &line))
data = line;
/* check for PGP armor checksum */
if (*data.ptr == '=')
{
*pgp = TRUE;
data.ptr++;
data.len--;
DBG(DBG_PARSING,
DBG_log(" Armor checksum: %.*s", (int)data.len, data.ptr);
)
continue;
}
ugh = ttodata(data.ptr, data.len, 64,
dst.ptr, blob->len - dst.len, &len);
if (ugh)
{
DBG(DBG_PARSING,
DBG_log(" %s", ugh);
)
state = PEM_ABORT;
break;
}
else
{
dst.ptr += len;
dst.len += len;
}
}
} }
}
} }
} /* set length to size of binary blob */
/* set length to size of binary blob */ blob->len = dst.len;
blob->len = dst.len;
if (state != PEM_POST) if (state != PEM_POST)
return "file coded in unknown format, discarded"; return "file coded in unknown format, discarded";
if (encrypted) if (encrypted)
return pem_decrypt(blob, &iv, pass, label); return pem_decrypt(blob, &iv, pass, label);
else else
return NULL; return NULL;
} }
+1 -1
View File
@@ -15,4 +15,4 @@
*/ */
extern err_t pemtobin(chunk_t *blob, prompt_pass_t *pass, const char* label extern err_t pemtobin(chunk_t *blob, prompt_pass_t *pass, const char* label
, bool *pgp); , bool *pgp);
+422 -422
View File
File diff suppressed because it is too large Load Diff
+10 -10
View File
@@ -21,7 +21,7 @@
/* /*
* Length of PGP V3 fingerprint * Length of PGP V3 fingerprint
*/ */
#define PGP_FINGERPRINT_SIZE MD5_DIGEST_SIZE #define PGP_FINGERPRINT_SIZE MD5_DIGEST_SIZE
typedef char fingerprint_t[PGP_FINGERPRINT_SIZE]; typedef char fingerprint_t[PGP_FINGERPRINT_SIZE];
@@ -30,16 +30,16 @@ typedef char fingerprint_t[PGP_FINGERPRINT_SIZE];
typedef struct pgpcert pgpcert_t; typedef struct pgpcert pgpcert_t;
struct pgpcert { struct pgpcert {
pgpcert_t *next; pgpcert_t *next;
time_t installed; time_t installed;
int count; int count;
chunk_t certificate; chunk_t certificate;
time_t created; time_t created;
time_t until; time_t until;
enum pubkey_alg pubkeyAlg; enum pubkey_alg pubkeyAlg;
chunk_t modulus; chunk_t modulus;
chunk_t publicExponent; chunk_t publicExponent;
fingerprint_t fingerprint; fingerprint_t fingerprint;
}; };
extern const pgpcert_t empty_pgpcert; extern const pgpcert_t empty_pgpcert;
+428 -428
View File
File diff suppressed because it is too large Load Diff
+23 -23
View File
@@ -27,39 +27,39 @@ typedef struct RSA_public_key RSA_public_key_t;
struct RSA_public_key struct RSA_public_key
{ {
char keyid[KEYID_BUF]; /* see ipsec_keyblobtoid(3) */ char keyid[KEYID_BUF]; /* see ipsec_keyblobtoid(3) */
/* length of modulus n in octets: [RSA_MIN_OCTETS, RSA_MAX_OCTETS] */ /* length of modulus n in octets: [RSA_MIN_OCTETS, RSA_MAX_OCTETS] */
unsigned k; unsigned k;
/* public: */ /* public: */
MP_INT MP_INT
n, /* modulus: p * q */ n, /* modulus: p * q */
e; /* exponent: relatively prime to (p-1) * (q-1) [probably small] */ e; /* exponent: relatively prime to (p-1) * (q-1) [probably small] */
}; };
typedef struct RSA_private_key RSA_private_key_t; typedef struct RSA_private_key RSA_private_key_t;
struct RSA_private_key { struct RSA_private_key {
struct RSA_public_key pub; /* must be at start for RSA_show_public_key */ struct RSA_public_key pub; /* must be at start for RSA_show_public_key */
MP_INT MP_INT
d, /* private exponent: (e^-1) mod ((p-1) * (q-1)) */ d, /* private exponent: (e^-1) mod ((p-1) * (q-1)) */
/* help for Chinese Remainder Theorem speedup: */ /* help for Chinese Remainder Theorem speedup: */
p, /* first secret prime */ p, /* first secret prime */
q, /* second secret prime */ q, /* second secret prime */
dP, /* first factor's exponent: (e^-1) mod (p-1) == d mod (p-1) */ dP, /* first factor's exponent: (e^-1) mod (p-1) == d mod (p-1) */
dQ, /* second factor's exponent: (e^-1) mod (q-1) == d mod (q-1) */ dQ, /* second factor's exponent: (e^-1) mod (q-1) == d mod (q-1) */
qInv; /* (q^-1) mod p */ qInv; /* (q^-1) mod p */
}; };
struct fld { struct fld {
const char *name; const char *name;
size_t offset; size_t offset;
}; };
extern const struct fld RSA_private_field[]; extern const struct fld RSA_private_field[];
#define RSA_PRIVATE_FIELD_ELEMENTS 8 #define RSA_PRIVATE_FIELD_ELEMENTS 8
extern void init_RSA_public_key(RSA_public_key_t *rsa, chunk_t e, chunk_t n); extern void init_RSA_public_key(RSA_public_key_t *rsa, chunk_t e, chunk_t n);
extern bool pkcs1_parse_private_key(chunk_t blob, RSA_private_key_t *key); extern bool pkcs1_parse_private_key(chunk_t blob, RSA_private_key_t *key);
@@ -67,15 +67,15 @@ extern chunk_t pkcs1_build_private_key(const RSA_private_key_t *key);
extern chunk_t pkcs1_build_public_key(const RSA_public_key_t *rsa); extern chunk_t pkcs1_build_public_key(const RSA_public_key_t *rsa);
extern chunk_t pkcs1_build_publicKeyInfo(const RSA_public_key_t *rsa); extern chunk_t pkcs1_build_publicKeyInfo(const RSA_public_key_t *rsa);
extern chunk_t pkcs1_build_signature(chunk_t tbs, int hash_alg extern chunk_t pkcs1_build_signature(chunk_t tbs, int hash_alg
, const RSA_private_key_t *key, bool bit_string); , const RSA_private_key_t *key, bool bit_string);
extern bool compute_digest(chunk_t tbs, int alg, chunk_t *digest); extern bool compute_digest(chunk_t tbs, int alg, chunk_t *digest);
extern void sign_hash(const RSA_private_key_t *k, const u_char *hash_val extern void sign_hash(const RSA_private_key_t *k, const u_char *hash_val
, size_t hash_len, u_char *sig_val, size_t sig_len); , size_t hash_len, u_char *sig_val, size_t sig_len);
extern chunk_t RSA_encrypt(const RSA_public_key_t *key, chunk_t in); extern chunk_t RSA_encrypt(const RSA_public_key_t *key, chunk_t in);
extern bool RSA_decrypt(const RSA_private_key_t *key, chunk_t in extern bool RSA_decrypt(const RSA_private_key_t *key, chunk_t in
, chunk_t *out); , chunk_t *out);
extern bool same_RSA_public_key(const RSA_public_key_t *a extern bool same_RSA_public_key(const RSA_public_key_t *a
, const RSA_public_key_t *b); , const RSA_public_key_t *b);
extern void form_keyid(chunk_t e, chunk_t n, char* keyid, unsigned *keysize); extern void form_keyid(chunk_t e, chunk_t n, char* keyid, unsigned *keysize);
extern err_t RSA_private_key_sanity(RSA_private_key_t *k); extern err_t RSA_private_key_sanity(RSA_private_key_t *k);
#ifdef DEBUG #ifdef DEBUG
+611 -611
View File
File diff suppressed because it is too large Load Diff
+7 -7
View File
@@ -28,24 +28,24 @@
typedef struct contentInfo contentInfo_t; typedef struct contentInfo contentInfo_t;
struct contentInfo { struct contentInfo {
int type; int type;
chunk_t content; chunk_t content;
}; };
extern const contentInfo_t empty_contentInfo; extern const contentInfo_t empty_contentInfo;
extern bool pkcs7_parse_contentInfo(chunk_t blob, u_int level0 extern bool pkcs7_parse_contentInfo(chunk_t blob, u_int level0
, contentInfo_t *cInfo); , contentInfo_t *cInfo);
extern bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data extern bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data
, x509cert_t **cert, chunk_t *attributes, const x509cert_t *cacert); , x509cert_t **cert, chunk_t *attributes, const x509cert_t *cacert);
extern bool pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data extern bool pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data
, chunk_t serialNumber, const RSA_private_key_t *key); , chunk_t serialNumber, const RSA_private_key_t *key);
extern chunk_t pkcs7_contentType_attribute(void); extern chunk_t pkcs7_contentType_attribute(void);
extern chunk_t pkcs7_messageDigest_attribute(chunk_t content, int digest_alg); extern chunk_t pkcs7_messageDigest_attribute(chunk_t content, int digest_alg);
extern chunk_t pkcs7_build_issuerAndSerialNumber(const x509cert_t *cert); extern chunk_t pkcs7_build_issuerAndSerialNumber(const x509cert_t *cert);
extern chunk_t pkcs7_build_signedData(chunk_t data, chunk_t attributes extern chunk_t pkcs7_build_signedData(chunk_t data, chunk_t attributes
,const x509cert_t *cert, int digest_alg, const RSA_private_key_t *key); ,const x509cert_t *cert, int digest_alg, const RSA_private_key_t *key);
extern chunk_t pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert extern chunk_t pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert
, int cipher); , int cipher);
#endif /* _PKCS7_H */ #endif /* _PKCS7_H */
+570 -570
View File
File diff suppressed because it is too large Load Diff
+441 -441
View File
@@ -1,5 +1,5 @@
/* primegen.c - prime number generator /* primegen.c - prime number generator
* Copyright (C) 1998 Free Software Foundation, Inc. * Copyright (C) 1998 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@@ -44,7 +44,7 @@
#endif /* !PLUTO */ #endif /* !PLUTO */
static int no_of_small_prime_numbers; static int no_of_small_prime_numbers;
static MPI gen_prime( unsigned nbits, int mode, int randomlevel ); static MPI gen_prime( unsigned nbits, int mode, int randomlevel );
static int check_prime( MPI prime, MPI val_2 ); static int check_prime( MPI prime, MPI val_2 );
static int is_prime( MPI n, unsigned steps, int *count ); static int is_prime( MPI n, unsigned steps, int *count );
static void m_out_of_n( char *array, int m, int n ); static void m_out_of_n( char *array, int m, int n );
@@ -53,7 +53,7 @@ static void m_out_of_n( char *array, int m, int n );
static void static void
progress( int c ) progress( int c )
{ {
fputc( c, stderr ); fputc( c, stderr );
} }
@@ -63,21 +63,21 @@ progress( int c )
MPI MPI
generate_secret_prime( unsigned nbits ) generate_secret_prime( unsigned nbits )
{ {
MPI prime; MPI prime;
prime = gen_prime( nbits, 1, 2 ); prime = gen_prime( nbits, 1, 2 );
progress('\n'); progress('\n');
return prime; return prime;
} }
MPI MPI
generate_public_prime( unsigned nbits ) generate_public_prime( unsigned nbits )
{ {
MPI prime; MPI prime;
prime = gen_prime( nbits, 0, 2 ); prime = gen_prime( nbits, 0, 2 );
progress('\n'); progress('\n');
return prime; return prime;
} }
@@ -88,220 +88,220 @@ generate_public_prime( unsigned nbits )
* indeed a strong prime. * indeed a strong prime.
* *
* mode 0: Standard * mode 0: Standard
* 1: Make sure that at least one factor is of size qbits. * 1: Make sure that at least one factor is of size qbits.
*/ */
MPI MPI
generate_elg_prime( int mode, unsigned pbits, unsigned qbits, generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
MPI g, MPI **ret_factors ) MPI g, MPI **ret_factors )
{ {
int n; /* number of factors */ int n; /* number of factors */
int m; /* number of primes in pool */ int m; /* number of primes in pool */
unsigned fbits; /* length of prime factors */ unsigned fbits; /* length of prime factors */
MPI *factors; /* current factors */ MPI *factors; /* current factors */
MPI *pool; /* pool of primes */ MPI *pool; /* pool of primes */
MPI q; /* first prime factor (variable)*/ MPI q; /* first prime factor (variable)*/
MPI prime; /* prime test value */ MPI prime; /* prime test value */
MPI q_factor; /* used for mode 1 */ MPI q_factor; /* used for mode 1 */
byte *perms = NULL; byte *perms = NULL;
int i, j; int i, j;
int count1, count2; int count1, count2;
unsigned nprime; unsigned nprime;
unsigned req_qbits = qbits; /* the requested q bits size */ unsigned req_qbits = qbits; /* the requested q bits size */
MPI val_2 = mpi_alloc_set_ui( 2 ); MPI val_2 = mpi_alloc_set_ui( 2 );
/* find number of needed prime factors */ /* find number of needed prime factors */
for(n=1; (pbits - qbits - 1) / n >= qbits; n++ ) for(n=1; (pbits - qbits - 1) / n >= qbits; n++ )
; ;
n--;
if( !n || (mode==1 && n < 2) )
log_fatal("can't gen prime with pbits=%u qbits=%u\n", pbits, qbits );
if( mode == 1 ) {
n--; n--;
fbits = (pbits - 2*req_qbits -1) / n; if( !n || (mode==1 && n < 2) )
qbits = pbits - req_qbits - n*fbits; log_fatal("can't gen prime with pbits=%u qbits=%u\n", pbits, qbits );
}
else {
fbits = (pbits - req_qbits -1) / n;
qbits = pbits - n*fbits;
}
if( DBG_CIPHER )
log_debug("gen prime: pbits=%u qbits=%u fbits=%u/%u n=%d\n",
pbits, req_qbits, qbits, fbits, n );
prime = mpi_alloc( (pbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB );
q = gen_prime( qbits, 0, 1 );
q_factor = mode==1? gen_prime( req_qbits, 0, 1 ) : NULL;
/* allocate an array to hold the factors + 2 for later usage */
#ifdef PLUTO
m_alloc_ptrs_clear(factors, n+2);
#else
factors = m_alloc_clear( (n+2) * sizeof *factors );
#endif
/* make a pool of 3n+5 primes (this is an arbitrary value) */
m = n*3+5;
if( mode == 1 )
m += 5; /* need some more for DSA */
if( m < 25 )
m = 25;
#ifdef PLUTO
m_alloc_ptrs_clear(pool, m);
#else
pool = m_alloc_clear( m * sizeof *pool );
#endif
/* permutate over the pool of primes */
count1=count2=0;
do {
next_try:
if( !perms ) {
/* allocate new primes */
for(i=0; i < m; i++ ) {
mpi_free(pool[i]);
pool[i] = NULL;
}
/* init m_out_of_n() */
#ifdef PLUTO
perms = malloc(m);
#else
perms = m_alloc_clear( m );
#endif
for(i=0; i < n; i++ ) {
perms[i] = 1;
pool[i] = gen_prime( fbits, 0, 1 );
factors[i] = pool[i];
}
}
else {
m_out_of_n( perms, n, m );
for(i=j=0; i < m && j < n ; i++ )
if( perms[i] ) {
if( !pool[i] )
pool[i] = gen_prime( fbits, 0, 1 );
factors[j++] = pool[i];
}
if( i == n ) {
m_free(perms); perms = NULL;
progress('!');
goto next_try; /* allocate new primes */
}
}
mpi_set( prime, q );
mpi_mul_ui( prime, prime, 2 );
if( mode == 1 )
mpi_mul( prime, prime, q_factor );
for(i=0; i < n; i++ )
mpi_mul( prime, prime, factors[i] );
mpi_add_ui( prime, prime, 1 );
nprime = mpi_get_nbits(prime);
if( nprime < pbits ) {
if( ++count1 > 20 ) {
count1 = 0;
qbits++;
progress('>');
q = gen_prime( qbits, 0, 1 );
goto next_try;
}
}
else
count1 = 0;
if( nprime > pbits ) {
if( ++count2 > 20 ) {
count2 = 0;
qbits--;
progress('<');
q = gen_prime( qbits, 0, 1 );
goto next_try;
}
}
else
count2 = 0;
} while( !(nprime == pbits && check_prime( prime, val_2 )) );
if( DBG_CIPHER ) {
progress('\n');
log_mpidump( "prime : ", prime );
log_mpidump( "factor q: ", q );
if( mode == 1 )
log_mpidump( "factor q0: ", q_factor );
for(i=0; i < n; i++ )
log_mpidump( "factor pi: ", factors[i] );
log_debug("bit sizes: prime=%u, q=%u", mpi_get_nbits(prime), mpi_get_nbits(q) );
if( mode == 1 )
fprintf(stderr, ", q0=%u", mpi_get_nbits(q_factor) );
for(i=0; i < n; i++ )
fprintf(stderr, ", p%d=%u", i, mpi_get_nbits(factors[i]) );
progress('\n');
}
if( ret_factors ) { /* caller wants the factors */
#ifdef PLUTO
m_alloc_ptrs_clear(*ret_factors, n+2);
#else
*ret_factors = m_alloc_clear( (n+2) * sizeof **ret_factors);
#endif
if( mode == 1 ) { if( mode == 1 ) {
i = 0; n--;
(*ret_factors)[i++] = mpi_copy( q_factor ); fbits = (pbits - 2*req_qbits -1) / n;
for(; i <= n; i++ ) qbits = pbits - req_qbits - n*fbits;
(*ret_factors)[i] = mpi_copy( factors[i] );
} }
else { else {
for(; i < n; i++ ) fbits = (pbits - req_qbits -1) / n;
(*ret_factors)[i] = mpi_copy( factors[i] ); qbits = pbits - n*fbits;
} }
} if( DBG_CIPHER )
log_debug("gen prime: pbits=%u qbits=%u fbits=%u/%u n=%d\n",
pbits, req_qbits, qbits, fbits, n );
prime = mpi_alloc( (pbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB );
q = gen_prime( qbits, 0, 1 );
q_factor = mode==1? gen_prime( req_qbits, 0, 1 ) : NULL;
if( g ) { /* create a generator (start with 3)*/ /* allocate an array to hold the factors + 2 for later usage */
MPI tmp = mpi_alloc( mpi_get_nlimbs(prime) );
MPI b = mpi_alloc( mpi_get_nlimbs(prime) );
MPI pmin1 = mpi_alloc( mpi_get_nlimbs(prime) );
if( mode == 1 )
BUG(); /* not yet implemented */
factors[n] = q;
factors[n+1] = mpi_alloc_set_ui(2);
mpi_sub_ui( pmin1, prime, 1 );
mpi_set_ui(g,2);
do {
mpi_add_ui(g, g, 1);
if( DBG_CIPHER ) {
#ifdef PLUTO #ifdef PLUTO
log_mpidump("checking g: ", g); m_alloc_ptrs_clear(factors, n+2);
#else #else
log_debug("checking g: "); factors = m_alloc_clear( (n+2) * sizeof *factors );
mpi_print( stderr, g, 1 );
#endif #endif
}
else
progress('^');
for(i=0; i < n+2; i++ ) {
/*fputc('~', stderr);*/
mpi_fdiv_q(tmp, pmin1, factors[i] );
/* (no mpi_pow(), but it is okay to use this with mod prime) */
mpi_powm(b, g, tmp, prime );
if( !mpi_cmp_ui(b, 1) )
break;
}
if( DBG_CIPHER )
progress('\n');
} while( i < n+2 );
mpi_free(factors[n+1]);
mpi_free(tmp);
mpi_free(b);
mpi_free(pmin1);
}
if( !DBG_CIPHER )
progress('\n');
m_free( factors ); /* (factors are shallow copies) */ /* make a pool of 3n+5 primes (this is an arbitrary value) */
for(i=0; i < m; i++ ) m = n*3+5;
mpi_free( pool[i] ); if( mode == 1 )
m_free( pool ); m += 5; /* need some more for DSA */
m_free(perms); if( m < 25 )
mpi_free(val_2); m = 25;
return prime; #ifdef PLUTO
m_alloc_ptrs_clear(pool, m);
#else
pool = m_alloc_clear( m * sizeof *pool );
#endif
/* permutate over the pool of primes */
count1=count2=0;
do {
next_try:
if( !perms ) {
/* allocate new primes */
for(i=0; i < m; i++ ) {
mpi_free(pool[i]);
pool[i] = NULL;
}
/* init m_out_of_n() */
#ifdef PLUTO
perms = malloc(m);
#else
perms = m_alloc_clear( m );
#endif
for(i=0; i < n; i++ ) {
perms[i] = 1;
pool[i] = gen_prime( fbits, 0, 1 );
factors[i] = pool[i];
}
}
else {
m_out_of_n( perms, n, m );
for(i=j=0; i < m && j < n ; i++ )
if( perms[i] ) {
if( !pool[i] )
pool[i] = gen_prime( fbits, 0, 1 );
factors[j++] = pool[i];
}
if( i == n ) {
m_free(perms); perms = NULL;
progress('!');
goto next_try; /* allocate new primes */
}
}
mpi_set( prime, q );
mpi_mul_ui( prime, prime, 2 );
if( mode == 1 )
mpi_mul( prime, prime, q_factor );
for(i=0; i < n; i++ )
mpi_mul( prime, prime, factors[i] );
mpi_add_ui( prime, prime, 1 );
nprime = mpi_get_nbits(prime);
if( nprime < pbits ) {
if( ++count1 > 20 ) {
count1 = 0;
qbits++;
progress('>');
q = gen_prime( qbits, 0, 1 );
goto next_try;
}
}
else
count1 = 0;
if( nprime > pbits ) {
if( ++count2 > 20 ) {
count2 = 0;
qbits--;
progress('<');
q = gen_prime( qbits, 0, 1 );
goto next_try;
}
}
else
count2 = 0;
} while( !(nprime == pbits && check_prime( prime, val_2 )) );
if( DBG_CIPHER ) {
progress('\n');
log_mpidump( "prime : ", prime );
log_mpidump( "factor q: ", q );
if( mode == 1 )
log_mpidump( "factor q0: ", q_factor );
for(i=0; i < n; i++ )
log_mpidump( "factor pi: ", factors[i] );
log_debug("bit sizes: prime=%u, q=%u", mpi_get_nbits(prime), mpi_get_nbits(q) );
if( mode == 1 )
fprintf(stderr, ", q0=%u", mpi_get_nbits(q_factor) );
for(i=0; i < n; i++ )
fprintf(stderr, ", p%d=%u", i, mpi_get_nbits(factors[i]) );
progress('\n');
}
if( ret_factors ) { /* caller wants the factors */
#ifdef PLUTO
m_alloc_ptrs_clear(*ret_factors, n+2);
#else
*ret_factors = m_alloc_clear( (n+2) * sizeof **ret_factors);
#endif
if( mode == 1 ) {
i = 0;
(*ret_factors)[i++] = mpi_copy( q_factor );
for(; i <= n; i++ )
(*ret_factors)[i] = mpi_copy( factors[i] );
}
else {
for(; i < n; i++ )
(*ret_factors)[i] = mpi_copy( factors[i] );
}
}
if( g ) { /* create a generator (start with 3)*/
MPI tmp = mpi_alloc( mpi_get_nlimbs(prime) );
MPI b = mpi_alloc( mpi_get_nlimbs(prime) );
MPI pmin1 = mpi_alloc( mpi_get_nlimbs(prime) );
if( mode == 1 )
BUG(); /* not yet implemented */
factors[n] = q;
factors[n+1] = mpi_alloc_set_ui(2);
mpi_sub_ui( pmin1, prime, 1 );
mpi_set_ui(g,2);
do {
mpi_add_ui(g, g, 1);
if( DBG_CIPHER ) {
#ifdef PLUTO
log_mpidump("checking g: ", g);
#else
log_debug("checking g: ");
mpi_print( stderr, g, 1 );
#endif
}
else
progress('^');
for(i=0; i < n+2; i++ ) {
/*fputc('~', stderr);*/
mpi_fdiv_q(tmp, pmin1, factors[i] );
/* (no mpi_pow(), but it is okay to use this with mod prime) */
mpi_powm(b, g, tmp, prime );
if( !mpi_cmp_ui(b, 1) )
break;
}
if( DBG_CIPHER )
progress('\n');
} while( i < n+2 );
mpi_free(factors[n+1]);
mpi_free(tmp);
mpi_free(b);
mpi_free(pmin1);
}
if( !DBG_CIPHER )
progress('\n');
m_free( factors ); /* (factors are shallow copies) */
for(i=0; i < m; i++ )
mpi_free( pool[i] );
m_free( pool );
m_free(perms);
mpi_free(val_2);
return prime;
} }
@@ -309,91 +309,91 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
static MPI static MPI
gen_prime( unsigned nbits, int secret, int randomlevel ) gen_prime( unsigned nbits, int secret, int randomlevel )
{ {
unsigned nlimbs; unsigned nlimbs;
MPI prime, ptest, pminus1, val_2, val_3, result; MPI prime, ptest, pminus1, val_2, val_3, result;
int i; int i;
unsigned x, step; unsigned x, step;
unsigned count1, count2; unsigned count1, count2;
int *mods; int *mods;
if( 0 && DBG_CIPHER ) if( 0 && DBG_CIPHER )
log_debug("generate a prime of %u bits ", nbits ); log_debug("generate a prime of %u bits ", nbits );
if( !no_of_small_prime_numbers ) { if( !no_of_small_prime_numbers ) {
for(i=0; small_prime_numbers[i]; i++ ) for(i=0; small_prime_numbers[i]; i++ )
no_of_small_prime_numbers++; no_of_small_prime_numbers++;
}
mods = m_alloc( no_of_small_prime_numbers * sizeof *mods );
/* make nbits fit into MPI implementation */
nlimbs = (nbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB;
val_2 = mpi_alloc_set_ui( 2 );
val_3 = mpi_alloc_set_ui( 3);
prime = secret? mpi_alloc_secure( nlimbs ): mpi_alloc( nlimbs );
result = mpi_alloc_like( prime );
pminus1= mpi_alloc_like( prime );
ptest = mpi_alloc_like( prime );
count1 = count2 = 0;
for(;;) { /* try forvever */
int dotcount=0;
/* generate a random number */
{ char *p = get_random_bits( nbits, randomlevel, secret );
mpi_set_buffer( prime, p, (nbits+7)/8, 0 );
m_free(p);
} }
mods = m_alloc( no_of_small_prime_numbers * sizeof *mods );
/* make nbits fit into MPI implementation */
nlimbs = (nbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB;
val_2 = mpi_alloc_set_ui( 2 );
val_3 = mpi_alloc_set_ui( 3);
prime = secret? mpi_alloc_secure( nlimbs ): mpi_alloc( nlimbs );
result = mpi_alloc_like( prime );
pminus1= mpi_alloc_like( prime );
ptest = mpi_alloc_like( prime );
count1 = count2 = 0;
for(;;) { /* try forvever */
int dotcount=0;
/* set high order bit to 1, set low order bit to 1 */ /* generate a random number */
mpi_set_highbit( prime, nbits-1 ); { char *p = get_random_bits( nbits, randomlevel, secret );
mpi_set_bit( prime, 0 ); mpi_set_buffer( prime, p, (nbits+7)/8, 0 );
m_free(p);
/* calculate all remainders */
for(i=0; (x = small_prime_numbers[i]); i++ )
mods[i] = mpi_fdiv_r_ui(NULL, prime, x);
/* now try some primes starting with prime */
for(step=0; step < 20000; step += 2 ) {
/* check against all the small primes we have in mods */
count1++;
for(i=0; (x = small_prime_numbers[i]); i++ ) {
while( mods[i] + step >= x )
mods[i] -= x;
if( !(mods[i] + step) )
break;
}
if( x )
continue; /* found a multiple of an already known prime */
mpi_add_ui( ptest, prime, step );
/* do a faster Fermat test */
count2++;
mpi_sub_ui( pminus1, ptest, 1);
mpi_powm( result, val_2, pminus1, ptest );
if( !mpi_cmp_ui( result, 1 ) ) { /* not composite */
/* perform stronger tests */
if( is_prime(ptest, 5, &count2 ) ) {
if( !mpi_test_bit( ptest, nbits-1 ) ) {
progress('\n');
log_debug("overflow in prime generation\n");
break; /* step loop, continue with a new prime */
}
mpi_free(val_2);
mpi_free(val_3);
mpi_free(result);
mpi_free(pminus1);
mpi_free(prime);
m_free(mods);
return ptest;
} }
}
if( ++dotcount == 10 ) { /* set high order bit to 1, set low order bit to 1 */
progress('.'); mpi_set_highbit( prime, nbits-1 );
dotcount = 0; mpi_set_bit( prime, 0 );
}
/* calculate all remainders */
for(i=0; (x = small_prime_numbers[i]); i++ )
mods[i] = mpi_fdiv_r_ui(NULL, prime, x);
/* now try some primes starting with prime */
for(step=0; step < 20000; step += 2 ) {
/* check against all the small primes we have in mods */
count1++;
for(i=0; (x = small_prime_numbers[i]); i++ ) {
while( mods[i] + step >= x )
mods[i] -= x;
if( !(mods[i] + step) )
break;
}
if( x )
continue; /* found a multiple of an already known prime */
mpi_add_ui( ptest, prime, step );
/* do a faster Fermat test */
count2++;
mpi_sub_ui( pminus1, ptest, 1);
mpi_powm( result, val_2, pminus1, ptest );
if( !mpi_cmp_ui( result, 1 ) ) { /* not composite */
/* perform stronger tests */
if( is_prime(ptest, 5, &count2 ) ) {
if( !mpi_test_bit( ptest, nbits-1 ) ) {
progress('\n');
log_debug("overflow in prime generation\n");
break; /* step loop, continue with a new prime */
}
mpi_free(val_2);
mpi_free(val_3);
mpi_free(result);
mpi_free(pminus1);
mpi_free(prime);
m_free(mods);
return ptest;
}
}
if( ++dotcount == 10 ) {
progress('.');
dotcount = 0;
}
}
progress(':'); /* restart with a new random value */
} }
progress(':'); /* restart with a new random value */
}
} }
/**************** /****************
@@ -402,36 +402,36 @@ gen_prime( unsigned nbits, int secret, int randomlevel )
static int static int
check_prime( MPI prime, MPI val_2 ) check_prime( MPI prime, MPI val_2 )
{ {
int i; int i;
unsigned x; unsigned x;
int count=0; int count=0;
/* check against small primes */ /* check against small primes */
for(i=0; (x = small_prime_numbers[i]); i++ ) { for(i=0; (x = small_prime_numbers[i]); i++ ) {
if( mpi_divisible_ui( prime, x ) ) if( mpi_divisible_ui( prime, x ) )
return 0; return 0;
}
/* a quick fermat test */
{
MPI result = mpi_alloc_like( prime );
MPI pminus1 = mpi_alloc_like( prime );
mpi_sub_ui( pminus1, prime, 1);
mpi_powm( result, val_2, pminus1, prime );
mpi_free( pminus1 );
if( mpi_cmp_ui( result, 1 ) ) { /* if composite */
mpi_free( result );
progress('.');
return 0;
} }
mpi_free( result );
}
/* perform stronger tests */ /* a quick fermat test */
if( is_prime(prime, 5, &count ) ) {
return 1; /* is probably a prime */ MPI result = mpi_alloc_like( prime );
progress('.'); MPI pminus1 = mpi_alloc_like( prime );
return 0; mpi_sub_ui( pminus1, prime, 1);
mpi_powm( result, val_2, pminus1, prime );
mpi_free( pminus1 );
if( mpi_cmp_ui( result, 1 ) ) { /* if composite */
mpi_free( result );
progress('.');
return 0;
}
mpi_free( result );
}
/* perform stronger tests */
if( is_prime(prime, 5, &count ) )
return 1; /* is probably a prime */
progress('.');
return 0;
} }
@@ -441,153 +441,153 @@ check_prime( MPI prime, MPI val_2 )
static int static int
is_prime( MPI n, unsigned steps, int *count ) is_prime( MPI n, unsigned steps, int *count )
{ {
MPI x = mpi_alloc( mpi_get_nlimbs( n ) ); MPI x = mpi_alloc( mpi_get_nlimbs( n ) );
MPI y = mpi_alloc( mpi_get_nlimbs( n ) ); MPI y = mpi_alloc( mpi_get_nlimbs( n ) );
MPI z = mpi_alloc( mpi_get_nlimbs( n ) ); MPI z = mpi_alloc( mpi_get_nlimbs( n ) );
MPI nminus1 = mpi_alloc( mpi_get_nlimbs( n ) ); MPI nminus1 = mpi_alloc( mpi_get_nlimbs( n ) );
MPI a2 = mpi_alloc_set_ui( 2 ); MPI a2 = mpi_alloc_set_ui( 2 );
MPI q; MPI q;
unsigned i, j, k; unsigned i, j, k;
int rc = 0; int rc = 0;
unsigned nbits = mpi_get_nbits( n ); unsigned nbits = mpi_get_nbits( n );
mpi_sub_ui( nminus1, n, 1 ); mpi_sub_ui( nminus1, n, 1 );
/* find q and k, so that n = 1 + 2^k * q */ /* find q and k, so that n = 1 + 2^k * q */
q = mpi_copy( nminus1 ); q = mpi_copy( nminus1 );
k = mpi_trailing_zeros( q ); k = mpi_trailing_zeros( q );
mpi_tdiv_q_2exp(q, q, k); mpi_tdiv_q_2exp(q, q, k);
for(i=0 ; i < steps; i++ ) { for(i=0 ; i < steps; i++ ) {
++*count; ++*count;
if( !i ) { if( !i ) {
mpi_set_ui( x, 2 ); mpi_set_ui( x, 2 );
}
else {
/*mpi_set_bytes( x, nbits-1, get_random_byte, 0 );*/
{ char *p = get_random_bits( nbits, 0, 0 );
mpi_set_buffer( x, p, (nbits+7)/8, 0 );
m_free(p);
}
/* make sure that the number is smaller than the prime
* and keep the randomness of the high bit */
if( mpi_test_bit( x, nbits-2 ) ) {
mpi_set_highbit( x, nbits-2 ); /* clear all higher bits */
}
else {
mpi_set_highbit( x, nbits-2 );
mpi_clear_bit( x, nbits-2 );
}
assert( mpi_cmp( x, nminus1 ) < 0 && mpi_cmp_ui( x, 1 ) > 0 );
}
mpi_powm( y, x, q, n);
if( mpi_cmp_ui(y, 1) && mpi_cmp( y, nminus1 ) ) {
for( j=1; j < k && mpi_cmp( y, nminus1 ); j++ ) {
mpi_powm(y, y, a2, n);
if( !mpi_cmp_ui( y, 1 ) )
goto leave; /* not a prime */
}
if( mpi_cmp( y, nminus1 ) )
goto leave; /* not a prime */
}
progress('+');
} }
else { rc = 1; /* may be a prime */
/*mpi_set_bytes( x, nbits-1, get_random_byte, 0 );*/
{ char *p = get_random_bits( nbits, 0, 0 );
mpi_set_buffer( x, p, (nbits+7)/8, 0 );
m_free(p);
}
/* make sure that the number is smaller than the prime
* and keep the randomness of the high bit */
if( mpi_test_bit( x, nbits-2 ) ) {
mpi_set_highbit( x, nbits-2 ); /* clear all higher bits */
}
else {
mpi_set_highbit( x, nbits-2 );
mpi_clear_bit( x, nbits-2 );
}
assert( mpi_cmp( x, nminus1 ) < 0 && mpi_cmp_ui( x, 1 ) > 0 );
}
mpi_powm( y, x, q, n);
if( mpi_cmp_ui(y, 1) && mpi_cmp( y, nminus1 ) ) {
for( j=1; j < k && mpi_cmp( y, nminus1 ); j++ ) {
mpi_powm(y, y, a2, n);
if( !mpi_cmp_ui( y, 1 ) )
goto leave; /* not a prime */
}
if( mpi_cmp( y, nminus1 ) )
goto leave; /* not a prime */
}
progress('+');
}
rc = 1; /* may be a prime */
leave: leave:
mpi_free( x ); mpi_free( x );
mpi_free( y ); mpi_free( y );
mpi_free( z ); mpi_free( z );
mpi_free( nminus1 ); mpi_free( nminus1 );
mpi_free( q ); mpi_free( q );
return rc; return rc;
} }
static void static void
m_out_of_n( char *array, int m, int n ) m_out_of_n( char *array, int m, int n )
{ {
int i=0, i1=0, j=0, jp=0, j1=0, k1=0, k2=0; int i=0, i1=0, j=0, jp=0, j1=0, k1=0, k2=0;
if( !m || m >= n ) if( !m || m >= n )
return;
if( m == 1 ) { /* special case */
for(i=0; i < n; i++ )
if( array[i] ) {
array[i++] = 0;
if( i >= n )
i = 0;
array[i] = 1;
return; return;
}
BUG();
}
for(j=1; j < n; j++ ) { if( m == 1 ) { /* special case */
if( array[n-1] == array[n-j-1] ) for(i=0; i < n; i++ )
continue; if( array[i] ) {
j1 = j; array[i++] = 0;
break; if( i >= n )
} i = 0;
array[i] = 1;
if( m & 1 ) { /* m is odd */ return;
if( array[n-1] ) { }
if( j1 & 1 ) { BUG();
k1 = n - j1;
k2 = k1+2;
if( k2 > n )
k2 = n;
goto leave;
}
goto scan;
}
k2 = n - j1 - 1;
if( k2 == 0 ) {
k1 = i;
k2 = n - j1;
}
else if( array[k2] && array[k2-1] )
k1 = n;
else
k1 = k2 + 1;
}
else { /* m is even */
if( !array[n-1] ) {
k1 = n - j1;
k2 = k1 + 1;
goto leave;
} }
if( !(j1 & 1) ) { for(j=1; j < n; j++ ) {
k1 = n - j1; if( array[n-1] == array[n-j-1] )
k2 = k1+2; continue;
if( k2 > n ) j1 = j;
k2 = n; break;
goto leave;
} }
scan:
jp = n - j1 - 1; if( m & 1 ) { /* m is odd */
for(i=1; i <= jp; i++ ) { if( array[n-1] ) {
i1 = jp + 2 - i; if( j1 & 1 ) {
if( array[i1-1] ) { k1 = n - j1;
if( array[i1-2] ) { k2 = k1+2;
k1 = i1 - 1; if( k2 > n )
k2 = n - j1; k2 = n;
goto leave;
}
goto scan;
} }
else { k2 = n - j1 - 1;
k1 = i1 - 1; if( k2 == 0 ) {
k2 = n + 1 - j1; k1 = i;
k2 = n - j1;
} }
goto leave; else if( array[k2] && array[k2-1] )
} k1 = n;
else
k1 = k2 + 1;
}
else { /* m is even */
if( !array[n-1] ) {
k1 = n - j1;
k2 = k1 + 1;
goto leave;
}
if( !(j1 & 1) ) {
k1 = n - j1;
k2 = k1+2;
if( k2 > n )
k2 = n;
goto leave;
}
scan:
jp = n - j1 - 1;
for(i=1; i <= jp; i++ ) {
i1 = jp + 2 - i;
if( array[i1-1] ) {
if( array[i1-2] ) {
k1 = i1 - 1;
k2 = n - j1;
}
else {
k1 = i1 - 1;
k2 = n + 1 - j1;
}
goto leave;
}
}
k1 = 1;
k2 = n + 1 - m;
} }
k1 = 1;
k2 = n + 1 - m;
}
leave: leave:
array[k1-1] = !array[k1-1]; array[k1-1] = !array[k1-1];
array[k2-1] = !array[k2-1]; array[k2-1] = !array[k2-1];
} }
+530 -530
View File
File diff suppressed because it is too large Load Diff
+63 -63
View File
@@ -68,7 +68,7 @@
#include "timer.h" #include "timer.h"
#ifdef linux #ifdef linux
# define USE_DEV_RANDOM 1 # define USE_DEV_RANDOM 1
# define RANDOM_PATH DEV_URANDOM # define RANDOM_PATH DEV_URANDOM
#else #else
# ifdef __OpenBSD__ # ifdef __OpenBSD__
@@ -82,7 +82,7 @@
#define get_rnd_byte() (arc4random() % 256) #define get_rnd_byte() (arc4random() % 256)
#else /**** start of large #else ****/ #else /**** start of large #else ****/
#ifdef USE_DEV_RANDOM #ifdef USE_DEV_RANDOM
static int random_fd = NULL_FD; static int random_fd = NULL_FD;
@@ -97,12 +97,12 @@ static u_char random_pool[RANDOM_POOL_SIZE];
static u_char static u_char
generate_rnd_byte(void) generate_rnd_byte(void)
{ {
u_char c; u_char c;
if (read(random_fd, &c, sizeof(c)) == -1) if (read(random_fd, &c, sizeof(c)) == -1)
exit_log_errno((e, "read() failed in get_rnd_byte()")); exit_log_errno((e, "read() failed in get_rnd_byte()"));
return c; return c;
} }
#else /* !USE_DEV_RANDOM */ #else /* !USE_DEV_RANDOM */
@@ -121,52 +121,52 @@ static volatile sig_atomic_t i, j, k;
static void static void
rnd_handler(int ignore_me UNUSED) rnd_handler(int ignore_me UNUSED)
{ {
k <<= 1; /* Shift left by 1 */ k <<= 1; /* Shift left by 1 */
j++; j++;
k |= (i & 0x1); /* Get lsbit of counter */ k |= (i & 0x1); /* Get lsbit of counter */
if (j != 8) if (j != 8)
signal(SIGVTALRM, rnd_handler); signal(SIGVTALRM, rnd_handler);
} }
static u_char static u_char
generate_rnd_byte(void) generate_rnd_byte(void)
{ {
struct itimerval tmval, ntmval; struct itimerval tmval, ntmval;
# ifdef NEVER /* ??? */ # ifdef NEVER /* ??? */
# ifdef linux # ifdef linux
int mask = siggetmask(); int mask = siggetmask();
mask |= SIGVTALRM; mask |= SIGVTALRM;
sigsetmask(mask); sigsetmask(mask);
# endif # endif
# endif # endif
i = 0; i = 0;
j = 0; j = 0;
ntmval.it_interval.tv_sec = 0; ntmval.it_interval.tv_sec = 0;
ntmval.it_interval.tv_usec = 1; ntmval.it_interval.tv_usec = 1;
ntmval.it_value.tv_sec = 0; ntmval.it_value.tv_sec = 0;
ntmval.it_value.tv_usec = 1; ntmval.it_value.tv_usec = 1;
signal(SIGVTALRM, rnd_handler); signal(SIGVTALRM, rnd_handler);
setitimer(ITIMER_VIRTUAL, &ntmval, &tmval); setitimer(ITIMER_VIRTUAL, &ntmval, &tmval);
while (j != 8) while (j != 8)
i++; i++;
setitimer(ITIMER_VIRTUAL, &tmval, &ntmval); setitimer(ITIMER_VIRTUAL, &tmval, &ntmval);
signal(SIGVTALRM, SIG_IGN); signal(SIGVTALRM, SIG_IGN);
# ifdef NEVER /* ??? */ # ifdef NEVER /* ??? */
# ifdef linux # ifdef linux
mask ^= SIGVTALRM; mask ^= SIGVTALRM;
sigsetmask(mask); sigsetmask(mask);
# endif # endif
# endif # endif
return k; return k;
} }
#endif /* !USE_DEV_RANDOM */ #endif /* !USE_DEV_RANDOM */
@@ -174,11 +174,11 @@ generate_rnd_byte(void)
static void static void
mix_pool(void) mix_pool(void)
{ {
SHA1_CTX ctx; SHA1_CTX ctx;
SHA1Init(&ctx); SHA1Init(&ctx);
SHA1Update(&ctx, random_pool, RANDOM_POOL_SIZE); SHA1Update(&ctx, random_pool, RANDOM_POOL_SIZE);
SHA1Final(random_pool, &ctx); SHA1Final(random_pool, &ctx);
} }
/* /*
@@ -187,21 +187,21 @@ mix_pool(void)
static u_char static u_char
get_rnd_byte(void) get_rnd_byte(void)
{ {
random_pool[RANDOM_POOL_SIZE - 1] = generate_rnd_byte(); random_pool[RANDOM_POOL_SIZE - 1] = generate_rnd_byte();
random_pool[0] = generate_rnd_byte(); random_pool[0] = generate_rnd_byte();
mix_pool(); mix_pool();
return random_pool[0]; return random_pool[0];
} }
#endif /* !USE_ARC4RANDOM */ /**** end of large #else ****/ #endif /* !USE_ARC4RANDOM */ /**** end of large #else ****/
void void
get_rnd_bytes(u_char *buffer, int length) get_rnd_bytes(u_char *buffer, int length)
{ {
int i; int i;
for (i = 0; i < length; i++) for (i = 0; i < length; i++)
buffer[i] = get_rnd_byte(); buffer[i] = get_rnd_byte();
} }
/* /*
@@ -212,24 +212,24 @@ init_rnd_pool(void)
{ {
#ifndef USE_ARC4RANDOM #ifndef USE_ARC4RANDOM
# ifdef USE_DEV_RANDOM # ifdef USE_DEV_RANDOM
DBG(DBG_KLIPS, DBG_log("opening %s", RANDOM_PATH)); DBG(DBG_KLIPS, DBG_log("opening %s", RANDOM_PATH));
random_fd = open(RANDOM_PATH, O_RDONLY); random_fd = open(RANDOM_PATH, O_RDONLY);
if (random_fd == -1) if (random_fd == -1)
exit_log_errno((e, "open of %s failed in init_rnd_pool()", RANDOM_PATH)); exit_log_errno((e, "open of %s failed in init_rnd_pool()", RANDOM_PATH));
fcntl(random_fd, F_SETFD, FD_CLOEXEC); fcntl(random_fd, F_SETFD, FD_CLOEXEC);
# endif # endif
get_rnd_bytes(random_pool, RANDOM_POOL_SIZE); get_rnd_bytes(random_pool, RANDOM_POOL_SIZE);
mix_pool(); mix_pool();
#endif /* !USE_ARC4RANDOM */ #endif /* !USE_ARC4RANDOM */
/* start of rand(3) on the right foot */ /* start of rand(3) on the right foot */
{ {
unsigned int seed; unsigned int seed;
get_rnd_bytes((void *)&seed, sizeof(seed)); get_rnd_bytes((void *)&seed, sizeof(seed));
srand(seed); srand(seed);
} }
} }
u_char secret_of_the_day[SHA1_DIGEST_SIZE]; u_char secret_of_the_day[SHA1_DIGEST_SIZE];
@@ -239,12 +239,12 @@ u_char secret_of_the_day[SHA1_DIGEST_SIZE];
void void
init_secret(void) init_secret(void)
{ {
/* /*
* Generate the secret value for responder cookies, and * Generate the secret value for responder cookies, and
* schedule an event for refresh. * schedule an event for refresh.
*/ */
get_rnd_bytes(secret_of_the_day, sizeof(secret_of_the_day)); get_rnd_bytes(secret_of_the_day, sizeof(secret_of_the_day));
event_schedule(EVENT_REINIT_SECRET, EVENT_REINIT_SECRET_DELAY, NULL); event_schedule(EVENT_REINIT_SECRET, EVENT_REINIT_SECRET_DELAY, NULL);
} }
#endif /* NO_PLUTO */ #endif /* NO_PLUTO */
+714 -714
View File
File diff suppressed because it is too large Load Diff
+13 -13
View File
@@ -14,16 +14,16 @@
* RCSID $Id$ * RCSID $Id$
*/ */
extern int ctl_fd; /* file descriptor of control (whack) socket */ extern int ctl_fd; /* file descriptor of control (whack) socket */
extern struct sockaddr_un ctl_addr; /* address of control (whack) socket */ extern struct sockaddr_un ctl_addr; /* address of control (whack) socket */
extern int info_fd; /* file descriptor of control (info) socket */ extern int info_fd; /* file descriptor of control (info) socket */
extern struct sockaddr_un info_addr; /* address of control (info) socket */ extern struct sockaddr_un info_addr; /* address of control (info) socket */
extern err_t init_ctl_socket(void); extern err_t init_ctl_socket(void);
extern void delete_ctl_socket(void); extern void delete_ctl_socket(void);
extern bool listening; /* should we pay attention to IKE messages? */ extern bool listening; /* should we pay attention to IKE messages? */
/* interface: a terminal point for IKE traffic, IPsec transport mode /* interface: a terminal point for IKE traffic, IPsec transport mode
@@ -35,16 +35,16 @@ extern bool listening; /* should we pay attention to IKE messages? */
* Note: the port for IKE is always implicitly UDP/pluto_port. * Note: the port for IKE is always implicitly UDP/pluto_port.
*/ */
struct iface { struct iface {
char *vname; /* virtual (ipsec) device name */ char *vname; /* virtual (ipsec) device name */
char *rname; /* real device name */ char *rname; /* real device name */
ip_address addr; /* interface IP address */ ip_address addr; /* interface IP address */
int fd; /* file descriptor of socket for IKE UDP messages */ int fd; /* file descriptor of socket for IKE UDP messages */
struct iface *next; struct iface *next;
bool ike_float; bool ike_float;
enum { IFN_ADD, IFN_KEEP, IFN_DELETE } change; enum { IFN_ADD, IFN_KEEP, IFN_DELETE } change;
}; };
extern struct iface *interfaces; /* public interfaces */ extern struct iface *interfaces; /* public interfaces */
extern bool use_interface(const char *rifn); extern bool use_interface(const char *rifn);
extern void find_ifaces(void); extern void find_ifaces(void);
+101 -101
View File
@@ -18,7 +18,7 @@ A million repetitions of "a"
#define SHA1HANDSOFF #define SHA1HANDSOFF
#include <string.h> #include <string.h>
#include <sys/types.h> /* for u_int*_t */ #include <sys/types.h> /* for u_int*_t */
#include <endian.h> /* sets BYTE_ORDER, LITTLE_ENDIAN, and BIG_ENDIAN */ #include <endian.h> /* sets BYTE_ORDER, LITTLE_ENDIAN, and BIG_ENDIAN */
#include "sha1.h" #include "sha1.h"
@@ -29,14 +29,14 @@ A million repetitions of "a"
/* I got the idea of expanding during the round function from SSLeay */ /* I got the idea of expanding during the round function from SSLeay */
#if BYTE_ORDER == LITTLE_ENDIAN #if BYTE_ORDER == LITTLE_ENDIAN
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|(rol(block->l[i],8)&0x00FF00FF)) |(rol(block->l[i],8)&0x00FF00FF))
#elif BYTE_ORDER == BIG_ENDIAN #elif BYTE_ORDER == BIG_ENDIAN
#define blk0(i) block->l[i] #define blk0(i) block->l[i]
#else #else
#error "Endianness not defined!" #error "Endianness not defined!"
#endif #endif
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
^block->l[(i+2)&15]^block->l[i&15],1)) ^block->l[(i+2)&15]^block->l[i&15],1))
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
@@ -52,57 +52,57 @@ void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64])
{ {
u_int32_t a, b, c, d, e; u_int32_t a, b, c, d, e;
typedef union { typedef union {
unsigned char c[64]; unsigned char c[64];
u_int32_t l[16]; u_int32_t l[16];
} CHAR64LONG16; } CHAR64LONG16;
#ifdef SHA1HANDSOFF #ifdef SHA1HANDSOFF
CHAR64LONG16 block[1]; /* use array to appear as a pointer */ CHAR64LONG16 block[1]; /* use array to appear as a pointer */
memcpy(block, buffer, 64); memcpy(block, buffer, 64);
#else #else
/* The following had better never be used because it causes the /* The following had better never be used because it causes the
* pointer-to-const buffer to be cast into a pointer to non-const. * pointer-to-const buffer to be cast into a pointer to non-const.
* And the result is written through. I threw a "const" in, hoping * And the result is written through. I threw a "const" in, hoping
* this will cause a diagnostic. * this will cause a diagnostic.
*/ */
CHAR64LONG16* block = (const CHAR64LONG16*)buffer; CHAR64LONG16* block = (const CHAR64LONG16*)buffer;
#endif #endif
/* Copy context->state[] to working vars */ /* Copy context->state[] to working vars */
a = state[0]; a = state[0];
b = state[1]; b = state[1];
c = state[2]; c = state[2];
d = state[3]; d = state[3];
e = state[4]; e = state[4];
/* 4 rounds of 20 operations each. Loop unrolled. */ /* 4 rounds of 20 operations each. Loop unrolled. */
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
/* Add the working vars back into context.state[] */ /* Add the working vars back into context.state[] */
state[0] += a; state[0] += a;
state[1] += b; state[1] += b;
state[2] += c; state[2] += c;
state[3] += d; state[3] += d;
state[4] += e; state[4] += e;
/* Wipe variables */ /* Wipe variables */
a = b = c = d = e = 0; a = b = c = d = e = 0;
#ifdef SHA1HANDSOFF #ifdef SHA1HANDSOFF
memset(block, '\0', sizeof(block)); memset(block, '\0', sizeof(block));
#endif #endif
} }
@@ -111,13 +111,13 @@ CHAR64LONG16* block = (const CHAR64LONG16*)buffer;
void SHA1Init(SHA1_CTX* context) void SHA1Init(SHA1_CTX* context)
{ {
/* SHA1 initialization constants */ /* SHA1 initialization constants */
context->state[0] = 0x67452301; context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89; context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE; context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476; context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0; context->state[4] = 0xC3D2E1F0;
context->count[0] = context->count[1] = 0; context->count[0] = context->count[1] = 0;
} }
@@ -128,21 +128,21 @@ void SHA1Update(SHA1_CTX* context, const unsigned char* data, u_int32_t len)
u_int32_t i; u_int32_t i;
u_int32_t j; u_int32_t j;
j = context->count[0]; j = context->count[0];
if ((context->count[0] += len << 3) < j) if ((context->count[0] += len << 3) < j)
context->count[1]++; context->count[1]++;
context->count[1] += (len>>29); context->count[1] += (len>>29);
j = (j >> 3) & 63; j = (j >> 3) & 63;
if ((j + len) > 63) { if ((j + len) > 63) {
memcpy(&context->buffer[j], data, (i = 64-j)); memcpy(&context->buffer[j], data, (i = 64-j));
SHA1Transform(context->state, context->buffer); SHA1Transform(context->state, context->buffer);
for ( ; i + 63 < len; i += 64) { for ( ; i + 63 < len; i += 64) {
SHA1Transform(context->state, &data[i]); SHA1Transform(context->state, &data[i]);
} }
j = 0; j = 0;
} }
else i = 0; else i = 0;
memcpy(&context->buffer[j], &data[i], len - i); memcpy(&context->buffer[j], &data[i], len - i);
} }
@@ -154,40 +154,40 @@ unsigned i;
unsigned char finalcount[8]; unsigned char finalcount[8];
unsigned char c; unsigned char c;
#if 0 /* untested "improvement" by DHR */ #if 0 /* untested "improvement" by DHR */
/* Convert context->count to a sequence of bytes /* Convert context->count to a sequence of bytes
* in finalcount. Second element first, but * in finalcount. Second element first, but
* big-endian order within element. * big-endian order within element.
* But we do it all backwards. * But we do it all backwards.
*/ */
unsigned char *fcp = &finalcount[8]; unsigned char *fcp = &finalcount[8];
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
{ {
u_int32_t t = context->count[i]; u_int32_t t = context->count[i];
int j; int j;
for (j = 0; j < 4; t >>= 8, j++) for (j = 0; j < 4; t >>= 8, j++)
*--fcp = (unsigned char) t *--fcp = (unsigned char) t
} }
#else #else
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
} }
#endif #endif
c = 0200; c = 0200;
SHA1Update(context, &c, 1); SHA1Update(context, &c, 1);
while ((context->count[0] & 504) != 448) { while ((context->count[0] & 504) != 448) {
c = 0000; c = 0000;
SHA1Update(context, &c, 1); SHA1Update(context, &c, 1);
} }
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
for (i = 0; i < 20; i++) { for (i = 0; i < 20; i++) {
digest[i] = (unsigned char) digest[i] = (unsigned char)
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
} }
/* Wipe variables */ /* Wipe variables */
memset(context, '\0', sizeof(*context)); memset(context, '\0', sizeof(*context));
memset(&finalcount, '\0', sizeof(finalcount)); memset(&finalcount, '\0', sizeof(finalcount));
} }
+3 -3
View File
@@ -5,9 +5,9 @@ By Steve Reid <[email protected]>
*/ */
typedef struct { typedef struct {
u_int32_t state[5]; u_int32_t state[5];
u_int32_t count[2]; u_int32_t count[2];
unsigned char buffer[64]; unsigned char buffer[64];
} SHA1_CTX; } SHA1_CTX;
void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64]); void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64]);
+81 -81
View File
@@ -1,5 +1,5 @@
/* smallprime.c - List of small primes /* smallprime.c - List of small primes
* Copyright (C) 1998 Free Software Foundation, Inc. * Copyright (C) 1998 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@@ -37,86 +37,86 @@
*/ */
ushort ushort
small_prime_numbers[] = { small_prime_numbers[] = {
3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383,
389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577,
587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769,
773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091,
1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277,
1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307,
1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609,
1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667,
1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,
1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931,
1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997,
1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111,
2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161,
2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243,
2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411,
2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473,
2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633,
2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729,
2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791,
2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851,
2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917, 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917,
2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061,
3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137,
3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209,
3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391,
3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467, 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467,
3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533,
3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583,
3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709,
3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779,
3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851, 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917,
3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049,
4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111, 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111,
4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177,
4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243,
4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391,
4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457,
4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519,
4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597,
4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799,
4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951,
4957, 4967, 4969, 4973, 4987, 4993, 4999, 4957, 4967, 4969, 4973, 4987, 4993, 4999,
0 0
}; };
+1329 -1329
View File
File diff suppressed because it is too large Load Diff
+27 -27
View File
@@ -21,19 +21,19 @@
#include "certs.h" #include "certs.h"
#define SCX_TOKEN "%smartcard" #define SCX_TOKEN "%smartcard"
#define SCX_CERT_CACHE_INTERVAL 60 /* seconds */ #define SCX_CERT_CACHE_INTERVAL 60 /* seconds */
#define SCX_MAX_PIN_TRIALS 3 #define SCX_MAX_PIN_TRIALS 3
/* smartcard operations, update copy in whack.h */ /* smartcard operations, update copy in whack.h */
#ifndef SC_OP_T #ifndef SC_OP_T
#define SC_OP_T #define SC_OP_T
typedef enum { typedef enum {
SC_OP_NONE = 0, SC_OP_NONE = 0,
SC_OP_ENCRYPT = 1, SC_OP_ENCRYPT = 1,
SC_OP_DECRYPT = 2, SC_OP_DECRYPT = 2,
SC_OP_SIGN = 3, SC_OP_SIGN = 3,
} sc_op_t; } sc_op_t;
#endif /* SC_OP_T */ #endif /* SC_OP_T */
@@ -42,21 +42,21 @@ typedef enum {
typedef struct smartcard smartcard_t; typedef struct smartcard smartcard_t;
struct smartcard { struct smartcard {
smartcard_t *next; smartcard_t *next;
time_t last_load; time_t last_load;
cert_t last_cert; cert_t last_cert;
int count; int count;
int number; int number;
unsigned long slot; unsigned long slot;
char *id; char *id;
char *label; char *label;
chunk_t pin; chunk_t pin;
bool pinpad; bool pinpad;
bool valid; bool valid;
bool session_opened; bool session_opened;
bool logged_in; bool logged_in;
bool any_slot; bool any_slot;
long session; long session;
}; };
extern const smartcard_t empty_sc; extern const smartcard_t empty_sc;
@@ -78,17 +78,17 @@ extern bool scx_establish_context(smartcard_t *sc);
extern bool scx_login(smartcard_t *sc); extern bool scx_login(smartcard_t *sc);
extern bool scx_on_smartcard(const char *filename); extern bool scx_on_smartcard(const char *filename);
extern bool scx_load_cert(const char *filename, smartcard_t **scp extern bool scx_load_cert(const char *filename, smartcard_t **scp
, cert_t *cert, bool *cached); , cert_t *cert, bool *cached);
extern bool scx_verify_pin(smartcard_t *sc); extern bool scx_verify_pin(smartcard_t *sc);
extern void scx_share(smartcard_t *sc); extern void scx_share(smartcard_t *sc);
extern bool scx_sign_hash(smartcard_t *sc, const u_char *in, size_t inlen extern bool scx_sign_hash(smartcard_t *sc, const u_char *in, size_t inlen
, u_char *out, size_t outlen); , u_char *out, size_t outlen);
extern bool scx_encrypt(smartcard_t *sc, const u_char *in, size_t inlen extern bool scx_encrypt(smartcard_t *sc, const u_char *in, size_t inlen
, u_char *out, size_t *outlen); , u_char *out, size_t *outlen);
extern bool scx_decrypt(smartcard_t *sc, const u_char *in, size_t inlen extern bool scx_decrypt(smartcard_t *sc, const u_char *in, size_t inlen
, u_char *out, size_t *outlen); , u_char *out, size_t *outlen);
extern bool scx_op_via_whack(const char* msg, int inbase, int outbase extern bool scx_op_via_whack(const char* msg, int inbase, int outbase
, sc_op_t op, const char *keyid, int whackfd); , sc_op_t op, const char *keyid, int whackfd);
extern bool scx_get_pin(smartcard_t *sc, int whackfd); extern bool scx_get_pin(smartcard_t *sc, int whackfd);
extern size_t scx_get_keylength(smartcard_t *sc); extern size_t scx_get_keylength(smartcard_t *sc);
extern smartcard_t* scx_add(smartcard_t *sc); extern smartcard_t* scx_add(smartcard_t *sc);
+1917 -1917
View File
File diff suppressed because it is too large Load Diff
+41 -41
View File
@@ -25,39 +25,39 @@
* Note: only "basic" values are represented so far. * Note: only "basic" values are represented so far.
*/ */
struct db_attr { struct db_attr {
u_int16_t type; /* ISAKMP_ATTR_AF_TV is implied; 0 for end */ u_int16_t type; /* ISAKMP_ATTR_AF_TV is implied; 0 for end */
u_int16_t val; u_int16_t val;
}; };
/* transform */ /* transform */
struct db_trans { struct db_trans {
u_int8_t transid; /* Transform-Id */ u_int8_t transid; /* Transform-Id */
struct db_attr *attrs; /* array */ struct db_attr *attrs; /* array */
int attr_cnt; /* number of elements */ int attr_cnt; /* number of elements */
}; };
/* proposal */ /* proposal */
struct db_prop { struct db_prop {
u_int8_t protoid; /* Protocol-Id */ u_int8_t protoid; /* Protocol-Id */
struct db_trans *trans; /* array (disjunction) */ struct db_trans *trans; /* array (disjunction) */
int trans_cnt; /* number of elements */ int trans_cnt; /* number of elements */
/* SPI size and value isn't part of DB */ /* SPI size and value isn't part of DB */
}; };
/* conjunction of proposals */ /* conjunction of proposals */
struct db_prop_conj { struct db_prop_conj {
struct db_prop *props; /* array */ struct db_prop *props; /* array */
int prop_cnt; /* number of elements */ int prop_cnt; /* number of elements */
}; };
/* security association */ /* security association */
struct db_sa { struct db_sa {
struct db_prop_conj *prop_conjs; /* array */ struct db_prop_conj *prop_conjs; /* array */
int prop_conj_cnt; /* number of elements */ int prop_conj_cnt; /* number of elements */
/* Hardwired for now; /* Hardwired for now;
* DOI: ISAKMP_DOI_IPSEC * DOI: ISAKMP_DOI_IPSEC
* Situation: SIT_IDENTITY_ONLY * Situation: SIT_IDENTITY_ONLY
*/ */
}; };
/* The oakley sadb */ /* The oakley sadb */
@@ -72,38 +72,38 @@ extern struct db_sa ipsec_sadb[1 << 3];
struct state; struct state;
extern bool out_sa( extern bool out_sa(
pb_stream *outs, pb_stream *outs,
struct db_sa *sadb, struct db_sa *sadb,
struct state *st, struct state *st,
bool oakley_mode, bool oakley_mode,
u_int8_t np); u_int8_t np);
extern notification_t preparse_isakmp_sa_body( extern notification_t preparse_isakmp_sa_body(
const struct isakmp_sa *sa, /* header of input SA Payload */ const struct isakmp_sa *sa, /* header of input SA Payload */
pb_stream *sa_pbs, /* body of input SA Payload */ pb_stream *sa_pbs, /* body of input SA Payload */
u_int32_t *ipsecdoisit, /* IPsec DOI SIT bitset */ u_int32_t *ipsecdoisit, /* IPsec DOI SIT bitset */
pb_stream *proposal_pbs, /* body of proposal Payload */ pb_stream *proposal_pbs, /* body of proposal Payload */
struct isakmp_proposal *proposal); struct isakmp_proposal *proposal);
extern notification_t parse_isakmp_policy( extern notification_t parse_isakmp_policy(
pb_stream *proposal_pbs, /* body of proposal Payload */ pb_stream *proposal_pbs, /* body of proposal Payload */
u_int notrans, /* number of transforms */ u_int notrans, /* number of transforms */
lset_t *policy); /* RSA, PSK or XAUTH policy */ lset_t *policy); /* RSA, PSK or XAUTH policy */
extern notification_t parse_isakmp_sa_body( extern notification_t parse_isakmp_sa_body(
u_int32_t ipsecdoisit, /* IPsec DOI SIT bitset */ u_int32_t ipsecdoisit, /* IPsec DOI SIT bitset */
pb_stream *proposal_pbs, /* body of proposal Payload */ pb_stream *proposal_pbs, /* body of proposal Payload */
struct isakmp_proposal *proposal, struct isakmp_proposal *proposal,
pb_stream *r_sa_pbs, /* if non-NULL, where to emit winning SA */ pb_stream *r_sa_pbs, /* if non-NULL, where to emit winning SA */
struct state *st, /* current state object */ struct state *st, /* current state object */
bool initiator); /* is caller initiator? */ bool initiator); /* is caller initiator? */
extern notification_t parse_ipsec_sa_body( extern notification_t parse_ipsec_sa_body(
pb_stream *sa_pbs, /* body of input SA Payload */ pb_stream *sa_pbs, /* body of input SA Payload */
const struct isakmp_sa *sa, /* header of input SA Payload */ const struct isakmp_sa *sa, /* header of input SA Payload */
pb_stream *r_sa_pbs, /* if non-NULL, where to emit winning SA */ pb_stream *r_sa_pbs, /* if non-NULL, where to emit winning SA */
bool selection, /* if this SA is a selection, only one tranform can appear */ bool selection, /* if this SA is a selection, only one tranform can appear */
struct state *st); /* current state object */ struct state *st); /* current state object */
extern void backup_pbs(pb_stream *pbs); extern void backup_pbs(pb_stream *pbs);
extern void restore_pbs(pb_stream *pbs); extern void restore_pbs(pb_stream *pbs);
+599 -599
View File
File diff suppressed because it is too large Load Diff
+126 -126
View File
@@ -40,10 +40,10 @@
* than specified by draft-jenkins-ipsec-rekeying-06.txt. * than specified by draft-jenkins-ipsec-rekeying-06.txt.
*/ */
typedef u_int32_t msgid_t; /* Network order! */ typedef u_int32_t msgid_t; /* Network order! */
#define MAINMODE_MSGID ((msgid_t) 0) #define MAINMODE_MSGID ((msgid_t) 0)
struct state; /* forward declaration of tag */ struct state; /* forward declaration of tag */
extern bool reserve_msgid(struct state *isakmp_sa, msgid_t msgid); extern bool reserve_msgid(struct state *isakmp_sa, msgid_t msgid);
extern msgid_t generate_msgid(struct state *isakmp_sa); extern msgid_t generate_msgid(struct state *isakmp_sa);
@@ -54,17 +54,17 @@ extern msgid_t generate_msgid(struct state *isakmp_sa);
* Names are chosen to match corresponding names in state. * Names are chosen to match corresponding names in state.
*/ */
struct oakley_trans_attrs { struct oakley_trans_attrs {
u_int16_t encrypt; /* Encryption algorithm */ u_int16_t encrypt; /* Encryption algorithm */
u_int16_t enckeylen; /* encryption key len (bits) */ u_int16_t enckeylen; /* encryption key len (bits) */
const struct encrypt_desc *encrypter; /* package of encryption routines */ const struct encrypt_desc *encrypter; /* package of encryption routines */
u_int16_t hash; /* Hash algorithm */ u_int16_t hash; /* Hash algorithm */
const struct hash_desc *hasher; /* package of hashing routines */ const struct hash_desc *hasher; /* package of hashing routines */
u_int16_t auth; /* Authentication method */ u_int16_t auth; /* Authentication method */
const struct oakley_group_desc *group; /* Oakley group */ const struct oakley_group_desc *group; /* Oakley group */
time_t life_seconds; /* When this SA expires (seconds) */ time_t life_seconds; /* When this SA expires (seconds) */
u_int32_t life_kilobytes; /* When this SA is exhausted (kilobytes) */ u_int32_t life_kilobytes; /* When this SA is exhausted (kilobytes) */
#if 0 /* not yet */ #if 0 /* not yet */
u_int16_t prf; /* Pseudo Random Function */ u_int16_t prf; /* Pseudo Random Function */
#endif #endif
}; };
@@ -74,28 +74,28 @@ struct oakley_trans_attrs {
* for ESP, and a funny one for IPCOMP. * for ESP, and a funny one for IPCOMP.
*/ */
struct ipsec_trans_attrs { struct ipsec_trans_attrs {
u_int8_t transid; /* transform id */ u_int8_t transid; /* transform id */
ipsec_spi_t spi; /* his SPI */ ipsec_spi_t spi; /* his SPI */
time_t life_seconds; /* When this SA expires */ time_t life_seconds; /* When this SA expires */
u_int32_t life_kilobytes; /* When this SA expires */ u_int32_t life_kilobytes; /* When this SA expires */
u_int16_t encapsulation; u_int16_t encapsulation;
u_int16_t auth; u_int16_t auth;
u_int16_t key_len; u_int16_t key_len;
u_int16_t key_rounds; u_int16_t key_rounds;
#if 0 /* not implemented yet */ #if 0 /* not implemented yet */
u_int16_t cmprs_dict_sz; u_int16_t cmprs_dict_sz;
u_int32_t cmprs_alg; u_int32_t cmprs_alg;
#endif #endif
}; };
/* IPsec per protocol state information */ /* IPsec per protocol state information */
struct ipsec_proto_info { struct ipsec_proto_info {
bool present; /* was this transform specified? */ bool present; /* was this transform specified? */
struct ipsec_trans_attrs attrs; struct ipsec_trans_attrs attrs;
ipsec_spi_t our_spi; ipsec_spi_t our_spi;
u_int16_t keymat_len; /* same for both */ u_int16_t keymat_len; /* same for both */
u_char *our_keymat; u_char *our_keymat;
u_char *peer_keymat; u_char *peer_keymat;
}; };
/* state object: record the state of a (possibly nascent) SA /* state object: record the state of a (possibly nascent) SA
@@ -107,135 +107,135 @@ struct ipsec_proto_info {
*/ */
struct state struct state
{ {
so_serial_t st_serialno; /* serial number (for seniority) */ so_serial_t st_serialno; /* serial number (for seniority) */
so_serial_t st_clonedfrom; /* serial number of parent */ so_serial_t st_clonedfrom; /* serial number of parent */
struct connection *st_connection; /* connection for this SA */ struct connection *st_connection; /* connection for this SA */
int st_whack_sock; /* fd for our Whack TCP socket. int st_whack_sock; /* fd for our Whack TCP socket.
* Single copy: close when freeing struct. * Single copy: close when freeing struct.
*/ */
struct msg_digest *st_suspended_md; /* suspended state-transition */ struct msg_digest *st_suspended_md; /* suspended state-transition */
struct oakley_trans_attrs st_oakley; struct oakley_trans_attrs st_oakley;
struct ipsec_proto_info st_ah; struct ipsec_proto_info st_ah;
struct ipsec_proto_info st_esp; struct ipsec_proto_info st_esp;
struct ipsec_proto_info st_ipcomp; struct ipsec_proto_info st_ipcomp;
#ifdef KLIPS #ifdef KLIPS
ipsec_spi_t st_tunnel_in_spi; /* KLUDGE */ ipsec_spi_t st_tunnel_in_spi; /* KLUDGE */
ipsec_spi_t st_tunnel_out_spi; /* KLUDGE */ ipsec_spi_t st_tunnel_out_spi; /* KLUDGE */
#endif #endif
const struct oakley_group_desc *st_pfs_group; /* group for Phase 2 PFS */ const struct oakley_group_desc *st_pfs_group; /* group for Phase 2 PFS */
u_int32_t st_doi; /* Domain of Interpretation */ u_int32_t st_doi; /* Domain of Interpretation */
u_int32_t st_situation; u_int32_t st_situation;
lset_t st_policy; /* policy for IPsec SA */ lset_t st_policy; /* policy for IPsec SA */
msgid_t st_msgid; /* MSG-ID from header. Network Order! */ msgid_t st_msgid; /* MSG-ID from header. Network Order! */
/* only for a state representing an ISAKMP SA */ /* only for a state representing an ISAKMP SA */
struct msgid_list *st_used_msgids; /* used-up msgids */ struct msgid_list *st_used_msgids; /* used-up msgids */
/* symmetric stuff */ /* symmetric stuff */
/* initiator stuff */ /* initiator stuff */
chunk_t st_gi; /* Initiator public value */ chunk_t st_gi; /* Initiator public value */
u_int8_t st_icookie[COOKIE_SIZE];/* Initiator Cookie */ u_int8_t st_icookie[COOKIE_SIZE];/* Initiator Cookie */
chunk_t st_ni; /* Ni nonce */ chunk_t st_ni; /* Ni nonce */
/* responder stuff */ /* responder stuff */
chunk_t st_gr; /* Responder public value */ chunk_t st_gr; /* Responder public value */
u_int8_t st_rcookie[COOKIE_SIZE];/* Responder Cookie */ u_int8_t st_rcookie[COOKIE_SIZE];/* Responder Cookie */
chunk_t st_nr; /* Nr nonce */ chunk_t st_nr; /* Nr nonce */
/* my stuff */ /* my stuff */
chunk_t st_tpacket; /* Transmitted packet */ chunk_t st_tpacket; /* Transmitted packet */
/* Phase 2 ID payload info about my user */ /* Phase 2 ID payload info about my user */
u_int8_t st_myuserprotoid; /* IDcx.protoid */ u_int8_t st_myuserprotoid; /* IDcx.protoid */
u_int16_t st_myuserport; u_int16_t st_myuserport;
/* his stuff */ /* his stuff */
chunk_t st_rpacket; /* Received packet */ chunk_t st_rpacket; /* Received packet */
/* Phase 2 ID payload info about peer's user */ /* Phase 2 ID payload info about peer's user */
u_int8_t st_peeruserprotoid; /* IDcx.protoid */ u_int8_t st_peeruserprotoid; /* IDcx.protoid */
u_int16_t st_peeruserport; u_int16_t st_peeruserport;
/* end of symmetric stuff */ /* end of symmetric stuff */
u_int8_t st_sec_in_use; /* bool: does st_sec hold a value */ u_int8_t st_sec_in_use; /* bool: does st_sec hold a value */
MP_INT st_sec; /* Our local secret value */ MP_INT st_sec; /* Our local secret value */
chunk_t st_shared; /* Derived shared secret chunk_t st_shared; /* Derived shared secret
* Note: during Quick Mode, * Note: during Quick Mode,
* presence indicates PFS * presence indicates PFS
* selected. * selected.
*/ */
/* In a Phase 1 state, preserve peer's public key after authentication */ /* In a Phase 1 state, preserve peer's public key after authentication */
struct pubkey *st_peer_pubkey; struct pubkey *st_peer_pubkey;
enum state_kind st_state; /* State of exchange */ enum state_kind st_state; /* State of exchange */
u_int8_t st_retransmit; /* Number of retransmits */ u_int8_t st_retransmit; /* Number of retransmits */
unsigned long st_try; /* number of times rekeying attempted */ unsigned long st_try; /* number of times rekeying attempted */
/* 0 means the only time */ /* 0 means the only time */
time_t st_margin; /* life after EVENT_SA_REPLACE */ time_t st_margin; /* life after EVENT_SA_REPLACE */
unsigned long st_outbound_count; /* traffic through eroute */ unsigned long st_outbound_count; /* traffic through eroute */
time_t st_outbound_time; /* time of last change to st_outbound_count */ time_t st_outbound_time; /* time of last change to st_outbound_count */
chunk_t st_p1isa; /* Phase 1 initiator SA (Payload) for HASH */ chunk_t st_p1isa; /* Phase 1 initiator SA (Payload) for HASH */
chunk_t st_skeyid; /* Key material */ chunk_t st_skeyid; /* Key material */
chunk_t st_skeyid_d; /* KM for non-ISAKMP key derivation */ chunk_t st_skeyid_d; /* KM for non-ISAKMP key derivation */
chunk_t st_skeyid_a; /* KM for ISAKMP authentication */ chunk_t st_skeyid_a; /* KM for ISAKMP authentication */
chunk_t st_skeyid_e; /* KM for ISAKMP encryption */ chunk_t st_skeyid_e; /* KM for ISAKMP encryption */
u_char st_iv[MAX_DIGEST_LEN]; /* IV for encryption */ u_char st_iv[MAX_DIGEST_LEN]; /* IV for encryption */
u_char st_new_iv[MAX_DIGEST_LEN]; u_char st_new_iv[MAX_DIGEST_LEN];
u_char st_ph1_iv[MAX_DIGEST_LEN]; /* IV at end if phase 1 */ u_char st_ph1_iv[MAX_DIGEST_LEN]; /* IV at end if phase 1 */
unsigned int st_iv_len; unsigned int st_iv_len;
unsigned int st_new_iv_len; unsigned int st_new_iv_len;
unsigned int st_ph1_iv_len; unsigned int st_ph1_iv_len;
chunk_t st_enc_key; /* Oakley Encryption key */ chunk_t st_enc_key; /* Oakley Encryption key */
struct event *st_event; /* backpointer for certain events */ struct event *st_event; /* backpointer for certain events */
struct state *st_hashchain_next; /* Next in list */ struct state *st_hashchain_next; /* Next in list */
struct state *st_hashchain_prev; /* Previous in list */ struct state *st_hashchain_prev; /* Previous in list */
struct { struct {
bool vars_set; bool vars_set;
bool started; bool started;
} st_modecfg; } st_modecfg;
struct { struct {
int attempt; int attempt;
bool started; bool started;
bool status; bool status;
} st_xauth; } st_xauth;
u_int32_t nat_traversal; u_int32_t nat_traversal;
ip_address nat_oa; ip_address nat_oa;
/* RFC 3706 Dead Peer Detection */ /* RFC 3706 Dead Peer Detection */
bool st_dpd; /* Peer supports DPD */ bool st_dpd; /* Peer supports DPD */
time_t st_last_dpd; /* Time of last DPD transmit */ time_t st_last_dpd; /* Time of last DPD transmit */
u_int32_t st_dpd_seqno; /* Next R_U_THERE to send */ u_int32_t st_dpd_seqno; /* Next R_U_THERE to send */
u_int32_t st_dpd_expectseqno; /* Next R_U_THERE_ACK to receive */ u_int32_t st_dpd_expectseqno; /* Next R_U_THERE_ACK to receive */
u_int32_t st_dpd_peerseqno; /* global variables */ u_int32_t st_dpd_peerseqno; /* global variables */
struct event *st_dpd_event; /* backpointer for DPD events */ struct event *st_dpd_event; /* backpointer for DPD events */
u_int32_t st_seen_vendorid; /* Bit field about recognized Vendor ID */ u_int32_t st_seen_vendorid; /* Bit field about recognized Vendor ID */
}; };
/* global variables */ /* global variables */
extern u_int16_t pluto_port; /* Pluto's port */ extern u_int16_t pluto_port; /* Pluto's port */
extern bool states_use_connection(struct connection *c); extern bool states_use_connection(struct connection *c);
@@ -247,27 +247,27 @@ extern void insert_state(struct state *st);
extern void unhash_state(struct state *st); extern void unhash_state(struct state *st);
extern void release_whack(struct state *st); extern void release_whack(struct state *st);
extern void state_eroute_usage(ip_subnet *ours, ip_subnet *his extern void state_eroute_usage(ip_subnet *ours, ip_subnet *his
, unsigned long count, time_t nw); , unsigned long count, time_t nw);
extern void delete_state(struct state *st); extern void delete_state(struct state *st);
extern void delete_states_by_connection(struct connection *c, bool relations); extern void delete_states_by_connection(struct connection *c, bool relations);
extern struct state extern struct state
*duplicate_state(struct state *st), *duplicate_state(struct state *st),
*find_state(const u_char *icookie *find_state(const u_char *icookie
, const u_char *rcookie , const u_char *rcookie
, const ip_address *peer , const ip_address *peer
, msgid_t msgid), , msgid_t msgid),
*state_with_serialno(so_serial_t sn), *state_with_serialno(so_serial_t sn),
*find_phase2_state_to_delete(const struct state *p1st, u_int8_t protoid *find_phase2_state_to_delete(const struct state *p1st, u_int8_t protoid
, ipsec_spi_t spi, bool *bogus), , ipsec_spi_t spi, bool *bogus),
*find_phase1_state(const struct connection *c, lset_t ok_states), *find_phase1_state(const struct connection *c, lset_t ok_states),
*find_sender(size_t packet_len, u_char *packet); *find_sender(size_t packet_len, u_char *packet);
extern void show_states_status(bool all, const char *name); extern void show_states_status(bool all, const char *name);
extern void for_each_state(void *(f)(struct state *, void *data), void *data); extern void for_each_state(void *(f)(struct state *, void *data), void *data);
extern void find_my_cpi_gap(cpi_t *latest_cpi, cpi_t *first_busy_cpi); extern void find_my_cpi_gap(cpi_t *latest_cpi, cpi_t *first_busy_cpi);
extern ipsec_spi_t uniquify_his_cpi(ipsec_spi_t cpi, struct state *st); extern ipsec_spi_t uniquify_his_cpi(ipsec_spi_t cpi, struct state *st);
extern void fmt_state(bool all, struct state *st, time_t n extern void fmt_state(bool all, struct state *st, time_t n
, char *state_buf, size_t state_buf_len , char *state_buf, size_t state_buf_len
, char *state_buf2, size_t state_buf_len2); , char *state_buf2, size_t state_buf_len2);
extern void delete_states_by_peer(ip_address *peer); extern void delete_states_by_peer(ip_address *peer);
+403 -403
View File
@@ -31,7 +31,7 @@
#include "connections.h" #include "connections.h"
#include "state.h" #include "state.h"
#include "demux.h" #include "demux.h"
#include "ipsec_doi.h" /* needs demux.h and state.h */ #include "ipsec_doi.h" /* needs demux.h and state.h */
#include "kernel.h" #include "kernel.h"
#include "server.h" #include "server.h"
#include "log.h" #include "log.h"
@@ -44,18 +44,18 @@
time_t time_t
now(void) now(void)
{ {
static time_t delta = 0 static time_t delta = 0
, last_time = 0; , last_time = 0;
time_t n = time((time_t)NULL); time_t n = time((time_t)NULL);
passert(n != (time_t)-1); passert(n != (time_t)-1);
if (last_time > n) if (last_time > n)
{ {
plog("time moved backwards %ld seconds", (long)(last_time - n)); plog("time moved backwards %ld seconds", (long)(last_time - n));
delta += last_time - n; delta += last_time - n;
} }
last_time = n; last_time = n;
return n + delta; return n + delta;
} }
/* This file has the event handling routines. Events are /* This file has the event handling routines. Events are
@@ -72,67 +72,67 @@ static struct event *evlist = (struct event *) NULL;
void void
event_schedule(enum event_type type, time_t tm, struct state *st) event_schedule(enum event_type type, time_t tm, struct state *st)
{ {
struct event *ev = malloc_thing(struct event); struct event *ev = malloc_thing(struct event);
ev->ev_type = type; ev->ev_type = type;
ev->ev_time = tm + now(); ev->ev_time = tm + now();
ev->ev_state = st; ev->ev_state = st;
/* If the event is associated with a state, put a backpointer to the /* If the event is associated with a state, put a backpointer to the
* event in the state object, so we can find and delete the event * event in the state object, so we can find and delete the event
* if we need to (for example, if we receive a reply). * if we need to (for example, if we receive a reply).
*/ */
if (st != NULL) if (st != NULL)
{
if (type == EVENT_DPD || type == EVENT_DPD_TIMEOUT)
{ {
passert(st->st_dpd_event == NULL); if (type == EVENT_DPD || type == EVENT_DPD_TIMEOUT)
st->st_dpd_event = ev; {
passert(st->st_dpd_event == NULL);
st->st_dpd_event = ev;
}
else
{
passert(st->st_event == NULL);
st->st_event = ev;
}
} }
else
{
passert(st->st_event == NULL);
st->st_event = ev;
}
}
DBG(DBG_CONTROL,
if (st == NULL)
DBG_log("inserting event %s, timeout in %lu seconds"
, enum_show(&timer_event_names, type), (unsigned long)tm);
else
DBG_log("inserting event %s, timeout in %lu seconds for #%lu"
, enum_show(&timer_event_names, type), (unsigned long)tm
, ev->ev_state->st_serialno));
if (evlist == (struct event *) NULL
|| evlist->ev_time >= ev->ev_time)
{
ev->ev_next = evlist;
evlist = ev;
}
else
{
struct event *evt;
for (evt = evlist; evt->ev_next != NULL; evt = evt->ev_next)
if (evt->ev_next->ev_time >= ev->ev_time)
break;
#ifdef NEVER /* this seems to be overkill */
DBG(DBG_CONTROL, DBG(DBG_CONTROL,
if (evt->ev_state == NULL) if (st == NULL)
DBG_log("event added after event %s" DBG_log("inserting event %s, timeout in %lu seconds"
, enum_show(&timer_event_names, evt->ev_type)); , enum_show(&timer_event_names, type), (unsigned long)tm);
else else
DBG_log("event added after event %s for #%lu" DBG_log("inserting event %s, timeout in %lu seconds for #%lu"
, enum_show(&timer_event_names, evt->ev_type) , enum_show(&timer_event_names, type), (unsigned long)tm
, evt->ev_state->st_serialno)); , ev->ev_state->st_serialno));
if (evlist == (struct event *) NULL
|| evlist->ev_time >= ev->ev_time)
{
ev->ev_next = evlist;
evlist = ev;
}
else
{
struct event *evt;
for (evt = evlist; evt->ev_next != NULL; evt = evt->ev_next)
if (evt->ev_next->ev_time >= ev->ev_time)
break;
#ifdef NEVER /* this seems to be overkill */
DBG(DBG_CONTROL,
if (evt->ev_state == NULL)
DBG_log("event added after event %s"
, enum_show(&timer_event_names, evt->ev_type));
else
DBG_log("event added after event %s for #%lu"
, enum_show(&timer_event_names, evt->ev_type)
, evt->ev_state->st_serialno));
#endif /* NEVER */ #endif /* NEVER */
ev->ev_next = evt->ev_next; ev->ev_next = evt->ev_next;
evt->ev_next = ev; evt->ev_next = ev;
} }
} }
/* /*
@@ -141,299 +141,299 @@ event_schedule(enum event_type type, time_t tm, struct state *st)
void void
handle_timer_event(void) handle_timer_event(void)
{ {
time_t tm; time_t tm;
struct event *ev = evlist; struct event *ev = evlist;
int type; int type;
struct state *st; struct state *st;
struct connection *c = NULL; struct connection *c = NULL;
ip_address peer; ip_address peer;
if (ev == (struct event *) NULL) /* Just paranoid */ if (ev == (struct event *) NULL) /* Just paranoid */
{ {
DBG(DBG_CONTROL, DBG_log("empty event list, yet we're called")); DBG(DBG_CONTROL, DBG_log("empty event list, yet we're called"));
return; return;
} }
type = ev->ev_type; type = ev->ev_type;
st = ev->ev_state; st = ev->ev_state;
tm = now(); tm = now();
if (tm < ev->ev_time) if (tm < ev->ev_time)
{ {
DBG(DBG_CONTROL, DBG_log("called while no event expired (%lu/%lu, %s)" DBG(DBG_CONTROL, DBG_log("called while no event expired (%lu/%lu, %s)"
, (unsigned long)tm, (unsigned long)ev->ev_time , (unsigned long)tm, (unsigned long)ev->ev_time
, enum_show(&timer_event_names, type))); , enum_show(&timer_event_names, type)));
/* This will happen if the most close-to-expire event was /* This will happen if the most close-to-expire event was
* a retransmission or cleanup, and we received a packet * a retransmission or cleanup, and we received a packet
* at the same time as the event expired. Due to the processing * at the same time as the event expired. Due to the processing
* order in call_server(), the packet processing will happen first, * order in call_server(), the packet processing will happen first,
* and the event will be removed. * and the event will be removed.
*/
return;
}
evlist = evlist->ev_next; /* Ok, we'll handle this event */
DBG(DBG_CONTROL,
if (evlist != (struct event *) NULL)
DBG_log("event after this is %s in %ld seconds"
, enum_show(&timer_event_names, evlist->ev_type)
, (long) (evlist->ev_time - tm)));
/* for state-associated events, pick up the state pointer
* and remove the backpointer from the state object.
* We'll eventually either schedule a new event, or delete the state.
*/ */
return; passert(GLOBALS_ARE_RESET());
} if (st != NULL)
evlist = evlist->ev_next; /* Ok, we'll handle this event */
DBG(DBG_CONTROL,
if (evlist != (struct event *) NULL)
DBG_log("event after this is %s in %ld seconds"
, enum_show(&timer_event_names, evlist->ev_type)
, (long) (evlist->ev_time - tm)));
/* for state-associated events, pick up the state pointer
* and remove the backpointer from the state object.
* We'll eventually either schedule a new event, or delete the state.
*/
passert(GLOBALS_ARE_RESET());
if (st != NULL)
{
c = st->st_connection;
if (type == EVENT_DPD || type == EVENT_DPD_TIMEOUT)
{ {
passert(st->st_dpd_event == ev); c = st->st_connection;
st->st_dpd_event = NULL; if (type == EVENT_DPD || type == EVENT_DPD_TIMEOUT)
{
passert(st->st_dpd_event == ev);
st->st_dpd_event = NULL;
}
else
{
passert(st->st_event == ev);
st->st_event = NULL;
}
peer = c->spd.that.host_addr;
set_cur_state(st);
} }
else
{
passert(st->st_event == ev);
st->st_event = NULL;
}
peer = c->spd.that.host_addr;
set_cur_state(st);
}
switch (type) switch (type)
{ {
case EVENT_REINIT_SECRET: case EVENT_REINIT_SECRET:
passert(st == NULL); passert(st == NULL);
DBG(DBG_CONTROL, DBG_log("event EVENT_REINIT_SECRET handled")); DBG(DBG_CONTROL, DBG_log("event EVENT_REINIT_SECRET handled"));
init_secret(); init_secret();
break; break;
#ifdef KLIPS #ifdef KLIPS
case EVENT_SHUNT_SCAN: case EVENT_SHUNT_SCAN:
passert(st == NULL); passert(st == NULL);
scan_proc_shunts(); scan_proc_shunts();
break; break;
#endif #endif
case EVENT_LOG_DAILY: case EVENT_LOG_DAILY:
daily_log_event(); daily_log_event();
break;
case EVENT_RETRANSMIT:
/* Time to retransmit, or give up.
*
* Generally, we'll only try to send the message
* MAXIMUM_RETRANSMISSIONS times. Each time we double
* our patience.
*
* As a special case, if this is the first initiating message
* of a Main Mode exchange, and we have been directed to try
* forever, we'll extend the number of retransmissions to
* MAXIMUM_RETRANSMISSIONS_INITIAL times, with all these
* extended attempts having the same patience. The intention
* is to reduce the bother when nobody is home.
*/
{
time_t delay = 0;
DBG(DBG_CONTROL, DBG_log(
"handling event EVENT_RETRANSMIT for %s \"%s\" #%lu"
, ip_str(&peer), c->name, st->st_serialno));
if (st->st_retransmit < MAXIMUM_RETRANSMISSIONS)
delay = EVENT_RETRANSMIT_DELAY_0 << (st->st_retransmit + 1);
else if (st->st_state == STATE_MAIN_I1
&& c->sa_keying_tries == 0
&& st->st_retransmit < MAXIMUM_RETRANSMISSIONS_INITIAL)
delay = EVENT_RETRANSMIT_DELAY_0 << MAXIMUM_RETRANSMISSIONS;
if (delay != 0)
{
st->st_retransmit++;
whack_log(RC_RETRANSMISSION
, "%s: retransmission; will wait %lus for response"
, enum_name(&state_names, st->st_state)
, (unsigned long)delay);
send_packet(st, "EVENT_RETRANSMIT");
event_schedule(EVENT_RETRANSMIT, delay, st);
}
else
{
/* check if we've tried rekeying enough times.
* st->st_try == 0 means that this should be the only try.
* c->sa_keying_tries == 0 means that there is no limit.
*/
unsigned long try = st->st_try;
unsigned long try_limit = c->sa_keying_tries;
const char *details = "";
switch (st->st_state)
{
case STATE_MAIN_I3:
details = ". Possible authentication failure:"
" no acceptable response to our"
" first encrypted message";
break; break;
case STATE_MAIN_I1:
details = ". No response (or no acceptable response) to our" case EVENT_RETRANSMIT:
" first IKE message"; /* Time to retransmit, or give up.
break; *
case STATE_QUICK_I1: * Generally, we'll only try to send the message
if (c->newest_ipsec_sa == SOS_NOBODY) * MAXIMUM_RETRANSMISSIONS times. Each time we double
details = ". No acceptable response to our" * our patience.
" first Quick Mode message:" *
" perhaps peer likes no proposal"; * As a special case, if this is the first initiating message
break; * of a Main Mode exchange, and we have been directed to try
default: * forever, we'll extend the number of retransmissions to
break; * MAXIMUM_RETRANSMISSIONS_INITIAL times, with all these
} * extended attempts having the same patience. The intention
loglog(RC_NORETRANSMISSION * is to reduce the bother when nobody is home.
, "max number of retransmissions (%d) reached %s%s"
, st->st_retransmit
, enum_show(&state_names, st->st_state), details);
if (try != 0 && try != try_limit)
{
/* A lot like EVENT_SA_REPLACE, but over again.
* Since we know that st cannot be in use,
* we can delete it right away.
*/ */
char story[80]; /* arbitrary limit */
try++;
snprintf(story, sizeof(story), try_limit == 0
? "starting keying attempt %ld of an unlimited number"
: "starting keying attempt %ld of at most %ld"
, try, try_limit);
if (st->st_whack_sock != NULL_FD)
{ {
/* Release whack because the observer will get bored. */ time_t delay = 0;
loglog(RC_COMMENT, "%s, but releasing whack"
, story); DBG(DBG_CONTROL, DBG_log(
release_pending_whacks(st, story); "handling event EVENT_RETRANSMIT for %s \"%s\" #%lu"
, ip_str(&peer), c->name, st->st_serialno));
if (st->st_retransmit < MAXIMUM_RETRANSMISSIONS)
delay = EVENT_RETRANSMIT_DELAY_0 << (st->st_retransmit + 1);
else if (st->st_state == STATE_MAIN_I1
&& c->sa_keying_tries == 0
&& st->st_retransmit < MAXIMUM_RETRANSMISSIONS_INITIAL)
delay = EVENT_RETRANSMIT_DELAY_0 << MAXIMUM_RETRANSMISSIONS;
if (delay != 0)
{
st->st_retransmit++;
whack_log(RC_RETRANSMISSION
, "%s: retransmission; will wait %lus for response"
, enum_name(&state_names, st->st_state)
, (unsigned long)delay);
send_packet(st, "EVENT_RETRANSMIT");
event_schedule(EVENT_RETRANSMIT, delay, st);
}
else
{
/* check if we've tried rekeying enough times.
* st->st_try == 0 means that this should be the only try.
* c->sa_keying_tries == 0 means that there is no limit.
*/
unsigned long try = st->st_try;
unsigned long try_limit = c->sa_keying_tries;
const char *details = "";
switch (st->st_state)
{
case STATE_MAIN_I3:
details = ". Possible authentication failure:"
" no acceptable response to our"
" first encrypted message";
break;
case STATE_MAIN_I1:
details = ". No response (or no acceptable response) to our"
" first IKE message";
break;
case STATE_QUICK_I1:
if (c->newest_ipsec_sa == SOS_NOBODY)
details = ". No acceptable response to our"
" first Quick Mode message:"
" perhaps peer likes no proposal";
break;
default:
break;
}
loglog(RC_NORETRANSMISSION
, "max number of retransmissions (%d) reached %s%s"
, st->st_retransmit
, enum_show(&state_names, st->st_state), details);
if (try != 0 && try != try_limit)
{
/* A lot like EVENT_SA_REPLACE, but over again.
* Since we know that st cannot be in use,
* we can delete it right away.
*/
char story[80]; /* arbitrary limit */
try++;
snprintf(story, sizeof(story), try_limit == 0
? "starting keying attempt %ld of an unlimited number"
: "starting keying attempt %ld of at most %ld"
, try, try_limit);
if (st->st_whack_sock != NULL_FD)
{
/* Release whack because the observer will get bored. */
loglog(RC_COMMENT, "%s, but releasing whack"
, story);
release_pending_whacks(st, story);
}
else
{
/* no whack: just log to syslog */
plog("%s", story);
}
ipsecdoi_replace(st, try);
}
delete_state(st);
}
} }
else break;
case EVENT_SA_REPLACE:
case EVENT_SA_REPLACE_IF_USED:
{ {
/* no whack: just log to syslog */ so_serial_t newest = IS_PHASE1(st->st_state)
plog("%s", story); ? c->newest_isakmp_sa : c->newest_ipsec_sa;
if (newest != st->st_serialno
&& newest != SOS_NOBODY)
{
/* not very interesting: no need to replace */
DBG(DBG_LIFECYCLE
, plog("not replacing stale %s SA: #%lu will do"
, IS_PHASE1(st->st_state)? "ISAKMP" : "IPsec"
, newest));
}
else if (type == EVENT_SA_REPLACE_IF_USED
&& st->st_outbound_time <= tm - c->sa_rekey_margin)
{
/* we observed no recent use: no need to replace
*
* The sampling effects mean that st_outbound_time
* could be up to SHUNT_SCAN_INTERVAL more recent
* than actual traffic because the sampler looks at change
* over that interval.
* st_outbound_time could also not yet reflect traffic
* in the last SHUNT_SCAN_INTERVAL.
* We expect that SHUNT_SCAN_INTERVAL is smaller than
* c->sa_rekey_margin so that the effects of this will
* be unimportant.
* This is just an optimization: correctness is not
* at stake.
*
* Note: we are abusing the DBG mechanism to control
* normal log output.
*/
DBG(DBG_LIFECYCLE
, plog("not replacing stale %s SA: inactive for %lus"
, IS_PHASE1(st->st_state)? "ISAKMP" : "IPsec"
, (unsigned long)(tm - st->st_outbound_time)));
}
else
{
DBG(DBG_LIFECYCLE
, plog("replacing stale %s SA"
, IS_PHASE1(st->st_state)? "ISAKMP" : "IPsec"));
ipsecdoi_replace(st, 1);
}
delete_dpd_event(st);
event_schedule(EVENT_SA_EXPIRE, st->st_margin, st);
} }
ipsecdoi_replace(st, try); break;
}
delete_state(st);
}
}
break;
case EVENT_SA_REPLACE: case EVENT_SA_EXPIRE:
case EVENT_SA_REPLACE_IF_USED: {
{ const char *satype;
so_serial_t newest = IS_PHASE1(st->st_state) so_serial_t latest;
? c->newest_isakmp_sa : c->newest_ipsec_sa;
if (newest != st->st_serialno if (IS_PHASE1(st->st_state))
&& newest != SOS_NOBODY) {
{ satype = "ISAKMP";
/* not very interesting: no need to replace */ latest = c->newest_isakmp_sa;
DBG(DBG_LIFECYCLE }
, plog("not replacing stale %s SA: #%lu will do" else
, IS_PHASE1(st->st_state)? "ISAKMP" : "IPsec" {
, newest)); satype = "IPsec";
} latest = c->newest_ipsec_sa;
else if (type == EVENT_SA_REPLACE_IF_USED }
&& st->st_outbound_time <= tm - c->sa_rekey_margin)
{
/* we observed no recent use: no need to replace
*
* The sampling effects mean that st_outbound_time
* could be up to SHUNT_SCAN_INTERVAL more recent
* than actual traffic because the sampler looks at change
* over that interval.
* st_outbound_time could also not yet reflect traffic
* in the last SHUNT_SCAN_INTERVAL.
* We expect that SHUNT_SCAN_INTERVAL is smaller than
* c->sa_rekey_margin so that the effects of this will
* be unimportant.
* This is just an optimization: correctness is not
* at stake.
*
* Note: we are abusing the DBG mechanism to control
* normal log output.
*/
DBG(DBG_LIFECYCLE
, plog("not replacing stale %s SA: inactive for %lus"
, IS_PHASE1(st->st_state)? "ISAKMP" : "IPsec"
, (unsigned long)(tm - st->st_outbound_time)));
}
else
{
DBG(DBG_LIFECYCLE
, plog("replacing stale %s SA"
, IS_PHASE1(st->st_state)? "ISAKMP" : "IPsec"));
ipsecdoi_replace(st, 1);
}
delete_dpd_event(st);
event_schedule(EVENT_SA_EXPIRE, st->st_margin, st);
}
break;
case EVENT_SA_EXPIRE: if (st->st_serialno != latest)
{ {
const char *satype; /* not very interesting: already superseded */
so_serial_t latest; DBG(DBG_LIFECYCLE
, plog("%s SA expired (superseded by #%lu)"
, satype, latest));
}
else
{
plog("%s SA expired (%s)", satype
, (c->policy & POLICY_DONT_REKEY)
? "--dontrekey"
: "LATEST!"
);
}
}
/* FALLTHROUGH */
case EVENT_SO_DISCARD:
/* Delete this state object. It must be in the hash table. */
delete_state(st);
break;
if (IS_PHASE1(st->st_state)) case EVENT_DPD:
{ dpd_outI(st);
satype = "ISAKMP"; break;
latest = c->newest_isakmp_sa; case EVENT_DPD_TIMEOUT:
} dpd_timeout(st);
else break;
{ case EVENT_NAT_T_KEEPALIVE:
satype = "IPsec"; nat_traversal_ka_event();
latest = c->newest_ipsec_sa; break;
} default:
loglog(RC_LOG_SERIOUS, "INTERNAL ERROR: ignoring unknown expiring event %s"
, enum_show(&timer_event_names, type));
}
if (st->st_serialno != latest) free(ev);
{ reset_cur_state();
/* not very interesting: already superseded */
DBG(DBG_LIFECYCLE
, plog("%s SA expired (superseded by #%lu)"
, satype, latest));
}
else
{
plog("%s SA expired (%s)", satype
, (c->policy & POLICY_DONT_REKEY)
? "--dontrekey"
: "LATEST!"
);
}
}
/* FALLTHROUGH */
case EVENT_SO_DISCARD:
/* Delete this state object. It must be in the hash table. */
delete_state(st);
break;
case EVENT_DPD:
dpd_outI(st);
break;
case EVENT_DPD_TIMEOUT:
dpd_timeout(st);
break;
case EVENT_NAT_T_KEEPALIVE:
nat_traversal_ka_event();
break;
default:
loglog(RC_LOG_SERIOUS, "INTERNAL ERROR: ignoring unknown expiring event %s"
, enum_show(&timer_event_names, type));
}
free(ev);
reset_cur_state();
} }
/* /*
@@ -443,28 +443,28 @@ handle_timer_event(void)
long long
next_event(void) next_event(void)
{ {
time_t tm; time_t tm;
if (evlist == (struct event *) NULL) if (evlist == (struct event *) NULL)
return -1; return -1;
tm = now(); tm = now();
DBG(DBG_CONTROL, DBG(DBG_CONTROL,
if (evlist->ev_state == NULL) if (evlist->ev_state == NULL)
DBG_log("next event %s in %ld seconds" DBG_log("next event %s in %ld seconds"
, enum_show(&timer_event_names, evlist->ev_type) , enum_show(&timer_event_names, evlist->ev_type)
, (long)evlist->ev_time - (long)tm); , (long)evlist->ev_time - (long)tm);
else
DBG_log("next event %s in %ld seconds for #%lu"
, enum_show(&timer_event_names, evlist->ev_type)
, (long)evlist->ev_time - (long)tm
, evlist->ev_state->st_serialno));
if (evlist->ev_time - tm <= 0)
return 0;
else else
DBG_log("next event %s in %ld seconds for #%lu" return evlist->ev_time - tm;
, enum_show(&timer_event_names, evlist->ev_type)
, (long)evlist->ev_time - (long)tm
, evlist->ev_state->st_serialno));
if (evlist->ev_time - tm <= 0)
return 0;
else
return evlist->ev_time - tm;
} }
/* /*
@@ -473,33 +473,33 @@ next_event(void)
void void
delete_event(struct state *st) delete_event(struct state *st)
{ {
if (st->st_event != (struct event *) NULL) if (st->st_event != (struct event *) NULL)
{
struct event **ev;
for (ev = &evlist; ; ev = &(*ev)->ev_next)
{ {
if (*ev == NULL) struct event **ev;
{
DBG(DBG_CONTROL, DBG_log("event %s to be deleted not found",
enum_show(&timer_event_names, st->st_event->ev_type)));
break;
}
if ((*ev) == st->st_event)
{
*ev = (*ev)->ev_next;
if (st->st_event->ev_type == EVENT_RETRANSMIT) for (ev = &evlist; ; ev = &(*ev)->ev_next)
{ {
st->st_retransmit = 0; if (*ev == NULL)
} {
free(st->st_event); DBG(DBG_CONTROL, DBG_log("event %s to be deleted not found",
st->st_event = (struct event *) NULL; enum_show(&timer_event_names, st->st_event->ev_type)));
break;
}
if ((*ev) == st->st_event)
{
*ev = (*ev)->ev_next;
break; if (st->st_event->ev_type == EVENT_RETRANSMIT)
} {
st->st_retransmit = 0;
}
free(st->st_event);
st->st_event = (struct event *) NULL;
break;
}
}
} }
}
} }
/* /*
@@ -508,27 +508,27 @@ delete_event(struct state *st)
void void
delete_dpd_event(struct state *st) delete_dpd_event(struct state *st)
{ {
if (st->st_dpd_event != (struct event *) NULL) if (st->st_dpd_event != (struct event *) NULL)
{ {
struct event **ev; struct event **ev;
for (ev = &evlist; ; ev = &(*ev)->ev_next) for (ev = &evlist; ; ev = &(*ev)->ev_next)
{ {
if (*ev == NULL) if (*ev == NULL)
{ {
DBG(DBG_CONTROL, DBG_log("event %s to be deleted not found", DBG(DBG_CONTROL, DBG_log("event %s to be deleted not found",
enum_show(&timer_event_names, st->st_dpd_event->ev_type))); enum_show(&timer_event_names, st->st_dpd_event->ev_type)));
break; break;
} }
if ((*ev) == st->st_dpd_event) if ((*ev) == st->st_dpd_event)
{ {
*ev = (*ev)->ev_next; *ev = (*ev)->ev_next;
free(st->st_dpd_event); free(st->st_dpd_event);
st->st_dpd_event = (struct event *) NULL; st->st_dpd_event = (struct event *) NULL;
break; break;
} }
} }
} }
} }
/* /*
@@ -537,16 +537,16 @@ delete_dpd_event(struct state *st)
void void
free_events(void) free_events(void)
{ {
struct event *ev_tmp, *ev; struct event *ev_tmp, *ev;
ev = evlist; ev = evlist;
evlist = NULL; evlist = NULL;
while (ev) while (ev)
{ {
ev_tmp = ev; ev_tmp = ev;
ev = ev->ev_next; ev = ev->ev_next;
free(ev_tmp); free(ev_tmp);
} }
} }
+6 -6
View File
@@ -14,16 +14,16 @@
* RCSID $Id$ * RCSID $Id$
*/ */
extern time_t now(void); /* careful version of time(2) */ extern time_t now(void); /* careful version of time(2) */
struct state; /* forward declaration */ struct state; /* forward declaration */
struct event struct event
{ {
time_t ev_time; time_t ev_time;
int ev_type; /* Event type */ int ev_type; /* Event type */
struct state *ev_state; /* Pointer to relevant state (if any) */ struct state *ev_state; /* Pointer to relevant state (if any) */
struct event *ev_next; /* Pointer to next event */ struct event *ev_next; /* Pointer to next event */
}; };
extern void event_schedule(enum event_type type, time_t tm, struct state *st); extern void event_schedule(enum event_type type, time_t tm, struct state *st);
+381 -381
View File
@@ -88,233 +88,233 @@
#define VID_SUBSTRING (VID_SUBSTRING_DUMPHEXA | VID_SUBSTRING_DUMPASCII | VID_SUBSTRING_MATCH) #define VID_SUBSTRING (VID_SUBSTRING_DUMPHEXA | VID_SUBSTRING_DUMPASCII | VID_SUBSTRING_MATCH)
struct vid_struct { struct vid_struct {
enum known_vendorid id; enum known_vendorid id;
unsigned short flags; unsigned short flags;
const char *data; const char *data;
const char *descr; const char *descr;
const char *vid; const char *vid;
u_int vid_len; u_int vid_len;
}; };
#define DEC_MD5_VID_D(id,str,descr) \ #define DEC_MD5_VID_D(id,str,descr) \
{ VID_##id, VID_MD5HASH, str, descr, NULL, 0 }, { VID_##id, VID_MD5HASH, str, descr, NULL, 0 },
#define DEC_MD5_VID(id,str) \ #define DEC_MD5_VID(id,str) \
{ VID_##id, VID_MD5HASH, str, NULL, NULL, 0 }, { VID_##id, VID_MD5HASH, str, NULL, NULL, 0 },
#define DEC_FSWAN_VID(id,str,descr) \ #define DEC_FSWAN_VID(id,str,descr) \
{ VID_##id, VID_FSWAN_HASH, str, descr, NULL, 0 }, { VID_##id, VID_FSWAN_HASH, str, descr, NULL, 0 },
static struct vid_struct _vid_tab[] = { static struct vid_struct _vid_tab[] = {
/* Implementation names */ /* Implementation names */
{ VID_OPENPGP, VID_STRING, "OpenPGP10171", "OpenPGP", NULL, 0 }, { VID_OPENPGP, VID_STRING, "OpenPGP10171", "OpenPGP", NULL, 0 },
DEC_MD5_VID(KAME_RACOON, "KAME/racoon") DEC_MD5_VID(KAME_RACOON, "KAME/racoon")
{ VID_MS_NT5, VID_MD5HASH | VID_SUBSTRING_DUMPHEXA, { VID_MS_NT5, VID_MD5HASH | VID_SUBSTRING_DUMPHEXA,
"MS NT5 ISAKMPOAKLEY", NULL, NULL, 0 }, "MS NT5 ISAKMPOAKLEY", NULL, NULL, 0 },
DEC_MD5_VID(SSH_SENTINEL, "SSH Sentinel") DEC_MD5_VID(SSH_SENTINEL, "SSH Sentinel")
DEC_MD5_VID(SSH_SENTINEL_1_1, "SSH Sentinel 1.1") DEC_MD5_VID(SSH_SENTINEL_1_1, "SSH Sentinel 1.1")
DEC_MD5_VID(SSH_SENTINEL_1_2, "SSH Sentinel 1.2") DEC_MD5_VID(SSH_SENTINEL_1_2, "SSH Sentinel 1.2")
DEC_MD5_VID(SSH_SENTINEL_1_3, "SSH Sentinel 1.3") DEC_MD5_VID(SSH_SENTINEL_1_3, "SSH Sentinel 1.3")
DEC_MD5_VID(SSH_SENTINEL_1_4, "SSH Sentinel 1.4") DEC_MD5_VID(SSH_SENTINEL_1_4, "SSH Sentinel 1.4")
DEC_MD5_VID(SSH_SENTINEL_1_4_1, "SSH Sentinel 1.4.1") DEC_MD5_VID(SSH_SENTINEL_1_4_1, "SSH Sentinel 1.4.1")
/* These ones come from SSH vendors.txt */ /* These ones come from SSH vendors.txt */
DEC_MD5_VID(SSH_IPSEC_1_1_0, DEC_MD5_VID(SSH_IPSEC_1_1_0,
"Ssh Communications Security IPSEC Express version 1.1.0") "Ssh Communications Security IPSEC Express version 1.1.0")
DEC_MD5_VID(SSH_IPSEC_1_1_1, DEC_MD5_VID(SSH_IPSEC_1_1_1,
"Ssh Communications Security IPSEC Express version 1.1.1") "Ssh Communications Security IPSEC Express version 1.1.1")
DEC_MD5_VID(SSH_IPSEC_1_1_2, DEC_MD5_VID(SSH_IPSEC_1_1_2,
"Ssh Communications Security IPSEC Express version 1.1.2") "Ssh Communications Security IPSEC Express version 1.1.2")
DEC_MD5_VID(SSH_IPSEC_1_2_1, DEC_MD5_VID(SSH_IPSEC_1_2_1,
"Ssh Communications Security IPSEC Express version 1.2.1") "Ssh Communications Security IPSEC Express version 1.2.1")
DEC_MD5_VID(SSH_IPSEC_1_2_2, DEC_MD5_VID(SSH_IPSEC_1_2_2,
"Ssh Communications Security IPSEC Express version 1.2.2") "Ssh Communications Security IPSEC Express version 1.2.2")
DEC_MD5_VID(SSH_IPSEC_2_0_0, DEC_MD5_VID(SSH_IPSEC_2_0_0,
"SSH Communications Security IPSEC Express version 2.0.0") "SSH Communications Security IPSEC Express version 2.0.0")
DEC_MD5_VID(SSH_IPSEC_2_1_0, DEC_MD5_VID(SSH_IPSEC_2_1_0,
"SSH Communications Security IPSEC Express version 2.1.0") "SSH Communications Security IPSEC Express version 2.1.0")
DEC_MD5_VID(SSH_IPSEC_2_1_1, DEC_MD5_VID(SSH_IPSEC_2_1_1,
"SSH Communications Security IPSEC Express version 2.1.1") "SSH Communications Security IPSEC Express version 2.1.1")
DEC_MD5_VID(SSH_IPSEC_2_1_2, DEC_MD5_VID(SSH_IPSEC_2_1_2,
"SSH Communications Security IPSEC Express version 2.1.2") "SSH Communications Security IPSEC Express version 2.1.2")
DEC_MD5_VID(SSH_IPSEC_3_0_0, DEC_MD5_VID(SSH_IPSEC_3_0_0,
"SSH Communications Security IPSEC Express version 3.0.0") "SSH Communications Security IPSEC Express version 3.0.0")
DEC_MD5_VID(SSH_IPSEC_3_0_1, DEC_MD5_VID(SSH_IPSEC_3_0_1,
"SSH Communications Security IPSEC Express version 3.0.1") "SSH Communications Security IPSEC Express version 3.0.1")
DEC_MD5_VID(SSH_IPSEC_4_0_0, DEC_MD5_VID(SSH_IPSEC_4_0_0,
"SSH Communications Security IPSEC Express version 4.0.0") "SSH Communications Security IPSEC Express version 4.0.0")
DEC_MD5_VID(SSH_IPSEC_4_0_1, DEC_MD5_VID(SSH_IPSEC_4_0_1,
"SSH Communications Security IPSEC Express version 4.0.1") "SSH Communications Security IPSEC Express version 4.0.1")
DEC_MD5_VID(SSH_IPSEC_4_1_0, DEC_MD5_VID(SSH_IPSEC_4_1_0,
"SSH Communications Security IPSEC Express version 4.1.0") "SSH Communications Security IPSEC Express version 4.1.0")
DEC_MD5_VID(SSH_IPSEC_4_2_0, DEC_MD5_VID(SSH_IPSEC_4_2_0,
"SSH Communications Security IPSEC Express version 4.2.0") "SSH Communications Security IPSEC Express version 4.2.0")
/* note: md5('CISCO-UNITY') = 12f5f28c457168a9702d9fe274cc02d4 */ /* note: md5('CISCO-UNITY') = 12f5f28c457168a9702d9fe274cc02d4 */
{ VID_CISCO_UNITY, VID_KEEP, NULL, "Cisco-Unity", { VID_CISCO_UNITY, VID_KEEP, NULL, "Cisco-Unity",
"\x12\xf5\xf2\x8c\x45\x71\x68\xa9\x70\x2d\x9f\xe2\x74\xcc\x01\x00", "\x12\xf5\xf2\x8c\x45\x71\x68\xa9\x70\x2d\x9f\xe2\x74\xcc\x01\x00",
16 }, 16 },
{ VID_CISCO3K, VID_KEEP | VID_SUBSTRING_MATCH, { VID_CISCO3K, VID_KEEP | VID_SUBSTRING_MATCH,
NULL, "Cisco VPN 3000 Series" , "\x1f\x07\xf7\x0e\xaa\x65\x14\xd3\xb0\xfa\x96\x54\x2a\x50", 14}, NULL, "Cisco VPN 3000 Series" , "\x1f\x07\xf7\x0e\xaa\x65\x14\xd3\xb0\xfa\x96\x54\x2a\x50", 14},
{ VID_CISCO_IOS, VID_KEEP | VID_SUBSTRING_MATCH, { VID_CISCO_IOS, VID_KEEP | VID_SUBSTRING_MATCH,
NULL, "Cisco IOS Device", "\x3e\x98\x40\x48", 4}, NULL, "Cisco IOS Device", "\x3e\x98\x40\x48", 4},
/* /*
* Timestep VID seen: * Timestep VID seen:
* - 54494d455354455020312053475720313532302033313520322e303145303133 * - 54494d455354455020312053475720313532302033313520322e303145303133
* = 'TIMESTEP 1 SGW 1520 315 2.01E013' * = 'TIMESTEP 1 SGW 1520 315 2.01E013'
*/ */
{ VID_TIMESTEP, VID_STRING | VID_SUBSTRING_DUMPASCII, "TIMESTEP", { VID_TIMESTEP, VID_STRING | VID_SUBSTRING_DUMPASCII, "TIMESTEP",
NULL, NULL, 0 }, NULL, NULL, 0 },
/* /*
* Netscreen: * Netscreen:
* 4865617274426561745f4e6f74696679386b0100 (HeartBeat_Notify + 386b0100) * 4865617274426561745f4e6f74696679386b0100 (HeartBeat_Notify + 386b0100)
*/ */
{ VID_MISC_HEARTBEAT_NOTIFY, VID_STRING | VID_SUBSTRING_DUMPHEXA, { VID_MISC_HEARTBEAT_NOTIFY, VID_STRING | VID_SUBSTRING_DUMPHEXA,
"HeartBeat_Notify", "HeartBeat Notify", NULL, 0 }, "HeartBeat_Notify", "HeartBeat Notify", NULL, 0 },
/* /*
* MacOS X * MacOS X
*/ */
{ VID_MACOSX, VID_STRING|VID_SUBSTRING_DUMPHEXA, "Mac OSX 10.x", { VID_MACOSX, VID_STRING|VID_SUBSTRING_DUMPHEXA, "Mac OSX 10.x",
"\x4d\xf3\x79\x28\xe9\xfc\x4f\xd1\xb3\x26\x21\x70\xd5\x15\xc6\x62", NULL, 0}, "\x4d\xf3\x79\x28\xe9\xfc\x4f\xd1\xb3\x26\x21\x70\xd5\x15\xc6\x62", NULL, 0},
/* /*
* Openswan * Openswan
*/ */
DEC_FSWAN_VID(OPENSWAN2, "Openswan 2.2.0", "Openswan 2.2.0") DEC_FSWAN_VID(OPENSWAN2, "Openswan 2.2.0", "Openswan 2.2.0")
/* NCP */ /* NCP */
{ VID_NCP_SERVER, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "NCP Server", { VID_NCP_SERVER, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "NCP Server",
"\xc6\xf5\x7a\xc3\x98\xf4\x93\x20\x81\x45\xb7\x58", 12}, "\xc6\xf5\x7a\xc3\x98\xf4\x93\x20\x81\x45\xb7\x58", 12},
{ VID_NCP_CLIENT, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "NCP Client", { VID_NCP_CLIENT, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "NCP Client",
"\xeb\x4c\x1b\x78\x8a\xfd\x4a\x9c\xb7\x73\x0a\x68", 12}, "\xeb\x4c\x1b\x78\x8a\xfd\x4a\x9c\xb7\x73\x0a\x68", 12},
/* /*
* Windows Vista (and Windows Server 2008?) * Windows Vista (and Windows Server 2008?)
*/ */
DEC_MD5_VID(VISTA_AUTHIP, "MS-Negotiation Discovery Capable") DEC_MD5_VID(VISTA_AUTHIP, "MS-Negotiation Discovery Capable")
DEC_MD5_VID(VISTA_AUTHIP2, "IKE CGA version 1") DEC_MD5_VID(VISTA_AUTHIP2, "IKE CGA version 1")
DEC_MD5_VID(VISTA_AUTHIP3, "MS-MamieExists") DEC_MD5_VID(VISTA_AUTHIP3, "MS-MamieExists")
/* /*
* strongSwan * strongSwan
*/ */
DEC_MD5_VID(STRONGSWAN, "strongSwan 4.3.0") DEC_MD5_VID(STRONGSWAN, "strongSwan 4.3.0")
DEC_MD5_VID(STRONGSWAN_4_2_14,"strongSwan 4.2.14") DEC_MD5_VID(STRONGSWAN_4_2_14,"strongSwan 4.2.14")
DEC_MD5_VID(STRONGSWAN_4_2_13,"strongSwan 4.2.13") DEC_MD5_VID(STRONGSWAN_4_2_13,"strongSwan 4.2.13")
DEC_MD5_VID(STRONGSWAN_4_2_12,"strongSwan 4.2.12") DEC_MD5_VID(STRONGSWAN_4_2_12,"strongSwan 4.2.12")
DEC_MD5_VID(STRONGSWAN_4_2_11,"strongSwan 4.2.11") DEC_MD5_VID(STRONGSWAN_4_2_11,"strongSwan 4.2.11")
DEC_MD5_VID(STRONGSWAN_4_2_10,"strongSwan 4.2.10") DEC_MD5_VID(STRONGSWAN_4_2_10,"strongSwan 4.2.10")
DEC_MD5_VID(STRONGSWAN_4_2_9, "strongSwan 4.2.9") DEC_MD5_VID(STRONGSWAN_4_2_9, "strongSwan 4.2.9")
DEC_MD5_VID(STRONGSWAN_4_2_8, "strongSwan 4.2.8") DEC_MD5_VID(STRONGSWAN_4_2_8, "strongSwan 4.2.8")
DEC_MD5_VID(STRONGSWAN_4_2_7, "strongSwan 4.2.7") DEC_MD5_VID(STRONGSWAN_4_2_7, "strongSwan 4.2.7")
DEC_MD5_VID(STRONGSWAN_4_2_6, "strongSwan 4.2.6") DEC_MD5_VID(STRONGSWAN_4_2_6, "strongSwan 4.2.6")
DEC_MD5_VID(STRONGSWAN_4_2_5, "strongSwan 4.2.5") DEC_MD5_VID(STRONGSWAN_4_2_5, "strongSwan 4.2.5")
DEC_MD5_VID(STRONGSWAN_4_2_4, "strongSwan 4.2.4") DEC_MD5_VID(STRONGSWAN_4_2_4, "strongSwan 4.2.4")
DEC_MD5_VID(STRONGSWAN_4_2_3, "strongSwan 4.2.3") DEC_MD5_VID(STRONGSWAN_4_2_3, "strongSwan 4.2.3")
DEC_MD5_VID(STRONGSWAN_4_2_2, "strongSwan 4.2.2") DEC_MD5_VID(STRONGSWAN_4_2_2, "strongSwan 4.2.2")
DEC_MD5_VID(STRONGSWAN_4_2_1, "strongSwan 4.2.1") DEC_MD5_VID(STRONGSWAN_4_2_1, "strongSwan 4.2.1")
DEC_MD5_VID(STRONGSWAN_4_2_0, "strongSwan 4.2.0") DEC_MD5_VID(STRONGSWAN_4_2_0, "strongSwan 4.2.0")
DEC_MD5_VID(STRONGSWAN_4_1_11,"strongSwan 4.1.11") DEC_MD5_VID(STRONGSWAN_4_1_11,"strongSwan 4.1.11")
DEC_MD5_VID(STRONGSWAN_4_1_10,"strongSwan 4.1.10") DEC_MD5_VID(STRONGSWAN_4_1_10,"strongSwan 4.1.10")
DEC_MD5_VID(STRONGSWAN_4_1_9, "strongSwan 4.1.9") DEC_MD5_VID(STRONGSWAN_4_1_9, "strongSwan 4.1.9")
DEC_MD5_VID(STRONGSWAN_4_1_8, "strongSwan 4.1.8") DEC_MD5_VID(STRONGSWAN_4_1_8, "strongSwan 4.1.8")
DEC_MD5_VID(STRONGSWAN_4_1_7, "strongSwan 4.1.7") DEC_MD5_VID(STRONGSWAN_4_1_7, "strongSwan 4.1.7")
DEC_MD5_VID(STRONGSWAN_4_1_6, "strongSwan 4.1.6") DEC_MD5_VID(STRONGSWAN_4_1_6, "strongSwan 4.1.6")
DEC_MD5_VID(STRONGSWAN_4_1_5, "strongSwan 4.1.5") DEC_MD5_VID(STRONGSWAN_4_1_5, "strongSwan 4.1.5")
DEC_MD5_VID(STRONGSWAN_4_1_4, "strongSwan 4.1.4") DEC_MD5_VID(STRONGSWAN_4_1_4, "strongSwan 4.1.4")
DEC_MD5_VID(STRONGSWAN_4_1_3, "strongSwan 4.1.3") DEC_MD5_VID(STRONGSWAN_4_1_3, "strongSwan 4.1.3")
DEC_MD5_VID(STRONGSWAN_4_1_2, "strongSwan 4.1.2") DEC_MD5_VID(STRONGSWAN_4_1_2, "strongSwan 4.1.2")
DEC_MD5_VID(STRONGSWAN_4_1_1, "strongSwan 4.1.1") DEC_MD5_VID(STRONGSWAN_4_1_1, "strongSwan 4.1.1")
DEC_MD5_VID(STRONGSWAN_4_1_0, "strongSwan 4.1.0") DEC_MD5_VID(STRONGSWAN_4_1_0, "strongSwan 4.1.0")
DEC_MD5_VID(STRONGSWAN_4_0_7, "strongSwan 4.0.7") DEC_MD5_VID(STRONGSWAN_4_0_7, "strongSwan 4.0.7")
DEC_MD5_VID(STRONGSWAN_4_0_6, "strongSwan 4.0.6") DEC_MD5_VID(STRONGSWAN_4_0_6, "strongSwan 4.0.6")
DEC_MD5_VID(STRONGSWAN_4_0_5, "strongSwan 4.0.5") DEC_MD5_VID(STRONGSWAN_4_0_5, "strongSwan 4.0.5")
DEC_MD5_VID(STRONGSWAN_4_0_4, "strongSwan 4.0.4") DEC_MD5_VID(STRONGSWAN_4_0_4, "strongSwan 4.0.4")
DEC_MD5_VID(STRONGSWAN_4_0_3, "strongSwan 4.0.3") DEC_MD5_VID(STRONGSWAN_4_0_3, "strongSwan 4.0.3")
DEC_MD5_VID(STRONGSWAN_4_0_2, "strongSwan 4.0.2") DEC_MD5_VID(STRONGSWAN_4_0_2, "strongSwan 4.0.2")
DEC_MD5_VID(STRONGSWAN_4_0_1, "strongSwan 4.0.1") DEC_MD5_VID(STRONGSWAN_4_0_1, "strongSwan 4.0.1")
DEC_MD5_VID(STRONGSWAN_4_0_0, "strongSwan 4.0.0") DEC_MD5_VID(STRONGSWAN_4_0_0, "strongSwan 4.0.0")
DEC_MD5_VID(STRONGSWAN_2_8_9, "strongSwan 2.8.9") DEC_MD5_VID(STRONGSWAN_2_8_9, "strongSwan 2.8.9")
DEC_MD5_VID(STRONGSWAN_2_8_8, "strongSwan 2.8.8") DEC_MD5_VID(STRONGSWAN_2_8_8, "strongSwan 2.8.8")
DEC_MD5_VID(STRONGSWAN_2_8_7, "strongSwan 2.8.7") DEC_MD5_VID(STRONGSWAN_2_8_7, "strongSwan 2.8.7")
DEC_MD5_VID(STRONGSWAN_2_8_6, "strongSwan 2.8.6") DEC_MD5_VID(STRONGSWAN_2_8_6, "strongSwan 2.8.6")
DEC_MD5_VID(STRONGSWAN_2_8_5, "strongSwan 2.8.5") DEC_MD5_VID(STRONGSWAN_2_8_5, "strongSwan 2.8.5")
DEC_MD5_VID(STRONGSWAN_2_8_4, "strongSwan 2.8.4") DEC_MD5_VID(STRONGSWAN_2_8_4, "strongSwan 2.8.4")
DEC_MD5_VID(STRONGSWAN_2_8_3, "strongSwan 2.8.3") DEC_MD5_VID(STRONGSWAN_2_8_3, "strongSwan 2.8.3")
DEC_MD5_VID(STRONGSWAN_2_8_2, "strongSwan 2.8.2") DEC_MD5_VID(STRONGSWAN_2_8_2, "strongSwan 2.8.2")
DEC_MD5_VID(STRONGSWAN_2_8_1, "strongSwan 2.8.1") DEC_MD5_VID(STRONGSWAN_2_8_1, "strongSwan 2.8.1")
DEC_MD5_VID(STRONGSWAN_2_8_0, "strongSwan 2.8.0") DEC_MD5_VID(STRONGSWAN_2_8_0, "strongSwan 2.8.0")
DEC_MD5_VID(STRONGSWAN_2_7_3, "strongSwan 2.7.3") DEC_MD5_VID(STRONGSWAN_2_7_3, "strongSwan 2.7.3")
DEC_MD5_VID(STRONGSWAN_2_7_2, "strongSwan 2.7.2") DEC_MD5_VID(STRONGSWAN_2_7_2, "strongSwan 2.7.2")
DEC_MD5_VID(STRONGSWAN_2_7_1, "strongSwan 2.7.1") DEC_MD5_VID(STRONGSWAN_2_7_1, "strongSwan 2.7.1")
DEC_MD5_VID(STRONGSWAN_2_7_0, "strongSwan 2.7.0") DEC_MD5_VID(STRONGSWAN_2_7_0, "strongSwan 2.7.0")
DEC_MD5_VID(STRONGSWAN_2_6_4, "strongSwan 2.6.4") DEC_MD5_VID(STRONGSWAN_2_6_4, "strongSwan 2.6.4")
DEC_MD5_VID(STRONGSWAN_2_6_3, "strongSwan 2.6.3") DEC_MD5_VID(STRONGSWAN_2_6_3, "strongSwan 2.6.3")
DEC_MD5_VID(STRONGSWAN_2_6_2, "strongSwan 2.6.2") DEC_MD5_VID(STRONGSWAN_2_6_2, "strongSwan 2.6.2")
DEC_MD5_VID(STRONGSWAN_2_6_1, "strongSwan 2.6.1") DEC_MD5_VID(STRONGSWAN_2_6_1, "strongSwan 2.6.1")
DEC_MD5_VID(STRONGSWAN_2_6_0, "strongSwan 2.6.0") DEC_MD5_VID(STRONGSWAN_2_6_0, "strongSwan 2.6.0")
DEC_MD5_VID(STRONGSWAN_2_5_7, "strongSwan 2.5.7") DEC_MD5_VID(STRONGSWAN_2_5_7, "strongSwan 2.5.7")
DEC_MD5_VID(STRONGSWAN_2_5_6, "strongSwan 2.5.6") DEC_MD5_VID(STRONGSWAN_2_5_6, "strongSwan 2.5.6")
DEC_MD5_VID(STRONGSWAN_2_5_5, "strongSwan 2.5.5") DEC_MD5_VID(STRONGSWAN_2_5_5, "strongSwan 2.5.5")
DEC_MD5_VID(STRONGSWAN_2_5_4, "strongSwan 2.5.4") DEC_MD5_VID(STRONGSWAN_2_5_4, "strongSwan 2.5.4")
DEC_MD5_VID(STRONGSWAN_2_5_3, "strongSwan 2.5.3") DEC_MD5_VID(STRONGSWAN_2_5_3, "strongSwan 2.5.3")
DEC_MD5_VID(STRONGSWAN_2_5_2, "strongSwan 2.5.2") DEC_MD5_VID(STRONGSWAN_2_5_2, "strongSwan 2.5.2")
DEC_MD5_VID(STRONGSWAN_2_5_1, "strongSwan 2.5.1") DEC_MD5_VID(STRONGSWAN_2_5_1, "strongSwan 2.5.1")
DEC_MD5_VID(STRONGSWAN_2_5_0, "strongSwan 2.5.0") DEC_MD5_VID(STRONGSWAN_2_5_0, "strongSwan 2.5.0")
DEC_MD5_VID(STRONGSWAN_2_4_4, "strongSwan 2.4.4") DEC_MD5_VID(STRONGSWAN_2_4_4, "strongSwan 2.4.4")
DEC_MD5_VID(STRONGSWAN_2_4_3, "strongSwan 2.4.3") DEC_MD5_VID(STRONGSWAN_2_4_3, "strongSwan 2.4.3")
DEC_MD5_VID(STRONGSWAN_2_4_2, "strongSwan 2.4.2") DEC_MD5_VID(STRONGSWAN_2_4_2, "strongSwan 2.4.2")
DEC_MD5_VID(STRONGSWAN_2_4_1, "strongSwan 2.4.1") DEC_MD5_VID(STRONGSWAN_2_4_1, "strongSwan 2.4.1")
DEC_MD5_VID(STRONGSWAN_2_4_0, "strongSwan 2.4.0") DEC_MD5_VID(STRONGSWAN_2_4_0, "strongSwan 2.4.0")
DEC_MD5_VID(STRONGSWAN_2_3_2, "strongSwan 2.3.2") DEC_MD5_VID(STRONGSWAN_2_3_2, "strongSwan 2.3.2")
DEC_MD5_VID(STRONGSWAN_2_3_1, "strongSwan 2.3.1") DEC_MD5_VID(STRONGSWAN_2_3_1, "strongSwan 2.3.1")
DEC_MD5_VID(STRONGSWAN_2_3_0, "strongSwan 2.3.0") DEC_MD5_VID(STRONGSWAN_2_3_0, "strongSwan 2.3.0")
DEC_MD5_VID(STRONGSWAN_2_2_2, "strongSwan 2.2.2") DEC_MD5_VID(STRONGSWAN_2_2_2, "strongSwan 2.2.2")
DEC_MD5_VID(STRONGSWAN_2_2_1, "strongSwan 2.2.1") DEC_MD5_VID(STRONGSWAN_2_2_1, "strongSwan 2.2.1")
DEC_MD5_VID(STRONGSWAN_2_2_0, "strongSwan 2.2.0") DEC_MD5_VID(STRONGSWAN_2_2_0, "strongSwan 2.2.0")
/* NAT-Traversal */ /* NAT-Traversal */
DEC_MD5_VID(NATT_STENBERG_01, "draft-stenberg-ipsec-nat-traversal-01") DEC_MD5_VID(NATT_STENBERG_01, "draft-stenberg-ipsec-nat-traversal-01")
DEC_MD5_VID(NATT_STENBERG_02, "draft-stenberg-ipsec-nat-traversal-02") DEC_MD5_VID(NATT_STENBERG_02, "draft-stenberg-ipsec-nat-traversal-02")
DEC_MD5_VID(NATT_HUTTUNEN, "ESPThruNAT") DEC_MD5_VID(NATT_HUTTUNEN, "ESPThruNAT")
DEC_MD5_VID(NATT_HUTTUNEN_ESPINUDP, "draft-huttunen-ipsec-esp-in-udp-00.txt") DEC_MD5_VID(NATT_HUTTUNEN_ESPINUDP, "draft-huttunen-ipsec-esp-in-udp-00.txt")
DEC_MD5_VID(NATT_IETF_00, "draft-ietf-ipsec-nat-t-ike-00") DEC_MD5_VID(NATT_IETF_00, "draft-ietf-ipsec-nat-t-ike-00")
DEC_MD5_VID(NATT_IETF_02, "draft-ietf-ipsec-nat-t-ike-02") DEC_MD5_VID(NATT_IETF_02, "draft-ietf-ipsec-nat-t-ike-02")
/* hash in draft-ietf-ipsec-nat-t-ike-02 contains '\n'... Accept both */ /* hash in draft-ietf-ipsec-nat-t-ike-02 contains '\n'... Accept both */
DEC_MD5_VID_D(NATT_IETF_02_N, "draft-ietf-ipsec-nat-t-ike-02\n", "draft-ietf-ipsec-nat-t-ike-02_n") DEC_MD5_VID_D(NATT_IETF_02_N, "draft-ietf-ipsec-nat-t-ike-02\n", "draft-ietf-ipsec-nat-t-ike-02_n")
DEC_MD5_VID(NATT_IETF_03, "draft-ietf-ipsec-nat-t-ike-03") DEC_MD5_VID(NATT_IETF_03, "draft-ietf-ipsec-nat-t-ike-03")
DEC_MD5_VID(NATT_RFC, "RFC 3947") DEC_MD5_VID(NATT_RFC, "RFC 3947")
/* misc */ /* misc */
{ VID_MISC_XAUTH, VID_KEEP, NULL, "XAUTH", { VID_MISC_XAUTH, VID_KEEP, NULL, "XAUTH",
"\x09\x00\x26\x89\xdf\xd6\xb7\x12", 8 }, "\x09\x00\x26\x89\xdf\xd6\xb7\x12", 8 },
{ VID_MISC_DPD, VID_KEEP, NULL, "Dead Peer Detection", { VID_MISC_DPD, VID_KEEP, NULL, "Dead Peer Detection",
"\xaf\xca\xd7\x13\x68\xa1\xf1\xc9\x6b\x86\x96\xfc\x77\x57\x01\x00", 16 }, "\xaf\xca\xd7\x13\x68\xa1\xf1\xc9\x6b\x86\x96\xfc\x77\x57\x01\x00", 16 },
DEC_MD5_VID(MISC_FRAGMENTATION, "FRAGMENTATION") DEC_MD5_VID(MISC_FRAGMENTATION, "FRAGMENTATION")
DEC_MD5_VID(INITIAL_CONTACT, "Vid-Initial-Contact") DEC_MD5_VID(INITIAL_CONTACT, "Vid-Initial-Contact")
/** /**
* Cisco VPN 3000 * Cisco VPN 3000
*/ */
{ VID_MISC_FRAGMENTATION, VID_MD5HASH | VID_SUBSTRING_DUMPHEXA, { VID_MISC_FRAGMENTATION, VID_MD5HASH | VID_SUBSTRING_DUMPHEXA,
"FRAGMENTATION", NULL, NULL, 0 }, "FRAGMENTATION", NULL, NULL, 0 },
/* -- */ /* -- */
{ 0, 0, NULL, NULL, NULL, 0 } { 0, 0, NULL, NULL, NULL, 0 }
}; };
@@ -325,212 +325,212 @@ static int _vid_struct_init = 0;
void void
init_vendorid(void) init_vendorid(void)
{ {
struct vid_struct *vid; struct vid_struct *vid;
MD5_CTX ctx; MD5_CTX ctx;
int i; int i;
for (vid = _vid_tab; vid->id; vid++) for (vid = _vid_tab; vid->id; vid++)
{
if (vid->flags & VID_STRING)
{ {
/** VendorID is a string **/ if (vid->flags & VID_STRING)
vid->vid = strdup(vid->data);
vid->vid_len = strlen(vid->data);
}
else if (vid->flags & VID_MD5HASH)
{
/** VendorID is a string to hash with MD5 **/
char *vidm = malloc(MD5_DIGEST_SIZE);
vid->vid = vidm;
if (vidm)
{
MD5Init(&ctx);
MD5Update(&ctx, (const u_char *)vid->data, strlen(vid->data));
MD5Final(vidm, &ctx);
vid->vid_len = MD5_DIGEST_SIZE;
}
}
else if (vid->flags & VID_FSWAN_HASH)
{
/** FreeS/WAN 2.00+ specific hash **/
#define FSWAN_VID_SIZE 12
unsigned char hash[MD5_DIGEST_SIZE];
char *vidm = malloc(FSWAN_VID_SIZE);
vid->vid = vidm;
if (vidm)
{
MD5Init(&ctx);
MD5Update(&ctx, (const u_char *)vid->data, strlen(vid->data));
MD5Final(hash, &ctx);
vidm[0] = 'O';
vidm[1] = 'E';
#if FSWAN_VID_SIZE - 2 <= MD5_DIGEST_SIZE
memcpy(vidm + 2, hash, FSWAN_VID_SIZE - 2);
#else
memcpy(vidm + 2, hash, MD5_DIGEST_SIZE);
memset(vidm + 2 + MD5_DIGEST_SIZE, '\0',
FSWAN_VID_SIZE - 2 - MD5_DIGEST_SIZE);
#endif
for (i = 2; i < FSWAN_VID_SIZE; i++)
{ {
vidm[i] &= 0x7f; /** VendorID is a string **/
vidm[i] |= 0x40; vid->vid = strdup(vid->data);
vid->vid_len = strlen(vid->data);
} }
vid->vid_len = FSWAN_VID_SIZE; else if (vid->flags & VID_MD5HASH)
} {
} /** VendorID is a string to hash with MD5 **/
char *vidm = malloc(MD5_DIGEST_SIZE);
if (vid->descr == NULL) vid->vid = vidm;
{ if (vidm)
/** Find something to display **/ {
vid->descr = vid->data; MD5Init(&ctx);
MD5Update(&ctx, (const u_char *)vid->data, strlen(vid->data));
MD5Final(vidm, &ctx);
vid->vid_len = MD5_DIGEST_SIZE;
}
}
else if (vid->flags & VID_FSWAN_HASH)
{
/** FreeS/WAN 2.00+ specific hash **/
#define FSWAN_VID_SIZE 12
unsigned char hash[MD5_DIGEST_SIZE];
char *vidm = malloc(FSWAN_VID_SIZE);
vid->vid = vidm;
if (vidm)
{
MD5Init(&ctx);
MD5Update(&ctx, (const u_char *)vid->data, strlen(vid->data));
MD5Final(hash, &ctx);
vidm[0] = 'O';
vidm[1] = 'E';
#if FSWAN_VID_SIZE - 2 <= MD5_DIGEST_SIZE
memcpy(vidm + 2, hash, FSWAN_VID_SIZE - 2);
#else
memcpy(vidm + 2, hash, MD5_DIGEST_SIZE);
memset(vidm + 2 + MD5_DIGEST_SIZE, '\0',
FSWAN_VID_SIZE - 2 - MD5_DIGEST_SIZE);
#endif
for (i = 2; i < FSWAN_VID_SIZE; i++)
{
vidm[i] &= 0x7f;
vidm[i] |= 0x40;
}
vid->vid_len = FSWAN_VID_SIZE;
}
}
if (vid->descr == NULL)
{
/** Find something to display **/
vid->descr = vid->data;
}
} }
} _vid_struct_init = 1;
_vid_struct_init = 1;
} }
static void static void
handle_known_vendorid (struct msg_digest *md handle_known_vendorid (struct msg_digest *md
, const char *vidstr, size_t len, struct vid_struct *vid) , const char *vidstr, size_t len, struct vid_struct *vid)
{ {
char vid_dump[128]; char vid_dump[128];
bool vid_useful = FALSE; bool vid_useful = FALSE;
size_t i, j; size_t i, j;
switch (vid->id) { switch (vid->id) {
/* Remote side supports OpenPGP certificates */ /* Remote side supports OpenPGP certificates */
case VID_OPENPGP: case VID_OPENPGP:
md->openpgp = TRUE; md->openpgp = TRUE;
vid_useful = TRUE; vid_useful = TRUE;
break; break;
/* /*
* Use most recent supported NAT-Traversal method and ignore the * Use most recent supported NAT-Traversal method and ignore the
* other ones (implementations will send all supported methods but * other ones (implementations will send all supported methods but
* only one will be used) * only one will be used)
* *
* Note: most recent == higher id in vendor.h * Note: most recent == higher id in vendor.h
*/ */
case VID_NATT_IETF_00: case VID_NATT_IETF_00:
if (!nat_traversal_support_non_ike) if (!nat_traversal_support_non_ike)
break; break;
if ((nat_traversal_enabled) && (!md->nat_traversal_vid)) if ((nat_traversal_enabled) && (!md->nat_traversal_vid))
{ {
md->nat_traversal_vid = vid->id; md->nat_traversal_vid = vid->id;
vid_useful = TRUE; vid_useful = TRUE;
}
break;
case VID_NATT_IETF_02:
case VID_NATT_IETF_02_N:
case VID_NATT_IETF_03:
case VID_NATT_RFC:
if (nat_traversal_support_port_floating
&& md->nat_traversal_vid < vid->id)
{
md->nat_traversal_vid = vid->id;
vid_useful = TRUE;
}
break;
/* Remote side would like to do DPD with us on this connection */
case VID_MISC_DPD:
md->dpd = TRUE;
vid_useful = TRUE;
break;
case VID_MISC_XAUTH:
vid_useful = TRUE;
break;
default:
break;
} }
break;
case VID_NATT_IETF_02:
case VID_NATT_IETF_02_N:
case VID_NATT_IETF_03:
case VID_NATT_RFC:
if (nat_traversal_support_port_floating
&& md->nat_traversal_vid < vid->id)
{
md->nat_traversal_vid = vid->id;
vid_useful = TRUE;
}
break;
/* Remote side would like to do DPD with us on this connection */ if (vid->flags & VID_SUBSTRING_DUMPHEXA)
case VID_MISC_DPD:
md->dpd = TRUE;
vid_useful = TRUE;
break;
case VID_MISC_XAUTH:
vid_useful = TRUE;
break;
default:
break;
}
if (vid->flags & VID_SUBSTRING_DUMPHEXA)
{
/* Dump description + Hexa */
memset(vid_dump, 0, sizeof(vid_dump));
snprintf(vid_dump, sizeof(vid_dump), "%s ",
vid->descr ? vid->descr : "");
for (i = strlen(vid_dump), j = vid->vid_len;
j < len && i < sizeof(vid_dump) - 2;
i += 2, j++)
{ {
vid_dump[i] = _hexdig[(vidstr[j] >> 4) & 0xF]; /* Dump description + Hexa */
vid_dump[i+1] = _hexdig[vidstr[j] & 0xF]; memset(vid_dump, 0, sizeof(vid_dump));
snprintf(vid_dump, sizeof(vid_dump), "%s ",
vid->descr ? vid->descr : "");
for (i = strlen(vid_dump), j = vid->vid_len;
j < len && i < sizeof(vid_dump) - 2;
i += 2, j++)
{
vid_dump[i] = _hexdig[(vidstr[j] >> 4) & 0xF];
vid_dump[i+1] = _hexdig[vidstr[j] & 0xF];
}
} }
} else if (vid->flags & VID_SUBSTRING_DUMPASCII)
else if (vid->flags & VID_SUBSTRING_DUMPASCII)
{
/* Dump ASCII content */
memset(vid_dump, 0, sizeof(vid_dump));
for (i = 0; i < len && i < sizeof(vid_dump) - 1; i++)
{ {
vid_dump[i] = (isprint(vidstr[i])) ? vidstr[i] : '.'; /* Dump ASCII content */
memset(vid_dump, 0, sizeof(vid_dump));
for (i = 0; i < len && i < sizeof(vid_dump) - 1; i++)
{
vid_dump[i] = (isprint(vidstr[i])) ? vidstr[i] : '.';
}
}
else
{
/* Dump description (descr) */
snprintf(vid_dump, sizeof(vid_dump), "%s",
vid->descr ? vid->descr : "");
} }
}
else
{
/* Dump description (descr) */
snprintf(vid_dump, sizeof(vid_dump), "%s",
vid->descr ? vid->descr : "");
}
loglog(RC_LOG_SERIOUS, "%s Vendor ID payload [%s]", loglog(RC_LOG_SERIOUS, "%s Vendor ID payload [%s]",
vid_useful ? "received" : "ignoring", vid_dump); vid_useful ? "received" : "ignoring", vid_dump);
} }
void void
handle_vendorid (struct msg_digest *md, const char *vid, size_t len) handle_vendorid (struct msg_digest *md, const char *vid, size_t len)
{ {
struct vid_struct *pvid; struct vid_struct *pvid;
if (!_vid_struct_init) if (!_vid_struct_init)
init_vendorid(); init_vendorid();
/* /*
* Find known VendorID in _vid_tab * Find known VendorID in _vid_tab
*/ */
for (pvid = _vid_tab; pvid->id; pvid++) for (pvid = _vid_tab; pvid->id; pvid++)
{
if (pvid->vid && vid && pvid->vid_len && len)
{ {
if (pvid->vid_len == len) if (pvid->vid && vid && pvid->vid_len && len)
{
if (memeq(pvid->vid, vid, len))
{ {
handle_known_vendorid(md, vid, len, pvid); if (pvid->vid_len == len)
return; {
if (memeq(pvid->vid, vid, len))
{
handle_known_vendorid(md, vid, len, pvid);
return;
}
}
else if ((pvid->vid_len < len) && (pvid->flags & VID_SUBSTRING))
{
if (memeq(pvid->vid, vid, pvid->vid_len))
{
handle_known_vendorid(md, vid, len, pvid);
return;
}
}
} }
}
else if ((pvid->vid_len < len) && (pvid->flags & VID_SUBSTRING))
{
if (memeq(pvid->vid, vid, pvid->vid_len))
{
handle_known_vendorid(md, vid, len, pvid);
return;
}
}
} }
}
/* /*
* Unknown VendorID. Log the beginning. * Unknown VendorID. Log the beginning.
*/ */
{
char log_vid[2*MAX_LOG_VID_LEN+1];
size_t i;
memset(log_vid, 0, sizeof(log_vid));
for (i = 0; i < len && i < MAX_LOG_VID_LEN; i++)
{ {
log_vid[2*i] = _hexdig[(vid[i] >> 4) & 0xF]; char log_vid[2*MAX_LOG_VID_LEN+1];
log_vid[2*i+1] = _hexdig[vid[i] & 0xF]; size_t i;
memset(log_vid, 0, sizeof(log_vid));
for (i = 0; i < len && i < MAX_LOG_VID_LEN; i++)
{
log_vid[2*i] = _hexdig[(vid[i] >> 4) & 0xF];
log_vid[2*i+1] = _hexdig[vid[i] & 0xF];
}
loglog(RC_LOG_SERIOUS, "ignoring Vendor ID payload [%s%s]",
log_vid, (len>MAX_LOG_VID_LEN) ? "..." : "");
} }
loglog(RC_LOG_SERIOUS, "ignoring Vendor ID payload [%s%s]",
log_vid, (len>MAX_LOG_VID_LEN) ? "..." : "");
}
} }
/** /**
@@ -539,22 +539,22 @@ handle_vendorid (struct msg_digest *md, const char *vid, size_t len)
bool bool
out_vendorid (u_int8_t np, pb_stream *outs, enum known_vendorid vid) out_vendorid (u_int8_t np, pb_stream *outs, enum known_vendorid vid)
{ {
struct vid_struct *pvid; struct vid_struct *pvid;
if (!_vid_struct_init) if (!_vid_struct_init)
init_vendorid(); init_vendorid();
for (pvid = _vid_tab; pvid->id && pvid->id != vid; pvid++); for (pvid = _vid_tab; pvid->id && pvid->id != vid; pvid++);
if (pvid->id != vid) if (pvid->id != vid)
return STF_INTERNAL_ERROR; /* not found */ return STF_INTERNAL_ERROR; /* not found */
if (!pvid->vid) if (!pvid->vid)
return STF_INTERNAL_ERROR; /* not initialized */ return STF_INTERNAL_ERROR; /* not initialized */
DBG(DBG_EMITTING, DBG(DBG_EMITTING,
DBG_log("out_vendorid(): sending [%s]", pvid->descr) DBG_log("out_vendorid(): sending [%s]", pvid->descr)
) )
return out_generic_raw(np, &isakmp_vendor_id_desc, outs, return out_generic_raw(np, &isakmp_vendor_id_desc, outs,
pvid->vid, pvid->vid_len, "V_ID"); pvid->vid, pvid->vid_len, "V_ID");
} }

Some files were not shown because too many files have changed in this diff Show More