From 1922fd129e288c22e9c0175a84c13c33cb9345cb Mon Sep 17 00:00:00 2001 From: Bruce M Simpson Date: Wed, 11 Feb 2004 04:34:34 +0000 Subject: [PATCH] Initial import of RFC 2385 (TCP-MD5) digest support. This is the second of two commits; bring in the userland support to finish. Teach libipsec and setkey about the tcp-md5 class of security associations, thus allowing administrators to add per-host keys to the SADB for use by the tcpsignature_compute() function. Document that a single SPI must be used until such time as the code which adds support to the SPD to specify flows for tcp-md5 treatment is suitable for production. Sponsored by: sentex.net --- lib/libipsec/ipsec_dump_policy.c | 2 ++ lib/libipsec/pfkey.c | 15 ++++++++++++++- lib/libipsec/pfkey_dump.c | 3 +++ lib/libipsec/policy_token.l | 1 + sbin/setkey/parse.y | 17 +++++++++++++---- sbin/setkey/setkey.8 | 7 +++++++ sbin/setkey/token.l | 2 ++ usr.sbin/setkey/parse.y | 17 +++++++++++++---- usr.sbin/setkey/setkey.8 | 7 +++++++ usr.sbin/setkey/token.l | 2 ++ 10 files changed, 64 insertions(+), 9 deletions(-) diff --git a/lib/libipsec/ipsec_dump_policy.c b/lib/libipsec/ipsec_dump_policy.c index 459e8a783aad..3ce525b16937 100644 --- a/lib/libipsec/ipsec_dump_policy.c +++ b/lib/libipsec/ipsec_dump_policy.c @@ -196,6 +196,8 @@ ipsec_dump_ipsecrequest(buf, len, xisr, bound) case IPPROTO_IPCOMP: proto = "ipcomp"; break; + case IPPROTO_TCP: + proto = "tcp"; default: __ipsec_errcode = EIPSEC_INVAL_PROTO; return NULL; diff --git a/lib/libipsec/pfkey.c b/lib/libipsec/pfkey.c index d7263eee7c59..ca75df44a17a 100644 --- a/lib/libipsec/pfkey.c +++ b/lib/libipsec/pfkey.c @@ -79,12 +79,13 @@ static caddr_t pfkey_setsadbxsa2(caddr_t, caddr_t, u_int32_t, u_int32_t); /* * make and search supported algorithm structure. */ -static struct sadb_supported *ipsec_supported[] = { NULL, NULL, NULL, }; +static struct sadb_supported *ipsec_supported[] = { NULL, NULL, NULL, NULL }; static int supported_map[] = { SADB_SATYPE_AH, SADB_SATYPE_ESP, SADB_X_SATYPE_IPCOMP, + SADB_X_SATYPE_TCPSIGNATURE }; static int @@ -1169,6 +1170,16 @@ pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize, return -1; } break; + case SADB_X_SATYPE_TCPSIGNATURE: + if (e_type != SADB_EALG_NONE) { + __ipsec_errcode = EIPSEC_INVAL_ALGS; + return -1; + } + if (a_type != SADB_X_AALG_TCP_MD5) { + __ipsec_errcode = EIPSEC_INVAL_ALGS; + return -1; + } + break; default: __ipsec_errcode = EIPSEC_INVAL_SATYPE; return -1; @@ -1379,6 +1390,7 @@ pfkey_send_x3(so, type, satype) case SADB_SATYPE_AH: case SADB_SATYPE_ESP: case SADB_X_SATYPE_IPCOMP: + case SADB_X_SATYPE_TCPSIGNATURE: break; default: __ipsec_errcode = EIPSEC_INVAL_SATYPE; @@ -1838,6 +1850,7 @@ pfkey_check(mhp) case SADB_SATYPE_ESP: case SADB_SATYPE_AH: case SADB_X_SATYPE_IPCOMP: + case SADB_X_SATYPE_TCPSIGNATURE: switch (msg->sadb_msg_type) { case SADB_X_SPDADD: case SADB_X_SPDDELETE: diff --git a/lib/libipsec/pfkey_dump.c b/lib/libipsec/pfkey_dump.c index 393f74ef2ec4..d8d467642a55 100644 --- a/lib/libipsec/pfkey_dump.c +++ b/lib/libipsec/pfkey_dump.c @@ -126,6 +126,8 @@ static char *str_satype[] = { "ripv2", "mip", "ipcomp", + "policy", + "tcp" }; static char *str_mode[] = { @@ -148,6 +150,7 @@ static struct val2str str_alg_auth[] = { { SADB_X_AALG_MD5, "md5", }, { SADB_X_AALG_SHA, "sha", }, { SADB_X_AALG_NULL, "null", }, + { SADB_X_AALG_TCP_MD5, "tcp-md5", }, #ifdef SADB_X_AALG_SHA2_256 { SADB_X_AALG_SHA2_256, "hmac-sha2-256", }, #endif diff --git a/lib/libipsec/policy_token.l b/lib/libipsec/policy_token.l index ced57b3fee71..f95756954e10 100644 --- a/lib/libipsec/policy_token.l +++ b/lib/libipsec/policy_token.l @@ -97,6 +97,7 @@ entrust { yylval.num = IPSEC_POLICY_ENTRUST; return(ACTION); } esp { yylval.num = IPPROTO_ESP; return(PROTOCOL); } ah { yylval.num = IPPROTO_AH; return(PROTOCOL); } ipcomp { yylval.num = IPPROTO_IPCOMP; return(PROTOCOL); } +tcp { yylval.num = IPPROTO_TCP; return(PROTOCOL); } transport { yylval.num = IPSEC_MODE_TRANSPORT; return(MODE); } tunnel { yylval.num = IPSEC_MODE_TUNNEL; return(MODE); } diff --git a/sbin/setkey/parse.y b/sbin/setkey/parse.y index 80b9d177e27e..bc944a821098 100644 --- a/sbin/setkey/parse.y +++ b/sbin/setkey/parse.y @@ -94,7 +94,7 @@ extern void yyerror __P((const char *)); %token EOT SLASH BLCL ELCL %token ADD GET DELETE DELETEALL FLUSH DUMP -%token PR_ESP PR_AH PR_IPCOMP +%token PR_ESP PR_AH PR_IPCOMP PR_TCP %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI %token F_MODE MODE F_REQID %token F_EXT EXTENSION NOCYCLICSEQ @@ -113,7 +113,7 @@ extern void yyerror __P((const char *)); %type ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY %type ALG_AUTH ALG_AUTH_NOKEY %type ALG_COMP -%type PR_ESP PR_AH PR_IPCOMP +%type PR_ESP PR_AH PR_IPCOMP PR_TCP %type EXTENSION MODE %type DECSTRING %type PL_REQUESTS portstr key_string @@ -250,8 +250,12 @@ protocol_spec { $$ = SADB_X_SATYPE_IPCOMP; } + | PR_TCP + { + $$ = SADB_X_SATYPE_TCPSIGNATURE; + } ; - + spi : DECSTRING { p_spi = $1; } | HEXSTRING @@ -400,7 +404,12 @@ auth_alg p_key_auth_len = $2.len; p_key_auth = $2.buf; - if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH, + + if (p_alg_auth == SADB_X_AALG_TCP_MD5) { + if ((p_key_auth_len < 1) || (p_key_auth_len > + 80)) + return -1; + } else if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH, p_alg_auth, PFKEY_UNUNIT64(p_key_auth_len)) < 0) { yyerror(ipsec_strerror()); return -1; diff --git a/sbin/setkey/setkey.8 b/sbin/setkey/setkey.8 index 1e03edf9bcea..567dde46952b 100644 --- a/sbin/setkey/setkey.8 +++ b/sbin/setkey/setkey.8 @@ -252,6 +252,8 @@ AH based on rfc2402 AH based on rfc1826 .It Li ipcomp IPComp +.It Li tcp +TCP-MD5 based on rfc2385 .El .\" .Pp @@ -265,6 +267,8 @@ must be a decimal number, or a hexadecimal number with prefix. SPI values between 0 and 255 are reserved for future use by IANA and they cannot be used. +TCP-MD5 associations must use 0x1000 and therefore only have per-host +granularity at this time. .\" .Pp .It Ar extensions @@ -585,6 +589,7 @@ hmac-ripemd160 160 ah: 96bit ICV (RFC2857) ah-old: 128bit ICV (no document) aes-xcbc-mac 128 ah: 96bit ICV (RFC3566) 128 ah-old: 128bit ICV (no document) +tcp-md5 8 to 640 tcp: rfc2385 .Ed .Pp Followings are the list of encryption algorithms that can be used as @@ -649,6 +654,8 @@ dump esp ; spdadd 10.0.11.41/32[21] 10.0.11.33/32[any] any -P out ipsec esp/tunnel/192.168.0.1-192.168.1.2/require ; +add 10.1.10.34 10.1.10.36 tcp 0x1000 -A tcp-md5 "TCP-MD5 BGP secret" ; + .Ed .\" .Sh SEE ALSO diff --git a/sbin/setkey/token.l b/sbin/setkey/token.l index f065fd31b0b6..9bea6ae490d4 100644 --- a/sbin/setkey/token.l +++ b/sbin/setkey/token.l @@ -139,6 +139,7 @@ esp { yylval.num = 0; return(PR_ESP); } ah-old { yylval.num = 1; return(PR_AH); } esp-old { yylval.num = 1; return(PR_ESP); } ipcomp { yylval.num = 0; return(PR_IPCOMP); } +tcp { yylval.num = 0; return(PR_TCP); } /* authentication alogorithm */ {hyphen}A { BEGIN S_AUTHALG; return(F_AUTH); } @@ -151,6 +152,7 @@ ipcomp { yylval.num = 0; return(PR_IPCOMP); } hmac-sha2-512 { yylval.num = SADB_X_AALG_SHA2_512; BEGIN INITIAL; return(ALG_AUTH); } hmac-ripemd160 { yylval.num = SADB_X_AALG_RIPEMD160HMAC; BEGIN INITIAL; return(ALG_AUTH); } aes-xcbc-mac { yylval.num = SADB_X_AALG_AES_XCBC_MAC; BEGIN INITIAL; return(ALG_AUTH); } +tcp-md5 { yylval.num = SADB_X_AALG_TCP_MD5; BEGIN INITIAL; return(ALG_AUTH); } null { yylval.num = SADB_X_AALG_NULL; BEGIN INITIAL; return(ALG_AUTH_NOKEY); } /* encryption alogorithm */ diff --git a/usr.sbin/setkey/parse.y b/usr.sbin/setkey/parse.y index 80b9d177e27e..bc944a821098 100644 --- a/usr.sbin/setkey/parse.y +++ b/usr.sbin/setkey/parse.y @@ -94,7 +94,7 @@ extern void yyerror __P((const char *)); %token EOT SLASH BLCL ELCL %token ADD GET DELETE DELETEALL FLUSH DUMP -%token PR_ESP PR_AH PR_IPCOMP +%token PR_ESP PR_AH PR_IPCOMP PR_TCP %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI %token F_MODE MODE F_REQID %token F_EXT EXTENSION NOCYCLICSEQ @@ -113,7 +113,7 @@ extern void yyerror __P((const char *)); %type ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY %type ALG_AUTH ALG_AUTH_NOKEY %type ALG_COMP -%type PR_ESP PR_AH PR_IPCOMP +%type PR_ESP PR_AH PR_IPCOMP PR_TCP %type EXTENSION MODE %type DECSTRING %type PL_REQUESTS portstr key_string @@ -250,8 +250,12 @@ protocol_spec { $$ = SADB_X_SATYPE_IPCOMP; } + | PR_TCP + { + $$ = SADB_X_SATYPE_TCPSIGNATURE; + } ; - + spi : DECSTRING { p_spi = $1; } | HEXSTRING @@ -400,7 +404,12 @@ auth_alg p_key_auth_len = $2.len; p_key_auth = $2.buf; - if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH, + + if (p_alg_auth == SADB_X_AALG_TCP_MD5) { + if ((p_key_auth_len < 1) || (p_key_auth_len > + 80)) + return -1; + } else if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH, p_alg_auth, PFKEY_UNUNIT64(p_key_auth_len)) < 0) { yyerror(ipsec_strerror()); return -1; diff --git a/usr.sbin/setkey/setkey.8 b/usr.sbin/setkey/setkey.8 index 1e03edf9bcea..567dde46952b 100644 --- a/usr.sbin/setkey/setkey.8 +++ b/usr.sbin/setkey/setkey.8 @@ -252,6 +252,8 @@ AH based on rfc2402 AH based on rfc1826 .It Li ipcomp IPComp +.It Li tcp +TCP-MD5 based on rfc2385 .El .\" .Pp @@ -265,6 +267,8 @@ must be a decimal number, or a hexadecimal number with prefix. SPI values between 0 and 255 are reserved for future use by IANA and they cannot be used. +TCP-MD5 associations must use 0x1000 and therefore only have per-host +granularity at this time. .\" .Pp .It Ar extensions @@ -585,6 +589,7 @@ hmac-ripemd160 160 ah: 96bit ICV (RFC2857) ah-old: 128bit ICV (no document) aes-xcbc-mac 128 ah: 96bit ICV (RFC3566) 128 ah-old: 128bit ICV (no document) +tcp-md5 8 to 640 tcp: rfc2385 .Ed .Pp Followings are the list of encryption algorithms that can be used as @@ -649,6 +654,8 @@ dump esp ; spdadd 10.0.11.41/32[21] 10.0.11.33/32[any] any -P out ipsec esp/tunnel/192.168.0.1-192.168.1.2/require ; +add 10.1.10.34 10.1.10.36 tcp 0x1000 -A tcp-md5 "TCP-MD5 BGP secret" ; + .Ed .\" .Sh SEE ALSO diff --git a/usr.sbin/setkey/token.l b/usr.sbin/setkey/token.l index f065fd31b0b6..9bea6ae490d4 100644 --- a/usr.sbin/setkey/token.l +++ b/usr.sbin/setkey/token.l @@ -139,6 +139,7 @@ esp { yylval.num = 0; return(PR_ESP); } ah-old { yylval.num = 1; return(PR_AH); } esp-old { yylval.num = 1; return(PR_ESP); } ipcomp { yylval.num = 0; return(PR_IPCOMP); } +tcp { yylval.num = 0; return(PR_TCP); } /* authentication alogorithm */ {hyphen}A { BEGIN S_AUTHALG; return(F_AUTH); } @@ -151,6 +152,7 @@ ipcomp { yylval.num = 0; return(PR_IPCOMP); } hmac-sha2-512 { yylval.num = SADB_X_AALG_SHA2_512; BEGIN INITIAL; return(ALG_AUTH); } hmac-ripemd160 { yylval.num = SADB_X_AALG_RIPEMD160HMAC; BEGIN INITIAL; return(ALG_AUTH); } aes-xcbc-mac { yylval.num = SADB_X_AALG_AES_XCBC_MAC; BEGIN INITIAL; return(ALG_AUTH); } +tcp-md5 { yylval.num = SADB_X_AALG_TCP_MD5; BEGIN INITIAL; return(ALG_AUTH); } null { yylval.num = SADB_X_AALG_NULL; BEGIN INITIAL; return(ALG_AUTH_NOKEY); } /* encryption alogorithm */