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 #define OSSL_IMPL_ARY2SK(name, type, expected_class, dup) \
00051 STACK_OF(type) * \
00052 ossl_##name##_ary2sk0(VALUE ary) \
00053 { \
00054 STACK_OF(type) *sk; \
00055 VALUE val; \
00056 type *x; \
00057 int i; \
00058 \
00059 Check_Type(ary, T_ARRAY); \
00060 sk = sk_##type##_new_null(); \
00061 if (!sk) ossl_raise(eOSSLError, NULL); \
00062 \
00063 for (i = 0; i < RARRAY_LEN(ary); i++) { \
00064 val = rb_ary_entry(ary, i); \
00065 if (!rb_obj_is_kind_of(val, expected_class)) { \
00066 sk_##type##_pop_free(sk, type##_free); \
00067 ossl_raise(eOSSLError, "object in array not" \
00068 " of class ##type##"); \
00069 } \
00070 x = dup(val); \
00071 sk_##type##_push(sk, x); \
00072 } \
00073 return sk; \
00074 } \
00075 \
00076 STACK_OF(type) * \
00077 ossl_protect_##name##_ary2sk(VALUE ary, int *status) \
00078 { \
00079 return (STACK_OF(type)*)rb_protect( \
00080 (VALUE(*)_((VALUE)))ossl_##name##_ary2sk0, \
00081 ary, \
00082 status); \
00083 } \
00084 \
00085 STACK_OF(type) * \
00086 ossl_##name##_ary2sk(VALUE ary) \
00087 { \
00088 STACK_OF(type) *sk; \
00089 int status = 0; \
00090 \
00091 sk = ossl_protect_##name##_ary2sk(ary, &status); \
00092 if (status) rb_jump_tag(status); \
00093 \
00094 return sk; \
00095 }
00096 OSSL_IMPL_ARY2SK(x509, X509, cX509Cert, DupX509CertPtr)
00097
00098 #define OSSL_IMPL_SK2ARY(name, type) \
00099 VALUE \
00100 ossl_##name##_sk2ary(STACK_OF(type) *sk) \
00101 { \
00102 type *t; \
00103 int i, num; \
00104 VALUE ary; \
00105 \
00106 if (!sk) { \
00107 OSSL_Debug("empty sk!"); \
00108 return Qnil; \
00109 } \
00110 num = sk_##type##_num(sk); \
00111 if (num < 0) { \
00112 OSSL_Debug("items in sk < -1???"); \
00113 return rb_ary_new(); \
00114 } \
00115 ary = rb_ary_new2(num); \
00116 \
00117 for (i=0; i<num; i++) { \
00118 t = sk_##type##_value(sk, i); \
00119 rb_ary_push(ary, ossl_##name##_new(t)); \
00120 } \
00121 return ary; \
00122 }
00123 OSSL_IMPL_SK2ARY(x509, X509)
00124 OSSL_IMPL_SK2ARY(x509crl, X509_CRL)
00125 OSSL_IMPL_SK2ARY(x509name, X509_NAME)
00126
00127 static VALUE
00128 ossl_str_new(int size)
00129 {
00130 return rb_str_new(0, size);
00131 }
00132
00133 VALUE
00134 ossl_buf2str(char *buf, int len)
00135 {
00136 VALUE str;
00137 int status = 0;
00138
00139 str = rb_protect((VALUE(*)_((VALUE)))ossl_str_new, len, &status);
00140 if(!NIL_P(str)) memcpy(RSTRING_PTR(str), buf, len);
00141 OPENSSL_free(buf);
00142 if(status) rb_jump_tag(status);
00143
00144 return str;
00145 }
00146
00147
00148
00149
00150 static VALUE
00151 ossl_pem_passwd_cb0(VALUE flag)
00152 {
00153 VALUE pass;
00154
00155 pass = rb_yield(flag);
00156 SafeStringValue(pass);
00157
00158 return pass;
00159 }
00160
00161 int
00162 ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd)
00163 {
00164 int len, status = 0;
00165 VALUE rflag, pass;
00166
00167 if (pwd || !rb_block_given_p())
00168 return PEM_def_callback(buf, max_len, flag, pwd);
00169
00170 while (1) {
00171
00172
00173
00174
00175
00176 rflag = flag ? Qtrue : Qfalse;
00177 pass = rb_protect(ossl_pem_passwd_cb0, rflag, &status);
00178 if (status) return -1;
00179 len = RSTRING_LENINT(pass);
00180 if (len < 4) {
00181 rb_warning("password must be longer than 4 bytes");
00182 continue;
00183 }
00184 if (len > max_len) {
00185 rb_warning("password must be shorter then %d bytes", max_len-1);
00186 continue;
00187 }
00188 memcpy(buf, RSTRING_PTR(pass), len);
00189 break;
00190 }
00191 return len;
00192 }
00193
00194
00195
00196
00197 int ossl_verify_cb_idx;
00198
00199 VALUE
00200 ossl_call_verify_cb_proc(struct ossl_verify_cb_args *args)
00201 {
00202 return rb_funcall(args->proc, rb_intern("call"), 2,
00203 args->preverify_ok, args->store_ctx);
00204 }
00205
00206 int
00207 ossl_verify_cb(int ok, X509_STORE_CTX *ctx)
00208 {
00209 VALUE proc, rctx, ret;
00210 struct ossl_verify_cb_args args;
00211 int state = 0;
00212
00213 proc = (VALUE)X509_STORE_CTX_get_ex_data(ctx, ossl_verify_cb_idx);
00214 if ((void*)proc == 0)
00215 proc = (VALUE)X509_STORE_get_ex_data(ctx->ctx, ossl_verify_cb_idx);
00216 if ((void*)proc == 0)
00217 return ok;
00218 if (!NIL_P(proc)) {
00219 rctx = rb_protect((VALUE(*)(VALUE))ossl_x509stctx_new,
00220 (VALUE)ctx, &state);
00221 ret = Qfalse;
00222 if (!state) {
00223 args.proc = proc;
00224 args.preverify_ok = ok ? Qtrue : Qfalse;
00225 args.store_ctx = rctx;
00226 ret = rb_protect((VALUE(*)(VALUE))ossl_call_verify_cb_proc, (VALUE)&args, &state);
00227 ossl_x509stctx_clear_ptr(rctx);
00228 if (state) {
00229 rb_warn("exception in verify_callback is ignored");
00230 }
00231 }
00232 if (ret == Qtrue) {
00233 X509_STORE_CTX_set_error(ctx, X509_V_OK);
00234 ok = 1;
00235 }
00236 else{
00237 if (X509_STORE_CTX_get_error(ctx) == X509_V_OK) {
00238 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
00239 }
00240 ok = 0;
00241 }
00242 }
00243
00244 return ok;
00245 }
00246
00247
00248
00249
00250 VALUE mOSSL;
00251
00252
00253
00254
00255 VALUE eOSSLError;
00256
00257
00258
00259
00260 ID ossl_s_to_der;
00261
00262 VALUE
00263 ossl_to_der(VALUE obj)
00264 {
00265 VALUE tmp;
00266
00267 tmp = rb_funcall(obj, ossl_s_to_der, 0);
00268 StringValue(tmp);
00269
00270 return tmp;
00271 }
00272
00273 VALUE
00274 ossl_to_der_if_possible(VALUE obj)
00275 {
00276 if(rb_respond_to(obj, ossl_s_to_der))
00277 return ossl_to_der(obj);
00278 return obj;
00279 }
00280
00281
00282
00283
00284 static VALUE
00285 ossl_make_error(VALUE exc, const char *fmt, va_list args)
00286 {
00287 VALUE str = Qnil;
00288 const char *msg;
00289 long e;
00290
00291 #ifdef HAVE_ERR_PEEK_LAST_ERROR
00292 e = ERR_peek_last_error();
00293 #else
00294 e = ERR_peek_error();
00295 #endif
00296 if (fmt) {
00297 str = rb_vsprintf(fmt, args);
00298 }
00299 if (e) {
00300 if (dOSSL == Qtrue)
00301 msg = ERR_error_string(e, NULL);
00302 else
00303 msg = ERR_reason_error_string(e);
00304 if (NIL_P(str)) {
00305 if (msg) str = rb_str_new_cstr(msg);
00306 }
00307 else {
00308 if (RSTRING_LEN(str)) rb_str_cat2(str, ": ");
00309 rb_str_cat2(str, msg ? msg : "(null)");
00310 }
00311 }
00312 if (dOSSL == Qtrue){
00313 while ((e = ERR_get_error()) != 0){
00314 rb_warn("error on stack: %s", ERR_error_string(e, NULL));
00315 }
00316 }
00317 ERR_clear_error();
00318
00319 if (NIL_P(str)) str = rb_str_new(0, 0);
00320 return rb_exc_new3(exc, str);
00321 }
00322
00323 void
00324 ossl_raise(VALUE exc, const char *fmt, ...)
00325 {
00326 va_list args;
00327 VALUE err;
00328 va_start(args, fmt);
00329 err = ossl_make_error(exc, fmt, args);
00330 va_end(args);
00331 rb_exc_raise(err);
00332 }
00333
00334 VALUE
00335 ossl_exc_new(VALUE exc, const char *fmt, ...)
00336 {
00337 va_list args;
00338 VALUE err;
00339 va_start(args, fmt);
00340 err = ossl_make_error(exc, fmt, args);
00341 va_end(args);
00342 return err;
00343 }
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 VALUE
00354 ossl_get_errors()
00355 {
00356 VALUE ary;
00357 long e;
00358
00359 ary = rb_ary_new();
00360 while ((e = ERR_get_error()) != 0){
00361 rb_ary_push(ary, rb_str_new2(ERR_error_string(e, NULL)));
00362 }
00363
00364 return ary;
00365 }
00366
00367
00368
00369
00370 VALUE dOSSL;
00371
00372 #if !defined(HAVE_VA_ARGS_MACRO)
00373 void
00374 ossl_debug(const char *fmt, ...)
00375 {
00376 va_list args;
00377
00378 if (dOSSL == Qtrue) {
00379 fprintf(stderr, "OSSL_DEBUG: ");
00380 va_start(args, fmt);
00381 vfprintf(stderr, fmt, args);
00382 va_end(args);
00383 fprintf(stderr, " [CONTEXT N/A]\n");
00384 }
00385 }
00386 #endif
00387
00388
00389
00390
00391
00392 static VALUE
00393 ossl_debug_get(VALUE self)
00394 {
00395 return dOSSL;
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405 static VALUE
00406 ossl_debug_set(VALUE self, VALUE val)
00407 {
00408 VALUE old = dOSSL;
00409 dOSSL = val;
00410
00411 if (old != dOSSL) {
00412 if (dOSSL == Qtrue) {
00413 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
00414 fprintf(stderr, "OSSL_DEBUG: IS NOW ON!\n");
00415 } else if (old == Qtrue) {
00416 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);
00417 fprintf(stderr, "OSSL_DEBUG: IS NOW OFF!\n");
00418 }
00419 }
00420 return val;
00421 }
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796 void
00797 Init_openssl()
00798 {
00799
00800
00801
00802 #if 0
00803 tzset();
00804 #endif
00805
00806
00807
00808
00809
00810
00811 OpenSSL_add_ssl_algorithms();
00812 OpenSSL_add_all_algorithms();
00813 ERR_load_crypto_strings();
00814 SSL_load_error_strings();
00815
00816
00817
00818
00819
00820 #if 0
00821 CONF_modules_unload(1);
00822 destroy_ui_method();
00823 EVP_cleanup();
00824 ENGINE_cleanup();
00825 CRYPTO_cleanup_all_ex_data();
00826 ERR_remove_state(0);
00827 ERR_free_strings();
00828 #endif
00829
00830
00831
00832
00833 mOSSL = rb_define_module("OpenSSL");
00834
00835
00836
00837
00838 rb_define_const(mOSSL, "VERSION", rb_str_new2(OSSL_VERSION));
00839
00840
00841
00842
00843 rb_define_const(mOSSL, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
00844
00845
00846
00847
00848 rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER));
00849
00850
00851
00852
00853
00854 eOSSLError = rb_define_class_under(mOSSL,"OpenSSLError",rb_eStandardError);
00855
00856
00857
00858
00859 if ((ossl_verify_cb_idx = X509_STORE_CTX_get_ex_new_index(0, (void *)"ossl_verify_cb_idx", 0, 0, 0)) < 0)
00860 ossl_raise(eOSSLError, "X509_STORE_CTX_get_ex_new_index");
00861
00862
00863
00864
00865 dOSSL = Qfalse;
00866 rb_define_module_function(mOSSL, "debug", ossl_debug_get, 0);
00867 rb_define_module_function(mOSSL, "debug=", ossl_debug_set, 1);
00868 rb_define_module_function(mOSSL, "errors", ossl_get_errors, 0);
00869
00870
00871
00872
00873 ossl_s_to_der = rb_intern("to_der");
00874
00875
00876
00877
00878 Init_ossl_bn();
00879 Init_ossl_cipher();
00880 Init_ossl_config();
00881 Init_ossl_digest();
00882 Init_ossl_hmac();
00883 Init_ossl_ns_spki();
00884 Init_ossl_pkcs12();
00885 Init_ossl_pkcs7();
00886 Init_ossl_pkcs5();
00887 Init_ossl_pkey();
00888 Init_ossl_rand();
00889 Init_ossl_ssl();
00890 Init_ossl_x509();
00891 Init_ossl_ocsp();
00892 Init_ossl_engine();
00893 Init_ossl_asn1();
00894 }
00895
00896 #if defined(OSSL_DEBUG)
00897
00898
00899
00900 int
00901 main(int argc, char *argv[])
00902 {
00903 return 0;
00904 }
00905 #endif
00906
00907