---
name: "keynote"
section: "3"
platform: "linux"
package: "libkeynote-dev"
version: "2.3-11"
release: "Debian 4.0 (Etch)"
platforms: ["linux"]
url: "https://new.carta.tech/keynote/3"
---

# keynote(3)

a trust-management system library

## NAME

**keynote** – 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;
};
```

*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 numauthauthorizers*);

*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 **KeyNote** 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 **KeyNote** 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 **KeyNote** library functions follows.

**kn\_init**() creates a new **KeyNote** 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(3). 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 with KEYNOTE\_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 with KEYNOTE\_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 **KeyNote** 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, keynote\_add\_action(3) 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(3) will be used. The programmer SHOULD NOT free *returnvalues* after the call to kn\_do\_query(3) 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(3) 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(3). 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(3) 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 in 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(3) 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(3), 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 *srclen* is not a multiple of 4, or *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 **KeyNote** 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(3)), 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 X509-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\_HEX SIG\_RSA\_SHA1\_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 X509-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)](/keynote/4.md) (quoted) string. This is useful for parsing key files.

## FILES

- *keynote.h*

  - *libkeynote.a*

  ## SEE ALSO

[keynote(1)](/keynote/1.md), [keynote(4)](/keynote/4.md), [keynote(5)](/keynote/5.md)

- \`\`The KeyNote Trust-Management System, Version 2''

  M. Blaze, J. Feigenbaum, A. D. Keromytis, Internet Drafts, RFC 2704.

- \`\`Decentralized Trust Management''

  M. Blaze, J. Feigenbaum, J. Lacy, 1996 IEEE Conference on Privacy and Security

- \`\`Compliance-Checking in the PolicyMaker Trust Management System''

  M. Blaze, J. Feigenbaum, M. Strauss, 1998 Financial Crypto Conference

- Web Page

  http://www.cis.upenn.edu/~keynote

## AUTHOR

Angelos D. Keromytis (angelos@dsl.cis.upenn.edu)

## DIAGNOSTICS

The return values of all the functions have been given along with the function description above.

## BUGS

None that we know of. If you find any, please report them to

```
keynote@research.att.com
```
