rxrpc: Support keys with multiple authentication tokens

rxrpc-type keys can have multiple tokens attached for different security
classes.  Currently, rxrpc always picks the first one, whether or not the
security class it indicates is supported.

Add preliminary support for choosing which security class will be used
(this will need to be directed from a higher layer) and go through the
tokens to find one that's supported.

Signed-off-by: David Howells <dhowells@redhat.com>
This commit is contained in:
David Howells 2020-09-16 08:19:12 +01:00
parent 0727d3ec38
commit 41057ebde0
5 changed files with 17 additions and 13 deletions

View File

@ -12,6 +12,7 @@
#include <net/netns/generic.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
#include <keys/rxrpc-type.h>
#include "protocol.h"
#if 0
@ -217,7 +218,8 @@ struct rxrpc_security {
void (*exit)(void);
/* initialise a connection's security */
int (*init_connection_security)(struct rxrpc_connection *);
int (*init_connection_security)(struct rxrpc_connection *,
struct rxrpc_key_token *);
/* prime a connection's packet security */
int (*prime_packet_security)(struct rxrpc_connection *);

View File

@ -333,7 +333,8 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,
if (ret < 0)
return ret;
ret = conn->security->init_connection_security(conn);
ret = conn->security->init_connection_security(
conn, conn->params.key->payload.data[0]);
if (ret < 0)
return ret;

View File

@ -8,7 +8,8 @@
#include <net/af_rxrpc.h>
#include "ar-internal.h"
static int none_init_connection_security(struct rxrpc_connection *conn)
static int none_init_connection_security(struct rxrpc_connection *conn,
struct rxrpc_key_token *token)
{
return 0;
}

View File

@ -49,15 +49,14 @@ static DEFINE_MUTEX(rxkad_ci_mutex);
/*
* initialise connection security
*/
static int rxkad_init_connection_security(struct rxrpc_connection *conn)
static int rxkad_init_connection_security(struct rxrpc_connection *conn,
struct rxrpc_key_token *token)
{
struct crypto_sync_skcipher *ci;
struct rxrpc_key_token *token;
int ret;
_enter("{%d},{%x}", conn->debug_id, key_serial(conn->params.key));
token = conn->params.key->payload.data[0];
conn->security_ix = token->security_index;
ci = crypto_alloc_sync_skcipher("pcbc(fcrypt)", 0, 0);

View File

@ -81,16 +81,17 @@ int rxrpc_init_client_conn_security(struct rxrpc_connection *conn)
if (ret < 0)
return ret;
token = key->payload.data[0];
if (!token)
return -EKEYREJECTED;
for (token = key->payload.data[0]; token; token = token->next) {
sec = rxrpc_security_lookup(token->security_index);
if (sec)
goto found;
}
return -EKEYREJECTED;
sec = rxrpc_security_lookup(token->security_index);
if (!sec)
return -EKEYREJECTED;
found:
conn->security = sec;
ret = conn->security->init_connection_security(conn);
ret = conn->security->init_connection_security(conn, token);
if (ret < 0) {
conn->security = &rxrpc_no_security;
return ret;