Формат OCSP-ответа

OCSP (Online Certificate Status Protocol) response представляет собой ASN.1-структуру, закодированную в DER, которая используется для проверки статуса X.509-сертификата в режиме реального времени. В контексте JavaScript-библиотеки jsrsasign работа с OCSP-ответами основана на разборе и генерации ASN.1-дерева, а также на интерпретации вложенных структур, описанных в RFC 6960.

На верхнем уровне OCSP-ответ описывается конструкцией:

  • OCSPResponse

    • responseStatus
    • responseBytes (опционально)
OCSPResponse ::= SEQUENCE {
   responseStatus         OCSPResponseStatus,
   responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL
}

responseStatus

Поле responseStatus определяет результат обработки OCSP-запроса сервером. Это целое значение ENUMERATED-типа:

  • successful (0) — успешный ответ
  • malformedRequest (1) — некорректный запрос
  • internalError (2) — внутренняя ошибка
  • tryLater (3) — повторить позже
  • sigRequired (5) — требуется подпись
  • unauthorized (6) — запрос не авторизован

В jsrsasign это поле извлекается через ASN.1-декодирование и интерпретируется как числовой статус до обработки основного ответа.

ResponseBytes и BasicOCSPResponse

Основная полезная информация содержится в responseBytes, внутри которого размещается структура BasicOCSPResponse.

ResponseBytes ::= SEQUENCE {
   responseType   OBJECT IDENTIFIER,
   response       OCTET STRING
}

Тип responseType почти всегда равен:

  • id-pkix-ocsp-basic (1.3.6.1.5.5.7.48.1.1)

response содержит DER-кодированный BasicOCSPResponse.

BasicOCSPResponse

BasicOCSPResponse ::= SEQUENCE {
   tbsResponseData      ResponseData,
   signatureAlgorithm   AlgorithmIdentifier,
   signature            BIT STRING,
   certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL
}

Эта структура является ядром OCSP-ответа и содержит как данные о статусе сертификата, так и цифровую подпись OCSP-ответчика.

ResponseData (TBS часть)

ResponseData — это подписываемая часть OCSP-ответа (To Be Signed).

ResponseData ::= SEQUENCE {
   version              [0] EXPLICIT Version DEFAULT v1,
   responderID          ResponderID,
   producedAt           GeneralizedTime,
   responses            SEQUENCE OF SingleResponse,
   responseExtensions   [1] EXPLICIT Extensions OPTIONAL
}

responderID

Определяет OCSP-ответчика:

  • по имени (Name)
  • или по ключевому хэшу (KeyHash)

В jsrsasign при разборе используется сопоставление с сертификатом OCSP-сервера, если он включён в ответ.

producedAt

Временная метка генерации OCSP-ответа. Используется для проверки актуальности ответа.

SingleResponse

Каждый проверяемый сертификат представлен структурой SingleResponse.

SingleResponse ::= SEQUENCE {
   certID                       CertID,
   certStatus                  CertStatus,
   thisUpdate                  GeneralizedTime,
   nextUpdate        [0]       EXPLICIT GeneralizedTime OPTIONAL,
   singleExtensions  [1]       EXPLICIT Extensions OPTIONAL
}

certID

Идентификатор сертификата формируется на основе:

  • хэш-алгоритма (SHA-1, SHA-256)
  • issuerNameHash
  • issuerKeyHash
  • serialNumber

В jsrsasign CertID сопоставляется с исходным сертификатом через вычисление хэшей издателя.

certStatus

Ключевое поле, определяющее статус сертификата:

CertStatus ::= CHOICE {
   good        [0] IMPLICIT NULL,
   revoked     [1] IMPLICIT RevokedInfo,
   unknown     [2] IMPLICIT UnknownInfo
}

good

Сертификат действителен, отзыв отсутствует.

revoked

Сертификат отозван:

