diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2016-10-12 23:06:17 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2016-10-15 11:50:41 +0200 |
commit | 422196759f93df249db38619f136cabd5dcf42cd (patch) | |
tree | 1e5846507af0f8f1bc7ca294ccfb0d4ac3392d17 /thirdparty/openssl/crypto/store/str_lib.c | |
parent | d9a291f6411f2e571c181da0ac89f550ba73f681 (diff) |
openssl: Move to a module and split thirdparty lib
Same rationale as the previous commits.
Diffstat (limited to 'thirdparty/openssl/crypto/store/str_lib.c')
-rw-r--r-- | thirdparty/openssl/crypto/store/str_lib.c | 1772 |
1 files changed, 1772 insertions, 0 deletions
diff --git a/thirdparty/openssl/crypto/store/str_lib.c b/thirdparty/openssl/crypto/store/str_lib.c new file mode 100644 index 0000000000..e3d5da9388 --- /dev/null +++ b/thirdparty/openssl/crypto/store/str_lib.c @@ -0,0 +1,1772 @@ +/* crypto/store/str_lib.c */ +/* + * 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; +} |