summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/openssl/extconf.rb1
-rw-r--r--ext/openssl/openssl_missing.c12
-rw-r--r--ext/openssl/openssl_missing.h4
-rw-r--r--ext/openssl/ossl_asn1.c33
4 files changed, 40 insertions, 10 deletions
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
@@ -201,6 +201,19 @@ 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
*/
static ASN1_BOOLEAN
@@ -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));