Commit 601590ec authored by Xin Long's avatar Xin Long Committed by David S. Miller

sctp: add sockopt SCTP_AUTH_DEACTIVATE_KEY

This patch is to add sockopt SCTP_AUTH_DEACTIVATE_KEY, as described in
section 8.3.4 of RFC6458.

This set option indicates that the application will no longer send user
messages using the indicated key identifier.

Note that RFC requires that only deactivated keys that are no longer used
by an association can be deleted, but for the backward compatibility, it
is not to check deactivated when deleting or replacing one sh_key.
Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
Acked-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3ff547c0
...@@ -65,6 +65,7 @@ struct sctp_shared_key { ...@@ -65,6 +65,7 @@ struct sctp_shared_key {
struct sctp_auth_bytes *key; struct sctp_auth_bytes *key;
refcount_t refcnt; refcount_t refcnt;
__u16 key_id; __u16 key_id;
__u8 deactivated;
}; };
#define key_for_each(__key, __list_head) \ #define key_for_each(__key, __list_head) \
...@@ -113,14 +114,13 @@ void sctp_auth_shkey_hold(struct sctp_shared_key *sh_key); ...@@ -113,14 +114,13 @@ void sctp_auth_shkey_hold(struct sctp_shared_key *sh_key);
int sctp_auth_ep_add_chunkid(struct sctp_endpoint *ep, __u8 chunk_id); int sctp_auth_ep_add_chunkid(struct sctp_endpoint *ep, __u8 chunk_id);
int sctp_auth_ep_set_hmacs(struct sctp_endpoint *ep, int sctp_auth_ep_set_hmacs(struct sctp_endpoint *ep,
struct sctp_hmacalgo *hmacs); struct sctp_hmacalgo *hmacs);
int sctp_auth_set_key(struct sctp_endpoint *ep, int sctp_auth_set_key(struct sctp_endpoint *ep, struct sctp_association *asoc,
struct sctp_association *asoc,
struct sctp_authkey *auth_key); struct sctp_authkey *auth_key);
int sctp_auth_set_active_key(struct sctp_endpoint *ep, int sctp_auth_set_active_key(struct sctp_endpoint *ep,
struct sctp_association *asoc, struct sctp_association *asoc, __u16 key_id);
__u16 key_id);
int sctp_auth_del_key_id(struct sctp_endpoint *ep, int sctp_auth_del_key_id(struct sctp_endpoint *ep,
struct sctp_association *asoc, struct sctp_association *asoc, __u16 key_id);
__u16 key_id); int sctp_auth_deact_key_id(struct sctp_endpoint *ep,
struct sctp_association *asoc, __u16 key_id);
#endif #endif
...@@ -99,6 +99,7 @@ typedef __s32 sctp_assoc_t; ...@@ -99,6 +99,7 @@ typedef __s32 sctp_assoc_t;
#define SCTP_RECVRCVINFO 32 #define SCTP_RECVRCVINFO 32
#define SCTP_RECVNXTINFO 33 #define SCTP_RECVNXTINFO 33
#define SCTP_DEFAULT_SNDINFO 34 #define SCTP_DEFAULT_SNDINFO 34
#define SCTP_AUTH_DEACTIVATE_KEY 35
/* Internal Socket Options. Some of the sctp library functions are /* Internal Socket Options. Some of the sctp library functions are
* implemented using these socket options. * implemented using these socket options.
......
...@@ -449,8 +449,11 @@ struct sctp_shared_key *sctp_auth_get_shkey( ...@@ -449,8 +449,11 @@ struct sctp_shared_key *sctp_auth_get_shkey(
/* First search associations set of endpoint pair shared keys */ /* First search associations set of endpoint pair shared keys */
key_for_each(key, &asoc->endpoint_shared_keys) { key_for_each(key, &asoc->endpoint_shared_keys) {
if (key->key_id == key_id) if (key->key_id == key_id) {
if (!key->deactivated)
return key; return key;
break;
}
} }
return NULL; return NULL;
...@@ -905,7 +908,7 @@ int sctp_auth_set_active_key(struct sctp_endpoint *ep, ...@@ -905,7 +908,7 @@ int sctp_auth_set_active_key(struct sctp_endpoint *ep,
} }
} }
if (!found) if (!found || key->deactivated)
return -EINVAL; return -EINVAL;
if (asoc) { if (asoc) {
...@@ -956,3 +959,40 @@ int sctp_auth_del_key_id(struct sctp_endpoint *ep, ...@@ -956,3 +959,40 @@ int sctp_auth_del_key_id(struct sctp_endpoint *ep,
return 0; return 0;
} }
int sctp_auth_deact_key_id(struct sctp_endpoint *ep,
struct sctp_association *asoc, __u16 key_id)
{
struct sctp_shared_key *key;
struct list_head *sh_keys;
int found = 0;
/* The key identifier MUST NOT be the current active key
* The key identifier MUST correst to an existing key
*/
if (asoc) {
if (asoc->active_key_id == key_id)
return -EINVAL;
sh_keys = &asoc->endpoint_shared_keys;
} else {
if (ep->active_key_id == key_id)
return -EINVAL;
sh_keys = &ep->endpoint_shared_keys;
}
key_for_each(key, sh_keys) {
if (key->key_id == key_id) {
found = 1;
break;
}
}
if (!found)
return -EINVAL;
key->deactivated = 1;
return 0;
}
...@@ -3646,6 +3646,33 @@ static int sctp_setsockopt_del_key(struct sock *sk, ...@@ -3646,6 +3646,33 @@ static int sctp_setsockopt_del_key(struct sock *sk,
} }
/*
* 8.3.4 Deactivate a Shared Key (SCTP_AUTH_DEACTIVATE_KEY)
*
* This set option will deactivate a shared secret key.
*/
static int sctp_setsockopt_deactivate_key(struct sock *sk, char __user *optval,
unsigned int optlen)
{
struct sctp_endpoint *ep = sctp_sk(sk)->ep;
struct sctp_authkeyid val;
struct sctp_association *asoc;
if (!ep->auth_enable)
return -EACCES;
if (optlen != sizeof(struct sctp_authkeyid))
return -EINVAL;
if (copy_from_user(&val, optval, optlen))
return -EFAULT;
asoc = sctp_id2assoc(sk, val.scact_assoc_id);
if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP))
return -EINVAL;
return sctp_auth_deact_key_id(ep, asoc, val.scact_keynumber);
}
/* /*
* 8.1.23 SCTP_AUTO_ASCONF * 8.1.23 SCTP_AUTO_ASCONF
* *
...@@ -4238,6 +4265,9 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname, ...@@ -4238,6 +4265,9 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
case SCTP_AUTH_DELETE_KEY: case SCTP_AUTH_DELETE_KEY:
retval = sctp_setsockopt_del_key(sk, optval, optlen); retval = sctp_setsockopt_del_key(sk, optval, optlen);
break; break;
case SCTP_AUTH_DEACTIVATE_KEY:
retval = sctp_setsockopt_deactivate_key(sk, optval, optlen);
break;
case SCTP_AUTO_ASCONF: case SCTP_AUTO_ASCONF:
retval = sctp_setsockopt_auto_asconf(sk, optval, optlen); retval = sctp_setsockopt_auto_asconf(sk, optval, optlen);
break; break;
...@@ -7212,6 +7242,7 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname, ...@@ -7212,6 +7242,7 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname,
case SCTP_AUTH_KEY: case SCTP_AUTH_KEY:
case SCTP_AUTH_CHUNK: case SCTP_AUTH_CHUNK:
case SCTP_AUTH_DELETE_KEY: case SCTP_AUTH_DELETE_KEY:
case SCTP_AUTH_DEACTIVATE_KEY:
retval = -EOPNOTSUPP; retval = -EOPNOTSUPP;
break; break;
case SCTP_HMAC_IDENT: case SCTP_HMAC_IDENT:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment