00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "ossl.h"
00012 #include <stdarg.h>
00013
00014
00015
00016
00017 int
00018 string2hex(const unsigned char *buf, int buf_len, char **hexbuf, int *hexbuf_len)
00019 {
00020 static const char hex[]="0123456789abcdef";
00021 int i, len = 2 * buf_len;
00022
00023 if (buf_len < 0 || len < buf_len) {
00024 return -1;
00025 }
00026 if (!hexbuf) {
00027 if (hexbuf_len) {
00028 *hexbuf_len = len;
00029 }
00030 return len;
00031 }
00032 if (!(*hexbuf = OPENSSL_malloc(len + 1))) {
00033 return -1;
00034 }
00035 for (i = 0; i < buf_len; i++) {
00036 (*hexbuf)[2 * i] = hex[((unsigned char)buf[i]) >> 4];
00037 (*hexbuf)[2 * i + 1] = hex[buf[i] & 0x0f];
00038 }
00039 (*hexbuf)[2 * i] = '\0';
00040
00041 if (hexbuf_len) {
00042 *hexbuf_len = len;
00043 }
00044 return len;
00045 }
00046
00047
00048
00049
00050 STACK_OF(X509) *
00051 ossl_x509_ary2sk0(VALUE ary)
00052 {
00053 STACK_OF(X509) *sk;
00054 VALUE val;
00055 X509 *x509;
00056 int i;
00057
00058 Check_Type(ary, T_ARRAY);
00059 sk = sk_X509_new_null();
00060 if (!sk) ossl_raise(eOSSLError, NULL);
00061
00062 for (i = 0; i < RARRAY_LEN(ary); i++) {
00063 val = rb_ary_entry(ary, i);
00064 if (!rb_obj_is_kind_of(val, cX509Cert)) {
00065 sk_X509_pop_free(sk, X509_free);
00066 ossl_raise(eOSSLError, "object not X509 cert in array");
00067 }
00068 x509 = DupX509CertPtr(val);
00069 sk_X509_push(sk, x509);
00070 }
00071 return sk;
00072 }
00073
00074 STACK_OF(X509) *
00075 ossl_protect_x509_ary2sk(VALUE ary, int *status)
00076 {
00077 return (STACK_OF(X509)*)rb_protect((VALUE(*)_((VALUE)))ossl_x509_ary2sk0,
00078 ary, status);
00079 }
00080
00081 STACK_OF(X509) *
00082 ossl_x509_ary2sk(VALUE ary)
00083 {
00084 STACK_OF(X509) *sk;
00085 int status = 0;
00086
00087 sk = ossl_protect_x509_ary2sk(ary, &status);
00088 if(status) rb_jump_tag(status);
00089
00090 return sk;
00091 }
00092
00093 #define OSSL_IMPL_SK2ARY(name, type) \
00094 VALUE \
00095 ossl_##name##_sk2ary(STACK_OF(type) *sk) \
00096 { \
00097 type *t; \
00098 int i, num; \
00099 VALUE ary; \
00100 \
00101 if (!sk) { \
00102 OSSL_Debug("empty sk!"); \
00103 return Qnil; \
00104 } \
00105 num = sk_##type##_num(sk); \
00106 if (num < 0) { \
00107 OSSL_Debug("items in sk < -1???"); \
00108 return rb_ary_new(); \
00109 } \
00110 ary = rb_ary_new2(num); \
00111 \
00112 for (i=0; i<num; i++) { \
00113 t = sk_##type##_value(sk, i); \
00114 rb_ary_push(ary, ossl_##name##_new(t)); \
00115 } \
00116 return ary; \
00117 }
00118 OSSL_IMPL_SK2ARY(x509, X509)
00119 OSSL_IMPL_SK2ARY(x509crl, X509_CRL)
00120
00121 static VALUE
00122 ossl_str_new(int size)
00123 {
00124 return rb_str_new(0, size);
00125 }
00126
00127 VALUE
00128 ossl_buf2str(char *buf, int len)
00129 {
00130 VALUE str;
00131 int status = 0;
00132
00133 str = rb_protect((VALUE(*)_((VALUE)))ossl_str_new, len, &status);
00134 if(!NIL_P(str)) memcpy(RSTRING_PTR(str), buf, len);
00135 OPENSSL_free(buf);
00136 if(status) rb_jump_tag(status);
00137
00138 return str;
00139 }
00140
00141
00142
00143
00144 static VALUE
00145 ossl_pem_passwd_cb0(VALUE flag)
00146 {
00147 VALUE pass;
00148
00149 pass = rb_yield(flag);
00150 SafeStringValue(pass);
00151
00152 return pass;
00153 }
00154
00155 int
00156 ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd)
00157 {
00158 int len, status = 0;
00159 VALUE rflag, pass;
00160
00161 if (pwd || !rb_block_given_p())
00162 return PEM_def_callback(buf, max_len, flag, pwd);
00163
00164 while (1) {
00165
00166
00167
00168
00169
00170 rflag = flag ? Qtrue : Qfalse;
00171 pass = rb_protect(ossl_pem_passwd_cb0, rflag, &status);
00172 if (status) return -1;
00173 len = RSTRING_LEN(pass);
00174 if (len < 4) {
00175 rb_warning("password must be longer than 4 bytes");
00176 continue;
00177 }
00178 if (len > max_len) {
00179 rb_warning("password must be shorter then %d bytes", max_len-1);
00180 continue;
00181 }
00182 memcpy(buf, RSTRING_PTR(pass), len);
00183 break;
00184 }
00185 return len;
00186 }
00187
00188
00189
00190
00191 int ossl_verify_cb_idx;
00192
00193 VALUE
00194 ossl_call_verify_cb_proc(struct ossl_verify_cb_args *args)
00195 {
00196 return rb_funcall(args->proc, rb_intern("call"), 2,
00197 args->preverify_ok, args->store_ctx);
00198 }
00199
00200 int
00201 ossl_verify_cb(int ok, X509_STORE_CTX *ctx)
00202 {
00203 VALUE proc, rctx, ret;
00204 struct ossl_verify_cb_args args;
00205 int state = 0;
00206
00207 proc = (VALUE)X509_STORE_CTX_get_ex_data(ctx, ossl_verify_cb_idx);
00208 if ((void*)proc == 0)
00209 proc = (VALUE)X509_STORE_get_ex_data(ctx->ctx, ossl_verify_cb_idx);
00210 if ((void*)proc == 0)
00211 return ok;
00212 if (!NIL_P(proc)) {
00213 rctx = rb_protect((VALUE(*)(VALUE))ossl_x509stctx_new,
00214 (VALUE)ctx, &state);
00215 ret = Qfalse;
00216 if (!state) {
00217 args.proc = proc;
00218 args.preverify_ok = ok ? Qtrue : Qfalse;
00219 args.store_ctx = rctx;
00220 ret = rb_ensure(ossl_call_verify_cb_proc, (VALUE)&args,
00221 ossl_x509stctx_clear_ptr, rctx);
00222 }
00223 if (ret == Qtrue) {
00224 X509_STORE_CTX_set_error(ctx, X509_V_OK);
00225 ok = 1;
00226 }
00227 else{
00228 if (X509_STORE_CTX_get_error(ctx) == X509_V_OK) {
00229 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
00230 }
00231 ok = 0;
00232 }
00233 }
00234
00235 return ok;
00236 }
00237
00238
00239
00240
00241 VALUE mOSSL;
00242
00243
00244
00245
00246 VALUE eOSSLError;
00247
00248
00249
00250
00251 ID ossl_s_to_der;
00252
00253 VALUE
00254 ossl_to_der(VALUE obj)
00255 {
00256 VALUE tmp;
00257
00258 tmp = rb_funcall(obj, ossl_s_to_der, 0);
00259 StringValue(tmp);
00260
00261 return tmp;
00262 }
00263
00264 VALUE
00265 ossl_to_der_if_possible(VALUE obj)
00266 {
00267 if(rb_respond_to(obj, ossl_s_to_der))
00268 return ossl_to_der(obj);
00269 return obj;
00270 }
00271
00272
00273
00274
00275 static VALUE
00276 ossl_make_error(VALUE exc, const char *fmt, va_list args)
00277 {
00278 char buf[BUFSIZ];
00279 const char *msg;
00280 long e;
00281 int len = 0;
00282
00283 #ifdef HAVE_ERR_PEEK_LAST_ERROR
00284 e = ERR_peek_last_error();
00285 #else
00286 e = ERR_peek_error();
00287 #endif
00288 if (fmt) {
00289 len = vsnprintf(buf, BUFSIZ, fmt, args);
00290 }
00291 if (len < BUFSIZ && e) {
00292 if (dOSSL == Qtrue)
00293 msg = ERR_error_string(e, NULL);
00294 else
00295 msg = ERR_reason_error_string(e);
00296 len += snprintf(buf+len, BUFSIZ-len, "%s%s", (len ? ": " : ""), msg);
00297 }
00298 if (dOSSL == Qtrue){
00299 while ((e = ERR_get_error()) != 0){
00300 rb_warn("error on stack: %s", ERR_error_string(e, NULL));
00301 }
00302 }
00303 ERR_clear_error();
00304
00305 if(len > BUFSIZ) len = strlen(buf);
00306 return rb_exc_new(exc, buf, len);
00307 }
00308
00309 void
00310 ossl_raise(VALUE exc, const char *fmt, ...)
00311 {
00312 va_list args;
00313 VALUE err;
00314 va_start(args, fmt);
00315 err = ossl_make_error(exc, fmt, args);
00316 va_end(args);
00317 rb_exc_raise(err);
00318 }
00319
00320 VALUE
00321 ossl_exc_new(VALUE exc, const char *fmt, ...)
00322 {
00323 va_list args;
00324 VALUE err;
00325 va_start(args, fmt);
00326 err = ossl_make_error(exc, fmt, args);
00327 va_end(args);
00328 return err;
00329 }
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339 VALUE
00340 ossl_get_errors()
00341 {
00342 VALUE ary;
00343 long e;
00344
00345 ary = rb_ary_new();
00346 while ((e = ERR_get_error()) != 0){
00347 rb_ary_push(ary, rb_str_new2(ERR_error_string(e, NULL)));
00348 }
00349
00350 return ary;
00351 }
00352
00353
00354
00355
00356 VALUE dOSSL;
00357
00358 #if !defined(HAVE_VA_ARGS_MACRO)
00359 void
00360 ossl_debug(const char *fmt, ...)
00361 {
00362 va_list args;
00363
00364 if (dOSSL == Qtrue) {
00365 fprintf(stderr, "OSSL_DEBUG: ");
00366 va_start(args, fmt);
00367 vfprintf(stderr, fmt, args);
00368 va_end(args);
00369 fprintf(stderr, " [CONTEXT N/A]\n");
00370 }
00371 }
00372 #endif
00373
00374
00375
00376
00377
00378 static VALUE
00379 ossl_debug_get(VALUE self)
00380 {
00381 return dOSSL;
00382 }
00383
00384
00385
00386
00387
00388
00389
00390
00391 static VALUE
00392 ossl_debug_set(VALUE self, VALUE val)
00393 {
00394 VALUE old = dOSSL;
00395 dOSSL = val;
00396
00397 if (old != dOSSL) {
00398 if (dOSSL == Qtrue) {
00399 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
00400 fprintf(stderr, "OSSL_DEBUG: IS NOW ON!\n");
00401 } else if (old == Qtrue) {
00402 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);
00403 fprintf(stderr, "OSSL_DEBUG: IS NOW OFF!\n");
00404 }
00405 }
00406 return val;
00407 }
00408
00409
00410
00411
00412 void
00413 Init_openssl()
00414 {
00415
00416
00417
00418 #if 0
00419 tzset();
00420 #endif
00421
00422
00423
00424
00425
00426
00427 OpenSSL_add_ssl_algorithms();
00428 OpenSSL_add_all_algorithms();
00429 ERR_load_crypto_strings();
00430 SSL_load_error_strings();
00431
00432
00433
00434
00435
00436 #if 0
00437 CONF_modules_unload(1);
00438 destroy_ui_method();
00439 EVP_cleanup();
00440 ENGINE_cleanup();
00441 CRYPTO_cleanup_all_ex_data();
00442 ERR_remove_state(0);
00443 ERR_free_strings();
00444 #endif
00445
00446
00447
00448
00449 mOSSL = rb_define_module("OpenSSL");
00450
00451
00452
00453
00454 rb_define_const(mOSSL, "VERSION", rb_str_new2(OSSL_VERSION));
00455 rb_define_const(mOSSL, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
00456 rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER));
00457
00458
00459
00460
00461
00462 eOSSLError = rb_define_class_under(mOSSL,"OpenSSLError",rb_eStandardError);
00463
00464
00465
00466
00467 if ((ossl_verify_cb_idx = X509_STORE_CTX_get_ex_new_index(0, (void *)"ossl_verify_cb_idx", 0, 0, 0)) < 0)
00468 ossl_raise(eOSSLError, "X509_STORE_CTX_get_ex_new_index");
00469
00470
00471
00472
00473 dOSSL = Qfalse;
00474 rb_define_module_function(mOSSL, "debug", ossl_debug_get, 0);
00475 rb_define_module_function(mOSSL, "debug=", ossl_debug_set, 1);
00476 rb_define_module_function(mOSSL, "errors", ossl_get_errors, 0);
00477
00478
00479
00480
00481 ossl_s_to_der = rb_intern("to_der");
00482
00483
00484
00485
00486 Init_ossl_bn();
00487 Init_ossl_cipher();
00488 Init_ossl_config();
00489 Init_ossl_digest();
00490 Init_ossl_hmac();
00491 Init_ossl_ns_spki();
00492 Init_ossl_pkcs12();
00493 Init_ossl_pkcs7();
00494 Init_ossl_pkcs5();
00495 Init_ossl_pkey();
00496 Init_ossl_rand();
00497 Init_ossl_ssl();
00498 Init_ossl_x509();
00499 Init_ossl_ocsp();
00500 Init_ossl_engine();
00501 Init_ossl_asn1();
00502 }
00503
00504 #if defined(OSSL_DEBUG)
00505
00506
00507
00508 int
00509 main(int argc, char *argv[])
00510 {
00511 return 0;
00512 }
00513 #endif
00514
00515