libndr: Avoid assigning duplicate versions to symbols
[amitay/samba.git] / source4 / heimdal / lib / hx509 / cert.c
1 /*
2  * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the Institute nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 #include "hx_locl.h"
35 #include "crypto-headers.h"
36 #include <rtbl.h>
37
38 /**
39  * @page page_cert The basic certificate
40  *
41  * The basic hx509 cerificate object in hx509 is hx509_cert. The
42  * hx509_cert object is representing one X509/PKIX certificate and
43  * associated attributes; like private key, friendly name, etc.
44  *
45  * A hx509_cert object is usully found via the keyset interfaces (@ref
46  * page_keyset), but its also possible to create a certificate
47  * directly from a parsed object with hx509_cert_init() and
48  * hx509_cert_init_data().
49  *
50  * See the library functions here: @ref hx509_cert
51  */
52
53 struct hx509_verify_ctx_data {
54     hx509_certs trust_anchors;
55     int flags;
56 #define HX509_VERIFY_CTX_F_TIME_SET                     1
57 #define HX509_VERIFY_CTX_F_ALLOW_PROXY_CERTIFICATE      2
58 #define HX509_VERIFY_CTX_F_REQUIRE_RFC3280              4
59 #define HX509_VERIFY_CTX_F_CHECK_TRUST_ANCHORS          8
60 #define HX509_VERIFY_CTX_F_NO_DEFAULT_ANCHORS           16
61 #define HX509_VERIFY_CTX_F_NO_BEST_BEFORE_CHECK         32
62     time_t time_now;
63     unsigned int max_depth;
64 #define HX509_VERIFY_MAX_DEPTH 30
65     hx509_revoke_ctx revoke_ctx;
66 };
67
68 #define REQUIRE_RFC3280(ctx) ((ctx)->flags & HX509_VERIFY_CTX_F_REQUIRE_RFC3280)
69 #define CHECK_TA(ctx) ((ctx)->flags & HX509_VERIFY_CTX_F_CHECK_TRUST_ANCHORS)
70 #define ALLOW_DEF_TA(ctx) (((ctx)->flags & HX509_VERIFY_CTX_F_NO_DEFAULT_ANCHORS) == 0)
71
72 struct _hx509_cert_attrs {
73     size_t len;
74     hx509_cert_attribute *val;
75 };
76
77 struct hx509_cert_data {
78     unsigned int ref;
79     char *friendlyname;
80     Certificate *data;
81     hx509_private_key private_key;
82     struct _hx509_cert_attrs attrs;
83     hx509_name basename;
84     _hx509_cert_release_func release;
85     void *ctx;
86 };
87
88 typedef struct hx509_name_constraints {
89     NameConstraints *val;
90     size_t len;
91 } hx509_name_constraints;
92
93 #define GeneralSubtrees_SET(g,var) \
94         (g)->len = (var)->len, (g)->val = (var)->val;
95
96 /**
97  * Creates a hx509 context that most functions in the library
98  * uses. The context is only allowed to be used by one thread at each
99  * moment. Free the context with hx509_context_free().
100  *
101  * @param context Returns a pointer to new hx509 context.
102  *
103  * @return Returns an hx509 error code.
104  *
105  * @ingroup hx509
106  */
107
108 int
109 hx509_context_init(hx509_context *context)
110 {
111     *context = calloc(1, sizeof(**context));
112     if (*context == NULL)
113         return ENOMEM;
114
115     _hx509_ks_null_register(*context);
116     _hx509_ks_mem_register(*context);
117     _hx509_ks_file_register(*context);
118     _hx509_ks_pkcs12_register(*context);
119     _hx509_ks_pkcs11_register(*context);
120     _hx509_ks_dir_register(*context);
121     _hx509_ks_keychain_register(*context);
122
123     ENGINE_add_conf_module();
124     OpenSSL_add_all_algorithms();
125
126     (*context)->ocsp_time_diff = HX509_DEFAULT_OCSP_TIME_DIFF;
127
128     initialize_hx_error_table_r(&(*context)->et_list);
129     initialize_asn1_error_table_r(&(*context)->et_list);
130
131 #ifdef HX509_DEFAULT_ANCHORS
132     (void)hx509_certs_init(*context, HX509_DEFAULT_ANCHORS, 0,
133                            NULL, &(*context)->default_trust_anchors);
134 #endif
135
136     return 0;
137 }
138
139 /**
140  * Selects if the hx509_revoke_verify() function is going to require
141  * the existans of a revokation method (OCSP, CRL) or not. Note that
142  * hx509_verify_path(), hx509_cms_verify_signed(), and other function
143  * call hx509_revoke_verify().
144  *
145  * @param context hx509 context to change the flag for.
146  * @param flag zero, revokation method required, non zero missing
147  * revokation method ok
148  *
149  * @ingroup hx509_verify
150  */
151
152 void
153 hx509_context_set_missing_revoke(hx509_context context, int flag)
154 {
155     if (flag)
156         context->flags |= HX509_CTX_VERIFY_MISSING_OK;
157     else
158         context->flags &= ~HX509_CTX_VERIFY_MISSING_OK;
159 }
160
161 /**
162  * Free the context allocated by hx509_context_init().
163  *
164  * @param context context to be freed.
165  *
166  * @ingroup hx509
167  */
168
169 void
170 hx509_context_free(hx509_context *context)
171 {
172     hx509_clear_error_string(*context);
173     if ((*context)->ks_ops) {
174         free((*context)->ks_ops);
175         (*context)->ks_ops = NULL;
176     }
177     (*context)->ks_num_ops = 0;
178     free_error_table ((*context)->et_list);
179     if ((*context)->querystat)
180         free((*context)->querystat);
181     memset(*context, 0, sizeof(**context));
182     free(*context);
183     *context = NULL;
184 }
185
186 /*
187  *
188  */
189
190 Certificate *
191 _hx509_get_cert(hx509_cert cert)
192 {
193     return cert->data;
194 }
195
196 /*
197  *
198  */
199
200 int
201 _hx509_cert_get_version(const Certificate *t)
202 {
203     return t->tbsCertificate.version ? *t->tbsCertificate.version + 1 : 1;
204 }
205
206 /**
207  * Allocate and init an hx509 certificate object from the decoded
208  * certificate `c´.
209  *
210  * @param context A hx509 context.
211  * @param c
212  * @param cert
213  *
214  * @return Returns an hx509 error code.
215  *
216  * @ingroup hx509_cert
217  */
218
219 int
220 hx509_cert_init(hx509_context context, const Certificate *c, hx509_cert *cert)
221 {
222     int ret;
223
224     *cert = malloc(sizeof(**cert));
225     if (*cert == NULL)
226         return ENOMEM;
227     (*cert)->ref = 1;
228     (*cert)->friendlyname = NULL;
229     (*cert)->attrs.len = 0;
230     (*cert)->attrs.val = NULL;
231     (*cert)->private_key = NULL;
232     (*cert)->basename = NULL;
233     (*cert)->release = NULL;
234     (*cert)->ctx = NULL;
235
236     (*cert)->data = calloc(1, sizeof(*(*cert)->data));
237     if ((*cert)->data == NULL) {
238         free(*cert);
239         return ENOMEM;
240     }
241     ret = copy_Certificate(c, (*cert)->data);
242     if (ret) {
243         free((*cert)->data);
244         free(*cert);
245         *cert = NULL;
246     }
247     return ret;
248 }
249
250 /**
251  * Just like hx509_cert_init(), but instead of a decode certificate
252  * takes an pointer and length to a memory region that contains a
253  * DER/BER encoded certificate.
254  *
255  * If the memory region doesn't contain just the certificate and
256  * nothing more the function will fail with
257  * HX509_EXTRA_DATA_AFTER_STRUCTURE.
258  *
259  * @param context A hx509 context.
260  * @param ptr pointer to memory region containing encoded certificate.
261  * @param len length of memory region.
262  * @param cert a return pointer to a hx509 certificate object, will
263  * contain NULL on error.
264  *
265  * @return An hx509 error code, see hx509_get_error_string().
266  *
267  * @ingroup hx509_cert
268  */
269
270 int
271 hx509_cert_init_data(hx509_context context,
272                      const void *ptr,
273                      size_t len,
274                      hx509_cert *cert)
275 {
276     Certificate t;
277     size_t size;
278     int ret;
279
280     ret = decode_Certificate(ptr, len, &t, &size);
281     if (ret) {
282         hx509_set_error_string(context, 0, ret, "Failed to decode certificate");
283         return ret;
284     }
285     if (size != len) {
286         free_Certificate(&t);
287         hx509_set_error_string(context, 0, HX509_EXTRA_DATA_AFTER_STRUCTURE,
288                                "Extra data after certificate");
289         return HX509_EXTRA_DATA_AFTER_STRUCTURE;
290     }
291
292     ret = hx509_cert_init(context, &t, cert);
293     free_Certificate(&t);
294     return ret;
295 }
296
297 void
298 _hx509_cert_set_release(hx509_cert cert,
299                         _hx509_cert_release_func release,
300                         void *ctx)
301 {
302     cert->release = release;
303     cert->ctx = ctx;
304 }
305
306
307 /* Doesn't make a copy of `private_key'. */
308
309 int
310 _hx509_cert_assign_key(hx509_cert cert, hx509_private_key private_key)
311 {
312     if (cert->private_key)
313         hx509_private_key_free(&cert->private_key);
314     cert->private_key = _hx509_private_key_ref(private_key);
315     return 0;
316 }
317
318 /**
319  * Free reference to the hx509 certificate object, if the refcounter
320  * reaches 0, the object if freed. Its allowed to pass in NULL.
321  *
322  * @param cert the cert to free.
323  *
324  * @ingroup hx509_cert
325  */
326
327 void
328 hx509_cert_free(hx509_cert cert)
329 {
330     size_t i;
331
332     if (cert == NULL)
333         return;
334
335     if (cert->ref <= 0)
336         _hx509_abort("cert refcount <= 0 on free");
337     if (--cert->ref > 0)
338         return;
339
340     if (cert->release)
341         (cert->release)(cert, cert->ctx);
342
343     if (cert->private_key)
344         hx509_private_key_free(&cert->private_key);
345
346     free_Certificate(cert->data);
347     free(cert->data);
348
349     for (i = 0; i < cert->attrs.len; i++) {
350         der_free_octet_string(&cert->attrs.val[i]->data);
351         der_free_oid(&cert->attrs.val[i]->oid);
352         free(cert->attrs.val[i]);
353     }
354     free(cert->attrs.val);
355     free(cert->friendlyname);
356     if (cert->basename)
357         hx509_name_free(&cert->basename);
358     memset(cert, 0, sizeof(*cert));
359     free(cert);
360 }
361
362 /**
363  * Add a reference to a hx509 certificate object.
364  *
365  * @param cert a pointer to an hx509 certificate object.
366  *
367  * @return the same object as is passed in.
368  *
369  * @ingroup hx509_cert
370  */
371
372 hx509_cert
373 hx509_cert_ref(hx509_cert cert)
374 {
375     if (cert == NULL)
376         return NULL;
377     if (cert->ref <= 0)
378         _hx509_abort("cert refcount <= 0");
379     cert->ref++;
380     if (cert->ref == 0)
381         _hx509_abort("cert refcount == 0");
382     return cert;
383 }
384
385 /**
386  * Allocate an verification context that is used fo control the
387  * verification process.
388  *
389  * @param context A hx509 context.
390  * @param ctx returns a pointer to a hx509_verify_ctx object.
391  *
392  * @return An hx509 error code, see hx509_get_error_string().
393  *
394  * @ingroup hx509_verify
395  */
396
397 int
398 hx509_verify_init_ctx(hx509_context context, hx509_verify_ctx *ctx)
399 {
400     hx509_verify_ctx c;
401
402     c = calloc(1, sizeof(*c));
403     if (c == NULL)
404         return ENOMEM;
405
406     c->max_depth = HX509_VERIFY_MAX_DEPTH;
407
408     *ctx = c;
409
410     return 0;
411 }
412
413 /**
414  * Free an hx509 verification context.
415  *
416  * @param ctx the context to be freed.
417  *
418  * @ingroup hx509_verify
419  */
420
421 void
422 hx509_verify_destroy_ctx(hx509_verify_ctx ctx)
423 {
424     if (ctx) {
425         hx509_certs_free(&ctx->trust_anchors);
426         hx509_revoke_free(&ctx->revoke_ctx);
427         memset(ctx, 0, sizeof(*ctx));
428     }
429     free(ctx);
430 }
431
432 /**
433  * Set the trust anchors in the verification context, makes an
434  * reference to the keyset, so the consumer can free the keyset
435  * independent of the destruction of the verification context (ctx).
436  * If there already is a keyset attached, it's released.
437  *
438  * @param ctx a verification context
439  * @param set a keyset containing the trust anchors.
440  *
441  * @ingroup hx509_verify
442  */
443
444 void
445 hx509_verify_attach_anchors(hx509_verify_ctx ctx, hx509_certs set)
446 {
447     if (ctx->trust_anchors)
448         hx509_certs_free(&ctx->trust_anchors);
449     ctx->trust_anchors = hx509_certs_ref(set);
450 }
451
452 /**
453  * Attach an revocation context to the verfication context, , makes an
454  * reference to the revoke context, so the consumer can free the
455  * revoke context independent of the destruction of the verification
456  * context. If there is no revoke context, the verification process is
457  * NOT going to check any verification status.
458  *
459  * @param ctx a verification context.
460  * @param revoke_ctx a revoke context.
461  *
462  * @ingroup hx509_verify
463  */
464
465 void
466 hx509_verify_attach_revoke(hx509_verify_ctx ctx, hx509_revoke_ctx revoke_ctx)
467 {
468     if (ctx->revoke_ctx)
469         hx509_revoke_free(&ctx->revoke_ctx);
470     ctx->revoke_ctx = _hx509_revoke_ref(revoke_ctx);
471 }
472
473 /**
474  * Set the clock time the the verification process is going to
475  * use. Used to check certificate in the past and future time. If not
476  * set the current time will be used.
477  *
478  * @param ctx a verification context.
479  * @param t the time the verifiation is using.
480  *
481  *
482  * @ingroup hx509_verify
483  */
484
485 void
486 hx509_verify_set_time(hx509_verify_ctx ctx, time_t t)
487 {
488     ctx->flags |= HX509_VERIFY_CTX_F_TIME_SET;
489     ctx->time_now = t;
490 }
491
492 time_t
493 _hx509_verify_get_time(hx509_verify_ctx ctx)
494 {
495     return ctx->time_now;
496 }
497
498 /**
499  * Set the maximum depth of the certificate chain that the path
500  * builder is going to try.
501  *
502  * @param ctx a verification context
503  * @param max_depth maxium depth of the certificate chain, include
504  * trust anchor.
505  *
506  * @ingroup hx509_verify
507  */
508
509 void
510 hx509_verify_set_max_depth(hx509_verify_ctx ctx, unsigned int max_depth)
511 {
512     ctx->max_depth = max_depth;
513 }
514
515 /**
516  * Allow or deny the use of proxy certificates
517  *
518  * @param ctx a verification context
519  * @param boolean if non zero, allow proxy certificates.
520  *
521  * @ingroup hx509_verify
522  */
523
524 void
525 hx509_verify_set_proxy_certificate(hx509_verify_ctx ctx, int boolean)
526 {
527     if (boolean)
528         ctx->flags |= HX509_VERIFY_CTX_F_ALLOW_PROXY_CERTIFICATE;
529     else
530         ctx->flags &= ~HX509_VERIFY_CTX_F_ALLOW_PROXY_CERTIFICATE;
531 }
532
533 /**
534  * Select strict RFC3280 verification of certificiates. This means
535  * checking key usage on CA certificates, this will make version 1
536  * certificiates unuseable.
537  *
538  * @param ctx a verification context
539  * @param boolean if non zero, use strict verification.
540  *
541  * @ingroup hx509_verify
542  */
543
544 void
545 hx509_verify_set_strict_rfc3280_verification(hx509_verify_ctx ctx, int boolean)
546 {
547     if (boolean)
548         ctx->flags |= HX509_VERIFY_CTX_F_REQUIRE_RFC3280;
549     else
550         ctx->flags &= ~HX509_VERIFY_CTX_F_REQUIRE_RFC3280;
551 }
552
553 /**
554  * Allow using the operating system builtin trust anchors if no other
555  * trust anchors are configured.
556  *
557  * @param ctx a verification context
558  * @param boolean if non zero, useing the operating systems builtin
559  * trust anchors.
560  *
561  *
562  * @return An hx509 error code, see hx509_get_error_string().
563  *
564  * @ingroup hx509_cert
565  */
566
567 void
568 hx509_verify_ctx_f_allow_default_trustanchors(hx509_verify_ctx ctx, int boolean)
569 {
570     if (boolean)
571         ctx->flags &= ~HX509_VERIFY_CTX_F_NO_DEFAULT_ANCHORS;
572     else
573         ctx->flags |= HX509_VERIFY_CTX_F_NO_DEFAULT_ANCHORS;
574 }
575
576 void
577 hx509_verify_ctx_f_allow_best_before_signature_algs(hx509_context ctx,
578                                                     int boolean)
579 {
580     if (boolean)
581         ctx->flags &= ~HX509_VERIFY_CTX_F_NO_BEST_BEFORE_CHECK;
582     else
583         ctx->flags |= HX509_VERIFY_CTX_F_NO_BEST_BEFORE_CHECK;
584 }
585
586 static const Extension *
587 find_extension(const Certificate *cert, const heim_oid *oid, size_t *idx)
588 {
589     const TBSCertificate *c = &cert->tbsCertificate;
590
591     if (c->version == NULL || *c->version < 2 || c->extensions == NULL)
592         return NULL;
593
594     for (;*idx < c->extensions->len; (*idx)++) {
595         if (der_heim_oid_cmp(&c->extensions->val[*idx].extnID, oid) == 0)
596             return &c->extensions->val[(*idx)++];
597     }
598     return NULL;
599 }
600
601 static int
602 find_extension_auth_key_id(const Certificate *subject,
603                            AuthorityKeyIdentifier *ai)
604 {
605     const Extension *e;
606     size_t size;
607     size_t i = 0;
608
609     memset(ai, 0, sizeof(*ai));
610
611     e = find_extension(subject, &asn1_oid_id_x509_ce_authorityKeyIdentifier, &i);
612     if (e == NULL)
613         return HX509_EXTENSION_NOT_FOUND;
614
615     return decode_AuthorityKeyIdentifier(e->extnValue.data,
616                                          e->extnValue.length,
617                                          ai, &size);
618 }
619
620 int
621 _hx509_find_extension_subject_key_id(const Certificate *issuer,
622                                      SubjectKeyIdentifier *si)
623 {
624     const Extension *e;
625     size_t size;
626     size_t i = 0;
627
628     memset(si, 0, sizeof(*si));
629
630     e = find_extension(issuer, &asn1_oid_id_x509_ce_subjectKeyIdentifier, &i);
631     if (e == NULL)
632         return HX509_EXTENSION_NOT_FOUND;
633
634     return decode_SubjectKeyIdentifier(e->extnValue.data,
635                                        e->extnValue.length,
636                                        si, &size);
637 }
638
639 static int
640 find_extension_name_constraints(const Certificate *subject,
641                                 NameConstraints *nc)
642 {
643     const Extension *e;
644     size_t size;
645     size_t i = 0;
646
647     memset(nc, 0, sizeof(*nc));
648
649     e = find_extension(subject, &asn1_oid_id_x509_ce_nameConstraints, &i);
650     if (e == NULL)
651         return HX509_EXTENSION_NOT_FOUND;
652
653     return decode_NameConstraints(e->extnValue.data,
654                                   e->extnValue.length,
655                                   nc, &size);
656 }
657
658 static int
659 find_extension_subject_alt_name(const Certificate *cert, size_t *i,
660                                 GeneralNames *sa)
661 {
662     const Extension *e;
663     size_t size;
664
665     memset(sa, 0, sizeof(*sa));
666
667     e = find_extension(cert, &asn1_oid_id_x509_ce_subjectAltName, i);
668     if (e == NULL)
669         return HX509_EXTENSION_NOT_FOUND;
670
671     return decode_GeneralNames(e->extnValue.data,
672                                e->extnValue.length,
673                                sa, &size);
674 }
675
676 static int
677 find_extension_eku(const Certificate *cert, ExtKeyUsage *eku)
678 {
679     const Extension *e;
680     size_t size;
681     size_t i = 0;
682
683     memset(eku, 0, sizeof(*eku));
684
685     e = find_extension(cert, &asn1_oid_id_x509_ce_extKeyUsage, &i);
686     if (e == NULL)
687         return HX509_EXTENSION_NOT_FOUND;
688
689     return decode_ExtKeyUsage(e->extnValue.data,
690                               e->extnValue.length,
691                               eku, &size);
692 }
693
694 static int
695 add_to_list(hx509_octet_string_list *list, const heim_octet_string *entry)
696 {
697     void *p;
698     int ret;
699
700     p = realloc(list->val, (list->len + 1) * sizeof(list->val[0]));
701     if (p == NULL)
702         return ENOMEM;
703     list->val = p;
704     ret = der_copy_octet_string(entry, &list->val[list->len]);
705     if (ret)
706         return ret;
707     list->len++;
708     return 0;
709 }
710
711 /**
712  * Free a list of octet strings returned by another hx509 library
713  * function.
714  *
715  * @param list list to be freed.
716  *
717  * @ingroup hx509_misc
718  */
719
720 void
721 hx509_free_octet_string_list(hx509_octet_string_list *list)
722 {
723     size_t i;
724     for (i = 0; i < list->len; i++)
725         der_free_octet_string(&list->val[i]);
726     free(list->val);
727     list->val = NULL;
728     list->len = 0;
729 }
730
731 /**
732  * Return a list of subjectAltNames specified by oid in the
733  * certificate. On error the
734  *
735  * The returned list of octet string should be freed with
736  * hx509_free_octet_string_list().
737  *
738  * @param context A hx509 context.
739  * @param cert a hx509 certificate object.
740  * @param oid an oid to for SubjectAltName.
741  * @param list list of matching SubjectAltName.
742  *
743  * @return An hx509 error code, see hx509_get_error_string().
744  *
745  * @ingroup hx509_cert
746  */
747
748 int
749 hx509_cert_find_subjectAltName_otherName(hx509_context context,
750                                          hx509_cert cert,
751                                          const heim_oid *oid,
752                                          hx509_octet_string_list *list)
753 {
754     GeneralNames sa;
755     int ret;
756     size_t i, j;
757
758     list->val = NULL;
759     list->len = 0;
760
761     i = 0;
762     while (1) {
763         ret = find_extension_subject_alt_name(_hx509_get_cert(cert), &i, &sa);
764         i++;
765         if (ret == HX509_EXTENSION_NOT_FOUND) {
766             return 0;
767         } else if (ret != 0) {
768             hx509_set_error_string(context, 0, ret, "Error searching for SAN");
769             hx509_free_octet_string_list(list);
770             return ret;
771         }
772
773         for (j = 0; j < sa.len; j++) {
774             if (sa.val[j].element == choice_GeneralName_otherName &&
775                 der_heim_oid_cmp(&sa.val[j].u.otherName.type_id, oid) == 0)
776             {
777                 ret = add_to_list(list, &sa.val[j].u.otherName.value);
778                 if (ret) {
779                     hx509_set_error_string(context, 0, ret,
780                                            "Error adding an exra SAN to "
781                                            "return list");
782                     hx509_free_octet_string_list(list);
783                     free_GeneralNames(&sa);
784                     return ret;
785                 }
786             }
787         }
788         free_GeneralNames(&sa);
789     }
790 }
791
792
793 static int
794 check_key_usage(hx509_context context, const Certificate *cert,
795                 unsigned flags, int req_present)
796 {
797     const Extension *e;
798     KeyUsage ku;
799     size_t size;
800     int ret;
801     size_t i = 0;
802     unsigned ku_flags;
803
804     if (_hx509_cert_get_version(cert) < 3)
805         return 0;
806
807     e = find_extension(cert, &asn1_oid_id_x509_ce_keyUsage, &i);
808     if (e == NULL) {
809         if (req_present) {
810             hx509_set_error_string(context, 0, HX509_KU_CERT_MISSING,
811                                    "Required extension key "
812                                    "usage missing from certifiate");
813             return HX509_KU_CERT_MISSING;
814         }
815         return 0;
816     }
817
818     ret = decode_KeyUsage(e->extnValue.data, e->extnValue.length, &ku, &size);
819     if (ret)
820         return ret;
821     ku_flags = KeyUsage2int(ku);
822     if ((ku_flags & flags) != flags) {
823         unsigned missing = (~ku_flags) & flags;
824         char buf[256], *name;
825
826         unparse_flags(missing, asn1_KeyUsage_units(), buf, sizeof(buf));
827         _hx509_unparse_Name(&cert->tbsCertificate.subject, &name);
828         hx509_set_error_string(context, 0, HX509_KU_CERT_MISSING,
829                                "Key usage %s required but missing "
830                                "from certifiate %s", buf, name);
831         free(name);
832         return HX509_KU_CERT_MISSING;
833     }
834     return 0;
835 }
836
837 /*
838  * Return 0 on matching key usage 'flags' for 'cert', otherwise return
839  * an error code. If 'req_present' the existence is required of the
840  * KeyUsage extension.
841  */
842
843 int
844 _hx509_check_key_usage(hx509_context context, hx509_cert cert,
845                        unsigned flags, int req_present)
846 {
847     return check_key_usage(context, _hx509_get_cert(cert), flags, req_present);
848 }
849
850 enum certtype { PROXY_CERT, EE_CERT, CA_CERT };
851
852 static int
853 check_basic_constraints(hx509_context context, const Certificate *cert,
854                         enum certtype type, size_t depth)
855 {
856     BasicConstraints bc;
857     const Extension *e;
858     size_t size;
859     int ret;
860     size_t i = 0;
861
862     if (_hx509_cert_get_version(cert) < 3)
863         return 0;
864
865     e = find_extension(cert, &asn1_oid_id_x509_ce_basicConstraints, &i);
866     if (e == NULL) {
867         switch(type) {
868         case PROXY_CERT:
869         case EE_CERT:
870             return 0;
871         case CA_CERT: {
872             char *name;
873             ret = _hx509_unparse_Name(&cert->tbsCertificate.subject, &name);
874             assert(ret == 0);
875             hx509_set_error_string(context, 0, HX509_EXTENSION_NOT_FOUND,
876                                    "basicConstraints missing from "
877                                    "CA certifiacte %s", name);
878             free(name);
879             return HX509_EXTENSION_NOT_FOUND;
880         }
881         }
882     }
883
884     ret = decode_BasicConstraints(e->extnValue.data,
885                                   e->extnValue.length, &bc,
886                                   &size);
887     if (ret)
888         return ret;
889     switch(type) {
890     case PROXY_CERT:
891         if (bc.cA != NULL && *bc.cA)
892             ret = HX509_PARENT_IS_CA;
893         break;
894     case EE_CERT:
895         ret = 0;
896         break;
897     case CA_CERT:
898         if (bc.cA == NULL || !*bc.cA)
899             ret = HX509_PARENT_NOT_CA;
900         else if (bc.pathLenConstraint)
901             if (depth - 1 > *bc.pathLenConstraint)
902                 ret = HX509_CA_PATH_TOO_DEEP;
903         break;
904     }
905     free_BasicConstraints(&bc);
906     return ret;
907 }
908
909 int
910 _hx509_cert_is_parent_cmp(const Certificate *subject,
911                           const Certificate *issuer,
912                           int allow_self_signed)
913 {
914     int diff;
915     AuthorityKeyIdentifier ai;
916     SubjectKeyIdentifier si;
917     int ret_ai, ret_si, ret;
918
919     ret = _hx509_name_cmp(&issuer->tbsCertificate.subject,
920                           &subject->tbsCertificate.issuer,
921                           &diff);
922     if (ret)
923         return ret;
924     if (diff)
925         return diff;
926
927     memset(&ai, 0, sizeof(ai));
928     memset(&si, 0, sizeof(si));
929
930     /*
931      * Try to find AuthorityKeyIdentifier, if it's not present in the
932      * subject certificate nor the parent.
933      */
934
935     ret_ai = find_extension_auth_key_id(subject, &ai);
936     if (ret_ai && ret_ai != HX509_EXTENSION_NOT_FOUND)
937         return 1;
938     ret_si = _hx509_find_extension_subject_key_id(issuer, &si);
939     if (ret_si && ret_si != HX509_EXTENSION_NOT_FOUND)
940         return -1;
941
942     if (ret_si && ret_ai)
943         goto out;
944     if (ret_ai)
945         goto out;
946     if (ret_si) {
947         if (allow_self_signed) {
948             diff = 0;
949             goto out;
950         } else if (ai.keyIdentifier) {
951             diff = -1;
952             goto out;
953         }
954     }
955
956     if (ai.keyIdentifier == NULL) {
957         Name name;
958
959         if (ai.authorityCertIssuer == NULL)
960             return -1;
961         if (ai.authorityCertSerialNumber == NULL)
962             return -1;
963
964         diff = der_heim_integer_cmp(ai.authorityCertSerialNumber,
965                                     &issuer->tbsCertificate.serialNumber);
966         if (diff)
967             return diff;
968         if (ai.authorityCertIssuer->len != 1)
969             return -1;
970         if (ai.authorityCertIssuer->val[0].element != choice_GeneralName_directoryName)
971             return -1;
972
973         name.element =
974             ai.authorityCertIssuer->val[0].u.directoryName.element;
975         name.u.rdnSequence =
976             ai.authorityCertIssuer->val[0].u.directoryName.u.rdnSequence;
977
978         ret = _hx509_name_cmp(&issuer->tbsCertificate.subject,
979                               &name,
980                               &diff);
981         if (ret)
982             return ret;
983         if (diff)
984             return diff;
985         diff = 0;
986     } else
987         diff = der_heim_octet_string_cmp(ai.keyIdentifier, &si);
988     if (diff)
989         goto out;
990
991  out:
992     free_AuthorityKeyIdentifier(&ai);
993     free_SubjectKeyIdentifier(&si);
994     return diff;
995 }
996
997 static int
998 certificate_is_anchor(hx509_context context,
999                       hx509_certs trust_anchors,
1000                       const hx509_cert cert)
1001 {
1002     hx509_query q;
1003     hx509_cert c;
1004     int ret;
1005
1006     if (trust_anchors == NULL)
1007         return 0;
1008
1009     _hx509_query_clear(&q);
1010
1011     q.match = HX509_QUERY_MATCH_CERTIFICATE;
1012     q.certificate = _hx509_get_cert(cert);
1013
1014     ret = hx509_certs_find(context, trust_anchors, &q, &c);
1015     if (ret == 0)
1016         hx509_cert_free(c);
1017     return ret == 0;
1018 }
1019
1020 static int
1021 certificate_is_self_signed(hx509_context context,
1022                            const Certificate *cert,
1023                            int *self_signed)
1024 {
1025     int ret, diff;
1026     ret = _hx509_name_cmp(&cert->tbsCertificate.subject,
1027                           &cert->tbsCertificate.issuer, &diff);
1028     *self_signed = (diff == 0);
1029     if (ret) {
1030         hx509_set_error_string(context, 0, ret,
1031                                "Failed to check if self signed");
1032     } else
1033         ret = _hx509_self_signed_valid(context, &cert->signatureAlgorithm);
1034
1035     return ret;
1036 }
1037
1038 /*
1039  * The subjectName is "null" when it's empty set of relative DBs.
1040  */
1041
1042 static int
1043 subject_null_p(const Certificate *c)
1044 {
1045     return c->tbsCertificate.subject.u.rdnSequence.len == 0;
1046 }
1047
1048
1049 static int
1050 find_parent(hx509_context context,
1051             time_t time_now,
1052             hx509_certs trust_anchors,
1053             hx509_path *path,
1054             hx509_certs pool,
1055             hx509_cert current,
1056             hx509_cert *parent)
1057 {
1058     AuthorityKeyIdentifier ai;
1059     hx509_query q;
1060     int ret;
1061
1062     *parent = NULL;
1063     memset(&ai, 0, sizeof(ai));
1064
1065     _hx509_query_clear(&q);
1066
1067     if (!subject_null_p(current->data)) {
1068         q.match |= HX509_QUERY_FIND_ISSUER_CERT;
1069         q.subject = _hx509_get_cert(current);
1070     } else {
1071         ret = find_extension_auth_key_id(current->data, &ai);
1072         if (ret) {
1073             hx509_set_error_string(context, 0, HX509_CERTIFICATE_MALFORMED,
1074                                    "Subjectless certificate missing AuthKeyID");
1075             return HX509_CERTIFICATE_MALFORMED;
1076         }
1077
1078         if (ai.keyIdentifier == NULL) {
1079             free_AuthorityKeyIdentifier(&ai);
1080             hx509_set_error_string(context, 0, HX509_CERTIFICATE_MALFORMED,
1081                                    "Subjectless certificate missing keyIdentifier "
1082                                    "inside AuthKeyID");
1083             return HX509_CERTIFICATE_MALFORMED;
1084         }
1085
1086         q.subject_id = ai.keyIdentifier;
1087         q.match = HX509_QUERY_MATCH_SUBJECT_KEY_ID;
1088     }
1089
1090     q.path = path;
1091     q.match |= HX509_QUERY_NO_MATCH_PATH;
1092
1093     if (pool) {
1094         q.timenow = time_now;
1095         q.match |= HX509_QUERY_MATCH_TIME;
1096
1097         ret = hx509_certs_find(context, pool, &q, parent);
1098         if (ret == 0) {
1099             free_AuthorityKeyIdentifier(&ai);
1100             return 0;
1101         }
1102         q.match &= ~HX509_QUERY_MATCH_TIME;
1103     }
1104
1105     if (trust_anchors) {
1106         ret = hx509_certs_find(context, trust_anchors, &q, parent);
1107         if (ret == 0) {
1108             free_AuthorityKeyIdentifier(&ai);
1109             return ret;
1110         }
1111     }
1112     free_AuthorityKeyIdentifier(&ai);
1113
1114     {
1115         hx509_name name;
1116         char *str;
1117
1118         ret = hx509_cert_get_subject(current, &name);
1119         if (ret) {
1120             hx509_clear_error_string(context);
1121             return HX509_ISSUER_NOT_FOUND;
1122         }
1123         ret = hx509_name_to_string(name, &str);
1124         hx509_name_free(&name);
1125         if (ret) {
1126             hx509_clear_error_string(context);
1127             return HX509_ISSUER_NOT_FOUND;
1128         }
1129
1130         hx509_set_error_string(context, 0, HX509_ISSUER_NOT_FOUND,
1131                                "Failed to find issuer for "
1132                                "certificate with subject: '%s'", str);
1133         free(str);
1134     }
1135     return HX509_ISSUER_NOT_FOUND;
1136 }
1137
1138 /*
1139  *
1140  */
1141
1142 static int
1143 is_proxy_cert(hx509_context context,
1144               const Certificate *cert,
1145               ProxyCertInfo *rinfo)
1146 {
1147     ProxyCertInfo info;
1148     const Extension *e;
1149     size_t size;
1150     int ret;
1151     size_t i = 0;
1152
1153     if (rinfo)
1154         memset(rinfo, 0, sizeof(*rinfo));
1155
1156     e = find_extension(cert, &asn1_oid_id_pkix_pe_proxyCertInfo, &i);
1157     if (e == NULL) {
1158         hx509_clear_error_string(context);
1159         return HX509_EXTENSION_NOT_FOUND;
1160     }
1161
1162     ret = decode_ProxyCertInfo(e->extnValue.data,
1163                                e->extnValue.length,
1164                                &info,
1165                                &size);
1166     if (ret) {
1167         hx509_clear_error_string(context);
1168         return ret;
1169     }
1170     if (size != e->extnValue.length) {
1171         free_ProxyCertInfo(&info);
1172         hx509_clear_error_string(context);
1173         return HX509_EXTRA_DATA_AFTER_STRUCTURE;
1174     }
1175     if (rinfo == NULL)
1176         free_ProxyCertInfo(&info);
1177     else
1178         *rinfo = info;
1179
1180     return 0;
1181 }
1182
1183 /*
1184  * Path operations are like MEMORY based keyset, but with exposed
1185  * internal so we can do easy searches.
1186  */
1187
1188 int
1189 _hx509_path_append(hx509_context context, hx509_path *path, hx509_cert cert)
1190 {
1191     hx509_cert *val;
1192     val = realloc(path->val, (path->len + 1) * sizeof(path->val[0]));
1193     if (val == NULL) {
1194         hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1195         return ENOMEM;
1196     }
1197
1198     path->val = val;
1199     path->val[path->len] = hx509_cert_ref(cert);
1200     path->len++;
1201
1202     return 0;
1203 }
1204
1205 void
1206 _hx509_path_free(hx509_path *path)
1207 {
1208     unsigned i;
1209
1210     for (i = 0; i < path->len; i++)
1211         hx509_cert_free(path->val[i]);
1212     free(path->val);
1213     path->val = NULL;
1214     path->len = 0;
1215 }
1216
1217 /*
1218  * Find path by looking up issuer for the top certificate and continue
1219  * until an anchor certificate is found or max limit is found. A
1220  * certificate never included twice in the path.
1221  *
1222  * If the trust anchors are not given, calculate optimistic path, just
1223  * follow the chain upward until we no longer find a parent or we hit
1224  * the max path limit. In this case, a failure will always be returned
1225  * depending on what error condition is hit first.
1226  *
1227  * The path includes a path from the top certificate to the anchor
1228  * certificate.
1229  *
1230  * The caller needs to free `path´ both on successful built path and
1231  * failure.
1232  */
1233
1234 int
1235 _hx509_calculate_path(hx509_context context,
1236                       int flags,
1237                       time_t time_now,
1238                       hx509_certs anchors,
1239                       unsigned int max_depth,
1240                       hx509_cert cert,
1241                       hx509_certs pool,
1242                       hx509_path *path)
1243 {
1244     hx509_cert parent, current;
1245     int ret;
1246
1247     if (max_depth == 0)
1248         max_depth = HX509_VERIFY_MAX_DEPTH;
1249
1250     ret = _hx509_path_append(context, path, cert);
1251     if (ret)
1252         return ret;
1253
1254     current = hx509_cert_ref(cert);
1255
1256     while (!certificate_is_anchor(context, anchors, current)) {
1257
1258         ret = find_parent(context, time_now, anchors, path,
1259                           pool, current, &parent);
1260         hx509_cert_free(current);
1261         if (ret)
1262             return ret;
1263
1264         ret = _hx509_path_append(context, path, parent);
1265         if (ret)
1266             return ret;
1267         current = parent;
1268
1269         if (path->len > max_depth) {
1270             hx509_cert_free(current);
1271             hx509_set_error_string(context, 0, HX509_PATH_TOO_LONG,
1272                                    "Path too long while bulding "
1273                                    "certificate chain");
1274             return HX509_PATH_TOO_LONG;
1275         }
1276     }
1277
1278     if ((flags & HX509_CALCULATE_PATH_NO_ANCHOR) &&
1279         path->len > 0 &&
1280         certificate_is_anchor(context, anchors, path->val[path->len - 1]))
1281     {
1282         hx509_cert_free(path->val[path->len - 1]);
1283         path->len--;
1284     }
1285
1286     hx509_cert_free(current);
1287     return 0;
1288 }
1289
1290 int
1291 _hx509_AlgorithmIdentifier_cmp(const AlgorithmIdentifier *p,
1292                                const AlgorithmIdentifier *q)
1293 {
1294     int diff;
1295     diff = der_heim_oid_cmp(&p->algorithm, &q->algorithm);
1296     if (diff)
1297         return diff;
1298     if (p->parameters) {
1299         if (q->parameters)
1300             return heim_any_cmp(p->parameters,
1301                                 q->parameters);
1302         else
1303             return 1;
1304     } else {
1305         if (q->parameters)
1306             return -1;
1307         else
1308             return 0;
1309     }
1310 }
1311
1312 int
1313 _hx509_Certificate_cmp(const Certificate *p, const Certificate *q)
1314 {
1315     int diff;
1316     diff = der_heim_bit_string_cmp(&p->signatureValue, &q->signatureValue);
1317     if (diff)
1318         return diff;
1319     diff = _hx509_AlgorithmIdentifier_cmp(&p->signatureAlgorithm,
1320                                           &q->signatureAlgorithm);
1321     if (diff)
1322         return diff;
1323     diff = der_heim_octet_string_cmp(&p->tbsCertificate._save,
1324                                      &q->tbsCertificate._save);
1325     return diff;
1326 }
1327
1328 /**
1329  * Compare to hx509 certificate object, useful for sorting.
1330  *
1331  * @param p a hx509 certificate object.
1332  * @param q a hx509 certificate object.
1333  *
1334  * @return 0 the objects are the same, returns > 0 is p is "larger"
1335  * then q, < 0 if p is "smaller" then q.
1336  *
1337  * @ingroup hx509_cert
1338  */
1339
1340 int
1341 hx509_cert_cmp(hx509_cert p, hx509_cert q)
1342 {
1343     return _hx509_Certificate_cmp(p->data, q->data);
1344 }
1345
1346 /**
1347  * Return the name of the issuer of the hx509 certificate.
1348  *
1349  * @param p a hx509 certificate object.
1350  * @param name a pointer to a hx509 name, should be freed by
1351  * hx509_name_free().
1352  *
1353  * @return An hx509 error code, see hx509_get_error_string().
1354  *
1355  * @ingroup hx509_cert
1356  */
1357
1358 int
1359 hx509_cert_get_issuer(hx509_cert p, hx509_name *name)
1360 {
1361     return _hx509_name_from_Name(&p->data->tbsCertificate.issuer, name);
1362 }
1363
1364 /**
1365  * Return the name of the subject of the hx509 certificate.
1366  *
1367  * @param p a hx509 certificate object.
1368  * @param name a pointer to a hx509 name, should be freed by
1369  * hx509_name_free(). See also hx509_cert_get_base_subject().
1370  *
1371  * @return An hx509 error code, see hx509_get_error_string().
1372  *
1373  * @ingroup hx509_cert
1374  */
1375
1376 int
1377 hx509_cert_get_subject(hx509_cert p, hx509_name *name)
1378 {
1379     return _hx509_name_from_Name(&p->data->tbsCertificate.subject, name);
1380 }
1381
1382 /**
1383  * Return the name of the base subject of the hx509 certificate. If
1384  * the certiicate is a verified proxy certificate, the this function
1385  * return the base certificate (root of the proxy chain). If the proxy
1386  * certificate is not verified with the base certificate
1387  * HX509_PROXY_CERTIFICATE_NOT_CANONICALIZED is returned.
1388  *
1389  * @param context a hx509 context.
1390  * @param c a hx509 certificate object.
1391  * @param name a pointer to a hx509 name, should be freed by
1392  * hx509_name_free(). See also hx509_cert_get_subject().
1393  *
1394  * @return An hx509 error code, see hx509_get_error_string().
1395  *
1396  * @ingroup hx509_cert
1397  */
1398
1399 int
1400 hx509_cert_get_base_subject(hx509_context context, hx509_cert c,
1401                             hx509_name *name)
1402 {
1403     if (c->basename)
1404         return hx509_name_copy(context, c->basename, name);
1405     if (is_proxy_cert(context, c->data, NULL) == 0) {
1406         int ret = HX509_PROXY_CERTIFICATE_NOT_CANONICALIZED;
1407         hx509_set_error_string(context, 0, ret,
1408                                "Proxy certificate have not been "
1409                                "canonicalize yet, no base name");
1410         return ret;
1411     }
1412     return _hx509_name_from_Name(&c->data->tbsCertificate.subject, name);
1413 }
1414
1415 /**
1416  * Get serial number of the certificate.
1417  *
1418  * @param p a hx509 certificate object.
1419  * @param i serial number, should be freed ith der_free_heim_integer().
1420  *
1421  * @return An hx509 error code, see hx509_get_error_string().
1422  *
1423  * @ingroup hx509_cert
1424  */
1425
1426 int
1427 hx509_cert_get_serialnumber(hx509_cert p, heim_integer *i)
1428 {
1429     return der_copy_heim_integer(&p->data->tbsCertificate.serialNumber, i);
1430 }
1431
1432 /**
1433  * Get notBefore time of the certificate.
1434  *
1435  * @param p a hx509 certificate object.
1436  *
1437  * @return return not before time
1438  *
1439  * @ingroup hx509_cert
1440  */
1441
1442 time_t
1443 hx509_cert_get_notBefore(hx509_cert p)
1444 {
1445     return _hx509_Time2time_t(&p->data->tbsCertificate.validity.notBefore);
1446 }
1447
1448 /**
1449  * Get notAfter time of the certificate.
1450  *
1451  * @param p a hx509 certificate object.
1452  *
1453  * @return return not after time.
1454  *
1455  * @ingroup hx509_cert
1456  */
1457
1458 time_t
1459 hx509_cert_get_notAfter(hx509_cert p)
1460 {
1461     return _hx509_Time2time_t(&p->data->tbsCertificate.validity.notAfter);
1462 }
1463
1464 /**
1465  * Get the SubjectPublicKeyInfo structure from the hx509 certificate.
1466  *
1467  * @param context a hx509 context.
1468  * @param p a hx509 certificate object.
1469  * @param spki SubjectPublicKeyInfo, should be freed with
1470  * free_SubjectPublicKeyInfo().
1471  *
1472  * @return An hx509 error code, see hx509_get_error_string().
1473  *
1474  * @ingroup hx509_cert
1475  */
1476
1477 int
1478 hx509_cert_get_SPKI(hx509_context context, hx509_cert p, SubjectPublicKeyInfo *spki)
1479 {
1480     int ret;
1481
1482     ret = copy_SubjectPublicKeyInfo(&p->data->tbsCertificate.subjectPublicKeyInfo, spki);
1483     if (ret)
1484         hx509_set_error_string(context, 0, ret, "Failed to copy SPKI");
1485     return ret;
1486 }
1487
1488 /**
1489  * Get the AlgorithmIdentifier from the hx509 certificate.
1490  *
1491  * @param context a hx509 context.
1492  * @param p a hx509 certificate object.
1493  * @param alg AlgorithmIdentifier, should be freed with
1494  *            free_AlgorithmIdentifier(). The algorithmidentifier is
1495  *            typicly rsaEncryption, or id-ecPublicKey, or some other
1496  *            public key mechanism.
1497  *
1498  * @return An hx509 error code, see hx509_get_error_string().
1499  *
1500  * @ingroup hx509_cert
1501  */
1502
1503 int
1504 hx509_cert_get_SPKI_AlgorithmIdentifier(hx509_context context,
1505                                         hx509_cert p,
1506                                         AlgorithmIdentifier *alg)
1507 {
1508     int ret;
1509
1510     ret = copy_AlgorithmIdentifier(&p->data->tbsCertificate.subjectPublicKeyInfo.algorithm, alg);
1511     if (ret)
1512         hx509_set_error_string(context, 0, ret,
1513                                "Failed to copy SPKI AlgorithmIdentifier");
1514     return ret;
1515 }
1516
1517 static int
1518 get_x_unique_id(hx509_context context, const char *name,
1519                 const heim_bit_string *cert, heim_bit_string *subject)
1520 {
1521     int ret;
1522
1523     if (cert == NULL) {
1524         ret = HX509_EXTENSION_NOT_FOUND;
1525         hx509_set_error_string(context, 0, ret, "%s unique id doesn't exists", name);
1526         return ret;
1527     }
1528     ret = der_copy_bit_string(cert, subject);
1529     if (ret) {
1530         hx509_set_error_string(context, 0, ret, "malloc out of memory", name);
1531         return ret;
1532     }
1533     return 0;
1534 }
1535
1536 /**
1537  * Get a copy of the Issuer Unique ID
1538  *
1539  * @param context a hx509_context
1540  * @param p a hx509 certificate
1541  * @param issuer the issuer id returned, free with der_free_bit_string()
1542  *
1543  * @return An hx509 error code, see hx509_get_error_string(). The
1544  * error code HX509_EXTENSION_NOT_FOUND is returned if the certificate
1545  * doesn't have a issuerUniqueID
1546  *
1547  * @ingroup hx509_cert
1548  */
1549
1550 int
1551 hx509_cert_get_issuer_unique_id(hx509_context context, hx509_cert p, heim_bit_string *issuer)
1552 {
1553     return get_x_unique_id(context, "issuer", p->data->tbsCertificate.issuerUniqueID, issuer);
1554 }
1555
1556 /**
1557  * Get a copy of the Subect Unique ID
1558  *
1559  * @param context a hx509_context
1560  * @param p a hx509 certificate
1561  * @param subject the subject id returned, free with der_free_bit_string()
1562  *
1563  * @return An hx509 error code, see hx509_get_error_string(). The
1564  * error code HX509_EXTENSION_NOT_FOUND is returned if the certificate
1565  * doesn't have a subjectUniqueID
1566  *
1567  * @ingroup hx509_cert
1568  */
1569
1570 int
1571 hx509_cert_get_subject_unique_id(hx509_context context, hx509_cert p, heim_bit_string *subject)
1572 {
1573     return get_x_unique_id(context, "subject", p->data->tbsCertificate.subjectUniqueID, subject);
1574 }
1575
1576
1577 hx509_private_key
1578 _hx509_cert_private_key(hx509_cert p)
1579 {
1580     return p->private_key;
1581 }
1582
1583 int
1584 hx509_cert_have_private_key(hx509_cert p)
1585 {
1586     return p->private_key ? 1 : 0;
1587 }
1588
1589
1590 int
1591 _hx509_cert_private_key_exportable(hx509_cert p)
1592 {
1593     if (p->private_key == NULL)
1594         return 0;
1595     return _hx509_private_key_exportable(p->private_key);
1596 }
1597
1598 int
1599 _hx509_cert_private_decrypt(hx509_context context,
1600                             const heim_octet_string *ciphertext,
1601                             const heim_oid *encryption_oid,
1602                             hx509_cert p,
1603                             heim_octet_string *cleartext)
1604 {
1605     cleartext->data = NULL;
1606     cleartext->length = 0;
1607
1608     if (p->private_key == NULL) {
1609         hx509_set_error_string(context, 0, HX509_PRIVATE_KEY_MISSING,
1610                                "Private key missing");
1611         return HX509_PRIVATE_KEY_MISSING;
1612     }
1613
1614     return hx509_private_key_private_decrypt(context,
1615                                               ciphertext,
1616                                               encryption_oid,
1617                                               p->private_key,
1618                                               cleartext);
1619 }
1620
1621 int
1622 hx509_cert_public_encrypt(hx509_context context,
1623                            const heim_octet_string *cleartext,
1624                            const hx509_cert p,
1625                            heim_oid *encryption_oid,
1626                            heim_octet_string *ciphertext)
1627 {
1628     return _hx509_public_encrypt(context,
1629                                  cleartext, p->data,
1630                                  encryption_oid, ciphertext);
1631 }
1632
1633 /*
1634  *
1635  */
1636
1637 time_t
1638 _hx509_Time2time_t(const Time *t)
1639 {
1640     switch(t->element) {
1641     case choice_Time_utcTime:
1642         return t->u.utcTime;
1643     case choice_Time_generalTime:
1644         return t->u.generalTime;
1645     }
1646     return 0;
1647 }
1648
1649 /*
1650  *
1651  */
1652
1653 static int
1654 init_name_constraints(hx509_name_constraints *nc)
1655 {
1656     memset(nc, 0, sizeof(*nc));
1657     return 0;
1658 }
1659
1660 static int
1661 add_name_constraints(hx509_context context, const Certificate *c, int not_ca,
1662                      hx509_name_constraints *nc)
1663 {
1664     NameConstraints tnc;
1665     int ret;
1666
1667     ret = find_extension_name_constraints(c, &tnc);
1668     if (ret == HX509_EXTENSION_NOT_FOUND)
1669         return 0;
1670     else if (ret) {
1671         hx509_set_error_string(context, 0, ret, "Failed getting NameConstraints");
1672         return ret;
1673     } else if (not_ca) {
1674         ret = HX509_VERIFY_CONSTRAINTS;
1675         hx509_set_error_string(context, 0, ret, "Not a CA and "
1676                                "have NameConstraints");
1677     } else {
1678         NameConstraints *val;
1679         val = realloc(nc->val, sizeof(nc->val[0]) * (nc->len + 1));
1680         if (val == NULL) {
1681             hx509_clear_error_string(context);
1682             ret = ENOMEM;
1683             goto out;
1684         }
1685         nc->val = val;
1686         ret = copy_NameConstraints(&tnc, &nc->val[nc->len]);
1687         if (ret) {
1688             hx509_clear_error_string(context);
1689             goto out;
1690         }
1691         nc->len += 1;
1692     }
1693 out:
1694     free_NameConstraints(&tnc);
1695     return ret;
1696 }
1697
1698 static int
1699 match_RDN(const RelativeDistinguishedName *c,
1700           const RelativeDistinguishedName *n)
1701 {
1702     size_t i;
1703
1704     if (c->len != n->len)
1705         return HX509_NAME_CONSTRAINT_ERROR;
1706
1707     for (i = 0; i < n->len; i++) {
1708         int diff, ret;
1709
1710         if (der_heim_oid_cmp(&c->val[i].type, &n->val[i].type) != 0)
1711             return HX509_NAME_CONSTRAINT_ERROR;
1712         ret = _hx509_name_ds_cmp(&c->val[i].value, &n->val[i].value, &diff);
1713         if (ret)
1714             return ret;
1715         if (diff != 0)
1716             return HX509_NAME_CONSTRAINT_ERROR;
1717     }
1718     return 0;
1719 }
1720
1721 static int
1722 match_X501Name(const Name *c, const Name *n)
1723 {
1724     size_t i;
1725     int ret;
1726
1727     if (c->element != choice_Name_rdnSequence
1728         || n->element != choice_Name_rdnSequence)
1729         return 0;
1730     if (c->u.rdnSequence.len > n->u.rdnSequence.len)
1731         return HX509_NAME_CONSTRAINT_ERROR;
1732     for (i = 0; i < c->u.rdnSequence.len; i++) {
1733         ret = match_RDN(&c->u.rdnSequence.val[i], &n->u.rdnSequence.val[i]);
1734         if (ret)
1735             return ret;
1736     }
1737     return 0;
1738 }
1739
1740
1741 static int
1742 match_general_name(const GeneralName *c, const GeneralName *n, int *match)
1743 {
1744     /*
1745      * Name constraints only apply to the same name type, see RFC3280,
1746      * 4.2.1.11.
1747      */
1748     assert(c->element == n->element);
1749
1750     switch(c->element) {
1751     case choice_GeneralName_otherName:
1752         if (der_heim_oid_cmp(&c->u.otherName.type_id,
1753                          &n->u.otherName.type_id) != 0)
1754             return HX509_NAME_CONSTRAINT_ERROR;
1755         if (heim_any_cmp(&c->u.otherName.value,
1756                          &n->u.otherName.value) != 0)
1757             return HX509_NAME_CONSTRAINT_ERROR;
1758         *match = 1;
1759         return 0;
1760     case choice_GeneralName_rfc822Name: {
1761         const char *s;
1762         size_t len1, len2;
1763         s = memchr(c->u.rfc822Name.data, '@', c->u.rfc822Name.length);
1764         if (s) {
1765             if (der_printable_string_cmp(&c->u.rfc822Name, &n->u.rfc822Name) != 0)
1766                 return HX509_NAME_CONSTRAINT_ERROR;
1767         } else {
1768             s = memchr(n->u.rfc822Name.data, '@', n->u.rfc822Name.length);
1769             if (s == NULL)
1770                 return HX509_NAME_CONSTRAINT_ERROR;
1771             len1 = c->u.rfc822Name.length;
1772             len2 = n->u.rfc822Name.length -
1773                 (s - ((char *)n->u.rfc822Name.data));
1774             if (len1 > len2)
1775                 return HX509_NAME_CONSTRAINT_ERROR;
1776             if (memcmp(s + 1 + len2 - len1, c->u.rfc822Name.data, len1) != 0)
1777                 return HX509_NAME_CONSTRAINT_ERROR;
1778             if (len1 < len2 && s[len2 - len1 + 1] != '.')
1779                 return HX509_NAME_CONSTRAINT_ERROR;
1780         }
1781         *match = 1;
1782         return 0;
1783     }
1784     case choice_GeneralName_dNSName: {
1785         size_t lenc, lenn;
1786         char *ptr;
1787
1788         lenc = c->u.dNSName.length;
1789         lenn = n->u.dNSName.length;
1790         if (lenc > lenn)
1791             return HX509_NAME_CONSTRAINT_ERROR;
1792         ptr = n->u.dNSName.data;
1793         if (memcmp(&ptr[lenn - lenc], c->u.dNSName.data, lenc) != 0)
1794             return HX509_NAME_CONSTRAINT_ERROR;
1795         if (lenn != lenc && ptr[lenn - lenc - 1] != '.')
1796             return HX509_NAME_CONSTRAINT_ERROR;
1797         *match = 1;
1798         return 0;
1799     }
1800     case choice_GeneralName_directoryName: {
1801         Name c_name, n_name;
1802         int ret;
1803
1804         c_name._save.data = NULL;
1805         c_name._save.length = 0;
1806         c_name.element = c->u.directoryName.element;
1807         c_name.u.rdnSequence = c->u.directoryName.u.rdnSequence;
1808
1809         n_name._save.data = NULL;
1810         n_name._save.length = 0;
1811         n_name.element = n->u.directoryName.element;
1812         n_name.u.rdnSequence = n->u.directoryName.u.rdnSequence;
1813
1814         ret = match_X501Name(&c_name, &n_name);
1815         if (ret == 0)
1816             *match = 1;
1817         return ret;
1818     }
1819     case choice_GeneralName_uniformResourceIdentifier:
1820     case choice_GeneralName_iPAddress:
1821     case choice_GeneralName_registeredID:
1822     default:
1823         return HX509_NAME_CONSTRAINT_ERROR;
1824     }
1825 }
1826
1827 static int
1828 match_alt_name(const GeneralName *n, const Certificate *c,
1829                int *same, int *match)
1830 {
1831     GeneralNames sa;
1832     int ret;
1833     size_t i, j;
1834
1835     i = 0;
1836     do {
1837         ret = find_extension_subject_alt_name(c, &i, &sa);
1838         if (ret == HX509_EXTENSION_NOT_FOUND) {
1839             ret = 0;
1840             break;
1841         } else if (ret != 0)
1842             break;
1843
1844         for (j = 0; j < sa.len; j++) {
1845             if (n->element == sa.val[j].element) {
1846                 *same = 1;
1847                 ret = match_general_name(n, &sa.val[j], match);
1848             }
1849         }
1850         free_GeneralNames(&sa);
1851     } while (1);
1852     return ret;
1853 }
1854
1855
1856 static int
1857 match_tree(const GeneralSubtrees *t, const Certificate *c, int *match)
1858 {
1859     int name, alt_name, same;
1860     unsigned int i;
1861     int ret = 0;
1862
1863     name = alt_name = same = *match = 0;
1864     for (i = 0; i < t->len; i++) {
1865         if (t->val[i].minimum && t->val[i].maximum)
1866             return HX509_RANGE;
1867
1868         /*
1869          * If the constraint apply to directoryNames, test is with
1870          * subjectName of the certificate if the certificate have a
1871          * non-null (empty) subjectName.
1872          */
1873
1874         if (t->val[i].base.element == choice_GeneralName_directoryName
1875             && !subject_null_p(c))
1876         {
1877             GeneralName certname;
1878
1879             memset(&certname, 0, sizeof(certname));
1880             certname.element = choice_GeneralName_directoryName;
1881             certname.u.directoryName.element =
1882                 c->tbsCertificate.subject.element;
1883             certname.u.directoryName.u.rdnSequence =
1884                 c->tbsCertificate.subject.u.rdnSequence;
1885
1886             ret = match_general_name(&t->val[i].base, &certname, &name);
1887         }
1888
1889         /* Handle subjectAltNames, this is icky since they
1890          * restrictions only apply if the subjectAltName is of the
1891          * same type. So if there have been a match of type, require
1892          * altname to be set.
1893          */
1894         ret = match_alt_name(&t->val[i].base, c, &same, &alt_name);
1895     }
1896     if (name && (!same || alt_name))
1897         *match = 1;
1898     return ret;
1899 }
1900
1901 static int
1902 check_name_constraints(hx509_context context,
1903                        const hx509_name_constraints *nc,
1904                        const Certificate *c)
1905 {
1906     int match, ret;
1907     size_t i;
1908
1909     for (i = 0 ; i < nc->len; i++) {
1910         GeneralSubtrees gs;
1911
1912         if (nc->val[i].permittedSubtrees) {
1913             GeneralSubtrees_SET(&gs, nc->val[i].permittedSubtrees);
1914             ret = match_tree(&gs, c, &match);
1915             if (ret) {
1916                 hx509_clear_error_string(context);
1917                 return ret;
1918             }
1919             /* allow null subjectNames, they wont matches anything */
1920             if (match == 0 && !subject_null_p(c)) {
1921                 hx509_set_error_string(context, 0, HX509_VERIFY_CONSTRAINTS,
1922                                        "Error verify constraints, "
1923                                        "certificate didn't match any "
1924                                        "permitted subtree");
1925                 return HX509_VERIFY_CONSTRAINTS;
1926             }
1927         }
1928         if (nc->val[i].excludedSubtrees) {
1929             GeneralSubtrees_SET(&gs, nc->val[i].excludedSubtrees);
1930             ret = match_tree(&gs, c, &match);
1931             if (ret) {
1932                 hx509_clear_error_string(context);
1933                 return ret;
1934             }
1935             if (match) {
1936                 hx509_set_error_string(context, 0, HX509_VERIFY_CONSTRAINTS,
1937                                        "Error verify constraints, "
1938                                        "certificate included in excluded "
1939                                        "subtree");
1940                 return HX509_VERIFY_CONSTRAINTS;
1941             }
1942         }
1943     }
1944     return 0;
1945 }
1946
1947 static void
1948 free_name_constraints(hx509_name_constraints *nc)
1949 {
1950     size_t i;
1951
1952     for (i = 0 ; i < nc->len; i++)
1953         free_NameConstraints(&nc->val[i]);
1954     free(nc->val);
1955 }
1956
1957 /**
1958  * Build and verify the path for the certificate to the trust anchor
1959  * specified in the verify context. The path is constructed from the
1960  * certificate, the pool and the trust anchors.
1961  *
1962  * @param context A hx509 context.
1963  * @param ctx A hx509 verification context.
1964  * @param cert the certificate to build the path from.
1965  * @param pool A keyset of certificates to build the chain from.
1966  *
1967  * @return An hx509 error code, see hx509_get_error_string().
1968  *
1969  * @ingroup hx509_verify
1970  */
1971
1972 int
1973 hx509_verify_path(hx509_context context,
1974                   hx509_verify_ctx ctx,
1975                   hx509_cert cert,
1976                   hx509_certs pool)
1977 {
1978     hx509_name_constraints nc;
1979     hx509_path path;
1980     int ret, diff;
1981     size_t proxy_cert_depth, selfsigned_depth;
1982     size_t i, k;
1983     enum certtype type;
1984     Name proxy_issuer;
1985     hx509_certs anchors = NULL;
1986
1987     memset(&proxy_issuer, 0, sizeof(proxy_issuer));
1988
1989     ret = init_name_constraints(&nc);
1990     if (ret)
1991         return ret;
1992
1993     path.val = NULL;
1994     path.len = 0;
1995
1996     if ((ctx->flags & HX509_VERIFY_CTX_F_TIME_SET) == 0)
1997         ctx->time_now = time(NULL);
1998
1999     /*
2000      *
2001      */
2002     if (ctx->trust_anchors)
2003         anchors = hx509_certs_ref(ctx->trust_anchors);
2004     else if (context->default_trust_anchors && ALLOW_DEF_TA(ctx))
2005         anchors = hx509_certs_ref(context->default_trust_anchors);
2006     else {
2007         ret = hx509_certs_init(context, "MEMORY:no-TA", 0, NULL, &anchors);
2008         if (ret)
2009             goto out;
2010     }
2011
2012     /*
2013      * Calculate the path from the certificate user presented to the
2014      * to an anchor.
2015      */
2016     ret = _hx509_calculate_path(context, 0, ctx->time_now,
2017                                 anchors, ctx->max_depth,
2018                                 cert, pool, &path);
2019     if (ret)
2020         goto out;
2021
2022     /*
2023      * Check CA and proxy certificate chain from the top of the
2024      * certificate chain. Also check certificate is valid with respect
2025      * to the current time.
2026      *
2027      */
2028
2029     proxy_cert_depth = 0;
2030     selfsigned_depth = 0;
2031
2032     if (ctx->flags & HX509_VERIFY_CTX_F_ALLOW_PROXY_CERTIFICATE)
2033         type = PROXY_CERT;
2034     else
2035         type = EE_CERT;
2036
2037     for (i = 0; i < path.len; i++) {
2038         Certificate *c;
2039         time_t t;
2040
2041         c = _hx509_get_cert(path.val[i]);
2042
2043         /*
2044          * Lets do some basic check on issuer like
2045          * keyUsage.keyCertSign and basicConstraints.cA bit depending
2046          * on what type of certificate this is.
2047          */
2048
2049         switch (type) {
2050         case CA_CERT:
2051
2052             /* XXX make constants for keyusage */
2053             ret = check_key_usage(context, c, 1 << 5,
2054                                   REQUIRE_RFC3280(ctx) ? TRUE : FALSE);
2055             if (ret) {
2056                 hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
2057                                        "Key usage missing from CA certificate");
2058                 goto out;
2059             }
2060
2061             /* self signed cert doesn't add to path length */
2062             if (i + 1 != path.len) {
2063                 int selfsigned;
2064
2065                 ret = certificate_is_self_signed(context, c, &selfsigned);
2066                 if (ret)
2067                     goto out;
2068                 if (selfsigned)
2069                     selfsigned_depth++;
2070             }
2071
2072             break;
2073         case PROXY_CERT: {
2074             ProxyCertInfo info;
2075
2076             if (is_proxy_cert(context, c, &info) == 0) {
2077                 size_t j;
2078
2079                 if (info.pCPathLenConstraint != NULL &&
2080                     *info.pCPathLenConstraint < i)
2081                 {
2082                     free_ProxyCertInfo(&info);
2083                     ret = HX509_PATH_TOO_LONG;
2084                     hx509_set_error_string(context, 0, ret,
2085                                            "Proxy certificate chain "
2086                                            "longer then allowed");
2087                     goto out;
2088                 }
2089                 /* XXX MUST check info.proxyPolicy */
2090                 free_ProxyCertInfo(&info);
2091
2092                 j = 0;
2093                 if (find_extension(c, &asn1_oid_id_x509_ce_subjectAltName, &j)) {
2094                     ret = HX509_PROXY_CERT_INVALID;
2095                     hx509_set_error_string(context, 0, ret,
2096                                            "Proxy certificate have explicitly "
2097                                            "forbidden subjectAltName");
2098                     goto out;
2099                 }
2100
2101                 j = 0;
2102                 if (find_extension(c, &asn1_oid_id_x509_ce_issuerAltName, &j)) {
2103                     ret = HX509_PROXY_CERT_INVALID;
2104                     hx509_set_error_string(context, 0, ret,
2105                                            "Proxy certificate have explicitly "
2106                                            "forbidden issuerAltName");
2107                     goto out;
2108                 }
2109
2110                 /*
2111                  * The subject name of the proxy certificate should be
2112                  * CN=XXX,<proxy issuer>, prune of CN and check if its
2113                  * the same over the whole chain of proxy certs and
2114                  * then check with the EE cert when we get to it.
2115                  */
2116
2117                 if (proxy_cert_depth) {
2118                     ret = _hx509_name_cmp(&proxy_issuer, &c->tbsCertificate.subject, &diff);
2119                     if (ret) {
2120                         hx509_set_error_string(context, 0, ret, "Out of memory");
2121                         goto out;
2122                     }
2123                     if (diff) {
2124                         ret = HX509_PROXY_CERT_NAME_WRONG;
2125                         hx509_set_error_string(context, 0, ret,
2126                                                "Base proxy name not right");
2127                         goto out;
2128                     }
2129                 }
2130
2131                 free_Name(&proxy_issuer);
2132
2133                 ret = copy_Name(&c->tbsCertificate.subject, &proxy_issuer);
2134                 if (ret) {
2135                     hx509_clear_error_string(context);
2136                     goto out;
2137                 }
2138
2139                 j = proxy_issuer.u.rdnSequence.len;
2140                 if (proxy_issuer.u.rdnSequence.len < 2
2141                     || proxy_issuer.u.rdnSequence.val[j - 1].len > 1
2142                     || der_heim_oid_cmp(&proxy_issuer.u.rdnSequence.val[j - 1].val[0].type,
2143                                         &asn1_oid_id_at_commonName))
2144                 {
2145                     ret = HX509_PROXY_CERT_NAME_WRONG;
2146                     hx509_set_error_string(context, 0, ret,
2147                                            "Proxy name too short or "
2148                                            "does not have Common name "
2149                                            "at the top");
2150                     goto out;
2151                 }
2152
2153                 free_RelativeDistinguishedName(&proxy_issuer.u.rdnSequence.val[j - 1]);
2154                 proxy_issuer.u.rdnSequence.len -= 1;
2155
2156                 ret = _hx509_name_cmp(&proxy_issuer, &c->tbsCertificate.issuer, &diff);
2157                 if (ret) {
2158                     hx509_set_error_string(context, 0, ret, "Out of memory");
2159                     goto out;
2160                 }
2161                 if (diff != 0) {
2162                     ret = HX509_PROXY_CERT_NAME_WRONG;
2163                     hx509_set_error_string(context, 0, ret,
2164                                            "Proxy issuer name not as expected");
2165                     goto out;
2166                 }
2167
2168                 break;
2169             } else {
2170                 /*
2171                  * Now we are done with the proxy certificates, this
2172                  * cert was an EE cert and we we will fall though to
2173                  * EE checking below.
2174                  */
2175                 type = EE_CERT;
2176                 /* FALLTHOUGH */
2177             }
2178         }
2179         case EE_CERT:
2180             /*
2181              * If there where any proxy certificates in the chain
2182              * (proxy_cert_depth > 0), check that the proxy issuer
2183              * matched proxy certificates "base" subject.
2184              */
2185             if (proxy_cert_depth) {
2186
2187                 ret = _hx509_name_cmp(&proxy_issuer,
2188                                       &c->tbsCertificate.subject, &diff);
2189                 if (ret) {
2190                     hx509_set_error_string(context, 0, ret, "out of memory");
2191                     goto out;
2192                 }
2193                 if (diff) {
2194                     ret = HX509_PROXY_CERT_NAME_WRONG;
2195                     hx509_clear_error_string(context);
2196                     goto out;
2197                 }
2198                 if (cert->basename)
2199                     hx509_name_free(&cert->basename);
2200
2201                 ret = _hx509_name_from_Name(&proxy_issuer, &cert->basename);
2202                 if (ret) {
2203                     hx509_clear_error_string(context);
2204                     goto out;
2205                 }
2206             }
2207
2208             break;
2209         }
2210
2211         ret = check_basic_constraints(context, c, type,
2212                                       i - proxy_cert_depth - selfsigned_depth);
2213         if (ret)
2214             goto out;
2215
2216         /*
2217          * Don't check the trust anchors expiration time since they
2218          * are transported out of band, from RFC3820.
2219          */
2220         if (i + 1 != path.len || CHECK_TA(ctx)) {
2221
2222             t = _hx509_Time2time_t(&c->tbsCertificate.validity.notBefore);
2223             if (t > ctx->time_now) {
2224                 ret = HX509_CERT_USED_BEFORE_TIME;
2225                 hx509_clear_error_string(context);
2226                 goto out;
2227             }
2228             t = _hx509_Time2time_t(&c->tbsCertificate.validity.notAfter);
2229             if (t < ctx->time_now) {
2230                 ret = HX509_CERT_USED_AFTER_TIME;
2231                 hx509_clear_error_string(context);
2232                 goto out;
2233             }
2234         }
2235
2236         if (type == EE_CERT)
2237             type = CA_CERT;
2238         else if (type == PROXY_CERT)
2239             proxy_cert_depth++;
2240     }
2241
2242     /*
2243      * Verify constraints, do this backward so path constraints are
2244      * checked in the right order.
2245      */
2246
2247     for (ret = 0, k = path.len; k > 0; k--) {
2248         Certificate *c;
2249         int selfsigned;
2250         i = k - 1;
2251
2252         c = _hx509_get_cert(path.val[i]);
2253
2254         ret = certificate_is_self_signed(context, c, &selfsigned);
2255         if (ret)
2256             goto out;
2257
2258         /* verify name constraints, not for selfsigned and anchor */
2259         if (!selfsigned || i + 1 != path.len) {
2260             ret = check_name_constraints(context, &nc, c);
2261             if (ret) {
2262                 goto out;
2263             }
2264         }
2265         ret = add_name_constraints(context, c, i == 0, &nc);
2266         if (ret)
2267             goto out;
2268
2269         /* XXX verify all other silly constraints */
2270
2271     }
2272
2273     /*
2274      * Verify that no certificates has been revoked.
2275      */
2276
2277     if (ctx->revoke_ctx) {
2278         hx509_certs certs;
2279
2280         ret = hx509_certs_init(context, "MEMORY:revoke-certs", 0,
2281                                NULL, &certs);
2282         if (ret)
2283             goto out;
2284
2285         for (i = 0; i < path.len; i++) {
2286             ret = hx509_certs_add(context, certs, path.val[i]);
2287             if (ret) {
2288                 hx509_certs_free(&certs);
2289                 goto out;
2290             }
2291         }
2292         ret = hx509_certs_merge(context, certs, pool);
2293         if (ret) {
2294             hx509_certs_free(&certs);
2295             goto out;
2296         }
2297
2298         for (i = 0; i < path.len - 1; i++) {
2299             size_t parent = (i < path.len - 1) ? i + 1 : i;
2300
2301             ret = hx509_revoke_verify(context,
2302                                       ctx->revoke_ctx,
2303                                       certs,
2304                                       ctx->time_now,
2305                                       path.val[i],
2306                                       path.val[parent]);
2307             if (ret) {
2308                 hx509_certs_free(&certs);
2309                 goto out;
2310             }
2311         }
2312         hx509_certs_free(&certs);
2313     }
2314
2315     /*
2316      * Verify signatures, do this backward so public key working
2317      * parameter is passed up from the anchor up though the chain.
2318      */
2319
2320     for (k = path.len; k > 0; k--) {
2321         hx509_cert signer;
2322         Certificate *c;
2323         i = k - 1;
2324
2325         c = _hx509_get_cert(path.val[i]);
2326
2327         /* is last in chain (trust anchor) */
2328         if (i + 1 == path.len) {
2329             int selfsigned;
2330
2331             signer = path.val[i];
2332
2333             ret = certificate_is_self_signed(context, signer->data, &selfsigned);
2334             if (ret)
2335                 goto out;
2336
2337             /* if trust anchor is not self signed, don't check sig */
2338             if (!selfsigned)
2339                 continue;
2340         } else {
2341             /* take next certificate in chain */
2342             signer = path.val[i + 1];
2343         }
2344
2345         /* verify signatureValue */
2346         ret = _hx509_verify_signature_bitstring(context,
2347                                                 signer,
2348                                                 &c->signatureAlgorithm,
2349                                                 &c->tbsCertificate._save,
2350                                                 &c->signatureValue);
2351         if (ret) {
2352             hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
2353                                    "Failed to verify signature of certificate");
2354             goto out;
2355         }
2356         /*
2357          * Verify that the sigature algorithm "best-before" date is
2358          * before the creation date of the certificate, do this for
2359          * trust anchors too, since any trust anchor that is created
2360          * after a algorithm is known to be bad deserved to be invalid.
2361          *
2362          * Skip the leaf certificate for now...
2363          */
2364
2365         if (i != 0 && (ctx->flags & HX509_VERIFY_CTX_F_NO_BEST_BEFORE_CHECK) == 0) {
2366             time_t notBefore =
2367                 _hx509_Time2time_t(&c->tbsCertificate.validity.notBefore);
2368             ret = _hx509_signature_best_before(context,
2369                                                &c->signatureAlgorithm,
2370                                                notBefore);
2371             if (ret)
2372                 goto out;
2373         }
2374     }
2375
2376 out:
2377     hx509_certs_free(&anchors);
2378     free_Name(&proxy_issuer);
2379     free_name_constraints(&nc);
2380     _hx509_path_free(&path);
2381
2382     return ret;
2383 }
2384
2385 /**
2386  * Verify a signature made using the private key of an certificate.
2387  *
2388  * @param context A hx509 context.
2389  * @param signer the certificate that made the signature.
2390  * @param alg algorthm that was used to sign the data.
2391  * @param data the data that was signed.
2392  * @param sig the sigature to verify.
2393  *
2394  * @return An hx509 error code, see hx509_get_error_string().
2395  *
2396  * @ingroup hx509_crypto
2397  */
2398
2399 int
2400 hx509_verify_signature(hx509_context context,
2401                        const hx509_cert signer,
2402                        const AlgorithmIdentifier *alg,
2403                        const heim_octet_string *data,
2404                        const heim_octet_string *sig)
2405 {
2406     return _hx509_verify_signature(context, signer, alg, data, sig);
2407 }
2408
2409 int
2410 _hx509_verify_signature_bitstring(hx509_context context,
2411                                   const hx509_cert signer,
2412                                   const AlgorithmIdentifier *alg,
2413                                   const heim_octet_string *data,
2414                                   const heim_bit_string *sig)
2415 {
2416     heim_octet_string os;
2417
2418     if (sig->length & 7) {
2419         hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
2420                                "signature not multiple of 8 bits");
2421         return HX509_CRYPTO_SIG_INVALID_FORMAT;
2422     }
2423
2424     os.data = sig->data;
2425     os.length = sig->length / 8;
2426
2427     return _hx509_verify_signature(context, signer, alg, data, &os);
2428 }
2429
2430
2431
2432 /**
2433  * Verify that the certificate is allowed to be used for the hostname
2434  * and address.
2435  *
2436  * @param context A hx509 context.
2437  * @param cert the certificate to match with
2438  * @param flags Flags to modify the behavior:
2439  * - HX509_VHN_F_ALLOW_NO_MATCH no match is ok
2440  * @param type type of hostname:
2441  * - HX509_HN_HOSTNAME for plain hostname.
2442  * - HX509_HN_DNSSRV for DNS SRV names.
2443  * @param hostname the hostname to check
2444  * @param sa address of the host
2445  * @param sa_size length of address
2446  *
2447  * @return An hx509 error code, see hx509_get_error_string().
2448  *
2449  * @ingroup hx509_cert
2450  */
2451
2452 int
2453 hx509_verify_hostname(hx509_context context,
2454                       const hx509_cert cert,
2455                       int flags,
2456                       hx509_hostname_type type,
2457                       const char *hostname,
2458                       const struct sockaddr *sa,
2459                       /* XXX krb5_socklen_t */ int sa_size)
2460 {
2461     GeneralNames san;
2462     const Name *name;
2463     int ret;
2464     size_t i, j, k;
2465
2466     if (sa && sa_size <= 0)
2467         return EINVAL;
2468
2469     memset(&san, 0, sizeof(san));
2470
2471     i = 0;
2472     do {
2473         ret = find_extension_subject_alt_name(cert->data, &i, &san);
2474         if (ret == HX509_EXTENSION_NOT_FOUND)
2475             break;
2476         else if (ret != 0)
2477             return HX509_PARSING_NAME_FAILED;
2478
2479         for (j = 0; j < san.len; j++) {
2480             switch (san.val[j].element) {
2481             case choice_GeneralName_dNSName: {
2482                 heim_printable_string hn;
2483                 hn.data = rk_UNCONST(hostname);
2484                 hn.length = strlen(hostname);
2485
2486                 if (der_printable_string_cmp(&san.val[j].u.dNSName, &hn) == 0) {
2487                     free_GeneralNames(&san);
2488                     return 0;
2489                 }
2490                 break;
2491             }
2492             default:
2493                 break;
2494             }
2495         }
2496         free_GeneralNames(&san);
2497     } while (1);
2498
2499     name = &cert->data->tbsCertificate.subject;
2500
2501     /* Find first CN= in the name, and try to match the hostname on that */
2502     for (ret = 0, k = name->u.rdnSequence.len; ret == 0 && k > 0; k--) {
2503         i = k - 1;
2504         for (j = 0; ret == 0 && j < name->u.rdnSequence.val[i].len; j++) {
2505             AttributeTypeAndValue *n = &name->u.rdnSequence.val[i].val[j];
2506
2507             if (der_heim_oid_cmp(&n->type, &asn1_oid_id_at_commonName) == 0) {
2508                 DirectoryString *ds = &n->value;
2509                 switch (ds->element) {
2510                 case choice_DirectoryString_printableString: {
2511                     heim_printable_string hn;
2512                     hn.data = rk_UNCONST(hostname);
2513                     hn.length = strlen(hostname);
2514
2515                     if (der_printable_string_cmp(&ds->u.printableString, &hn) == 0)
2516                         return 0;
2517                     break;
2518                 }
2519                 case choice_DirectoryString_ia5String: {
2520                     heim_ia5_string hn;
2521                     hn.data = rk_UNCONST(hostname);
2522                     hn.length = strlen(hostname);
2523
2524                     if (der_ia5_string_cmp(&ds->u.ia5String, &hn) == 0)
2525                         return 0;
2526                     break;
2527                 }
2528                 case choice_DirectoryString_utf8String:
2529                     if (strcasecmp(ds->u.utf8String, hostname) == 0)
2530                         return 0;
2531                 default:
2532                     break;
2533                 }
2534                 ret = HX509_NAME_CONSTRAINT_ERROR;
2535             }
2536         }
2537     }
2538
2539     if ((flags & HX509_VHN_F_ALLOW_NO_MATCH) == 0)
2540         ret = HX509_NAME_CONSTRAINT_ERROR;
2541
2542     return ret;
2543 }
2544
2545 int
2546 _hx509_set_cert_attribute(hx509_context context,
2547                           hx509_cert cert,
2548                           const heim_oid *oid,
2549                           const heim_octet_string *attr)
2550 {
2551     hx509_cert_attribute a;
2552     void *d;
2553
2554     if (hx509_cert_get_attribute(cert, oid) != NULL)
2555         return 0;
2556
2557     d = realloc(cert->attrs.val,
2558                 sizeof(cert->attrs.val[0]) * (cert->attrs.len + 1));
2559     if (d == NULL) {
2560         hx509_clear_error_string(context);
2561         return ENOMEM;
2562     }
2563     cert->attrs.val = d;
2564
2565     a = malloc(sizeof(*a));
2566     if (a == NULL)
2567         return ENOMEM;
2568
2569     der_copy_octet_string(attr, &a->data);
2570     der_copy_oid(oid, &a->oid);
2571
2572     cert->attrs.val[cert->attrs.len] = a;
2573     cert->attrs.len++;
2574
2575     return 0;
2576 }
2577
2578 /**
2579  * Get an external attribute for the certificate, examples are
2580  * friendly name and id.
2581  *
2582  * @param cert hx509 certificate object to search
2583  * @param oid an oid to search for.
2584  *
2585  * @return an hx509_cert_attribute, only valid as long as the
2586  * certificate is referenced.
2587  *
2588  * @ingroup hx509_cert
2589  */
2590
2591 hx509_cert_attribute
2592 hx509_cert_get_attribute(hx509_cert cert, const heim_oid *oid)
2593 {
2594     size_t i;
2595     for (i = 0; i < cert->attrs.len; i++)
2596         if (der_heim_oid_cmp(oid, &cert->attrs.val[i]->oid) == 0)
2597             return cert->attrs.val[i];
2598     return NULL;
2599 }
2600
2601 /**
2602  * Set the friendly name on the certificate.
2603  *
2604  * @param cert The certificate to set the friendly name on
2605  * @param name Friendly name.
2606  *
2607  * @return An hx509 error code, see hx509_get_error_string().
2608  *
2609  * @ingroup hx509_cert
2610  */
2611
2612 int
2613 hx509_cert_set_friendly_name(hx509_cert cert, const char *name)
2614 {
2615     if (cert->friendlyname)
2616         free(cert->friendlyname);
2617     cert->friendlyname = strdup(name);
2618     if (cert->friendlyname == NULL)
2619         return ENOMEM;
2620     return 0;
2621 }
2622
2623 /**
2624  * Get friendly name of the certificate.
2625  *
2626  * @param cert cert to get the friendly name from.
2627  *
2628  * @return an friendly name or NULL if there is. The friendly name is
2629  * only valid as long as the certificate is referenced.
2630  *
2631  * @ingroup hx509_cert
2632  */
2633
2634 const char *
2635 hx509_cert_get_friendly_name(hx509_cert cert)
2636 {
2637     hx509_cert_attribute a;
2638     PKCS9_friendlyName n;
2639     size_t sz;
2640     int ret;
2641     size_t i;
2642
2643     if (cert->friendlyname)
2644         return cert->friendlyname;
2645
2646     a = hx509_cert_get_attribute(cert, &asn1_oid_id_pkcs_9_at_friendlyName);
2647     if (a == NULL) {
2648         hx509_name name;
2649
2650         ret = hx509_cert_get_subject(cert, &name);
2651         if (ret)
2652             return NULL;
2653         ret = hx509_name_to_string(name, &cert->friendlyname);
2654         hx509_name_free(&name);
2655         if (ret)
2656             return NULL;
2657         return cert->friendlyname;
2658     }
2659
2660     ret = decode_PKCS9_friendlyName(a->data.data, a->data.length, &n, &sz);
2661     if (ret)
2662         return NULL;
2663
2664     if (n.len != 1) {
2665         free_PKCS9_friendlyName(&n);
2666         return NULL;
2667     }
2668
2669     cert->friendlyname = malloc(n.val[0].length + 1);
2670     if (cert->friendlyname == NULL) {
2671         free_PKCS9_friendlyName(&n);
2672         return NULL;
2673     }
2674
2675     for (i = 0; i < n.val[0].length; i++) {
2676         if (n.val[0].data[i] <= 0xff)
2677             cert->friendlyname[i] = n.val[0].data[i] & 0xff;
2678         else
2679             cert->friendlyname[i] = 'X';
2680     }
2681     cert->friendlyname[i] = '\0';
2682     free_PKCS9_friendlyName(&n);
2683
2684     return cert->friendlyname;
2685 }
2686
2687 void
2688 _hx509_query_clear(hx509_query *q)
2689 {
2690     memset(q, 0, sizeof(*q));
2691 }
2692
2693 /**
2694  * Allocate an query controller. Free using hx509_query_free().
2695  *
2696  * @param context A hx509 context.
2697  * @param q return pointer to a hx509_query.
2698  *
2699  * @return An hx509 error code, see hx509_get_error_string().
2700  *
2701  * @ingroup hx509_cert
2702  */
2703
2704 int
2705 hx509_query_alloc(hx509_context context, hx509_query **q)
2706 {
2707     *q = calloc(1, sizeof(**q));
2708     if (*q == NULL)
2709         return ENOMEM;
2710     return 0;
2711 }
2712
2713
2714 /**
2715  * Set match options for the hx509 query controller.
2716  *
2717  * @param q query controller.
2718  * @param option options to control the query controller.
2719  *
2720  * @return An hx509 error code, see hx509_get_error_string().
2721  *
2722  * @ingroup hx509_cert
2723  */
2724
2725 void
2726 hx509_query_match_option(hx509_query *q, hx509_query_option option)
2727 {
2728     switch(option) {
2729     case HX509_QUERY_OPTION_PRIVATE_KEY:
2730         q->match |= HX509_QUERY_PRIVATE_KEY;
2731         break;
2732     case HX509_QUERY_OPTION_KU_ENCIPHERMENT:
2733         q->match |= HX509_QUERY_KU_ENCIPHERMENT;
2734         break;
2735     case HX509_QUERY_OPTION_KU_DIGITALSIGNATURE:
2736         q->match |= HX509_QUERY_KU_DIGITALSIGNATURE;
2737         break;
2738     case HX509_QUERY_OPTION_KU_KEYCERTSIGN:
2739         q->match |= HX509_QUERY_KU_KEYCERTSIGN;
2740         break;
2741     case HX509_QUERY_OPTION_END:
2742     default:
2743         break;
2744     }
2745 }
2746
2747 /**
2748  * Set the issuer and serial number of match in the query
2749  * controller. The function make copies of the isser and serial number.
2750  *
2751  * @param q a hx509 query controller
2752  * @param issuer issuer to search for
2753  * @param serialNumber the serialNumber of the issuer.
2754  *
2755  * @return An hx509 error code, see hx509_get_error_string().
2756  *
2757  * @ingroup hx509_cert
2758  */
2759
2760 int
2761 hx509_query_match_issuer_serial(hx509_query *q,
2762                                 const Name *issuer,
2763                                 const heim_integer *serialNumber)
2764 {
2765     int ret;
2766     if (q->serial) {
2767         der_free_heim_integer(q->serial);
2768         free(q->serial);
2769     }
2770     q->serial = malloc(sizeof(*q->serial));
2771     if (q->serial == NULL)
2772         return ENOMEM;
2773     ret = der_copy_heim_integer(serialNumber, q->serial);
2774     if (ret) {
2775         free(q->serial);
2776         q->serial = NULL;
2777         return ret;
2778     }
2779     if (q->issuer_name) {
2780         free_Name(q->issuer_name);
2781         free(q->issuer_name);
2782     }
2783     q->issuer_name = malloc(sizeof(*q->issuer_name));
2784     if (q->issuer_name == NULL)
2785         return ENOMEM;
2786     ret = copy_Name(issuer, q->issuer_name);
2787     if (ret) {
2788         free(q->issuer_name);
2789         q->issuer_name = NULL;
2790         return ret;
2791     }
2792     q->match |= HX509_QUERY_MATCH_SERIALNUMBER|HX509_QUERY_MATCH_ISSUER_NAME;
2793     return 0;
2794 }
2795
2796 /**
2797  * Set the query controller to match on a friendly name
2798  *
2799  * @param q a hx509 query controller.
2800  * @param name a friendly name to match on
2801  *
2802  * @return An hx509 error code, see hx509_get_error_string().
2803  *
2804  * @ingroup hx509_cert
2805  */
2806
2807 int
2808 hx509_query_match_friendly_name(hx509_query *q, const char *name)
2809 {
2810     if (q->friendlyname)
2811         free(q->friendlyname);
2812     q->friendlyname = strdup(name);
2813     if (q->friendlyname == NULL)
2814         return ENOMEM;
2815     q->match |= HX509_QUERY_MATCH_FRIENDLY_NAME;
2816     return 0;
2817 }
2818
2819 /**
2820  * Set the query controller to require an one specific EKU (extended
2821  * key usage). Any previous EKU matching is overwitten. If NULL is
2822  * passed in as the eku, the EKU requirement is reset.
2823  *
2824  * @param q a hx509 query controller.
2825  * @param eku an EKU to match on.
2826  *
2827  * @return An hx509 error code, see hx509_get_error_string().
2828  *
2829  * @ingroup hx509_cert
2830  */
2831
2832 int
2833 hx509_query_match_eku(hx509_query *q, const heim_oid *eku)
2834 {
2835     int ret;
2836
2837     if (eku == NULL) {
2838         if (q->eku) {
2839             der_free_oid(q->eku);
2840             free(q->eku);
2841             q->eku = NULL;
2842         }
2843         q->match &= ~HX509_QUERY_MATCH_EKU;
2844     } else {
2845         if (q->eku) {
2846             der_free_oid(q->eku);
2847         } else {
2848             q->eku = calloc(1, sizeof(*q->eku));
2849             if (q->eku == NULL)
2850                 return ENOMEM;
2851         }
2852         ret = der_copy_oid(eku, q->eku);
2853         if (ret) {
2854             free(q->eku);
2855             q->eku = NULL;
2856             return ret;
2857         }
2858         q->match |= HX509_QUERY_MATCH_EKU;
2859     }
2860     return 0;
2861 }
2862
2863 int
2864 hx509_query_match_expr(hx509_context context, hx509_query *q, const char *expr)
2865 {
2866     if (q->expr) {
2867         _hx509_expr_free(q->expr);
2868         q->expr = NULL;
2869     }
2870
2871     if (expr == NULL) {
2872         q->match &= ~HX509_QUERY_MATCH_EXPR;
2873     } else {
2874         q->expr = _hx509_expr_parse(expr);
2875         if (q->expr)
2876             q->match |= HX509_QUERY_MATCH_EXPR;
2877     }
2878
2879     return 0;
2880 }
2881
2882 /**
2883  * Set the query controller to match using a specific match function.
2884  *
2885  * @param q a hx509 query controller.
2886  * @param func function to use for matching, if the argument is NULL,
2887  * the match function is removed.
2888  * @param ctx context passed to the function.
2889  *
2890  * @return An hx509 error code, see hx509_get_error_string().
2891  *
2892  * @ingroup hx509_cert
2893  */
2894
2895 int
2896 hx509_query_match_cmp_func(hx509_query *q,
2897                            int (*func)(hx509_context, hx509_cert, void *),
2898                            void *ctx)
2899 {
2900     if (func)
2901         q->match |= HX509_QUERY_MATCH_FUNCTION;
2902     else
2903         q->match &= ~HX509_QUERY_MATCH_FUNCTION;
2904     q->cmp_func = func;
2905     q->cmp_func_ctx = ctx;
2906     return 0;
2907 }
2908
2909 /**
2910  * Free the query controller.
2911  *
2912  * @param context A hx509 context.
2913  * @param q a pointer to the query controller.
2914  *
2915  * @ingroup hx509_cert
2916  */
2917
2918 void
2919 hx509_query_free(hx509_context context, hx509_query *q)
2920 {
2921     if (q == NULL)
2922         return;
2923
2924     if (q->serial) {
2925         der_free_heim_integer(q->serial);
2926         free(q->serial);
2927     }
2928     if (q->issuer_name) {
2929         free_Name(q->issuer_name);
2930         free(q->issuer_name);
2931     }
2932     if (q->eku) {
2933         der_free_oid(q->eku);
2934         free(q->eku);
2935     }
2936     if (q->friendlyname)
2937         free(q->friendlyname);
2938     if (q->expr)
2939         _hx509_expr_free(q->expr);
2940
2941     memset(q, 0, sizeof(*q));
2942     free(q);
2943 }
2944
2945 int
2946 _hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert cert)
2947 {
2948     Certificate *c = _hx509_get_cert(cert);
2949     int ret, diff;
2950
2951     _hx509_query_statistic(context, 1, q);
2952
2953     if ((q->match & HX509_QUERY_FIND_ISSUER_CERT) &&
2954         _hx509_cert_is_parent_cmp(q->subject, c, 0) != 0)
2955         return 0;
2956
2957     if ((q->match & HX509_QUERY_MATCH_CERTIFICATE) &&
2958         _hx509_Certificate_cmp(q->certificate, c) != 0)
2959         return 0;
2960
2961     if ((q->match & HX509_QUERY_MATCH_SERIALNUMBER)
2962         && der_heim_integer_cmp(&c->tbsCertificate.serialNumber, q->serial) != 0)
2963         return 0;
2964
2965     if (q->match & HX509_QUERY_MATCH_ISSUER_NAME) {
2966         ret = _hx509_name_cmp(&c->tbsCertificate.issuer, q->issuer_name, &diff);
2967         if (ret || diff)
2968             return 0;
2969     }
2970
2971     if (q->match & HX509_QUERY_MATCH_SUBJECT_NAME) {
2972         ret = _hx509_name_cmp(&c->tbsCertificate.subject, q->subject_name, &diff);
2973         if (ret || diff)
2974             return 0;
2975     }
2976
2977     if (q->match & HX509_QUERY_MATCH_SUBJECT_KEY_ID) {
2978         SubjectKeyIdentifier si;
2979
2980         ret = _hx509_find_extension_subject_key_id(c, &si);
2981         if (ret == 0) {
2982             if (der_heim_octet_string_cmp(&si, q->subject_id) != 0)
2983                 ret = 1;
2984             free_SubjectKeyIdentifier(&si);
2985         }
2986         if (ret)
2987             return 0;
2988     }
2989     if ((q->match & HX509_QUERY_MATCH_ISSUER_ID))
2990         return 0;
2991     if ((q->match & HX509_QUERY_PRIVATE_KEY) &&
2992         _hx509_cert_private_key(cert) == NULL)
2993         return 0;
2994
2995     {
2996         unsigned ku = 0;
2997         if (q->match & HX509_QUERY_KU_DIGITALSIGNATURE)
2998             ku |= (1 << 0);
2999         if (q->match & HX509_QUERY_KU_NONREPUDIATION)
3000             ku |= (1 << 1);
3001         if (q->match & HX509_QUERY_KU_ENCIPHERMENT)
3002             ku |= (1 << 2);
3003         if (q->match & HX509_QUERY_KU_DATAENCIPHERMENT)
3004             ku |= (1 << 3);
3005         if (q->match & HX509_QUERY_KU_KEYAGREEMENT)
3006             ku |= (1 << 4);
3007         if (q->match & HX509_QUERY_KU_KEYCERTSIGN)
3008             ku |= (1 << 5);
3009         if (q->match & HX509_QUERY_KU_CRLSIGN)
3010             ku |= (1 << 6);
3011         if (ku && check_key_usage(context, c, ku, TRUE))
3012             return 0;
3013     }
3014     if ((q->match & HX509_QUERY_ANCHOR))
3015         return 0;
3016
3017     if (q->match & HX509_QUERY_MATCH_LOCAL_KEY_ID) {
3018         hx509_cert_attribute a;
3019
3020         a = hx509_cert_get_attribute(cert, &asn1_oid_id_pkcs_9_at_localKeyId);
3021         if (a == NULL)
3022             return 0;
3023         if (der_heim_octet_string_cmp(&a->data, q->local_key_id) != 0)
3024             return 0;
3025     }
3026
3027     if (q->match & HX509_QUERY_NO_MATCH_PATH) {
3028         size_t i;
3029
3030         for (i = 0; i < q->path->len; i++)
3031             if (hx509_cert_cmp(q->path->val[i], cert) == 0)
3032                 return 0;
3033     }
3034     if (q->match & HX509_QUERY_MATCH_FRIENDLY_NAME) {
3035         const char *name = hx509_cert_get_friendly_name(cert);
3036         if (name == NULL)
3037             return 0;
3038         if (strcasecmp(q->friendlyname, name) != 0)
3039             return 0;
3040     }
3041     if (q->match & HX509_QUERY_MATCH_FUNCTION) {
3042         ret = (*q->cmp_func)(context, cert, q->cmp_func_ctx);
3043         if (ret != 0)
3044             return 0;
3045     }
3046
3047     if (q->match & HX509_QUERY_MATCH_KEY_HASH_SHA1) {
3048         heim_octet_string os;
3049
3050         os.data = c->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.data;
3051         os.length =
3052             c->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.length / 8;
3053
3054         ret = _hx509_verify_signature(context,
3055                                       NULL,
3056                                       hx509_signature_sha1(),
3057                                       &os,
3058                                       q->keyhash_sha1);
3059         if (ret != 0)
3060             return 0;
3061     }
3062
3063     if (q->match & HX509_QUERY_MATCH_TIME) {
3064         time_t t;
3065         t = _hx509_Time2time_t(&c->tbsCertificate.validity.notBefore);
3066         if (t > q->timenow)
3067             return 0;
3068         t = _hx509_Time2time_t(&c->tbsCertificate.validity.notAfter);
3069         if (t < q->timenow)
3070             return 0;
3071     }
3072
3073     /* If an EKU is required, check the cert for it. */
3074     if ((q->match & HX509_QUERY_MATCH_EKU) &&
3075         hx509_cert_check_eku(context, cert, q->eku, 0))
3076         return 0;
3077
3078     if ((q->match & HX509_QUERY_MATCH_EXPR)) {
3079         hx509_env env = NULL;
3080
3081         ret = _hx509_cert_to_env(context, cert, &env);
3082         if (ret)
3083             return 0;
3084
3085         ret = _hx509_expr_eval(context, env, q->expr);
3086         hx509_env_free(&env);
3087         if (ret == 0)
3088             return 0;
3089     }
3090
3091     if (q->match & ~HX509_QUERY_MASK)
3092         return 0;
3093
3094     return 1;
3095 }
3096
3097 /**
3098  * Set a statistic file for the query statistics.
3099  *
3100  * @param context A hx509 context.
3101  * @param fn statistics file name
3102  *
3103  * @ingroup hx509_cert
3104  */
3105
3106 void
3107 hx509_query_statistic_file(hx509_context context, const char *fn)
3108 {
3109     if (context->querystat)
3110         free(context->querystat);
3111     context->querystat = strdup(fn);
3112 }
3113
3114 void
3115 _hx509_query_statistic(hx509_context context, int type, const hx509_query *q)
3116 {
3117     FILE *f;
3118     if (context->querystat == NULL)
3119         return;
3120     f = fopen(context->querystat, "a");
3121     if (f == NULL)
3122         return;
3123     rk_cloexec_file(f);
3124     fprintf(f, "%d %d\n", type, q->match);
3125     fclose(f);
3126 }
3127
3128 static const char *statname[] = {
3129     "find issuer cert",
3130     "match serialnumber",
3131     "match issuer name",
3132     "match subject name",
3133     "match subject key id",
3134     "match issuer id",
3135     "private key",
3136     "ku encipherment",
3137     "ku digitalsignature",
3138     "ku keycertsign",
3139     "ku crlsign",
3140     "ku nonrepudiation",
3141     "ku keyagreement",
3142     "ku dataencipherment",
3143     "anchor",
3144     "match certificate",
3145     "match local key id",
3146     "no match path",
3147     "match friendly name",
3148     "match function",
3149     "match key hash sha1",
3150     "match time"
3151 };
3152
3153 struct stat_el {
3154     unsigned long stats;
3155     unsigned int index;
3156 };
3157
3158
3159 static int
3160 stat_sort(const void *a, const void *b)
3161 {
3162     const struct stat_el *ae = a;
3163     const struct stat_el *be = b;
3164     return be->stats - ae->stats;
3165 }
3166
3167 /**
3168  * Unparse the statistics file and print the result on a FILE descriptor.
3169  *
3170  * @param context A hx509 context.
3171  * @param printtype tyep to print
3172  * @param out the FILE to write the data on.
3173  *
3174  * @ingroup hx509_cert
3175  */
3176
3177 void
3178 hx509_query_unparse_stats(hx509_context context, int printtype, FILE *out)
3179 {
3180     rtbl_t t;
3181     FILE *f;
3182     int type, mask, num;
3183     size_t i;
3184     unsigned long multiqueries = 0, totalqueries = 0;
3185     struct stat_el stats[32];
3186
3187     if (context->querystat == NULL)
3188         return;
3189     f = fopen(context->querystat, "r");
3190     if (f == NULL) {
3191         fprintf(out, "No statistic file %s: %s.\n",
3192                 context->querystat, strerror(errno));
3193         return;
3194     }
3195     rk_cloexec_file(f);
3196
3197     for (i = 0; i < sizeof(stats)/sizeof(stats[0]); i++) {
3198         stats[i].index = i;
3199         stats[i].stats = 0;
3200     }
3201
3202     while (fscanf(f, "%d %d\n", &type, &mask) == 2) {
3203         if (type != printtype)
3204             continue;
3205         num = i = 0;
3206         while (mask && i < sizeof(stats)/sizeof(stats[0])) {
3207             if (mask & 1) {
3208                 stats[i].stats++;
3209                 num++;
3210             }
3211             mask = mask >>1 ;
3212             i++;
3213         }
3214         if (num > 1)
3215             multiqueries++;
3216         totalqueries++;
3217     }
3218     fclose(f);
3219
3220     qsort(stats, sizeof(stats)/sizeof(stats[0]), sizeof(stats[0]), stat_sort);
3221
3222     t = rtbl_create();
3223     if (t == NULL)
3224         errx(1, "out of memory");
3225
3226     rtbl_set_separator (t, "  ");
3227
3228     rtbl_add_column_by_id (t, 0, "Name", 0);
3229     rtbl_add_column_by_id (t, 1, "Counter", 0);
3230
3231
3232     for (i = 0; i < sizeof(stats)/sizeof(stats[0]); i++) {
3233         char str[10];
3234
3235         if (stats[i].index < sizeof(statname)/sizeof(statname[0]))
3236             rtbl_add_column_entry_by_id (t, 0, statname[stats[i].index]);
3237         else {
3238             snprintf(str, sizeof(str), "%d", stats[i].index);
3239             rtbl_add_column_entry_by_id (t, 0, str);
3240         }
3241         snprintf(str, sizeof(str), "%lu", stats[i].stats);
3242         rtbl_add_column_entry_by_id (t, 1, str);
3243     }
3244
3245     rtbl_format(t, out);
3246     rtbl_destroy(t);
3247
3248     fprintf(out, "\nQueries: multi %lu total %lu\n",
3249             multiqueries, totalqueries);
3250 }
3251
3252 /**
3253  * Check the extended key usage on the hx509 certificate.
3254  *
3255  * @param context A hx509 context.
3256  * @param cert A hx509 context.
3257  * @param eku the EKU to check for
3258  * @param allow_any_eku if the any EKU is set, allow that to be a
3259  * substitute.
3260  *
3261  * @return An hx509 error code, see hx509_get_error_string().
3262  *
3263  * @ingroup hx509_cert
3264  */
3265
3266 int
3267 hx509_cert_check_eku(hx509_context context, hx509_cert cert,
3268                      const heim_oid *eku, int allow_any_eku)
3269 {
3270     ExtKeyUsage e;
3271     int ret;
3272     size_t i;
3273
3274     ret = find_extension_eku(_hx509_get_cert(cert), &e);
3275     if (ret) {
3276         hx509_clear_error_string(context);
3277         return ret;
3278     }
3279
3280     for (i = 0; i < e.len; i++) {
3281         if (der_heim_oid_cmp(eku, &e.val[i]) == 0) {
3282             free_ExtKeyUsage(&e);
3283             return 0;
3284         }
3285         if (allow_any_eku) {
3286 #if 0
3287             if (der_heim_oid_cmp(id_any_eku, &e.val[i]) == 0) {
3288                 free_ExtKeyUsage(&e);
3289                 return 0;
3290             }
3291 #endif
3292         }
3293     }
3294     free_ExtKeyUsage(&e);
3295     hx509_clear_error_string(context);
3296     return HX509_CERTIFICATE_MISSING_EKU;
3297 }
3298
3299 int
3300 _hx509_cert_get_keyusage(hx509_context context,
3301                          hx509_cert c,
3302                          KeyUsage *ku)
3303 {
3304     Certificate *cert;
3305     const Extension *e;
3306     size_t size;
3307     int ret;
3308     size_t i = 0;
3309
3310     memset(ku, 0, sizeof(*ku));
3311
3312     cert = _hx509_get_cert(c);
3313
3314     if (_hx509_cert_get_version(cert) < 3)
3315         return 0;
3316
3317     e = find_extension(cert, &asn1_oid_id_x509_ce_keyUsage, &i);
3318     if (e == NULL)
3319         return HX509_KU_CERT_MISSING;
3320
3321     ret = decode_KeyUsage(e->extnValue.data, e->extnValue.length, ku, &size);
3322     if (ret)
3323         return ret;
3324     return 0;
3325 }
3326
3327 int
3328 _hx509_cert_get_eku(hx509_context context,
3329                     hx509_cert cert,
3330                     ExtKeyUsage *e)
3331 {
3332     int ret;
3333
3334     memset(e, 0, sizeof(*e));
3335
3336     ret = find_extension_eku(_hx509_get_cert(cert), e);
3337     if (ret && ret != HX509_EXTENSION_NOT_FOUND) {
3338         hx509_clear_error_string(context);
3339         return ret;
3340     }
3341     return 0;
3342 }
3343
3344 /**
3345  * Encodes the hx509 certificate as a DER encode binary.
3346  *
3347  * @param context A hx509 context.
3348  * @param c the certificate to encode.
3349  * @param os the encode certificate, set to NULL, 0 on case of
3350  * error. Free the os->data with hx509_xfree().
3351  *
3352  * @return An hx509 error code, see hx509_get_error_string().
3353  *
3354  * @ingroup hx509_cert
3355  */
3356
3357 int
3358 hx509_cert_binary(hx509_context context, hx509_cert c, heim_octet_string *os)
3359 {
3360     size_t size;
3361     int ret;
3362
3363     os->data = NULL;
3364     os->length = 0;
3365
3366     ASN1_MALLOC_ENCODE(Certificate, os->data, os->length,
3367                        _hx509_get_cert(c), &size, ret);
3368     if (ret) {
3369         os->data = NULL;
3370         os->length = 0;
3371         return ret;
3372     }
3373     if (os->length != size)
3374         _hx509_abort("internal ASN.1 encoder error");
3375
3376     return ret;
3377 }
3378
3379 /*
3380  * Last to avoid lost __attribute__s due to #undef.
3381  */
3382
3383 #undef __attribute__
3384 #define __attribute__(X)
3385
3386 void
3387 _hx509_abort(const char *fmt, ...)
3388      __attribute__ ((noreturn, format (printf, 1, 2)))
3389 {
3390     va_list ap;
3391     va_start(ap, fmt);
3392     vprintf(fmt, ap);
3393     va_end(ap);
3394     printf("\n");
3395     fflush(stdout);
3396     abort();
3397 }
3398
3399 /**
3400  * Free a data element allocated in the library.
3401  *
3402  * @param ptr data to be freed.
3403  *
3404  * @ingroup hx509_misc
3405  */
3406
3407 void
3408 hx509_xfree(void *ptr)
3409 {
3410     free(ptr);
3411 }
3412
3413 /**
3414  *
3415  */
3416
3417 int
3418 _hx509_cert_to_env(hx509_context context, hx509_cert cert, hx509_env *env)
3419 {
3420     ExtKeyUsage eku;
3421     hx509_name name;
3422     char *buf;
3423     int ret;
3424     hx509_env envcert = NULL;
3425
3426     *env = NULL;
3427
3428     /* version */
3429     asprintf(&buf, "%d", _hx509_cert_get_version(_hx509_get_cert(cert)));
3430     ret = hx509_env_add(context, &envcert, "version", buf);
3431     free(buf);
3432     if (ret)
3433         goto out;
3434
3435     /* subject */
3436     ret = hx509_cert_get_subject(cert, &name);
3437     if (ret)
3438         goto out;
3439
3440     ret = hx509_name_to_string(name, &buf);
3441     if (ret) {
3442         hx509_name_free(&name);
3443         goto out;
3444     }
3445
3446     ret = hx509_env_add(context, &envcert, "subject", buf);
3447     hx509_name_free(&name);
3448     if (ret)
3449         goto out;
3450
3451     /* issuer */
3452     ret = hx509_cert_get_issuer(cert, &name);
3453     if (ret)
3454         goto out;
3455
3456     ret = hx509_name_to_string(name, &buf);
3457     hx509_name_free(&name);
3458     if (ret)
3459         goto out;
3460
3461     ret = hx509_env_add(context, &envcert, "issuer", buf);
3462     hx509_xfree(buf);
3463     if (ret)
3464         goto out;
3465
3466     /* eku */
3467
3468     ret = _hx509_cert_get_eku(context, cert, &eku);
3469     if (ret == HX509_EXTENSION_NOT_FOUND)
3470         ;
3471     else if (ret != 0)
3472         goto out;
3473     else {
3474         size_t i;
3475         hx509_env enveku = NULL;
3476
3477         for (i = 0; i < eku.len; i++) {
3478
3479             ret = der_print_heim_oid(&eku.val[i], '.', &buf);
3480             if (ret) {
3481                 free_ExtKeyUsage(&eku);
3482                 hx509_env_free(&enveku);
3483                 goto out;
3484             }
3485             ret = hx509_env_add(context, &enveku, buf, "oid-name-here");
3486             free(buf);
3487             if (ret) {
3488                 free_ExtKeyUsage(&eku);
3489                 hx509_env_free(&enveku);
3490                 goto out;
3491             }
3492         }
3493         free_ExtKeyUsage(&eku);
3494
3495         ret = hx509_env_add_binding(context, &envcert, "eku", enveku);
3496         if (ret) {
3497             hx509_env_free(&enveku);
3498             goto out;
3499         }
3500     }
3501
3502     {
3503         Certificate *c = _hx509_get_cert(cert);
3504         heim_octet_string os, sig;
3505         hx509_env envhash = NULL;
3506
3507         os.data = c->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.data;
3508         os.length =
3509           c->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.length / 8;
3510
3511         ret = _hx509_create_signature(context,
3512                                       NULL,
3513                                       hx509_signature_sha1(),
3514                                       &os,
3515                                       NULL,
3516                                       &sig);
3517         if (ret != 0)
3518             goto out;
3519
3520         ret = hex_encode(sig.data, sig.length, &buf);
3521         der_free_octet_string(&sig);
3522         if (ret < 0) {
3523             ret = ENOMEM;
3524             hx509_set_error_string(context, 0, ret,
3525                                    "Out of memory");
3526             goto out;
3527         }
3528
3529         ret = hx509_env_add(context, &envhash, "sha1", buf);
3530         free(buf);
3531         if (ret)
3532             goto out;
3533
3534         ret = hx509_env_add_binding(context, &envcert, "hash", envhash);
3535         if (ret) {
3536           hx509_env_free(&envhash);
3537           goto out;
3538         }
3539     }
3540
3541     ret = hx509_env_add_binding(context, env, "certificate", envcert);
3542     if (ret)
3543         goto out;
3544
3545     return 0;
3546
3547 out:
3548     hx509_env_free(&envcert);
3549     return ret;
3550 }
3551
3552 /**
3553  * Print a simple representation of a certificate
3554  *
3555  * @param context A hx509 context, can be NULL
3556  * @param cert certificate to print
3557  * @param out the stdio output stream, if NULL, stdout is used
3558  *
3559  * @return An hx509 error code
3560  *
3561  * @ingroup hx509_cert
3562  */
3563
3564 int
3565 hx509_print_cert(hx509_context context, hx509_cert cert, FILE *out)
3566 {
3567     hx509_name name;
3568     char *str;
3569     int ret;
3570
3571     if (out == NULL)
3572         out = stderr;
3573
3574     ret = hx509_cert_get_issuer(cert, &name);
3575     if (ret)
3576         return ret;
3577     hx509_name_to_string(name, &str);
3578     hx509_name_free(&name);
3579     fprintf(out, "    issuer:  \"%s\"\n", str);
3580     free(str);
3581
3582     ret = hx509_cert_get_subject(cert, &name);
3583     if (ret)
3584         return ret;
3585     hx509_name_to_string(name, &str);
3586     hx509_name_free(&name);
3587     fprintf(out, "    subject: \"%s\"\n", str);
3588     free(str);
3589
3590     {
3591         heim_integer serialNumber;
3592
3593         ret = hx509_cert_get_serialnumber(cert, &serialNumber);
3594         if (ret)
3595             return ret;
3596         ret = der_print_hex_heim_integer(&serialNumber, &str);
3597         if (ret)
3598             return ret;
3599         der_free_heim_integer(&serialNumber);
3600         fprintf(out, "    serial: %s\n", str);
3601         free(str);
3602     }
3603
3604     printf("    keyusage: ");
3605     ret = hx509_cert_keyusage_print(context, cert, &str);
3606     if (ret == 0) {
3607         fprintf(out, "%s\n", str);
3608         free(str);
3609     } else
3610         fprintf(out, "no");
3611
3612     return 0;
3613 }