Add the possibility to store arbitrary data in a STORE.
[openssl.git] / crypto / store / str_lib.c
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 #include <openssl/engine.h>
63 #include "str_locl.h"
64
65 const char * const STORE_object_type_string[STORE_OBJECT_TYPE_NUM+1] =
66         {
67         0,
68         "X.509 Certificate",
69         "X.509 CRL",
70         "Private Key",
71         "Public Key",
72         "Number"
73         };
74
75 const int STORE_param_sizes[STORE_PARAM_TYPE_NUM+1] =
76         {
77         0,
78         sizeof(int),            /* EVP_TYPE */
79         sizeof(size_t),         /* BITS */
80         -1,                     /* KEY_PARAMETERS */
81         0                       /* KEY_NO_PARAMETERS */
82         };      
83
84 const int STORE_attr_sizes[STORE_ATTR_TYPE_NUM+1] =
85         {
86         0,
87         -1,                     /* FRIENDLYNAME:                C string */
88         SHA_DIGEST_LENGTH,      /* KEYID:               SHA1 digest, 160 bits */
89         SHA_DIGEST_LENGTH,      /* ISSUERKEYID:         SHA1 digest, 160 bits */
90         SHA_DIGEST_LENGTH,      /* SUBJECTKEYID:                SHA1 digest, 160 bits */
91         SHA_DIGEST_LENGTH,      /* ISSUERSERIALHASH:    SHA1 digest, 160 bits */
92         sizeof(X509_NAME *),    /* ISSUER:              X509_NAME * */
93         sizeof(BIGNUM *),       /* SERIAL:              BIGNUM * */
94         sizeof(X509_NAME *),    /* SUBJECT:             X509_NAME * */
95         SHA_DIGEST_LENGTH,      /* CERTHASH:            SHA1 digest, 160 bits */
96         -1,                     /* EMAIL:               C string */
97         -1,                     /* FILENAME:            C string */
98         };      
99
100 STORE *STORE_new_method(const STORE_METHOD *method)
101         {
102         STORE *ret;
103
104         ret=(STORE *)OPENSSL_malloc(sizeof(STORE));
105         if (ret == NULL)
106                 {
107                 STOREerr(STORE_F_STORE_NEW_METHOD,ERR_R_MALLOC_FAILURE);
108                 return NULL;
109                 }
110         if (method == NULL)
111                 {
112                 STOREerr(STORE_F_STORE_NEW_METHOD,ERR_R_PASSED_NULL_PARAMETER);
113                 return NULL;
114                 }
115         else
116                 ret->meth=method;
117
118         CRYPTO_new_ex_data(CRYPTO_EX_INDEX_STORE, ret, &ret->ex_data);
119         if (ret->meth->init && !ret->meth->init(ret))
120                 {
121                 STORE_free(ret);
122                 ret = NULL;
123                 }
124         return ret;
125         }
126
127 STORE *STORE_new_engine(ENGINE *engine)
128         {
129         STORE *ret = NULL;
130         ENGINE *e = engine;
131         const STORE_METHOD *meth = 0;
132
133 #ifdef OPENSSL_NO_ENGINE
134         e = NULL;
135 #else
136         if (engine)
137                 {
138                 if (!ENGINE_init(engine))
139                         {
140                         STOREerr(STORE_F_STORE_NEW_ENGINE, ERR_R_ENGINE_LIB);
141                         return NULL;
142                         }
143                 e = engine;
144                 }
145         else
146                 {
147                 STOREerr(STORE_F_STORE_NEW_ENGINE,ERR_R_PASSED_NULL_PARAMETER);
148                 return NULL;
149                 }
150         if(e)
151                 {
152                 meth = ENGINE_get_STORE(e);
153                 if(!meth)
154                         {
155                         STOREerr(STORE_F_STORE_NEW_ENGINE,
156                                 ERR_R_ENGINE_LIB);
157                         ENGINE_finish(e);
158                         return NULL;
159                         }
160                 }
161 #endif
162
163         ret = STORE_new_method(meth);
164         if (ret == NULL)
165                 {
166                 STOREerr(STORE_F_STORE_NEW_ENGINE,ERR_R_STORE_LIB);
167                 return NULL;
168                 }
169
170         ret->engine = e;
171
172         return(ret);
173         }
174
175 void STORE_free(STORE *store)
176         {
177         if (store == NULL)
178                 return;
179         if (store->meth->clean)
180                 store->meth->clean(store);
181         CRYPTO_free_ex_data(CRYPTO_EX_INDEX_STORE, store, &store->ex_data);
182         OPENSSL_free(store);
183         }
184
185
186 int STORE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
187              CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
188         {
189         return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_STORE, argl, argp,
190                                 new_func, dup_func, free_func);
191         }
192
193 int STORE_set_ex_data(STORE *r, int idx, void *arg)
194         {
195         return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
196         }
197
198 void *STORE_get_ex_data(STORE *r, int idx)
199         {
200         return(CRYPTO_get_ex_data(&r->ex_data,idx));
201         }
202
203 const STORE_METHOD *STORE_get_method(STORE *store)
204         {
205         return store->meth;
206         }
207
208 const STORE_METHOD *STORE_set_method(STORE *store, const STORE_METHOD *meth)
209         {
210         store->meth=meth;
211         return store->meth;
212         }
213
214
215 /* API helpers */
216
217 #define check_store(s,fncode,fnname,fnerrcode) \
218         do \
219                 { \
220                 if ((s) == NULL || (s)->meth) \
221                         { \
222                         STOREerr((fncode), ERR_R_PASSED_NULL_PARAMETER); \
223                         return 0; \
224                         } \
225                 if ((s)->meth->fnname == NULL) \
226                         { \
227                         STOREerr((fncode), (fnerrcode)); \
228                         return 0; \
229                         } \
230                 } \
231         while(0)
232
233 /* API functions */
234
235 X509 *STORE_get_certificate(STORE *s, OPENSSL_ITEM attributes[])
236         {
237         STORE_OBJECT *object;
238         X509 *x;
239
240         check_store(s,STORE_F_STORE_GET_CERTIFICATE,
241                 get_object,STORE_R_NO_GET_OBJECT_FUNCTION);
242
243         object = s->meth->get_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE, attributes);
244         if (!object || !object->data.x509.certificate)
245                 {
246                 STOREerr(STORE_F_STORE_GET_CERTIFICATE,
247                         STORE_R_FAILED_GETTING_CERTIFICATE);
248                 return 0;
249                 }
250         CRYPTO_add(&object->data.x509.certificate->references,1,CRYPTO_LOCK_X509);
251 #ifdef REF_PRINT
252         REF_PRINT("X509",data);
253 #endif
254         x = object->data.x509.certificate;
255         STORE_OBJECT_free(object);
256         return x;
257         }
258
259 int store_certificate(STORE *s, X509 *data, OPENSSL_ITEM attributes[])
260         {
261         STORE_OBJECT *object = STORE_OBJECT_new();
262         int i;
263
264         check_store(s,STORE_F_STORE_CERTIFICATE,
265                 store_object,STORE_R_NO_STORE_OBJECT_FUNCTION);
266
267         if (!object)
268                 {
269                 STOREerr(STORE_F_STORE_CERTIFICATE,
270                         ERR_R_MALLOC_FAILURE);
271                 return 0;
272                 }
273         
274         CRYPTO_add(&data->references,1,CRYPTO_LOCK_X509);
275 #ifdef REF_PRINT
276         REF_PRINT("X509",data);
277 #endif
278         object->data.x509.certificate = data;
279
280         i = s->meth->store_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE, object, attributes);
281
282         STORE_OBJECT_free(object);
283
284         if (!i)
285                 {
286                 STOREerr(STORE_F_STORE_CERTIFICATE,
287                         STORE_R_FAILED_STORING_CERTIFICATE);
288                 return 0;
289                 }
290         return 1;
291         }
292
293 int STORE_revoke_certificate(STORE *s, OPENSSL_ITEM attributes[])
294         {
295         check_store(s,STORE_F_STORE_REVOKE_CERTIFICATE,
296                 revoke_object,STORE_R_NO_REVOKE_OBJECT_FUNCTION);
297
298         if (!s->meth->revoke_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE, attributes))
299                 {
300                 STOREerr(STORE_F_STORE_REVOKE_CERTIFICATE,
301                         STORE_R_FAILED_REVOKING_CERTIFICATE);
302                 return 0;
303                 }
304         return 1;
305         }
306
307 int STORE_delete_certificate(STORE *s, OPENSSL_ITEM attributes[])
308         {
309         check_store(s,STORE_F_STORE_DELETE_CERTIFICATE,
310                 delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION);
311
312         if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE, attributes))
313                 {
314                 STOREerr(STORE_F_STORE_DELETE_CERTIFICATE,
315                         STORE_R_FAILED_DELETING_CERTIFICATE);
316                 return 0;
317                 }
318         return 1;
319         }
320
321 void *STORE_list_certificate_start(STORE *s, OPENSSL_ITEM attributes[])
322         {
323         void *handle;
324
325         check_store(s,STORE_F_STORE_LIST_CERTIFICATE_START,
326                 list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION);
327
328         handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_X509_CERTIFICATE, attributes);
329         if (!handle)
330                 {
331                 STOREerr(STORE_F_STORE_LIST_CERTIFICATE_START,
332                         STORE_R_FAILED_LISTING_CERTIFICATES);
333                 return 0;
334                 }
335         return handle;
336         }
337
338 X509 *STORE_list_certificate_next(STORE *s, void *handle)
339         {
340         STORE_OBJECT *object;
341         X509 *x;
342
343         check_store(s,STORE_F_STORE_LIST_CERTIFICATE_NEXT,
344                 list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION);
345
346         object = s->meth->list_object_next(s, handle);
347         if (!object || !object->data.x509.certificate)
348                 {
349                 STOREerr(STORE_F_STORE_LIST_CERTIFICATE_NEXT,
350                         STORE_R_FAILED_LISTING_CERTIFICATES);
351                 return 0;
352                 }
353         CRYPTO_add(&object->data.x509.certificate->references,1,CRYPTO_LOCK_X509);
354 #ifdef REF_PRINT
355         REF_PRINT("X509",data);
356 #endif
357         x = object->data.x509.certificate;
358         STORE_OBJECT_free(object);
359         return x;
360         }
361
362 int STORE_list_certificate_end(STORE *s, void *handle)
363         {
364         check_store(s,STORE_F_STORE_LIST_CERTIFICATE_END,
365                 list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION);
366
367         if (!s->meth->list_object_end(s, handle))
368                 {
369                 STOREerr(STORE_F_STORE_LIST_CERTIFICATE_END,
370                         STORE_R_FAILED_LISTING_CERTIFICATES);
371                 return 0;
372                 }
373         return 1;
374         }
375
376 int STORE_list_certificate_endp(STORE *s, void *handle)
377         {
378         check_store(s,STORE_F_STORE_LIST_CERTIFICATE_ENDP,
379                 list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION);
380
381         if (!s->meth->list_object_endp(s, handle))
382                 {
383                 STOREerr(STORE_F_STORE_LIST_CERTIFICATE_ENDP,
384                         STORE_R_FAILED_LISTING_CERTIFICATES);
385                 return 0;
386                 }
387         return 1;
388         }
389
390 EVP_PKEY *STORE_generate_key(STORE *s,
391         int evp_type, size_t bits, OPENSSL_ITEM attributes[])
392         {
393         STORE_OBJECT *object;
394         EVP_PKEY *pkey;
395         OPENSSL_ITEM params[3];
396
397         params[0].code = STORE_PARAM_EVP_TYPE;
398         params[0].value = &evp_type;
399         params[0].value_size = sizeof(evp_type);
400         params[1].code = STORE_PARAM_BITS;
401         params[1].value = &bits;
402         params[1].value_size = sizeof(bits);
403         params[2].code = 0;
404
405         check_store(s,STORE_F_STORE_GENERATE_KEY,
406                 generate_object,STORE_R_NO_GENERATE_OBJECT_FUNCTION);
407
408         object = s->meth->generate_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY,
409                 params, attributes);
410         if (!object || !object->data.key)
411                 {
412                 STOREerr(STORE_F_STORE_GENERATE_KEY,
413                         STORE_R_FAILED_GENERATING_KEY);
414                 return 0;
415                 }
416         CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY);
417 #ifdef REF_PRINT
418         REF_PRINT("EVP_PKEY",data);
419 #endif
420         pkey = object->data.key;
421         STORE_OBJECT_free(object);
422         return pkey;
423         }
424
425 EVP_PKEY *STORE_get_private_key(STORE *s, OPENSSL_ITEM attributes[])
426         {
427         STORE_OBJECT *object;
428         EVP_PKEY *pkey;
429
430         check_store(s,STORE_F_STORE_GET_PRIVATE_KEY,
431                 get_object,STORE_R_NO_GET_OBJECT_FUNCTION);
432
433         object = s->meth->get_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, attributes);
434         if (!object || !object->data.key || !object->data.key)
435                 {
436                 STOREerr(STORE_F_STORE_GET_PRIVATE_KEY,
437                         STORE_R_FAILED_GETTING_KEY);
438                 return 0;
439                 }
440         CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY);
441 #ifdef REF_PRINT
442         REF_PRINT("EVP_PKEY",data);
443 #endif
444         pkey = object->data.key;
445         STORE_OBJECT_free(object);
446         return pkey;
447         }
448
449 int store_private_key(STORE *s, EVP_PKEY *data, OPENSSL_ITEM attributes[])
450         {
451         STORE_OBJECT *object = STORE_OBJECT_new();
452         int i;
453
454         check_store(s,STORE_F_STORE_PRIVATE_KEY,
455                 store_object,STORE_R_NO_STORE_OBJECT_FUNCTION);
456
457         if (!object)
458                 {
459                 STOREerr(STORE_F_STORE_PRIVATE_KEY,
460                         ERR_R_MALLOC_FAILURE);
461                 return 0;
462                 }
463         object->data.key = EVP_PKEY_new();
464         if (!object->data.key)
465                 {
466                 STOREerr(STORE_F_STORE_PRIVATE_KEY,
467                         ERR_R_MALLOC_FAILURE);
468                 return 0;
469                 }
470         
471         CRYPTO_add(&data->references,1,CRYPTO_LOCK_EVP_PKEY);
472 #ifdef REF_PRINT
473         REF_PRINT("EVP_PKEY",data);
474 #endif
475         object->data.key = data;
476
477         i = s->meth->store_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, object, attributes);
478
479         STORE_OBJECT_free(object);
480
481         if (!i)
482                 {
483                 STOREerr(STORE_F_STORE_PRIVATE_KEY,
484                         STORE_R_FAILED_STORING_KEY);
485                 return 0;
486                 }
487         return i;
488         }
489
490 int STORE_revoke_private_key(STORE *s, OPENSSL_ITEM attributes[])
491         {
492         int i;
493
494         check_store(s,STORE_F_STORE_REVOKE_PRIVATE_KEY,
495                 revoke_object,STORE_R_NO_REVOKE_OBJECT_FUNCTION);
496
497         i = s->meth->revoke_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, attributes);
498
499         if (!i)
500                 {
501                 STOREerr(STORE_F_STORE_REVOKE_PRIVATE_KEY,
502                         STORE_R_FAILED_REVOKING_KEY);
503                 return 0;
504                 }
505         return i;
506         }
507
508 int STORE_delete_private_key(STORE *s, OPENSSL_ITEM attributes[])
509         {
510         check_store(s,STORE_F_STORE_DELETE_PRIVATE_KEY,
511                 delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION);
512         
513         if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, attributes))
514                 {
515                 STOREerr(STORE_F_STORE_DELETE_PRIVATE_KEY,
516                         STORE_R_FAILED_DELETING_KEY);
517                 return 0;
518                 }
519         return 1;
520         }
521
522 void *STORE_list_private_key_start(STORE *s, OPENSSL_ITEM attributes[])
523         {
524         void *handle;
525
526         check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_START,
527                 list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION);
528
529         handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_PRIVATE_KEY, attributes);
530         if (!handle)
531                 {
532                 STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_START,
533                         STORE_R_FAILED_LISTING_KEYS);
534                 return 0;
535                 }
536         return handle;
537         }
538
539 EVP_PKEY *STORE_list_private_key_next(STORE *s, void *handle)
540         {
541         STORE_OBJECT *object;
542         EVP_PKEY *pkey;
543
544         check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_NEXT,
545                 list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION);
546
547         object = s->meth->list_object_next(s, handle);
548         if (!object || !object->data.key || !object->data.key)
549                 {
550                 STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_NEXT,
551                         STORE_R_FAILED_LISTING_KEYS);
552                 return 0;
553                 }
554         CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY);
555 #ifdef REF_PRINT
556         REF_PRINT("EVP_PKEY",data);
557 #endif
558         pkey = object->data.key;
559         STORE_OBJECT_free(object);
560         return pkey;
561         }
562
563 int STORE_list_private_key_end(STORE *s, void *handle)
564         {
565         check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_END,
566                 list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION);
567
568         if (!s->meth->list_object_end(s, handle))
569                 {
570                 STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_END,
571                         STORE_R_FAILED_LISTING_KEYS);
572                 return 0;
573                 }
574         return 1;
575         }
576
577 int STORE_list_private_key_endp(STORE *s, void *handle)
578         {
579         check_store(s,STORE_F_STORE_LIST_PRIVATE_KEY_ENDP,
580                 list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION);
581
582         if (!s->meth->list_object_endp(s, handle))
583                 {
584                 STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_ENDP,
585                         STORE_R_FAILED_LISTING_KEYS);
586                 return 0;
587                 }
588         return 1;
589         }
590
591 EVP_PKEY *STORE_get_public_key(STORE *s, OPENSSL_ITEM attributes[])
592         {
593         STORE_OBJECT *object;
594         EVP_PKEY *pkey;
595
596         check_store(s,STORE_F_STORE_GET_PUBLIC_KEY,
597                 get_object,STORE_R_NO_GET_OBJECT_FUNCTION);
598
599         object = s->meth->get_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, attributes);
600         if (!object || !object->data.key || !object->data.key)
601                 {
602                 STOREerr(STORE_F_STORE_GET_PUBLIC_KEY,
603                         STORE_R_FAILED_GETTING_KEY);
604                 return 0;
605                 }
606         CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY);
607 #ifdef REF_PRINT
608         REF_PRINT("EVP_PKEY",data);
609 #endif
610         pkey = object->data.key;
611         STORE_OBJECT_free(object);
612         return pkey;
613         }
614
615 int store_public_key(STORE *s, EVP_PKEY *data, OPENSSL_ITEM attributes[])
616         {
617         STORE_OBJECT *object = STORE_OBJECT_new();
618         int i;
619
620         check_store(s,STORE_F_STORE_PUBLIC_KEY,
621                 store_object,STORE_R_NO_STORE_OBJECT_FUNCTION);
622
623         if (!object)
624                 {
625                 STOREerr(STORE_F_STORE_PUBLIC_KEY,
626                         ERR_R_MALLOC_FAILURE);
627                 return 0;
628                 }
629         object->data.key = EVP_PKEY_new();
630         if (!object->data.key)
631                 {
632                 STOREerr(STORE_F_STORE_PUBLIC_KEY,
633                         ERR_R_MALLOC_FAILURE);
634                 return 0;
635                 }
636         
637         CRYPTO_add(&data->references,1,CRYPTO_LOCK_EVP_PKEY);
638 #ifdef REF_PRINT
639         REF_PRINT("EVP_PKEY",data);
640 #endif
641         object->data.key = data;
642
643         i = s->meth->store_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, object, attributes);
644
645         STORE_OBJECT_free(object);
646
647         if (!i)
648                 {
649                 STOREerr(STORE_F_STORE_PUBLIC_KEY,
650                         STORE_R_FAILED_STORING_KEY);
651                 return 0;
652                 }
653         return i;
654         }
655
656 int STORE_revoke_public_key(STORE *s, OPENSSL_ITEM attributes[])
657         {
658         int i;
659
660         check_store(s,STORE_F_STORE_REVOKE_PUBLIC_KEY,
661                 revoke_object,STORE_R_NO_REVOKE_OBJECT_FUNCTION);
662
663         i = s->meth->revoke_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, attributes);
664
665         if (!i)
666                 {
667                 STOREerr(STORE_F_STORE_REVOKE_PUBLIC_KEY,
668                         STORE_R_FAILED_REVOKING_KEY);
669                 return 0;
670                 }
671         return i;
672         }
673
674 int STORE_delete_public_key(STORE *s, OPENSSL_ITEM attributes[])
675         {
676         check_store(s,STORE_F_STORE_DELETE_PUBLIC_KEY,
677                 delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION);
678         
679         if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, attributes))
680                 {
681                 STOREerr(STORE_F_STORE_DELETE_PUBLIC_KEY,
682                         STORE_R_FAILED_DELETING_KEY);
683                 return 0;
684                 }
685         return 1;
686         }
687
688 void *STORE_list_public_key_start(STORE *s, OPENSSL_ITEM attributes[])
689         {
690         void *handle;
691
692         check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_START,
693                 list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION);
694
695         handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_PUBLIC_KEY, attributes);
696         if (!handle)
697                 {
698                 STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_START,
699                         STORE_R_FAILED_LISTING_KEYS);
700                 return 0;
701                 }
702         return handle;
703         }
704
705 EVP_PKEY *STORE_list_public_key_next(STORE *s, void *handle)
706         {
707         STORE_OBJECT *object;
708         EVP_PKEY *pkey;
709
710         check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_NEXT,
711                 list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION);
712
713         object = s->meth->list_object_next(s, handle);
714         if (!object || !object->data.key || !object->data.key)
715                 {
716                 STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_NEXT,
717                         STORE_R_FAILED_LISTING_KEYS);
718                 return 0;
719                 }
720         CRYPTO_add(&object->data.key->references,1,CRYPTO_LOCK_EVP_PKEY);
721 #ifdef REF_PRINT
722         REF_PRINT("EVP_PKEY",data);
723 #endif
724         pkey = object->data.key;
725         STORE_OBJECT_free(object);
726         return pkey;
727         }
728
729 int STORE_list_public_key_end(STORE *s, void *handle)
730         {
731         check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_END,
732                 list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION);
733
734         if (!s->meth->list_object_end(s, handle))
735                 {
736                 STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_END,
737                         STORE_R_FAILED_LISTING_KEYS);
738                 return 0;
739                 }
740         return 1;
741         }
742
743 int STORE_list_public_key_endp(STORE *s, void *handle)
744         {
745         check_store(s,STORE_F_STORE_LIST_PUBLIC_KEY_ENDP,
746                 list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION);
747
748         if (!s->meth->list_object_endp(s, handle))
749                 {
750                 STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_ENDP,
751                         STORE_R_FAILED_LISTING_KEYS);
752                 return 0;
753                 }
754         return 1;
755         }
756
757 X509_CRL *STORE_generate_crl(STORE *s, OPENSSL_ITEM attributes[])
758         {
759         STORE_OBJECT *object;
760         X509_CRL *crl;
761
762         check_store(s,STORE_F_STORE_GENERATE_CRL,
763                 generate_object,STORE_R_NO_GENERATE_CRL_FUNCTION);
764
765         object = s->meth->generate_object(s, STORE_OBJECT_TYPE_X509_CRL, 0, attributes);
766         if (!object || !object->data.crl)
767                 {
768                 STOREerr(STORE_F_STORE_GENERATE_CRL,
769                         STORE_R_FAILED_GENERATING_CRL);
770                 return 0;
771                 }
772         CRYPTO_add(&object->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
773 #ifdef REF_PRINT
774         REF_PRINT("X509_CRL",data);
775 #endif
776         crl = object->data.crl;
777         STORE_OBJECT_free(object);
778         return crl;
779         }
780
781 X509_CRL *STORE_get_crl(STORE *s, OPENSSL_ITEM attributes[])
782         {
783         STORE_OBJECT *object;
784         X509_CRL *crl;
785
786         check_store(s,STORE_F_STORE_GET_CRL,
787                 get_object,STORE_R_NO_GET_OBJECT_FUNCTION);
788
789         object = s->meth->get_object(s, STORE_OBJECT_TYPE_X509_CRL, attributes);
790         if (!object || !object->data.crl)
791                 {
792                 STOREerr(STORE_F_STORE_GET_CRL,
793                         STORE_R_FAILED_GETTING_KEY);
794                 return 0;
795                 }
796         CRYPTO_add(&object->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
797 #ifdef REF_PRINT
798         REF_PRINT("X509_CRL",data);
799 #endif
800         crl = object->data.crl;
801         STORE_OBJECT_free(object);
802         return crl;
803         }
804
805 int store_crl(STORE *s, X509_CRL *data, OPENSSL_ITEM attributes[])
806         {
807         STORE_OBJECT *object = STORE_OBJECT_new();
808         int i;
809
810         check_store(s,STORE_F_STORE_CRL,
811                 store_object,STORE_R_NO_STORE_OBJECT_FUNCTION);
812
813         if (!object)
814                 {
815                 STOREerr(STORE_F_STORE_CRL,
816                         ERR_R_MALLOC_FAILURE);
817                 return 0;
818                 }
819         
820         CRYPTO_add(&data->references,1,CRYPTO_LOCK_X509_CRL);
821 #ifdef REF_PRINT
822         REF_PRINT("X509_CRL",data);
823 #endif
824         object->data.crl = data;
825
826         i = s->meth->store_object(s, STORE_OBJECT_TYPE_X509_CRL, object, attributes);
827
828         STORE_OBJECT_free(object);
829
830         if (!i)
831                 {
832                 STOREerr(STORE_F_STORE_CRL,
833                         STORE_R_FAILED_STORING_KEY);
834                 return 0;
835                 }
836         return i;
837         }
838
839 int STORE_delete_crl(STORE *s, OPENSSL_ITEM attributes[])
840         {
841         check_store(s,STORE_F_STORE_DELETE_CRL,
842                 delete_object,STORE_R_NO_DELETE_OBJECT_FUNCTION);
843         
844         if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_X509_CRL, attributes))
845                 {
846                 STOREerr(STORE_F_STORE_DELETE_CRL,
847                         STORE_R_FAILED_DELETING_KEY);
848                 return 0;
849                 }
850         return 1;
851         }
852
853 void *STORE_list_crl_start(STORE *s, OPENSSL_ITEM attributes[])
854         {
855         void *handle;
856
857         check_store(s,STORE_F_STORE_LIST_CRL_START,
858                 list_object_start,STORE_R_NO_LIST_OBJECT_START_FUNCTION);
859
860         handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_X509_CRL, attributes);
861         if (!handle)
862                 {
863                 STOREerr(STORE_F_STORE_LIST_CRL_START,
864                         STORE_R_FAILED_LISTING_KEYS);
865                 return 0;
866                 }
867         return handle;
868         }
869
870 X509_CRL *STORE_list_crl_next(STORE *s, void *handle)
871         {
872         STORE_OBJECT *object;
873         X509_CRL *crl;
874
875         check_store(s,STORE_F_STORE_LIST_CRL_NEXT,
876                 list_object_next,STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION);
877
878         object = s->meth->list_object_next(s, handle);
879         if (!object || !object->data.crl)
880                 {
881                 STOREerr(STORE_F_STORE_LIST_CRL_NEXT,
882                         STORE_R_FAILED_LISTING_KEYS);
883                 return 0;
884                 }
885         CRYPTO_add(&object->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
886 #ifdef REF_PRINT
887         REF_PRINT("X509_CRL",data);
888 #endif
889         crl = object->data.crl;
890         STORE_OBJECT_free(object);
891         return crl;
892         }
893
894 int STORE_list_crl_end(STORE *s, void *handle)
895         {
896         check_store(s,STORE_F_STORE_LIST_CRL_END,
897                 list_object_end,STORE_R_NO_LIST_OBJECT_END_FUNCTION);
898
899         if (!s->meth->list_object_end(s, handle))
900                 {
901                 STOREerr(STORE_F_STORE_LIST_CRL_END,
902                         STORE_R_FAILED_LISTING_KEYS);
903                 return 0;
904                 }
905         return 1;
906         }
907
908 int STORE_list_crl_endp(STORE *s, void *handle)
909         {
910         check_store(s,STORE_F_STORE_LIST_CRL_ENDP,
911                 list_object_endp,STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION);
912
913         if (!s->meth->list_object_endp(s, handle))
914                 {
915                 STOREerr(STORE_F_STORE_LIST_CRL_ENDP,
916                         STORE_R_FAILED_LISTING_KEYS);
917                 return 0;
918                 }
919         return 1;
920         }
921
922 int store_number(STORE *s, BIGNUM *data, OPENSSL_ITEM attributes[])
923         {
924         STORE_OBJECT *object = STORE_OBJECT_new();
925         int i;
926
927         check_store(s,STORE_F_STORE_NUMBER,
928                 store_object,STORE_R_NO_STORE_OBJECT_NUMBER_FUNCTION);
929
930         if (!object)
931                 {
932                 STOREerr(STORE_F_STORE_NUMBER,
933                         ERR_R_MALLOC_FAILURE);
934                 return 0;
935                 }
936         
937         object->data.number = data;
938
939         i = s->meth->store_object(s, STORE_OBJECT_TYPE_NUMBER, object, attributes);
940
941         STORE_OBJECT_free(object);
942
943         if (!i)
944                 {
945                 STOREerr(STORE_F_STORE_NUMBER,
946                         STORE_R_FAILED_STORING_NUMBER);
947                 return 0;
948                 }
949         return 1;
950         }
951
952 BIGNUM *STORE_get_number(STORE *s, OPENSSL_ITEM attributes[])
953         {
954         STORE_OBJECT *object;
955         BIGNUM *n;
956
957         check_store(s,STORE_F_STORE_GET_NUMBER,
958                 get_object,STORE_R_NO_GET_OBJECT_NUMBER_FUNCTION);
959
960         object = s->meth->get_object(s, STORE_OBJECT_TYPE_NUMBER, attributes);
961         if (!object || !object->data.number)
962                 {
963                 STOREerr(STORE_F_STORE_GET_NUMBER,
964                         STORE_R_FAILED_GETTING_NUMBER);
965                 return 0;
966                 }
967         n = object->data.number;
968         object->data.number = NULL;
969         STORE_OBJECT_free(object);
970         return n;
971         }
972
973 int STORE_delete_number(STORE *s, OPENSSL_ITEM attributes[])
974         {
975         check_store(s,STORE_F_STORE_DELETE_NUMBER,
976                 delete_object,STORE_R_NO_DELETE_NUMBER_FUNCTION);
977
978         if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_NUMBER, attributes))
979                 {
980                 STOREerr(STORE_F_STORE_DELETE_NUMBER,
981                         STORE_R_FAILED_DELETING_NUMBER);
982                 return 0;
983                 }
984         return 1;
985         }
986
987 int store_arbitrary(STORE *s, BUF_MEM *data, OPENSSL_ITEM attributes[])
988         {
989         STORE_OBJECT *object = STORE_OBJECT_new();
990         int i;
991
992         check_store(s,STORE_F_STORE_ARBITRARY,
993                 store_object,STORE_R_NO_STORE_OBJECT_ARBITRARY_FUNCTION);
994
995         if (!object)
996                 {
997                 STOREerr(STORE_F_STORE_ARBITRARY,
998                         ERR_R_MALLOC_FAILURE);
999                 return 0;
1000                 }
1001         
1002         object->data.arbitrary = data;
1003
1004         i = s->meth->store_object(s, STORE_OBJECT_TYPE_ARBITRARY, object, attributes);
1005
1006         STORE_OBJECT_free(object);
1007
1008         if (!i)
1009                 {
1010                 STOREerr(STORE_F_STORE_ARBITRARY,
1011                         STORE_R_FAILED_STORING_ARBITRARY);
1012                 return 0;
1013                 }
1014         return 1;
1015         }
1016
1017 BUF_MEM *STORE_get_arbitrary(STORE *s, OPENSSL_ITEM attributes[])
1018         {
1019         STORE_OBJECT *object;
1020         BUF_MEM *b;
1021
1022         check_store(s,STORE_F_STORE_GET_ARBITRARY,
1023                 get_object,STORE_R_NO_GET_OBJECT_ARBITRARY_FUNCTION);
1024
1025         object = s->meth->get_object(s, STORE_OBJECT_TYPE_ARBITRARY, attributes);
1026         if (!object || !object->data.arbitrary)
1027                 {
1028                 STOREerr(STORE_F_STORE_GET_ARBITRARY,
1029                         STORE_R_FAILED_GETTING_ARBITRARY);
1030                 return 0;
1031                 }
1032         b = object->data.arbitrary;
1033         object->data.arbitrary = NULL;
1034         STORE_OBJECT_free(object);
1035         return b;
1036         }
1037
1038 int STORE_delete_arbitrary(STORE *s, OPENSSL_ITEM attributes[])
1039         {
1040         check_store(s,STORE_F_STORE_DELETE_ARBITRARY,
1041                 delete_object,STORE_R_NO_DELETE_ARBITRARY_FUNCTION);
1042
1043         if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_ARBITRARY, attributes))
1044                 {
1045                 STOREerr(STORE_F_STORE_DELETE_ARBITRARY,
1046                         STORE_R_FAILED_DELETING_ARBITRARY);
1047                 return 0;
1048                 }
1049         return 1;
1050         }
1051
1052 STORE_OBJECT *STORE_OBJECT_new(void)
1053         {
1054         STORE_OBJECT *object = OPENSSL_malloc(sizeof(STORE_OBJECT));
1055         if (object) memset(object, 0, sizeof(STORE_OBJECT));
1056         return object;
1057         }
1058 void STORE_OBJECT_free(STORE_OBJECT *data)
1059         {
1060         if (!data) return;
1061         switch (data->type)
1062                 {
1063         case STORE_OBJECT_TYPE_X509_CERTIFICATE:
1064                 X509_free(data->data.x509.certificate);
1065                 break;
1066         case STORE_OBJECT_TYPE_X509_CRL:
1067                 X509_CRL_free(data->data.crl);
1068                 break;
1069         case STORE_OBJECT_TYPE_PRIVATE_KEY:
1070         case STORE_OBJECT_TYPE_PUBLIC_KEY:
1071                 EVP_PKEY_free(data->data.key);
1072                 break;
1073         case STORE_OBJECT_TYPE_NUMBER:
1074                 BN_free(data->data.number);
1075                 break;
1076         case STORE_OBJECT_TYPE_ARBITRARY:
1077                 BUF_MEM_free(data->data.arbitrary);
1078                 break;
1079                 }
1080         OPENSSL_free(data);
1081         }
1082
1083 IMPLEMENT_STACK_OF(STORE_OBJECT*);
1084
1085
1086 struct STORE_attr_info_st
1087         {
1088         unsigned char set[(STORE_ATTR_TYPE_NUM + 8) / 8];
1089         union
1090                 {
1091                 char *cstring;
1092                 unsigned char *sha1string;
1093                 X509_NAME *dn;
1094                 BIGNUM *number;
1095                 void *any;
1096                 } values[STORE_ATTR_TYPE_NUM+1];
1097         size_t value_sizes[STORE_ATTR_TYPE_NUM+1];
1098         };
1099
1100 #define ATTR_IS_SET(a,i)        ((i) > 0 && (i) < STORE_ATTR_TYPE_NUM \
1101                                 && ((a)->set[(i) / 8] & (1 << ((i) % 8))))
1102 #define SET_ATTRBIT(a,i)        ((a)->set[(i) / 8] |= (1 << ((i) % 8)))
1103 #define CLEAR_ATTRBIT(a,i)      ((a)->set[(i) / 8] &= ~(1 << ((i) % 8)))
1104
1105 STORE_ATTR_INFO *STORE_ATTR_INFO_new(void)
1106         {
1107         return (STORE_ATTR_INFO *)OPENSSL_malloc(sizeof(STORE_ATTR_INFO));
1108         }
1109 static void STORE_ATTR_INFO_attr_free(STORE_ATTR_INFO *attrs,
1110         STORE_ATTR_TYPES code)
1111         {
1112         if (ATTR_IS_SET(attrs,code))
1113                 {
1114                 switch(code)
1115                         {
1116                 case STORE_ATTR_FRIENDLYNAME:
1117                 case STORE_ATTR_EMAIL:
1118                 case STORE_ATTR_FILENAME:
1119                         STORE_ATTR_INFO_modify_cstr(attrs, code, NULL, 0);
1120                         break;
1121                 case STORE_ATTR_KEYID:
1122                 case STORE_ATTR_ISSUERKEYID:
1123                 case STORE_ATTR_SUBJECTKEYID:
1124                 case STORE_ATTR_ISSUERSERIALHASH:
1125                 case STORE_ATTR_CERTHASH:
1126                         STORE_ATTR_INFO_modify_sha1str(attrs, code, NULL, 0);
1127                         break;
1128                 case STORE_ATTR_ISSUER:
1129                 case STORE_ATTR_SUBJECT:
1130                         STORE_ATTR_INFO_modify_dn(attrs, code, NULL);
1131                         break;
1132                 case STORE_ATTR_SERIAL:
1133                         STORE_ATTR_INFO_modify_number(attrs, code, NULL);
1134                         break;
1135                 default:
1136                         break;
1137                         }
1138                 }
1139         }
1140 int STORE_ATTR_INFO_free(STORE_ATTR_INFO *attrs)
1141         {
1142         if (attrs)
1143                 {
1144                 STORE_ATTR_TYPES i;
1145                 for(i = 0; i++ < STORE_ATTR_TYPE_NUM;)
1146                         STORE_ATTR_INFO_attr_free(attrs, i);
1147                 OPENSSL_free(attrs);
1148                 }
1149         return 1;
1150         }
1151 char *STORE_ATTR_INFO_get0_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code)
1152         {
1153         if (!attrs)
1154                 {
1155                 STOREerr(STORE_F_STORE_ATTR_INFO_GET0_CSTR,
1156                         ERR_R_PASSED_NULL_PARAMETER);
1157                 return NULL;
1158                 }
1159         if (ATTR_IS_SET(attrs,code))
1160                 return attrs->values[code].cstring;
1161         STOREerr(STORE_F_STORE_ATTR_INFO_GET0_CSTR,
1162                 STORE_R_NO_VALUE);
1163         return NULL;
1164         }
1165 unsigned char *STORE_ATTR_INFO_get0_sha1str(STORE_ATTR_INFO *attrs,
1166         STORE_ATTR_TYPES code)
1167         {
1168         if (!attrs)
1169                 {
1170                 STOREerr(STORE_F_STORE_ATTR_INFO_GET0_SHA1STR,
1171                         ERR_R_PASSED_NULL_PARAMETER);
1172                 return NULL;
1173                 }
1174         if (ATTR_IS_SET(attrs,code))
1175                 return attrs->values[code].sha1string;
1176         STOREerr(STORE_F_STORE_ATTR_INFO_GET0_SHA1STR,
1177                 STORE_R_NO_VALUE);
1178         return NULL;
1179         }
1180 X509_NAME *STORE_ATTR_INFO_get0_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code)
1181         {
1182         if (!attrs)
1183                 {
1184                 STOREerr(STORE_F_STORE_ATTR_INFO_GET0_DN,
1185                         ERR_R_PASSED_NULL_PARAMETER);
1186                 return NULL;
1187                 }
1188         if (ATTR_IS_SET(attrs,code))
1189                 return attrs->values[code].dn;
1190         STOREerr(STORE_F_STORE_ATTR_INFO_GET0_DN,
1191                 STORE_R_NO_VALUE);
1192         return NULL;
1193         }
1194 BIGNUM *STORE_ATTR_INFO_get0_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code)
1195         {
1196         if (!attrs)
1197                 {
1198                 STOREerr(STORE_F_STORE_ATTR_INFO_GET0_NUMBER,
1199                         ERR_R_PASSED_NULL_PARAMETER);
1200                 return NULL;
1201                 }
1202         if (ATTR_IS_SET(attrs,code))
1203                 return attrs->values[code].number;
1204         STOREerr(STORE_F_STORE_ATTR_INFO_GET0_NUMBER,
1205                 STORE_R_NO_VALUE);
1206         return NULL;
1207         }
1208 int STORE_ATTR_INFO_set_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1209         char *cstr, size_t cstr_size)
1210         {
1211         if (!attrs)
1212                 {
1213                 STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR,
1214                         ERR_R_PASSED_NULL_PARAMETER);
1215                 return 0;
1216                 }
1217         if (!ATTR_IS_SET(attrs,code))
1218                 {
1219                 if ((attrs->values[code].cstring = BUF_strndup(cstr, cstr_size)))
1220                         return 1;
1221                 STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR,
1222                         ERR_R_MALLOC_FAILURE);
1223                 return 0;
1224                 }
1225         STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR, STORE_R_ALREADY_HAS_A_VALUE);
1226         return 0;
1227         }
1228 int STORE_ATTR_INFO_set_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1229         unsigned char *sha1str, size_t sha1str_size)
1230         {
1231         if (!attrs)
1232                 {
1233                 STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR,
1234                         ERR_R_PASSED_NULL_PARAMETER);
1235                 return 0;
1236                 }
1237         if (!ATTR_IS_SET(attrs,code))
1238                 {
1239                 if ((attrs->values[code].sha1string =
1240                             (unsigned char *)BUF_memdup(sha1str,
1241                                     sha1str_size)))
1242                         return 1;
1243                 STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR,
1244                         ERR_R_MALLOC_FAILURE);
1245                 return 0;
1246                 }
1247         STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR, STORE_R_ALREADY_HAS_A_VALUE);
1248         return 0;
1249         }
1250 int STORE_ATTR_INFO_set_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1251         X509_NAME *dn)
1252         {
1253         if (!attrs)
1254                 {
1255                 STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN,
1256                         ERR_R_PASSED_NULL_PARAMETER);
1257                 return 0;
1258                 }
1259         if (!ATTR_IS_SET(attrs,code))
1260                 {
1261                 if ((attrs->values[code].dn = X509_NAME_dup(dn)))
1262                         return 1;
1263                 STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR,
1264                         ERR_R_MALLOC_FAILURE);
1265                 return 0;
1266                 }
1267         STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN, STORE_R_ALREADY_HAS_A_VALUE);
1268         return 0;
1269         }
1270 int STORE_ATTR_INFO_set_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1271         BIGNUM *number)
1272         {
1273         if (!attrs)
1274                 {
1275                 STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER,
1276                         ERR_R_PASSED_NULL_PARAMETER);
1277                 return 0;
1278                 }
1279         if (!ATTR_IS_SET(attrs,code))
1280                 {
1281                 if ((attrs->values[code].number = BN_dup(number)))
1282                         return 1;
1283                 STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR,
1284                         ERR_R_MALLOC_FAILURE);
1285                 return 0;
1286                 }
1287         STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER, STORE_R_ALREADY_HAS_A_VALUE);
1288         return 0;
1289         }
1290 int STORE_ATTR_INFO_modify_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1291         char *cstr, size_t cstr_size)
1292         {
1293         if (!attrs)
1294                 {
1295                 STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_CSTR,
1296                         ERR_R_PASSED_NULL_PARAMETER);
1297                 return 0;
1298                 }
1299         if (ATTR_IS_SET(attrs,code))
1300                 {
1301                 OPENSSL_free(attrs->values[code].cstring);
1302                 attrs->values[code].cstring = NULL;
1303                 CLEAR_ATTRBIT(attrs, code);
1304                 }
1305         return STORE_ATTR_INFO_set_cstr(attrs, code, cstr, cstr_size);
1306         }
1307 int STORE_ATTR_INFO_modify_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1308         unsigned char *sha1str, size_t sha1str_size)
1309         {
1310         if (!attrs)
1311                 {
1312                 STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_SHA1STR,
1313                         ERR_R_PASSED_NULL_PARAMETER);
1314                 return 0;
1315                 }
1316         if (ATTR_IS_SET(attrs,code))
1317                 {
1318                 OPENSSL_free(attrs->values[code].sha1string);
1319                 attrs->values[code].sha1string = NULL;
1320                 CLEAR_ATTRBIT(attrs, code);
1321                 }
1322         return STORE_ATTR_INFO_set_sha1str(attrs, code, sha1str, sha1str_size);
1323         }
1324 int STORE_ATTR_INFO_modify_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1325         X509_NAME *dn)
1326         {
1327         if (!attrs)
1328                 {
1329                 STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_DN,
1330                         ERR_R_PASSED_NULL_PARAMETER);
1331                 return 0;
1332                 }
1333         if (ATTR_IS_SET(attrs,code))
1334                 {
1335                 OPENSSL_free(attrs->values[code].dn);
1336                 attrs->values[code].dn = NULL;
1337                 CLEAR_ATTRBIT(attrs, code);
1338                 }
1339         return STORE_ATTR_INFO_set_dn(attrs, code, dn);
1340         }
1341 int STORE_ATTR_INFO_modify_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1342         BIGNUM *number)
1343         {
1344         if (!attrs)
1345                 {
1346                 STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_NUMBER,
1347                         ERR_R_PASSED_NULL_PARAMETER);
1348                 return 0;
1349                 }
1350         if (ATTR_IS_SET(attrs,code))
1351                 {
1352                 OPENSSL_free(attrs->values[code].number);
1353                 attrs->values[code].number = NULL;
1354                 CLEAR_ATTRBIT(attrs, code);
1355                 }
1356         return STORE_ATTR_INFO_set_number(attrs, code, number);
1357         }
1358
1359 struct attr_list_ctx_st
1360         {
1361         OPENSSL_ITEM *attributes;
1362         };
1363 void *STORE_parse_attrs_start(OPENSSL_ITEM *attributes)
1364         {
1365         if (attributes)
1366                 {
1367                 struct attr_list_ctx_st *context =
1368                         (struct attr_list_ctx_st *)OPENSSL_malloc(sizeof(struct attr_list_ctx_st));
1369                 if (context)
1370                         context->attributes = attributes;
1371                 else
1372                         STOREerr(STORE_F_STORE_PARSE_ATTRS_END,
1373                                 ERR_R_MALLOC_FAILURE);
1374                 return context;
1375                 }
1376         STOREerr(STORE_F_STORE_PARSE_ATTRS_END, ERR_R_PASSED_NULL_PARAMETER);
1377         return 0;
1378         }
1379 STORE_ATTR_INFO *STORE_parse_attrs_next(void *handle)
1380         {
1381         struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle;
1382
1383         if (context && context->attributes)
1384                 {
1385                 STORE_ATTR_INFO *attrs = NULL;
1386
1387                 while(context->attributes
1388                         && context->attributes->code != STORE_ATTR_OR
1389                         && context->attributes->code != STORE_ATTR_END)
1390                         {
1391                         switch(context->attributes->code)
1392                                 {
1393                         case STORE_ATTR_FRIENDLYNAME:
1394                         case STORE_ATTR_EMAIL:
1395                         case STORE_ATTR_FILENAME:
1396                                 if (!attrs) attrs = STORE_ATTR_INFO_new();
1397                                 if (attrs == NULL)
1398                                         {
1399                                         STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT,
1400                                                 ERR_R_MALLOC_FAILURE);
1401                                         goto err;
1402                                         }
1403                                 STORE_ATTR_INFO_set_cstr(attrs,
1404                                         context->attributes->code,
1405                                         context->attributes->value,
1406                                         context->attributes->value_size);
1407                                 break;
1408                         case STORE_ATTR_KEYID:
1409                         case STORE_ATTR_ISSUERKEYID:
1410                         case STORE_ATTR_SUBJECTKEYID:
1411                         case STORE_ATTR_ISSUERSERIALHASH:
1412                         case STORE_ATTR_CERTHASH:
1413                                 if (!attrs) attrs = STORE_ATTR_INFO_new();
1414                                 if (attrs == NULL)
1415                                         {
1416                                         STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT,
1417                                                 ERR_R_MALLOC_FAILURE);
1418                                         goto err;
1419                                         }
1420                                 STORE_ATTR_INFO_set_sha1str(attrs,
1421                                         context->attributes->code,
1422                                         context->attributes->value,
1423                                         context->attributes->value_size);
1424                                 break;
1425                         case STORE_ATTR_ISSUER:
1426                         case STORE_ATTR_SUBJECT:
1427                                 if (!attrs) attrs = STORE_ATTR_INFO_new();
1428                                 if (attrs == NULL)
1429                                         {
1430                                         STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT,
1431                                                 ERR_R_MALLOC_FAILURE);
1432                                         goto err;
1433                                         }
1434                                 STORE_ATTR_INFO_modify_dn(attrs,
1435                                         context->attributes->code,
1436                                         context->attributes->value);
1437                                 break;
1438                         case STORE_ATTR_SERIAL:
1439                                 if (!attrs) attrs = STORE_ATTR_INFO_new();
1440                                 if (attrs == NULL)
1441                                         {
1442                                         STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT,
1443                                                 ERR_R_MALLOC_FAILURE);
1444                                         goto err;
1445                                         }
1446                                 STORE_ATTR_INFO_modify_number(attrs,
1447                                         context->attributes->code,
1448                                         context->attributes->value);
1449                                 break;
1450                                 }
1451                         context->attributes++;
1452                         }
1453                 if (context->attributes->code == STORE_ATTR_OR)
1454                         context->attributes++;
1455                 return attrs;
1456         err:
1457                 while(context->attributes
1458                         && context->attributes->code != STORE_ATTR_OR
1459                         && context->attributes->code != STORE_ATTR_END)
1460                         context->attributes++;
1461                 if (context->attributes->code == STORE_ATTR_OR)
1462                         context->attributes++;
1463                 return NULL;
1464                 }
1465         STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT, ERR_R_PASSED_NULL_PARAMETER);
1466         return NULL;
1467         }
1468 int STORE_parse_attrs_end(void *handle)
1469         {
1470         struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle;
1471
1472         if (context && context->attributes)
1473                 {
1474 #if 0
1475                 OPENSSL_ITEM *attributes = context->attributes;
1476 #endif
1477                 OPENSSL_free(context);
1478                 return 1;
1479                 }
1480         STOREerr(STORE_F_STORE_PARSE_ATTRS_END, ERR_R_PASSED_NULL_PARAMETER);
1481         return 0;
1482         }
1483
1484 int STORE_parse_attrs_endp(void *handle)
1485         {
1486         struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle;
1487
1488         if (context && context->attributes)
1489                 {
1490                 return context->attributes->code == STORE_ATTR_END;
1491                 }
1492         STOREerr(STORE_F_STORE_PARSE_ATTRS_END, ERR_R_PASSED_NULL_PARAMETER);
1493         return 0;
1494         }
1495
1496 int STORE_ATTR_INFO_compare(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
1497         {
1498         unsigned char *abits, *bbits;
1499         int i;
1500
1501         if (a == b) return 0;
1502         if (!a) return -1;
1503         if (!b) return 1;
1504         abits = a->set;
1505         bbits = b->set;
1506         for (i = 0; i < (STORE_ATTR_TYPE_NUM + 8) / 8; i++, abits++, bbits++)
1507                 {
1508                 if (*abits < *bbits) return -1;
1509                 if (*abits > *bbits) return 1;
1510                 }
1511         return 0;
1512         }
1513 int STORE_ATTR_INFO_in(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
1514         {
1515         unsigned char *abits, *bbits;
1516         int i;
1517
1518         if (a == b) return 1;
1519         if (!a) return 0;
1520         if (!b) return 0;
1521         abits = a->set;
1522         bbits = b->set;
1523         for (i = 0; i < (STORE_ATTR_TYPE_NUM + 8) / 8; i++, abits++, bbits++)
1524                 {
1525                 if (*abits && *bbits != *abits)
1526                         return 0;
1527                 }
1528         return 1;
1529         }
1530 int STORE_ATTR_INFO_in_ex(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
1531         {
1532         STORE_ATTR_TYPES i;
1533
1534         if (a == b) return 1;
1535         if (!STORE_ATTR_INFO_in(a, b)) return 0;
1536         for (i = 1; i < STORE_ATTR_TYPE_NUM; i++)
1537                 if (ATTR_IS_SET(a, i))
1538                         {
1539                         switch(i)
1540                                 {
1541                         case STORE_ATTR_FRIENDLYNAME:
1542                         case STORE_ATTR_EMAIL:
1543                         case STORE_ATTR_FILENAME:
1544                                 if (strcmp(a->values[i].cstring,
1545                                             b->values[i].cstring))
1546                                         return 0;
1547                                 break;
1548                         case STORE_ATTR_KEYID:
1549                         case STORE_ATTR_ISSUERKEYID:
1550                         case STORE_ATTR_SUBJECTKEYID:
1551                         case STORE_ATTR_ISSUERSERIALHASH:
1552                         case STORE_ATTR_CERTHASH:
1553                                 if (memcmp(a->values[i].sha1string,
1554                                             b->values[i].sha1string,
1555                                             a->value_sizes[i]))
1556                                         return 0;
1557                                 break;
1558                         case STORE_ATTR_ISSUER:
1559                         case STORE_ATTR_SUBJECT:
1560                                 if (X509_NAME_cmp(a->values[i].dn,
1561                                             b->values[i].dn))
1562                                         return 0;
1563                                 break;
1564                         case STORE_ATTR_SERIAL:
1565                                 if (BN_cmp(a->values[i].number,
1566                                             b->values[i].number))
1567                                         return 0;
1568                                 break;
1569                         default:
1570                                 break;
1571                                 }
1572                         }
1573
1574         return 1;
1575         }