NAME
kn_init
,
kn_add_assertion
,
kn_remove_assertion
,
kn_add_action
,
kn_remove_action
,
kn_add_authorizer
,
kn_remove_authorizer
,
kn_do_query
, kn_get_failed
,
kn_cleanup_action_environment
,
kn_close
, kn_query
,
kn_read_asserts
,
kn_keycompare
,
kn_get_authorizer
,
kn_get_licensees
,
kn_encode_base64
,
kn_decode_base64
,
kn_encode_hex
,
kn_decode_hex
,
kn_encode_key
,
kn_decode_key
,
kn_sign_assertion
,
kn_verify_assertion
,
kn_free_key
, kn_get_string
— a trust-management system
library
SYNOPSIS
#include
<sys/types.h>
#include <regex.h>
#include <keynote.h>
struct environment { char *env_name; char *env_value; int env_flags; regex_t env_regex; struct environment *env_next; }; struct keynote_deckey { int dec_algorithm; void *dec_key; }; struct keynote_binary { int bn_len; char *bn_key; }; struct keynote_keylist { int key_alg; void *key_key; char *key_stringkey; struct keynote_keylist *key_next; };
extern int keynote_errno;
int
kn_init
(void);
int
kn_add_assertion
(int
sessid, char
*assertion, int
len, int
flags);
int
kn_remove_assertion
(int
sessid, int
assertid);
int
kn_add_action
(int
sessid, char *name,
char *value,
int flags);
int
kn_remove_action
(int
sessid, char
*name);
int
kn_add_authorizer
(int
sessid, char
*principal);
int
kn_remove_authorizer
(int
sessid, char
*principal);
int
kn_do_query
(int
sessid, char
**returnvalues, int
numvalues);
int
kn_get_failed
(int
sessid, int type,
int seq);
int
kn_cleanup_action_environment
(int
sessid);
int
kn_close
(int
sessid);
int
kn_query
(struct environment
*env, char **returnvalues, int
numvalues, char **trusted, int
*trustedlen, int numtrusted,
char **untrusted, int
*untrustedlen, int numuntrusted,
char **authorizers, int
numauthorizers);
char **
kn_read_asserts
(char
*array, int
arraylen, int
*numassertions);
int
kn_keycompare
(void
*key1, void *key2,
int algorithm);
void *
kn_get_authorizer
(int
sessid, int
assertid, int
*algorithm);
struct keynote_keylist *
kn_get_licensees
(int
sessid, int
assertid);
int
kn_encode_base64
(unsigned
char const *src, unsigned
int srclen, char
*dst, unsigned int
dstlen);
int
kn_decode_base64
(char
const *src, unsigned char
*dst, unsigned int
dstlen);
int
kn_encode_hex
(unsigned
char *src, char
**dst, int
srclen);
int
kn_decode_hex
(char
*src, char
**dst);
char *
kn_encode_key
(struct
keynote_deckey *dc, int
iencoding, int
encoding, int
keytype);
int
kn_decode_key
(struct
keynote_deckey *dc, char
*key, int
keytype);
char *
kn_sign_assertion
(char
*assertion, int
len, char *key,
char *algorithm,
int vflag);
int
kn_verify_assertion
(char
*assertion, int
len);
void
kn_free_key
(struct
keynote_deckey *);
char *
kn_get_string
(char
*);
Link options: -lkeynote -lm -lcrypto
DESCRIPTION
For more details on keynote
, see RFC
2704.
keynote_errno contains an error code if some
library call failed. Failed calls return -1 (if their return value is
integer), or NULL
(if their return value is a
pointer) and set keynote_errno. The defined error
codes are:
ERROR_MEMORY
- Some memory allocation or usage error was encountered.
ERROR_SYNTAX
- Some syntactic or logical error was encountered.
ERROR_NOTFOUND
- One of the arguments referred to a nonexistent structure or entry.
If no errors were encountered, keynote_errno will be set to 0. This variable should be reset to 0 if an error was encountered, prior to calling other library routines.
The main interface to kn_init
is centered
around the concept of a session. A session describes a collection of
policies, assertions, action authorizers, return values, and action
attributes that the kn_init
system uses to evaluate
a query. Information is not shared between sessions. Policies, credentials,
action authorizers, and action attributes can be added or deleted at any
point during the lifetime of a session. Furthermore, an application can
discover which assertions failed to be evaluated, and in what way, during a
query.
For those applications that only need to do a simple query, there exists a single call that takes as arguments all the necessary information and performs all the necessary steps. This is essentially a wrapper that calls the session API functions as necessary.
Finally, there exist functions for doing ASCII to hexadecimal and Base64 encoding (and vice versa), for encoding/decoding keys between ASCII and binary formats, and for signing and verifying assertions.
The description of all kn_init
library
functions follows.
kn_init
()
creates a new kn_init
session, and performs any
necessary initializations. On success, this function returns the new session
ID, which is used by all subsequent calls with a
sessid argument. On failure, it returns -1 and sets
keynote_errno to
ERROR_MEMORY
.
kn_add_assertion
()
adds the assertion pointed to by the array assertion,
of length len in the session identified by
sessid. The first argument can be discarded after the
call to this function. The following flags are defined:
- ASSERT_FLAG_LOCAL
- Mark this assertion as ultimately trusted. Trusted assertions need not be signed, and the Authorizer and Licensees fields can have non-key entries.
At least one (trusted) assertion should
have POLICY
as the Authorizer.
On success, this function will return an assertion ID which can be used to
remove the assertion from the session, by using
kn_remove_assertion
().
On failure, -1 is returned, and keynote_errno is set
to ERROR_NOTFOUND
if the session was not found,
ERROR_SYNTAX
if the assertion was syntactically
incorrect, or ERROR_MEMORY
if necessary memory could
not be allocated.
kn_remove_assertion
()
removes the assertion identified by assertid from the
session identified by sessid. On success, this
function returns 0. On failure, it returns -1 and sets
keynote_errno to
ERROR_NOTFOUND
.
kn_add_action
()
inserts the variable name in the action environment of
session sessid, with the value
value. The same attribute may be added more than once,
but only the last instance will be used (memory resources are consumed
however).
The flags specified are formed by or'ing the following values:
- ENVIRONMENT_FLAG_FUNC
- In this case, value is a pointer to a function that
takes as argument a string and returns a string. This is used to implement
callbacks for getting action attribute values. The argument passed to such
a callback function is a string identifying the action attribute whose
value is requested, and should return a pointer to string containing that
value (this pointer will not be freed by the library), the empty string if
the value was not found, or a
NULL
to indicate an error (and may set keynote_errno appropriately). Prior to first use (currently, at the time the attribute is added to the session environment), such functions are called withKEYNOTE_CALLBACK_INITIALIZE
as the argument (defined in keynote.h) so that they can perform any special initializations. Furthermore, when the session is deleted, all such functions will be called withKEYNOTE_CALLBACK_CLEANUP
to perform any special cleanup (such as free any allocated memory). A function may be called with either of these arguments more than once, if it has been defined as the callback function for more than one attribute. - ENVIRONMENT_FLAG_REGEX
- In this case, name is a regular expression that may
match more than one attribute. In case of conflict between a regular
expression and a “simple” attribute, the latter will be
given priority. In case of conflict between two regular expression
attributes, the one added later will be given priority. A callback
function should never change the current
kn_init
session, start/invoke/operate on another session, or call one of the session-API functions.
The combination of the two flags may be used to specify callback functions that handle large sets of attributes (even to the extent of having one callback function handling all attribute references). This is particularly useful when the action attribute set is particularly large.
On success,
kn_add_action
()
returns 0. On failure, it returns -1 and sets
keynote_errno to
ERROR_NOTFOUND
if the session was not found,
ERROR_SYNTAX
if the name was
invalid (e.g., started with an underscore character) or was
NULL
, or ERROR_MEMORY
if
necessary memory could not be allocated.
kn_remove_action
()
removes action attribute name from the environment of
session sessid. Notice that if more than one instances
of name exist, only the one added last will be
deleted. On success, this function returns 0. On failure, it returns -1 and
keynote_errno is set to
ERROR_NOTFOUND
if the session or the attribute were
not found, or ERROR_SYNTAX
if the name was invalid.
If the attribute value was a callback, that function will be called with the
define KEYNOTE_CALLBACK_CLEANUP
as the argument.
kn_add_authorizer
()
adds the principal pointed to by principal to the
action authorizers list of session sessid. The
principal is typically an ASCII-encoded key. On success, this function will
return 0. On failure, it returns -1 and sets
keynote_errno to
ERROR_NOTFOUND
if the session was not found,
ERROR_SYNTAX
if the encoding was invalid, or
ERROR_MEMORY
if necessary memory could not be
allocated.
kn_remove_authorizer
()
removes principal from the action authorizer list of
session sessid. On success, this function returns 0.
On failure, it returns -1 and sets keynote_errno to
ERROR_NOTFOUND
if the session was not found.
kn_do_query
()
evaluates the request based on the assertions, action attributes, and action
authorizers added to session sessid.
returnvalues is an ordered array of strings that
contain the return values. The lowest-ordered return value is contained in
returnvalues[0], and the highest-ordered value is
returnvalues[numvalues
- 1]. If returnvalues is
NULL
, the returnvalues from
the previous call to kn_do_query
() will be used. The
programmer SHOULD NOT free returnvalues after the call
to kn_do_query
() if this feature is used, as the
array is not replicated internally. On success, this function returns an
index into the returnvalues array. On failure, it
returns -1 and sets keynote_errno to
ERROR_NOTFOUND
if the session was not found or the
authorizers list was empty, ERROR_SYNTAX
if no
returnvalues have been specified, or
ERROR_MEMORY
if necessary memory could not be
allocated.
kn_get_failed
()
returns the assertion ID of the num'th assertion
(starting from zero) in session sessid that was
somehow invalid during evaluation. This function is typically called after
kn_do_query
() is used to evaluate a request.
type specifies the type of failure the application is
interested in. It can be set to:
- KEYNOTE_ERROR_ANY
- to indicate interest in any error.
- KEYNOTE_ERROR_SYNTAX
- for syntactic or semantic errors.
- KEYNOTE_ERROR_MEMORY
- for memory-related problems.
- KEYNOTE_ERROR_SIGNATURE
- if the assertion could not be cryptographically verified.
These values are defined in keynote.h.
An application can then delete the offending assertion using
kn_remove_assertion
().
For example, to remove all assertion whose signature failed, an application
could do something like:
while ((assertid = kn_get_failed(sessid, KEYNOTE_ERROR_SIGNATURE, 0) != -1) kn_remove_assertion(sessid, assertid);
On success,
kn_get_failed
()
returns an assertion ID. On failure, or when no assertion matching the given
criteria is found, it returns -1 and set keynote_errno
to ERROR_NOTFOUND
.
kn_cleanup_action_environment
()
removes all action attributes from the action environment of session
sessid. It returns 0 on success.
kn_close
()
closes session sessid and frees all related resources,
deleting action attributes, action authorizers, and assertions. On success,
this function returns 0. On failure, it returns -1 and sets
keynote_errno to
ERROR_NOTFOUND
if the session was not found.
kn_read_asserts
()
parses the string array of length
arraylen and returns an array of pointers to strings
containing copies of the assertions found in array.
Both the array of pointers and the strings are allocated by
kn_read_asserts
() dynamically, and thus should be
freed by the programmer when they are no longer needed.
numassertions contains the number of assertions (and
thus strings in the returned array) found in array. On
failure, this function returns NULL
and sets
keynote_errno to ERROR_MEMORY
if necessary memory could not be allocated, or
ERROR_SYNTAX
if array was
NULL
. Note that if there were no assertions found in
array, a valid pointer will be returned, but
numassertions will contain the value zero on return.
The returned pointer should be freed by the programmer.
kn_keycompare
()
compares key1 and key2 (which
must be of the same algorithm) and returns 1 if equal
and 0 otherwise.
kn_get_authorizer
()
returns the authorizer key (in binary format) for assertion
assertid in session sessid. It
also sets the algorithm argument to the algorithm of
the authorizer key. On failure, kn_get_authorizer
()
returns NULL
, and sets
keynote_errno to
ERROR_NOTFOUND
.
kn_get_licensees
()
returns the licensee key(s) for assertion assertid in
session sessid. The keys are returned in a linked list
of struct keynote_keylist structures. On failure,
kn_get_licensees
() returns
NULL
. and sets keynote_errno
to ERROR_NOTFOUND
.
kn_query
()
takes as arguments a list of action attributes in env,
a list of return values in returnvalues (the number of
returnvalues is indicated by numvalues), a number
(numtrusted) of locally-trusted assertions in
trusted (the length of each assertion is given by the
respective element of trustedlen), a number
(numuntrusted) of assertions that need to be
cryptographically verified in untrusted (the length of
each assertion is given by the respective element of
untrustedlen), and a number
(numauthorizers) of action authorizers in
authorizers. env is a linked
list of struct environment structures. The
env_name, env_value, and
env_flags fields correspond to the
name, value, and
flags arguments to
kn_add_assertion
() respectively.
env_regex is not used. On success, this function
returns an index in returnvalues indicating the
returned value to the query. On failure, it returns -1 and sets
keynote_errno to the same values as
kn_do_query
(), or to
ERROR_MEMORY
if a trusted or untrusted assertion
could not be added to the session due to lack of memory resources. Syntax
errors in assertions will not be reported by
kn_query
().
kn_encode_base64
()
converts the data of length srclen contained in
src in Base64 encoding and stores them in
dst which is of length dstlen.
The actual length of the encoding stored in dst is
returned. dst should be long enough to also contain
the trailing string terminator. If dst is not long
enough to contain the encoded data, this function returns -1 and sets
keynote_errno to
ERROR_SYNTAX
.
kn_decode_base64
()
decodes the Base64-encoded data stored in src and
stores the result in dst, which is of length
dstlen. The actual length of the decoded data is
returned on success. On failure, this function returns -1 and sets
keynote_errno to ERROR_SYNTAX
,
denoting either an invalid Base64 encoding or insufficient space in
dst.
kn_encode_hex
()
encodes in ASCII-hexadecimal format the data of length
srclen contained in src. This
function allocates a chunk of memory to store the result, which is returned
in dst. Thus, this function should be used as
follows:
char *dst; kn_encode_hex(src, &dst, srclen);
The length of the allocated buffer will be (2 * srclen + 1). On
success, this function returns 0. On failure, it returns -1 and sets
keynote_errno to ERROR_MEMORY
if it failed to allocate enough memory, ERROR_SYNTAX
if dst was NULL
.
kn_decode_hex
()
decodes the ASCII hex-encoded string in src and stores
the result in a memory chunk allocated by the function. A pointer to that
memory is stored in dst. The length of the allocated
memory will be (strlen(src) / 2). On success, this function returns 0. On
failure, it returns -1 and sets keynote_errno to
ERROR_MEMORY
if it could not allocate enough memory,
or ERROR_SYNTAX
if dst was
NULL
, or the length of src is
not even.
kn_encode_key
()
ASCII-encodes a cryptographic key. The binary representation of the key is
contained in dc. The field
dec_key in that structure is a pointer to some
cryptographic algorithm dependent information describing the key. In this
implementation, this pointer should be a DSA * or
RSA * for DSA or RSA keys respectively, as used in the
SSL library, or a keynote_binary * for cryptographic
keys whose algorithm kn_init
does not know about but
the application wishes to include in the action authorizers (and thus need
to be canonicalized). The field dec_algorithm
describes the cryptographic algorithm, and may be one of
KEYNOTE_ALGORITHM_DSA
,
KEYNOTE_ALGORITHM_RSA
, or
KEYNOTE_ALGORITHM_BINARY
in this implementation.
iencoding describes how the key should be
binary-encoded. This implementation supports
INTERNAL_ENC_PKCS1
for RSA keys,
INTERNAL_ENC_ASN1
for DSA keys, and
INTERNAL_ENC_NONE
for BINARY keys.
encoding describes what ASCII encoding should be
applied to the key. Valid values are ENCODING_HEX
and ENCODING_BASE64
, for hexadecimal and Base64
encoding respectively. keytype is one of
KEYNOTE_PUBLIC_KEY
or
KEYNOTE_PRIVATE_KEY
to indicate whether the key is
public or private. Private keys have the string
KEYNOTE_PRIVATE_KEY_PREFIX
(defined in keynote.h)
prefixed to the algorithm name. On success, this function returns a string
containing the encoded key. On failure, it returns
NULL
and sets keynote_errno to
ERROR_NOTFOUND
if the dc
argument was invalid, ERROR_MEMORY
if it failed to
allocate the necessary memory, or ERROR_SYNTAX
if
the key to be converted was invalid.
kn_decode_key
()
decodes the ASCII-encoded string contained in key. The
result is placed in dc, with
dec_algorithm describing the algorithm (see
kn_encode_key
()), and dec_key
pointing to an algorithm-dependent structure. In this implementation, this
is an SSLeay/OpenSSL-defined DSA * for DSA keys,
RSA * for RSA and X.509-based keys, and a
keynote_binary * for BINARY keys.
keytype takes the values
KEYNOTE_PUBLIC_KEY
or
KEYNOTE_PRIVATE_KEY
to specify a public or private
key, where applicable. On success, this function returns 0. On failure, it
returns -1 and sets keynote_errno to
ERROR_MEMORY
if necessary memory could not be
allocated, or ERROR_SYNTAX
if the key or the ASCII
encoding was malformed.
kn_sign_assertion
()
produces the cryptographic signature for the assertion of length
len stored in assertion, using
the ASCII-encoded cryptographic key contained in key.
The type of signature to be produced is described by the string
algorithm. Possible values for this string are
SIG_RSA_SHA1_PKCS1_HEX
,
SIG_RSA_SHA1_PKCS1_BASE64
,
SIG_RSA_MD5_HEX
and
SIG_RSA_MD5_HEX
for RSA keys,
SIG_DSA_SHA1_HEX
and
SIG_DSA_SHA1_BASE64
for DSA keys,
SIG_X509_SHA1_HEX
and
SIG_X509_SHA1_BASE64
for X.509-based keys. No other
cryptographic signatures are currently supported by this implementation. If
vflag is set to 1, then the generated signature will
also be verified. On success, this function returns a string containing the
ASCII-encoded signature, without modifying the
assertion. On failure, it returns
NULL
and sets keynote_errno to
ERROR_NOTFOUND
if one of the arguments was
NULL
, ERROR_MEMORY
if
necessary memory could not be allocated, or
ERROR_SYNTAX
if the algorithm,
the key, or the assertion (if
signature verification was requested) was invalid.
kn_verify_assertion
()
verifies the cryptographic signature on the assertion of length
len contained in string
assertion. On success, this function returns
SIGRESULT_TRUE
if the signature could be verified,
or SIGRESULT_FALSE
otherwise. On failure, this
function returns -1 and sets keynote_errno to
ERROR_MEMORY
if necessary memory could not be
allocated, or ERROR_SYNTAX
if the assertion
contained a syntactic error, or the cryptographic algorithm was not
supported.
kn_free_key
()
frees a cryptographic key.
kn_get_string
()
parses the argument, treating it as a
keynote(4) (quoted) string. This is useful for parsing key files. On
success, this function returns a pointer to the parsing result. The result
is dynamically allocated and should be freed after use. On failure,
NULL
is returned.
FILES
- keynote.h
- libkeynote.a
DIAGNOSTICS
The return values of all the functions have been given along with the function description above.
SEE ALSO
keynote(1), keynote(4), keynote(5)
M. Blaze, J. Feigenbaum, and J. Lacy, Decentralized Trust Management, IEEE Symposium on Security and Privacy, 1996.
M. Blaze, J. Feigenbaum, and M. Strauss, Compliance-Checking in the PolicyMaker Trust Management System, Financial Crypto Conference, 1998.
STANDARDS
M. Blaze, J. Feigenbaum, J. Ioannidis, and A. Keromytis, The KeyNote Trust-Management System Version 2, RFC 2704, September 1999.
AUTHORS
Angelos D. Keromytis <angelos@cs.columbia.edu>