ruby-changes:43382
From: rhe <ko1@a...>
Date: Sun, 19 Jun 2016 18:42:36 +0900 (JST)
Subject: [ruby-changes:43382] rhe:r55456 (trunk): openssl: allow passing absolute times in OCSP::BasicResponse#add_status
rhe 2016-06-19 18:42:30 +0900 (Sun, 19 Jun 2016) New Revision: 55456 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=55456 Log: openssl: allow passing absolute times in OCSP::BasicResponse#add_status * ext/openssl/ossl_ocsp.c (ossl_ocspbres_add_status): Allow specifying the times (thisUpdate, nextUpdate and revocationTime) with Time objects. Currently they accepts only relative seconds from the current time. This is inconvenience, especially for revocationTime. When Integer is passed, they are still treated as relative times. Since the type check is currently done with rb_Integer(), this is a slightly incompatible change. Hope no one passes a relative time as String or Time object... Also, allow passing nil as nextUpdate. It is optional. * ext/openssl/ruby_missing.h: Define RB_INTEGER_TYPE_P() if not defined. openssl gem will be released before Ruby 2.4.0. Modified files: trunk/ChangeLog trunk/ext/openssl/ossl_ocsp.c trunk/ext/openssl/ruby_missing.h Index: ChangeLog =================================================================== --- ChangeLog (revision 55455) +++ ChangeLog (revision 55456) @@ -1,3 +1,18 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sun Jun 19 18:40:19 2016 Kazuki Yamaguchi <k@r...> + + * ext/openssl/ossl_ocsp.c (ossl_ocspbres_add_status): Allow specifying + the times (thisUpdate, nextUpdate and revocationTime) with Time + objects. Currently they accepts only relative seconds from the current + time. This is inconvenience, especially for revocationTime. When + Integer is passed, they are still treated as relative times. Since the + type check is currently done with rb_Integer(), this is a slightly + incompatible change. Hope no one passes a relative time as String or + Time object... + Also, allow passing nil as nextUpdate. It is optional. + + * ext/openssl/ruby_missing.h: Define RB_INTEGER_TYPE_P() if not defined. + openssl gem will be released before Ruby 2.4.0. + Sun Jun 19 18:39:38 2016 Kazuki Yamaguchi <k@r...> * ext/openssl/ossl_ocsp.c: Implement OCSP::{CertificateId,Request, Index: ext/openssl/ruby_missing.h =================================================================== --- ext/openssl/ruby_missing.h (revision 55455) +++ ext/openssl/ruby_missing.h (revision 55456) @@ -24,4 +24,9 @@ https://github.com/ruby/ruby/blob/trunk/ext/openssl/ruby_missing.h#L24 #define rb_io_t OpenFile #endif +#ifndef RB_INTEGER_TYPE_P +/* for Ruby 2.3 compatibility */ +#define RB_INTEGER_TYPE_P(obj) (RB_FIXNUM_P(obj) || RB_TYPE_P(obj, T_BIGNUM)) +#endif + #endif /* _OSSL_RUBY_MISSING_H_ */ Index: ext/openssl/ossl_ocsp.c =================================================================== --- ext/openssl/ossl_ocsp.c (revision 55455) +++ ext/openssl/ossl_ocsp.c (revision 55456) @@ -726,22 +726,49 @@ ossl_ocspbres_add_nonce(int argc, VALUE https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_ocsp.c#L726 return self; } +static VALUE +add_status_convert_time(VALUE obj) +{ + ASN1_TIME *time; + + if (RB_INTEGER_TYPE_P(obj)) + time = X509_gmtime_adj(NULL, NUM2INT(obj)); + else + time = ossl_x509_time_adjust(NULL, obj); + + if (!time) + ossl_raise(eOCSPError, NULL); + + return (VALUE)time; +} + /* * call-seq: * basic_response.add_status(certificate_id, status, reason, revocation_time, this_update, next_update, extensions) -> basic_response * - * Adds a validation +status+ (0 for good, 1 for revoked, 2 for unknown) to this - * response for +certificate_id+. +reason+ describes the reason for the - * revocation, if any. - * - * The +revocation_time+, +this_update+ and +next_update+ are times for the - * certificate's revocation time, the time of this status and the next update - * time for a new status, respectively. + * Adds a certificate status for +certificate_id+. +status+ is the status, and + * must be one of these: + * + * - OpenSSL::OCSP::V_CERTSTATUS_GOOD + * - OpenSSL::OCSP::V_CERTSTATUS_REVOKED + * - OpenSSL::OCSP::V_CERTSTATUS_UNKNOWN + * + * +reason+ and +revocation_time+ can be given only when +status+ is + * OpenSSL::OCSP::V_CERTSTATUS_REVOKED. +reason+ describes the reason for the + * revocation, and must be one of OpenSSL::OCSP::REVOKED_STATUS_* constants. + * +revocation_time+ is the time when the certificate is revoked. + * + * +this_update+ and +next_update+ indicate the time at which ths status is + * verified to be correct and the time at or before which newer information + * will be available, respectively. +next_update+ is optional. * - * +extensions+ may be an Array of OpenSSL::X509::Extension that will - * be added to this response or nil. + * +extensions+ is an Array of OpenSSL::X509::Extension to be included in the + * SingleResponse. This is also optional. + * + * Note that the times, +revocation_time+, +this_update+ and +next_update+ + * can be specified in either of Integer or Time object. If they are Integer, it + * is treated as the relative seconds from the current time. */ - static VALUE ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status, VALUE reason, VALUE revtime, @@ -750,36 +777,37 @@ ossl_ocspbres_add_status(VALUE self, VAL https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_ocsp.c#L777 OCSP_BASICRESP *bs; OCSP_SINGLERESP *single; OCSP_CERTID *id; - ASN1_TIME *ths, *nxt, *rev; - int st, rsn, error, rstatus = 0; + ASN1_TIME *ths = NULL, *nxt = NULL, *rev = NULL; + int st, rsn = 0, error = 0, rstatus = 0; long i; VALUE tmp; + GetOCSPBasicRes(self, bs); + SafeGetOCSPCertId(cid, id); st = NUM2INT(status); - rsn = NIL_P(status) ? 0 : NUM2INT(reason); - if(!NIL_P(ext)){ - /* All ary's members should be X509Extension */ - Check_Type(ext, T_ARRAY); + if (!NIL_P(ext)) { /* All ext's members must be X509::Extension */ + ext = rb_check_array_type(ext); for (i = 0; i < RARRAY_LEN(ext); i++) OSSL_Check_Kind(RARRAY_AREF(ext, i), cX509Ext); } - error = 0; - ths = nxt = rev = NULL; - if(!NIL_P(revtime)){ - tmp = rb_protect(rb_Integer, revtime, &rstatus); - if(rstatus) goto err; - rev = X509_gmtime_adj(NULL, NUM2INT(tmp)); + if (st == V_OCSP_CERTSTATUS_REVOKED) { + rsn = NUM2INT(reason); + tmp = rb_protect(add_status_convert_time, revtime, &rstatus); + if (rstatus) goto err; + rev = (ASN1_TIME *)tmp; + } + + tmp = rb_protect(add_status_convert_time, thisupd, &rstatus); + if (rstatus) goto err; + ths = (ASN1_TIME *)tmp; + + if (!NIL_P(nextupd)) { + tmp = rb_protect(add_status_convert_time, nextupd, &rstatus); + if (rstatus) goto err; + nxt = (ASN1_TIME *)tmp; } - tmp = rb_protect(rb_Integer, thisupd, &rstatus); - if(rstatus) goto err; - ths = X509_gmtime_adj(NULL, NUM2INT(tmp)); - tmp = rb_protect(rb_Integer, nextupd, &rstatus); - if(rstatus) goto err; - nxt = X509_gmtime_adj(NULL, NUM2INT(tmp)); - GetOCSPBasicRes(self, bs); - SafeGetOCSPCertId(cid, id); if(!(single = OCSP_basic_add1_status(bs, id, st, rsn, rev, ths, nxt))){ error = 1; goto err; @@ -787,8 +815,7 @@ ossl_ocspbres_add_status(VALUE self, VAL https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_ocsp.c#L815 if(!NIL_P(ext)){ X509_EXTENSION *x509ext; - while ((x509ext = OCSP_SINGLERESP_delete_ext(single, 0))) - X509_EXTENSION_free(x509ext); + for(i = 0; i < RARRAY_LEN(ext); i++){ x509ext = DupX509ExtPtr(RARRAY_AREF(ext, i)); if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)){ -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/