From bd96b4c8ccbfbaf68c6996d74515fd603b2aea63 Mon Sep 17 00:00:00 2001 From: michal Date: Fri, 12 Sep 2003 13:46:48 +0000 Subject: OpenSSL update git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4552 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 24 ++++++ ext/openssl/MANIFEST | 4 + ext/openssl/openssl_missing.c | 130 +++++++++++++++++++----------- ext/openssl/openssl_missing.h | 5 +- ext/openssl/ossl.c | 182 ------------------------------------------ ext/openssl/ossl.h | 20 +---- ext/openssl/ossl_asn1.c | 148 ++++++++++++++++++++++++++++++++++ ext/openssl/ossl_asn1.h | 27 +++++++ ext/openssl/ossl_bio.c | 58 ++++++++++++++ ext/openssl/ossl_bio.h | 20 +++++ ext/openssl/ossl_bn.c | 17 ---- ext/openssl/ossl_config.c | 12 ++- ext/openssl/ossl_pkey.c | 15 ++++ ext/openssl/ossl_pkey.h | 2 + ext/openssl/ossl_pkey_dh.c | 28 ++----- ext/openssl/ossl_pkey_dsa.c | 28 ++----- ext/openssl/ossl_pkey_rsa.c | 24 +----- 17 files changed, 409 insertions(+), 335 deletions(-) create mode 100644 ext/openssl/ossl_asn1.c create mode 100644 ext/openssl/ossl_asn1.h create mode 100644 ext/openssl/ossl_bio.c create mode 100644 ext/openssl/ossl_bio.h diff --git a/ChangeLog b/ChangeLog index 5e2292669c..9b915bc728 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Fri Sep 12 22:41:48 2003 Michal Rokos + + * ext/openssl/ossl.c: move ASN.1 stuff to ossl_asn1.[ch] + + * ext/openssl/ossl.c: move BIO stuff to ossl_bio.[ch] + + * ext/openssl/ossl_asn1.[ch]: new files + + * ext/openssl/ossl_bio.[ch]: new files + Fri Sep 12 12:30:41 2003 Nobuyoshi Nakada * intern.h (rb_disable_super, rb_enable_super): replace with dummy @@ -56,6 +66,10 @@ Tue Sep 9 05:17:04 2003 GOTOU Yuuzou * ext/openssl/ossl_config.rb: avoid compile error in OpenSSL-0.9.6. +Tue Sep 9 02:41:35 2003 Michal Rokos + + * ext/openssl/ossl_config.c: Refine compatibility. + Tue Sep 9 01:50:45 2003 GOTOU Yuuzou * lib/webrick/httpserver.rb (HTTPServer#access_log): add "\n" to @@ -764,6 +778,16 @@ Fri Aug 15 02:08:53 2003 Yukihiro Matsumoto * gc.c (id2ref): recycle check should be done by klass == 0. [ruby-core:01408] +Fri Aug 15 01:34:23 2003 Michal Rokos + + * ext/openssl/ossl_pkey.c: move generate_cb here + + * ext/openssl/ossl_pkey_{dh|dsa|rsa}.c: adapt to this cb + + * ext/openssl/openssl_missing.[ch]: add (0.9.6x, x * ext/bigdecimal/bigdecimal.c: Bug in div method fixed. diff --git a/ext/openssl/MANIFEST b/ext/openssl/MANIFEST index e049b0c76e..78ac7e98b2 100644 --- a/ext/openssl/MANIFEST +++ b/ext/openssl/MANIFEST @@ -15,6 +15,10 @@ openssl_missing.c openssl_missing.h ossl.c ossl.h +ossl_asn1.c +ossl_asn1.h +ossl_bio.c +ossl_bio.h ossl_bn.c ossl_bn.h ossl_cipher.c diff --git a/ext/openssl/openssl_missing.c b/ext/openssl/openssl_missing.c index e201e750c9..0c0be5fc1f 100644 --- a/ext/openssl/openssl_missing.c +++ b/ext/openssl/openssl_missing.c @@ -17,21 +17,13 @@ int HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in) { - if (!out || !in) { - /* HMACerr(HMAC_CTX_COPY,HMAC_R_INPUT_NOT_INITIALIZED); */ - return 0; - } + if (!out || !in) return 0; memcpy(out, in, sizeof(HMAC_CTX)); - if (!EVP_MD_CTX_copy(&out->md_ctx, &in->md_ctx)) { - return 0; - } - if (!EVP_MD_CTX_copy(&out->i_ctx, &in->i_ctx)) { + if (!EVP_MD_CTX_copy(&out->md_ctx, &in->md_ctx) + || !EVP_MD_CTX_copy(&out->i_ctx, &in->i_ctx) + || !EVP_MD_CTX_copy(&out->o_ctx, &in->o_ctx)) return 0; - } - if (!EVP_MD_CTX_copy(&out->o_ctx, &in->o_ctx)) { - return 0; - } return 1; } #endif /* HAVE_HMAC_CTX_COPY */ @@ -42,12 +34,12 @@ HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in) int X509_STORE_set_ex_data(X509_STORE *str, int idx, void *data) { - return CRYPTO_set_ex_data(&str->ex_data,idx,data); + return CRYPTO_set_ex_data(&str->ex_data, idx, data); } void *X509_STORE_get_ex_data(X509_STORE *str, int idx) { - return CRYPTO_get_ex_data(&str->ex_data,idx); + return CRYPTO_get_ex_data(&str->ex_data, idx); } #endif @@ -55,9 +47,10 @@ void *X509_STORE_get_ex_data(X509_STORE *str, int idx) EVP_MD_CTX * EVP_MD_CTX_create(void) { - EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof *ctx); + EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof(EVP_MD_CTX)); + if (!ctx) return NULL; - memset(ctx, '\0', sizeof *ctx); + memset(ctx, 0, sizeof(EVP_MD_CTX)); return ctx; } @@ -68,7 +61,7 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) { /* FIXME!!! */ - memset(ctx, '\0', sizeof *ctx); + memset(ctx, 0, sizeof(EVP_MD_CTX)); return 1; } @@ -87,7 +80,7 @@ EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) void EVP_MD_CTX_init(EVP_MD_CTX *ctx) { - memset(ctx,'\0',sizeof *ctx); + memset(ctx, 0, sizeof(EVP_MD_CTX)); } #endif @@ -108,7 +101,7 @@ HMAC_CTX_cleanup(HMAC_CTX *ctx) EVP_MD_CTX_cleanup(&ctx->i_ctx); EVP_MD_CTX_cleanup(&ctx->o_ctx); EVP_MD_CTX_cleanup(&ctx->md_ctx); - memset(ctx,0,sizeof *ctx); + memset(ctx, 0, sizeof(HMAC_CTX)); } #endif @@ -116,13 +109,12 @@ HMAC_CTX_cleanup(HMAC_CTX *ctx) int X509_CRL_set_version(X509_CRL *x, long version) { - if (x == NULL) return(0); - if (x->crl->version == NULL) - { - if ((x->crl->version=M_ASN1_INTEGER_new()) == NULL) - return(0); - } - return(ASN1_INTEGER_set(x->crl->version,version)); + if (x == NULL || x->crl == NULL) return 0; + if (x->crl->version == NULL) { + x->crl->version = M_ASN1_INTEGER_new(); + if (x->crl->version == NULL) return 0; + } + return ASN1_INTEGER_set(x->crl->version, version); } #endif @@ -130,8 +122,8 @@ X509_CRL_set_version(X509_CRL *x, long version) int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) { - if ((x == NULL) || (x->crl == NULL)) return(0); - return(X509_NAME_set(&x->crl->issuer,name)); + if (x == NULL || x->crl == NULL) return 0; + return X509_NAME_set(&x->crl->issuer, name); } #endif @@ -144,8 +136,8 @@ X509_CRL_sort(X509_CRL *c) /* sort the data so it will be written in serial * number order */ sk_X509_REVOKED_sort(c->crl->revoked); - for (i=0; icrl->revoked); i++){ - r=sk_X509_REVOKED_value(c->crl->revoked,i); + for (i=0; icrl->revoked); i++) { + r=sk_X509_REVOKED_value(c->crl->revoked, i); r->sequence=i; } return 1; @@ -165,13 +157,12 @@ int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev) { X509_CRL_INFO *inf; + inf = crl->crl; - if(!inf->revoked) + if (!inf->revoked) inf->revoked = sk_X509_REVOKED_new(OSSL_X509_REVOKED_cmp); - if(!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) { - /* ASN1err(ASN1_F_X509_CRL_ADD0_REVOKED, ERR_R_MALLOC_FAILURE); */ + if (!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) return 0; - } return 1; } #endif @@ -181,7 +172,6 @@ int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) { if (!BN_sqr(r, (BIGNUM*)a, ctx)) return 0; - /* r->neg == 0, thus we don't need BN_nnmod */ return BN_mod(r, r, m, ctx); } #endif @@ -189,11 +179,8 @@ BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) #if !defined(HAVE_BN_MOD_ADD) || !defined(HAVE_BN_MOD_SUB) int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) { - /* like BN_mod, but returns non-negative remainder - * (i.e., 0 <= r < |d| always holds) */ - if (!(BN_mod(r,m,d,ctx))) return 0; + if (!BN_mod(r,m,d,ctx)) return 0; if (!r->neg) return 1; - /* now -|d| < r < 0, so we have to set r := r + |d| */ return (d->neg ? BN_sub : BN_add)(r, r, d); } #endif @@ -216,6 +203,54 @@ BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX } #endif +#if !defined(HAVE_BN_RAND_RANGE) || !defined(HAVE_BN_PSEUDO_RAND_RANGE) +static int +bn_rand_range(int pseudo, BIGNUM *r, BIGNUM *range) +{ + int (*bn_rand)(BIGNUM *, int, int, int) = pseudo ? BN_pseudo_rand : BN_rand; + int n; + + if (range->neg || BN_is_zero(range)) return 0; + + n = BN_num_bits(range); + + if (n == 1) { + if (!BN_zero(r)) return 0; + } else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3)) { + do { + if (!bn_rand(r, n + 1, -1, 0)) return 0; + if (BN_cmp(r ,range) >= 0) { + if (!BN_sub(r, r, range)) return 0; + if (BN_cmp(r, range) >= 0) + if (!BN_sub(r, r, range)) return 0; + } + } while (BN_cmp(r, range) >= 0); + } else { + do { + if (!bn_rand(r, n, -1, 0)) return 0; + } while (BN_cmp(r, range) >= 0); + } + + return 1; +} +#endif + +#if !defined(HAVE_BN_RAND_RANGE) +int +BN_rand_range(BIGNUM *r, BIGNUM *range) +{ + return bn_rand_range(0, r, range); +} +#endif + +#if !defined(HAVE_BN_PSEUDO_RAND_RANGE) +int +BN_pseudo_rand_range(BIGNUM *r, BIGNUM *range) +{ + return bn_rand_range(1, r, range); +} +#endif + #if !defined(HAVE_CONF_GET1_DEFAULT_CONFIG_FILE) #define OPENSSL_CONF "openssl.cnf" char * @@ -250,30 +285,31 @@ PEM_def_callback(char *buf, int num, int w, void *key) { int i,j; const char *prompt; - if(key){ + + if (key) { i = strlen(key); i = (i > num) ? num : i; memcpy(buf, key, i); - return(i); + return i; } prompt = EVP_get_pw_prompt(); - if (prompt == NULL) prompt= "Enter PEM pass phrase:"; - for(;;){ + if (prompt == NULL) prompt = "Enter PEM pass phrase:"; + for (;;) { i = EVP_read_pw_string(buf, num, prompt, w); - if(i != 0){ - memset(buf,0,(unsigned int)num); + if (i != 0) { + memset(buf, 0, (unsigned int)num); return(-1); } j = strlen(buf); - if(j < OSSL_PASS_MIN_LENGTH){ + if (j < OSSL_PASS_MIN_LENGTH) { fprintf(stderr, "phrase is too short, needs to be at least %d chars\n", OSSL_PASS_MIN_LENGTH); } else break; } - return(j); + return j; } #endif diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h index 33b15f6aa6..7a755f79b5 100644 --- a/ext/openssl/openssl_missing.h +++ b/ext/openssl/openssl_missing.h @@ -90,11 +90,10 @@ int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx); int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx); +int BN_rand_range(BIGNUM *r, BIGNUM *range); +int BN_pseudo_rand_range(BIGNUM *r, BIGNUM *range); char *CONF_get1_default_config_file(void); - -#if !defined(HAVE_PEM_DEF_CALLBACK) int PEM_def_callback(char *buf, int num, int w, void *key); -#endif #if defined(__cplusplus) } diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index 9e476cb5af..b90ea10780 100644 --- a/ext/openssl/ossl.c +++ b/ext/openssl/ossl.c @@ -11,142 +11,6 @@ #include "ossl.h" #include /* for ossl_raise */ -#if defined(HAVE_SYS_TIME_H) -# include -#elif !defined(NT) && !defined(_WIN32) -struct timeval { - long tv_sec; /* seconds */ - long tv_usec; /* and microseconds */ -}; -#endif - -/* - * DATE conversion - */ -VALUE -asn1time_to_time(ASN1_TIME *time) -{ - struct tm tm; - VALUE argv[6]; - - if (!time) { - ossl_raise(rb_eTypeError, "ASN1_TIME is NULL!"); - } - memset(&tm, 0, sizeof(struct tm)); - - switch (time->type) { - case V_ASN1_UTCTIME: - if (sscanf(time->data, "%2d%2d%2d%2d%2d%2dZ", &tm.tm_year, &tm.tm_mon, - &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { - ossl_raise(rb_eTypeError, "bad UTCTIME format"); - } - if (tm.tm_year < 69) { - tm.tm_year += 2000; - } else { - tm.tm_year += 1900; - } - tm.tm_mon -= 1; - break; - case V_ASN1_GENERALIZEDTIME: - if (sscanf(time->data, "%4d%2d%2d%2d%2d%2dZ", &tm.tm_year, &tm.tm_mon, - &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { - ossl_raise(rb_eTypeError, "bad GENERALIZEDTIME format" ); - } - tm.tm_mon -= 1; - break; - default: - rb_warning("unknown time format"); - return Qnil; - } - argv[0] = INT2NUM(tm.tm_year); - argv[1] = INT2NUM(tm.tm_mon+1); - argv[2] = INT2NUM(tm.tm_mday); - argv[3] = INT2NUM(tm.tm_hour); - argv[4] = INT2NUM(tm.tm_min); - argv[5] = INT2NUM(tm.tm_sec); - - return rb_funcall2(rb_cTime, rb_intern("utc"), 6, argv); -} - -/* - * This function is not exported in Ruby's *.h - */ -extern struct timeval rb_time_timeval(VALUE); - -time_t -time_to_time_t(VALUE time) -{ - struct timeval t = rb_time_timeval(time); - return t.tv_sec; -} - -/* - * ASN1_INTEGER conversions - * TODO: Make a decision what's the right way to do this. - */ -#define DO_IT_VIA_RUBY 0 -VALUE -asn1integer_to_num(ASN1_INTEGER *ai) -{ - BIGNUM *bn; -#if DO_IT_VIA_RUBY - char *txt; -#endif - VALUE num; - - if (!ai) { - ossl_raise(rb_eTypeError, "ASN1_INTEGER is NULL!"); - } - if (!(bn = ASN1_INTEGER_to_BN(ai, NULL))) { - ossl_raise(eOSSLError, NULL); - } -#if DO_IT_VIA_RUBY - if (!(txt = BN_bn2dec(bn))) { - BN_free(bn); - ossl_raise(eOSSLError, NULL); - } - num = rb_cstr_to_inum(txt, 10, Qtrue); - OPENSSL_free(txt); -#else - num = ossl_bn_new(bn); -#endif - BN_free(bn); - - return num; -} - -#if DO_IT_VIA_RUBY -ASN1_INTEGER *num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai) -{ - BIGNUM *bn = NULL; - - if (RTEST(rb_obj_is_kind_of(obj, cBN))) { - bn = GetBNPtr(obj); - } else { - obj = rb_String(obj); - if (!BN_dec2bn(&bn, StringValuePtr(obj))) { - ossl_raise(eOSSLError, NULL); - } - } - if (!(ai = BN_to_ASN1_INTEGER(bn, ai))) { - BN_free(bn); - ossl_raise(eOSSLError, NULL); - } - BN_free(bn); - return ai; -} -#else -ASN1_INTEGER *num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai) -{ - BIGNUM *bn = GetBNPtr(obj); - - if (!(ai = BN_to_ASN1_INTEGER(bn, ai))) { - ossl_raise(eOSSLError, NULL); - } - return ai; -} -#endif - /* * String to HEXString conversion */ @@ -183,52 +47,6 @@ string2hex(char *buf, int buf_len, char **hexbuf, int *hexbuf_len) /* * Data Conversion */ -BIO * -ossl_obj2bio(VALUE obj) -{ - BIO *bio; - - if (TYPE(obj) == T_FILE) { - OpenFile *fptr; - GetOpenFile(obj, fptr); - rb_io_check_readable(fptr); - bio = BIO_new_fp(fptr->f, BIO_NOCLOSE); - } - else { - StringValue(obj); - bio = BIO_new_mem_buf(RSTRING(obj)->ptr, RSTRING(obj)->len); - } - if (!bio) ossl_raise(eOSSLError, NULL); - - return bio; -} - -BIO * -ossl_protect_obj2bio(VALUE obj, int *status) -{ - BIO *ret = NULL; - ret = (BIO*)rb_protect((VALUE(*)_((VALUE)))ossl_obj2bio, obj, status); - return ret; -} - -VALUE -ossl_membio2str(BIO *bio) -{ - VALUE ret; - BUF_MEM *buf; - - BIO_get_mem_ptr(bio, &buf); - ret = rb_str_new(buf->data, buf->length); - - return ret; -} - -VALUE -ossl_protect_membio2str(BIO *bio, int *status) -{ - return rb_protect((VALUE(*)_((VALUE)))ossl_membio2str, (VALUE)bio, status); -} - STACK_OF(X509) * ossl_x509_ary2sk(VALUE ary) { diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h index fd0c41ee1d..efb7057adb 100644 --- a/ext/openssl/ossl.h +++ b/ext/openssl/ossl.h @@ -87,18 +87,6 @@ extern VALUE eOSSLError; }\ } while (0) -/* - * ASN1_DATE conversions - */ -VALUE asn1time_to_time(ASN1_TIME *); -time_t time_to_time_t(VALUE); - -/* - * ASN1_INTEGER conversions - */ -VALUE asn1integer_to_num(ASN1_INTEGER *); -ASN1_INTEGER *num_to_asn1integer(VALUE, ASN1_INTEGER *); - /* * String to HEXString conversion */ @@ -107,10 +95,6 @@ int string2hex(char *, int, char **, int *); /* * Data Conversion */ -BIO *ossl_obj2bio(VALUE); -BIO *ossl_protect_obj2bio(VALUE,int*); -VALUE ossl_membio2str(BIO*); -VALUE ossl_protect_membio2str(BIO*,int*); STACK_OF(X509) *ossl_x509_ary2sk(VALUE); STACK_OF(X509) *ossl_protect_x509_ary2sk(VALUE,int*); @@ -174,19 +158,21 @@ void ossl_debug(const char *, ...); */ #include "openssl_missing.h" #include "ruby_missing.h" +#include "ossl_asn1.h" +#include "ossl_bio.h" #include "ossl_bn.h" #include "ossl_cipher.h" #include "ossl_config.h" #include "ossl_digest.h" #include "ossl_hmac.h" #include "ossl_ns_spki.h" +#include "ossl_ocsp.h" #include "ossl_pkcs7.h" #include "ossl_pkey.h" #include "ossl_rand.h" #include "ossl_ssl.h" #include "ossl_version.h" #include "ossl_x509.h" -#include "ossl_ocsp.h" void Init_openssl(void); diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c new file mode 100644 index 0000000000..f0a6379e42 --- /dev/null +++ b/ext/openssl/ossl_asn1.c @@ -0,0 +1,148 @@ +/* + * $Id$ + * 'OpenSSL for Ruby' team members + * Copyright (C) 2003 + * All rights reserved. + */ +/* + * This program is licenced under the same licence as Ruby. + * (See the file 'LICENCE'.) + */ +#include "ossl.h" + +#if defined(HAVE_SYS_TIME_H) +# include +#elif !defined(NT) && !defined(_WIN32) +struct timeval { + long tv_sec; /* seconds */ + long tv_usec; /* and microseconds */ +}; +#endif + +/* + * DATE conversion + */ +VALUE +asn1time_to_time(ASN1_TIME *time) +{ + struct tm tm; + VALUE argv[6]; + + if (!time) { + ossl_raise(rb_eTypeError, "ASN1_TIME is NULL!"); + } + memset(&tm, 0, sizeof(struct tm)); + + switch (time->type) { + case V_ASN1_UTCTIME: + if (sscanf(time->data, "%2d%2d%2d%2d%2d%2dZ", &tm.tm_year, &tm.tm_mon, + &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { + ossl_raise(rb_eTypeError, "bad UTCTIME format"); + } + if (tm.tm_year < 69) { + tm.tm_year += 2000; + } else { + tm.tm_year += 1900; + } + tm.tm_mon -= 1; + break; + case V_ASN1_GENERALIZEDTIME: + if (sscanf(time->data, "%4d%2d%2d%2d%2d%2dZ", &tm.tm_year, &tm.tm_mon, + &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { + ossl_raise(rb_eTypeError, "bad GENERALIZEDTIME format" ); + } + tm.tm_mon -= 1; + break; + default: + rb_warning("unknown time format"); + return Qnil; + } + argv[0] = INT2NUM(tm.tm_year); + argv[1] = INT2NUM(tm.tm_mon+1); + argv[2] = INT2NUM(tm.tm_mday); + argv[3] = INT2NUM(tm.tm_hour); + argv[4] = INT2NUM(tm.tm_min); + argv[5] = INT2NUM(tm.tm_sec); + + return rb_funcall2(rb_cTime, rb_intern("utc"), 6, argv); +} + +/* + * This function is not exported in Ruby's *.h + */ +extern struct timeval rb_time_timeval(VALUE); + +time_t +time_to_time_t(VALUE time) +{ + struct timeval t = rb_time_timeval(time); + return t.tv_sec; +} + +/* + * ASN1_INTEGER conversions + * TODO: Make a decision what's the right way to do this. + */ +#define DO_IT_VIA_RUBY 0 +VALUE +asn1integer_to_num(ASN1_INTEGER *ai) +{ + BIGNUM *bn; +#if DO_IT_VIA_RUBY + char *txt; +#endif + VALUE num; + + if (!ai) { + ossl_raise(rb_eTypeError, "ASN1_INTEGER is NULL!"); + } + if (!(bn = ASN1_INTEGER_to_BN(ai, NULL))) { + ossl_raise(eOSSLError, NULL); + } +#if DO_IT_VIA_RUBY + if (!(txt = BN_bn2dec(bn))) { + BN_free(bn); + ossl_raise(eOSSLError, NULL); + } + num = rb_cstr_to_inum(txt, 10, Qtrue); + OPENSSL_free(txt); +#else + num = ossl_bn_new(bn); +#endif + BN_free(bn); + + return num; +} + +#if DO_IT_VIA_RUBY +ASN1_INTEGER *num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai) +{ + BIGNUM *bn = NULL; + + if (RTEST(rb_obj_is_kind_of(obj, cBN))) { + bn = GetBNPtr(obj); + } else { + obj = rb_String(obj); + if (!BN_dec2bn(&bn, StringValuePtr(obj))) { + ossl_raise(eOSSLError, NULL); + } + } + if (!(ai = BN_to_ASN1_INTEGER(bn, ai))) { + BN_free(bn); + ossl_raise(eOSSLError, NULL); + } + BN_free(bn); + return ai; +} +#else +ASN1_INTEGER *num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai) +{ + BIGNUM *bn = GetBNPtr(obj); + + if (!(ai = BN_to_ASN1_INTEGER(bn, ai))) { + ossl_raise(eOSSLError, NULL); + } + return ai; +} +#endif + diff --git a/ext/openssl/ossl_asn1.h b/ext/openssl/ossl_asn1.h new file mode 100644 index 0000000000..b277c573a9 --- /dev/null +++ b/ext/openssl/ossl_asn1.h @@ -0,0 +1,27 @@ +/* + * $Id$ + * 'OpenSSL for Ruby' team members + * Copyright (C) 2003 + * All rights reserved. + */ +/* + * This program is licenced under the same licence as Ruby. + * (See the file 'LICENCE'.) + */ +#if !defined(_OSSL_ASN1_H_) +#define _OSSL_ASN1_H_ + +/* + * ASN1_DATE conversions + */ +VALUE asn1time_to_time(ASN1_TIME *); +time_t time_to_time_t(VALUE); + +/* + * ASN1_INTEGER conversions + */ +VALUE asn1integer_to_num(ASN1_INTEGER *); +ASN1_INTEGER *num_to_asn1integer(VALUE, ASN1_INTEGER *); + +#endif + diff --git a/ext/openssl/ossl_bio.c b/ext/openssl/ossl_bio.c new file mode 100644 index 0000000000..364e2ed71f --- /dev/null +++ b/ext/openssl/ossl_bio.c @@ -0,0 +1,58 @@ +/* + * $Id$ + * 'OpenSSL for Ruby' team members + * Copyright (C) 2003 + * All rights reserved. + */ +/* + * This program is licenced under the same licence as Ruby. + * (See the file 'LICENCE'.) + */ +#include "ossl.h" + +BIO * +ossl_obj2bio(VALUE obj) +{ + BIO *bio; + + if (TYPE(obj) == T_FILE) { + OpenFile *fptr; + GetOpenFile(obj, fptr); + rb_io_check_readable(fptr); + bio = BIO_new_fp(fptr->f, BIO_NOCLOSE); + } + else { + StringValue(obj); + bio = BIO_new_mem_buf(RSTRING(obj)->ptr, RSTRING(obj)->len); + } + if (!bio) ossl_raise(eOSSLError, NULL); + + return bio; +} + +BIO * +ossl_protect_obj2bio(VALUE obj, int *status) +{ + BIO *ret = NULL; + ret = (BIO*)rb_protect((VALUE(*)_((VALUE)))ossl_obj2bio, obj, status); + return ret; +} + +VALUE +ossl_membio2str(BIO *bio) +{ + VALUE ret; + BUF_MEM *buf; + + BIO_get_mem_ptr(bio, &buf); + ret = rb_str_new(buf->data, buf->length); + + return ret; +} + +VALUE +ossl_protect_membio2str(BIO *bio, int *status) +{ + return rb_protect((VALUE(*)_((VALUE)))ossl_membio2str, (VALUE)bio, status); +} + diff --git a/ext/openssl/ossl_bio.h b/ext/openssl/ossl_bio.h new file mode 100644 index 0000000000..0795c5dbed --- /dev/null +++ b/ext/openssl/ossl_bio.h @@ -0,0 +1,20 @@ +/* + * $Id$ + * 'OpenSSL for Ruby' team members + * Copyright (C) 2003 + * All rights reserved. + */ +/* + * This program is licenced under the same licence as Ruby. + * (See the file 'LICENCE'.) + */ +#if !defined(_OSSL_BIO_H_) +#define _OSSL_BIO_H_ + +BIO *ossl_obj2bio(VALUE); +BIO *ossl_protect_obj2bio(VALUE,int*); +VALUE ossl_membio2str(BIO*); +VALUE ossl_protect_membio2str(BIO*,int*); + +#endif + diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c index d815334613..750d8ad87f 100644 --- a/ext/openssl/ossl_bn.c +++ b/ext/openssl/ossl_bn.c @@ -471,25 +471,8 @@ BIGNUM_RAND(pseudo_rand); WrapBN(klass, obj, result); \ return obj; \ } - -#define BIGNUM_RAND_RANGE_NOT_IMPL(func) \ - static VALUE \ - ossl_bn_s_##func##_range(VALUE klass, VALUE range) \ - { \ - rb_notimplement(); \ - } - -#if defined(HAVE_BN_RAND_RANGE) BIGNUM_RAND_RANGE(rand); -#else -BIGNUM_RAND_RANGE_NOT_IMPL(rand); -#endif - -#if defined(HAVE_BN_PSEUDO_RAND_RANGE) BIGNUM_RAND_RANGE(pseudo_rand); -#else -BIGNUM_RAND_RANGE_NOT_IMPL(pseudo_rand); -#endif static VALUE ossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass) diff --git a/ext/openssl/ossl_config.c b/ext/openssl/ossl_config.c index baed8345e7..78fae970de 100644 --- a/ext/openssl/ossl_config.c +++ b/ext/openssl/ossl_config.c @@ -52,7 +52,6 @@ GetConfigPtr(VALUE obj) CONF * DupConfigPtr(VALUE obj) { - CONF *conf; VALUE str; OSSL_Check_Kind(obj, cConfig); @@ -70,7 +69,6 @@ parse_config(VALUE str, CONF *dst) CONF *conf; BIO *bio; long eline = -1; - VALUE obj; bio = ossl_obj2bio(str); conf = dst ? dst : NCONF_new(NULL); @@ -210,7 +208,17 @@ static VALUE ossl_config_get_value_old(int argc, VALUE *argv, VALUE self) { VALUE section, name; + rb_scan_args(argc, argv, "11", §ion, &name); + + /* support conf.value(nil, "HOME") -> conf.get_value("", "HOME") */ + if (NIL_P(section)) section = rb_str_new2(""); + /* support conf.value("HOME") -> conf.get_value("", "HOME") */ + if (NIL_P(name)) { + name = section; + section = rb_str_new2(""); + } + /* NOTE: Don't care about conf.get_value(nil, nil) */ rb_warn("Config#value is deprecated; use Config#get_value"); return ossl_config_get_value(self, section, name); } diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index 3121cdbb6a..f9f8c0ad5e 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -18,6 +18,21 @@ VALUE cPKey; VALUE ePKeyError; ID id_private_q; +/* + * callback for generating keys + */ +void +ossl_generate_cb(int p, int n, void *arg) +{ + VALUE ary; + + ary = rb_ary_new2(2); + rb_ary_store(ary, 0, INT2NUM(p)); + rb_ary_store(ary, 1, INT2NUM(n)); + + rb_yield(ary); +} + /* * Public */ diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h index f3cf20c5d3..189573546e 100644 --- a/ext/openssl/ossl_pkey.h +++ b/ext/openssl/ossl_pkey.h @@ -33,6 +33,8 @@ extern ID id_private_q; GetPKey(obj, pkey); \ } while (0) +void ossl_generate_cb(int, int, void *); + VALUE ossl_pkey_new(EVP_PKEY *); VALUE ossl_pkey_new_from_file(VALUE); EVP_PKEY *GetPKeyPtr(VALUE); diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c index 9a6bec15eb..84eff16f49 100644 --- a/ext/openssl/ossl_pkey_dh.c +++ b/ext/openssl/ossl_pkey_dh.c @@ -74,34 +74,16 @@ ossl_dh_new(EVP_PKEY *pkey) /* * Private */ -/* - * CB for yielding when generating DH params - */ -static void -ossl_dh_generate_cb(int p, int n, void *arg) -{ - VALUE ary; - - ary = rb_ary_new2(2); - rb_ary_store(ary, 0, INT2NUM(p)); - rb_ary_store(ary, 1, INT2NUM(n)); - - rb_yield(ary); -} - static DH * dh_generate(int size, int gen) { DH *dh; - void (*cb)(int, int, void *) = NULL; + + dh = DH_generate_parameters(size, gen, + rb_block_given_p() ? ossl_generate_cb : NULL, + NULL); + if (!dh) return 0; - if (rb_block_given_p()) { - cb = ossl_dh_generate_cb; - } - /* arg to cb = NULL */ - if (!(dh = DH_generate_parameters(size, gen, cb, NULL))) { - return 0; - } if (!DH_generate_key(dh)) { DH_free(dh); return 0; diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c index 73ab47b2c9..5cea9345e9 100644 --- a/ext/openssl/ossl_pkey_dsa.c +++ b/ext/openssl/ossl_pkey_dsa.c @@ -74,21 +74,6 @@ ossl_dsa_new(EVP_PKEY *pkey) /* * Private */ -/* - * CB for yielding when generating DSA params - */ -static void -ossl_dsa_generate_cb(int p, int n, void *arg) -{ - VALUE ary; - - ary = rb_ary_new2(2); - rb_ary_store(ary, 0, INT2NUM(p)); - rb_ary_store(ary, 1, INT2NUM(n)); - - rb_yield(ary); -} - static DSA * dsa_generate(int size) { @@ -96,18 +81,15 @@ dsa_generate(int size) unsigned char seed[20]; int seed_len = 20, counter; unsigned long h; - void (*cb)(int, int, void *) = NULL; if (!RAND_bytes(seed, seed_len)) { return 0; } - if (rb_block_given_p()) { - cb = ossl_dsa_generate_cb; - } - dsa = DSA_generate_parameters(size, seed, seed_len, &counter, &h, cb, NULL); - if(!dsa) { /* arg to cb = NULL */ - return 0; - } + dsa = DSA_generate_parameters(size, seed, seed_len, &counter, &h, + rb_block_given_p() ? ossl_generate_cb : NULL, + NULL); + if(!dsa) return 0; + if (!DSA_generate_key(dsa)) { DSA_free(dsa); return 0; diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c index c3d23666c9..ce53a898e0 100644 --- a/ext/openssl/ossl_pkey_rsa.c +++ b/ext/openssl/ossl_pkey_rsa.c @@ -75,30 +75,12 @@ ossl_rsa_new(EVP_PKEY *pkey) /* * Private */ -/* - * CB for yielding when generating RSA data - */ -static void -ossl_rsa_generate_cb(int p, int n, void *arg) -{ - VALUE ary; - - ary = rb_ary_new2(2); - rb_ary_store(ary, 0, INT2NUM(p)); - rb_ary_store(ary, 1, INT2NUM(n)); - - rb_yield(ary); -} - static RSA * rsa_generate(int size, int exp) { - void (*cb)(int, int, void *) = NULL; - - if (rb_block_given_p()) { - cb = ossl_rsa_generate_cb; - } - return RSA_generate_key(size, exp, cb, NULL); + return RSA_generate_key(size, exp, + rb_block_given_p() ? ossl_generate_cb : NULL, + NULL); } static VALUE -- cgit v1.2.3