/* Copyright (c) 2018, Google Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <openssl/ssl.h> #include <openssl/bytestring.h> #include <openssl/err.h> #include "../crypto/internal.h" #include "internal.h" BSSL_NAMESPACE_BEGIN constexpr int kHandoffVersion = …; constexpr int kHandbackVersion = …; static const CBS_ASN1_TAG kHandoffTagALPS = …; // early_data_t represents the state of early data in a more compact way than // the 3 bits used by the implementation. enum early_data_t { … }; // serialize_features adds a description of features supported by this binary to // |out|. Returns true on success and false on error. static bool serialize_features(CBB *out) { … } bool SSL_serialize_handoff(const SSL *ssl, CBB *out, SSL_CLIENT_HELLO *out_hello) { … } bool SSL_decline_handoff(SSL *ssl) { … } // apply_remote_features reads a list of supported features from |in| and // (possibly) reconfigures |ssl| to disallow the negotation of features whose // support has not been indicated. (This prevents the the handshake from // committing to features that are not supported on the handoff/handback side.) static bool apply_remote_features(SSL *ssl, CBS *in) { … } // uses_disallowed_feature returns true iff |ssl| enables a feature that // disqualifies it for split handshakes. static bool uses_disallowed_feature(const SSL *ssl) { … } bool SSL_apply_handoff(SSL *ssl, Span<const uint8_t> handoff) { … } bool SSL_serialize_handback(const SSL *ssl, CBB *out) { … } static bool CopyExact(Span<uint8_t> out, const CBS *in) { … } bool SSL_apply_handback(SSL *ssl, Span<const uint8_t> handback) { … } BSSL_NAMESPACE_END usingnamespacebssl; int SSL_serialize_capabilities(const SSL *ssl, CBB *out) { … } int SSL_request_handshake_hints(SSL *ssl, const uint8_t *client_hello, size_t client_hello_len, const uint8_t *capabilities, size_t capabilities_len) { … } // |SSL_HANDSHAKE_HINTS| is serialized as the following ASN.1 structure. We use // implicit tagging to make it a little more compact. // // HandshakeHints ::= SEQUENCE { // serverRandomTLS13 [0] IMPLICIT OCTET STRING OPTIONAL, // keyShareHint [1] IMPLICIT KeyShareHint OPTIONAL, // signatureHint [2] IMPLICIT SignatureHint OPTIONAL, // -- At most one of decryptedPSKHint or ignorePSKHint may be present. It // -- corresponds to the first entry in pre_shared_keys. TLS 1.2 session // -- tickets use a separate hint, to ensure the caller does not apply the // -- hint to the wrong field. // decryptedPSKHint [3] IMPLICIT OCTET STRING OPTIONAL, // ignorePSKHint [4] IMPLICIT NULL OPTIONAL, // compressCertificateHint [5] IMPLICIT CompressCertificateHint OPTIONAL, // -- TLS 1.2 and 1.3 use different server random hints because one contains // -- a timestamp while the other doesn't. If the hint was generated // -- assuming TLS 1.3 but we actually negotiate TLS 1.2, mixing the two // -- will break this. // serverRandomTLS12 [6] IMPLICIT OCTET STRING OPTIONAL, // ecdheHint [7] IMPLICIT ECDHEHint OPTIONAL // -- At most one of decryptedTicketHint or ignoreTicketHint may be present. // -- renewTicketHint requires decryptedTicketHint. // decryptedTicketHint [8] IMPLICIT OCTET STRING OPTIONAL, // renewTicketHint [9] IMPLICIT NULL OPTIONAL, // ignoreTicketHint [10] IMPLICIT NULL OPTIONAL, // } // // KeyShareHint ::= SEQUENCE { // groupId INTEGER, // ciphertext OCTET STRING, // secret OCTET STRING, // } // // SignatureHint ::= SEQUENCE { // algorithm INTEGER, // input OCTET STRING, // subjectPublicKeyInfo OCTET STRING, // signature OCTET STRING, // } // // CompressCertificateHint ::= SEQUENCE { // algorithm INTEGER, // input OCTET STRING, // compressed OCTET STRING, // } // // ECDHEHint ::= SEQUENCE { // groupId INTEGER, // publicKey OCTET STRING, // privateKey OCTET STRING, // } // HandshakeHints tags. static const CBS_ASN1_TAG kServerRandomTLS13Tag = …; static const CBS_ASN1_TAG kKeyShareHintTag = …; static const CBS_ASN1_TAG kSignatureHintTag = …; static const CBS_ASN1_TAG kDecryptedPSKTag = …; static const CBS_ASN1_TAG kIgnorePSKTag = …; static const CBS_ASN1_TAG kCompressCertificateTag = …; static const CBS_ASN1_TAG kServerRandomTLS12Tag = …; static const CBS_ASN1_TAG kECDHEHintTag = …; static const CBS_ASN1_TAG kDecryptedTicketTag = …; static const CBS_ASN1_TAG kRenewTicketTag = …; static const CBS_ASN1_TAG kIgnoreTicketTag = …; int SSL_serialize_handshake_hints(const SSL *ssl, CBB *out) { … } static bool get_optional_implicit_null(CBS *cbs, bool *out_present, CBS_ASN1_TAG tag) { … } int SSL_set_handshake_hints(SSL *ssl, const uint8_t *hints, size_t hints_len) { … }