summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels Provos <provos@cvs.openbsd.org>1997-09-02 17:26:51 +0000
committerNiels Provos <provos@cvs.openbsd.org>1997-09-02 17:26:51 +0000
commitecfa99a7a95ad310f3c23d407c08aca22da15424 (patch)
tree62f5c647a743d7114c661ac1537f19c4e4b1ce50
parenta8c41d8a2134b154c44149e99cb71f89f05b9fd2 (diff)
including changes between drafts-14-16.
update cookie and counters correctly after receiving a resource limit message.
-rw-r--r--sbin/ipsec/photurisd/compute_secrets.c259
-rw-r--r--sbin/ipsec/photurisd/handle_identity_request.c10
-rw-r--r--sbin/ipsec/photurisd/handle_identity_response.c10
-rw-r--r--sbin/ipsec/photurisd/handle_resource_limit.c17
-rw-r--r--sbin/ipsec/photurisd/handle_spi_needed.c3
-rw-r--r--sbin/ipsec/photurisd/handle_spi_update.c3
-rw-r--r--sbin/ipsec/photurisd/handle_value_request.c10
-rw-r--r--sbin/ipsec/photurisd/handle_value_response.c6
-rw-r--r--sbin/ipsec/photurisd/identity.c163
-rw-r--r--sbin/ipsec/photurisd/identity.h59
-rw-r--r--sbin/ipsec/photurisd/photuris_cookie_request.c39
-rw-r--r--sbin/ipsec/photurisd/photuris_error_message.c6
-rw-r--r--sbin/ipsec/photurisd/schedule.c32
-rw-r--r--sbin/ipsec/photurisd/secrets.h4
-rw-r--r--sbin/ipsec/photurisd/state.c51
-rw-r--r--sbin/ipsec/photurisd/state.h12
-rw-r--r--sbin/ipsec/photurisd/validity.c183
17 files changed, 536 insertions, 331 deletions
diff --git a/sbin/ipsec/photurisd/compute_secrets.c b/sbin/ipsec/photurisd/compute_secrets.c
index c3622479b8f..f52feae8110 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.3 1997/07/24 23:47:08 provos Exp $";
+static char rcsid[] = "$Id: compute_secrets.c,v 1.4 1997/09/02 17:26:35 provos Exp $";
#endif
#define _SECRETS_C_
@@ -51,6 +51,7 @@ static char rcsid[] = "$Id: compute_secrets.c,v 1.3 1997/07/24 23:47:08 provos E
#include "state.h"
#include <sha1.h>
#include "config.h"
+#include "identity.h"
#include "attributes.h"
#include "modulus.h"
#include "secrets.h"
@@ -60,12 +61,8 @@ static char rcsid[] = "$Id: compute_secrets.c,v 1.3 1997/07/24 23:47:08 provos E
#include "scheme.h"
#include "errlog.h"
-int MD5privacykey(struct stateob *st, u_int8_t *key, u_int8_t *packet,
- u_int16_t bytes, u_int16_t order, int owner);
-int SHA1privacykey(struct stateob *st, u_int8_t *key, u_int8_t *packet,
- u_int16_t bytes, u_int16_t order, int owner);
-
-
+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);
int
compute_shared_secret(struct stateob *st,
u_int8_t **shared, u_int16_t *sharedsize)
@@ -193,14 +190,38 @@ get_session_key_length(u_int8_t *attribute)
*/
int
-compute_session_key(struct stateob *st, u_int8_t *key,
+compute_session_key(struct stateob *st, u_int8_t *key,
u_int8_t *attribute, int owner,
u_int16_t *order)
{
- u_int16_t size, i,n;
- u_int8_t digest[16];
- int bits;
- MD5_CTX ctx;
+ struct idxform *hash;
+ u_int16_t size, i, n;
+ u_int8_t digest[HASH_MAX];
+ int bits, hbits;
+
+ switch(ntohs(*((u_int16_t *)st->scheme))) {
+ case DH_G_2_MD5:
+ case DH_G_3_MD5:
+ case DH_G_2_DES_MD5:
+ case DH_G_5_MD5:
+ case DH_G_3_DES_MD5:
+ case DH_G_5_DES_MD5:
+ case DH_G_VAR_MD5:
+ case DH_G_VAR_DES_MD5:
+ hash = get_hash(HASH_MD5);
+ break;
+ case DH_G_2_3DES_SHA1:
+ case DH_G_3_3DES_SHA1:
+ case DH_G_5_3DES_SHA1:
+ case DH_G_VAR_3DES_SHA1:
+ hash = get_hash(HASH_SHA1);
+ break;
+ default:
+ log_error(0, "Unkown scheme %d in compute_session_key()",
+ ntohs(*((u_int16_t *)st->scheme)));
+ return -1;
+ }
+
if ((bits = get_session_key_length(attribute)) == -1)
return -1;
@@ -209,42 +230,109 @@ compute_session_key(struct stateob *st, u_int8_t *key,
if(bits & 0x7)
size++;
- /* XXX - we only do md5 at the moment */
- *order = (*order^(*order&0x7f)) + (*order & 0x7f ? 128 : 0);
+ hbits = (hash->hashsize << 3);
+ *order += (*order%hbits) ? hbits - (*order%hbits) : 0;
/* As many shared secrets we used already */
- n = *order >> 7;
+ n = *order/hbits;
+
+ hash->Init(hash->ctx);
+ hash->Update(hash->ctx, st->icookie, COOKIE_SIZE);
+ hash->Update(hash->ctx, st->rcookie, COOKIE_SIZE);
+ if(owner) { /* Session key for Owner SPI */
+ hash->Update(hash->ctx,st->oSPIsecret,st->oSPIsecretsize);
+ hash->Update(hash->ctx,st->uSPIsecret,st->uSPIsecretsize);
+ } else { /* Session key for User SPI */
+ hash->Update(hash->ctx,st->uSPIsecret,st->uSPIsecretsize);
+ hash->Update(hash->ctx,st->oSPIsecret,st->oSPIsecretsize);
+ }
+
+ /* Message Verification field */
+ hash->Update(hash->ctx, st->verification, st->versize);
+
+ for (i=0; i<n; i++)
+ hash->Update(hash->ctx, st->shared, st->sharedsize);
do {
- MD5Init(&ctx);
- MD5Update(&ctx, st->icookie, COOKIE_SIZE);
- MD5Update(&ctx, st->rcookie, COOKIE_SIZE);
- if(owner) { /* Session key for Owner SPI */
- MD5Update(&ctx,st->oSPIsecret,st->oSPIsecretsize);
- MD5Update(&ctx,st->uSPIsecret,st->uSPIsecretsize);
- MD5Update(&ctx,st->oSPIidentver, st->oSPIidentversize);
- } else { /* Session key for User SPI */
- MD5Update(&ctx,st->uSPIsecret,st->uSPIsecretsize);
- MD5Update(&ctx,st->oSPIsecret,st->oSPIsecretsize);
- MD5Update(&ctx,st->uSPIidentver, st->uSPIidentversize);
- }
- for(i=0; i<n; i++)
- MD5Update(&ctx,st->shared, st->sharedsize);
- n++;
- MD5Final(digest, &ctx);
- bcopy(digest, key, size>16 ? 16 : size);
- key += size>16 ? 16 : size;
+ bcopy(hash->ctx, hash->ctx2, hash->ctxsize);
+ hash->Update(hash->ctx2,st->shared, st->sharedsize);
+ bcopy(hash->ctx2, hash->ctx, hash->ctxsize);
+
+ hash->Final(digest, hash->ctx2);
+ bcopy(digest, key, size>hash->hashsize ? hash->hashsize : size);
+ key += size>hash->hashsize ? hash->hashsize : size;
/* Unsigned integer arithmetic */
- size -= size>16 ? 16 : size;
+ size -= size>hash->hashsize ? hash->hashsize : size;
} while(size > 0);
- *order += (bits^(bits&0x7f)) + (bits & 0x7f ? 128 : 0);
+ *order += bits + (bits%hbits ? hbits - (bits%hbits) : 0 );
return bits;
}
/*
+ * Initializes the hash contexts for privacy key computation.
+ */
+
+int
+init_privacy_key(struct stateob *st, int owner)
+{
+ void **ctx;
+ struct idxform *hash;
+ u_int8_t *first, *second;
+ u_int16_t firstsize, secondsize;
+
+ if (owner) {
+ ctx = &st->oSPIprivacyctx;
+ first = st->exchangevalue;
+ firstsize = st->exchangesize;
+ second = st->texchange;
+ secondsize = st->texchangesize;
+ } else {
+ ctx = &st->uSPIprivacyctx;
+ first = st->texchange;
+ firstsize = st->texchangesize;
+ second = st->exchangevalue;
+ secondsize = st->exchangesize;
+ }
+
+ switch(ntohs(*((u_int16_t *)st->scheme))) {
+ case DH_G_2_MD5:
+ case DH_G_3_MD5:
+ case DH_G_5_MD5:
+ case DH_G_2_DES_MD5:
+ case DH_G_3_DES_MD5:
+ case DH_G_5_DES_MD5:
+ hash = get_hash(HASH_MD5);
+ break;
+ case DH_G_2_3DES_SHA1:
+ case DH_G_3_3DES_SHA1:
+ case DH_G_5_3DES_SHA1:
+ hash = get_hash(HASH_SHA1);
+ break;
+ default:
+ log_error(0, "Unknown exchange scheme in init_privacy_key()");
+ return -1;
+ }
+
+ if (hash == NULL)
+ return -1;
+
+ if (*ctx != NULL)
+ free(*ctx);
+
+ if ((*ctx = calloc(hash->ctxsize, sizeof(char))) == NULL) {
+ log_error(1, "calloc() in init_privacy_key()");
+ return -1;
+ }
+ hash->Init(*ctx);
+ hash->Update(*ctx, first, firstsize);
+ hash->Update(*ctx, second, secondsize);
+ return 1;
+}
+
+/*
* order gives the number of bits already used for keys
*/
@@ -253,6 +341,7 @@ 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 size;
+ struct idxform *hash;
size = bits >> 3;
if(bits & 0x7)
@@ -265,100 +354,58 @@ compute_privacy_key(struct stateob *st, u_int8_t *key, u_int8_t *packet,
case DH_G_2_DES_MD5:
case DH_G_3_DES_MD5:
case DH_G_5_DES_MD5:
- return MD5privacykey(st, key, packet, size, order, owner);
+ hash = get_hash(HASH_MD5);
+ break;
case DH_G_2_3DES_SHA1:
case DH_G_3_3DES_SHA1:
case DH_G_5_3DES_SHA1:
- return SHA1privacykey(st, key, packet, size, order, owner);
+ hash = get_hash(HASH_SHA1);
+ break;
default:
log_error(0, "Unknown exchange scheme in compute_privacy_key()");
return -1;
}
+
+ if (hash == NULL)
+ return -1;
+
+ return privacykey(st, hash, key, packet, size, order, owner);
}
int
-MD5privacykey(struct stateob *st, u_int8_t *key, u_int8_t *packet,
- u_int16_t bytes, u_int16_t order, int owner)
+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)
{
- MD5_CTX ctx, ctxb;
- u_int16_t i, n;
- u_int8_t digest[16];
+ u_int16_t i, n, hbits;
+ u_int8_t digest[HASH_MAX];
- MD5Init(&ctxb);
+ /* SPIprivacyctx contains the hashed exchangevalues */
+ bcopy(owner ? st->oSPIprivacyctx : st->uSPIprivacyctx,
+ hash->ctx2, hash->ctxsize);
- MD5Update(&ctxb, packet, 2*COOKIE_SIZE + 4 + SPI_SIZE);
-
- if (owner) {
- MD5Update(&ctxb, st->exchangevalue, st->exchangesize);
- MD5Update(&ctxb, st->texchange, st->texchangesize);
- } else {
- MD5Update(&ctxb, st->texchange, st->texchangesize);
- MD5Update(&ctxb, st->exchangevalue, st->exchangesize);
- }
+ hash->Update(hash->ctx2, packet, 2*COOKIE_SIZE + 4 + SPI_SIZE);
/* As many shared secrets we used already */
- n = order&0x7f ? (order >> 7) + 1 : order >> 7;
+ hbits = (hash->hashsize << 3);
+ n = order/hbits + (order%hbits ? 1 : 0);
for(i=0; i<n; i++)
- MD5Update(&ctxb, st->shared, st->sharedsize);
+ hash->Update(hash->ctx2, st->shared, st->sharedsize);
do {
- ctx = ctxb;
- MD5Update(&ctx, st->shared, st->sharedsize);
- ctxb = ctx;
+ bcopy(hash->ctx2, hash->ctx, hash->ctxsize);
+ hash->Update(hash->ctx, st->shared, st->sharedsize);
+ bcopy(hash->ctx, hash->ctx2, hash->ctxsize);
- MD5Final(digest, &ctx);
- bcopy(digest, key, bytes>16 ? 16 : bytes);
- key += bytes>16 ? 16 : bytes;
+ hash->Final(digest, hash->ctx);
+ bcopy(digest, key, bytes>hash->hashsize ? hash->hashsize : bytes);
+ key += bytes>hash->hashsize ? hash->hashsize : bytes;
/* Unsigned integer arithmetic */
- bytes -= bytes>16 ? 16 : bytes;
- } while(bytes>=16);
+ bytes -= bytes>hash->hashsize ? hash->hashsize : bytes;
+ } while(bytes > 0);
return 0;
}
-int
-SHA1privacykey(struct stateob *st, u_int8_t *key, u_int8_t *packet,
- u_int16_t bytes, u_int16_t order, int owner)
-{
- SHA1_CTX ctx, ctxb;
- u_int16_t i, n;
- u_int8_t digest[20];
-
- SHA1Init(&ctxb);
-
- SHA1Update(&ctxb, packet, 2*COOKIE_SIZE + 4 + SPI_SIZE);
-
- if (owner) {
- SHA1Update(&ctxb, st->exchangevalue, st->exchangesize);
- SHA1Update(&ctxb, st->texchange, st->texchangesize);
- } else {
- SHA1Update(&ctxb, st->texchange, st->texchangesize);
- SHA1Update(&ctxb, st->exchangevalue, st->exchangesize);
- }
-
-
- /* As many shared secrets we used already */
- n = order%160 ? order/160+1 : order/160;
- for (i=0; i<n; i++)
- SHA1Update(&ctxb, st->shared, st->sharedsize);
-
- do {
-
- ctx = ctxb;
- SHA1Update(&ctx, st->shared, st->sharedsize);
- ctxb = ctx;
-
- SHA1Final(digest, &ctx);
-
- bcopy(digest, key, bytes>20 ? 20 : bytes);
-
- key += bytes>20 ? 20 : bytes;
-
- /* Unsigned integer arithmetic */
- bytes -= bytes>20 ? 20 : bytes;
- } while(bytes>0);
-
- return 0;
-}
diff --git a/sbin/ipsec/photurisd/handle_identity_request.c b/sbin/ipsec/photurisd/handle_identity_request.c
index 7ba9868c5a8..73ac171827a 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.3 1997/07/23 12:28:48 provos Exp $";
+static char rcsid[] = "$Id: handle_identity_request.c,v 1.4 1997/09/02 17:26:36 provos Exp $";
#endif
#include <stdio.h>
@@ -241,6 +241,10 @@ handle_identity_request(u_char *packet, int size, char *address,
packet_save(st, packet_buffer, packet_size);
+ /* At this point we do not need the exchange values any longer */
+ free(st->texchange); st->texchange = NULL;
+ free(st->exchangevalue); st->exchangevalue = NULL;
+
bcopy(header->SPI, st->uSPI, SPI_SIZE);
st->ulifetime = (header->lifetime[0] << 16) +
(header->lifetime[1] << 8) + header->lifetime[2];
@@ -267,6 +271,8 @@ handle_identity_request(u_char *packet, int size, char *address,
bcopy(st->oSPIattrib, spi->attributes, spi->attribsize);
spi->lifetime = time(NULL) + st->olifetime;
+ /* Cludge for getting the right verification field */
+ state_save_verification(st, st->oSPIidentver, st->oSPIidentversize);
/* Make session keys for Owner */
make_session_keys(st, spi);
@@ -298,6 +304,8 @@ handle_identity_request(u_char *packet, int size, char *address,
bcopy(st->uSPIattrib, spi->attributes, spi->attribsize);
spi->lifetime = time(NULL) + st->ulifetime;
+ /* Cludge for getting the right verification field */
+ state_save_verification(st, st->uSPIidentver, st->uSPIidentversize);
/* Make session keys for User */
make_session_keys(st, spi);
diff --git a/sbin/ipsec/photurisd/handle_identity_response.c b/sbin/ipsec/photurisd/handle_identity_response.c
index 30152173ef5..a0cbedb0839 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.3 1997/07/23 12:28:49 provos Exp $";
+static char rcsid[] = "$Id: handle_identity_response.c,v 1.4 1997/09/02 17:26:37 provos Exp $";
#endif
#include <stdio.h>
@@ -52,6 +52,7 @@ static char rcsid[] = "$Id: handle_identity_response.c,v 1.3 1997/07/23 12:28:49
#include "schedule.h"
#include "encrypt.h"
#include "identity.h"
+#include "attributes.h"
#include "secrets.h"
#include "scheme.h"
#include "errlog.h"
@@ -216,6 +217,9 @@ handle_identity_response(u_char *packet, int size, char *address,
st->packetlen = 0;
}
+ /* At this point we do not need the exchange values any longer */
+ free(st->texchange); st->texchange = NULL;
+ free(st->exchangevalue); st->exchangevalue = NULL;
if (st->oSPI[0] || st->oSPI[1] || st->oSPI[2] || st->oSPI[3]) {
/* Insert Owner SPI */
@@ -239,6 +243,8 @@ handle_identity_response(u_char *packet, int size, char *address,
bcopy(st->oSPIattrib, spi->attributes, spi->attribsize);
spi->lifetime = time(NULL) + st->olifetime;
+ /* Cludge for getting the right verification field */
+ state_save_verification(st, st->oSPIidentver, st->oSPIidentversize);
/* Make session keys for Owner */
make_session_keys(st, spi);
@@ -269,6 +275,8 @@ handle_identity_response(u_char *packet, int size, char *address,
bcopy(st->uSPIattrib, spi->attributes, spi->attribsize);
spi->lifetime = time(NULL) + st->ulifetime;
+ /* Cludge for getting the right verification field */
+ state_save_verification(st, st->uSPIidentver, st->uSPIidentversize);
/* Session keys for User */
make_session_keys(st, spi);
diff --git a/sbin/ipsec/photurisd/handle_resource_limit.c b/sbin/ipsec/photurisd/handle_resource_limit.c
index d3b7b8c5946..2fa5b38e70f 100644
--- a/sbin/ipsec/photurisd/handle_resource_limit.c
+++ b/sbin/ipsec/photurisd/handle_resource_limit.c
@@ -34,7 +34,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: handle_resource_limit.c,v 1.1 1997/07/18 22:48:50 provos Exp $";
+static char rcsid[] = "$Id: handle_resource_limit.c,v 1.2 1997/09/02 17:26:38 provos Exp $";
#endif
#include <stdio.h>
@@ -63,8 +63,7 @@ handle_resource_limit(u_char *packet, int size, char *address)
header = (struct error_message *) packet;
counter = packet[ERROR_MESSAGE_PACKET_SIZE];
- if ((st = state_find_cookies(NULL, header->icookie,
- header->rcookie)) == NULL) {
+ if ((st = state_find_cookies(NULL, header->icookie, NULL)) == NULL) {
log_error(0, "No state for RESOURCE_LIMIT message from %s",
address);
return -1;
@@ -72,6 +71,18 @@ handle_resource_limit(u_char *packet, int size, char *address)
switch(st->phase) {
case COOKIE_REQUEST:
+ /*
+ * The other party has still an exchange which has been
+ * purged on our side.
+ */
+ if (counter != 0) {
+ bcopy(header->rcookie, st->rcookie, COOKIE_SIZE);
+ st->counter = counter;
+ }
+
+ /* We crank the timeout, so we can start a new exchange */
+ st->lifetime += exchange_timeout;
+ st->resource = 1;
case VALUE_REQUEST:
offset = schedule_offset(TIMEOUT, st->icookie);
if (offset == -1)
diff --git a/sbin/ipsec/photurisd/handle_spi_needed.c b/sbin/ipsec/photurisd/handle_spi_needed.c
index f070d675b81..2db8f8e81cd 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.3 1997/07/23 12:28:49 provos Exp $";
+static char rcsid[] = "$Id: handle_spi_needed.c,v 1.4 1997/09/02 17:26:39 provos Exp $";
#endif
#include <stdio.h>
@@ -49,6 +49,7 @@ static char rcsid[] = "$Id: handle_spi_needed.c,v 1.3 1997/07/23 12:28:49 provos
#include "packet.h"
#include "encrypt.h"
#include "validity.h"
+#include "attributes.h"
#include "secrets.h"
#include "schedule.h"
#include "scheme.h"
diff --git a/sbin/ipsec/photurisd/handle_spi_update.c b/sbin/ipsec/photurisd/handle_spi_update.c
index 20bd3a488a4..84ef551e5eb 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.3 1997/07/23 12:28:50 provos Exp $";
+static char rcsid[] = "$Id: handle_spi_update.c,v 1.4 1997/09/02 17:26:40 provos Exp $";
#endif
#include <stdio.h>
@@ -49,6 +49,7 @@ static char rcsid[] = "$Id: handle_spi_update.c,v 1.3 1997/07/23 12:28:50 provos
#include "packet.h"
#include "encrypt.h"
#include "validity.h"
+#include "attributes.h"
#include "secrets.h"
#include "schedule.h"
#include "scheme.h"
diff --git a/sbin/ipsec/photurisd/handle_value_request.c b/sbin/ipsec/photurisd/handle_value_request.c
index 4abd1f3402e..b3df46b3639 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.3 1997/07/24 23:47:13 provos Exp $";
+static char rcsid[] = "$Id: handle_value_request.c,v 1.4 1997/09/02 17:26:40 provos Exp $";
#endif
#include <stdio.h>
@@ -218,6 +218,8 @@ handle_value_request(u_char *packet, int size,
}
bcopy(VALUE_REQUEST_VALUE(header), st->texchange, st->texchangesize);
+
+ /* Fill in the state object with generic data */
strncpy(st->address, address, 15);
st->port = port;
st->counter = header->counter;
@@ -259,6 +261,12 @@ handle_value_request(u_char *packet, int size,
}
#endif
+ if (st->oSPIprivacyctx == NULL) {
+ /* Initialize Privacy Keys from Exchange Values */
+ init_privacy_key(st, 0); /* User -> Owner direction */
+ init_privacy_key(st, 1); /* Owner -> User direction */
+ }
+
st->retries = 0;
st->phase = VALUE_RESPONSE;
return 0;
diff --git a/sbin/ipsec/photurisd/handle_value_response.c b/sbin/ipsec/photurisd/handle_value_response.c
index 34311281236..2ef53dd557c 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.2 1997/07/24 23:47:14 provos Exp $";
+static char rcsid[] = "$Id: handle_value_response.c,v 1.3 1997/09/02 17:26:41 provos Exp $";
#endif
#include <stdlib.h>
@@ -148,6 +148,10 @@ handle_value_response(u_char *packet, int size, char *address,
return -1;
}
+ /* Initialize Privacy Keys from Exchange Values */
+ init_privacy_key(st, 0); /* User -> Owner direction */
+ init_privacy_key(st, 1); /* Owner -> User direction */
+
packet_size = PACKET_BUFFER_SIZE;
if (photuris_identity_request(st, packet_buffer, &packet_size) == -1)
return -1;
diff --git a/sbin/ipsec/photurisd/identity.c b/sbin/ipsec/photurisd/identity.c
index 6b905929d92..f5517e4508c 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.3 1997/07/24 23:47:15 provos Exp $";
+static char rcsid[] = "$Id: identity.c,v 1.4 1997/09/02 17:26:42 provos Exp $";
#endif
#define _IDENTITY_C_
@@ -72,17 +72,19 @@ static struct identity *idob = NULL;
static union {
MD5_CTX md5ctx;
SHA1_CTX sha1ctx;
-} Ctx;
+} Ctx, Ctx2;
/* Identity transforms */
/* XXX - argh, cast the funtions */
static struct idxform idxform[] = {
- { AT_MD5_DP, MD5_SIZE, (void *)&Ctx.md5ctx,
+ { HASH_MD5, 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 },
- { AT_SHA1_DP, SHA1_SIZE, (void *)&Ctx.sha1ctx,
+ { HASH_SHA1, SHA1_SIZE, (void *)&Ctx.sha1ctx,
+ sizeof(SHA1_CTX), (void *)&Ctx2.sha1ctx,
(void (*)(void *))SHA1Init,
(void (*)(void *, unsigned char *, unsigned int))SHA1Update,
(void (*)(unsigned char *, void *))SHA1Final },
@@ -464,23 +466,78 @@ get_identity_verification_size(struct stateob *st, u_int8_t *choice)
}
}
+struct idxform *get_hash(enum hashes hashtype)
+{
+ int i;
+ for (i=0; i<sizeof(idxform)/sizeof(idxform[0]); i++)
+ if (hashtype == idxform[i].type)
+ return &idxform[i];
+ log_error(0, "Unkown hash type: %d in get_hash()", hashtype);
+ return NULL;
+}
+
+int
+create_verification_key(struct stateob *st, u_int8_t *buffer, u_int16_t *size,
+ int owner)
+{
+ struct idxform *hash;
+
+ 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));
+ return -1;
+ }
+
+ if (hash == NULL)
+ return -1;
+
+ if (*size < hash->hashsize)
+ return -1;
+
+ hash->Init(hash->ctx);
+ if (owner)
+ hash->Update(hash->ctx, st->oSPIsecret, st->oSPIsecretsize);
+ else
+ hash->Update(hash->ctx, st->uSPIsecret, st->uSPIsecretsize);
+
+ hash->Update(hash->ctx, st->shared, st->sharedsize);
+ hash->Final(buffer, hash->ctx);
+ *size = hash->hashsize;
+
+ return 0;
+}
+
int
create_identity_verification(struct stateob *st, u_int8_t *buffer,
u_int8_t *packet, u_int16_t size)
{
- int hash_size, i;
+ int hash_size;
+ struct idxform *hash;
- for (i=0; i<sizeof(idxform)/sizeof(idxform[0]); i++)
- if (*(st->oSPIidentchoice) == idxform[i].type)
- break;
-
- if (i == sizeof(idxform)/sizeof(idxform[0])) {
- log_error(0, "Unknown identity choice: %d",
- *(st->oSPIidentchoice));
+ switch(*(st->oSPIidentchoice)) {
+ 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",
+ *(st->oSPIidentchoice));
return 0;
- }
+ }
+
+ if (hash == NULL)
+ return 0;
- hash_size = idsign(st, &idxform[i], buffer+2, packet,size);
+ hash_size = idsign(st, hash, buffer+2, packet,size);
if(hash_size) {
/* Create varpre number from digest */
@@ -498,6 +555,8 @@ create_identity_verification(struct stateob *st, u_int8_t *buffer,
bcopy(buffer, st->oSPIidentver, hash_size+2);
st->oSPIidentversize = hash_size+2;
+
+ state_save_verification(st, st->oSPIidentver, hash_size+2);
}
return hash_size+2;
}
@@ -506,21 +565,30 @@ int
verify_identity_verification(struct stateob *st, u_int8_t *buffer,
u_int8_t *packet, u_int16_t size)
{
- int i;
+ struct idxform *hash;
- for (i=0; i<sizeof(idxform)/sizeof(idxform[0]); i++)
- if (*(st->uSPIidentchoice) == idxform[i].type)
- break;
-
- if (i == sizeof(idxform)/sizeof(idxform[0])) {
- log_error(0, "Unknown identity choice %d in verify_identity_verification()",
- *(st->uSPIidentchoice));
+ switch(*(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",
+ *(st->uSPIidentchoice));
return 0;
- }
+ }
- if (varpre2octets(buffer) != idxform[i].hashsize +2)
+ if (hash == NULL)
return 0;
- return idverify(st, &idxform[i], buffer+2, packet, size);
+
+ if (varpre2octets(buffer) != hash->hashsize +2)
+ return 0;
+
+ state_save_verification(st, buffer, hash->hashsize+2);
+
+ return idverify(st, hash, buffer+2, packet, size);
}
@@ -529,34 +597,38 @@ 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;
+
+ create_verification_key(st, key, &keylen, 1); /* Owner direction */
hash->Init(hash->ctx);
- hash->Update(hash->ctx, st->shared, st->sharedsize);
+ /* Our verification key */
+ hash->Update(hash->ctx, key, keylen);
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));
- hash->Update(hash->ctx, st->oSPIsecret, st->oSPIsecretsize);
/* Their exchange value */
hash->Update(hash->ctx, st->texchange, st->texchangesize);
hash->Update(hash->ctx, st->uSPIoattrib, st->uSPIoattribsize);
if(st->uSPIident != NULL) {
- hash->Update(hash->ctx, st->uSPIident, strlen(st->uSPIident));
- hash->Update(hash->ctx, st->uSPIsecret, st->uSPIsecretsize);
+ hash->Update(hash->ctx, st->uSPIidentver, st->uSPIidentversize);
}
- /* Hash type, lifetime + spi fields */
- p = (struct identity_message *)packet;
- hash->Update(hash->ctx, (char *)&(p->type), IDENTITY_MESSAGE_MIN - 2*COOKIE_SIZE);
-
/* Hash attribute choice, padding */
packet += IDENTITY_MESSAGE_MIN;
psize -= IDENTITY_MESSAGE_MIN + packet[1] + 2;
@@ -570,7 +642,7 @@ idsign(struct stateob *st, struct idxform *hash, u_int8_t *signature,
hash->Final(NULL, hash->ctx);
/* And finally the trailing key */
- hash->Update(hash->ctx, st->shared, st->sharedsize);
+ hash->Update(hash->ctx, key, keylen);
hash->Final(signature, hash->ctx);
@@ -581,25 +653,32 @@ int
idverify(struct stateob *st, struct idxform *hash, u_int8_t *signature,
u_int8_t *packet, u_int16_t psize)
{
- u_int8_t digest[20]; /* XXX - needs adjusting */
+ u_int8_t digest[HASH_MAX];
struct identity_message *p;
+ u_int8_t key[HASH_MAX];
+ u_int16_t keylen = HASH_MAX;
+
+ create_verification_key(st, key, &keylen, 0); /* User direction */
p = (struct identity_message *)packet;
hash->Init(hash->ctx);
- /* Our shared secret */
- hash->Update(hash->ctx, st->shared, st->sharedsize);
+ /* Their verification key */
+ hash->Update(hash->ctx, key, keylen);
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));
- hash->Update(hash->ctx, st->uSPIsecret, st->uSPIsecretsize);
/* Our exchange value */
hash->Update(hash->ctx, st->exchangevalue, st->exchangesize);
@@ -607,13 +686,9 @@ idverify(struct stateob *st, struct idxform *hash, u_int8_t *signature,
/* Determine if the sender knew our secret already */
if(p->type != IDENTITY_REQUEST) {
- hash->Update(hash->ctx, st->oSPIident, strlen(st->oSPIident));
- hash->Update(hash->ctx, st->oSPIsecret, st->oSPIsecretsize);
+ hash->Update(hash->ctx, st->oSPIidentver, st->oSPIidentversize);
}
- /* Hash type, lifetime + spi fields */
- hash->Update(hash->ctx, (char *)&(p->type), IDENTITY_MESSAGE_MIN - 2*COOKIE_SIZE);
-
packet += IDENTITY_MESSAGE_MIN;
psize -= IDENTITY_MESSAGE_MIN + packet[1] + 2;
packet += packet[1] + 2;
@@ -625,7 +700,7 @@ idverify(struct stateob *st, struct idxform *hash, u_int8_t *signature,
hash->Final(NULL, hash->ctx);
/* And finally the trailing key */
- hash->Update(hash->ctx, st->shared, st->sharedsize);
+ hash->Update(hash->ctx, key, keylen);
hash->Final(digest, hash->ctx);
diff --git a/sbin/ipsec/photurisd/identity.h b/sbin/ipsec/photurisd/identity.h
index 8e26d7223fa..141a8412845 100644
--- a/sbin/ipsec/photurisd/identity.h
+++ b/sbin/ipsec/photurisd/identity.h
@@ -37,6 +37,30 @@
#define _IDENTITY_H_
#include "state.h"
+struct identity {
+ struct identity *next;
+ struct identity *root;
+ int type;
+ char *tag;
+ char *pairid;
+ void *object;
+};
+
+enum hashes {
+ HASH_MD5 = 0,
+ 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 */
+ int ctxsize;
+ void *ctx2; /* Pointer to a 2nd context for speedup */
+ void (*Init)(void *);
+ void (*Update)(void *, unsigned char *, unsigned int);
+ void (*Final)(unsigned char *, void *);
+};
+
#undef EXTERN
#ifdef _IDENTITY_C_
#define EXTERN
@@ -49,39 +73,23 @@ char *secret_file = NULL;
extern char *secret_file;
#endif
-#define ID_LOCAL 1
-#define ID_LOCALPAIR 2
-#define ID_REMOTE 4
-#define ID_LOOKUP 8
+#define ID_LOCAL 1
+#define ID_LOCALPAIR 2
+#define ID_REMOTE 4
+#define ID_LOOKUP 8
#define IDENT_LOCAL "identity local"
#define IDENT_LOCALPAIR "identity pair local"
#define IDENT_REMOTE "identity remote"
#define IDENT_LOOKUP "identity lookup"
-#define MAX_IDENT 120
+#define MAX_IDENT 120
#define MAX_IDENT_SECRET 120
-struct identity {
- struct identity *next;
- struct identity *root;
- int type;
- char *tag;
- char *pairid;
- void *object;
-};
+#define MD5_SIZE 16
+#define SHA1_SIZE 20
-#define MD5_SIZE 16
-#define SHA1_SIZE 20
-
-struct idxform {
- u_int8_t type; /* Type of the transform */
- u_int8_t hashsize; /* Size of the hash */
- void *ctx; /* Pointer to a context */
- void (*Init)(void *);
- void (*Update)(void *, unsigned char *, unsigned int);
- void (*Final)(unsigned char *, void *);
-};
+#define HASH_MAX 20 /* Keep this uptodate with hashsizes */
int init_identities(char *name, struct identity *ob);
int identity_insert(struct identity **idob, struct identity *ob);
@@ -101,6 +109,9 @@ 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(enum hashes hashtype);
+int create_verification_key(struct stateob *, u_int8_t *, u_int16_t *, int);
+
int idsign(struct stateob *, struct idxform *, u_int8_t *,
u_int8_t *, u_int16_t);
int idverify(struct stateob *, struct idxform *, u_int8_t *,
diff --git a/sbin/ipsec/photurisd/photuris_cookie_request.c b/sbin/ipsec/photurisd/photuris_cookie_request.c
index d1b279dc0c2..aad05e3368a 100644
--- a/sbin/ipsec/photurisd/photuris_cookie_request.c
+++ b/sbin/ipsec/photurisd/photuris_cookie_request.c
@@ -34,7 +34,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: photuris_cookie_request.c,v 1.2 1997/07/24 23:47:16 provos Exp $";
+static char rcsid[] = "$Id: photuris_cookie_request.c,v 1.3 1997/09/02 17:26:44 provos Exp $";
#endif
#include <stdio.h>
@@ -61,25 +61,26 @@ photuris_cookie_request(struct stateob *st, u_char *buffer, int *size)
header = (struct cookie_request *) buffer;
*size = COOKIE_REQUEST_PACKET_SIZE; /* fixed size */
- st->counter = 0;
- prev_st = state_find(st->address);
- old_st = NULL;
- while (prev_st != NULL) {
- if (prev_st->lifetime >= timeout) {
- timeout = prev_st->lifetime;
- old_st = prev_st;
+ if (st->counter == 0) {
+ prev_st = state_find(st->address);
+ old_st = NULL;
+ while (prev_st != NULL) {
+ if (prev_st->lifetime >= timeout) {
+ timeout = prev_st->lifetime;
+ old_st = prev_st;
+ }
+ prev_st = prev_st->next;
}
- prev_st = prev_st->next;
- }
-
- /* Check if we have an exchange going already */
- if (old_st != NULL && old_st != st && timeout > time(NULL)) {
- if (old_st->initiator) {
- bcopy(old_st->rcookie, st->rcookie, COOKIE_SIZE);
- st->counter = old_st->counter;
- } else {
- bcopy(old_st->icookie, st->rcookie, COOKIE_SIZE);
- st->counter = 0;
+
+ /* Check if we have an exchange going already */
+ if (old_st != NULL && old_st != st && timeout > time(NULL)) {
+ if (old_st->initiator) {
+ bcopy(old_st->rcookie, st->rcookie, COOKIE_SIZE);
+ st->counter = old_st->counter;
+ } else {
+ bcopy(old_st->icookie, st->rcookie, COOKIE_SIZE);
+ st->counter = 0;
+ }
}
}
diff --git a/sbin/ipsec/photurisd/photuris_error_message.c b/sbin/ipsec/photurisd/photuris_error_message.c
index dd83a0fcd60..882b026fc20 100644
--- a/sbin/ipsec/photurisd/photuris_error_message.c
+++ b/sbin/ipsec/photurisd/photuris_error_message.c
@@ -34,7 +34,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: photuris_error_message.c,v 1.1 1997/07/18 22:48:49 provos Exp $";
+static char rcsid[] = "$Id: photuris_error_message.c,v 1.2 1997/09/02 17:26:45 provos Exp $";
#endif
#include <stdio.h>
@@ -76,8 +76,10 @@ photuris_error_message(struct stateob *st, u_char *buffer, int *size,
if (i != COOKIE_SIZE || counter != 0)
return 0;
- if (st != NULL)
+ if (st != NULL) {
bcopy(st->rcookie, header->rcookie, COOKIE_SIZE);
+ buffer[ERROR_MESSAGE_PACKET_SIZE] = st->counter;
+ }
}
return 0;
diff --git a/sbin/ipsec/photurisd/schedule.c b/sbin/ipsec/photurisd/schedule.c
index 8200cb5e5a7..84ea933f34a 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.3 1997/07/23 12:28:54 provos Exp $";
+static char rcsid[] = "$Id: schedule.c,v 1.4 1997/09/02 17:26:46 provos Exp $";
#endif
#define _SCHEDULE_C_
@@ -58,6 +58,7 @@ static char rcsid[] = "$Id: schedule.c,v 1.3 1997/07/23 12:28:54 provos Exp $";
#include "errlog.h"
#include "cookie.h"
#include "modulus.h"
+#include "api.h"
#ifdef IPSEC
#include "kernel.h"
#endif
@@ -228,23 +229,42 @@ schedule_process(int sock)
break;
} else if (st->retries >= max_retries) {
remove = 1;
- if (st->phase == COOKIE_REQUEST)
+ if (st->phase == COOKIE_REQUEST && st->resource == 0) {
log_error(0, "no anwser for cookie request to %s:%d",
st->address, st->port);
- else
+ break;
+ } else if(st->phase == COOKIE_REQUEST) {
+ /* Try again with updated counters */
+ struct stateob *newst;
+ if ((newst = state_new()) == NULL) {
+ log_error(1, "state_new() in schedule_process()");
+ break;
+ }
+ 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);
+#endif /* DEBUG */
+ start_exchange(sock, newst, st->address, st->port);
+ break;
+ } else {
log_error(0, "exchange terminated, phase %d to %s:%d",
st->phase, st->address, st->port);
- break;
+ break;
+ }
}
- st->retries++;
-
+
if (st->packet == NULL || st->packetlen == 0) {
log_error(0, "no packet in schedule_process()");
remove = 1;
+ break;
}
+
/* Only send the packet when no error occured */
if (!remove) {
+ st->retries++;
+
sin.sin_port = htons(st->port);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(st->address);
diff --git a/sbin/ipsec/photurisd/secrets.h b/sbin/ipsec/photurisd/secrets.h
index 3063ab7b3e0..ed7e763dba4 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.1 1997/07/18 22:48:49 provos Exp $ */
+/* $Id: secrets.h,v 1.2 1997/09/02 17:26:48 provos Exp $ */
/*
* secrets.h:
* prototypes for compute_secrets.c
@@ -53,6 +53,8 @@ EXTERN int compute_session_key(struct stateob *st, u_int8_t *key,
u_int8_t *attribute, int owner,
u_int16_t *order);
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);
diff --git a/sbin/ipsec/photurisd/state.c b/sbin/ipsec/photurisd/state.c
index 6256c8275c4..5b45ef9d7a4 100644
--- a/sbin/ipsec/photurisd/state.c
+++ b/sbin/ipsec/photurisd/state.c
@@ -88,6 +88,51 @@ state_unlink(struct stateob *ob)
return 0;
}
+int
+state_save_verification(struct stateob *st, u_int8_t *buf, u_int16_t len)
+{
+ if (st->verification == NULL || len > st->versize) {
+ if (st->verification != NULL)
+ free(st->verification);
+
+ if ((st->verification = calloc(len, sizeof(u_int8_t))) == NULL) {
+ log_error(1, "calloc() in state_save_verification()");
+ return -1;
+ }
+ }
+
+ bcopy(buf, st->verification, len);
+ st->versize = len;
+ return 0;
+}
+
+
+/*
+ * Copies configuration flags from one state to the other
+ */
+
+void
+state_copy_flags(struct stateob *src, struct stateob *dst)
+{
+ dst->initiator = src->initiator;
+
+ if (src->user != NULL)
+ dst->user = strdup(src->user);
+
+ dst->flags = src->flags;
+ dst->isrc = src->isrc;
+ dst->ismask = src->ismask;
+ dst->idst = src->idst;
+ dst->idmask = src->idmask;
+
+ strncpy(dst->address, src->address, sizeof(src->address)-1);
+ dst->address[sizeof(dst->address)-1] = 0;
+
+ dst->lifetime = src->lifetime;
+ dst->exchange_lifetime = src->exchange_lifetime;
+ dst->spi_lifetime = src->spi_lifetime;
+}
+
struct stateob *
state_new(void)
{
@@ -116,6 +161,8 @@ state_value_reset(struct stateob *ob)
if (ob->exchangevalue != NULL)
free(ob->exchangevalue);
+ if (ob->verification != NULL)
+ free(ob->verification);
if (ob->roschemes != NULL)
free(ob->roschemes);
if (ob->scheme != NULL)
@@ -138,6 +185,8 @@ state_value_reset(struct stateob *ob)
free(ob->oSPIidentver);
if (ob->oSPIidentchoice != NULL)
free(ob->oSPIidentchoice);
+ if (ob->oSPIprivacyctx != NULL)
+ free(ob->oSPIprivacyctx);
if (ob->uSPIident != NULL)
free(ob->uSPIident);
@@ -151,6 +200,8 @@ state_value_reset(struct stateob *ob)
free(ob->uSPIidentver);
if (ob->uSPIidentchoice != NULL)
free(ob->uSPIidentchoice);
+ if (ob->uSPIprivacyctx != NULL)
+ free(ob->uSPIprivacyctx);
if (ob->packet != NULL)
free(ob->packet);
diff --git a/sbin/ipsec/photurisd/state.h b/sbin/ipsec/photurisd/state.h
index 823ea69c44e..8cf69c98de3 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.3 1997/07/24 23:47:20 provos Exp $ */
+/* $Id: state.h,v 1.4 1997/09/02 17:26:49 provos Exp $ */
/*
* state.h:
* state object
@@ -72,7 +72,11 @@ struct stateob {
u_int8_t icookie[COOKIE_SIZE]; /* Initator cookie */
u_int8_t rcookie[COOKIE_SIZE]; /* Responder cookie */
- u_int8_t counter; /* */
+ u_int8_t counter; /* Connection counter */
+ u_int8_t resource; /* Received a resource limit */
+
+ u_int8_t *verification; /* Verification field of last touched message */
+ u_int16_t versize;
u_int8_t *scheme; /* Selected exchange scheme, holds gen. */
u_int16_t schemesize; /* Size including value ... */
@@ -92,6 +96,7 @@ struct stateob {
u_int16_t oSPIidentversize;
u_int8_t *oSPIidentchoice; /* Owner SPI Identity Choice */
u_int16_t oSPIidentchoicesize;
+ void *oSPIprivacyctx;
time_t olifetime; /* Owner SPI lifetime */
u_int8_t uSPI[SPI_SIZE]; /* User SPI */
@@ -106,6 +111,7 @@ struct stateob {
u_int16_t uSPIidentversize;
u_int8_t *uSPIidentchoice; /* User SPI Identity Choice */
u_int16_t uSPIidentchoicesize;
+ void *uSPIprivacyctx;
time_t ulifetime; /* User SPI lifetime */
mpz_t modulus; /* Modulus for look up in cache */
@@ -134,6 +140,8 @@ struct stateob *state_root(void);
struct stateob *state_find(char *);
struct stateob *state_find_next(struct stateob *, char *);
struct stateob *state_find_cookies(char *, u_int8_t *, u_int8_t *);
+int state_save_verification(struct stateob *st, u_int8_t *buf, u_int16_t len);
+void state_copy_flags(struct stateob *src, struct stateob *dst);
void state_cleanup(void);
void state_expire(void);
diff --git a/sbin/ipsec/photurisd/validity.c b/sbin/ipsec/photurisd/validity.c
index d1b64268f0f..92d778bb63e 100644
--- a/sbin/ipsec/photurisd/validity.c
+++ b/sbin/ipsec/photurisd/validity.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: validity.c,v 1.1 1997/07/18 22:48:50 provos Exp $";
+static char rcsid[] = "$Id: validity.c,v 1.2 1997/09/02 17:26:50 provos Exp $";
#endif
#define _VALIDITY_C_
@@ -54,16 +54,13 @@ static char rcsid[] = "$Id: validity.c,v 1.1 1997/07/18 22:48:50 provos Exp $";
#include "state.h"
#include "attributes.h"
#include "validity.h"
+#include "identity.h"
#include "buffer.h"
-int MD5valsign(struct stateob *st, u_int8_t *signature,
- u_int8_t *packet, u_int16_t psize);
-int MD5valverify(struct stateob *st, u_int8_t *signature,
- u_int8_t *packet, u_int16_t psize);
-int SHA1valsign(struct stateob *st, u_int8_t *signature,
- u_int8_t *packet, u_int16_t psize);
-int SHA1valverify(struct stateob *st, u_int8_t *signature,
- u_int8_t *packet, u_int16_t psize);
+int valsign(struct stateob *st, struct idxform *hash, u_int8_t *signature,
+ u_int8_t *packet, u_int16_t psize);
+int valverify(struct stateob *st, struct idxform *hash, u_int8_t *signature,
+ u_int8_t *packet, u_int16_t psize);
u_int16_t
get_validity_verification_size(struct stateob *st)
@@ -91,7 +88,7 @@ int
create_validity_verification(struct stateob *st, u_int8_t *buffer,
u_int8_t *packet, u_int16_t size)
{
- int hash_size;
+ struct idxform *hash;
switch(ntohs(*((u_int16_t *)st->scheme))) {
case DH_G_2_MD5:
@@ -100,12 +97,12 @@ create_validity_verification(struct stateob *st, u_int8_t *buffer,
case DH_G_2_DES_MD5:
case DH_G_3_DES_MD5:
case DH_G_5_DES_MD5:
- hash_size = MD5valsign(st, buffer+2, packet, size);
+ hash = get_hash(HASH_MD5);
break;
case DH_G_2_3DES_SHA1:
case DH_G_3_3DES_SHA1:
case DH_G_5_3DES_SHA1:
- hash_size = SHA1valsign(st, buffer+2, packet, size);
+ hash = get_hash(HASH_SHA1);
break;
default:
log_error(0, "validity.c: Unknown exchange scheme: %d\n",
@@ -113,19 +110,23 @@ create_validity_verification(struct stateob *st, u_int8_t *buffer,
return 0;
}
- if(hash_size) {
+ if(valsign(st, hash, buffer+2, packet, size)) {
/* Create varpre number from digest */
- buffer[0] = (hash_size >> 5) & 0xFF;
- buffer[1] = (hash_size << 3) & 0xFF;
+ buffer[0] = (hash->hashsize >> 5) & 0xFF;
+ buffer[1] = (hash->hashsize << 3) & 0xFF;
}
- return size+2;
+ state_save_verification(st, buffer, hash->hashsize+2);
+
+ return hash->hashsize+2;
}
int
verify_validity_verification(struct stateob *st, u_int8_t *buffer,
u_int8_t *packet, u_int16_t size)
{
+ struct idxform *hash;
+
switch(ntohs(*((u_int16_t *)st->scheme))) {
case DH_G_2_MD5:
case DH_G_3_MD5:
@@ -135,150 +136,96 @@ verify_validity_verification(struct stateob *st, u_int8_t *buffer,
case DH_G_5_DES_MD5:
if (varpre2octets(buffer) != 18)
return 0;
- return MD5valverify(st, buffer+2, packet, size);
+ hash = get_hash(HASH_MD5);
+ break;
case DH_G_2_3DES_SHA1:
case DH_G_3_3DES_SHA1:
case DH_G_5_3DES_SHA1:
if (varpre2octets(buffer) != 22)
return 0;
- return SHA1valverify(st, buffer+2, packet, size);
+ hash = get_hash(HASH_SHA1);
+ break;
default:
log_error(0, "validity.c: Unknown exchange scheme: %d\n",
*((u_int16_t *)st->scheme));
return 0;
}
-}
-
-
-int
-MD5valsign(struct stateob *st, u_int8_t *signature,
- u_int8_t *packet, u_int16_t psize)
-{
- MD5_CTX ctx;
-
- MD5Init(&ctx);
-
- MD5Update(&ctx, st->shared, st->sharedsize);
- MD5Update(&ctx, st->icookie, COOKIE_SIZE);
- MD5Update(&ctx, st->rcookie, COOKIE_SIZE);
+ state_save_verification(st, buffer, hash->hashsize+2);
- MD5Update(&ctx, st->oSPIidentver, st->oSPIidentversize);
- MD5Update(&ctx, st->uSPIidentver, st->uSPIidentversize);
-
- packet += 2*COOKIE_SIZE; psize -= 2*COOKIE_SIZE;
- MD5Update(&ctx, packet, 4 + SPI_SIZE);
-
- packet += 4 + SPI_SIZE + 18; psize -= 4 + SPI_SIZE + 18;
- MD5Update(&ctx, packet, psize);
-
- /* Data fill */
- MD5Final(NULL, &ctx);
-
- MD5Update(&ctx, st->shared, st->sharedsize);
- MD5Final(signature, &ctx);
+ return valverify(st, hash, buffer+2, packet, size);
+}
- return MD5_SIZE;
-}
-
-/* We assume that the verification field is zeroed */
int
-MD5valverify(struct stateob *st, u_int8_t *signature,
- u_int8_t *packet, u_int16_t psize)
+valsign(struct stateob *st, struct idxform *hash, u_int8_t *signature,
+ u_int8_t *packet, u_int16_t psize)
{
- MD5_CTX ctx;
- u_int8_t digest[MD5_SIZE];
-
+ u_int8_t key[HASH_MAX];
+ u_int16_t keylen = HASH_MAX;
- MD5Init(&ctx);
+ create_verification_key(st, key, &keylen, 1); /* Owner direction */
- MD5Update(&ctx, st->shared, st->sharedsize);
-
- MD5Update(&ctx, st->icookie, COOKIE_SIZE);
- MD5Update(&ctx, st->rcookie, COOKIE_SIZE);
-
-
- MD5Update(&ctx, st->uSPIidentver, st->uSPIidentversize);
- MD5Update(&ctx, st->oSPIidentver, st->oSPIidentversize);
-
- packet += 2*COOKIE_SIZE; psize -= 2*COOKIE_SIZE;
- MD5Update(&ctx, packet, 4 + SPI_SIZE);
-
- packet += 4 + SPI_SIZE + 18; psize -= 4 + SPI_SIZE + 18;
- MD5Update(&ctx, packet, psize);
-
- /* Data fill */
- MD5Final(NULL, &ctx);
-
- MD5Update(&ctx, st->shared, st->sharedsize);
- MD5Final(digest, &ctx);
-
- return !bcmp(digest,signature,MD5_SIZE);
-}
-
-int
-SHA1valsign(struct stateob *st, u_int8_t *signature,
- u_int8_t *packet, u_int16_t psize)
-{
- SHA1_CTX ctx;
+ hash->Init(hash->ctx);
- SHA1Init(&ctx);
-
- SHA1Update(&ctx, st->shared, st->sharedsize);
-
- SHA1Update(&ctx, st->icookie, COOKIE_SIZE);
- SHA1Update(&ctx, st->rcookie, COOKIE_SIZE);
+ hash->Update(hash->ctx, key, keylen);
- SHA1Update(&ctx, st->oSPIidentver, st->oSPIidentversize);
- SHA1Update(&ctx, st->uSPIidentver, st->uSPIidentversize);
+ hash->Update(hash->ctx, st->icookie, COOKIE_SIZE);
+ hash->Update(hash->ctx, st->rcookie, COOKIE_SIZE);
packet += 2*COOKIE_SIZE; psize -= 2*COOKIE_SIZE;
- SHA1Update(&ctx, packet, 4 + SPI_SIZE);
+ hash->Update(hash->ctx, packet, 4 + SPI_SIZE);
- packet += 4 + SPI_SIZE + 22; psize -= 4 + SPI_SIZE + 22;
- SHA1Update(&ctx, packet, psize);
+ hash->Update(hash->ctx, st->oSPIidentver, st->oSPIidentversize);
+ hash->Update(hash->ctx, st->uSPIidentver, st->uSPIidentversize);
+
+ packet += 4 + SPI_SIZE + hash->hashsize + 2;
+ psize -= 4 + SPI_SIZE + hash->hashsize + 2;
+ hash->Update(hash->ctx, packet, psize);
/* Data fill */
- SHA1Final(NULL, &ctx);
+ hash->Final(NULL, hash->ctx);
- SHA1Update(&ctx, st->shared, st->sharedsize);
- SHA1Final(signature, &ctx);
+ hash->Update(hash->ctx, key, keylen);
+ hash->Final(signature, hash->ctx);
- return SHA1_SIZE;
+ return hash->hashsize;
}
/* We assume that the verification field is zeroed */
int
-SHA1valverify(struct stateob *st, u_int8_t *signature,
+valverify(struct stateob *st, struct idxform *hash, u_int8_t *signature,
u_int8_t *packet, u_int16_t psize)
{
- SHA1_CTX ctx;
- u_int8_t digest[SHA1_SIZE];
-
+ u_int8_t digest[HASH_MAX];
+ u_int8_t key[HASH_MAX];
+ u_int16_t keylen = HASH_MAX;
- SHA1Init(&ctx);
+ create_verification_key(st, key, &keylen, 0); /* User direction */
- SHA1Update(&ctx, st->shared, st->sharedsize);
-
- SHA1Update(&ctx, st->icookie, COOKIE_SIZE);
- SHA1Update(&ctx, st->rcookie, COOKIE_SIZE);
+ hash->Init(hash->ctx);
+
+ hash->Update(hash->ctx, key, keylen);
- SHA1Update(&ctx, st->uSPIidentver, st->uSPIidentversize);
- SHA1Update(&ctx, st->oSPIidentver, st->oSPIidentversize);
+ hash->Update(hash->ctx, st->icookie, COOKIE_SIZE);
+ hash->Update(hash->ctx, st->rcookie, COOKIE_SIZE);
packet += 2*COOKIE_SIZE; psize -= 2*COOKIE_SIZE;
- SHA1Update(&ctx, packet, 4 + SPI_SIZE);
+ hash->Update(hash->ctx, packet, 4 + SPI_SIZE);
+
+ hash->Update(hash->ctx, st->uSPIidentver, st->uSPIidentversize);
+ hash->Update(hash->ctx, st->oSPIidentver, st->oSPIidentversize);
- packet += 4 + SPI_SIZE + 22; psize -= 4 + SPI_SIZE + 22;
- SHA1Update(&ctx, packet, psize);
+ packet += 4 + SPI_SIZE + hash->hashsize + 2;
+ psize -= 4 + SPI_SIZE + hash->hashsize + 2;
+ hash->Update(hash->ctx, packet, psize);
/* Data fill */
- SHA1Final(NULL, &ctx);
+ hash->Final(NULL, hash->ctx);
- SHA1Update(&ctx, st->shared, st->sharedsize);
- SHA1Final(digest, &ctx);
+ hash->Update(hash->ctx, key, keylen);
+ hash->Final(digest, hash->ctx);
- return !bcmp(digest,signature,SHA1_SIZE);
+ return !bcmp(digest,signature,hash->hashsize);
}