diff options
author | Niels Provos <provos@cvs.openbsd.org> | 1997-09-02 17:26:51 +0000 |
---|---|---|
committer | Niels Provos <provos@cvs.openbsd.org> | 1997-09-02 17:26:51 +0000 |
commit | ecfa99a7a95ad310f3c23d407c08aca22da15424 (patch) | |
tree | 62f5c647a743d7114c661ac1537f19c4e4b1ce50 /sbin/ipsec | |
parent | a8c41d8a2134b154c44149e99cb71f89f05b9fd2 (diff) |
including changes between drafts-14-16.
update cookie and counters correctly after receiving a resource limit
message.
Diffstat (limited to 'sbin/ipsec')
-rw-r--r-- | sbin/ipsec/photurisd/compute_secrets.c | 259 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/handle_identity_request.c | 10 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/handle_identity_response.c | 10 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/handle_resource_limit.c | 17 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/handle_spi_needed.c | 3 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/handle_spi_update.c | 3 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/handle_value_request.c | 10 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/handle_value_response.c | 6 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/identity.c | 163 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/identity.h | 59 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/photuris_cookie_request.c | 39 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/photuris_error_message.c | 6 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/schedule.c | 32 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/secrets.h | 4 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/state.c | 51 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/state.h | 12 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/validity.c | 183 |
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); } |