1 /* $OpenBSD: cert.c,v 1.32 2007/08/05 09:43:09 tom 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 "isakmp_num.h" 39 #include "log.h" 40 #include "cert.h" 41 #include "x509.h" 42 43 #include "policy.h" 44 45 struct cert_handler cert_handler[] = { 46 { 47 ISAKMP_CERTENC_X509_SIG, 48 x509_cert_init, x509_crl_init, x509_cert_get, x509_cert_validate, 49 x509_cert_insert, x509_cert_free, 50 x509_certreq_validate, x509_certreq_decode, x509_free_aca, 51 x509_cert_obtain, x509_cert_get_key, x509_cert_get_subjects, 52 x509_cert_dup, x509_serialize, x509_printable, x509_from_printable, 53 x509_ca_count 54 }, 55 { 56 ISAKMP_CERTENC_KEYNOTE, 57 keynote_cert_init, NULL, keynote_cert_get, keynote_cert_validate, 58 keynote_cert_insert, keynote_cert_free, 59 keynote_certreq_validate, keynote_certreq_decode, keynote_free_aca, 60 keynote_cert_obtain, keynote_cert_get_key, keynote_cert_get_subjects, 61 keynote_cert_dup, keynote_serialize, keynote_printable, 62 keynote_from_printable, keynote_ca_count 63 }, 64 }; 65 66 /* Initialize all certificate handlers */ 67 int 68 cert_init(void) 69 { 70 size_t i; 71 int err = 1; 72 73 for (i = 0; i < sizeof cert_handler / sizeof cert_handler[0]; i++) 74 if (cert_handler[i].cert_init && 75 !(*cert_handler[i].cert_init)()) 76 err = 0; 77 78 return err; 79 } 80 81 int 82 crl_init(void) 83 { 84 size_t i; 85 int err = 1; 86 87 for (i = 0; i < sizeof cert_handler / sizeof cert_handler[0]; i++) 88 if (cert_handler[i].crl_init && !(*cert_handler[i].crl_init)()) 89 err = 0; 90 91 return err; 92 } 93 94 struct cert_handler * 95 cert_get(u_int16_t id) 96 { 97 size_t i; 98 99 for (i = 0; i < sizeof cert_handler / sizeof cert_handler[0]; i++) 100 if (id == cert_handler[i].id) 101 return &cert_handler[i]; 102 return 0; 103 } 104 105 /* 106 * Decode the certificate request of type TYPE contained in DATA extending 107 * DATALEN bytes. Return a certreq_aca structure which the caller is 108 * responsible for deallocating. 109 */ 110 struct certreq_aca * 111 certreq_decode(u_int16_t type, u_int8_t *data, u_int32_t datalen) 112 { 113 struct cert_handler *handler; 114 struct certreq_aca aca, *ret; 115 116 handler = cert_get(type); 117 if (!handler) 118 return 0; 119 120 aca.id = type; 121 aca.handler = handler; 122 aca.data = aca.raw_ca = NULL; 123 124 if (datalen > 0) { 125 int rc; 126 127 rc = handler->certreq_decode(&aca.data, data, datalen); 128 if (!rc) 129 return 0; 130 131 aca.raw_ca = malloc(datalen); 132 if (aca.raw_ca == NULL) { 133 log_error("certreq_decode: malloc (%lu) failed", 134 (unsigned long)datalen); 135 handler->free_aca(aca.data); 136 return 0; 137 } 138 139 memcpy(aca.raw_ca, data, datalen); 140 } 141 aca.raw_ca_len = datalen; 142 143 ret = malloc(sizeof aca); 144 if (!ret) { 145 log_error("certreq_decode: malloc (%lu) failed", 146 (unsigned long)sizeof aca); 147 free(aca.raw_ca); 148 handler->free_aca(aca.data); 149 return 0; 150 } 151 memcpy(ret, &aca, sizeof aca); 152 return ret; 153 } 154 155 void 156 cert_free_subjects(int n, u_int8_t **id, u_int32_t *len) 157 { 158 int i; 159 160 for (i = 0; i < n; i++) 161 free(id[i]); 162 free(id); 163 free(len); 164 } 165