]> git.ipfire.org Git - thirdparty/openssl.git/blame - ssl/ssl_cert.c
One more 0.9.2b
[thirdparty/openssl.git] / ssl / ssl_cert.c
CommitLineData
eb90a483 1/*! \file ssl/ssl_cert.c */
58964a49 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
d02b48c6
RE
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
eb90a483 60#include <sys/types.h>
06c68491 61#ifndef WIN32
eb90a483 62#include <dirent.h>
06c68491 63#endif
d02b48c6
RE
64#include "objects.h"
65#include "bio.h"
66#include "pem.h"
67#include "ssl_locl.h"
68
dfeab068
RE
69int SSL_get_ex_data_X509_STORE_CTX_idx()
70 {
71 static int ssl_x509_store_ctx_idx= -1;
72
73 if (ssl_x509_store_ctx_idx < 0)
74 {
75 ssl_x509_store_ctx_idx=X509_STORE_CTX_get_ex_new_index(
651d0aff 76 0,"SSL for verify callback",NULL,NULL,NULL);
dfeab068
RE
77 }
78 return(ssl_x509_store_ctx_idx);
79 }
80
d02b48c6
RE
81CERT *ssl_cert_new()
82 {
83 CERT *ret;
84
85 ret=(CERT *)Malloc(sizeof(CERT));
86 if (ret == NULL)
87 {
88 SSLerr(SSL_F_SSL_CERT_NEW,ERR_R_MALLOC_FAILURE);
89 return(NULL);
90 }
91 memset(ret,0,sizeof(CERT));
92/*
93 ret->valid=0;
94 ret->mask=0;
95 ret->export_mask=0;
96 ret->cert_type=0;
97 ret->key->x509=NULL;
98 ret->key->publickey=NULL;
99 ret->key->privatekey=NULL; */
100
101 ret->key= &(ret->pkeys[SSL_PKEY_RSA_ENC]);
102 ret->references=1;
103
104 return(ret);
105 }
106
eb90a483 107void ssl_cert_free(CERT *c)
d02b48c6
RE
108 {
109 int i;
110
e03ddfae
BL
111 if(c == NULL)
112 return;
113
d02b48c6 114 i=CRYPTO_add(&c->references,-1,CRYPTO_LOCK_SSL_CERT);
58964a49
RE
115#ifdef REF_PRINT
116 REF_PRINT("CERT",c);
117#endif
d02b48c6
RE
118 if (i > 0) return;
119#ifdef REF_CHECK
120 if (i < 0)
121 {
122 fprintf(stderr,"ssl_cert_free, bad reference count\n");
123 abort(); /* ok */
124 }
125#endif
126
127#ifndef NO_RSA
128 if (c->rsa_tmp) RSA_free(c->rsa_tmp);
129#endif
130#ifndef NO_DH
131 if (c->dh_tmp) DH_free(c->dh_tmp);
132#endif
133
134 for (i=0; i<SSL_PKEY_NUM; i++)
135 {
136 if (c->pkeys[i].x509 != NULL)
137 X509_free(c->pkeys[i].x509);
138 if (c->pkeys[i].privatekey != NULL)
139 EVP_PKEY_free(c->pkeys[i].privatekey);
140#if 0
141 if (c->pkeys[i].publickey != NULL)
142 EVP_PKEY_free(c->pkeys[i].publickey);
143#endif
144 }
145 if (c->cert_chain != NULL)
146 sk_pop_free(c->cert_chain,X509_free);
147 Free(c);
148 }
149
15d21c2d
RE
150int ssl_cert_instantiate(CERT **o, CERT *d)
151 {
152 CERT *n;
153 if (o == NULL)
154 {
155 SSLerr(SSL_F_SSL_CERT_INSTANTIATE, ERR_R_PASSED_NULL_PARAMETER);
156 return(0);
157 }
c707fb27 158 if (*o != NULL && (d == NULL || *o != d))
15d21c2d
RE
159 return(1);
160 if ((n = ssl_cert_new()) == NULL)
161 {
162 SSLerr(SSL_F_SSL_CERT_INSTANTIATE, ERR_R_MALLOC_FAILURE);
163 return(0);
164 }
165 if (*o != NULL)
166 ssl_cert_free(*o);
167 *o = n;
168 return(1);
169 }
170
eb90a483 171int ssl_set_cert_type(CERT *c,int type)
d02b48c6
RE
172 {
173 c->cert_type=type;
174 return(1);
175 }
176
eb90a483 177int ssl_verify_cert_chain(SSL *s,STACK *sk)
d02b48c6
RE
178 {
179 X509 *x;
180 int i;
181 X509_STORE_CTX ctx;
182
183 if ((sk == NULL) || (sk_num(sk) == 0))
184 return(0);
185
186 x=(X509 *)sk_value(sk,0);
187 X509_STORE_CTX_init(&ctx,s->ctx->cert_store,x,sk);
dfeab068
RE
188 X509_STORE_CTX_set_ex_data(&ctx,SSL_get_ex_data_X509_STORE_CTX_idx(),
189 (char *)s);
d02b48c6
RE
190
191 if (s->ctx->app_verify_callback != NULL)
192 i=s->ctx->app_verify_callback(&ctx);
193 else
dfeab068
RE
194 {
195#ifndef NO_X509_VERIFY
d02b48c6 196 i=X509_verify_cert(&ctx);
dfeab068
RE
197#else
198 i=0;
199 ctx.error=X509_V_ERR_APPLICATION_VERIFICATION;
200 SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,SSL_R_NO_VERIFY_CALLBACK);
201#endif
202 }
d02b48c6 203
d02b48c6 204 s->verify_result=ctx.error;
dfeab068 205 X509_STORE_CTX_cleanup(&ctx);
d02b48c6
RE
206
207 return(i);
208 }
209
eb90a483 210static void set_client_CA_list(STACK **ca_list,STACK *list)
d02b48c6
RE
211 {
212 if (*ca_list != NULL)
213 sk_pop_free(*ca_list,X509_NAME_free);
214
215 *ca_list=list;
216 }
217
eb90a483 218STACK *SSL_dup_CA_list(STACK *sk)
d02b48c6
RE
219 {
220 int i;
221 STACK *ret;
222 X509_NAME *name;
223
224 ret=sk_new_null();
225 for (i=0; i<sk_num(sk); i++)
226 {
227 name=X509_NAME_dup((X509_NAME *)sk_value(sk,i));
228 if ((name == NULL) || !sk_push(ret,(char *)name))
229 {
230 sk_pop_free(ret,X509_NAME_free);
231 return(NULL);
232 }
233 }
234 return(ret);
235 }
236
eb90a483 237void SSL_set_client_CA_list(SSL *s,STACK *list)
d02b48c6
RE
238 {
239 set_client_CA_list(&(s->client_CA),list);
240 }
241
eb90a483 242void SSL_CTX_set_client_CA_list(SSL_CTX *ctx,STACK *list)
d02b48c6
RE
243 {
244 set_client_CA_list(&(ctx->client_CA),list);
245 }
246
eb90a483 247STACK *SSL_CTX_get_client_CA_list(SSL_CTX *ctx)
d02b48c6
RE
248 {
249 return(ctx->client_CA);
250 }
251
eb90a483 252STACK *SSL_get_client_CA_list(SSL *s)
d02b48c6
RE
253 {
254 if (s->type == SSL_ST_CONNECT)
255 { /* we are in the client */
58964a49
RE
256 if (((s->version>>8) == SSL3_VERSION_MAJOR) &&
257 (s->s3 != NULL))
d02b48c6
RE
258 return(s->s3->tmp.ca_names);
259 else
260 return(NULL);
261 }
262 else
263 {
264 if (s->client_CA != NULL)
265 return(s->client_CA);
266 else
267 return(s->ctx->client_CA);
268 }
269 }
270
eb90a483 271static int add_client_CA(STACK **sk,X509 *x)
d02b48c6
RE
272 {
273 X509_NAME *name;
274
275 if (x == NULL) return(0);
276 if ((*sk == NULL) && ((*sk=sk_new_null()) == NULL))
277 return(0);
278
279 if ((name=X509_NAME_dup(X509_get_subject_name(x))) == NULL)
280 return(0);
281
282 if (!sk_push(*sk,(char *)name))
283 {
284 X509_NAME_free(name);
285 return(0);
286 }
287 return(1);
288 }
289
eb90a483 290int SSL_add_client_CA(SSL *ssl,X509 *x)
d02b48c6
RE
291 {
292 return(add_client_CA(&(ssl->client_CA),x));
293 }
294
eb90a483 295int SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x)
d02b48c6
RE
296 {
297 return(add_client_CA(&(ctx->client_CA),x));
298 }
299
eb90a483 300static int name_cmp(X509_NAME **a,X509_NAME **b)
d02b48c6
RE
301 {
302 return(X509_NAME_cmp(*a,*b));
303 }
304
58964a49 305#ifndef NO_STDIO
eb90a483
BL
306/*!
307 * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed;
308 * it doesn't really have anything to do with clients (except that a common use
309 * for a stack of CAs is to send it to the client). Actually, it doesn't have
310 * much to do with CAs, either, since it will load any old cert.
311 * \param file the file containing one or more certs.
312 * \return a ::STACK containing the certs.
313 */
314STACK *SSL_load_client_CA_file(char *file)
d02b48c6
RE
315 {
316 BIO *in;
317 X509 *x=NULL;
318 X509_NAME *xn=NULL;
319 STACK *ret,*sk;
320
321 ret=sk_new(NULL);
322 sk=sk_new(name_cmp);
58964a49
RE
323
324 in=BIO_new(BIO_s_file_internal());
325
d02b48c6
RE
326 if ((ret == NULL) || (sk == NULL) || (in == NULL))
327 {
328 SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE,ERR_R_MALLOC_FAILURE);
329 goto err;
330 }
331
332 if (!BIO_read_filename(in,file))
333 goto err;
334
335 for (;;)
336 {
337 if (PEM_read_bio_X509(in,&x,NULL) == NULL)
338 break;
339 if ((xn=X509_get_subject_name(x)) == NULL) goto err;
340 /* check for duplicates */
341 xn=X509_NAME_dup(xn);
342 if (xn == NULL) goto err;
343 if (sk_find(sk,(char *)xn) >= 0)
344 X509_NAME_free(xn);
345 else
346 {
347 sk_push(sk,(char *)xn);
348 sk_push(ret,(char *)xn);
349 }
350 }
351
352 if (0)
353 {
354err:
355 if (ret != NULL) sk_pop_free(ret,X509_NAME_free);
356 ret=NULL;
357 }
358 if (sk != NULL) sk_free(sk);
359 if (in != NULL) BIO_free(in);
360 if (x != NULL) X509_free(x);
361 return(ret);
362 }
58964a49 363#endif
d02b48c6 364
eb90a483
BL
365/*!
366 * Add a file of certs to a stack.
367 * \param stack the stack to add to.
368 * \param file the file to add from. All certs in this file that are not
369 * already in the stack will be added.
370 * \return 1 for success, 0 for failure. Note that in the case of failure some
371 * certs may have been added to \c stack.
372 */
373
a49034ab 374int SSL_add_file_cert_subjects_to_stack(STACK *stack,const char *file)
eb90a483
BL
375 {
376 BIO *in;
377 X509 *x=NULL;
378 X509_NAME *xn=NULL;
379 int ret=1;
380 int (*oldcmp)();
381
382 oldcmp=sk_set_cmp_func(stack,name_cmp);
383
384 in=BIO_new(BIO_s_file_internal());
385
06c68491 386 if (in == NULL)
eb90a483 387 {
a49034ab 388 SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK,ERR_R_MALLOC_FAILURE);
eb90a483
BL
389 goto err;
390 }
391
392 if (!BIO_read_filename(in,file))
393 goto err;
394
395 for (;;)
396 {
397 if (PEM_read_bio_X509(in,&x,NULL) == NULL)
398 break;
399 if ((xn=X509_get_subject_name(x)) == NULL) goto err;
400 xn=X509_NAME_dup(xn);
401 if (xn == NULL) goto err;
402 if (sk_find(stack,(char *)xn) >= 0)
403 X509_NAME_free(xn);
404 else
405 sk_push(stack,(char *)xn);
406 }
407
408 if (0)
409 {
410err:
411 ret=0;
412 }
413 if(in != NULL)
414 BIO_free(in);
415 if(x != NULL)
416 X509_free(x);
417
418 sk_set_cmp_func(stack,oldcmp);
419
420 return ret;
421 }
422
423/*!
424 * Add a directory of certs to a stack.
425 * \param stack the stack to append to.
426 * \param dir the directory to append from. All files in this directory will be
427 * examined as potential certs. Any that are acceptable to
428 * SSL_add_cert_file_to_stack() that are not already in the stack will be
429 * included.
430 * \return 1 for success, 0 for failure. Note that in the case of failure some
431 * certs may have been added to \c stack.
432 */
433
06c68491
DSH
434#ifndef WIN32
435
a49034ab 436int SSL_add_dir_cert_subjects_to_stack(STACK *stack,const char *dir)
eb90a483
BL
437 {
438 DIR *d=opendir(dir);
439 struct dirent *dstruct;
440
441 /* Note that a side effect is that the CAs will be sorted by name */
442 if(!d)
443 {
a49034ab 444 SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,ERR_R_MALLOC_FAILURE);
eb90a483
BL
445 return 0;
446 }
447
448 while((dstruct=readdir(d)))
449 {
450 char buf[1024];
451
452 if(strlen(dir)+strlen(dstruct->d_name)+2 > sizeof buf)
453 {
a49034ab 454 SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,SSL_R_PATH_TOO_LONG);
eb90a483
BL
455 return 0;
456 }
457
458 sprintf(buf,"%s/%s",dir,dstruct->d_name);
a49034ab 459 if(!SSL_add_file_cert_subjects_to_stack(stack,buf))
eb90a483
BL
460 return 0;
461 }
462
463 return 1;
464 }
06c68491
DSH
465
466#endif