RevokedInfo ::= SEQUENCE {
   revocationTime              GeneralizedTime,
   revocationReason   [0]      EXPLICIT CRLReason OPTIONAL
}

Поле revocationTime фиксирует момент отзыва, а CRLReason уточняет причину (keyCompromise, CACompromise и др.).

unknown

Статус неизвестен OCSP-ответчику.

thisUpdate и nextUpdate

  • thisUpdate — время актуальности текущего статуса
  • nextUpdate — предполагаемое время следующего обновления

Эти поля используются для контроля “свежести” OCSP-ответа.

Подпись OCSP-ответа

Подпись в BasicOCSPResponse гарантирует целостность данных.

signatureAlgorithm   AlgorithmIdentifier
signature            BIT STRING

Алгоритмы подписи включают:

  • SHA256withRSA
  • ECDSAwithSHA256
  • SHA1withRSA (устаревший)

В jsrsasign проверка подписи выполняется через сопоставление tbsResponseData и signature с использованием публичного ключа OCSP-ответчика.

Дополнительные сертификаты

Поле certs может содержать цепочку сертификатов OCSP-ответчика, необходимую для проверки подписи:

  • сертификат OCSP responder
  • промежуточные CA сертификаты

В jsrsasign эти данные используются для построения временной цепочки доверия.

ASN.1 представление и работа jsrsasign

В jsrsasign OCSP-ответ разбирается через ASN.1-парсеры:

  • ASN1HEX — низкоуровневый разбор DER-структур
  • X509 — работа с сертификатами
  • KJUR.asn1.ocsp — формирование и обработка OCSP-запросов и ответов

Типичный процесс декодирования включает:

  1. Разбор DER-ответа в ASN.1 дерево
  2. Извлечение OCSPResponse.responseStatus
  3. Декодирование responseBytes
  4. Разбор BasicOCSPResponse
  5. Извлечение ResponseData
  6. Анализ SingleResponse для каждого сертификата
  7. Проверка подписи OCSP-ответа

Форматирование статуса сертификата

В jsrsasign результат интерпретируется в удобную структуру:

  • status: good / revoked / unknown
  • thisUpdate
  • nextUpdate
  • revocationTime (если применимо)

Пример логической модели:

CertStatus:
  serialNumber
  status
  thisUpdate
  nextUpdate
  revocationTime (optional)

Особенности кодирования

OCSP полностью основан на DER-кодировании ASN.1:

  • строгая бинарная структура
  • фиксированные теги типов
  • обязательная последовательность SEQUENCE
  • контекстно-зависимые поля [0], [1]

Ошибки декодирования в jsrsasign чаще всего связаны с:

  • неполной цепочкой сертификатов
  • некорректным DER-пакетом
  • отсутствием responseBytes при error status
  • несовпадением алгоритма подписи

Связь OCSP с X.509 инфраструктурой

OCSP-ответ всегда привязан к:

  • issuer certificate
  • serial number проверяемого сертификата
  • алгоритму хэширования издателя

В jsrsasign это выражается через вычисление:

  • issuerNameHash = hash(DN издателя)
  • issuerKeyHash = hash(SubjectPublicKeyInfo издателя)

Эти значения должны совпадать между запросом и ответом, иначе CertID не считается валидным.

Интерпретация времени и актуальности

Поле времени в OCSP критично для доверия к ответу:

  • слишком старый thisUpdate делает ответ недействительным
  • отсутствие nextUpdate требует осторожной интерпретации
  • разница времени клиента и OCSP-сервера может приводить к ошибкам проверки

В jsrsasign часто применяется локальная валидация временных интервалов при интерпретации результата.

Внутренняя модель обработки OCSP в jsrsasign

Обобщённая логика:

  • получение DER-ответа
  • ASN.1 декодирование
  • проверка responseStatus
  • извлечение BasicOCSPResponse
  • верификация подписи
  • сопоставление CertID
  • интерпретация CertStatus
  • формирование итогового статуса сертификата