diff options
author | Niels Provos <provos@cvs.openbsd.org> | 1998-06-30 16:58:48 +0000 |
---|---|---|
committer | Niels Provos <provos@cvs.openbsd.org> | 1998-06-30 16:58:48 +0000 |
commit | 9d79a7f4acf7ea61399f02aaded1960f02c764f6 (patch) | |
tree | 8aca115df77ea3ff52cf7d85d3ca3169e149149d /sbin/ipsec | |
parent | c6b9f5e2c16caf7e839d9e14dd0354ea78bfc3e8 (diff) |
- support HMAC flag which if present in the attribute list toggles to
HMAC authentication transforms and otherwise to simple keyed authentication.
Note, HMAC is necessary if new esp is to use integrity checking, i.e.
authentication of the payload.
- Also fix bug, where SPIs were reserved for more than one protocol when
only one protocol, e.g. ESP or AH, could be agreed upon.
- Also make kernel.c a bit less complex, I hope.
- return notifies to kernel on failure only when kernel started the keying.
Diffstat (limited to 'sbin/ipsec')
-rw-r--r-- | sbin/ipsec/photurisd/attributes.c | 8 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/attributes.h | 8 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/compute_secrets.c | 27 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/config.c | 70 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/handle_identity_request.c | 7 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/handle_identity_response.c | 4 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/kernel.c | 344 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/kernel.h | 31 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/photuris_identity_request.c | 6 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/photuris_identity_response.c | 6 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/photurisd.c | 3 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/schedule.c | 6 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/server.c | 10 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/spi.c | 17 |
14 files changed, 331 insertions, 216 deletions
diff --git a/sbin/ipsec/photurisd/attributes.c b/sbin/ipsec/photurisd/attributes.c index bc3e84b347d..608aa1a310a 100644 --- a/sbin/ipsec/photurisd/attributes.c +++ b/sbin/ipsec/photurisd/attributes.c @@ -1,5 +1,5 @@ /* - * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> + * Copyright 1997,1998 Niels Provos <provos@physnet.uni-hamburg.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,7 +33,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: attributes.c,v 1.3 1998/03/04 11:43:08 provos Exp $"; +static char rcsid[] = "$Id: attributes.c,v 1.4 1998/06/30 16:58:47 provos Exp $"; #endif #define _ATTRIBUTES_C_ @@ -61,9 +61,9 @@ putattrib(attrib_t *attrib) } attrib_t * -getattrib(int id) +getattrib(u_int8_t id) { - int hashval = id % ATTRIBHASHMOD; + u_int8_t hashval = id % ATTRIBHASHMOD; attrib_t *attrib; for(attrib=attribhash[hashval]; attrib; attrib = attrib->next) diff --git a/sbin/ipsec/photurisd/attributes.h b/sbin/ipsec/photurisd/attributes.h index 93bc01dc552..ccfdea8701a 100644 --- a/sbin/ipsec/photurisd/attributes.h +++ b/sbin/ipsec/photurisd/attributes.h @@ -1,5 +1,5 @@ /* - * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> + * Copyright 1997,1998 Niels Provos <provos@physnet.uni-hamburg.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,6 +49,7 @@ #define AT_PAD 0 #define AT_AH_ATTRIB 1 #define AT_ESP_ATTRIB 2 +#define AT_HMAC 254 /* XXX - Only for the moment */ #define DH_G_2_MD5 2 @@ -74,8 +75,7 @@ typedef struct _attribute_list { typedef struct _attrib_t { struct _attrib_t *next; - int id; /* Photuris Attribute ID */ - int koff; /* Offset into kernel data structure */ + u_int16_t id; /* Photuris Attribute ID */ int type; /* Type of attribute: ident, enc, auth */ int klen; /* required key length */ } attrib_t; @@ -83,7 +83,7 @@ typedef struct _attrib_t { #define ATTRIBHASHMOD 17 EXTERN void putattrib(attrib_t *attrib); -EXTERN attrib_t *getattrib(int id); +EXTERN attrib_t *getattrib(u_int8_t id); EXTERN void clearattrib(void); EXTERN void get_attrib_section(u_int8_t *, u_int16_t, u_int8_t **, u_int16_t *, diff --git a/sbin/ipsec/photurisd/compute_secrets.c b/sbin/ipsec/photurisd/compute_secrets.c index a2e5a3294e8..a32f0855232 100644 --- a/sbin/ipsec/photurisd/compute_secrets.c +++ b/sbin/ipsec/photurisd/compute_secrets.c @@ -1,5 +1,5 @@ /* - * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> + * Copyright 1997,1998 Niels Provos <provos@physnet.uni-hamburg.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,7 +34,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: compute_secrets.c,v 1.5 1998/03/04 11:43:14 provos Exp $"; +static char rcsid[] = "$Id: compute_secrets.c,v 1.6 1998/06/30 16:58:45 provos Exp $"; #endif #define _SECRETS_C_ @@ -160,18 +160,21 @@ make_session_keys(struct stateob *st, struct spiob *spi) &count); if (bits == -1) return -1; + if (bits > 0) { #ifdef DEBUG - { int d = BUFFER_SIZE; - printf("%s session key for AT %d: ", - spi->flags & SPI_OWNER ? - "Owner" : "User", (int)attributes[i]); - bin2hex(buffer, &d, p, - bits & 7 ? (bits >> 3) + 1 : bits >> 3); - printf("0x%s\n", buffer); - } + { + int d = BUFFER_SIZE; + printf("%s session key for AT %d: ", + spi->flags & SPI_OWNER ? + "Owner" : "User", (int)attributes[i]); + bin2hex(buffer, &d, p, + bits & 7 ? (bits >> 3) + 1 : bits >> 3); + printf("0x%s\n", buffer); + } #endif /* DEBUG */ - p += bits & 7 ? (bits >> 3) + 1 : bits >> 3; + p += bits & 7 ? (bits >> 3) + 1 : bits >> 3; + } } } @@ -239,6 +242,8 @@ compute_session_key(struct stateob *st, u_int8_t *key, if ((bits = get_session_key_length(attribute)) == -1) return -1; + if (bits == 0) + return 0; size = bits >> 3; if(bits & 0x7) diff --git a/sbin/ipsec/photurisd/config.c b/sbin/ipsec/photurisd/config.c index 1f02f8e18ac..59ebac2f89b 100644 --- a/sbin/ipsec/photurisd/config.c +++ b/sbin/ipsec/photurisd/config.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: config.c,v 1.9 1998/06/03 16:17:26 deraadt Exp $"; +static char rcsid[] = "$Id: config.c,v 1.10 1998/06/30 16:58:34 provos Exp $"; #endif #define _CONFIG_C_ @@ -266,7 +266,7 @@ init_attributes(void) #ifdef IPSEC if ((tmpatt.type & ~AT_ID) && - (tmpatt.koff = kernel_get_offset(tmpatt.id)) == -1) { + kernel_known_transform(tmpatt.id) == -1) { log_error(0, "Attribute %s not supported by kernel in init_attributes()", name); continue; } @@ -981,9 +981,36 @@ select_attrib(struct stateob *st, u_int8_t **attributes, u_int16_t *attribsize) /* Take the ESP section */ char *tp = wantesp, *ta = wantesp; u_int16_t tpsize = 0, tasize = 0; + u_int8_t flag[20], flagc, hmac = 0; int res; attrib_t *attah = NULL; + /* + * We travers the ESP section and look for flags, + * perhaps mutually exclusive flags should be handled + * but at the moment we only support the HMAC indicator + */ + + flagc = 0; + while (tpsize < wantespsize && flagc < sizeof(flag)) { + if (isinattrib(offeresp, offerespsize, tp[tpsize])) { + attprop = getattrib(tp[tpsize]); + /* A simple flag has no type */ + if (attprop != NULL && attprop->type == 0) { + flag[flagc++] = attprop->id; + switch(attprop->id) { + case AT_HMAC: + hmac = 1; + break; + default: + break; + } + } + } + tpsize += tp[tpsize+1]+2; + } + + tpsize = 0; attprop = NULL; /* We travers the ESP section and look for the first ENC attribute */ while (tpsize < wantespsize) { @@ -998,12 +1025,12 @@ select_attrib(struct stateob *st, u_int8_t **attributes, u_int16_t *attribsize) attprop = NULL; /* If we find a fitting AH, we take it */ - while (attprop != NULL && tasize < wantespsize) { + while (hmac && attprop != NULL && tasize < wantespsize) { if (isinattrib(offeresp, offerespsize, ta[tasize])) { attah = getattrib(ta[tasize]); if (attah != NULL && (attah->type & AT_AUTH)) { #ifdef IPSEC - res = kernel_valid(attprop->koff, attah->koff); + res = kernel_valid(attprop, attah); #else res = 0; #endif @@ -1043,6 +1070,14 @@ select_attrib(struct stateob *st, u_int8_t **attributes, u_int16_t *attribsize) count += wantesp[tasize+1] + 2; p += wantesp[tasize+1] + 2; } + + /* Insert the flags also */ + while (flagc--) { + p[0] = flag[flagc]; + p[1] = 0; + p += 2; + count += 2; + } } } @@ -1050,13 +1085,30 @@ select_attrib(struct stateob *st, u_int8_t **attributes, u_int16_t *attribsize) /* Take the AH section */ u_int8_t *tp = wantah; u_int16_t tpsize = 0; + u_int8_t flag[20], flagc; + flagc = 0; + /* Look for flags */ + while (tpsize < wantahsize && flagc < sizeof(flag)) { + if (isinattrib(offerah, offerahsize, tp[tpsize])) { + attprop = getattrib(tp[tpsize]); + if (attprop != NULL && attprop->type == 0) + flag[flagc++] = attprop->id; + } + tpsize += tp[tpsize+1]+2; + } + + tpsize = 0; attprop = NULL; /* We travers the AH section and look for the first AH attribute */ while (tpsize < wantahsize) { if (isinattrib(offerah, offerahsize, tp[tpsize])) { attprop = getattrib(tp[tpsize]); - if (attprop != NULL && (attprop->type & AT_AUTH)) + if (attprop != NULL && (attprop->type & AT_AUTH) +#ifdef IPSEC + && (kernel_valid_auth(attprop, flag, flagc) != -1) +#endif + ) break; } tpsize += tp[tpsize+1]+2; @@ -1075,6 +1127,14 @@ select_attrib(struct stateob *st, u_int8_t **attributes, u_int16_t *attribsize) bcopy(wantah+tpsize, p, wantah[tpsize+1] + 2); count += wantah[tpsize+1] + 2; p += wantah[tpsize+1] + 2; + + /* Insert flags also */ + while (flagc--) { + p[0] = flag[flagc]; + p[1] = 0; + p += 2; + count += 2; + } } } diff --git a/sbin/ipsec/photurisd/handle_identity_request.c b/sbin/ipsec/photurisd/handle_identity_request.c index 73d1affc8e9..cfcad52ffed 100644 --- a/sbin/ipsec/photurisd/handle_identity_request.c +++ b/sbin/ipsec/photurisd/handle_identity_request.c @@ -30,11 +30,10 @@ /* * handle_identity_request: * receive a IDENTITY_REQUEST packet; return -1 on failure, 0 on success - * */ #ifndef lint -static char rcsid[] = "$Id: handle_identity_request.c,v 1.6 1998/05/18 21:25:23 provos Exp $"; +static char rcsid[] = "$Id: handle_identity_request.c,v 1.7 1998/06/30 16:58:41 provos Exp $"; #endif #include <stdio.h> @@ -97,7 +96,7 @@ handle_identity_request(u_char *packet, int size, char *address, if (st == NULL) { packet_size = PACKET_BUFFER_SIZE; photuris_error_message(st, packet_buffer, &packet_size, - header->icookie, header->rcookie, + header->icookie, header->rcookie, 0, BAD_COOKIE); send_packet(); return 0; @@ -113,7 +112,7 @@ handle_identity_request(u_char *packet, int size, char *address, goto verification_failed; } -#ifdef DEBUG +#ifdef DEBUG2 printf("Identity-Request (after decryption):\n"); packet_dump(packet, size, 0); #endif diff --git a/sbin/ipsec/photurisd/handle_identity_response.c b/sbin/ipsec/photurisd/handle_identity_response.c index 258a232aac3..f96dd62a784 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.6 1998/05/18 21:25:25 provos Exp $"; +static char rcsid[] = "$Id: handle_identity_response.c,v 1.7 1998/06/30 16:58:44 provos Exp $"; #endif #include <stdio.h> @@ -107,7 +107,7 @@ handle_identity_response(u_char *packet, int size, char *address, goto verification_failed; } -#ifdef DEBUG +#ifdef DEBUG2 printf("Identity Response (after decryption):\n"); packet_dump((u_int8_t *)header, size, 0); #endif diff --git a/sbin/ipsec/photurisd/kernel.c b/sbin/ipsec/photurisd/kernel.c index ae6a3e82c4a..a0604362ba2 100644 --- a/sbin/ipsec/photurisd/kernel.c +++ b/sbin/ipsec/photurisd/kernel.c @@ -39,7 +39,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: kernel.c,v 1.10 1998/06/01 10:56:10 provos Exp $"; +static char rcsid[] = "$Id: kernel.c,v 1.11 1998/06/30 16:58:31 provos Exp $"; #endif #include <time.h> @@ -98,46 +98,26 @@ time_t now; static int sd; -typedef struct { - int photuris_id; - int kernel_id, flags; -} transform; - -/* - * Translation from Photuris Attributes to Kernel Transforms. - * For the actual ids see: draft-simpson-photuris-*.txt and - * draft-simpson-photuris-schemes-*.txt - */ - -transform xf[] = { - { 5, ALG_AUTH_MD5, XF_AUTH|AH_OLD}, - { 6, ALG_AUTH_SHA1, XF_AUTH|AH_OLD}, - { 8, ALG_ENC_DES, XF_ENC|ESP_OLD}, - {100, ALG_ENC_3DES, XF_ENC|ESP_NEW}, - {101, ALG_ENC_BLF, XF_ENC|ESP_NEW}, - {102, ALG_ENC_CAST, XF_ENC|ESP_NEW}, - {105, ALG_AUTH_MD5, XF_AUTH|AH_NEW|ESP_NEW}, - {106, ALG_AUTH_SHA1, XF_AUTH|AH_NEW|ESP_NEW}, - {107, ALG_AUTH_RMD160, XF_AUTH|AH_NEW|ESP_NEW}, -}; - /* - * Translate a Photuris ID to an offset into a data structure for the + * Translate a Photuris ID into a data structure for the * corresponding Kernel transform. - * This makes is easier to write kernel modules for different IPSec - * implementations. */ -int -kernel_get_offset(int id) +transform * +kernel_get_transform(int id) { int i; for (i=sizeof(xf)/sizeof(transform)-1; i >= 0; i--) if (xf[i].photuris_id == id) - return i; + return &xf[i]; + return NULL; +} - return -1; +int +kernel_known_transform(int id) +{ + return kernel_get_transform(id) == NULL ? -1 : 0; } /* @@ -148,15 +128,52 @@ kernel_get_offset(int id) */ int -kernel_valid(int encoff, int authoff) +kernel_valid(attrib_t *enc, attrib_t *auth) { - if (xf[encoff].flags & ESP_OLD) + transform *xf_enc, *xf_auth; + + xf_enc = kernel_get_transform(enc->id); + xf_auth = kernel_get_transform(auth->id); + + if (xf_enc->flags & ESP_OLD) return AT_ENC; - if (!(xf[authoff].flags & ESP_NEW)) + if (!(xf_auth->flags & ESP_NEW)) return AT_AUTH; return 0; } +/* + * Check if the chosen authentication transform, satisfies the + * selected flags. + */ + +int +kernel_valid_auth(attrib_t *auth, u_int8_t *flag, u_int16_t size) +{ + int i, hmac = 0; + transform *xf_auth = kernel_get_transform(auth->id); + + if (xf_auth == NULL) + return -1; /* We don't know this attribute */ + + for (i=0; i<size; i++) { + switch (flag[i]) { + case AT_HMAC: + hmac = 1; + break; + default: + break; + } + } + + if (!hmac && !(xf_auth->flags & AH_OLD)) + return -1; + if (hmac && !(xf_auth->flags & AH_NEW)) + return -1; + + return 0; +} + int init_kernel(void) { @@ -274,20 +291,21 @@ kernel_reserve_single_spi(char *srcaddress, u_int32_t spi, int proto) } int -kernel_ah(attrib_t *ob, struct spiob *SPI, u_int8_t *secrets) +kernel_ah(attrib_t *ob, struct spiob *SPI, u_int8_t *secrets, int hmac) { struct encap_msghdr *em; struct ah_old_xencap *xdo; struct ah_new_xencap *xdn; + transform *xf = kernel_get_transform(ob->id); - if (!(xf[ob->koff].flags & XF_AUTH)) { + if (xf == NULL || !(xf->flags & XF_AUTH)) { log_error(0, "%d is not an auth transform in kernel_ah()", ob->id); return -1; } em = (struct encap_msghdr *)buffer; - if (xf[ob->koff].flags & AH_OLD) { + if (!hmac) { bzero(buffer, EMT_SETSPI_FLEN + 4 + ob->klen); em->em_msglen = EMT_SETSPI_FLEN + AH_OLD_XENCAP_LEN + ob->klen; @@ -296,7 +314,7 @@ kernel_ah(attrib_t *ob, struct spiob *SPI, u_int8_t *secrets) xdo = (struct ah_old_xencap *)(em->em_dat); - xdo->amx_hash_algorithm = xf[ob->koff].kernel_id; + xdo->amx_hash_algorithm = xf->kernel_id; xdo->amx_keylen = ob->klen; bcopy(secrets, xdo->amx_key, ob->klen); @@ -310,7 +328,7 @@ kernel_ah(attrib_t *ob, struct spiob *SPI, u_int8_t *secrets) xdn = (struct ah_new_xencap *)(em->em_dat); - xdn->amx_hash_algorithm = xf[ob->koff].kernel_id; + xdn->amx_hash_algorithm = xf->kernel_id; xdn->amx_wnd = 16; xdn->amx_keylen = ob->klen; @@ -353,6 +371,7 @@ kernel_esp(attrib_t *ob, attrib_t *ob2, struct spiob *SPI, u_int8_t *secrets) struct esp_new_xencap *xdn; attrib_t *attenc, *attauth = NULL; u_int8_t *sec1, *sec2 = NULL; + transform *xf_enc, *xf_auth; if (ob->type & AT_AUTH) { if (ob2 == NULL || ob2->type != AT_ENC) { @@ -375,14 +394,18 @@ kernel_esp(attrib_t *ob, attrib_t *ob2, struct spiob *SPI, u_int8_t *secrets) return -1; } - if ((xf[attenc->koff].flags & ESP_OLD) && attauth != NULL) { + xf_enc = kernel_get_transform(attenc->id); + if ((xf_enc->flags & ESP_OLD) && attauth != NULL) { log_error(0, "Old ESP does not support AH in kernel_esp()"); return -1; } + if (attauth != NULL) + xf_auth = kernel_get_transform(attauth->id); + em = (struct encap_msghdr *)buffer; - if (xf[attenc->koff].flags & ESP_OLD) { + if (xf_enc->flags & ESP_OLD) { bzero(buffer, EMT_SETSPI_FLEN + ESP_OLD_XENCAP_LEN +4+attenc->klen); em->em_msglen = EMT_SETSPI_FLEN + ESP_OLD_XENCAP_LEN +4+attenc->klen; @@ -391,7 +414,7 @@ kernel_esp(attrib_t *ob, attrib_t *ob2, struct spiob *SPI, u_int8_t *secrets) xdo = (struct esp_old_xencap *)(em->em_dat); - xdo->edx_enc_algorithm = ALG_ENC_DES; + xdo->edx_enc_algorithm = xf_enc->kernel_id; xdo->edx_ivlen = 4; xdo->edx_keylen = attenc->klen; @@ -408,8 +431,8 @@ kernel_esp(attrib_t *ob, attrib_t *ob2, struct spiob *SPI, u_int8_t *secrets) xdn = (struct esp_new_xencap *)(em->em_dat); - xdn->edx_enc_algorithm = xf[attenc->koff].kernel_id; - xdn->edx_hash_algorithm = attauth ? xf[attauth->koff].kernel_id : 0; + xdn->edx_enc_algorithm = xf_enc->kernel_id; + xdn->edx_hash_algorithm = attauth ? xf_auth->kernel_id : 0; xdn->edx_ivlen = 0; xdn->edx_confkeylen = attenc->klen; xdn->edx_authkeylen = attauth ? attauth->klen : 0; @@ -607,78 +630,100 @@ kernel_insert_spi(struct stateob *st, struct spiob *SPI) { u_int8_t *spi; u_int8_t *attributes; - u_int16_t attribsize; - u_int8_t *secrets; - attrib_t *attprop, *attprop2; - int i, n, offset, proto = 0; - int phase = 0; + u_int16_t attribsize, ahsize, espsize; + u_int8_t *secrets, *ah, *esp; + attrib_t *attprop; + int offset, proto = 0; spi = SPI->SPI; attributes = SPI->attributes; attribsize = SPI->attribsize; secrets = SPI->sessionkey; - if (vpn_mode) - SPI->flags |= SPI_TUNNEL; - - for(n=0, i=0; n<attribsize; n += attributes[n+1] + 2) { - switch(attributes[n]) { - case AT_AH_ATTRIB: - phase = AT_AH_ATTRIB; - break; - case AT_ESP_ATTRIB: - phase = AT_ESP_ATTRIB; - break; - default: - if (phase == 0) { - log_error(0, "Unaligned attribute %d in kernel_insert_spi()", attributes[n]); + get_attrib_section(attributes, attribsize, &esp, &espsize, + AT_ESP_ATTRIB); + get_attrib_section(attributes, attribsize, &ah, &ahsize, + AT_AH_ATTRIB); + + if (esp != NULL) { + int count = 0; + attrib_t *atesp = NULL, *atah = NULL; + + while (count < espsize && (atesp == NULL || atah == NULL)) { + if ((attprop = getattrib(esp[count])) == NULL) { + log_error(0, "Unknown attribute %d for ESP in kernel_insert_spi()", + esp[count]); return -1; } - if ((attprop = getattrib(attributes[n])) == NULL) { - log_error(0, "Unknown attribute %d in kernel_insert_spi()", - attributes[n]); + if (atesp == NULL && attprop->type == AT_ENC) + atesp = attprop; + else if(atah == NULL && (attprop->type & AT_AUTH)) + atah = attprop; + + count += esp[count+1]+2; + } + if (atesp == NULL) { + log_error(0, "No encryption attribute in ESP section for SA(%08x, %s->%s) in kernel_insert()", (SPI->SPI[0] << 24) + (SPI->SPI[1] << 16) + (SPI->SPI[2] << 8) + SPI->SPI[3], SPI->local_address, SPI->address); + return -1; + } + + if (vpn_mode) + SPI->flags |= SPI_TUNNEL; + + offset = kernel_esp(atesp, atah, SPI, secrets); + if (offset == -1) + return -1; + secrets += offset; + } + + if (ah != NULL) { + int count = 0, hmac = 0; + attrib_t *atah = NULL; + + while (count < ahsize) { + if ((attprop = getattrib(ah[count])) == NULL) { + log_error(0, "Unknown attribute %d for AH in kernel_insert_spi()", + ah[count]); return -1; } - switch (phase) { - case AT_AH_ATTRIB: - offset = kernel_ah(attprop, SPI, secrets); - if (offset == -1) - return -1; - phase = 0; - secrets += offset; - i++; - if (!proto) { - proto = IPPROTO_AH; - if (vpn_mode) - SPI->flags = SPI->flags & ~SPI_TUNNEL; - } - break; - case AT_ESP_ATTRIB: - offset = attributes[n+1] + 2; - attprop2 = NULL; - if (n+offset < attribsize) - attprop2 = getattrib(attributes[n+offset]); - if (attprop2 != NULL) - n += offset; - offset = kernel_esp(attprop, attprop2, SPI, secrets); - if (offset == -1) - return -1; - phase = 0; - secrets += offset; - i++; - if (!proto) { - proto = IPPROTO_ESP; - if (vpn_mode) - SPI->flags = SPI->flags & ~SPI_TUNNEL; + if(atah == NULL && (attprop->type & AT_AUTH)) + atah = attprop; + else if (attprop->type == 0) { + switch (attprop->id) { + case AT_HMAC: + hmac = 1; + break; + default: + break; } - break; } + + count += ah[count+1]+2; } - + + if (atah == NULL) { + log_error(0, "No authentication attribute in AH section for SA(%08x, %s->%s) in kernel_insert()", (SPI->SPI[0] << 24) + (SPI->SPI[1] << 16) + (SPI->SPI[2] << 8) + SPI->SPI[3], SPI->local_address, SPI->address); + return -1; + } + + if (vpn_mode && esp == NULL) + SPI->flags |= SPI_TUNNEL; + else + SPI->flags &= ~SPI_TUNNEL; + + offset = kernel_ah(atah, SPI, secrets, hmac); + if (offset == -1) + return -1; + secrets += offset; } + if (esp != NULL) + proto = IPPROTO_ESP; + else + proto = IPPROTO_AH; + /* Group the SPIs for User */ - if (!(SPI->flags & SPI_OWNER) && i > 1) { + if (!(SPI->flags & SPI_OWNER) && ah != NULL && esp != NULL) { if (kernel_group_spi(SPI->address, spi) == -1) log_error(0, "kernel_group_spi() in kernel_insert_spi()"); } @@ -718,83 +763,50 @@ int kernel_unlink_spi(struct spiob *ospi) { int n, proto = 0; - int phase = 0, offset; attrib_t *attprop; u_int32_t spi; - u_int8_t SPI[SPI_SIZE], *p; + u_int8_t *p, *ah, *esp; + u_int16_t ahsize, espsize; if (!(ospi->flags & SPI_OWNER)) p = ospi->address; - else + else p = ospi->local_address; - - spi = (ospi->SPI[0]<<24) + (ospi->SPI[1]<<16) + - (ospi->SPI[2]<<8) + ospi->SPI[3]; + get_attrib_section(ospi->attributes, ospi->attribsize, &esp, &espsize, + AT_ESP_ATTRIB); + get_attrib_section(ospi->attributes, ospi->attribsize, &ah, &ahsize, + AT_AH_ATTRIB); + + if (esp != NULL) { + int flag = (vpn_mode ? ENABLE_FLAG_MODIFY : 0) | ENABLE_FLAG_LOCAL; + if (!(ospi->flags & SPI_OWNER) && + kernel_disable_spi(ospi->isrc, ospi->ismask, + ospi->idst, ospi->idmask, + ospi->address, ospi->SPI, + IPPROTO_ESP, flag) == -1) + log_error(0, "kernel_disable_spi() in kernel_unlink_spi()"); + + if (kernel_delete_spi(p, ospi->SPI, IPPROTO_ESP) == -1) + log_error(0, "kernel_delete_spi() in kernel_unlink_spi()"); + } - for(n=0; n<ospi->attribsize; n += ospi->attributes[n+1] + 2) { - SPI[0] = (spi >> 24) & 0xFF; - SPI[1] = (spi >> 16) & 0xFF; - SPI[2] = (spi >> 8) & 0xFF; - SPI[3] = spi & 0xFF; - switch(ospi->attributes[n]) { - case AT_AH_ATTRIB: - phase = AT_AH_ATTRIB; - break; - case AT_ESP_ATTRIB: - phase = AT_ESP_ATTRIB; - break; - default: - if (phase == 0) { - log_error(0, "Unaligned attribute %d in kernel_unlink_spi()", ospi->attributes[n]); - return -1; - } - if ((attprop = getattrib(ospi->attributes[n])) == NULL) { - log_error(0, "Unknown attribute %d in kernel_unlink_spi()", - ospi->attributes[n]); - return -1; - } - switch (phase) { - case AT_AH_ATTRIB: - if (!proto) { - int flag = (vpn_mode ? ENABLE_FLAG_MODIFY : 0) | - ENABLE_FLAG_LOCAL; - proto = IPPROTO_AH; - if (!(ospi->flags & SPI_OWNER) && - kernel_disable_spi(ospi->isrc, ospi->ismask, - ospi->idst, ospi->idmask, - ospi->address, ospi->SPI, - proto, flag) == -1) - log_error(0, "kernel_disable_spi() in kernel_unlink_spi()"); - } - - if (kernel_delete_spi(p, SPI, IPPROTO_AH) == -1) - log_error(0, "kernel_delete_spi() in kernel_unlink_spi()"); - break; - case AT_ESP_ATTRIB: - if (!proto) { - int flag = (vpn_mode ? ENABLE_FLAG_MODIFY : 0) | - ENABLE_FLAG_LOCAL; - proto = IPPROTO_ESP; - if (!(ospi->flags & SPI_OWNER) && - kernel_disable_spi(ospi->isrc, ospi->ismask, - ospi->idst, ospi->idmask, - ospi->address, ospi->SPI, - proto, flag) == -1) - log_error(0, "kernel_disable_spi() in kernel_unlink_spi()"); - } - if (kernel_delete_spi(p, SPI, IPPROTO_ESP) == -1) - log_error(0, "kernel_delete_spi() in kernel_unlink_spi()"); - offset = ospi->attributes[n+1] + 2; - if ((n + offset < ospi->attribsize) && - getattrib(ospi->attributes[n+offset]) != NULL) - n += offset; - break; - } + if (ah != NULL) { + if (esp == NULL) { + int flag = (vpn_mode ? ENABLE_FLAG_MODIFY : 0) | + ENABLE_FLAG_LOCAL; + if (!(ospi->flags & SPI_OWNER) && + kernel_disable_spi(ospi->isrc, ospi->ismask, + ospi->idst, ospi->idmask, + ospi->address, ospi->SPI, + IPPROTO_AH, flag) == -1) + log_error(0, "kernel_disable_spi() in kernel_unlink_spi()"); } + + if (kernel_delete_spi(p, ospi->SPI, IPPROTO_AH) == -1) + log_error(0, "kernel_delete_spi() in kernel_unlink_spi()"); } - return 1; } diff --git a/sbin/ipsec/photurisd/kernel.h b/sbin/ipsec/photurisd/kernel.h index 92704d589fc..c52f3951021 100644 --- a/sbin/ipsec/photurisd/kernel.h +++ b/sbin/ipsec/photurisd/kernel.h @@ -27,7 +27,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: kernel.h,v 1.6 1998/05/18 21:25:33 provos Exp $ */ +/* $Id: kernel.h,v 1.7 1998/06/30 16:58:33 provos Exp $ */ /* * kernel.h: * security paramter index creation. @@ -48,11 +48,33 @@ #define XF_ENC 0x10 #define XF_AUTH 0x20 +typedef struct { + int photuris_id; + int kernel_id, flags; +} transform; + +/* + * Translation from Photuris Attributes to Kernel Transforms. + * For the actual ids see: draft-simpson-photuris-*.txt and + * draft-simpson-photuris-schemes-*.txt + */ + +transform xf[] = { + { 5, ALG_AUTH_MD5, XF_AUTH|AH_OLD|AH_NEW|ESP_NEW}, + { 6, ALG_AUTH_SHA1, XF_AUTH|AH_OLD|AH_NEW|ESP_NEW}, + { 7, ALG_AUTH_RMD160, XF_AUTH|AH_NEW|ESP_NEW}, + { 8, ALG_ENC_DES, XF_ENC|ESP_OLD}, + { 18, ALG_ENC_3DES, XF_ENC|ESP_NEW}, + { 16, ALG_ENC_BLF, XF_ENC|ESP_NEW}, + { 17, ALG_ENC_CAST, XF_ENC|ESP_NEW}, +}; + +transform *kernel_get_transform(int id); int kernel_xf_set(struct encap_msghdr *em); int kernel_xf_read(struct encap_msghdr *em, int msglen); -int kernel_ah(attrib_t *ob, struct spiob *SPI, u_int8_t *secrets); +int kernel_ah(attrib_t *ob, struct spiob *SPI, u_int8_t *secrets, int hmac); int kernel_esp(attrib_t *ob, attrib_t *ob2, struct spiob *SPI, u_int8_t *secrets); @@ -71,8 +93,9 @@ int kernel_request_sa(struct encap_msghdr *em); #define EXTERN extern #endif -EXTERN int kernel_get_offset(int id); -EXTERN int kernel_valid(int encoff, int authoff); +EXTERN int kernel_known_transform(int id); +EXTERN int kernel_valid(attrib_t *enc, attrib_t *auth); +EXTERN int kernel_valid_auth(attrib_t *auth, u_int8_t *flag, u_int16_t size); EXTERN u_int32_t kernel_reserve_spi( char *srcaddress, int options); EXTERN u_int32_t kernel_reserve_single_spi(char *srcaddress, u_int32_t spi, diff --git a/sbin/ipsec/photurisd/photuris_identity_request.c b/sbin/ipsec/photurisd/photuris_identity_request.c index abf34aae699..ce9143dd0d7 100644 --- a/sbin/ipsec/photurisd/photuris_identity_request.c +++ b/sbin/ipsec/photurisd/photuris_identity_request.c @@ -1,5 +1,5 @@ /* - * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> + * Copyright 1997,1998 Niels Provos <provos@physnet.uni-hamburg.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,7 +34,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: photuris_identity_request.c,v 1.2 1998/03/04 11:43:39 provos Exp $"; +static char rcsid[] = "$Id: photuris_identity_request.c,v 1.3 1998/06/30 16:58:43 provos Exp $"; #endif #include <stdio.h> @@ -118,7 +118,7 @@ photuris_identity_request(struct stateob *st, u_char *buffer, int *size) /* Create verification data */ create_identity_verification(st, verifyp, (u_int8_t *)header, asize); -#ifdef DEBUG +#ifdef DEBUG2 printf("Identity-Request (before encryption):\n"); packet_dump((u_int8_t *)header, asize, 0); #endif diff --git a/sbin/ipsec/photurisd/photuris_identity_response.c b/sbin/ipsec/photurisd/photuris_identity_response.c index ebc5ce56f41..b11f54f2111 100644 --- a/sbin/ipsec/photurisd/photuris_identity_response.c +++ b/sbin/ipsec/photurisd/photuris_identity_response.c @@ -1,5 +1,5 @@ /* - * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> + * Copyright 1997,1998 Niels Provos <provos@physnet.uni-hamburg.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,7 +34,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: photuris_identity_response.c,v 1.2 1998/03/04 11:43:40 provos Exp $"; +static char rcsid[] = "$Id: photuris_identity_response.c,v 1.3 1998/06/30 16:58:42 provos Exp $"; #endif #include <stdio.h> @@ -118,7 +118,7 @@ photuris_identity_response(struct stateob *st, u_char *buffer, int *size) /* Create verification data */ create_identity_verification(st, verifyp, (u_int8_t *)header, asize); -#ifdef DEBUG +#ifdef DEBUG2 printf("Identity-Response (before encryption):\n"); packet_dump((u_int8_t *)header, asize, 0); #endif diff --git a/sbin/ipsec/photurisd/photurisd.c b/sbin/ipsec/photurisd/photurisd.c index f57561f1343..aba740f969d 100644 --- a/sbin/ipsec/photurisd/photurisd.c +++ b/sbin/ipsec/photurisd/photurisd.c @@ -32,7 +32,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: photurisd.c,v 1.8 1998/06/24 01:13:08 provos Exp $"; +static char rcsid[] = "$Id: photurisd.c,v 1.9 1998/06/30 16:58:38 provos Exp $"; #endif #define _PHOTURIS_C_ @@ -56,6 +56,7 @@ static char rcsid[] = "$Id: photurisd.c,v 1.8 1998/06/24 01:13:08 provos Exp $"; #include "schedule.h" #include "errlog.h" #ifdef IPSEC +#include "attributes.h" #include "kernel.h" #endif diff --git a/sbin/ipsec/photurisd/schedule.c b/sbin/ipsec/photurisd/schedule.c index 98973b5afb4..569565e30a8 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.7 1998/05/18 21:25:35 provos Exp $"; +static char rcsid[] = "$Id: schedule.c,v 1.8 1998/06/30 16:58:36 provos Exp $"; #endif #define _SCHEDULE_C_ @@ -60,6 +60,7 @@ static char rcsid[] = "$Id: schedule.c,v 1.7 1998/05/18 21:25:35 provos Exp $"; #include "modulus.h" #include "api.h" #ifdef IPSEC +#include "attributes.h" #include "kernel.h" #endif #ifdef DEBUG @@ -234,7 +235,8 @@ schedule_process(int sock) log_error(0, "no anwser for cookie request to %s:%d", st->address, st->port); #ifdef IPSEC - kernel_notify_result(st, NULL, 0); + if (st->flags & IPSEC_NOTIFY) + kernel_notify_result(st, NULL, 0); #endif break; } else if(st->phase == COOKIE_REQUEST) { diff --git a/sbin/ipsec/photurisd/server.c b/sbin/ipsec/photurisd/server.c index 718a17cd54a..76193e462ba 100644 --- a/sbin/ipsec/photurisd/server.c +++ b/sbin/ipsec/photurisd/server.c @@ -35,7 +35,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: server.c,v 1.5 1998/05/18 21:25:36 provos Exp $"; +static char rcsid[] = "$Id: server.c,v 1.6 1998/06/30 16:58:40 provos Exp $"; #endif #define _SERVER_C_ @@ -67,6 +67,7 @@ static char rcsid[] = "$Id: server.c,v 1.5 1998/05/18 21:25:36 provos Exp $"; #include "buffer.h" #ifdef IPSEC #include "spi.h" +#include "attributes.h" #include "kernel.h" #endif @@ -275,11 +276,14 @@ server(void) for (i=0; i<num_ifs; i++) { if (FD_ISSET(sockets[i], readfds)) { +#ifdef IPSEC if (i == 1) /* PF_ENCAP NOTIFIES */ kernel_handle_notify(sockets[i]); - else if (addresses[i] == NULL) + else +#endif + if (addresses[i] == NULL) process_api(sockets[i], global_socket); - else if (strcmp("127.0.0.1", inet_ntoa(sin.sin_addr))) { + else if (strcmp("127.0.0.1", inet_ntoa(sin.sin_addr))) { d = sizeof(struct sockaddr_in); if (recvfrom(sockets[i], #ifdef BROKEN_RECVFROM diff --git a/sbin/ipsec/photurisd/spi.c b/sbin/ipsec/photurisd/spi.c index b106947946a..db28baf766d 100644 --- a/sbin/ipsec/photurisd/spi.c +++ b/sbin/ipsec/photurisd/spi.c @@ -1,5 +1,5 @@ /* - * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> + * Copyright 1997,1998 Niels Provos <provos@physnet.uni-hamburg.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,7 +33,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: spi.c,v 1.5 1998/03/04 11:43:53 provos Exp $"; +static char rcsid[] = "$Id: spi.c,v 1.6 1998/06/30 16:58:35 provos Exp $"; #endif #define _SPI_C_ @@ -84,12 +84,21 @@ make_spi(struct stateob *st, char *local_address, /* Just grab a random number, this should be uniq */ for(i=0; i<SPI_SIZE; i++) { - if(i%4 == 0) + if(i%4 == 0) { #ifdef IPSEC - tmp = kernel_reserve_spi(local_address, st->flags); + int i, flags = 0; + + for (i=0; i<*attribsize; i += (*attributes)[i+1]+2) + if ((*attributes)[i] == AT_ESP_ATTRIB) + flags |= IPSEC_OPT_ENC; + else if ((*attributes)[i] == AT_AH_ATTRIB) + flags |= IPSEC_OPT_AUTH; + + tmp = kernel_reserve_spi(local_address, flags); #else tmp = arc4random(); #endif + } SPI[i] = tmp & 0xFF; tmp = tmp >> 8; } |