From 93e1583d735bac916ac815ee2737a9596dccad0f Mon Sep 17 00:00:00 2001 From: emboss Date: Sun, 26 Jun 2011 01:32:03 +0000 Subject: * ext/openssl/extconf.rb * ext/openssl/ossl_missing.h/.c: add ASN1_put_eoc if missing. * ext/openssl/ossl_asn1.c: introduce ossl_asn1_object_size and ossl_asn1_put_object to wrap functionality depending on OpenSSL version in use. Fixes [ Ruby 1.9 - Bug #4916 ] reported by Hiroshi Nakamura. [ruby-core:37286] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32230 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 11 +++++++++++ ext/openssl/extconf.rb | 1 + ext/openssl/openssl_missing.c | 12 ++++++++++++ ext/openssl/openssl_missing.h | 4 ++++ ext/openssl/ossl_asn1.c | 33 +++++++++++++++++++++++---------- 5 files changed, 51 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index eb7482abed..d6cf30e091 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Sun Jun 26 10:08:28 2011 Martin Bosslet + + * ext/openssl/extconf.rb + * ext/openssl/ossl_missing.h/.c: add ASN1_put_eoc if missing. + + * ext/openssl/ossl_asn1.c: introduce ossl_asn1_object_size and + ossl_asn1_put_object to wrap functionality depending on OpenSSL + version in use. + Fixes [ Ruby 1.9 - Bug #4916 ] reported by Hiroshi Nakamura. + [ruby-core:37286] + Sun Jun 26 01:00:15 2011 Tadayoshi Funaba * ext/date/date_core.c (date_strftime_internal): removed meaningless braces. diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb index d38af40b36..920caa641d 100644 --- a/ext/openssl/extconf.rb +++ b/ext/openssl/extconf.rb @@ -66,6 +66,7 @@ end message "=== Checking for OpenSSL features... ===\n" have_func("ERR_peek_last_error") +have_func("ASN1_put_eoc") have_func("BN_mod_add") have_func("BN_mod_sqr") have_func("BN_mod_sub") diff --git a/ext/openssl/openssl_missing.c b/ext/openssl/openssl_missing.c index 3ffe651b5b..f88dd403be 100644 --- a/ext/openssl/openssl_missing.c +++ b/ext/openssl/openssl_missing.c @@ -342,3 +342,15 @@ PEM_def_callback(char *buf, int num, int w, void *key) } #endif +#if !defined(HAVE_ASN1_PUT_EOC) +int +ASN1_put_eoc(unsigned char **pp) +{ + unsigned char *p = *pp; + *p++ = 0; + *p++ = 0; + *pp = p; + return 2; +} +#endif + diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h index 257089cce8..3635f88b73 100644 --- a/ext/openssl/openssl_missing.h +++ b/ext/openssl/openssl_missing.h @@ -185,6 +185,10 @@ char *CONF_get1_default_config_file(void); int PEM_def_callback(char *buf, int num, int w, void *key); #endif +#if !defined(HAVE_ASN1_PUT_EOC) +int ASN1_put_eoc(unsigned char **pp); +#endif + #if defined(__cplusplus) } #endif diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c index 354009ddce..0de80a32a9 100644 --- a/ext/openssl/ossl_asn1.c +++ b/ext/openssl/ossl_asn1.c @@ -200,6 +200,19 @@ static ID sIMPLICIT, sEXPLICIT; static ID sUNIVERSAL, sAPPLICATION, sCONTEXT_SPECIFIC, sPRIVATE; static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINFINITE_LENGTH, sivUNUSED_BITS; +/* + * We need to implement these for backward compatibility + * reasons, behavior of ASN1_put_object and ASN1_object_size + * for infinite length values is different in OpenSSL <= 0.9.7 + */ +#if OPENSSL_VERSION_NUMBER < 0x00908000L +#define ossl_asn1_object_size(cons, len, tag) (cons) == 2 ? (len) + ASN1_object_size((cons), 0, (tag)) : ASN1_object_size((cons), (len), (tag)) +#define ossl_asn1_put_object(pp, cons, len, tag, xc) (cons) == 2 ? ASN1_put_object((pp), (cons), 0, (tag), (xc)) : ASN1_put_object((pp), (cons), (len), (tag), (xc)) +#else +#define ossl_asn1_object_size(cons, len, tag) ASN1_object_size((cons), (len), (tag)) +#define ossl_asn1_put_object(pp, cons, len, tag, xc) ASN1_put_object((pp), (cons), (len), (tag), (xc)) +#endif + /* * Ruby to ASN1 converters */ @@ -752,11 +765,11 @@ ossl_asn1data_to_der(VALUE self) if (inf_length == Qtrue) { is_cons = 2; } - if((length = ASN1_object_size(is_cons, RSTRING_LENINT(value), tag)) <= 0) + if((length = ossl_asn1_object_size(is_cons, RSTRING_LENINT(value), tag)) <= 0) ossl_raise(eASN1Error, NULL); der = rb_str_new(0, length); p = (unsigned char *)RSTRING_PTR(der); - ASN1_put_object(&p, is_cons, RSTRING_LENINT(value), tag, tag_class); + ossl_asn1_put_object(&p, is_cons, RSTRING_LENINT(value), tag, tag_class); memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value)); p += RSTRING_LEN(value); ossl_str_adjust(der, p); @@ -1193,7 +1206,7 @@ ossl_asn1prim_to_der(VALUE self) explicit = ossl_asn1_is_explicit(self); asn1 = ossl_asn1_get_asn1type(self); - len = ASN1_object_size(1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn); + len = ossl_asn1_object_size(1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn); if(!(buf = OPENSSL_malloc(len))){ ossl_ASN1_TYPE_free(asn1); ossl_raise(eASN1Error, "cannot alloc buffer"); @@ -1202,7 +1215,7 @@ ossl_asn1prim_to_der(VALUE self) if (tc == V_ASN1_UNIVERSAL) { ossl_i2d_ASN1_TYPE(asn1, &p); } else if (explicit) { - ASN1_put_object(&p, 1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn, tc); + ossl_asn1_put_object(&p, 1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn, tc); ossl_i2d_ASN1_TYPE(asn1, &p); } else { ossl_i2d_ASN1_TYPE(asn1, &p); @@ -1274,19 +1287,19 @@ ossl_asn1cons_to_der(VALUE self) explicit = ossl_asn1_is_explicit(self); value = join_der(ossl_asn1_get_value(self)); - seq_len = ASN1_object_size(constructed, RSTRING_LENINT(value), tag); - length = ASN1_object_size(constructed, seq_len, tn); + seq_len = ossl_asn1_object_size(constructed, RSTRING_LENINT(value), tag); + length = ossl_asn1_object_size(constructed, seq_len, tn); str = rb_str_new(0, length); p = (unsigned char *)RSTRING_PTR(str); if(tc == V_ASN1_UNIVERSAL) - ASN1_put_object(&p, constructed, RSTRING_LENINT(value), tn, tc); + ossl_asn1_put_object(&p, constructed, RSTRING_LENINT(value), tn, tc); else{ if(explicit){ - ASN1_put_object(&p, constructed, seq_len, tn, tc); - ASN1_put_object(&p, constructed, RSTRING_LENINT(value), tag, V_ASN1_UNIVERSAL); + ossl_asn1_put_object(&p, constructed, seq_len, tn, tc); + ossl_asn1_put_object(&p, constructed, RSTRING_LENINT(value), tag, V_ASN1_UNIVERSAL); } else{ - ASN1_put_object(&p, constructed, RSTRING_LENINT(value), tn, tc); + ossl_asn1_put_object(&p, constructed, RSTRING_LENINT(value), tn, tc); } } memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value)); -- cgit v1.2.3