Spec-Zone.ru › Ruby 3.1

класс OpenSSL::Timestamp::Response

Родитель:
Объект

Неизменяемое и только для чтения представление ответа о времени, возвращаемого сервером времени после получения связанного Request. Позволяет получить доступ к определенной информации об ответе, а также позволяет проверить Response.

Константы

GRANTED

Указывает на успешный ответ. Равно 0.

GRANTED_WITH_MODS

Указывает на успешный ответ, который, вероятно, содержит изменения от исходного запроса. Равно 1.

REJECTION

Указывает на ошибку. Жетоны времени не созданы. Равно 2.

REVOCATION_NOTIFICATION

Указывает на ошибку. Жетоны времени не созданы. Сертификат отозван. Равно 5.

REVOCATION_WARNING

Указывает на ошибку. Жетоны времени не созданы. Отозывание сертификата ожидается. Равно 4.

WAITING

Указывает на ошибку. Жетоны времени не созданы. Равно 3.

Общедоступные методы класса

OpenSSL::Timestamp::Response.new(file) → response Показать исходный код
OpenSSL::Timestamp::Response.new(string) → response
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;
}

Создает Response из File или string параметра, соответствующие File или string должны быть закодированы в DER. Обратите внимание, что Response — неизменяемый класс только для чтения. Если вы хотите создать метки времени, обратитесь к Factory вместо этого.

Общедоступные методы экземпляра

failure_info → nil или символ Показать исходный код
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.");
}

В случае отсутствия токена времени это поле содержит дополнительную информацию о причине неудачи создания ответа. Метод возвращает либо nil (запрос был успешным и токен времени был создан), либо одно из следующих значений:

  • :BAD_ALG - Указывает, что сервер времени отказывается от алгоритма отпечатков сообщений, используемого в Request

  • :BAD_REQUEST - Указывает, что сервер времени не смог обработать Request должным образом

  • :BAD_DATA_FORMAT - Указывает, что сервер времени не смог разобрать определенные данные в Request

  • :TIME_NOT_AVAILABLE - Указывает, что сервер не смог получить доступ к источнику времени

  • :UNACCEPTED_POLICY - Указывает, что идентификатор запрошенной политики не распознан или не поддерживается сервером времени

  • :UNACCEPTED_EXTENSIION - Указывает, что расширение в Request не поддерживается сервером времени

  • :ADD_INFO_NOT_AVAILABLE - Указывает, что запрашиваемая дополнительная информация либо не понята, либо в настоящее время недоступна

  • :SYSTEM_FAILURE - Создание Timestamp не удалось из-за внутренней ошибки, произошедшей на сервере времени

status → BN (никогда не nil) Показать исходный код
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);
}

Возвращает одно из значений GRANTED, GRANTED_WITH_MODS, REJECTION, WAITING, REVOCATION_WARNING или REVOCATION_NOTIFICATION. Токен времени был создан только в том случае, если status равно GRANTED или GRANTED_WITH_MODS.

status_text → Массив строк или nil Показать исходный код
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 → строка Показать исходный код
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);
}

Возвращает Response в кодировке DER.

token → nil или OpenSSL::PKCS7 Показать исходный код
static VALUE
ossl_ts_resp_get_token(VALUE self)
{
    TS_RESP *resp;
    PKCS7 *p7, *copy;
    VALUE obj;

    GetTSResponse(self, resp);
    if (!(p7 = TS_RESP_get_token(resp)))
        return Qnil;

    obj = NewPKCS7(cPKCS7);

    if (!(copy = PKCS7_dup(p7)))
        ossl_raise(eTimestampError, NULL);

    SetPKCS7(obj, copy);

    return obj;
}

Если токен времени присутствует, он возвращается в виде OpenSSL::PKCS7.

token_info → nil или OpenSSL::Timestamp::TokenInfo Показать исходный код
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 → OpenSSL::X509::Certificate или nil Показать исходный код
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);
}

Если в Request был указан запрос на сертификат ЦА (Request#cert_requested = true), то это поле содержит сертификат центра сертификации.

verify(Request, root_store) → Response Показать исходный код
verify(Request, root_store, [intermediate_cert]) → Response
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;
}

Проверяет токен времени, проверяя подпись, проверяя цепочку сертификатов, подразумеваемую tsa_certificate, и проверяя соответствие заданному Request. Обязательными параметрами являются связанный с этим Request Response и хранилище доверенных корневых сертификатов.

Дополнительные промежуточные сертификаты могут быть предоставлены для создания цепочки сертификатов. Эти промежуточные сертификаты должны быть экземплярами OpenSSL::X509::Certificate.

Если проверка не пройдена, могут быть подняты несколько типов исключений:

  • TypeError, если типы не соответствуют

  • TimestampError, если что-то не так с самим токеном времени, если он не соответствует Request, или если проверка цепочки сертификатов токена времени не проходит.

Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API