| /* 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; |
| } |