/* 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 #include #include #ifndef OPENSSL_NO_ENGINE # include #endif #include #include #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 = OPENSSL_malloc(sizeof(*ret)); 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; } X509_up_ref(object->data.x509.certificate); #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; } X509_up_ref(data); #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; } X509_up_ref(object->data.x509.certificate); #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; } X509_CRL_up_ref(object->data.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; } X509_CRL_up_ref(object->data.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; } X509_CRL_up_ref(data); #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; } X509_CRL_up_ref(object->data.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_zalloc(sizeof(*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); } 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) { STORE_ATTR_INFO *p = OPENSSL_malloc(sizeof(*p)); return p; } 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 = OPENSSL_malloc(sizeof(*context)); 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; }