Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Xin Long <lucien.xin@gmail.com>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Xin Long and committed by
David S. Miller
601590ec 3ff547c0

+81 -9
+6 -6
include/net/sctp/auth.h
··· 65 65 struct sctp_auth_bytes *key; 66 66 refcount_t refcnt; 67 67 __u16 key_id; 68 + __u8 deactivated; 68 69 }; 69 70 70 71 #define key_for_each(__key, __list_head) \ ··· 114 113 int sctp_auth_ep_add_chunkid(struct sctp_endpoint *ep, __u8 chunk_id); 115 114 int sctp_auth_ep_set_hmacs(struct sctp_endpoint *ep, 116 115 struct sctp_hmacalgo *hmacs); 117 - int sctp_auth_set_key(struct sctp_endpoint *ep, 118 - struct sctp_association *asoc, 116 + int sctp_auth_set_key(struct sctp_endpoint *ep, struct sctp_association *asoc, 119 117 struct sctp_authkey *auth_key); 120 118 int sctp_auth_set_active_key(struct sctp_endpoint *ep, 121 - struct sctp_association *asoc, 122 - __u16 key_id); 119 + struct sctp_association *asoc, __u16 key_id); 123 120 int sctp_auth_del_key_id(struct sctp_endpoint *ep, 124 - struct sctp_association *asoc, 125 - __u16 key_id); 121 + struct sctp_association *asoc, __u16 key_id); 122 + int sctp_auth_deact_key_id(struct sctp_endpoint *ep, 123 + struct sctp_association *asoc, __u16 key_id); 126 124 127 125 #endif
+1
include/uapi/linux/sctp.h
··· 99 99 #define SCTP_RECVRCVINFO 32 100 100 #define SCTP_RECVNXTINFO 33 101 101 #define SCTP_DEFAULT_SNDINFO 34 102 + #define SCTP_AUTH_DEACTIVATE_KEY 35 102 103 103 104 /* Internal Socket Options. Some of the sctp library functions are 104 105 * implemented using these socket options.
+43 -3
net/sctp/auth.c
··· 449 449 450 450 /* First search associations set of endpoint pair shared keys */ 451 451 key_for_each(key, &asoc->endpoint_shared_keys) { 452 - if (key->key_id == key_id) 453 - return key; 452 + if (key->key_id == key_id) { 453 + if (!key->deactivated) 454 + return key; 455 + break; 456 + } 454 457 } 455 458 456 459 return NULL; ··· 908 905 } 909 906 } 910 907 911 - if (!found) 908 + if (!found || key->deactivated) 912 909 return -EINVAL; 913 910 914 911 if (asoc) { ··· 956 953 /* Delete the shared key */ 957 954 list_del_init(&key->key_list); 958 955 sctp_auth_shkey_release(key); 956 + 957 + return 0; 958 + } 959 + 960 + int sctp_auth_deact_key_id(struct sctp_endpoint *ep, 961 + struct sctp_association *asoc, __u16 key_id) 962 + { 963 + struct sctp_shared_key *key; 964 + struct list_head *sh_keys; 965 + int found = 0; 966 + 967 + /* The key identifier MUST NOT be the current active key 968 + * The key identifier MUST correst to an existing key 969 + */ 970 + if (asoc) { 971 + if (asoc->active_key_id == key_id) 972 + return -EINVAL; 973 + 974 + sh_keys = &asoc->endpoint_shared_keys; 975 + } else { 976 + if (ep->active_key_id == key_id) 977 + return -EINVAL; 978 + 979 + sh_keys = &ep->endpoint_shared_keys; 980 + } 981 + 982 + key_for_each(key, sh_keys) { 983 + if (key->key_id == key_id) { 984 + found = 1; 985 + break; 986 + } 987 + } 988 + 989 + if (!found) 990 + return -EINVAL; 991 + 992 + key->deactivated = 1; 959 993 960 994 return 0; 961 995 }
+31
net/sctp/socket.c
··· 3647 3647 } 3648 3648 3649 3649 /* 3650 + * 8.3.4 Deactivate a Shared Key (SCTP_AUTH_DEACTIVATE_KEY) 3651 + * 3652 + * This set option will deactivate a shared secret key. 3653 + */ 3654 + static int sctp_setsockopt_deactivate_key(struct sock *sk, char __user *optval, 3655 + unsigned int optlen) 3656 + { 3657 + struct sctp_endpoint *ep = sctp_sk(sk)->ep; 3658 + struct sctp_authkeyid val; 3659 + struct sctp_association *asoc; 3660 + 3661 + if (!ep->auth_enable) 3662 + return -EACCES; 3663 + 3664 + if (optlen != sizeof(struct sctp_authkeyid)) 3665 + return -EINVAL; 3666 + if (copy_from_user(&val, optval, optlen)) 3667 + return -EFAULT; 3668 + 3669 + asoc = sctp_id2assoc(sk, val.scact_assoc_id); 3670 + if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP)) 3671 + return -EINVAL; 3672 + 3673 + return sctp_auth_deact_key_id(ep, asoc, val.scact_keynumber); 3674 + } 3675 + 3676 + /* 3650 3677 * 8.1.23 SCTP_AUTO_ASCONF 3651 3678 * 3652 3679 * This option will enable or disable the use of the automatic generation of ··· 4264 4237 break; 4265 4238 case SCTP_AUTH_DELETE_KEY: 4266 4239 retval = sctp_setsockopt_del_key(sk, optval, optlen); 4240 + break; 4241 + case SCTP_AUTH_DEACTIVATE_KEY: 4242 + retval = sctp_setsockopt_deactivate_key(sk, optval, optlen); 4267 4243 break; 4268 4244 case SCTP_AUTO_ASCONF: 4269 4245 retval = sctp_setsockopt_auto_asconf(sk, optval, optlen); ··· 7242 7212 case SCTP_AUTH_KEY: 7243 7213 case SCTP_AUTH_CHUNK: 7244 7214 case SCTP_AUTH_DELETE_KEY: 7215 + case SCTP_AUTH_DEACTIVATE_KEY: 7245 7216 retval = -EOPNOTSUPP; 7246 7217 break; 7247 7218 case SCTP_HMAC_IDENT: