summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorNiels Provos <provos@cvs.openbsd.org>1998-03-04 11:43:56 +0000
committerNiels Provos <provos@cvs.openbsd.org>1998-03-04 11:43:56 +0000
commit4be2eb12506cf065e68c51750f45f81ba3d63717 (patch)
treeb4cb6a032a89a159e425ace730b3bda6a7b1c25f /sbin
parent8b1bb75ad56e072dc58c33715385fa7e439b2503 (diff)
compliance with draft-simpson-photuris-18.txt, better packet structure
checking, better support for new esp and ah, documentation ...
Diffstat (limited to 'sbin')
-rw-r--r--sbin/ipsec/photurisd/INSTALL2
-rw-r--r--sbin/ipsec/photurisd/README4
-rw-r--r--sbin/ipsec/photurisd/README.howtouse4
-rw-r--r--sbin/ipsec/photurisd/api.c4
-rw-r--r--sbin/ipsec/photurisd/attributes.c104
-rw-r--r--sbin/ipsec/photurisd/attributes.h50
-rw-r--r--sbin/ipsec/photurisd/buffer.c6
-rw-r--r--sbin/ipsec/photurisd/buffer.h6
-rw-r--r--sbin/ipsec/photurisd/compute_secrets.c59
-rw-r--r--sbin/ipsec/photurisd/config.c338
-rw-r--r--sbin/ipsec/photurisd/config.h9
-rw-r--r--sbin/ipsec/photurisd/encrypt.h4
-rw-r--r--sbin/ipsec/photurisd/handle_identity_request.c216
-rw-r--r--sbin/ipsec/photurisd/handle_identity_response.c117
-rw-r--r--sbin/ipsec/photurisd/handle_spi_needed.c54
-rw-r--r--sbin/ipsec/photurisd/handle_spi_update.c54
-rw-r--r--sbin/ipsec/photurisd/handle_value_request.c50
-rw-r--r--sbin/ipsec/photurisd/handle_value_response.c51
-rw-r--r--sbin/ipsec/photurisd/identity.c198
-rw-r--r--sbin/ipsec/photurisd/identity.h10
-rw-r--r--sbin/ipsec/photurisd/kernel.c432
-rw-r--r--sbin/ipsec/photurisd/kernel.h21
-rw-r--r--sbin/ipsec/photurisd/packet.c120
-rw-r--r--sbin/ipsec/photurisd/packet.h7
-rw-r--r--sbin/ipsec/photurisd/packets.h25
-rw-r--r--sbin/ipsec/photurisd/photuris_identity_request.c10
-rw-r--r--sbin/ipsec/photurisd/photuris_identity_response.c10
-rw-r--r--sbin/ipsec/photurisd/photuris_packet_encrypt.c94
-rw-r--r--sbin/ipsec/photurisd/photuris_value_request.c4
-rw-r--r--sbin/ipsec/photurisd/photuris_value_response.c3
-rw-r--r--sbin/ipsec/photurisd/photurisd.163
-rw-r--r--sbin/ipsec/photurisd/photurisd.c13
-rw-r--r--sbin/ipsec/photurisd/schedule.c15
-rw-r--r--sbin/ipsec/photurisd/secrets.h4
-rw-r--r--sbin/ipsec/photurisd/server.c15
-rw-r--r--sbin/ipsec/photurisd/spi.c76
-rw-r--r--sbin/ipsec/photurisd/state.h7
37 files changed, 1515 insertions, 744 deletions
diff --git a/sbin/ipsec/photurisd/INSTALL b/sbin/ipsec/photurisd/INSTALL
index b86c90058e9..a43abf7b6c8 100644
--- a/sbin/ipsec/photurisd/INSTALL
+++ b/sbin/ipsec/photurisd/INSTALL
@@ -14,7 +14,7 @@ add -DIPSEC to the CFLAGS.
Run make.
After starting the photurisd on two machines, you can start the program
-startkey <ip-number-of-the-other-machine> to start a key exchange.
+startkey dst=<ip-number-of-the-other-machine> to start a key exchange.
For the daemon to work with other IPSec implementations you should look
in the sources for #ifdef IPSEC.
diff --git a/sbin/ipsec/photurisd/README b/sbin/ipsec/photurisd/README
index d77f1f9d03c..59f7880e55e 100644
--- a/sbin/ipsec/photurisd/README
+++ b/sbin/ipsec/photurisd/README
@@ -1,7 +1,7 @@
This is an implementation of the Photuris keymanagement protocol
according to the drafts:
- draft-simpson-photuris-12.txt
- draft-simpson-photuris-schemes-01.txt
+ draft-simpson-photuris-18.txt
+ draft-simpson-photuris-schemes-04.txt
For quick installation instructions read INSTALL, or otherwise
README.howtouse for more complete information.
diff --git a/sbin/ipsec/photurisd/README.howtouse b/sbin/ipsec/photurisd/README.howtouse
index 9e14f4bd67a..49c0c819741 100644
--- a/sbin/ipsec/photurisd/README.howtouse
+++ b/sbin/ipsec/photurisd/README.howtouse
@@ -34,7 +34,7 @@ How to get it working ?
happens, or remove -DIPSEC if you dont want to actually setup encrypted
and authenticated connections within the kernel)
6. start ./photurid on two hosts.
-7. ./startkey host1 (for example ./startkey 134.100.33.22)
+7. ./startkey dst=host1 (for example ./startkey dst=134.100.33.22)
If you compiled the photuris daemon with -DDEBUG you should see an
exchange of values now and finally the shared secret from which the
@@ -58,7 +58,7 @@ How to get it working ?
Add the following two lines into your kernel config file:
config IPSEC
-pseudo-device enc 4
+pseudo-device enc 1
Possible configuration
diff --git a/sbin/ipsec/photurisd/api.c b/sbin/ipsec/photurisd/api.c
index fde4257a3d8..b60382d6c78 100644
--- a/sbin/ipsec/photurisd/api.c
+++ b/sbin/ipsec/photurisd/api.c
@@ -37,7 +37,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: api.c,v 1.3 1997/09/14 10:37:48 deraadt Exp $";
+static char rcsid[] = "$Id: api.c,v 1.4 1998/03/04 11:43:07 provos Exp $";
#endif
#define _API_C_
@@ -95,6 +95,7 @@ process_api(int fd, int sendsock)
startup_parse(st, buffer);
+#ifndef DEBUG
if (addresses != (char **) NULL && strlen(st->address))
for (i = 0; i<num_ifs; i++) {
if (addresses[i] == (char *)NULL)
@@ -107,6 +108,7 @@ process_api(int fd, int sendsock)
return;
}
}
+#endif
startup_end(st);
diff --git a/sbin/ipsec/photurisd/attributes.c b/sbin/ipsec/photurisd/attributes.c
index 28052e6d3cf..bc3e84b347d 100644
--- a/sbin/ipsec/photurisd/attributes.c
+++ b/sbin/ipsec/photurisd/attributes.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: attributes.c,v 1.2 1997/07/19 12:07:40 provos Exp $";
+static char rcsid[] = "$Id: attributes.c,v 1.3 1998/03/04 11:43:08 provos Exp $";
#endif
#define _ATTRIBUTES_C_
@@ -47,7 +47,44 @@ static char rcsid[] = "$Id: attributes.c,v 1.2 1997/07/19 12:07:40 provos Exp $"
#include "config.h"
#include "attributes.h"
-static struct attribute_list *attribob = NULL;
+static attribute_list *attribob = NULL;
+static attrib_t *attribhash[ATTRIBHASHMOD];
+
+/* Put or get attribute properties from the hashtable */
+
+void
+putattrib(attrib_t *attrib)
+{
+ int hashval = attrib->id % ATTRIBHASHMOD;
+ attrib->next = attribhash[hashval];
+ attribhash[hashval] = attrib;
+}
+
+attrib_t *
+getattrib(int id)
+{
+ int hashval = id % ATTRIBHASHMOD;
+ attrib_t *attrib;
+
+ for(attrib=attribhash[hashval]; attrib; attrib = attrib->next)
+ if (attrib->id == id)
+ break;
+
+ return attrib;
+}
+
+void
+clearattrib(void)
+{
+ int i;
+ attrib_t *attrib;
+
+ for (i=0; i<ATTRIBHASHMOD; i++)
+ while ((attrib=attribhash[i]) != NULL) {
+ attribhash[i] = attrib->next;
+ free(attrib);
+ }
+}
int
isinattrib(u_int8_t *attributes, u_int16_t attribsize, u_int8_t attribute)
@@ -64,6 +101,41 @@ isinattrib(u_int8_t *attributes, u_int16_t attribsize, u_int8_t attribute)
return 0;
}
+void
+get_attrib_section(u_int8_t *set, u_int16_t setsize,
+ u_int8_t **subset, u_int16_t *subsetsize,
+ u_int8_t section)
+{
+ int i = 0;
+ u_int8_t *tset;
+ u_int16_t tsetsize;
+
+ while (i < setsize) {
+ if (set[i] == section)
+ break;
+ i += set[i+1] + 2;
+ }
+
+ if ((i >= setsize) || (i+set[i+1] + 2 > setsize)) {
+ *subset = NULL;
+ *subsetsize = 0;
+ return;
+ }
+
+ tset = *subset = set+i+set[i+1]+2;
+ tsetsize = *subsetsize = setsize - i - set[i+1] - 2;
+
+ i = 0;
+ while (i < tsetsize) {
+ if (tset[i] == AT_ESP_ATTRIB || tset[i] == AT_AH_ATTRIB) {
+ *subsetsize = i;
+ return;
+ }
+ i += tset[i+1]+2;
+ }
+}
+
+
int
isattribsubset(u_int8_t *set, u_int16_t setsize,
u_int8_t *subset, u_int16_t subsetsize)
@@ -80,9 +152,9 @@ isattribsubset(u_int8_t *set, u_int16_t setsize,
}
int
-attrib_insert(struct attribute_list *ob)
+attrib_insert(attribute_list *ob)
{
- struct attribute_list *tmp;
+ attribute_list *tmp;
ob->next = NULL;
@@ -100,9 +172,9 @@ attrib_insert(struct attribute_list *ob)
}
int
-attrib_unlink(struct attribute_list *ob)
+attrib_unlink(attribute_list *ob)
{
- struct attribute_list *tmp;
+ attribute_list *tmp;
if(attribob == ob) {
attribob = ob->next;
free(ob);
@@ -119,26 +191,26 @@ attrib_unlink(struct attribute_list *ob)
return 0;
}
-struct attribute_list *
+attribute_list *
attrib_new(void)
{
- struct attribute_list *p;
+ attribute_list *p;
- if((p = calloc(1, sizeof(struct attribute_list)))==NULL)
+ if((p = calloc(1, sizeof(attribute_list)))==NULL)
return NULL;
return p;
}
int
-attrib_value_reset(struct attribute_list *ob)
+attrib_value_reset(attribute_list *ob)
{
if (ob->address != NULL)
free(ob->address);
if (ob->attributes != NULL)
free(ob->attributes);
- bzero(ob, sizeof(struct attribute_list));
+ bzero(ob, sizeof(attribute_list));
return 1;
}
@@ -148,11 +220,11 @@ attrib_value_reset(struct attribute_list *ob)
* list.
*/
-struct attribute_list *
+attribute_list *
attrib_find(char *address)
{
- struct attribute_list *tmp = attribob;
- struct attribute_list *null = NULL;
+ attribute_list *tmp = attribob;
+ attribute_list *null = NULL;
while(tmp!=NULL) {
if (tmp->address == NULL) {
null = tmp;
@@ -172,8 +244,8 @@ attrib_find(char *address)
void
attrib_cleanup()
{
- struct attribute_list *p;
- struct attribute_list *tmp = attribob;
+ attribute_list *p;
+ attribute_list *tmp = attribob;
while(tmp!=NULL) {
p = tmp;
tmp = tmp->next;
diff --git a/sbin/ipsec/photurisd/attributes.h b/sbin/ipsec/photurisd/attributes.h
index aaafd307eee..93bc01dc552 100644
--- a/sbin/ipsec/photurisd/attributes.h
+++ b/sbin/ipsec/photurisd/attributes.h
@@ -42,18 +42,13 @@
#define EXTERN extern
#endif
-#define AT_PAD 0
-#define AT_AH_ATTRIB 1
-#define AT_ESP_ATTRIB 2
-#define AT_MD5_DP 3
-#define AT_SHA1_DP 4
-#define AT_MD5_KDP 5
-#define AT_SHA1_KDP 6
-#define AT_DES_CBC 8
-#define AT_ORG 255
+#define AT_ID 1
+#define AT_ENC 2
+#define AT_AUTH 4
-#define MD5_KEYLEN 384
-#define DES_KEYLEN 64
+#define AT_PAD 0
+#define AT_AH_ATTRIB 1
+#define AT_ESP_ATTRIB 2
/* XXX - Only for the moment */
#define DH_G_2_MD5 2
@@ -69,23 +64,40 @@
#define DH_G_5_3DES_SHA1 20
#define DH_G_VAR_3DES_SHA1 28
-struct attribute_list {
- struct attribute_list *next;
+typedef struct _attribute_list {
+ struct _attribute_list *next;
char *address;
in_addr_t netmask;
u_int8_t *attributes;
u_int16_t attribsize;
-};
+} attribute_list;
+
+typedef struct _attrib_t {
+ struct _attrib_t *next;
+ int id; /* Photuris Attribute ID */
+ int koff; /* Offset into kernel data structure */
+ int type; /* Type of attribute: ident, enc, auth */
+ int klen; /* required key length */
+} attrib_t;
+
+#define ATTRIBHASHMOD 17
+
+EXTERN void putattrib(attrib_t *attrib);
+EXTERN attrib_t *getattrib(int id);
+EXTERN void clearattrib(void);
+
+EXTERN void get_attrib_section(u_int8_t *, u_int16_t, u_int8_t **, u_int16_t *,
+ u_int8_t);
EXTERN int isinattrib(u_int8_t *attributes, u_int16_t attribsize,
u_int8_t attribute);
EXTERN int isattribsubset(u_int8_t *set, u_int16_t setsize,
u_int8_t *subset, u_int16_t subsetsize);
-EXTERN struct attribute_list *attrib_new(void);
-EXTERN int attrib_insert(struct attribute_list *);
-EXTERN int attrib_unlink(struct attribute_list *);
-EXTERN int attrib_value_reset(struct attribute_list *);
-EXTERN struct attribute_list *attrib_find(char *);
+EXTERN attribute_list *attrib_new(void);
+EXTERN int attrib_insert(attribute_list *);
+EXTERN int attrib_unlink(attribute_list *);
+EXTERN int attrib_value_reset(attribute_list *);
+EXTERN attribute_list *attrib_find(char *);
EXTERN void attrib_cleanup(void);
#endif /* ATTRIBUTES_H */
diff --git a/sbin/ipsec/photurisd/buffer.c b/sbin/ipsec/photurisd/buffer.c
index 5794e28118f..afc3a22d383 100644
--- a/sbin/ipsec/photurisd/buffer.c
+++ b/sbin/ipsec/photurisd/buffer.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: buffer.c,v 1.1 1997/07/18 22:48:50 provos Exp $";
+static char rcsid[] = "$Id: buffer.c,v 1.2 1998/03/04 11:43:11 provos Exp $";
#endif
#include <sys/types.h>
@@ -42,5 +42,5 @@ static char rcsid[] = "$Id: buffer.c,v 1.1 1997/07/18 22:48:50 provos Exp $";
#include "buffer.h"
int packet_size;
-char buffer[BUFFER_SIZE];
-char packet_buffer[PACKET_BUFFER_SIZE];
+u_char buffer[BUFFER_SIZE];
+u_char packet_buffer[PACKET_BUFFER_SIZE];
diff --git a/sbin/ipsec/photurisd/buffer.h b/sbin/ipsec/photurisd/buffer.h
index fa4eaf34bff..e208582b353 100644
--- a/sbin/ipsec/photurisd/buffer.h
+++ b/sbin/ipsec/photurisd/buffer.h
@@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* $Id: buffer.h,v 1.1 1997/07/18 22:48:51 provos Exp $ */
+/* $Id: buffer.h,v 1.2 1998/03/04 11:43:12 provos Exp $ */
/*
* buffer.h:
* variables with buffers.
@@ -40,8 +40,8 @@
#define BUFFER_SIZE 8192
#ifndef _BUFFER_C
-extern char buffer[];
-extern char packet_buffer[];
+extern u_char buffer[];
+extern u_char packet_buffer[];
extern int packet_size;
#endif
diff --git a/sbin/ipsec/photurisd/compute_secrets.c b/sbin/ipsec/photurisd/compute_secrets.c
index f52feae8110..a2e5a3294e8 100644
--- a/sbin/ipsec/photurisd/compute_secrets.c
+++ b/sbin/ipsec/photurisd/compute_secrets.c
@@ -34,7 +34,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: compute_secrets.c,v 1.4 1997/09/02 17:26:35 provos Exp $";
+static char rcsid[] = "$Id: compute_secrets.c,v 1.5 1998/03/04 11:43:14 provos Exp $";
#endif
#define _SECRETS_C_
@@ -62,12 +62,13 @@ static char rcsid[] = "$Id: compute_secrets.c,v 1.4 1997/09/02 17:26:35 provos E
#include "errlog.h"
int privacykey(struct stateob *st, struct idxform *hash, u_int8_t *key,
- u_int8_t *packet, u_int16_t bytes, u_int16_t order, int owner);
+ u_int8_t *packet, u_int16_t bytes, u_int16_t *order, int owner);
int
compute_shared_secret(struct stateob *st,
u_int8_t **shared, u_int16_t *sharedsize)
{
struct moduli_cache *mod;
+ int header;
mpz_t tmp, bits, tex;
@@ -94,11 +95,21 @@ compute_shared_secret(struct stateob *st,
mpz_clear(bits);
mpz_clear(tmp);
+ /* The shared secret is not used with the size part */
+ if (buffer[0] == 255 && buffer[1] == 255)
+ header = 8;
+ else if (buffer[0] == 255)
+ header = 4;
+ else
+ header = 2;
+
+ *sharedsize -= header;
+
if((*shared = calloc(*sharedsize,sizeof(u_int8_t))) == NULL) {
log_error(0, "Not enough memory for shared secret in compute_shared_secret()");
return -1;
}
- bcopy(buffer, *shared, *sharedsize);
+ bcopy(buffer+header, *shared, *sharedsize);
return 0;
}
@@ -167,20 +178,23 @@ make_session_keys(struct stateob *st, struct spiob *spi)
return 0;
}
+/*
+ * Return length of requried session key in bits.
+ * DES would be 64 bits.
+ */
int
get_session_key_length(u_int8_t *attribute)
{
- switch(*attribute) {
- case AT_MD5_KDP:
- return MD5_KEYLEN;
- case AT_DES_CBC:
- return DES_KEYLEN;
- default:
+ attrib_t *ob;
+
+ if ((ob = getattrib(*attribute)) == NULL) {
log_error(0, "Unknown attribute %d in get_session_key_length()",
*attribute);
return -1;
}
+
+ return ob->klen << 3;
}
/*
@@ -197,7 +211,7 @@ compute_session_key(struct stateob *st, u_int8_t *key,
struct idxform *hash;
u_int16_t size, i, n;
u_int8_t digest[HASH_MAX];
- int bits, hbits;
+ int bits;
switch(ntohs(*((u_int16_t *)st->scheme))) {
case DH_G_2_MD5:
@@ -230,11 +244,8 @@ compute_session_key(struct stateob *st, u_int8_t *key,
if(bits & 0x7)
size++;
- hbits = (hash->hashsize << 3);
- *order += (*order%hbits) ? hbits - (*order%hbits) : 0;
-
/* As many shared secrets we used already */
- n = *order/hbits;
+ n = *order;
hash->Init(hash->ctx);
hash->Update(hash->ctx, st->icookie, COOKIE_SIZE);
@@ -259,6 +270,9 @@ compute_session_key(struct stateob *st, u_int8_t *key,
bcopy(hash->ctx2, hash->ctx, hash->ctxsize);
hash->Final(digest, hash->ctx2);
+ /* One iteration more */
+ n++;
+
bcopy(digest, key, size>hash->hashsize ? hash->hashsize : size);
key += size>hash->hashsize ? hash->hashsize : size;
@@ -266,7 +280,7 @@ compute_session_key(struct stateob *st, u_int8_t *key,
size -= size>hash->hashsize ? hash->hashsize : size;
} while(size > 0);
- *order += bits + (bits%hbits ? hbits - (bits%hbits) : 0 );
+ *order = n;
return bits;
}
@@ -333,12 +347,12 @@ init_privacy_key(struct stateob *st, int owner)
}
/*
- * order gives the number of bits already used for keys
+ * order gives the number of iterations already done for keys
*/
int
compute_privacy_key(struct stateob *st, u_int8_t *key, u_int8_t *packet,
- u_int16_t bits, u_int16_t order, int owner)
+ u_int16_t bits, u_int16_t *order, int owner)
{
u_int16_t size;
struct idxform *hash;
@@ -376,9 +390,9 @@ compute_privacy_key(struct stateob *st, u_int8_t *key, u_int8_t *packet,
int
privacykey(struct stateob *st, struct idxform *hash,
u_int8_t *key, u_int8_t *packet,
- u_int16_t bytes, u_int16_t order, int owner)
+ u_int16_t bytes, u_int16_t *order, int owner)
{
- u_int16_t i, n, hbits;
+ u_int16_t i, n;
u_int8_t digest[HASH_MAX];
/* SPIprivacyctx contains the hashed exchangevalues */
@@ -388,8 +402,7 @@ privacykey(struct stateob *st, struct idxform *hash,
hash->Update(hash->ctx2, packet, 2*COOKIE_SIZE + 4 + SPI_SIZE);
/* As many shared secrets we used already */
- hbits = (hash->hashsize << 3);
- n = order/hbits + (order%hbits ? 1 : 0);
+ n = *order;
for(i=0; i<n; i++)
hash->Update(hash->ctx2, st->shared, st->sharedsize);
@@ -404,8 +417,12 @@ privacykey(struct stateob *st, struct idxform *hash,
/* Unsigned integer arithmetic */
bytes -= bytes>hash->hashsize ? hash->hashsize : bytes;
+
+ /* Increment the times we called Final */
+ i++;
} while(bytes > 0);
+ *order = i;
return 0;
}
diff --git a/sbin/ipsec/photurisd/config.c b/sbin/ipsec/photurisd/config.c
index d3a24512921..1dbd1c02c4a 100644
--- a/sbin/ipsec/photurisd/config.c
+++ b/sbin/ipsec/photurisd/config.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: config.c,v 1.5 1997/09/14 10:37:49 deraadt Exp $";
+static char rcsid[] = "$Id: config.c,v 1.6 1998/03/04 11:43:15 provos Exp $";
#endif
#define _CONFIG_C_
@@ -68,9 +68,13 @@ static char rcsid[] = "$Id: config.c,v 1.5 1997/09/14 10:37:49 deraadt Exp $";
#include "buffer.h"
#include "scheme.h"
#include "api.h"
+#ifdef IPSEC
+#include "kernel.h"
+#endif
static FILE *config_fp;
+static struct cfgx *cfgxroot;
static void
open_config_file(char *file)
@@ -120,18 +124,93 @@ config_get(char *token)
}
int
+cfgx_insert(char *name, int id)
+{
+ struct cfgx *ob;
+
+ if ((ob = malloc(sizeof(struct cfgx))) == NULL)
+ return -1;
+
+ ob->name = strdup(name);
+ ob->id = id;
+
+ ob->next = cfgxroot;
+ cfgxroot = ob;
+
+ return 0;
+}
+
+struct cfgx *
+cfgx_get(char *name)
+{
+ struct cfgx *ob;
+
+ for(ob = cfgxroot; ob; ob = ob->next)
+ if (ob->name && !strcmp(name, ob->name))
+ break;
+
+ return ob;
+}
+
+void
+cfgx_clear(void)
+{
+ struct cfgx *ob;
+ while(cfgxroot) {
+ ob = cfgxroot;
+ cfgxroot = cfgxroot->next;
+ free(ob);
+ }
+}
+
+/*
+ * Parses the type of an attribute: ident|enc|auth.
+ */
+
+int
+parse_type(char *line)
+{
+
+ int type = 0;
+ while (*line) {
+ if (!strncmp(line, "ident", 5)) {
+ type |= AT_ID;
+ line += 5;
+ } else if (!strncmp(line, "enc", 3)) {
+ type |= AT_ENC;
+ line += 3;
+ } else if (!strncmp(line, "auth", 4)) {
+ type |= AT_AUTH;
+ line += 4;
+ } else
+ return -1;
+ while (isspace(*line))
+ line++;
+ if (*line && *line++ != '|')
+ return -1;
+ }
+
+ return type;
+}
+
+int
init_attributes(void)
{
char *p, *p2;
- struct attribute_list *ob = NULL;
+ attribute_list *ob = NULL;
struct in_addr in;
- int def_flag = 0;
+ int i, def_flag = 0;
char attrib[257];
+ struct cfgx *cfgattrib = NULL;
#ifdef DEBUG
printf("[Setting up attributes]\n");
#endif
+ /* Set up attribute delimeter */
+ cfgx_insert("AT_AH_ATTRIB", AT_AH_ATTRIB);
+ cfgx_insert("AT_ESP_ATTRIB", AT_ESP_ATTRIB);
+
open_config_file(attrib_file);
while((p2 = config_get("")) != NULL) {
p = strsep(&p2, " ");
@@ -141,35 +220,84 @@ init_attributes(void)
if (p2 == NULL || inet_addr(p) == -1 ||
inet_network(p2) == -1) { /* Attributes follow now */
- if (ob == NULL && (ob = attrib_new()) == NULL)
- crit_error(1, "attribute_new() in init_attributes()");
- else
- def_flag = 1;
+ cfgattrib = cfgx_get(p);
+ if (cfgattrib == NULL && strchr(p, ',') != NULL) {
+ char *name, *p3, *p4;
+ attrib_t tmpatt, *ob;
+
+ p4 = p;
+
+ if (p2 != NULL)
+ p4[strlen(p4)] = ' ';
+
+ name = strsep(&p4, ",");
+ while (isspace(*name))
+ name++;
+ i = strlen(name) - 1;
+ while (isspace(name[i]) && i > 0)
+ name[i--] = 0;
+
+ if ((p2 = strsep(&p4, ",")) == NULL ||
+ (p3 = strsep(&p4, ",")) == NULL) {
+ log_error(0, "Mal formated attribute definition for %s in init_attributess()", name);
+ continue;
+ }
+
+ if ((tmpatt.id = atoi(p2)) <= 0) {
+ log_error(0, "Bad id %s for %s in init_attributes()", p2, name);
+ continue;
+ }
+
+ if ((tmpatt.klen = atoi(p4)) < 0) {
+ log_error(0, "Bad key length %s for %s in init_attributes()", p4, name);
+ continue;
+ }
+
+ while (isspace(*p3))
+ p3++;
+ i = strlen(p3) - 1;
+ while (isspace(p3[i]) && i > 0)
+ p3[i--] = 0;
+
+ if ((tmpatt.type = parse_type(p3)) == -1) {
+ log_error(0, "Unkown attribute type %s for %s in init_attributes()", p3, name);
+ continue;
+ }
+
+#ifdef IPSEC
+ if ((tmpatt.type & ~AT_ID) &&
+ (tmpatt.koff = kernel_get_offset(tmpatt.id)) == -1) {
+ log_error(0, "Attribute %s not supported by kernel in init_attributes()", name);
+ continue;
+ }
+#endif
+
+ if ((ob = calloc(1, sizeof(attrib_t))) == NULL)
+ crit_error(1, "calloc() in init_attributes()");
+
+ *ob = tmpatt;
+ putattrib(ob);
+ cfgx_insert(name, ob->id);
+ cfgattrib = cfgx_get(name);
+#ifdef DEBUG
+ printf("New attribute: %s, id: %d, type: %d, klen: %d\n", name, ob->id, ob->type, ob->klen);
+#endif
+ }
- if (!strcmp(p, "AT_AH_ATTRIB")) {
- attrib[0] = AT_AH_ATTRIB;
- attrib[1] = 0;
- } else if (!strcmp(p, "AT_ESP_ATTRIB")) {
- attrib[0] = AT_ESP_ATTRIB;
- attrib[1] = 0;
- } else if (!strcmp(p, "AT_MD5_DP")) {
- attrib[0] = AT_MD5_DP;
- attrib[1] = 0;
- } else if (!strcmp(p, "AT_SHA1_DP")) {
- attrib[0] = AT_SHA1_DP;
- attrib[1] = 0;
- } else if (!strcmp(p, "AT_MD5_KDP")) {
- attrib[0] = AT_MD5_KDP;
- attrib[1] = 0;
- } else if (!strcmp(p, "AT_DES_CBC")) {
- attrib[0] = AT_DES_CBC;
- attrib[1] = 0;
- } else {
+ if (cfgattrib == NULL) {
log_error(0, "Unknown attribute %s in init_attributes()",
p);
continue;
}
+ if (ob == NULL && (ob = attrib_new()) == NULL)
+ crit_error(1, "attribute_new() in init_attributes()");
+ else
+ def_flag = 1;
+
+ attrib[0] = cfgattrib->id;
+ attrib[1] = 0;
+
/* Copy attributes in object */
ob->attributes = realloc(ob->attributes,
ob->attribsize + attrib[1] +2);
@@ -209,6 +337,8 @@ init_attributes(void)
if (!def_flag)
crit_error(0, "No default attribute list in init_attributes()");
+
+ cfgx_clear();
return 1;
}
@@ -444,7 +574,7 @@ startup_parse(struct stateob *st, char *p2)
char *p, *p3;
struct hostent *hp;
- while((p=strsep(&p2, " ")) != NULL) {
+ while((p=strsep(&p2, " ")) != NULL && strlen(p)) {
if ((p3 = strchr(p, '=')) == NULL) {
log_error(0, "missing = in %s in startup_parse()", p);
continue;
@@ -629,7 +759,9 @@ reconfig(int sig)
{
log_error(0, "Reconfiguring on SIGHUP");
- attrib_cleanup();
+ clearattrib(); /* Clear attribute id hash */
+ attrib_cleanup(); /* Clear list of offered attributes */
+
identity_cleanup(NULL);
mod_cleanup();
@@ -763,7 +895,7 @@ pick_scheme(u_int8_t **scheme, u_int16_t *schemesize,
int
pick_attrib(struct stateob *st, u_int8_t **attrib, u_int16_t *attribsize)
{
- struct attribute_list *ob;
+ attribute_list *ob;
int mode = 0, i, n, count, first;
if ((ob = attrib_find(st->address)) == NULL) {
@@ -807,6 +939,154 @@ pick_attrib(struct stateob *st, u_int8_t **attrib, u_int16_t *attribsize)
/*
+ * Select attributes we actually want to use for the SA.
+ */
+
+int
+select_attrib(struct stateob *st, u_int8_t **attributes, u_int16_t *attribsize)
+{
+ u_int16_t count = 0;
+ u_int8_t *wantesp, *wantah, *offeresp, *offerah, *p;
+ u_int16_t wantespsize, wantahsize, offerespsize, offerahsize;
+ attribute_list *ob;
+ attrib_t *attprop;
+
+ if ((ob = attrib_find(NULL)) == NULL) {
+ log_error(0, "attrib_find() for default in select_attrib() in "
+ "exchange to %s", st->address);
+ return -1;
+ }
+
+ /* Take from Owner */
+ get_attrib_section(ob->attributes, ob->attribsize,
+ &wantesp, &wantespsize, AT_ESP_ATTRIB);
+ get_attrib_section(ob->attributes, ob->attribsize,
+ &wantah, &wantahsize, AT_AH_ATTRIB);
+
+
+ /* Take from User */
+ get_attrib_section(st->uSPIoattrib, st->uSPIoattribsize,
+ &offeresp, &offerespsize, AT_ESP_ATTRIB);
+ get_attrib_section(st->uSPIoattrib, st->uSPIoattribsize,
+ &offerah, &offerahsize, AT_AH_ATTRIB);
+
+ p = buffer;
+ if (wantesp != NULL && offeresp != NULL && (st->flags & IPSEC_OPT_ENC)) {
+ /* Take the ESP section */
+ char *tp = wantesp, *ta = wantesp;
+ u_int16_t tpsize = 0, tasize = 0;
+ int res;
+ attrib_t *attah = NULL;
+
+ attprop = NULL;
+ /* We travers the ESP section and look for the first ENC attribute */
+ while (tpsize < wantespsize) {
+ if (isinattrib(offeresp, offerespsize, tp[tpsize])) {
+ attprop = getattrib(tp[tpsize]);
+ if (attprop != NULL && attprop->type == AT_ENC)
+ break;
+ }
+ tpsize += tp[tpsize+1]+2;
+ }
+ if (tpsize >= wantespsize)
+ attprop = NULL;
+
+ /* If we find a fitting AH, we take it */
+ while (attprop != NULL && tasize < wantespsize) {
+ if (isinattrib(offeresp, offerespsize, ta[tasize])) {
+ attah = getattrib(ta[tasize]);
+ if (attah != NULL && (attah->type & AT_AUTH)) {
+#ifdef IPSEC
+ res = kernel_valid(attprop->koff, attah->koff);
+#else
+ res = 0;
+#endif
+ if (res == AT_ENC) {
+ /*
+ * Our ESP attribute does not allow AH, but
+ * since the ESP attribute is our first choice,
+ * dont try for other.
+ */
+ attah = NULL;
+ break;
+ } else if (res != AT_AUTH)
+ break;
+ }
+ }
+
+ tasize += ta[tasize+1]+2;
+ }
+ if (tasize >= wantespsize)
+ attah = NULL;
+
+ if (attprop != NULL) {
+ /* Put proper header in there */
+ p[0] = AT_ESP_ATTRIB;
+ p[1] = 0;
+ count += 2;
+ p += 2;
+
+ /* We are using our own attributes, safe to proceed */
+ bcopy(wantesp+tpsize, p, wantesp[tpsize+1] + 2);
+ count += wantesp[tpsize+1] + 2;
+ p += wantesp[tpsize+1] + 2;
+
+ if (attah != NULL) {
+ /* We are using our own attributes, safe to proceed */
+ bcopy(wantesp+tasize, p, wantesp[tasize+1] + 2);
+ count += wantesp[tasize+1] + 2;
+ p += wantesp[tasize+1] + 2;
+ }
+ }
+ }
+
+ if (wantah != NULL && offerah != NULL && (st->flags & IPSEC_OPT_AUTH)) {
+ /* Take the AH section */
+ u_int8_t *tp = wantah;
+ u_int16_t tpsize = 0;
+
+ attprop = NULL;
+ /* We travers the AH section and look for the first AH attribute */
+ while (tpsize < wantahsize) {
+ if (isinattrib(offerah, offerahsize, tp[tpsize])) {
+ attprop = getattrib(tp[tpsize]);
+ if (attprop != NULL && (attprop->type & AT_AUTH))
+ break;
+ }
+ tpsize += tp[tpsize+1]+2;
+ }
+ if (tpsize >= wantahsize)
+ attprop = NULL;
+
+ if (attprop != NULL) {
+ /* Put proper header in there */
+ p[0] = AT_AH_ATTRIB;
+ p[1] = 0;
+ count += 2;
+ p += 2;
+
+ /* We are using our own attributes, safe to proceed */
+ bcopy(wantah+tpsize, p, wantah[tpsize+1] + 2);
+ count += wantah[tpsize+1] + 2;
+ p += wantah[tpsize+1] + 2;
+ }
+ }
+
+ if (count == 0) {
+ log_error(0, "Offered and wanted list of attributes did not have a common subset in select_attrib()");
+ return -1;
+ }
+
+ if ((*attributes=calloc(count,sizeof(u_int8_t))) == NULL) {
+ log_error(1, "Out of memory for SPI attributes (%d)", count);
+ return -1;
+ }
+ *attribsize = count;
+ bcopy(buffer, *attributes, count);
+
+ return 0;
+}
+/*
* Removes whitespace from the end of a string
*/
diff --git a/sbin/ipsec/photurisd/config.h b/sbin/ipsec/photurisd/config.h
index 5f54072e229..6f0dbfe8244 100644
--- a/sbin/ipsec/photurisd/config.h
+++ b/sbin/ipsec/photurisd/config.h
@@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* $Id: config.h,v 1.3 1997/07/23 12:28:47 provos Exp $ */
+/* $Id: config.h,v 1.4 1998/03/04 11:43:17 provos Exp $ */
/*
* config.h:
* handling config
@@ -99,6 +99,12 @@ void reconfig(int sig);
#define OPT_TSRC "tsrc"
#define OPT_TDST "tdst"
+struct cfgx {
+ struct cfgx *next;
+ char *name;
+ int id;
+};
+
EXTERN int bin2hex(char *, int *, u_int8_t *, u_int16_t);
EXTERN char *chomp(char *);
@@ -113,6 +119,7 @@ EXTERN int init_signals(void);
EXTERN int pick_scheme(u_int8_t **, u_int16_t *, u_int8_t *, u_int16_t);
EXTERN int pick_attrib(struct stateob *, u_int8_t **, u_int16_t *);
+EXTERN int select_attrib(struct stateob *, u_int8_t **, u_int16_t *);
#endif /* _CONFIG_H_ */
diff --git a/sbin/ipsec/photurisd/encrypt.h b/sbin/ipsec/photurisd/encrypt.h
index a9f8e99bade..5da050a1a8e 100644
--- a/sbin/ipsec/photurisd/encrypt.h
+++ b/sbin/ipsec/photurisd/encrypt.h
@@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* $Id: encrypt.h,v 1.1 1997/07/18 22:48:48 provos Exp $ */
+/* $Id: encrypt.h,v 1.2 1998/03/04 11:43:18 provos Exp $ */
/*
* encrypt.h:
* prototypes for photuris_packet_encrypt.c
@@ -46,8 +46,6 @@
#define EXTERN extern
#endif
-EXTERN int packet_make_iv(u_int32_t *iv, u_int32_t *packet);
-
EXTERN int packet_create_padding(struct stateob *st, u_int16_t size,
u_int8_t *padd, u_int16_t *rsize);
EXTERN int packet_encrypt(struct stateob *st,
diff --git a/sbin/ipsec/photurisd/handle_identity_request.c b/sbin/ipsec/photurisd/handle_identity_request.c
index 73ac171827a..fee093ad3e5 100644
--- a/sbin/ipsec/photurisd/handle_identity_request.c
+++ b/sbin/ipsec/photurisd/handle_identity_request.c
@@ -34,7 +34,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: handle_identity_request.c,v 1.4 1997/09/02 17:26:36 provos Exp $";
+static char rcsid[] = "$Id: handle_identity_request.c,v 1.5 1998/03/04 11:43:20 provos Exp $";
#endif
#include <stdio.h>
@@ -55,19 +55,37 @@ static char rcsid[] = "$Id: handle_identity_request.c,v 1.4 1997/09/02 17:26:36
#include "errlog.h"
#include "schedule.h"
#include "attributes.h"
+#include "md5.h"
#ifdef IPSEC
#include "kernel.h"
#endif
+#ifdef DEBUG
+#include "packet.h"
+#endif
int
handle_identity_request(u_char *packet, int size, char *address,
char *local_address)
{
+ struct packet_sub parts[] = {
+ { "IDChoice", FLD_ATTRIB, FMD_ATT_ONE, 0, },
+ { "Identity", FLD_VARPRE, 0, 0, },
+ { "Verification", FLD_VARPRE, 0, 0, },
+ { "Attributes", FLD_ATTRIB, FMD_ATT_FILL, 0, },
+ { NULL }
+ };
+
+ struct packet id_msg = {
+ "Identity Request",
+ IDENTITY_MESSAGE_MIN, 0, parts
+ };
+
struct identity_message *header;
struct stateob *st;
struct spiob *spi;
+ MD5_CTX ctx;
u_int8_t *p, *attributes;
- u_int16_t i, asize, attribsize, tmp;
+ u_int16_t i, attribsize, tmp;
u_int8_t signature[22]; /* XXX - constant */
if (size < IDENTITY_MESSAGE_MIN)
@@ -95,31 +113,45 @@ handle_identity_request(u_char *packet, int size, char *address,
goto verification_failed;
}
- /* Verify message */
- if (!(i = get_identity_verification_size(st, IDENTITY_MESSAGE_CHOICE(header))))
- goto verification_failed;
+#ifdef DEBUG
+ printf("Identity-Request (after decryption):\n");
+ packet_dump(packet, size, 0);
+#endif
+ /* Verify message structure */
+ if (packet_check((u_int8_t *)header, size - packet[size-1], &id_msg) == -1) {
+ log_error(0, "bad packet structure in handle_identity_request()");
+ return -1;
+ }
- asize = IDENTITY_MESSAGE_MIN;
+#ifdef DEBUG
+ packet_ordered_dump(packet, size - packet[size-1], &id_msg);
+#endif
- p = IDENTITY_MESSAGE_CHOICE(header);
- asize += p[1] + 2;
- p += p[1] + 2;
- asize += varpre2octets(p);
- p += varpre2octets(p);
+ /* Create a signature of this packet */
+ MD5Init(&ctx);
+ MD5Update(&ctx, packet, size);
+ MD5Final(signature, &ctx);
- attributes = p + i;
- asize += i; /* Verification size */
- asize += packet[size-1]; /* Padding size */
- attribsize = 0;
- while(asize + attribsize < size)
- attribsize += attributes[attribsize+1] + 2;
+ if (st->phase != VALUE_RESPONSE) {
+ /*
+ * Compare with the identity request which got verified
+ * initially. If matching resend our response.
+ */
- asize += attribsize;
+ if (bcmp(signature, st->packetsig, sizeof(st->packetsig)))
+ goto verification_failed;
- if (asize != size) {
- log_error(0, "wrong packet size in handle_identity_request()");
+ /* We got send the old packet again */
+ bcopy(st->packet, packet_buffer, st->packetlen);
+ packet_size = st->packetlen;
+
+ send_packet();
return 0;
- }
+ } else
+ bcopy(signature, st->packetsig, sizeof(st->packetsig));
+
+ attributes = parts[3].where;
+ attribsize = parts[3].size;
if (!isattribsubset(st->oSPIoattrib,st->oSPIoattribsize,
attributes, attribsize)) {
@@ -127,86 +159,81 @@ handle_identity_request(u_char *packet, int size, char *address,
return 0;
}
- if (i > sizeof(signature)) {
- log_error(0, "verification too long in handle_identity_request()");
+ i = get_identity_verification_size(st, IDENTITY_MESSAGE_CHOICE(header));
+ if (!i || i != parts[2].size || i > sizeof(signature)) {
+ log_error(0, "verification size mismatch in handle_identity_request()");
goto verification_failed;
}
- bcopy(p, signature, i);
- bzero(p, i);
-
- if (st->phase == VALUE_RESPONSE) {
- /* Fill the state object, but only if we have not dont so before */
- if (st->uSPIidentver == NULL) {
- if((st->uSPIidentver = calloc(i, sizeof(u_int8_t))) == NULL) {
- log_error(1, "calloc() in handle_identity_request()");
- goto verification_failed;
- }
- bcopy(signature, st->uSPIidentver, i);
- st->uSPIidentversize = i;
- }
-
- p = IDENTITY_MESSAGE_CHOICE(header);
- if (st->uSPIidentchoice == NULL) {
- if((st->uSPIidentchoice = calloc(p[1]+2, sizeof(u_int8_t))) == NULL) {
- log_error(1, "calloc() in handle_identity_request()");
- goto verification_failed;
- }
- bcopy(p, st->uSPIidentchoice, p[1]+2);
- st->uSPIidentchoicesize = p[1]+2;
- }
+ bcopy(parts[2].where, signature, i);
- p += p[1] + 2;
- if (st->uSPIident == NULL) {
- if((st->uSPIident = calloc(varpre2octets(p), sizeof(u_int8_t))) == NULL) {
- log_error(1,"calloc() in handle_identity_request()");
- goto verification_failed;
- }
- bcopy(p, st->uSPIident, varpre2octets(p));
+ /* Fill the state object, but only if we have not dont so before */
+ if (st->uSPIidentver == NULL) {
+ if((st->uSPIidentver = calloc(i, sizeof(u_int8_t))) == NULL) {
+ log_error(1, "calloc() in handle_identity_request()");
+ goto verification_failed;
}
+ bcopy(signature, st->uSPIidentver, i);
+ st->uSPIidentversize = i;
+ }
- if (st->uSPIattrib == NULL) {
- if((st->uSPIattrib = calloc(attribsize, sizeof(u_int8_t))) == NULL) {
- log_error(1, "calloc() in handle_identity_request()");
- return -1;
- }
- bcopy(attributes, st->uSPIattrib, attribsize);
- st->uSPIattribsize = attribsize;
+ p = IDENTITY_MESSAGE_CHOICE(header);
+ if (st->uSPIidentchoice == NULL) {
+ if((st->uSPIidentchoice = calloc(p[1]+2, sizeof(u_int8_t))) == NULL) {
+ log_error(1, "calloc() in handle_identity_request()");
+ goto verification_failed;
}
-
- if (st->oSPIident == NULL &&
- get_secrets(st, (ID_REMOTE|ID_LOCAL)) == -1) {
- log_error(0, "get_secrets() in in handle_identity_request()");
+ bcopy(p, st->uSPIidentchoice, p[1]+2);
+ st->uSPIidentchoicesize = p[1]+2;
+ }
+
+ p += p[1] + 2;
+ if (st->uSPIident == NULL) {
+ if((st->uSPIident = calloc(varpre2octets(p), sizeof(u_int8_t))) == NULL) {
+ log_error(1,"calloc() in handle_identity_request()");
goto verification_failed;
}
-
+ bcopy(p, st->uSPIident, varpre2octets(p));
}
-
- if (!verify_identity_verification(st, signature, packet, size)) {
- if (st->phase != SPI_UPDATE) {
- /*
- * Clean up everything used from this packet
- * but only if we did not get a valid packet before.
- * Otherwise this could be used as Denial of Service.
- */
- free(st->uSPIidentchoice);
- st->uSPIidentchoice = NULL; st->uSPIidentchoicesize = 0;
- free(st->uSPIidentver);
- st->uSPIidentver = NULL; st->uSPIidentversize = 0;
- free(st->uSPIattrib);
- st->uSPIattrib = NULL; st->uSPIattribsize = 0;
- free(st->uSPIident);
- st->uSPIident = NULL;
- free(st->oSPIident);
- st->oSPIident = NULL;
-
- /* Clean up secrets */
- free(st->oSPIsecret);
- st->oSPIsecret = NULL; st->oSPIsecretsize = 0;
- free(st->uSPIsecret);
- st->uSPIsecret = NULL; st->uSPIsecretsize = 0;
+
+ if (st->uSPIattrib == NULL) {
+ if((st->uSPIattrib = calloc(attribsize, sizeof(u_int8_t))) == NULL) {
+ log_error(1, "calloc() in handle_identity_request()");
+ return -1;
}
-
+ bcopy(attributes, st->uSPIattrib, attribsize);
+ st->uSPIattribsize = attribsize;
+ }
+
+ if (st->oSPIident == NULL &&
+ get_secrets(st, (ID_REMOTE|ID_LOCAL)) == -1) {
+ log_error(0, "get_secrets() in in handle_identity_request()");
+ goto verification_failed;
+ }
+
+ if (!verify_identity_verification(st, signature, packet, size)) {
+ /*
+ * Clean up everything used from this packet
+ * but only if we did not get a valid packet before.
+ * Otherwise this could be used as Denial of Service.
+ */
+ free(st->uSPIidentchoice);
+ st->uSPIidentchoice = NULL; st->uSPIidentchoicesize = 0;
+ free(st->uSPIidentver);
+ st->uSPIidentver = NULL; st->uSPIidentversize = 0;
+ free(st->uSPIattrib);
+ st->uSPIattrib = NULL; st->uSPIattribsize = 0;
+ free(st->uSPIident);
+ st->uSPIident = NULL;
+ free(st->oSPIident);
+ st->oSPIident = NULL;
+
+ /* Clean up secrets */
+ free(st->oSPIsecret);
+ st->oSPIsecret = NULL; st->oSPIsecretsize = 0;
+ free(st->uSPIsecret);
+ st->uSPIsecret = NULL; st->uSPIsecretsize = 0;
+
verification_failed:
log_error(0, "verification failed in handle_identity_request()");
packet_size = PACKET_BUFFER_SIZE;
@@ -217,15 +244,6 @@ handle_identity_request(u_char *packet, int size, char *address,
return 0;
}
- if (st->phase != VALUE_RESPONSE) {
- /* We got send the old packet again */
- bcopy(st->packet, packet_buffer, st->packetlen);
- packet_size = st->packetlen;
-
- send_packet();
- return 0;
- }
-
/* Create SPI + choice of attributes */
if(make_spi(st, local_address, st->oSPI, &(st->olifetime),
&(st->oSPIattrib), &(st->oSPIattribsize)) == -1) {
diff --git a/sbin/ipsec/photurisd/handle_identity_response.c b/sbin/ipsec/photurisd/handle_identity_response.c
index a0cbedb0839..8674421c8f7 100644
--- a/sbin/ipsec/photurisd/handle_identity_response.c
+++ b/sbin/ipsec/photurisd/handle_identity_response.c
@@ -34,7 +34,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: handle_identity_response.c,v 1.4 1997/09/02 17:26:37 provos Exp $";
+static char rcsid[] = "$Id: handle_identity_response.c,v 1.5 1998/03/04 11:43:21 provos Exp $";
#endif
#include <stdio.h>
@@ -60,16 +60,32 @@ static char rcsid[] = "$Id: handle_identity_response.c,v 1.4 1997/09/02 17:26:37
#ifdef IPSEC
#include "kernel.h"
#endif
+#ifdef DEBUG
+#include "packet.h"
+#endif
int
handle_identity_response(u_char *packet, int size, char *address,
char *local_address)
{
+ struct packet_sub parts[] = {
+ { "IDChoice", FLD_ATTRIB, FMD_ATT_ONE, 0, },
+ { "Identity", FLD_VARPRE, 0, 0, },
+ { "Verification", FLD_VARPRE, 0, 0, },
+ { "Attributes", FLD_ATTRIB, FMD_ATT_FILL, 0, },
+ { NULL }
+ };
+
+ struct packet id_msg = {
+ "Identity Response",
+ IDENTITY_MESSAGE_MIN, 0, parts
+ };
+
struct identity_message *header;
struct stateob *st;
struct spiob *spi;
- u_int8_t *p, *attributes;
- u_int16_t i, asize, attribsize, tmp;
+ u_int8_t *attributes;
+ u_int16_t i, attribsize, tmp;
u_int8_t signature[22]; /* XXX - constant */
if (size < IDENTITY_MESSAGE_MIN)
@@ -91,31 +107,25 @@ handle_identity_response(u_char *packet, int size, char *address,
goto verification_failed;
}
- /* Verify message */
- if (!(i = get_identity_verification_size(st, IDENTITY_MESSAGE_CHOICE(header))))
- goto verification_failed;
-
- asize = IDENTITY_MESSAGE_MIN;
-
- p = IDENTITY_MESSAGE_CHOICE(header);
- asize += p[1] + 2;
- p += p[1] + 2;
- asize += varpre2octets(p);
- p += varpre2octets(p);
-
- attributes = p + i;
- asize += i; /* Verification size */
- asize += packet[size-1]; /* Padding size */
- attribsize = 0;
- while(asize + attribsize < size)
- attribsize += attributes[attribsize+1] + 2;
-
- asize += attribsize;
+#ifdef DEBUG
+ printf("Identity Response (after decryption):\n");
+ packet_dump((u_int8_t *)header, size, 0);
+#endif
+ /* Verify message structure */
+ if (packet_check(packet, size - packet[size-1], &id_msg) == -1) {
+ log_error(0, "bad packet structure in handle_identity_response()");
+ return -1;
+ }
- if (asize != size) {
- log_error(0, "wrong packet size in handle_identity_response()");
- return 0;
+ i = get_identity_verification_size(st, IDENTITY_MESSAGE_CHOICE(header));
+ if (!i || i != parts[2].size || i >sizeof(signature)) {
+ log_error(0, "verification size mismatch in handle_identity_response()");
+ goto verification_failed;
}
+ bcopy(parts[2].where, signature, parts[2].size);
+
+ attributes = parts[3].where;
+ attribsize = parts[3].size;
if (!isattribsubset(st->oSPIoattrib,st->oSPIoattribsize,
attributes, attribsize)) {
@@ -123,51 +133,34 @@ handle_identity_response(u_char *packet, int size, char *address,
return 0;
}
- if (i > sizeof(signature)) {
- log_error(0, "verification too long in handle_identity_response()");
- goto verification_failed;
- }
-
- bcopy(p, signature, i);
- bzero(p, i);
/* Fill the state object */
- if (st->uSPIidentver == NULL) {
- if((st->uSPIidentver = calloc(i, sizeof(u_int8_t))) == NULL) {
- log_error(1, "calloc() in handle_identity_response()");
- goto verification_failed;
- }
- bcopy(signature, st->uSPIidentver, i);
- st->uSPIidentversize = i;
+ if((st->uSPIidentver = calloc(i, sizeof(u_int8_t))) == NULL) {
+ log_error(1, "calloc() in handle_identity_response()");
+ goto verification_failed;
}
+ bcopy(signature, st->uSPIidentver, i);
+ st->uSPIidentversize = i;
- p = IDENTITY_MESSAGE_CHOICE(header);
- if (st->uSPIidentchoice == NULL) {
- if((st->uSPIidentchoice = calloc(p[1]+2, sizeof(u_int8_t))) == NULL) {
- log_error(1, "calloc() in handle_identity_response()");
- goto verification_failed;
- }
- bcopy(p, st->uSPIidentchoice, p[1]+2);
- st->uSPIidentchoicesize = p[1]+2;
+ if((st->uSPIidentchoice = calloc(parts[0].size, sizeof(u_int8_t))) == NULL) {
+ log_error(1, "calloc() in handle_identity_response()");
+ goto verification_failed;
}
+ bcopy(parts[0].where, st->uSPIidentchoice, parts[0].size);
+ st->uSPIidentchoicesize = parts[0].size;
- p += p[1] + 2;
- if (st->uSPIident == NULL) {
- if((st->uSPIident = calloc(varpre2octets(p), sizeof(u_int8_t))) == NULL) {
- log_error(1, "calloc() in handle_identity_response()");
- goto verification_failed;
- }
- bcopy(p, st->uSPIident, varpre2octets(p));
+ if((st->uSPIident = calloc(parts[1].size, sizeof(u_int8_t))) == NULL) {
+ log_error(1, "calloc() in handle_identity_response()");
+ goto verification_failed;
}
+ bcopy(parts[1].where, st->uSPIident, parts[1].size);
- if (st->uSPIattrib == NULL) {
- if((st->uSPIattrib = calloc(attribsize, sizeof(u_int8_t))) == NULL) {
- log_error(1, "calloc() in handle_identity_response()");
- goto verification_failed;
- }
- bcopy(attributes, st->uSPIattrib, attribsize);
- st->uSPIattribsize = attribsize;
+ if((st->uSPIattrib = calloc(attribsize, sizeof(u_int8_t))) == NULL) {
+ log_error(1, "calloc() in handle_identity_response()");
+ goto verification_failed;
}
+ bcopy(attributes, st->uSPIattrib, attribsize);
+ st->uSPIattribsize = attribsize;
if (get_secrets(st, ID_REMOTE) == -1) {
log_error(0, "get_secrets() in in handle_identity_response()");
diff --git a/sbin/ipsec/photurisd/handle_spi_needed.c b/sbin/ipsec/photurisd/handle_spi_needed.c
index 2db8f8e81cd..0cdb1946971 100644
--- a/sbin/ipsec/photurisd/handle_spi_needed.c
+++ b/sbin/ipsec/photurisd/handle_spi_needed.c
@@ -34,7 +34,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: handle_spi_needed.c,v 1.4 1997/09/02 17:26:39 provos Exp $";
+static char rcsid[] = "$Id: handle_spi_needed.c,v 1.5 1998/03/04 11:43:23 provos Exp $";
#endif
#include <stdio.h>
@@ -63,11 +63,20 @@ int
handle_spi_needed(u_char *packet, int size, char *address,
char *local_address)
{
+ struct packet_sub parts[] = {
+ { "Verification", FLD_VARPRE, 0, 0, },
+ { "Attributes", FLD_ATTRIB, FMD_ATT_FILL, 0, },
+ { NULL }
+ };
+ struct packet spi_msg = {
+ "SPI Needed",
+ SPI_NEEDED_MIN, 0, parts
+ };
struct spi_needed *header;
struct stateob *st;
struct spiob *spi;
- u_int8_t *p, *attributes;
- u_int16_t i, asize, attribsize, tmp;
+ u_int8_t *attributes;
+ u_int16_t i, attribsize, tmp;
u_int8_t signature[22]; /* XXX - constant */
if (size < SPI_NEEDED_MIN)
@@ -95,26 +104,21 @@ handle_spi_needed(u_char *packet, int size, char *address,
goto verification_failed;
}
- /* Verify message */
- if (!(i = get_validity_verification_size(st)))
- goto verification_failed;
-
- asize = SPI_NEEDED_MIN + i;
-
- p = SPI_NEEDED_VERIFICATION(header);
-
- attributes = p + i;
- asize += packet[size-1]; /* Padding size */
- attribsize = 0;
- while(asize + attribsize < size)
- attribsize += attributes[attribsize+1] + 2;
-
- asize += attribsize;
+ /* Verify message structure*/
+ if (packet_check((u_int8_t *)header, size - packet[size-1], &spi_msg) == -1) {
+ log_error(0, "bad packet structure in handle_spi_update()");
+ return -1;
+ }
- if (asize != size) {
- log_error(0, "wrong packet size in handle_spi_needed()");
- return 0;
+ i = get_validity_verification_size(st);
+ if (!i || i != parts[0].size || i > sizeof(signature)) {
+ log_error(0, "verification size mismatch in handle_spi_needed()");
+ goto verification_failed;
}
+ bcopy(parts[0].where, signature, i);
+
+ attributes = parts[1].where;
+ attribsize = parts[1].size;
if (!isattribsubset(st->oSPIoattrib,st->oSPIoattribsize,
attributes, attribsize)) {
@@ -122,14 +126,6 @@ handle_spi_needed(u_char *packet, int size, char *address,
return 0;
}
- if (i > sizeof(signature)) {
- log_error(0, "verification too long in handle_spi_needed()");
- goto verification_failed;
- }
-
- bcopy(p, signature, i);
- bzero(p, i);
-
if (!verify_validity_verification(st, signature, packet, size)) {
verification_failed:
log_error(0, "verification failed in handle_spi_needed()");
diff --git a/sbin/ipsec/photurisd/handle_spi_update.c b/sbin/ipsec/photurisd/handle_spi_update.c
index 84ef551e5eb..3d5e284c867 100644
--- a/sbin/ipsec/photurisd/handle_spi_update.c
+++ b/sbin/ipsec/photurisd/handle_spi_update.c
@@ -34,7 +34,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: handle_spi_update.c,v 1.4 1997/09/02 17:26:40 provos Exp $";
+static char rcsid[] = "$Id: handle_spi_update.c,v 1.5 1998/03/04 11:43:24 provos Exp $";
#endif
#include <stdio.h>
@@ -63,12 +63,21 @@ int
handle_spi_update(u_char *packet, int size, char *address,
char *local_address)
{
+ struct packet_sub parts[] = {
+ { "Verification", FLD_VARPRE, 0, 0, },
+ { "Attributes", FLD_ATTRIB, FMD_ATT_FILL, 0, },
+ { NULL }
+ };
+ struct packet spi_msg = {
+ "SPI Update",
+ SPI_UPDATE_MIN, 0, parts
+ };
struct spi_update *header;
struct stateob *st;
struct spiob *spi;
time_t lifetime;
- u_int8_t *p, *attributes;
- u_int16_t i, asize, attribsize, tmp;
+ u_int8_t *attributes;
+ u_int16_t i, attribsize, tmp;
u_int8_t signature[22]; /* XXX - constant */
if (size < SPI_UPDATE_MIN)
@@ -96,26 +105,21 @@ handle_spi_update(u_char *packet, int size, char *address,
goto verification_failed;
}
- /* Verify message */
- if (!(i = get_validity_verification_size(st)))
- goto verification_failed;
-
- asize = SPI_UPDATE_MIN + i;
-
- p = SPI_UPDATE_VERIFICATION(header);
-
- attributes = p + i;
- asize += packet[size-1]; /* Padding size */
- attribsize = 0;
- while(asize + attribsize < size)
- attribsize += attributes[attribsize+1] + 2;
-
- asize += attribsize;
+ /* Verify message structure*/
+ if (packet_check((u_int8_t *)header, size - packet[size-1], &spi_msg) == -1) {
+ log_error(0, "bad packet structure in handle_spi_update()");
+ return -1;
+ }
- if (asize != size) {
- log_error(0, "wrong packet size in handle_spi_update()");
- return 0;
+ i = get_validity_verification_size(st);
+ if (!i || i != parts[0].size || i > sizeof(signature)) {
+ log_error(0, "verification size mismatch in handle_spi_update()");
+ goto verification_failed;
}
+ bcopy(parts[0].where, signature, i);
+
+ attributes = parts[1].where;
+ attribsize = parts[1].size;
if (!isattribsubset(st->oSPIoattrib,st->oSPIoattribsize,
attributes, attribsize)) {
@@ -123,14 +127,6 @@ handle_spi_update(u_char *packet, int size, char *address,
return 0;
}
- if (i > sizeof(signature)) {
- log_error(0, "verification too long in handle_spi_update()");
- goto verification_failed;
- }
-
- bcopy(p, signature, i);
- bzero(p, i);
-
if (!verify_validity_verification(st, signature, packet, size)) {
verification_failed:
log_error(0, "verification failed in handle_spi_update()");
diff --git a/sbin/ipsec/photurisd/handle_value_request.c b/sbin/ipsec/photurisd/handle_value_request.c
index b3df46b3639..614061a42de 100644
--- a/sbin/ipsec/photurisd/handle_value_request.c
+++ b/sbin/ipsec/photurisd/handle_value_request.c
@@ -34,7 +34,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: handle_value_request.c,v 1.4 1997/09/02 17:26:40 provos Exp $";
+static char rcsid[] = "$Id: handle_value_request.c,v 1.5 1998/03/04 11:43:26 provos Exp $";
#endif
#include <stdio.h>
@@ -63,17 +63,31 @@ handle_value_request(u_char *packet, int size,
u_int8_t *schemes, u_int16_t ssize)
{
+ struct packet_sub parts[] = {
+ { "Exchange Value", FLD_VARPRE, 0, 0, },
+ { "Offered Attributes", FLD_ATTRIB, FMD_ATT_FILL, 0, },
+ { NULL }
+ };
+ struct packet vr_msg = {
+ "Value Request",
+ VALUE_REQUEST_MIN, 0, parts
+ };
struct value_request *header;
struct stateob *st;
mpz_t test, gen, mod;
u_int8_t *p, *modp, *refp, *genp = NULL;
- u_int16_t i, sstart, vsize, asize, modsize, modflag;
+ u_int16_t sstart, vsize, modsize, modflag;
u_int8_t scheme_ref[2];
u_int8_t rcookie[COOKIE_SIZE];
if (size < VALUE_REQUEST_MIN)
return -1; /* packet too small */
+ if (packet_check(packet, size, &vr_msg) == -1) {
+ log_error(0, "bad packet structure in handle_value_request()");
+ return -1;
+ }
+
header = (struct value_request *) packet;
st = state_find_cookies(address, header->icookie, header->rcookie);
@@ -99,11 +113,7 @@ handle_value_request(u_char *packet, int size,
}
/* Check exchange value - XXX doesn't check long form */
- p = VALUE_REQUEST_VALUE(header);
- vsize = varpre2octets(p);
- asize = VALUE_REQUEST_MIN + vsize;
- if (asize >= size)
- return -1; /* Exchange value too big */
+ vsize = parts[0].size;
/* Check schemes - selected length is in exchange value*/
sstart = 0;
@@ -137,19 +147,8 @@ handle_value_request(u_char *packet, int size,
if (sstart >= ssize)
return -1; /* Did not find a scheme - XXX log */
- p = VALUE_REQUEST_VALUE(header) + vsize;
-
- /* Check attributes */
- i = 0;
- while(asize + i < size)
- i += p[i+1] + 2;
-
- /* This 'i' is used below as well as p */
- if (asize + i != size)
- return -1; /* attributes dont match udp length */
-
/* now check the exchange value */
- mpz_init_set_varpre(test, VALUE_REQUEST_VALUE(header));
+ mpz_init_set_varpre(test, parts[0].where);
mpz_init_set_varpre(mod, modp);
mpz_init(gen);
if (exchange_set_generator(gen, header->scheme, genp) == -1 ||
@@ -170,13 +169,13 @@ handle_value_request(u_char *packet, int size,
st->flags = IPSEC_OPT_ENC|IPSEC_OPT_AUTH;
/* Fill the state object */
- st->uSPIoattrib = calloc(i, sizeof(u_int8_t));
+ st->uSPIoattrib = calloc(parts[1].size, sizeof(u_int8_t));
if (st->uSPIoattrib == NULL) {
state_value_reset(st);
return -1;
}
- bcopy(p, st->uSPIoattrib, i);
- st->uSPIoattribsize = i;
+ bcopy(parts[1].where, st->uSPIoattrib, parts[1].size);
+ st->uSPIoattribsize = parts[1].size;
/* Save scheme, which will be used by both parties */
vsize = 2 + varpre2octets(modp);
@@ -204,19 +203,19 @@ handle_value_request(u_char *packet, int size,
#ifdef DEBUG
{
int i = BUFFER_SIZE;
- bin2hex(buffer, &i, VALUE_REQUEST_VALUE(header), varpre2octets(VALUE_REQUEST_VALUE(header)));
+ bin2hex(buffer, &i, parts[0].where, varpre2octets(VALUE_REQUEST_VALUE(header)));
printf("Got exchange value 0x%s\n", buffer);
}
#endif
/* Set exchange value */
- st->texchangesize = varpre2octets(VALUE_REQUEST_VALUE(header));
+ st->texchangesize = parts[0].size;
st->texchange = calloc(st->texchangesize, sizeof(u_int8_t));
if (st->texchange == NULL) {
log_error(1, "calloc() in handle_value_request()");
return -1;
}
- bcopy(VALUE_REQUEST_VALUE(header), st->texchange, st->texchangesize);
+ bcopy(parts[0].where, st->texchange, st->texchangesize);
/* Fill in the state object with generic data */
@@ -225,6 +224,7 @@ handle_value_request(u_char *packet, int size,
st->counter = header->counter;
bcopy(header->icookie, st->icookie, COOKIE_SIZE);
bcopy(header->rcookie, st->rcookie, COOKIE_SIZE);
+ bcopy(&header->counter, st->uSPITBV, 3);
if ((st->roschemes = calloc(ssize, sizeof(u_int8_t))) == NULL) {
state_value_reset(st);
diff --git a/sbin/ipsec/photurisd/handle_value_response.c b/sbin/ipsec/photurisd/handle_value_response.c
index 2ef53dd557c..cbd542c7310 100644
--- a/sbin/ipsec/photurisd/handle_value_response.c
+++ b/sbin/ipsec/photurisd/handle_value_response.c
@@ -34,7 +34,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: handle_value_response.c,v 1.3 1997/09/02 17:26:41 provos Exp $";
+static char rcsid[] = "$Id: handle_value_response.c,v 1.4 1998/03/04 11:43:27 provos Exp $";
#endif
#include <stdlib.h>
@@ -62,15 +62,27 @@ handle_value_response(u_char *packet, int size, char *address,
char *local_address)
{
+ struct packet_sub parts[] = {
+ { "Exchange Value", FLD_VARPRE, 0, 0, },
+ { "Offered Attributes", FLD_ATTRIB, FMD_ATT_FILL, 0, },
+ { NULL }
+ };
+ struct packet vr_msg = {
+ "Value Response",
+ VALUE_RESPONSE_MIN, 0, parts
+ };
struct value_response *header;
struct stateob *st;
mpz_t test;
- u_int8_t *p;
- u_int16_t i, asize;
if (size < VALUE_RESPONSE_MIN)
return -1; /* packet too small */
+ if (packet_check(packet, size, &vr_msg) == -1) {
+ log_error(0, "bad packet structure in handle_value_response()");
+ return -1;
+ }
+
header = (struct value_response *) packet;
st = state_find_cookies(address, header->icookie, header->rcookie);
@@ -80,56 +92,43 @@ handle_value_response(u_char *packet, int size, char *address,
if (st->phase != VALUE_REQUEST)
return -1; /* We don't want this packet */
- /* Check exchange value - XXX doesn't check long form */
- p = VALUE_RESPONSE_VALUE(header);
- asize = VALUE_RESPONSE_MIN + varpre2octets(p);
- p += varpre2octets(p);
- if (asize >= size)
- return -1; /* Exchange value too big */
-
- /* Check attributes */
- i = 0;
- while(asize + i < size)
- i += p[i+1] + 2;
-
- if (asize + i != size)
- return -1; /* attributes dont match udp length */
-
/* Now check the exchange value for defects */
- mpz_init_set_varpre(test, VALUE_RESPONSE_VALUE(header));
+ mpz_init_set_varpre(test, parts[0].where);
if (!exchange_check_value(test, st->generator, st->modulus)) {
mpz_clear(test);
return 0;
}
mpz_clear(test);
+ /* Reserved Field for TBV */
+ bcopy(header->reserved, st->uSPITBV, 3);
+
/* Fill the state object */
- st->uSPIoattrib = calloc(i, sizeof(u_int8_t));
+ st->uSPIoattrib = calloc(parts[1].size, sizeof(u_int8_t));
if (st->uSPIoattrib == NULL) {
state_value_reset(st);
state_unlink(st);
return -1;
}
- bcopy(p, st->uSPIoattrib, i);
- st->uSPIoattribsize = i;
+ bcopy(parts[1].where, st->uSPIoattrib, parts[1].size);
+ st->uSPIoattribsize = parts[1].size;
#ifdef DEBUG
{
int i = BUFFER_SIZE;
- bin2hex(buffer, &i, VALUE_RESPONSE_VALUE(header),
- varpre2octets(VALUE_RESPONSE_VALUE(header)));
+ bin2hex(buffer, &i, parts[0].where, parts[0].size);
printf("Got exchange value 0x%s\n", buffer);
}
#endif
/* Set exchange value */
- st->texchangesize = varpre2octets(VALUE_RESPONSE_VALUE(header));
+ st->texchangesize = parts[0].size;
st->texchange = calloc(st->texchangesize, sizeof(u_int8_t));
if (st->texchange == NULL) {
log_error(1, "calloc() in handle_value_response()");
return -1;
}
- bcopy(VALUE_RESPONSE_VALUE(header), st->texchange, st->texchangesize);
+ bcopy(parts[0].where, st->texchange, st->texchangesize);
/* Compute the shared secret now */
compute_shared_secret(st, &(st->shared), &(st->sharedsize));
diff --git a/sbin/ipsec/photurisd/identity.c b/sbin/ipsec/photurisd/identity.c
index f5517e4508c..e4ec661fcaf 100644
--- a/sbin/ipsec/photurisd/identity.c
+++ b/sbin/ipsec/photurisd/identity.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: identity.c,v 1.4 1997/09/02 17:26:42 provos Exp $";
+static char rcsid[] = "$Id: identity.c,v 1.5 1998/03/04 11:43:29 provos Exp $";
#endif
#define _IDENTITY_C_
@@ -78,12 +78,12 @@ static union {
/* XXX - argh, cast the funtions */
static struct idxform idxform[] = {
- { HASH_MD5, MD5_SIZE, (void *)&Ctx.md5ctx,
+ { HASH_MD5, 5, MD5_SIZE, (void *)&Ctx.md5ctx,
sizeof(MD5_CTX), (void *)&Ctx2.md5ctx,
(void (*)(void *))MD5Init,
(void (*)(void *, unsigned char *, unsigned int))MD5Update,
(void (*)(unsigned char *, void *))MD5Final },
- { HASH_SHA1, SHA1_SIZE, (void *)&Ctx.sha1ctx,
+ { HASH_SHA1, 6, SHA1_SIZE, (void *)&Ctx.sha1ctx,
sizeof(SHA1_CTX), (void *)&Ctx2.sha1ctx,
(void (*)(void *))SHA1Init,
(void (*)(void *, unsigned char *, unsigned int))SHA1Update,
@@ -364,19 +364,19 @@ get_secrets(struct stateob *st, int mode)
st->oSPIident[0] = ((strlen(local_ident)+1) >> 5) & 0xFF;
st->oSPIident[1] = ((strlen(local_ident)+1) << 3) & 0xFF;
- st->oSPIsecret = calloc(strlen(local_secret)+1,sizeof(u_int8_t));
+ st->oSPIsecretsize = strlen(local_secret);
+ st->oSPIsecret = calloc(st->oSPIsecretsize,sizeof(u_int8_t));
if(st->oSPIsecret == NULL)
return -1;
- strcpy(st->oSPIsecret,local_secret);
- st->oSPIsecretsize = strlen(local_secret)+1;
+ strncpy(st->oSPIsecret, local_secret, st->oSPIsecretsize);
}
if(st->uSPIident != NULL && st->uSPIsecret == NULL &&
(mode & ID_REMOTE)) {
- st->uSPIsecret = calloc(strlen(remote_secret)+1,sizeof(u_int8_t));
+ st->uSPIsecretsize = strlen(remote_secret);
+ st->uSPIsecret = calloc(st->uSPIsecretsize,sizeof(u_int8_t));
if(st->uSPIsecret == NULL)
return -1;
- strcpy(st->uSPIsecret,remote_secret);
- st->uSPIsecretsize = strlen(remote_secret)+1;
+ strncpy(st->uSPIsecret, remote_secret, st->uSPIsecretsize);
}
return 0;
}
@@ -386,31 +386,29 @@ choose_identity(struct stateob *st, u_int8_t *packet, u_int16_t *size,
u_int8_t *attributes, u_int16_t attribsize)
{
u_int16_t rsize, asize, tmp;
+ attrib_t *ob;
int mode = 0;
rsize = *size;
/* XXX - preference of identity choice ? */
tmp = 0;
- while(attribsize>0 && !tmp) {
- switch(*attributes) {
- case AT_MD5_DP:
- case AT_SHA1_DP:
- tmp = 1;
+ while(attribsize>0) {
+ /* Check if we support this identity choice */
+ if ((ob = getattrib(*attributes)) != NULL &&
+ (ob->type & AT_ID))
break;
- default:
- if(attribsize -(*(attributes+1)+2) > attribsize) {
- attribsize=0;
- break;
- }
- attribsize -= *(attributes+1)+2;
- attributes += *(attributes+1)+2;
+
+ if(attribsize -(*(attributes+1)+2) > attribsize) {
+ attribsize=0;
break;
- }
+ }
+ attribsize -= *(attributes+1)+2;
+ attributes += *(attributes+1)+2;
}
if(attribsize == 0) {
log_error(0, "No identity choice found in offered attributes "
- "in choose_identity");
+ "in choose_identity()");
return -1;
}
@@ -440,7 +438,7 @@ choose_identity(struct stateob *st, u_int8_t *packet, u_int16_t *size,
return -1;
/* oSPIident is varpre already */
- tmp = 2+strlen(st->oSPIident+2)+1;
+ tmp = varpre2octets(st->oSPIident);
if(rsize < tmp)
return -1;
@@ -455,15 +453,27 @@ choose_identity(struct stateob *st, u_int8_t *packet, u_int16_t *size,
u_int16_t
get_identity_verification_size(struct stateob *st, u_int8_t *choice)
{
- switch(*choice) {
- case AT_MD5_DP:
- return (128/8)+2;
- case AT_SHA1_DP:
- return (160/8)+2;
- default:
+ struct idxform *hash;
+
+ if ((hash = get_hash_id(*choice)) == NULL) {
log_error(0, "Unknown identity choice: %d\n", *choice);
return 0;
}
+
+ return hash->hashsize+2;
+}
+
+/*
+ * Gets a hash corresponding with a Photuris ID
+ */
+
+struct idxform *get_hash_id(int id)
+{
+ int i;
+ for (i=0; i<sizeof(idxform)/sizeof(idxform[0]); i++)
+ if (id == idxform[i].id)
+ return &idxform[i];
+ return NULL;
}
struct idxform *get_hash(enum hashes hashtype)
@@ -481,23 +491,13 @@ create_verification_key(struct stateob *st, u_int8_t *buffer, u_int16_t *size,
int owner)
{
struct idxform *hash;
+ int id = owner ? *(st->oSPIidentchoice) : *(st->uSPIidentchoice);
- switch(owner ? *(st->oSPIidentchoice) : *(st->uSPIidentchoice)) {
- case AT_MD5_DP:
- hash = get_hash(HASH_MD5);
- break;
- case AT_SHA1_DP:
- hash = get_hash(HASH_SHA1);
- break;
- default:
- log_error(0, "Unkown identity choice %d in create_verification_key",
- owner ? *(st->oSPIidentchoice):*(st->uSPIidentchoice));
+ if ((hash = get_hash_id(id)) == NULL) {
+ log_error(0, "Unkown identity choice %d in create_verification_key", id);
return -1;
}
- if (hash == NULL)
- return -1;
-
if (*size < hash->hashsize)
return -1;
@@ -521,22 +521,12 @@ create_identity_verification(struct stateob *st, u_int8_t *buffer,
int hash_size;
struct idxform *hash;
- switch(*(st->oSPIidentchoice)) {
- case AT_MD5_DP:
- hash = get_hash(HASH_MD5);
- break;
- case AT_SHA1_DP:
- hash = get_hash(HASH_SHA1);
- break;
- default:
+ if ((hash = get_hash_id(*(st->oSPIidentchoice))) == NULL) {
log_error(0, "Unkown identity choice %d in create_verification_key",
*(st->oSPIidentchoice));
return 0;
}
- if (hash == NULL)
- return 0;
-
hash_size = idsign(st, hash, buffer+2, packet,size);
if(hash_size) {
@@ -567,22 +557,12 @@ verify_identity_verification(struct stateob *st, u_int8_t *buffer,
{
struct idxform *hash;
- switch(*(st->uSPIidentchoice)) {
- case AT_MD5_DP:
- hash = get_hash(HASH_MD5);
- break;
- case AT_SHA1_DP:
- hash = get_hash(HASH_SHA1);
- break;
- default:
+ if ((hash = get_hash_id(*(st->uSPIidentchoice))) == NULL) {
log_error(0, "Unkown identity choice %d in create_verification_key",
*(st->uSPIidentchoice));
return 0;
}
- if (hash == NULL)
- return 0;
-
if (varpre2octets(buffer) != hash->hashsize +2)
return 0;
@@ -596,7 +576,6 @@ int
idsign(struct stateob *st, struct idxform *hash, u_int8_t *signature,
u_int8_t *packet, u_int16_t psize)
{
- struct identity_message *p;
u_int8_t key[HASH_MAX];
u_int16_t keylen = HASH_MAX;
@@ -606,24 +585,15 @@ idsign(struct stateob *st, struct idxform *hash, u_int8_t *signature,
/* Our verification key */
hash->Update(hash->ctx, key, keylen);
+ /* Key fill */
+ hash->Final(NULL, hash->ctx);
- hash->Update(hash->ctx, st->icookie, COOKIE_SIZE);
- hash->Update(hash->ctx, st->rcookie, COOKIE_SIZE);
-
- /* Hash type, lifetime + spi fields */
- p = (struct identity_message *)packet;
- hash->Update(hash->ctx, (char *)&(p->type), IDENTITY_MESSAGE_MIN - 2*COOKIE_SIZE);
-
- hash->Update(hash->ctx, st->roschemes, st->roschemesize);
-
- /* Our exchange value */
- hash->Update(hash->ctx, st->exchangevalue, st->exchangesize);
- hash->Update(hash->ctx, st->oSPIoattrib, st->oSPIoattribsize);
- hash->Update(hash->ctx, st->oSPIident, strlen(st->oSPIident));
-
- /* Their exchange value */
- hash->Update(hash->ctx, st->texchange, st->texchangesize);
- hash->Update(hash->ctx, st->uSPIoattrib, st->uSPIoattribsize);
+ /*
+ * Hash Cookies, type, lifetime + spi fields +
+ * SPI owner Identity Choice + Identity
+ */
+ hash->Update(hash->ctx, packet, IDENTITY_MESSAGE_MIN +
+ st->oSPIidentchoicesize + varpre2octets(st->oSPIident));
if(st->uSPIident != NULL) {
hash->Update(hash->ctx, st->uSPIidentver, st->uSPIidentversize);
@@ -633,11 +603,24 @@ idsign(struct stateob *st, struct idxform *hash, u_int8_t *signature,
packet += IDENTITY_MESSAGE_MIN;
psize -= IDENTITY_MESSAGE_MIN + packet[1] + 2;
packet += packet[1] + 2;
- psize -= varpre2octets(packet) + 2 + MD5_SIZE;
- packet += varpre2octets(packet) + 2 + MD5_SIZE;
+ psize -= varpre2octets(packet) + 2 + hash->hashsize;
+ packet += varpre2octets(packet) + 2 + hash->hashsize;
hash->Update(hash->ctx, packet, psize);
+ /* Our exchange value */
+ hash->Update(hash->ctx, st->oSPITBV, 3);
+ hash->Update(hash->ctx, st->exchangevalue, st->exchangesize);
+ hash->Update(hash->ctx, st->oSPIoattrib, st->oSPIoattribsize);
+
+ /* Their exchange value */
+ hash->Update(hash->ctx, st->uSPITBV, 3);
+ hash->Update(hash->ctx, st->texchange, st->texchangesize);
+ hash->Update(hash->ctx, st->uSPIoattrib, st->uSPIoattribsize);
+
+ /* Responder offered schemes */
+ hash->Update(hash->ctx, st->roschemes, st->roschemesize);
+
/* Data fill */
hash->Final(NULL, hash->ctx);
@@ -654,35 +637,25 @@ idverify(struct stateob *st, struct idxform *hash, u_int8_t *signature,
u_int8_t *packet, u_int16_t psize)
{
u_int8_t digest[HASH_MAX];
- struct identity_message *p;
u_int8_t key[HASH_MAX];
u_int16_t keylen = HASH_MAX;
+ struct identity_message *p = (struct identity_message *)packet;
create_verification_key(st, key, &keylen, 0); /* User direction */
- p = (struct identity_message *)packet;
-
hash->Init(hash->ctx);
/* Their verification key */
hash->Update(hash->ctx, key, keylen);
+ /* Key fill */
+ hash->Final(NULL, hash->ctx);
- hash->Update(hash->ctx, st->icookie, COOKIE_SIZE);
- hash->Update(hash->ctx, st->rcookie, COOKIE_SIZE);
-
- /* Hash type, lifetime + spi fields */
- hash->Update(hash->ctx, (char *)&(p->type), IDENTITY_MESSAGE_MIN - 2*COOKIE_SIZE);
-
- hash->Update(hash->ctx, st->roschemes, st->roschemesize);
-
- /* Their exchange value */
- hash->Update(hash->ctx, st->texchange, st->texchangesize);
- hash->Update(hash->ctx, st->uSPIoattrib, st->uSPIoattribsize);
- hash->Update(hash->ctx, st->uSPIident, strlen(st->uSPIident));
-
- /* Our exchange value */
- hash->Update(hash->ctx, st->exchangevalue, st->exchangesize);
- hash->Update(hash->ctx, st->oSPIoattrib, st->oSPIoattribsize);
+ /*
+ * Hash Cookies, type, lifetime + spi fields +
+ * SPI owner Identity Choice + Identity
+ */
+ hash->Update(hash->ctx, packet, IDENTITY_MESSAGE_MIN +
+ st->uSPIidentchoicesize + varpre2octets(st->uSPIident));
/* Determine if the sender knew our secret already */
if(p->type != IDENTITY_REQUEST) {
@@ -692,10 +665,23 @@ idverify(struct stateob *st, struct idxform *hash, u_int8_t *signature,
packet += IDENTITY_MESSAGE_MIN;
psize -= IDENTITY_MESSAGE_MIN + packet[1] + 2;
packet += packet[1] + 2;
- psize -= varpre2octets(packet) + 2 + MD5_SIZE;
- packet += varpre2octets(packet) + 2 + MD5_SIZE;
+ psize -= varpre2octets(packet) + 2 + hash->hashsize;
+ packet += varpre2octets(packet) + 2 + hash->hashsize;
hash->Update(hash->ctx, packet, psize);
+ /* Their exchange value */
+ hash->Update(hash->ctx, st->uSPITBV, 3);
+ hash->Update(hash->ctx, st->texchange, st->texchangesize);
+ hash->Update(hash->ctx, st->uSPIoattrib, st->uSPIoattribsize);
+
+ /* Our exchange value */
+ hash->Update(hash->ctx, st->oSPITBV, 3);
+ hash->Update(hash->ctx, st->exchangevalue, st->exchangesize);
+ hash->Update(hash->ctx, st->oSPIoattrib, st->oSPIoattribsize);
+
+ /* Responder offered schemes */
+ hash->Update(hash->ctx, st->roschemes, st->roschemesize);
+
/* Data fill */
hash->Final(NULL, hash->ctx);
diff --git a/sbin/ipsec/photurisd/identity.h b/sbin/ipsec/photurisd/identity.h
index 141a8412845..46802c16bfc 100644
--- a/sbin/ipsec/photurisd/identity.h
+++ b/sbin/ipsec/photurisd/identity.h
@@ -51,11 +51,12 @@ enum hashes {
HASH_SHA1 };
struct idxform {
- enum hashes type; /* Type of the transform */
- u_int8_t hashsize; /* Size of the hash */
- void *ctx; /* Pointer to a context */
+ enum hashes type; /* Type of the transform */
+ int id; /* Photuris Attribute ID */
+ u_int8_t hashsize; /* Size of the hash */
+ void *ctx; /* Pointer to a context */
int ctxsize;
- void *ctx2; /* Pointer to a 2nd context for speedup */
+ void *ctx2; /* Pointer to a 2nd context for speedup */
void (*Init)(void *);
void (*Update)(void *, unsigned char *, unsigned int);
void (*Final)(unsigned char *, void *);
@@ -109,6 +110,7 @@ int create_identity_verification(struct stateob *st, u_int8_t *buffer,
int verify_identity_verification(struct stateob *st, u_int8_t *buffer,
u_int8_t *packet, u_int16_t size);
+struct idxform *get_hash_id(int id);
struct idxform *get_hash(enum hashes hashtype);
int create_verification_key(struct stateob *, u_int8_t *, u_int16_t *, int);
diff --git a/sbin/ipsec/photurisd/kernel.c b/sbin/ipsec/photurisd/kernel.c
index 09d33c7116b..d36d287b580 100644
--- a/sbin/ipsec/photurisd/kernel.c
+++ b/sbin/ipsec/photurisd/kernel.c
@@ -29,7 +29,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: kernel.c,v 1.4 1997/09/14 10:37:51 deraadt Exp $";
+static char rcsid[] = "$Id: kernel.c,v 1.5 1998/03/04 11:43:32 provos Exp $";
#endif
#include <sys/param.h>
@@ -73,13 +73,80 @@ static char rcsid[] = "$Id: kernel.c,v 1.4 1997/09/14 10:37:51 deraadt Exp $";
#include "config.h"
#endif
+#ifdef DEBUG
+time_t now;
+
+#define kernel_debug(x) {time(&now); printf("%.24s", ctime(&now)); printf x;}
+#else
+#define kernel_debug(x)
+#endif
+
static int sd;
+typedef struct {
+ int photuris_id;
+ int kernel_id, flags;
+} transform;
+
+/*
+ * Translation from Photuris Attributes to Kernel Transforms.
+ * For the actual ids see: draft-simpson-photuris-*.txt and
+ * draft-simpson-photuris-schemes-*.txt
+ */
+
+transform xf[] = {
+ { 5, ALG_AUTH_MD5, XF_AUTH|AH_OLD},
+ { 6, ALG_AUTH_SHA1, XF_AUTH|AH_OLD},
+ { 8, ALG_ENC_DES, XF_ENC|ESP_OLD},
+ {100, ALG_ENC_3DES, XF_ENC|ESP_NEW},
+ {101, ALG_ENC_BLF, XF_ENC|ESP_NEW},
+ {102, ALG_ENC_CAST, XF_ENC|ESP_NEW},
+ {105, ALG_AUTH_MD5, XF_AUTH|AH_NEW|ESP_NEW},
+ {106, ALG_AUTH_SHA1, XF_AUTH|AH_NEW|ESP_NEW},
+ {107, ALG_AUTH_RMD160, XF_AUTH|AH_NEW|ESP_NEW},
+};
+
+/*
+ * Translate a Photuris ID to an offset into a data structure for the
+ * corresponding Kernel transform.
+ * This makes is easier to write kernel modules for different IPSec
+ * implementations.
+ */
+
+int
+kernel_get_offset(int id)
+{
+ int i;
+
+ for (i=sizeof(xf)/sizeof(transform)-1; i >= 0; i--)
+ if (xf[i].photuris_id == id)
+ return i;
+
+ return -1;
+}
+
+/*
+ * For ESP, we can specify an additional AH transform.
+ * Not all combinations are possible.
+ * Returns AT_ENC, when the ESP transform does not allow this AH.
+ * Returns AT_AUTH, when the AH transform does not work with ESP.
+ */
+
+int
+kernel_valid(int encoff, int authoff)
+{
+ if (xf[encoff].flags & ESP_OLD)
+ return AT_ENC;
+ if (!(xf[authoff].flags & ESP_NEW))
+ return AT_AUTH;
+ return 0;
+}
+
int
init_kernel(void)
{
if ((sd = socket(AF_ENCAP, SOCK_RAW, AF_UNSPEC)) < 0)
- crit_error(1, "socket() in init_kernel()");
+ crit_error(1, "socket() for IPSec in init_kernel()");
return 1;
}
@@ -92,10 +159,8 @@ kernel_get_socket(void)
int
kernel_xf_set(struct encap_msghdr *em)
{
- if (write(sd, (char *)em, em->em_msglen) != em->em_msglen) {
- log_error(1, "write() in kernel_xf_set()");
+ if (write(sd, (char *)em, em->em_msglen) != em->em_msglen)
return 0;
- }
return 1;
}
@@ -115,6 +180,8 @@ kernel_reserve_spi(char *srcaddress, int options)
u_int32_t spi;
int proto;
+ kernel_debug(("kernel_reserve_spi: %s\n", srcaddress));
+
if ((options & (IPSEC_OPT_ENC|IPSEC_OPT_AUTH)) !=
(IPSEC_OPT_ENC|IPSEC_OPT_AUTH)) {
switch(options & (IPSEC_OPT_ENC|IPSEC_OPT_AUTH)) {
@@ -144,6 +211,8 @@ kernel_reserve_single_spi(char *srcaddress, u_int32_t spi, int proto)
{
struct encap_msghdr *em;
+ kernel_debug(("kernel_reserve_single_spi: %s, %08x\n", srcaddress, spi));
+
bzero(buffer, EMT_ENABLESPI_FLEN);
em = (struct encap_msghdr *)buffer;
@@ -156,8 +225,10 @@ kernel_reserve_single_spi(char *srcaddress, u_int32_t spi, int proto)
em->em_gen_dst.s_addr = inet_addr(srcaddress);
em->em_gen_sproto = proto;
- if (!kernel_xf_set(em))
+ if (!kernel_xf_set(em)) {
+ log_error(1, "kernel_xf_set() in kernel_reserve_single_spi()");
return 0;
+ }
if (!kernel_xf_read(em, EMT_RESERVESPI_FLEN))
return 0;
@@ -166,88 +237,173 @@ kernel_reserve_single_spi(char *srcaddress, u_int32_t spi, int proto)
}
int
-kernel_md5(char *srcaddress, char *dstaddress, u_int8_t *spi, u_int8_t *secret,
- int tunnel)
+kernel_ah(attrib_t *ob, struct spiob *SPI, u_int8_t *secrets)
{
struct encap_msghdr *em;
- struct ah_old_xencap *xd;
- int klen;
+ struct ah_old_xencap *xdo;
+ struct ah_new_xencap *xdn;
- klen = MD5_KEYLEN/8;
-
- bzero(buffer, EMT_SETSPI_FLEN + 4 + klen);
+ if (!(xf[ob->koff].flags & XF_AUTH)) {
+ log_error(0, "%d is not an auth transform in kernel_ah()", ob->id);
+ return -1;
+ }
em = (struct encap_msghdr *)buffer;
+
+ if (xf[ob->koff].flags & AH_OLD) {
+ bzero(buffer, EMT_SETSPI_FLEN + 4 + ob->klen);
+
+ em->em_msglen = EMT_SETSPI_FLEN + AH_OLD_XENCAP_LEN + ob->klen;
+
+ em->em_alg = XF_OLD_AH;
+
+ xdo = (struct ah_old_xencap *)(em->em_dat);
+
+ xdo->amx_hash_algorithm = xf[ob->koff].kernel_id;
+ xdo->amx_keylen = ob->klen;
- em->em_msglen = EMT_SETSPI_FLEN + AH_OLD_XENCAP_LEN + klen;
+ bcopy(secrets, xdo->amx_key, ob->klen);
+
+ } else {
+ bzero(buffer, EMT_SETSPI_FLEN + AH_NEW_XENCAP_LEN + ob->klen);
+
+ em->em_msglen = EMT_SETSPI_FLEN + AH_NEW_XENCAP_LEN + ob->klen;
+
+ em->em_alg = XF_NEW_AH;
+
+ xdn = (struct ah_new_xencap *)(em->em_dat);
+
+ xdn->amx_hash_algorithm = xf[ob->koff].kernel_id;
+ xdn->amx_wnd = 16;
+ xdn->amx_keylen = ob->klen;
+
+ bcopy(secrets, xdn->amx_key, ob->klen);
+ }
+
em->em_version = PFENCAP_VERSION_1;
em->em_type = EMT_SETSPI;
- em->em_spi = htonl((spi[0]<<24) + (spi[1]<<16) +
- (spi[2]<<8) + spi[3]);
- em->em_src.s_addr = inet_addr(srcaddress);
- em->em_dst.s_addr = inet_addr(dstaddress);
-
- if (tunnel) {
- em->em_osrc.s_addr = inet_addr(srcaddress);
- em->em_odst.s_addr = inet_addr(dstaddress);
+ em->em_spi = htonl((SPI->SPI[0]<<24) + (SPI->SPI[1]<<16) +
+ (SPI->SPI[2]<<8) + SPI->SPI[3]);
+ em->em_src.s_addr = inet_addr(SPI->local_address);
+ em->em_dst.s_addr = inet_addr(SPI->flags & SPI_OWNER ?
+ SPI->local_address : SPI->address);
+
+ if (SPI->flags & SPI_TUNNEL) {
+ em->em_osrc.s_addr = inet_addr(SPI->local_address);
+ em->em_odst.s_addr = inet_addr(SPI->flags & SPI_OWNER ?
+ SPI->local_address : SPI->address);
}
-
- em->em_alg = XF_OLD_AH;
em->em_sproto = IPPROTO_AH;
- xd = (struct ah_old_xencap *)(em->em_dat);
+ kernel_debug(("kernel_ah: %08x.\n", em->em_spi));
- xd->amx_hash_algorithm = ALG_AUTH_MD5;
- xd->amx_keylen = klen;
-
- bcopy(secret, xd->amx_key, klen);
-
- if (!kernel_xf_set(em))
+ if (!kernel_xf_set(em)) {
+ log_error(1, "kernel_xf_set() in kernel_ah()");
return -1;
-
- return MD5_KEYLEN/8;
+ }
+ return ob->klen;
}
int
-kernel_des(char *srcaddress, char *dstaddress, u_int8_t *spi, u_int8_t *secret,
- int tunnel)
+kernel_esp(attrib_t *ob, attrib_t *ob2, struct spiob *SPI, u_int8_t *secrets)
{
struct encap_msghdr *em;
- struct esp_old_xencap *xd;
+ struct esp_old_xencap *xdo;
+ struct esp_new_xencap *xdn;
+ attrib_t *attenc, *attauth = NULL;
+ u_int8_t *sec1, *sec2 = NULL;
+
+ if (ob->type & AT_AUTH) {
+ if (ob2 == NULL || ob2->type != AT_ENC) {
+ log_error(0, "No encryption after auth given in kernel_esp()");
+ return -1;
+ }
+ attenc = ob2;
+ attauth = ob;
+ sec2 = secrets;
+ sec1 = secrets + ob->klen;
+ } else if (ob->type == AT_ENC) {
+ attenc = ob;
+ sec1 = secrets;
+ if (ob2 != NULL && (ob2->type & AT_AUTH)) {
+ attauth = ob2;
+ sec2 = secrets + ob->klen;
+ }
+ } else {
+ log_error(0, "No encryption transform given in kernel_esp()");
+ return -1;
+ }
- bzero(buffer, EMT_SETSPI_FLEN + ESP_OLD_XENCAP_LEN + 4 + 8);
+ if ((xf[attenc->koff].flags & ESP_OLD) && attauth != NULL) {
+ log_error(0, "Old ESP does not support AH in kernel_esp()");
+ return -1;
+ }
em = (struct encap_msghdr *)buffer;
-
- em->em_msglen = EMT_SETSPI_FLEN + ESP_OLD_XENCAP_LEN + 4 + 8;
+
+ if (xf[attenc->koff].flags & ESP_OLD) {
+ bzero(buffer, EMT_SETSPI_FLEN + ESP_OLD_XENCAP_LEN +4+attenc->klen);
+
+ em->em_msglen = EMT_SETSPI_FLEN + ESP_OLD_XENCAP_LEN +4+attenc->klen;
+
+ em->em_alg = XF_OLD_ESP;
+
+ xdo = (struct esp_old_xencap *)(em->em_dat);
+
+ xdo->edx_enc_algorithm = ALG_ENC_DES;
+ xdo->edx_ivlen = 4;
+ xdo->edx_keylen = attenc->klen;
+
+ bcopy(SPI->SPI, xdo->edx_data, 4);
+ bcopy(sec1, xdo->edx_data+4, attenc->klen);
+ } else {
+ bzero(buffer, EMT_SETSPI_FLEN + ESP_NEW_XENCAP_LEN + attenc->klen +
+ (attauth ? attauth->klen : 0));
+
+ em->em_msglen = EMT_SETSPI_FLEN + ESP_NEW_XENCAP_LEN +
+ attenc->klen + (attauth ? attauth->klen : 0);
+
+ em->em_alg = XF_NEW_ESP;
+
+ xdn = (struct esp_new_xencap *)(em->em_dat);
+
+ xdn->edx_enc_algorithm = xf[attenc->koff].kernel_id;
+ xdn->edx_hash_algorithm = attauth ? xf[attauth->koff].kernel_id : 0;
+ xdn->edx_ivlen = 0;
+ xdn->edx_confkeylen = attenc->klen;
+ xdn->edx_authkeylen = attauth ? attauth->klen : 0;
+ xdn->edx_wnd = 16;
+ xdn->edx_flags = attauth ? ESP_NEW_FLAG_AUTH : 0;
+
+ bcopy(sec1, xdn->edx_data, attenc->klen);
+ if (attauth != NULL)
+ bcopy(sec2, xdn->edx_data + attenc->klen, attauth->klen);
+ }
+ /* Common settings shared by ESP_OLD and ESP_NEW */
+
em->em_version = PFENCAP_VERSION_1;
em->em_type = EMT_SETSPI;
- em->em_spi = htonl((spi[0]<<24) + (spi[1]<<16) +
- (spi[2]<<8) + spi[3]);
- em->em_src.s_addr = inet_addr(srcaddress);
- em->em_dst.s_addr = inet_addr(dstaddress);
+ em->em_spi = htonl((SPI->SPI[0]<<24) + (SPI->SPI[1]<<16) +
+ (SPI->SPI[2]<<8) + SPI->SPI[3]);
+ em->em_src.s_addr = inet_addr(SPI->local_address);
+ em->em_dst.s_addr = inet_addr(SPI->flags & SPI_OWNER ?
+ SPI->local_address : SPI->address);
+ em->em_sproto = IPPROTO_ESP;
- if (tunnel) {
- em->em_osrc.s_addr = inet_addr(srcaddress);
- em->em_odst.s_addr = inet_addr(dstaddress);
+ if (SPI->flags & SPI_TUNNEL) {
+ em->em_osrc.s_addr = inet_addr(SPI->local_address);
+ em->em_odst.s_addr = inet_addr(SPI->flags & SPI_OWNER ?
+ SPI->local_address : SPI->address);
}
- em->em_alg = XF_OLD_ESP;
- em->em_sproto = IPPROTO_ESP;
-
- xd = (struct esp_old_xencap *)(em->em_dat);
-
- xd->edx_enc_algorithm = ALG_ENC_DES;
- xd->edx_ivlen = 4;
- xd->edx_keylen = 8;
-
- bcopy(spi, xd->edx_data, 4);
- bcopy(secret, xd->edx_data + 8, 8);
+ kernel_debug(("kernel_esp: %08x\n", em->em_spi));
- if (!kernel_xf_set(em))
+ if (!kernel_xf_set(em)) {
+ log_error(1, "kernel_xf_set() in kernel_esp()");
return -1;
+ }
- return 8;
+ return attenc->klen + (attauth ? attauth->klen : 0);
}
/* Group an ESP SPI with an AH SPI */
@@ -260,6 +416,9 @@ kernel_group_spi(char *address, u_int8_t *spi)
u_int32_t SPI;
SPI = (spi[0]<<24) + (spi[1]<<16) + (spi[2]<<8) + spi[3];
+
+ kernel_debug(("kernel_group_spi: %s, %08x\n", address, SPI));
+
addr = inet_addr(address);
bzero(buffer, EMT_GRPSPIS_FLEN);
@@ -277,8 +436,10 @@ kernel_group_spi(char *address, u_int8_t *spi)
em->em_rel_dst2.s_addr = addr;
em->em_rel_sproto2 = IPPROTO_AH;
- if (!kernel_xf_set(em))
+ if (!kernel_xf_set(em)) {
+ log_error(1, "kernel_xf_set() in kernel_group_spi()");
return -1;
+ }
return 1;
}
@@ -293,6 +454,8 @@ kernel_enable_spi(in_addr_t isrc, in_addr_t ismask,
SPI = (spi[0]<<24) + (spi[1]<<16) + (spi[2]<<8) + spi[3];
+ kernel_debug(("kernel_enable_spi: %08x\n", SPI));
+
bzero(buffer, EMT_ENABLESPI_FLEN);
em = (struct encap_msghdr *)buffer;
@@ -311,8 +474,10 @@ kernel_enable_spi(in_addr_t isrc, in_addr_t ismask,
em->em_ena_sproto = proto;
em->em_ena_flags = flags;
- if (!kernel_xf_set(em))
+ if (!kernel_xf_set(em)) {
+ log_error(1, "kernel_xf_set() in kernel_enable_spi()");
return -1;
+ }
return 1;
}
@@ -327,6 +492,8 @@ kernel_disable_spi(in_addr_t isrc, in_addr_t ismask,
SPI = (spi[0]<<24) + (spi[1]<<16) + (spi[2]<<8) + spi[3];
+ kernel_debug(("kernel_disable_spi: %08x\n", SPI));
+
bzero(buffer, EMT_DISABLESPI_FLEN);
em = (struct encap_msghdr *)buffer;
@@ -345,8 +512,10 @@ kernel_disable_spi(in_addr_t isrc, in_addr_t ismask,
em->em_ena_sproto = proto;
em->em_ena_flags = flags;
- if (!kernel_xf_set(em))
+/* if (!kernel_xf_set(em) && errno != ENOENT) {
+ log_error(1, "kernel_xf_set() in kernel_disable_spi()");
return -1;
+ }*/
return 1;
}
@@ -368,8 +537,12 @@ kernel_delete_spi(char *address, u_int8_t *spi, int proto)
em->em_gen_dst.s_addr = inet_addr(address);
em->em_gen_sproto = proto;
- if (!kernel_xf_set(em))
+ kernel_debug(("kernel_delete_spi: %08x\n", em->em_gen_spi));
+
+ if (!kernel_xf_set(em)) {
+ log_error(1, "kernel_xf_set() in kernel_delete_spi()");
return -1;
+ }
return 1;
}
@@ -381,7 +554,9 @@ kernel_insert_spi(struct spiob *SPI)
u_int8_t *attributes;
u_int16_t attribsize;
u_int8_t *secrets;
+ attrib_t *attprop, *attprop2;
int i, n, offset, proto = 0;
+ int phase = 0;
spi = SPI->SPI;
attributes = SPI->attributes;
@@ -391,35 +566,51 @@ kernel_insert_spi(struct spiob *SPI)
for(n=0, i=0; n<attribsize; n += attributes[n+1] + 2) {
switch(attributes[n]) {
case AT_AH_ATTRIB:
+ phase = AT_AH_ATTRIB;
+ break;
case AT_ESP_ATTRIB:
+ phase = AT_ESP_ATTRIB;
break;
- case AT_MD5_KDP:
- offset = kernel_md5(SPI->local_address, SPI->flags & SPI_OWNER ?
- SPI->local_address : SPI->address,
- spi, secrets, SPI->flags & SPI_TUNNEL);
- if (offset == -1)
+ default:
+ if (phase == 0) {
+ log_error(0, "Unaligned attribute %d in kernel_insert_spi()", attributes[n]);
return -1;
- secrets += offset;
- i++;
- if (!proto)
- proto = IPPROTO_AH;
- break;
- case AT_DES_CBC:
- offset = kernel_des(SPI->local_address, SPI->flags & SPI_OWNER ?
- SPI->local_address : SPI->address,
- spi, secrets, SPI->flags & SPI_TUNNEL);
- if (offset == -1)
+ }
+ if ((attprop = getattrib(attributes[n])) == NULL) {
+ log_error(0, "Unknown attribute %d in kernel_insert_spi()",
+ attributes[n]);
return -1;
- secrets += offset;
- i++;
- if (!proto)
- proto = IPPROTO_ESP;
- break;
- default:
- log_error(0, "Unknown attribute %d in kernel_insert_spi()",
- attributes[n]);
- return -1;
+ }
+ switch (phase) {
+ case AT_AH_ATTRIB:
+ offset = kernel_ah(attprop, SPI, secrets);
+ if (offset == -1)
+ return -1;
+ phase = 0;
+ secrets += offset;
+ i++;
+ if (!proto)
+ proto = IPPROTO_AH;
+ break;
+ case AT_ESP_ATTRIB:
+ offset = attributes[n+1] + 2;
+ attprop2 = NULL;
+ if (n+offset < attribsize)
+ attprop2 = getattrib(attributes[n+offset]);
+ if (attprop2 != NULL)
+ n += offset;
+ offset = kernel_esp(attprop, attprop2, SPI, secrets);
+ if (offset == -1)
+ return -1;
+ phase = 0;
+ secrets += offset;
+ i++;
+ if (!proto)
+ proto = IPPROTO_ESP;
+ break;
+ }
}
+
}
/* Group the SPIs for User */
@@ -448,6 +639,8 @@ int
kernel_unlink_spi(struct spiob *ospi)
{
int n, proto = 0;
+ int phase = 0, offset;
+ attrib_t *attprop;
u_int32_t spi;
u_int8_t SPI[SPI_SIZE], *p;
@@ -467,39 +660,54 @@ kernel_unlink_spi(struct spiob *ospi)
SPI[3] = spi & 0xFF;
switch(ospi->attributes[n]) {
case AT_AH_ATTRIB:
+ phase = AT_AH_ATTRIB;
+ break;
case AT_ESP_ATTRIB:
+ phase = AT_ESP_ATTRIB;
break;
- case AT_MD5_KDP:
- if (!proto) {
- proto = IPPROTO_AH;
- if (!(ospi->flags & SPI_OWNER) &&
- kernel_disable_spi(ospi->isrc, ospi->ismask,
- ospi->idst, ospi->idmask,
- ospi->address, ospi->SPI, proto,
- ENABLE_FLAG_LOCAL) == -1)
- log_error(0, "kernel_disable_spi() in kernel_unlink_spi()");
+ default:
+ if (phase == 0) {
+ log_error(0, "Unaligned attribute %d in kernel_unlink_spi()", ospi->attributes[n]);
+ return -1;
+ }
+ if ((attprop = getattrib(ospi->attributes[n])) == NULL) {
+ log_error(0, "Unknown attribute %d in kernel_unlink_spi()",
+ ospi->attributes[n]);
+ return -1;
+ }
+ switch (phase) {
+ case AT_AH_ATTRIB:
+ if (!proto) {
+ proto = IPPROTO_AH;
+ if (!(ospi->flags & SPI_OWNER) &&
+ kernel_disable_spi(ospi->isrc, ospi->ismask,
+ ospi->idst, ospi->idmask,
+ ospi->address, ospi->SPI, proto,
+ ENABLE_FLAG_LOCAL) == -1)
+ log_error(0, "kernel_disable_spi() in kernel_unlink_spi()");
}
if (kernel_delete_spi(p, SPI, IPPROTO_AH) == -1)
log_error(0, "kernel_delete_spi() in kernel_unlink_spi()");
break;
- case AT_DES_CBC:
- if (!proto) {
- proto = IPPROTO_ESP;
- if (!(ospi->flags & SPI_OWNER) &&
- kernel_disable_spi(ospi->isrc, ospi->ismask,
- ospi->idst, ospi->idmask,
- ospi->address, ospi->SPI, proto,
- ENABLE_FLAG_LOCAL) == -1)
- log_error(0, "kernel_disable_spi() in kernel_unlink_spi()");
+ case AT_ESP_ATTRIB:
+ if (!proto) {
+ proto = IPPROTO_ESP;
+ if (!(ospi->flags & SPI_OWNER) &&
+ kernel_disable_spi(ospi->isrc, ospi->ismask,
+ ospi->idst, ospi->idmask,
+ ospi->address, ospi->SPI, proto,
+ ENABLE_FLAG_LOCAL) == -1)
+ log_error(0, "kernel_disable_spi() in kernel_unlink_spi()");
+ }
+ if (kernel_delete_spi(p, SPI, IPPROTO_ESP) == -1)
+ log_error(0, "kernel_delete_spi() in kernel_unlink_spi()");
+ offset = ospi->attributes[n+1] + 2;
+ if ((n + offset < ospi->attribsize) &&
+ getattrib(ospi->attributes[n+offset]) != NULL)
+ n += offset;
+ break;
}
- if (kernel_delete_spi(p, SPI, IPPROTO_ESP) == -1)
- log_error(0, "kernel_delete_spi() in kernel_unlink_spi()");
- break;
- default:
- log_error(0, "Unknown attribute %d in kernel_unlink_spi()",
- ospi->attributes[n]);
- return -1;
}
}
diff --git a/sbin/ipsec/photurisd/kernel.h b/sbin/ipsec/photurisd/kernel.h
index ad1ac0020d4..d30ceb6b7af 100644
--- a/sbin/ipsec/photurisd/kernel.h
+++ b/sbin/ipsec/photurisd/kernel.h
@@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* $Id: kernel.h,v 1.3 1997/07/26 20:55:16 provos Exp $ */
+/* $Id: kernel.h,v 1.4 1998/03/04 11:43:33 provos Exp $ */
/*
* kernel.h:
* security paramter index creation.
@@ -40,13 +40,21 @@
#ifdef _KERNEL_C_
#define EXTERN
+#define ESP_OLD 0x01
+#define ESP_NEW 0x02
+#define AH_OLD 0x04
+#define AH_NEW 0x08
+
+#define XF_ENC 0x10
+#define XF_AUTH 0x20
+
+
int kernel_xf_set(struct encap_msghdr *em);
int kernel_xf_read(struct encap_msghdr *em, int msglen);
-int kernel_des(char *srcaddress, char *dstaddress,
- u_int8_t *spi, u_int8_t *secret, int tunnel);
-int kernel_md5(char *srcaddress, char *dstaddress,
- u_int8_t *spi, u_int8_t *secret, int tunnel);
+int kernel_ah(attrib_t *ob, struct spiob *SPI, u_int8_t *secrets);
+int kernel_esp(attrib_t *ob, attrib_t *ob2, struct spiob *SPI,
+ u_int8_t *secrets);
int kernel_group_spi(char *address, u_int8_t *spi);
@@ -62,6 +70,9 @@ int kernel_delete_spi(char *address, u_int8_t *spi, int proto);
#define EXTERN extern
#endif
+EXTERN int kernel_get_offset(int id);
+EXTERN int kernel_valid(int encoff, int authoff);
+
EXTERN u_int32_t kernel_reserve_spi( char *srcaddress, int options);
EXTERN u_int32_t kernel_reserve_single_spi(char *srcaddress, u_int32_t spi,
int proto);
diff --git a/sbin/ipsec/photurisd/packet.c b/sbin/ipsec/photurisd/packet.c
index 4eb182d0ca4..9b1ced8041b 100644
--- a/sbin/ipsec/photurisd/packet.c
+++ b/sbin/ipsec/photurisd/packet.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: packet.c,v 1.1 1997/07/18 22:48:50 provos Exp $";
+static char rcsid[] = "$Id: packet.c,v 1.2 1998/03/04 11:43:35 provos Exp $";
#endif
#define _PACKET_C_
@@ -41,6 +41,7 @@ static char rcsid[] = "$Id: packet.c,v 1.1 1997/07/18 22:48:50 provos Exp $";
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -52,6 +53,7 @@ static char rcsid[] = "$Id: packet.c,v 1.1 1997/07/18 22:48:50 provos Exp $";
#include "errlog.h"
#include "buffer.h"
#include "config.h"
+#include "scheme.h"
#include "packet.h"
#include "server.h"
@@ -207,6 +209,72 @@ send_packet(void)
}
}
+/*
+ * packet_check() checks the format of the received packet against
+ * the specified logical format. The position and size of the fields
+ * are returned.
+ */
+
+int
+packet_check(u_char *packet, u_int16_t size, struct packet *format)
+{
+ struct packet_sub *parts = format->parts;
+ u_int16_t off, val, fsize;
+
+ if (format->max != 0 && size > format->max)
+ return -1;
+ if (size < format->min)
+ return -1;
+
+ off = format->min;
+ packet += off;
+
+ while (off < size && parts != NULL && parts->field != NULL) {
+ parts->where = packet;
+ switch (parts->type) {
+ case FLD_CONST:
+ off += parts->size;
+ packet += parts->size;
+ fsize = parts->size;
+ break;
+ case FLD_VARPRE:
+ val = varpre2octets(packet);
+ off += val;
+ packet += val;
+ fsize = val;
+ break;
+ case FLD_ATTRIB:
+ if (parts->mod == FMD_ATT_FILL) {
+ fsize = 0;
+ while (off < size) {
+ val = packet[1] + 2;
+ off += val;
+ packet += val;
+ fsize += val;
+ }
+ } else {
+ val = packet[1] + 2;
+ off += val;
+ packet += val;
+ fsize = val;
+ }
+ break;
+ default:
+ return -1;
+ }
+ if (parts->size == 0)
+ parts->size = fsize;
+ else if(parts->size != fsize)
+ return -1;
+ parts++;
+ }
+
+ if (off != size || (parts != NULL && parts->field != NULL))
+ return -1;
+
+ return 0;
+}
+
void
packet_save(struct stateob *st, u_int8_t *buffer, u_int16_t len)
{
@@ -221,3 +289,53 @@ packet_save(struct stateob *st, u_int8_t *buffer, u_int16_t len)
bcopy(buffer, st->packet, len);
st->packetlen = len;
}
+
+#ifdef DEBUG
+void
+packet_ordered_dump(u_int8_t *packet, u_int16_t size, struct packet *format)
+{
+ struct packet_sub *parts = format->parts;
+ u_int16_t off = 0;
+
+ printf("Packet Header (%s):\n", format->name);
+ packet_dump(packet, format->min, off);
+
+ off += format->min;
+ packet += format->min;
+ while (off < size) {
+ printf("%s (%d):\n", parts->field, parts->size);
+ packet_dump(packet, parts->size, off);
+ off += parts->size;
+ packet += parts->size;
+
+ parts++;
+ }
+}
+
+void
+packet_dump(u_int8_t *packet, u_int16_t plen, u_int16_t start)
+{
+ char tmp[73], dump[33];
+ int i, size, len, off;
+
+ off = 0;
+ while (off < plen) {
+ memset(tmp, ' ', sizeof(tmp));
+ tmp[72] = 0;
+
+ sprintf(tmp, "%04x ", (u_int32_t)(off + start));
+
+ len = 33;
+ size = plen - off > 16 ? 16 : plen - off;
+ bin2hex(dump, &len, packet, size);
+ for (i=0; i<size; i++) {
+ bcopy(dump+i*2, tmp+5+i*3, 2);
+ tmp[5 + 16*3 + 3 + i] = isprint(packet[i]) ? packet[i] : '.';
+ }
+ printf("%s\n", tmp);
+
+ off += size;
+ packet += size;
+ }
+}
+#endif
diff --git a/sbin/ipsec/photurisd/packet.h b/sbin/ipsec/photurisd/packet.h
index 389e9b54ddf..ae1753d7929 100644
--- a/sbin/ipsec/photurisd/packet.h
+++ b/sbin/ipsec/photurisd/packet.h
@@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* $Id: packet.h,v 1.1 1997/07/18 22:48:50 provos Exp $ */
+/* $Id: packet.h,v 1.2 1998/03/04 11:43:36 provos Exp $ */
/*
* packet.h:
* prototyped for receiving and anwsering packets
@@ -45,6 +45,11 @@
EXTERN int handle_packet(int, char *);
EXTERN void send_packet(void);
+EXTERN int packet_check(u_char *packet, u_int16_t size, struct packet *format);
EXTERN void packet_save(struct stateob *, u_int8_t *, u_int16_t);
+#ifdef DEBUG
+EXTERN void packet_ordered_dump(u_int8_t *packet, u_int16_t size, struct packet *format);
+EXTERN void packet_dump(u_int8_t *packet, u_int16_t plen, u_int16_t start);
+#endif
#endif /* _STATE_H */
diff --git a/sbin/ipsec/photurisd/packets.h b/sbin/ipsec/photurisd/packets.h
index 7d8ed7ee4f7..4fd87c4ec90 100644
--- a/sbin/ipsec/photurisd/packets.h
+++ b/sbin/ipsec/photurisd/packets.h
@@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* $Id: packets.h,v 1.1 1997/07/18 22:48:49 provos Exp $ */
+/* $Id: packets.h,v 1.2 1998/03/04 11:43:37 provos Exp $ */
/*
* packets.h:
*/
@@ -53,6 +53,29 @@
#define COOKIE_SIZE 16
#define SPI_SIZE 4
+/* General packet definition */
+
+#define FLD_CONST 0
+#define FLD_VARPRE 1
+#define FLD_ATTRIB 2
+
+#define FMD_ATT_ONE 0
+#define FMD_ATT_FILL 1
+
+struct packet_sub {
+ char *field; /* Name of Field */
+ int type; /* Type of Field */
+ int mod; /* Modifier: */
+ u_int16_t size; /* Pointer to start of Field */
+ void *where; /* Pointer to start of Field */
+};
+
+struct packet {
+ char *name;
+ int min, max;
+ struct packet_sub *parts;
+};
+
struct cookie_request {
u_int8_t icookie[COOKIE_SIZE];
u_int8_t rcookie[COOKIE_SIZE];
diff --git a/sbin/ipsec/photurisd/photuris_identity_request.c b/sbin/ipsec/photurisd/photuris_identity_request.c
index 4a6296a02ef..abf34aae699 100644
--- a/sbin/ipsec/photurisd/photuris_identity_request.c
+++ b/sbin/ipsec/photurisd/photuris_identity_request.c
@@ -34,7 +34,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: photuris_identity_request.c,v 1.1 1997/07/18 22:48:49 provos Exp $";
+static char rcsid[] = "$Id: photuris_identity_request.c,v 1.2 1998/03/04 11:43:39 provos Exp $";
#endif
#include <stdio.h>
@@ -45,6 +45,9 @@ static char rcsid[] = "$Id: photuris_identity_request.c,v 1.1 1997/07/18 22:48:4
#include "state.h"
#include "identity.h"
#include "encrypt.h"
+#ifdef DEBUG
+#include "packet.h"
+#endif
int
photuris_identity_request(struct stateob *st, u_char *buffer, int *size)
@@ -115,6 +118,11 @@ photuris_identity_request(struct stateob *st, u_char *buffer, int *size)
/* Create verification data */
create_identity_verification(st, verifyp, (u_int8_t *)header, asize);
+#ifdef DEBUG
+ printf("Identity-Request (before encryption):\n");
+ packet_dump((u_int8_t *)header, asize, 0);
+#endif
+
/* Encrypt the packet after SPI if wished for */
packet_encrypt(st, IDENTITY_MESSAGE_CHOICE(header),
asize - IDENTITY_MESSAGE_MIN);
diff --git a/sbin/ipsec/photurisd/photuris_identity_response.c b/sbin/ipsec/photurisd/photuris_identity_response.c
index 550fa0d25ec..ebc5ce56f41 100644
--- a/sbin/ipsec/photurisd/photuris_identity_response.c
+++ b/sbin/ipsec/photurisd/photuris_identity_response.c
@@ -34,7 +34,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: photuris_identity_response.c,v 1.1 1997/07/18 22:48:49 provos Exp $";
+static char rcsid[] = "$Id: photuris_identity_response.c,v 1.2 1998/03/04 11:43:40 provos Exp $";
#endif
#include <stdio.h>
@@ -45,6 +45,9 @@ static char rcsid[] = "$Id: photuris_identity_response.c,v 1.1 1997/07/18 22:48:
#include "state.h"
#include "identity.h"
#include "encrypt.h"
+#ifdef DEBUG
+#include "packet.h"
+#endif
int
photuris_identity_response(struct stateob *st, u_char *buffer, int *size)
@@ -114,6 +117,11 @@ photuris_identity_response(struct stateob *st, u_char *buffer, int *size)
/* Create verification data */
create_identity_verification(st, verifyp, (u_int8_t *)header, asize);
+
+#ifdef DEBUG
+ printf("Identity-Response (before encryption):\n");
+ packet_dump((u_int8_t *)header, asize, 0);
+#endif
/* Encrypt the packet after SPI if wished for */
packet_encrypt(st, IDENTITY_MESSAGE_CHOICE(header),
diff --git a/sbin/ipsec/photurisd/photuris_packet_encrypt.c b/sbin/ipsec/photurisd/photuris_packet_encrypt.c
index f614cede679..f0b2e7bbc3b 100644
--- a/sbin/ipsec/photurisd/photuris_packet_encrypt.c
+++ b/sbin/ipsec/photurisd/photuris_packet_encrypt.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: photuris_packet_encrypt.c,v 1.1 1997/07/18 22:48:49 provos Exp $";
+static char rcsid[] = "$Id: photuris_packet_encrypt.c,v 1.2 1998/03/04 11:43:41 provos Exp $";
#endif
#define _ENCRYPT_C_
@@ -66,15 +66,6 @@ packet_mask(u_int8_t *packet, u_int16_t len, u_int8_t *key)
}
int
-packet_make_iv(u_int32_t *iv, u_int32_t *packet)
-{
- iv[0] = iv[0] ^ packet[0];
- iv[1] = iv[1] ^ packet[1];
-
- return 1;
-}
-
-int
packet_create_padding(struct stateob *st, u_int16_t size, u_int8_t *padd,
u_int16_t *rsize)
{
@@ -113,6 +104,8 @@ packet_encrypt(struct stateob *st, u_int8_t *payload, u_int16_t payloadlen)
des_cblock keys[4], *input;
des_key_schedule key1,key2,key3;
u_int8_t *pkey;
+ u_int16_t order = 0;
+ int i;
input = (des_cblock *)payload;
@@ -131,7 +124,7 @@ packet_encrypt(struct stateob *st, u_int8_t *payload, u_int16_t payloadlen)
}
if(compute_privacy_key(st, pkey,
payload - 2*COOKIE_SIZE - 4 - SPI_SIZE,
- payloadlen*8, 0, 1) == -1)
+ payloadlen*8, &order, 1) == -1)
return -1;
#ifdef DEBUG
{
@@ -150,34 +143,40 @@ packet_encrypt(struct stateob *st, u_int8_t *payload, u_int16_t payloadlen)
#ifdef DEBUG
printf("[Packet encryption: DES]\n");
#endif
- pkey = calloc(payloadlen + 16, sizeof(u_int8_t));
+ pkey = calloc(payloadlen + 8, sizeof(u_int8_t));
if(pkey == NULL) {
log_error(1, "Not enough memory for privacy secret");
return -1;
}
+ /* XOR Mask */
if(compute_privacy_key(st, pkey,
payload - 2*COOKIE_SIZE - 4 - SPI_SIZE,
- payloadlen*8+128, 0, 1) == -1)
+ payloadlen*8, &order, 1) == -1)
+ return -1;
+ /* DES Key */
+ if(compute_privacy_key(st, pkey+payloadlen,
+ payload - 2*COOKIE_SIZE - 4 - SPI_SIZE,
+ 64, &order, 1) == -1)
return -1;
#ifdef DEBUG
{
int i;
char buffer[3000];
i = 3000;
- bin2hex(buffer, &i, pkey, payloadlen+16);
+ bin2hex(buffer, &i, pkey, payloadlen+8);
printf("Encrypt key: %s\n", buffer );
}
#endif
bcopy(pkey+payloadlen, &keys[0], 8);
des_set_odd_parity(&keys[0]);
- bcopy(pkey+payloadlen+8, &keys[1], 8);
+
+ /* Zero IV, we will mask the packet instead */
+ bzero(&keys[1], 8);
des_set_key(&keys[0], key1);
packet_mask(payload, payloadlen, pkey);
- packet_make_iv((u_int32_t *)&keys[1], (u_int32_t *)(payload - 8));
-
des_cbc_encrypt(input,input,payloadlen, key1,&keys[1], DES_ENCRYPT);
break;
case DH_G_2_3DES_SHA1:
@@ -186,21 +185,29 @@ packet_encrypt(struct stateob *st, u_int8_t *payload, u_int16_t payloadlen)
#ifdef DEBUG
printf("[Packet encryption: 3DES]\n");
#endif
- pkey = calloc(payloadlen+32, sizeof(u_int8_t));
+ pkey = calloc(payloadlen+24, sizeof(u_int8_t));
if(pkey == NULL) {
log_error(1, "Not enough memory for owner privacy secret");
return -1;
}
+ /* XOR Mask */
if(compute_privacy_key(st, pkey,
payload - 2*COOKIE_SIZE - 4 - SPI_SIZE,
- payloadlen*8+256, 0, 1) == -1)
+ payloadlen*8, &order, 1) == -1)
return -1;
+ /* 3 DES Keys */
+ for (i=0; i<3; i++) {
+ if(compute_privacy_key(st, pkey+payloadlen + (i<<3),
+ payload - 2*COOKIE_SIZE - 4 - SPI_SIZE,
+ 64, &order, 1) == -1)
+ return -1;
+ }
#ifdef DEBUG
{
int i;
char buffer[3000];
i = 3000;
- bin2hex(buffer, &i, pkey, payloadlen+32);
+ bin2hex(buffer, &i, pkey, payloadlen+24);
printf("Encrypt key: %s\n", buffer );
}
#endif
@@ -210,7 +217,9 @@ packet_encrypt(struct stateob *st, u_int8_t *payload, u_int16_t payloadlen)
des_set_odd_parity(&keys[1]);
bcopy(pkey+payloadlen+16, &keys[2], 8);
des_set_odd_parity(&keys[2]);
- bcopy(pkey+payloadlen+24, &keys[3], 8);
+
+ /* Zero IV, we will make the packet instead */
+ bzero(&keys[3], 8);
des_set_key(&keys[0], key1);
des_set_key(&keys[1], key2);
@@ -218,8 +227,6 @@ packet_encrypt(struct stateob *st, u_int8_t *payload, u_int16_t payloadlen)
packet_mask(payload, payloadlen, pkey);
- packet_make_iv((u_int32_t *)&keys[3], (u_int32_t *)(payload - 8));
-
des_ede3_cbc_encrypt(input, input, payloadlen,
key1, key2, key3, &keys[3], DES_ENCRYPT);
break;
@@ -241,6 +248,7 @@ packet_decrypt(struct stateob *st, u_int8_t *payload, u_int16_t *payloadlen)
des_cblock keys[4], *input;
des_key_schedule key1,key2,key3;
u_int8_t *pkey;
+ u_int16_t order = 0;
input = (des_cblock *)payload;
@@ -259,7 +267,7 @@ packet_decrypt(struct stateob *st, u_int8_t *payload, u_int16_t *payloadlen)
}
if(compute_privacy_key(st, pkey,
payload - 2*COOKIE_SIZE - 4 - SPI_SIZE,
- *payloadlen*8, 0, 0) == -1)
+ *payloadlen*8, &order, 0) == -1)
return -1;
#ifdef DEBUG
{
@@ -277,30 +285,36 @@ packet_decrypt(struct stateob *st, u_int8_t *payload, u_int16_t *payloadlen)
#ifdef DEBUG
printf("[Packet decryption: DES]\n");
#endif
- pkey = calloc(*payloadlen+16, sizeof(u_int8_t));
+ pkey = calloc(*payloadlen+8, sizeof(u_int8_t));
if(pkey == NULL) {
log_error(1, "Not enough memory for privacy secret");
return -1;
}
+ /* XOR Mask */
if(compute_privacy_key(st, pkey,
payload - 2*COOKIE_SIZE - 4 - SPI_SIZE,
- *payloadlen*8+128, 0, 0) == -1)
+ *payloadlen*8, &order, 0) == -1)
+ return -1;
+ /* DES Key */
+ if(compute_privacy_key(st, pkey + *payloadlen,
+ payload - 2*COOKIE_SIZE - 4 - SPI_SIZE,
+ 64, &order, 0) == -1)
return -1;
#ifdef DEBUG
{
int i = 3000;
char buffer[3000];
- bin2hex(buffer, &i, pkey, *payloadlen+ 16);
+ bin2hex(buffer, &i, pkey, *payloadlen + 8);
printf("Decrypt key: %s\n", buffer );
}
#endif
bcopy(pkey+*payloadlen, &keys[0], 8);
des_set_odd_parity(&keys[0]);
- bcopy(pkey+*payloadlen+8, &keys[1], 8);
- des_set_key(&keys[0], key1);
+ /* Zero IV, we will mask the packet instead */
+ bzero(&keys[1], 8);
- packet_make_iv((u_int32_t *)&keys[1], (u_int32_t *)(payload - 8));
+ des_set_key(&keys[0], key1);
des_cbc_encrypt(input,input,*payloadlen, key1,&keys[1], DES_DECRYPT);
@@ -312,20 +326,28 @@ packet_decrypt(struct stateob *st, u_int8_t *payload, u_int16_t *payloadlen)
#ifdef DEBUG
printf("[Packet decryption: 3DES]\n");
#endif
- pkey = calloc(*payloadlen + 32, sizeof(u_int8_t));
+ pkey = calloc(*payloadlen + 24, sizeof(u_int8_t));
if(pkey == NULL) {
log_error(1, "Not enough memory for privacy secret");
return -1;
}
+ /* XOR Mask */
if(compute_privacy_key(st, pkey,
payload - 2*COOKIE_SIZE - 4 - SPI_SIZE,
- *payloadlen*8+256, 0, 0) == -1)
+ *payloadlen*8, &order, 0) == -1)
return -1;
+ /* 3 DES keys + 1 DES IV */
+ for (i=0; i<3; i++) {
+ if(compute_privacy_key(st, pkey + *payloadlen + (i<<3),
+ payload - 2*COOKIE_SIZE - 4 - SPI_SIZE,
+ 64, &order, 0) == -1)
+ return -1;
+ }
#ifdef DEBUG
{
int i = 3000;
char buffer[3000];
- bin2hex(buffer, &i, pkey, *payloadlen+32);
+ bin2hex(buffer, &i, pkey, *payloadlen+24);
printf("Decrypt key: %s\n", buffer );
}
#endif
@@ -335,14 +357,14 @@ packet_decrypt(struct stateob *st, u_int8_t *payload, u_int16_t *payloadlen)
des_set_odd_parity(&keys[1]);
bcopy(pkey+*payloadlen+16, &keys[2], 8);
des_set_odd_parity(&keys[2]);
- bcopy(pkey+*payloadlen+24, &keys[3], 8);
+
+ /* Zero IV, we will mask the packet instead */
+ bzero(&keys[3], 8);
des_set_key(&keys[0], key1);
des_set_key(&keys[1], key2);
des_set_key(&keys[2], key3);
- packet_make_iv((u_int32_t *)&keys[3], (u_int32_t *)(payload - 8));
-
des_ede3_cbc_encrypt(input, input, *payloadlen,
key1, key2, key3, &keys[3], DES_DECRYPT);
diff --git a/sbin/ipsec/photurisd/photuris_value_request.c b/sbin/ipsec/photurisd/photuris_value_request.c
index 92eb6bc34fe..a2b3318294d 100644
--- a/sbin/ipsec/photurisd/photuris_value_request.c
+++ b/sbin/ipsec/photurisd/photuris_value_request.c
@@ -34,7 +34,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: photuris_value_request.c,v 1.1 1997/07/18 22:48:49 provos Exp $";
+static char rcsid[] = "$Id: photuris_value_request.c,v 1.2 1998/03/04 11:43:43 provos Exp $";
#endif
#include <stdio.h>
@@ -80,6 +80,8 @@ photuris_value_request(struct stateob *st, u_char *buffer, int *size)
header->counter = st->counter;
bcopy(st->scheme, header->scheme, 2 ); /* Only scheme */
+ bcopy(&header->counter, st->oSPITBV, 3);
+
*size = asize;
return 0;
}
diff --git a/sbin/ipsec/photurisd/photuris_value_response.c b/sbin/ipsec/photurisd/photuris_value_response.c
index 78d20847915..090233c5e16 100644
--- a/sbin/ipsec/photurisd/photuris_value_response.c
+++ b/sbin/ipsec/photurisd/photuris_value_response.c
@@ -34,7 +34,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: photuris_value_response.c,v 1.1 1997/07/18 22:48:49 provos Exp $";
+static char rcsid[] = "$Id: photuris_value_response.c,v 1.2 1998/03/04 11:43:44 provos Exp $";
#endif
#include <stdio.h>
@@ -78,6 +78,7 @@ photuris_value_response(struct stateob *st, u_char *buffer, int *size)
bcopy(st->rcookie, header->rcookie, COOKIE_SIZE);
bzero(header->reserved, sizeof(header->reserved)); /* zero for now */
+ bzero(st->oSPITBV, 3);
*size = asize;
return 0;
diff --git a/sbin/ipsec/photurisd/photurisd.1 b/sbin/ipsec/photurisd/photurisd.1
index f607a7a2e30..66c34e2e6ce 100644
--- a/sbin/ipsec/photurisd/photurisd.1
+++ b/sbin/ipsec/photurisd/photurisd.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: photurisd.1,v 1.7 1997/12/02 10:57:37 provos Exp $
+.\" $OpenBSD: photurisd.1,v 1.8 1998/03/04 11:43:46 provos Exp $
.\" Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
.\" All rights reserved.
.\"
@@ -39,6 +39,7 @@
.Nm photurisd
.Op Fl ci
.Op Fl d Ar directory
+.Op Fl p Ar port
.Sh DESCRIPTION
The
.Nm photuris
@@ -71,6 +72,10 @@ option specifies the directory in which
.Nm photurisd
looks for its startup files. The default is
.Pa /etc/photuris/ .
+.It Fl p
+The
+.Fl p
+option specifies the local port the daemon shall bind to.
.El
.Pp
The file
@@ -114,26 +119,62 @@ The file
contains the attributes, i.e. different choices of encryption
and authenication, offered to the other peer. If a line starts with an ip
address and a space seperated netmask the following attributes are only
-offered to hosts lying in that net range. Possible attributes are:
+offered to hosts lying in that net range. Only one attribute per line
+is allowed. An attribute can either be an already defined tag or
+an new definition of an attribute. In that case the line is followed by a
+comma separated list:
+.Nm attribute name ,
+.Nm Photuris id ,
+.Nm type of attribute
+and
+.Nm key length .
+The name is only used as reference. A list of possible Photuris ids can
+be found in
+.Pa /usr/share/ipsec/attributes.conf .
+The attribute type is one of the following:
+.Nm enc ,
+.Nm ident ,
+.Nm auth
+or
+.Nm ident|auth .
+The key length is so far only used by the encryption attributes and
+specifies the number of keying bytes the daemon has to generate.
+Predefined attributes are:
.Bl -tag -width AT_ESP_ATTRIB -offset indent
.It AT_AH_ATTRIB
Starts the list of authentication attributes.
.It AT_ESP_ATTRIB
Starts the list of encryption attributes.
-.It AT_MD5_DP
-MD5 symmetric identification. This attribute must be offered.
-.It AT_SHA1_DP
-SHA1 symmetric identification.
-.It AT_MD5_KDP
-Simple MD5 keyed authentication.
-.It AT_DES_CBC
-DES CBC encryption.
.El
.Pp
The file
.Pa secrets.conf
contains the party preconfigured symmetric secrets for the
-identity exchange. User secrets files can be included.
+identity exchange.
+.Bl -tag -width identity_pair_local -offset indent
+.It identity local
+Defines the identity the local daemon will assume and the according
+password. Both name and secret are braced by quotation marks and follow
+the
+.Nm identity local
+directive.
+.It identity remote
+Defines the parties the daemon can communicate with and their secrets.
+Both name and secret are braced by quotation marks and follow the
+.Nm identity remote
+directive. The name and secret are the same as the identity local
+on the remote site.
+.It identity pair local
+If the identity of the remote site is already known,
+.Nm identity pair local
+enables the daemon to assume an identity and secret based on
+the remote identity. The directive is followed by the
+remote identity, a new local identity and an according secret.
+In that way the secrets are not shared with all other parties.
+.El
+.Pp
+Once DNSSEC or other public key infrastructures are available, those will
+be supported also.
.Pp
Finally the file
.Pa photuris.startup
diff --git a/sbin/ipsec/photurisd/photurisd.c b/sbin/ipsec/photurisd/photurisd.c
index 0b9aef231ce..5668ede6050 100644
--- a/sbin/ipsec/photurisd/photurisd.c
+++ b/sbin/ipsec/photurisd/photurisd.c
@@ -32,7 +32,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: photurisd.c,v 1.5 1997/09/14 10:37:52 deraadt Exp $";
+static char rcsid[] = "$Id: photurisd.c,v 1.6 1998/03/04 11:43:47 provos Exp $";
#endif
#define _PHOTURIS_C_
@@ -67,10 +67,11 @@ usage(void)
{
FILE *f = stderr;
- fprintf(f, "usage: photurisd [-ci] [-d directory]\n");
+ fprintf(f, "usage: photurisd [-ci] [-d directory] [-p port]\n");
fprintf(f, "\t-c check primes on startup\n");
- fprintf(f, "\t-t ignore startup file %s\n", PHOTURIS_STARTUP);
+ fprintf(f, "\t-i ignore startup file %s\n", PHOTURIS_STARTUP);
fprintf(f, "\t-d specifies the startup dir\n");
+ fprintf(f, "\t-p specifies the local port to bind to\n");
exit(1);
}
@@ -115,8 +116,9 @@ main(int argc, char **argv)
char *dir = PHOTURIS_DIR;
daemon_mode = 0;
+ global_port = 0;
- while ((ch = getopt(argc, argv, "cid:")) != -1)
+ while ((ch = getopt(argc, argv, "cid:p:")) != -1)
switch((char)ch) {
case 'c':
primes = 1;
@@ -127,6 +129,9 @@ main(int argc, char **argv)
case 'd':
dir = optarg;
break;
+ case 'p':
+ global_port = atoi(optarg);
+ break;
case '?':
default:
usage();
diff --git a/sbin/ipsec/photurisd/schedule.c b/sbin/ipsec/photurisd/schedule.c
index a5a1f89afda..a0749558ba3 100644
--- a/sbin/ipsec/photurisd/schedule.c
+++ b/sbin/ipsec/photurisd/schedule.c
@@ -35,7 +35,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: schedule.c,v 1.5 1997/09/03 08:44:41 provos Exp $";
+static char rcsid[] = "$Id: schedule.c,v 1.6 1998/03/04 11:43:49 provos Exp $";
#endif
#define _SCHEDULE_C_
@@ -80,7 +80,7 @@ schedule_insert(int type, int off, u_int8_t *cookie, u_int16_t cookie_size)
bin2hex(buffer, &i, cookie, cookie_size);
}
printf("Adding event type %d, due in %d seconds, cookie %s\n",
- type, off, cookie == NULL ? "None" : buffer);
+ type, off, cookie == NULL ? "None" : (char *)buffer);
}
#endif
@@ -199,7 +199,8 @@ schedule_process(int sock)
switch(tmp->event) {
case REKEY:
#ifdef DEBUG
- printf("Resetting secrets\n");
+ if (state_root() != NULL)
+ printf("Resetting secrets\n");
#endif
reset_secret();
tmp->tm = time(NULL) + REKEY_TIMEOUT;
@@ -243,7 +244,7 @@ schedule_process(int sock)
state_copy_flags(st, newst);
#ifdef DEBUG
printf("Starting a new exchange to %s:%d with updated rcookie and"
- "counter.\n", newst->address, newst->port);
+ " counter.\n", newst->address, newst->port);
#endif /* DEBUG */
start_exchange(sock, newst, st->address, st->port);
state_insert(newst);
@@ -300,7 +301,13 @@ schedule_process(int sock)
break;
}
if ((st = state_find_cookies(spi->address, spi->icookie, NULL)) == NULL) {
+#ifdef DEBUG2
+ /*
+ * This happens always when an exchange expires but
+ * updates are still scheduled for it.
+ */
log_error(0, "state_find_cookies() in schedule_process()");
+#endif
break;
}
diff --git a/sbin/ipsec/photurisd/secrets.h b/sbin/ipsec/photurisd/secrets.h
index ed7e763dba4..71e3564cf33 100644
--- a/sbin/ipsec/photurisd/secrets.h
+++ b/sbin/ipsec/photurisd/secrets.h
@@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* $Id: secrets.h,v 1.2 1997/09/02 17:26:48 provos Exp $ */
+/* $Id: secrets.h,v 1.3 1998/03/04 11:43:50 provos Exp $ */
/*
* secrets.h:
* prototypes for compute_secrets.c
@@ -57,7 +57,7 @@ EXTERN int get_session_key_length(u_int8_t *attribute);
EXTERN int init_privacy_key(struct stateob *st, int owner);
EXTERN int compute_privacy_key(struct stateob *st, u_int8_t *key,
u_int8_t *packet, u_int16_t bits,
- u_int16_t order, int owner);
+ u_int16_t *order, int owner);
EXTERN int make_session_keys(struct stateob *st, struct spiob *spi);
#endif /* _SECRETS_H_ */
diff --git a/sbin/ipsec/photurisd/server.c b/sbin/ipsec/photurisd/server.c
index e2228260b2c..c3062d19ffd 100644
--- a/sbin/ipsec/photurisd/server.c
+++ b/sbin/ipsec/photurisd/server.c
@@ -35,7 +35,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: server.c,v 1.2 1997/07/22 11:18:25 provos Exp $";
+static char rcsid[] = "$Id: server.c,v 1.3 1998/03/04 11:43:52 provos Exp $";
#endif
#define _SERVER_C_
@@ -80,17 +80,18 @@ init_server(void)
struct ifconf ifconf;
char buf[1024];
+ if (global_port == 0) {
#ifndef PHOTURIS_PORT
- struct servent *ser;
+ struct servent *ser;
- if ((ser = getservbyname("photuris", "udp")) == (struct servent *) NULL)
- crit_error(1, "getservbyname() in init_server()");
+ if ((ser = getservbyname("photuris", "udp")) == (struct servent *) NULL)
+ crit_error(1, "getservbyname(\"photuris\") in init_server()");
- global_port = ser->s_port;
+ global_port = ser->s_port;
#else
- global_port = PHOTURIS_PORT;
+ global_port = PHOTURIS_PORT;
#endif
-
+ }
if ((proto = getprotobyname("udp")) == (struct protoent *) NULL)
crit_error(1, "getprotobyname() in init_server()");
diff --git a/sbin/ipsec/photurisd/spi.c b/sbin/ipsec/photurisd/spi.c
index e6c8a4dbbeb..b106947946a 100644
--- a/sbin/ipsec/photurisd/spi.c
+++ b/sbin/ipsec/photurisd/spi.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: spi.c,v 1.4 1997/07/26 20:55:17 provos Exp $";
+static char rcsid[] = "$Id: spi.c,v 1.5 1998/03/04 11:43:53 provos Exp $";
#endif
#define _SPI_C_
@@ -76,80 +76,10 @@ make_spi(struct stateob *st, char *local_address,
u_int16_t i;
if(*attributes == NULL) { /* We are in need of attributes */
- u_int16_t count = 0;
- u_int8_t *wanted, *offered, *p;
- u_int16_t wantedsize, offeredsize;
- u_int16_t mode = 0; /* We only take when in ah|esp mode */
- int first = 0; /* Obmit AH|ESP header if not needed*/
- struct attribute_list *ob;
-
- if ((ob = attrib_find(NULL)) == NULL) {
- log_error(0, "attrib_find() for default in make_spi() in "
- "exchange to %s", st->address);
- return -1;
- }
-
- /* Take from Owner */
- wanted = ob->attributes;
- wantedsize = ob->attribsize;
-
- /* Take from User */
- offered = st->uSPIoattrib;
- offeredsize = st->uSPIoattribsize;
-
- /* This should never happen */
- if(wantedsize>BUFFER_SIZE)
- return -1;
-
- p = buffer;
- while(wantedsize>0) {
- /* Scan the offered attributes */
- if (*wanted == AT_AH_ATTRIB &&
- (st->flags & IPSEC_OPT_AUTH)) {
- first = 1;
- mode = AT_AH_ATTRIB;
- } else if (*wanted == AT_ESP_ATTRIB &&
- (st->flags & IPSEC_OPT_ENC)) {
- mode = AT_ESP_ATTRIB;
- first = 1;
- }
-
- /*
- * Take attributes only from AH or ESP sections.
- * Obmit AH or ESP header when there are no entries
- * in that section.
- * XXX - put && first && in if to take only one attrib
- * in each section.
- */
-
- if (mode && first &&
- *wanted != AT_AH_ATTRIB && *wanted != AT_ESP_ATTRIB &&
- isinattrib(offered, offeredsize, *wanted)) {
-
- /* Put prober header in there */
- if (first) {
- p[0] = mode;
- p[1] = 0;
- first = 0;
- count += 2;
- p += 2;
- }
- /* We are using our own attributes, safe to proceed */
- bcopy(wanted, p, *(wanted+1) + 2);
- count += *(wanted+1) + 2;
- p += *(wanted+1) + 2;
- }
- if(wantedsize - *(wanted+1) - 2 > wantedsize)
- break;
- wantedsize -= *(wanted+1) + 2;
- wanted += *(wanted+1) + 2;
- }
- if((*attributes=calloc(count,sizeof(u_int8_t))) == NULL) {
- log_error(1, "Out of memory for SPI attributes (%d)", count);
+ if (select_attrib(st, attributes, attribsize) == -1) {
+ log_error(0, "select_attrib() in make_spi()");
return -1;
}
- *attribsize = count;
- bcopy(buffer, *attributes, count);
}
/* Just grab a random number, this should be uniq */
diff --git a/sbin/ipsec/photurisd/state.h b/sbin/ipsec/photurisd/state.h
index 8cf69c98de3..2e82cb3a202 100644
--- a/sbin/ipsec/photurisd/state.h
+++ b/sbin/ipsec/photurisd/state.h
@@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* $Id: state.h,v 1.4 1997/09/02 17:26:49 provos Exp $ */
+/* $Id: state.h,v 1.5 1998/03/04 11:43:55 provos Exp $ */
/*
* state.h:
* state object
@@ -69,7 +69,6 @@ struct stateob {
char address[16]; /* Remote address */
u_int16_t port; /* Remote port */
-
u_int8_t icookie[COOKIE_SIZE]; /* Initator cookie */
u_int8_t rcookie[COOKIE_SIZE]; /* Responder cookie */
u_int8_t counter; /* Connection counter */
@@ -85,6 +84,7 @@ struct stateob {
u_int16_t roschemesize; /* Responder offered schemes size */
u_int8_t oSPI[SPI_SIZE]; /* Owner SPI */
+ u_int8_t oSPITBV[3]; /* Three Byte Value */
u_int8_t *oSPIident; /* Owner SPI identification */
u_int8_t *oSPIattrib; /* Owner SPI attributes */
u_int16_t oSPIattribsize;
@@ -100,6 +100,7 @@ struct stateob {
time_t olifetime; /* Owner SPI lifetime */
u_int8_t uSPI[SPI_SIZE]; /* User SPI */
+ u_int8_t uSPITBV[3]; /* Three Byte Value */
u_int8_t *uSPIident; /* User SPI identification */
u_int8_t *uSPIattrib; /* User SPI attributes */
u_int16_t uSPIattribsize;
@@ -126,6 +127,8 @@ struct stateob {
int retries; /* Number of retransmits */
u_int8_t *packet; /* Buffer for retransmits */
u_int16_t packetlen;
+ u_int8_t packetsig[16]; /* MD5 hash of an old packet */
+
time_t lifetime; /* Lifetime for the exchange */
time_t exchange_lifetime; /* Use this as default */
time_t spi_lifetime; /* Use this as default */