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 47325 additions and 47325 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/* Support of X.509 attribute certificates
* Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
* Copyright (C) 2003 Martin Berner, Lukas Suter
*
* 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
@ -22,9 +22,9 @@
/* definition of ietfAttribute kinds */
typedef enum {
IETF_ATTRIBUTE_OCTETS = 0,
IETF_ATTRIBUTE_OID = 1,
IETF_ATTRIBUTE_STRING = 2
IETF_ATTRIBUTE_OCTETS = 0,
IETF_ATTRIBUTE_OID = 1,
IETF_ATTRIBUTE_STRING = 2
} ietfAttribute_t;
/* access structure for an ietfAttribute */
@ -32,17 +32,17 @@ typedef enum {
typedef struct ietfAttr ietfAttr_t;
struct ietfAttr {
time_t installed;
int count;
time_t installed;
int count;
ietfAttribute_t kind;
chunk_t value;
chunk_t value;
};
typedef struct ietfAttrList ietfAttrList_t;
struct ietfAttrList {
ietfAttrList_t *next;
ietfAttr_t *attr;
ietfAttr_t *attr;
};
@ -52,31 +52,31 @@ typedef struct x509acert x509acert_t;
struct x509acert {
x509acert_t *next;
time_t installed;
chunk_t certificate;
chunk_t certificateInfo;
u_int version;
/* holder */
/* baseCertificateID */
chunk_t holderIssuer;
chunk_t holderSerial;
chunk_t entityName;
/* v2Form */
chunk_t issuerName;
/* signature */
time_t installed;
chunk_t certificate;
chunk_t certificateInfo;
u_int version;
/* holder */
/* baseCertificateID */
chunk_t holderIssuer;
chunk_t holderSerial;
chunk_t entityName;
/* v2Form */
chunk_t issuerName;
/* signature */
int sigAlg;
chunk_t serialNumber;
/* attrCertValidityPeriod */
chunk_t serialNumber;
/* attrCertValidityPeriod */
time_t notBefore;
time_t notAfter;
/* attributes */
/* attributes */
ietfAttrList_t *charging;
ietfAttrList_t *groups;
/* extensions */
/* extensions */
chunk_t authKeyID;
chunk_t authKeySerialNumber;
bool noRevAvail;
/* signatureAlgorithm */
bool noRevAvail;
/* signatureAlgorithm */
int algorithm;
chunk_t signature;
};
@ -88,7 +88,7 @@ extern void unshare_ietfAttrList(ietfAttrList_t **listp);
extern void free_ietfAttrList(ietfAttrList_t *list);
extern void decode_groups(char *groups, ietfAttrList_t **listp);
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 verify_x509acert(x509acert_t *ac, bool strict);
extern x509acert_t* get_x509acert(chunk_t issuer, chunk_t serial);

View File

@ -14,7 +14,7 @@
* RCSID $Id$
*/
#ifndef USE_LWRES /* whole file! */
#ifndef USE_LWRES /* whole file! */
/* This program executes as multiple processes. The Master process
* receives queries (struct adns_query messages) from Pluto and distributes
@ -58,7 +58,7 @@
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <netdb.h> /* ??? for h_errno */
#include <netdb.h> /* ??? for h_errno */
#include <freeswan.h>
@ -70,11 +70,11 @@
#endif
#include "constants.h"
#include "adns.h" /* needs <resolv.h> */
#include "adns.h" /* needs <resolv.h> */
/* shared by all processes */
static const char *name; /* program name, for messages */
static const char *name; /* program name, for messages */
static bool debug = FALSE;
@ -88,43 +88,43 @@ static bool debug = FALSE;
static enum helper_exit_status
read_pipe(int fd, unsigned char *stuff, size_t minlen, size_t maxlen)
{
size_t n = 0;
size_t goal = minlen;
size_t n = 0;
size_t goal = minlen;
do {
ssize_t m = read(fd, stuff + n, goal - n);
do {
ssize_t m = read(fd, stuff + n, goal - n);
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 (m == -1)
{
if (debug)
fprintf(stderr, "%lu : [%lu, %lu]\n"
, (unsigned long)goal
, (unsigned long)minlen, (unsigned long)maxlen);
return HES_BAD_LEN;
if (errno != EINTR)
{
syslog(LOG_ERR, "Input error on pipe: %s", strerror(errno));
return HES_IO_ERROR_IN;
}
}
}
}
} while (n < goal);
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)
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.
@ -135,27 +135,27 @@ read_pipe(int fd, unsigned char *stuff, size_t minlen, size_t maxlen)
static enum helper_exit_status
write_pipe(int fd, const unsigned char *stuff)
{
size_t len = *(const size_t *)(const void *)stuff;
size_t n = 0;
size_t len = *(const size_t *)(const void *)stuff;
size_t n = 0;
do {
ssize_t m = write(fd, stuff + n, len - n);
do {
ssize_t m = write(fd, stuff + n, len - n);
if (m == -1)
{
/* error, but ignore and retry if EINTR */
if (errno != EINTR)
{
syslog(LOG_ERR, "Output error from master: %s", strerror(errno));
return HES_IO_ERROR_OUT;
}
}
else
{
n += m;
}
} while (n != len);
return HES_CONTINUE;
if (m == -1)
{
/* error, but ignore and retry if EINTR */
if (errno != EINTR)
{
syslog(LOG_ERR, "Output error from master: %s", strerror(errno));
return HES_IO_ERROR_OUT;
}
}
else
{
n += m;
}
} while (n != len);
return HES_CONTINUE;
}
/**************** worker process ****************/
@ -171,14 +171,14 @@ write_pipe(int fd, const unsigned char *stuff)
*/
#if (__RES) <= 19960801
# define OLD_RESOLVER 1
# define OLD_RESOLVER 1
#endif
#ifdef OLD_RESOLVER
# define res_ninit(statp) res_init()
# 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()
static struct __res_state *statp = &_res;
@ -193,75 +193,75 @@ static res_state statp = &my_res_state;
static int
worker(int qfd, int afd)
{
{
int r = res_ninit(statp);
if (r != 0)
{
syslog(LOG_ERR, "cannot initialize resolver");
return HES_RES_INIT;
}
int r = res_ninit(statp);
if (r != 0)
{
syslog(LOG_ERR, "cannot initialize resolver");
return HES_RES_INIT;
}
#ifndef OLD_RESOLVER
statp->options |= RES_ROTATE;
statp->options |= RES_ROTATE;
#endif
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;
statp->options |= RES_DEBUG;
}
a.amagic = ADNS_A_MAGIC;
a.serial = q.serial;
for (;;)
{
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));
a.h_errno_val = h_errno;
enum helper_exit_status r = read_pipe(qfd, (unsigned char *)&q
, 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
if (((q.debugging & IMPAIR_DELAY_ADNS_KEY_ANSWER) && q.type == T_KEY)
|| ((q.debugging & IMPAIR_DELAY_ADNS_TXT_ANSWER) && q.type == T_TXT))
sleep(30); /* delay the answer */
if (((q.debugging & IMPAIR_DELAY_ADNS_KEY_ANSWER) && q.type == T_KEY)
|| ((q.debugging & IMPAIR_DELAY_ADNS_TXT_ANSWER) && q.type == T_TXT))
sleep(30); /* delay the answer */
#endif
/* write answer, possibly a bit at a time */
r = write_pipe(afd, (const unsigned char *)&a);
/* write answer, possibly a bit at a time */
r = write_pipe(afd, (const unsigned char *)&a);
if (r != HES_CONTINUE)
return r; /* some kind of exit */
}
if (r != HES_CONTINUE)
return r; /* some kind of exit */
}
}
/**************** master process ****************/
bool eof_from_pluto = FALSE;
#define PLUTO_QFD 0 /* queries come on stdin */
#define PLUTO_AFD 1 /* answers go out on stdout */
#define PLUTO_QFD 0 /* queries come on stdin */
#define PLUTO_AFD 1 /* answers go out on stdout */
#ifndef MAX_WORKERS
# define MAX_WORKERS 10 /* number of in-flight queries */
# define MAX_WORKERS 10 /* number of in-flight queries */
#endif
struct worker_info {
int qfd; /* query pipe's file descriptor */
int afd; /* answer pipe's file descriptor */
pid_t pid;
bool busy;
void *continuation; /* of outstanding request */
int qfd; /* query pipe's file descriptor */
int afd; /* answer pipe's file descriptor */
pid_t pid;
bool busy;
void *continuation; /* of outstanding request */
};
static struct worker_info wi[MAX_WORKERS];
@ -270,300 +270,300 @@ static struct worker_info *wi_roof = wi;
/* request FIFO */
struct query_list {
struct query_list *next;
struct adns_query aq;
struct query_list *next;
struct adns_query aq;
};
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 bool
spawn_worker(void)
{
int qfds[2];
int afds[2];
pid_t p;
int qfds[2];
int afds[2];
pid_t p;
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)
if (pipe(qfds) != 0 || pipe(afds) != 0)
{
syslog(LOG_ERR, "fork(2) error creating first worker: %s", strerror(errno));
exit(HES_FORK);
syslog(LOG_ERR, "pipe(2) failed: %s", strerror(errno));
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);
close(PLUTO_AFD);
/* close all master pipes, including ours */
for (w = wi; w <= wi_roof; w++)
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)
{
close(w->qfd);
close(w->afd);
/* 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));
exit(HES_FORK);
}
close(qfds[0]);
close(qfds[1]);
close(afds[0]);
close(afds[1]);
return FALSE;
}
exit(worker(qfds[0], afds[1]));
}
else
{
/* parent */
struct worker_info *w = wi_roof++;
else if (p == 0)
{
/* child */
struct worker_info *w;
w->pid = p;
w->busy = FALSE;
close(qfds[0]);
close(afds[1]);
return TRUE;
}
close(PLUTO_QFD);
close(PLUTO_AFD);
/* close all master pipes, including ours */
for (w = wi; w <= wi_roof; w++)
{
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
send_eof(struct worker_info *w)
{
pid_t p;
int status;
pid_t p;
int status;
close(w->qfd);
w->qfd = NULL_FD;
close(w->qfd);
w->qfd = NULL_FD;
close(w->afd);
w->afd = NULL_FD;
close(w->afd);
w->afd = NULL_FD;
/* reap child */
p = waitpid(w->pid, &status, 0);
/* ignore result -- what could we do with it? */
/* reap child */
p = waitpid(w->pid, &status, 0);
/* ignore result -- what could we do with it? */
}
static void
forward_query(struct worker_info *w)
{
struct query_list *q = oldest_query;
struct query_list *q = oldest_query;
if (q == NULL)
{
if (eof_from_pluto)
send_eof(w);
}
else
{
enum helper_exit_status r
= write_pipe(w->qfd, (const unsigned char *) &q->aq);
if (q == NULL)
{
if (eof_from_pluto)
send_eof(w);
}
else
{
enum helper_exit_status r
= write_pipe(w->qfd, (const unsigned char *) &q->aq);
if (r != HES_CONTINUE)
exit(r);
if (r != HES_CONTINUE)
exit(r);
w->busy = TRUE;
w->busy = TRUE;
oldest_query = q->next;
q->next = free_queries;
free_queries = q;
}
oldest_query = q->next;
q->next = free_queries;
free_queries = q;
}
}
static void
query(void)
{
struct query_list *q = free_queries;
enum helper_exit_status r;
struct query_list *q = free_queries;
enum helper_exit_status r;
/* find an unused queue entry */
if (q == NULL)
{
q = malloc(sizeof(*q));
/* find an unused queue entry */
if (q == NULL)
{
syslog(LOG_ERR, "malloc(3) failed");
exit(HES_MALLOC);
q = malloc(sizeof(*q));
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
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;
}
free_queries = q->next;
}
}
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
answer(struct worker_info *w)
{
struct adns_answer a;
enum helper_exit_status r = read_pipe(w->afd, (unsigned char *)&a
, offsetof(struct adns_answer, ans), sizeof(a));
struct adns_answer a;
enum helper_exit_status r = read_pipe(w->afd, (unsigned char *)&a
, offsetof(struct adns_answer, ans), sizeof(a));
if (r == HES_OK)
{
/* unexpected EOF */
syslog(LOG_ERR, "unexpected EOF from worker");
exit(HES_IO_ERROR_IN);
}
else if (r != HES_CONTINUE)
{
exit(r);
}
else if (a.amagic != ADNS_A_MAGIC)
{
syslog(LOG_ERR, "Input from worker error: bad magic");
exit(HES_BAD_MAGIC);
}
else if (a.continuation != w->continuation)
{
/* answer doesn't match query */
syslog(LOG_ERR, "Input from worker error: continuation mismatch");
exit(HES_SYNC);
}
else
{
/* pass the answer on to Pluto */
enum helper_exit_status r
= write_pipe(PLUTO_AFD, (const unsigned char *) &a);
if (r == HES_OK)
{
/* unexpected EOF */
syslog(LOG_ERR, "unexpected EOF from worker");
exit(HES_IO_ERROR_IN);
}
else if (r != HES_CONTINUE)
{
exit(r);
}
else if (a.amagic != ADNS_A_MAGIC)
{
syslog(LOG_ERR, "Input from worker error: bad magic");
exit(HES_BAD_MAGIC);
}
else if (a.continuation != w->continuation)
{
/* answer doesn't match query */
syslog(LOG_ERR, "Input from worker error: continuation mismatch");
exit(HES_SYNC);
}
else
{
/* pass the answer on to Pluto */
enum helper_exit_status r
= write_pipe(PLUTO_AFD, (const unsigned char *) &a);
if (r != HES_CONTINUE)
exit(r);
w->busy = FALSE;
forward_query(w);
}
if (r != HES_CONTINUE)
exit(r);
w->busy = FALSE;
forward_query(w);
}
}
/* assumption: input limited; accept blocking on output */
static int
master(void)
{
for (;;)
{
fd_set readfds;
int maxfd = PLUTO_QFD; /* approximate lower bound */
int ndes = 0;
struct worker_info *w;
for (;;)
{
fd_set readfds;
int maxfd = PLUTO_QFD; /* approximate lower bound */
int ndes = 0;
struct worker_info *w;
FD_ZERO(&readfds);
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))
FD_ZERO(&readfds);
if (!eof_from_pluto)
{
answer(w);
ndes--;
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);
ndes--;
}
}
}
}
}
}
}
/* Not to be invoked by strangers -- user hostile.
@ -574,42 +574,42 @@ master(void)
static void
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, "\n%s\n", ipsec_version_string());
fprintf(stderr, fmt, arg);
fprintf(stderr, "\n%s\n", ipsec_version_string());
for (; *sp != NULL; sp++)
fprintf(stderr, "%s\n", *sp);
for (; *sp != NULL; sp++)
fprintf(stderr, "%s\n", *sp);
syslog(LOG_ERR, fmt, arg);
exit(HES_INVOCATION);
syslog(LOG_ERR, fmt, arg);
exit(HES_INVOCATION);
}
int
main(int argc UNUSED, char **argv)
{
int i = 1;
int i = 1;
name = argv[0];
name = argv[0];
while (i < argc)
{
if (streq(argv[i], "-d"))
while (i < argc)
{
i++;
debug = TRUE;
if (streq(argv[i], "-d"))
{
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 */

View File

@ -14,7 +14,7 @@
* 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,
* so we build some of our own :-(
@ -38,38 +38,38 @@
*/
struct adns_query {
size_t len;
unsigned int qmagic;
unsigned long serial;
lset_t debugging; /* only used #ifdef DEBUG, but don't want layout to change */
u_char name_buf[NS_MAXDNAME + 2];
int type; /* T_KEY or T_TXT */
size_t len;
unsigned int qmagic;
unsigned long serial;
lset_t debugging; /* only used #ifdef DEBUG, but don't want layout to change */
u_char name_buf[NS_MAXDNAME + 2];
int type; /* T_KEY or T_TXT */
};
struct adns_answer {
size_t len;
unsigned int amagic;
unsigned long serial;
struct adns_continuation *continuation;
int result;
int h_errno_val;
u_char ans[NS_PACKETSZ * 10]; /* very probably bigger than necessary */
size_t len;
unsigned int amagic;
unsigned long serial;
struct adns_continuation *continuation;
int result;
int h_errno_val;
u_char ans[NS_PACKETSZ * 10]; /* very probably bigger than necessary */
};
enum helper_exit_status {
HES_CONTINUE = -1, /* not an exit */
HES_OK = 0, /* all's well that ends well (perhaps EOF) */
HES_INVOCATION, /* improper invocation */
HES_IO_ERROR_SELECT, /* IO error in select() */
HES_MALLOC, /* malloc failed */
HES_IO_ERROR_IN, /* error reading pipe */
HES_IO_ERROR_OUT, /* error reading pipe */
HES_PIPE, /* pipe(2) failed */
HES_SYNC, /* answer from worker doesn't match query */
HES_FORK, /* fork(2) failed */
HES_RES_INIT, /* resolver initialization failed */
HES_BAD_LEN, /* implausible .len field */
HES_BAD_MAGIC, /* .magic field wrong */
HES_CONTINUE = -1, /* not an exit */
HES_OK = 0, /* all's well that ends well (perhaps EOF) */
HES_INVOCATION, /* improper invocation */
HES_IO_ERROR_SELECT, /* IO error in select() */
HES_MALLOC, /* malloc failed */
HES_IO_ERROR_IN, /* error reading pipe */
HES_IO_ERROR_OUT, /* error reading pipe */
HES_PIPE, /* pipe(2) failed */
HES_SYNC, /* answer from worker doesn't match query */
HES_FORK, /* fork(2) failed */
HES_RES_INIT, /* resolver initialization failed */
HES_BAD_LEN, /* implausible .len field */
HES_BAD_MAGIC, /* .magic field wrong */
};
#endif /* !USE_LWRES */

File diff suppressed because it is too large Load Diff

View File

@ -18,49 +18,49 @@
#define ALG_INFO_H
struct esp_info {
u_int8_t transid; /* ESP transform */
u_int16_t auth; /* AUTH */
size_t enckeylen; /* keylength for ESP transform */
size_t authkeylen; /* keylength for AUTH */
u_int8_t encryptalg; /* normally encryptalg=transid */
u_int8_t authalg; /* normally authalg=auth+1 */
u_int8_t transid; /* ESP transform */
u_int16_t auth; /* AUTH */
size_t enckeylen; /* keylength for ESP transform */
size_t authkeylen; /* keylength for AUTH */
u_int8_t encryptalg; /* normally encryptalg=transid */
u_int8_t authalg; /* normally authalg=auth+1 */
};
struct ike_info {
u_int16_t ike_ealg; /* high 16 bit nums for reserved */
u_int8_t ike_halg;
size_t ike_eklen;
size_t ike_hklen;
u_int16_t ike_modp;
u_int16_t ike_ealg; /* high 16 bit nums for reserved */
u_int8_t ike_halg;
size_t ike_eklen;
size_t ike_hklen;
u_int16_t ike_modp;
};
#define ALG_INFO_COMMON \
int alg_info_cnt; \
int ref_cnt; \
unsigned alg_info_flags; \
unsigned alg_info_protoid
int alg_info_cnt; \
int ref_cnt; \
unsigned alg_info_flags; \
unsigned alg_info_protoid
struct alg_info {
ALG_INFO_COMMON;
ALG_INFO_COMMON;
};
struct alg_info_esp {
ALG_INFO_COMMON;
struct esp_info esp[64];
int esp_pfsgroup;
ALG_INFO_COMMON;
struct esp_info esp[64];
int esp_pfsgroup;
};
struct alg_info_ike {
ALG_INFO_COMMON;
struct ike_info ike[64];
ALG_INFO_COMMON;
struct ike_info ike[64];
};
#define esp_ealg_id transid
#define esp_aalg_id auth
#define esp_ealg_keylen enckeylen /* bits */
#define esp_aalg_keylen authkeylen /* bits */
#define esp_ealg_keylen enckeylen /* bits */
#define esp_aalg_keylen authkeylen /* bits */
/* alg_info_flags bits */
#define ALG_INFO_F_STRICT 0x01
/* alg_info_flags bits */
#define ALG_INFO_F_STRICT 0x01
extern int alg_info_esp_aa2sadb(int auth);
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_delref(struct alg_info **alg_info);
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
, const char **err_p);
, const char **err_p);
extern int alg_info_parse(const char *str);
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
, struct alg_info_esp *alg_info);
, struct alg_info_esp *alg_info);
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) \
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) \
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 */

File diff suppressed because it is too large Load Diff

View File

@ -25,82 +25,82 @@
/* Defines some primitive ASN1 types */
typedef enum {
ASN1_EOC = 0x00,
ASN1_BOOLEAN = 0x01,
ASN1_INTEGER = 0x02,
ASN1_BIT_STRING = 0x03,
ASN1_OCTET_STRING = 0x04,
ASN1_NULL = 0x05,
ASN1_OID = 0x06,
ASN1_ENUMERATED = 0x0A,
ASN1_UTF8STRING = 0x0C,
ASN1_NUMERICSTRING = 0x12,
ASN1_PRINTABLESTRING = 0x13,
ASN1_T61STRING = 0x14,
ASN1_VIDEOTEXSTRING = 0x15,
ASN1_IA5STRING = 0x16,
ASN1_UTCTIME = 0x17,
ASN1_GENERALIZEDTIME = 0x18,
ASN1_GRAPHICSTRING = 0x19,
ASN1_VISIBLESTRING = 0x1A,
ASN1_GENERALSTRING = 0x1B,
ASN1_UNIVERSALSTRING = 0x1C,
ASN1_BMPSTRING = 0x1E,
ASN1_EOC = 0x00,
ASN1_BOOLEAN = 0x01,
ASN1_INTEGER = 0x02,
ASN1_BIT_STRING = 0x03,
ASN1_OCTET_STRING = 0x04,
ASN1_NULL = 0x05,
ASN1_OID = 0x06,
ASN1_ENUMERATED = 0x0A,
ASN1_UTF8STRING = 0x0C,
ASN1_NUMERICSTRING = 0x12,
ASN1_PRINTABLESTRING = 0x13,
ASN1_T61STRING = 0x14,
ASN1_VIDEOTEXSTRING = 0x15,
ASN1_IA5STRING = 0x16,
ASN1_UTCTIME = 0x17,
ASN1_GENERALIZEDTIME = 0x18,
ASN1_GRAPHICSTRING = 0x19,
ASN1_VISIBLESTRING = 0x1A,
ASN1_GENERALSTRING = 0x1B,
ASN1_UNIVERSALSTRING = 0x1C,
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_1 = 0x81,
ASN1_CONTEXT_S_2 = 0x82,
ASN1_CONTEXT_S_3 = 0x83,
ASN1_CONTEXT_S_4 = 0x84,
ASN1_CONTEXT_S_5 = 0x85,
ASN1_CONTEXT_S_6 = 0x86,
ASN1_CONTEXT_S_7 = 0x87,
ASN1_CONTEXT_S_8 = 0x88,
ASN1_CONTEXT_S_0 = 0x80,
ASN1_CONTEXT_S_1 = 0x81,
ASN1_CONTEXT_S_2 = 0x82,
ASN1_CONTEXT_S_3 = 0x83,
ASN1_CONTEXT_S_4 = 0x84,
ASN1_CONTEXT_S_5 = 0x85,
ASN1_CONTEXT_S_6 = 0x86,
ASN1_CONTEXT_S_7 = 0x87,
ASN1_CONTEXT_S_8 = 0x88,
ASN1_CONTEXT_C_0 = 0xA0,
ASN1_CONTEXT_C_1 = 0xA1,
ASN1_CONTEXT_C_2 = 0xA2,
ASN1_CONTEXT_C_3 = 0xA3,
ASN1_CONTEXT_C_4 = 0xA4,
ASN1_CONTEXT_C_5 = 0xA5
ASN1_CONTEXT_C_0 = 0xA0,
ASN1_CONTEXT_C_1 = 0xA1,
ASN1_CONTEXT_C_2 = 0xA2,
ASN1_CONTEXT_C_3 = 0xA3,
ASN1_CONTEXT_C_4 = 0xA4,
ASN1_CONTEXT_C_5 = 0xA5
} asn1_t;
/* Definition of ASN1 flags */
#define ASN1_NONE 0x00
#define ASN1_DEF 0x01
#define ASN1_OPT 0x02
#define ASN1_LOOP 0x04
#define ASN1_END 0x08
#define ASN1_OBJ 0x10
#define ASN1_BODY 0x20
#define ASN1_RAW 0x40
#define ASN1_NONE 0x00
#define ASN1_DEF 0x01
#define ASN1_OPT 0x02
#define ASN1_LOOP 0x04
#define ASN1_END 0x08
#define ASN1_OBJ 0x10
#define ASN1_BODY 0x20
#define ASN1_RAW 0x40
#define ASN1_INVALID_LENGTH 0xffffffff
#define ASN1_INVALID_LENGTH 0xffffffff
/* definition of an ASN.1 object */
typedef struct {
u_int level;
const u_char *name;
asn1_t type;
u_char flags;
u_int level;
const u_char *name;
asn1_t type;
u_char flags;
} asn1Object_t;
#define ASN1_MAX_LEVEL 10
#define ASN1_MAX_LEVEL 10
typedef struct {
bool implicit;
u_int cond;
u_int level0;
u_int loopAddr[ASN1_MAX_LEVEL+1];
chunk_t blobs[ASN1_MAX_LEVEL+2];
bool implicit;
u_int cond;
u_int level0;
u_int loopAddr[ASN1_MAX_LEVEL+1];
chunk_t blobs[ASN1_MAX_LEVEL+2];
} asn1_ctx_t;
/* 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 chunk_t timetoasn1(const time_t *time, asn1_t type);
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
, 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
, const char* name);
, const char* name);
extern int parse_algorithmIdentifier(chunk_t blob, int level0
, chunk_t *parameters);
, chunk_t *parameters);
extern bool is_asn1(chunk_t blob);
#endif /* _ASN1_H */

File diff suppressed because it is too large Load Diff

View File

@ -20,45 +20,45 @@
#include "x509.h"
#include "whack.h"
#define MAX_CA_PATH_LEN 7
#define MAX_CA_PATH_LEN 7
/* authority flags */
#define AUTH_NONE 0x00 /* no authorities */
#define AUTH_CA 0x01 /* certification authority */
#define AUTH_AA 0x02 /* authorization authority */
#define AUTH_OCSP 0x04 /* ocsp signing authority */
#define AUTH_NONE 0x00 /* no authorities */
#define AUTH_CA 0x01 /* certification authority */
#define AUTH_AA 0x02 /* authorization authority */
#define AUTH_OCSP 0x04 /* ocsp signing authority */
/* CA info structures */
typedef struct ca_info ca_info_t;
struct ca_info {
ca_info_t *next;
char *name;
time_t installed;
chunk_t authName;
chunk_t authKeyID;
chunk_t authKeySerialNumber;
char *ldaphost;
char *ldapbase;
char *ocspuri;
generalName_t *crluri;
bool strictcrlpolicy;
ca_info_t *next;
char *name;
time_t installed;
chunk_t authName;
chunk_t authKeyID;
chunk_t authKeySerialNumber;
char *ldaphost;
char *ldapbase;
char *ocspuri;
generalName_t *crluri;
bool strictcrlpolicy;
};
extern bool trusted_ca(chunk_t a, chunk_t b, int *pathlen);
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
, u_char auth_flags);
, u_char auth_flags);
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 void free_authcerts(void);
extern void list_authcerts(const char *caption, u_char auth_flags, bool utc);
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 bool find_ca_info_by_name(const char *name, bool delete);
extern void add_ca_info(const whack_message_t *msg);

View File

@ -43,15 +43,15 @@ const cert_t empty_cert = {CERT_NONE, {NULL}};
chunk_t
get_mycert(cert_t cert)
{
switch (cert.type)
{
case CERT_PGP:
return cert.u.pgp->certificate;
case CERT_X509_SIGNATURE:
return cert.u.x509->certificate;
default:
return chunk_empty;
}
switch (cert.type)
{
case CERT_PGP:
return cert.u.pgp->certificate;
case CERT_X509_SIGNATURE:
return cert.u.x509->certificate;
default:
return chunk_empty;
}
}
/* 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
, 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)
{
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))
if (fd)
{
DBG(DBG_PARSING,
DBG_log(" file coded in DER format");
)
return TRUE;
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,
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;
}
/* try PEM format */
ugh = pemtobin(blob, pass, filename, pgp);
if (ugh == NULL)
else
{
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";
plog(" could not open %s file '%s'", type, filename);
}
/* 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;
return FALSE;
}
/*
@ -128,30 +128,30 @@ err_t
load_rsa_private_key(const char* filename, prompt_pass_t *pass
, RSA_private_key_t *key)
{
err_t ugh = NULL;
bool pgp = FALSE;
chunk_t blob = chunk_empty;
err_t ugh = NULL;
bool pgp = FALSE;
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 (pgp)
if (load_coded_file(path, pass, "private key", &blob, &pgp))
{
if (!parse_pgp(blob, NULL, key))
ugh = "syntax error in PGP private key file";
if (pgp)
{
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
{
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";
ugh = "error loading RSA private key file";
return ugh;
return ugh;
}
/*
* Loads a X.509 or OpenPGP certificate
@ -159,51 +159,51 @@ load_rsa_private_key(const char* filename, prompt_pass_t *pass
bool
load_cert(const char *filename, const char *label, cert_t *cert)
{
bool pgp = FALSE;
chunk_t blob = chunk_empty;
bool pgp = FALSE;
chunk_t blob = chunk_empty;
/* initialize cert struct */
cert->type = CERT_NONE;
cert->u.x509 = NULL;
/* initialize cert struct */
cert->type = CERT_NONE;
cert->u.x509 = NULL;
if (load_coded_file(filename, NULL, label, &blob, &pgp))
{
if (pgp)
if (load_coded_file(filename, NULL, label, &blob, &pgp))
{
pgpcert_t *pgpcert = malloc_thing(pgpcert_t);
*pgpcert = empty_pgpcert;
if (parse_pgp(blob, pgpcert, NULL))
{
cert->type = CERT_PGP;
cert->u.pgp = pgpcert;
return TRUE;
}
else
{
plog(" error in OpenPGP certificate");
free_pgpcert(pgpcert);
return FALSE;
}
if (pgp)
{
pgpcert_t *pgpcert = malloc_thing(pgpcert_t);
*pgpcert = empty_pgpcert;
if (parse_pgp(blob, pgpcert, NULL))
{
cert->type = CERT_PGP;
cert->u.pgp = pgpcert;
return TRUE;
}
else
{
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
{
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;
return FALSE;
}
/*
@ -212,9 +212,9 @@ load_cert(const char *filename, const char *label, cert_t *cert)
bool
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
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
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
@ -243,17 +243,17 @@ same_cert(const cert_t *a, const cert_t *b)
void
share_cert(cert_t cert)
{
switch (cert.type)
{
case CERT_PGP:
share_pgpcert(cert.u.pgp);
break;
case CERT_X509_SIGNATURE:
share_x509cert(cert.u.x509);
break;
default:
break;
}
switch (cert.type)
{
case CERT_PGP:
share_pgpcert(cert.u.pgp);
break;
case CERT_X509_SIGNATURE:
share_x509cert(cert.u.x509);
break;
default:
break;
}
}
/* release of a certificate decreases the count by one
@ -263,16 +263,16 @@ void
release_cert(cert_t cert)
{
switch (cert.type)
{
case CERT_PGP:
release_pgpcert(cert.u.pgp);
break;
case CERT_X509_SIGNATURE:
release_x509cert(cert.u.x509);
break;
default:
break;
}
{
case CERT_PGP:
release_pgpcert(cert.u.pgp);
break;
case CERT_X509_SIGNATURE:
release_x509cert(cert.u.x509);
break;
default:
break;
}
}
/*
@ -281,7 +281,7 @@ release_cert(cert_t cert)
void
list_certs(bool utc)
{
list_x509_end_certs(utc);
list_pgp_end_certs(utc);
list_x509_end_certs(utc);
list_pgp_end_certs(utc);
}

View File

@ -26,31 +26,31 @@
*/
#define PRIVATE_KEY_PATH IPSEC_CONFDIR "/ipsec.d/private"
#define HOST_CERT_PATH IPSEC_CONFDIR "/ipsec.d/certs"
#define CA_CERT_PATH IPSEC_CONFDIR "/ipsec.d/cacerts"
#define A_CERT_PATH IPSEC_CONFDIR "/ipsec.d/acerts"
#define AA_CERT_PATH IPSEC_CONFDIR "/ipsec.d/aacerts"
#define OCSP_CERT_PATH IPSEC_CONFDIR "/ipsec.d/ocspcerts"
#define CRL_PATH IPSEC_CONFDIR "/ipsec.d/crls"
#define REQ_PATH IPSEC_CONFDIR "/ipsec.d/reqs"
#define CA_CERT_PATH IPSEC_CONFDIR "/ipsec.d/cacerts"
#define A_CERT_PATH IPSEC_CONFDIR "/ipsec.d/acerts"
#define AA_CERT_PATH IPSEC_CONFDIR "/ipsec.d/aacerts"
#define OCSP_CERT_PATH IPSEC_CONFDIR "/ipsec.d/ocspcerts"
#define CRL_PATH IPSEC_CONFDIR "/ipsec.d/crls"
#define REQ_PATH IPSEC_CONFDIR "/ipsec.d/reqs"
/* advance warning of imminent expiry of
* cacerts, public keys, and crls
*/
#define CA_CERT_WARNING_INTERVAL 30 /* days */
#define OCSP_CERT_WARNING_INTERVAL 30 /* days */
#define PUBKEY_WARNING_INTERVAL 7 /* days */
#define CRL_WARNING_INTERVAL 7 /* days */
#define ACERT_WARNING_INTERVAL 1 /* day */
#define CA_CERT_WARNING_INTERVAL 30 /* days */
#define OCSP_CERT_WARNING_INTERVAL 30 /* days */
#define PUBKEY_WARNING_INTERVAL 7 /* days */
#define CRL_WARNING_INTERVAL 7 /* days */
#define ACERT_WARNING_INTERVAL 1 /* day */
/* certificate access structure
* currently X.509 and OpenPGP certificates are supported
*/
typedef struct {
u_char type;
union {
x509cert_t *x509;
pgpcert_t *pgp;
} u;
u_char type;
union {
x509cert_t *x509;
pgpcert_t *pgp;
} u;
} cert_t;
/* used for initialization */
@ -62,12 +62,12 @@ extern const cert_t empty_cert;
extern bool no_cr_send;
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 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
, cert_t *cert);
, 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 same_cert(const cert_t *a, const cert_t *b);

File diff suppressed because it is too large Load Diff

View File

@ -118,135 +118,135 @@
* - display format: n,m
*/
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 = \
((policy_prio_t)(c)->spd.this.client.maskbits << 16) \
| ((policy_prio_t)(c)->spd.that.client.maskbits << 8) \
| (policy_prio_t)1; }
#define POLICY_PRIO_BUF (3+1+3+1)
((policy_prio_t)(c)->spd.this.client.maskbits << 16) \
| ((policy_prio_t)(c)->spd.that.client.maskbits << 8) \
| (policy_prio_t)1; }
#define POLICY_PRIO_BUF (3+1+3+1)
extern void fmt_policy_prio(policy_prio_t pp, char buf[POLICY_PRIO_BUF]);
struct virtual_t;
struct end {
struct id id;
ip_address
host_addr,
host_nexthop,
host_srcip;
ip_subnet client;
struct id id;
ip_address
host_addr,
host_nexthop,
host_srcip;
ip_subnet client;
bool key_from_DNS_on_demand;
bool has_client;
bool has_client_wildcard;
bool has_port_wildcard;
bool has_id_wildcards;
bool has_natip;
char *updown;
u_int16_t host_port; /* host order */
u_int16_t port; /* host order */
u_int8_t protocol;
cert_t cert; /* end certificate */
chunk_t ca; /* CA distinguished name */
struct ietfAttrList *groups;/* access control groups */
smartcard_t *sc; /* smartcard reader and key info */
struct virtual_t *virt;
bool modecfg; /* this end: request local address from server */
/* that end: give local addresses to clients */
bool hostaccess; /* allow access to host via iptables INPUT/OUTPUT */
/* rules if client behind host is a subnet */
bool allow_any; /* IP address is subject to change */
certpolicy_t sendcert; /* whether or not to send the certificate */
bool key_from_DNS_on_demand;
bool has_client;
bool has_client_wildcard;
bool has_port_wildcard;
bool has_id_wildcards;
bool has_natip;
char *updown;
u_int16_t host_port; /* host order */
u_int16_t port; /* host order */
u_int8_t protocol;
cert_t cert; /* end certificate */
chunk_t ca; /* CA distinguished name */
struct ietfAttrList *groups;/* access control groups */
smartcard_t *sc; /* smartcard reader and key info */
struct virtual_t *virt;
bool modecfg; /* this end: request local address from server */
/* that end: give local addresses to clients */
bool hostaccess; /* allow access to host via iptables INPUT/OUTPUT */
/* rules if client behind host is a subnet */
bool allow_any; /* IP address is subject to change */
certpolicy_t sendcert; /* whether or not to send the certificate */
};
struct spd_route {
struct spd_route *next;
struct end this;
struct end that;
so_serial_t eroute_owner;
enum routing_t routing; /* level of routing in place */
uint32_t reqid;
struct spd_route *next;
struct end this;
struct end that;
so_serial_t eroute_owner;
enum routing_t routing; /* level of routing in place */
uint32_t reqid;
};
struct connection {
char *name;
bool ikev1;
char *name;
bool ikev1;
lset_t policy;
time_t sa_ike_life_seconds;
time_t sa_ipsec_life_seconds;
time_t sa_rekey_margin;
unsigned long sa_rekey_fuzz;
unsigned long sa_keying_tries;
lset_t policy;
time_t sa_ike_life_seconds;
time_t sa_ipsec_life_seconds;
time_t sa_rekey_margin;
unsigned long sa_rekey_fuzz;
unsigned long sa_keying_tries;
/* RFC 3706 DPD */
time_t dpd_delay;
time_t dpd_timeout;
dpd_action_t dpd_action;
/* RFC 3706 DPD */
time_t dpd_delay;
time_t dpd_timeout;
dpd_action_t dpd_action;
char *log_file_name; /* name of log file */
FILE *log_file; /* possibly open FILE */
TAILQ_ENTRY(connection) log_link; /* linked list of open conns */
bool log_file_err; /* only bitch once */
char *log_file_name; /* name of log file */
FILE *log_file; /* possibly open FILE */
TAILQ_ENTRY(connection) log_link; /* linked list of open conns */
bool log_file_err; /* only bitch once */
struct spd_route spd;
struct spd_route spd;
/* internal fields: */
/* internal fields: */
unsigned long instance_serial;
policy_prio_t prio;
bool instance_initiation_ok; /* this is an instance of a policy that mandates initiate */
enum connection_kind kind;
const struct iface *interface; /* filled in iff oriented */
unsigned long instance_serial;
policy_prio_t prio;
bool instance_initiation_ok; /* this is an instance of a policy that mandates initiate */
enum connection_kind kind;
const struct iface *interface; /* filled in iff oriented */
so_serial_t /* state object serial number */
newest_isakmp_sa,
newest_ipsec_sa;
so_serial_t /* state object serial number */
newest_isakmp_sa,
newest_ipsec_sa;
#ifdef DEBUG
lset_t extra_debugging;
lset_t extra_debugging;
#endif
/* note: if the client is the gateway, the following must be equal */
sa_family_t addr_family; /* between gateways */
sa_family_t tunnel_addr_family; /* between clients */
/* note: if the client is the gateway, the following must be equal */
sa_family_t addr_family; /* between gateways */
sa_family_t tunnel_addr_family; /* between clients */
struct connection *policy_next; /* if multiple policies,
next one to apply */
struct connection *policy_next; /* if multiple policies,
next one to apply */
struct gw_info *gw_info;
struct alg_info_esp *alg_info_esp;
struct alg_info_ike *alg_info_ike;
struct gw_info *gw_info;
struct alg_info_esp *alg_info_esp;
struct alg_info_ike *alg_info_ike;
struct host_pair *host_pair;
struct connection *hp_next; /* host pair list link */
struct host_pair *host_pair;
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 */
bool got_certrequest;
generalName_t *requested_ca; /* collected certificate requests */
bool got_certrequest;
};
#define oriented(c) ((c).interface != NULL)
extern bool orient(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.
* Largest left end looks like: client === host : port [ host_id ] --- hop
* 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
, const struct end *this, const struct end *that
, bool is_left, lset_t policy);
, const struct end *this, const struct end *that
, bool is_left, lset_t policy);
extern void add_connection(const whack_message_t *wm);
extern void initiate_connection(const char *name, int whackfd);
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 release_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 check_orientations(void);
extern struct connection *route_owner(struct connection *c
, struct spd_route **srp
, struct connection **erop
, struct spd_route **esrp);
, struct spd_route **srp
, struct connection **erop
, struct spd_route **esrp);
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);
#define his_id_was_instantiated(c) ((c)->kind == CK_INSTANCE \
&& (id_is_ipaddr(&(c)->spd.that.id)? \
sameaddr(&(c)->spd.that.id.ip_addr, &(c)->spd.that.host_addr) : TRUE))
&& (id_is_ipaddr(&(c)->spd.that.id)? \
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
*con_by_name(const char *nm, bool strict),
*find_host_connection(const ip_address *me, u_int16_t my_port
, const ip_address *him, u_int16_t his_port, lset_t policy),
*refine_host_connection(const struct state *st, const struct id *id
, chunk_t peer_ca),
*find_client_connection(struct connection *c
, const ip_subnet *our_net
, const ip_subnet *peer_net
, const u_int8_t our_protocol
, const u_int16_t out_port
, const u_int8_t peer_protocol
, const u_int16_t peer_port),
*find_connection_by_reqid(uint32_t reqid);
*con_by_name(const char *nm, bool strict),
*find_host_connection(const ip_address *me, u_int16_t my_port
, const ip_address *him, u_int16_t his_port, lset_t policy),
*refine_host_connection(const struct state *st, const struct id *id
, chunk_t peer_ca),
*find_client_connection(struct connection *c
, const ip_subnet *our_net
, const ip_subnet *peer_net
, const u_int8_t our_protocol
, const u_int16_t out_port
, const u_int8_t peer_protocol
, const u_int16_t peer_port),
*find_connection_by_reqid(uint32_t reqid);
extern struct connection *
find_connection_for_clients(struct spd_route **srp
, const ip_address *our_client
, const ip_address *peer_client
, int transport_proto);
, const ip_address *our_client
, const ip_address *peer_client
, int transport_proto);
extern chunk_t get_peer_ca_and_groups(struct connection *c
, const ietfAttrList_t **peer_list);
, const ietfAttrList_t **peer_list);
/* instantiating routines
* Note: connection_discard() is in state.h because all its work
* is looking through state objects.
*/
struct gw_info; /* forward declaration of tag (defined in dnskey.h) */
struct alg_info; /* forward declaration of tag (defined in alg_info.h) */
struct gw_info; /* forward declaration of tag (defined in dnskey.h) */
struct alg_info; /* forward declaration of tag (defined in alg_info.h) */
extern struct connection *rw_instantiate(struct connection *c
, const ip_address *him
, u_int16_t his_port
, const ip_subnet *his_net
, const struct id *his_id);
, const ip_address *him
, u_int16_t his_port
, const ip_subnet *his_net
, const struct id *his_id);
extern struct connection *oppo_instantiate(struct connection *c
, const ip_address *him
, const struct id *his_id
, struct gw_info *gw
, const ip_address *our_client
, const ip_address *peer_client);
, const ip_address *him
, const struct id *his_id
, struct gw_info *gw
, const ip_address *our_client
, const ip_address *peer_client);
extern struct connection
*build_outgoing_opportunistic_connection(struct gw_info *gw
, const ip_address *our_client
, const ip_address *peer_client);
, const ip_address *our_client
, const ip_address *peer_client);
/* worst case: "[" serial "] " myclient "=== ..." peer "===" hisclient '\0' */
#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
, char buf[CONN_INST_BUF]);
, char buf[CONN_INST_BUF]);
/* operations on "pending", the structure representing Quick Mode
* 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
, struct state *isakmp_sa
, struct connection *c
, lset_t policy
, unsigned long try
, so_serial_t replacing);
, struct state *isakmp_sa
, struct connection *c
, lset_t policy
, unsigned long try
, so_serial_t replacing);
extern void release_pending_whacks(struct state *st, err_t story);
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 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
, const ip_address *myaddr, u_int16_t myport
, const ip_address *hisaddr, u_int16_t hisport);
, const ip_address *myaddr, u_int16_t myport
, const ip_address *hisaddr, u_int16_t hisport);
#endif /* _CONNECTIONS_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,7 @@
#include "rnd.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.
* 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
get_cookie(bool initiator, u_int8_t *cookie, int length, const ip_address *addr)
{
u_char buffer[SHA1_DIGEST_SIZE];
SHA1_CTX ctx;
u_char buffer[SHA1_DIGEST_SIZE];
SHA1_CTX ctx;
do {
if (initiator)
{
get_rnd_bytes(cookie, length);
}
else /* Responder cookie */
{
/* This looks as good as any way */
size_t addr_length;
static u_int32_t counter = 0;
unsigned char addr_buff[
sizeof(union {struct in_addr A; struct in6_addr B;})];
do {
if (initiator)
{
get_rnd_bytes(cookie, length);
}
else /* Responder cookie */
{
/* This looks as good as any way */
size_t addr_length;
static u_int32_t counter = 0;
unsigned char addr_buff[
sizeof(union {struct in_addr A; struct in6_addr B;})];
addr_length = addrbytesof(addr, addr_buff, sizeof(addr_buff));
SHA1Init(&ctx);
SHA1Update(&ctx, addr_buff, addr_length);
SHA1Update(&ctx, secret_of_the_day, sizeof(secret_of_the_day));
counter++;
SHA1Update(&ctx, (const void *) &counter, sizeof(counter));
SHA1Final(buffer, &ctx);
memcpy(cookie, buffer, length);
}
} while (is_zero_cookie(cookie)); /* probably never loops */
addr_length = addrbytesof(addr, addr_buff, sizeof(addr_buff));
SHA1Init(&ctx);
SHA1Update(&ctx, addr_buff, addr_length);
SHA1Update(&ctx, secret_of_the_day, sizeof(secret_of_the_day));
counter++;
SHA1Update(&ctx, (const void *) &counter, sizeof(counter));
SHA1Final(buffer, &ctx);
memcpy(cookie, buffer, length);
}
} while (is_zero_cookie(cookie)); /* probably never loops */
}

View File

@ -16,9 +16,9 @@
#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
, const ip_address *addr);
, const ip_address *addr);
#define is_zero_cookie(cookie) all_zero((cookie), COOKIE_SIZE)

File diff suppressed because it is too large Load Diff

View File

@ -22,9 +22,9 @@ typedef struct revokedCert revokedCert_t;
struct revokedCert{
revokedCert_t *next;
chunk_t userCertificate;
time_t revocationDate;
crl_reason_t revocationReason;
chunk_t userCertificate;
time_t revocationDate;
crl_reason_t revocationReason;
};
/* storage structure for an X.509 CRL */
@ -33,28 +33,28 @@ typedef struct x509crl x509crl_t;
struct x509crl {
x509crl_t *next;
time_t installed;
time_t installed;
generalName_t *distributionPoints;
chunk_t certificateList;
chunk_t tbsCertList;
u_int version;
/* signature */
/* signature */
int sigAlg;
chunk_t issuer;
time_t thisUpdate;
time_t nextUpdate;
revokedCert_t *revokedCertificates;
/* v2 extensions */
/* crlExtensions */
/* extension */
/* extnID */
/* critical */
/* extnValue */
chunk_t authKeyID;
chunk_t authKeySerialNumber;
chunk_t crlNumber;
/* v2 extensions */
/* crlExtensions */
/* extension */
/* extnID */
/* critical */
/* extnValue */
chunk_t authKeyID;
chunk_t authKeySerialNumber;
chunk_t crlNumber;
/* signatureAlgorithm */
/* signatureAlgorithm */
int algorithm;
chunk_t signature;
};
@ -82,7 +82,7 @@ extern void load_crls(void);
extern void check_crls(void);
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
, time_t *revocationDate, crl_reason_t *revocationReason);
, time_t *revocationDate, crl_reason_t *revocationReason);
extern void list_crls(bool utc, bool strict);
extern void free_crls(void);
extern void free_crl(x509crl_t *crl);

View File

@ -40,29 +40,29 @@
/* moduli and generator. */
static MP_INT
modp1024_modulus,
modp1536_modulus,
modp2048_modulus,
modp3072_modulus,
modp4096_modulus,
modp6144_modulus,
modp8192_modulus;
modp1024_modulus,
modp1536_modulus,
modp2048_modulus,
modp3072_modulus,
modp4096_modulus,
modp6144_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 struct encrypt_desc crypto_encryptor_3des =
{
algo_type: IKE_ALG_ENCRYPT,
algo_id: OAKLEY_3DES_CBC,
algo_next: NULL,
enc_ctxsize: sizeof(des_key_schedule) * 3,
enc_blocksize: DES_CBC_BLOCK_SIZE,
keydeflen: 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,
do_crypt: do_3des,
{
algo_type: IKE_ALG_ENCRYPT,
algo_id: OAKLEY_3DES_CBC,
algo_next: NULL,
enc_ctxsize: sizeof(des_key_schedule) * 3,
enc_blocksize: DES_CBC_BLOCK_SIZE,
keydeflen: 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,
do_crypt: do_3des,
};
/* MD5 hash test vectors
@ -75,93 +75,93 @@ static const u_char md5_test0_msg[] = {
};
static const u_char md5_test0_msg_digest[] = {
0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e
0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e
};
static const u_char md5_test1_msg[] = {
0x61
0x61
};
static const u_char md5_test1_msg_digest[] = {
0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61
0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61
};
static const u_char md5_test2_msg[] = {
0x61, 0x62, 0x63
0x61, 0x62, 0x63
};
static const u_char md5_test2_msg_digest[] = {
0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72
0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72
};
static const u_char md5_test3_msg[] = {
0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20,
0x64, 0x69, 0x67, 0x65, 0x73, 0x74
0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20,
0x64, 0x69, 0x67, 0x65, 0x73, 0x74
};
static const u_char md5_test3_msg_digest[] = {
0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0
0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0
};
static const u_char md5_test4_msg[] = {
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
0x79, 0x7a
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
0x79, 0x7a
};
static const u_char md5_test4_msg_digest[] = {
0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b
0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b
};
static const u_char md5_test5_msg[] = {
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39
};
static const u_char md5_test5_msg_digest[] = {
0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f
0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f
};
static const u_char md5_test6_msg[] = {
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34,
0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32,
0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34,
0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32,
0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34,
0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32,
0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34,
0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32,
0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30
};
static const u_char md5_test6_msg_digest[] = {
0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a
0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a
};
static const hash_testvector_t md5_hash_testvectors[] = {
{ sizeof(md5_test0_msg), md5_test0_msg, md5_test0_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_test3_msg), md5_test3_msg, md5_test3_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_test6_msg), md5_test6_msg, md5_test6_msg_digest },
{ 0, NULL, NULL }
{ sizeof(md5_test0_msg), md5_test0_msg, md5_test0_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_test3_msg), md5_test3_msg, md5_test3_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_test6_msg), md5_test6_msg, md5_test6_msg_digest },
{ 0, NULL, NULL }
};
/* MD5 hmac test vectors
@ -170,146 +170,146 @@ static const hash_testvector_t md5_hash_testvectors[] = {
*/
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[] = {
0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65
0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65
};
static const u_char md5_hmac1[] = {
0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d
0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d
};
static const u_char md5_hmac2_key[] = {
0x4a, 0x65, 0x66, 0x65
0x4a, 0x65, 0x66, 0x65
};
static const u_char md5_hmac2_msg[] = {
0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20,
0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20,
0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68,
0x69, 0x6e, 0x67, 0x3f
0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20,
0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20,
0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68,
0x69, 0x6e, 0x67, 0x3f
};
static const u_char md5_hmac2[] = {
0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38
0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38
};
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[] = {
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[] = {
0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6
0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6
};
static const u_char md5_hmac4_key[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x19
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x19
};
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[] = {
0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea,
0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79
0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea,
0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79
};
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[] = {
0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69,
0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65,
0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a,
0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x2d, 0x20,
0x48, 0x61, 0x73, 0x68, 0x20, 0x4b, 0x65, 0x79,
0x20, 0x46, 0x69, 0x72, 0x73, 0x74
0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69,
0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65,
0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a,
0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x2d, 0x20,
0x48, 0x61, 0x73, 0x68, 0x20, 0x4b, 0x65, 0x79,
0x20, 0x46, 0x69, 0x72, 0x73, 0x74
};
static const u_char md5_hmac6[] = {
0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f,
0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd
0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f,
0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd
};
static const u_char md5_hmac7_msg[] = {
0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69,
0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65,
0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a,
0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x61, 0x6e,
0x64, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65, 0x72,
0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x4f, 0x6e,
0x65, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x2d,
0x53, 0x69, 0x7a, 0x65, 0x20, 0x44, 0x61, 0x74,
0x61
0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69,
0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65,
0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a,
0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x61, 0x6e,
0x64, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65, 0x72,
0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x4f, 0x6e,
0x65, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x2d,
0x53, 0x69, 0x7a, 0x65, 0x20, 0x44, 0x61, 0x74,
0x61
};
static const u_char md5_hmac7[] = {
0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee,
0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e
0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee,
0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e
};
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_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_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_hmac7_msg), md5_hmac7_msg, md5_hmac7 },
{ 0, NULL, 0, NULL, NULL }
{ 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_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_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 },
{ 0, NULL, 0, NULL, NULL }
};
static struct hash_desc crypto_hasher_md5 =
{
algo_type: IKE_ALG_HASH,
algo_id: OAKLEY_MD5,
algo_next: NULL,
hash_ctx_size: sizeof(MD5_CTX),
hash_block_size: MD5_BLOCK_SIZE,
hash_digest_size: MD5_DIGEST_SIZE,
hash_testvectors: md5_hash_testvectors,
hmac_testvectors: md5_hmac_testvectors,
hash_init: (void (*)(void *)) MD5Init,
hash_update: (void (*)(void *, const u_int8_t *, size_t)) MD5Update,
hash_final: (void (*)(u_char *, void *)) MD5Final
{
algo_type: IKE_ALG_HASH,
algo_id: OAKLEY_MD5,
algo_next: NULL,
hash_ctx_size: sizeof(MD5_CTX),
hash_block_size: MD5_BLOCK_SIZE,
hash_digest_size: MD5_DIGEST_SIZE,
hash_testvectors: md5_hash_testvectors,
hmac_testvectors: md5_hmac_testvectors,
hash_init: (void (*)(void *)) MD5Init,
hash_update: (void (*)(void *, const u_int8_t *, size_t)) MD5Update,
hash_final: (void (*)(u_char *, void *)) MD5Final
};
/* SHA-1 test vectors
@ -318,61 +318,61 @@ static struct hash_desc crypto_hasher_md5 =
*/
static const u_char sha1_short2_msg[] = {
0x5e
0x5e
};
static const u_char sha1_short2_msg_digest[] = {
0x5e, 0x6f, 0x80, 0xa3, 0x4a, 0x97, 0x98, 0xca,
0xfc, 0x6a, 0x5d, 0xb9, 0x6c, 0xc5, 0x7b, 0xa4,
0xc4, 0xdb, 0x59, 0xc2
0x5e, 0x6f, 0x80, 0xa3, 0x4a, 0x97, 0x98, 0xca,
0xfc, 0x6a, 0x5d, 0xb9, 0x6c, 0xc5, 0x7b, 0xa4,
0xc4, 0xdb, 0x59, 0xc2
};
static const u_char sha1_short4_msg[] = {
0x9a, 0x7d, 0xfd, 0xf1, 0xec, 0xea, 0xd0, 0x6e,
0xd6, 0x46, 0xaa, 0x55, 0xfe, 0x75, 0x71, 0x46
0x9a, 0x7d, 0xfd, 0xf1, 0xec, 0xea, 0xd0, 0x6e,
0xd6, 0x46, 0xaa, 0x55, 0xfe, 0x75, 0x71, 0x46
};
static const u_char sha1_short4_msg_digest[] = {
0x82, 0xab, 0xff, 0x66, 0x05, 0xdb, 0xe1, 0xc1,
0x7d, 0xef, 0x12, 0xa3, 0x94, 0xfa, 0x22, 0xa8,
0x2b, 0x54, 0x4a, 0x35
0x82, 0xab, 0xff, 0x66, 0x05, 0xdb, 0xe1, 0xc1,
0x7d, 0xef, 0x12, 0xa3, 0x94, 0xfa, 0x22, 0xa8,
0x2b, 0x54, 0x4a, 0x35
};
static const u_char sha1_long2_msg[] = {
0xf7, 0x8f, 0x92, 0x14, 0x1b, 0xcd, 0x17, 0x0a,
0xe8, 0x9b, 0x4f, 0xba, 0x15, 0xa1, 0xd5, 0x9f,
0x3f, 0xd8, 0x4d, 0x22, 0x3c, 0x92, 0x51, 0xbd,
0xac, 0xbb, 0xae, 0x61, 0xd0, 0x5e, 0xd1, 0x15,
0xa0, 0x6a, 0x7c, 0xe1, 0x17, 0xb7, 0xbe, 0xea,
0xd2, 0x44, 0x21, 0xde, 0xd9, 0xc3, 0x25, 0x92,
0xbd, 0x57, 0xed, 0xea, 0xe3, 0x9c, 0x39, 0xfa,
0x1f, 0xe8, 0x94, 0x6a, 0x84, 0xd0, 0xcf, 0x1f,
0x7b, 0xee, 0xad, 0x17, 0x13, 0xe2, 0xe0, 0x95,
0x98, 0x97, 0x34, 0x7f, 0x67, 0xc8, 0x0b, 0x04,
0x00, 0xc2, 0x09, 0x81, 0x5d, 0x6b, 0x10, 0xa6,
0x83, 0x83, 0x6f, 0xd5, 0x56, 0x2a, 0x56, 0xca,
0xb1, 0xa2, 0x8e, 0x81, 0xb6, 0x57, 0x66, 0x54,
0x63, 0x1c, 0xf1, 0x65, 0x66, 0xb8, 0x6e, 0x3b,
0x33, 0xa1, 0x08, 0xb0, 0x53, 0x07, 0xc0, 0x0a,
0xff, 0x14, 0xa7, 0x68, 0xed, 0x73, 0x50, 0x60,
0x6a, 0x0f, 0x85, 0xe6, 0xa9, 0x1d, 0x39, 0x6f,
0x5b, 0x5c, 0xbe, 0x57, 0x7f, 0x9b, 0x38, 0x80,
0x7c, 0x7d, 0x52, 0x3d, 0x6d, 0x79, 0x2f, 0x6e,
0xbc, 0x24, 0xa4, 0xec, 0xf2, 0xb3, 0xa4, 0x27,
0xcd, 0xbb, 0xfb
0xf7, 0x8f, 0x92, 0x14, 0x1b, 0xcd, 0x17, 0x0a,
0xe8, 0x9b, 0x4f, 0xba, 0x15, 0xa1, 0xd5, 0x9f,
0x3f, 0xd8, 0x4d, 0x22, 0x3c, 0x92, 0x51, 0xbd,
0xac, 0xbb, 0xae, 0x61, 0xd0, 0x5e, 0xd1, 0x15,
0xa0, 0x6a, 0x7c, 0xe1, 0x17, 0xb7, 0xbe, 0xea,
0xd2, 0x44, 0x21, 0xde, 0xd9, 0xc3, 0x25, 0x92,
0xbd, 0x57, 0xed, 0xea, 0xe3, 0x9c, 0x39, 0xfa,
0x1f, 0xe8, 0x94, 0x6a, 0x84, 0xd0, 0xcf, 0x1f,
0x7b, 0xee, 0xad, 0x17, 0x13, 0xe2, 0xe0, 0x95,
0x98, 0x97, 0x34, 0x7f, 0x67, 0xc8, 0x0b, 0x04,
0x00, 0xc2, 0x09, 0x81, 0x5d, 0x6b, 0x10, 0xa6,
0x83, 0x83, 0x6f, 0xd5, 0x56, 0x2a, 0x56, 0xca,
0xb1, 0xa2, 0x8e, 0x81, 0xb6, 0x57, 0x66, 0x54,
0x63, 0x1c, 0xf1, 0x65, 0x66, 0xb8, 0x6e, 0x3b,
0x33, 0xa1, 0x08, 0xb0, 0x53, 0x07, 0xc0, 0x0a,
0xff, 0x14, 0xa7, 0x68, 0xed, 0x73, 0x50, 0x60,
0x6a, 0x0f, 0x85, 0xe6, 0xa9, 0x1d, 0x39, 0x6f,
0x5b, 0x5c, 0xbe, 0x57, 0x7f, 0x9b, 0x38, 0x80,
0x7c, 0x7d, 0x52, 0x3d, 0x6d, 0x79, 0x2f, 0x6e,
0xbc, 0x24, 0xa4, 0xec, 0xf2, 0xb3, 0xa4, 0x27,
0xcd, 0xbb, 0xfb
};
static const u_char sha1_long2_msg_digest[] = {
0xcb, 0x00, 0x82, 0xc8, 0xf1, 0x97, 0xd2, 0x60,
0x99, 0x1b, 0xa6, 0xa4, 0x60, 0xe7, 0x6e, 0x20,
0x2b, 0xad, 0x27, 0xb3
0xcb, 0x00, 0x82, 0xc8, 0xf1, 0x97, 0xd2, 0x60,
0x99, 0x1b, 0xa6, 0xa4, 0x60, 0xe7, 0x6e, 0x20,
0x2b, 0xad, 0x27, 0xb3
};
static const hash_testvector_t sha1_hash_testvectors[] = {
{ sizeof(sha1_short2_msg), sha1_short2_msg, sha1_short2_msg_digest },
{ sizeof(sha1_short4_msg), sha1_short4_msg, sha1_short4_msg_digest },
{ sizeof(sha1_long2_msg), sha1_long2_msg, sha1_long2_msg_digest },
{ 0, NULL, NULL }
{ sizeof(sha1_short2_msg), sha1_short2_msg, sha1_short2_msg_digest },
{ sizeof(sha1_short4_msg), sha1_short4_msg, sha1_short4_msg_digest },
{ sizeof(sha1_long2_msg), sha1_long2_msg, sha1_long2_msg_digest },
{ 0, NULL, NULL }
};
/* SHA-1 hmac test vectors
@ -381,109 +381,109 @@ static const hash_testvector_t sha1_hash_testvectors[] = {
*/
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[] = {
0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
0xf1, 0x46, 0xbe, 0x00
0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
0xf1, 0x46, 0xbe, 0x00
};
static const u_char sha1_hmac2[] = {
0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2,
0xd2, 0x74, 0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c,
0x25, 0x9a, 0x7c, 0x79
0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2,
0xd2, 0x74, 0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c,
0x25, 0x9a, 0x7c, 0x79
};
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[] = {
0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd,
0x91, 0xa3, 0x9a, 0xf4, 0x8a, 0xa1, 0x7b, 0x4f,
0x63, 0xf1, 0x75, 0xd3
0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd,
0x91, 0xa3, 0x9a, 0xf4, 0x8a, 0xa1, 0x7b, 0x4f,
0x63, 0xf1, 0x75, 0xd3
};
static const u_char sha1_hmac4[] = {
0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6,
0xbc, 0x84, 0x14, 0xf9, 0xbf, 0x50, 0xc8, 0x6c,
0x2d, 0x72, 0x35, 0xda
0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6,
0xbc, 0x84, 0x14, 0xf9, 0xbf, 0x50, 0xc8, 0x6c,
0x2d, 0x72, 0x35, 0xda
};
static const u_char sha1_hmac6[] = {
0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e,
0x95, 0x70, 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55,
0xed, 0x40, 0x21, 0x12
0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e,
0x95, 0x70, 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55,
0xed, 0x40, 0x21, 0x12
};
static const u_char sha1_hmac7[] = {
0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78,
0x6d, 0x6b, 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08,
0xbb, 0xff, 0x1a, 0x91
0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78,
0x6d, 0x6b, 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08,
0xbb, 0xff, 0x1a, 0x91
};
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(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(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_hmac7_msg), md5_hmac7_msg, sha1_hmac7 },
{ 0, NULL, 0, NULL, NULL }
{ 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(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_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 },
{ 0, NULL, 0, NULL, NULL }
};
static struct hash_desc crypto_hasher_sha1 =
{
algo_type: IKE_ALG_HASH,
algo_id: OAKLEY_SHA,
algo_next: NULL,
hash_ctx_size: sizeof(SHA1_CTX),
hash_block_size: SHA1_BLOCK_SIZE,
hash_digest_size: SHA1_DIGEST_SIZE,
hash_testvectors: sha1_hash_testvectors,
hmac_testvectors: sha1_hmac_testvectors,
hash_init: (void (*)(void *)) SHA1Init,
hash_update: (void (*)(void *, const u_int8_t *, size_t)) SHA1Update,
hash_final: (void (*)(u_char *, void *)) SHA1Final
{
algo_type: IKE_ALG_HASH,
algo_id: OAKLEY_SHA,
algo_next: NULL,
hash_ctx_size: sizeof(SHA1_CTX),
hash_block_size: SHA1_BLOCK_SIZE,
hash_digest_size: SHA1_DIGEST_SIZE,
hash_testvectors: sha1_hash_testvectors,
hmac_testvectors: sha1_hmac_testvectors,
hash_init: (void (*)(void *)) SHA1Init,
hash_update: (void (*)(void *, const u_int8_t *, size_t)) SHA1Update,
hash_final: (void (*)(u_char *, void *)) SHA1Final
};
void
init_crypto(void)
{
if (mpz_init_set_str(&groupgenerator, MODP_GENERATOR, 10) != 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(&modp2048_modulus, MODP2048_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(&modp6144_modulus, MODP6144_MODULUS, 16) != 0
|| mpz_init_set_str(&modp8192_modulus, MODP8192_MODULUS, 16) != 0)
exit_log("mpz_init_set_str() failed in init_crypto()");
if (mpz_init_set_str(&groupgenerator, MODP_GENERATOR, 10) != 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(&modp2048_modulus, MODP2048_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(&modp6144_modulus, MODP6144_MODULUS, 16) != 0
|| mpz_init_set_str(&modp8192_modulus, MODP8192_MODULUS, 16) != 0)
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_hasher_sha1);
ike_alg_add((struct ike_alg *) &crypto_hasher_md5);
ike_alg_init();
ike_alg_test();
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_md5);
ike_alg_init();
ike_alg_test();
}
void
free_crypto(void)
{
mpz_clear(&groupgenerator);
mpz_clear(&modp1024_modulus);
mpz_clear(&modp1536_modulus);
mpz_clear(&modp2048_modulus);
mpz_clear(&modp3072_modulus);
mpz_clear(&modp4096_modulus);
mpz_clear(&modp6144_modulus);
mpz_clear(&modp8192_modulus);
mpz_clear(&groupgenerator);
mpz_clear(&modp1024_modulus);
mpz_clear(&modp1536_modulus);
mpz_clear(&modp2048_modulus);
mpz_clear(&modp3072_modulus);
mpz_clear(&modp4096_modulus);
mpz_clear(&modp6144_modulus);
mpz_clear(&modp8192_modulus);
}
/* Oakley group description
@ -491,29 +491,29 @@ free_crypto(void)
* 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] = {
# define BYTES(bits) (((bits) + BITS_PER_BYTE - 1) / BITS_PER_BYTE)
{ OAKLEY_GROUP_MODP1024, &modp1024_modulus, BYTES(1024) },
{ OAKLEY_GROUP_MODP1536, &modp1536_modulus, BYTES(1536) },
{ OAKLEY_GROUP_MODP2048, &modp2048_modulus, BYTES(2048) },
{ OAKLEY_GROUP_MODP3072, &modp3072_modulus, BYTES(3072) },
{ OAKLEY_GROUP_MODP4096, &modp4096_modulus, BYTES(4096) },
{ OAKLEY_GROUP_MODP6144, &modp6144_modulus, BYTES(6144) },
{ OAKLEY_GROUP_MODP8192, &modp8192_modulus, BYTES(8192) },
{ OAKLEY_GROUP_MODP1024, &modp1024_modulus, BYTES(1024) },
{ OAKLEY_GROUP_MODP1536, &modp1536_modulus, BYTES(1536) },
{ OAKLEY_GROUP_MODP2048, &modp2048_modulus, BYTES(2048) },
{ OAKLEY_GROUP_MODP3072, &modp3072_modulus, BYTES(3072) },
{ OAKLEY_GROUP_MODP4096, &modp4096_modulus, BYTES(4096) },
{ OAKLEY_GROUP_MODP6144, &modp6144_modulus, BYTES(6144) },
{ OAKLEY_GROUP_MODP8192, &modp8192_modulus, BYTES(8192) },
# undef BYTES
};
const struct oakley_group_desc *
lookup_group(u_int16_t group)
{
int i;
int i;
for (i = 0; i != countof(oakley_group); i++)
if (group == oakley_group[i].group)
return &oakley_group[i];
return NULL;
for (i = 0; i != countof(oakley_group); i++)
if (group == oakley_group[i].group)
return &oakley_group[i];
return NULL;
}
/* Encryption Routines
@ -528,16 +528,16 @@ lookup_group(u_int16_t group)
static void __attribute__ ((unused))
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);
st->st_new_iv_len = DES_CBC_BLOCK_SIZE; /* truncate */
passert(st->st_new_iv_len >= DES_CBC_BLOCK_SIZE);
st->st_new_iv_len = DES_CBC_BLOCK_SIZE; /* truncate */
des_ncbc_encrypt((des_cblock *)buf, (des_cblock *)buf, buf_len,
ks,
(des_cblock *)st->st_new_iv, enc);
des_ncbc_encrypt((des_cblock *)buf, (des_cblock *)buf, buf_len,
ks,
(des_cblock *)st->st_new_iv, enc);
}
/* 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
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)))
(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 + 2, ks[2]);
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 + 1, ks[1]);
(void) des_set_key((des_cblock *)key + 2, ks[2]);
des_ede3_cbc_encrypt((des_cblock *)buf, (des_cblock *)buf, buf_len,
ks[0], ks[1], ks[2],
(des_cblock *)iv, enc);
des_ede3_cbc_encrypt((des_cblock *)buf, (des_cblock *)buf, buf_len,
ks[0], ks[1], ks[2],
(des_cblock *)iv, enc);
}
/* hash and prf routines */
void
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);
st->st_new_iv_len = e->enc_blocksize; /* truncate */
passert(st->st_new_iv_len >= e->enc_blocksize);
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->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->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->cbc_crypt(&ctx, buf, size, st->st_new_iv, enc);
*/
}
/* HMAC package
@ -578,63 +578,63 @@ crypto_cbc_encrypt(const struct encrypt_desc *e, bool enc, u_int8_t *buf, size_t
void
hmac_init(struct hmac_ctx *ctx,
const struct hash_desc *h,
const u_char *key, size_t key_len)
const struct hash_desc *h,
const u_char *key, size_t key_len)
{
int k;
int k;
ctx->h = h;
ctx->hmac_digest_size = h->hash_digest_size;
ctx->h = h;
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)
{
memcpy(ctx->buf1, key, key_len);
}
else
{
h->hash_init(&ctx->hash_ctx);
h->hash_update(&ctx->hash_ctx, key, key_len);
h->hash_final(ctx->buf1, &ctx->hash_ctx);
}
if (key_len <= h->hash_block_size)
{
memcpy(ctx->buf1, key, key_len);
}
else
{
h->hash_init(&ctx->hash_ctx);
h->hash_update(&ctx->hash_ctx, key, key_len);
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++)
{
ctx->buf1[k] ^= HMAC_IPAD;
ctx->buf2[k] ^= HMAC_OPAD;
}
for (k = 0; k < h->hash_block_size; k++)
{
ctx->buf1[k] ^= HMAC_IPAD;
ctx->buf2[k] ^= HMAC_OPAD;
}
hmac_reinit(ctx);
hmac_reinit(ctx);
}
void
hmac_reinit(struct hmac_ctx *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_init(&ctx->hash_ctx);
ctx->h->hash_update(&ctx->hash_ctx, ctx->buf1, ctx->h->hash_block_size);
}
void
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
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_update(&ctx->hash_ctx, ctx->buf2, h->hash_block_size);
h->hash_update(&ctx->hash_ctx, output, h->hash_digest_size);
h->hash_final(output, &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, output, h->hash_digest_size);
h->hash_final(output, &ctx->hash_ctx);
}

View File

@ -24,15 +24,15 @@ extern void free_crypto(void);
/* Oakley group descriptions */
extern MP_INT groupgenerator; /* MODP group generator (2) */
extern MP_INT groupgenerator; /* MODP group generator (2) */
struct oakley_group_desc {
u_int16_t group;
MP_INT *modulus;
size_t bytes;
u_int16_t group;
MP_INT *modulus;
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);
#define OAKLEY_GROUP_SIZE 7
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_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);
#define update_iv(st) memcpy((st)->st_iv, (st)->st_new_iv \
, (st)->st_iv_len = (st)->st_new_iv_len)
#define update_iv(st) memcpy((st)->st_iv, (st)->st_new_iv \
, (st)->st_iv_len = (st)->st_new_iv_len)
#define set_ph1_iv(st, iv) \
passert((st)->st_ph1_iv_len <= sizeof((st)->st_ph1_iv)); \
memcpy((st)->st_ph1_iv, (iv), (st)->st_ph1_iv_len);
passert((st)->st_ph1_iv_len <= sizeof((st)->st_ph1_iv)); \
memcpy((st)->st_ph1_iv, (iv), (st)->st_ph1_iv_len);
/* unification of cryptographic hashing mechanisms */
#ifndef NO_HASH_CTX
union hash_ctx {
MD5_CTX ctx_md5;
SHA1_CTX ctx_sha1;
sha256_context ctx_sha256;
sha512_context ctx_sha512;
};
MD5_CTX ctx_md5;
SHA1_CTX ctx_sha1;
sha256_context ctx_sha256;
sha512_context ctx_sha512;
};
/* HMAC package
* Note that hmac_ctx can be (and is) copied since there are
@ -74,36 +74,36 @@ union hash_ctx {
*/
struct hmac_ctx {
const struct hash_desc *h; /* underlying hash function */
size_t hmac_digest_size; /* copy of h->hash_digest_size */
union hash_ctx hash_ctx; /* ctx for hash function */
u_char buf1[MAX_HASH_BLOCK_SIZE];
u_char buf2[MAX_HASH_BLOCK_SIZE];
};
const struct hash_desc *h; /* underlying hash function */
size_t hmac_digest_size; /* copy of h->hash_digest_size */
union hash_ctx hash_ctx; /* ctx for hash function */
u_char buf1[MAX_HASH_BLOCK_SIZE];
u_char buf2[MAX_HASH_BLOCK_SIZE];
};
extern void hmac_init(
struct hmac_ctx *ctx,
const struct hash_desc *h,
const u_char *key,
size_t key_len);
struct hmac_ctx *ctx,
const struct hash_desc *h,
const u_char *key,
size_t key_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(
struct hmac_ctx *ctx,
const u_char *data,
size_t data_len);
struct hmac_ctx *ctx,
const u_char *data,
size_t data_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);
#define hmac_final_chunk(ch, name, ctx) { \
free((ch).ptr); \
(ch).len = (ctx)->hmac_digest_size; \
(ch).ptr = malloc((ch).len); \
hmac_final((ch).ptr, (ctx)); \
}
free((ch).ptr); \
(ch).len = (ctx)->hmac_digest_size; \
(ch).ptr = malloc((ch).len); \
hmac_final((ch).ptr, (ctx)); \
}
#endif

View File

@ -31,22 +31,22 @@
* also update attrs_cur (by offset)
*
* db_context structure:
* +---------------------+
* | prop |
* | .protoid |
* | .trans | --+
* | .trans_cnt | |
* +---------------------+ <-+
* | trans0 | ----> { trans#1 | ... | trans#i | ... }
* +---------------------+ ^
* | trans_cur | ----------------------' current transf.
* +---------------------+
* | attrs0 | ----> { attr#1 | ... | attr#j | ... }
* +---------------------+ ^
* | attrs_cur | ---------------------' current attr.
* +---------------------+
* | max_trans,max_attrs | max_trans/attrs: number of elem. of each vector
* +---------------------+
* +---------------------+
* | prop |
* | .protoid |
* | .trans | --+
* | .trans_cnt | |
* +---------------------+ <-+
* | trans0 | ----> { trans#1 | ... | trans#i | ... }
* +---------------------+ ^
* | trans_cur | ----------------------' current transf.
* +---------------------+
* | attrs0 | ----> { attr#1 | ... | attr#j | ... }
* +---------------------+ ^
* | attrs_cur | ---------------------' current attr.
* +---------------------+
* | max_trans,max_attrs | max_trans/attrs: number of elem. of each vector
* +---------------------+
*
* See testing examples at end for interface usage.
*/
@ -71,29 +71,29 @@
#ifdef NOT_YET
/*
* Allocator cache:
* Because of the single-threaded nature of pluto/spdb.c,
* alloc()/free() is exercised many times with very small
* lifetime objects.
* Just caching last object (currently it will select the
* largest) will avoid this allocation mas^Wperturbations
* Allocator cache:
* Because of the single-threaded nature of pluto/spdb.c,
* alloc()/free() is exercised many times with very small
* lifetime objects.
* Just caching last object (currently it will select the
* largest) will avoid this allocation mas^Wperturbations
*
*/
struct db_ops_alloc_cache {
void *ptr;
int size;
void *ptr;
int size;
};
#endif
#ifndef NO_DB_OPS_STATS
/*
* stats: do account for allocations
* displayed in db_ops_show_status()
/*
* stats: do account for allocations
* displayed in db_ops_show_status()
*/
struct db_ops_stats {
int st_curr_cnt; /* current number of allocations */
int st_total_cnt; /* total allocations so far */
size_t st_maxsz; /* max. size requested */
int st_curr_cnt; /* current number of allocations */
int st_total_cnt; /* total allocations so far */
size_t st_maxsz; /* max. size requested */
};
#define DB_OPS_ZERO { 0, 0, 0};
#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 __inline__ void *malloc_bytes_st(size_t size, struct db_ops_stats *st)
{
void *ptr = malloc(size);
if (ptr)
{
st->st_curr_cnt++;
st->st_total_cnt++;
if (size > st->st_maxsz) st->st_maxsz=size;
}
return ptr;
void *ptr = malloc(size);
if (ptr)
{
st->st_curr_cnt++;
st->st_total_cnt++;
if (size > st->st_maxsz) st->st_maxsz=size;
}
return ptr;
}
#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);
@ -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);
#endif /* NO_DB_OPS_STATS */
/* Initialize db object
* max_trans and max_attrs can be 0, will be dynamically expanded
* as a result of "add" operations
/* Initialize db object
* max_trans and max_attrs can be 0, will be dynamically expanded
* as a result of "add" operations
*/
int
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->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;
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->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
db_trans_expand(struct db_context *ctx, int delta_trans)
{
int ret = -1;
struct db_trans *new_trans, *old_trans;
int max_trans = ctx->max_trans + delta_trans;
int offset;
int ret = -1;
struct db_trans *new_trans, *old_trans;
int max_trans = ctx->max_trans + delta_trans;
int offset;
old_trans = ctx->trans0;
new_trans = ALLOC_BYTES_ST ( sizeof (struct db_trans) * max_trans,
db_trans_st);
if (!new_trans)
goto out;
memcpy(new_trans, old_trans, ctx->max_trans * sizeof(struct db_trans));
/* update trans0 (obviously) */
ctx->trans0 = ctx->prop.trans = new_trans;
/* update trans_cur (by offset) */
offset = (char *)(new_trans) - (char *)(old_trans);
old_trans = ctx->trans0;
new_trans = ALLOC_BYTES_ST ( sizeof (struct db_trans) * max_trans,
db_trans_st);
if (!new_trans)
goto out;
memcpy(new_trans, old_trans, ctx->max_trans * sizeof(struct db_trans));
/* update trans0 (obviously) */
ctx->trans0 = ctx->prop.trans = new_trans;
/* update trans_cur (by offset) */
offset = (char *)(new_trans) - (char *)(old_trans);
{
char *cctx = (char *)(ctx->trans_cur);
cctx += offset;
ctx->trans_cur = (struct db_trans *)cctx;
}
/* update elem count */
ctx->max_trans = max_trans;
PFREE_ST(old_trans, db_trans_st);
ret = 0;
{
char *cctx = (char *)(ctx->trans_cur);
cctx += offset;
ctx->trans_cur = (struct db_trans *)cctx;
}
/* update elem count */
ctx->max_trans = max_trans;
PFREE_ST(old_trans, db_trans_st);
ret = 0;
out:
return ret;
return ret;
}
/*
* Expand storage for attributes by delta_attrs number AND
* rewrite trans->attr pointers
/*
* Expand storage for attributes by delta_attrs number AND
* rewrite trans->attr pointers
*/
static int
db_attrs_expand(struct db_context *ctx, int delta_attrs)
{
int ret = -1;
struct db_attr *new_attrs, *old_attrs;
struct db_trans *t;
int ti;
int max_attrs = ctx->max_attrs + delta_attrs;
int offset;
int ret = -1;
struct db_attr *new_attrs, *old_attrs;
struct db_trans *t;
int ti;
int max_attrs = ctx->max_attrs + delta_attrs;
int offset;
old_attrs = ctx->attrs0;
new_attrs = ALLOC_BYTES_ST ( sizeof (struct db_attr) * max_attrs,
db_attrs_st);
if (!new_attrs)
goto out;
old_attrs = ctx->attrs0;
new_attrs = ALLOC_BYTES_ST ( sizeof (struct db_attr) * max_attrs,
db_attrs_st);
if (!new_attrs)
goto out;
memcpy(new_attrs, old_attrs, ctx->max_attrs * sizeof(struct db_attr));
/* update attrs0 and attrs_cur (obviously) */
offset = (char *)(new_attrs) - (char *)(old_attrs);
{
char *actx = (char *)(ctx->attrs0);
actx += offset;
ctx->attrs0 = (struct db_attr *)actx;
actx = (char *)ctx->attrs_cur;
actx += offset;
ctx->attrs_cur = (struct db_attr *)actx;
}
memcpy(new_attrs, old_attrs, ctx->max_attrs * sizeof(struct db_attr));
/* update attrs0 and attrs_cur (obviously) */
offset = (char *)(new_attrs) - (char *)(old_attrs);
{
char *actx = (char *)(ctx->attrs0);
actx += offset;
ctx->attrs0 = (struct db_attr *)actx;
actx = (char *)ctx->attrs_cur;
actx += offset;
ctx->attrs_cur = (struct db_attr *)actx;
}
/* for each transform, rewrite attrs pointer by offsetting it */
for (t=ctx->prop.trans, ti=0; ti < ctx->prop.trans_cnt; t++, ti++) {
char *actx = (char *)(t->attrs);
actx += offset;
t->attrs = (struct db_attr *)actx;
}
/* update elem count */
ctx->max_attrs = max_attrs;
PFREE_ST(old_attrs, db_attrs_st);
ret = 0;
/* for each transform, rewrite attrs pointer by offsetting it */
for (t=ctx->prop.trans, ti=0; ti < ctx->prop.trans_cnt; t++, ti++) {
char *actx = (char *)(t->attrs);
actx += offset;
t->attrs = (struct db_attr *)actx;
}
/* update elem count */
ctx->max_attrs = max_attrs;
PFREE_ST(old_attrs, db_attrs_st);
ret = 0;
out:
return ret;
return ret;
}
/* 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 *ctx;
ctx = ALLOC_BYTES_ST ( sizeof (struct db_context), db_context_st);
if (!ctx) goto out;
if (db_prop_init(ctx, protoid, max_trans, max_attrs) < 0) {
PFREE_ST(ctx, db_context_st);
ctx=NULL;
}
struct db_context *ctx;
ctx = ALLOC_BYTES_ST ( sizeof (struct db_context), db_context_st);
if (!ctx) goto out;
if (db_prop_init(ctx, protoid, max_trans, max_attrs) < 0) {
PFREE_ST(ctx, db_context_st);
ctx=NULL;
}
out:
return ctx;
return ctx;
}
/* Free a db object */
/* Free a db object */
void
db_destroy(struct db_context *ctx)
{
if (ctx->trans0) PFREE_ST(ctx->trans0, db_trans_st);
if (ctx->attrs0) PFREE_ST(ctx->attrs0, db_attrs_st);
PFREE_ST(ctx, db_context_st);
if (ctx->trans0) PFREE_ST(ctx->trans0, db_trans_st);
if (ctx->attrs0) PFREE_ST(ctx->attrs0, db_attrs_st);
PFREE_ST(ctx, db_context_st);
}
/* Start a new transform, expand trans0 is needed */
/* Start a new transform, expand trans0 is needed */
int
db_trans_add(struct db_context *ctx, u_int8_t transid)
{
/* skip incrementing current trans pointer the 1st time*/
if (ctx->trans_cur && ctx->trans_cur->attr_cnt)
ctx->trans_cur++;
/*
* Strategy: if more space is needed, expand by
* <current_size>/2 + 1
*
* This happens to produce a "reasonable" sequence
* after few allocations, eg.:
* 0,1,2,4,8,13,20,31,47
*/
if ((ctx->trans_cur - ctx->trans0) >= ctx->max_trans) {
/* XXX:jjo if fails should shout and flag it */
if (db_trans_expand(ctx, ctx->max_trans/2 + 1)<0)
return -1;
}
ctx->trans_cur->transid = transid;
ctx->trans_cur->attrs=ctx->attrs_cur;
ctx->trans_cur->attr_cnt = 0;
ctx->prop.trans_cnt++;
return 0;
/* skip incrementing current trans pointer the 1st time*/
if (ctx->trans_cur && ctx->trans_cur->attr_cnt)
ctx->trans_cur++;
/*
* Strategy: if more space is needed, expand by
* <current_size>/2 + 1
*
* This happens to produce a "reasonable" sequence
* after few allocations, eg.:
* 0,1,2,4,8,13,20,31,47
*/
if ((ctx->trans_cur - ctx->trans0) >= ctx->max_trans) {
/* XXX:jjo if fails should shout and flag it */
if (db_trans_expand(ctx, ctx->max_trans/2 + 1)<0)
return -1;
}
ctx->trans_cur->transid = transid;
ctx->trans_cur->attrs=ctx->attrs_cur;
ctx->trans_cur->attr_cnt = 0;
ctx->prop.trans_cnt++;
return 0;
}
/* Add attr copy to current transform, expanding attrs0 if needed */
/* Add attr copy to current transform, expanding attrs0 if needed */
int
db_attr_add(struct db_context *ctx, const struct db_attr *a)
{
/*
* Strategy: if more space is needed, expand by
* <current_size>/2 + 1
*/
if ((ctx->attrs_cur - ctx->attrs0) >= ctx->max_attrs) {
/* XXX:jjo if fails should shout and flag it */
if (db_attrs_expand(ctx, ctx->max_attrs/2 + 1) < 0)
return -1;
}
*ctx->attrs_cur++=*a;
ctx->trans_cur->attr_cnt++;
return 0;
/*
* Strategy: if more space is needed, expand by
* <current_size>/2 + 1
*/
if ((ctx->attrs_cur - ctx->attrs0) >= ctx->max_attrs) {
/* XXX:jjo if fails should shout and flag it */
if (db_attrs_expand(ctx, ctx->max_attrs/2 + 1) < 0)
return -1;
}
*ctx->attrs_cur++=*a;
ctx->trans_cur->attr_cnt++;
return 0;
}
/* Add attr copy (by value) to current transform,
* expanding attrs0 if needed, just calls db_attr_add().
/* Add attr copy (by value) to current transform,
* expanding attrs0 if needed, just calls db_attr_add().
*/
int
db_attr_add_values(struct db_context *ctx, u_int16_t type, u_int16_t val)
{
struct db_attr attr;
attr.type = type;
attr.val = val;
return db_attr_add (ctx, &attr);
struct db_attr attr;
attr.type = type;
attr.val = val;
return db_attr_add (ctx, &attr);
}
#ifndef NO_DB_OPS_STATS
int
db_ops_show_status(void)
{
whack_log(RC_COMMENT, "stats " __FILE__ ": "
DB_OPS_STATS_DESC " :"
DB_OPS_STATS_STR("context")
DB_OPS_STATS_STR("trans")
DB_OPS_STATS_STR("attrs"),
DB_OPS_STATS_F(db_context_st),
DB_OPS_STATS_F(db_trans_st),
DB_OPS_STATS_F(db_attrs_st)
);
return 0;
whack_log(RC_COMMENT, "stats " __FILE__ ": "
DB_OPS_STATS_DESC " :"
DB_OPS_STATS_STR("context")
DB_OPS_STATS_STR("trans")
DB_OPS_STATS_STR("attrs"),
DB_OPS_STATS_F(db_context_st),
DB_OPS_STATS_F(db_trans_st),
DB_OPS_STATS_F(db_attrs_st)
);
return 0;
}
#endif /* NO_DB_OPS_STATS */
/*
@ -344,51 +344,51 @@ db_ops_show_status(void)
#ifdef TEST
static void db_prop_print(struct db_prop *p)
{
struct db_trans *t;
struct db_attr *a;
int ti, ai;
enum_names *n, *n_at, *n_av;
printf("protoid=\"%s\"\n", enum_name(&protocol_names, p->protoid));
for (ti=0, t=p->trans; ti< p->trans_cnt; ti++, t++) {
switch( t->transid) {
case PROTO_ISAKMP:
n=&isakmp_transformid_names;break;
case PROTO_IPSEC_ESP:
n=&esp_transformid_names;break;
default:
continue;
struct db_trans *t;
struct db_attr *a;
int ti, ai;
enum_names *n, *n_at, *n_av;
printf("protoid=\"%s\"\n", enum_name(&protocol_names, p->protoid));
for (ti=0, t=p->trans; ti< p->trans_cnt; ti++, t++) {
switch( t->transid) {
case PROTO_ISAKMP:
n=&isakmp_transformid_names;break;
case PROTO_IPSEC_ESP:
n=&esp_transformid_names;break;
default:
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)
{
printf("trans_cur diff=%d, attrs_cur diff=%d\n",
ctx->trans_cur - ctx->trans0,
ctx->attrs_cur - ctx->attrs0);
db_prop_print(&ctx->prop);
printf("trans_cur diff=%d, attrs_cur diff=%d\n",
ctx->trans_cur - ctx->trans0,
ctx->attrs_cur - ctx->attrs0);
db_prop_print(&ctx->prop);
}
void
@ -397,25 +397,25 @@ void abort(void);
void
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);
abort(); /* exiting correctly doesn't always work */
fprintf(stderr, "ASSERTION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
abort(); /* exiting correctly doesn't always work */
}
int main(void) {
struct db_context *ctx=db_prop_new(PROTO_ISAKMP, 0, 0);
db_trans_add(ctx, KEY_IKE);
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_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG);
db_attr_add_values(ctx, OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024);
db_trans_add(ctx, KEY_IKE);
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_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY);
db_attr_add_values(ctx, OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536);
db_trans_add(ctx, ESP_3DES);
db_attr_add_values(ctx, AUTH_ALGORITHM, AUTH_ALGORITHM_HMAC_SHA1);
db_print(ctx);
db_destroy(ctx);
return 0;
struct db_context *ctx=db_prop_new(PROTO_ISAKMP, 0, 0);
db_trans_add(ctx, KEY_IKE);
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_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG);
db_attr_add_values(ctx, OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024);
db_trans_add(ctx, KEY_IKE);
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_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY);
db_attr_add_values(ctx, OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536);
db_trans_add(ctx, ESP_3DES);
db_attr_add_values(ctx, AUTH_ALGORITHM, AUTH_ALGORITHM_HMAC_SHA1);
db_print(ctx);
db_destroy(ctx);
return 0;
}
#endif

View File

@ -18,39 +18,39 @@
#define _DB_OPS_H
/*
* Main db object, (quite proposal "oriented")
* Main db object, (quite proposal "oriented")
*/
#ifndef NO_DB_CONTEXT
struct db_context {
struct db_prop prop; /* proposal buffer (not pointer) */
struct db_trans *trans0; /* transf. list, dynamically sized */
struct db_trans *trans_cur; /* current transform ptr */
struct db_attr *attrs0; /* attr. list, dynamically sized */
struct db_attr *attrs_cur; /* current attribute ptr */
int max_trans; /* size of trans list */
int max_attrs; /* size of attrs list */
struct db_prop prop; /* proposal buffer (not pointer) */
struct db_trans *trans0; /* transf. list, dynamically sized */
struct db_trans *trans_cur; /* current transform ptr */
struct db_attr *attrs0; /* attr. list, dynamically sized */
struct db_attr *attrs_cur; /* current attribute ptr */
int max_trans; /* size of trans 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);
/* 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);
/* Free all resourses for this db */
/* Free all resourses for this db */
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);
/* 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);
/* 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);
/* Get proposal from db object */
/* Get proposal from db object */
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 */
int db_ops_show_status(void);
#endif /* _DB_OPS_H */

View File

@ -27,25 +27,25 @@
#include "constants.h"
#include "defs.h"
#include "log.h"
#include "whack.h" /* for RC_LOG_SERIOUS */
#include "whack.h" /* for RC_LOG_SERIOUS */
bool
all_zero(const unsigned char *m, size_t len)
{
size_t i;
size_t i;
for (i = 0; i != len; i++)
if (m[i] != '\0')
return FALSE;
return TRUE;
for (i = 0; i != len; i++)
if (m[i] != '\0')
return FALSE;
return TRUE;
}
void *clone_bytes(const void *orig, size_t size)
{
void *p = malloc(size);
void *p = malloc(size);
memcpy(p, orig, size);
return p;
memcpy(p, orig, size);
return p;
}
/* 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.
* We rotate them. Be careful!
*/
#define MAX_BUF 10
#define MAX_BUF 10
char*
temporary_cyclic_buffer(void)
{
static char buf[MAX_BUF][BUF_LEN]; /* MAX_BUF internal buffers */
static int counter = 0; /* cyclic counter */
static char buf[MAX_BUF][BUF_LEN]; /* MAX_BUF internal buffers */
static int counter = 0; /* cyclic counter */
if (++counter == MAX_BUF) counter = 0; /* next internal buffer */
return buf[counter]; /* assign temporary buffer */
if (++counter == MAX_BUF) counter = 0; /* next internal buffer */
return buf[counter]; /* assign temporary buffer */
}
/* concatenates two sub paths into a string with a maximum size of BUF_LEN
@ -71,14 +71,14 @@ temporary_cyclic_buffer(void)
const char*
concatenate_paths(const char *a, const char *b)
{
char *c;
char *c;
if (*b == '/' || *b == '.')
return b;
if (*b == '/' || *b == '.')
return b;
c = temporary_cyclic_buffer();
snprintf(c, BUF_LEN, "%s/%s", a, b);
return c;
c = temporary_cyclic_buffer();
snprintf(c, BUF_LEN, "%s/%s", a, b);
return c;
}
/* moves a chunk to a memory position, chunk is freed afterwards
@ -87,11 +87,11 @@ concatenate_paths(const char *a, const char *b)
void
mv_chunk(u_char **pos, chunk_t content)
{
if (content.len > 0)
{
chunkcpy(*pos, content);
free(content.ptr);
}
if (content.len > 0)
{
chunkcpy(*pos, content);
free(content.ptr);
}
}
/*
@ -101,46 +101,46 @@ bool
write_chunk(const char *filename, const char *label, chunk_t ch
, mode_t mask, bool force)
{
mode_t oldmask;
FILE *fd;
size_t written;
mode_t oldmask;
FILE *fd;
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)
{
fclose(fd);
plog(" %s file '%s' already exists", label, filename);
return FALSE;
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);
umask(oldmask);
return FALSE;
}
plog(" written %s file '%s' (%d bytes)", label, filename, (int)ch.len);
umask(oldmask);
return TRUE;
}
}
/* 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)
else
{
plog(" writing to %s file '%s' failed", label, filename);
umask(oldmask);
return FALSE;
plog(" could not open %s file '%s' for writing", label, filename);
umask(oldmask);
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
@ -151,44 +151,44 @@ write_chunk(const char *filename, const char *label, chunk_t ch
const char*
check_expiry(time_t expiration_date, int warning_interval, bool strict)
{
time_t now;
int time_left;
time_t now;
int time_left;
if (expiration_date == UNDEFINED_TIME)
return "ok (expires never)";
if (expiration_date == UNDEFINED_TIME)
return "ok (expires never)";
/* determine the current time */
time(&now);
/* determine the current time */
time(&now);
time_left = (expiration_date - now);
if (time_left < 0)
return strict? "fatal (expired)" : "warning (expired)";
time_left = (expiration_date - now);
if (time_left < 0)
return strict? "fatal (expired)" : "warning (expired)";
if (time_left > 86400*warning_interval)
return "ok";
{
static char buf[35]; /* temporary storage */
const char* unit = "second";
if (time_left > 172800)
if (time_left > 86400*warning_interval)
return "ok";
{
time_left /= 86400;
unit = "day";
static char buf[35]; /* temporary storage */
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
file_select(const struct dirent *entry)
{
return strcmp(entry->d_name, "." ) &&
strcmp(entry->d_name, "..");
return strcmp(entry->d_name, "." ) &&
strcmp(entry->d_name, "..");
}

View File

@ -24,23 +24,23 @@
#include <chunk.h>
#ifdef KLIPS
# define USED_BY_KLIPS /* ignore */
# define USED_BY_KLIPS /* ignore */
#else
# define USED_BY_KLIPS UNUSED
# define USED_BY_KLIPS UNUSED
#endif
#ifdef DEBUG
# define USED_BY_DEBUG /* ignore */
# define USED_BY_DEBUG /* ignore */
#else
# define USED_BY_DEBUG UNUSED
# define USED_BY_DEBUG UNUSED
#endif
/* type of serial number of a state object
* Needed in connections.h and state.h; here to simplify dependencies.
*/
typedef unsigned long so_serial_t;
#define SOS_NOBODY 0 /* null serial number */
#define SOS_FIRST 1 /* first normal serial number */
#define SOS_NOBODY 0 /* null serial number */
#define SOS_FIRST 1 /* first normal serial number */
/* 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_str(str) \
((str) == NULL? NULL : strdup(str))
((str) == NULL? NULL : strdup(str))
#define replace(p, q) \
{ free(p); (p) = (q); }
{ free(p); (p) = (q); }
#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 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 */
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 */
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 PROMPT_PASS_LEN 64
#define MAX_PROMPT_PASS_TRIALS 5
#define PROMPT_PASS_LEN 64
/* struct used to prompt for a secret passphrase
* from a console with file descriptor fd
*/
typedef struct {
char secret[PROMPT_PASS_LEN+1];
bool prompt;
int fd;
char secret[PROMPT_PASS_LEN+1];
bool prompt;
int fd;
} prompt_pass_t;
/* size of timetoa string buffer */
#define TIMETOA_BUF 30
#define TIMETOA_BUF 30
/* filter eliminating the directory entries '.' and '..' */
typedef struct dirent dirent_t;

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@
#include "packet.h"
struct state; /* forward declaration of tag */
struct state; /* forward declaration of tag */
extern void init_demux(void);
extern bool send_packet(struct state *st, const char *where);
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 {
pb_stream pbs;
union payload payload;
struct payload_digest *next; /* of same kind */
pb_stream pbs;
union payload payload;
struct payload_digest *next; /* of same kind */
};
/* message digest
@ -46,30 +46,30 @@ struct payload_digest {
*/
struct msg_digest {
struct msg_digest *next; /* for free list */
chunk_t raw_packet; /* if encrypted, received packet before decryption */
const struct iface *iface; /* interface on which message arrived */
ip_address sender; /* where message came from */
u_int16_t sender_port; /* host order */
pb_stream packet_pbs; /* whole packet */
pb_stream message_pbs; /* message to be processed */
struct isakmp_hdr hdr; /* message's header */
bool encrypted; /* was it encrypted? */
enum state_kind from_state; /* state we started in */
const struct state_microcode *smc; /* microcode for initial state */
struct state *st; /* current state object */
pb_stream reply; /* room for reply */
pb_stream rbody; /* room for reply body (after header) */
notification_t note; /* reason for failure */
bool dpd; /* peer supports RFC 3706 DPD */
bool openpgp; /* peer supports OpenPGP certificates */
struct msg_digest *next; /* for free list */
chunk_t raw_packet; /* if encrypted, received packet before decryption */
const struct iface *iface; /* interface on which message arrived */
ip_address sender; /* where message came from */
u_int16_t sender_port; /* host order */
pb_stream packet_pbs; /* whole packet */
pb_stream message_pbs; /* message to be processed */
struct isakmp_hdr hdr; /* message's header */
bool encrypted; /* was it encrypted? */
enum state_kind from_state; /* state we started in */
const struct state_microcode *smc; /* microcode for initial state */
struct state *st; /* current state object */
pb_stream reply; /* room for reply */
pb_stream rbody; /* room for reply body (after header) */
notification_t note; /* reason for failure */
bool dpd; /* peer supports RFC 3706 DPD */
bool openpgp; /* peer supports OpenPGP certificates */
# define PAYLIMIT 40
struct payload_digest
digest[PAYLIMIT],
*digest_roof,
*chain[ISAKMP_NEXT_ROOF];
unsigned short nat_traversal_vid;
struct payload_digest
digest[PAYLIMIT],
*digest_roof,
*chain[ISAKMP_NEXT_ROOF];
unsigned short nat_traversal_vid;
};
extern void release_md(struct msg_digest *md);
@ -79,11 +79,11 @@ extern void release_md(struct msg_digest *md);
*/
typedef enum {
STF_IGNORE, /* don't respond */
STF_SUSPEND, /* unfinished -- don't release resources */
STF_OK, /* success */
STF_INTERNAL_ERROR, /* discard everything, we failed */
STF_FAIL /* discard everything, something failed. notification_t added. */
STF_IGNORE, /* don't respond */
STF_SUSPEND, /* unfinished -- don't release resources */
STF_OK, /* success */
STF_INTERNAL_ERROR, /* discard everything, we failed */
STF_FAIL /* discard everything, something failed. notification_t added. */
} stf_status;
typedef stf_status state_transition_fn(struct msg_digest *md);

File diff suppressed because it is too large Load Diff

View File

@ -15,9 +15,9 @@
*/
extern int
adns_qfd, /* file descriptor for sending queries to adns */
adns_afd; /* file descriptor for receiving answers from adns */
extern const char *pluto_adns_option; /* path from --pluto_adns */
adns_qfd, /* file descriptor for sending queries to adns */
adns_afd; /* file descriptor for receiving answers from adns */
extern const char *pluto_adns_option; /* path from --pluto_adns */
extern void init_adns(void);
extern void stop_adns(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.
*/
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);
struct adns_continuation {
unsigned long qtid; /* query transaction id number */
int type; /* T_TXT or T_KEY, selecting rr type of interest */
cont_fn_t cont_fn; /* function to carry on suspended work */
struct id id; /* subject of query */
bool sgw_specified;
struct id sgw_id; /* peer, if constrained */
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 */
unsigned long qtid; /* query transaction id number */
int type; /* T_TXT or T_KEY, selecting rr type of interest */
cont_fn_t cont_fn; /* function to carry on suspended work */
struct id id; /* subject of query */
bool sgw_specified;
struct id sgw_id; /* peer, if constrained */
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 */
#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
struct adns_continuation *previous, *next;
struct pubkey *last_info; /* the last structure we accumulated */
struct adns_continuation *previous, *next;
struct pubkey *last_info; /* the last structure we accumulated */
#ifdef USE_LWRES
bool used; /* have we called the cont_fn yet? */
struct {
u_char name_buf[NS_MAXDNAME + 2];
} query;
bool used; /* have we called the cont_fn yet? */
struct {
u_char name_buf[NS_MAXDNAME + 2];
} query;
#else /* ! USE_LWRES */
struct adns_query query;
struct adns_query query;
#endif /* ! USE_LWRES */
};
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 */
, int type /* T_TXT or T_KEY, selecting rr type of interest */
, cont_fn_t cont_fn /* continuation function */
, struct adns_continuation *cr);
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 */
, int type /* T_TXT or T_KEY, selecting rr type of interest */
, cont_fn_t cont_fn /* continuation function */
, struct adns_continuation *cr);
/* Gateway info gleaned from reverse DNS of client */
struct gw_info {
unsigned refcnt; /* reference counted! */
unsigned pref; /* preference: lower is better */
#define NO_TIME ((time_t) -2) /* time_t value meaning "not_yet" */
struct id client_id; /* id of client of peer */
struct id gw_id; /* id of peer (if id_is_ipaddr, .ip_addr is address) */
bool gw_key_present;
struct pubkey *key;
struct gw_info *next;
unsigned refcnt; /* reference counted! */
unsigned pref; /* preference: lower is better */
#define NO_TIME ((time_t) -2) /* time_t value meaning "not_yet" */
struct id client_id; /* id of client of peer */
struct id gw_id; /* id of peer (if id_is_ipaddr, .ip_addr is address) */
bool gw_key_present;
struct pubkey *key;
struct gw_info *next;
};
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);

View File

@ -1,5 +1,5 @@
/* 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.
*
@ -44,19 +44,19 @@
#include "dsa.h"
typedef struct {
MPI p; /* prime */
MPI q; /* group order */
MPI g; /* group generator */
MPI y; /* g^x mod p */
MPI p; /* prime */
MPI q; /* group order */
MPI g; /* group generator */
MPI y; /* g^x mod p */
} DSA_public_key;
typedef struct {
MPI p; /* prime */
MPI q; /* group order */
MPI g; /* group generator */
MPI y; /* g^x mod p */
MPI x; /* secret exponent */
MPI p; /* prime */
MPI q; /* group order */
MPI g; /* group generator */
MPI y; /* g^x mod p */
MPI x; /* secret exponent */
} DSA_secret_key;
@ -70,7 +70,7 @@ static int verify(MPI r, MPI s, MPI input, DSA_public_key *pkey);
static void
progress( int c )
{
fputc( c, stderr );
fputc( c, stderr );
}
@ -80,82 +80,82 @@ progress( int c )
static MPI
gen_k( MPI q )
{
MPI k = mpi_alloc_secure( mpi_get_nlimbs(q) );
unsigned int nbits = mpi_get_nbits(q);
unsigned int nbytes = (nbits+7)/8;
char *rndbuf = NULL;
MPI k = mpi_alloc_secure( mpi_get_nlimbs(q) );
unsigned int nbits = mpi_get_nbits(q);
unsigned int nbytes = (nbits+7)/8;
char *rndbuf = NULL;
if( DBG_CIPHER )
log_debug("choosing a random k ");
for(;;) {
if( DBG_CIPHER )
progress('.');
log_debug("choosing a random k ");
for(;;) {
if( DBG_CIPHER )
progress('.');
if( !rndbuf || nbits < 32 ) {
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 );
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( !rndbuf || nbits < 32 ) {
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 );
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, q ) < 0) ) { /* check: k < q */
if( DBG_CIPHER )
progress('+');
continue; /* no */
if( !(mpi_cmp( k, q ) < 0) ) { /* check: k < q */
if( DBG_CIPHER )
progress('+');
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 */
if( DBG_CIPHER )
progress('-');
continue; /* no */
}
break; /* okay */
}
m_free(rndbuf);
if( DBG_CIPHER )
progress('\n');
m_free(rndbuf);
if( DBG_CIPHER )
progress('\n');
return k;
return k;
}
static void
test_keys( DSA_secret_key *sk, unsigned qbits )
{
DSA_public_key pk;
MPI test = 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 );
DSA_public_key pk;
MPI test = 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 );
pk.p = sk->p;
pk.q = sk->q;
pk.g = sk->g;
pk.y = sk->y;
/*mpi_set_bytes( test, qbits, get_random_byte, 0 );*/
{ char *p = get_random_bits( qbits, 0, 0 );
mpi_set_buffer( test, p, (qbits+7)/8, 0 );
m_free(p);
}
pk.p = sk->p;
pk.q = sk->q;
pk.g = sk->g;
pk.y = sk->y;
/*mpi_set_bytes( test, qbits, get_random_byte, 0 );*/
{ char *p = get_random_bits( qbits, 0, 0 );
mpi_set_buffer( test, p, (qbits+7)/8, 0 );
m_free(p);
}
sign( out1_a, out1_b, test, sk );
if( !verify( out1_a, out1_b, test, &pk ) )
log_fatal("DSA:: sign, verify failed\n");
sign( out1_a, out1_b, test, sk );
if( !verify( out1_a, out1_b, test, &pk ) )
log_fatal("DSA:: sign, verify failed\n");
mpi_free( test );
mpi_free( out1_a );
mpi_free( out1_b );
mpi_free( test );
mpi_free( out1_a );
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
* 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
generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors )
{
MPI p; /* the prime */
MPI q; /* the 160 bit prime factor */
MPI g; /* the generator */
MPI y; /* g^x mod p */
MPI x; /* the secret exponent */
MPI h, e; /* helper */
unsigned qbits;
byte *rndbuf;
MPI p; /* the prime */
MPI q; /* the 160 bit prime factor */
MPI g; /* the generator */
MPI y; /* g^x mod p */
MPI x; /* the secret exponent */
MPI h, e; /* helper */
unsigned qbits;
byte *rndbuf;
assert( nbits >= 512 && nbits <= 1024 );
assert( nbits >= 512 && nbits <= 1024 );
qbits = 160;
p = generate_elg_prime( 1, nbits, qbits, NULL, ret_factors );
/* get q out of factors */
q = mpi_copy((*ret_factors)[0]);
if( mpi_get_nbits(q) != qbits )
BUG();
qbits = 160;
p = generate_elg_prime( 1, nbits, qbits, NULL, ret_factors );
/* get q out of factors */
q = mpi_copy((*ret_factors)[0]);
if( mpi_get_nbits(q) != qbits )
BUG();
/* find a generator g (h and e are helpers)*/
/* e = (p-1)/q */
e = mpi_alloc( mpi_get_nlimbs(p) );
mpi_sub_ui( e, p, 1 );
mpi_fdiv_q( e, e, q );
g = mpi_alloc( mpi_get_nlimbs(p) );
h = mpi_alloc_set_ui( 1 ); /* we start with 2 */
do {
mpi_add_ui( h, h, 1 );
/* g = h^e mod p */
mpi_powm( g, h, e, p );
} while( !mpi_cmp_ui( g, 1 ) ); /* continue until g != 1 */
/* find a generator g (h and e are helpers)*/
/* e = (p-1)/q */
e = mpi_alloc( mpi_get_nlimbs(p) );
mpi_sub_ui( e, p, 1 );
mpi_fdiv_q( e, e, q );
g = mpi_alloc( mpi_get_nlimbs(p) );
h = mpi_alloc_set_ui( 1 ); /* we start with 2 */
do {
mpi_add_ui( h, h, 1 );
/* g = h^e mod p */
mpi_powm( g, h, e, p );
} while( !mpi_cmp_ui( g, 1 ) ); /* continue until g != 1 */
/* select a random number which has these properties:
* 0 < x < q-1
* This must be a very good random number because this
* 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 {
/* select a random number which has these properties:
* 0 < x < q-1
* This must be a very good random number because this
* is the secret part. */
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);
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 )
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 */
y = mpi_alloc( mpi_get_nlimbs(p) );
mpi_powm( y, g, x, p );
/* copy the stuff to the key structures */
sk->p = p;
sk->q = q;
sk->g = g;
sk->y = y;
sk->x = x;
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 );
}
/* 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 );
/* 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
check_secret_key( DSA_secret_key *sk )
{
int rc;
MPI y = mpi_alloc( mpi_get_nlimbs(sk->y) );
int rc;
MPI y = mpi_alloc( mpi_get_nlimbs(sk->y) );
mpi_powm( y, sk->g, sk->x, sk->p );
rc = !mpi_cmp( y, sk->y );
mpi_free( y );
return rc;
mpi_powm( y, sk->g, sk->x, sk->p );
rc = !mpi_cmp( y, sk->y );
mpi_free( y );
return rc;
}
@ -277,30 +277,30 @@ check_secret_key( DSA_secret_key *sk )
static void
sign(MPI r, MPI s, MPI hash, DSA_secret_key *skey )
{
MPI k;
MPI kinv;
MPI tmp;
MPI k;
MPI kinv;
MPI tmp;
/* select a random k with 0 < k < q */
k = gen_k( skey->q );
/* select a random k with 0 < k < q */
k = gen_k( skey->q );
/* r = (a^k mod p) mod q */
mpi_powm( r, skey->g, k, skey->p );
mpi_fdiv_r( r, r, skey->q );
/* r = (a^k mod p) mod q */
mpi_powm( r, skey->g, k, skey->p );
mpi_fdiv_r( r, r, skey->q );
/* kinv = k^(-1) mod q */
kinv = mpi_alloc( mpi_get_nlimbs(k) );
mpi_invm(kinv, k, skey->q );
/* kinv = k^(-1) mod q */
kinv = mpi_alloc( mpi_get_nlimbs(k) );
mpi_invm(kinv, k, skey->q );
/* s = (kinv * ( hash + x * r)) mod q */
tmp = mpi_alloc( mpi_get_nlimbs(skey->p) );
mpi_mul( tmp, skey->x, r );
mpi_add( tmp, tmp, hash );
mpi_mulm( s , kinv, tmp, skey->q );
/* s = (kinv * ( hash + x * r)) mod q */
tmp = mpi_alloc( mpi_get_nlimbs(skey->p) );
mpi_mul( tmp, skey->x, r );
mpi_add( tmp, tmp, hash );
mpi_mulm( s , kinv, tmp, skey->q );
mpi_free(k);
mpi_free(kinv);
mpi_free(tmp);
mpi_free(k);
mpi_free(kinv);
mpi_free(tmp);
}
@ -310,45 +310,45 @@ sign(MPI r, MPI s, MPI hash, DSA_secret_key *skey )
static int
verify(MPI r, MPI s, MPI hash, DSA_public_key *pkey )
{
int rc;
MPI w, u1, u2, v;
MPI base[3];
MPI exp[3];
int rc;
MPI w, u1, u2, v;
MPI base[3];
MPI exp[3];
if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) )
return 0; /* assertion 0 < r < q failed */
if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) )
return 0; /* assertion 0 < s < q failed */
if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) )
return 0; /* assertion 0 < r < q failed */
if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) )
return 0; /* assertion 0 < s < q failed */
w = mpi_alloc( mpi_get_nlimbs(pkey->q) );
u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
u2 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
v = mpi_alloc( mpi_get_nlimbs(pkey->p) );
w = mpi_alloc( mpi_get_nlimbs(pkey->q) );
u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
u2 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
v = mpi_alloc( mpi_get_nlimbs(pkey->p) );
/* w = s^(-1) mod q */
mpi_invm( w, s, pkey->q );
/* w = s^(-1) mod q */
mpi_invm( w, s, pkey->q );
/* u1 = (hash * w) mod q */
mpi_mulm( u1, hash, w, pkey->q );
/* u1 = (hash * w) mod q */
mpi_mulm( u1, hash, w, pkey->q );
/* u2 = r * w mod q */
mpi_mulm( u2, r, w, pkey->q );
/* u2 = r * w mod q */
mpi_mulm( u2, r, w, pkey->q );
/* v = g^u1 * y^u2 mod p mod q */
base[0] = pkey->g; exp[0] = u1;
base[1] = pkey->y; exp[1] = u2;
base[2] = NULL; exp[2] = NULL;
mpi_mulpowm( v, base, exp, pkey->p );
mpi_fdiv_r( v, v, pkey->q );
/* v = g^u1 * y^u2 mod p mod q */
base[0] = pkey->g; exp[0] = u1;
base[1] = pkey->y; exp[1] = u2;
base[2] = NULL; exp[2] = NULL;
mpi_mulpowm( v, base, exp, pkey->p );
mpi_fdiv_r( v, v, pkey->q );
rc = !mpi_cmp( v, r );
rc = !mpi_cmp( v, r );
mpi_free(w);
mpi_free(u1);
mpi_free(u2);
mpi_free(v);
return rc;
mpi_free(w);
mpi_free(u1);
mpi_free(u2);
mpi_free(v);
return rc;
}
@ -359,40 +359,40 @@ verify(MPI r, MPI s, MPI hash, DSA_public_key *pkey )
int
dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
{
DSA_secret_key sk;
DSA_secret_key sk;
if( algo != PUBKEY_ALGO_DSA )
return G10ERR_PUBKEY_ALGO;
if( algo != PUBKEY_ALGO_DSA )
return G10ERR_PUBKEY_ALGO;
generate( &sk, nbits, retfactors );
skey[0] = sk.p;
skey[1] = sk.q;
skey[2] = sk.g;
skey[3] = sk.y;
skey[4] = sk.x;
return 0;
generate( &sk, nbits, retfactors );
skey[0] = sk.p;
skey[1] = sk.q;
skey[2] = sk.g;
skey[3] = sk.y;
skey[4] = sk.x;
return 0;
}
int
dsa_check_secret_key( int algo, MPI *skey )
{
DSA_secret_key sk;
DSA_secret_key sk;
if( algo != PUBKEY_ALGO_DSA )
return G10ERR_PUBKEY_ALGO;
if( !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] )
return G10ERR_BAD_MPI;
if( algo != PUBKEY_ALGO_DSA )
return G10ERR_PUBKEY_ALGO;
if( !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] )
return G10ERR_BAD_MPI;
sk.p = skey[0];
sk.q = skey[1];
sk.g = skey[2];
sk.y = skey[3];
sk.x = skey[4];
if( !check_secret_key( &sk ) )
return G10ERR_BAD_SECKEY;
sk.p = skey[0];
sk.q = skey[1];
sk.g = skey[2];
sk.y = skey[3];
sk.x = skey[4];
if( !check_secret_key( &sk ) )
return G10ERR_BAD_SECKEY;
return 0;
return 0;
}
@ -400,43 +400,43 @@ dsa_check_secret_key( int algo, MPI *skey )
int
dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey )
{
DSA_secret_key sk;
DSA_secret_key sk;
if( algo != PUBKEY_ALGO_DSA )
return G10ERR_PUBKEY_ALGO;
if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] )
return G10ERR_BAD_MPI;
if( algo != PUBKEY_ALGO_DSA )
return G10ERR_PUBKEY_ALGO;
if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] )
return G10ERR_BAD_MPI;
sk.p = skey[0];
sk.q = skey[1];
sk.g = skey[2];
sk.y = skey[3];
sk.x = skey[4];
resarr[0] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
resarr[1] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
sign( resarr[0], resarr[1], data, &sk );
return 0;
sk.p = skey[0];
sk.q = skey[1];
sk.g = skey[2];
sk.y = skey[3];
sk.x = skey[4];
resarr[0] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
resarr[1] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
sign( resarr[0], resarr[1], data, &sk );
return 0;
}
int
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 )
return G10ERR_PUBKEY_ALGO;
if( !data[0] || !data[1] || !hash
|| !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] )
return G10ERR_BAD_MPI;
if( algo != PUBKEY_ALGO_DSA )
return G10ERR_PUBKEY_ALGO;
if( !data[0] || !data[1] || !hash
|| !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] )
return G10ERR_BAD_MPI;
pk.p = pkey[0];
pk.q = pkey[1];
pk.g = pkey[2];
pk.y = pkey[3];
if( !verify( data[0], data[1], hash, &pk ) )
return G10ERR_BAD_SIGN;
return 0;
pk.p = pkey[0];
pk.q = pkey[1];
pk.g = pkey[2];
pk.y = pkey[3];
if( !verify( data[0], data[1], hash, &pk ) )
return G10ERR_BAD_SIGN;
return 0;
}
@ -444,9 +444,9 @@ dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
unsigned
dsa_get_nbits( int algo, MPI *pkey )
{
if( algo != PUBKEY_ALGO_DSA )
return 0;
return mpi_get_nbits( pkey[0] );
if( algo != PUBKEY_ALGO_DSA )
return 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
* distinguish different flavors of the algorithm.
* 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
* 1 set : allows encryption
* 1 set : allows encryption
*/
const char *
dsa_get_info( int algo, int *npkey, int *nskey, int *nenc, int *nsig,
int *use )
int *use )
{
*npkey = 4;
*nskey = 5;
*nenc = 0;
*nsig = 2;
*npkey = 4;
*nskey = 5;
*nenc = 0;
*nsig = 2;
switch( algo ) {
case PUBKEY_ALGO_DSA: *use = PUBKEY_USAGE_SIG; return "DSA";
default: *use = 0; return NULL;
}
switch( algo ) {
case PUBKEY_ALGO_DSA: *use = PUBKEY_USAGE_SIG; return "DSA";
default: *use = 0; return NULL;
}
}

View File

@ -1,5 +1,5 @@
/* 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.
*
@ -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_sign( int algo, MPI *resarr, MPI data, MPI *skey );
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 );
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*/

View File

@ -1,5 +1,5 @@
/* 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:
* Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
@ -47,17 +47,17 @@
#include "elgamal.h"
typedef struct {
MPI p; /* prime */
MPI g; /* group generator */
MPI y; /* g^x mod p */
MPI p; /* prime */
MPI g; /* group generator */
MPI y; /* g^x mod p */
} ELG_public_key;
typedef struct {
MPI p; /* prime */
MPI g; /* group generator */
MPI y; /* g^x mod p */
MPI x; /* secret exponent */
MPI p; /* prime */
MPI g; /* group generator */
MPI y; /* g^x mod p */
MPI x; /* secret exponent */
} ELG_secret_key;
@ -74,42 +74,42 @@ static int verify(MPI a, MPI b, MPI input, ELG_public_key *pkey);
static void
progress( int c )
{
fputc( c, stderr );
fputc( c, stderr );
}
static void
test_keys( ELG_secret_key *sk, unsigned nbits )
{
ELG_public_key pk;
MPI test = mpi_alloc( 0 );
MPI out1_a = 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 );
ELG_public_key pk;
MPI test = mpi_alloc( 0 );
MPI out1_a = 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 );
pk.p = sk->p;
pk.g = sk->g;
pk.y = sk->y;
pk.p = sk->p;
pk.g = sk->g;
pk.y = sk->y;
/*mpi_set_bytes( test, nbits, get_random_byte, 0 );*/
{ char *p = get_random_bits( nbits, 0, 0 );
mpi_set_buffer( test, p, (nbits+7)/8, 0 );
m_free(p);
}
/*mpi_set_bytes( test, nbits, get_random_byte, 0 );*/
{ char *p = get_random_bits( nbits, 0, 0 );
mpi_set_buffer( test, p, (nbits+7)/8, 0 );
m_free(p);
}
encrypt( out1_a, out1_b, test, &pk );
decrypt( out2, out1_a, out1_b, sk );
if( mpi_cmp( test, out2 ) )
log_fatal("ElGamal operation: encrypt, decrypt failed\n");
encrypt( out1_a, out1_b, test, &pk );
decrypt( out2, out1_a, out1_b, sk );
if( mpi_cmp( test, out2 ) )
log_fatal("ElGamal operation: encrypt, decrypt failed\n");
sign( out1_a, out1_b, test, sk );
if( !verify( out1_a, out1_b, test, &pk ) )
log_fatal("ElGamal operation: sign, verify failed\n");
sign( out1_a, out1_b, test, sk );
if( !verify( out1_a, out1_b, test, &pk ) )
log_fatal("ElGamal operation: sign, verify failed\n");
mpi_free( test );
mpi_free( out1_a );
mpi_free( out1_b );
mpi_free( out2 );
mpi_free( test );
mpi_free( out1_a );
mpi_free( out1_b );
mpi_free( out2 );
}
@ -120,151 +120,151 @@ test_keys( ELG_secret_key *sk, unsigned nbits )
static MPI
gen_k( MPI p )
{
MPI k = mpi_alloc_secure( 0 );
MPI temp = mpi_alloc( mpi_get_nlimbs(p) );
MPI p_1 = mpi_copy(p);
unsigned int nbits = mpi_get_nbits(p);
unsigned int nbytes = (nbits+7)/8;
char *rndbuf = NULL;
MPI k = mpi_alloc_secure( 0 );
MPI temp = mpi_alloc( mpi_get_nlimbs(p) );
MPI p_1 = mpi_copy(p);
unsigned int nbits = mpi_get_nbits(p);
unsigned int nbytes = (nbits+7)/8;
char *rndbuf = NULL;
if( DBG_CIPHER )
log_debug("choosing a random k ");
mpi_sub_ui( p_1, p, 1);
for(;;) {
if( DBG_CIPHER )
progress('.');
if( !rndbuf || nbits < 32 ) {
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 );
log_debug("choosing a random k ");
mpi_sub_ui( p_1, p, 1);
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);
progress('.');
if( !rndbuf || nbits < 32 ) {
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 );
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
* 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
generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
{
MPI p; /* the prime */
MPI p_min1;
MPI g;
MPI x; /* the secret exponent */
MPI y;
MPI temp;
unsigned qbits;
byte *rndbuf;
MPI p; /* the prime */
MPI p_min1;
MPI g;
MPI x; /* the secret exponent */
MPI y;
MPI temp;
unsigned qbits;
byte *rndbuf;
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 );
if( nbits < 512 )
qbits = 120;
else if( nbits <= 1024 )
qbits = 160;
else if( nbits <= 2048 )
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);
}
}
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 );
if( nbits < 512 )
qbits = 120;
else if( nbits <= 1024 )
qbits = 160;
else if( nbits <= 2048 )
qbits = 200;
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);
qbits = 240;
g = mpi_alloc(1);
p = generate_elg_prime( 0, nbits, qbits, g, ret_factors );
mpi_sub_ui(p_min1, p, 1);
y = mpi_alloc(nbits/BITS_PER_MPI_LIMB);
mpi_powm( y, g, x, p );
if( DBG_CIPHER ) {
progress('\n');
log_mpidump("elg p= ", p );
log_mpidump("elg g= ", g );
log_mpidump("elg y= ", y );
log_mpidump("elg x= ", x );
}
/* 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
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 */
sk->p = p;
sk->g = g;
sk->y = y;
sk->x = x;
y = mpi_alloc(nbits/BITS_PER_MPI_LIMB);
mpi_powm( y, g, x, p );
/* now we can test our keys (this should never fail!) */
test_keys( sk, nbits - 64 );
if( DBG_CIPHER ) {
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 );
mpi_free( temp );
/* copy the stuff to the key structures */
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
check_secret_key( ELG_secret_key *sk )
{
int rc;
MPI y = mpi_alloc( mpi_get_nlimbs(sk->y) );
int rc;
MPI y = mpi_alloc( mpi_get_nlimbs(sk->y) );
mpi_powm( y, sk->g, sk->x, sk->p );
rc = !mpi_cmp( y, sk->y );
mpi_free( y );
return rc;
mpi_powm( y, sk->g, sk->x, sk->p );
rc = !mpi_cmp( y, sk->y );
mpi_free( y );
return rc;
}
static void
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
* is possible to check that input is < p and return an
* error code.
*/
/* Note: maybe we should change the interface, so that it
* is possible to check that input is < p and return an
* error code.
*/
k = gen_k( pkey->p );
mpi_powm( a, pkey->g, k, pkey->p );
/* b = (y^k * input) mod p
* = ((y^k mod p) * (input mod p)) mod p
* and because input is < p
* = ((y^k mod p) * input) mod p
*/
mpi_powm( b, pkey->y, k, pkey->p );
mpi_mulm( b, b, input, pkey->p );
k = gen_k( pkey->p );
mpi_powm( a, pkey->g, k, pkey->p );
/* b = (y^k * input) mod p
* = ((y^k mod p) * (input mod p)) mod p
* and because input is < p
* = ((y^k mod p) * input) mod p
*/
mpi_powm( b, pkey->y, k, pkey->p );
mpi_mulm( b, b, input, pkey->p );
#if 0
if( DBG_CIPHER ) {
log_mpidump("elg encrypted y= ", pkey->y);
log_mpidump("elg encrypted p= ", pkey->p);
log_mpidump("elg encrypted k= ", k);
log_mpidump("elg encrypted M= ", input);
log_mpidump("elg encrypted a= ", a);
log_mpidump("elg encrypted b= ", b);
}
if( DBG_CIPHER ) {
log_mpidump("elg encrypted y= ", pkey->y);
log_mpidump("elg encrypted p= ", pkey->p);
log_mpidump("elg encrypted k= ", k);
log_mpidump("elg encrypted M= ", input);
log_mpidump("elg encrypted a= ", a);
log_mpidump("elg encrypted b= ", b);
}
#endif
mpi_free(k);
mpi_free(k);
}
@ -323,23 +323,23 @@ encrypt(MPI a, MPI b, MPI input, ELG_public_key *pkey )
static void
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_invm( t1, t1, skey->p );
mpi_mulm( output, b, t1, skey->p );
mpi_powm( t1, a, skey->x, skey->p );
mpi_invm( t1, t1, skey->p );
mpi_mulm( output, b, t1, skey->p );
#if 0
if( DBG_CIPHER ) {
log_mpidump("elg decrypted x= ", skey->x);
log_mpidump("elg decrypted p= ", skey->p);
log_mpidump("elg decrypted a= ", a);
log_mpidump("elg decrypted b= ", b);
log_mpidump("elg decrypted M= ", output);
}
if( DBG_CIPHER ) {
log_mpidump("elg decrypted x= ", skey->x);
log_mpidump("elg decrypted p= ", skey->p);
log_mpidump("elg decrypted a= ", a);
log_mpidump("elg decrypted b= ", b);
log_mpidump("elg decrypted M= ", output);
}
#endif
mpi_free(t1);
mpi_free(t1);
}
@ -350,43 +350,43 @@ decrypt(MPI output, MPI a, MPI b, ELG_secret_key *skey )
static void
sign(MPI a, MPI b, MPI input, ELG_secret_key *skey )
{
MPI k;
MPI t = mpi_alloc( mpi_get_nlimbs(a) );
MPI inv = mpi_alloc( mpi_get_nlimbs(a) );
MPI p_1 = mpi_copy(skey->p);
MPI k;
MPI t = mpi_alloc( mpi_get_nlimbs(a) );
MPI inv = mpi_alloc( mpi_get_nlimbs(a) );
MPI p_1 = mpi_copy(skey->p);
/*
* b = (t * inv) 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)
*
*/
mpi_sub_ui(p_1, p_1, 1);
k = gen_k( skey->p );
mpi_powm( a, skey->g, k, skey->p );
mpi_mul(t, skey->x, a );
mpi_subm(t, input, t, p_1 );
while( mpi_is_neg(t) )
mpi_add(t, t, p_1);
mpi_invm(inv, k, p_1 );
mpi_mulm(b, t, inv, p_1 );
* b = (t * inv) 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)
*
*/
mpi_sub_ui(p_1, p_1, 1);
k = gen_k( skey->p );
mpi_powm( a, skey->g, k, skey->p );
mpi_mul(t, skey->x, a );
mpi_subm(t, input, t, p_1 );
while( mpi_is_neg(t) )
mpi_add(t, t, p_1);
mpi_invm(inv, k, p_1 );
mpi_mulm(b, t, inv, p_1 );
#if 0
if( DBG_CIPHER ) {
log_mpidump("elg sign p= ", skey->p);
log_mpidump("elg sign g= ", skey->g);
log_mpidump("elg sign y= ", skey->y);
log_mpidump("elg sign x= ", skey->x);
log_mpidump("elg sign k= ", k);
log_mpidump("elg sign M= ", input);
log_mpidump("elg sign a= ", a);
log_mpidump("elg sign b= ", b);
}
if( DBG_CIPHER ) {
log_mpidump("elg sign p= ", skey->p);
log_mpidump("elg sign g= ", skey->g);
log_mpidump("elg sign y= ", skey->y);
log_mpidump("elg sign x= ", skey->x);
log_mpidump("elg sign k= ", k);
log_mpidump("elg sign M= ", input);
log_mpidump("elg sign a= ", a);
log_mpidump("elg sign b= ", b);
}
#endif
mpi_free(k);
mpi_free(t);
mpi_free(inv);
mpi_free(p_1);
mpi_free(k);
mpi_free(t);
mpi_free(inv);
mpi_free(p_1);
}
@ -396,54 +396,54 @@ sign(MPI a, MPI b, MPI input, ELG_secret_key *skey )
static int
verify(MPI a, MPI b, MPI input, ELG_public_key *pkey )
{
int rc;
MPI t1;
MPI t2;
MPI base[4];
MPI exp[4];
int rc;
MPI t1;
MPI t2;
MPI base[4];
MPI exp[4];
if( !(mpi_cmp_ui( a, 0 ) > 0 && mpi_cmp( a, pkey->p ) < 0) )
return 0; /* assertion 0 < a < p failed */
if( !(mpi_cmp_ui( a, 0 ) > 0 && mpi_cmp( a, pkey->p ) < 0) )
return 0; /* assertion 0 < a < p failed */
t1 = mpi_alloc( mpi_get_nlimbs(a) );
t2 = mpi_alloc( mpi_get_nlimbs(a) );
t1 = mpi_alloc( mpi_get_nlimbs(a) );
t2 = mpi_alloc( mpi_get_nlimbs(a) );
#if 0
/* t1 = (y^a mod p) * (a^b mod p) mod p */
mpi_powm( t1, pkey->y, a, pkey->p );
mpi_powm( t2, a, b, pkey->p );
mpi_mulm( t1, t1, t2, pkey->p );
/* t1 = (y^a mod p) * (a^b mod p) mod p */
mpi_powm( t1, pkey->y, a, pkey->p );
mpi_powm( t2, a, b, pkey->p );
mpi_mulm( t1, t1, t2, pkey->p );
/* t2 = g ^ input mod p */
mpi_powm( t2, pkey->g, input, pkey->p );
/* t2 = g ^ input mod p */
mpi_powm( t2, pkey->g, input, pkey->p );
rc = !mpi_cmp( t1, t2 );
rc = !mpi_cmp( t1, t2 );
#elif 0
/* t1 = (y^a mod p) * (a^b mod p) mod p */
base[0] = pkey->y; exp[0] = a;
base[1] = a; exp[1] = b;
base[2] = NULL; exp[2] = NULL;
mpi_mulpowm( t1, base, exp, pkey->p );
/* t1 = (y^a mod p) * (a^b mod p) mod p */
base[0] = pkey->y; exp[0] = a;
base[1] = a; exp[1] = b;
base[2] = NULL; exp[2] = NULL;
mpi_mulpowm( t1, base, exp, pkey->p );
/* t2 = g ^ input mod p */
mpi_powm( t2, pkey->g, input, pkey->p );
/* t2 = g ^ input mod p */
mpi_powm( t2, pkey->g, input, pkey->p );
rc = !mpi_cmp( t1, t2 );
rc = !mpi_cmp( t1, t2 );
#else
/* t1 = g ^ - input * y ^ a * a ^ b mod p */
mpi_invm(t2, pkey->g, pkey->p );
base[0] = t2 ; exp[0] = input;
base[1] = pkey->y; exp[1] = a;
base[2] = a; exp[2] = b;
base[3] = NULL; exp[3] = NULL;
mpi_mulpowm( t1, base, exp, pkey->p );
rc = !mpi_cmp_ui( t1, 1 );
/* t1 = g ^ - input * y ^ a * a ^ b mod p */
mpi_invm(t2, pkey->g, pkey->p );
base[0] = t2 ; exp[0] = input;
base[1] = pkey->y; exp[1] = a;
base[2] = a; exp[2] = b;
base[3] = NULL; exp[3] = NULL;
mpi_mulpowm( t1, base, exp, pkey->p );
rc = !mpi_cmp_ui( t1, 1 );
#endif
mpi_free(t1);
mpi_free(t2);
return rc;
mpi_free(t1);
mpi_free(t2);
return rc;
}
/*********************************************
@ -453,38 +453,38 @@ verify(MPI a, MPI b, MPI input, ELG_public_key *pkey )
int
elg_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
{
ELG_secret_key sk;
ELG_secret_key sk;
if( !is_ELGAMAL(algo) )
return G10ERR_PUBKEY_ALGO;
if( !is_ELGAMAL(algo) )
return G10ERR_PUBKEY_ALGO;
generate( &sk, nbits, retfactors );
skey[0] = sk.p;
skey[1] = sk.g;
skey[2] = sk.y;
skey[3] = sk.x;
return 0;
generate( &sk, nbits, retfactors );
skey[0] = sk.p;
skey[1] = sk.g;
skey[2] = sk.y;
skey[3] = sk.x;
return 0;
}
int
elg_check_secret_key( int algo, MPI *skey )
{
ELG_secret_key sk;
ELG_secret_key sk;
if( !is_ELGAMAL(algo) )
return G10ERR_PUBKEY_ALGO;
if( !skey[0] || !skey[1] || !skey[2] || !skey[3] )
return G10ERR_BAD_MPI;
if( !is_ELGAMAL(algo) )
return G10ERR_PUBKEY_ALGO;
if( !skey[0] || !skey[1] || !skey[2] || !skey[3] )
return G10ERR_BAD_MPI;
sk.p = skey[0];
sk.g = skey[1];
sk.y = skey[2];
sk.x = skey[3];
if( !check_secret_key( &sk ) )
return G10ERR_BAD_SECKEY;
sk.p = skey[0];
sk.g = skey[1];
sk.y = skey[2];
sk.x = skey[3];
if( !check_secret_key( &sk ) )
return G10ERR_BAD_SECKEY;
return 0;
return 0;
}
@ -492,80 +492,80 @@ elg_check_secret_key( int algo, MPI *skey )
int
elg_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
{
ELG_public_key pk;
ELG_public_key pk;
if( !is_ELGAMAL(algo) )
return G10ERR_PUBKEY_ALGO;
if( !data || !pkey[0] || !pkey[1] || !pkey[2] )
return G10ERR_BAD_MPI;
if( !is_ELGAMAL(algo) )
return G10ERR_PUBKEY_ALGO;
if( !data || !pkey[0] || !pkey[1] || !pkey[2] )
return G10ERR_BAD_MPI;
pk.p = pkey[0];
pk.g = pkey[1];
pk.y = pkey[2];
resarr[0] = mpi_alloc( mpi_get_nlimbs( pk.p ) );
resarr[1] = mpi_alloc( mpi_get_nlimbs( pk.p ) );
encrypt( resarr[0], resarr[1], data, &pk );
return 0;
pk.p = pkey[0];
pk.g = pkey[1];
pk.y = pkey[2];
resarr[0] = mpi_alloc( mpi_get_nlimbs( pk.p ) );
resarr[1] = mpi_alloc( mpi_get_nlimbs( pk.p ) );
encrypt( resarr[0], resarr[1], data, &pk );
return 0;
}
int
elg_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
{
ELG_secret_key sk;
ELG_secret_key sk;
if( !is_ELGAMAL(algo) )
return G10ERR_PUBKEY_ALGO;
if( !data[0] || !data[1]
|| !skey[0] || !skey[1] || !skey[2] || !skey[3] )
return G10ERR_BAD_MPI;
if( !is_ELGAMAL(algo) )
return G10ERR_PUBKEY_ALGO;
if( !data[0] || !data[1]
|| !skey[0] || !skey[1] || !skey[2] || !skey[3] )
return G10ERR_BAD_MPI;
sk.p = skey[0];
sk.g = skey[1];
sk.y = skey[2];
sk.x = skey[3];
*result = mpi_alloc_secure( mpi_get_nlimbs( sk.p ) );
decrypt( *result, data[0], data[1], &sk );
return 0;
sk.p = skey[0];
sk.g = skey[1];
sk.y = skey[2];
sk.x = skey[3];
*result = mpi_alloc_secure( mpi_get_nlimbs( sk.p ) );
decrypt( *result, data[0], data[1], &sk );
return 0;
}
int
elg_sign( int algo, MPI *resarr, MPI data, MPI *skey )
{
ELG_secret_key sk;
ELG_secret_key sk;
if( !is_ELGAMAL(algo) )
return G10ERR_PUBKEY_ALGO;
if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] )
return G10ERR_BAD_MPI;
if( !is_ELGAMAL(algo) )
return G10ERR_PUBKEY_ALGO;
if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] )
return G10ERR_BAD_MPI;
sk.p = skey[0];
sk.g = skey[1];
sk.y = skey[2];
sk.x = skey[3];
resarr[0] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
resarr[1] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
sign( resarr[0], resarr[1], data, &sk );
return 0;
sk.p = skey[0];
sk.g = skey[1];
sk.y = skey[2];
sk.x = skey[3];
resarr[0] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
resarr[1] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
sign( resarr[0], resarr[1], data, &sk );
return 0;
}
int
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) )
return G10ERR_PUBKEY_ALGO;
if( !data[0] || !data[1] || !hash
|| !pkey[0] || !pkey[1] || !pkey[2] )
return G10ERR_BAD_MPI;
if( !is_ELGAMAL(algo) )
return G10ERR_PUBKEY_ALGO;
if( !data[0] || !data[1] || !hash
|| !pkey[0] || !pkey[1] || !pkey[2] )
return G10ERR_BAD_MPI;
pk.p = pkey[0];
pk.g = pkey[1];
pk.y = pkey[2];
if( !verify( data[0], data[1], hash, &pk ) )
return G10ERR_BAD_SIGN;
return 0;
pk.p = pkey[0];
pk.g = pkey[1];
pk.y = pkey[2];
if( !verify( data[0], data[1], hash, &pk ) )
return G10ERR_BAD_SIGN;
return 0;
}
@ -573,9 +573,9 @@ elg_verify( int algo, MPI hash, MPI *data, MPI *pkey,
unsigned
elg_get_nbits( int algo, MPI *pkey )
{
if( !is_ELGAMAL(algo) )
return 0;
return mpi_get_nbits( pkey[0] );
if( !is_ELGAMAL(algo) )
return 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
* distinguish different flavors of the algorithm.
* 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
* 1 set : allows encryption
* 1 set : allows encryption
* 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
* is done in the gnupg ocde depending on the packet version.
*/
const char *
elg_get_info( int algo, int *npkey, int *nskey, int *nenc, int *nsig,
int *use )
int *use )
{
*npkey = 3;
*nskey = 4;
*nenc = 2;
*nsig = 2;
*npkey = 3;
*nskey = 4;
*nenc = 2;
*nsig = 2;
switch( algo ) {
case PUBKEY_ALGO_ELGAMAL:
*use = PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC;
return "ELG";
case PUBKEY_ALGO_ELGAMAL_E:
*use = PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC;
return "ELG-E";
default: *use = 0; return NULL;
}
switch( algo ) {
case PUBKEY_ALGO_ELGAMAL:
*use = PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC;
return "ELG";
case PUBKEY_ALGO_ELGAMAL_E:
*use = PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC;
return "ELG-E";
default: *use = 0; return NULL;
}
}

View File

@ -1,5 +1,5 @@
/* elgamal.h
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998 Free Software Foundation, Inc.
*
* 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_sign( int algo, MPI *resarr, MPI data, MPI *skey );
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 );
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*/

File diff suppressed because it is too large Load Diff

View File

@ -17,25 +17,25 @@
#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 {
FETCH_GET = 1,
FETCH_POST = 2
FETCH_GET = 1,
FETCH_POST = 2
} fetch_request_t;
typedef struct fetch_req fetch_req_t;
struct fetch_req {
fetch_req_t *next;
time_t installed;
int trials;
chunk_t issuer;
chunk_t authKeyID;
chunk_t authKeySerialNumber;
generalName_t *distributionPoints;
fetch_req_t *next;
time_t installed;
int trials;
chunk_t issuer;
chunk_t authKeyID;
chunk_t authKeySerialNumber;
generalName_t *distributionPoints;
};
#ifdef THREADS
@ -67,9 +67,9 @@ extern void init_fetch(void);
extern void free_crl_fetch(void);
extern void free_ocsp_fetch(void);
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
, 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_ocsp_fetch_request(struct ocsp_location *location, chunk_t serialNumber);
extern void list_distribution_points(const generalName_t *gn);

View File

@ -49,8 +49,8 @@ static size_t fg_path_space = 0;
*/
struct fg_groups {
struct fg_groups *next;
struct connection *connection;
struct fg_groups *next;
struct connection *connection;
};
static struct fg_groups *groups = NULL;
@ -66,10 +66,10 @@ static struct fg_groups *groups = NULL;
*/
struct fg_targets {
struct fg_targets *next;
struct fg_groups *group;
ip_subnet subnet;
char *name; /* name of instance of group conn */
struct fg_targets *next;
struct fg_groups *group;
ip_subnet subnet;
char *name; /* name of instance of group conn */
};
static struct fg_targets *targets = NULL;
@ -83,24 +83,24 @@ struct fg_targets *new_targets;
static int
ipcmp(ip_address *a, ip_address *b)
{
if (addrtypeof(a) != addrtypeof(b))
{
return addrtypeof(a) < addrtypeof(b)? -1 : 1;
}
else if (sameaddr(a, b))
{
return 0;
}
else
{
const struct sockaddr *sa = sockaddrof(a)
, *sb = sockaddrof(b);
if (addrtypeof(a) != addrtypeof(b))
{
return addrtypeof(a) < addrtypeof(b)? -1 : 1;
}
else if (sameaddr(a, b))
{
return 0;
}
else
{
const struct sockaddr *sa = sockaddrof(a)
, *sb = sockaddrof(b);
passert(addrtypeof(a) == AF_INET); /* not yet implemented IPv6 version :-( */
return (ntohl(((const struct sockaddr_in *)sa)->sin_addr.s_addr)
< ntohl(((const struct sockaddr_in *)sb)->sin_addr.s_addr))
? -1 : 1;
}
passert(addrtypeof(a) == AF_INET); /* not yet implemented IPv6 version :-( */
return (ntohl(((const struct sockaddr_in *)sa)->sin_addr.s_addr)
< ntohl(((const struct sockaddr_in *)sb)->sin_addr.s_addr))
? -1 : 1;
}
}
/* subnetcmp compares the two ip_subnet values a and b.
@ -110,353 +110,353 @@ ipcmp(ip_address *a, ip_address *b)
static int
subnetcmp(const ip_subnet *a, const ip_subnet *b)
{
ip_address neta, maska, netb, maskb;
int r;
ip_address neta, maska, netb, maskb;
int r;
networkof(a, &neta);
maskof(a, &maska);
networkof(b, &netb);
maskof(b, &maskb);
r = ipcmp(&neta, &netb);
if (r == 0)
r = ipcmp(&maska, &maskb);
return r;
networkof(a, &neta);
maskof(a, &maska);
networkof(b, &netb);
maskof(b, &maskb);
r = ipcmp(&neta, &netb);
if (r == 0)
r = ipcmp(&maska, &maskb);
return r;
}
static void
read_foodgroup(struct fg_groups *g)
{
const char *fgn = g->connection->name;
const ip_subnet *lsn = &g->connection->spd.this.client;
size_t plen = strlen(policygroups_dir) + 1 + strlen(fgn) + 1;
struct file_lex_position flp_space;
const char *fgn = g->connection->name;
const ip_subnet *lsn = &g->connection->spd.this.client;
size_t plen = strlen(policygroups_dir) + 1 + strlen(fgn) + 1;
struct file_lex_position flp_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 (;;)
if (plen > fg_path_space)
{
switch (flp->bdry)
{
case B_none:
{
/* !!! 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(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 (ugh != NULL)
{
loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s \"%s\""
, 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)
{
if (*pp == NULL)
{
r = -1; /* end of list is infinite */
break;
}
r = subnetcmp(lsn, &(*pp)->group->connection->spd.this.client);
if (r == 0)
r = subnetcmp(&sn, &(*pp)->subnet);
if (r <= 0)
break;
}
if (r == 0)
{
char source[SUBNETTOT_BUF];
subnettot(lsn, 0, source, sizeof(source));
loglog(RC_LOG_SERIOUS
, "\"%s\" line %d: subnet \"%s\", source %s, already \"%s\""
, flp->filename
, flp->lino
, tok
, source
, (*pp)->group->connection->name);
}
else
{
struct fg_targets *f = malloc_thing(struct fg_targets);
f->next = *pp;
f->group = g;
f->subnet = sn;
f->name = NULL;
*pp = f;
}
}
}
(void)shift(); /* next */
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 */
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)
{
case B_none:
{
/* !!! 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(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 (ugh != NULL)
{
loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s \"%s\""
, 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)
{
if (*pp == NULL)
{
r = -1; /* end of list is infinite */
break;
}
r = subnetcmp(lsn, &(*pp)->group->connection->spd.this.client);
if (r == 0)
r = subnetcmp(&sn, &(*pp)->subnet);
if (r <= 0)
break;
}
if (r == 0)
{
char source[SUBNETTOT_BUF];
subnettot(lsn, 0, source, sizeof(source));
loglog(RC_LOG_SERIOUS
, "\"%s\" line %d: subnet \"%s\", source %s, already \"%s\""
, flp->filename
, flp->lino
, tok
, source
, (*pp)->group->connection->name);
}
else
{
struct fg_targets *f = malloc_thing(struct fg_targets);
f->next = *pp;
f->group = g;
f->subnet = sn;
f->name = NULL;
*pp = f;
}
}
}
(void)shift(); /* next */
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();
}
lexclose();
}
}
static void
free_targets(void)
{
while (targets != NULL)
{
struct fg_targets *t = targets;
while (targets != NULL)
{
struct fg_targets *t = targets;
targets = t->next;
free(t->name);
free(t);
}
targets = t->next;
free(t->name);
free(t);
}
}
void
load_groups(void)
{
passert(new_targets == NULL);
passert(new_targets == NULL);
/* 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,
/* for each group, add config file targets into new_targets */
{
struct fg_targets *t;
struct fg_groups *g;
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 (g = groups; g != NULL; g = g->next)
if (oriented(*g->connection))
read_foodgroup(g);
}
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;
}
/* dump new_targets */
DBG(DBG_CONTROL,
{
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
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;
groups = g;
g->next = groups;
groups = g;
g->connection = c;
g->connection = c;
}
static struct fg_groups *
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)
;
return g;
for (g = groups; g != NULL && g->connection != c; g = g->next)
;
return g;
}
void
route_group(struct connection *c)
{
/* it makes no sense to route a connection that is ISAKMP-only */
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)
/* it makes no sense to route a connection that is ISAKMP-only */
if (!NEVER_NEGOTIATE(c->policy) && !HAS_IPSEC_POLICY(c->policy))
{
if (t->group == g)
{
struct connection *ci = con_by_name(t->name, FALSE);
if (ci != NULL)
{
set_cur_connection(ci);
if (!trap_connection(ci))
whack_log(RC_ROUTE, "could not route");
set_cur_connection(c);
}
}
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)
{
struct connection *ci = con_by_name(t->name, FALSE);
if (ci != NULL)
{
set_cur_connection(ci);
if (!trap_connection(ci))
whack_log(RC_ROUTE, "could not route");
set_cur_connection(c);
}
}
}
}
}
}
void
unroute_group(struct connection *c)
{
struct fg_groups *g = find_group(c);
struct fg_targets *t;
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)
passert(g != NULL);
g->connection->policy &= ~POLICY_GROUTED;
for (t = targets; t != NULL; t = t->next)
{
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)
{
set_cur_connection(ci);
unroute_connection(ci);
set_cur_connection(c);
}
if (ci != NULL)
{
set_cur_connection(ci);
unroute_connection(ci);
set_cur_connection(c);
}
}
}
}
}
void
delete_group(const struct connection *c)
{
struct fg_groups *g;
struct fg_groups *g;
/* 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; )
/* find and remove from groups */
{
struct fg_targets *t = *pp;
struct fg_groups **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;
}
for (pp = &groups; (g = *pp)->connection != c; pp = &(*pp)->next)
;
*pp = g->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);
}

View File

@ -14,7 +14,7 @@
* RCSID $Id$
*/
struct connection; /* forward declaration */
struct connection; /* forward declaration */
extern void add_group(struct connection *c);
extern void route_group(struct connection *c);
extern void unroute_group(struct connection *c);

View File

@ -22,134 +22,134 @@
#include "defs.h"
#include "log.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_alloc( unsigned nlimbs UNUSED )
{
MPI n = malloc(sizeof *n);
MPI n = malloc(sizeof *n);
mpz_init(n);
return n;
mpz_init(n);
return n;
}
MPI
mpi_alloc_secure( unsigned nlimbs )
{
return mpi_alloc(nlimbs);
return mpi_alloc(nlimbs);
}
MPI
mpi_alloc_set_ui( unsigned long u)
{
MPI n = malloc(sizeof *n);
MPI n = malloc(sizeof *n);
mpz_init_set_ui(n, u);
return n;
mpz_init_set_ui(n, u);
return n;
}
MPI
mpi_copy( MPI a )
{
MPI n = malloc(sizeof *n);
MPI n = malloc(sizeof *n);
mpz_init_set(n, a);
return n;
mpz_init_set(n, a);
return n;
}
void
mpi_free( MPI a )
{
mpz_clear(a);
free(a);
mpz_clear(a);
free(a);
}
int
mpi_divisible_ui(MPI dividend, ulong divisor )
{
ulong rem;
mpz_t remtoo;
ulong rem;
mpz_t remtoo;
mpz_init(remtoo);
rem = mpz_mod_ui(remtoo, dividend, divisor);
mpz_clear(remtoo);
return rem == 0;
mpz_init(remtoo);
rem = mpz_mod_ui(remtoo, dividend, divisor);
mpz_clear(remtoo);
return rem == 0;
}
unsigned
mpi_trailing_zeros( MPI a )
{
return mpz_scan1(a, 0);
return mpz_scan1(a, 0);
}
unsigned
mpi_get_nbits( MPI a )
{
return mpz_sizeinbase(a, 2);
return mpz_sizeinbase(a, 2);
}
int
mpi_test_bit( MPI a, unsigned n )
{
/* inspired by gmp/mpz/clrbit.c */
mp_size_t li = n / mp_bits_per_limb;
/* inspired by gmp/mpz/clrbit.c */
mp_size_t li = n / mp_bits_per_limb;
if (li >= a->_mp_size)
return 0;
return (a->_mp_d[li] & ((mp_limb_t) 1 << (n % mp_bits_per_limb))) != 0;
if (li >= a->_mp_size)
return 0;
return (a->_mp_d[li] & ((mp_limb_t) 1 << (n % mp_bits_per_limb))) != 0;
}
void
mpi_set_bit( MPI a, unsigned n )
{
mpz_setbit(a, n);
mpz_setbit(a, n);
}
void
mpi_clear_bit( MPI a, unsigned n )
{
mpz_clrbit(a, n);
mpz_clrbit(a, n);
}
void
mpi_clear_highbit( MPI a, unsigned n )
{
/* This seems whacky, but what do I know. */
mpz_fdiv_r_2exp(a, a, n);
/* This seems whacky, but what do I know. */
mpz_fdiv_r_2exp(a, a, n);
}
void
mpi_set_highbit( MPI a, unsigned n )
{
/* This seems whacky, but what do I know. */
mpz_fdiv_r_2exp(a, a, n+1);
mpz_setbit(a, n);
/* This seems whacky, but what do I know. */
mpz_fdiv_r_2exp(a, a, n+1);
mpz_setbit(a, n);
}
void
mpi_set_buffer( MPI a, const u_char *buffer, unsigned nbytes, int sign )
{
/* this is a lot like n_to_mpz */
size_t i;
/* this is a lot like n_to_mpz */
size_t i;
passert(sign == 0); /* we won't hit any negative numbers */
mpz_init_set_ui(a, 0);
passert(sign == 0); /* we won't hit any negative numbers */
mpz_init_set_ui(a, 0);
for (i = 0; i != nbytes; i++)
{
mpz_mul_ui(a, a, 1 << BITS_PER_BYTE);
mpz_add_ui(a, a, buffer[i]);
}
for (i = 0; i != nbytes; i++)
{
mpz_mul_ui(a, a, 1 << BITS_PER_BYTE);
mpz_add_ui(a, a, buffer[i]);
}
}
u_char *
get_random_bits(size_t nbits, int level UNUSED, int secure UNUSED)
{
size_t nbytes = (nbits+7)/8;
u_char *b = malloc(nbytes);
size_t nbytes = (nbits+7)/8;
u_char *b = malloc(nbytes);
get_rnd_bytes(b, nbytes);
return b;
get_rnd_bytes(b, nbytes);
return b;
}
/**************** from gnupg-1.0.0/mpi/mpi-mpow.c
* 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
build_index( MPI *exparray, int k, int i, int t )
{
int j, bitno;
int index = 0;
int j, bitno;
int index = 0;
bitno = t-i;
for(j=k-1; j >= 0; j-- ) {
index <<= 1;
if( mpi_test_bit( exparray[j], bitno ) )
index |= 1;
}
/*log_debug("t=%d i=%d index=%d\n", t, i, index );*/
return index;
bitno = t-i;
for(j=k-1; j >= 0; j-- ) {
index <<= 1;
if( mpi_test_bit( exparray[j], bitno ) )
index |= 1;
}
/*log_debug("t=%d i=%d index=%d\n", t, i, index );*/
return index;
}
void
mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI m)
{
int k; /* number of elements */
int t; /* bit size of largest exponent */
int i, j, idx;
MPI *G; /* table with precomputed values of size 2^k */
MPI tmp;
int k; /* number of elements */
int t; /* bit size of largest exponent */
int i, j, idx;
MPI *G; /* table with precomputed values of size 2^k */
MPI tmp;
#ifdef USE_BARRETT
MPI barrett_y, barrett_r1, barrett_r2;
int barrett_k;
MPI barrett_y, barrett_r1, barrett_r2;
int barrett_k;
#endif
for(k=0; basearray[k]; k++ )
;
passert(k);
for(t=0, i=0; (tmp=exparray[i]); i++ ) {
/*log_mpidump("exp: ", tmp );*/
j = mpi_get_nbits(tmp);
if( j > t )
t = j;
}
/*log_mpidump("mod: ", m );*/
passert(i==k);
passert(t);
passert( k < 10 );
for(k=0; basearray[k]; k++ )
;
passert(k);
for(t=0, i=0; (tmp=exparray[i]); i++ ) {
/*log_mpidump("exp: ", tmp );*/
j = mpi_get_nbits(tmp);
if( j > t )
t = j;
}
/*log_mpidump("mod: ", m );*/
passert(i==k);
passert(t);
passert( k < 10 );
#ifdef PLUTO
m_alloc_ptrs_clear(G, 1<<k);
m_alloc_ptrs_clear(G, 1<<k);
#else
G = m_alloc_clear( (1<<k) * sizeof *G );
G = m_alloc_clear( (1<<k) * sizeof *G );
#endif
#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
/* and calculate */
tmp = mpi_alloc( mpi_get_nlimbs(m)+1 );
mpi_set_ui( res, 1 );
for(i = 1; i <= t; i++ ) {
barrett_mulm(tmp, res, res, m, barrett_y, barrett_k,
barrett_r1, barrett_r2 );
idx = build_index( exparray, k, i, t );
passert( idx >= 0 && idx < (1<<k) );
if( !G[idx] ) {
if( !idx )
G[0] = mpi_alloc_set_ui( 1 );
else {
for(j=0; j < k; j++ ) {
if( (idx & (1<<j) ) ) {
if( !G[idx] )
G[idx] = mpi_copy( basearray[j] );
else
barrett_mulm( G[idx], G[idx], basearray[j],
m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
}
/* and calculate */
tmp = mpi_alloc( mpi_get_nlimbs(m)+1 );
mpi_set_ui( res, 1 );
for(i = 1; i <= t; i++ ) {
barrett_mulm(tmp, res, res, m, barrett_y, barrett_k,
barrett_r1, barrett_r2 );
idx = build_index( exparray, k, i, t );
passert( idx >= 0 && idx < (1<<k) );
if( !G[idx] ) {
if( !idx )
G[0] = mpi_alloc_set_ui( 1 );
else {
for(j=0; j < k; j++ ) {
if( (idx & (1<<j) ) ) {
if( !G[idx] )
G[idx] = mpi_copy( basearray[j] );
else
barrett_mulm( G[idx], G[idx], basearray[j],
m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
}
}
if( !G[idx] )
G[idx] = mpi_alloc(0);
}
}
if( !G[idx] )
G[idx] = mpi_alloc(0);
}
barrett_mulm(res, tmp, G[idx], m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
}
barrett_mulm(res, tmp, G[idx], m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
}
/* cleanup */
mpi_free(tmp);
/* cleanup */
mpi_free(tmp);
#ifdef USE_BARRETT
mpi_free(barrett_y);
mpi_free(barrett_r1);
mpi_free(barrett_r2);
mpi_free(barrett_y);
mpi_free(barrett_r1);
mpi_free(barrett_r2);
#endif
for(i=0; i < (1<<k); i++ )
mpi_free(G[i]);
m_free(G);
for(i=0; i < (1<<k); i++ )
mpi_free(G[i]);
m_free(G);
}
void
log_mpidump( const char *text UNUSED, MPI a )
{
/* Print number in hex -- helpful to see if they match bytes.
* Humans are not going to do arithmetic with the large numbers!
* Much code adapted from mpz_to_n.
*/
u_char buf[8048]; /* this ought to be big enough */
size_t len = (mpz_sizeinbase(a, 16) + 1) / 2; /* bytes */
MP_INT temp1, temp2;
int i;
/* Print number in hex -- helpful to see if they match bytes.
* Humans are not going to do arithmetic with the large numbers!
* Much code adapted from mpz_to_n.
*/
u_char buf[8048]; /* this ought to be big enough */
size_t len = (mpz_sizeinbase(a, 16) + 1) / 2; /* bytes */
MP_INT temp1, temp2;
int i;
passert(len <= sizeof(buf));
passert(len <= sizeof(buf));
mpz_init(&temp1);
mpz_init(&temp2);
mpz_init(&temp1);
mpz_init(&temp2);
mpz_set(&temp1, a);
mpz_set(&temp1, a);
for (i = len-1; i >= 0; i--)
{
buf[i] = mpz_mdivmod_ui(&temp2, NULL, &temp1, 1 << BITS_PER_BYTE);
mpz_set(&temp1, &temp2);
}
for (i = len-1; i >= 0; i--)
{
buf[i] = mpz_mdivmod_ui(&temp2, NULL, &temp1, 1 << BITS_PER_BYTE);
mpz_set(&temp1, &temp2);
}
passert(mpz_sgn(&temp1) == 0); /* we must have done all the bits */
mpz_clear(&temp1);
mpz_clear(&temp2);
passert(mpz_sgn(&temp1) == 0); /* we must have done all the bits */
mpz_clear(&temp1);
mpz_clear(&temp2);
#ifdef DEBUG
DBG_dump(text, buf, len);
DBG_dump(text, buf, len);
#endif /* DEBUG */
}

View File

@ -14,7 +14,7 @@
* 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.
* 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 MPI mpi_copy( 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 unsigned mpi_trailing_zeros( MPI a );
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
# define log_debug(f...) DBG_log(f)
#else
# define log_debug(f...) do ; while (0) /* do nothing, carefully */
# define log_debug(f...) do ; while (0) /* do nothing, carefully */
#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 );
#define assert(p) passert(p)
#define BUG() passert(FALSE)
#define m_alloc_ptrs_clear(pp, n) { \
int c = (n); \
(pp) = malloc((n) * sizeof(*(pp))); \
while (c > 0) (pp)[--c] = NULL; \
}
int c = (n); \
(pp) = malloc((n) * sizeof(*(pp))); \
while (c > 0) (pp)[--c] = NULL; \
}
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 */
/* 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_public_prime( unsigned nbits );
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_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 PUBKEY_USAGE_SIG 1 /* key is good for signatures */
#define PUBKEY_USAGE_ENC 2 /* key is good for encryption */
#define PUBKEY_USAGE_SIG 1 /* key is good for signatures */
#define PUBKEY_USAGE_ENC 2 /* key is good for encryption */
/* from gnupg-1.0.0/include/errors.h */
#define G10ERR_PUBKEY_ALGO 4 /* Unknown pubkey algorithm */
#define G10ERR_BAD_SECKEY 7 /* Bad secret key */
#define G10ERR_BAD_SIGN 8 /* Bad signature */
#define G10ERR_BAD_MPI 30
#define G10ERR_BAD_MPI 30
/*-- smallprime.c --*/
extern ushort small_prime_numbers[];

View File

@ -22,8 +22,8 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#ifndef HOST_NAME_MAX /* POSIX 1003.1-2001 says <unistd.h> defines this */
# define HOST_NAME_MAX 255 /* upper bound, according to SUSv2 */
#ifndef HOST_NAME_MAX /* POSIX 1003.1-2001 says <unistd.h> defines this */
# define HOST_NAME_MAX 255 /* upper bound, according to SUSv2 */
#endif
#include <sys/queue.h>
@ -38,10 +38,10 @@
#include "packet.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;
struct id myids[MYID_SPECIFIED+1]; /* %myid */
struct id myids[MYID_SPECIFIED+1]; /* %myid */
char *myid_str[MYID_SPECIFIED+1]; /* string form of IDs */
/* initialize id module
@ -50,20 +50,20 @@ char *myid_str[MYID_SPECIFIED+1]; /* string form of IDs */
void
init_id(void)
{
passert(empty_id.kind == ID_NONE);
myid_state = MYID_UNKNOWN;
{
enum myid_state s;
for (s = MYID_UNKNOWN; s <= MYID_SPECIFIED; s++)
passert(empty_id.kind == ID_NONE);
myid_state = MYID_UNKNOWN;
{
myids[s] = empty_id;
myid_str[s] = NULL;
enum myid_state s;
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_IP, getenv("defaultrouteaddr"));
set_myFQDN();
set_myid(MYID_SPECIFIED, getenv("IPSECmyid"));
set_myid(MYID_IP, getenv("defaultrouteaddr"));
set_myFQDN();
}
/*
@ -72,95 +72,95 @@ init_id(void)
void
free_id(void)
{
enum myid_state s;
enum myid_state s;
for (s = MYID_UNKNOWN; s <= MYID_SPECIFIED; s++)
{
free_id_content(&myids[s]);
free(myid_str[s]);
}
for (s = MYID_UNKNOWN; s <= MYID_SPECIFIED; s++)
{
free_id_content(&myids[s]);
free(myid_str[s]);
}
}
static void
calc_myid_str(enum myid_state s)
{
/* preformat the ID name */
char buf[BUF_LEN];
/* preformat the ID name */
char buf[BUF_LEN];
idtoa(&myids[s], buf, BUF_LEN);
replace(myid_str[s], clone_str(buf));
idtoa(&myids[s], buf, BUF_LEN);
replace(myid_str[s], clone_str(buf));
}
void
set_myid(enum myid_state s, char *idstr)
{
if (idstr != NULL)
{
struct id id;
err_t ugh = atoid(idstr, &id, FALSE);
if (ugh != NULL)
if (idstr != 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;
struct id id;
err_t ugh = atoid(idstr, &id, FALSE);
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
set_myFQDN(void)
{
char FQDN[HOST_NAME_MAX + 1];
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 */
char FQDN[HOST_NAME_MAX + 1];
int r = gethostname(FQDN, sizeof(FQDN));
free_id_content(&myids[MYID_HOSTNAME]);
myids[MYID_HOSTNAME] = empty_id;
if (r != 0)
{
size_t len = strlen(FQDN);
if (len > 0 && FQDN[len-1] == '.')
{
/* nuke trailing . */
FQDN[len-1]='\0';
}
log_errno((e, "gethostname() failed in set_myFQDN"));
}
if (!strcaseeq(FQDN, "localhost.localdomain"))
else
{
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;
calc_myid_str(MYID_HOSTNAME);
{
size_t len = strlen(FQDN);
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
show_myid_status(void)
{
char idstr[BUF_LEN];
char idstr[BUF_LEN];
(void)idtoa(&myids[myid_state], idstr, sizeof(idstr));
whack_log(RC_COMMENT, "%%myid = %s", idstr);
(void)idtoa(&myids[myid_state], idstr, sizeof(idstr));
whack_log(RC_COMMENT, "%%myid = %s", idstr);
}
/* Convert textual form of id into a (temporary) struct id.
@ -169,86 +169,86 @@ show_myid_status(void)
err_t
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))
{
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"))
if (myid_ok && streq("%myid", src))
{
/* any ID will be accepted */
id->kind = ID_NONE;
id->kind = ID_MYID;
}
else
else if (strchr(src, '=') != NULL)
{
/* !!! 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
{
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
*/
/* we interpret this as an ASCII X.501 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;
}
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_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
{
/* 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);
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->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
keyidtoa(char *dst, size_t dstlen, chunk_t keyid)
{
int n = datatot(keyid.ptr, keyid.len, 'x', dst, dstlen);
return (((size_t)n < dstlen)? n : dstlen) - 1;
int n = datatot(keyid.ptr, keyid.len, 'x', dst, dstlen);
return (((size_t)n < dstlen)? n : dstlen) - 1;
}
void
iptoid(const ip_address *ip, struct id *id)
{
*id = empty_id;
*id = empty_id;
switch (addrtypeof(ip))
{
case AF_INET:
id->kind = ID_IPV4_ADDR;
break;
case AF_INET6:
id->kind = ID_IPV6_ADDR;
break;
default:
bad_case(addrtypeof(ip));
}
id->ip_addr = *ip;
switch (addrtypeof(ip))
{
case AF_INET:
id->kind = ID_IPV4_ADDR;
break;
case AF_INET6:
id->kind = ID_IPV6_ADDR;
break;
default:
bad_case(addrtypeof(ip));
}
id->ip_addr = *ip;
}
int
idtoa(const struct id *id, char *dst, size_t dstlen)
{
int n;
int n;
id = resolve_myid(id);
switch (id->kind)
{
case ID_NONE:
n = snprintf(dst, dstlen, "(none)");
break;
case ID_IPV4_ADDR:
case ID_IPV6_ADDR:
n = (int)addrtot(&id->ip_addr, 0, dst, dstlen) - 1;
break;
case ID_FQDN:
n = snprintf(dst, dstlen, "@%.*s", (int)id->name.len, id->name.ptr);
break;
case ID_USER_FQDN:
n = snprintf(dst, dstlen, "%.*s", (int)id->name.len, id->name.ptr);
break;
case ID_DER_ASN1_DN:
n = dntoa(dst, dstlen, id->name);
break;
case ID_KEY_ID:
n = keyidtoa(dst, dstlen, id->name);
break;
default:
n = snprintf(dst, dstlen, "unknown id kind %d", id->kind);
break;
}
id = resolve_myid(id);
switch (id->kind)
{
case ID_NONE:
n = snprintf(dst, dstlen, "(none)");
break;
case ID_IPV4_ADDR:
case ID_IPV6_ADDR:
n = (int)addrtot(&id->ip_addr, 0, dst, dstlen) - 1;
break;
case ID_FQDN:
n = snprintf(dst, dstlen, "@%.*s", (int)id->name.len, id->name.ptr);
break;
case ID_USER_FQDN:
n = snprintf(dst, dstlen, "%.*s", (int)id->name.len, id->name.ptr);
break;
case ID_DER_ASN1_DN:
n = dntoa(dst, dstlen, id->name);
break;
case ID_KEY_ID:
n = keyidtoa(dst, dstlen, id->name);
break;
default:
n = snprintf(dst, dstlen, "unknown id kind %d", id->kind);
break;
}
/* "Sanitize" string so that log isn't endangered:
* replace unprintable characters with '?'.
*/
if (n > 0)
{
for ( ; *dst != '\0'; dst++)
if (!isprint(*dst))
*dst = '?';
}
/* "Sanitize" string so that log isn't endangered:
* replace unprintable characters with '?'.
*/
if (n > 0)
{
for ( ; *dst != '\0'; dst++)
if (!isprint(*dst))
*dst = '?';
}
return n;
return n;
}
/* Replace the shell metacharacters ', \, ", `, and $ in a character string
@ -332,26 +332,26 @@ idtoa(const struct id *id, char *dst, size_t dstlen)
void
escape_metachar(const char *src, char *dst, size_t dstlen)
{
while (*src != '\0' && dstlen > 4)
{
switch (*src)
while (*src != '\0' && dstlen > 4)
{
case '\'':
case '\\':
case '"':
case '`':
case '$':
sprintf(dst,"\\%s%o", (*src < 64)?"0":"", *src);
dst += 4;
dstlen -= 4;
break;
default:
*dst++ = *src;
dstlen--;
switch (*src)
{
case '\'':
case '\\':
case '"':
case '`':
case '$':
sprintf(dst,"\\%s%o", (*src < 64)?"0":"", *src);
dst += 4;
dstlen -= 4;
break;
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
unshare_id_content(struct id *id)
{
switch (id->kind)
{
case ID_FQDN:
case ID_USER_FQDN:
case ID_DER_ASN1_DN:
case ID_KEY_ID:
id->name = chunk_clone(id->name);
break;
case ID_MYID:
case ID_NONE:
case ID_IPV4_ADDR:
case ID_IPV6_ADDR:
break;
default:
bad_case(id->kind);
}
switch (id->kind)
{
case ID_FQDN:
case ID_USER_FQDN:
case ID_DER_ASN1_DN:
case ID_KEY_ID:
id->name = chunk_clone(id->name);
break;
case ID_MYID:
case ID_NONE:
case ID_IPV4_ADDR:
case ID_IPV6_ADDR:
break;
default:
bad_case(id->kind);
}
}
void
free_id_content(struct id *id)
{
switch (id->kind)
{
case ID_FQDN:
case ID_USER_FQDN:
case ID_DER_ASN1_DN:
case ID_KEY_ID:
free(id->name.ptr);
break;
case ID_MYID:
case ID_NONE:
case ID_IPV4_ADDR:
case ID_IPV6_ADDR:
break;
default:
bad_case(id->kind);
}
switch (id->kind)
{
case ID_FQDN:
case ID_USER_FQDN:
case ID_DER_ASN1_DN:
case ID_KEY_ID:
free(id->name.ptr);
break;
case ID_MYID:
case ID_NONE:
case ID_IPV4_ADDR:
case ID_IPV6_ADDR:
break;
default:
bad_case(id->kind);
}
}
/* compare two struct id values */
bool
same_id(const struct id *a, const struct id *b)
{
a = resolve_myid(a);
b = resolve_myid(b);
if (a->kind != b->kind)
return FALSE;
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?)
*/
a = resolve_myid(a);
b = resolve_myid(b);
if (a->kind != b->kind)
return FALSE;
switch (a->kind)
{
size_t al = a->name.len
, bl = b->name.len;
case ID_NONE:
return TRUE; /* kind of vacuous */
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_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
, 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);
}
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;
return FALSE;
}
/* compare two struct id values, DNs can contain wildcards */
bool
match_id(const struct id *a, const struct id *b, int *wildcards)
{
if (b->kind == ID_NONE)
{
*wildcards = MAX_WILDCARDS;
return TRUE;
}
if (a->kind != b->kind)
return FALSE;
if (a->kind == ID_DER_ASN1_DN)
return match_dn(a->name, b->name, wildcards);
else
{
*wildcards = 0;
return same_id(a, b);
}
if (b->kind == ID_NONE)
{
*wildcards = MAX_WILDCARDS;
return TRUE;
}
if (a->kind != b->kind)
return FALSE;
if (a->kind == ID_DER_ASN1_DN)
return match_dn(a->name, b->name, wildcards);
else
{
*wildcards = 0;
return same_id(a, b);
}
}
/* count the numer of wildcards in an id */
int
id_count_wildcards(const struct id *id)
{
switch (id->kind)
{
case ID_NONE:
return MAX_WILDCARDS;
case ID_DER_ASN1_DN:
return dn_count_wildcards(id->name);
default:
return 0;
}
switch (id->kind)
{
case ID_NONE:
return MAX_WILDCARDS;
case ID_DER_ASN1_DN:
return dn_count_wildcards(id->name);
default:
return 0;
}
}
/* build an ID payload
@ -491,31 +491,31 @@ id_count_wildcards(const struct id *id)
void
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);
hd->isaiid_idtype = id->kind;
switch (id->kind)
{
case ID_NONE:
hd->isaiid_idtype = aftoinfo(addrtypeof(&end->host_addr))->id_addr;
tl->len = addrbytesptr(&end->host_addr
, (const unsigned char **)&tl->ptr); /* sets tl->ptr too */
break;
case ID_FQDN:
case ID_USER_FQDN:
case ID_DER_ASN1_DN:
case ID_KEY_ID:
*tl = id->name;
break;
case ID_IPV4_ADDR:
case ID_IPV6_ADDR:
tl->len = addrbytesptr(&id->ip_addr
, (const unsigned char **)&tl->ptr); /* sets tl->ptr too */
break;
default:
bad_case(id->kind);
}
zero(hd);
hd->isaiid_idtype = id->kind;
switch (id->kind)
{
case ID_NONE:
hd->isaiid_idtype = aftoinfo(addrtypeof(&end->host_addr))->id_addr;
tl->len = addrbytesptr(&end->host_addr
, (const unsigned char **)&tl->ptr); /* sets tl->ptr too */
break;
case ID_FQDN:
case ID_USER_FQDN:
case ID_DER_ASN1_DN:
case ID_KEY_ID:
*tl = id->name;
break;
case ID_IPV4_ADDR:
case ID_IPV6_ADDR:
tl->len = addrbytesptr(&id->ip_addr
, (const unsigned char **)&tl->ptr); /* sets tl->ptr too */
break;
default:
bad_case(id->kind);
}
}
/*

View File

@ -20,25 +20,25 @@
#include "defs.h"
struct id {
int kind; /* ID_* value */
ip_address ip_addr; /* ID_IPV4_ADDR, ID_IPV6_ADDR */
chunk_t name; /* ID_FQDN, ID_USER_FQDN (with @) */
/* ID_KEY_ID, ID_DER_ASN_DN */
int kind; /* ID_* value */
ip_address ip_addr; /* ID_IPV4_ADDR, ID_IPV6_ADDR */
chunk_t name; /* ID_FQDN, ID_USER_FQDN (with @) */
/* ID_KEY_ID, ID_DER_ASN_DN */
};
extern void init_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 {
MYID_UNKNOWN, /* not yet figured out */
MYID_HOSTNAME, /* our current hostname */
MYID_IP, /* our default IP address */
MYID_SPECIFIED /* as specified by ipsec.conf */
MYID_UNKNOWN, /* not yet figured out */
MYID_HOSTNAME, /* our current hostname */
MYID_IP, /* our default IP address */
MYID_SPECIFIED /* as specified by ipsec.conf */
};
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 void set_myid(enum myid_state s, char *);
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 void iptoid(const ip_address *ip, struct id *id);
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);
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 free_id_content(struct id *id);
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 int id_count_wildcards(const struct id *id);
#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
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 */

View File

@ -56,13 +56,13 @@ static struct ike_alg *ike_alg_base[IKE_ALG_MAX+1] = {NULL, NULL};
static struct ike_alg *
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)
{
e = e->algo_next;
}
return (e != NULL && e->algo_id == algo_id) ? e : NULL;
while (e != NULL && algo_id > e->algo_id)
{
e = e->algo_next;
}
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
ike_alg_add(struct ike_alg* a)
{
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)
if (a->algo_type > IKE_ALG_MAX)
{
ep = &e->algo_next;
e = *ep;
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;
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)
{
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)
{
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
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
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
ike_alg_register_hash(struct hash_desc *hash_desc)
{
const char *alg_name = NULL;
int ret = 0;
const char *alg_name = NULL;
int ret = 0;
if (hash_desc->algo_id > OAKLEY_HASH_MAX)
{
plog ("ike_alg: hash alg=%d > max=%d"
, hash_desc->algo_id, OAKLEY_HASH_MAX);
return_on(ret,-EINVAL);
}
if (hash_desc->algo_id > OAKLEY_HASH_MAX)
{
plog ("ike_alg: hash alg=%d > max=%d"
, hash_desc->algo_id, OAKLEY_HASH_MAX);
return_on(ret,-EINVAL);
}
if (hash_desc->hash_ctx_size > sizeof (union hash_ctx))
{
plog ("ike_alg: hash alg=%d has ctx_size=%d > hash_ctx=%d"
, hash_desc->algo_id
, (int)hash_desc->hash_ctx_size
, (int)sizeof (union hash_ctx));
return_on(ret,-EOVERFLOW);
}
if (hash_desc->hash_ctx_size > sizeof (union hash_ctx))
{
plog ("ike_alg: hash alg=%d has ctx_size=%d > hash_ctx=%d"
, hash_desc->algo_id
, (int)hash_desc->hash_ctx_size
, (int)sizeof (union hash_ctx));
return_on(ret,-EOVERFLOW);
}
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()"
, hash_desc->algo_id);
return_on(ret,-EINVAL);
}
alg_name = enum_name(&oakley_hash_names, hash_desc->algo_id);
if (!alg_name)
{
plog ("ike_alg: hash alg=%d not found in constants.c:oakley_hash_names"
, hash_desc->algo_id);
alg_name = "<NULL>";
}
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()"
, hash_desc->algo_id);
return_on(ret,-EINVAL);
}
alg_name = enum_name(&oakley_hash_names, hash_desc->algo_id);
if (!alg_name)
{
plog ("ike_alg: hash alg=%d not found in constants.c:oakley_hash_names"
, hash_desc->algo_id);
alg_name = "<NULL>";
}
return_out:
if (ret == 0)
ret = ike_alg_add((struct ike_alg *)hash_desc);
if (ret == 0)
ret = ike_alg_add((struct ike_alg *)hash_desc);
plog("ike_alg: Activating %s hash: %s"
,alg_name, ret == 0 ? "Ok" : "FAILED");
plog("ike_alg: Activating %s hash: %s"
,alg_name, ret == 0 ? "Ok" : "FAILED");
return ret;
return ret;
}
/*
@ -188,24 +188,24 @@ return_out:
int
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];
/* algorithm is not listed in oakley_enc_names */
if (alg_name == NULL)
{
snprintf(alg_number, sizeof(alg_number), "OAKLEY_ID_%d"
, enc_desc->algo_id);
alg_name = alg_number;
}
char alg_number[20];
/* algorithm is not listed in oakley_enc_names */
if (alg_name == NULL)
{
snprintf(alg_number, sizeof(alg_number), "OAKLEY_ID_%d"
, enc_desc->algo_id);
alg_name = alg_number;
}
plog("ike_alg: Activating %s encryption: %s"
, alg_name, ret == 0 ? "Ok" : "FAILED");
plog("ike_alg: Activating %s encryption: %s"
, 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 *
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)
&& c->alg_info_esp
&& c->alg_info_esp->esp_pfsgroup)
ret = lookup_group(c->alg_info_esp->esp_pfsgroup);
return ret;
if ((policy & POLICY_PFS)
&& c->alg_info_esp
&& c->alg_info_esp->esp_pfsgroup)
ret = lookup_group(c->alg_info_esp->esp_pfsgroup);
return ret;
}
/*
@ -229,109 +229,109 @@ ike_alg_pfsgroup(struct connection *c, lset_t policy)
struct db_context *
ike_alg_db_new(struct alg_info_ike *ai , lset_t policy)
{
struct db_context *db_ctx = NULL;
struct ike_info *ike_info;
struct encrypt_desc *enc_desc;
u_int ealg, halg, modp, eklen = 0;
int i;
struct db_context *db_ctx = NULL;
struct ike_info *ike_info;
struct encrypt_desc *enc_desc;
u_int ealg, halg, modp, eklen = 0;
int i;
bool is_xauth_server = (policy & POLICY_XAUTH_SERVER) != LEMPTY;
bool is_xauth_server = (policy & POLICY_XAUTH_SERVER) != LEMPTY;
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))
if (!ai)
{
DBG_log("ike_alg: ike enc ealg=%d not present"
, ealg);
continue;
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);
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"
, halg);
continue;
}
ealg = ike_info->ike_ealg;
halg = ike_info->ike_halg;
modp = ike_info->ike_modp;
eklen= ike_info->ike_eklen;
enc_desc = ike_alg_get_encrypter(ealg);
passert(enc_desc != NULL);
if (!ike_alg_enc_present(ealg))
{
DBG_log("ike_alg: ike enc ealg=%d not present"
, ealg);
continue;
}
if (eklen
&& (eklen < enc_desc->keyminlen || eklen > enc_desc->keymaxlen))
{
DBG_log("ike_alg: ealg=%d (specified) keylen:%d, not valid min=%d, max=%d"
, ealg
, eklen
, enc_desc->keyminlen
, enc_desc->keymaxlen
);
continue;
}
if (!ike_alg_hash_present(halg))
{
DBG_log("ike_alg: ike hash halg=%d not present"
, halg);
continue;
}
if (policy & POLICY_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, OAKLEY_RSA_SIG);
db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
}
enc_desc = ike_alg_get_encrypter(ealg);
passert(enc_desc != NULL);
if (policy & POLICY_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, OAKLEY_PRESHARED_KEY);
db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
}
if (eklen
&& (eklen < enc_desc->keyminlen || eklen > enc_desc->keymaxlen))
{
DBG_log("ike_alg: ealg=%d (specified) keylen:%d, not valid min=%d, max=%d"
, ealg
, eklen
, enc_desc->keyminlen
, enc_desc->keymaxlen
);
continue;
}
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_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, OAKLEY_RSA_SIG);
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);
if (policy & POLICY_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, OAKLEY_PRESHARED_KEY);
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:
return db_ctx;
return db_ctx;
}
/*
@ -340,54 +340,54 @@ fail:
void
ike_alg_list(void)
{
u_int i;
struct ike_alg *a;
u_int i;
struct ike_alg *a;
whack_log(RC_COMMENT, " ");
whack_log(RC_COMMENT, "List of registered IKE Encryption Algorithms:");
whack_log(RC_COMMENT, " ");
whack_log(RC_COMMENT, " ");
whack_log(RC_COMMENT, "List of registered IKE Encryption Algorithms:");
whack_log(RC_COMMENT, " ");
for (a = ike_alg_base[IKE_ALG_ENCRYPT]; a != NULL; a = a->algo_next)
{
struct encrypt_desc *desc = (struct encrypt_desc*)a;
for (a = ike_alg_base[IKE_ALG_ENCRYPT]; a != NULL; a = a->algo_next)
{
struct encrypt_desc *desc = (struct encrypt_desc*)a;
whack_log(RC_COMMENT, "#%-5d %s, blocksize: %d, keylen: %d-%d-%d"
, a->algo_id
, enum_name(&oakley_enc_names, a->algo_id)
, (int)desc->enc_blocksize*BITS_PER_BYTE
, desc->keyminlen
, desc->keydeflen
, desc->keymaxlen
);
}
whack_log(RC_COMMENT, "#%-5d %s, blocksize: %d, keylen: %d-%d-%d"
, a->algo_id
, enum_name(&oakley_enc_names, a->algo_id)
, (int)desc->enc_blocksize*BITS_PER_BYTE
, desc->keyminlen
, desc->keydeflen
, desc->keymaxlen
);
}
whack_log(RC_COMMENT, " ");
whack_log(RC_COMMENT, "List of registered IKE Hash Algorithms:");
whack_log(RC_COMMENT, " ");
whack_log(RC_COMMENT, " ");
whack_log(RC_COMMENT, "List of registered IKE Hash Algorithms:");
whack_log(RC_COMMENT, " ");
for (a = ike_alg_base[IKE_ALG_HASH]; a != NULL; a = a->algo_next)
{
whack_log(RC_COMMENT, "#%-5d %s, hashsize: %d"
, a->algo_id
, enum_name(&oakley_hash_names, a->algo_id)
, (int)((struct hash_desc *)a)->hash_digest_size*BITS_PER_BYTE
);
}
for (a = ike_alg_base[IKE_ALG_HASH]; a != NULL; a = a->algo_next)
{
whack_log(RC_COMMENT, "#%-5d %s, hashsize: %d"
, a->algo_id
, enum_name(&oakley_hash_names, a->algo_id)
, (int)((struct hash_desc *)a)->hash_digest_size*BITS_PER_BYTE
);
}
whack_log(RC_COMMENT, " ");
whack_log(RC_COMMENT, "List of registered IKE DH Groups:");
whack_log(RC_COMMENT, " ");
whack_log(RC_COMMENT, " ");
whack_log(RC_COMMENT, "List of registered IKE DH Groups:");
whack_log(RC_COMMENT, " ");
for (i = 0; i < countof(oakley_group); i++)
{
const struct oakley_group_desc *gdesc=oakley_group + i;
for (i = 0; i < countof(oakley_group); i++)
{
const struct oakley_group_desc *gdesc=oakley_group + i;
whack_log(RC_COMMENT, "#%-5d %s, groupsize: %d"
, gdesc->group
, enum_name(&oakley_group_names, gdesc->group)
, (int)gdesc->bytes*BITS_PER_BYTE
);
}
whack_log(RC_COMMENT, "#%-5d %s, groupsize: %d"
, gdesc->group
, enum_name(&oakley_group_names, gdesc->group)
, (int)gdesc->bytes*BITS_PER_BYTE
);
}
}
/* Show IKE algorithms for
@ -397,43 +397,43 @@ ike_alg_list(void)
void
ike_alg_show_connection(struct connection *c, const char *instance)
{
char buf[256];
struct state *st;
char buf[256];
struct state *st;
if (c->alg_info_ike)
{
alg_info_snprint(buf, sizeof(buf)-1, (struct alg_info *)c->alg_info_ike);
whack_log(RC_COMMENT
, "\"%s\"%s: IKE algorithms wanted: %s"
, c->name
, instance
, buf
);
if (c->alg_info_ike)
{
alg_info_snprint(buf, sizeof(buf)-1, (struct alg_info *)c->alg_info_ike);
whack_log(RC_COMMENT
, "\"%s\"%s: IKE algorithms wanted: %s"
, c->name
, instance
, buf
);
alg_info_snprint_ike(buf, sizeof(buf)-1, c->alg_info_ike);
whack_log(RC_COMMENT
, "\"%s\"%s: IKE algorithms found: %s"
, c->name
, instance
, buf
);
}
alg_info_snprint_ike(buf, sizeof(buf)-1, c->alg_info_ike);
whack_log(RC_COMMENT
, "\"%s\"%s: IKE algorithms found: %s"
, c->name
, instance
, buf
);
}
st = state_with_serialno(c->newest_isakmp_sa);
if (st)
whack_log(RC_COMMENT
, "\"%s\"%s: IKE algorithm newest: %s_%d-%s-%s"
, c->name
, instance
, enum_show(&oakley_enc_names, st->st_oakley.encrypt)
+7 /* strlen("OAKLEY_") */
/* , st->st_oakley.encrypter->keydeflen */
, st->st_oakley.enckeylen
, enum_show(&oakley_hash_names, st->st_oakley.hash)
+7 /* strlen("OAKLEY_") */
, enum_show(&oakley_group_names, st->st_oakley.group->group)
+13 /* strlen("OAKLEY_GROUP_") */
);
st = state_with_serialno(c->newest_isakmp_sa);
if (st)
whack_log(RC_COMMENT
, "\"%s\"%s: IKE algorithm newest: %s_%d-%s-%s"
, c->name
, instance
, enum_show(&oakley_enc_names, st->st_oakley.encrypt)
+7 /* strlen("OAKLEY_") */
/* , st->st_oakley.encrypter->keydeflen */
, st->st_oakley.enckeylen
, enum_show(&oakley_hash_names, st->st_oakley.hash)
+7 /* strlen("OAKLEY_") */
, enum_show(&oakley_group_names, st->st_oakley.group->group)
+13 /* strlen("OAKLEY_GROUP_") */
);
}
/*
@ -442,70 +442,70 @@ ike_alg_show_connection(struct connection *c, const char *instance)
static bool
ike_hash_test(const struct hash_desc *desc)
{
bool hash_results = TRUE;
bool hmac_results = TRUE;
bool hash_results = TRUE;
bool hmac_results = TRUE;
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++)
if (desc->hash_testvectors == NULL)
{
u_char digest[MAX_DIGEST_LEN];
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 not available", enum_name(&oakley_hash_names, desc->algo_id));
}
plog(" %s hash self-test %s", enum_name(&oakley_hash_names, desc->algo_id)
, 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++)
else
{
u_char digest[MAX_DIGEST_LEN];
bool result;
int i;
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
, 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;
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)
, hash_results ? "passed":"failed");
}
plog(" %s hmac self-test %s", enum_name(&oakley_hash_names, desc->algo_id)
, hmac_results ? "passed":"failed");
}
return hash_results && hmac_results;
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];
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
ike_alg_test(void)
{
bool all_results = TRUE;
struct ike_alg *a;
bool all_results = TRUE;
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)
{
plog(" %s self-test not available", enum_name(&oakley_enc_names, a->algo_id));
}
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("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)
{
struct hash_desc *desc = (struct hash_desc*)a;
for (a = ike_alg_base[IKE_ALG_HASH]; a != NULL; a = a->algo_next)
{
struct hash_desc *desc = (struct hash_desc*)a;
all_results &= ike_hash_test(desc);
}
all_results &= ike_hash_test(desc);
}
if (all_results)
plog("All crypto self-tests passed");
else
plog("Some crypto self-tests failed");
return all_results;
if (all_results)
plog("All crypto self-tests passed");
else
plog("Some crypto self-tests failed");
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
, struct alg_info_ike *alg_info_ike)
{
/*
* simple test to discard low key_len, will accept it only
* if specified in "esp" string
*/
bool ealg_insecure = (key_len < 128);
/*
* simple test to discard low key_len, will accept it only
* if specified in "esp" string
*/
bool ealg_insecure = (key_len < 128);
if (ealg_insecure
|| (alg_info_ike && alg_info_ike->alg_info_flags & ALG_INFO_F_STRICT))
{
int i;
struct ike_info *ike_info;
if (alg_info_ike)
if (ealg_insecure
|| (alg_info_ike && alg_info_ike->alg_info_flags & ALG_INFO_F_STRICT))
{
ALG_INFO_IKE_FOREACH(alg_info_ike, ike_info, i)
{
if (ike_info->ike_ealg == ealg
&& (ike_info->ike_eklen == 0 || key_len == 0 || ike_info->ike_eklen == key_len)
&& ike_info->ike_halg == aalg
&& ike_info->ike_modp == group)
int i;
struct ike_info *ike_info;
if (alg_info_ike)
{
if (ealg_insecure)
loglog(RC_LOG_SERIOUS, "You should NOT use insecure IKE algorithms (%s)!"
, enum_name(&oakley_enc_names, ealg));
return TRUE;
ALG_INFO_IKE_FOREACH(alg_info_ike, ike_info, i)
{
if (ike_info->ike_ealg == ealg
&& (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"
, 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;
return TRUE;
}

View File

@ -13,66 +13,66 @@
*
* RCSID $Id$
*/
#ifndef _IKE_ALG_H
#define _IKE_ALG_H
#include "connections.h"
struct ike_alg {
u_int16_t algo_type;
u_int16_t algo_id;
struct ike_alg *algo_next;
u_int16_t algo_type;
u_int16_t algo_id;
struct ike_alg *algo_next;
};
struct encrypt_desc {
u_int16_t algo_type;
u_int16_t algo_id;
struct ike_alg *algo_next;
u_int16_t algo_type;
u_int16_t algo_id;
struct ike_alg *algo_next;
size_t enc_ctxsize;
size_t enc_blocksize;
u_int keydeflen;
u_int keymaxlen;
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);
size_t enc_ctxsize;
size_t enc_blocksize;
u_int keydeflen;
u_int keymaxlen;
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);
};
typedef struct hash_testvector hash_testvector_t;
struct hash_testvector {
const size_t msg_size;
const u_char *msg;
const u_char *msg_digest;
const size_t msg_size;
const u_char *msg;
const u_char *msg_digest;
};
typedef struct hmac_testvector hmac_testvector_t;
struct hmac_testvector {
const size_t key_size;
const u_char *key;
const size_t msg_size;
const u_char *msg;
const u_char *hmac;
const size_t key_size;
const u_char *key;
const size_t msg_size;
const u_char *msg;
const u_char *hmac;
};
struct hash_desc {
u_int16_t algo_type;
u_int16_t algo_id;
struct ike_alg *algo_next;
u_int16_t algo_type;
u_int16_t algo_id;
struct ike_alg *algo_next;
size_t hash_ctx_size;
size_t hash_block_size;
size_t hash_digest_size;
const hash_testvector_t *hash_testvectors;
const hmac_testvector_t *hmac_testvectors;
void (*hash_init)(void *ctx);
void (*hash_update)(void *ctx, const u_int8_t *in, size_t datasize);
void (*hash_final)(u_int8_t *out, void *ctx);
size_t hash_ctx_size;
size_t hash_block_size;
size_t hash_digest_size;
const hash_testvector_t *hash_testvectors;
const hmac_testvector_t *hmac_testvectors;
void (*hash_init)(void *ctx);
void (*hash_update)(void *ctx, const u_int8_t *in, size_t datasize);
void (*hash_final)(u_int8_t *out, void *ctx);
};
#define IKE_ALG_ENCRYPT 0
#define IKE_ALG_HASH 1
#define IKE_ALG_MAX IKE_ALG_HASH
#define IKE_ALG_ENCRYPT 0
#define IKE_ALG_HASH 1
#define IKE_ALG_MAX IKE_ALG_HASH
extern int ike_alg_add(struct ike_alg *a);
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_enc(struct encrypt_desc *e);
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 void ike_alg_list(void);
extern void ike_alg_show_connection(struct connection *c, const char *instance);
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
, struct alg_info_ike *alg_info_ike);
, struct alg_info_ike *alg_info_ike);
extern int ike_alg_init(void);
#endif /* _IKE_ALG_H */

File diff suppressed because it is too large Load Diff

View File

@ -17,48 +17,48 @@
extern void echo_hdr(struct msg_digest *md, bool enc, u_int8_t np);
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 init_phase2_iv(struct state *st, const msgid_t *msgid);
extern stf_status quick_outI1(int whack_sock
, struct state *isakmp_sa
, struct connection *c
, lset_t policy
, unsigned long try
, so_serial_t replacing);
, struct state *isakmp_sa
, struct connection *c
, lset_t policy
, unsigned long try
, so_serial_t replacing);
extern state_transition_fn
main_inI1_outR1,
main_inR1_outI2,
main_inI2_outR2,
main_inR2_outI3,
main_inI3_outR3,
main_inR3,
quick_inI1_outR1,
quick_inR1_outI2,
quick_inI2;
main_inI1_outR1,
main_inR1_outI2,
main_inI2_outR2,
main_inR2_outI3,
main_inI3_outR3,
main_inR3,
quick_inI1_outR1,
quick_inR1_outI2,
quick_inI2;
extern void send_delete(struct state *st);
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 bool encrypt_message(pb_stream *pbs, 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 const char *init_pluto_vendorid(void);
extern void dpd_outI(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
, 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);
/* 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)
*/
#define START_HASH_PAYLOAD(rbody, np) { \
pb_stream hash_pbs; \
if (!out_generic(np, &isakmp_hash_desc, &(rbody), &hash_pbs)) \
return STF_INTERNAL_ERROR; \
r_hashval = hash_pbs.cur; /* remember where to plant value */ \
if (!out_zero(st->st_oakley.hasher->hash_digest_size, &hash_pbs, "HASH")) \
return STF_INTERNAL_ERROR; \
close_output_pbs(&hash_pbs); \
r_hash_start = (rbody).cur; /* hash from after HASH payload */ \
pb_stream hash_pbs; \
if (!out_generic(np, &isakmp_hash_desc, &(rbody), &hash_pbs)) \
return STF_INTERNAL_ERROR; \
r_hashval = hash_pbs.cur; /* remember where to plant value */ \
if (!out_zero(st->st_oakley.hasher->hash_digest_size, &hash_pbs, "HASH")) \
return STF_INTERNAL_ERROR; \
close_output_pbs(&hash_pbs); \
r_hash_start = (rbody).cur; /* hash from after HASH payload */ \
}
/* CHECK_QUICK_HASH
@ -88,17 +88,17 @@ extern void dpd_timeout(struct state *st);
* expression to reference them (hash_val, hash_pbs)
*/
#define CHECK_QUICK_HASH(md, do_hash, hash_name, msg_name) { \
pb_stream *const hash_pbs = &md->chain[ISAKMP_NEXT_HASH]->pbs; \
u_char hash_val[MAX_DIGEST_LEN]; \
size_t hash_len = do_hash; \
if (pbs_left(hash_pbs) != hash_len \
|| memcmp(hash_pbs->cur, hash_val, hash_len) != 0) \
{ \
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); \
/* XXX Could send notification back */ \
return STF_FAIL + INVALID_HASH_INFORMATION; \
} \
}
pb_stream *const hash_pbs = &md->chain[ISAKMP_NEXT_HASH]->pbs; \
u_char hash_val[MAX_DIGEST_LEN]; \
size_t hash_len = do_hash; \
if (pbs_left(hash_pbs) != hash_len \
|| memcmp(hash_pbs->cur, hash_val, hash_len) != 0) \
{ \
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); \
/* XXX Could send notification back */ \
return STF_FAIL + INVALID_HASH_INFORMATION; \
} \
}

View File

@ -3,45 +3,45 @@
/* The definitions, required to talk to KAME racoon IKE. */
#define IPSEC_PORT_ANY 0
#define IPSEC_ULPROTO_ANY 255
#define IPSEC_PROTO_ANY 255
#define IPSEC_PORT_ANY 0
#define IPSEC_ULPROTO_ANY 255
#define IPSEC_PROTO_ANY 255
enum {
IPSEC_MODE_ANY = 0, /* We do not support this for SA */
IPSEC_MODE_TRANSPORT = 1,
IPSEC_MODE_TUNNEL = 2
IPSEC_MODE_ANY = 0, /* We do not support this for SA */
IPSEC_MODE_TRANSPORT = 1,
IPSEC_MODE_TUNNEL = 2
};
enum {
IPSEC_DIR_ANY = 0,
IPSEC_DIR_INBOUND = 1,
IPSEC_DIR_OUTBOUND = 2,
IPSEC_DIR_FWD = 3, /* It is our own */
IPSEC_DIR_MAX = 4,
IPSEC_DIR_INVALID = 5
IPSEC_DIR_ANY = 0,
IPSEC_DIR_INBOUND = 1,
IPSEC_DIR_OUTBOUND = 2,
IPSEC_DIR_FWD = 3, /* It is our own */
IPSEC_DIR_MAX = 4,
IPSEC_DIR_INVALID = 5
};
enum {
IPSEC_POLICY_DISCARD = 0,
IPSEC_POLICY_NONE = 1,
IPSEC_POLICY_IPSEC = 2,
IPSEC_POLICY_ENTRUST = 3,
IPSEC_POLICY_BYPASS = 4
IPSEC_POLICY_DISCARD = 0,
IPSEC_POLICY_NONE = 1,
IPSEC_POLICY_IPSEC = 2,
IPSEC_POLICY_ENTRUST = 3,
IPSEC_POLICY_BYPASS = 4
};
enum {
IPSEC_LEVEL_DEFAULT = 0,
IPSEC_LEVEL_USE = 1,
IPSEC_LEVEL_REQUIRE = 2,
IPSEC_LEVEL_UNIQUE = 3
IPSEC_LEVEL_DEFAULT = 0,
IPSEC_LEVEL_USE = 1,
IPSEC_LEVEL_REQUIRE = 2,
IPSEC_LEVEL_UNIQUE = 3
};
#define IPSEC_MANUAL_REQID_MAX 0x3fff
#define IPSEC_MANUAL_REQID_MAX 0x3fff
#define IPSEC_REPLAYWSIZE 32
#define IP_IPSEC_POLICY 16
#define IPV6_IPSEC_POLICY 34
#endif /* __IPSEC_H */
#endif /* __IPSEC_H */

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@
#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? */
#ifdef KLIPS
@ -28,96 +28,96 @@ extern bool can_do_IPcomp; /* can system actually perform IPCOMP? */
* limited to appropriate source and destination addresses.
*/
#define ERO_MASK 0xFF
#define ERO_FLAG_SHIFT 8
#define ERO_MASK 0xFF
#define ERO_FLAG_SHIFT 8
#define ERO_DELETE SADB_X_DELFLOW
#define ERO_ADD SADB_X_ADDFLOW
#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_DEL_INBOUND (SADB_X_DELFLOW | (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
#define ERO_DELETE SADB_X_DELFLOW
#define ERO_ADD SADB_X_ADDFLOW
#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_DEL_INBOUND (SADB_X_DELFLOW | (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
struct pfkey_proto_info {
int proto;
int encapsulation;
unsigned reqid;
int proto;
int encapsulation;
unsigned reqid;
};
struct sadb_msg;
struct kernel_sa {
const ip_address *src;
const ip_address *dst;
const ip_address *src;
const ip_address *dst;
const ip_subnet *src_client;
const ip_subnet *dst_client;
const ip_subnet *src_client;
const ip_subnet *dst_client;
ipsec_spi_t spi;
unsigned proto;
unsigned satype;
unsigned transport_proto;
unsigned replay_window;
unsigned reqid;
ipsec_spi_t spi;
unsigned proto;
unsigned satype;
unsigned transport_proto;
unsigned replay_window;
unsigned reqid;
unsigned authalg;
unsigned authkeylen;
char *authkey;
unsigned authalg;
unsigned authkeylen;
char *authkey;
unsigned encalg;
unsigned enckeylen;
char *enckey;
unsigned encalg;
unsigned enckeylen;
char *enckey;
unsigned compalg;
unsigned compalg;
int encapsulation;
int encapsulation;
u_int16_t natt_sport, natt_dport;
u_int8_t transid, natt_type;
ip_address *natt_oa;
u_int16_t natt_sport, natt_dport;
u_int8_t transid, natt_type;
ip_address *natt_oa;
const char *text_said;
const char *text_said;
};
struct kernel_ops {
enum {
KERNEL_TYPE_NONE,
KERNEL_TYPE_KLIPS,
KERNEL_TYPE_LINUX,
} type;
bool inbound_eroute;
bool policy_lifetime;
int *async_fdp;
enum {
KERNEL_TYPE_NONE,
KERNEL_TYPE_KLIPS,
KERNEL_TYPE_LINUX,
} type;
bool inbound_eroute;
bool policy_lifetime;
int *async_fdp;
void (*init)(void);
void (*pfkey_register)(void);
void (*pfkey_register_response)(const struct sadb_msg *msg);
void (*process_queue)(void);
void (*process_msg)(void);
bool (*raw_eroute)(const ip_address *this_host,
const ip_subnet *this_client,
const ip_address *that_host,
const ip_subnet *that_client,
ipsec_spi_t spi,
unsigned int satype,
unsigned int transport_proto,
const struct pfkey_proto_info *proto_info,
time_t use_lifetime,
unsigned int op,
const char *text_said);
bool (*get_policy)(const struct kernel_sa *sa, bool inbound,
time_t *use_time);
bool (*add_sa)(const struct kernel_sa *sa, bool replace);
bool (*grp_sa)(const struct kernel_sa *sa_outer,
const struct kernel_sa *sa_inner);
bool (*del_sa)(const struct kernel_sa *sa);
bool (*get_sa)(const struct kernel_sa *sa, u_int *bytes);
ipsec_spi_t (*get_spi)(const ip_address *src,
const ip_address *dst,
int proto,
bool tunnel_mode,
unsigned reqid,
ipsec_spi_t min,
ipsec_spi_t max,
const char *text_said);
void (*init)(void);
void (*pfkey_register)(void);
void (*pfkey_register_response)(const struct sadb_msg *msg);
void (*process_queue)(void);
void (*process_msg)(void);
bool (*raw_eroute)(const ip_address *this_host,
const ip_subnet *this_client,
const ip_address *that_host,
const ip_subnet *that_client,
ipsec_spi_t spi,
unsigned int satype,
unsigned int transport_proto,
const struct pfkey_proto_info *proto_info,
time_t use_lifetime,
unsigned int op,
const char *text_said);
bool (*get_policy)(const struct kernel_sa *sa, bool inbound,
time_t *use_time);
bool (*add_sa)(const struct kernel_sa *sa, bool replace);
bool (*grp_sa)(const struct kernel_sa *sa_outer,
const struct kernel_sa *sa_inner);
bool (*del_sa)(const struct kernel_sa *sa);
bool (*get_sa)(const struct kernel_sa *sa, u_int *bytes);
ipsec_spi_t (*get_spi)(const ip_address *src,
const ip_address *dst,
int proto,
bool tunnel_mode,
unsigned reqid,
ipsec_spi_t min,
ipsec_spi_t max,
const char *text_said);
};
@ -126,13 +126,13 @@ extern const struct kernel_ops *kernel_ops;
/* information from /proc/net/ipsec_eroute */
struct eroute_info {
unsigned long count;
ip_subnet ours;
ip_subnet his;
ip_address dst;
ip_said said;
int transport_proto;
struct eroute_info *next;
unsigned long count;
ip_subnet ours;
ip_subnet his;
ip_address dst;
ip_said said;
int transport_proto;
struct eroute_info *next;
};
extern struct eroute_info *orphaned_holds;
@ -144,13 +144,13 @@ extern void show_shunt_status(void);
* Is there a PF_KEY equivalent?
*/
#ifndef EM_MAXRELSPIS
# define EM_MAXRELSPIS 4 /* AH ESP IPCOMP IPIP */
# define EM_MAXRELSPIS 4 /* AH ESP IPCOMP IPIP */
#endif
extern void record_and_initiate_opportunistic(const ip_subnet *
, const ip_subnet *
, int transport_proto
, const char *why);
, const ip_subnet *
, int transport_proto
, const char *why);
extern void init_kernel(void);
@ -160,39 +160,39 @@ extern bool trap_connection(struct connection *c);
extern void unroute_connection(struct connection *c);
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
, policy_prio_t policy_prio
, ipsec_spi_t shunt_spi /* in host order! */
, bool repl
, unsigned int transport_proto
, const char *why);
, policy_prio_t policy_prio
, ipsec_spi_t shunt_spi /* in host order! */
, bool repl
, unsigned int transport_proto
, const char *why);
extern bool assign_hold(struct connection *c
, struct spd_route *sr
, int transport_proto
, const ip_address *src, const ip_address *dst);
, struct spd_route *sr
, int transport_proto
, const ip_address *src, const ip_address *dst);
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
, int proto
, struct spd_route *sr
, bool tunnel_mode);
, int proto
, 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_ipsec_sa(struct state *st, bool inbound_also);
extern void delete_ipsec_sa(struct state *st, bool inbound_only);
extern bool route_and_eroute(struct connection *c
, struct spd_route *sr
, struct state *st);
, struct spd_route *sr
, struct state *st);
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
, time_t *use_time);
, time_t *use_time);
extern bool update_ipsec_sa(struct state *st);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -39,7 +39,7 @@
#include "kernel.h"
#include "kernel_noklips.h"
#include "log.h"
#include "whack.h" /* for RC_LOG_SERIOUS */
#include "whack.h" /* for RC_LOG_SERIOUS */
void
init_noklips(void)
@ -71,30 +71,30 @@ noklips_register(void)
static bool
noklips_raw_eroute(const ip_address *this_host UNUSED
, const ip_subnet *this_client UNUSED
, const ip_address *that_host UNUSED
, const ip_subnet *that_client UNUSED
, ipsec_spi_t spi UNUSED
, unsigned int satype UNUSED
, unsigned int transport_proto UNUSED
, const struct pfkey_proto_info *proto_info UNUSED
, time_t use_lifetime UNUSED
, unsigned int op UNUSED
, const char *text_said UNUSED)
, const ip_subnet *this_client UNUSED
, const ip_address *that_host UNUSED
, const ip_subnet *that_client UNUSED
, ipsec_spi_t spi UNUSED
, unsigned int satype UNUSED
, unsigned int transport_proto UNUSED
, const struct pfkey_proto_info *proto_info UNUSED
, time_t use_lifetime UNUSED
, unsigned int op UNUSED
, const char *text_said UNUSED)
{
return TRUE;
}
static bool
noklips_add_sa(const struct kernel_sa *sa UNUSED
, bool replace UNUSED)
, bool replace UNUSED)
{
return TRUE;
}
static bool
noklips_grp_sa(const struct kernel_sa *sa0 UNUSED
, const struct kernel_sa *sa1 UNUSED)
, const struct kernel_sa *sa1 UNUSED)
{
return TRUE;
}
@ -107,20 +107,20 @@ noklips_del_sa(const struct kernel_sa *sa UNUSED)
const struct kernel_ops noklips_kernel_ops = {
type: KERNEL_TYPE_NONE,
async_fdp: NULL,
init: init_noklips,
pfkey_register: noklips_register,
pfkey_register_response: noklips_register_response,
process_queue: noklips_dequeue,
process_msg: noklips_event,
raw_eroute: noklips_raw_eroute,
add_sa: noklips_add_sa,
grp_sa: noklips_grp_sa,
del_sa: noklips_del_sa,
get_sa: NULL,
get_spi: NULL,
inbound_eroute: FALSE,
policy_lifetime: FALSE
type: KERNEL_TYPE_NONE,
async_fdp: NULL,
init: init_noklips,
pfkey_register: noklips_register,
pfkey_register_response: noklips_register_response,
process_queue: noklips_dequeue,
process_msg: noklips_event,
raw_eroute: noklips_raw_eroute,
add_sa: noklips_add_sa,
grp_sa: noklips_grp_sa,
del_sa: noklips_del_sa,
get_sa: NULL,
get_spi: NULL,
inbound_eroute: FALSE,
policy_lifetime: FALSE
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -32,11 +32,11 @@ extern void load_preshared_secrets(int whackfd);
extern void free_preshared_secrets(void);
enum PrivateKeyKind {
PPK_PSK,
/* PPK_DSS, */ /* not implemented */
PPK_RSA,
PPK_XAUTH,
PPK_PIN
PPK_PSK,
/* PPK_DSS, */ /* not implemented */
PPK_RSA,
PPK_XAUTH,
PPK_PIN
};
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;
struct pubkey {
struct id id;
unsigned refcnt; /* reference counted! */
enum dns_auth_level dns_auth_level;
char *dns_sig;
time_t installed_time
, last_tried_time
, last_worked_time
, until_time;
chunk_t issuer;
chunk_t serial;
enum pubkey_alg alg;
union {
RSA_public_key_t rsa;
} u;
struct id id;
unsigned refcnt; /* reference counted! */
enum dns_auth_level dns_auth_level;
char *dns_sig;
time_t installed_time
, last_tried_time
, last_worked_time
, until_time;
chunk_t issuer;
chunk_t serial;
enum pubkey_alg alg;
union {
RSA_public_key_t rsa;
} u;
};
typedef struct pubkey_list pubkey_list_t;
struct pubkey_list {
pubkey_t *key;
pubkey_list_t *next;
pubkey_t *key;
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_list_t *free_public_keyentry(pubkey_list_t *p);
extern void free_public_keys(pubkey_list_t **keys);
extern void free_remembered_public_keys(void);
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 void unreference_key(pubkey_t **pkp);
extern err_t add_public_key(const struct id *id
, enum dns_auth_level dns_auth_level
, enum pubkey_alg alg
, const chunk_t *key
, pubkey_list_t **head);
, enum dns_auth_level dns_auth_level
, enum pubkey_alg alg
, const chunk_t *key
, pubkey_list_t **head);
extern bool has_private_key(cert_t cert);
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
, 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 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
#ifdef USE_KEYRR
, pubkey_list_t **keys
, pubkey_list_t **keys
#endif /* USE_KEYRR */
);
);
#endif /* _KEYS_H */

View File

@ -27,7 +27,7 @@
#include "constants.h"
#include "defs.h"
#include "log.h"
#include "whack.h" /* for RC_LOG_SERIOUS */
#include "whack.h" /* for RC_LOG_SERIOUS */
#include "lex.h"
struct file_lex_position *flp = NULL;
@ -39,36 +39,36 @@ struct file_lex_position *flp = NULL;
bool
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 (!optional || errno != ENOENT)
log_errno((e, "could not open \"%s\"", name));
return FALSE;
}
else
{
new_flp->previous = flp;
flp = new_flp;
flp->filename = name;
flp->fp = f;
flp->lino = 0;
flp->bdry = B_none;
if (f == NULL)
{
if (!optional || errno != ENOENT)
log_errno((e, "could not open \"%s\"", name));
return FALSE;
}
else
{
new_flp->previous = flp;
flp = new_flp;
flp->filename = name;
flp->fp = f;
flp->lino = 0;
flp->bdry = B_none;
flp->cur = flp->buffer; /* nothing loaded yet */
flp->under = *flp->cur = '\0';
flp->cur = flp->buffer; /* nothing loaded yet */
flp->under = *flp->cur = '\0';
(void) shift(); /* prime tok */
return TRUE;
}
(void) shift(); /* prime tok */
return TRUE;
}
}
void
lexclose(void)
{
fclose(flp->fp);
flp = flp->previous;
fclose(flp->fp);
flp = flp->previous;
}
/* Token decoding: shift() loads the next token into tok.
@ -88,110 +88,110 @@ char *tok;
bool
shift(void)
{
char *p = flp->cur;
char *sor = NULL; /* start of record for any new lines */
char *p = flp->cur;
char *sor = NULL; /* start of record for any new lines */
passert(flp->bdry == B_none);
passert(flp->bdry == B_none);
*p = flp->under;
flp->under = '\0';
*p = flp->under;
flp->under = '\0';
for (;;)
{
switch (*p)
for (;;)
{
case '\0': /* end of line */
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)
switch (*p)
{
loglog(RC_LOG_SERIOUS, "\"%s\" line %d: unterminated string"
, flp->filename, flp->lino);
p = tok + strlen(tok);
}
else
{
p++; /* include delimiter in token */
}
case '\0': /* end of line */
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 */
/* 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;
for (p = flp->buffer+strlen(flp->buffer)-1
; p>flp->buffer && isspace(p[-1]); p--)
;
*p = '\0';
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 {
flp->lino++;
sor = p = flp->buffer;
}
break; /* try again for a token */
case ' ': /* whitespace */
case '\t':
p++;
} while (*p != '\0' && !isspace(*p))
;
break; /* try again for a token */
/* fudge to separate ':' from a preceding adjacent token */
if (p-1 > tok && p[-1] == ':')
p--;
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"
, 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 */
@ -199,15 +199,15 @@ shift(void)
bool
flushline(const char *m)
{
if (flp->bdry != B_none)
{
return TRUE;
}
else
{
if (m != NULL)
loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s", flp->filename, flp->lino, m);
do ; while (shift());
return FALSE;
}
if (flp->bdry != B_none)
{
return TRUE;
}
else
{
if (m != NULL)
loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s", flp->filename, flp->lino, m);
do ; while (shift());
return FALSE;
}
}

View File

@ -17,15 +17,15 @@
#define MAX_TOK_LEN 2048 /* includes terminal '\0' */
struct file_lex_position
{
int depth; /* how deeply we are nested */
const char *filename;
FILE *fp;
enum { B_none, B_record, B_file } bdry; /* current boundary */
int lino; /* line number in file */
char buffer[MAX_TOK_LEN + 1]; /* note: one extra char for our use (jamming '"') */
char *cur; /* cursor */
char under; /* except in shift(): character orignally at *cur */
struct file_lex_position *previous;
int depth; /* how deeply we are nested */
const char *filename;
FILE *fp;
enum { B_none, B_record, B_file } bdry; /* current boundary */
int lino; /* line number in file */
char buffer[MAX_TOK_LEN + 1]; /* note: one extra char for our use (jamming '"') */
char *cur; /* cursor */
char under; /* except in shift(): character orignally at *cur */
struct file_lex_position *previous;
};
extern struct file_lex_position *flp;

View File

@ -33,16 +33,16 @@ typedef struct private_library_t private_library_t;
*/
struct private_library_t {
/**
* public functions
*/
library_t public;
/**
* public functions
*/
library_t public;
#ifdef LEAK_DETECTIVE
/**
* Memory leak detective, if enabled
*/
leak_detective_t *detective;
/**
* Memory leak detective, if enabled
*/
leak_detective_t *detective;
#endif /* LEAK_DETECTIVE */
};
@ -56,19 +56,19 @@ library_t *lib;
*/
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.printf_hook->destroy(this->public.printf_hook);
this->public.settings->destroy(this->public.settings);
this->public.printf_hook->destroy(this->public.printf_hook);
#ifdef LEAK_DETECTIVE
if (this->detective)
{
this->detective->destroy(this->detective);
}
if (this->detective)
{
this->detective->destroy(this->detective);
}
#endif /* LEAK_DETECTIVE */
free(this);
lib = NULL;
free(this);
lib = NULL;
}
/*
@ -76,31 +76,31 @@ void library_deinit()
*/
void library_init(char *settings)
{
printf_hook_t *pfh;
private_library_t *this = malloc_thing(private_library_t);
lib = &this->public;
lib->leak_detective = FALSE;
printf_hook_t *pfh;
private_library_t *this = malloc_thing(private_library_t);
lib = &this->public;
lib->leak_detective = FALSE;
#ifdef LEAK_DETECTIVE
this->detective = leak_detective_create();
this->detective = leak_detective_create();
#endif /* LEAK_DETECTIVE */
pfh = printf_hook_create();
this->public.printf_hook = pfh;
pfh->add_handler(pfh, 'b', mem_printf_hook,
PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_INT,
PRINTF_HOOK_ARGTYPE_END);
pfh->add_handler(pfh, 'B', chunk_printf_hook,
PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_END);
pfh->add_handler(pfh, 'T', time_printf_hook,
PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_INT,
PRINTF_HOOK_ARGTYPE_END);
pfh->add_handler(pfh, 'V', time_delta_printf_hook,
PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_POINTER,
PRINTF_HOOK_ARGTYPE_END);
pfh = printf_hook_create();
this->public.printf_hook = pfh;
pfh->add_handler(pfh, 'b', mem_printf_hook,
PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_INT,
PRINTF_HOOK_ARGTYPE_END);
pfh->add_handler(pfh, 'B', chunk_printf_hook,
PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_END);
pfh->add_handler(pfh, 'T', time_printf_hook,
PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_INT,
PRINTF_HOOK_ARGTYPE_END);
pfh->add_handler(pfh, 'V', time_delta_printf_hook,
PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_POINTER,
PRINTF_HOOK_ARGTYPE_END);
this->public.settings = settings_create(settings);
this->public.settings = settings_create(settings);
}

View File

@ -28,26 +28,26 @@ typedef struct library_t library_t;
*/
struct library_t {
/**
* Printf hook registering facility
*/
printf_hook_t *printf_hook;
/**
* various settings loaded from settings file
*/
settings_t *settings;
/**
* is leak detective running?
*/
bool leak_detective;
/**
* Printf hook registering facility
*/
printf_hook_t *printf_hook;
/**
* various settings loaded from settings file
*/
settings_t *settings;
/**
* is leak detective running?
*/
bool leak_detective;
};
/**
* 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);

File diff suppressed because it is too large Load Diff

View File

@ -27,49 +27,49 @@
#ifdef DEBUG
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
, const char *file_str, unsigned long line_no);
, const char *file_str, unsigned long line_no);
# define impossible() passert_fail("impossible", __FILE__, __LINE__)
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 passert(pred) { \
if (!(pred)) \
passert_fail(#pred, __FILE__, __LINE__); \
}
if (!(pred)) \
passert_fail(#pred, __FILE__, __LINE__); \
}
# define pexpect(pred) { \
if (!(pred)) \
pexpect_log(#pred, __FILE__, __LINE__); \
}
if (!(pred)) \
pexpect_log(#pred, __FILE__, __LINE__); \
}
/* assert that an err_t is NULL; evaluate exactly once */
# define happy(x) { \
err_t ugh = x; \
if (ugh != NULL) \
passert_fail(ugh, __FILE__, __LINE__); \
}
err_t ugh = x; \
if (ugh != NULL) \
passert_fail(ugh, __FILE__, __LINE__); \
}
#else /*!DEBUG*/
# define impossible() abort()
# define bad_case(n) abort()
# define passert(pred) { } /* do nothing */
# define happy(x) { (void) x; } /* evaluate non-judgementally */
# define passert(pred) { } /* do nothing */
# define happy(x) { (void) x; } /* evaluate non-judgementally */
#endif /*!DEBUG*/
extern bool
log_to_stderr, /* should log go to stderr? */
log_to_syslog, /* should log go to syslog? */
log_to_perpeer; /* should log go to per-IP file? */
log_to_stderr, /* should log go to stderr? */
log_to_syslog, /* should log go to syslog? */
log_to_perpeer; /* should log go to per-IP file? */
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
* should be copied to it -- see whack_log()
*/
extern int whack_log_fd; /* only set during whack_handle() */
extern struct state *cur_state; /* current state, for diagnostics */
extern struct connection *cur_connection; /* current connection, for diagnostics */
extern const ip_address *cur_from; /* source of current current message */
extern u_int16_t cur_from_port; /* host order */
extern int whack_log_fd; /* only set during whack_handle() */
extern struct state *cur_state; /* current state, for diagnostics */
extern struct connection *cur_connection; /* current connection, for diagnostics */
extern const ip_address *cur_from; /* source of current current message */
extern u_int16_t cur_from_port; /* host order */
#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);
# define reset_debugging() { cur_debugging = base_debugging; }
# define GLOBALS_ARE_RESET() (whack_log_fd == NULL_FD \
&& cur_state == NULL \
&& cur_connection == NULL \
&& cur_from == NULL \
&& cur_debugging == base_debugging)
&& cur_state == NULL \
&& cur_connection == NULL \
&& cur_from == NULL \
&& cur_debugging == base_debugging)
#else /*!DEBUG*/
@ -111,40 +111,40 @@ extern u_int16_t cur_from_port; /* host order */
# define reset_debugging() { }
# define GLOBALS_ARE_RESET() (whack_log_fd == NULL_FD \
&& cur_state == NULL \
&& cur_connection == NULL \
&& cur_from == NULL)
&& cur_state == NULL \
&& cur_connection == NULL \
&& cur_from == NULL)
#endif /*!DEBUG*/
#define reset_globals() { \
whack_log_fd = NULL_FD; \
cur_state = NULL; \
cur_from = NULL; \
reset_cur_connection(); \
}
whack_log_fd = NULL_FD; \
cur_state = NULL; \
cur_from = NULL; \
reset_cur_connection(); \
}
#define set_cur_connection(c) { \
cur_connection = (c); \
extra_debugging(c); \
}
cur_connection = (c); \
extra_debugging(c); \
}
#define reset_cur_connection() { \
cur_connection = NULL; \
reset_debugging(); \
}
cur_connection = NULL; \
reset_debugging(); \
}
#define set_cur_state(s) { \
cur_state = (s); \
extra_debugging((s)->st_connection); \
}
cur_state = (s); \
extra_debugging((s)->st_connection); \
}
#define reset_cur_state() { \
cur_state = NULL; \
reset_debugging(); \
}
cur_state = NULL; \
reset_debugging(); \
}
extern void init_log(const char *program);
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
* 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);
#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 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*/
#define DBG(cond, action) { } /* do nothing */
#define DBG(cond, action) { } /* do nothing */
#endif /*!DEBUG*/

View File

@ -21,15 +21,15 @@
#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
((unsigned char [16], unsigned char [16], const unsigned char [16]));
#ifdef HAVEMEMCOPY
#include <memory.h>
#define MD2_memcpy memcpy
#define MD2_memset memset
#define MD2_memcpy memcpy
#define MD2_memset memset
#else
#ifdef HAVEBCOPY
#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 *)"\014\014\014\014\014\014\014\014\014\014\014\014",
(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 *)
"\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 *)
"\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 *)
"\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.
@ -96,12 +96,12 @@ MD2_CTX *context; /* context */
context->count = 0;
MD2_memset ((POINTER)context->state, 0, sizeof (context->state));
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
operation, processing another message block, and updating the
context.
operation, processing another message block, and updating the
context.
*/
void MD2Update (context, input, inputLen)
MD2_CTX *context; /* context */
@ -117,28 +117,28 @@ unsigned int inputLen; /* length of input block */
partLen = 16 - index;
/* Transform as many times as possible.
*/
*/
if (inputLen >= partLen) {
MD2_memcpy
((POINTER)&context->buffer[index], (CONST_POINTER)input, partLen);
MD2Transform (context->state, context->checksum, context->buffer);
MD2_memcpy
((POINTER)&context->buffer[index], (CONST_POINTER)input, partLen);
MD2Transform (context->state, context->checksum, context->buffer);
for (i = partLen; i + 15 < inputLen; i += 16)
MD2Transform (context->state, context->checksum, &input[i]);
for (i = partLen; i + 15 < inputLen; i += 16)
MD2Transform (context->state, context->checksum, &input[i]);
index = 0;
index = 0;
}
else
i = 0;
i = 0;
/* Buffer remaining input */
MD2_memcpy
((POINTER)&context->buffer[index], (CONST_POINTER)&input[i],
inputLen-i);
((POINTER)&context->buffer[index], (CONST_POINTER)&input[i],
inputLen-i);
}
/* 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)
@ -165,7 +165,7 @@ MD2_CTX *context; /* context */
}
/* MD2 basic transformation. Transforms state and updates checksum
based on block.
based on block.
*/
static void MD2Transform (state, checksum, block)
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+16, (CONST_POINTER)block, 16);
for (i = 0; i < 16; i++)
x[i+32] = state[i] ^ block[i];
x[i+32] = state[i] ^ block[i];
/* Encrypt block (18 rounds).
*/
t = 0;
for (i = 0; i < 18; i++) {
for (j = 0; j < 48; j++)
t = x[j] ^= PI_SUBST[t];
t = (t + i) & 0xff;
for (j = 0; j < 48; j++)
t = x[j] ^= PI_SUBST[t];
t = (t + i) & 0xff;
}
/* Save new state */
@ -198,7 +198,7 @@ const unsigned char block[16];
*/
t = checksum[15];
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.
*/
@ -217,7 +217,7 @@ unsigned int len;
unsigned int i;
for (i = 0; i < len; i++)
output[i] = input[i];
output[i] = input[i];
}
/* Note: Replace "for loop" with standard memset if possible.
@ -230,7 +230,7 @@ unsigned int len;
unsigned int i;
for (i = 0; i < len; i++)
((char *)output)[i] = (char)value;
((char *)output)[i] = (char)value;
}
#endif
#endif

View File

@ -4,9 +4,9 @@
*/
/* 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
been defined with C compiler flags.
been defined with C compiler flags.
*/
#ifndef PROTOTYPES
#define PROTOTYPES 1
@ -24,7 +24,7 @@ typedef unsigned long int UINT4;
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
returns an empty list.
returns an empty list.
*/
#if PROTOTYPES

View File

@ -41,12 +41,12 @@ documentation and/or software.
#include <stddef.h>
#include <string.h>
#include <sys/types.h> /* for u_int*_t */
#include <endian.h> /* sets BYTE_ORDER, LITTLE_ENDIAN, and BIG_ENDIAN */
#include <sys/types.h> /* for u_int*_t */
#include <endian.h> /* sets BYTE_ORDER, LITTLE_ENDIAN, and BIG_ENDIAN */
#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.
*/
@ -84,8 +84,8 @@ static void Decode PROTO_LIST
#ifdef HAVEMEMCOPY
#include <memory.h>
#define MD5_memcpy memcpy
#define MD5_memset memset
#define MD5_memcpy memcpy
#define MD5_memset memset
#else
#ifdef HAVEBCOPY
#define MD5_memcpy(_a,_b,_c) memcpy((_a), (_b),(_c))
@ -167,23 +167,23 @@ UINT4 inputLen; /* length of input block */
/* Update number of bits */
if ((context->count[0] += (inputLen << 3)) < (inputLen << 3))
context->count[1]++;
context->count[1]++;
context->count[1] += (inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible. */
if (inputLen >= partLen) {
MD5_memcpy((POINTER)&context->buffer[index], (CONSTPOINTER)input, partLen);
MD5Transform (context->state, context->buffer);
MD5_memcpy((POINTER)&context->buffer[index], (CONSTPOINTER)input, partLen);
MD5Transform (context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform (context->state, &input[i]);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform (context->state, &input[i]);
index = 0;
index = 0;
}
else
i = 0;
i = 0;
/* Buffer remaining input */
MD5_memcpy((POINTER)&context->buffer[index], (CONSTPOINTER)&input[i], inputLen-i);
@ -211,14 +211,14 @@ MD5_CTX *context; /* context */
/* Append length (before padding) */
MD5Update (context, bits, 8);
if (digest != NULL) /* Bill Simpson's padding */
if (digest != NULL) /* Bill Simpson's padding */
{
/* store state in digest */
Encode (digest, context->state, 16);
/* store state in digest */
Encode (digest, context->state, 16);
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)context, 0, sizeof (*context));
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)context, 0, sizeof (*context));
}
}

View File

@ -4,9 +4,9 @@
*/
/* 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
been defined with C compiler flags.
been defined with C compiler flags.
*/
#ifndef PROTOTYPES
#define PROTOTYPES 1
@ -24,7 +24,7 @@ typedef u_int32_t UINT4;
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
returns an empty list.
returns an empty list.
*/
#if PROTOTYPES

File diff suppressed because it is too large Load Diff

View File

@ -27,29 +27,29 @@
chunk_t
mpz_to_n(const MP_INT *mp, size_t bytes)
{
chunk_t r;
MP_INT temp1, temp2;
int i;
chunk_t r;
MP_INT temp1, temp2;
int i;
r.len = bytes;
r.ptr = malloc(r.len);
r.len = bytes;
r.ptr = malloc(r.len);
mpz_init(&temp1);
mpz_init(&temp2);
mpz_init(&temp1);
mpz_init(&temp2);
mpz_set(&temp1, mp);
mpz_set(&temp1, mp);
for (i = r.len-1; i >= 0; i--)
{
r.ptr[i] = mpz_mdivmod_ui(&temp2, NULL, &temp1, 1 << BITS_PER_BYTE);
mpz_set(&temp1, &temp2);
}
for (i = r.len-1; i >= 0; i--)
{
r.ptr[i] = mpz_mdivmod_ui(&temp2, NULL, &temp1, 1 << BITS_PER_BYTE);
mpz_set(&temp1, &temp2);
}
passert(mpz_sgn(&temp1) == 0); /* we must have done all the bits */
mpz_clear(&temp1);
mpz_clear(&temp2);
passert(mpz_sgn(&temp1) == 0); /* we must have done all the bits */
mpz_clear(&temp1);
mpz_clear(&temp2);
return r;
return r;
}
/* 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
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++)
{
mpz_mul_ui(mp, mp, 1 << BITS_PER_BYTE);
mpz_add_ui(mp, mp, nbytes[i]);
}
for (i = 0; i != nlen; i++)
{
mpz_mul_ui(mp, mp, 1 << BITS_PER_BYTE);
mpz_add_ui(mp, mp, nbytes[i]);
}
}

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 */
#define mpz_init_powm(flag, var, base, exp, mod) { \
if (!(flag)) \
mpz_init(&(var)); \
(flag) = TRUE; \
mpz_powm(&(var), &(base), &(exp), (mod)); \
}
if (!(flag)) \
mpz_init(&(var)); \
(flag) = TRUE; \
mpz_powm(&(var), &(base), &(exp), (mod)); \
}
#endif /* _MP_DEFS_H */

File diff suppressed because it is too large Load Diff

View File

@ -32,37 +32,37 @@
* NAT-Traversal methods which need NAT-D
*/
#define NAT_T_WITH_NATD \
( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
LELEM(NAT_TRAVERSAL_RFC) )
( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
LELEM(NAT_TRAVERSAL_RFC) )
/**
* NAT-Traversal methods which need NAT-OA
*/
#define NAT_T_WITH_NATOA \
( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
LELEM(NAT_TRAVERSAL_RFC) )
( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
LELEM(NAT_TRAVERSAL_RFC) )
/**
* NAT-Traversal methods which use NAT-KeepAlive
*/
#define NAT_T_WITH_KA \
( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
LELEM(NAT_TRAVERSAL_RFC) )
( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
LELEM(NAT_TRAVERSAL_RFC) )
/**
* NAT-Traversal methods which use floating port
*/
#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)
*/
#define NAT_T_WITH_RFC_VALUES \
( LELEM(NAT_TRAVERSAL_RFC) )
( LELEM(NAT_TRAVERSAL_RFC) )
/**
* NAT-Traversal 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
@ -70,7 +70,7 @@
#define NAT_T_IKE_FLOAT_PORT 4500
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_support_non_ike;
@ -82,7 +82,7 @@ extern bool nat_traversal_support_port_floating;
void nat_traversal_natd_lookup(struct msg_digest *md);
#ifndef PB_STREAM_UNDEFINED
bool nat_traversal_add_natd(u_int8_t np, pb_stream *outs,
struct msg_digest *md);
struct msg_digest *md);
#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);
#ifndef PB_STREAM_UNDEFINED
bool nat_traversal_add_natoa(u_int8_t np, pb_stream *outs,
struct state *st);
struct state *st);
#endif
/**
@ -119,8 +119,8 @@ void nat_traversal_change_port_lookup(struct msg_digest *md, struct state *st);
*/
#ifdef __PFKEY_V2_H
void process_pfkey_nat_t_new_mapping(
struct sadb_msg *,
struct sadb_ext *[SADB_EXT_MAX + 1]);
struct sadb_msg *,
struct sadb_ext *[SADB_EXT_MAX + 1]);
#endif
/**
@ -133,22 +133,22 @@ nat_traversal_port_float(struct state *st, struct msg_digest *md, bool in);
* Encapsulation mode macro (see demux.c)
*/
#define NAT_T_ENCAPSULATION_MODE(st,nat_t_policy) ( \
((st)->nat_traversal & NAT_T_DETECTED) \
? ( ((nat_t_policy) & POLICY_TUNNEL) \
? ( ((st)->nat_traversal & NAT_T_WITH_RFC_VALUES) \
? (ENCAPSULATION_MODE_UDP_TUNNEL_RFC) \
: (ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS) \
) \
: ( ((st)->nat_traversal & NAT_T_WITH_RFC_VALUES) \
? (ENCAPSULATION_MODE_UDP_TRANSPORT_RFC) \
: (ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS) \
) \
) \
: ( ((st)->st_policy & POLICY_TUNNEL) \
? (ENCAPSULATION_MODE_TUNNEL) \
: (ENCAPSULATION_MODE_TRANSPORT) \
) \
)
((st)->nat_traversal & NAT_T_DETECTED) \
? ( ((nat_t_policy) & POLICY_TUNNEL) \
? ( ((st)->nat_traversal & NAT_T_WITH_RFC_VALUES) \
? (ENCAPSULATION_MODE_UDP_TUNNEL_RFC) \
: (ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS) \
) \
: ( ((st)->nat_traversal & NAT_T_WITH_RFC_VALUES) \
? (ENCAPSULATION_MODE_UDP_TRANSPORT_RFC) \
: (ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS) \
) \
) \
: ( ((st)->st_policy & POLICY_TUNNEL) \
? (ENCAPSULATION_MODE_TUNNEL) \
: (ENCAPSULATION_MODE_TRANSPORT) \
) \
)
#endif /* _NAT_TRAVERSAL_H */

File diff suppressed because it is too large Load Diff

View File

@ -19,19 +19,19 @@
/* constants */
#define OCSP_BASIC_RESPONSE_VERSION 1
#define OCSP_DEFAULT_VALID_TIME 120 /* validity of one-time response in seconds */
#define OCSP_WARNING_INTERVAL 2 /* days */
#define OCSP_BASIC_RESPONSE_VERSION 1
#define OCSP_DEFAULT_VALID_TIME 120 /* validity of one-time response in seconds */
#define OCSP_WARNING_INTERVAL 2 /* days */
/* OCSP response status */
typedef enum {
STATUS_SUCCESSFUL = 0,
STATUS_MALFORMEDREQUEST = 1,
STATUS_INTERNALERROR = 2,
STATUS_TRYLATER = 3,
STATUS_SIGREQUIRED = 5,
STATUS_UNAUTHORIZED= 6
STATUS_SUCCESSFUL = 0,
STATUS_MALFORMEDREQUEST = 1,
STATUS_INTERNALERROR = 2,
STATUS_TRYLATER = 3,
STATUS_SIGREQUIRED = 5,
STATUS_UNAUTHORIZED= 6
} response_status;
/* OCSP access structures */
@ -39,46 +39,46 @@ typedef enum {
typedef struct ocsp_certinfo ocsp_certinfo_t;
struct ocsp_certinfo {
ocsp_certinfo_t *next;
int trials;
chunk_t serialNumber;
cert_status_t status;
bool once;
crl_reason_t revocationReason;
time_t revocationTime;
time_t thisUpdate;
time_t nextUpdate;
ocsp_certinfo_t *next;
int trials;
chunk_t serialNumber;
cert_status_t status;
bool once;
crl_reason_t revocationReason;
time_t revocationTime;
time_t thisUpdate;
time_t nextUpdate;
};
typedef struct ocsp_location ocsp_location_t;
struct ocsp_location {
ocsp_location_t *next;
chunk_t issuer;
chunk_t authNameID;
chunk_t authKeyID;
chunk_t authKeySerialNumber;
chunk_t uri;
chunk_t nonce;
ocsp_certinfo_t *certinfo;
ocsp_location_t *next;
chunk_t issuer;
chunk_t authNameID;
chunk_t authKeyID;
chunk_t authKeySerialNumber;
chunk_t uri;
chunk_t nonce;
ocsp_certinfo_t *certinfo;
};
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
, ocsp_location_t **chain);
, ocsp_location_t **chain);
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 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 void ocsp_set_default_uri(char* uri);
extern void ocsp_cache_add_cert(const x509cert_t* cert);
extern chunk_t build_ocsp_request(ocsp_location_t* location);
extern void parse_ocsp(ocsp_location_t* location, chunk_t blob);
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 free_ocsp_locations(ocsp_location_t **chain);
extern void free_ocsp_cache(void);

File diff suppressed because it is too large Load Diff

View File

@ -23,9 +23,9 @@
*/
typedef const struct struct_desc {
const char *name;
const struct field_desc *fields;
size_t size;
const char *name;
const struct field_desc *fields;
size_t size;
} struct_desc;
/* 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 {
ft_mbz, /* must be zero */
ft_nat, /* natural number (may be 0) */
ft_len, /* length of this struct and any following crud */
ft_lv, /* length/value field of attribute */
ft_enum, /* value from an enumeration */
ft_loose_enum, /* value from an enumeration with only some names known */
ft_af_loose_enum, /* Attribute Format + enumeration, some names known */
ft_af_enum, /* Attribute Format + value from an enumeration */
ft_set, /* bits representing set */
ft_raw, /* bytes to be left in network-order */
ft_end, /* end of field list */
ft_mbz, /* must be zero */
ft_nat, /* natural number (may be 0) */
ft_len, /* length of this struct and any following crud */
ft_lv, /* length/value field of attribute */
ft_enum, /* value from an enumeration */
ft_loose_enum, /* value from an enumeration with only some names known */
ft_af_loose_enum, /* Attribute Format + enumeration, some names known */
ft_af_enum, /* Attribute Format + value from an enumeration */
ft_set, /* bits representing set */
ft_raw, /* bytes to be left in network-order */
ft_end, /* end of field list */
};
typedef const struct field_desc {
enum field_type field_type;
int size; /* size, in bytes, of field */
const char *name;
const void *desc; /* enum_names for enum or char *[] for bits */
enum field_type field_type;
int size; /* size, in bytes, of field */
const char *name;
const void *desc; /* enum_names for enum or char *[] for bits */
} field_desc;
/* 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.
*/
typedef struct packet_byte_stream {
struct packet_byte_stream *container; /* PBS of which we are part */
struct_desc *desc;
const char *name; /* what does this PBS represent? */
u_int8_t
*start,
*cur, /* current position in stream */
*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
* we need to record its particulars. Note: it may not be aligned.
*/
u_int8_t *lenfld;
field_desc *lenfld_desc;
struct packet_byte_stream *container; /* PBS of which we are part */
struct_desc *desc;
const char *name; /* what does this PBS represent? */
u_int8_t
*start,
*cur, /* current position in stream */
*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
* we need to record its particulars. Note: it may not be aligned.
*/
u_int8_t *lenfld;
field_desc *lenfld_desc;
} pb_stream;
/* 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 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 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,
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,
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) \
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_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))
@ -106,7 +106,7 @@ extern void close_output_pbs(pb_stream *pbs);
#ifdef DEBUG
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
/* ISAKMP Header: for all messages
@ -160,16 +160,16 @@ extern void DBG_print_struct(const char *label, const void *struct_ptr,
struct isakmp_hdr
{
u_int8_t isa_icookie[COOKIE_SIZE];
u_int8_t isa_rcookie[COOKIE_SIZE];
u_int8_t isa_np; /* Next payload */
u_int8_t isa_version; /* high-order 4 bits: Major; low order 4: Minor */
#define ISA_MAJ_SHIFT 4
#define ISA_MIN_MASK (~((~0u) << ISA_MAJ_SHIFT))
u_int8_t isa_xchg; /* Exchange type */
u_int8_t isa_flags;
u_int32_t isa_msgid; /* Message ID (RAW) */
u_int32_t isa_length; /* Length of message */
u_int8_t isa_icookie[COOKIE_SIZE];
u_int8_t isa_rcookie[COOKIE_SIZE];
u_int8_t isa_np; /* Next payload */
u_int8_t isa_version; /* high-order 4 bits: Major; low order 4: Minor */
#define ISA_MAJ_SHIFT 4
#define ISA_MIN_MASK (~((~0u) << ISA_MAJ_SHIFT))
u_int8_t isa_xchg; /* Exchange type */
u_int8_t isa_flags;
u_int32_t isa_msgid; /* Message ID (RAW) */
u_int32_t isa_length; /* Length of message */
};
extern struct_desc isakmp_hdr_desc;
@ -186,9 +186,9 @@ extern struct_desc isakmp_hdr_desc;
*/
struct isakmp_generic
{
u_int8_t isag_np;
u_int8_t isag_reserved;
u_int16_t isag_length;
u_int8_t isag_np;
u_int8_t isag_reserved;
u_int16_t isag_length;
};
extern struct_desc isakmp_generic_desc;
@ -209,17 +209,17 @@ extern struct_desc isakmp_generic_desc;
*/
struct isakmp_attribute
{
/* 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
* attribute value.
* 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.
*
* The low order 15 bits of isaat_af_type is the Attribute Type.
* 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_lv; /* Length or value */
/* 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
* attribute value.
* 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.
*
* The low order 15 bits of isaat_af_type is the Attribute Type.
* 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_lv; /* Length or value */
};
#define ISAKMP_ATTR_AF_MASK 0x8000
@ -229,8 +229,8 @@ struct isakmp_attribute
#define ISAKMP_ATTR_RTYPE_MASK 0x7FFF
extern struct_desc
isakmp_oakley_attribute_desc,
isakmp_ipsec_attribute_desc;
isakmp_oakley_attribute_desc,
isakmp_ipsec_attribute_desc;
/* ISAKMP Security Association Payload
* layout from RFC 2408 "ISAKMP" section 3.4
@ -250,10 +250,10 @@ extern struct_desc
*/
struct isakmp_sa
{
u_int8_t isasa_np; /* Next payload */
u_int8_t isasa_reserved;
u_int16_t isasa_length; /* Payload length */
u_int32_t isasa_doi; /* DOI */
u_int8_t isasa_np; /* Next payload */
u_int8_t isasa_reserved;
u_int16_t isasa_length; /* Payload length */
u_int32_t isasa_doi; /* DOI */
};
extern struct_desc isakmp_sa_desc;
@ -276,13 +276,13 @@ extern struct_desc ipsec_sit_desc;
*/
struct isakmp_proposal
{
u_int8_t isap_np;
u_int8_t isap_reserved;
u_int16_t isap_length;
u_int8_t isap_proposal;
u_int8_t isap_protoid;
u_int8_t isap_spisize;
u_int8_t isap_notrans; /* Number of transforms */
u_int8_t isap_np;
u_int8_t isap_reserved;
u_int16_t isap_length;
u_int8_t isap_proposal;
u_int8_t isap_protoid;
u_int8_t isap_spisize;
u_int8_t isap_notrans; /* Number of transforms */
};
extern struct_desc isakmp_proposal_desc;
@ -305,19 +305,19 @@ extern struct_desc isakmp_proposal_desc;
*/
struct isakmp_transform
{
u_int8_t isat_np;
u_int8_t isat_reserved;
u_int16_t isat_length;
u_int8_t isat_transnum; /* Number of the transform */
u_int8_t isat_transid;
u_int16_t isat_reserved2;
u_int8_t isat_np;
u_int8_t isat_reserved;
u_int16_t isat_length;
u_int8_t isat_transnum; /* Number of the transform */
u_int8_t isat_transid;
u_int16_t isat_reserved2;
};
extern struct_desc
isakmp_isakmp_transform_desc,
isakmp_ah_transform_desc,
isakmp_esp_transform_desc,
isakmp_ipcomp_transform_desc;
isakmp_isakmp_transform_desc,
isakmp_ah_transform_desc,
isakmp_esp_transform_desc,
isakmp_ipcomp_transform_desc;
/* ISAKMP Key Exchange Payload: no fixed fields beyond the generic ones.
* layout from RFC 2408 "ISAKMP" section 3.7
@ -354,12 +354,12 @@ extern struct_desc isakmp_keyex_desc;
*/
struct isakmp_id
{
u_int8_t isaid_np;
u_int8_t isaid_reserved;
u_int16_t isaid_length;
u_int8_t isaid_idtype;
u_int8_t isaid_doi_specific_a;
u_int16_t isaid_doi_specific_b;
u_int8_t isaid_np;
u_int8_t isaid_reserved;
u_int16_t isaid_length;
u_int8_t isaid_idtype;
u_int8_t isaid_doi_specific_a;
u_int16_t isaid_doi_specific_b;
};
extern struct_desc isakmp_identification_desc;
@ -381,12 +381,12 @@ extern struct_desc isakmp_identification_desc;
*/
struct isakmp_ipsec_id
{
u_int8_t isaiid_np;
u_int8_t isaiid_reserved;
u_int16_t isaiid_length;
u_int8_t isaiid_idtype;
u_int8_t isaiid_protoid;
u_int16_t isaiid_port;
u_int8_t isaiid_np;
u_int8_t isaiid_reserved;
u_int16_t isaiid_length;
u_int8_t isaiid_idtype;
u_int8_t isaiid_protoid;
u_int16_t isaiid_port;
};
extern struct_desc isakmp_ipsec_identification_desc;
@ -408,17 +408,17 @@ extern struct_desc isakmp_ipsec_identification_desc;
*/
struct isakmp_cert
{
u_int8_t isacert_np;
u_int8_t isacert_reserved;
u_int16_t isacert_length;
u_int8_t isacert_type;
u_int8_t isacert_np;
u_int8_t isacert_reserved;
u_int16_t isacert_length;
u_int8_t isacert_type;
};
/* NOTE: this packet type has a fixed portion that is not a
* multiple of 4 octets. This means that sizeof(struct isakmp_cert)
* yields the wrong value for the length.
*/
#define ISAKMP_CERT_SIZE 5
#define ISAKMP_CERT_SIZE 5
extern struct_desc isakmp_ipsec_certificate_desc;
@ -439,17 +439,17 @@ extern struct_desc isakmp_ipsec_certificate_desc;
*/
struct isakmp_cr
{
u_int8_t isacr_np;
u_int8_t isacr_reserved;
u_int16_t isacr_length;
u_int8_t isacr_type;
u_int8_t isacr_np;
u_int8_t isacr_reserved;
u_int16_t isacr_length;
u_int8_t isacr_type;
};
/* NOTE: this packet type has a fixed portion that is not a
* multiple of 4 octets. This means that sizeof(struct isakmp_cr)
* 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;
@ -526,13 +526,13 @@ extern struct_desc isakmp_nonce_desc;
*/
struct isakmp_notification
{
u_int8_t isan_np;
u_int8_t isan_reserved;
u_int16_t isan_length;
u_int32_t isan_doi;
u_int8_t isan_protoid;
u_int8_t isan_spisize;
u_int16_t isan_type;
u_int8_t isan_np;
u_int8_t isan_reserved;
u_int16_t isan_length;
u_int32_t isan_doi;
u_int8_t isan_protoid;
u_int8_t isan_spisize;
u_int16_t isan_type;
};
extern struct_desc isakmp_notification_desc;
@ -557,40 +557,40 @@ extern struct_desc isakmp_notification_desc;
*/
struct isakmp_delete
{
u_int8_t isad_np;
u_int8_t isad_reserved;
u_int16_t isad_length;
u_int32_t isad_doi;
u_int8_t isad_protoid;
u_int8_t isad_spisize;
u_int16_t isad_nospi;
u_int8_t isad_np;
u_int8_t isad_reserved;
u_int16_t isad_length;
u_int32_t isad_doi;
u_int8_t isad_protoid;
u_int8_t isad_spisize;
u_int16_t isad_nospi;
};
extern struct_desc isakmp_delete_desc;
/* From draft-dukes-ike-mode-cfg
3.2. Attribute Payload
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! Next Payload ! RESERVED ! Payload Length !
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! Type ! RESERVED ! Identifier !
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! !
! !
~ Attributes ~
! !
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! Next Payload ! RESERVED ! Payload Length !
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! Type ! RESERVED ! Identifier !
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! !
! !
~ Attributes ~
! !
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
struct isakmp_mode_attr
{
u_int8_t isama_np;
u_int8_t isama_reserved;
u_int16_t isama_length;
u_int8_t isama_type;
u_int8_t isama_reserved2;
u_int16_t isama_identifier;
u_int8_t isama_np;
u_int8_t isama_reserved;
u_int16_t isama_length;
u_int8_t isama_type;
u_int8_t isama_reserved2;
u_int16_t isama_identifier;
};
extern struct_desc isakmp_attr_desc;
@ -614,12 +614,12 @@ extern struct_desc isakmp_vendor_id_desc;
struct isakmp_nat_oa
{
u_int8_t isanoa_np;
u_int8_t isanoa_reserved_1;
u_int16_t isanoa_length;
u_int8_t isanoa_idtype;
u_int8_t isanoa_reserved_2;
u_int16_t isanoa_reserved_3;
u_int8_t isanoa_np;
u_int8_t isanoa_reserved_1;
u_int16_t isanoa_length;
u_int8_t isanoa_idtype;
u_int8_t isanoa_reserved_2;
u_int16_t isanoa_reserved_3;
};
extern struct_desc isakmp_nat_d;
@ -628,18 +628,18 @@ extern struct_desc isakmp_nat_oa;
/* union of all payloads */
union payload {
struct isakmp_generic generic;
struct isakmp_sa sa;
struct isakmp_proposal proposal;
struct isakmp_transform transform;
struct isakmp_id id; /* Main Mode */
struct isakmp_cert cert;
struct isakmp_cr cr;
struct isakmp_ipsec_id ipsec_id; /* Quick Mode */
struct isakmp_notification notification;
struct isakmp_delete delete;
struct isakmp_nat_oa nat_oa;
struct isakmp_mode_attr attribute;
struct isakmp_generic generic;
struct isakmp_sa sa;
struct isakmp_proposal proposal;
struct isakmp_transform transform;
struct isakmp_id id; /* Main Mode */
struct isakmp_cert cert;
struct isakmp_cr cr;
struct isakmp_ipsec_id ipsec_id; /* Quick Mode */
struct isakmp_notification notification;
struct isakmp_delete delete;
struct isakmp_nat_oa nat_oa;
struct isakmp_mode_attr attribute;
};
/* descriptor for each payload type

View File

@ -43,15 +43,15 @@
static bool
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))
{
ch->ptr += pattern_len;
ch->len -= pattern_len;
return TRUE;
}
return FALSE;
if (ch->len >= pattern_len && strneq(ch->ptr, pattern, pattern_len))
{
ch->ptr += pattern_len;
ch->len -= pattern_len;
return TRUE;
}
return FALSE;
}
/*
@ -60,7 +60,7 @@ present(const char* pattern, chunk_t* ch)
static bool
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
find_boundary(const char* tag, chunk_t *line)
{
chunk_t name = chunk_empty;
chunk_t name = chunk_empty;
if (!present("-----", line))
return FALSE;
if (!present(tag, line))
return FALSE;
if (*line->ptr != ' ')
return FALSE;
line->ptr++; line->len--;
if (!present("-----", line))
return FALSE;
if (!present(tag, line))
return FALSE;
if (*line->ptr != ' ')
return FALSE;
line->ptr++; line->len--;
/* extract name */
name.ptr = line->ptr;
while (line->len > 0)
{
if (present("-----", line))
/* extract name */
name.ptr = line->ptr;
while (line->len > 0)
{
DBG(DBG_PARSING,
DBG_log(" -----%s %.*s-----",
tag, (int)name.len, name.ptr);
)
return TRUE;
if (present("-----", line))
{
DBG(DBG_PARSING,
DBG_log(" -----%s %.*s-----",
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
eat_whitespace(chunk_t *src)
{
while (src->len > 0 && (*src->ptr == ' ' || *src->ptr == '\t'))
{
src->ptr++; src->len--;
}
while (src->len > 0 && (*src->ptr == ' ' || *src->ptr == '\t'))
{
src->ptr++; src->len--;
}
}
/*
@ -114,21 +114,21 @@ eat_whitespace(chunk_t *src)
static bool
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 */
*token = chunk_empty;
/* initialize empty token */
*token = chunk_empty;
if (eot == NULL) /* termination symbol not found */
return FALSE;
if (eot == NULL) /* termination symbol not found */
return FALSE;
/* extract token */
token->ptr = src->ptr;
token->len = (u_int)(eot - src->ptr);
/* extract token */
token->ptr = src->ptr;
token->len = (u_int)(eot - src->ptr);
/* advance src pointer after termination symbol */
src->ptr = eot + 1;
src->len -= (token->len + 1);
/* advance src pointer after termination symbol */
src->ptr = eot + 1;
src->len -= (token->len + 1);
return TRUE;
}
@ -139,19 +139,19 @@ extract_token(chunk_t *token, char termination, chunk_t *src)
static bool
extract_parameter(chunk_t *name, chunk_t *value, chunk_t *line)
{
DBG(DBG_PARSING,
DBG_log(" %.*s", (int)line->len, line->ptr);
)
DBG(DBG_PARSING,
DBG_log(" %.*s", (int)line->len, line->ptr);
)
/* extract name */
if (!extract_token(name,':', line))
return FALSE;
/* extract name */
if (!extract_token(name,':', line))
return FALSE;
eat_whitespace(line);
eat_whitespace(line);
/* extract value */
*value = *line;
return TRUE;
/* extract value */
*value = *line;
return TRUE;
}
/*
@ -160,21 +160,21 @@ extract_parameter(chunk_t *name, chunk_t *value, chunk_t *line)
static bool
fetchline(chunk_t *src, chunk_t *line)
{
if (src->len == 0) /* end of src reached */
return FALSE;
if (src->len == 0) /* end of src reached */
return FALSE;
if (extract_token(line, '\n', src))
{
if (line->len > 0 && *(line->ptr + line->len -1) == '\r')
line->len--; /* remove optional \r */
}
else /*last line ends without newline */
{
*line = *src;
src->ptr += src->len;
src->len = 0;
}
return TRUE;
if (extract_token(line, '\n', src))
{
if (line->len > 0 && *(line->ptr + line->len -1) == '\r')
line->len--; /* remove optional \r */
}
else /*last line ends without newline */
{
*line = *src;
src->ptr += src->len;
src->len = 0;
}
return TRUE;
}
/*
@ -183,55 +183,55 @@ fetchline(chunk_t *src, chunk_t *line)
static bool
pem_decrypt_3des(chunk_t *blob, chunk_t *iv, const char *passphrase)
{
MD5_CTX context;
u_char digest[MD5_DIGEST_SIZE];
u_char des_iv[DES_CBC_BLOCK_SIZE];
u_char key[24];
des_cblock *deskey = (des_cblock *)key;
des_key_schedule ks[3];
u_char padding, *last_padding_pos, *first_padding_pos;
MD5_CTX context;
u_char digest[MD5_DIGEST_SIZE];
u_char des_iv[DES_CBC_BLOCK_SIZE];
u_char key[24];
des_cblock *deskey = (des_cblock *)key;
des_key_schedule ks[3];
u_char padding, *last_padding_pos, *first_padding_pos;
/* Convert passphrase to 3des key */
MD5Init(&context);
MD5Update(&context, passphrase, strlen(passphrase));
MD5Update(&context, iv->ptr, iv->len);
MD5Final(digest, &context);
/* Convert passphrase to 3des key */
MD5Init(&context);
MD5Update(&context, passphrase, strlen(passphrase));
MD5Update(&context, iv->ptr, iv->len);
MD5Final(digest, &context);
memcpy(key, digest, MD5_DIGEST_SIZE);
memcpy(key, digest, MD5_DIGEST_SIZE);
MD5Init(&context);
MD5Update(&context, digest, MD5_DIGEST_SIZE);
MD5Update(&context, passphrase, strlen(passphrase));
MD5Update(&context, iv->ptr, iv->len);
MD5Final(digest, &context);
MD5Init(&context);
MD5Update(&context, digest, MD5_DIGEST_SIZE);
MD5Update(&context, passphrase, strlen(passphrase));
MD5Update(&context, iv->ptr, iv->len);
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[1], ks[1]);
(void) des_set_key(&deskey[2], ks[2]);
(void) des_set_key(&deskey[0], ks[0]);
(void) des_set_key(&deskey[1], ks[1]);
(void) des_set_key(&deskey[2], ks[2]);
/* decrypt data block */
memcpy(des_iv, iv->ptr, DES_CBC_BLOCK_SIZE);
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);
/* decrypt data block */
memcpy(des_iv, iv->ptr, DES_CBC_BLOCK_SIZE);
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);
/* determine amount of padding */
last_padding_pos = blob->ptr + blob->len - 1;
padding = *last_padding_pos;
first_padding_pos = (padding > blob->len)?
blob->ptr : last_padding_pos - padding;
/* determine amount of padding */
last_padding_pos = blob->ptr + blob->len - 1;
padding = *last_padding_pos;
first_padding_pos = (padding > blob->len)?
blob->ptr : last_padding_pos - padding;
/* check the padding pattern */
while (--last_padding_pos > first_padding_pos)
{
if (*last_padding_pos != padding)
return FALSE;
}
/* check the padding pattern */
while (--last_padding_pos > first_padding_pos)
{
if (*last_padding_pos != padding)
return FALSE;
}
/* remove padding */
blob->len -= padding;
return TRUE;
/* remove padding */
blob->len -= padding;
return TRUE;
}
/*
@ -241,74 +241,74 @@ pem_decrypt_3des(chunk_t *blob, chunk_t *iv, const char *passphrase)
static err_t
pem_decrypt(chunk_t *blob, chunk_t *iv, prompt_pass_t *pass, const char* label)
{
DBG(DBG_CRYPT,
DBG_log(" decrypting file using 'DES-EDE3-CBC'");
)
if (iv->len != DES_CBC_BLOCK_SIZE)
return "size of DES-EDE3-CBC IV is not 8 bytes";
DBG(DBG_CRYPT,
DBG_log(" decrypting file using 'DES-EDE3-CBC'");
)
if (iv->len != DES_CBC_BLOCK_SIZE)
return "size of DES-EDE3-CBC IV is not 8 bytes";
if (pass == NULL)
return "no passphrase available";
if (pass == NULL)
return "no passphrase available";
/* do we prompt for the passphrase? */
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++)
/* do we prompt for the passphrase? */
if (pass->prompt && pass->fd != NULL_FD)
{
int n;
int i;
chunk_t blob_copy;
err_t ugh = "invalid passphrase, too many trials";
if (i > 0)
whack_log(RC_ENTERSECRET, "invalid passphrase, please try again");
whack_log(RC_ENTERSECRET, "need passphrase for '%s'", label);
n = read(pass->fd, pass->secret, PROMPT_PASS_LEN);
for (i = 0; i < MAX_PROMPT_PASS_TRIALS; i++)
{
int n;
if (n == -1)
{
err_t ugh = "read(whackfd) failed";
if (i > 0)
whack_log(RC_ENTERSECRET, "invalid passphrase, please try again");
whack_log(RC_LOG_SERIOUS,ugh);
return ugh;
}
n = read(pass->fd, pass->secret, PROMPT_PASS_LEN);
pass->secret[n-1] = '\0';
if (strlen(pass->secret) == 0)
{
err_t ugh = "no passphrase entered, aborted";
if (n == -1)
{
err_t ugh = "read(whackfd) failed";
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);
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
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
@ -319,144 +319,144 @@ pem_decrypt(chunk_t *blob, chunk_t *iv, prompt_pass_t *pass, const char* label)
err_t
pemtobin(chunk_t *blob, prompt_pass_t *pass, const char* label, bool *pgp)
{
typedef enum {
PEM_PRE = 0,
PEM_MSG = 1,
PEM_HEADER = 2,
PEM_BODY = 3,
PEM_POST = 4,
PEM_ABORT = 5
} state_t;
typedef enum {
PEM_PRE = 0,
PEM_MSG = 1,
PEM_HEADER = 2,
PEM_BODY = 3,
PEM_POST = 4,
PEM_ABORT = 5
} state_t;
bool encrypted = FALSE;
bool encrypted = FALSE;
state_t state = PEM_PRE;
state_t state = PEM_PRE;
chunk_t src = *blob;
chunk_t dst = *blob;
chunk_t line = chunk_empty;
chunk_t iv = chunk_empty;
chunk_t src = *blob;
chunk_t dst = *blob;
chunk_t line = 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 */
dst.len = 0;
/* zero size of converted blob */
dst.len = 0;
/* zero size of IV */
iv.ptr = iv_buf;
iv.len = 0;
/* zero size of IV */
iv.ptr = iv_buf;
iv.len = 0;
while (fetchline(&src, &line))
{
if (state == PEM_PRE)
while (fetchline(&src, &line))
{
if (find_boundary("BEGIN", &line))
{
*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)
if (state == PEM_PRE)
{
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;
if (find_boundary("BEGIN", &line))
{
*pgp = FALSE;
state = PEM_MSG;
}
continue;
}
else
{
dst.ptr += len;
dst.len += len;
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;
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 */
blob->len = dst.len;
/* set length to size of binary blob */
blob->len = dst.len;
if (state != PEM_POST)
return "file coded in unknown format, discarded";
if (state != PEM_POST)
return "file coded in unknown format, discarded";
if (encrypted)
return pem_decrypt(blob, &iv, pass, label);
else
return NULL;
if (encrypted)
return pem_decrypt(blob, &iv, pass, label);
else
return NULL;
}

View File

@ -15,4 +15,4 @@
*/
extern err_t pemtobin(chunk_t *blob, prompt_pass_t *pass, const char* label
, bool *pgp);
, bool *pgp);

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,7 @@
/*
* 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];
@ -30,16 +30,16 @@ typedef char fingerprint_t[PGP_FINGERPRINT_SIZE];
typedef struct pgpcert pgpcert_t;
struct pgpcert {
pgpcert_t *next;
time_t installed;
int count;
chunk_t certificate;
time_t created;
time_t until;
pgpcert_t *next;
time_t installed;
int count;
chunk_t certificate;
time_t created;
time_t until;
enum pubkey_alg pubkeyAlg;
chunk_t modulus;
chunk_t publicExponent;
fingerprint_t fingerprint;
chunk_t modulus;
chunk_t publicExponent;
fingerprint_t fingerprint;
};
extern const pgpcert_t empty_pgpcert;

File diff suppressed because it is too large Load Diff

View File

@ -27,39 +27,39 @@ typedef struct RSA_public_key RSA_public_key_t;
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] */
unsigned k;
/* length of modulus n in octets: [RSA_MIN_OCTETS, RSA_MAX_OCTETS] */
unsigned k;
/* public: */
MP_INT
n, /* modulus: p * q */
e; /* exponent: relatively prime to (p-1) * (q-1) [probably small] */
/* public: */
MP_INT
n, /* modulus: p * q */
e; /* exponent: relatively prime to (p-1) * (q-1) [probably small] */
};
typedef struct RSA_private_key RSA_private_key_t;
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
d, /* private exponent: (e^-1) mod ((p-1) * (q-1)) */
/* help for Chinese Remainder Theorem speedup: */
p, /* first secret prime */
q, /* second secret prime */
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) */
qInv; /* (q^-1) mod p */
MP_INT
d, /* private exponent: (e^-1) mod ((p-1) * (q-1)) */
/* help for Chinese Remainder Theorem speedup: */
p, /* first secret prime */
q, /* second secret prime */
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) */
qInv; /* (q^-1) mod p */
};
struct fld {
const char *name;
size_t offset;
const char *name;
size_t offset;
};
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 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_publicKeyInfo(const RSA_public_key_t *rsa);
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 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 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
, 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 err_t RSA_private_key_sanity(RSA_private_key_t *k);
#ifdef DEBUG

File diff suppressed because it is too large Load Diff

View File

@ -28,24 +28,24 @@
typedef struct contentInfo contentInfo_t;
struct contentInfo {
int type;
chunk_t content;
int type;
chunk_t content;
};
extern const contentInfo_t empty_contentInfo;
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
, 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
, 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_messageDigest_attribute(chunk_t content, int digest_alg);
extern chunk_t pkcs7_build_issuerAndSerialNumber(const x509cert_t *cert);
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
, int cipher);
, int cipher);
#endif /* _PKCS7_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* 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.
*
@ -44,7 +44,7 @@
#endif /* !PLUTO */
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 is_prime( MPI n, unsigned steps, int *count );
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
progress( int c )
{
fputc( c, stderr );
fputc( c, stderr );
}
@ -63,21 +63,21 @@ progress( int c )
MPI
generate_secret_prime( unsigned nbits )
{
MPI prime;
MPI prime;
prime = gen_prime( nbits, 1, 2 );
progress('\n');
return prime;
prime = gen_prime( nbits, 1, 2 );
progress('\n');
return prime;
}
MPI
generate_public_prime( unsigned nbits )
{
MPI prime;
MPI prime;
prime = gen_prime( nbits, 0, 2 );
progress('\n');
return prime;
prime = gen_prime( nbits, 0, 2 );
progress('\n');
return prime;
}
@ -88,220 +88,220 @@ generate_public_prime( unsigned nbits )
* indeed a strong prime.
*
* 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
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 m; /* number of primes in pool */
unsigned fbits; /* length of prime factors */
MPI *factors; /* current factors */
MPI *pool; /* pool of primes */
MPI q; /* first prime factor (variable)*/
MPI prime; /* prime test value */
MPI q_factor; /* used for mode 1 */
byte *perms = NULL;
int i, j;
int count1, count2;
unsigned nprime;
unsigned req_qbits = qbits; /* the requested q bits size */
MPI val_2 = mpi_alloc_set_ui( 2 );
int n; /* number of factors */
int m; /* number of primes in pool */
unsigned fbits; /* length of prime factors */
MPI *factors; /* current factors */
MPI *pool; /* pool of primes */
MPI q; /* first prime factor (variable)*/
MPI prime; /* prime test value */
MPI q_factor; /* used for mode 1 */
byte *perms = NULL;
int i, j;
int count1, count2;
unsigned nprime;
unsigned req_qbits = qbits; /* the requested q bits size */
MPI val_2 = mpi_alloc_set_ui( 2 );
/* find number of needed prime factors */
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 ) {
/* find number of needed prime factors */
for(n=1; (pbits - qbits - 1) / n >= qbits; n++ )
;
n--;
fbits = (pbits - 2*req_qbits -1) / n;
qbits = pbits - req_qbits - n*fbits;
}
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( !n || (mode==1 && n < 2) )
log_fatal("can't gen prime with pbits=%u qbits=%u\n", pbits, qbits );
if( mode == 1 ) {
i = 0;
(*ret_factors)[i++] = mpi_copy( q_factor );
for(; i <= n; i++ )
(*ret_factors)[i] = mpi_copy( factors[i] );
n--;
fbits = (pbits - 2*req_qbits -1) / n;
qbits = pbits - req_qbits - n*fbits;
}
else {
for(; i < n; i++ )
(*ret_factors)[i] = mpi_copy( factors[i] );
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;
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 ) {
/* allocate an array to hold the factors + 2 for later usage */
#ifdef PLUTO
log_mpidump("checking g: ", g);
m_alloc_ptrs_clear(factors, n+2);
#else
log_debug("checking g: ");
mpi_print( stderr, g, 1 );
factors = m_alloc_clear( (n+2) * sizeof *factors );
#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;
/* 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 ) {
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
gen_prime( unsigned nbits, int secret, int randomlevel )
{
unsigned nlimbs;
MPI prime, ptest, pminus1, val_2, val_3, result;
int i;
unsigned x, step;
unsigned count1, count2;
int *mods;
unsigned nlimbs;
MPI prime, ptest, pminus1, val_2, val_3, result;
int i;
unsigned x, step;
unsigned count1, count2;
int *mods;
if( 0 && DBG_CIPHER )
log_debug("generate a prime of %u bits ", nbits );
if( 0 && DBG_CIPHER )
log_debug("generate a prime of %u bits ", nbits );
if( !no_of_small_prime_numbers ) {
for(i=0; small_prime_numbers[i]; i++ )
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);
if( !no_of_small_prime_numbers ) {
for(i=0; small_prime_numbers[i]; i++ )
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;
/* set high order bit to 1, set low order bit to 1 */
mpi_set_highbit( prime, nbits-1 );
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;
/* generate a random number */
{ char *p = get_random_bits( nbits, randomlevel, secret );
mpi_set_buffer( prime, p, (nbits+7)/8, 0 );
m_free(p);
}
}
if( ++dotcount == 10 ) {
progress('.');
dotcount = 0;
}
/* set high order bit to 1, set low order bit to 1 */
mpi_set_highbit( prime, nbits-1 );
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
check_prime( MPI prime, MPI val_2 )
{
int i;
unsigned x;
int count=0;
int i;
unsigned x;
int count=0;
/* check against small primes */
for(i=0; (x = small_prime_numbers[i]); i++ ) {
if( mpi_divisible_ui( prime, x ) )
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;
/* check against small primes */
for(i=0; (x = small_prime_numbers[i]); i++ ) {
if( mpi_divisible_ui( prime, x ) )
return 0;
}
mpi_free( result );
}
/* perform stronger tests */
if( is_prime(prime, 5, &count ) )
return 1; /* is probably a prime */
progress('.');
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 */
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
is_prime( MPI n, unsigned steps, int *count )
{
MPI x = mpi_alloc( mpi_get_nlimbs( n ) );
MPI y = mpi_alloc( mpi_get_nlimbs( n ) );
MPI z = mpi_alloc( mpi_get_nlimbs( n ) );
MPI nminus1 = mpi_alloc( mpi_get_nlimbs( n ) );
MPI a2 = mpi_alloc_set_ui( 2 );
MPI q;
unsigned i, j, k;
int rc = 0;
unsigned nbits = mpi_get_nbits( n );
MPI x = mpi_alloc( mpi_get_nlimbs( n ) );
MPI y = mpi_alloc( mpi_get_nlimbs( n ) );
MPI z = mpi_alloc( mpi_get_nlimbs( n ) );
MPI nminus1 = mpi_alloc( mpi_get_nlimbs( n ) );
MPI a2 = mpi_alloc_set_ui( 2 );
MPI q;
unsigned i, j, k;
int rc = 0;
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 */
q = mpi_copy( nminus1 );
k = mpi_trailing_zeros( q );
mpi_tdiv_q_2exp(q, q, k);
/* find q and k, so that n = 1 + 2^k * q */
q = mpi_copy( nminus1 );
k = mpi_trailing_zeros( q );
mpi_tdiv_q_2exp(q, q, k);
for(i=0 ; i < steps; i++ ) {
++*count;
if( !i ) {
mpi_set_ui( x, 2 );
for(i=0 ; i < steps; i++ ) {
++*count;
if( !i ) {
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 {
/*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 */
rc = 1; /* may be a prime */
leave:
mpi_free( x );
mpi_free( y );
mpi_free( z );
mpi_free( nminus1 );
mpi_free( q );
mpi_free( x );
mpi_free( y );
mpi_free( z );
mpi_free( nminus1 );
mpi_free( q );
return rc;
return rc;
}
static void
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 )
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;
if( !m || m >= n )
return;
}
BUG();
}
for(j=1; j < n; j++ ) {
if( array[n-1] == array[n-j-1] )
continue;
j1 = j;
break;
}
if( m & 1 ) { /* m is odd */
if( array[n-1] ) {
if( j1 & 1 ) {
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( 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;
}
BUG();
}
if( !(j1 & 1) ) {
k1 = n - j1;
k2 = k1+2;
if( k2 > n )
k2 = n;
goto leave;
for(j=1; j < n; j++ ) {
if( array[n-1] == array[n-j-1] )
continue;
j1 = j;
break;
}
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;
if( m & 1 ) { /* m is odd */
if( array[n-1] ) {
if( j1 & 1 ) {
k1 = n - j1;
k2 = k1+2;
if( k2 > n )
k2 = n;
goto leave;
}
goto scan;
}
else {
k1 = i1 - 1;
k2 = n + 1 - j1;
k2 = n - j1 - 1;
if( k2 == 0 ) {
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:
array[k1-1] = !array[k1-1];
array[k2-1] = !array[k2-1];
array[k1-1] = !array[k1-1];
array[k2-1] = !array[k2-1];
}

File diff suppressed because it is too large Load Diff

View File

@ -68,7 +68,7 @@
#include "timer.h"
#ifdef linux
# define USE_DEV_RANDOM 1
# define USE_DEV_RANDOM 1
# define RANDOM_PATH DEV_URANDOM
#else
# ifdef __OpenBSD__
@ -82,7 +82,7 @@
#define get_rnd_byte() (arc4random() % 256)
#else /**** start of large #else ****/
#else /**** start of large #else ****/
#ifdef USE_DEV_RANDOM
static int random_fd = NULL_FD;
@ -97,12 +97,12 @@ static u_char random_pool[RANDOM_POOL_SIZE];
static u_char
generate_rnd_byte(void)
{
u_char c;
u_char c;
if (read(random_fd, &c, sizeof(c)) == -1)
exit_log_errno((e, "read() failed in get_rnd_byte()"));
if (read(random_fd, &c, sizeof(c)) == -1)
exit_log_errno((e, "read() failed in get_rnd_byte()"));
return c;
return c;
}
#else /* !USE_DEV_RANDOM */
@ -121,52 +121,52 @@ static volatile sig_atomic_t i, j, k;
static void
rnd_handler(int ignore_me UNUSED)
{
k <<= 1; /* Shift left by 1 */
j++;
k |= (i & 0x1); /* Get lsbit of counter */
k <<= 1; /* Shift left by 1 */
j++;
k |= (i & 0x1); /* Get lsbit of counter */
if (j != 8)
signal(SIGVTALRM, rnd_handler);
if (j != 8)
signal(SIGVTALRM, rnd_handler);
}
static u_char
generate_rnd_byte(void)
{
struct itimerval tmval, ntmval;
struct itimerval tmval, ntmval;
# ifdef NEVER /* ??? */
# ifdef NEVER /* ??? */
# ifdef linux
int mask = siggetmask();
int mask = siggetmask();
mask |= SIGVTALRM;
sigsetmask(mask);
mask |= SIGVTALRM;
sigsetmask(mask);
# endif
# endif
i = 0;
j = 0;
i = 0;
j = 0;
ntmval.it_interval.tv_sec = 0;
ntmval.it_interval.tv_usec = 1;
ntmval.it_value.tv_sec = 0;
ntmval.it_value.tv_usec = 1;
signal(SIGVTALRM, rnd_handler);
setitimer(ITIMER_VIRTUAL, &ntmval, &tmval);
ntmval.it_interval.tv_sec = 0;
ntmval.it_interval.tv_usec = 1;
ntmval.it_value.tv_sec = 0;
ntmval.it_value.tv_usec = 1;
signal(SIGVTALRM, rnd_handler);
setitimer(ITIMER_VIRTUAL, &ntmval, &tmval);
while (j != 8)
i++;
while (j != 8)
i++;
setitimer(ITIMER_VIRTUAL, &tmval, &ntmval);
signal(SIGVTALRM, SIG_IGN);
setitimer(ITIMER_VIRTUAL, &tmval, &ntmval);
signal(SIGVTALRM, SIG_IGN);
# ifdef NEVER /* ??? */
# ifdef NEVER /* ??? */
# ifdef linux
mask ^= SIGVTALRM;
sigsetmask(mask);
mask ^= SIGVTALRM;
sigsetmask(mask);
# endif
# endif
return k;
return k;
}
#endif /* !USE_DEV_RANDOM */
@ -174,11 +174,11 @@ generate_rnd_byte(void)
static void
mix_pool(void)
{
SHA1_CTX ctx;
SHA1_CTX ctx;
SHA1Init(&ctx);
SHA1Update(&ctx, random_pool, RANDOM_POOL_SIZE);
SHA1Final(random_pool, &ctx);
SHA1Init(&ctx);
SHA1Update(&ctx, random_pool, RANDOM_POOL_SIZE);
SHA1Final(random_pool, &ctx);
}
/*
@ -187,21 +187,21 @@ mix_pool(void)
static u_char
get_rnd_byte(void)
{
random_pool[RANDOM_POOL_SIZE - 1] = generate_rnd_byte();
random_pool[0] = generate_rnd_byte();
mix_pool();
return random_pool[0];
random_pool[RANDOM_POOL_SIZE - 1] = generate_rnd_byte();
random_pool[0] = generate_rnd_byte();
mix_pool();
return random_pool[0];
}
#endif /* !USE_ARC4RANDOM */ /**** end of large #else ****/
#endif /* !USE_ARC4RANDOM */ /**** end of large #else ****/
void
get_rnd_bytes(u_char *buffer, int length)
{
int i;
int i;
for (i = 0; i < length; i++)
buffer[i] = get_rnd_byte();
for (i = 0; i < length; i++)
buffer[i] = get_rnd_byte();
}
/*
@ -212,24 +212,24 @@ init_rnd_pool(void)
{
#ifndef USE_ARC4RANDOM
# ifdef USE_DEV_RANDOM
DBG(DBG_KLIPS, DBG_log("opening %s", RANDOM_PATH));
random_fd = open(RANDOM_PATH, O_RDONLY);
if (random_fd == -1)
exit_log_errno((e, "open of %s failed in init_rnd_pool()", RANDOM_PATH));
fcntl(random_fd, F_SETFD, FD_CLOEXEC);
DBG(DBG_KLIPS, DBG_log("opening %s", RANDOM_PATH));
random_fd = open(RANDOM_PATH, O_RDONLY);
if (random_fd == -1)
exit_log_errno((e, "open of %s failed in init_rnd_pool()", RANDOM_PATH));
fcntl(random_fd, F_SETFD, FD_CLOEXEC);
# endif
get_rnd_bytes(random_pool, RANDOM_POOL_SIZE);
mix_pool();
get_rnd_bytes(random_pool, RANDOM_POOL_SIZE);
mix_pool();
#endif /* !USE_ARC4RANDOM */
/* start of rand(3) on the right foot */
{
unsigned int seed;
/* start of rand(3) on the right foot */
{
unsigned int seed;
get_rnd_bytes((void *)&seed, sizeof(seed));
srand(seed);
}
get_rnd_bytes((void *)&seed, sizeof(seed));
srand(seed);
}
}
u_char secret_of_the_day[SHA1_DIGEST_SIZE];
@ -239,12 +239,12 @@ u_char secret_of_the_day[SHA1_DIGEST_SIZE];
void
init_secret(void)
{
/*
* Generate the secret value for responder cookies, and
* schedule an event for refresh.
*/
get_rnd_bytes(secret_of_the_day, sizeof(secret_of_the_day));
event_schedule(EVENT_REINIT_SECRET, EVENT_REINIT_SECRET_DELAY, NULL);
/*
* Generate the secret value for responder cookies, and
* schedule an event for refresh.
*/
get_rnd_bytes(secret_of_the_day, sizeof(secret_of_the_day));
event_schedule(EVENT_REINIT_SECRET, EVENT_REINIT_SECRET_DELAY, NULL);
}
#endif /* NO_PLUTO */

File diff suppressed because it is too large Load Diff

View File

@ -14,16 +14,16 @@
* RCSID $Id$
*/
extern int ctl_fd; /* file descriptor of control (whack) socket */
extern struct sockaddr_un ctl_addr; /* address 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 int info_fd; /* file descriptor of control (info) socket */
extern struct sockaddr_un info_addr; /* address 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 err_t init_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
@ -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.
*/
struct iface {
char *vname; /* virtual (ipsec) device name */
char *rname; /* real device name */
ip_address addr; /* interface IP address */
int fd; /* file descriptor of socket for IKE UDP messages */
struct iface *next;
bool ike_float;
enum { IFN_ADD, IFN_KEEP, IFN_DELETE } change;
char *vname; /* virtual (ipsec) device name */
char *rname; /* real device name */
ip_address addr; /* interface IP address */
int fd; /* file descriptor of socket for IKE UDP messages */
struct iface *next;
bool ike_float;
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 void find_ifaces(void);

View File

@ -18,7 +18,7 @@ A million repetitions of "a"
#define SHA1HANDSOFF
#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 "sha1.h"
@ -29,14 +29,14 @@ A million repetitions of "a"
/* I got the idea of expanding during the round function from SSLeay */
#if BYTE_ORDER == LITTLE_ENDIAN
#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
#define blk0(i) block->l[i]
#else
#error "Endianness not defined!"
#endif
#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 */
#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;
typedef union {
unsigned char c[64];
u_int32_t l[16];
unsigned char c[64];
u_int32_t l[16];
} CHAR64LONG16;
#ifdef SHA1HANDSOFF
CHAR64LONG16 block[1]; /* use array to appear as a pointer */
memcpy(block, buffer, 64);
memcpy(block, buffer, 64);
#else
/* The following had better never be used because it causes the
* 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
* this will cause a diagnostic.
*/
/* The following had better never be used because it causes the
* 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
* this will cause a diagnostic.
*/
CHAR64LONG16* block = (const CHAR64LONG16*)buffer;
#endif
/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
/* 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(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(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);
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(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(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(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(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);
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(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(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[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
/* Wipe variables */
a = b = c = d = e = 0;
/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
/* 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(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(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);
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(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(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(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(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);
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(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(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[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
/* Wipe variables */
a = b = c = d = e = 0;
#ifdef SHA1HANDSOFF
memset(block, '\0', sizeof(block));
memset(block, '\0', sizeof(block));
#endif
}
@ -111,13 +111,13 @@ CHAR64LONG16* block = (const CHAR64LONG16*)buffer;
void SHA1Init(SHA1_CTX* context)
{
/* SHA1 initialization constants */
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;
context->count[0] = context->count[1] = 0;
/* SHA1 initialization constants */
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;
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 j;
j = context->count[0];
if ((context->count[0] += len << 3) < j)
context->count[1]++;
context->count[1] += (len>>29);
j = (j >> 3) & 63;
if ((j + len) > 63) {
memcpy(&context->buffer[j], data, (i = 64-j));
SHA1Transform(context->state, context->buffer);
for ( ; i + 63 < len; i += 64) {
SHA1Transform(context->state, &data[i]);
}
j = 0;
}
else i = 0;
memcpy(&context->buffer[j], &data[i], len - i);
j = context->count[0];
if ((context->count[0] += len << 3) < j)
context->count[1]++;
context->count[1] += (len>>29);
j = (j >> 3) & 63;
if ((j + len) > 63) {
memcpy(&context->buffer[j], data, (i = 64-j));
SHA1Transform(context->state, context->buffer);
for ( ; i + 63 < len; i += 64) {
SHA1Transform(context->state, &data[i]);
}
j = 0;
}
else i = 0;
memcpy(&context->buffer[j], &data[i], len - i);
}
@ -154,40 +154,40 @@ unsigned i;
unsigned char finalcount[8];
unsigned char c;
#if 0 /* untested "improvement" by DHR */
/* Convert context->count to a sequence of bytes
* in finalcount. Second element first, but
* big-endian order within element.
* But we do it all backwards.
*/
unsigned char *fcp = &finalcount[8];
#if 0 /* untested "improvement" by DHR */
/* Convert context->count to a sequence of bytes
* in finalcount. Second element first, but
* big-endian order within element.
* But we do it all backwards.
*/
unsigned char *fcp = &finalcount[8];
for (i = 0; i < 2; i++)
{
u_int32_t t = context->count[i];
int j;
for (i = 0; i < 2; i++)
{
u_int32_t t = context->count[i];
int j;
for (j = 0; j < 4; t >>= 8, j++)
*--fcp = (unsigned char) t
}
for (j = 0; j < 4; t >>= 8, j++)
*--fcp = (unsigned char) t
}
#else
for (i = 0; i < 8; i++) {
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
}
for (i = 0; i < 8; i++) {
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
}
#endif
c = 0200;
SHA1Update(context, &c, 1);
while ((context->count[0] & 504) != 448) {
c = 0000;
SHA1Update(context, &c, 1);
}
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
for (i = 0; i < 20; i++) {
digest[i] = (unsigned char)
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
}
/* Wipe variables */
memset(context, '\0', sizeof(*context));
memset(&finalcount, '\0', sizeof(finalcount));
c = 0200;
SHA1Update(context, &c, 1);
while ((context->count[0] & 504) != 448) {
c = 0000;
SHA1Update(context, &c, 1);
}
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
for (i = 0; i < 20; i++) {
digest[i] = (unsigned char)
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
}
/* Wipe variables */
memset(context, '\0', sizeof(*context));
memset(&finalcount, '\0', sizeof(finalcount));
}

View File

@ -5,9 +5,9 @@ By Steve Reid <steve@edmweb.com>
*/
typedef struct {
u_int32_t state[5];
u_int32_t count[2];
unsigned char buffer[64];
u_int32_t state[5];
u_int32_t count[2];
unsigned char buffer[64];
} SHA1_CTX;
void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64]);

View File

@ -1,5 +1,5 @@
/* 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.
*
@ -37,86 +37,86 @@
*/
ushort
small_prime_numbers[] = {
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,
103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
331, 337, 347, 349, 353, 359, 367, 373, 379, 383,
389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
509, 521, 523, 541, 547, 557, 563, 569, 571, 577,
587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
709, 719, 727, 733, 739, 743, 751, 757, 761, 769,
773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091,
1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277,
1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307,
1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609,
1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667,
1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,
1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931,
1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997,
1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111,
2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161,
2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243,
2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411,
2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473,
2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633,
2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729,
2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791,
2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851,
2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917,
2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061,
3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137,
3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209,
3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391,
3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467,
3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533,
3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583,
3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709,
3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779,
3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917,
3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049,
4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111,
4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177,
4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243,
4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391,
4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457,
4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519,
4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597,
4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799,
4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951,
4957, 4967, 4969, 4973, 4987, 4993, 4999,
0
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,
103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
331, 337, 347, 349, 353, 359, 367, 373, 379, 383,
389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
509, 521, 523, 541, 547, 557, 563, 569, 571, 577,
587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
709, 719, 727, 733, 739, 743, 751, 757, 761, 769,
773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091,
1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277,
1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307,
1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609,
1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667,
1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,
1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931,
1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997,
1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111,
2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161,
2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243,
2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411,
2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473,
2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633,
2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729,
2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791,
2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851,
2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917,
2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061,
3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137,
3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209,
3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391,
3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467,
3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533,
3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583,
3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709,
3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779,
3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917,
3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049,
4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111,
4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177,
4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243,
4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391,
4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457,
4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519,
4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597,
4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799,
4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951,
4957, 4967, 4969, 4973, 4987, 4993, 4999,
0
};

File diff suppressed because it is too large Load Diff

View File

@ -21,19 +21,19 @@
#include "certs.h"
#define SCX_TOKEN "%smartcard"
#define SCX_CERT_CACHE_INTERVAL 60 /* seconds */
#define SCX_MAX_PIN_TRIALS 3
#define SCX_TOKEN "%smartcard"
#define SCX_CERT_CACHE_INTERVAL 60 /* seconds */
#define SCX_MAX_PIN_TRIALS 3
/* smartcard operations, update copy in whack.h */
#ifndef SC_OP_T
#define SC_OP_T
typedef enum {
SC_OP_NONE = 0,
SC_OP_ENCRYPT = 1,
SC_OP_DECRYPT = 2,
SC_OP_SIGN = 3,
SC_OP_NONE = 0,
SC_OP_ENCRYPT = 1,
SC_OP_DECRYPT = 2,
SC_OP_SIGN = 3,
} sc_op_t;
#endif /* SC_OP_T */
@ -42,21 +42,21 @@ typedef enum {
typedef struct smartcard smartcard_t;
struct smartcard {
smartcard_t *next;
time_t last_load;
cert_t last_cert;
int count;
int number;
unsigned long slot;
char *id;
char *label;
chunk_t pin;
bool pinpad;
bool valid;
bool session_opened;
bool logged_in;
bool any_slot;
long session;
smartcard_t *next;
time_t last_load;
cert_t last_cert;
int count;
int number;
unsigned long slot;
char *id;
char *label;
chunk_t pin;
bool pinpad;
bool valid;
bool session_opened;
bool logged_in;
bool any_slot;
long session;
};
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_on_smartcard(const char *filename);
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 void scx_share(smartcard_t *sc);
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
, 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
, 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
, 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 size_t scx_get_keylength(smartcard_t *sc);
extern smartcard_t* scx_add(smartcard_t *sc);

File diff suppressed because it is too large Load Diff

View File

@ -25,39 +25,39 @@
* Note: only "basic" values are represented so far.
*/
struct db_attr {
u_int16_t type; /* ISAKMP_ATTR_AF_TV is implied; 0 for end */
u_int16_t val;
u_int16_t type; /* ISAKMP_ATTR_AF_TV is implied; 0 for end */
u_int16_t val;
};
/* transform */
struct db_trans {
u_int8_t transid; /* Transform-Id */
struct db_attr *attrs; /* array */
int attr_cnt; /* number of elements */
u_int8_t transid; /* Transform-Id */
struct db_attr *attrs; /* array */
int attr_cnt; /* number of elements */
};
/* proposal */
struct db_prop {
u_int8_t protoid; /* Protocol-Id */
struct db_trans *trans; /* array (disjunction) */
int trans_cnt; /* number of elements */
/* SPI size and value isn't part of DB */
u_int8_t protoid; /* Protocol-Id */
struct db_trans *trans; /* array (disjunction) */
int trans_cnt; /* number of elements */
/* SPI size and value isn't part of DB */
};
/* conjunction of proposals */
struct db_prop_conj {
struct db_prop *props; /* array */
int prop_cnt; /* number of elements */
struct db_prop *props; /* array */
int prop_cnt; /* number of elements */
};
/* security association */
struct db_sa {
struct db_prop_conj *prop_conjs; /* array */
int prop_conj_cnt; /* number of elements */
/* Hardwired for now;
* DOI: ISAKMP_DOI_IPSEC
* Situation: SIT_IDENTITY_ONLY
*/
struct db_prop_conj *prop_conjs; /* array */
int prop_conj_cnt; /* number of elements */
/* Hardwired for now;
* DOI: ISAKMP_DOI_IPSEC
* Situation: SIT_IDENTITY_ONLY
*/
};
/* The oakley sadb */
@ -72,38 +72,38 @@ extern struct db_sa ipsec_sadb[1 << 3];
struct state;
extern bool out_sa(
pb_stream *outs,
struct db_sa *sadb,
struct state *st,
bool oakley_mode,
u_int8_t np);
pb_stream *outs,
struct db_sa *sadb,
struct state *st,
bool oakley_mode,
u_int8_t np);
extern notification_t preparse_isakmp_sa_body(
const struct isakmp_sa *sa, /* header of input SA Payload */
pb_stream *sa_pbs, /* body of input SA Payload */
u_int32_t *ipsecdoisit, /* IPsec DOI SIT bitset */
pb_stream *proposal_pbs, /* body of proposal Payload */
struct isakmp_proposal *proposal);
const struct isakmp_sa *sa, /* header of input SA Payload */
pb_stream *sa_pbs, /* body of input SA Payload */
u_int32_t *ipsecdoisit, /* IPsec DOI SIT bitset */
pb_stream *proposal_pbs, /* body of proposal Payload */
struct isakmp_proposal *proposal);
extern notification_t parse_isakmp_policy(
pb_stream *proposal_pbs, /* body of proposal Payload */
u_int notrans, /* number of transforms */
lset_t *policy); /* RSA, PSK or XAUTH policy */
pb_stream *proposal_pbs, /* body of proposal Payload */
u_int notrans, /* number of transforms */
lset_t *policy); /* RSA, PSK or XAUTH policy */
extern notification_t parse_isakmp_sa_body(
u_int32_t ipsecdoisit, /* IPsec DOI SIT bitset */
pb_stream *proposal_pbs, /* body of proposal Payload */
struct isakmp_proposal *proposal,
pb_stream *r_sa_pbs, /* if non-NULL, where to emit winning SA */
struct state *st, /* current state object */
bool initiator); /* is caller initiator? */
u_int32_t ipsecdoisit, /* IPsec DOI SIT bitset */
pb_stream *proposal_pbs, /* body of proposal Payload */
struct isakmp_proposal *proposal,
pb_stream *r_sa_pbs, /* if non-NULL, where to emit winning SA */
struct state *st, /* current state object */
bool initiator); /* is caller initiator? */
extern notification_t parse_ipsec_sa_body(
pb_stream *sa_pbs, /* body 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 */
bool selection, /* if this SA is a selection, only one tranform can appear */
struct state *st); /* current state object */
pb_stream *sa_pbs, /* body 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 */
bool selection, /* if this SA is a selection, only one tranform can appear */
struct state *st); /* current state object */
extern void backup_pbs(pb_stream *pbs);
extern void restore_pbs(pb_stream *pbs);

File diff suppressed because it is too large Load Diff

View File

@ -40,10 +40,10 @@
* 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)
struct state; /* forward declaration of tag */
struct state; /* forward declaration of tag */
extern bool reserve_msgid(struct state *isakmp_sa, msgid_t msgid);
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.
*/
struct oakley_trans_attrs {
u_int16_t encrypt; /* Encryption algorithm */
u_int16_t enckeylen; /* encryption key len (bits) */
const struct encrypt_desc *encrypter; /* package of encryption routines */
u_int16_t hash; /* Hash algorithm */
const struct hash_desc *hasher; /* package of hashing routines */
u_int16_t auth; /* Authentication method */
const struct oakley_group_desc *group; /* Oakley group */
time_t life_seconds; /* When this SA expires (seconds) */
u_int32_t life_kilobytes; /* When this SA is exhausted (kilobytes) */
u_int16_t encrypt; /* Encryption algorithm */
u_int16_t enckeylen; /* encryption key len (bits) */
const struct encrypt_desc *encrypter; /* package of encryption routines */
u_int16_t hash; /* Hash algorithm */
const struct hash_desc *hasher; /* package of hashing routines */
u_int16_t auth; /* Authentication method */
const struct oakley_group_desc *group; /* Oakley group */
time_t life_seconds; /* When this SA expires (seconds) */
u_int32_t life_kilobytes; /* When this SA is exhausted (kilobytes) */
#if 0 /* not yet */
u_int16_t prf; /* Pseudo Random Function */
u_int16_t prf; /* Pseudo Random Function */
#endif
};
@ -74,28 +74,28 @@ struct oakley_trans_attrs {
* for ESP, and a funny one for IPCOMP.
*/
struct ipsec_trans_attrs {
u_int8_t transid; /* transform id */
ipsec_spi_t spi; /* his SPI */
time_t life_seconds; /* When this SA expires */
u_int32_t life_kilobytes; /* When this SA expires */
u_int16_t encapsulation;
u_int16_t auth;
u_int16_t key_len;
u_int16_t key_rounds;
u_int8_t transid; /* transform id */
ipsec_spi_t spi; /* his SPI */
time_t life_seconds; /* When this SA expires */
u_int32_t life_kilobytes; /* When this SA expires */
u_int16_t encapsulation;
u_int16_t auth;
u_int16_t key_len;
u_int16_t key_rounds;
#if 0 /* not implemented yet */
u_int16_t cmprs_dict_sz;
u_int32_t cmprs_alg;
u_int16_t cmprs_dict_sz;
u_int32_t cmprs_alg;
#endif
};
/* IPsec per protocol state information */
struct ipsec_proto_info {
bool present; /* was this transform specified? */
struct ipsec_trans_attrs attrs;
ipsec_spi_t our_spi;
u_int16_t keymat_len; /* same for both */
u_char *our_keymat;
u_char *peer_keymat;
bool present; /* was this transform specified? */
struct ipsec_trans_attrs attrs;
ipsec_spi_t our_spi;
u_int16_t keymat_len; /* same for both */
u_char *our_keymat;
u_char *peer_keymat;
};
/* state object: record the state of a (possibly nascent) SA
@ -107,135 +107,135 @@ struct ipsec_proto_info {
*/
struct state
{
so_serial_t st_serialno; /* serial number (for seniority) */
so_serial_t st_clonedfrom; /* serial number of parent */
so_serial_t st_serialno; /* serial number (for seniority) */
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.
* Single copy: close when freeing struct.
*/
int st_whack_sock; /* fd for our Whack TCP socket.
* 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_esp;
struct ipsec_proto_info st_ipcomp;
struct ipsec_proto_info st_ah;
struct ipsec_proto_info st_esp;
struct ipsec_proto_info st_ipcomp;
#ifdef KLIPS
ipsec_spi_t st_tunnel_in_spi; /* KLUDGE */
ipsec_spi_t st_tunnel_out_spi; /* KLUDGE */
ipsec_spi_t st_tunnel_in_spi; /* KLUDGE */
ipsec_spi_t st_tunnel_out_spi; /* KLUDGE */
#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_situation;
u_int32_t st_doi; /* Domain of Interpretation */
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 */
struct msgid_list *st_used_msgids; /* used-up msgids */
/* only for a state representing an ISAKMP SA */
struct msgid_list *st_used_msgids; /* used-up msgids */
/* symmetric stuff */
/* initiator stuff */
chunk_t st_gi; /* Initiator public value */
u_int8_t st_icookie[COOKIE_SIZE];/* Initiator Cookie */
chunk_t st_ni; /* Ni nonce */
chunk_t st_gi; /* Initiator public value */
u_int8_t st_icookie[COOKIE_SIZE];/* Initiator Cookie */
chunk_t st_ni; /* Ni nonce */
/* responder stuff */
chunk_t st_gr; /* Responder public value */
u_int8_t st_rcookie[COOKIE_SIZE];/* Responder Cookie */
chunk_t st_nr; /* Nr nonce */
chunk_t st_gr; /* Responder public value */
u_int8_t st_rcookie[COOKIE_SIZE];/* Responder Cookie */
chunk_t st_nr; /* Nr nonce */
/* my stuff */
chunk_t st_tpacket; /* Transmitted packet */
chunk_t st_tpacket; /* Transmitted packet */
/* Phase 2 ID payload info about my user */
u_int8_t st_myuserprotoid; /* IDcx.protoid */
u_int16_t st_myuserport;
/* Phase 2 ID payload info about my user */
u_int8_t st_myuserprotoid; /* IDcx.protoid */
u_int16_t st_myuserport;
/* his stuff */
chunk_t st_rpacket; /* Received packet */
chunk_t st_rpacket; /* Received packet */
/* Phase 2 ID payload info about peer's user */
u_int8_t st_peeruserprotoid; /* IDcx.protoid */
u_int16_t st_peeruserport;
/* Phase 2 ID payload info about peer's user */
u_int8_t st_peeruserprotoid; /* IDcx.protoid */
u_int16_t st_peeruserport;
/* end of symmetric stuff */
u_int8_t st_sec_in_use; /* bool: does st_sec hold a value */
MP_INT st_sec; /* Our local secret value */
u_int8_t st_sec_in_use; /* bool: does st_sec hold a value */
MP_INT st_sec; /* Our local secret value */
chunk_t st_shared; /* Derived shared secret
* Note: during Quick Mode,
* presence indicates PFS
* selected.
*/
chunk_t st_shared; /* Derived shared secret
* Note: during Quick Mode,
* presence indicates PFS
* selected.
*/
/* In a Phase 1 state, preserve peer's public key after authentication */
struct pubkey *st_peer_pubkey;
/* In a Phase 1 state, preserve peer's public key after authentication */
struct pubkey *st_peer_pubkey;
enum state_kind st_state; /* State of exchange */
u_int8_t st_retransmit; /* Number of retransmits */
unsigned long st_try; /* number of times rekeying attempted */
/* 0 means the only time */
time_t st_margin; /* life after EVENT_SA_REPLACE */
unsigned long st_outbound_count; /* traffic through eroute */
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_skeyid; /* Key material */
chunk_t st_skeyid_d; /* KM for non-ISAKMP key derivation */
chunk_t st_skeyid_a; /* KM for ISAKMP authentication */
chunk_t st_skeyid_e; /* KM for ISAKMP encryption */
u_char st_iv[MAX_DIGEST_LEN]; /* IV for encryption */
u_char st_new_iv[MAX_DIGEST_LEN];
u_char st_ph1_iv[MAX_DIGEST_LEN]; /* IV at end if phase 1 */
unsigned int st_iv_len;
unsigned int st_new_iv_len;
unsigned int st_ph1_iv_len;
enum state_kind st_state; /* State of exchange */
u_int8_t st_retransmit; /* Number of retransmits */
unsigned long st_try; /* number of times rekeying attempted */
/* 0 means the only time */
time_t st_margin; /* life after EVENT_SA_REPLACE */
unsigned long st_outbound_count; /* traffic through eroute */
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_skeyid; /* Key material */
chunk_t st_skeyid_d; /* KM for non-ISAKMP key derivation */
chunk_t st_skeyid_a; /* KM for ISAKMP authentication */
chunk_t st_skeyid_e; /* KM for ISAKMP encryption */
u_char st_iv[MAX_DIGEST_LEN]; /* IV for encryption */
u_char st_new_iv[MAX_DIGEST_LEN];
u_char st_ph1_iv[MAX_DIGEST_LEN]; /* IV at end if phase 1 */
unsigned int st_iv_len;
unsigned int st_new_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 state *st_hashchain_next; /* Next in list */
struct state *st_hashchain_prev; /* Previous in list */
struct event *st_event; /* backpointer for certain events */
struct state *st_hashchain_next; /* Next in list */
struct state *st_hashchain_prev; /* Previous in list */
struct {
bool vars_set;
bool started;
} st_modecfg;
struct {
bool vars_set;
bool started;
} st_modecfg;
struct {
int attempt;
bool started;
bool status;
} st_xauth;
struct {
int attempt;
bool started;
bool status;
} st_xauth;
u_int32_t nat_traversal;
ip_address nat_oa;
u_int32_t nat_traversal;
ip_address nat_oa;
/* RFC 3706 Dead Peer Detection */
bool st_dpd; /* Peer supports DPD */
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_expectseqno; /* Next R_U_THERE_ACK to receive */
u_int32_t st_dpd_peerseqno; /* global variables */
struct event *st_dpd_event; /* backpointer for DPD events */
/* RFC 3706 Dead Peer Detection */
bool st_dpd; /* Peer supports DPD */
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_expectseqno; /* Next R_U_THERE_ACK to receive */
u_int32_t st_dpd_peerseqno; /* global variables */
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 */
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);
@ -247,27 +247,27 @@ extern void insert_state(struct state *st);
extern void unhash_state(struct state *st);
extern void release_whack(struct state *st);
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_states_by_connection(struct connection *c, bool relations);
extern struct state
*duplicate_state(struct state *st),
*find_state(const u_char *icookie
, const u_char *rcookie
, const ip_address *peer
, msgid_t msgid),
*state_with_serialno(so_serial_t sn),
*find_phase2_state_to_delete(const struct state *p1st, u_int8_t protoid
, ipsec_spi_t spi, bool *bogus),
*find_phase1_state(const struct connection *c, lset_t ok_states),
*find_sender(size_t packet_len, u_char *packet);
*duplicate_state(struct state *st),
*find_state(const u_char *icookie
, const u_char *rcookie
, const ip_address *peer
, msgid_t msgid),
*state_with_serialno(so_serial_t sn),
*find_phase2_state_to_delete(const struct state *p1st, u_int8_t protoid
, ipsec_spi_t spi, bool *bogus),
*find_phase1_state(const struct connection *c, lset_t ok_states),
*find_sender(size_t packet_len, u_char *packet);
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 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 void fmt_state(bool all, struct state *st, time_t n
, char *state_buf, size_t state_buf_len
, char *state_buf2, size_t state_buf_len2);
, char *state_buf, size_t state_buf_len
, char *state_buf2, size_t state_buf_len2);
extern void delete_states_by_peer(ip_address *peer);

View File

@ -31,7 +31,7 @@
#include "connections.h"
#include "state.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 "server.h"
#include "log.h"
@ -44,18 +44,18 @@
time_t
now(void)
{
static time_t delta = 0
, last_time = 0;
time_t n = time((time_t)NULL);
static time_t delta = 0
, last_time = 0;
time_t n = time((time_t)NULL);
passert(n != (time_t)-1);
if (last_time > n)
{
plog("time moved backwards %ld seconds", (long)(last_time - n));
delta += last_time - n;
}
last_time = n;
return n + delta;
passert(n != (time_t)-1);
if (last_time > n)
{
plog("time moved backwards %ld seconds", (long)(last_time - n));
delta += last_time - n;
}
last_time = n;
return n + delta;
}
/* This file has the event handling routines. Events are
@ -72,67 +72,67 @@ static struct event *evlist = (struct event *) NULL;
void
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_time = tm + now();
ev->ev_state = st;
ev->ev_type = type;
ev->ev_time = tm + now();
ev->ev_state = st;
/* 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
* if we need to (for example, if we receive a reply).
*/
if (st != NULL)
{
if (type == EVENT_DPD || type == EVENT_DPD_TIMEOUT)
/* 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
* if we need to (for example, if we receive a reply).
*/
if (st != NULL)
{
passert(st->st_dpd_event == NULL);
st->st_dpd_event = ev;
if (type == EVENT_DPD || type == EVENT_DPD_TIMEOUT)
{
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,
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));
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,
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 */
ev->ev_next = evt->ev_next;
evt->ev_next = ev;
}
ev->ev_next = evt->ev_next;
evt->ev_next = ev;
}
}
/*
@ -141,299 +141,299 @@ event_schedule(enum event_type type, time_t tm, struct state *st)
void
handle_timer_event(void)
{
time_t tm;
struct event *ev = evlist;
int type;
struct state *st;
struct connection *c = NULL;
ip_address peer;
time_t tm;
struct event *ev = evlist;
int type;
struct state *st;
struct connection *c = NULL;
ip_address peer;
if (ev == (struct event *) NULL) /* Just paranoid */
{
DBG(DBG_CONTROL, DBG_log("empty event list, yet we're called"));
return;
}
if (ev == (struct event *) NULL) /* Just paranoid */
{
DBG(DBG_CONTROL, DBG_log("empty event list, yet we're called"));
return;
}
type = ev->ev_type;
st = ev->ev_state;
type = ev->ev_type;
st = ev->ev_state;
tm = now();
tm = now();
if (tm < ev->ev_time)
{
DBG(DBG_CONTROL, DBG_log("called while no event expired (%lu/%lu, %s)"
, (unsigned long)tm, (unsigned long)ev->ev_time
, enum_show(&timer_event_names, type)));
if (tm < ev->ev_time)
{
DBG(DBG_CONTROL, DBG_log("called while no event expired (%lu/%lu, %s)"
, (unsigned long)tm, (unsigned long)ev->ev_time
, enum_show(&timer_event_names, type)));
/* This will happen if the most close-to-expire event was
* a retransmission or cleanup, and we received a packet
* at the same time as the event expired. Due to the processing
* order in call_server(), the packet processing will happen first,
* and the event will be removed.
/* This will happen if the most close-to-expire event was
* a retransmission or cleanup, and we received a packet
* at the same time as the event expired. Due to the processing
* order in call_server(), the packet processing will happen first,
* 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;
}
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(GLOBALS_ARE_RESET());
if (st != NULL)
{
passert(st->st_dpd_event == ev);
st->st_dpd_event = NULL;
c = st->st_connection;
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)
{
case EVENT_REINIT_SECRET:
passert(st == NULL);
DBG(DBG_CONTROL, DBG_log("event EVENT_REINIT_SECRET handled"));
init_secret();
break;
switch (type)
{
case EVENT_REINIT_SECRET:
passert(st == NULL);
DBG(DBG_CONTROL, DBG_log("event EVENT_REINIT_SECRET handled"));
init_secret();
break;
#ifdef KLIPS
case EVENT_SHUNT_SCAN:
passert(st == NULL);
scan_proc_shunts();
break;
case EVENT_SHUNT_SCAN:
passert(st == NULL);
scan_proc_shunts();
break;
#endif
case EVENT_LOG_DAILY:
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";
case EVENT_LOG_DAILY:
daily_log_event();
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.
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.
*/
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);
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;
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 */
plog("%s", story);
so_serial_t newest = IS_PHASE1(st->st_state)
? 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);
}
delete_state(st);
}
}
break;
break;
case EVENT_SA_REPLACE:
case EVENT_SA_REPLACE_IF_USED:
{
so_serial_t newest = IS_PHASE1(st->st_state)
? c->newest_isakmp_sa : c->newest_ipsec_sa;
case EVENT_SA_EXPIRE:
{
const char *satype;
so_serial_t latest;
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);
}
break;
if (IS_PHASE1(st->st_state))
{
satype = "ISAKMP";
latest = c->newest_isakmp_sa;
}
else
{
satype = "IPsec";
latest = c->newest_ipsec_sa;
}
case EVENT_SA_EXPIRE:
{
const char *satype;
so_serial_t latest;
if (st->st_serialno != latest)
{
/* 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;
if (IS_PHASE1(st->st_state))
{
satype = "ISAKMP";
latest = c->newest_isakmp_sa;
}
else
{
satype = "IPsec";
latest = c->newest_ipsec_sa;
}
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));
}
if (st->st_serialno != latest)
{
/* 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();
free(ev);
reset_cur_state();
}
/*
@ -443,28 +443,28 @@ handle_timer_event(void)
long
next_event(void)
{
time_t tm;
time_t tm;
if (evlist == (struct event *) NULL)
return -1;
if (evlist == (struct event *) NULL)
return -1;
tm = now();
tm = now();
DBG(DBG_CONTROL,
if (evlist->ev_state == NULL)
DBG_log("next event %s in %ld seconds"
, enum_show(&timer_event_names, evlist->ev_type)
, (long)evlist->ev_time - (long)tm);
DBG(DBG_CONTROL,
if (evlist->ev_state == NULL)
DBG_log("next event %s in %ld seconds"
, enum_show(&timer_event_names, evlist->ev_type)
, (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
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
return evlist->ev_time - tm;
return evlist->ev_time - tm;
}
/*
@ -473,33 +473,33 @@ next_event(void)
void
delete_event(struct state *st)
{
if (st->st_event != (struct event *) NULL)
{
struct event **ev;
for (ev = &evlist; ; ev = &(*ev)->ev_next)
if (st->st_event != (struct event *) NULL)
{
if (*ev == NULL)
{
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;
struct event **ev;
if (st->st_event->ev_type == EVENT_RETRANSMIT)
for (ev = &evlist; ; ev = &(*ev)->ev_next)
{
st->st_retransmit = 0;
}
free(st->st_event);
st->st_event = (struct event *) NULL;
if (*ev == NULL)
{
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;
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
delete_dpd_event(struct state *st)
{
if (st->st_dpd_event != (struct event *) NULL)
{
struct event **ev;
if (st->st_dpd_event != (struct event *) NULL)
{
struct event **ev;
for (ev = &evlist; ; ev = &(*ev)->ev_next)
{
if (*ev == NULL)
{
DBG(DBG_CONTROL, DBG_log("event %s to be deleted not found",
enum_show(&timer_event_names, st->st_dpd_event->ev_type)));
break;
}
if ((*ev) == st->st_dpd_event)
{
*ev = (*ev)->ev_next;
free(st->st_dpd_event);
st->st_dpd_event = (struct event *) NULL;
break;
}
}
}
for (ev = &evlist; ; ev = &(*ev)->ev_next)
{
if (*ev == NULL)
{
DBG(DBG_CONTROL, DBG_log("event %s to be deleted not found",
enum_show(&timer_event_names, st->st_dpd_event->ev_type)));
break;
}
if ((*ev) == st->st_dpd_event)
{
*ev = (*ev)->ev_next;
free(st->st_dpd_event);
st->st_dpd_event = (struct event *) NULL;
break;
}
}
}
}
/*
@ -537,16 +537,16 @@ delete_dpd_event(struct state *st)
void
free_events(void)
{
struct event *ev_tmp, *ev;
struct event *ev_tmp, *ev;
ev = evlist;
evlist = NULL;
ev = evlist;
evlist = NULL;
while (ev)
{
ev_tmp = ev;
ev = ev->ev_next;
free(ev_tmp);
}
while (ev)
{
ev_tmp = ev;
ev = ev->ev_next;
free(ev_tmp);
}
}

View File

@ -14,16 +14,16 @@
* 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
{
time_t ev_time;
int ev_type; /* Event type */
struct state *ev_state; /* Pointer to relevant state (if any) */
struct event *ev_next; /* Pointer to next event */
time_t ev_time;
int ev_type; /* Event type */
struct state *ev_state; /* Pointer to relevant state (if any) */
struct event *ev_next; /* Pointer to next event */
};
extern void event_schedule(enum event_type type, time_t tm, struct state *st);

View File

@ -88,233 +88,233 @@
#define VID_SUBSTRING (VID_SUBSTRING_DUMPHEXA | VID_SUBSTRING_DUMPASCII | VID_SUBSTRING_MATCH)
struct vid_struct {
enum known_vendorid id;
unsigned short flags;
const char *data;
const char *descr;
const char *vid;
u_int vid_len;
enum known_vendorid id;
unsigned short flags;
const char *data;
const char *descr;
const char *vid;
u_int vid_len;
};
#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) \
{ VID_##id, VID_MD5HASH, str, NULL, NULL, 0 },
{ VID_##id, VID_MD5HASH, str, NULL, NULL, 0 },
#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[] = {
/* 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,
"MS NT5 ISAKMPOAKLEY", NULL, NULL, 0 },
{ VID_MS_NT5, VID_MD5HASH | VID_SUBSTRING_DUMPHEXA,
"MS NT5 ISAKMPOAKLEY", NULL, NULL, 0 },
DEC_MD5_VID(SSH_SENTINEL, "SSH Sentinel")
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_3, "SSH Sentinel 1.3")
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, "SSH Sentinel")
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_3, "SSH Sentinel 1.3")
DEC_MD5_VID(SSH_SENTINEL_1_4, "SSH Sentinel 1.4")
DEC_MD5_VID(SSH_SENTINEL_1_4_1, "SSH Sentinel 1.4.1")
/* These ones come from SSH vendors.txt */
DEC_MD5_VID(SSH_IPSEC_1_1_0,
"Ssh Communications Security IPSEC Express version 1.1.0")
DEC_MD5_VID(SSH_IPSEC_1_1_1,
"Ssh Communications Security IPSEC Express version 1.1.1")
DEC_MD5_VID(SSH_IPSEC_1_1_2,
"Ssh Communications Security IPSEC Express version 1.1.2")
DEC_MD5_VID(SSH_IPSEC_1_2_1,
"Ssh Communications Security IPSEC Express version 1.2.1")
DEC_MD5_VID(SSH_IPSEC_1_2_2,
"Ssh Communications Security IPSEC Express version 1.2.2")
DEC_MD5_VID(SSH_IPSEC_2_0_0,
"SSH Communications Security IPSEC Express version 2.0.0")
DEC_MD5_VID(SSH_IPSEC_2_1_0,
"SSH Communications Security IPSEC Express version 2.1.0")
DEC_MD5_VID(SSH_IPSEC_2_1_1,
"SSH Communications Security IPSEC Express version 2.1.1")
DEC_MD5_VID(SSH_IPSEC_2_1_2,
"SSH Communications Security IPSEC Express version 2.1.2")
DEC_MD5_VID(SSH_IPSEC_3_0_0,
"SSH Communications Security IPSEC Express version 3.0.0")
DEC_MD5_VID(SSH_IPSEC_3_0_1,
"SSH Communications Security IPSEC Express version 3.0.1")
DEC_MD5_VID(SSH_IPSEC_4_0_0,
"SSH Communications Security IPSEC Express version 4.0.0")
DEC_MD5_VID(SSH_IPSEC_4_0_1,
"SSH Communications Security IPSEC Express version 4.0.1")
DEC_MD5_VID(SSH_IPSEC_4_1_0,
"SSH Communications Security IPSEC Express version 4.1.0")
DEC_MD5_VID(SSH_IPSEC_4_2_0,
"SSH Communications Security IPSEC Express version 4.2.0")
/* These ones come from SSH vendors.txt */
DEC_MD5_VID(SSH_IPSEC_1_1_0,
"Ssh Communications Security IPSEC Express version 1.1.0")
DEC_MD5_VID(SSH_IPSEC_1_1_1,
"Ssh Communications Security IPSEC Express version 1.1.1")
DEC_MD5_VID(SSH_IPSEC_1_1_2,
"Ssh Communications Security IPSEC Express version 1.1.2")
DEC_MD5_VID(SSH_IPSEC_1_2_1,
"Ssh Communications Security IPSEC Express version 1.2.1")
DEC_MD5_VID(SSH_IPSEC_1_2_2,
"Ssh Communications Security IPSEC Express version 1.2.2")
DEC_MD5_VID(SSH_IPSEC_2_0_0,
"SSH Communications Security IPSEC Express version 2.0.0")
DEC_MD5_VID(SSH_IPSEC_2_1_0,
"SSH Communications Security IPSEC Express version 2.1.0")
DEC_MD5_VID(SSH_IPSEC_2_1_1,
"SSH Communications Security IPSEC Express version 2.1.1")
DEC_MD5_VID(SSH_IPSEC_2_1_2,
"SSH Communications Security IPSEC Express version 2.1.2")
DEC_MD5_VID(SSH_IPSEC_3_0_0,
"SSH Communications Security IPSEC Express version 3.0.0")
DEC_MD5_VID(SSH_IPSEC_3_0_1,
"SSH Communications Security IPSEC Express version 3.0.1")
DEC_MD5_VID(SSH_IPSEC_4_0_0,
"SSH Communications Security IPSEC Express version 4.0.0")
DEC_MD5_VID(SSH_IPSEC_4_0_1,
"SSH Communications Security IPSEC Express version 4.0.1")
DEC_MD5_VID(SSH_IPSEC_4_1_0,
"SSH Communications Security IPSEC Express version 4.1.0")
DEC_MD5_VID(SSH_IPSEC_4_2_0,
"SSH Communications Security IPSEC Express version 4.2.0")
/* note: md5('CISCO-UNITY') = 12f5f28c457168a9702d9fe274cc02d4 */
{ VID_CISCO_UNITY, VID_KEEP, NULL, "Cisco-Unity",
"\x12\xf5\xf2\x8c\x45\x71\x68\xa9\x70\x2d\x9f\xe2\x74\xcc\x01\x00",
16 },
/* note: md5('CISCO-UNITY') = 12f5f28c457168a9702d9fe274cc02d4 */
{ VID_CISCO_UNITY, VID_KEEP, NULL, "Cisco-Unity",
"\x12\xf5\xf2\x8c\x45\x71\x68\xa9\x70\x2d\x9f\xe2\x74\xcc\x01\x00",
16 },
{ 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},
{ 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},
{ VID_CISCO_IOS, VID_KEEP | VID_SUBSTRING_MATCH,
NULL, "Cisco IOS Device", "\x3e\x98\x40\x48", 4},
{ VID_CISCO_IOS, VID_KEEP | VID_SUBSTRING_MATCH,
NULL, "Cisco IOS Device", "\x3e\x98\x40\x48", 4},
/*
* Timestep VID seen:
* - 54494d455354455020312053475720313532302033313520322e303145303133
* = 'TIMESTEP 1 SGW 1520 315 2.01E013'
*/
{ VID_TIMESTEP, VID_STRING | VID_SUBSTRING_DUMPASCII, "TIMESTEP",
NULL, NULL, 0 },
/*
* Timestep VID seen:
* - 54494d455354455020312053475720313532302033313520322e303145303133
* = 'TIMESTEP 1 SGW 1520 315 2.01E013'
*/
{ VID_TIMESTEP, VID_STRING | VID_SUBSTRING_DUMPASCII, "TIMESTEP",
NULL, NULL, 0 },
/*
* Netscreen:
* 4865617274426561745f4e6f74696679386b0100 (HeartBeat_Notify + 386b0100)
*/
{ VID_MISC_HEARTBEAT_NOTIFY, VID_STRING | VID_SUBSTRING_DUMPHEXA,
"HeartBeat_Notify", "HeartBeat Notify", NULL, 0 },
/*
* Netscreen:
* 4865617274426561745f4e6f74696679386b0100 (HeartBeat_Notify + 386b0100)
*/
{ VID_MISC_HEARTBEAT_NOTIFY, VID_STRING | VID_SUBSTRING_DUMPHEXA,
"HeartBeat_Notify", "HeartBeat Notify", NULL, 0 },
/*
* MacOS 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},
/*
* MacOS 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},
/*
* Openswan
*/
DEC_FSWAN_VID(OPENSWAN2, "Openswan 2.2.0", "Openswan 2.2.0")
/* NCP */
{ VID_NCP_SERVER, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "NCP Server",
"\xc6\xf5\x7a\xc3\x98\xf4\x93\x20\x81\x45\xb7\x58", 12},
{ VID_NCP_CLIENT, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "NCP Client",
"\xeb\x4c\x1b\x78\x8a\xfd\x4a\x9c\xb7\x73\x0a\x68", 12},
/*
* Openswan
*/
DEC_FSWAN_VID(OPENSWAN2, "Openswan 2.2.0", "Openswan 2.2.0")
/* NCP */
{ VID_NCP_SERVER, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "NCP Server",
"\xc6\xf5\x7a\xc3\x98\xf4\x93\x20\x81\x45\xb7\x58", 12},
{ VID_NCP_CLIENT, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "NCP Client",
"\xeb\x4c\x1b\x78\x8a\xfd\x4a\x9c\xb7\x73\x0a\x68", 12},
/*
* Windows Vista (and Windows Server 2008?)
*/
DEC_MD5_VID(VISTA_AUTHIP, "MS-Negotiation Discovery Capable")
DEC_MD5_VID(VISTA_AUTHIP2, "IKE CGA version 1")
DEC_MD5_VID(VISTA_AUTHIP3, "MS-MamieExists")
/*
* Windows Vista (and Windows Server 2008?)
*/
DEC_MD5_VID(VISTA_AUTHIP, "MS-Negotiation Discovery Capable")
DEC_MD5_VID(VISTA_AUTHIP2, "IKE CGA version 1")
DEC_MD5_VID(VISTA_AUTHIP3, "MS-MamieExists")
/*
* strongSwan
*/
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_13,"strongSwan 4.2.13")
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_10,"strongSwan 4.2.10")
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_7, "strongSwan 4.2.7")
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_4, "strongSwan 4.2.4")
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_1, "strongSwan 4.2.1")
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_10,"strongSwan 4.1.10")
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_7, "strongSwan 4.1.7")
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_4, "strongSwan 4.1.4")
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_1, "strongSwan 4.1.1")
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_6, "strongSwan 4.0.6")
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_3, "strongSwan 4.0.3")
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_0, "strongSwan 4.0.0")
/*
* strongSwan
*/
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_13,"strongSwan 4.2.13")
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_10,"strongSwan 4.2.10")
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_7, "strongSwan 4.2.7")
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_4, "strongSwan 4.2.4")
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_1, "strongSwan 4.2.1")
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_10,"strongSwan 4.1.10")
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_7, "strongSwan 4.1.7")
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_4, "strongSwan 4.1.4")
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_1, "strongSwan 4.1.1")
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_6, "strongSwan 4.0.6")
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_3, "strongSwan 4.0.3")
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_0, "strongSwan 4.0.0")
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_7, "strongSwan 2.8.7")
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_4, "strongSwan 2.8.4")
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_1, "strongSwan 2.8.1")
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_2, "strongSwan 2.7.2")
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_6_4, "strongSwan 2.6.4")
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_1, "strongSwan 2.6.1")
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_6, "strongSwan 2.5.6")
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_3, "strongSwan 2.5.3")
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_0, "strongSwan 2.5.0")
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_2, "strongSwan 2.4.2")
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_3_2, "strongSwan 2.3.2")
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_2_2, "strongSwan 2.2.2")
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_8_9, "strongSwan 2.8.9")
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_6, "strongSwan 2.8.6")
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_3, "strongSwan 2.8.3")
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_0, "strongSwan 2.8.0")
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_1, "strongSwan 2.7.1")
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_3, "strongSwan 2.6.3")
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_0, "strongSwan 2.6.0")
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_5, "strongSwan 2.5.5")
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_2, "strongSwan 2.5.2")
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_4_4, "strongSwan 2.4.4")
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_1, "strongSwan 2.4.1")
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_1, "strongSwan 2.3.1")
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_1, "strongSwan 2.2.1")
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_02, "draft-stenberg-ipsec-nat-traversal-02")
DEC_MD5_VID(NATT_HUTTUNEN, "ESPThruNAT")
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_02, "draft-ietf-ipsec-nat-t-ike-02")
/* 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(NATT_IETF_03, "draft-ietf-ipsec-nat-t-ike-03")
DEC_MD5_VID(NATT_RFC, "RFC 3947")
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_HUTTUNEN, "ESPThruNAT")
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_02, "draft-ietf-ipsec-nat-t-ike-02")
/* 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(NATT_IETF_03, "draft-ietf-ipsec-nat-t-ike-03")
DEC_MD5_VID(NATT_RFC, "RFC 3947")
/* misc */
{ VID_MISC_XAUTH, VID_KEEP, NULL, "XAUTH",
"\x09\x00\x26\x89\xdf\xd6\xb7\x12", 8 },
/* misc */
{ VID_MISC_XAUTH, VID_KEEP, NULL, "XAUTH",
"\x09\x00\x26\x89\xdf\xd6\xb7\x12", 8 },
{ 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 },
{ 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 },
DEC_MD5_VID(MISC_FRAGMENTATION, "FRAGMENTATION")
DEC_MD5_VID(INITIAL_CONTACT, "Vid-Initial-Contact")
DEC_MD5_VID(MISC_FRAGMENTATION, "FRAGMENTATION")
DEC_MD5_VID(INITIAL_CONTACT, "Vid-Initial-Contact")
/**
* Cisco VPN 3000
*/
{ VID_MISC_FRAGMENTATION, VID_MD5HASH | VID_SUBSTRING_DUMPHEXA,
"FRAGMENTATION", NULL, NULL, 0 },
/**
* Cisco VPN 3000
*/
{ VID_MISC_FRAGMENTATION, VID_MD5HASH | VID_SUBSTRING_DUMPHEXA,
"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
init_vendorid(void)
{
struct vid_struct *vid;
MD5_CTX ctx;
int i;
struct vid_struct *vid;
MD5_CTX ctx;
int i;
for (vid = _vid_tab; vid->id; vid++)
{
if (vid->flags & VID_STRING)
for (vid = _vid_tab; vid->id; vid++)
{
/** VendorID is a 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++)
if (vid->flags & VID_STRING)
{
vidm[i] &= 0x7f;
vidm[i] |= 0x40;
/** VendorID is a string **/
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)
{
/** Find something to display **/
vid->descr = vid->data;
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;
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
handle_known_vendorid (struct msg_digest *md
, const char *vidstr, size_t len, struct vid_struct *vid)
{
char vid_dump[128];
bool vid_useful = FALSE;
size_t i, j;
char vid_dump[128];
bool vid_useful = FALSE;
size_t i, j;
switch (vid->id) {
/* Remote side supports OpenPGP certificates */
case VID_OPENPGP:
md->openpgp = TRUE;
vid_useful = TRUE;
break;
switch (vid->id) {
/* Remote side supports OpenPGP certificates */
case VID_OPENPGP:
md->openpgp = TRUE;
vid_useful = TRUE;
break;
/*
* Use most recent supported NAT-Traversal method and ignore the
* other ones (implementations will send all supported methods but
* only one will be used)
*
* Note: most recent == higher id in vendor.h
*/
case VID_NATT_IETF_00:
if (!nat_traversal_support_non_ike)
break;
if ((nat_traversal_enabled) && (!md->nat_traversal_vid))
{
md->nat_traversal_vid = vid->id;
vid_useful = TRUE;
/*
* Use most recent supported NAT-Traversal method and ignore the
* other ones (implementations will send all supported methods but
* only one will be used)
*
* Note: most recent == higher id in vendor.h
*/
case VID_NATT_IETF_00:
if (!nat_traversal_support_non_ike)
break;
if ((nat_traversal_enabled) && (!md->nat_traversal_vid))
{
md->nat_traversal_vid = vid->id;
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 */
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++)
if (vid->flags & VID_SUBSTRING_DUMPHEXA)
{
vid_dump[i] = _hexdig[(vidstr[j] >> 4) & 0xF];
vid_dump[i+1] = _hexdig[vidstr[j] & 0xF];
/* 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];
vid_dump[i+1] = _hexdig[vidstr[j] & 0xF];
}
}
}
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++)
else if (vid->flags & VID_SUBSTRING_DUMPASCII)
{
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]",
vid_useful ? "received" : "ignoring", vid_dump);
loglog(RC_LOG_SERIOUS, "%s Vendor ID payload [%s]",
vid_useful ? "received" : "ignoring", vid_dump);
}
void
handle_vendorid (struct msg_digest *md, const char *vid, size_t len)
{
struct vid_struct *pvid;
struct vid_struct *pvid;
if (!_vid_struct_init)
init_vendorid();
if (!_vid_struct_init)
init_vendorid();
/*
* Find known VendorID in _vid_tab
*/
for (pvid = _vid_tab; pvid->id; pvid++)
{
if (pvid->vid && vid && pvid->vid_len && len)
/*
* Find known VendorID in _vid_tab
*/
for (pvid = _vid_tab; pvid->id; pvid++)
{
if (pvid->vid_len == len)
{
if (memeq(pvid->vid, vid, len))
if (pvid->vid && vid && pvid->vid_len && len)
{
handle_known_vendorid(md, vid, len, pvid);
return;
if (pvid->vid_len == len)
{
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.
*/
{
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++)
/*
* Unknown VendorID. Log the beginning.
*/
{
log_vid[2*i] = _hexdig[(vid[i] >> 4) & 0xF];
log_vid[2*i+1] = _hexdig[vid[i] & 0xF];
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];
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
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)
init_vendorid();
if (!_vid_struct_init)
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)
return STF_INTERNAL_ERROR; /* not found */
if (!pvid->vid)
return STF_INTERNAL_ERROR; /* not initialized */
if (pvid->id != vid)
return STF_INTERNAL_ERROR; /* not found */
if (!pvid->vid)
return STF_INTERNAL_ERROR; /* not initialized */
DBG(DBG_EMITTING,
DBG_log("out_vendorid(): sending [%s]", pvid->descr)
)
return out_generic_raw(np, &isakmp_vendor_id_desc, outs,
pvid->vid, pvid->vid_len, "V_ID");
DBG(DBG_EMITTING,
DBG_log("out_vendorid(): sending [%s]", pvid->descr)
)
return out_generic_raw(np, &isakmp_vendor_id_desc, outs,
pvid->vid, pvid->vid_len, "V_ID");
}

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