summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog24
-rw-r--r--ext/openssl/MANIFEST4
-rw-r--r--ext/openssl/openssl_missing.c130
-rw-r--r--ext/openssl/openssl_missing.h5
-rw-r--r--ext/openssl/ossl.c182
-rw-r--r--ext/openssl/ossl.h20
-rw-r--r--ext/openssl/ossl_asn1.c148
-rw-r--r--ext/openssl/ossl_asn1.h27
-rw-r--r--ext/openssl/ossl_bio.c58
-rw-r--r--ext/openssl/ossl_bio.h20
-rw-r--r--ext/openssl/ossl_bn.c17
-rw-r--r--ext/openssl/ossl_config.c12
-rw-r--r--ext/openssl/ossl_pkey.c15
-rw-r--r--ext/openssl/ossl_pkey.h2
-rw-r--r--ext/openssl/ossl_pkey_dh.c28
-rw-r--r--ext/openssl/ossl_pkey_dsa.c28
-rw-r--r--ext/openssl/ossl_pkey_rsa.c24
17 files changed, 409 insertions, 335 deletions
diff --git a/ChangeLog b/ChangeLog
index 5e2292669c3..9b915bc7285 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Fri Sep 12 22:41:48 2003 Michal Rokos <m.rokos@sh.cvut.cz>
+
+ * 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 <nobu@ruby-lang.org>
* intern.h (rb_disable_super, rb_enable_super): replace with dummy
@@ -56,6 +66,10 @@ Tue Sep 9 05:17:04 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
* ext/openssl/ossl_config.rb: avoid compile error in OpenSSL-0.9.6.
+Tue Sep 9 02:41:35 2003 Michal Rokos <m.rokos@sh.cvut.cz>
+
+ * ext/openssl/ossl_config.c: Refine compatibility.
+
Tue Sep 9 01:50:45 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
* lib/webrick/httpserver.rb (HTTPServer#access_log): add "\n" to
@@ -764,6 +778,16 @@ Fri Aug 15 02:08:53 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* gc.c (id2ref): recycle check should be done by klass == 0.
[ruby-core:01408]
+Fri Aug 15 01:34:23 2003 Michal Rokos <m.rokos@sh.cvut.cz>
+
+ * 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<j) missing BN funcs
+
+ * ext/openssl/ossl_bn.c: use supplied funcs from openssl_missing.c
+
Fri Aug 15 00:38:00 2003 Shigeo Kobayashi <shigek@ruby-lang.org>
* ext/bigdecimal/bigdecimal.c: Bug in div method fixed.
diff --git a/ext/openssl/MANIFEST b/ext/openssl/MANIFEST
index e049b0c76e1..78ac7e98b20 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 e201e750c97..0c0be5fc1f5 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; i<sk_X509_REVOKED_num(c->crl->revoked); i++){
- r=sk_X509_REVOKED_value(c->crl->revoked,i);
+ for (i=0; i<sk_X509_REVOKED_num(c->crl->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 33b15f6aa68..7a755f79b5d 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 9e476cb5afd..b90ea107800 100644
--- a/ext/openssl/ossl.c
+++ b/ext/openssl/ossl.c
@@ -11,142 +11,6 @@
#include "ossl.h"
#include <stdarg.h> /* for ossl_raise */
-#if defined(HAVE_SYS_TIME_H)
-# include <sys/time.h>
-#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 fd0c41ee1d4..efb7057adb2 100644
--- a/ext/openssl/ossl.h
+++ b/ext/openssl/ossl.h
@@ -88,18 +88,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
*/
int string2hex(char *, int, char **, int *);
@@ -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 00000000000..f0a6379e424
--- /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 <sys/time.h>
+#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 00000000000..b277c573a91
--- /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 00000000000..364e2ed71f7
--- /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 00000000000..0795c5dbed7
--- /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 d8153346131..750d8ad87fa 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 baed8345e70..78fae970de1 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", &section, &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 3121cdbb6a0..f9f8c0ad5ec 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -19,6 +19,21 @@ 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
*/
VALUE
diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h
index f3cf20c5d30..189573546e9 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 9a6bec15eb2..84eff16f49a 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 73ab47b2c95..5cea9345e97 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 c3d23666c94..ce53a898e07 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