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. 8296465Sdelphij * 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). 15296465Sdelphij * 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. 22296465Sdelphij * 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 :-). 37296465Sdelphij * 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)" 40296465Sdelphij * 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. 52296465Sdelphij * 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, 72296465Sdelphij long argl, char **ret); 73296465SdelphijX509_LOOKUP_METHOD x509_file_lookup = { 74296465Sdelphij "Load file into cache", 75296465Sdelphij NULL, /* new */ 76296465Sdelphij NULL, /* free */ 77296465Sdelphij NULL, /* init */ 78296465Sdelphij NULL, /* shutdown */ 79296465Sdelphij by_file_ctrl, /* ctrl */ 80296465Sdelphij NULL, /* get_by_subject */ 81296465Sdelphij NULL, /* get_by_issuer_serial */ 82296465Sdelphij NULL, /* get_by_fingerprint */ 83296465Sdelphij NULL, /* get_by_alias */ 84296465Sdelphij}; 8555714Skris 8655714SkrisX509_LOOKUP_METHOD *X509_LOOKUP_file(void) 87296465Sdelphij{ 88296465Sdelphij return (&x509_file_lookup); 89296465Sdelphij} 9055714Skris 91296465Sdelphijstatic int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, 92296465Sdelphij long argl, char **ret) 93296465Sdelphij{ 94296465Sdelphij int ok = 0; 95296465Sdelphij char *file; 9655714Skris 97296465Sdelphij switch (cmd) { 98296465Sdelphij case X509_L_FILE_LOAD: 99296465Sdelphij if (argl == X509_FILETYPE_DEFAULT) { 100296465Sdelphij file = (char *)Getenv(X509_get_default_cert_file_env()); 101296465Sdelphij if (file) 102296465Sdelphij ok = (X509_load_cert_crl_file(ctx, file, 103296465Sdelphij X509_FILETYPE_PEM) != 0); 104109998Smarkm 105296465Sdelphij else 106296465Sdelphij ok = (X509_load_cert_crl_file 107296465Sdelphij (ctx, X509_get_default_cert_file(), 108296465Sdelphij X509_FILETYPE_PEM) != 0); 109109998Smarkm 110296465Sdelphij if (!ok) { 111296465Sdelphij X509err(X509_F_BY_FILE_CTRL, X509_R_LOADING_DEFAULTS); 112296465Sdelphij } 113296465Sdelphij } else { 114296465Sdelphij if (argl == X509_FILETYPE_PEM) 115296465Sdelphij ok = (X509_load_cert_crl_file(ctx, argp, 116296465Sdelphij X509_FILETYPE_PEM) != 0); 117296465Sdelphij else 118296465Sdelphij ok = (X509_load_cert_file(ctx, argp, (int)argl) != 0); 119296465Sdelphij } 120296465Sdelphij break; 121296465Sdelphij } 122296465Sdelphij return (ok); 123296465Sdelphij} 12455714Skris 12555714Skrisint X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) 126296465Sdelphij{ 127296465Sdelphij int ret = 0; 128296465Sdelphij BIO *in = NULL; 129296465Sdelphij int i, count = 0; 130296465Sdelphij X509 *x = NULL; 13155714Skris 132296465Sdelphij if (file == NULL) 133296465Sdelphij return (1); 134296465Sdelphij in = BIO_new(BIO_s_file_internal()); 13555714Skris 136296465Sdelphij if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { 137296465Sdelphij X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_SYS_LIB); 138296465Sdelphij goto err; 139296465Sdelphij } 14055714Skris 141296465Sdelphij if (type == X509_FILETYPE_PEM) { 142296465Sdelphij for (;;) { 143296465Sdelphij x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL); 144296465Sdelphij if (x == NULL) { 145296465Sdelphij if ((ERR_GET_REASON(ERR_peek_last_error()) == 146296465Sdelphij PEM_R_NO_START_LINE) && (count > 0)) { 147296465Sdelphij ERR_clear_error(); 148296465Sdelphij break; 149296465Sdelphij } else { 150296465Sdelphij X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_PEM_LIB); 151296465Sdelphij goto err; 152296465Sdelphij } 153296465Sdelphij } 154296465Sdelphij i = X509_STORE_add_cert(ctx->store_ctx, x); 155296465Sdelphij if (!i) 156296465Sdelphij goto err; 157296465Sdelphij count++; 158296465Sdelphij X509_free(x); 159296465Sdelphij x = NULL; 160296465Sdelphij } 161296465Sdelphij ret = count; 162296465Sdelphij } else if (type == X509_FILETYPE_ASN1) { 163296465Sdelphij x = d2i_X509_bio(in, NULL); 164296465Sdelphij if (x == NULL) { 165296465Sdelphij X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_ASN1_LIB); 166296465Sdelphij goto err; 167296465Sdelphij } 168296465Sdelphij i = X509_STORE_add_cert(ctx->store_ctx, x); 169296465Sdelphij if (!i) 170296465Sdelphij goto err; 171296465Sdelphij ret = i; 172296465Sdelphij } else { 173296465Sdelphij X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_BAD_X509_FILETYPE); 174296465Sdelphij goto err; 175296465Sdelphij } 176296465Sdelphij err: 177296465Sdelphij if (x != NULL) 178296465Sdelphij X509_free(x); 179296465Sdelphij if (in != NULL) 180296465Sdelphij BIO_free(in); 181296465Sdelphij return (ret); 182296465Sdelphij} 18355714Skris 18455714Skrisint X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) 185296465Sdelphij{ 186296465Sdelphij int ret = 0; 187296465Sdelphij BIO *in = NULL; 188296465Sdelphij int i, count = 0; 189296465Sdelphij X509_CRL *x = NULL; 19055714Skris 191296465Sdelphij if (file == NULL) 192296465Sdelphij return (1); 193296465Sdelphij in = BIO_new(BIO_s_file_internal()); 19455714Skris 195296465Sdelphij if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { 196296465Sdelphij X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_SYS_LIB); 197296465Sdelphij goto err; 198296465Sdelphij } 19955714Skris 200296465Sdelphij if (type == X509_FILETYPE_PEM) { 201296465Sdelphij for (;;) { 202296465Sdelphij x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 203296465Sdelphij if (x == NULL) { 204296465Sdelphij if ((ERR_GET_REASON(ERR_peek_last_error()) == 205296465Sdelphij PEM_R_NO_START_LINE) && (count > 0)) { 206296465Sdelphij ERR_clear_error(); 207296465Sdelphij break; 208296465Sdelphij } else { 209296465Sdelphij X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_PEM_LIB); 210296465Sdelphij goto err; 211296465Sdelphij } 212296465Sdelphij } 213296465Sdelphij i = X509_STORE_add_crl(ctx->store_ctx, x); 214296465Sdelphij if (!i) 215296465Sdelphij goto err; 216296465Sdelphij count++; 217296465Sdelphij X509_CRL_free(x); 218296465Sdelphij x = NULL; 219296465Sdelphij } 220296465Sdelphij ret = count; 221296465Sdelphij } else if (type == X509_FILETYPE_ASN1) { 222296465Sdelphij x = d2i_X509_CRL_bio(in, NULL); 223296465Sdelphij if (x == NULL) { 224296465Sdelphij X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_ASN1_LIB); 225296465Sdelphij goto err; 226296465Sdelphij } 227296465Sdelphij i = X509_STORE_add_crl(ctx->store_ctx, x); 228296465Sdelphij if (!i) 229296465Sdelphij goto err; 230296465Sdelphij ret = i; 231296465Sdelphij } else { 232296465Sdelphij X509err(X509_F_X509_LOAD_CRL_FILE, X509_R_BAD_X509_FILETYPE); 233296465Sdelphij goto err; 234296465Sdelphij } 235296465Sdelphij err: 236296465Sdelphij if (x != NULL) 237296465Sdelphij X509_CRL_free(x); 238296465Sdelphij if (in != NULL) 239296465Sdelphij BIO_free(in); 240296465Sdelphij return (ret); 241296465Sdelphij} 24255714Skris 24359191Skrisint X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) 24459191Skris{ 245296465Sdelphij STACK_OF(X509_INFO) *inf; 246296465Sdelphij X509_INFO *itmp; 247296465Sdelphij BIO *in; 248296465Sdelphij int i, count = 0; 249296465Sdelphij if (type != X509_FILETYPE_PEM) 250296465Sdelphij return X509_load_cert_file(ctx, file, type); 251296465Sdelphij in = BIO_new_file(file, "r"); 252296465Sdelphij if (!in) { 253296465Sdelphij X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_SYS_LIB); 254296465Sdelphij return 0; 255296465Sdelphij } 256296465Sdelphij inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); 257296465Sdelphij BIO_free(in); 258296465Sdelphij if (!inf) { 259296465Sdelphij X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_PEM_LIB); 260296465Sdelphij return 0; 261296465Sdelphij } 262296465Sdelphij for (i = 0; i < sk_X509_INFO_num(inf); i++) { 263296465Sdelphij itmp = sk_X509_INFO_value(inf, i); 264296465Sdelphij if (itmp->x509) { 265296465Sdelphij X509_STORE_add_cert(ctx->store_ctx, itmp->x509); 266296465Sdelphij count++; 267296465Sdelphij } 268296465Sdelphij if (itmp->crl) { 269296465Sdelphij X509_STORE_add_crl(ctx->store_ctx, itmp->crl); 270296465Sdelphij count++; 271296465Sdelphij } 272296465Sdelphij } 273296465Sdelphij sk_X509_INFO_pop_free(inf, X509_INFO_free); 274296465Sdelphij return count; 27559191Skris} 27659191Skris 277296465Sdelphij#endif /* OPENSSL_NO_STDIO */ 278