1/* crypto/store/str_lib.c -*- mode:C; c-file-style: "eay" -*- */
2/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
3 * project 2003.
4 */
5/* ====================================================================
6 * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in
17 *    the documentation and/or other materials provided with the
18 *    distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 *    software must display the following acknowledgment:
22 *    "This product includes software developed by the OpenSSL Project
23 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 *    endorse or promote products derived from this software without
27 *    prior written permission. For written permission, please contact
28 *    openssl-core@openssl.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 *    nor may "OpenSSL" appear in their names without prior written
32 *    permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 *    acknowledgment:
36 *    "This product includes software developed by the OpenSSL Project
37 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com).  This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <string.h>
60#include <openssl/bn.h>
61#include <openssl/err.h>
62#ifndef OPENSSL_NO_ENGINE
63#include <openssl/engine.h>
64#endif
65#include <openssl/sha.h>
66#include <openssl/x509.h>
67#include "str_locl.h"
68
69const char * const STORE_object_type_string[STORE_OBJECT_TYPE_NUM+1] =
70	{
71	0,
72	"X.509 Certificate",
73	"X.509 CRL",
74	"Private Key",
75	"Public Key",
76	"Number",
77	"Arbitrary Data"
78	};
79
80const int STORE_param_sizes[STORE_PARAM_TYPE_NUM+1] =
81	{
82	0,
83	sizeof(int),		/* EVP_TYPE */
84	sizeof(size_t),		/* BITS */
85	-1,			/* KEY_PARAMETERS */
86	0			/* KEY_NO_PARAMETERS */
87	};
88
89const int STORE_attr_sizes[STORE_ATTR_TYPE_NUM+1] =
90	{
91	0,
92	-1,			/* FRIENDLYNAME:	C string */
93	SHA_DIGEST_LENGTH,	/* KEYID:		SHA1 digest, 160 bits */
94	SHA_DIGEST_LENGTH,	/* ISSUERKEYID:		SHA1 digest, 160 bits */
95	SHA_DIGEST_LENGTH,	/* SUBJECTKEYID:	SHA1 digest, 160 bits */
96	SHA_DIGEST_LENGTH,	/* ISSUERSERIALHASH:	SHA1 digest, 160 bits */
97	sizeof(X509_NAME *),	/* ISSUER:		X509_NAME * */
98	sizeof(BIGNUM *),	/* SERIAL:		BIGNUM * */
99	sizeof(X509_NAME *),	/* SUBJECT:		X509_NAME * */
100	SHA_DIGEST_LENGTH,	/* CERTHASH:		SHA1 digest, 160 bits */
101	-1,			/* EMAIL:		C string */
102	-1,			/* FILENAME:		C string */
103	};
104
105STORE *STORE_new_method(const STORE_METHOD *method)
106	{
107	STORE *ret;
108
109	if (method == NULL)
110		{
111		STOREerr(STORE_F_STORE_NEW_METHOD,ERR_R_PASSED_NULL_PARAMETER);
112		return NULL;
113		}
114
115	ret=(STORE *)OPENSSL_malloc(sizeof(STORE));
116	if (ret == NULL)
117		{
118		STOREerr(STORE_F_STORE_NEW_METHOD,ERR_R_MALLOC_FAILURE);
119		return NULL;
120		}
121
122	ret->meth=method;
123
124	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_STORE, ret, &ret->ex_data);
125	if (ret->meth->init && !ret->meth->init(ret))
126		{
127		STORE_free(ret);
128		ret = NULL;
129		}
130	return ret;
131	}
132
133STORE *STORE_new_engine(ENGINE *engine)
134	{
135	STORE *ret = NULL;
136	ENGINE *e = engine;
137	const STORE_METHOD *meth = 0;
138
139#ifdef OPENSSL_NO_ENGINE
140	e = NULL;
141#else
142	if (engine)
143		{
144		if (!ENGINE_init(engine))
145			{
146			STOREerr(STORE_F_STORE_NEW_ENGINE, ERR_R_ENGINE_LIB);
147			return NULL;
148			}
149		e = engine;
150		}
151	else
152		{
153		STOREerr(STORE_F_STORE_NEW_ENGINE,ERR_R_PASSED_NULL_PARAMETER);
154		return NULL;
155		}
156	if(e)
157		{
158		meth = ENGINE_get_STORE(e);
159		if(!meth)
160			{
161			STOREerr(STORE_F_STORE_NEW_ENGINE,
162				ERR_R_ENGINE_LIB);
163			ENGINE_finish(e);
164			return NULL;
165			}
166		}
167#endif
168
169	ret = STORE_new_method(meth);
170	if (ret == NULL)
171		{
172		STOREerr(STORE_F_STORE_NEW_ENGINE,ERR_R_STORE_LIB);
173		return NULL;
174		}
175
176	ret->engine = e;
177
178	return(ret);
179	}
180
181void STORE_free(STORE *store)
182	{
183	if (store == NULL)
184		return;
185	if (store->meth->clean)
186		store->meth->clean(store);
187	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_STORE, store, &store->ex_data);
188	OPENSSL_free(store);
189	}
190
191int STORE_ctrl(STORE *store, int cmd, long i, void *p, void (*f)(void))
192	{
193	if (store == NULL)
194		{
195		STOREerr(STORE_F_STORE_CTRL,ERR_R_PASSED_NULL_PARAMETER);
196		return 0;
197		}
198	if (store->meth->ctrl)
199		return store->meth->ctrl(store, cmd, i, p, f);
200	STOREerr(STORE_F_STORE_CTRL,STORE_R_NO_CONTROL_FUNCTION);
201	return 0;
202	}
203
204
205int STORE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
206	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
207        {
208	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_STORE, argl, argp,
209				new_func, dup_func, free_func);
210        }
211
212int STORE_set_ex_data(STORE *r, int idx, void *arg)
213	{
214	return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
215	}
216
217void *STORE_get_ex_data(STORE *r, int idx)
218	{
219	return(CRYPTO_get_ex_data(&r->ex_data,idx));
220	}
221
222const STORE_METHOD *STORE_get_method(STORE *store)
223	{
224	return store->meth;
225	}
226
227const STORE_METHOD *STORE_set_method(STORE *store, const STORE_METHOD *meth)
228	{
229	store->meth=meth;
230	return store->meth;
231	}
232
233
234/* API helpers */
235
236#define check_store(s,fncode,fnname,fnerrcode) \
237	do \
238		{ \
239		if ((s) == NULL || (s)->meth == NULL) \
240			{ \
241			STOREerr((fncode), ERR_R_PASSED_NULL_PARAMETER); \
242			return 0; \
243			} \
244		if ((s)->meth->fnname == NULL) \
245			{ \
246			STOREerr((fncode), (fnerrcode)); \
247			return 0; \
248			} \
249		} \
250	while(0)
251
252/* API functions */
253
254X509 *STORE_get_certificate(STORE *s, OPENSSL_ITEM attributes[],
255	OPENSSL_ITEM parameters[])
256	{
257	STORE_OBJECT *object;
258	X509 *x;
259
260	check_store(s,STORE_F_STORE_GET_CERTIFICATE,
261		get_object,STORE_R_NO_GET_OBJECT_FUNCTION);
262
263	object = s->meth->get_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE,
264		attributes, parameters);
265	if (!object || !object->data.x509.certificate)
266		{
267		STOREerr(STORE_F_STORE_GET_CERTIFICATE,
268			STORE_R_FAILED_GETTING_CERTIFICATE);
269		return 0;
270		}
271	CRYPTO_add(&object->data.x509.certificate->references,1,CRYPTO_LOCK_X509);
272#ifdef REF_PRINT
273	REF_PRINT("X509",data);
274#endif
275	x = object->data.x509.certificate;
276	STORE_OBJECT_free(object);
277	return x;
278	}
279
280int STORE_store_certificate(STORE *s, X509 *data, OPENSSL_ITEM attributes[],
281	OPENSSL_ITEM parameters[])
282	{
283	STORE_OBJECT *object;
284	int i;
285
286	check_store(s,STORE_F_STORE_CERTIFICATE,
287		store_object,STORE_R_NO_STORE_OBJECT_FUNCTION);
288
289	object = STORE_OBJECT_new();
290	if (!object)
291		{
292		STOREerr(STORE_F_STORE_STORE_CERTIFICATE,
293			ERR_R_MALLOC_FAILURE);
294		return 0;
295		}
296
297	CRYPTO_add(&data->references,1,CRYPTO_LOCK_X509);
298#ifdef REF_PRINT
299	REF_PRINT("X509",data);
300#endif
301	object->data.x509.certificate = data;
302
303	i = s->meth->store_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE,
304		object, attributes, parameters);
305
306	STORE_OBJECT_free(object);
307
308	if (!i)
309		{
310		STOREerr(STORE_F_STORE_STORE_CERTIFICATE,
311			STORE_R_FAILED_STORING_CERTIFICATE);
312		return 0;
313		}
314	return 1;
315	}
316
317int STORE_modify_certificate(STORE *s, OPENSSL_ITEM search_attributes[],
318	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
319	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[])
320	{
321	check_store(s,STORE_F_STORE_MODIFY_CERTIFICATE,
322		modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION);
323
324	if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE,
325		    search_attributes, add_attributes, modify_attributes,
326		    delete_attributes, parameters))
327		{
328		STOREerr(STORE_F_STORE_MODIFY_CERTIFICATE,
329			STORE_R_FAILED_MODIFYING_CERTIFICATE);
330		return 0;
331		}
332	return 1;
333	}
334
335int STORE_revoke_certificate(STORE *s, OPENSSL_ITEM attributes[],
336	OPENSSL_ITEM parameters[])
337	{
338	check_store(s,STORE_F_STORE_REVOKE_CERTIFICATE,
339		revoke_object,STORE_R_NO_REVOKE_OBJECT_FUNCTION);
340
341	if (!s->meth->revoke_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE,
342		    attributes, parameters))
343		{
344		STOREerr(STORE_F_STORE_REVOKE_CERTIFICATE,
345			STORE_R_FAILED_REVOKING_CERTIFICATE);
346		return 0;
347		}
348	return 1;
349	}
350
351int STORE_delete_certificate(STORE *s, OPENSSL_ITEM attributes[],
352	OPENSSL_ITEM parameters[])
353	{
354	check_store(s,STORE_F_STORE_DELETE_CERTIFICATE,
355		delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION);
356
357	if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE,
358		    attributes, parameters))
359		{
360		STOREerr(STORE_F_STORE_DELETE_CERTIFICATE,
361			STORE_R_FAILED_DELETING_CERTIFICATE);
362		return 0;
363		}
364	return 1;
365	}
366
367void *STORE_list_certificate_start(STORE *s, OPENSSL_ITEM attributes[],
368	OPENSSL_ITEM parameters[])
369	{
370	void *handle;
371
372	check_store(s,STORE_F_STORE_LIST_CERTIFICATE_START,
373		list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION);
374
375	handle = s->meth->list_object_start(s,
376		STORE_OBJECT_TYPE_X509_CERTIFICATE, attributes, parameters);
377	if (!handle)
378		{
379		STOREerr(STORE_F_STORE_LIST_CERTIFICATE_START,
380			STORE_R_FAILED_LISTING_CERTIFICATES);
381		return 0;
382		}
383	return handle;
384	}
385
386X509 *STORE_list_certificate_next(STORE *s, void *handle)
387	{
388	STORE_OBJECT *object;
389	X509 *x;
390
391	check_store(s,STORE_F_STORE_LIST_CERTIFICATE_NEXT,
392		list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION);
393
394	object = s->meth->list_object_next(s, handle);
395	if (!object || !object->data.x509.certificate)
396		{
397		STOREerr(STORE_F_STORE_LIST_CERTIFICATE_NEXT,
398			STORE_R_FAILED_LISTING_CERTIFICATES);
399		return 0;
400		}
401	CRYPTO_add(&object->data.x509.certificate->references,1,CRYPTO_LOCK_X509);
402#ifdef REF_PRINT
403	REF_PRINT("X509",data);
404#endif
405	x = object->data.x509.certificate;
406	STORE_OBJECT_free(object);
407	return x;
408	}
409
410int STORE_list_certificate_end(STORE *s, void *handle)
411	{
412	check_store(s,STORE_F_STORE_LIST_CERTIFICATE_END,
413		list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION);
414
415	if (!s->meth->list_object_end(s, handle))
416		{
417		STOREerr(STORE_F_STORE_LIST_CERTIFICATE_END,
418			STORE_R_FAILED_LISTING_CERTIFICATES);
419		return 0;
420		}
421	return 1;
422	}
423
424int STORE_list_certificate_endp(STORE *s, void *handle)
425	{
426	check_store(s,STORE_F_STORE_LIST_CERTIFICATE_ENDP,
427		list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION);
428
429	if (!s->meth->list_object_endp(s, handle))
430		{
431		STOREerr(STORE_F_STORE_LIST_CERTIFICATE_ENDP,
432			STORE_R_FAILED_LISTING_CERTIFICATES);
433		return 0;
434		}
435	return 1;
436	}
437
438EVP_PKEY *STORE_generate_key(STORE *s, OPENSSL_ITEM attributes[],
439	OPENSSL_ITEM parameters[])
440	{
441	STORE_OBJECT *object;
442	EVP_PKEY *pkey;
443
444	check_store(s,STORE_F_STORE_GENERATE_KEY,
445		generate_object,STORE_R_NO_GENERATE_OBJECT_FUNCTION);
446
447	object = s->meth->generate_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY,
448		attributes, parameters);
449	if (!object || !object->data.key)
450		{
451		STOREerr(STORE_F_STORE_GENERATE_KEY,
452			STORE_R_FAILED_GENERATING_KEY);
453		return 0;
454		}
455	CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY);
456#ifdef REF_PRINT
457	REF_PRINT("EVP_PKEY",data);
458#endif
459	pkey = object->data.key;
460	STORE_OBJECT_free(object);
461	return pkey;
462	}
463
464EVP_PKEY *STORE_get_private_key(STORE *s, OPENSSL_ITEM attributes[],
465	OPENSSL_ITEM parameters[])
466	{
467	STORE_OBJECT *object;
468	EVP_PKEY *pkey;
469
470	check_store(s,STORE_F_STORE_GET_PRIVATE_KEY,
471		get_object,STORE_R_NO_GET_OBJECT_FUNCTION);
472
473	object = s->meth->get_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY,
474		attributes, parameters);
475	if (!object || !object->data.key || !object->data.key)
476		{
477		STOREerr(STORE_F_STORE_GET_PRIVATE_KEY,
478			STORE_R_FAILED_GETTING_KEY);
479		return 0;
480		}
481	CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY);
482#ifdef REF_PRINT
483	REF_PRINT("EVP_PKEY",data);
484#endif
485	pkey = object->data.key;
486	STORE_OBJECT_free(object);
487	return pkey;
488	}
489
490int STORE_store_private_key(STORE *s, EVP_PKEY *data, OPENSSL_ITEM attributes[],
491	OPENSSL_ITEM parameters[])
492	{
493	STORE_OBJECT *object;
494	int i;
495
496	check_store(s,STORE_F_STORE_STORE_PRIVATE_KEY,
497		store_object,STORE_R_NO_STORE_OBJECT_FUNCTION);
498
499	object = STORE_OBJECT_new();
500	if (!object)
501		{
502		STOREerr(STORE_F_STORE_STORE_PRIVATE_KEY,
503			ERR_R_MALLOC_FAILURE);
504		return 0;
505		}
506	object->data.key = EVP_PKEY_new();
507	if (!object->data.key)
508		{
509		STOREerr(STORE_F_STORE_STORE_PRIVATE_KEY,
510			ERR_R_MALLOC_FAILURE);
511		return 0;
512		}
513
514	CRYPTO_add(&data->references,1,CRYPTO_LOCK_EVP_PKEY);
515#ifdef REF_PRINT
516	REF_PRINT("EVP_PKEY",data);
517#endif
518	object->data.key = data;
519
520	i = s->meth->store_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, object,
521		attributes, parameters);
522
523	STORE_OBJECT_free(object);
524
525	if (!i)
526		{
527		STOREerr(STORE_F_STORE_STORE_PRIVATE_KEY,
528			STORE_R_FAILED_STORING_KEY);
529		return 0;
530		}
531	return i;
532	}
533
534int STORE_modify_private_key(STORE *s, OPENSSL_ITEM search_attributes[],
535	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
536	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[])
537	{
538	check_store(s,STORE_F_STORE_MODIFY_PRIVATE_KEY,
539		modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION);
540
541	if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY,
542		    search_attributes, add_attributes, modify_attributes,
543		    delete_attributes, parameters))
544		{
545		STOREerr(STORE_F_STORE_MODIFY_PRIVATE_KEY,
546			STORE_R_FAILED_MODIFYING_PRIVATE_KEY);
547		return 0;
548		}
549	return 1;
550	}
551
552int STORE_revoke_private_key(STORE *s, OPENSSL_ITEM attributes[],
553	OPENSSL_ITEM parameters[])
554	{
555	int i;
556
557	check_store(s,STORE_F_STORE_REVOKE_PRIVATE_KEY,
558		revoke_object,STORE_R_NO_REVOKE_OBJECT_FUNCTION);
559
560	i = s->meth->revoke_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY,
561		attributes, parameters);
562
563	if (!i)
564		{
565		STOREerr(STORE_F_STORE_REVOKE_PRIVATE_KEY,
566			STORE_R_FAILED_REVOKING_KEY);
567		return 0;
568		}
569	return i;
570	}
571
572int STORE_delete_private_key(STORE *s, OPENSSL_ITEM attributes[],
573	OPENSSL_ITEM parameters[])
574	{
575	check_store(s,STORE_F_STORE_DELETE_PRIVATE_KEY,
576		delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION);
577
578	if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY,
579		    attributes, parameters))
580		{
581		STOREerr(STORE_F_STORE_DELETE_PRIVATE_KEY,
582			STORE_R_FAILED_DELETING_KEY);
583		return 0;
584		}
585	return 1;
586	}
587
588void *STORE_list_private_key_start(STORE *s, OPENSSL_ITEM attributes[],
589	OPENSSL_ITEM parameters[])
590	{
591	void *handle;
592
593	check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_START,
594		list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION);
595
596	handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_PRIVATE_KEY,
597		attributes, parameters);
598	if (!handle)
599		{
600		STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_START,
601			STORE_R_FAILED_LISTING_KEYS);
602		return 0;
603		}
604	return handle;
605	}
606
607EVP_PKEY *STORE_list_private_key_next(STORE *s, void *handle)
608	{
609	STORE_OBJECT *object;
610	EVP_PKEY *pkey;
611
612	check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_NEXT,
613		list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION);
614
615	object = s->meth->list_object_next(s, handle);
616	if (!object || !object->data.key || !object->data.key)
617		{
618		STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_NEXT,
619			STORE_R_FAILED_LISTING_KEYS);
620		return 0;
621		}
622	CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY);
623#ifdef REF_PRINT
624	REF_PRINT("EVP_PKEY",data);
625#endif
626	pkey = object->data.key;
627	STORE_OBJECT_free(object);
628	return pkey;
629	}
630
631int STORE_list_private_key_end(STORE *s, void *handle)
632	{
633	check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_END,
634		list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION);
635
636	if (!s->meth->list_object_end(s, handle))
637		{
638		STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_END,
639			STORE_R_FAILED_LISTING_KEYS);
640		return 0;
641		}
642	return 1;
643	}
644
645int STORE_list_private_key_endp(STORE *s, void *handle)
646	{
647	check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_ENDP,
648		list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION);
649
650	if (!s->meth->list_object_endp(s, handle))
651		{
652		STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_ENDP,
653			STORE_R_FAILED_LISTING_KEYS);
654		return 0;
655		}
656	return 1;
657	}
658
659EVP_PKEY *STORE_get_public_key(STORE *s, OPENSSL_ITEM attributes[],
660	OPENSSL_ITEM parameters[])
661	{
662	STORE_OBJECT *object;
663	EVP_PKEY *pkey;
664
665	check_store(s,STORE_F_STORE_GET_PUBLIC_KEY,
666		get_object,STORE_R_NO_GET_OBJECT_FUNCTION);
667
668	object = s->meth->get_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY,
669		attributes, parameters);
670	if (!object || !object->data.key || !object->data.key)
671		{
672		STOREerr(STORE_F_STORE_GET_PUBLIC_KEY,
673			STORE_R_FAILED_GETTING_KEY);
674		return 0;
675		}
676	CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY);
677#ifdef REF_PRINT
678	REF_PRINT("EVP_PKEY",data);
679#endif
680	pkey = object->data.key;
681	STORE_OBJECT_free(object);
682	return pkey;
683	}
684
685int STORE_store_public_key(STORE *s, EVP_PKEY *data, OPENSSL_ITEM attributes[],
686	OPENSSL_ITEM parameters[])
687	{
688	STORE_OBJECT *object;
689	int i;
690
691	check_store(s,STORE_F_STORE_STORE_PUBLIC_KEY,
692		store_object,STORE_R_NO_STORE_OBJECT_FUNCTION);
693
694	object = STORE_OBJECT_new();
695	if (!object)
696		{
697		STOREerr(STORE_F_STORE_STORE_PUBLIC_KEY,
698			ERR_R_MALLOC_FAILURE);
699		return 0;
700		}
701	object->data.key = EVP_PKEY_new();
702	if (!object->data.key)
703		{
704		STOREerr(STORE_F_STORE_STORE_PUBLIC_KEY,
705			ERR_R_MALLOC_FAILURE);
706		return 0;
707		}
708
709	CRYPTO_add(&data->references,1,CRYPTO_LOCK_EVP_PKEY);
710#ifdef REF_PRINT
711	REF_PRINT("EVP_PKEY",data);
712#endif
713	object->data.key = data;
714
715	i = s->meth->store_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, object,
716		attributes, parameters);
717
718	STORE_OBJECT_free(object);
719
720	if (!i)
721		{
722		STOREerr(STORE_F_STORE_STORE_PUBLIC_KEY,
723			STORE_R_FAILED_STORING_KEY);
724		return 0;
725		}
726	return i;
727	}
728
729int STORE_modify_public_key(STORE *s, OPENSSL_ITEM search_attributes[],
730	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
731	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[])
732	{
733	check_store(s,STORE_F_STORE_MODIFY_PUBLIC_KEY,
734		modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION);
735
736	if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY,
737		    search_attributes, add_attributes, modify_attributes,
738		    delete_attributes, parameters))
739		{
740		STOREerr(STORE_F_STORE_MODIFY_PUBLIC_KEY,
741			STORE_R_FAILED_MODIFYING_PUBLIC_KEY);
742		return 0;
743		}
744	return 1;
745	}
746
747int STORE_revoke_public_key(STORE *s, OPENSSL_ITEM attributes[],
748	OPENSSL_ITEM parameters[])
749	{
750	int i;
751
752	check_store(s,STORE_F_STORE_REVOKE_PUBLIC_KEY,
753		revoke_object,STORE_R_NO_REVOKE_OBJECT_FUNCTION);
754
755	i = s->meth->revoke_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY,
756		attributes, parameters);
757
758	if (!i)
759		{
760		STOREerr(STORE_F_STORE_REVOKE_PUBLIC_KEY,
761			STORE_R_FAILED_REVOKING_KEY);
762		return 0;
763		}
764	return i;
765	}
766
767int STORE_delete_public_key(STORE *s, OPENSSL_ITEM attributes[],
768	OPENSSL_ITEM parameters[])
769	{
770	check_store(s,STORE_F_STORE_DELETE_PUBLIC_KEY,
771		delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION);
772
773	if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY,
774		    attributes, parameters))
775		{
776		STOREerr(STORE_F_STORE_DELETE_PUBLIC_KEY,
777			STORE_R_FAILED_DELETING_KEY);
778		return 0;
779		}
780	return 1;
781	}
782
783void *STORE_list_public_key_start(STORE *s, OPENSSL_ITEM attributes[],
784	OPENSSL_ITEM parameters[])
785	{
786	void *handle;
787
788	check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_START,
789		list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION);
790
791	handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_PUBLIC_KEY,
792		attributes, parameters);
793	if (!handle)
794		{
795		STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_START,
796			STORE_R_FAILED_LISTING_KEYS);
797		return 0;
798		}
799	return handle;
800	}
801
802EVP_PKEY *STORE_list_public_key_next(STORE *s, void *handle)
803	{
804	STORE_OBJECT *object;
805	EVP_PKEY *pkey;
806
807	check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_NEXT,
808		list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION);
809
810	object = s->meth->list_object_next(s, handle);
811	if (!object || !object->data.key || !object->data.key)
812		{
813		STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_NEXT,
814			STORE_R_FAILED_LISTING_KEYS);
815		return 0;
816		}
817	CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY);
818#ifdef REF_PRINT
819	REF_PRINT("EVP_PKEY",data);
820#endif
821	pkey = object->data.key;
822	STORE_OBJECT_free(object);
823	return pkey;
824	}
825
826int STORE_list_public_key_end(STORE *s, void *handle)
827	{
828	check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_END,
829		list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION);
830
831	if (!s->meth->list_object_end(s, handle))
832		{
833		STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_END,
834			STORE_R_FAILED_LISTING_KEYS);
835		return 0;
836		}
837	return 1;
838	}
839
840int STORE_list_public_key_endp(STORE *s, void *handle)
841	{
842	check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_ENDP,
843		list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION);
844
845	if (!s->meth->list_object_endp(s, handle))
846		{
847		STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_ENDP,
848			STORE_R_FAILED_LISTING_KEYS);
849		return 0;
850		}
851	return 1;
852	}
853
854X509_CRL *STORE_generate_crl(STORE *s, OPENSSL_ITEM attributes[],
855	OPENSSL_ITEM parameters[])
856	{
857	STORE_OBJECT *object;
858	X509_CRL *crl;
859
860	check_store(s,STORE_F_STORE_GENERATE_CRL,
861		generate_object,STORE_R_NO_GENERATE_CRL_FUNCTION);
862
863	object = s->meth->generate_object(s, STORE_OBJECT_TYPE_X509_CRL,
864		attributes, parameters);
865	if (!object || !object->data.crl)
866		{
867		STOREerr(STORE_F_STORE_GENERATE_CRL,
868			STORE_R_FAILED_GENERATING_CRL);
869		return 0;
870		}
871	CRYPTO_add(&object->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
872#ifdef REF_PRINT
873	REF_PRINT("X509_CRL",data);
874#endif
875	crl = object->data.crl;
876	STORE_OBJECT_free(object);
877	return crl;
878	}
879
880X509_CRL *STORE_get_crl(STORE *s, OPENSSL_ITEM attributes[],
881	OPENSSL_ITEM parameters[])
882	{
883	STORE_OBJECT *object;
884	X509_CRL *crl;
885
886	check_store(s,STORE_F_STORE_GET_CRL,
887		get_object,STORE_R_NO_GET_OBJECT_FUNCTION);
888
889	object = s->meth->get_object(s, STORE_OBJECT_TYPE_X509_CRL,
890		attributes, parameters);
891	if (!object || !object->data.crl)
892		{
893		STOREerr(STORE_F_STORE_GET_CRL,
894			STORE_R_FAILED_GETTING_KEY);
895		return 0;
896		}
897	CRYPTO_add(&object->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
898#ifdef REF_PRINT
899	REF_PRINT("X509_CRL",data);
900#endif
901	crl = object->data.crl;
902	STORE_OBJECT_free(object);
903	return crl;
904	}
905
906int STORE_store_crl(STORE *s, X509_CRL *data, OPENSSL_ITEM attributes[],
907	OPENSSL_ITEM parameters[])
908	{
909	STORE_OBJECT *object;
910	int i;
911
912	check_store(s,STORE_F_STORE_STORE_CRL,
913		store_object,STORE_R_NO_STORE_OBJECT_FUNCTION);
914
915	object = STORE_OBJECT_new();
916	if (!object)
917		{
918		STOREerr(STORE_F_STORE_STORE_CRL,
919			ERR_R_MALLOC_FAILURE);
920		return 0;
921		}
922
923	CRYPTO_add(&data->references,1,CRYPTO_LOCK_X509_CRL);
924#ifdef REF_PRINT
925	REF_PRINT("X509_CRL",data);
926#endif
927	object->data.crl = data;
928
929	i = s->meth->store_object(s, STORE_OBJECT_TYPE_X509_CRL, object,
930		attributes, parameters);
931
932	STORE_OBJECT_free(object);
933
934	if (!i)
935		{
936		STOREerr(STORE_F_STORE_STORE_CRL,
937			STORE_R_FAILED_STORING_KEY);
938		return 0;
939		}
940	return i;
941	}
942
943int STORE_modify_crl(STORE *s, OPENSSL_ITEM search_attributes[],
944	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
945	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[])
946	{
947	check_store(s,STORE_F_STORE_MODIFY_CRL,
948		modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION);
949
950	if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_X509_CRL,
951		    search_attributes, add_attributes, modify_attributes,
952		    delete_attributes, parameters))
953		{
954		STOREerr(STORE_F_STORE_MODIFY_CRL,
955			STORE_R_FAILED_MODIFYING_CRL);
956		return 0;
957		}
958	return 1;
959	}
960
961int STORE_delete_crl(STORE *s, OPENSSL_ITEM attributes[],
962	OPENSSL_ITEM parameters[])
963	{
964	check_store(s,STORE_F_STORE_DELETE_CRL,
965		delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION);
966
967	if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_X509_CRL,
968		    attributes, parameters))
969		{
970		STOREerr(STORE_F_STORE_DELETE_CRL,
971			STORE_R_FAILED_DELETING_KEY);
972		return 0;
973		}
974	return 1;
975	}
976
977void *STORE_list_crl_start(STORE *s, OPENSSL_ITEM attributes[],
978	OPENSSL_ITEM parameters[])
979	{
980	void *handle;
981
982	check_store(s,STORE_F_STORE_LIST_CRL_START,
983		list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION);
984
985	handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_X509_CRL,
986		attributes, parameters);
987	if (!handle)
988		{
989		STOREerr(STORE_F_STORE_LIST_CRL_START,
990			STORE_R_FAILED_LISTING_KEYS);
991		return 0;
992		}
993	return handle;
994	}
995
996X509_CRL *STORE_list_crl_next(STORE *s, void *handle)
997	{
998	STORE_OBJECT *object;
999	X509_CRL *crl;
1000
1001	check_store(s,STORE_F_STORE_LIST_CRL_NEXT,
1002		list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION);
1003
1004	object = s->meth->list_object_next(s, handle);
1005	if (!object || !object->data.crl)
1006		{
1007		STOREerr(STORE_F_STORE_LIST_CRL_NEXT,
1008			STORE_R_FAILED_LISTING_KEYS);
1009		return 0;
1010		}
1011	CRYPTO_add(&object->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
1012#ifdef REF_PRINT
1013	REF_PRINT("X509_CRL",data);
1014#endif
1015	crl = object->data.crl;
1016	STORE_OBJECT_free(object);
1017	return crl;
1018	}
1019
1020int STORE_list_crl_end(STORE *s, void *handle)
1021	{
1022	check_store(s,STORE_F_STORE_LIST_CRL_END,
1023		list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION);
1024
1025	if (!s->meth->list_object_end(s, handle))
1026		{
1027		STOREerr(STORE_F_STORE_LIST_CRL_END,
1028			STORE_R_FAILED_LISTING_KEYS);
1029		return 0;
1030		}
1031	return 1;
1032	}
1033
1034int STORE_list_crl_endp(STORE *s, void *handle)
1035	{
1036	check_store(s,STORE_F_STORE_LIST_CRL_ENDP,
1037		list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION);
1038
1039	if (!s->meth->list_object_endp(s, handle))
1040		{
1041		STOREerr(STORE_F_STORE_LIST_CRL_ENDP,
1042			STORE_R_FAILED_LISTING_KEYS);
1043		return 0;
1044		}
1045	return 1;
1046	}
1047
1048int STORE_store_number(STORE *s, BIGNUM *data, OPENSSL_ITEM attributes[],
1049	OPENSSL_ITEM parameters[])
1050	{
1051	STORE_OBJECT *object;
1052	int i;
1053
1054	check_store(s,STORE_F_STORE_STORE_NUMBER,
1055		store_object,STORE_R_NO_STORE_OBJECT_NUMBER_FUNCTION);
1056
1057	object = STORE_OBJECT_new();
1058	if (!object)
1059		{
1060		STOREerr(STORE_F_STORE_STORE_NUMBER,
1061			ERR_R_MALLOC_FAILURE);
1062		return 0;
1063		}
1064
1065	object->data.number = data;
1066
1067	i = s->meth->store_object(s, STORE_OBJECT_TYPE_NUMBER, object,
1068		attributes, parameters);
1069
1070	STORE_OBJECT_free(object);
1071
1072	if (!i)
1073		{
1074		STOREerr(STORE_F_STORE_STORE_NUMBER,
1075			STORE_R_FAILED_STORING_NUMBER);
1076		return 0;
1077		}
1078	return 1;
1079	}
1080
1081int STORE_modify_number(STORE *s, OPENSSL_ITEM search_attributes[],
1082	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
1083	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[])
1084	{
1085	check_store(s,STORE_F_STORE_MODIFY_NUMBER,
1086		modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION);
1087
1088	if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_NUMBER,
1089		    search_attributes, add_attributes, modify_attributes,
1090		    delete_attributes, parameters))
1091		{
1092		STOREerr(STORE_F_STORE_MODIFY_NUMBER,
1093			STORE_R_FAILED_MODIFYING_NUMBER);
1094		return 0;
1095		}
1096	return 1;
1097	}
1098
1099BIGNUM *STORE_get_number(STORE *s, OPENSSL_ITEM attributes[],
1100	OPENSSL_ITEM parameters[])
1101	{
1102	STORE_OBJECT *object;
1103	BIGNUM *n;
1104
1105	check_store(s,STORE_F_STORE_GET_NUMBER,
1106		get_object,STORE_R_NO_GET_OBJECT_NUMBER_FUNCTION);
1107
1108	object = s->meth->get_object(s, STORE_OBJECT_TYPE_NUMBER, attributes,
1109		parameters);
1110	if (!object || !object->data.number)
1111		{
1112		STOREerr(STORE_F_STORE_GET_NUMBER,
1113			STORE_R_FAILED_GETTING_NUMBER);
1114		return 0;
1115		}
1116	n = object->data.number;
1117	object->data.number = NULL;
1118	STORE_OBJECT_free(object);
1119	return n;
1120	}
1121
1122int STORE_delete_number(STORE *s, OPENSSL_ITEM attributes[],
1123	OPENSSL_ITEM parameters[])
1124	{
1125	check_store(s,STORE_F_STORE_DELETE_NUMBER,
1126		delete_object,STORE_R_NO_DELETE_NUMBER_FUNCTION);
1127
1128	if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_NUMBER, attributes,
1129		    parameters))
1130		{
1131		STOREerr(STORE_F_STORE_DELETE_NUMBER,
1132			STORE_R_FAILED_DELETING_NUMBER);
1133		return 0;
1134		}
1135	return 1;
1136	}
1137
1138int STORE_store_arbitrary(STORE *s, BUF_MEM *data, OPENSSL_ITEM attributes[],
1139	OPENSSL_ITEM parameters[])
1140	{
1141	STORE_OBJECT *object;
1142	int i;
1143
1144	check_store(s,STORE_F_STORE_STORE_ARBITRARY,
1145		store_object,STORE_R_NO_STORE_OBJECT_ARBITRARY_FUNCTION);
1146
1147	object = STORE_OBJECT_new();
1148	if (!object)
1149		{
1150		STOREerr(STORE_F_STORE_STORE_ARBITRARY,
1151			ERR_R_MALLOC_FAILURE);
1152		return 0;
1153		}
1154
1155	object->data.arbitrary = data;
1156
1157	i = s->meth->store_object(s, STORE_OBJECT_TYPE_ARBITRARY, object,
1158		attributes, parameters);
1159
1160	STORE_OBJECT_free(object);
1161
1162	if (!i)
1163		{
1164		STOREerr(STORE_F_STORE_STORE_ARBITRARY,
1165			STORE_R_FAILED_STORING_ARBITRARY);
1166		return 0;
1167		}
1168	return 1;
1169	}
1170
1171int STORE_modify_arbitrary(STORE *s, OPENSSL_ITEM search_attributes[],
1172	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
1173	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[])
1174	{
1175	check_store(s,STORE_F_STORE_MODIFY_ARBITRARY,
1176		modify_object,STORE_R_NO_MODIFY_OBJECT_FUNCTION);
1177
1178	if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_ARBITRARY,
1179		    search_attributes, add_attributes, modify_attributes,
1180		    delete_attributes, parameters))
1181		{
1182		STOREerr(STORE_F_STORE_MODIFY_ARBITRARY,
1183			STORE_R_FAILED_MODIFYING_ARBITRARY);
1184		return 0;
1185		}
1186	return 1;
1187	}
1188
1189BUF_MEM *STORE_get_arbitrary(STORE *s, OPENSSL_ITEM attributes[],
1190	OPENSSL_ITEM parameters[])
1191	{
1192	STORE_OBJECT *object;
1193	BUF_MEM *b;
1194
1195	check_store(s,STORE_F_STORE_GET_ARBITRARY,
1196		get_object,STORE_R_NO_GET_OBJECT_ARBITRARY_FUNCTION);
1197
1198	object = s->meth->get_object(s, STORE_OBJECT_TYPE_ARBITRARY,
1199		attributes, parameters);
1200	if (!object || !object->data.arbitrary)
1201		{
1202		STOREerr(STORE_F_STORE_GET_ARBITRARY,
1203			STORE_R_FAILED_GETTING_ARBITRARY);
1204		return 0;
1205		}
1206	b = object->data.arbitrary;
1207	object->data.arbitrary = NULL;
1208	STORE_OBJECT_free(object);
1209	return b;
1210	}
1211
1212int STORE_delete_arbitrary(STORE *s, OPENSSL_ITEM attributes[],
1213	OPENSSL_ITEM parameters[])
1214	{
1215	check_store(s,STORE_F_STORE_DELETE_ARBITRARY,
1216		delete_object,STORE_R_NO_DELETE_ARBITRARY_FUNCTION);
1217
1218	if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_ARBITRARY, attributes,
1219		    parameters))
1220		{
1221		STOREerr(STORE_F_STORE_DELETE_ARBITRARY,
1222			STORE_R_FAILED_DELETING_ARBITRARY);
1223		return 0;
1224		}
1225	return 1;
1226	}
1227
1228STORE_OBJECT *STORE_OBJECT_new(void)
1229	{
1230	STORE_OBJECT *object = OPENSSL_malloc(sizeof(STORE_OBJECT));
1231	if (object) memset(object, 0, sizeof(STORE_OBJECT));
1232	return object;
1233	}
1234void STORE_OBJECT_free(STORE_OBJECT *data)
1235	{
1236	if (!data) return;
1237	switch (data->type)
1238		{
1239	case STORE_OBJECT_TYPE_X509_CERTIFICATE:
1240		X509_free(data->data.x509.certificate);
1241		break;
1242	case STORE_OBJECT_TYPE_X509_CRL:
1243		X509_CRL_free(data->data.crl);
1244		break;
1245	case STORE_OBJECT_TYPE_PRIVATE_KEY:
1246	case STORE_OBJECT_TYPE_PUBLIC_KEY:
1247		EVP_PKEY_free(data->data.key);
1248		break;
1249	case STORE_OBJECT_TYPE_NUMBER:
1250		BN_free(data->data.number);
1251		break;
1252	case STORE_OBJECT_TYPE_ARBITRARY:
1253		BUF_MEM_free(data->data.arbitrary);
1254		break;
1255		}
1256	OPENSSL_free(data);
1257	}
1258
1259IMPLEMENT_STACK_OF(STORE_OBJECT*)
1260
1261
1262struct STORE_attr_info_st
1263	{
1264	unsigned char set[(STORE_ATTR_TYPE_NUM + 8) / 8];
1265	union
1266		{
1267		char *cstring;
1268		unsigned char *sha1string;
1269		X509_NAME *dn;
1270		BIGNUM *number;
1271		void *any;
1272		} values[STORE_ATTR_TYPE_NUM+1];
1273	size_t value_sizes[STORE_ATTR_TYPE_NUM+1];
1274	};
1275
1276#define ATTR_IS_SET(a,i)	((i) > 0 && (i) < STORE_ATTR_TYPE_NUM \
1277				&& ((a)->set[(i) / 8] & (1 << ((i) % 8))))
1278#define SET_ATTRBIT(a,i)	((a)->set[(i) / 8] |= (1 << ((i) % 8)))
1279#define CLEAR_ATTRBIT(a,i)	((a)->set[(i) / 8] &= ~(1 << ((i) % 8)))
1280
1281STORE_ATTR_INFO *STORE_ATTR_INFO_new(void)
1282	{
1283	return (STORE_ATTR_INFO *)OPENSSL_malloc(sizeof(STORE_ATTR_INFO));
1284	}
1285static void STORE_ATTR_INFO_attr_free(STORE_ATTR_INFO *attrs,
1286	STORE_ATTR_TYPES code)
1287	{
1288	if (ATTR_IS_SET(attrs,code))
1289		{
1290		switch(code)
1291			{
1292		case STORE_ATTR_FRIENDLYNAME:
1293		case STORE_ATTR_EMAIL:
1294		case STORE_ATTR_FILENAME:
1295			STORE_ATTR_INFO_modify_cstr(attrs, code, NULL, 0);
1296			break;
1297		case STORE_ATTR_KEYID:
1298		case STORE_ATTR_ISSUERKEYID:
1299		case STORE_ATTR_SUBJECTKEYID:
1300		case STORE_ATTR_ISSUERSERIALHASH:
1301		case STORE_ATTR_CERTHASH:
1302			STORE_ATTR_INFO_modify_sha1str(attrs, code, NULL, 0);
1303			break;
1304		case STORE_ATTR_ISSUER:
1305		case STORE_ATTR_SUBJECT:
1306			STORE_ATTR_INFO_modify_dn(attrs, code, NULL);
1307			break;
1308		case STORE_ATTR_SERIAL:
1309			STORE_ATTR_INFO_modify_number(attrs, code, NULL);
1310			break;
1311		default:
1312			break;
1313			}
1314		}
1315	}
1316int STORE_ATTR_INFO_free(STORE_ATTR_INFO *attrs)
1317	{
1318	if (attrs)
1319		{
1320		STORE_ATTR_TYPES i;
1321		for(i = 0; i++ < STORE_ATTR_TYPE_NUM;)
1322			STORE_ATTR_INFO_attr_free(attrs, i);
1323		OPENSSL_free(attrs);
1324		}
1325	return 1;
1326	}
1327char *STORE_ATTR_INFO_get0_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code)
1328	{
1329	if (!attrs)
1330		{
1331		STOREerr(STORE_F_STORE_ATTR_INFO_GET0_CSTR,
1332			ERR_R_PASSED_NULL_PARAMETER);
1333		return NULL;
1334		}
1335	if (ATTR_IS_SET(attrs,code))
1336		return attrs->values[code].cstring;
1337	STOREerr(STORE_F_STORE_ATTR_INFO_GET0_CSTR,
1338		STORE_R_NO_VALUE);
1339	return NULL;
1340	}
1341unsigned char *STORE_ATTR_INFO_get0_sha1str(STORE_ATTR_INFO *attrs,
1342	STORE_ATTR_TYPES code)
1343	{
1344	if (!attrs)
1345		{
1346		STOREerr(STORE_F_STORE_ATTR_INFO_GET0_SHA1STR,
1347			ERR_R_PASSED_NULL_PARAMETER);
1348		return NULL;
1349		}
1350	if (ATTR_IS_SET(attrs,code))
1351		return attrs->values[code].sha1string;
1352	STOREerr(STORE_F_STORE_ATTR_INFO_GET0_SHA1STR,
1353		STORE_R_NO_VALUE);
1354	return NULL;
1355	}
1356X509_NAME *STORE_ATTR_INFO_get0_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code)
1357	{
1358	if (!attrs)
1359		{
1360		STOREerr(STORE_F_STORE_ATTR_INFO_GET0_DN,
1361			ERR_R_PASSED_NULL_PARAMETER);
1362		return NULL;
1363		}
1364	if (ATTR_IS_SET(attrs,code))
1365		return attrs->values[code].dn;
1366	STOREerr(STORE_F_STORE_ATTR_INFO_GET0_DN,
1367		STORE_R_NO_VALUE);
1368	return NULL;
1369	}
1370BIGNUM *STORE_ATTR_INFO_get0_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code)
1371	{
1372	if (!attrs)
1373		{
1374		STOREerr(STORE_F_STORE_ATTR_INFO_GET0_NUMBER,
1375			ERR_R_PASSED_NULL_PARAMETER);
1376		return NULL;
1377		}
1378	if (ATTR_IS_SET(attrs,code))
1379		return attrs->values[code].number;
1380	STOREerr(STORE_F_STORE_ATTR_INFO_GET0_NUMBER,
1381		STORE_R_NO_VALUE);
1382	return NULL;
1383	}
1384int STORE_ATTR_INFO_set_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1385	char *cstr, size_t cstr_size)
1386	{
1387	if (!attrs)
1388		{
1389		STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR,
1390			ERR_R_PASSED_NULL_PARAMETER);
1391		return 0;
1392		}
1393	if (!ATTR_IS_SET(attrs,code))
1394		{
1395		if ((attrs->values[code].cstring = BUF_strndup(cstr, cstr_size)))
1396			return 1;
1397		STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR,
1398			ERR_R_MALLOC_FAILURE);
1399		return 0;
1400		}
1401	STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR, STORE_R_ALREADY_HAS_A_VALUE);
1402	return 0;
1403	}
1404int STORE_ATTR_INFO_set_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1405	unsigned char *sha1str, size_t sha1str_size)
1406	{
1407	if (!attrs)
1408		{
1409		STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR,
1410			ERR_R_PASSED_NULL_PARAMETER);
1411		return 0;
1412		}
1413	if (!ATTR_IS_SET(attrs,code))
1414		{
1415		if ((attrs->values[code].sha1string =
1416			    (unsigned char *)BUF_memdup(sha1str,
1417				    sha1str_size)))
1418			return 1;
1419		STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR,
1420			ERR_R_MALLOC_FAILURE);
1421		return 0;
1422		}
1423	STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR, STORE_R_ALREADY_HAS_A_VALUE);
1424	return 0;
1425	}
1426int STORE_ATTR_INFO_set_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1427	X509_NAME *dn)
1428	{
1429	if (!attrs)
1430		{
1431		STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN,
1432			ERR_R_PASSED_NULL_PARAMETER);
1433		return 0;
1434		}
1435	if (!ATTR_IS_SET(attrs,code))
1436		{
1437		if ((attrs->values[code].dn = X509_NAME_dup(dn)))
1438			return 1;
1439		STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN,
1440			ERR_R_MALLOC_FAILURE);
1441		return 0;
1442		}
1443	STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN, STORE_R_ALREADY_HAS_A_VALUE);
1444	return 0;
1445	}
1446int STORE_ATTR_INFO_set_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1447	BIGNUM *number)
1448	{
1449	if (!attrs)
1450		{
1451		STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER,
1452			ERR_R_PASSED_NULL_PARAMETER);
1453		return 0;
1454		}
1455	if (!ATTR_IS_SET(attrs,code))
1456		{
1457		if ((attrs->values[code].number = BN_dup(number)))
1458			return 1;
1459		STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER,
1460			ERR_R_MALLOC_FAILURE);
1461		return 0;
1462		}
1463	STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER, STORE_R_ALREADY_HAS_A_VALUE);
1464	return 0;
1465	}
1466int STORE_ATTR_INFO_modify_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1467	char *cstr, size_t cstr_size)
1468	{
1469	if (!attrs)
1470		{
1471		STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_CSTR,
1472			ERR_R_PASSED_NULL_PARAMETER);
1473		return 0;
1474		}
1475	if (ATTR_IS_SET(attrs,code))
1476		{
1477		OPENSSL_free(attrs->values[code].cstring);
1478		attrs->values[code].cstring = NULL;
1479		CLEAR_ATTRBIT(attrs, code);
1480		}
1481	return STORE_ATTR_INFO_set_cstr(attrs, code, cstr, cstr_size);
1482	}
1483int STORE_ATTR_INFO_modify_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1484	unsigned char *sha1str, size_t sha1str_size)
1485	{
1486	if (!attrs)
1487		{
1488		STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_SHA1STR,
1489			ERR_R_PASSED_NULL_PARAMETER);
1490		return 0;
1491		}
1492	if (ATTR_IS_SET(attrs,code))
1493		{
1494		OPENSSL_free(attrs->values[code].sha1string);
1495		attrs->values[code].sha1string = NULL;
1496		CLEAR_ATTRBIT(attrs, code);
1497		}
1498	return STORE_ATTR_INFO_set_sha1str(attrs, code, sha1str, sha1str_size);
1499	}
1500int STORE_ATTR_INFO_modify_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1501	X509_NAME *dn)
1502	{
1503	if (!attrs)
1504		{
1505		STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_DN,
1506			ERR_R_PASSED_NULL_PARAMETER);
1507		return 0;
1508		}
1509	if (ATTR_IS_SET(attrs,code))
1510		{
1511		OPENSSL_free(attrs->values[code].dn);
1512		attrs->values[code].dn = NULL;
1513		CLEAR_ATTRBIT(attrs, code);
1514		}
1515	return STORE_ATTR_INFO_set_dn(attrs, code, dn);
1516	}
1517int STORE_ATTR_INFO_modify_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1518	BIGNUM *number)
1519	{
1520	if (!attrs)
1521		{
1522		STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_NUMBER,
1523			ERR_R_PASSED_NULL_PARAMETER);
1524		return 0;
1525		}
1526	if (ATTR_IS_SET(attrs,code))
1527		{
1528		OPENSSL_free(attrs->values[code].number);
1529		attrs->values[code].number = NULL;
1530		CLEAR_ATTRBIT(attrs, code);
1531		}
1532	return STORE_ATTR_INFO_set_number(attrs, code, number);
1533	}
1534
1535struct attr_list_ctx_st
1536	{
1537	OPENSSL_ITEM *attributes;
1538	};
1539void *STORE_parse_attrs_start(OPENSSL_ITEM *attributes)
1540	{
1541	if (attributes)
1542		{
1543		struct attr_list_ctx_st *context =
1544			(struct attr_list_ctx_st *)OPENSSL_malloc(sizeof(struct attr_list_ctx_st));
1545		if (context)
1546			context->attributes = attributes;
1547		else
1548			STOREerr(STORE_F_STORE_PARSE_ATTRS_START,
1549				ERR_R_MALLOC_FAILURE);
1550		return context;
1551		}
1552	STOREerr(STORE_F_STORE_PARSE_ATTRS_START, ERR_R_PASSED_NULL_PARAMETER);
1553	return 0;
1554	}
1555STORE_ATTR_INFO *STORE_parse_attrs_next(void *handle)
1556	{
1557	struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle;
1558
1559	if (context && context->attributes)
1560		{
1561		STORE_ATTR_INFO *attrs = NULL;
1562
1563		while(context->attributes
1564			&& context->attributes->code != STORE_ATTR_OR
1565			&& context->attributes->code != STORE_ATTR_END)
1566			{
1567			switch(context->attributes->code)
1568				{
1569			case STORE_ATTR_FRIENDLYNAME:
1570			case STORE_ATTR_EMAIL:
1571			case STORE_ATTR_FILENAME:
1572				if (!attrs) attrs = STORE_ATTR_INFO_new();
1573				if (attrs == NULL)
1574					{
1575					STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT,
1576						ERR_R_MALLOC_FAILURE);
1577					goto err;
1578					}
1579				STORE_ATTR_INFO_set_cstr(attrs,
1580					context->attributes->code,
1581					context->attributes->value,
1582					context->attributes->value_size);
1583				break;
1584			case STORE_ATTR_KEYID:
1585			case STORE_ATTR_ISSUERKEYID:
1586			case STORE_ATTR_SUBJECTKEYID:
1587			case STORE_ATTR_ISSUERSERIALHASH:
1588			case STORE_ATTR_CERTHASH:
1589				if (!attrs) attrs = STORE_ATTR_INFO_new();
1590				if (attrs == NULL)
1591					{
1592					STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT,
1593						ERR_R_MALLOC_FAILURE);
1594					goto err;
1595					}
1596				STORE_ATTR_INFO_set_sha1str(attrs,
1597					context->attributes->code,
1598					context->attributes->value,
1599					context->attributes->value_size);
1600				break;
1601			case STORE_ATTR_ISSUER:
1602			case STORE_ATTR_SUBJECT:
1603				if (!attrs) attrs = STORE_ATTR_INFO_new();
1604				if (attrs == NULL)
1605					{
1606					STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT,
1607						ERR_R_MALLOC_FAILURE);
1608					goto err;
1609					}
1610				STORE_ATTR_INFO_modify_dn(attrs,
1611					context->attributes->code,
1612					context->attributes->value);
1613				break;
1614			case STORE_ATTR_SERIAL:
1615				if (!attrs) attrs = STORE_ATTR_INFO_new();
1616				if (attrs == NULL)
1617					{
1618					STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT,
1619						ERR_R_MALLOC_FAILURE);
1620					goto err;
1621					}
1622				STORE_ATTR_INFO_modify_number(attrs,
1623					context->attributes->code,
1624					context->attributes->value);
1625				break;
1626				}
1627			context->attributes++;
1628			}
1629		if (context->attributes->code == STORE_ATTR_OR)
1630			context->attributes++;
1631		return attrs;
1632	err:
1633		while(context->attributes
1634			&& context->attributes->code != STORE_ATTR_OR
1635			&& context->attributes->code != STORE_ATTR_END)
1636			context->attributes++;
1637		if (context->attributes->code == STORE_ATTR_OR)
1638			context->attributes++;
1639		return NULL;
1640		}
1641	STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT, ERR_R_PASSED_NULL_PARAMETER);
1642	return NULL;
1643	}
1644int STORE_parse_attrs_end(void *handle)
1645	{
1646	struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle;
1647
1648	if (context && context->attributes)
1649		{
1650#if 0
1651		OPENSSL_ITEM *attributes = context->attributes;
1652#endif
1653		OPENSSL_free(context);
1654		return 1;
1655		}
1656	STOREerr(STORE_F_STORE_PARSE_ATTRS_END, ERR_R_PASSED_NULL_PARAMETER);
1657	return 0;
1658	}
1659
1660int STORE_parse_attrs_endp(void *handle)
1661	{
1662	struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle;
1663
1664	if (context && context->attributes)
1665		{
1666		return context->attributes->code == STORE_ATTR_END;
1667		}
1668	STOREerr(STORE_F_STORE_PARSE_ATTRS_ENDP, ERR_R_PASSED_NULL_PARAMETER);
1669	return 0;
1670	}
1671
1672static int attr_info_compare_compute_range(
1673	const unsigned char *abits, const unsigned char *bbits,
1674	unsigned int *alowp, unsigned int *ahighp,
1675	unsigned int *blowp, unsigned int *bhighp)
1676	{
1677	unsigned int alow = (unsigned int)-1, ahigh = 0;
1678	unsigned int blow = (unsigned int)-1, bhigh = 0;
1679	int i, res = 0;
1680
1681	for (i = 0; i < (STORE_ATTR_TYPE_NUM + 8) / 8; i++, abits++, bbits++)
1682		{
1683		if (res == 0)
1684			{
1685			if (*abits < *bbits) res = -1;
1686			if (*abits > *bbits) res = 1;
1687			}
1688		if (*abits)
1689			{
1690			if (alow == (unsigned int)-1)
1691				{
1692				alow = i * 8;
1693				if (!(*abits & 0x01)) alow++;
1694				if (!(*abits & 0x02)) alow++;
1695				if (!(*abits & 0x04)) alow++;
1696				if (!(*abits & 0x08)) alow++;
1697				if (!(*abits & 0x10)) alow++;
1698				if (!(*abits & 0x20)) alow++;
1699				if (!(*abits & 0x40)) alow++;
1700				}
1701			ahigh = i * 8 + 7;
1702			if (!(*abits & 0x80)) ahigh++;
1703			if (!(*abits & 0x40)) ahigh++;
1704			if (!(*abits & 0x20)) ahigh++;
1705			if (!(*abits & 0x10)) ahigh++;
1706			if (!(*abits & 0x08)) ahigh++;
1707			if (!(*abits & 0x04)) ahigh++;
1708			if (!(*abits & 0x02)) ahigh++;
1709			}
1710		if (*bbits)
1711			{
1712			if (blow == (unsigned int)-1)
1713				{
1714				blow = i * 8;
1715				if (!(*bbits & 0x01)) blow++;
1716				if (!(*bbits & 0x02)) blow++;
1717				if (!(*bbits & 0x04)) blow++;
1718				if (!(*bbits & 0x08)) blow++;
1719				if (!(*bbits & 0x10)) blow++;
1720				if (!(*bbits & 0x20)) blow++;
1721				if (!(*bbits & 0x40)) blow++;
1722				}
1723			bhigh = i * 8 + 7;
1724			if (!(*bbits & 0x80)) bhigh++;
1725			if (!(*bbits & 0x40)) bhigh++;
1726			if (!(*bbits & 0x20)) bhigh++;
1727			if (!(*bbits & 0x10)) bhigh++;
1728			if (!(*bbits & 0x08)) bhigh++;
1729			if (!(*bbits & 0x04)) bhigh++;
1730			if (!(*bbits & 0x02)) bhigh++;
1731			}
1732		}
1733	if (ahigh + alow < bhigh + blow) res = -1;
1734	if (ahigh + alow > bhigh + blow) res = 1;
1735	if (alowp) *alowp = alow;
1736	if (ahighp) *ahighp = ahigh;
1737	if (blowp) *blowp = blow;
1738	if (bhighp) *bhighp = bhigh;
1739	return res;
1740	}
1741
1742int STORE_ATTR_INFO_compare(const STORE_ATTR_INFO * const *a,
1743			    const STORE_ATTR_INFO * const *b)
1744	{
1745	if (a == b) return 0;
1746	if (!a) return -1;
1747	if (!b) return 1;
1748	return attr_info_compare_compute_range((*a)->set, (*b)->set, 0, 0, 0, 0);
1749	}
1750
1751int STORE_ATTR_INFO_in_range(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
1752	{
1753	unsigned int alow, ahigh, blow, bhigh;
1754
1755	if (a == b) return 1;
1756	if (!a) return 0;
1757	if (!b) return 0;
1758	attr_info_compare_compute_range(a->set, b->set,
1759		&alow, &ahigh, &blow, &bhigh);
1760	if (alow >= blow && ahigh <= bhigh)
1761		return 1;
1762	return 0;
1763	}
1764
1765int STORE_ATTR_INFO_in(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
1766	{
1767	unsigned char *abits, *bbits;
1768	int i;
1769
1770	if (a == b) return 1;
1771	if (!a) return 0;
1772	if (!b) return 0;
1773	abits = a->set;
1774	bbits = b->set;
1775	for (i = 0; i < (STORE_ATTR_TYPE_NUM + 8) / 8; i++, abits++, bbits++)
1776		{
1777		if (*abits && (*bbits & *abits) != *abits)
1778			return 0;
1779		}
1780	return 1;
1781	}
1782
1783int STORE_ATTR_INFO_in_ex(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
1784	{
1785	STORE_ATTR_TYPES i;
1786
1787	if (a == b) return 1;
1788	if (!STORE_ATTR_INFO_in(a, b)) return 0;
1789	for (i = 1; i < STORE_ATTR_TYPE_NUM; i++)
1790		if (ATTR_IS_SET(a, i))
1791			{
1792			switch(i)
1793				{
1794			case STORE_ATTR_FRIENDLYNAME:
1795			case STORE_ATTR_EMAIL:
1796			case STORE_ATTR_FILENAME:
1797				if (strcmp(a->values[i].cstring,
1798					    b->values[i].cstring))
1799					return 0;
1800				break;
1801			case STORE_ATTR_KEYID:
1802			case STORE_ATTR_ISSUERKEYID:
1803			case STORE_ATTR_SUBJECTKEYID:
1804			case STORE_ATTR_ISSUERSERIALHASH:
1805			case STORE_ATTR_CERTHASH:
1806				if (memcmp(a->values[i].sha1string,
1807					    b->values[i].sha1string,
1808					    a->value_sizes[i]))
1809					return 0;
1810				break;
1811			case STORE_ATTR_ISSUER:
1812			case STORE_ATTR_SUBJECT:
1813				if (X509_NAME_cmp(a->values[i].dn,
1814					    b->values[i].dn))
1815					return 0;
1816				break;
1817			case STORE_ATTR_SERIAL:
1818				if (BN_cmp(a->values[i].number,
1819					    b->values[i].number))
1820					return 0;
1821				break;
1822			default:
1823				break;
1824				}
1825			}
1826
1827	return 1;
1828	}
1829