00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "klone_conf.h"
00020 #include <u/libu.h>
00021 #include <klone/io.h>
00022 #include <klone/emb.h>
00023
00024 #ifndef HAVE_LIBOPENSSL
00025 int tls_dummy_decl_stub = 0;
00026 #else
00027 #include <openssl/ssl.h>
00028 #include <openssl/x509.h>
00029
00030
00031 BIO *bio_from_emb (const char *res_name)
00032 {
00033 int c;
00034 enum { BUFSZ = 1024 };
00035 char buf[BUFSZ];
00036 io_t *tmp = NULL;
00037 BIO *b = NULL;
00038
00039 dbg_return_if (!res_name, NULL);
00040
00041 dbg_err_if (emb_open(res_name, &tmp));
00042 dbg_err_if (!(b = BIO_new(BIO_s_mem())));
00043
00044 for (;;)
00045 {
00046 c = io_read(tmp, buf, BUFSZ);
00047
00048 if (c == 0)
00049 break;
00050 else if (c < 0)
00051 goto err;
00052
00053 dbg_err_if (BIO_write(b, buf, c) <= 0);
00054 }
00055
00056 io_free(tmp);
00057
00058 return b;
00059
00060 err:
00061 if (tmp)
00062 io_free(tmp);
00063 if (b)
00064 BIO_free(b);
00065
00066 return NULL;
00067 }
00068
00069 BIO* tls_get_file_bio(const char *res_name)
00070 {
00071 BIO *b = NULL;
00072
00073
00074 if((b = bio_from_emb(res_name)) != NULL)
00075 return b;
00076
00077
00078 if((b = BIO_new_file(res_name, "r")) != NULL)
00079 return b;
00080
00081
00082 return NULL;
00083 }
00084
00085
00086
00087 int tls_load_verify_locations (SSL_CTX *c, const char *res_name)
00088 {
00089 int i;
00090 BIO *b = NULL;
00091 STACK_OF(X509_INFO) *info = NULL;
00092
00093 dbg_return_if (!c, ~0);
00094 dbg_return_if (!res_name, ~0);
00095
00096 dbg_err_if (!(b = tls_get_file_bio(res_name)));
00097 dbg_err_if (!(info = PEM_X509_INFO_read_bio(b, NULL, NULL, NULL)));
00098 BIO_free(b);
00099
00100 for (i = 0; i < sk_X509_INFO_num(info); i++)
00101 {
00102 X509_INFO *tmp = sk_X509_INFO_value(info, i);
00103
00104 if (tmp->x509)
00105 X509_STORE_add_cert(c->cert_store, tmp->x509);
00106
00107 if (tmp->crl)
00108 X509_STORE_add_crl(c->cert_store, tmp->crl);
00109 }
00110
00111 sk_X509_INFO_pop_free(info, X509_INFO_free);
00112
00113 return 0;
00114
00115 err:
00116 if (b)
00117 BIO_free(b);
00118 if (info)
00119 sk_X509_INFO_pop_free(info, X509_INFO_free);
00120
00121 return ~0;
00122 }
00123
00124
00125
00126 STACK_OF(X509_NAME) *tls_load_client_CA_file (const char *res_name)
00127 {
00128 BIO *b = NULL;
00129 X509 *x = NULL;
00130 X509_NAME *xn = NULL;
00131 STACK_OF(X509_NAME) *ret, *sk;
00132
00133 dbg_return_if (!res_name, NULL);
00134
00135 dbg_err_if (!(ret = sk_X509_NAME_new_null()));
00136 dbg_err_if (!(sk = sk_X509_NAME_new(X509_NAME_cmp)));
00137 dbg_err_if (!(b = tls_get_file_bio(res_name)));
00138
00139 for (;;)
00140 {
00141 if (!PEM_read_bio_X509(b, &x, NULL, NULL))
00142 break;
00143
00144 dbg_err_if (!(xn = X509_get_subject_name(x)));
00145
00146
00147 dbg_err_if (!(xn = X509_NAME_dup(xn)));
00148 if (sk_X509_NAME_find(sk, xn) >= 0)
00149 X509_NAME_free(xn);
00150 else
00151 {
00152 sk_X509_NAME_push(sk, xn);
00153 sk_X509_NAME_push(ret, xn);
00154 }
00155 }
00156
00157 sk_X509_NAME_free(sk);
00158 BIO_free(b);
00159 X509_free(x);
00160
00161 return ret;
00162
00163 err:
00164 if (ret)
00165 {
00166 sk_X509_NAME_pop_free(ret, X509_NAME_free);
00167 ret = NULL;
00168 }
00169 if (sk)
00170 sk_X509_NAME_free(sk);
00171 if (b)
00172 BIO_free(b);
00173 if (x)
00174 X509_free(x);
00175
00176 return ret;
00177 }
00178
00179
00180 int tls_use_certificate_file (SSL_CTX *ctx, const char *res_name, int type)
00181 {
00182 BIO *b = NULL;
00183 int ret = 0;
00184 X509 *x = NULL;
00185
00186 dbg_return_if (!ctx, 0);
00187 dbg_return_if (!res_name, 0);
00188 dbg_return_if (type != SSL_FILETYPE_PEM, 0);
00189
00190 dbg_goto_if (!(b = tls_get_file_bio(res_name)), end);
00191 dbg_goto_if (!(x = PEM_read_bio_X509(b, NULL, NULL, NULL)), end);
00192 ret = SSL_CTX_use_certificate(ctx, x);
00193
00194 end:
00195 if (x)
00196 X509_free(x);
00197 if (b)
00198 BIO_free(b);
00199
00200 return ret;
00201 }
00202
00203
00204
00205 int tls_use_PrivateKey_file (SSL_CTX *ctx, const char *res_name, int type)
00206 {
00207 int ret = 0;
00208 BIO *b = NULL;
00209 EVP_PKEY *pkey = NULL;
00210
00211 dbg_return_if (!ctx, 0);
00212 dbg_return_if (!res_name, 0);
00213 dbg_return_if (type != SSL_FILETYPE_PEM, 0);
00214
00215 dbg_goto_if (!(b = tls_get_file_bio(res_name)), end);
00216 dbg_goto_if (!(pkey = PEM_read_bio_PrivateKey(b, NULL, NULL, NULL)), end);
00217 ret = SSL_CTX_use_PrivateKey(ctx, pkey);
00218 EVP_PKEY_free(pkey);
00219
00220 end:
00221 if (b)
00222 BIO_free(b);
00223
00224 return ret;
00225 }
00226
00227
00228
00229
00230 int tls_use_certificate_chain (SSL_CTX *ctx, const char *res_name,
00231 int skipfirst, int (*cb)())
00232 {
00233 BIO *b = NULL;
00234 X509 *x = NULL;
00235 unsigned long err;
00236 int n;
00237
00238 dbg_return_if (!ctx, -1);
00239 dbg_return_if (!res_name, -1);
00240
00241 dbg_err_if (!(b = tls_get_file_bio(res_name)));
00242
00243
00244 if (skipfirst)
00245 {
00246 dbg_err_if (!(x = PEM_read_bio_X509(b, NULL, cb, NULL)));
00247 X509_free(x);
00248 x = NULL;
00249 }
00250
00251
00252 if (!ctx->extra_certs)
00253 {
00254 sk_X509_pop_free(ctx->extra_certs, X509_free);
00255 ctx->extra_certs = NULL;
00256 }
00257
00258
00259 n = 0;
00260 while ((x = PEM_read_bio_X509(b, NULL, cb, NULL)))
00261 {
00262 dbg_err_if (!SSL_CTX_add_extra_chain_cert(ctx, x));
00263 n++;
00264 }
00265
00266
00267 if ((err = ERR_peek_error()) > 0)
00268 {
00269 dbg_err_if (!(ERR_GET_LIB(err) == ERR_LIB_PEM &&
00270 ERR_GET_REASON(err) == PEM_R_NO_START_LINE));
00271
00272 while (ERR_get_error() > 0) ;
00273 }
00274
00275 BIO_free(b);
00276
00277 return n;
00278
00279 err:
00280 if (b)
00281 BIO_free(b);
00282 if (x)
00283 X509_free(x);
00284
00285 return -1;
00286 }
00287
00288 #endif