It's usually best if the function name matches everywhere...
[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, BIGNUM *data, 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 STORE_OBJECT *STORE_OBJECT_new(void)
988         {
989         STORE_OBJECT *object = OPENSSL_malloc(sizeof(STORE_OBJECT));
990         if (object) memset(object, 0, sizeof(STORE_OBJECT));
991         return object;
992         }
993 void STORE_OBJECT_free(STORE_OBJECT *data)
994         {
995         if (!data) return;
996         switch (data->type)
997                 {
998         case STORE_OBJECT_TYPE_X509_CERTIFICATE:
999                 X509_free(data->data.x509.certificate);
1000                 break;
1001         case STORE_OBJECT_TYPE_X509_CRL:
1002                 X509_CRL_free(data->data.crl);
1003                 break;
1004         case STORE_OBJECT_TYPE_PRIVATE_KEY:
1005         case STORE_OBJECT_TYPE_PUBLIC_KEY:
1006                 EVP_PKEY_free(data->data.key);
1007                 break;
1008         case STORE_OBJECT_TYPE_NUMBER:
1009                 BN_free(data->data.number);
1010                 break;
1011                 }
1012         OPENSSL_free(data);
1013         }
1014
1015 IMPLEMENT_STACK_OF(STORE_OBJECT*);
1016
1017
1018 struct STORE_attr_info_st
1019         {
1020         unsigned char set[(STORE_ATTR_TYPE_NUM + 8) / 8];
1021         union
1022                 {
1023                 char *cstring;
1024                 unsigned char *sha1string;
1025                 X509_NAME *dn;
1026                 BIGNUM *number;
1027                 void *any;
1028                 } values[STORE_ATTR_TYPE_NUM+1];
1029         size_t value_sizes[STORE_ATTR_TYPE_NUM+1];
1030         };
1031
1032 #define ATTR_IS_SET(a,i)        ((i) > 0 && (i) < STORE_ATTR_TYPE_NUM \
1033                                 && ((a)->set[(i) / 8] & (1 << ((i) % 8))))
1034 #define SET_ATTRBIT(a,i)        ((a)->set[(i) / 8] |= (1 << ((i) % 8)))
1035 #define CLEAR_ATTRBIT(a,i)      ((a)->set[(i) / 8] &= ~(1 << ((i) % 8)))
1036
1037 STORE_ATTR_INFO *STORE_ATTR_INFO_new(void)
1038         {
1039         return (STORE_ATTR_INFO *)OPENSSL_malloc(sizeof(STORE_ATTR_INFO));
1040         }
1041 static void STORE_ATTR_INFO_attr_free(STORE_ATTR_INFO *attrs,
1042         STORE_ATTR_TYPES code)
1043         {
1044         if (ATTR_IS_SET(attrs,code))
1045                 {
1046                 switch(code)
1047                         {
1048                 case STORE_ATTR_FRIENDLYNAME:
1049                 case STORE_ATTR_EMAIL:
1050                 case STORE_ATTR_FILENAME:
1051                         STORE_ATTR_INFO_modify_cstr(attrs, code, NULL, 0);
1052                         break;
1053                 case STORE_ATTR_KEYID:
1054                 case STORE_ATTR_ISSUERKEYID:
1055                 case STORE_ATTR_SUBJECTKEYID:
1056                 case STORE_ATTR_ISSUERSERIALHASH:
1057                 case STORE_ATTR_CERTHASH:
1058                         STORE_ATTR_INFO_modify_sha1str(attrs, code, NULL, 0);
1059                         break;
1060                 case STORE_ATTR_ISSUER:
1061                 case STORE_ATTR_SUBJECT:
1062                         STORE_ATTR_INFO_modify_dn(attrs, code, NULL);
1063                         break;
1064                 case STORE_ATTR_SERIAL:
1065                         STORE_ATTR_INFO_modify_number(attrs, code, NULL);
1066                         break;
1067                 default:
1068                         break;
1069                         }
1070                 }
1071         }
1072 int STORE_ATTR_INFO_free(STORE_ATTR_INFO *attrs)
1073         {
1074         if (attrs)
1075                 {
1076                 STORE_ATTR_TYPES i;
1077                 for(i = 0; i++ < STORE_ATTR_TYPE_NUM;)
1078                         STORE_ATTR_INFO_attr_free(attrs, i);
1079                 OPENSSL_free(attrs);
1080                 }
1081         return 1;
1082         }
1083 char *STORE_ATTR_INFO_get0_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code)
1084         {
1085         if (!attrs)
1086                 {
1087                 STOREerr(STORE_F_STORE_ATTR_INFO_GET0_CSTR,
1088                         ERR_R_PASSED_NULL_PARAMETER);
1089                 return NULL;
1090                 }
1091         if (ATTR_IS_SET(attrs,code))
1092                 return attrs->values[code].cstring;
1093         STOREerr(STORE_F_STORE_ATTR_INFO_GET0_CSTR,
1094                 STORE_R_NO_VALUE);
1095         return NULL;
1096         }
1097 unsigned char *STORE_ATTR_INFO_get0_sha1str(STORE_ATTR_INFO *attrs,
1098         STORE_ATTR_TYPES code)
1099         {
1100         if (!attrs)
1101                 {
1102                 STOREerr(STORE_F_STORE_ATTR_INFO_GET0_SHA1STR,
1103                         ERR_R_PASSED_NULL_PARAMETER);
1104                 return NULL;
1105                 }
1106         if (ATTR_IS_SET(attrs,code))
1107                 return attrs->values[code].sha1string;
1108         STOREerr(STORE_F_STORE_ATTR_INFO_GET0_SHA1STR,
1109                 STORE_R_NO_VALUE);
1110         return NULL;
1111         }
1112 X509_NAME *STORE_ATTR_INFO_get0_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code)
1113         {
1114         if (!attrs)
1115                 {
1116                 STOREerr(STORE_F_STORE_ATTR_INFO_GET0_DN,
1117                         ERR_R_PASSED_NULL_PARAMETER);
1118                 return NULL;
1119                 }
1120         if (ATTR_IS_SET(attrs,code))
1121                 return attrs->values[code].dn;
1122         STOREerr(STORE_F_STORE_ATTR_INFO_GET0_DN,
1123                 STORE_R_NO_VALUE);
1124         return NULL;
1125         }
1126 BIGNUM *STORE_ATTR_INFO_get0_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code)
1127         {
1128         if (!attrs)
1129                 {
1130                 STOREerr(STORE_F_STORE_ATTR_INFO_GET0_NUMBER,
1131                         ERR_R_PASSED_NULL_PARAMETER);
1132                 return NULL;
1133                 }
1134         if (ATTR_IS_SET(attrs,code))
1135                 return attrs->values[code].number;
1136         STOREerr(STORE_F_STORE_ATTR_INFO_GET0_NUMBER,
1137                 STORE_R_NO_VALUE);
1138         return NULL;
1139         }
1140 int STORE_ATTR_INFO_set_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1141         char *cstr, size_t cstr_size)
1142         {
1143         if (!attrs)
1144                 {
1145                 STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR,
1146                         ERR_R_PASSED_NULL_PARAMETER);
1147                 return 0;
1148                 }
1149         if (!ATTR_IS_SET(attrs,code))
1150                 {
1151                 if ((attrs->values[code].cstring = BUF_strndup(cstr, cstr_size)))
1152                         return 1;
1153                 STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR,
1154                         ERR_R_MALLOC_FAILURE);
1155                 return 0;
1156                 }
1157         STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR, STORE_R_ALREADY_HAS_A_VALUE);
1158         return 0;
1159         }
1160 int STORE_ATTR_INFO_set_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1161         unsigned char *sha1str, size_t sha1str_size)
1162         {
1163         if (!attrs)
1164                 {
1165                 STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR,
1166                         ERR_R_PASSED_NULL_PARAMETER);
1167                 return 0;
1168                 }
1169         if (!ATTR_IS_SET(attrs,code))
1170                 {
1171                 if ((attrs->values[code].sha1string =
1172                             (unsigned char *)BUF_memdup(sha1str,
1173                                     sha1str_size)))
1174                         return 1;
1175                 STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR,
1176                         ERR_R_MALLOC_FAILURE);
1177                 return 0;
1178                 }
1179         STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR, STORE_R_ALREADY_HAS_A_VALUE);
1180         return 0;
1181         }
1182 int STORE_ATTR_INFO_set_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1183         X509_NAME *dn)
1184         {
1185         if (!attrs)
1186                 {
1187                 STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN,
1188                         ERR_R_PASSED_NULL_PARAMETER);
1189                 return 0;
1190                 }
1191         if (!ATTR_IS_SET(attrs,code))
1192                 {
1193                 if ((attrs->values[code].dn = X509_NAME_dup(dn)))
1194                         return 1;
1195                 STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR,
1196                         ERR_R_MALLOC_FAILURE);
1197                 return 0;
1198                 }
1199         STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN, STORE_R_ALREADY_HAS_A_VALUE);
1200         return 0;
1201         }
1202 int STORE_ATTR_INFO_set_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1203         BIGNUM *number)
1204         {
1205         if (!attrs)
1206                 {
1207                 STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER,
1208                         ERR_R_PASSED_NULL_PARAMETER);
1209                 return 0;
1210                 }
1211         if (!ATTR_IS_SET(attrs,code))
1212                 {
1213                 if ((attrs->values[code].number = BN_dup(number)))
1214                         return 1;
1215                 STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR,
1216                         ERR_R_MALLOC_FAILURE);
1217                 return 0;
1218                 }
1219         STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER, STORE_R_ALREADY_HAS_A_VALUE);
1220         return 0;
1221         }
1222 int STORE_ATTR_INFO_modify_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1223         char *cstr, size_t cstr_size)
1224         {
1225         if (!attrs)
1226                 {
1227                 STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_CSTR,
1228                         ERR_R_PASSED_NULL_PARAMETER);
1229                 return 0;
1230                 }
1231         if (ATTR_IS_SET(attrs,code))
1232                 {
1233                 OPENSSL_free(attrs->values[code].cstring);
1234                 attrs->values[code].cstring = NULL;
1235                 CLEAR_ATTRBIT(attrs, code);
1236                 }
1237         return STORE_ATTR_INFO_set_cstr(attrs, code, cstr, cstr_size);
1238         }
1239 int STORE_ATTR_INFO_modify_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1240         unsigned char *sha1str, size_t sha1str_size)
1241         {
1242         if (!attrs)
1243                 {
1244                 STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_SHA1STR,
1245                         ERR_R_PASSED_NULL_PARAMETER);
1246                 return 0;
1247                 }
1248         if (ATTR_IS_SET(attrs,code))
1249                 {
1250                 OPENSSL_free(attrs->values[code].sha1string);
1251                 attrs->values[code].sha1string = NULL;
1252                 CLEAR_ATTRBIT(attrs, code);
1253                 }
1254         return STORE_ATTR_INFO_set_sha1str(attrs, code, sha1str, sha1str_size);
1255         }
1256 int STORE_ATTR_INFO_modify_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1257         X509_NAME *dn)
1258         {
1259         if (!attrs)
1260                 {
1261                 STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_DN,
1262                         ERR_R_PASSED_NULL_PARAMETER);
1263                 return 0;
1264                 }
1265         if (ATTR_IS_SET(attrs,code))
1266                 {
1267                 OPENSSL_free(attrs->values[code].dn);
1268                 attrs->values[code].dn = NULL;
1269                 CLEAR_ATTRBIT(attrs, code);
1270                 }
1271         return STORE_ATTR_INFO_set_dn(attrs, code, dn);
1272         }
1273 int STORE_ATTR_INFO_modify_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
1274         BIGNUM *number)
1275         {
1276         if (!attrs)
1277                 {
1278                 STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_NUMBER,
1279                         ERR_R_PASSED_NULL_PARAMETER);
1280                 return 0;
1281                 }
1282         if (ATTR_IS_SET(attrs,code))
1283                 {
1284                 OPENSSL_free(attrs->values[code].number);
1285                 attrs->values[code].number = NULL;
1286                 CLEAR_ATTRBIT(attrs, code);
1287                 }
1288         return STORE_ATTR_INFO_set_number(attrs, code, number);
1289         }
1290
1291 struct attr_list_ctx_st
1292         {
1293         OPENSSL_ITEM *attributes;
1294         };
1295 void *STORE_parse_attrs_start(OPENSSL_ITEM *attributes)
1296         {
1297         if (attributes)
1298                 {
1299                 struct attr_list_ctx_st *context =
1300                         (struct attr_list_ctx_st *)OPENSSL_malloc(sizeof(struct attr_list_ctx_st));
1301                 if (context)
1302                         context->attributes = attributes;
1303                 else
1304                         STOREerr(STORE_F_STORE_PARSE_ATTRS_END,
1305                                 ERR_R_MALLOC_FAILURE);
1306                 return context;
1307                 }
1308         STOREerr(STORE_F_STORE_PARSE_ATTRS_END, ERR_R_PASSED_NULL_PARAMETER);
1309         return 0;
1310         }
1311 STORE_ATTR_INFO *STORE_parse_attrs_next(void *handle)
1312         {
1313         struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle;
1314
1315         if (context && context->attributes)
1316                 {
1317                 STORE_ATTR_INFO *attrs = NULL;
1318
1319                 while(context->attributes
1320                         && context->attributes->code != STORE_ATTR_OR
1321                         && context->attributes->code != STORE_ATTR_END)
1322                         {
1323                         switch(context->attributes->code)
1324                                 {
1325                         case STORE_ATTR_FRIENDLYNAME:
1326                         case STORE_ATTR_EMAIL:
1327                         case STORE_ATTR_FILENAME:
1328                                 if (!attrs) attrs = STORE_ATTR_INFO_new();
1329                                 if (attrs == NULL)
1330                                         {
1331                                         STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT,
1332                                                 ERR_R_MALLOC_FAILURE);
1333                                         goto err;
1334                                         }
1335                                 STORE_ATTR_INFO_set_cstr(attrs,
1336                                         context->attributes->code,
1337                                         context->attributes->value,
1338                                         context->attributes->value_size);
1339                                 break;
1340                         case STORE_ATTR_KEYID:
1341                         case STORE_ATTR_ISSUERKEYID:
1342                         case STORE_ATTR_SUBJECTKEYID:
1343                         case STORE_ATTR_ISSUERSERIALHASH:
1344                         case STORE_ATTR_CERTHASH:
1345                                 if (!attrs) attrs = STORE_ATTR_INFO_new();
1346                                 if (attrs == NULL)
1347                                         {
1348                                         STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT,
1349                                                 ERR_R_MALLOC_FAILURE);
1350                                         goto err;
1351                                         }
1352                                 STORE_ATTR_INFO_set_sha1str(attrs,
1353                                         context->attributes->code,
1354                                         context->attributes->value,
1355                                         context->attributes->value_size);
1356                                 break;
1357                         case STORE_ATTR_ISSUER:
1358                         case STORE_ATTR_SUBJECT:
1359                                 if (!attrs) attrs = STORE_ATTR_INFO_new();
1360                                 if (attrs == NULL)
1361                                         {
1362                                         STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT,
1363                                                 ERR_R_MALLOC_FAILURE);
1364                                         goto err;
1365                                         }
1366                                 STORE_ATTR_INFO_modify_dn(attrs,
1367                                         context->attributes->code,
1368                                         context->attributes->value);
1369                                 break;
1370                         case STORE_ATTR_SERIAL:
1371                                 if (!attrs) attrs = STORE_ATTR_INFO_new();
1372                                 if (attrs == NULL)
1373                                         {
1374                                         STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT,
1375                                                 ERR_R_MALLOC_FAILURE);
1376                                         goto err;
1377                                         }
1378                                 STORE_ATTR_INFO_modify_number(attrs,
1379                                         context->attributes->code,
1380                                         context->attributes->value);
1381                                 break;
1382                                 }
1383                         context->attributes++;
1384                         }
1385                 if (context->attributes->code == STORE_ATTR_OR)
1386                         context->attributes++;
1387                 return attrs;
1388         err:
1389                 while(context->attributes
1390                         && context->attributes->code != STORE_ATTR_OR
1391                         && context->attributes->code != STORE_ATTR_END)
1392                         context->attributes++;
1393                 if (context->attributes->code == STORE_ATTR_OR)
1394                         context->attributes++;
1395                 return NULL;
1396                 }
1397         STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT, ERR_R_PASSED_NULL_PARAMETER);
1398         return NULL;
1399         }
1400 int STORE_parse_attrs_end(void *handle)
1401         {
1402         struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle;
1403
1404         if (context && context->attributes)
1405                 {
1406 #if 0
1407                 OPENSSL_ITEM *attributes = context->attributes;
1408 #endif
1409                 OPENSSL_free(context);
1410                 return 1;
1411                 }
1412         STOREerr(STORE_F_STORE_PARSE_ATTRS_END, ERR_R_PASSED_NULL_PARAMETER);
1413         return 0;
1414         }
1415
1416 int STORE_parse_attrs_endp(void *handle)
1417         {
1418         struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle;
1419
1420         if (context && context->attributes)
1421                 {
1422                 return context->attributes->code == STORE_ATTR_END;
1423                 }
1424         STOREerr(STORE_F_STORE_PARSE_ATTRS_END, ERR_R_PASSED_NULL_PARAMETER);
1425         return 0;
1426         }
1427
1428 int STORE_ATTR_INFO_compare(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
1429         {
1430         unsigned char *abits, *bbits;
1431         int i;
1432
1433         if (a == b) return 0;
1434         if (!a) return -1;
1435         if (!b) return 1;
1436         abits = a->set;
1437         bbits = b->set;
1438         for (i = 0; i < (STORE_ATTR_TYPE_NUM + 8) / 8; i++, abits++, bbits++)
1439                 {
1440                 if (*abits < *bbits) return -1;
1441                 if (*abits > *bbits) return 1;
1442                 }
1443         return 0;
1444         }
1445 int STORE_ATTR_INFO_in(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
1446         {
1447         unsigned char *abits, *bbits;
1448         int i;
1449
1450         if (a == b) return 1;
1451         if (!a) return 0;
1452         if (!b) return 0;
1453         abits = a->set;
1454         bbits = b->set;
1455         for (i = 0; i < (STORE_ATTR_TYPE_NUM + 8) / 8; i++, abits++, bbits++)
1456                 {
1457                 if (*abits && *bbits != *abits)
1458                         return 0;
1459                 }
1460         return 1;
1461         }
1462 int STORE_ATTR_INFO_in_ex(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
1463         {
1464         STORE_ATTR_TYPES i;
1465
1466         if (a == b) return 1;
1467         if (!STORE_ATTR_INFO_in(a, b)) return 0;
1468         for (i = 1; i < STORE_ATTR_TYPE_NUM; i++)
1469                 if (ATTR_IS_SET(a, i))
1470                         {
1471                         switch(i)
1472                                 {
1473                         case STORE_ATTR_FRIENDLYNAME:
1474                         case STORE_ATTR_EMAIL:
1475                         case STORE_ATTR_FILENAME:
1476                                 if (strcmp(a->values[i].cstring,
1477                                             b->values[i].cstring))
1478                                         return 0;
1479                                 break;
1480                         case STORE_ATTR_KEYID:
1481                         case STORE_ATTR_ISSUERKEYID:
1482                         case STORE_ATTR_SUBJECTKEYID:
1483                         case STORE_ATTR_ISSUERSERIALHASH:
1484                         case STORE_ATTR_CERTHASH:
1485                                 if (memcmp(a->values[i].sha1string,
1486                                             b->values[i].sha1string,
1487                                             a->value_sizes[i]))
1488                                         return 0;
1489                                 break;
1490                         case STORE_ATTR_ISSUER:
1491                         case STORE_ATTR_SUBJECT:
1492                                 if (X509_NAME_cmp(a->values[i].dn,
1493                                             b->values[i].dn))
1494                                         return 0;
1495                                 break;
1496                         case STORE_ATTR_SERIAL:
1497                                 if (BN_cmp(a->values[i].number,
1498                                             b->values[i].number))
1499                                         return 0;
1500                                 break;
1501                         default:
1502                                 break;
1503                                 }
1504                         }
1505
1506         return 1;
1507         }