STACK API

From OpenSSLWiki
Jump to navigationJump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

The stack library provides a generic way to handle collections of objects in OpenSSL. A comparison function can be registered to sort the collection.

Interface is split in two headers, <openssl/stack.h> and <openssl/safestack.h>. The former declares the C functions that will execute the insert, delete, pop, push, and other operations on the stack, while the latter declares a bunch of macros to enforce some type-checking by the compiler; these macros are mostly auto-generated by mkstack.pl.

It is highly discouraged to use the C functions declared in <openssl/stack.h>. Rather, use the macros defined in <openssl/safestack.h> for OpenSSL built-in stacks, and declare your own type-checking wrappers for your custom stacks.

Basic Use

A stack type is defined with the DECLARE_STACK_OF() macro and its instances are declared with the STACK_OF() macro.

Example from <openssl/x509.h>:

/* a sequence of these are used */
typedef struct x509_attributes_st
        {
        ASN1_OBJECT *object;
        int single; /* 0 for a set, 1 for a single item (which is wrong) */
        union   {
                char            *ptr;
/* 0 */         STACK_OF(ASN1_TYPE) *set;
/* 1 */         ASN1_TYPE       *single;
                } value;
        } X509_ATTRIBUTE;

DECLARE_STACK_OF(X509_ATTRIBUTE)
DECLARE_ASN1_SET_OF(X509_ATTRIBUTE)


typedef struct X509_req_info_st
        {
        ASN1_ENCODING enc;
        ASN1_INTEGER *version;
        X509_NAME *subject;
        X509_PUBKEY *pubkey;
        /*  d=2 hl=2 l=  0 cons: cont: 00 */
        STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
        } X509_REQ_INFO;

For each kind of stack, a set of macros is available to manipulate its state and contents. Here is an example with the BIO object:

/* allocate & free */
#define sk_BIO_new(cmp)                 SKM_sk_new(BIO, (cmp))
#define sk_BIO_new_null()               SKM_sk_new_null(BIO)
#define sk_BIO_free(st)                 SKM_sk_free(BIO, (st))
#define sk_BIO_pop_free(st, free_func)  SKM_sk_pop_free(BIO, (st), (free_func))
#define sk_BIO_dup(st)                  SKM_sk_dup(BIO, st)

/* get & set */
#define sk_BIO_num(st)                  SKM_sk_num(BIO, (st))
#define sk_BIO_value(st, i)             SKM_sk_value(BIO, (st), (i))
#define sk_BIO_set(st, i, val)          SKM_sk_set(BIO, (st), (i), (val))

/* add value */
#define sk_BIO_insert(st, val, i)       SKM_sk_insert(BIO, (st), (val), (i))
#define sk_BIO_push(st, val)            SKM_sk_push(BIO, (st), (val))
#define sk_BIO_unshift(st, val)         SKM_sk_unshift(BIO, (st), (val))

/* sort & find */
#define sk_BIO_set_cmp_func(st, cmp)    SKM_sk_set_cmp_func(BIO, (st), (cmp))
#define sk_BIO_sort(st)                 SKM_sk_sort(BIO, (st))
#define sk_BIO_is_sorted(st)            SKM_sk_is_sorted(BIO, (st))
#define sk_BIO_find(st, val)            SKM_sk_find(BIO, (st), (val))
#define sk_BIO_find_ex(st, val)         SKM_sk_find_ex(BIO, (st), (val))

/* delete value */
#define sk_BIO_delete(st, i)            SKM_sk_delete(BIO, (st), (i))
#define sk_BIO_delete_ptr(st, ptr)      SKM_sk_delete_ptr(BIO, (st), (ptr))
#define sk_BIO_pop(st)                  SKM_sk_pop(BIO, (st))
#define sk_BIO_shift(st)                SKM_sk_shift(BIO, (st))
#define sk_BIO_zero(st)                 SKM_sk_zero(BIO, (st))