123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- /*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
- #include "tls/extensions/s2n_cert_status.h"
- #include "tls/s2n_config.h"
- #include "tls/s2n_connection.h"
- #include "tls/s2n_tls.h"
- #include "tls/s2n_x509_validator.h"
- #include "utils/s2n_safety.h"
- #define U24_SIZE 3
- static bool s2n_cert_status_should_send(struct s2n_connection *conn);
- /*
- * The cert_status extension is sent in response to OCSP status requests in TLS 1.3. The
- * OCSP response is contained in the extension data. In TLS 1.2, the cert_status_response
- * extension is sent instead, indicating that the OCSP response will be sent in a
- * Certificate Status handshake message.
- */
- const s2n_extension_type s2n_cert_status_extension = {
- .iana_value = TLS_EXTENSION_STATUS_REQUEST,
- .is_response = true,
- .send = s2n_cert_status_send,
- .recv = s2n_cert_status_recv,
- .should_send = s2n_cert_status_should_send,
- .if_missing = s2n_extension_noop_if_missing,
- };
- static bool s2n_cert_status_should_send(struct s2n_connection *conn)
- {
- return conn->handshake_params.our_chain_and_key
- && conn->handshake_params.our_chain_and_key->ocsp_status.size > 0;
- }
- int s2n_cert_status_send(struct s2n_connection *conn, struct s2n_stuffer *out)
- {
- POSIX_ENSURE_REF(conn);
- struct s2n_blob *ocsp_status = &conn->handshake_params.our_chain_and_key->ocsp_status;
- POSIX_ENSURE_REF(ocsp_status);
- POSIX_GUARD(s2n_stuffer_write_uint8(out, (uint8_t) S2N_STATUS_REQUEST_OCSP));
- POSIX_GUARD(s2n_stuffer_write_uint24(out, ocsp_status->size));
- POSIX_GUARD(s2n_stuffer_write(out, ocsp_status));
- return S2N_SUCCESS;
- }
- int s2n_cert_status_recv(struct s2n_connection *conn, struct s2n_stuffer *in)
- {
- POSIX_ENSURE_REF(conn);
- /**
- *= https://tools.ietf.org/rfc/rfc6066#section-8
- *# struct {
- *# CertificateStatusType status_type;
- *# select (status_type) {
- *# case ocsp: OCSPResponse;
- *# } response;
- *# } CertificateStatus;
- *#
- *# opaque OCSPResponse<1..2^24-1>;
- *#
- *# An "ocsp_response" contains a complete, DER-encoded OCSP response
- *# (using the ASN.1 type OCSPResponse defined in [RFC2560]). Only one
- *# OCSP response may be sent.
- **/
- uint8_t type;
- POSIX_GUARD(s2n_stuffer_read_uint8(in, &type));
- if (type != S2N_STATUS_REQUEST_OCSP) {
- /* We only support OCSP */
- return S2N_SUCCESS;
- }
- /* The status_type variable is only used when a client requests OCSP stapling from a
- * server. A server can request OCSP stapling from a client, but it is not tracked
- * with this variable.
- */
- if (conn->mode == S2N_CLIENT) {
- conn->status_type = S2N_STATUS_REQUEST_OCSP;
- }
- uint32_t status_size;
- POSIX_GUARD(s2n_stuffer_read_uint24(in, &status_size));
- POSIX_ENSURE_LTE(status_size, s2n_stuffer_data_available(in));
- POSIX_GUARD(s2n_realloc(&conn->status_response, status_size));
- POSIX_GUARD(s2n_stuffer_read_bytes(in, conn->status_response.data, status_size));
- POSIX_GUARD_RESULT(s2n_x509_validator_validate_cert_stapled_ocsp_response(&conn->x509_validator, conn,
- conn->status_response.data, conn->status_response.size));
- return S2N_SUCCESS;
- }
|