summaryrefslogtreecommitdiff
path: root/ext/openssl/ossl_ts.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/openssl/ossl_ts.c')
-rw-r--r--ext/openssl/ossl_ts.c121
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+.