Class: OpenSSL::Timestamp::Response
- Inherits:
-
Object
- Object
- OpenSSL::Timestamp::Response
- Defined in:
- ossl_ts.c,
ossl_ts.c
Overview
Immutable and read-only representation of a timestamp response returned from a timestamp server after receiving an associated Request. Allows access to specific information about the response but also allows to verify the Response.
Constant Summary collapse
- GRANTED =
Indicates a successful response. Equal to
0
. INT2NUM(TS_STATUS_GRANTED)
- GRANTED_WITH_MODS =
Indicates a successful response that probably contains modifications from the initial request. Equal to
1
. INT2NUM(TS_STATUS_GRANTED_WITH_MODS)
- REJECTION =
Indicates a failure. No timestamp token was created. Equal to
2
. INT2NUM(TS_STATUS_REJECTION)
- WAITING =
Indicates a failure. No timestamp token was created. Equal to
3
. INT2NUM(TS_STATUS_WAITING)
- REVOCATION_WARNING =
Indicates a failure. No timestamp token was created. Revocation of a certificate is imminent. Equal to
4
. INT2NUM(TS_STATUS_REVOCATION_WARNING)
- REVOCATION_NOTIFICATION =
Indicates a failure. No timestamp token was created. A certificate has been revoked. Equal to
5
. INT2NUM(TS_STATUS_REVOCATION_NOTIFICATION)
Instance Method Summary collapse
-
#failure_info ⇒ Object
In cases no timestamp token has been created, this field contains further info about the reason why response creation failed.
-
#initialize(der) ⇒ Object
constructor
Creates a Response from a
File
orstring
parameter, the correspondingFile
orstring
must be DER-encoded. -
#status ⇒ Object
Returns one of GRANTED, GRANTED_WITH_MODS, REJECTION, WAITING, REVOCATION_WARNING or REVOCATION_NOTIFICATION.
-
#status_text ⇒ Object
In cases of failure this field may contain an array of strings further describing the origin of the failure.
-
#to_der ⇒ Object
Returns the Response in DER-encoded form.
- #to_text ⇒ Object
-
#token ⇒ Object
If a timestamp token is present, this returns it in the form of a OpenSSL::PKCS7.
-
#token_info ⇒ Object
Get the response’s token info if present.
-
#tsa_certificate ⇒ Object
If the Request specified to request the TSA certificate (Request#cert_requested = true), then this field contains the certificate of the timestamp authority.
-
#verify(*args) ⇒ Object
Verifies a timestamp token by checking the signature, validating the certificate chain implied by tsa_certificate and by checking conformance to a given Request.
Constructor Details
#initialize(der) ⇒ Object
Creates a Response from a File
or string
parameter, the corresponding File
or string
must be DER-encoded. Please note that Response is an immutable read-only class. If you’d like to create timestamps please refer to Factory instead.
call-seq:
OpenSSL::Timestamp::Response.new(file) -> response
OpenSSL::Timestamp::Response.new(string) -> response
552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 |
# File 'ossl_ts.c', line 552
static VALUE
ossl_ts_resp_initialize(VALUE self, VALUE der)
{
TS_RESP *ts_resp = DATA_PTR(self);
BIO *in;
der = ossl_to_der_if_possible(der);
in = ossl_obj2bio(&der);
ts_resp = d2i_TS_RESP_bio(in, &ts_resp);
BIO_free(in);
if (!ts_resp) {
DATA_PTR(self) = NULL;
ossl_raise(eTimestampError, "Error when decoding the timestamp response");
}
DATA_PTR(self) = ts_resp;
return self;
}
|
Instance Method Details
#failure_info ⇒ Object
In cases no timestamp token has been created, this field contains further info about the reason why response creation failed. The method returns either nil (the request was successful and a timestamp token was created) or one of the following:
-
:BAD_ALG - Indicates that the timestamp server rejects the message imprint algorithm used in the Request
-
:BAD_REQUEST - Indicates that the timestamp server was not able to process the Request properly
-
:BAD_DATA_FORMAT - Indicates that the timestamp server was not able to parse certain data in the Request
-
:TIME_NOT_AVAILABLE - Indicates that the server could not access its time source
-
:UNACCEPTED_POLICY - Indicates that the requested policy identifier is not recognized or supported by the timestamp server
-
:UNACCEPTED_EXTENSIION - Indicates that an extension in the Request is not supported by the timestamp server
-
:ADD_INFO_NOT_AVAILABLE -Indicates that additional information requested is either not understood or currently not available
-
:SYSTEM_FAILURE - Timestamp creation failed due to an internal error that occurred on the timestamp server
call-seq:
response.failure_info -> nil or symbol
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 |
# File 'ossl_ts.c', line 618
static VALUE
ossl_ts_resp_get_failure_info(VALUE self)
{
TS_RESP *resp;
TS_STATUS_INFO *si;
/* The ASN1_BIT_STRING_get_bit changed from 1.0.0. to 1.1.0, making this
* const. */
#if defined(HAVE_TS_STATUS_INFO_GET0_FAILURE_INFO)
const ASN1_BIT_STRING *fi;
#else
ASN1_BIT_STRING *fi;
#endif
GetTSResponse(self, resp);
si = TS_RESP_get_status_info(resp);
fi = TS_STATUS_INFO_get0_failure_info(si);
if (!fi)
return Qnil;
if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_BAD_ALG))
return sBAD_ALG;
if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_BAD_REQUEST))
return sBAD_REQUEST;
if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_BAD_DATA_FORMAT))
return sBAD_DATA_FORMAT;
if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_TIME_NOT_AVAILABLE))
return sTIME_NOT_AVAILABLE;
if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_UNACCEPTED_POLICY))
return sUNACCEPTED_POLICY;
if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_UNACCEPTED_EXTENSION))
return sUNACCEPTED_EXTENSION;
if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_ADD_INFO_NOT_AVAILABLE))
return sADD_INFO_NOT_AVAILABLE;
if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_SYSTEM_FAILURE))
return sSYSTEM_FAILURE;
ossl_raise(eTimestampError, "Unrecognized failure info.");
}
|
#status ⇒ Object
Returns one of GRANTED, GRANTED_WITH_MODS, REJECTION, WAITING, REVOCATION_WARNING or REVOCATION_NOTIFICATION. A timestamp token has been created only in case status
is equal to GRANTED or GRANTED_WITH_MODS.
call-seq:
response.status -> BN (never nil)
579 580 581 582 583 584 585 586 587 588 589 590 591 |
# File 'ossl_ts.c', line 579
static VALUE
ossl_ts_resp_get_status(VALUE self)
{
TS_RESP *resp;
TS_STATUS_INFO *si;
const ASN1_INTEGER *st;
GetTSResponse(self, resp);
si = TS_RESP_get_status_info(resp);
st = TS_STATUS_INFO_get0_status(si);
return asn1integer_to_num(st);
}
|
#status_text ⇒ Object
In cases of failure this field may contain an array of strings further describing the origin of the failure.
call-seq:
response.status_text -> Array of strings or nil
664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 |
# File 'ossl_ts.c', line 664
static VALUE
ossl_ts_resp_get_status_text(VALUE self)
{
TS_RESP *resp;
TS_STATUS_INFO *si;
const STACK_OF(ASN1_UTF8STRING) *text;
ASN1_UTF8STRING *current;
int i;
VALUE ret = rb_ary_new();
GetTSResponse(self, resp);
si = TS_RESP_get_status_info(resp);
if ((text = TS_STATUS_INFO_get0_text(si))) {
for (i = 0; i < sk_ASN1_UTF8STRING_num(text); i++) {
current = sk_ASN1_UTF8STRING_value(text, i);
rb_ary_push(ret, asn1str_to_str(current));
}
}
return ret;
}
|
#to_der ⇒ Object
Returns the Response in DER-encoded form.
call-seq:
response.to_der -> string
764 765 766 767 768 769 770 771 |
# File 'ossl_ts.c', line 764
static VALUE
ossl_ts_resp_to_der(VALUE self)
{
TS_RESP *resp;
GetTSResponse(self, resp);
return asn1_to_der((void *)resp, (int (*)(void *, unsigned char **))i2d_TS_RESP);
}
|
#to_text ⇒ Object
773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 |
# File 'ossl_ts.c', line 773
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);
}
|
#token ⇒ Object
If a timestamp token is present, this returns it in the form of a OpenSSL::PKCS7.
call-seq:
response.token -> nil or OpenSSL::PKCS7
693 694 695 696 697 698 699 700 701 702 703 |
# File 'ossl_ts.c', line 693
static VALUE
ossl_ts_resp_get_token(VALUE self)
{
TS_RESP *resp;
PKCS7 *p7;
GetTSResponse(self, resp);
if (!(p7 = TS_RESP_get_token(resp)))
return Qnil;
return ossl_pkcs7_new(p7);
}
|
#token_info ⇒ Object
Get the response’s token info if present.
call-seq:
response.token_info -> nil or OpenSSL::Timestamp::TokenInfo
711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 |
# File 'ossl_ts.c', line 711
static VALUE
ossl_ts_resp_get_token_info(VALUE self)
{
TS_RESP *resp;
TS_TST_INFO *info, *copy;
VALUE obj;
GetTSResponse(self, resp);
if (!(info = TS_RESP_get_tst_info(resp)))
return Qnil;
obj = NewTSTokenInfo(cTimestampTokenInfo);
if (!(copy = TS_TST_INFO_dup(info)))
ossl_raise(eTimestampError, NULL);
SetTSTokenInfo(obj, copy);
return obj;
}
|
#tsa_certificate ⇒ Object
If the Request specified to request the TSA certificate (Request#cert_requested = true), then this field contains the certificate of the timestamp authority.
call-seq:
response.tsa_certificate -> OpenSSL::X509::Certificate or nil
740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 |
# File 'ossl_ts.c', line 740
static VALUE
ossl_ts_resp_get_tsa_certificate(VALUE self)
{
TS_RESP *resp;
PKCS7 *p7;
PKCS7_SIGNER_INFO *ts_info;
X509 *cert;
GetTSResponse(self, resp);
if (!(p7 = TS_RESP_get_token(resp)))
return Qnil;
ts_info = sk_PKCS7_SIGNER_INFO_value(p7->d.sign->signer_info, 0);
cert = PKCS7_cert_from_signer_info(p7, ts_info);
if (!cert)
return Qnil;
return ossl_x509_new(cert);
}
|
#verify(*args) ⇒ Object
Verifies a timestamp token by checking the signature, validating the certificate chain implied by tsa_certificate and by checking conformance to a given Request. Mandatory parameters are the Request associated to this Response, and an OpenSSL::X509::Store of trusted roots.
Intermediate certificates can optionally be supplied for creating the certificate chain. These intermediate certificates must all be instances of OpenSSL::X509::Certificate.
If validation fails, several kinds of exceptions can be raised:
-
TypeError if types don’t fit
-
TimestampError if something is wrong with the timestamp token itself, if it is not conformant to the Request, or if validation of the timestamp certificate chain fails.
call-seq:
response.verify(Request, root_store) -> Response
response.verify(Request, root_store, [intermediate_cert]) -> Response
812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 |
# File 'ossl_ts.c', line 812
static VALUE
ossl_ts_resp_verify(int argc, VALUE *argv, VALUE self)
{
VALUE ts_req, store, intermediates;
TS_RESP *resp;
TS_REQ *req;
X509_STORE *x509st;
TS_VERIFY_CTX *ctx;
STACK_OF(X509) *x509inter = NULL;
PKCS7* p7;
X509 *cert;
int status, i, ok;
rb_scan_args(argc, argv, "21", &ts_req, &store, &intermediates);
GetTSResponse(self, resp);
GetTSRequest(ts_req, req);
x509st = GetX509StorePtr(store);
if (!(ctx = TS_REQ_to_TS_VERIFY_CTX(req, NULL))) {
ossl_raise(eTimestampError, "Error when creating the verification context.");
}
if (!NIL_P(intermediates)) {
x509inter = ossl_protect_x509_ary2sk(intermediates, &status);
if (status) {
TS_VERIFY_CTX_free(ctx);
rb_jump_tag(status);
}
} else if (!(x509inter = sk_X509_new_null())) {
TS_VERIFY_CTX_free(ctx);
ossl_raise(eTimestampError, "sk_X509_new_null");
}
if (!(p7 = TS_RESP_get_token(resp))) {
TS_VERIFY_CTX_free(ctx);
sk_X509_pop_free(x509inter, X509_free);
ossl_raise(eTimestampError, "TS_RESP_get_token");
}
for (i=0; i < sk_X509_num(p7->d.sign->cert); i++) {
cert = sk_X509_value(p7->d.sign->cert, i);
if (!sk_X509_push(x509inter, cert)) {
sk_X509_pop_free(x509inter, X509_free);
TS_VERIFY_CTX_free(ctx);
ossl_raise(eTimestampError, "sk_X509_push");
}
X509_up_ref(cert);
}
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);
/*
* 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);
if (!ok)
ossl_raise(eTimestampError, "TS_RESP_verify_response");
return self;
}
|