diff options
Diffstat (limited to 'ext/openssl/ossl_asn1.c')
-rw-r--r-- | ext/openssl/ossl_asn1.c | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c index 43a3d2d88a..5be0a0ba55 100644 --- a/ext/openssl/ossl_asn1.c +++ b/ext/openssl/ossl_asn1.c @@ -75,11 +75,27 @@ asn1time_to_time(ASN1_TIME *time) return rb_funcall2(rb_cTime, rb_intern("utc"), 6, argv); } +#if defined(HAVE_ASN1_TIME_ADJ) +void +ossl_time_extract(VALUE time, time_t *sec, int *days) +{ + VALUE divmod; + + divmod = rb_check_array_type( + rb_funcall(rb_Integer(time), rb_intern("divmod"), 1, INT2FIX(86400))); + *days = NUM2INT(RARRAY_AREF(divmod, 0)); + *sec = NUM2TIMET(RARRAY_AREF(divmod, 1)); +} +#else +/* OpenSSL 0.9.8 does not have ASN1_TIME_adj(). In that case, we have to use + * ASN1_TIME_set() but it has the Year 2038 issue on sizeof(time_t) == 4 + * environment. */ time_t time_to_time_t(VALUE time) { return (time_t)NUM2TIMET(rb_Integer(time)); } +#endif /* * STRING conversion @@ -279,27 +295,41 @@ obj_to_asn1obj(VALUE obj) return a1obj; } -static ASN1_UTCTIME* +static ASN1_UTCTIME * obj_to_asn1utime(VALUE time) { time_t sec; ASN1_UTCTIME *t; +#if defined(HAVE_ASN1_TIME_ADJ) + int off_days; + + ossl_time_extract(time, &sec, &off_days); + if (!(t = ASN1_UTCTIME_adj(NULL, sec, off_days, 0))) +#else sec = time_to_time_t(time); - if(!(t = ASN1_UTCTIME_set(NULL, sec))) + if (!(t = ASN1_UTCTIME_set(NULL, sec))) +#endif ossl_raise(eASN1Error, NULL); return t; } -static ASN1_GENERALIZEDTIME* +static ASN1_GENERALIZEDTIME * obj_to_asn1gtime(VALUE time) { time_t sec; ASN1_GENERALIZEDTIME *t; +#if defined(HAVE_ASN1_TIME_ADJ) + int off_days; + + ossl_time_extract(time, &sec, &off_days); + if (!(t = ASN1_GENERALIZEDTIME_adj(NULL, sec, off_days, 0))) +#else sec = time_to_time_t(time); - if(!(t =ASN1_GENERALIZEDTIME_set(NULL, sec))) + if (!(t = ASN1_GENERALIZEDTIME_set(NULL, sec))) +#endif ossl_raise(eASN1Error, NULL); return t; |