155714Skris/* crypto/x509/by_file.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 8280304Sjkim * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15280304Sjkim * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 22280304Sjkim * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 37280304Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40280304Sjkim * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 52280304Sjkim * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 5855714Skris 5955714Skris#include <stdio.h> 6055714Skris#include <time.h> 6155714Skris#include <errno.h> 6255714Skris 6355714Skris#include "cryptlib.h" 6455714Skris#include <openssl/lhash.h> 6555714Skris#include <openssl/buffer.h> 6655714Skris#include <openssl/x509.h> 6755714Skris#include <openssl/pem.h> 6855714Skris 69109998Smarkm#ifndef OPENSSL_NO_STDIO 7055714Skris 7155714Skrisstatic int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, 72280304Sjkim long argl, char **ret); 73280304SjkimX509_LOOKUP_METHOD x509_file_lookup = { 74280304Sjkim "Load file into cache", 75280304Sjkim NULL, /* new */ 76280304Sjkim NULL, /* free */ 77280304Sjkim NULL, /* init */ 78280304Sjkim NULL, /* shutdown */ 79280304Sjkim by_file_ctrl, /* ctrl */ 80280304Sjkim NULL, /* get_by_subject */ 81280304Sjkim NULL, /* get_by_issuer_serial */ 82280304Sjkim NULL, /* get_by_fingerprint */ 83280304Sjkim NULL, /* get_by_alias */ 84280304Sjkim}; 8555714Skris 8655714SkrisX509_LOOKUP_METHOD *X509_LOOKUP_file(void) 87280304Sjkim{ 88280304Sjkim return (&x509_file_lookup); 89280304Sjkim} 9055714Skris 91280304Sjkimstatic int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, 92280304Sjkim long argl, char **ret) 93280304Sjkim{ 94280304Sjkim int ok = 0; 95280304Sjkim char *file; 9655714Skris 97280304Sjkim switch (cmd) { 98280304Sjkim case X509_L_FILE_LOAD: 99280304Sjkim if (argl == X509_FILETYPE_DEFAULT) { 100280304Sjkim file = (char *)getenv(X509_get_default_cert_file_env()); 101280304Sjkim if (file) 102280304Sjkim ok = (X509_load_cert_crl_file(ctx, file, 103280304Sjkim X509_FILETYPE_PEM) != 0); 104109998Smarkm 105280304Sjkim else 106280304Sjkim ok = (X509_load_cert_crl_file 107280304Sjkim (ctx, X509_get_default_cert_file(), 108280304Sjkim X509_FILETYPE_PEM) != 0); 109109998Smarkm 110280304Sjkim if (!ok) { 111280304Sjkim X509err(X509_F_BY_FILE_CTRL, X509_R_LOADING_DEFAULTS); 112280304Sjkim } 113280304Sjkim } else { 114280304Sjkim if (argl == X509_FILETYPE_PEM) 115280304Sjkim ok = (X509_load_cert_crl_file(ctx, argp, 116280304Sjkim X509_FILETYPE_PEM) != 0); 117280304Sjkim else 118280304Sjkim ok = (X509_load_cert_file(ctx, argp, (int)argl) != 0); 119280304Sjkim } 120280304Sjkim break; 121280304Sjkim } 122280304Sjkim return (ok); 123280304Sjkim} 12455714Skris 12555714Skrisint X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) 126280304Sjkim{ 127280304Sjkim int ret = 0; 128280304Sjkim BIO *in = NULL; 129280304Sjkim int i, count = 0; 130280304Sjkim X509 *x = NULL; 13155714Skris 132280304Sjkim if (file == NULL) 133280304Sjkim return (1); 134280304Sjkim in = BIO_new(BIO_s_file_internal()); 13555714Skris 136280304Sjkim if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { 137280304Sjkim X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_SYS_LIB); 138280304Sjkim goto err; 139280304Sjkim } 14055714Skris 141280304Sjkim if (type == X509_FILETYPE_PEM) { 142280304Sjkim for (;;) { 143280304Sjkim x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL); 144280304Sjkim if (x == NULL) { 145280304Sjkim if ((ERR_GET_REASON(ERR_peek_last_error()) == 146280304Sjkim PEM_R_NO_START_LINE) && (count > 0)) { 147280304Sjkim ERR_clear_error(); 148280304Sjkim break; 149280304Sjkim } else { 150280304Sjkim X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_PEM_LIB); 151280304Sjkim goto err; 152280304Sjkim } 153280304Sjkim } 154280304Sjkim i = X509_STORE_add_cert(ctx->store_ctx, x); 155280304Sjkim if (!i) 156280304Sjkim goto err; 157280304Sjkim count++; 158280304Sjkim X509_free(x); 159280304Sjkim x = NULL; 160280304Sjkim } 161280304Sjkim ret = count; 162280304Sjkim } else if (type == X509_FILETYPE_ASN1) { 163280304Sjkim x = d2i_X509_bio(in, NULL); 164280304Sjkim if (x == NULL) { 165280304Sjkim X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_ASN1_LIB); 166280304Sjkim goto err; 167280304Sjkim } 168280304Sjkim i = X509_STORE_add_cert(ctx->store_ctx, x); 169280304Sjkim if (!i) 170280304Sjkim goto err; 171280304Sjkim ret = i; 172280304Sjkim } else { 173280304Sjkim X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_BAD_X509_FILETYPE); 174280304Sjkim goto err; 175280304Sjkim } 176280304Sjkim err: 177280304Sjkim if (x != NULL) 178280304Sjkim X509_free(x); 179280304Sjkim if (in != NULL) 180280304Sjkim BIO_free(in); 181280304Sjkim return (ret); 182280304Sjkim} 18355714Skris 18455714Skrisint X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) 185280304Sjkim{ 186280304Sjkim int ret = 0; 187280304Sjkim BIO *in = NULL; 188280304Sjkim int i, count = 0; 189280304Sjkim X509_CRL *x = NULL; 19055714Skris 191280304Sjkim if (file == NULL) 192280304Sjkim return (1); 193280304Sjkim in = BIO_new(BIO_s_file_internal()); 19455714Skris 195280304Sjkim if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { 196280304Sjkim X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_SYS_LIB); 197280304Sjkim goto err; 198280304Sjkim } 19955714Skris 200280304Sjkim if (type == X509_FILETYPE_PEM) { 201280304Sjkim for (;;) { 202280304Sjkim x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 203280304Sjkim if (x == NULL) { 204280304Sjkim if ((ERR_GET_REASON(ERR_peek_last_error()) == 205280304Sjkim PEM_R_NO_START_LINE) && (count > 0)) { 206280304Sjkim ERR_clear_error(); 207280304Sjkim break; 208280304Sjkim } else { 209280304Sjkim X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_PEM_LIB); 210280304Sjkim goto err; 211280304Sjkim } 212280304Sjkim } 213280304Sjkim i = X509_STORE_add_crl(ctx->store_ctx, x); 214280304Sjkim if (!i) 215280304Sjkim goto err; 216280304Sjkim count++; 217280304Sjkim X509_CRL_free(x); 218280304Sjkim x = NULL; 219280304Sjkim } 220280304Sjkim ret = count; 221280304Sjkim } else if (type == X509_FILETYPE_ASN1) { 222280304Sjkim x = d2i_X509_CRL_bio(in, NULL); 223280304Sjkim if (x == NULL) { 224280304Sjkim X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_ASN1_LIB); 225280304Sjkim goto err; 226280304Sjkim } 227280304Sjkim i = X509_STORE_add_crl(ctx->store_ctx, x); 228280304Sjkim if (!i) 229280304Sjkim goto err; 230280304Sjkim ret = i; 231280304Sjkim } else { 232280304Sjkim X509err(X509_F_X509_LOAD_CRL_FILE, X509_R_BAD_X509_FILETYPE); 233280304Sjkim goto err; 234280304Sjkim } 235280304Sjkim err: 236280304Sjkim if (x != NULL) 237280304Sjkim X509_CRL_free(x); 238280304Sjkim if (in != NULL) 239280304Sjkim BIO_free(in); 240280304Sjkim return (ret); 241280304Sjkim} 24255714Skris 24359191Skrisint X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) 24459191Skris{ 245280304Sjkim STACK_OF(X509_INFO) *inf; 246280304Sjkim X509_INFO *itmp; 247280304Sjkim BIO *in; 248280304Sjkim int i, count = 0; 249280304Sjkim if (type != X509_FILETYPE_PEM) 250280304Sjkim return X509_load_cert_file(ctx, file, type); 251280304Sjkim in = BIO_new_file(file, "r"); 252280304Sjkim if (!in) { 253280304Sjkim X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_SYS_LIB); 254280304Sjkim return 0; 255280304Sjkim } 256280304Sjkim inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); 257280304Sjkim BIO_free(in); 258280304Sjkim if (!inf) { 259280304Sjkim X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_PEM_LIB); 260280304Sjkim return 0; 261280304Sjkim } 262280304Sjkim for (i = 0; i < sk_X509_INFO_num(inf); i++) { 263280304Sjkim itmp = sk_X509_INFO_value(inf, i); 264280304Sjkim if (itmp->x509) { 265280304Sjkim X509_STORE_add_cert(ctx->store_ctx, itmp->x509); 266280304Sjkim count++; 267280304Sjkim } 268280304Sjkim if (itmp->crl) { 269280304Sjkim X509_STORE_add_crl(ctx->store_ctx, itmp->crl); 270280304Sjkim count++; 271280304Sjkim } 272280304Sjkim } 273280304Sjkim sk_X509_INFO_pop_free(inf, X509_INFO_free); 274280304Sjkim return count; 27559191Skris} 27659191Skris 277280304Sjkim#endif /* OPENSSL_NO_STDIO */ 278