conversion from 8 spaces to 4 spaces per tab
This commit is contained in:
parent
d940c7638c
commit
3d7a244b54
1384
src/pluto/ac.c
1384
src/pluto/ac.c
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
|
718
src/pluto/adns.c
718
src/pluto/adns.c
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
1664
src/pluto/alg_info.c
1664
src/pluto/alg_info.c
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
||||
|
|
1096
src/pluto/asn1.c
1096
src/pluto/asn1.c
File diff suppressed because it is too large
Load Diff
124
src/pluto/asn1.h
124
src/pluto/asn1.h
|
@ -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 */
|
||||
|
|
904
src/pluto/ca.c
904
src/pluto/ca.c
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
@ -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
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
1106
src/pluto/crl.c
1106
src/pluto/crl.c
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
186
src/pluto/defs.c
186
src/pluto/defs.c
|
@ -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, "..");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
3860
src/pluto/demux.c
3860
src/pluto/demux.c
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
|
2514
src/pluto/dnskey.c
2514
src/pluto/dnskey.c
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
||||
|
|
530
src/pluto/dsa.c
530
src/pluto/dsa.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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*/
|
||||
|
|
1180
src/pluto/fetch.c
1180
src/pluto/fetch.c
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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[];
|
||||
|
|
660
src/pluto/id.c
660
src/pluto/id.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
@ -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; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
4502
src/pluto/kernel.c
4502
src/pluto/kernel.c
File diff suppressed because it is too large
Load Diff
|
@ -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
|
@ -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
2048
src/pluto/keys.c
2048
src/pluto/keys.c
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
||||
|
|
254
src/pluto/lex.c
254
src/pluto/lex.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
986
src/pluto/log.c
986
src/pluto/log.c
File diff suppressed because it is too large
Load Diff
102
src/pluto/log.h
102
src/pluto/log.h
|
@ -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*/
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
1860
src/pluto/modecfg.c
1860
src/pluto/modecfg.c
File diff suppressed because it is too large
Load Diff
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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 */
|
||||
|
||||
|
|
1964
src/pluto/ocsp.c
1964
src/pluto/ocsp.c
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
|
1278
src/pluto/packet.c
1278
src/pluto/packet.c
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
|
|
576
src/pluto/pem.c
576
src/pluto/pem.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -15,4 +15,4 @@
|
|||
*/
|
||||
|
||||
extern err_t pemtobin(chunk_t *blob, prompt_pass_t *pass, const char* label
|
||||
, bool *pgp);
|
||||
, bool *pgp);
|
||||
|
|
844
src/pluto/pgp.c
844
src/pluto/pgp.c
File diff suppressed because it is too large
Load Diff
|
@ -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
|
@ -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
|
||||
|
|
1222
src/pluto/pkcs7.c
1222
src/pluto/pkcs7.c
File diff suppressed because it is too large
Load Diff
|
@ -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
|
@ -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
126
src/pluto/rnd.c
126
src/pluto/rnd.c
|
@ -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 */
|
||||
|
|
1428
src/pluto/server.c
1428
src/pluto/server.c
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
|
202
src/pluto/sha1.c
202
src/pluto/sha1.c
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
|
|
3834
src/pluto/spdb.c
3834
src/pluto/spdb.c
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
|
1198
src/pluto/state.c
1198
src/pluto/state.c
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue