/* RxRPC key management
*
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* RxRPC keys should have a description of describing their purpose:
* "afs@CAMBRIDGE.REDHAT.COM>
*/
#include <linux/module.h>
#include <linux/net.h>
#include <linux/skbuff.h>
#include <linux/key-type.h>
#include <linux/crypto.h>
#include <linux/ctype.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
#include <keys/rxrpc-type.h>
#include <keys/user-type.h>
#include "ar-internal.h"
static int rxrpc_instantiate(struct key *, const void *, size_t);
static int rxrpc_instantiate_s(struct key *, const void *, size_t);
static void rxrpc_destroy(struct key *);
static void rxrpc_destroy_s(struct key *);
static void rxrpc_describe(const struct key *, struct seq_file *);
static long rxrpc_read(const struct key *, char __user *, size_t);
/*
* rxrpc defined keys take an arbitrary string as the description and an
* arbitrary blob of data as the payload
*/
struct key_type key_type_rxrpc = {
.name = "rxrpc",
.instantiate = rxrpc_instantiate,
.match = user_match,
.destroy = rxrpc_destroy,
.describe = rxrpc_describe,
.read = rxrpc_read,
};
EXPORT_SYMBOL(key_type_rxrpc);
/*
* rxrpc server defined keys take "<serviceId>:<securityIndex>" as the
* description and an 8-byte decryption key as the payload
*/
struct key_type key_type_rxrpc_s = {
.name = "rxrpc_s",
.instantiate = rxrpc_instantiate_s,
.match = user_match,
.destroy = rxrpc_destroy_s,
.describe = rxrpc_describe,
};
/*
* parse an RxKAD type XDR format token
* - the caller guarantees we have at least 4 words
*/
static int rxrpc_instantiate_xdr_rxkad(struct key *key, const __be32 *xdr,
unsigned toklen)
{
struct rxrpc_key_token *token, **pptoken;
size_t plen;
u32 tktlen;
int ret;
_enter(",{%x,%x,%x,%x},%u",
ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
toklen);
if (toklen <= 8 * 4)
return -EKEYREJECTED;
tktlen = ntohl(xdr[7]);
_debug("tktlen: %x", tktlen);
if (tktlen > AFSTOKEN_RK_TIX_MAX)
return -EKEYREJECTED;
if (8 * 4 + tktlen != toklen)
return -EKEYREJECTED;
plen = sizeof(*token) + sizeof(*token->kad) + tktlen;
ret = key_payload_reserve(key, key->datalen + plen);
if (ret < 0)
return ret;
plen -= sizeof(*token);
token = kmalloc(sizeof(*token), GFP_KERNEL);
if (!token)
return -ENOMEM;
token->kad = kmalloc(plen, GFP_KERNEL);