diff options
Diffstat (limited to 'ext/openssl/ossl_ts.c')
-rw-r--r-- | ext/openssl/ossl_ts.c | 121 |
1 files changed, 103 insertions, 18 deletions
diff --git a/ext/openssl/ossl_ts.c b/ext/openssl/ossl_ts.c index 9450e435e0..d6a5fc9892 100644 --- a/ext/openssl/ossl_ts.c +++ b/ext/openssl/ossl_ts.c @@ -5,7 +5,7 @@ */ /* * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -83,7 +83,7 @@ static const rb_data_type_t ossl_ts_req_type = { { 0, ossl_ts_req_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static void @@ -97,7 +97,7 @@ static const rb_data_type_t ossl_ts_resp_type = { { 0, ossl_ts_resp_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static void @@ -111,7 +111,7 @@ static const rb_data_type_t ossl_ts_token_info_type = { { 0, ossl_ts_token_info_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -146,6 +146,12 @@ obj_to_asn1obj(VALUE obj) } static VALUE +obj_to_asn1obj_i(VALUE obj) +{ + return (VALUE)obj_to_asn1obj(obj); +} + +static VALUE get_asn1obj(ASN1_OBJECT *obj) { BIO *out; @@ -205,8 +211,10 @@ ossl_ts_req_initialize(int argc, VALUE *argv, VALUE self) in = ossl_obj2bio(&arg); ts_req = d2i_TS_REQ_bio(in, &ts_req); BIO_free(in); - if (!ts_req) + if (!ts_req) { + DATA_PTR(self) = NULL; ossl_raise(eTimestampError, "Error when decoding the timestamp request"); + } DATA_PTR(self) = ts_req; return self; @@ -496,6 +504,25 @@ ossl_ts_req_to_der(VALUE self) } static VALUE +ossl_ts_req_to_text(VALUE self) +{ + TS_REQ *req; + BIO *out; + + GetTSRequest(self, req); + + out = BIO_new(BIO_s_mem()); + if (!out) ossl_raise(eTimestampError, NULL); + + if (!TS_REQ_print_bio(out, req)) { + BIO_free(out); + ossl_raise(eTimestampError, NULL); + } + + return ossl_membio2str(out); +} + +static VALUE ossl_ts_resp_alloc(VALUE klass) { TS_RESP *resp; @@ -529,8 +556,10 @@ ossl_ts_resp_initialize(VALUE self, VALUE der) in = ossl_obj2bio(&der); ts_resp = d2i_TS_RESP_bio(in, &ts_resp); BIO_free(in); - if (!ts_resp) + if (!ts_resp) { + DATA_PTR(self) = NULL; ossl_raise(eTimestampError, "Error when decoding the timestamp response"); + } DATA_PTR(self) = ts_resp; return self; @@ -747,6 +776,25 @@ ossl_ts_resp_to_der(VALUE self) return asn1_to_der((void *)resp, (int (*)(void *, unsigned char **))i2d_TS_RESP); } +static VALUE +ossl_ts_resp_to_text(VALUE self) +{ + TS_RESP *resp; + BIO *out; + + GetTSResponse(self, resp); + + out = BIO_new(BIO_s_mem()); + if (!out) ossl_raise(eTimestampError, NULL); + + if (!TS_RESP_print_bio(out, resp)) { + BIO_free(out); + ossl_raise(eTimestampError, NULL); + } + + return ossl_membio2str(out); +} + /* * Verifies a timestamp token by checking the signature, validating the * certificate chain implied by tsa_certificate and by checking conformance to @@ -816,17 +864,14 @@ ossl_ts_resp_verify(int argc, VALUE *argv, VALUE self) X509_up_ref(cert); } - TS_VERIFY_CTS_set_certs(ctx, x509inter); + TS_VERIFY_CTX_set_certs(ctx, x509inter); TS_VERIFY_CTX_add_flags(ctx, TS_VFY_SIGNATURE); TS_VERIFY_CTX_set_store(ctx, x509st); ok = TS_RESP_verify_response(ctx, resp); - - /* WORKAROUND: - * X509_STORE can count references, but X509_STORE_free() doesn't check - * this. To prevent our X509_STORE from being freed with our - * TS_VERIFY_CTX we set the store to NULL first. - * Fixed in OpenSSL 1.0.2; bff9ce4db38b (master), 5b4b9ce976fc (1.0.2) + /* + * TS_VERIFY_CTX_set_store() call above does not increment the reference + * counter, so it must be unset before TS_VERIFY_CTX_free() is called. */ TS_VERIFY_CTX_set_store(ctx, NULL); TS_VERIFY_CTX_free(ctx); @@ -871,8 +916,10 @@ ossl_ts_token_info_initialize(VALUE self, VALUE der) in = ossl_obj2bio(&der); info = d2i_TS_TST_INFO_bio(in, &info); BIO_free(in); - if (!info) + if (!info) { + DATA_PTR(self) = NULL; ossl_raise(eTimestampError, "Error when decoding the timestamp token info"); + } DATA_PTR(self) = info; return self; @@ -1064,6 +1111,25 @@ ossl_ts_token_info_to_der(VALUE self) return asn1_to_der((void *)info, (int (*)(void *, unsigned char **))i2d_TS_TST_INFO); } +static VALUE +ossl_ts_token_info_to_text(VALUE self) +{ + TS_TST_INFO *info; + BIO *out; + + GetTSTokenInfo(self, info); + + out = BIO_new(BIO_s_mem()); + if (!out) ossl_raise(eTimestampError, NULL); + + if (!TS_TST_INFO_print_bio(out, info)) { + BIO_free(out); + ossl_raise(eTimestampError, NULL); + } + + return ossl_membio2str(out); +} + static ASN1_INTEGER * ossl_tsfac_serial_cb(struct TS_resp_ctx *ctx, void *data) { @@ -1074,13 +1140,29 @@ ossl_tsfac_serial_cb(struct TS_resp_ctx *ctx, void *data) } static int +#if !defined(LIBRESSL_VERSION_NUMBER) ossl_tsfac_time_cb(struct TS_resp_ctx *ctx, void *data, long *sec, long *usec) +#else +ossl_tsfac_time_cb(struct TS_resp_ctx *ctx, void *data, time_t *sec, long *usec) +#endif { *sec = *((long *)data); *usec = 0; return 1; } +static VALUE +ossl_evp_get_digestbyname_i(VALUE arg) +{ + return (VALUE)ossl_evp_get_digestbyname(arg); +} + +static VALUE +ossl_obj2bio_i(VALUE arg) +{ + return (VALUE)ossl_obj2bio((VALUE *)arg); +} + /* * Creates a Response with the help of an OpenSSL::PKey, an * OpenSSL::X509::Certificate and a Request. @@ -1149,7 +1231,7 @@ ossl_tsfac_create_ts(VALUE self, VALUE key, VALUE certificate, VALUE request) goto end; } if (!NIL_P(def_policy_id) && !TS_REQ_get_policy_id(req)) { - def_policy_id_obj = (ASN1_OBJECT*)rb_protect((VALUE (*)(VALUE))obj_to_asn1obj, (VALUE)def_policy_id, &status); + def_policy_id_obj = (ASN1_OBJECT*)rb_protect(obj_to_asn1obj_i, (VALUE)def_policy_id, &status); if (status) goto end; } @@ -1191,7 +1273,7 @@ ossl_tsfac_create_ts(VALUE self, VALUE key, VALUE certificate, VALUE request) for (i = 0; i < RARRAY_LEN(allowed_digests); i++) { rbmd = rb_ary_entry(allowed_digests, i); - md = (const EVP_MD *)rb_protect((VALUE (*)(VALUE))ossl_evp_get_digestbyname, rbmd, &status); + md = (const EVP_MD *)rb_protect(ossl_evp_get_digestbyname_i, rbmd, &status); if (status) goto end; TS_RESP_CTX_add_md(ctx, md); @@ -1202,7 +1284,7 @@ ossl_tsfac_create_ts(VALUE self, VALUE key, VALUE certificate, VALUE request) if (status) goto end; - req_bio = (BIO*)rb_protect((VALUE (*)(VALUE))ossl_obj2bio, (VALUE)&str, &status); + req_bio = (BIO*)rb_protect(ossl_obj2bio_i, (VALUE)&str, &status); if (status) goto end; @@ -1226,7 +1308,7 @@ end: ASN1_OBJECT_free(def_policy_id_obj); TS_RESP_CTX_free(ctx); if (err_msg) - ossl_raise(eTimestampError, err_msg); + rb_exc_raise(ossl_make_error(eTimestampError, rb_str_new_cstr(err_msg))); if (status) rb_jump_tag(status); return ret; @@ -1331,6 +1413,7 @@ Init_ossl_ts(void) rb_define_method(cTimestampResponse, "token_info", ossl_ts_resp_get_token_info, 0); rb_define_method(cTimestampResponse, "tsa_certificate", ossl_ts_resp_get_tsa_certificate, 0); rb_define_method(cTimestampResponse, "to_der", ossl_ts_resp_to_der, 0); + rb_define_method(cTimestampResponse, "to_text", ossl_ts_resp_to_text, 0); rb_define_method(cTimestampResponse, "verify", ossl_ts_resp_verify, -1); /* Document-class: OpenSSL::Timestamp::TokenInfo @@ -1349,6 +1432,7 @@ Init_ossl_ts(void) rb_define_method(cTimestampTokenInfo, "ordering", ossl_ts_token_info_get_ordering, 0); rb_define_method(cTimestampTokenInfo, "nonce", ossl_ts_token_info_get_nonce, 0); rb_define_method(cTimestampTokenInfo, "to_der", ossl_ts_token_info_to_der, 0); + rb_define_method(cTimestampTokenInfo, "to_text", ossl_ts_token_info_to_text, 0); /* Document-class: OpenSSL::Timestamp::Request * Allows to create timestamp requests or parse existing ones. A Request is @@ -1374,6 +1458,7 @@ Init_ossl_ts(void) rb_define_method(cTimestampRequest, "cert_requested=", ossl_ts_req_set_cert_requested, 1); rb_define_method(cTimestampRequest, "cert_requested?", ossl_ts_req_get_cert_requested, 0); rb_define_method(cTimestampRequest, "to_der", ossl_ts_req_to_der, 0); + rb_define_method(cTimestampRequest, "to_text", ossl_ts_req_to_text, 0); /* * Indicates a successful response. Equal to +0+. |