diff options
Diffstat (limited to 'common/asn1.c')
-rw-r--r-- | common/asn1.c | 326 |
1 files changed, 0 insertions, 326 deletions
diff --git a/common/asn1.c b/common/asn1.c deleted file mode 100644 index 29cca3a..0000000 --- a/common/asn1.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (C) 2012 Red Hat Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * * Redistributions in binary form must reproduce the - * above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * * The names of contributors to this software may not be - * used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * Author: Stef Walter <stefw@redhat.com> - */ - -#include "config.h" - -#include "asn1.h" -#define P11_DEBUG_FLAG P11_DEBUG_TRUST -#include "debug.h" -#include "oid.h" - -#include "openssl.asn.h" -#include "pkix.asn.h" - -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -static void -free_asn1_def (void *data) -{ - node_asn *def = data; - asn1_delete_structure (&def); -} - -struct { - const ASN1_ARRAY_TYPE* tab; - const char *prefix; - int prefix_len; -} asn1_tabs[] = { - { pkix_asn1_tab, "PKIX1.", 6 }, - { openssl_asn1_tab, "OPENSSL.", 8 }, - { NULL, }, -}; - -p11_dict * -p11_asn1_defs_load (void) -{ - char message[ASN1_MAX_ERROR_DESCRIPTION_SIZE] = { 0, }; - node_asn *def; - p11_dict *defs; - int ret; - int i; - - defs = p11_dict_new (p11_dict_str_hash, p11_dict_str_equal, NULL, free_asn1_def); - - for (i = 0; asn1_tabs[i].tab != NULL; i++) { - - def = NULL; - ret = asn1_array2tree (asn1_tabs[i].tab, &def, message); - if (ret != ASN1_SUCCESS) { - p11_debug_precond ("failed to load %s* definitions: %s: %s\n", - asn1_tabs[i].prefix, asn1_strerror (ret), message); - return NULL; - } - - if (!p11_dict_set (defs, (void *)asn1_tabs[i].prefix, def)) - return_val_if_reached (NULL); - } - - return defs; -} - -static node_asn * -lookup_def (p11_dict *asn1_defs, - const char *struct_name) -{ - int i; - - for (i = 0; asn1_tabs[i].tab != NULL; i++) { - if (strncmp (struct_name, asn1_tabs[i].prefix, asn1_tabs[i].prefix_len) == 0) - return p11_dict_get (asn1_defs, asn1_tabs[i].prefix); - } - - p11_debug_precond ("unknown prefix for element: %s\n", struct_name); - return NULL; -} - -node_asn * -p11_asn1_create (p11_dict *asn1_defs, - const char *struct_name) -{ - node_asn *def; - node_asn *asn; - int ret; - - return_val_if_fail (asn1_defs != NULL, NULL); - - def = lookup_def (asn1_defs, struct_name); - return_val_if_fail (def != NULL, NULL); - - ret = asn1_create_element (def, struct_name, &asn); - if (ret != ASN1_SUCCESS) { - p11_debug_precond ("failed to create element %s: %s\n", - struct_name, asn1_strerror (ret)); - return NULL; - } - - return asn; -} - -node_asn * -p11_asn1_decode (p11_dict *asn1_defs, - const char *struct_name, - const unsigned char *der, - size_t der_len, - char *message) -{ - char msg[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; - node_asn *asn = NULL; - int ret; - - return_val_if_fail (asn1_defs != NULL, NULL); - - asn = p11_asn1_create (asn1_defs, struct_name); - return_val_if_fail (asn != NULL, NULL); - - /* asn1_der_decoding destroys the element if fails */ - ret = asn1_der_decoding (&asn, der, der_len, message ? message : msg); - - if (ret != ASN1_SUCCESS) { - /* If caller passed in a message buffer, assume they're logging */ - if (!message) { - p11_debug ("couldn't parse %s: %s: %s", - struct_name, asn1_strerror (ret), msg); - } - return NULL; - } - - return asn; -} - -unsigned char * -p11_asn1_encode (node_asn *asn, - size_t *der_len) -{ - char message[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; - unsigned char *der; - int len; - int ret; - - return_val_if_fail (der_len != NULL, NULL); - - len = 0; - ret = asn1_der_coding (asn, "", NULL, &len, message); - return_val_if_fail (ret != ASN1_SUCCESS, NULL); - - if (ret == ASN1_MEM_ERROR) { - der = malloc (len); - return_val_if_fail (der != NULL, NULL); - - ret = asn1_der_coding (asn, "", der, &len, message); - } - - if (ret != ASN1_SUCCESS) { - p11_debug_precond ("failed to encode: %s\n", message); - return NULL; - } - - if (der_len) - *der_len = len; - return der; -} - -ssize_t -p11_asn1_tlv_length (const unsigned char *data, - size_t length) -{ - unsigned char cls; - int counter = 0; - int cb, len; - unsigned long tag; - - if (asn1_get_tag_der (data, length, &cls, &cb, &tag) == ASN1_SUCCESS) { - counter += cb; - len = asn1_get_length_der (data + cb, length - cb, &cb); - counter += cb; - if (len >= 0) { - len += counter; - if (length >= len) - return len; - } - } - - return -1; -} - -typedef struct { - node_asn *node; - char *struct_name; - size_t length; -} asn1_item; - -static void -free_asn1_item (void *data) -{ - asn1_item *item = data; - free (item->struct_name); - asn1_delete_structure (&item->node); - free (item); -} - -struct _p11_asn1_cache { - p11_dict *defs; - p11_dict *items; -}; - -p11_asn1_cache * -p11_asn1_cache_new (void) -{ - p11_asn1_cache *cache; - - cache = calloc (1, sizeof (p11_asn1_cache)); - return_val_if_fail (cache != NULL, NULL); - - cache->defs = p11_asn1_defs_load (); - return_val_if_fail (cache->defs != NULL, NULL); - - cache->items = p11_dict_new (p11_dict_direct_hash, p11_dict_direct_equal, - NULL, free_asn1_item); - return_val_if_fail (cache->items != NULL, NULL); - - return cache; -} - -node_asn * -p11_asn1_cache_get (p11_asn1_cache *cache, - const char *struct_name, - const unsigned char *der, - size_t der_len) -{ - asn1_item *item; - - return_val_if_fail (cache != NULL, NULL); - return_val_if_fail (struct_name != NULL, NULL); - return_val_if_fail (der != NULL, NULL); - - item = p11_dict_get (cache->items, der); - if (item != NULL) { - return_val_if_fail (item->length == der_len, NULL); - return_val_if_fail (strcmp (item->struct_name, struct_name) == 0, NULL); - return item->node; - } - - return NULL; -} - -void -p11_asn1_cache_take (p11_asn1_cache *cache, - node_asn *node, - const char *struct_name, - const unsigned char *der, - size_t der_len) -{ - asn1_item *item; - - return_if_fail (cache != NULL); - return_if_fail (struct_name != NULL); - return_if_fail (der != NULL); - return_if_fail (der_len != 0); - - item = calloc (1, sizeof (asn1_item)); - return_if_fail (item != NULL); - - item->length = der_len; - item->node = node; - item->struct_name = strdup (struct_name); - return_if_fail (item->struct_name != NULL); - - if (!p11_dict_set (cache->items, (void *)der, item)) - return_if_reached (); -} - -void -p11_asn1_cache_flush (p11_asn1_cache *cache) -{ - return_if_fail (cache != NULL); - p11_dict_clear (cache->items); -} - -p11_dict * -p11_asn1_cache_defs (p11_asn1_cache *cache) -{ - return_val_if_fail (cache != NULL, NULL); - return cache->defs; -} - -void -p11_asn1_cache_free (p11_asn1_cache *cache) -{ - if (!cache) - return; - p11_dict_free (cache->items); - p11_dict_free (cache->defs); - free (cache); -} |