diff options
author | Arne Schwabe <arne@rfc2549.org> | 2012-04-16 19:21:14 +0200 |
---|---|---|
committer | Arne Schwabe <arne@rfc2549.org> | 2012-04-16 19:21:14 +0200 |
commit | 3e4d8f433239c40311037616b1b8833a06651ae0 (patch) | |
tree | 98ab7fce0d011d34677b0beb762d389cb5c39199 /openssl/crypto/store/str_lib.c |
Initial import
Diffstat (limited to 'openssl/crypto/store/str_lib.c')
-rw-r--r-- | openssl/crypto/store/str_lib.c | 1828 |
1 files changed, 1828 insertions, 0 deletions
diff --git a/openssl/crypto/store/str_lib.c b/openssl/crypto/store/str_lib.c new file mode 100644 index 00000000..f1dbcbd0 --- /dev/null +++ b/openssl/crypto/store/str_lib.c @@ -0,0 +1,1828 @@ +/* crypto/store/str_lib.c -*- mode:C; c-file-style: "eay" -*- */ +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL + * project 2003. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS 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. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include <string.h> +#include <openssl/bn.h> +#include <openssl/err.h> +#ifndef OPENSSL_NO_ENGINE +#include <openssl/engine.h> +#endif +#include <openssl/sha.h> +#include <openssl/x509.h> +#include "str_locl.h" + +const char * const STORE_object_type_string[STORE_OBJECT_TYPE_NUM+1] = + { + 0, + "X.509 Certificate", + "X.509 CRL", + "Private Key", + "Public Key", + "Number", + "Arbitrary Data" + }; + +const int STORE_param_sizes[STORE_PARAM_TYPE_NUM+1] = + { + 0, + sizeof(int), /* EVP_TYPE */ + sizeof(size_t), /* BITS */ + -1, /* KEY_PARAMETERS */ + 0 /* KEY_NO_PARAMETERS */ + }; + +const int STORE_attr_sizes[STORE_ATTR_TYPE_NUM+1] = + { + 0, + -1, /* FRIENDLYNAME: C string */ + SHA_DIGEST_LENGTH, /* KEYID: SHA1 digest, 160 bits */ + SHA_DIGEST_LENGTH, /* ISSUERKEYID: SHA1 digest, 160 bits */ + SHA_DIGEST_LENGTH, /* SUBJECTKEYID: SHA1 digest, 160 bits */ + SHA_DIGEST_LENGTH, /* ISSUERSERIALHASH: SHA1 digest, 160 bits */ + sizeof(X509_NAME *), /* ISSUER: X509_NAME * */ + sizeof(BIGNUM *), /* SERIAL: BIGNUM * */ + sizeof(X509_NAME *), /* SUBJECT: X509_NAME * */ + SHA_DIGEST_LENGTH, /* CERTHASH: SHA1 digest, 160 bits */ + -1, /* EMAIL: C string */ + -1, /* FILENAME: C string */ + }; + +STORE *STORE_new_method(const STORE_METHOD *method) + { + STORE *ret; + + if (method == NULL) + { + STOREerr(STORE_F_STORE_NEW_METHOD,ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + ret=(STORE *)OPENSSL_malloc(sizeof(STORE)); + if (ret == NULL) + { + STOREerr(STORE_F_STORE_NEW_METHOD,ERR_R_MALLOC_FAILURE); + return NULL; + } + + ret->meth=method; + + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_STORE, ret, &ret->ex_data); + if (ret->meth->init && !ret->meth->init(ret)) + { + STORE_free(ret); + ret = NULL; + } + return ret; + } + +STORE *STORE_new_engine(ENGINE *engine) + { + STORE *ret = NULL; + ENGINE *e = engine; + const STORE_METHOD *meth = 0; + +#ifdef OPENSSL_NO_ENGINE + e = NULL; +#else + if (engine) + { + if (!ENGINE_init(engine)) + { + STOREerr(STORE_F_STORE_NEW_ENGINE, ERR_R_ENGINE_LIB); + return NULL; + } + e = engine; + } + else + { + STOREerr(STORE_F_STORE_NEW_ENGINE,ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if(e) + { + meth = ENGINE_get_STORE(e); + if(!meth) + { + STOREerr(STORE_F_STORE_NEW_ENGINE, + ERR_R_ENGINE_LIB); + ENGINE_finish(e); + return NULL; + } + } +#endif + + ret = STORE_new_method(meth); + if (ret == NULL) + { + STOREerr(STORE_F_STORE_NEW_ENGINE,ERR_R_STORE_LIB); + return NULL; + } + + ret->engine = e; + + return(ret); + } + +void STORE_free(STORE *store) + { + if (store == NULL) + return; + if (store->meth->clean) + store->meth->clean(store); + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_STORE, store, &store->ex_data); + OPENSSL_free(store); + } + +int STORE_ctrl(STORE *store, int cmd, long i, void *p, void (*f)(void)) + { + if (store == NULL) + { + STOREerr(STORE_F_STORE_CTRL,ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (store->meth->ctrl) + return store->meth->ctrl(store, cmd, i, p, f); + STOREerr(STORE_F_STORE_CTRL,STORE_R_NO_CONTROL_FUNCTION); + return 0; + } + + +int STORE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) + { + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_STORE, argl, argp, + new_func, dup_func, free_func); + } + +int STORE_set_ex_data(STORE *r, int idx, void *arg) + { + return(CRYPTO_set_ex_data(&r->ex_data,idx,arg)); + } + +void *STORE_get_ex_data(STORE *r, int idx) + { + return(CRYPTO_get_ex_data(&r->ex_data,idx)); + } + +const STORE_METHOD *STORE_get_method(STORE *store) + { + return store->meth; + } + +const STORE_METHOD *STORE_set_method(STORE *store, const STORE_METHOD *meth) + { + store->meth=meth; + return store->meth; + } + + +/* API helpers */ + +#define check_store(s,fncode,fnname,fnerrcode) \ + do \ + { \ + if ((s) == NULL || (s)->meth == NULL) \ + { \ + STOREerr((fncode), ERR_R_PASSED_NULL_PARAMETER); \ + return 0; \ + } \ + if ((s)->meth->fnname == NULL) \ + { \ + STOREerr((fncode), (fnerrcode)); \ + return 0; \ + } \ + } \ + while(0) + +/* API functions */ + +X509 *STORE_get_certificate(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + STORE_OBJECT *object; + X509 *x; + + check_store(s,STORE_F_STORE_GET_CERTIFICATE, + get_object,STORE_R_NO_GET_OBJECT_FUNCTION); + + object = s->meth->get_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE, + attributes, parameters); + if (!object || !object->data.x509.certificate) + { + STOREerr(STORE_F_STORE_GET_CERTIFICATE, + STORE_R_FAILED_GETTING_CERTIFICATE); + return 0; + } + CRYPTO_add(&object->data.x509.certificate->references,1,CRYPTO_LOCK_X509); +#ifdef REF_PRINT + REF_PRINT("X509",data); +#endif + x = object->data.x509.certificate; + STORE_OBJECT_free(object); + return x; + } + +int STORE_store_certificate(STORE *s, X509 *data, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + STORE_OBJECT *object; + int i; + + check_store(s,STORE_F_STORE_CERTIFICATE, + store_object,STORE_R_NO_STORE_OBJECT_FUNCTION); + + object = STORE_OBJECT_new(); + if (!object) + { + STOREerr(STORE_F_STORE_STORE_CERTIFICATE, + ERR_R_MALLOC_FAILURE); + return 0; + } + + CRYPTO_add(&data->references,1,CRYPTO_LOCK_X509); +#ifdef REF_PRINT + REF_PRINT("X509",data); +#endif + object->data.x509.certificate = data; + + i = s->meth->store_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE, + object, attributes, parameters); + + STORE_OBJECT_free(object); + + if (!i) + { + STOREerr(STORE_F_STORE_STORE_CERTIFICATE, + STORE_R_FAILED_STORING_CERTIFICATE); + return 0; + } + return 1; + } + +int STORE_modify_certificate(STORE *s, OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]) + { + check_store(s,STORE_F_STORE_MODIFY_CERTIFICATE, + modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION); + + if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE, + search_attributes, add_attributes, modify_attributes, + delete_attributes, parameters)) + { + STOREerr(STORE_F_STORE_MODIFY_CERTIFICATE, + STORE_R_FAILED_MODIFYING_CERTIFICATE); + return 0; + } + return 1; + } + +int STORE_revoke_certificate(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + check_store(s,STORE_F_STORE_REVOKE_CERTIFICATE, + revoke_object,STORE_R_NO_REVOKE_OBJECT_FUNCTION); + + if (!s->meth->revoke_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE, + attributes, parameters)) + { + STOREerr(STORE_F_STORE_REVOKE_CERTIFICATE, + STORE_R_FAILED_REVOKING_CERTIFICATE); + return 0; + } + return 1; + } + +int STORE_delete_certificate(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + check_store(s,STORE_F_STORE_DELETE_CERTIFICATE, + delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION); + + if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE, + attributes, parameters)) + { + STOREerr(STORE_F_STORE_DELETE_CERTIFICATE, + STORE_R_FAILED_DELETING_CERTIFICATE); + return 0; + } + return 1; + } + +void *STORE_list_certificate_start(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + void *handle; + + check_store(s,STORE_F_STORE_LIST_CERTIFICATE_START, + list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION); + + handle = s->meth->list_object_start(s, + STORE_OBJECT_TYPE_X509_CERTIFICATE, attributes, parameters); + if (!handle) + { + STOREerr(STORE_F_STORE_LIST_CERTIFICATE_START, + STORE_R_FAILED_LISTING_CERTIFICATES); + return 0; + } + return handle; + } + +X509 *STORE_list_certificate_next(STORE *s, void *handle) + { + STORE_OBJECT *object; + X509 *x; + + check_store(s,STORE_F_STORE_LIST_CERTIFICATE_NEXT, + list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION); + + object = s->meth->list_object_next(s, handle); + if (!object || !object->data.x509.certificate) + { + STOREerr(STORE_F_STORE_LIST_CERTIFICATE_NEXT, + STORE_R_FAILED_LISTING_CERTIFICATES); + return 0; + } + CRYPTO_add(&object->data.x509.certificate->references,1,CRYPTO_LOCK_X509); +#ifdef REF_PRINT + REF_PRINT("X509",data); +#endif + x = object->data.x509.certificate; + STORE_OBJECT_free(object); + return x; + } + +int STORE_list_certificate_end(STORE *s, void *handle) + { + check_store(s,STORE_F_STORE_LIST_CERTIFICATE_END, + list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION); + + if (!s->meth->list_object_end(s, handle)) + { + STOREerr(STORE_F_STORE_LIST_CERTIFICATE_END, + STORE_R_FAILED_LISTING_CERTIFICATES); + return 0; + } + return 1; + } + +int STORE_list_certificate_endp(STORE *s, void *handle) + { + check_store(s,STORE_F_STORE_LIST_CERTIFICATE_ENDP, + list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION); + + if (!s->meth->list_object_endp(s, handle)) + { + STOREerr(STORE_F_STORE_LIST_CERTIFICATE_ENDP, + STORE_R_FAILED_LISTING_CERTIFICATES); + return 0; + } + return 1; + } + +EVP_PKEY *STORE_generate_key(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + STORE_OBJECT *object; + EVP_PKEY *pkey; + + check_store(s,STORE_F_STORE_GENERATE_KEY, + generate_object,STORE_R_NO_GENERATE_OBJECT_FUNCTION); + + object = s->meth->generate_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, + attributes, parameters); + if (!object || !object->data.key) + { + STOREerr(STORE_F_STORE_GENERATE_KEY, + STORE_R_FAILED_GENERATING_KEY); + return 0; + } + CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY); +#ifdef REF_PRINT + REF_PRINT("EVP_PKEY",data); +#endif + pkey = object->data.key; + STORE_OBJECT_free(object); + return pkey; + } + +EVP_PKEY *STORE_get_private_key(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + STORE_OBJECT *object; + EVP_PKEY *pkey; + + check_store(s,STORE_F_STORE_GET_PRIVATE_KEY, + get_object,STORE_R_NO_GET_OBJECT_FUNCTION); + + object = s->meth->get_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, + attributes, parameters); + if (!object || !object->data.key || !object->data.key) + { + STOREerr(STORE_F_STORE_GET_PRIVATE_KEY, + STORE_R_FAILED_GETTING_KEY); + return 0; + } + CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY); +#ifdef REF_PRINT + REF_PRINT("EVP_PKEY",data); +#endif + pkey = object->data.key; + STORE_OBJECT_free(object); + return pkey; + } + +int STORE_store_private_key(STORE *s, EVP_PKEY *data, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + STORE_OBJECT *object; + int i; + + check_store(s,STORE_F_STORE_STORE_PRIVATE_KEY, + store_object,STORE_R_NO_STORE_OBJECT_FUNCTION); + + object = STORE_OBJECT_new(); + if (!object) + { + STOREerr(STORE_F_STORE_STORE_PRIVATE_KEY, + ERR_R_MALLOC_FAILURE); + return 0; + } + object->data.key = EVP_PKEY_new(); + if (!object->data.key) + { + STOREerr(STORE_F_STORE_STORE_PRIVATE_KEY, + ERR_R_MALLOC_FAILURE); + return 0; + } + + CRYPTO_add(&data->references,1,CRYPTO_LOCK_EVP_PKEY); +#ifdef REF_PRINT + REF_PRINT("EVP_PKEY",data); +#endif + object->data.key = data; + + i = s->meth->store_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, object, + attributes, parameters); + + STORE_OBJECT_free(object); + + if (!i) + { + STOREerr(STORE_F_STORE_STORE_PRIVATE_KEY, + STORE_R_FAILED_STORING_KEY); + return 0; + } + return i; + } + +int STORE_modify_private_key(STORE *s, OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]) + { + check_store(s,STORE_F_STORE_MODIFY_PRIVATE_KEY, + modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION); + + if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, + search_attributes, add_attributes, modify_attributes, + delete_attributes, parameters)) + { + STOREerr(STORE_F_STORE_MODIFY_PRIVATE_KEY, + STORE_R_FAILED_MODIFYING_PRIVATE_KEY); + return 0; + } + return 1; + } + +int STORE_revoke_private_key(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + int i; + + check_store(s,STORE_F_STORE_REVOKE_PRIVATE_KEY, + revoke_object,STORE_R_NO_REVOKE_OBJECT_FUNCTION); + + i = s->meth->revoke_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, + attributes, parameters); + + if (!i) + { + STOREerr(STORE_F_STORE_REVOKE_PRIVATE_KEY, + STORE_R_FAILED_REVOKING_KEY); + return 0; + } + return i; + } + +int STORE_delete_private_key(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + check_store(s,STORE_F_STORE_DELETE_PRIVATE_KEY, + delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION); + + if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, + attributes, parameters)) + { + STOREerr(STORE_F_STORE_DELETE_PRIVATE_KEY, + STORE_R_FAILED_DELETING_KEY); + return 0; + } + return 1; + } + +void *STORE_list_private_key_start(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + void *handle; + + check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_START, + list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION); + + handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_PRIVATE_KEY, + attributes, parameters); + if (!handle) + { + STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_START, + STORE_R_FAILED_LISTING_KEYS); + return 0; + } + return handle; + } + +EVP_PKEY *STORE_list_private_key_next(STORE *s, void *handle) + { + STORE_OBJECT *object; + EVP_PKEY *pkey; + + check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_NEXT, + list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION); + + object = s->meth->list_object_next(s, handle); + if (!object || !object->data.key || !object->data.key) + { + STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_NEXT, + STORE_R_FAILED_LISTING_KEYS); + return 0; + } + CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY); +#ifdef REF_PRINT + REF_PRINT("EVP_PKEY",data); +#endif + pkey = object->data.key; + STORE_OBJECT_free(object); + return pkey; + } + +int STORE_list_private_key_end(STORE *s, void *handle) + { + check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_END, + list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION); + + if (!s->meth->list_object_end(s, handle)) + { + STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_END, + STORE_R_FAILED_LISTING_KEYS); + return 0; + } + return 1; + } + +int STORE_list_private_key_endp(STORE *s, void *handle) + { + check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_ENDP, + list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION); + + if (!s->meth->list_object_endp(s, handle)) + { + STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_ENDP, + STORE_R_FAILED_LISTING_KEYS); + return 0; + } + return 1; + } + +EVP_PKEY *STORE_get_public_key(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + STORE_OBJECT *object; + EVP_PKEY *pkey; + + check_store(s,STORE_F_STORE_GET_PUBLIC_KEY, + get_object,STORE_R_NO_GET_OBJECT_FUNCTION); + + object = s->meth->get_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, + attributes, parameters); + if (!object || !object->data.key || !object->data.key) + { + STOREerr(STORE_F_STORE_GET_PUBLIC_KEY, + STORE_R_FAILED_GETTING_KEY); + return 0; + } + CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY); +#ifdef REF_PRINT + REF_PRINT("EVP_PKEY",data); +#endif + pkey = object->data.key; + STORE_OBJECT_free(object); + return pkey; + } + +int STORE_store_public_key(STORE *s, EVP_PKEY *data, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + STORE_OBJECT *object; + int i; + + check_store(s,STORE_F_STORE_STORE_PUBLIC_KEY, + store_object,STORE_R_NO_STORE_OBJECT_FUNCTION); + + object = STORE_OBJECT_new(); + if (!object) + { + STOREerr(STORE_F_STORE_STORE_PUBLIC_KEY, + ERR_R_MALLOC_FAILURE); + return 0; + } + object->data.key = EVP_PKEY_new(); + if (!object->data.key) + { + STOREerr(STORE_F_STORE_STORE_PUBLIC_KEY, + ERR_R_MALLOC_FAILURE); + return 0; + } + + CRYPTO_add(&data->references,1,CRYPTO_LOCK_EVP_PKEY); +#ifdef REF_PRINT + REF_PRINT("EVP_PKEY",data); +#endif + object->data.key = data; + + i = s->meth->store_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, object, + attributes, parameters); + + STORE_OBJECT_free(object); + + if (!i) + { + STOREerr(STORE_F_STORE_STORE_PUBLIC_KEY, + STORE_R_FAILED_STORING_KEY); + return 0; + } + return i; + } + +int STORE_modify_public_key(STORE *s, OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]) + { + check_store(s,STORE_F_STORE_MODIFY_PUBLIC_KEY, + modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION); + + if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, + search_attributes, add_attributes, modify_attributes, + delete_attributes, parameters)) + { + STOREerr(STORE_F_STORE_MODIFY_PUBLIC_KEY, + STORE_R_FAILED_MODIFYING_PUBLIC_KEY); + return 0; + } + return 1; + } + +int STORE_revoke_public_key(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + int i; + + check_store(s,STORE_F_STORE_REVOKE_PUBLIC_KEY, + revoke_object,STORE_R_NO_REVOKE_OBJECT_FUNCTION); + + i = s->meth->revoke_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, + attributes, parameters); + + if (!i) + { + STOREerr(STORE_F_STORE_REVOKE_PUBLIC_KEY, + STORE_R_FAILED_REVOKING_KEY); + return 0; + } + return i; + } + +int STORE_delete_public_key(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + check_store(s,STORE_F_STORE_DELETE_PUBLIC_KEY, + delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION); + + if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, + attributes, parameters)) + { + STOREerr(STORE_F_STORE_DELETE_PUBLIC_KEY, + STORE_R_FAILED_DELETING_KEY); + return 0; + } + return 1; + } + +void *STORE_list_public_key_start(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + void *handle; + + check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_START, + list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION); + + handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_PUBLIC_KEY, + attributes, parameters); + if (!handle) + { + STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_START, + STORE_R_FAILED_LISTING_KEYS); + return 0; + } + return handle; + } + +EVP_PKEY *STORE_list_public_key_next(STORE *s, void *handle) + { + STORE_OBJECT *object; + EVP_PKEY *pkey; + + check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_NEXT, + list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION); + + object = s->meth->list_object_next(s, handle); + if (!object || !object->data.key || !object->data.key) + { + STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_NEXT, + STORE_R_FAILED_LISTING_KEYS); + return 0; + } + CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY); +#ifdef REF_PRINT + REF_PRINT("EVP_PKEY",data); +#endif + pkey = object->data.key; + STORE_OBJECT_free(object); + return pkey; + } + +int STORE_list_public_key_end(STORE *s, void *handle) + { + check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_END, + list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION); + + if (!s->meth->list_object_end(s, handle)) + { + STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_END, + STORE_R_FAILED_LISTING_KEYS); + return 0; + } + return 1; + } + +int STORE_list_public_key_endp(STORE *s, void *handle) + { + check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_ENDP, + list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION); + + if (!s->meth->list_object_endp(s, handle)) + { + STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_ENDP, + STORE_R_FAILED_LISTING_KEYS); + return 0; + } + return 1; + } + +X509_CRL *STORE_generate_crl(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + STORE_OBJECT *object; + X509_CRL *crl; + + check_store(s,STORE_F_STORE_GENERATE_CRL, + generate_object,STORE_R_NO_GENERATE_CRL_FUNCTION); + + object = s->meth->generate_object(s, STORE_OBJECT_TYPE_X509_CRL, + attributes, parameters); + if (!object || !object->data.crl) + { + STOREerr(STORE_F_STORE_GENERATE_CRL, + STORE_R_FAILED_GENERATING_CRL); + return 0; + } + CRYPTO_add(&object->data.crl->references,1,CRYPTO_LOCK_X509_CRL); +#ifdef REF_PRINT + REF_PRINT("X509_CRL",data); +#endif + crl = object->data.crl; + STORE_OBJECT_free(object); + return crl; + } + +X509_CRL *STORE_get_crl(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + STORE_OBJECT *object; + X509_CRL *crl; + + check_store(s,STORE_F_STORE_GET_CRL, + get_object,STORE_R_NO_GET_OBJECT_FUNCTION); + + object = s->meth->get_object(s, STORE_OBJECT_TYPE_X509_CRL, + attributes, parameters); + if (!object || !object->data.crl) + { + STOREerr(STORE_F_STORE_GET_CRL, + STORE_R_FAILED_GETTING_KEY); + return 0; + } + CRYPTO_add(&object->data.crl->references,1,CRYPTO_LOCK_X509_CRL); +#ifdef REF_PRINT + REF_PRINT("X509_CRL",data); +#endif + crl = object->data.crl; + STORE_OBJECT_free(object); + return crl; + } + +int STORE_store_crl(STORE *s, X509_CRL *data, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + STORE_OBJECT *object; + int i; + + check_store(s,STORE_F_STORE_STORE_CRL, + store_object,STORE_R_NO_STORE_OBJECT_FUNCTION); + + object = STORE_OBJECT_new(); + if (!object) + { + STOREerr(STORE_F_STORE_STORE_CRL, + ERR_R_MALLOC_FAILURE); + return 0; + } + + CRYPTO_add(&data->references,1,CRYPTO_LOCK_X509_CRL); +#ifdef REF_PRINT + REF_PRINT("X509_CRL",data); +#endif + object->data.crl = data; + + i = s->meth->store_object(s, STORE_OBJECT_TYPE_X509_CRL, object, + attributes, parameters); + + STORE_OBJECT_free(object); + + if (!i) + { + STOREerr(STORE_F_STORE_STORE_CRL, + STORE_R_FAILED_STORING_KEY); + return 0; + } + return i; + } + +int STORE_modify_crl(STORE *s, OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]) + { + check_store(s,STORE_F_STORE_MODIFY_CRL, + modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION); + + if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_X509_CRL, + search_attributes, add_attributes, modify_attributes, + delete_attributes, parameters)) + { + STOREerr(STORE_F_STORE_MODIFY_CRL, + STORE_R_FAILED_MODIFYING_CRL); + return 0; + } + return 1; + } + +int STORE_delete_crl(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + check_store(s,STORE_F_STORE_DELETE_CRL, + delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION); + + if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_X509_CRL, + attributes, parameters)) + { + STOREerr(STORE_F_STORE_DELETE_CRL, + STORE_R_FAILED_DELETING_KEY); + return 0; + } + return 1; + } + +void *STORE_list_crl_start(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + void *handle; + + check_store(s,STORE_F_STORE_LIST_CRL_START, + list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION); + + handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_X509_CRL, + attributes, parameters); + if (!handle) + { + STOREerr(STORE_F_STORE_LIST_CRL_START, + STORE_R_FAILED_LISTING_KEYS); + return 0; + } + return handle; + } + +X509_CRL *STORE_list_crl_next(STORE *s, void *handle) + { + STORE_OBJECT *object; + X509_CRL *crl; + + check_store(s,STORE_F_STORE_LIST_CRL_NEXT, + list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION); + + object = s->meth->list_object_next(s, handle); + if (!object || !object->data.crl) + { + STOREerr(STORE_F_STORE_LIST_CRL_NEXT, + STORE_R_FAILED_LISTING_KEYS); + return 0; + } + CRYPTO_add(&object->data.crl->references,1,CRYPTO_LOCK_X509_CRL); +#ifdef REF_PRINT + REF_PRINT("X509_CRL",data); +#endif + crl = object->data.crl; + STORE_OBJECT_free(object); + return crl; + } + +int STORE_list_crl_end(STORE *s, void *handle) + { + check_store(s,STORE_F_STORE_LIST_CRL_END, + list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION); + + if (!s->meth->list_object_end(s, handle)) + { + STOREerr(STORE_F_STORE_LIST_CRL_END, + STORE_R_FAILED_LISTING_KEYS); + return 0; + } + return 1; + } + +int STORE_list_crl_endp(STORE *s, void *handle) + { + check_store(s,STORE_F_STORE_LIST_CRL_ENDP, + list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION); + + if (!s->meth->list_object_endp(s, handle)) + { + STOREerr(STORE_F_STORE_LIST_CRL_ENDP, + STORE_R_FAILED_LISTING_KEYS); + return 0; + } + return 1; + } + +int STORE_store_number(STORE *s, BIGNUM *data, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + STORE_OBJECT *object; + int i; + + check_store(s,STORE_F_STORE_STORE_NUMBER, + store_object,STORE_R_NO_STORE_OBJECT_NUMBER_FUNCTION); + + object = STORE_OBJECT_new(); + if (!object) + { + STOREerr(STORE_F_STORE_STORE_NUMBER, + ERR_R_MALLOC_FAILURE); + return 0; + } + + object->data.number = data; + + i = s->meth->store_object(s, STORE_OBJECT_TYPE_NUMBER, object, + attributes, parameters); + + STORE_OBJECT_free(object); + + if (!i) + { + STOREerr(STORE_F_STORE_STORE_NUMBER, + STORE_R_FAILED_STORING_NUMBER); + return 0; + } + return 1; + } + +int STORE_modify_number(STORE *s, OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]) + { + check_store(s,STORE_F_STORE_MODIFY_NUMBER, + modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION); + + if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_NUMBER, + search_attributes, add_attributes, modify_attributes, + delete_attributes, parameters)) + { + STOREerr(STORE_F_STORE_MODIFY_NUMBER, + STORE_R_FAILED_MODIFYING_NUMBER); + return 0; + } + return 1; + } + +BIGNUM *STORE_get_number(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + STORE_OBJECT *object; + BIGNUM *n; + + check_store(s,STORE_F_STORE_GET_NUMBER, + get_object,STORE_R_NO_GET_OBJECT_NUMBER_FUNCTION); + + object = s->meth->get_object(s, STORE_OBJECT_TYPE_NUMBER, attributes, + parameters); + if (!object || !object->data.number) + { + STOREerr(STORE_F_STORE_GET_NUMBER, + STORE_R_FAILED_GETTING_NUMBER); + return 0; + } + n = object->data.number; + object->data.number = NULL; + STORE_OBJECT_free(object); + return n; + } + +int STORE_delete_number(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + check_store(s,STORE_F_STORE_DELETE_NUMBER, + delete_object,STORE_R_NO_DELETE_NUMBER_FUNCTION); + + if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_NUMBER, attributes, + parameters)) + { + STOREerr(STORE_F_STORE_DELETE_NUMBER, + STORE_R_FAILED_DELETING_NUMBER); + return 0; + } + return 1; + } + +int STORE_store_arbitrary(STORE *s, BUF_MEM *data, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + STORE_OBJECT *object; + int i; + + check_store(s,STORE_F_STORE_STORE_ARBITRARY, + store_object,STORE_R_NO_STORE_OBJECT_ARBITRARY_FUNCTION); + + object = STORE_OBJECT_new(); + if (!object) + { + STOREerr(STORE_F_STORE_STORE_ARBITRARY, + ERR_R_MALLOC_FAILURE); + return 0; + } + + object->data.arbitrary = data; + + i = s->meth->store_object(s, STORE_OBJECT_TYPE_ARBITRARY, object, + attributes, parameters); + + STORE_OBJECT_free(object); + + if (!i) + { + STOREerr(STORE_F_STORE_STORE_ARBITRARY, + STORE_R_FAILED_STORING_ARBITRARY); + return 0; + } + return 1; + } + +int STORE_modify_arbitrary(STORE *s, OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]) + { + check_store(s,STORE_F_STORE_MODIFY_ARBITRARY, + modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION); + + if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_ARBITRARY, + search_attributes, add_attributes, modify_attributes, + delete_attributes, parameters)) + { + STOREerr(STORE_F_STORE_MODIFY_ARBITRARY, + STORE_R_FAILED_MODIFYING_ARBITRARY); + return 0; + } + return 1; + } + +BUF_MEM *STORE_get_arbitrary(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + STORE_OBJECT *object; + BUF_MEM *b; + + check_store(s,STORE_F_STORE_GET_ARBITRARY, + get_object,STORE_R_NO_GET_OBJECT_ARBITRARY_FUNCTION); + + object = s->meth->get_object(s, STORE_OBJECT_TYPE_ARBITRARY, + attributes, parameters); + if (!object || !object->data.arbitrary) + { + STOREerr(STORE_F_STORE_GET_ARBITRARY, + STORE_R_FAILED_GETTING_ARBITRARY); + return 0; + } + b = object->data.arbitrary; + object->data.arbitrary = NULL; + STORE_OBJECT_free(object); + return b; + } + +int STORE_delete_arbitrary(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) + { + check_store(s,STORE_F_STORE_DELETE_ARBITRARY, + delete_object,STORE_R_NO_DELETE_ARBITRARY_FUNCTION); + + if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_ARBITRARY, attributes, + parameters)) + { + STOREerr(STORE_F_STORE_DELETE_ARBITRARY, + STORE_R_FAILED_DELETING_ARBITRARY); + return 0; + } + return 1; + } + +STORE_OBJECT *STORE_OBJECT_new(void) + { + STORE_OBJECT *object = OPENSSL_malloc(sizeof(STORE_OBJECT)); + if (object) memset(object, 0, sizeof(STORE_OBJECT)); + return object; + } +void STORE_OBJECT_free(STORE_OBJECT *data) + { + if (!data) return; + switch (data->type) + { + case STORE_OBJECT_TYPE_X509_CERTIFICATE: + X509_free(data->data.x509.certificate); + break; + case STORE_OBJECT_TYPE_X509_CRL: + X509_CRL_free(data->data.crl); + break; + case STORE_OBJECT_TYPE_PRIVATE_KEY: + case STORE_OBJECT_TYPE_PUBLIC_KEY: + EVP_PKEY_free(data->data.key); + break; + case STORE_OBJECT_TYPE_NUMBER: + BN_free(data->data.number); + break; + case STORE_OBJECT_TYPE_ARBITRARY: + BUF_MEM_free(data->data.arbitrary); + break; + } + OPENSSL_free(data); + } + +IMPLEMENT_STACK_OF(STORE_OBJECT*) + + +struct STORE_attr_info_st + { + unsigned char set[(STORE_ATTR_TYPE_NUM + 8) / 8]; + union + { + char *cstring; + unsigned char *sha1string; + X509_NAME *dn; + BIGNUM *number; + void *any; + } values[STORE_ATTR_TYPE_NUM+1]; + size_t value_sizes[STORE_ATTR_TYPE_NUM+1]; + }; + +#define ATTR_IS_SET(a,i) ((i) > 0 && (i) < STORE_ATTR_TYPE_NUM \ + && ((a)->set[(i) / 8] & (1 << ((i) % 8)))) +#define SET_ATTRBIT(a,i) ((a)->set[(i) / 8] |= (1 << ((i) % 8))) +#define CLEAR_ATTRBIT(a,i) ((a)->set[(i) / 8] &= ~(1 << ((i) % 8))) + +STORE_ATTR_INFO *STORE_ATTR_INFO_new(void) + { + return (STORE_ATTR_INFO *)OPENSSL_malloc(sizeof(STORE_ATTR_INFO)); + } +static void STORE_ATTR_INFO_attr_free(STORE_ATTR_INFO *attrs, + STORE_ATTR_TYPES code) + { + if (ATTR_IS_SET(attrs,code)) + { + switch(code) + { + case STORE_ATTR_FRIENDLYNAME: + case STORE_ATTR_EMAIL: + case STORE_ATTR_FILENAME: + STORE_ATTR_INFO_modify_cstr(attrs, code, NULL, 0); + break; + case STORE_ATTR_KEYID: + case STORE_ATTR_ISSUERKEYID: + case STORE_ATTR_SUBJECTKEYID: + case STORE_ATTR_ISSUERSERIALHASH: + case STORE_ATTR_CERTHASH: + STORE_ATTR_INFO_modify_sha1str(attrs, code, NULL, 0); + break; + case STORE_ATTR_ISSUER: + case STORE_ATTR_SUBJECT: + STORE_ATTR_INFO_modify_dn(attrs, code, NULL); + break; + case STORE_ATTR_SERIAL: + STORE_ATTR_INFO_modify_number(attrs, code, NULL); + break; + default: + break; + } + } + } +int STORE_ATTR_INFO_free(STORE_ATTR_INFO *attrs) + { + if (attrs) + { + STORE_ATTR_TYPES i; + for(i = 0; i++ < STORE_ATTR_TYPE_NUM;) + STORE_ATTR_INFO_attr_free(attrs, i); + OPENSSL_free(attrs); + } + return 1; + } +char *STORE_ATTR_INFO_get0_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code) + { + if (!attrs) + { + STOREerr(STORE_F_STORE_ATTR_INFO_GET0_CSTR, + ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (ATTR_IS_SET(attrs,code)) + return attrs->values[code].cstring; + STOREerr(STORE_F_STORE_ATTR_INFO_GET0_CSTR, + STORE_R_NO_VALUE); + return NULL; + } +unsigned char *STORE_ATTR_INFO_get0_sha1str(STORE_ATTR_INFO *attrs, + STORE_ATTR_TYPES code) + { + if (!attrs) + { + STOREerr(STORE_F_STORE_ATTR_INFO_GET0_SHA1STR, + ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (ATTR_IS_SET(attrs,code)) + return attrs->values[code].sha1string; + STOREerr(STORE_F_STORE_ATTR_INFO_GET0_SHA1STR, + STORE_R_NO_VALUE); + return NULL; + } +X509_NAME *STORE_ATTR_INFO_get0_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code) + { + if (!attrs) + { + STOREerr(STORE_F_STORE_ATTR_INFO_GET0_DN, + ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (ATTR_IS_SET(attrs,code)) + return attrs->values[code].dn; + STOREerr(STORE_F_STORE_ATTR_INFO_GET0_DN, + STORE_R_NO_VALUE); + return NULL; + } +BIGNUM *STORE_ATTR_INFO_get0_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code) + { + if (!attrs) + { + STOREerr(STORE_F_STORE_ATTR_INFO_GET0_NUMBER, + ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (ATTR_IS_SET(attrs,code)) + return attrs->values[code].number; + STOREerr(STORE_F_STORE_ATTR_INFO_GET0_NUMBER, + STORE_R_NO_VALUE); + return NULL; + } +int STORE_ATTR_INFO_set_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, + char *cstr, size_t cstr_size) + { + if (!attrs) + { + STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (!ATTR_IS_SET(attrs,code)) + { + if ((attrs->values[code].cstring = BUF_strndup(cstr, cstr_size))) + return 1; + STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR, + ERR_R_MALLOC_FAILURE); + return 0; + } + STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR, STORE_R_ALREADY_HAS_A_VALUE); + return 0; + } +int STORE_ATTR_INFO_set_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, + unsigned char *sha1str, size_t sha1str_size) + { + if (!attrs) + { + STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (!ATTR_IS_SET(attrs,code)) + { + if ((attrs->values[code].sha1string = + (unsigned char *)BUF_memdup(sha1str, + sha1str_size))) + return 1; + STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR, + ERR_R_MALLOC_FAILURE); + return 0; + } + STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR, STORE_R_ALREADY_HAS_A_VALUE); + return 0; + } +int STORE_ATTR_INFO_set_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, + X509_NAME *dn) + { + if (!attrs) + { + STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (!ATTR_IS_SET(attrs,code)) + { + if ((attrs->values[code].dn = X509_NAME_dup(dn))) + return 1; + STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN, + ERR_R_MALLOC_FAILURE); + return 0; + } + STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN, STORE_R_ALREADY_HAS_A_VALUE); + return 0; + } +int STORE_ATTR_INFO_set_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, + BIGNUM *number) + { + if (!attrs) + { + STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (!ATTR_IS_SET(attrs,code)) + { + if ((attrs->values[code].number = BN_dup(number))) + return 1; + STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER, + ERR_R_MALLOC_FAILURE); + return 0; + } + STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER, STORE_R_ALREADY_HAS_A_VALUE); + return 0; + } +int STORE_ATTR_INFO_modify_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, + char *cstr, size_t cstr_size) + { + if (!attrs) + { + STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_CSTR, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (ATTR_IS_SET(attrs,code)) + { + OPENSSL_free(attrs->values[code].cstring); + attrs->values[code].cstring = NULL; + CLEAR_ATTRBIT(attrs, code); + } + return STORE_ATTR_INFO_set_cstr(attrs, code, cstr, cstr_size); + } +int STORE_ATTR_INFO_modify_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, + unsigned char *sha1str, size_t sha1str_size) + { + if (!attrs) + { + STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_SHA1STR, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (ATTR_IS_SET(attrs,code)) + { + OPENSSL_free(attrs->values[code].sha1string); + attrs->values[code].sha1string = NULL; + CLEAR_ATTRBIT(attrs, code); + } + return STORE_ATTR_INFO_set_sha1str(attrs, code, sha1str, sha1str_size); + } +int STORE_ATTR_INFO_modify_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, + X509_NAME *dn) + { + if (!attrs) + { + STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_DN, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (ATTR_IS_SET(attrs,code)) + { + OPENSSL_free(attrs->values[code].dn); + attrs->values[code].dn = NULL; + CLEAR_ATTRBIT(attrs, code); + } + return STORE_ATTR_INFO_set_dn(attrs, code, dn); + } +int STORE_ATTR_INFO_modify_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, + BIGNUM *number) + { + if (!attrs) + { + STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_NUMBER, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (ATTR_IS_SET(attrs,code)) + { + OPENSSL_free(attrs->values[code].number); + attrs->values[code].number = NULL; + CLEAR_ATTRBIT(attrs, code); + } + return STORE_ATTR_INFO_set_number(attrs, code, number); + } + +struct attr_list_ctx_st + { + OPENSSL_ITEM *attributes; + }; +void *STORE_parse_attrs_start(OPENSSL_ITEM *attributes) + { + if (attributes) + { + struct attr_list_ctx_st *context = + (struct attr_list_ctx_st *)OPENSSL_malloc(sizeof(struct attr_list_ctx_st)); + if (context) + context->attributes = attributes; + else + STOREerr(STORE_F_STORE_PARSE_ATTRS_START, + ERR_R_MALLOC_FAILURE); + return context; + } + STOREerr(STORE_F_STORE_PARSE_ATTRS_START, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } +STORE_ATTR_INFO *STORE_parse_attrs_next(void *handle) + { + struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle; + + if (context && context->attributes) + { + STORE_ATTR_INFO *attrs = NULL; + + while(context->attributes + && context->attributes->code != STORE_ATTR_OR + && context->attributes->code != STORE_ATTR_END) + { + switch(context->attributes->code) + { + case STORE_ATTR_FRIENDLYNAME: + case STORE_ATTR_EMAIL: + case STORE_ATTR_FILENAME: + if (!attrs) attrs = STORE_ATTR_INFO_new(); + if (attrs == NULL) + { + STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT, + ERR_R_MALLOC_FAILURE); + goto err; + } + STORE_ATTR_INFO_set_cstr(attrs, + context->attributes->code, + context->attributes->value, + context->attributes->value_size); + break; + case STORE_ATTR_KEYID: + case STORE_ATTR_ISSUERKEYID: + case STORE_ATTR_SUBJECTKEYID: + case STORE_ATTR_ISSUERSERIALHASH: + case STORE_ATTR_CERTHASH: + if (!attrs) attrs = STORE_ATTR_INFO_new(); + if (attrs == NULL) + { + STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT, + ERR_R_MALLOC_FAILURE); + goto err; + } + STORE_ATTR_INFO_set_sha1str(attrs, + context->attributes->code, + context->attributes->value, + context->attributes->value_size); + break; + case STORE_ATTR_ISSUER: + case STORE_ATTR_SUBJECT: + if (!attrs) attrs = STORE_ATTR_INFO_new(); + if (attrs == NULL) + { + STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT, + ERR_R_MALLOC_FAILURE); + goto err; + } + STORE_ATTR_INFO_modify_dn(attrs, + context->attributes->code, + context->attributes->value); + break; + case STORE_ATTR_SERIAL: + if (!attrs) attrs = STORE_ATTR_INFO_new(); + if (attrs == NULL) + { + STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT, + ERR_R_MALLOC_FAILURE); + goto err; + } + STORE_ATTR_INFO_modify_number(attrs, + context->attributes->code, + context->attributes->value); + break; + } + context->attributes++; + } + if (context->attributes->code == STORE_ATTR_OR) + context->attributes++; + return attrs; + err: + while(context->attributes + && context->attributes->code != STORE_ATTR_OR + && context->attributes->code != STORE_ATTR_END) + context->attributes++; + if (context->attributes->code == STORE_ATTR_OR) + context->attributes++; + return NULL; + } + STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } +int STORE_parse_attrs_end(void *handle) + { + struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle; + + if (context && context->attributes) + { +#if 0 + OPENSSL_ITEM *attributes = context->attributes; +#endif + OPENSSL_free(context); + return 1; + } + STOREerr(STORE_F_STORE_PARSE_ATTRS_END, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + +int STORE_parse_attrs_endp(void *handle) + { + struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle; + + if (context && context->attributes) + { + return context->attributes->code == STORE_ATTR_END; + } + STOREerr(STORE_F_STORE_PARSE_ATTRS_ENDP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + +static int attr_info_compare_compute_range( + const unsigned char *abits, const unsigned char *bbits, + unsigned int *alowp, unsigned int *ahighp, + unsigned int *blowp, unsigned int *bhighp) + { + unsigned int alow = (unsigned int)-1, ahigh = 0; + unsigned int blow = (unsigned int)-1, bhigh = 0; + int i, res = 0; + + for (i = 0; i < (STORE_ATTR_TYPE_NUM + 8) / 8; i++, abits++, bbits++) + { + if (res == 0) + { + if (*abits < *bbits) res = -1; + if (*abits > *bbits) res = 1; + } + if (*abits) + { + if (alow == (unsigned int)-1) + { + alow = i * 8; + if (!(*abits & 0x01)) alow++; + if (!(*abits & 0x02)) alow++; + if (!(*abits & 0x04)) alow++; + if (!(*abits & 0x08)) alow++; + if (!(*abits & 0x10)) alow++; + if (!(*abits & 0x20)) alow++; + if (!(*abits & 0x40)) alow++; + } + ahigh = i * 8 + 7; + if (!(*abits & 0x80)) ahigh++; + if (!(*abits & 0x40)) ahigh++; + if (!(*abits & 0x20)) ahigh++; + if (!(*abits & 0x10)) ahigh++; + if (!(*abits & 0x08)) ahigh++; + if (!(*abits & 0x04)) ahigh++; + if (!(*abits & 0x02)) ahigh++; + } + if (*bbits) + { + if (blow == (unsigned int)-1) + { + blow = i * 8; + if (!(*bbits & 0x01)) blow++; + if (!(*bbits & 0x02)) blow++; + if (!(*bbits & 0x04)) blow++; + if (!(*bbits & 0x08)) blow++; + if (!(*bbits & 0x10)) blow++; + if (!(*bbits & 0x20)) blow++; + if (!(*bbits & 0x40)) blow++; + } + bhigh = i * 8 + 7; + if (!(*bbits & 0x80)) bhigh++; + if (!(*bbits & 0x40)) bhigh++; + if (!(*bbits & 0x20)) bhigh++; + if (!(*bbits & 0x10)) bhigh++; + if (!(*bbits & 0x08)) bhigh++; + if (!(*bbits & 0x04)) bhigh++; + if (!(*bbits & 0x02)) bhigh++; + } + } + if (ahigh + alow < bhigh + blow) res = -1; + if (ahigh + alow > bhigh + blow) res = 1; + if (alowp) *alowp = alow; + if (ahighp) *ahighp = ahigh; + if (blowp) *blowp = blow; + if (bhighp) *bhighp = bhigh; + return res; + } + +int STORE_ATTR_INFO_compare(const STORE_ATTR_INFO * const *a, + const STORE_ATTR_INFO * const *b) + { + if (a == b) return 0; + if (!a) return -1; + if (!b) return 1; + return attr_info_compare_compute_range((*a)->set, (*b)->set, 0, 0, 0, 0); + } + +int STORE_ATTR_INFO_in_range(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b) + { + unsigned int alow, ahigh, blow, bhigh; + + if (a == b) return 1; + if (!a) return 0; + if (!b) return 0; + attr_info_compare_compute_range(a->set, b->set, + &alow, &ahigh, &blow, &bhigh); + if (alow >= blow && ahigh <= bhigh) + return 1; + return 0; + } + +int STORE_ATTR_INFO_in(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b) + { + unsigned char *abits, *bbits; + int i; + + if (a == b) return 1; + if (!a) return 0; + if (!b) return 0; + abits = a->set; + bbits = b->set; + for (i = 0; i < (STORE_ATTR_TYPE_NUM + 8) / 8; i++, abits++, bbits++) + { + if (*abits && (*bbits & *abits) != *abits) + return 0; + } + return 1; + } + +int STORE_ATTR_INFO_in_ex(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b) + { + STORE_ATTR_TYPES i; + + if (a == b) return 1; + if (!STORE_ATTR_INFO_in(a, b)) return 0; + for (i = 1; i < STORE_ATTR_TYPE_NUM; i++) + if (ATTR_IS_SET(a, i)) + { + switch(i) + { + case STORE_ATTR_FRIENDLYNAME: + case STORE_ATTR_EMAIL: + case STORE_ATTR_FILENAME: + if (strcmp(a->values[i].cstring, + b->values[i].cstring)) + return 0; + break; + case STORE_ATTR_KEYID: + case STORE_ATTR_ISSUERKEYID: + case STORE_ATTR_SUBJECTKEYID: + case STORE_ATTR_ISSUERSERIALHASH: + case STORE_ATTR_CERTHASH: + if (memcmp(a->values[i].sha1string, + b->values[i].sha1string, + a->value_sizes[i])) + return 0; + break; + case STORE_ATTR_ISSUER: + case STORE_ATTR_SUBJECT: + if (X509_NAME_cmp(a->values[i].dn, + b->values[i].dn)) + return 0; + break; + case STORE_ATTR_SERIAL: + if (BN_cmp(a->values[i].number, + b->values[i].number)) + return 0; + break; + default: + break; + } + } + + return 1; + } |