cert.c revision 1.24
1/*	$OpenBSD: cert.c,v 1.24 2003/06/03 14:28:16 ho Exp $	*/
2/*	$EOM: cert.c,v 1.18 2000/09/28 12:53:27 niklas Exp $	*/
3
4/*
5 * Copyright (c) 1998, 1999 Niels Provos.  All rights reserved.
6 * Copyright (c) 1999, 2000 Niklas Hallqvist.  All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/*
30 * This code was written under funding by Ericsson Radio Systems.
31 */
32
33#include <sys/param.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37
38#include "sysdep.h"
39
40#include "isakmp_num.h"
41#include "log.h"
42#include "cert.h"
43
44#ifdef USE_X509
45#include "x509.h"
46#endif
47
48#ifdef USE_KEYNOTE
49#include "policy.h"
50#endif
51
52struct cert_handler cert_handler[] = {
53#ifdef USE_X509
54  {
55    ISAKMP_CERTENC_X509_SIG,
56    x509_cert_init, x509_crl_init, x509_cert_get, x509_cert_validate,
57    x509_cert_insert, x509_cert_free,
58    x509_certreq_validate, x509_certreq_decode, x509_free_aca,
59    x509_cert_obtain, x509_cert_get_key, x509_cert_get_subjects,
60    x509_cert_dup, x509_serialize, x509_printable, x509_from_printable
61  },
62#endif
63#ifdef USE_KEYNOTE
64  {
65    ISAKMP_CERTENC_KEYNOTE,
66    keynote_cert_init, NULL, keynote_cert_get, keynote_cert_validate,
67    keynote_cert_insert, keynote_cert_free,
68    keynote_certreq_validate, keynote_certreq_decode, keynote_free_aca,
69    keynote_cert_obtain, keynote_cert_get_key, keynote_cert_get_subjects,
70    keynote_cert_dup, keynote_serialize, keynote_printable,
71    keynote_from_printable
72  },
73#endif
74};
75
76/* Initialize all certificate handlers */
77
78int
79cert_init (void)
80{
81  int i, err = 1;
82
83  for (i = 0; i < sizeof cert_handler / sizeof cert_handler[0]; i++)
84    if (cert_handler[i].cert_init && !(*cert_handler[i].cert_init) ())
85      err = 0;
86
87  return err;
88}
89
90int
91crl_init (void)
92{
93  int i, err = 1;
94
95  for (i = 0; i < sizeof cert_handler / sizeof cert_handler[0]; i++)
96    if (cert_handler[i].crl_init && !(*cert_handler[i].crl_init) ())
97      err = 0;
98
99  return err;
100}
101
102struct cert_handler *
103cert_get (u_int16_t id)
104{
105  int i;
106
107  for (i = 0; i < sizeof cert_handler / sizeof cert_handler[0]; i++)
108    if (id == cert_handler[i].id)
109      return &cert_handler[i];
110  return 0;
111}
112
113/*
114 * Decode the certificate request of type TYPE contained in DATA extending
115 * DATALEN bytes.  Return a certreq_aca structure which the caller is
116 * responsible for deallocating.
117 */
118struct certreq_aca *
119certreq_decode (u_int16_t type, u_int8_t *data, u_int32_t datalen)
120{
121  struct cert_handler *handler;
122  struct certreq_aca aca, *ret;
123
124  handler = cert_get (type);
125  if (!handler)
126    return 0;
127
128  aca.id = type;
129  aca.handler = handler;
130
131  if (datalen > 0)
132    {
133      aca.data = handler->certreq_decode (data, datalen);
134      if (!aca.data)
135	return 0;
136    }
137  else
138    aca.data = 0;
139
140  ret = malloc (sizeof aca);
141  if (!ret)
142    {
143      log_error ("certreq_decode: malloc (%lu) failed",
144		 (unsigned long)sizeof aca);
145      handler->free_aca (aca.data);
146      return 0;
147    }
148
149  memcpy (ret, &aca, sizeof aca);
150
151  return ret;
152}
153
154void
155cert_free_subjects (int n, u_int8_t **id, u_int32_t *len)
156{
157  int i;
158
159  for (i = 0; i < n; i++)
160    free (id[i]);
161  free (id);
162  free (len);
163}
164