Added ALPN support (client and server).
authorThomas Pornin <pornin@bolet.org>
Wed, 28 Dec 2016 13:11:51 +0000 (14:11 +0100)
committerThomas Pornin <pornin@bolet.org>
Wed, 28 Dec 2016 13:11:51 +0000 (14:11 +0100)
inc/bearssl_ssl.h
src/ssl/ssl_hs_client.c
src/ssl/ssl_hs_client.t0
src/ssl/ssl_hs_common.t0
src/ssl/ssl_hs_server.c
src/ssl/ssl_hs_server.t0
tools/client.c
tools/server.c
tools/sslio.c

index 9e45514..5ea257f 100644 (file)
@@ -946,6 +946,27 @@ typedef struct {
        size_t cert_len;
 
        /*
+        * List of supported protocol names (ALPN extension). If unset,
+        * (number of names is 0), then:
+        *  - the client sends no ALPN extension;
+        *  - the server ignores any incoming ALPN extension.
+        *
+        * Otherwise:
+        *  - the client sends an ALPN extension with all the names;
+        *  - the server selects the first protocol in its list that
+        *    the client also supports, or fails (fatal alert 120)
+        *    if the client sends an ALPN extension and there is no
+        *    match.
+        *
+        * The 'selected_protocol' field contains 1+n if the matching
+        * name has index n in the list (the value is 0 if no match was
+        * performed, e.g. the peer did not send an ALPN extension).
+        */
+       const char **protocol_names;
+       uint16_t protocol_names_num;
+       uint16_t selected_protocol;
+
+       /*
         * Pointers to implementations; left to NULL for unsupported
         * functions. For the raw hash functions, implementations are
         * referenced from the multihasher (mhash field).
@@ -1065,6 +1086,32 @@ br_ssl_engine_remove_flags(br_ssl_engine_context *cc, uint32_t flags)
 #define BR_OPT_TOLERATE_NO_CLIENT_AUTH         ((uint32_t)1 << 2)
 
 /**
+ * \brief Behavioural flag: fail on application protocol mismatch.
+ *
+ * The ALPN extension ([RFC 7301](https://tools.ietf.org/html/rfc7301))
+ * allows the client to send a list of application protocol names, and
+ * the server to select one. A mismatch is one of the following occurrences:
+ *
+ *   - On the client: the client sends a list of names, the server
+ *     responds with a protocol name which is _not_ part of the list of
+ *     names sent by the client.
+ *
+ *   - On the server: the client sends a list of names, and the server
+ *     is also configured with a list of names, but there is no common
+ *     protocol name between the two lists.
+ *
+ * Normal behaviour in case of mismatch is to report no matching name
+ * (`br_ssl_engine_get_selected_protocol()` returns `NULL`) and carry on.
+ * If the flag is set, then a mismatch implies a protocol failure (if
+ * the mismatch is detected by the server, it will send a fatal alert).
+ *
+ * Note: even with this flag, `br_ssl_engine_get_selected_protocol()`
+ * may still return `NULL` if the client or the server does not send an
+ * ALPN extension at all.
+ */
+#define BR_OPT_FAIL_ON_ALPN_MISMATCH           ((uint32_t)1 << 3)
+
+/**
  * \brief Set the minimum and maximum supported protocol versions.
  *
  * The two provided versions MUST be supported by the implementation
@@ -1120,6 +1167,65 @@ br_ssl_engine_set_x509(br_ssl_engine_context *cc, const br_x509_class **x509ctx)
 }
 
 /**
+ * \brief Set the supported protocol names.
+ *
+ * Protocol names are part of the ALPN extension ([RFC
+ * 7301](https://tools.ietf.org/html/rfc7301)). Each protocol name is a
+ * character string, containing no more than 255 characters (256 with the
+ * terminating zero). When names are set, then:
+ *
+ *   - The client will send an ALPN extension, containing the names. If
+ *     the server responds with an ALPN extension, the client will verify
+ *     that the response contains one of its name, and report that name
+ *     through `br_ssl_engine_get_selected_protocol()`.
+ *
+ *   - The server will parse incoming ALPN extension (from clients), and
+ *     try to find a common protocol; if none is found, the connection
+ *     is aborted with a fatal alert. On match, a response ALPN extension
+ *     is sent, and name is reported through
+ *     `br_ssl_engine_get_selected_protocol()`.
+ *
+ * The provided array is linked in, and must remain valid while the
+ * connection is live.
+ *
+ * Names MUST NOT be empty. Names MUST NOT be longer than 255 characters
+ * (excluding the terminating 0).
+ *
+ * \param ctx     SSL engine context.
+ * \param names   list of protocol names (zero-terminated).
+ * \param num     number of protocol names (MUST be 1 or more).
+ */
+static inline void
+br_ssl_engine_set_protocol_names(br_ssl_engine_context *ctx,
+       const char **names, size_t num)
+{
+       ctx->protocol_names = names;
+       ctx->protocol_names_num = num;
+}
+
+/**
+ * \brief Get the selected protocol.
+ *
+ * If this context was initialised with a non-empty list of protocol
+ * names, and both client and server sent ALPN extensions during the
+ * handshake, and a common name was found, then that name is returned.
+ * Otherwise, `NULL` is returned.
+ *
+ * The returned pointer is one of the pointers provided to the context
+ * with `br_ssl_engine_set_protocol_names()`.
+ *
+ * \return  the selected protocol, or `NULL`.
+ */
+static inline const char *
+br_ssl_engine_get_selected_protocol(br_ssl_engine_context *ctx)
+{
+       unsigned k;
+
+       k = ctx->selected_protocol;
+       return (k == 0 || k == 0xFFFF) ? NULL : ctx->protocol_names[k - 1];
+}
+
+/**
  * \brief Set a hash function implementation (by ID).
  *
  * Hash functions set with this call will be used for SSL/TLS specific
@@ -3727,5 +3833,6 @@ int br_sslio_close(br_sslio_context *cc);
 #define BR_ALERT_USER_CANCELED              90
 #define BR_ALERT_NO_RENEGOTIATION          100
 #define BR_ALERT_UNSUPPORTED_EXTENSION     110
+#define BR_ALERT_NO_APPLICATION_PROTOCOL   120
 
 #endif
index 0901441..393badf 100644 (file)
@@ -438,7 +438,7 @@ static const uint8_t t0_codeblock[] = {
        0x00, 0x01, 0x00, 0x0A, 0x00, 0x00, 0x01, 0x00, 0x0D, 0x00, 0x00, 0x01,
        0x00, 0x0E, 0x00, 0x00, 0x01, 0x00, 0x0F, 0x00, 0x00, 0x01, 0x01, 0x08,
        0x00, 0x00, 0x01, 0x01, 0x09, 0x00, 0x00, 0x01, 0x02, 0x08, 0x00, 0x00,
-       0x01, 0x02, 0x09, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x01,
+       0x01, 0x02, 0x09, 0x00, 0x00, 0x25, 0x25, 0x00, 0x00, 0x01,
        T0_INT1(BR_ERR_BAD_CCS), 0x00, 0x00, 0x01,
        T0_INT1(BR_ERR_BAD_CIPHER_SUITE), 0x00, 0x00, 0x01,
        T0_INT1(BR_ERR_BAD_COMPRESSION), 0x00, 0x00, 0x01,
@@ -477,14 +477,18 @@ static const uint8_t t0_codeblock[] = {
        0x00, 0x00, 0x01,
        T0_INT2(offsetof(br_ssl_client_context, min_clienthello_len)), 0x00,
        0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, pad)), 0x00, 0x00,
-       0x01, T0_INT2(offsetof(br_ssl_engine_context, record_type_in)), 0x00,
-       0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, record_type_out)),
-       0x00, 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, reneg)),
+       0x01, T0_INT2(offsetof(br_ssl_engine_context, protocol_names_num)),
        0x00, 0x00, 0x01,
-       T0_INT2(offsetof(br_ssl_engine_context, saved_finished)), 0x00, 0x00,
-       0x01, T0_INT2(offsetof(br_ssl_engine_context, server_name)), 0x00,
-       0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, server_random)),
+       T0_INT2(offsetof(br_ssl_engine_context, record_type_in)), 0x00, 0x00,
+       0x01, T0_INT2(offsetof(br_ssl_engine_context, record_type_out)), 0x00,
+       0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, reneg)), 0x00,
+       0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, saved_finished)),
        0x00, 0x00, 0x01,
+       T0_INT2(offsetof(br_ssl_engine_context, selected_protocol)), 0x00,
+       0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, server_name)),
+       0x00, 0x00, 0x01,
+       T0_INT2(offsetof(br_ssl_engine_context, server_random)), 0x00, 0x00,
+       0x01,
        T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, session_id)),
        0x00, 0x00, 0x01,
        T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, session_id_len)),
@@ -499,237 +503,245 @@ static const uint8_t t0_codeblock[] = {
        T0_INT2(offsetof(br_ssl_engine_context, version_max)), 0x00, 0x00,
        0x01, T0_INT2(offsetof(br_ssl_engine_context, version_min)), 0x00,
        0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, version_out)),
-       0x00, 0x00, 0x09, 0x25, 0x52, 0x06, 0x02, 0x62, 0x26, 0x00, 0x00, 0x06,
-       0x08, 0x2A, 0x0E, 0x05, 0x02, 0x6B, 0x26, 0x04, 0x01, 0x3A, 0x00, 0x00,
-       0x01, 0x01, 0x00, 0x01, 0x03, 0x00, 0x91, 0x25, 0x58, 0x41, 0x95, 0x25,
-       0x05, 0x04, 0x5A, 0x01, 0x00, 0x00, 0x02, 0x00, 0x0E, 0x06, 0x02, 0x95,
-       0x00, 0x58, 0x04, 0x6B, 0x00, 0x06, 0x02, 0x62, 0x26, 0x00, 0x00, 0x25,
-       0x82, 0x41, 0x05, 0x03, 0x01, 0x0C, 0x08, 0x41, 0x73, 0x2A, 0xA3, 0x1C,
-       0x7E, 0x01, 0x0C, 0x2F, 0x00, 0x00, 0x25, 0x1E, 0x01, 0x08, 0x0B, 0x41,
-       0x56, 0x1E, 0x08, 0x00, 0x01, 0x03, 0x00, 0x01, 0x00, 0x71, 0x3B, 0x27,
-       0x1A, 0x34, 0x06, 0x07, 0x02, 0x00, 0xC5, 0x03, 0x00, 0x04, 0x75, 0x01,
-       0x00, 0xBC, 0x02, 0x00, 0x25, 0x1A, 0x17, 0x06, 0x02, 0x69, 0x26, 0xC5,
-       0x04, 0x76, 0x01, 0x01, 0x00, 0x71, 0x3B, 0x01, 0x16, 0x80, 0x3B, 0x32,
-       0xCB, 0x27, 0xAB, 0x06, 0x09, 0x01, 0x7F, 0xA6, 0x01, 0x7F, 0xC8, 0x04,
-       0x80, 0x53, 0xA8, 0x73, 0x2A, 0x99, 0x01, T0_INT1(BR_KEYTYPE_SIGN),
-       0x17, 0x06, 0x01, 0xAC, 0xAF, 0x25, 0x01, 0x0D, 0x0E, 0x06, 0x07, 0x24,
-       0xAE, 0xAF, 0x01, 0x7F, 0x04, 0x02, 0x01, 0x00, 0x03, 0x00, 0x01, 0x0E,
-       0x0E, 0x05, 0x02, 0x6C, 0x26, 0x06, 0x02, 0x61, 0x26, 0x31, 0x06, 0x02,
-       0x6C, 0x26, 0x02, 0x00, 0x06, 0x1C, 0xC9, 0x7A, 0x2C, 0x01, 0x81, 0x7F,
-       0x0E, 0x06, 0x0D, 0x24, 0x01, 0x10, 0xD4, 0x01, 0x00, 0xD3, 0x73, 0x2A,
-       0xA3, 0x23, 0x04, 0x04, 0xCC, 0x06, 0x01, 0xCA, 0x04, 0x01, 0xCC, 0x01,
-       0x7F, 0xC8, 0x01, 0x7F, 0xA6, 0x01, 0x01, 0x71, 0x3B, 0x01, 0x17, 0x80,
-       0x3B, 0x00, 0x00, 0x36, 0x36, 0x00, 0x00, 0x92, 0x01, 0x0C, 0x11, 0x01,
-       0x00, 0x36, 0x0E, 0x06, 0x05, 0x24, 0x01,
+       0x00, 0x00, 0x09, 0x26, 0x55, 0x06, 0x02, 0x65, 0x28, 0x00, 0x00, 0x06,
+       0x08, 0x2C, 0x0E, 0x05, 0x02, 0x6E, 0x28, 0x04, 0x01, 0x3C, 0x00, 0x00,
+       0x01, 0x01, 0x00, 0x01, 0x03, 0x00, 0x96, 0x26, 0x5B, 0x43, 0x9A, 0x26,
+       0x05, 0x04, 0x5D, 0x01, 0x00, 0x00, 0x02, 0x00, 0x0E, 0x06, 0x02, 0x9A,
+       0x00, 0x5B, 0x04, 0x6B, 0x00, 0x06, 0x02, 0x65, 0x28, 0x00, 0x00, 0x26,
+       0x86, 0x43, 0x05, 0x03, 0x01, 0x0C, 0x08, 0x43, 0x76, 0x2C, 0xA8, 0x1C,
+       0x81, 0x01, 0x0C, 0x31, 0x00, 0x00, 0x26, 0x1F, 0x01, 0x08, 0x0B, 0x43,
+       0x59, 0x1F, 0x08, 0x00, 0x01, 0x03, 0x00, 0x01, 0x00, 0x74, 0x3D, 0x29,
+       0x1A, 0x36, 0x06, 0x07, 0x02, 0x00, 0xCB, 0x03, 0x00, 0x04, 0x75, 0x01,
+       0x00, 0xC2, 0x02, 0x00, 0x26, 0x1A, 0x17, 0x06, 0x02, 0x6C, 0x28, 0xCB,
+       0x04, 0x76, 0x01, 0x01, 0x00, 0x74, 0x3D, 0x01, 0x16, 0x84, 0x3D, 0x01,
+       0x00, 0x87, 0x3C, 0x34, 0xD1, 0x29, 0xB1, 0x06, 0x09, 0x01, 0x7F, 0xAC,
+       0x01, 0x7F, 0xCE, 0x04, 0x80, 0x53, 0xAE, 0x76, 0x2C, 0x9E, 0x01,
+       T0_INT1(BR_KEYTYPE_SIGN), 0x17, 0x06, 0x01, 0xB2, 0xB5, 0x26, 0x01,
+       0x0D, 0x0E, 0x06, 0x07, 0x25, 0xB4, 0xB5, 0x01, 0x7F, 0x04, 0x02, 0x01,
+       0x00, 0x03, 0x00, 0x01, 0x0E, 0x0E, 0x05, 0x02, 0x6F, 0x28, 0x06, 0x02,
+       0x64, 0x28, 0x33, 0x06, 0x02, 0x6F, 0x28, 0x02, 0x00, 0x06, 0x1C, 0xCF,
+       0x7D, 0x2E, 0x01, 0x81, 0x7F, 0x0E, 0x06, 0x0D, 0x25, 0x01, 0x10, 0xDA,
+       0x01, 0x00, 0xD9, 0x76, 0x2C, 0xA8, 0x24, 0x04, 0x04, 0xD2, 0x06, 0x01,
+       0xD0, 0x04, 0x01, 0xD2, 0x01, 0x7F, 0xCE, 0x01, 0x7F, 0xAC, 0x01, 0x01,
+       0x74, 0x3D, 0x01, 0x17, 0x84, 0x3D, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00,
+       0x97, 0x01, 0x0C, 0x11, 0x01, 0x00, 0x38, 0x0E, 0x06, 0x05, 0x25, 0x01,
        T0_INT1(BR_KEYTYPE_RSA | BR_KEYTYPE_KEYX), 0x04, 0x30, 0x01, 0x01,
-       0x36, 0x0E, 0x06, 0x05, 0x24, 0x01,
+       0x38, 0x0E, 0x06, 0x05, 0x25, 0x01,
        T0_INT1(BR_KEYTYPE_RSA | BR_KEYTYPE_SIGN), 0x04, 0x25, 0x01, 0x02,
-       0x36, 0x0E, 0x06, 0x05, 0x24, 0x01,
+       0x38, 0x0E, 0x06, 0x05, 0x25, 0x01,
        T0_INT1(BR_KEYTYPE_EC  | BR_KEYTYPE_SIGN), 0x04, 0x1A, 0x01, 0x03,
-       0x36, 0x0E, 0x06, 0x05, 0x24, 0x01,
+       0x38, 0x0E, 0x06, 0x05, 0x25, 0x01,
        T0_INT1(BR_KEYTYPE_EC  | BR_KEYTYPE_KEYX), 0x04, 0x0F, 0x01, 0x04,
-       0x36, 0x0E, 0x06, 0x05, 0x24, 0x01,
+       0x38, 0x0E, 0x06, 0x05, 0x25, 0x01,
        T0_INT1(BR_KEYTYPE_EC  | BR_KEYTYPE_KEYX), 0x04, 0x04, 0x01, 0x00,
-       0x41, 0x24, 0x00, 0x00, 0x7C, 0x2C, 0x01, 0x0E, 0x0E, 0x06, 0x04, 0x01,
-       0x00, 0x04, 0x02, 0x01, 0x05, 0x00, 0x00, 0x3D, 0x06, 0x04, 0x01, 0x06,
-       0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x81, 0x2C, 0x25, 0x06, 0x08, 0x01,
-       0x01, 0x09, 0x01, 0x11, 0x07, 0x04, 0x03, 0x24, 0x01, 0x05, 0x00, 0x01,
-       0x3E, 0x03, 0x00, 0x24, 0x01, 0x00, 0x40, 0x06, 0x03, 0x02, 0x00, 0x08,
-       0x3F, 0x06, 0x03, 0x02, 0x00, 0x08, 0x25, 0x06, 0x06, 0x01, 0x01, 0x0B,
-       0x01, 0x06, 0x08, 0x00, 0x00, 0x83, 0x3C, 0x25, 0x06, 0x03, 0x01, 0x09,
-       0x08, 0x00, 0x01, 0x3D, 0x25, 0x06, 0x1E, 0x01, 0x00, 0x03, 0x00, 0x25,
-       0x06, 0x0E, 0x25, 0x01, 0x01, 0x17, 0x02, 0x00, 0x08, 0x03, 0x00, 0x01,
-       0x01, 0x11, 0x04, 0x6F, 0x24, 0x02, 0x00, 0x01, 0x01, 0x0B, 0x01, 0x06,
-       0x08, 0x00, 0x00, 0x79, 0x2B, 0x41, 0x11, 0x01, 0x01, 0x17, 0x33, 0x00,
-       0x00, 0x97, 0xC4, 0x25, 0x01, 0x07, 0x17, 0x01, 0x00, 0x36, 0x0E, 0x06,
-       0x09, 0x24, 0x01, 0x10, 0x17, 0x06, 0x01, 0x97, 0x04, 0x2D, 0x01, 0x01,
-       0x36, 0x0E, 0x06, 0x24, 0x24, 0x24, 0x01, 0x00, 0x71, 0x3B, 0xAA, 0x81,
-       0x2C, 0x01, 0x01, 0x0E, 0x01, 0x01, 0xA0, 0x35, 0x06, 0x0F, 0x27, 0x1A,
-       0x34, 0x06, 0x04, 0xC4, 0x24, 0x04, 0x78, 0x01, 0x80, 0x64, 0xBC, 0x04,
-       0x01, 0x97, 0x04, 0x03, 0x6C, 0x26, 0x24, 0x04, 0xFF, 0x3C, 0x01, 0x25,
-       0x03, 0x00, 0x09, 0x25, 0x52, 0x06, 0x02, 0x62, 0x26, 0x02, 0x00, 0x00,
-       0x00, 0x92, 0x01, 0x0F, 0x17, 0x00, 0x00, 0x70, 0x2C, 0x01, 0x00, 0x36,
-       0x0E, 0x06, 0x10, 0x24, 0x25, 0x01, 0x01, 0x0D, 0x06, 0x03, 0x24, 0x01,
-       0x02, 0x70, 0x3B, 0x01, 0x00, 0x04, 0x22, 0x01, 0x01, 0x36, 0x0E, 0x06,
-       0x15, 0x24, 0x01, 0x00, 0x70, 0x3B, 0x25, 0x01, 0x80, 0x64, 0x0E, 0x06,
-       0x05, 0x01, 0x82, 0x00, 0x08, 0x26, 0x54, 0x00, 0x04, 0x07, 0x24, 0x01,
-       0x82, 0x00, 0x08, 0x26, 0x24, 0x00, 0x00, 0x01, 0x00, 0x2D, 0x06, 0x05,
-       0x38, 0xA4, 0x35, 0x04, 0x78, 0x25, 0x06, 0x04, 0x01, 0x01, 0x87, 0x3B,
-       0x00, 0x00, 0x2D, 0x06, 0x0B, 0x7F, 0x2C, 0x01, 0x14, 0x0D, 0x06, 0x02,
-       0x6C, 0x26, 0x04, 0x11, 0xC4, 0x01, 0x07, 0x17, 0x25, 0x01, 0x02, 0x0D,
-       0x06, 0x06, 0x06, 0x02, 0x6C, 0x26, 0x04, 0x70, 0x24, 0xB9, 0x01, 0x01,
-       0x0D, 0x31, 0x35, 0x06, 0x02, 0x5B, 0x26, 0x25, 0x01, 0x01, 0xBF, 0x34,
-       0xA9, 0x00, 0x01, 0xAF, 0x01, 0x0B, 0x0E, 0x05, 0x02, 0x6C, 0x26, 0x25,
-       0x01, 0x03, 0x0E, 0x06, 0x08, 0xB7, 0x06, 0x02, 0x62, 0x26, 0x41, 0x24,
-       0x00, 0x41, 0x51, 0xB7, 0xA2, 0x25, 0x06, 0x23, 0xB7, 0xA2, 0x25, 0x50,
-       0x25, 0x06, 0x18, 0x25, 0x01, 0x82, 0x00, 0x0F, 0x06, 0x05, 0x01, 0x82,
-       0x00, 0x04, 0x01, 0x25, 0x03, 0x00, 0x7E, 0x02, 0x00, 0xAD, 0x02, 0x00,
-       0x4D, 0x04, 0x65, 0x93, 0x4E, 0x04, 0x5A, 0x93, 0x93, 0x4F, 0x25, 0x06,
-       0x02, 0x33, 0x00, 0x24, 0x29, 0x00, 0x00, 0x73, 0x2A, 0x99, 0x01, 0x7F,
-       0xA7, 0x25, 0x52, 0x06, 0x02, 0x33, 0x26, 0x25, 0x05, 0x02, 0x6C, 0x26,
-       0x36, 0x17, 0x0D, 0x06, 0x02, 0x6E, 0x26, 0x39, 0x00, 0x00, 0x94, 0xAF,
-       0x01, 0x14, 0x0D, 0x06, 0x02, 0x6C, 0x26, 0x7E, 0x01, 0x0C, 0x08, 0x01,
-       0x0C, 0xAD, 0x93, 0x7E, 0x25, 0x01, 0x0C, 0x08, 0x01, 0x0C, 0x2E, 0x05,
-       0x02, 0x5E, 0x26, 0x00, 0x00, 0xB0, 0x06, 0x02, 0x6C, 0x26, 0x06, 0x02,
-       0x60, 0x26, 0x00, 0x09, 0xAF, 0x01, 0x02, 0x0E, 0x05, 0x02, 0x6C, 0x26,
-       0xB6, 0x03, 0x00, 0x02, 0x00, 0x8D, 0x2A, 0x0A, 0x02, 0x00, 0x8C, 0x2A,
-       0x0F, 0x35, 0x06, 0x02, 0x6D, 0x26, 0x02, 0x00, 0x8B, 0x2A, 0x0D, 0x06,
-       0x02, 0x65, 0x26, 0x02, 0x00, 0x8E, 0x3A, 0x84, 0x01, 0x20, 0xAD, 0x01,
-       0x00, 0x03, 0x01, 0xB8, 0x03, 0x02, 0x02, 0x02, 0x01, 0x20, 0x0F, 0x06,
-       0x02, 0x6A, 0x26, 0x7E, 0x02, 0x02, 0xAD, 0x02, 0x02, 0x86, 0x2C, 0x0E,
-       0x02, 0x02, 0x01, 0x00, 0x0F, 0x17, 0x06, 0x0B, 0x85, 0x7E, 0x02, 0x02,
-       0x2E, 0x06, 0x04, 0x01, 0x7F, 0x03, 0x01, 0x85, 0x7E, 0x02, 0x02, 0x2F,
-       0x02, 0x02, 0x86, 0x3B, 0x02, 0x00, 0x8A, 0x02, 0x01, 0x90, 0xB6, 0x25,
-       0xBA, 0x52, 0x06, 0x02, 0x5C, 0x26, 0x73, 0x02, 0x01, 0x90, 0xB8, 0x06,
-       0x02, 0x5D, 0x26, 0x25, 0x06, 0x81, 0x2D, 0xB6, 0xA2, 0x9E, 0x03, 0x03,
-       0x9C, 0x03, 0x04, 0x9A, 0x03, 0x05, 0x9D, 0x03, 0x06, 0x9F, 0x03, 0x07,
-       0x9B, 0x03, 0x08, 0x25, 0x06, 0x81, 0x03, 0xB6, 0x01, 0x00, 0x36, 0x0E,
-       0x06, 0x0F, 0x24, 0x02, 0x03, 0x05, 0x02, 0x66, 0x26, 0x01, 0x00, 0x03,
-       0x03, 0xB5, 0x04, 0x80, 0x6A, 0x01, 0x01, 0x36, 0x0E, 0x06, 0x0F, 0x24,
-       0x02, 0x05, 0x05, 0x02, 0x66, 0x26, 0x01, 0x00, 0x03, 0x05, 0xB3, 0x04,
-       0x80, 0x55, 0x01, 0x83, 0xFE, 0x01, 0x36, 0x0E, 0x06, 0x0E, 0x24, 0x02,
-       0x04, 0x05, 0x02, 0x66, 0x26, 0x01, 0x00, 0x03, 0x04, 0xB4, 0x04, 0x3F,
-       0x01, 0x0D, 0x36, 0x0E, 0x06, 0x0E, 0x24, 0x02, 0x06, 0x05, 0x02, 0x66,
-       0x26, 0x01, 0x00, 0x03, 0x06, 0xB1, 0x04, 0x2B, 0x01, 0x0A, 0x36, 0x0E,
-       0x06, 0x0E, 0x24, 0x02, 0x07, 0x05, 0x02, 0x66, 0x26, 0x01, 0x00, 0x03,
-       0x07, 0xB1, 0x04, 0x17, 0x01, 0x0B, 0x36, 0x0E, 0x06, 0x0E, 0x24, 0x02,
-       0x08, 0x05, 0x02, 0x66, 0x26, 0x01, 0x00, 0x03, 0x08, 0xB1, 0x04, 0x03,
-       0x66, 0x26, 0x24, 0x04, 0xFE, 0x79, 0x02, 0x04, 0x06, 0x0D, 0x02, 0x04,
-       0x01, 0x05, 0x0F, 0x06, 0x02, 0x63, 0x26, 0x01, 0x01, 0x81, 0x3B, 0x93,
-       0x93, 0x02, 0x01, 0x00, 0x04, 0xAF, 0x01, 0x0C, 0x0E, 0x05, 0x02, 0x6C,
-       0x26, 0xB8, 0x01, 0x03, 0x0E, 0x05, 0x02, 0x67, 0x26, 0xB6, 0x25, 0x76,
-       0x3B, 0x25, 0x01, 0x20, 0x10, 0x06, 0x02, 0x67, 0x26, 0x3D, 0x41, 0x11,
-       0x01, 0x01, 0x17, 0x05, 0x02, 0x67, 0x26, 0xB8, 0x25, 0x01, 0x81, 0x05,
-       0x0F, 0x06, 0x02, 0x67, 0x26, 0x25, 0x78, 0x3B, 0x77, 0x41, 0xAD, 0x8A,
-       0x2A, 0x01, 0x86, 0x03, 0x10, 0x03, 0x00, 0x73, 0x2A, 0xC2, 0x03, 0x01,
-       0x01, 0x02, 0x03, 0x02, 0x02, 0x00, 0x06, 0x21, 0xB8, 0x25, 0x25, 0x01,
-       0x02, 0x0A, 0x41, 0x01, 0x06, 0x0F, 0x35, 0x06, 0x02, 0x67, 0x26, 0x03,
-       0x02, 0xB8, 0x02, 0x01, 0x01, 0x01, 0x0B, 0x01, 0x03, 0x08, 0x0E, 0x05,
-       0x02, 0x67, 0x26, 0x04, 0x08, 0x02, 0x01, 0x06, 0x04, 0x01, 0x00, 0x03,
-       0x02, 0xB6, 0x25, 0x03, 0x03, 0x25, 0x01, 0x84, 0x00, 0x0F, 0x06, 0x02,
-       0x68, 0x26, 0x7E, 0x41, 0xAD, 0x02, 0x02, 0x02, 0x01, 0x02, 0x03, 0x4A,
-       0x25, 0x06, 0x01, 0x26, 0x24, 0x93, 0x00, 0x02, 0x03, 0x00, 0x03, 0x01,
-       0x02, 0x00, 0x8F, 0x02, 0x01, 0x02, 0x00, 0x37, 0x25, 0x01, 0x00, 0x0E,
-       0x06, 0x02, 0x5A, 0x00, 0xC6, 0x04, 0x74, 0x02, 0x01, 0x00, 0x03, 0x00,
-       0xB8, 0xA2, 0x25, 0x06, 0x80, 0x43, 0xB8, 0x01, 0x01, 0x36, 0x0E, 0x06,
-       0x06, 0x24, 0x01, 0x81, 0x7F, 0x04, 0x2E, 0x01, 0x80, 0x40, 0x36, 0x0E,
-       0x06, 0x07, 0x24, 0x01, 0x83, 0xFE, 0x00, 0x04, 0x20, 0x01, 0x80, 0x41,
-       0x36, 0x0E, 0x06, 0x07, 0x24, 0x01, 0x84, 0x80, 0x00, 0x04, 0x12, 0x01,
-       0x80, 0x42, 0x36, 0x0E, 0x06, 0x07, 0x24, 0x01, 0x88, 0x80, 0x00, 0x04,
-       0x04, 0x01, 0x00, 0x41, 0x24, 0x02, 0x00, 0x35, 0x03, 0x00, 0x04, 0xFF,
-       0x39, 0x93, 0x73, 0x2A, 0xC0, 0x05, 0x09, 0x02, 0x00, 0x01, 0x83, 0xFF,
-       0x7F, 0x17, 0x03, 0x00, 0x8A, 0x2A, 0x01, 0x86, 0x03, 0x10, 0x06, 0x3A,
-       0xB2, 0x25, 0x7B, 0x3A, 0x3E, 0x24, 0x25, 0x01, 0x08, 0x0B, 0x35, 0x01,
-       0x8C, 0x80, 0x00, 0x35, 0x17, 0x02, 0x00, 0x17, 0x02, 0x00, 0x01, 0x8C,
-       0x80, 0x00, 0x17, 0x06, 0x19, 0x25, 0x01, 0x81, 0x7F, 0x17, 0x06, 0x05,
-       0x01, 0x84, 0x80, 0x00, 0x35, 0x25, 0x01, 0x83, 0xFE, 0x00, 0x17, 0x06,
-       0x05, 0x01, 0x88, 0x80, 0x00, 0x35, 0x03, 0x00, 0x04, 0x09, 0x02, 0x00,
-       0x01, 0x8C, 0x88, 0x01, 0x17, 0x03, 0x00, 0x16, 0xB6, 0xA2, 0x25, 0x06,
-       0x23, 0xB6, 0xA2, 0x25, 0x15, 0x25, 0x06, 0x18, 0x25, 0x01, 0x82, 0x00,
-       0x0F, 0x06, 0x05, 0x01, 0x82, 0x00, 0x04, 0x01, 0x25, 0x03, 0x01, 0x7E,
-       0x02, 0x01, 0xAD, 0x02, 0x01, 0x12, 0x04, 0x65, 0x93, 0x13, 0x04, 0x5A,
-       0x93, 0x14, 0x93, 0x02, 0x00, 0x28, 0x00, 0x00, 0xB0, 0x25, 0x54, 0x06,
-       0x07, 0x24, 0x06, 0x02, 0x60, 0x26, 0x04, 0x74, 0x00, 0x00, 0xB9, 0x01,
-       0x03, 0xB7, 0x41, 0x24, 0x41, 0x00, 0x00, 0xB6, 0xBD, 0x00, 0x03, 0x01,
-       0x00, 0x03, 0x00, 0xB6, 0xA2, 0x25, 0x06, 0x32, 0xB8, 0x03, 0x01, 0xB8,
-       0x03, 0x02, 0x02, 0x01, 0x01, 0x02, 0x10, 0x02, 0x01, 0x01, 0x06, 0x0C,
-       0x17, 0x02, 0x02, 0x01, 0x01, 0x0E, 0x02, 0x02, 0x01, 0x03, 0x0E, 0x35,
-       0x17, 0x06, 0x11, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x57, 0x01, 0x02,
-       0x0B, 0x02, 0x01, 0x08, 0x0B, 0x35, 0x03, 0x00, 0x04, 0x4B, 0x93, 0x02,
-       0x00, 0x00, 0x00, 0xB6, 0x01, 0x01, 0x0E, 0x05, 0x02, 0x5F, 0x26, 0xB8,
-       0x01, 0x08, 0x08, 0x7C, 0x2C, 0x0E, 0x05, 0x02, 0x5F, 0x26, 0x00, 0x00,
-       0xB6, 0x81, 0x2C, 0x05, 0x15, 0x01, 0x01, 0x0E, 0x05, 0x02, 0x63, 0x26,
-       0xB8, 0x01, 0x00, 0x0E, 0x05, 0x02, 0x63, 0x26, 0x01, 0x02, 0x81, 0x3B,
-       0x04, 0x1C, 0x01, 0x19, 0x0E, 0x05, 0x02, 0x63, 0x26, 0xB8, 0x01, 0x18,
-       0x0E, 0x05, 0x02, 0x63, 0x26, 0x7E, 0x01, 0x18, 0xAD, 0x82, 0x7E, 0x01,
-       0x18, 0x2E, 0x05, 0x02, 0x63, 0x26, 0x00, 0x00, 0xB6, 0x06, 0x02, 0x64,
-       0x26, 0x00, 0x00, 0x01, 0x02, 0x8F, 0xB9, 0x01, 0x08, 0x0B, 0xB9, 0x08,
-       0x00, 0x00, 0x01, 0x03, 0x8F, 0xB9, 0x01, 0x08, 0x0B, 0xB9, 0x08, 0x01,
-       0x08, 0x0B, 0xB9, 0x08, 0x00, 0x00, 0x01, 0x01, 0x8F, 0xB9, 0x00, 0x00,
-       0x38, 0x25, 0x52, 0x05, 0x01, 0x00, 0x24, 0xC6, 0x04, 0x76, 0x02, 0x03,
-       0x00, 0x89, 0x2C, 0x03, 0x01, 0x01, 0x00, 0x25, 0x02, 0x01, 0x0A, 0x06,
-       0x10, 0x25, 0x01, 0x01, 0x0B, 0x88, 0x08, 0x2A, 0x02, 0x00, 0x0E, 0x06,
-       0x01, 0x00, 0x56, 0x04, 0x6A, 0x24, 0x01, 0x7F, 0x00, 0x00, 0x01, 0x15,
-       0x80, 0x3B, 0x41, 0x4C, 0x24, 0x4C, 0x24, 0x27, 0x00, 0x00, 0x01, 0x01,
-       0x41, 0xBB, 0x00, 0x00, 0x41, 0x36, 0x8F, 0x41, 0x25, 0x06, 0x05, 0xB9,
-       0x24, 0x57, 0x04, 0x78, 0x24, 0x00, 0x00, 0x25, 0x01, 0x81, 0xAC, 0x00,
-       0x0E, 0x06, 0x04, 0x24, 0x01, 0x7F, 0x00, 0x92, 0x53, 0x00, 0x02, 0x03,
-       0x00, 0x73, 0x2A, 0x92, 0x03, 0x01, 0x02, 0x01, 0x01, 0x0F, 0x17, 0x02,
-       0x01, 0x01, 0x04, 0x11, 0x01, 0x0F, 0x17, 0x02, 0x01, 0x01, 0x08, 0x11,
-       0x01, 0x0F, 0x17, 0x01, 0x00, 0x36, 0x0E, 0x06, 0x10, 0x24, 0x01, 0x00,
-       0x01, 0x18, 0x02, 0x00, 0x06, 0x03, 0x44, 0x04, 0x01, 0x45, 0x04, 0x80,
-       0x68, 0x01, 0x01, 0x36, 0x0E, 0x06, 0x10, 0x24, 0x01, 0x01, 0x01, 0x10,
-       0x02, 0x00, 0x06, 0x03, 0x44, 0x04, 0x01, 0x45, 0x04, 0x80, 0x52, 0x01,
-       0x02, 0x36, 0x0E, 0x06, 0x0F, 0x24, 0x01, 0x01, 0x01, 0x20, 0x02, 0x00,
-       0x06, 0x03, 0x44, 0x04, 0x01, 0x45, 0x04, 0x3D, 0x01, 0x03, 0x36, 0x0E,
-       0x06, 0x0E, 0x24, 0x24, 0x01, 0x10, 0x02, 0x00, 0x06, 0x03, 0x42, 0x04,
-       0x01, 0x43, 0x04, 0x29, 0x01, 0x04, 0x36, 0x0E, 0x06, 0x0E, 0x24, 0x24,
-       0x01, 0x20, 0x02, 0x00, 0x06, 0x03, 0x42, 0x04, 0x01, 0x43, 0x04, 0x15,
-       0x01, 0x05, 0x36, 0x0E, 0x06, 0x0C, 0x24, 0x24, 0x02, 0x00, 0x06, 0x03,
-       0x46, 0x04, 0x01, 0x47, 0x04, 0x03, 0x62, 0x26, 0x24, 0x00, 0x00, 0x92,
-       0x01, 0x0C, 0x11, 0x01, 0x02, 0x0F, 0x00, 0x00, 0x92, 0x01, 0x0C, 0x11,
-       0x25, 0x55, 0x41, 0x01, 0x03, 0x0A, 0x17, 0x00, 0x00, 0x92, 0x01, 0x0C,
-       0x11, 0x01, 0x01, 0x0E, 0x00, 0x00, 0x92, 0x01, 0x0C, 0x11, 0x54, 0x00,
-       0x00, 0x1B, 0x01, 0x00, 0x6F, 0x2C, 0x25, 0x06, 0x1F, 0x01, 0x01, 0x36,
-       0x0E, 0x06, 0x06, 0x24, 0x01, 0x00, 0x96, 0x04, 0x11, 0x01, 0x02, 0x36,
-       0x0E, 0x06, 0x0A, 0x24, 0x71, 0x2C, 0x06, 0x03, 0x01, 0x10, 0x35, 0x04,
-       0x01, 0x24, 0x04, 0x01, 0x24, 0x75, 0x2C, 0x05, 0x33, 0x2D, 0x06, 0x30,
-       0x7F, 0x2C, 0x01, 0x14, 0x36, 0x0E, 0x06, 0x06, 0x24, 0x01, 0x02, 0x35,
-       0x04, 0x22, 0x01, 0x15, 0x36, 0x0E, 0x06, 0x09, 0x24, 0xA5, 0x06, 0x03,
-       0x01, 0x7F, 0x96, 0x04, 0x13, 0x01, 0x16, 0x36, 0x0E, 0x06, 0x06, 0x24,
-       0x01, 0x01, 0x35, 0x04, 0x07, 0x24, 0x01, 0x04, 0x35, 0x01, 0x00, 0x24,
-       0x1A, 0x06, 0x03, 0x01, 0x08, 0x35, 0x00, 0x00, 0x1B, 0x25, 0x05, 0x0F,
-       0x2D, 0x06, 0x0C, 0x7F, 0x2C, 0x01, 0x15, 0x0E, 0x06, 0x04, 0x24, 0xA5,
-       0x04, 0x01, 0x1F, 0x00, 0x00, 0xC4, 0x01, 0x07, 0x17, 0x01, 0x01, 0x0F,
-       0x06, 0x02, 0x6C, 0x26, 0x00, 0x01, 0x03, 0x00, 0x27, 0x1A, 0x06, 0x05,
-       0x02, 0x00, 0x80, 0x3B, 0x00, 0xC4, 0x24, 0x04, 0x74, 0x00, 0x01, 0x14,
-       0xC7, 0x01, 0x01, 0xD4, 0x27, 0x25, 0x01, 0x00, 0xBF, 0x01, 0x16, 0xC7,
-       0xCD, 0x27, 0x00, 0x00, 0x01, 0x0B, 0xD4, 0x48, 0x25, 0x25, 0x01, 0x03,
-       0x08, 0xD3, 0xD3, 0x18, 0x25, 0x52, 0x06, 0x02, 0x24, 0x00, 0xD3, 0x1D,
-       0x25, 0x06, 0x05, 0x7E, 0x41, 0xCE, 0x04, 0x77, 0x24, 0x04, 0x6C, 0x00,
-       0x20, 0x01, 0x0F, 0xD4, 0x25, 0x8A, 0x2A, 0x01, 0x86, 0x03, 0x10, 0x06,
-       0x0C, 0x01, 0x04, 0x08, 0xD3, 0x7A, 0x2C, 0xD4, 0x72, 0x2C, 0xD4, 0x04,
-       0x02, 0x58, 0xD3, 0x25, 0xD2, 0x7E, 0x41, 0xCE, 0x00, 0x02, 0x9C, 0x9E,
-       0x08, 0x9A, 0x08, 0x9D, 0x08, 0x9F, 0x08, 0x9B, 0x08, 0x03, 0x00, 0x01,
-       0x01, 0xD4, 0x01, 0x27, 0x86, 0x2C, 0x08, 0x89, 0x2C, 0x01, 0x01, 0x0B,
-       0x08, 0x02, 0x00, 0x06, 0x04, 0x58, 0x02, 0x00, 0x08, 0x7D, 0x2A, 0x36,
-       0x09, 0x25, 0x55, 0x06, 0x24, 0x02, 0x00, 0x05, 0x04, 0x41, 0x58, 0x41,
-       0x59, 0x01, 0x04, 0x09, 0x25, 0x52, 0x06, 0x03, 0x24, 0x01, 0x00, 0x25,
-       0x01, 0x04, 0x08, 0x02, 0x00, 0x08, 0x03, 0x00, 0x41, 0x01, 0x04, 0x08,
-       0x36, 0x08, 0x41, 0x04, 0x03, 0x24, 0x01, 0x7F, 0x03, 0x01, 0xD3, 0x8C,
-       0x2A, 0xD2, 0x74, 0x01, 0x04, 0x19, 0x74, 0x01, 0x04, 0x08, 0x01, 0x1C,
-       0x30, 0x74, 0x01, 0x20, 0xCE, 0x85, 0x86, 0x2C, 0xD0, 0x89, 0x2C, 0x25,
-       0x01, 0x01, 0x0B, 0xD2, 0x88, 0x41, 0x25, 0x06, 0x0F, 0x57, 0x36, 0x2A,
-       0x25, 0xBE, 0x05, 0x02, 0x5C, 0x26, 0xD2, 0x41, 0x58, 0x41, 0x04, 0x6E,
-       0x5A, 0x01, 0x01, 0xD4, 0x01, 0x00, 0xD4, 0x02, 0x00, 0x06, 0x81, 0x22,
-       0x02, 0x00, 0xD2, 0x9C, 0x06, 0x0E, 0x01, 0x83, 0xFE, 0x01, 0xD2, 0x82,
-       0x9C, 0x01, 0x04, 0x09, 0x25, 0xD2, 0x57, 0xD0, 0x9E, 0x06, 0x16, 0x01,
-       0x00, 0xD2, 0x83, 0x9E, 0x01, 0x04, 0x09, 0x25, 0xD2, 0x01, 0x02, 0x09,
-       0x25, 0xD2, 0x01, 0x00, 0xD4, 0x01, 0x03, 0x09, 0xCF, 0x9A, 0x06, 0x0C,
-       0x01, 0x01, 0xD2, 0x01, 0x01, 0xD2, 0x7C, 0x2C, 0x01, 0x08, 0x09, 0xD4,
-       0x9D, 0x06, 0x19, 0x01, 0x0D, 0xD2, 0x9D, 0x01, 0x04, 0x09, 0x25, 0xD2,
-       0x01, 0x02, 0x09, 0xD2, 0x3F, 0x06, 0x03, 0x01, 0x03, 0xD1, 0x40, 0x06,
-       0x03, 0x01, 0x01, 0xD1, 0x9F, 0x25, 0x06, 0x22, 0x01, 0x0A, 0xD2, 0x01,
-       0x04, 0x09, 0x25, 0xD2, 0x59, 0xD2, 0x3D, 0x01, 0x00, 0x25, 0x01, 0x20,
-       0x0A, 0x06, 0x0C, 0x98, 0x11, 0x01, 0x01, 0x17, 0x06, 0x02, 0x25, 0xD2,
-       0x56, 0x04, 0x6E, 0x5A, 0x04, 0x01, 0x24, 0x9B, 0x06, 0x0A, 0x01, 0x0B,
-       0xD2, 0x01, 0x02, 0xD2, 0x01, 0x82, 0x00, 0xD2, 0x02, 0x01, 0x52, 0x05,
-       0x11, 0x01, 0x15, 0xD2, 0x02, 0x01, 0x25, 0xD2, 0x25, 0x06, 0x06, 0x57,
-       0x01, 0x00, 0xD4, 0x04, 0x77, 0x24, 0x00, 0x00, 0x01, 0x10, 0xD4, 0x73,
-       0x2A, 0x25, 0xC3, 0x06, 0x0C, 0xA3, 0x22, 0x25, 0x58, 0xD3, 0x25, 0xD2,
-       0x7E, 0x41, 0xCE, 0x04, 0x0D, 0x25, 0xC1, 0x41, 0xA3, 0x21, 0x25, 0x56,
-       0xD3, 0x25, 0xD4, 0x7E, 0x41, 0xCE, 0x00, 0x00, 0x94, 0x01, 0x14, 0xD4,
-       0x01, 0x0C, 0xD3, 0x7E, 0x01, 0x0C, 0xCE, 0x00, 0x00, 0x4B, 0x25, 0x01,
-       0x00, 0x0E, 0x06, 0x02, 0x5A, 0x00, 0xC4, 0x24, 0x04, 0x73, 0x00, 0x25,
-       0xD2, 0xCE, 0x00, 0x00, 0x25, 0xD4, 0xCE, 0x00, 0x01, 0x03, 0x00, 0x3E,
-       0x24, 0x25, 0x01, 0x10, 0x17, 0x06, 0x06, 0x01, 0x04, 0xD4, 0x02, 0x00,
-       0xD4, 0x25, 0x01, 0x08, 0x17, 0x06, 0x06, 0x01, 0x03, 0xD4, 0x02, 0x00,
-       0xD4, 0x25, 0x01, 0x20, 0x17, 0x06, 0x06, 0x01, 0x05, 0xD4, 0x02, 0x00,
-       0xD4, 0x25, 0x01, 0x80, 0x40, 0x17, 0x06, 0x06, 0x01, 0x06, 0xD4, 0x02,
-       0x00, 0xD4, 0x01, 0x04, 0x17, 0x06, 0x06, 0x01, 0x02, 0xD4, 0x02, 0x00,
-       0xD4, 0x00, 0x00, 0x25, 0x01, 0x08, 0x49, 0xD4, 0xD4, 0x00, 0x00, 0x25,
-       0x01, 0x10, 0x49, 0xD4, 0xD2, 0x00, 0x00, 0x25, 0x4C, 0x06, 0x02, 0x24,
-       0x00, 0xC4, 0x24, 0x04, 0x76
+       0x43, 0x25, 0x00, 0x00, 0x7F, 0x2E, 0x01, 0x0E, 0x0E, 0x06, 0x04, 0x01,
+       0x00, 0x04, 0x02, 0x01, 0x05, 0x00, 0x00, 0x3F, 0x06, 0x04, 0x01, 0x06,
+       0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x85, 0x2E, 0x26, 0x06, 0x08, 0x01,
+       0x01, 0x09, 0x01, 0x11, 0x07, 0x04, 0x03, 0x25, 0x01, 0x05, 0x00, 0x01,
+       0x40, 0x03, 0x00, 0x25, 0x01, 0x00, 0x42, 0x06, 0x03, 0x02, 0x00, 0x08,
+       0x41, 0x06, 0x03, 0x02, 0x00, 0x08, 0x26, 0x06, 0x06, 0x01, 0x01, 0x0B,
+       0x01, 0x06, 0x08, 0x00, 0x00, 0x88, 0x3E, 0x26, 0x06, 0x03, 0x01, 0x09,
+       0x08, 0x00, 0x01, 0x3F, 0x26, 0x06, 0x1E, 0x01, 0x00, 0x03, 0x00, 0x26,
+       0x06, 0x0E, 0x26, 0x01, 0x01, 0x17, 0x02, 0x00, 0x08, 0x03, 0x00, 0x01,
+       0x01, 0x11, 0x04, 0x6F, 0x25, 0x02, 0x00, 0x01, 0x01, 0x0B, 0x01, 0x06,
+       0x08, 0x00, 0x00, 0x7C, 0x2D, 0x43, 0x11, 0x01, 0x01, 0x17, 0x35, 0x00,
+       0x00, 0x9C, 0xCA, 0x26, 0x01, 0x07, 0x17, 0x01, 0x00, 0x38, 0x0E, 0x06,
+       0x09, 0x25, 0x01, 0x10, 0x17, 0x06, 0x01, 0x9C, 0x04, 0x2D, 0x01, 0x01,
+       0x38, 0x0E, 0x06, 0x24, 0x25, 0x25, 0x01, 0x00, 0x74, 0x3D, 0xB0, 0x85,
+       0x2E, 0x01, 0x01, 0x0E, 0x01, 0x01, 0xA5, 0x37, 0x06, 0x0F, 0x29, 0x1A,
+       0x36, 0x06, 0x04, 0xCA, 0x25, 0x04, 0x78, 0x01, 0x80, 0x64, 0xC2, 0x04,
+       0x01, 0x9C, 0x04, 0x03, 0x6F, 0x28, 0x25, 0x04, 0xFF, 0x3C, 0x01, 0x26,
+       0x03, 0x00, 0x09, 0x26, 0x55, 0x06, 0x02, 0x65, 0x28, 0x02, 0x00, 0x00,
+       0x00, 0x97, 0x01, 0x0F, 0x17, 0x00, 0x00, 0x73, 0x2E, 0x01, 0x00, 0x38,
+       0x0E, 0x06, 0x10, 0x25, 0x26, 0x01, 0x01, 0x0D, 0x06, 0x03, 0x25, 0x01,
+       0x02, 0x73, 0x3D, 0x01, 0x00, 0x04, 0x22, 0x01, 0x01, 0x38, 0x0E, 0x06,
+       0x15, 0x25, 0x01, 0x00, 0x73, 0x3D, 0x26, 0x01, 0x80, 0x64, 0x0E, 0x06,
+       0x05, 0x01, 0x82, 0x00, 0x08, 0x28, 0x57, 0x00, 0x04, 0x07, 0x25, 0x01,
+       0x82, 0x00, 0x08, 0x28, 0x25, 0x00, 0x00, 0x01, 0x00, 0x2F, 0x06, 0x05,
+       0x3A, 0xA9, 0x37, 0x04, 0x78, 0x26, 0x06, 0x04, 0x01, 0x01, 0x8C, 0x3D,
+       0x00, 0x01, 0xBC, 0xA7, 0xBC, 0xA7, 0xBE, 0x81, 0x43, 0x26, 0x03, 0x00,
+       0xB3, 0x98, 0x98, 0x02, 0x00, 0x4A, 0x26, 0x55, 0x06, 0x0A, 0x01, 0x03,
+       0xA5, 0x06, 0x02, 0x6F, 0x28, 0x25, 0x04, 0x03, 0x59, 0x87, 0x3C, 0x00,
+       0x00, 0x2F, 0x06, 0x0B, 0x83, 0x2E, 0x01, 0x14, 0x0D, 0x06, 0x02, 0x6F,
+       0x28, 0x04, 0x11, 0xCA, 0x01, 0x07, 0x17, 0x26, 0x01, 0x02, 0x0D, 0x06,
+       0x06, 0x06, 0x02, 0x6F, 0x28, 0x04, 0x70, 0x25, 0xBF, 0x01, 0x01, 0x0D,
+       0x33, 0x37, 0x06, 0x02, 0x5E, 0x28, 0x26, 0x01, 0x01, 0xC5, 0x36, 0xAF,
+       0x00, 0x01, 0xB5, 0x01, 0x0B, 0x0E, 0x05, 0x02, 0x6F, 0x28, 0x26, 0x01,
+       0x03, 0x0E, 0x06, 0x08, 0xBD, 0x06, 0x02, 0x65, 0x28, 0x43, 0x25, 0x00,
+       0x43, 0x54, 0xBD, 0xA7, 0x26, 0x06, 0x23, 0xBD, 0xA7, 0x26, 0x53, 0x26,
+       0x06, 0x18, 0x26, 0x01, 0x82, 0x00, 0x0F, 0x06, 0x05, 0x01, 0x82, 0x00,
+       0x04, 0x01, 0x26, 0x03, 0x00, 0x81, 0x02, 0x00, 0xB3, 0x02, 0x00, 0x50,
+       0x04, 0x65, 0x98, 0x51, 0x04, 0x5A, 0x98, 0x98, 0x52, 0x26, 0x06, 0x02,
+       0x35, 0x00, 0x25, 0x2B, 0x00, 0x00, 0x76, 0x2C, 0x9E, 0x01, 0x7F, 0xAD,
+       0x26, 0x55, 0x06, 0x02, 0x35, 0x28, 0x26, 0x05, 0x02, 0x6F, 0x28, 0x38,
+       0x17, 0x0D, 0x06, 0x02, 0x71, 0x28, 0x3B, 0x00, 0x00, 0x99, 0xB5, 0x01,
+       0x14, 0x0D, 0x06, 0x02, 0x6F, 0x28, 0x81, 0x01, 0x0C, 0x08, 0x01, 0x0C,
+       0xB3, 0x98, 0x81, 0x26, 0x01, 0x0C, 0x08, 0x01, 0x0C, 0x30, 0x05, 0x02,
+       0x61, 0x28, 0x00, 0x00, 0xB6, 0x06, 0x02, 0x6F, 0x28, 0x06, 0x02, 0x63,
+       0x28, 0x00, 0x0A, 0xB5, 0x01, 0x02, 0x0E, 0x05, 0x02, 0x6F, 0x28, 0xBC,
+       0x03, 0x00, 0x02, 0x00, 0x92, 0x2C, 0x0A, 0x02, 0x00, 0x91, 0x2C, 0x0F,
+       0x37, 0x06, 0x02, 0x70, 0x28, 0x02, 0x00, 0x90, 0x2C, 0x0D, 0x06, 0x02,
+       0x68, 0x28, 0x02, 0x00, 0x93, 0x3C, 0x89, 0x01, 0x20, 0xB3, 0x01, 0x00,
+       0x03, 0x01, 0xBE, 0x03, 0x02, 0x02, 0x02, 0x01, 0x20, 0x0F, 0x06, 0x02,
+       0x6D, 0x28, 0x81, 0x02, 0x02, 0xB3, 0x02, 0x02, 0x8B, 0x2E, 0x0E, 0x02,
+       0x02, 0x01, 0x00, 0x0F, 0x17, 0x06, 0x0B, 0x8A, 0x81, 0x02, 0x02, 0x30,
+       0x06, 0x04, 0x01, 0x7F, 0x03, 0x01, 0x8A, 0x81, 0x02, 0x02, 0x31, 0x02,
+       0x02, 0x8B, 0x3D, 0x02, 0x00, 0x8F, 0x02, 0x01, 0x95, 0xBC, 0x26, 0xC0,
+       0x55, 0x06, 0x02, 0x5F, 0x28, 0x76, 0x02, 0x01, 0x95, 0xBE, 0x06, 0x02,
+       0x60, 0x28, 0x26, 0x06, 0x81, 0x45, 0xBC, 0xA7, 0xA3, 0x03, 0x03, 0xA1,
+       0x03, 0x04, 0x9F, 0x03, 0x05, 0xA2, 0x03, 0x06, 0xA4, 0x03, 0x07, 0xA0,
+       0x03, 0x08, 0x27, 0x03, 0x09, 0x26, 0x06, 0x81, 0x18, 0xBC, 0x01, 0x00,
+       0x38, 0x0E, 0x06, 0x0F, 0x25, 0x02, 0x03, 0x05, 0x02, 0x69, 0x28, 0x01,
+       0x00, 0x03, 0x03, 0xBB, 0x04, 0x80, 0x7F, 0x01, 0x01, 0x38, 0x0E, 0x06,
+       0x0F, 0x25, 0x02, 0x05, 0x05, 0x02, 0x69, 0x28, 0x01, 0x00, 0x03, 0x05,
+       0xB9, 0x04, 0x80, 0x6A, 0x01, 0x83, 0xFE, 0x01, 0x38, 0x0E, 0x06, 0x0F,
+       0x25, 0x02, 0x04, 0x05, 0x02, 0x69, 0x28, 0x01, 0x00, 0x03, 0x04, 0xBA,
+       0x04, 0x80, 0x53, 0x01, 0x0D, 0x38, 0x0E, 0x06, 0x0E, 0x25, 0x02, 0x06,
+       0x05, 0x02, 0x69, 0x28, 0x01, 0x00, 0x03, 0x06, 0xB7, 0x04, 0x3F, 0x01,
+       0x0A, 0x38, 0x0E, 0x06, 0x0E, 0x25, 0x02, 0x07, 0x05, 0x02, 0x69, 0x28,
+       0x01, 0x00, 0x03, 0x07, 0xB7, 0x04, 0x2B, 0x01, 0x0B, 0x38, 0x0E, 0x06,
+       0x0E, 0x25, 0x02, 0x08, 0x05, 0x02, 0x69, 0x28, 0x01, 0x00, 0x03, 0x08,
+       0xB7, 0x04, 0x17, 0x01, 0x10, 0x38, 0x0E, 0x06, 0x0E, 0x25, 0x02, 0x09,
+       0x05, 0x02, 0x69, 0x28, 0x01, 0x00, 0x03, 0x09, 0xAB, 0x04, 0x03, 0x69,
+       0x28, 0x25, 0x04, 0xFE, 0x64, 0x02, 0x04, 0x06, 0x0D, 0x02, 0x04, 0x01,
+       0x05, 0x0F, 0x06, 0x02, 0x66, 0x28, 0x01, 0x01, 0x85, 0x3D, 0x98, 0x98,
+       0x02, 0x01, 0x00, 0x04, 0xB5, 0x01, 0x0C, 0x0E, 0x05, 0x02, 0x6F, 0x28,
+       0xBE, 0x01, 0x03, 0x0E, 0x05, 0x02, 0x6A, 0x28, 0xBC, 0x26, 0x79, 0x3D,
+       0x26, 0x01, 0x20, 0x10, 0x06, 0x02, 0x6A, 0x28, 0x3F, 0x43, 0x11, 0x01,
+       0x01, 0x17, 0x05, 0x02, 0x6A, 0x28, 0xBE, 0x26, 0x01, 0x81, 0x05, 0x0F,
+       0x06, 0x02, 0x6A, 0x28, 0x26, 0x7B, 0x3D, 0x7A, 0x43, 0xB3, 0x8F, 0x2C,
+       0x01, 0x86, 0x03, 0x10, 0x03, 0x00, 0x76, 0x2C, 0xC8, 0x03, 0x01, 0x01,
+       0x02, 0x03, 0x02, 0x02, 0x00, 0x06, 0x21, 0xBE, 0x26, 0x26, 0x01, 0x02,
+       0x0A, 0x43, 0x01, 0x06, 0x0F, 0x37, 0x06, 0x02, 0x6A, 0x28, 0x03, 0x02,
+       0xBE, 0x02, 0x01, 0x01, 0x01, 0x0B, 0x01, 0x03, 0x08, 0x0E, 0x05, 0x02,
+       0x6A, 0x28, 0x04, 0x08, 0x02, 0x01, 0x06, 0x04, 0x01, 0x00, 0x03, 0x02,
+       0xBC, 0x26, 0x03, 0x03, 0x26, 0x01, 0x84, 0x00, 0x0F, 0x06, 0x02, 0x6B,
+       0x28, 0x81, 0x43, 0xB3, 0x02, 0x02, 0x02, 0x01, 0x02, 0x03, 0x4D, 0x26,
+       0x06, 0x01, 0x28, 0x25, 0x98, 0x00, 0x02, 0x03, 0x00, 0x03, 0x01, 0x02,
+       0x00, 0x94, 0x02, 0x01, 0x02, 0x00, 0x39, 0x26, 0x01, 0x00, 0x0E, 0x06,
+       0x02, 0x5D, 0x00, 0xCC, 0x04, 0x74, 0x02, 0x01, 0x00, 0x03, 0x00, 0xBE,
+       0xA7, 0x26, 0x06, 0x80, 0x43, 0xBE, 0x01, 0x01, 0x38, 0x0E, 0x06, 0x06,
+       0x25, 0x01, 0x81, 0x7F, 0x04, 0x2E, 0x01, 0x80, 0x40, 0x38, 0x0E, 0x06,
+       0x07, 0x25, 0x01, 0x83, 0xFE, 0x00, 0x04, 0x20, 0x01, 0x80, 0x41, 0x38,
+       0x0E, 0x06, 0x07, 0x25, 0x01, 0x84, 0x80, 0x00, 0x04, 0x12, 0x01, 0x80,
+       0x42, 0x38, 0x0E, 0x06, 0x07, 0x25, 0x01, 0x88, 0x80, 0x00, 0x04, 0x04,
+       0x01, 0x00, 0x43, 0x25, 0x02, 0x00, 0x37, 0x03, 0x00, 0x04, 0xFF, 0x39,
+       0x98, 0x76, 0x2C, 0xC6, 0x05, 0x09, 0x02, 0x00, 0x01, 0x83, 0xFF, 0x7F,
+       0x17, 0x03, 0x00, 0x8F, 0x2C, 0x01, 0x86, 0x03, 0x10, 0x06, 0x3A, 0xB8,
+       0x26, 0x7E, 0x3C, 0x40, 0x25, 0x26, 0x01, 0x08, 0x0B, 0x37, 0x01, 0x8C,
+       0x80, 0x00, 0x37, 0x17, 0x02, 0x00, 0x17, 0x02, 0x00, 0x01, 0x8C, 0x80,
+       0x00, 0x17, 0x06, 0x19, 0x26, 0x01, 0x81, 0x7F, 0x17, 0x06, 0x05, 0x01,
+       0x84, 0x80, 0x00, 0x37, 0x26, 0x01, 0x83, 0xFE, 0x00, 0x17, 0x06, 0x05,
+       0x01, 0x88, 0x80, 0x00, 0x37, 0x03, 0x00, 0x04, 0x09, 0x02, 0x00, 0x01,
+       0x8C, 0x88, 0x01, 0x17, 0x03, 0x00, 0x16, 0xBC, 0xA7, 0x26, 0x06, 0x23,
+       0xBC, 0xA7, 0x26, 0x15, 0x26, 0x06, 0x18, 0x26, 0x01, 0x82, 0x00, 0x0F,
+       0x06, 0x05, 0x01, 0x82, 0x00, 0x04, 0x01, 0x26, 0x03, 0x01, 0x81, 0x02,
+       0x01, 0xB3, 0x02, 0x01, 0x12, 0x04, 0x65, 0x98, 0x13, 0x04, 0x5A, 0x98,
+       0x14, 0x98, 0x02, 0x00, 0x2A, 0x00, 0x00, 0xB6, 0x26, 0x57, 0x06, 0x07,
+       0x25, 0x06, 0x02, 0x63, 0x28, 0x04, 0x74, 0x00, 0x00, 0xBF, 0x01, 0x03,
+       0xBD, 0x43, 0x25, 0x43, 0x00, 0x00, 0xBC, 0xC3, 0x00, 0x03, 0x01, 0x00,
+       0x03, 0x00, 0xBC, 0xA7, 0x26, 0x06, 0x32, 0xBE, 0x03, 0x01, 0xBE, 0x03,
+       0x02, 0x02, 0x01, 0x01, 0x02, 0x10, 0x02, 0x01, 0x01, 0x06, 0x0C, 0x17,
+       0x02, 0x02, 0x01, 0x01, 0x0E, 0x02, 0x02, 0x01, 0x03, 0x0E, 0x37, 0x17,
+       0x06, 0x11, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x5A, 0x01, 0x02, 0x0B,
+       0x02, 0x01, 0x08, 0x0B, 0x37, 0x03, 0x00, 0x04, 0x4B, 0x98, 0x02, 0x00,
+       0x00, 0x00, 0xBC, 0x01, 0x01, 0x0E, 0x05, 0x02, 0x62, 0x28, 0xBE, 0x01,
+       0x08, 0x08, 0x7F, 0x2E, 0x0E, 0x05, 0x02, 0x62, 0x28, 0x00, 0x00, 0xBC,
+       0x85, 0x2E, 0x05, 0x15, 0x01, 0x01, 0x0E, 0x05, 0x02, 0x66, 0x28, 0xBE,
+       0x01, 0x00, 0x0E, 0x05, 0x02, 0x66, 0x28, 0x01, 0x02, 0x85, 0x3D, 0x04,
+       0x1C, 0x01, 0x19, 0x0E, 0x05, 0x02, 0x66, 0x28, 0xBE, 0x01, 0x18, 0x0E,
+       0x05, 0x02, 0x66, 0x28, 0x81, 0x01, 0x18, 0xB3, 0x86, 0x81, 0x01, 0x18,
+       0x30, 0x05, 0x02, 0x66, 0x28, 0x00, 0x00, 0xBC, 0x06, 0x02, 0x67, 0x28,
+       0x00, 0x00, 0x01, 0x02, 0x94, 0xBF, 0x01, 0x08, 0x0B, 0xBF, 0x08, 0x00,
+       0x00, 0x01, 0x03, 0x94, 0xBF, 0x01, 0x08, 0x0B, 0xBF, 0x08, 0x01, 0x08,
+       0x0B, 0xBF, 0x08, 0x00, 0x00, 0x01, 0x01, 0x94, 0xBF, 0x00, 0x00, 0x3A,
+       0x26, 0x55, 0x05, 0x01, 0x00, 0x25, 0xCC, 0x04, 0x76, 0x02, 0x03, 0x00,
+       0x8E, 0x2E, 0x03, 0x01, 0x01, 0x00, 0x26, 0x02, 0x01, 0x0A, 0x06, 0x10,
+       0x26, 0x01, 0x01, 0x0B, 0x8D, 0x08, 0x2C, 0x02, 0x00, 0x0E, 0x06, 0x01,
+       0x00, 0x59, 0x04, 0x6A, 0x25, 0x01, 0x7F, 0x00, 0x00, 0x01, 0x15, 0x84,
+       0x3D, 0x43, 0x4F, 0x25, 0x4F, 0x25, 0x29, 0x00, 0x00, 0x01, 0x01, 0x43,
+       0xC1, 0x00, 0x00, 0x43, 0x38, 0x94, 0x43, 0x26, 0x06, 0x05, 0xBF, 0x25,
+       0x5A, 0x04, 0x78, 0x25, 0x00, 0x00, 0x26, 0x01, 0x81, 0xAC, 0x00, 0x0E,
+       0x06, 0x04, 0x25, 0x01, 0x7F, 0x00, 0x97, 0x56, 0x00, 0x02, 0x03, 0x00,
+       0x76, 0x2C, 0x97, 0x03, 0x01, 0x02, 0x01, 0x01, 0x0F, 0x17, 0x02, 0x01,
+       0x01, 0x04, 0x11, 0x01, 0x0F, 0x17, 0x02, 0x01, 0x01, 0x08, 0x11, 0x01,
+       0x0F, 0x17, 0x01, 0x00, 0x38, 0x0E, 0x06, 0x10, 0x25, 0x01, 0x00, 0x01,
+       0x18, 0x02, 0x00, 0x06, 0x03, 0x46, 0x04, 0x01, 0x47, 0x04, 0x80, 0x68,
+       0x01, 0x01, 0x38, 0x0E, 0x06, 0x10, 0x25, 0x01, 0x01, 0x01, 0x10, 0x02,
+       0x00, 0x06, 0x03, 0x46, 0x04, 0x01, 0x47, 0x04, 0x80, 0x52, 0x01, 0x02,
+       0x38, 0x0E, 0x06, 0x0F, 0x25, 0x01, 0x01, 0x01, 0x20, 0x02, 0x00, 0x06,
+       0x03, 0x46, 0x04, 0x01, 0x47, 0x04, 0x3D, 0x01, 0x03, 0x38, 0x0E, 0x06,
+       0x0E, 0x25, 0x25, 0x01, 0x10, 0x02, 0x00, 0x06, 0x03, 0x44, 0x04, 0x01,
+       0x45, 0x04, 0x29, 0x01, 0x04, 0x38, 0x0E, 0x06, 0x0E, 0x25, 0x25, 0x01,
+       0x20, 0x02, 0x00, 0x06, 0x03, 0x44, 0x04, 0x01, 0x45, 0x04, 0x15, 0x01,
+       0x05, 0x38, 0x0E, 0x06, 0x0C, 0x25, 0x25, 0x02, 0x00, 0x06, 0x03, 0x48,
+       0x04, 0x01, 0x49, 0x04, 0x03, 0x65, 0x28, 0x25, 0x00, 0x00, 0x97, 0x01,
+       0x0C, 0x11, 0x01, 0x02, 0x0F, 0x00, 0x00, 0x97, 0x01, 0x0C, 0x11, 0x26,
+       0x58, 0x43, 0x01, 0x03, 0x0A, 0x17, 0x00, 0x00, 0x97, 0x01, 0x0C, 0x11,
+       0x01, 0x01, 0x0E, 0x00, 0x00, 0x97, 0x01, 0x0C, 0x11, 0x57, 0x00, 0x00,
+       0x1B, 0x01, 0x00, 0x72, 0x2E, 0x26, 0x06, 0x1F, 0x01, 0x01, 0x38, 0x0E,
+       0x06, 0x06, 0x25, 0x01, 0x00, 0x9B, 0x04, 0x11, 0x01, 0x02, 0x38, 0x0E,
+       0x06, 0x0A, 0x25, 0x74, 0x2E, 0x06, 0x03, 0x01, 0x10, 0x37, 0x04, 0x01,
+       0x25, 0x04, 0x01, 0x25, 0x78, 0x2E, 0x05, 0x33, 0x2F, 0x06, 0x30, 0x83,
+       0x2E, 0x01, 0x14, 0x38, 0x0E, 0x06, 0x06, 0x25, 0x01, 0x02, 0x37, 0x04,
+       0x22, 0x01, 0x15, 0x38, 0x0E, 0x06, 0x09, 0x25, 0xAA, 0x06, 0x03, 0x01,
+       0x7F, 0x9B, 0x04, 0x13, 0x01, 0x16, 0x38, 0x0E, 0x06, 0x06, 0x25, 0x01,
+       0x01, 0x37, 0x04, 0x07, 0x25, 0x01, 0x04, 0x37, 0x01, 0x00, 0x25, 0x1A,
+       0x06, 0x03, 0x01, 0x08, 0x37, 0x00, 0x00, 0x1B, 0x26, 0x05, 0x0F, 0x2F,
+       0x06, 0x0C, 0x83, 0x2E, 0x01, 0x15, 0x0E, 0x06, 0x04, 0x25, 0xAA, 0x04,
+       0x01, 0x20, 0x00, 0x00, 0xCA, 0x01, 0x07, 0x17, 0x01, 0x01, 0x0F, 0x06,
+       0x02, 0x6F, 0x28, 0x00, 0x01, 0x03, 0x00, 0x29, 0x1A, 0x06, 0x05, 0x02,
+       0x00, 0x84, 0x3D, 0x00, 0xCA, 0x25, 0x04, 0x74, 0x00, 0x01, 0x14, 0xCD,
+       0x01, 0x01, 0xDA, 0x29, 0x26, 0x01, 0x00, 0xC5, 0x01, 0x16, 0xCD, 0xD3,
+       0x29, 0x00, 0x00, 0x01, 0x0B, 0xDA, 0x4B, 0x26, 0x26, 0x01, 0x03, 0x08,
+       0xD9, 0xD9, 0x18, 0x26, 0x55, 0x06, 0x02, 0x25, 0x00, 0xD9, 0x1D, 0x26,
+       0x06, 0x05, 0x81, 0x43, 0xD4, 0x04, 0x77, 0x25, 0x04, 0x6C, 0x00, 0x21,
+       0x01, 0x0F, 0xDA, 0x26, 0x8F, 0x2C, 0x01, 0x86, 0x03, 0x10, 0x06, 0x0C,
+       0x01, 0x04, 0x08, 0xD9, 0x7D, 0x2E, 0xDA, 0x75, 0x2E, 0xDA, 0x04, 0x02,
+       0x5B, 0xD9, 0x26, 0xD8, 0x81, 0x43, 0xD4, 0x00, 0x02, 0xA1, 0xA3, 0x08,
+       0x9F, 0x08, 0xA2, 0x08, 0xA4, 0x08, 0xA0, 0x08, 0x27, 0x08, 0x03, 0x00,
+       0x01, 0x01, 0xDA, 0x01, 0x27, 0x8B, 0x2E, 0x08, 0x8E, 0x2E, 0x01, 0x01,
+       0x0B, 0x08, 0x02, 0x00, 0x06, 0x04, 0x5B, 0x02, 0x00, 0x08, 0x80, 0x2C,
+       0x38, 0x09, 0x26, 0x58, 0x06, 0x24, 0x02, 0x00, 0x05, 0x04, 0x43, 0x5B,
+       0x43, 0x5C, 0x01, 0x04, 0x09, 0x26, 0x55, 0x06, 0x03, 0x25, 0x01, 0x00,
+       0x26, 0x01, 0x04, 0x08, 0x02, 0x00, 0x08, 0x03, 0x00, 0x43, 0x01, 0x04,
+       0x08, 0x38, 0x08, 0x43, 0x04, 0x03, 0x25, 0x01, 0x7F, 0x03, 0x01, 0xD9,
+       0x91, 0x2C, 0xD8, 0x77, 0x01, 0x04, 0x19, 0x77, 0x01, 0x04, 0x08, 0x01,
+       0x1C, 0x32, 0x77, 0x01, 0x20, 0xD4, 0x8A, 0x8B, 0x2E, 0xD6, 0x8E, 0x2E,
+       0x26, 0x01, 0x01, 0x0B, 0xD8, 0x8D, 0x43, 0x26, 0x06, 0x0F, 0x5A, 0x38,
+       0x2C, 0x26, 0xC4, 0x05, 0x02, 0x5F, 0x28, 0xD8, 0x43, 0x5B, 0x43, 0x04,
+       0x6E, 0x5D, 0x01, 0x01, 0xDA, 0x01, 0x00, 0xDA, 0x02, 0x00, 0x06, 0x81,
+       0x46, 0x02, 0x00, 0xD8, 0xA1, 0x06, 0x0E, 0x01, 0x83, 0xFE, 0x01, 0xD8,
+       0x86, 0xA1, 0x01, 0x04, 0x09, 0x26, 0xD8, 0x5A, 0xD6, 0xA3, 0x06, 0x16,
+       0x01, 0x00, 0xD8, 0x88, 0xA3, 0x01, 0x04, 0x09, 0x26, 0xD8, 0x01, 0x02,
+       0x09, 0x26, 0xD8, 0x01, 0x00, 0xDA, 0x01, 0x03, 0x09, 0xD5, 0x9F, 0x06,
+       0x0C, 0x01, 0x01, 0xD8, 0x01, 0x01, 0xD8, 0x7F, 0x2E, 0x01, 0x08, 0x09,
+       0xDA, 0xA2, 0x06, 0x19, 0x01, 0x0D, 0xD8, 0xA2, 0x01, 0x04, 0x09, 0x26,
+       0xD8, 0x01, 0x02, 0x09, 0xD8, 0x41, 0x06, 0x03, 0x01, 0x03, 0xD7, 0x42,
+       0x06, 0x03, 0x01, 0x01, 0xD7, 0xA4, 0x26, 0x06, 0x22, 0x01, 0x0A, 0xD8,
+       0x01, 0x04, 0x09, 0x26, 0xD8, 0x5C, 0xD8, 0x3F, 0x01, 0x00, 0x26, 0x01,
+       0x20, 0x0A, 0x06, 0x0C, 0x9D, 0x11, 0x01, 0x01, 0x17, 0x06, 0x02, 0x26,
+       0xD8, 0x59, 0x04, 0x6E, 0x5D, 0x04, 0x01, 0x25, 0xA0, 0x06, 0x0A, 0x01,
+       0x0B, 0xD8, 0x01, 0x02, 0xD8, 0x01, 0x82, 0x00, 0xD8, 0x27, 0x26, 0x06,
+       0x1F, 0x01, 0x10, 0xD8, 0x01, 0x04, 0x09, 0x26, 0xD8, 0x5C, 0xD8, 0x82,
+       0x2C, 0x01, 0x00, 0x9D, 0x0F, 0x06, 0x0A, 0x26, 0x1E, 0x26, 0xDA, 0x81,
+       0x43, 0xD4, 0x59, 0x04, 0x72, 0x5D, 0x04, 0x01, 0x25, 0x02, 0x01, 0x55,
+       0x05, 0x11, 0x01, 0x15, 0xD8, 0x02, 0x01, 0x26, 0xD8, 0x26, 0x06, 0x06,
+       0x5A, 0x01, 0x00, 0xDA, 0x04, 0x77, 0x25, 0x00, 0x00, 0x01, 0x10, 0xDA,
+       0x76, 0x2C, 0x26, 0xC9, 0x06, 0x0C, 0xA8, 0x23, 0x26, 0x5B, 0xD9, 0x26,
+       0xD8, 0x81, 0x43, 0xD4, 0x04, 0x0D, 0x26, 0xC7, 0x43, 0xA8, 0x22, 0x26,
+       0x59, 0xD9, 0x26, 0xDA, 0x81, 0x43, 0xD4, 0x00, 0x00, 0x99, 0x01, 0x14,
+       0xDA, 0x01, 0x0C, 0xD9, 0x81, 0x01, 0x0C, 0xD4, 0x00, 0x00, 0x4E, 0x26,
+       0x01, 0x00, 0x0E, 0x06, 0x02, 0x5D, 0x00, 0xCA, 0x25, 0x04, 0x73, 0x00,
+       0x26, 0xD8, 0xD4, 0x00, 0x00, 0x26, 0xDA, 0xD4, 0x00, 0x01, 0x03, 0x00,
+       0x40, 0x25, 0x26, 0x01, 0x10, 0x17, 0x06, 0x06, 0x01, 0x04, 0xDA, 0x02,
+       0x00, 0xDA, 0x26, 0x01, 0x08, 0x17, 0x06, 0x06, 0x01, 0x03, 0xDA, 0x02,
+       0x00, 0xDA, 0x26, 0x01, 0x20, 0x17, 0x06, 0x06, 0x01, 0x05, 0xDA, 0x02,
+       0x00, 0xDA, 0x26, 0x01, 0x80, 0x40, 0x17, 0x06, 0x06, 0x01, 0x06, 0xDA,
+       0x02, 0x00, 0xDA, 0x01, 0x04, 0x17, 0x06, 0x06, 0x01, 0x02, 0xDA, 0x02,
+       0x00, 0xDA, 0x00, 0x00, 0x26, 0x01, 0x08, 0x4C, 0xDA, 0xDA, 0x00, 0x00,
+       0x26, 0x01, 0x10, 0x4C, 0xDA, 0xD8, 0x00, 0x00, 0x26, 0x4F, 0x06, 0x02,
+       0x25, 0x00, 0xCA, 0x25, 0x04, 0x76
 };
 
 static const uint16_t t0_caddr[] = {
@@ -795,78 +807,81 @@ static const uint16_t t0_caddr[] = {
        274,
        279,
        284,
-       293,
-       306,
-       310,
-       335,
-       341,
-       360,
-       371,
-       405,
-       521,
-       525,
-       590,
-       605,
-       616,
-       634,
-       663,
-       673,
-       709,
-       719,
-       789,
+       289,
+       294,
+       303,
+       316,
+       320,
+       345,
+       351,
+       370,
+       381,
+       415,
+       535,
+       539,
+       604,
+       619,
+       630,
+       648,
+       677,
+       687,
+       723,
+       733,
        803,
-       809,
-       869,
-       888,
+       817,
+       823,
+       883,
+       902,
        937,
-       1013,
-       1040,
-       1071,
-       1082,
-       1383,
-       1530,
-       1554,
-       1770,
-       1784,
-       1793,
-       1797,
-       1861,
-       1882,
-       1938,
-       1945,
-       1956,
-       1972,
-       1978,
-       1989,
-       2024,
-       2036,
-       2042,
-       2057,
-       2073,
-       2229,
-       2238,
-       2251,
-       2260,
-       2267,
-       2370,
-       2391,
-       2404,
-       2420,
-       2438,
-       2470,
-       2504,
-       2814,
-       2850,
-       2863,
-       2877,
-       2882,
-       2887,
-       2953,
+       986,
+       1062,
+       1089,
+       1120,
+       1131,
+       1456,
+       1603,
+       1627,
+       1843,
+       1857,
+       1866,
+       1870,
+       1934,
+       1955,
+       2011,
+       2018,
+       2029,
+       2045,
+       2051,
+       2062,
+       2097,
+       2109,
+       2115,
+       2130,
+       2146,
+       2302,
+       2311,
+       2324,
+       2333,
+       2340,
+       2443,
+       2464,
+       2477,
+       2493,
+       2511,
+       2543,
+       2577,
+       2925,
        2961,
-       2969
+       2974,
+       2988,
+       2993,
+       2998,
+       3064,
+       3072,
+       3080
 };
 
-#define T0_INTERPRETED   82
+#define T0_INTERPRETED   85
 
 #define T0_ENTER(ip, rp, slot)   do { \
                const unsigned char *t0_newip; \
@@ -887,7 +902,7 @@ name(void *ctx) \
        T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \
 }
 
-T0_DEFENTRY(br_ssl_hs_client_init_main, 161)
+T0_DEFENTRY(br_ssl_hs_client_init_main, 166)
 
 #define T0_NEXT(t0ipp)   (*(*(t0ipp)) ++)
 
@@ -1228,6 +1243,16 @@ br_ssl_hs_client_run(void *t0ctx)
                                }
                                break;
                        case 30: {
+                               /* copy-protocol-name */
+
+       size_t idx = T0_POP();
+       size_t len = strlen(ENG->protocol_names[idx]);
+       memcpy(ENG->pad, ENG->protocol_names[idx], len);
+       T0_PUSH(len);
+
+                               }
+                               break;
+                       case 31: {
                                /* data-get8 */
 
        size_t addr = T0_POP();
@@ -1235,14 +1260,14 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 31: {
+                       case 32: {
                                /* discard-input */
 
        ENG->hlen_in = 0;
 
                                }
                                break;
-                       case 32: {
+                       case 33: {
                                /* do-client-sign */
 
        size_t sig_len;
@@ -1256,7 +1281,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 33: {
+                       case 34: {
                                /* do-ecdh */
 
        unsigned prf_id = T0_POP();
@@ -1273,7 +1298,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 34: {
+                       case 35: {
                                /* do-rsa-encrypt */
 
        int x;
@@ -1288,7 +1313,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 35: {
+                       case 36: {
                                /* do-static-ecdh */
 
        unsigned prf_id = T0_POP();
@@ -1300,17 +1325,34 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 36: {
+                       case 37: {
                                /* drop */
  (void)T0_POP(); 
                                }
                                break;
-                       case 37: {
+                       case 38: {
                                /* dup */
  T0_PUSH(T0_PEEK(0)); 
                                }
                                break;
-                       case 38: {
+                       case 39: {
+                               /* ext-ALPN-length */
+
+       size_t u, len;
+
+       if (ENG->protocol_names_num == 0) {
+               T0_PUSH(0);
+               T0_RET();
+       }
+       len = 6;
+       for (u = 0; u < ENG->protocol_names_num; u ++) {
+               len += 1 + strlen(ENG->protocol_names[u]);
+       }
+       T0_PUSH(len);
+
+                               }
+                               break;
+                       case 40: {
                                /* fail */
 
        br_ssl_engine_fail(ENG, (int)T0_POPi());
@@ -1318,14 +1360,14 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 39: {
+                       case 41: {
                                /* flush-record */
 
        br_ssl_engine_flush_record(ENG);
 
                                }
                                break;
-                       case 40: {
+                       case 42: {
                                /* get-client-chain */
 
        uint32_t auth_types;
@@ -1347,7 +1389,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 41: {
+                       case 43: {
                                /* get-key-type-usages */
 
        const br_x509_class *xc;
@@ -1364,7 +1406,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 42: {
+                       case 44: {
                                /* get16 */
 
        size_t addr = (size_t)T0_POP();
@@ -1372,7 +1414,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 43: {
+                       case 45: {
                                /* get32 */
 
        size_t addr = (size_t)T0_POP();
@@ -1380,7 +1422,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 44: {
+                       case 46: {
                                /* get8 */
 
        size_t addr = (size_t)T0_POP();
@@ -1388,14 +1430,14 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 45: {
+                       case 47: {
                                /* has-input? */
 
        T0_PUSHi(-(ENG->hlen_in != 0));
 
                                }
                                break;
-                       case 46: {
+                       case 48: {
                                /* memcmp */
 
        size_t len = (size_t)T0_POP();
@@ -1406,7 +1448,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 47: {
+                       case 49: {
                                /* memcpy */
 
        size_t len = (size_t)T0_POP();
@@ -1416,7 +1458,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 48: {
+                       case 50: {
                                /* mkrand */
 
        size_t len = (size_t)T0_POP();
@@ -1425,21 +1467,21 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 49: {
+                       case 51: {
                                /* more-incoming-bytes? */
 
        T0_PUSHi(ENG->hlen_in != 0 || !br_ssl_engine_recvrec_finished(ENG));
 
                                }
                                break;
-                       case 50: {
+                       case 52: {
                                /* multihash-init */
 
        br_multihash_init(&ENG->mhash);
 
                                }
                                break;
-                       case 51: {
+                       case 53: {
                                /* neg */
 
        uint32_t a = T0_POP();
@@ -1447,7 +1489,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 52: {
+                       case 54: {
                                /* not */
 
        uint32_t a = T0_POP();
@@ -1455,7 +1497,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 53: {
+                       case 55: {
                                /* or */
 
        uint32_t b = T0_POP();
@@ -1464,12 +1506,12 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 54: {
+                       case 56: {
                                /* over */
  T0_PUSH(T0_PEEK(1)); 
                                }
                                break;
-                       case 55: {
+                       case 57: {
                                /* read-chunk-native */
 
        size_t clen = ENG->hlen_in;
@@ -1493,7 +1535,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 56: {
+                       case 58: {
                                /* read8-native */
 
        if (ENG->hlen_in > 0) {
@@ -1511,7 +1553,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 57: {
+                       case 59: {
                                /* set-server-curve */
 
        const br_x509_class *xc;
@@ -1524,7 +1566,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 58: {
+                       case 60: {
                                /* set16 */
 
        size_t addr = (size_t)T0_POP();
@@ -1532,7 +1574,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 59: {
+                       case 61: {
                                /* set8 */
 
        size_t addr = (size_t)T0_POP();
@@ -1540,7 +1582,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 60: {
+                       case 62: {
                                /* strlen */
 
        void *str = (unsigned char *)ENG + (size_t)T0_POP();
@@ -1548,7 +1590,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 61: {
+                       case 63: {
                                /* supported-curves */
 
        uint32_t x = ENG->iec == NULL ? 0 : ENG->iec->supported_curves;
@@ -1556,7 +1598,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 62: {
+                       case 64: {
                                /* supported-hash-functions */
 
        int i;
@@ -1575,26 +1617,26 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 63: {
+                       case 65: {
                                /* supports-ecdsa? */
 
        T0_PUSHi(-(ENG->iecdsa != 0));
 
                                }
                                break;
-                       case 64: {
+                       case 66: {
                                /* supports-rsa-sign? */
 
        T0_PUSHi(-(ENG->irsavrfy != 0));
 
                                }
                                break;
-                       case 65: {
+                       case 67: {
                                /* swap */
  T0_SWAP(); 
                                }
                                break;
-                       case 66: {
+                       case 68: {
                                /* switch-aesgcm-in */
 
        int is_client, prf_id;
@@ -1608,7 +1650,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 67: {
+                       case 69: {
                                /* switch-aesgcm-out */
 
        int is_client, prf_id;
@@ -1622,7 +1664,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 68: {
+                       case 70: {
                                /* switch-cbc-in */
 
        int is_client, prf_id, mac_id, aes;
@@ -1638,7 +1680,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 69: {
+                       case 71: {
                                /* switch-cbc-out */
 
        int is_client, prf_id, mac_id, aes;
@@ -1654,7 +1696,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 70: {
+                       case 72: {
                                /* switch-chapol-in */
 
        int is_client, prf_id;
@@ -1665,7 +1707,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 71: {
+                       case 73: {
                                /* switch-chapol-out */
 
        int is_client, prf_id;
@@ -1676,7 +1718,26 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 72: {
+                       case 74: {
+                               /* test-protocol-name */
+
+       size_t len = T0_POP();
+       size_t u;
+
+       for (u = 0; u < ENG->protocol_names_num; u ++) {
+               const char *name;
+
+               name = ENG->protocol_names[u];
+               if (len == strlen(name) && memcmp(ENG->pad, name, len) == 0) {
+                       T0_PUSH(u);
+                       T0_RET();
+               }
+       }
+       T0_PUSHi(-1);
+
+                               }
+                               break;
+                       case 75: {
                                /* total-chain-length */
 
        size_t u;
@@ -1690,7 +1751,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 73: {
+                       case 76: {
                                /* u>> */
 
        int c = (int)T0_POPi();
@@ -1699,7 +1760,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 74: {
+                       case 77: {
                                /* verify-SKE-sig */
 
        size_t sig_len = T0_POP();
@@ -1710,7 +1771,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 75: {
+                       case 78: {
                                /* write-blob-chunk */
 
        size_t clen = ENG->hlen_out;
@@ -1734,7 +1795,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 76: {
+                       case 79: {
                                /* write8-native */
 
        unsigned char x;
@@ -1753,7 +1814,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 77: {
+                       case 80: {
                                /* x509-append */
 
        const br_x509_class *xc;
@@ -1765,7 +1826,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 78: {
+                       case 81: {
                                /* x509-end-cert */
 
        const br_x509_class *xc;
@@ -1775,7 +1836,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 79: {
+                       case 82: {
                                /* x509-end-chain */
 
        const br_x509_class *xc;
@@ -1785,7 +1846,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 80: {
+                       case 83: {
                                /* x509-start-cert */
 
        const br_x509_class *xc;
@@ -1795,7 +1856,7 @@ br_ssl_hs_client_run(void *t0ctx)
 
                                }
                                break;
-                       case 81: {
+                       case 84: {
                                /* x509-start-chain */
 
        const br_x509_class *xc;
index 37c554c..4067b4d 100644 (file)
@@ -429,6 +429,21 @@ addr-ctx: hash_id
 : ext-point-format-length ( -- len )
        supported-curves if 6 else 0 then ;
 
+\ Length of ALPN extension.
+cc: ext-ALPN-length ( -- len ) {
+       size_t u, len;
+
+       if (ENG->protocol_names_num == 0) {
+               T0_PUSH(0);
+               T0_RET();
+       }
+       len = 6;
+       for (u = 0; u < ENG->protocol_names_num; u ++) {
+               len += 1 + strlen(ENG->protocol_names[u]);
+       }
+       T0_PUSH(len);
+}
+
 \ Write handshake message: ClientHello
 : write-ClientHello ( -- )
        { ; total-ext-length }
@@ -438,6 +453,7 @@ addr-ctx: hash_id
        ext-reneg-length ext-sni-length + ext-frag-length +
        ext-signatures-length +
        ext-supported-curves-length + ext-point-format-length +
+       ext-ALPN-length +
        >total-ext-length
 
        \ ClientHello type
@@ -542,6 +558,21 @@ addr-ctx: hash_id
                        0x0002 write16          \ extension length
                        0x0100 write16          \ value: 1 format: uncompressed
                then
+               ext-ALPN-length dup if
+                       0x0010 write16          \ extension type (16)
+                       4 - dup write16         \ extension length
+                       2- write16              \ list length
+                       addr-protocol_names_num get16 0
+                       begin
+                               dup2 > while
+                               dup copy-protocol-name
+                               dup write8 addr-pad swap write-blob
+                               1+
+                       repeat
+                       2drop
+               else
+                       drop
+               then
                ext-padding-amount 0< ifnot
                        0x0015 write16          \ extension value (21)
                        ext-padding-amount
@@ -595,6 +626,24 @@ addr-ctx: hash_id
                then
        then ;
 
+\ Read the ALPN extension from the server. It must contain a single name,
+\ and that name must match one of our names.
+: read-ALPN-from-server ( lim -- lim )
+       \ Extension contents length.
+       read16 open-elt
+       \ Length of list of names.
+       read16 open-elt
+       \ There should be a single name.
+       read8 addr-pad swap dup { len } read-blob
+       close-elt
+       close-elt
+       len test-protocol-name dup 0< if
+               3 flag? if ERR_UNEXPECTED fail then
+               drop
+       else
+               1+ addr-selected_protocol set16
+       then ;
+
 \ Save a value in a 16-bit field, or check it in case of session resumption.
 : check-resume ( val addr resume -- )
        if get16 = ifnot ERR_RESUME_MISMATCH fail then else set16 then ;
@@ -688,6 +737,7 @@ cc: DEBUG-BLOB ( addr len -- ) {
                ext-signatures-length { ok-signatures }
                ext-supported-curves-length { ok-curves }
                ext-point-format-length { ok-points }
+               ext-ALPN-length { ok-ALPN }
                begin dup while
                        read16
                        case
@@ -753,6 +803,15 @@ cc: DEBUG-BLOB ( addr len -- ) {
                                        read-ignore-16
                                endof
 
+                               \ ALPN.
+                               0x0010 of
+                                       ok-ALPN ifnot
+                                               ERR_EXTRA_EXTENSION fail
+                                       then
+                                       0 >ok-ALPN
+                                       read-ALPN-from-server
+                               endof
+
                                ERR_EXTRA_EXTENSION fail
                        endcase
                repeat
@@ -1102,6 +1161,7 @@ cc: do-client-sign ( -- sig_len ) {
 : do-handshake ( -- )
        0 addr-application_data set8
        22 addr-record_type_out set8
+       0 addr-selected_protocol set16
        multihash-init
 
        write-ClientHello
index bbd37ac..28a4032 100644 (file)
@@ -157,6 +157,8 @@ addr-eng: pad
 addr-eng: action
 addr-eng: alert
 addr-eng: close_received
+addr-eng: protocol_names_num
+addr-eng: selected_protocol
 
 \ Similar to 'addr-eng:', for fields in the 'session' substructure.
 : addr-session-field:
@@ -1235,3 +1237,33 @@ cc: get-key-type-usages ( -- key-type-usages ) {
 
        \ Return key type and usages.
        get-key-type-usages ;
+
+\ =======================================================================
+
+\ Copy a specific protocol name from the list to the pad. The byte
+\ length is returned.
+cc: copy-protocol-name ( idx -- len ) {
+       size_t idx = T0_POP();
+       size_t len = strlen(ENG->protocol_names[idx]);
+       memcpy(ENG->pad, ENG->protocol_names[idx], len);
+       T0_PUSH(len);
+}
+
+\ Compare name in pad with the configured list of protocol names.
+\ If a match is found, then the index is returned; otherwise, -1
+\ is returned.
+cc: test-protocol-name ( len -- n ) {
+       size_t len = T0_POP();
+       size_t u;
+
+       for (u = 0; u < ENG->protocol_names_num; u ++) {
+               const char *name;
+
+               name = ENG->protocol_names[u];
+               if (len == strlen(name) && memcmp(ENG->pad, name, len) == 0) {
+                       T0_PUSH(u);
+                       T0_RET();
+               }
+       }
+       T0_PUSHi(-1);
+}
index c8f934c..e25c37b 100644 (file)
@@ -452,8 +452,9 @@ static const uint8_t t0_codeblock[] = {
        0x00, 0x01, 0x00, 0x0B, 0x00, 0x00, 0x01, 0x00, 0x0E, 0x00, 0x00, 0x01,
        0x00, 0x0F, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x01, 0x01, 0x08,
        0x00, 0x00, 0x01, 0x01, 0x09, 0x00, 0x00, 0x01, 0x02, 0x08, 0x00, 0x00,
-       0x28, 0x28, 0x00, 0x00, 0x01, T0_INT1(BR_ERR_BAD_CCS), 0x00, 0x00,
-       0x01, T0_INT1(BR_ERR_BAD_FINISHED), 0x00, 0x00, 0x01,
+       0x01, 0x02, 0x09, 0x00, 0x00, 0x29, 0x29, 0x00, 0x00, 0x01,
+       T0_INT1(BR_ERR_BAD_CCS), 0x00, 0x00, 0x01,
+       T0_INT1(BR_ERR_BAD_FINISHED), 0x00, 0x00, 0x01,
        T0_INT1(BR_ERR_BAD_FRAGLEN), 0x00, 0x00, 0x01,
        T0_INT1(BR_ERR_BAD_HANDSHAKE), 0x00, 0x00, 0x01,
        T0_INT1(BR_ERR_BAD_PARAM), 0x00, 0x00, 0x01,
@@ -484,17 +485,21 @@ static const uint8_t t0_codeblock[] = {
        0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, ecdhe_point_len)),
        0x00, 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, flags)),
        0x00, 0x00, 0x01, T0_INT2(offsetof(br_ssl_server_context, hashes)),
-       0x00, 0x00, 0x75, 0x01,
+       0x00, 0x00, 0x79, 0x01,
        T0_INT2(BR_MAX_CIPHER_SUITES * sizeof(br_suite_translated)), 0x00,
        0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, log_max_frag_len)),
        0x00, 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, pad)), 0x00,
        0x00, 0x01,
        T0_INT2(offsetof(br_ssl_engine_context, peer_log_max_frag_len)), 0x00,
+       0x00, 0x01,
+       T0_INT2(offsetof(br_ssl_engine_context, protocol_names_num)), 0x00,
        0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, record_type_in)),
        0x00, 0x00, 0x01,
        T0_INT2(offsetof(br_ssl_engine_context, record_type_out)), 0x00, 0x00,
        0x01, T0_INT2(offsetof(br_ssl_engine_context, reneg)), 0x00, 0x00,
        0x01, T0_INT2(offsetof(br_ssl_engine_context, saved_finished)), 0x00,
+       0x00, 0x01,
+       T0_INT2(offsetof(br_ssl_engine_context, selected_protocol)), 0x00,
        0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, server_name)),
        0x00, 0x00, 0x01,
        T0_INT2(offsetof(br_ssl_engine_context, server_random)), 0x00, 0x00,
@@ -514,233 +519,244 @@ static const uint8_t t0_codeblock[] = {
        T0_INT2(offsetof(br_ssl_engine_context, version_max)), 0x00, 0x00,
        0x01, T0_INT2(offsetof(br_ssl_engine_context, version_min)), 0x00,
        0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, version_out)),
-       0x00, 0x00, 0x09, 0x29, 0x58, 0x06, 0x02, 0x64, 0x2A, 0x00, 0x00, 0x01,
-       0x01, 0x00, 0x01, 0x03, 0x00, 0x93, 0x29, 0x5E, 0x46, 0x97, 0x29, 0x05,
-       0x04, 0x5F, 0x01, 0x00, 0x00, 0x02, 0x00, 0x0F, 0x06, 0x02, 0x97, 0x00,
-       0x5E, 0x04, 0x6B, 0x00, 0x06, 0x02, 0x64, 0x2A, 0x00, 0x00, 0x29, 0x84,
-       0x46, 0x05, 0x03, 0x01, 0x0C, 0x08, 0x46, 0x72, 0x2D, 0x9F, 0x1C, 0x7F,
-       0x01, 0x0C, 0x32, 0x00, 0x00, 0x29, 0x21, 0x01, 0x08, 0x0C, 0x46, 0x5C,
-       0x21, 0x08, 0x00, 0x01, 0x03, 0x00, 0x01, 0x00, 0x71, 0x41, 0x2B, 0x19,
-       0x37, 0x06, 0x07, 0x02, 0x00, 0xC5, 0x03, 0x00, 0x04, 0x75, 0x01, 0x00,
-       0xBD, 0x02, 0x00, 0x29, 0x19, 0x13, 0x06, 0x02, 0x6B, 0x2A, 0xC5, 0x04,
-       0x76, 0x00, 0x01, 0x00, 0x71, 0x41, 0x01, 0x16, 0x82, 0x41, 0x35, 0xA7,
-       0x34, 0x06, 0x02, 0x6D, 0x2A, 0x06, 0x0A, 0xCC, 0x01, 0x00, 0xC8, 0x01,
-       0x00, 0xA3, 0x04, 0x80, 0x46, 0xCC, 0xC9, 0x28, 0xCE, 0x4D, 0x06, 0x01,
-       0xCA, 0xCD, 0x2B, 0x4D, 0x06, 0x31, 0x01, 0x00, 0xA4, 0x29, 0x58, 0x06,
-       0x0F, 0x01, 0x02, 0x9C, 0x05, 0x02, 0x36, 0x2A, 0x28, 0xA8, 0xA6, 0x29,
-       0xBE, 0x28, 0x04, 0x19, 0x29, 0x5A, 0x06, 0x0B, 0x28, 0x01, 0x02, 0x9C,
-       0x05, 0x02, 0x6A, 0x2A, 0xA8, 0x04, 0x0A, 0xAA, 0x29, 0x05, 0x04, 0x28,
-       0xA2, 0x04, 0x02, 0xA9, 0xA5, 0x04, 0x01, 0xA8, 0x01, 0x00, 0xA3, 0x01,
-       0x00, 0xC8, 0x3D, 0x01, 0x01, 0x71, 0x41, 0x01, 0x17, 0x82, 0x41, 0x00,
-       0x00, 0x39, 0x39, 0x00, 0x01, 0x03, 0x00, 0x2B, 0x19, 0x37, 0x06, 0x04,
-       0xC4, 0x28, 0x04, 0x78, 0x01, 0x02, 0x02, 0x00, 0xBC, 0x19, 0x37, 0x06,
-       0x04, 0xC4, 0x28, 0x04, 0x78, 0x02, 0x00, 0x01, 0x84, 0x00, 0x08, 0x2A,
-       0x00, 0x00, 0x7B, 0x2E, 0x46, 0x12, 0x01, 0x01, 0x13, 0x36, 0x00, 0x00,
-       0x01, 0x7F, 0x99, 0xC4, 0x29, 0x01, 0x07, 0x13, 0x01, 0x00, 0x39, 0x0F,
-       0x06, 0x09, 0x28, 0x01, 0x10, 0x13, 0x06, 0x01, 0xBB, 0x04, 0x2A, 0x01,
-       0x01, 0x39, 0x0F, 0x06, 0x21, 0x28, 0x28, 0x83, 0x2F, 0x01, 0x01, 0x0F,
-       0x01, 0x01, 0x9C, 0x38, 0x06, 0x0F, 0x2B, 0x19, 0x37, 0x06, 0x04, 0xC4,
-       0x28, 0x04, 0x78, 0x01, 0x80, 0x64, 0xBD, 0x04, 0x03, 0x01, 0x00, 0x99,
-       0x04, 0x03, 0x6D, 0x2A, 0x28, 0x04, 0x40, 0x01, 0x29, 0x03, 0x00, 0x09,
-       0x29, 0x58, 0x06, 0x02, 0x64, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x94, 0x01,
-       0x0F, 0x13, 0x00, 0x00, 0x70, 0x2F, 0x01, 0x00, 0x39, 0x0F, 0x06, 0x10,
-       0x28, 0x29, 0x01, 0x01, 0x0E, 0x06, 0x03, 0x28, 0x01, 0x02, 0x70, 0x41,
-       0x01, 0x00, 0x04, 0x22, 0x01, 0x01, 0x39, 0x0F, 0x06, 0x15, 0x28, 0x01,
-       0x00, 0x70, 0x41, 0x29, 0x01, 0x80, 0x64, 0x0F, 0x06, 0x05, 0x01, 0x82,
-       0x00, 0x08, 0x2A, 0x5A, 0x00, 0x04, 0x07, 0x28, 0x01, 0x82, 0x00, 0x08,
-       0x2A, 0x28, 0x00, 0x00, 0x01, 0x00, 0x30, 0x06, 0x05, 0x3C, 0xA0, 0x38,
-       0x04, 0x78, 0x29, 0x06, 0x04, 0x01, 0x01, 0x89, 0x41, 0x00, 0x00, 0x01,
-       0x1F, 0x13, 0x01, 0x12, 0x0F, 0x05, 0x02, 0x6E, 0x2A, 0x72, 0x2D, 0x29,
-       0xC0, 0x05, 0x02, 0x6D, 0x2A, 0x9F, 0x27, 0x00, 0x00, 0x30, 0x06, 0x0B,
-       0x81, 0x2F, 0x01, 0x14, 0x0E, 0x06, 0x02, 0x6D, 0x2A, 0x04, 0x11, 0xC4,
-       0x01, 0x07, 0x13, 0x29, 0x01, 0x02, 0x0E, 0x06, 0x06, 0x06, 0x02, 0x6D,
-       0x2A, 0x04, 0x70, 0x28, 0xB9, 0x01, 0x01, 0x0E, 0x34, 0x38, 0x06, 0x02,
-       0x60, 0x2A, 0x29, 0x01, 0x01, 0xBF, 0x37, 0xAB, 0x00, 0x01, 0xB0, 0x01,
-       0x0B, 0x0F, 0x05, 0x02, 0x6D, 0x2A, 0x29, 0x01, 0x03, 0x0F, 0x06, 0x08,
-       0xB7, 0x06, 0x02, 0x64, 0x2A, 0x46, 0x28, 0x00, 0x46, 0x57, 0xB7, 0x9E,
-       0x29, 0x06, 0x23, 0xB7, 0x9E, 0x29, 0x56, 0x29, 0x06, 0x18, 0x29, 0x01,
-       0x82, 0x00, 0x10, 0x06, 0x05, 0x01, 0x82, 0x00, 0x04, 0x01, 0x29, 0x03,
-       0x00, 0x7F, 0x02, 0x00, 0xAC, 0x02, 0x00, 0x53, 0x04, 0x65, 0x95, 0x54,
-       0x04, 0x5A, 0x95, 0x95, 0x55, 0x29, 0x06, 0x02, 0x36, 0x00, 0x28, 0x2C,
-       0x00, 0x02, 0x29, 0x01, 0x20, 0x13, 0x05, 0x02, 0x6E, 0x2A, 0x01, 0x0F,
-       0x13, 0x03, 0x00, 0xA6, 0x8D, 0x2D, 0x01, 0x86, 0x03, 0x11, 0x06, 0x23,
-       0xB6, 0x29, 0x01, 0x81, 0x7F, 0x13, 0x5C, 0x01, 0x01, 0x12, 0x02, 0x00,
-       0x0F, 0x05, 0x02, 0x66, 0x2A, 0x01, 0x08, 0x12, 0x29, 0x01, 0x02, 0x0B,
-       0x39, 0x01, 0x06, 0x10, 0x38, 0x06, 0x02, 0x68, 0x2A, 0x04, 0x0D, 0x02,
-       0x00, 0x01, 0x01, 0x0F, 0x06, 0x04, 0x01, 0x00, 0x04, 0x02, 0x01, 0x02,
-       0x20, 0x05, 0x02, 0x68, 0x2A, 0xB6, 0x29, 0x03, 0x01, 0x29, 0x01, 0x84,
-       0x00, 0x10, 0x06, 0x02, 0x69, 0x2A, 0x7F, 0x46, 0xAC, 0x02, 0x01, 0x50,
-       0x29, 0x06, 0x01, 0x2A, 0x28, 0x95, 0x00, 0x00, 0x1D, 0xB0, 0x01, 0x0F,
-       0x0F, 0x05, 0x02, 0x6D, 0x2A, 0x00, 0x0A, 0xB0, 0x01, 0x01, 0x0F, 0x05,
-       0x02, 0x6D, 0x2A, 0xB6, 0x29, 0x03, 0x00, 0x73, 0x3F, 0x74, 0x01, 0x20,
-       0xAC, 0xB8, 0x29, 0x01, 0x20, 0x10, 0x06, 0x02, 0x6C, 0x2A, 0x29, 0x88,
-       0x41, 0x87, 0x46, 0xAC, 0x1A, 0x03, 0x01, 0xB6, 0x9E, 0x01, 0x00, 0x03,
-       0x02, 0x01, 0x00, 0x03, 0x03, 0x7D, 0x9A, 0x17, 0x39, 0x08, 0x03, 0x04,
-       0x03, 0x05, 0x29, 0x06, 0x80, 0x6D, 0xB6, 0x29, 0x03, 0x06, 0x02, 0x01,
-       0x06, 0x0A, 0x29, 0x72, 0x2D, 0x0F, 0x06, 0x04, 0x01, 0x7F, 0x03, 0x03,
-       0x29, 0x01, 0x81, 0x7F, 0x0F, 0x06, 0x0A, 0x83, 0x2F, 0x06, 0x02, 0x65,
-       0x2A, 0x01, 0x7F, 0x03, 0x02, 0x29, 0x01, 0x81, 0xAC, 0x00, 0x0F, 0x06,
-       0x11, 0x02, 0x00, 0x90, 0x2D, 0x11, 0x02, 0x00, 0x8F, 0x2D, 0x0B, 0x13,
-       0x06, 0x04, 0x01, 0x7F, 0x03, 0x00, 0xBA, 0x29, 0x58, 0x06, 0x03, 0x28,
-       0x04, 0x26, 0x01, 0x00, 0x9C, 0x06, 0x0B, 0x01, 0x02, 0x0C, 0x75, 0x08,
-       0x02, 0x06, 0x46, 0x3F, 0x04, 0x16, 0x28, 0x02, 0x05, 0x02, 0x04, 0x11,
-       0x06, 0x02, 0x63, 0x2A, 0x02, 0x06, 0x02, 0x05, 0x3F, 0x02, 0x05, 0x01,
-       0x04, 0x08, 0x03, 0x05, 0x04, 0xFF, 0x0F, 0x28, 0x01, 0x00, 0x03, 0x07,
-       0xB8, 0x9E, 0x29, 0x06, 0x09, 0xB8, 0x05, 0x04, 0x01, 0x7F, 0x03, 0x07,
-       0x04, 0x74, 0x95, 0x01, 0x00, 0x85, 0x41, 0x01, 0x88, 0x04, 0x7C, 0x3F,
-       0x01, 0x84, 0x80, 0x80, 0x00, 0x78, 0x40, 0x29, 0x06, 0x80, 0x42, 0xB6,
-       0x9E, 0x29, 0x06, 0x3C, 0xB6, 0x01, 0x00, 0x39, 0x0F, 0x06, 0x04, 0x28,
-       0xAF, 0x04, 0x2F, 0x01, 0x01, 0x39, 0x0F, 0x06, 0x04, 0x28, 0xAD, 0x04,
-       0x25, 0x01, 0x83, 0xFE, 0x01, 0x39, 0x0F, 0x06, 0x04, 0x28, 0xAE, 0x04,
-       0x19, 0x01, 0x0D, 0x39, 0x0F, 0x06, 0x04, 0x28, 0xB4, 0x04, 0x0F, 0x01,
-       0x0A, 0x39, 0x0F, 0x06, 0x04, 0x28, 0xB5, 0x04, 0x05, 0x28, 0xB2, 0x01,
-       0x00, 0x28, 0x04, 0x41, 0x95, 0x95, 0x02, 0x01, 0x02, 0x03, 0x13, 0x03,
-       0x01, 0x02, 0x00, 0x58, 0x06, 0x08, 0x73, 0x2D, 0x91, 0x3F, 0x01, 0x80,
-       0x56, 0x9B, 0x8F, 0x2D, 0x29, 0x02, 0x00, 0x10, 0x06, 0x03, 0x28, 0x02,
-       0x00, 0x29, 0x01, 0x86, 0x00, 0x0B, 0x06, 0x02, 0x67, 0x2A, 0x02, 0x00,
-       0x90, 0x2D, 0x0B, 0x06, 0x04, 0x01, 0x80, 0x46, 0x9B, 0x02, 0x01, 0x06,
-       0x10, 0x8D, 0x2D, 0x02, 0x00, 0x0D, 0x06, 0x05, 0x28, 0x8D, 0x2D, 0x04,
-       0x04, 0x01, 0x00, 0x03, 0x01, 0x29, 0x8D, 0x3F, 0x29, 0x8E, 0x3F, 0x29,
-       0x91, 0x3F, 0x01, 0x86, 0x03, 0x11, 0x03, 0x08, 0x02, 0x02, 0x06, 0x04,
-       0x01, 0x02, 0x83, 0x41, 0x02, 0x07, 0x05, 0x03, 0x01, 0x28, 0x9B, 0x43,
-       0x28, 0x01, 0x82, 0x01, 0x07, 0x7C, 0x2D, 0x13, 0x29, 0x7C, 0x3F, 0x29,
-       0x01, 0x81, 0x7F, 0x13, 0x59, 0x36, 0x46, 0x01, 0x08, 0x12, 0x59, 0x01,
-       0x02, 0x13, 0x38, 0x01, 0x0C, 0x0C, 0x03, 0x09, 0x78, 0x2E, 0x42, 0x13,
-       0x29, 0x78, 0x40, 0x05, 0x04, 0x01, 0x00, 0x03, 0x09, 0x02, 0x01, 0x06,
-       0x03, 0x01, 0x7F, 0x00, 0x87, 0x01, 0x20, 0x33, 0x01, 0x20, 0x88, 0x41,
-       0x75, 0x29, 0x03, 0x05, 0x29, 0x02, 0x04, 0x0B, 0x06, 0x80, 0x49, 0x29,
-       0x2D, 0x29, 0x94, 0x29, 0x01, 0x0C, 0x12, 0x29, 0x01, 0x01, 0x0F, 0x46,
-       0x01, 0x02, 0x0F, 0x38, 0x06, 0x0A, 0x29, 0x02, 0x09, 0x13, 0x05, 0x04,
-       0x5F, 0x01, 0x00, 0x29, 0x02, 0x08, 0x05, 0x0E, 0x29, 0x01, 0x81, 0x70,
-       0x13, 0x01, 0x20, 0x0E, 0x06, 0x04, 0x5F, 0x01, 0x00, 0x29, 0x29, 0x06,
-       0x10, 0x02, 0x05, 0x5E, 0x3F, 0x02, 0x05, 0x3F, 0x02, 0x05, 0x01, 0x04,
-       0x08, 0x03, 0x05, 0x04, 0x01, 0x5F, 0x01, 0x04, 0x08, 0x04, 0xFF, 0x30,
-       0x28, 0x02, 0x05, 0x75, 0x09, 0x01, 0x02, 0x12, 0x29, 0x05, 0x03, 0x01,
-       0x28, 0x9B, 0x76, 0x41, 0x18, 0x05, 0x03, 0x01, 0x28, 0x9B, 0x01, 0x00,
-       0x00, 0x00, 0xAA, 0xA9, 0x00, 0x04, 0x72, 0x2D, 0xC3, 0x06, 0x16, 0xB6,
-       0x29, 0x01, 0x84, 0x00, 0x10, 0x06, 0x02, 0x69, 0x2A, 0x29, 0x03, 0x00,
-       0x7F, 0x46, 0xAC, 0x02, 0x00, 0x72, 0x2D, 0x9F, 0x26, 0x72, 0x2D, 0x29,
-       0xC1, 0x46, 0xC0, 0x03, 0x01, 0x03, 0x02, 0x02, 0x01, 0x02, 0x02, 0x38,
-       0x06, 0x14, 0xB8, 0x29, 0x03, 0x03, 0x7F, 0x46, 0xAC, 0x02, 0x03, 0x72,
-       0x2D, 0x9F, 0x02, 0x02, 0x06, 0x03, 0x25, 0x04, 0x01, 0x23, 0x95, 0x00,
-       0x00, 0xB0, 0x01, 0x10, 0x0F, 0x05, 0x02, 0x6D, 0x2A, 0x00, 0x00, 0x96,
-       0xB0, 0x01, 0x14, 0x0E, 0x06, 0x02, 0x6D, 0x2A, 0x7F, 0x01, 0x0C, 0x08,
-       0x01, 0x0C, 0xAC, 0x95, 0x7F, 0x29, 0x01, 0x0C, 0x08, 0x01, 0x0C, 0x31,
-       0x05, 0x02, 0x61, 0x2A, 0x00, 0x02, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00,
-       0x92, 0x02, 0x01, 0x02, 0x00, 0x3B, 0x29, 0x01, 0x00, 0x0F, 0x06, 0x02,
-       0x5F, 0x00, 0xC6, 0x04, 0x74, 0x00, 0xB6, 0x01, 0x01, 0x0E, 0x06, 0x02,
-       0x62, 0x2A, 0xB8, 0x29, 0x29, 0x5A, 0x46, 0x01, 0x05, 0x11, 0x38, 0x06,
-       0x02, 0x62, 0x2A, 0x01, 0x08, 0x08, 0x29, 0x7E, 0x2F, 0x0B, 0x06, 0x0D,
-       0x29, 0x01, 0x01, 0x46, 0x0C, 0x3E, 0x29, 0x7E, 0x41, 0x80, 0x41, 0x04,
-       0x01, 0x28, 0x00, 0x00, 0xB6, 0x83, 0x2F, 0x01, 0x00, 0x39, 0x0F, 0x06,
-       0x13, 0x28, 0x01, 0x01, 0x0F, 0x05, 0x02, 0x65, 0x2A, 0xB8, 0x06, 0x02,
-       0x65, 0x2A, 0x01, 0x02, 0x83, 0x41, 0x04, 0x28, 0x01, 0x02, 0x39, 0x0F,
-       0x06, 0x1F, 0x28, 0x01, 0x0D, 0x0F, 0x05, 0x02, 0x65, 0x2A, 0xB8, 0x01,
-       0x0C, 0x0F, 0x05, 0x02, 0x65, 0x2A, 0x7F, 0x01, 0x0C, 0xAC, 0x84, 0x7F,
-       0x01, 0x0C, 0x31, 0x05, 0x02, 0x65, 0x2A, 0x04, 0x03, 0x65, 0x2A, 0x28,
-       0x00, 0x00, 0xB6, 0x9E, 0xB6, 0x9E, 0x29, 0x06, 0x1D, 0xB8, 0x06, 0x03,
-       0xB2, 0x04, 0x15, 0xB6, 0x29, 0x01, 0x81, 0x7F, 0x0D, 0x06, 0x0C, 0x29,
-       0x85, 0x08, 0x01, 0x00, 0x46, 0x41, 0x85, 0x46, 0xAC, 0x04, 0x01, 0xBE,
-       0x04, 0x60, 0x95, 0x95, 0x00, 0x00, 0xB1, 0x29, 0x5A, 0x06, 0x07, 0x28,
-       0x06, 0x02, 0x63, 0x2A, 0x04, 0x74, 0x00, 0x00, 0xB9, 0x01, 0x03, 0xB7,
-       0x46, 0x28, 0x46, 0x00, 0x00, 0xB6, 0xBE, 0x00, 0x03, 0x01, 0x00, 0x03,
-       0x00, 0xB6, 0x9E, 0x29, 0x06, 0x32, 0xB8, 0x03, 0x01, 0xB8, 0x03, 0x02,
-       0x02, 0x01, 0x01, 0x02, 0x11, 0x02, 0x01, 0x01, 0x06, 0x0D, 0x13, 0x02,
-       0x02, 0x01, 0x01, 0x0F, 0x02, 0x02, 0x01, 0x03, 0x0F, 0x38, 0x13, 0x06,
-       0x11, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x5D, 0x01, 0x02, 0x0C, 0x02,
-       0x01, 0x08, 0x0C, 0x38, 0x03, 0x00, 0x04, 0x4B, 0x95, 0x02, 0x00, 0x00,
-       0x00, 0xB6, 0x9E, 0xB3, 0x7C, 0x3F, 0x95, 0x00, 0x00, 0xB6, 0x9E, 0xB6,
-       0x9E, 0x01, 0x00, 0x78, 0x40, 0x29, 0x06, 0x15, 0xB6, 0x29, 0x01, 0x20,
-       0x0B, 0x06, 0x0B, 0x01, 0x01, 0x46, 0x0C, 0x78, 0x2E, 0x38, 0x78, 0x40,
-       0x04, 0x01, 0x28, 0x04, 0x68, 0x95, 0x95, 0x00, 0x00, 0x01, 0x02, 0x92,
-       0xB9, 0x01, 0x08, 0x0C, 0xB9, 0x08, 0x00, 0x00, 0x01, 0x03, 0x92, 0xB9,
-       0x01, 0x08, 0x0C, 0xB9, 0x08, 0x01, 0x08, 0x0C, 0xB9, 0x08, 0x00, 0x00,
-       0x01, 0x01, 0x92, 0xB9, 0x00, 0x00, 0x3C, 0x29, 0x58, 0x05, 0x01, 0x00,
-       0x28, 0xC6, 0x04, 0x76, 0x02, 0x03, 0x00, 0x8C, 0x2F, 0x03, 0x01, 0x01,
-       0x00, 0x29, 0x02, 0x01, 0x0B, 0x06, 0x10, 0x29, 0x01, 0x01, 0x0C, 0x8B,
-       0x08, 0x2D, 0x02, 0x00, 0x0F, 0x06, 0x01, 0x00, 0x5C, 0x04, 0x6A, 0x28,
-       0x01, 0x7F, 0x00, 0x00, 0x2B, 0x19, 0x37, 0x06, 0x04, 0xC4, 0x28, 0x04,
-       0x78, 0x01, 0x16, 0x82, 0x41, 0x01, 0x00, 0xD7, 0x01, 0x00, 0xD6, 0x2B,
-       0x01, 0x17, 0x82, 0x41, 0x00, 0x00, 0x01, 0x15, 0x82, 0x41, 0x46, 0x52,
-       0x28, 0x52, 0x28, 0x2B, 0x00, 0x00, 0x01, 0x01, 0x46, 0xBC, 0x00, 0x00,
-       0x46, 0x39, 0x92, 0x46, 0x29, 0x06, 0x05, 0xB9, 0x28, 0x5D, 0x04, 0x78,
-       0x28, 0x00, 0x02, 0x03, 0x00, 0x72, 0x2D, 0x94, 0x03, 0x01, 0x02, 0x01,
-       0x01, 0x0F, 0x13, 0x02, 0x01, 0x01, 0x04, 0x12, 0x01, 0x0F, 0x13, 0x02,
-       0x01, 0x01, 0x08, 0x12, 0x01, 0x0F, 0x13, 0x01, 0x00, 0x39, 0x0F, 0x06,
-       0x10, 0x28, 0x01, 0x00, 0x01, 0x18, 0x02, 0x00, 0x06, 0x03, 0x49, 0x04,
-       0x01, 0x4A, 0x04, 0x80, 0x68, 0x01, 0x01, 0x39, 0x0F, 0x06, 0x10, 0x28,
-       0x01, 0x01, 0x01, 0x10, 0x02, 0x00, 0x06, 0x03, 0x49, 0x04, 0x01, 0x4A,
-       0x04, 0x80, 0x52, 0x01, 0x02, 0x39, 0x0F, 0x06, 0x0F, 0x28, 0x01, 0x01,
-       0x01, 0x20, 0x02, 0x00, 0x06, 0x03, 0x49, 0x04, 0x01, 0x4A, 0x04, 0x3D,
-       0x01, 0x03, 0x39, 0x0F, 0x06, 0x0E, 0x28, 0x28, 0x01, 0x10, 0x02, 0x00,
-       0x06, 0x03, 0x47, 0x04, 0x01, 0x48, 0x04, 0x29, 0x01, 0x04, 0x39, 0x0F,
-       0x06, 0x0E, 0x28, 0x28, 0x01, 0x20, 0x02, 0x00, 0x06, 0x03, 0x47, 0x04,
-       0x01, 0x48, 0x04, 0x15, 0x01, 0x05, 0x39, 0x0F, 0x06, 0x0C, 0x28, 0x28,
-       0x02, 0x00, 0x06, 0x03, 0x4B, 0x04, 0x01, 0x4C, 0x04, 0x03, 0x64, 0x2A,
-       0x28, 0x00, 0x00, 0x94, 0x01, 0x0C, 0x12, 0x01, 0x02, 0x10, 0x00, 0x00,
-       0x94, 0x01, 0x0C, 0x12, 0x29, 0x5B, 0x46, 0x01, 0x03, 0x0B, 0x13, 0x00,
-       0x00, 0x94, 0x01, 0x0C, 0x12, 0x01, 0x01, 0x0F, 0x00, 0x00, 0x94, 0x01,
-       0x0C, 0x12, 0x5A, 0x00, 0x00, 0x1B, 0x01, 0x00, 0x6F, 0x2F, 0x29, 0x06,
-       0x1F, 0x01, 0x01, 0x39, 0x0F, 0x06, 0x06, 0x28, 0x01, 0x00, 0x98, 0x04,
-       0x11, 0x01, 0x02, 0x39, 0x0F, 0x06, 0x0A, 0x28, 0x71, 0x2F, 0x06, 0x03,
-       0x01, 0x10, 0x38, 0x04, 0x01, 0x28, 0x04, 0x01, 0x28, 0x77, 0x2F, 0x05,
-       0x33, 0x30, 0x06, 0x30, 0x81, 0x2F, 0x01, 0x14, 0x39, 0x0F, 0x06, 0x06,
-       0x28, 0x01, 0x02, 0x38, 0x04, 0x22, 0x01, 0x15, 0x39, 0x0F, 0x06, 0x09,
-       0x28, 0xA1, 0x06, 0x03, 0x01, 0x7F, 0x98, 0x04, 0x13, 0x01, 0x16, 0x39,
-       0x0F, 0x06, 0x06, 0x28, 0x01, 0x01, 0x38, 0x04, 0x07, 0x28, 0x01, 0x04,
-       0x38, 0x01, 0x00, 0x28, 0x19, 0x06, 0x03, 0x01, 0x08, 0x38, 0x00, 0x00,
-       0x1B, 0x29, 0x05, 0x0F, 0x30, 0x06, 0x0C, 0x81, 0x2F, 0x01, 0x15, 0x0F,
-       0x06, 0x04, 0x28, 0xA1, 0x04, 0x01, 0x22, 0x00, 0x00, 0xC4, 0x01, 0x07,
-       0x13, 0x01, 0x01, 0x10, 0x06, 0x02, 0x6D, 0x2A, 0x00, 0x01, 0x03, 0x00,
-       0x2B, 0x19, 0x06, 0x05, 0x02, 0x00, 0x82, 0x41, 0x00, 0xC4, 0x28, 0x04,
-       0x74, 0x00, 0x01, 0x14, 0xC7, 0x01, 0x01, 0xD7, 0x2B, 0x29, 0x01, 0x00,
-       0xBF, 0x01, 0x16, 0xC7, 0xCB, 0x2B, 0x00, 0x00, 0x01, 0x0B, 0xD7, 0x4E,
-       0x29, 0x29, 0x01, 0x03, 0x08, 0xD6, 0xD6, 0x14, 0x29, 0x58, 0x06, 0x02,
-       0x28, 0x00, 0xD6, 0x1E, 0x29, 0x06, 0x05, 0x7F, 0x46, 0xCF, 0x04, 0x77,
-       0x28, 0x04, 0x6C, 0x00, 0x01, 0x00, 0xD1, 0x8D, 0x2D, 0x01, 0x86, 0x03,
-       0x11, 0x06, 0x05, 0x5E, 0x01, 0x00, 0xD2, 0x08, 0x4D, 0x08, 0x01, 0x03,
-       0x08, 0x01, 0x0D, 0xD7, 0xD6, 0x01, 0x00, 0xD1, 0xD7, 0x01, 0x01, 0xD1,
-       0x28, 0x8D, 0x2D, 0x01, 0x86, 0x03, 0x11, 0x06, 0x08, 0x01, 0x00, 0xD2,
-       0xD5, 0x01, 0x01, 0xD2, 0x28, 0x4D, 0xD5, 0x16, 0x15, 0x29, 0x58, 0x06,
-       0x02, 0x28, 0x00, 0xD5, 0x1F, 0x29, 0x06, 0x05, 0x7F, 0x46, 0xCF, 0x04,
-       0x77, 0x28, 0x04, 0x6C, 0x00, 0x96, 0x01, 0x14, 0xD7, 0x01, 0x0C, 0xD6,
-       0x7F, 0x01, 0x0C, 0xCF, 0x00, 0x03, 0x03, 0x00, 0x01, 0x02, 0xD7, 0x01,
-       0x80, 0x46, 0x83, 0x2F, 0x01, 0x02, 0x0F, 0x06, 0x0C, 0x02, 0x00, 0x06,
-       0x04, 0x01, 0x05, 0x04, 0x02, 0x01, 0x1D, 0x04, 0x02, 0x01, 0x00, 0x03,
-       0x01, 0x80, 0x2F, 0x06, 0x04, 0x01, 0x05, 0x04, 0x02, 0x01, 0x00, 0x03,
-       0x02, 0x02, 0x01, 0x02, 0x02, 0x08, 0x29, 0x06, 0x03, 0x01, 0x02, 0x08,
-       0x08, 0xD6, 0x8D, 0x2D, 0xD5, 0x86, 0x01, 0x04, 0x17, 0x86, 0x01, 0x04,
-       0x08, 0x01, 0x1C, 0x33, 0x86, 0x01, 0x20, 0xCF, 0x01, 0x20, 0xD7, 0x87,
-       0x01, 0x20, 0xCF, 0x72, 0x2D, 0xD5, 0x01, 0x00, 0xD7, 0x02, 0x01, 0x02,
-       0x02, 0x08, 0x29, 0x06, 0x29, 0xD5, 0x02, 0x01, 0x29, 0x06, 0x10, 0x01,
-       0x83, 0xFE, 0x01, 0xD5, 0x01, 0x04, 0x09, 0x29, 0xD5, 0x5D, 0x84, 0x46,
-       0xD0, 0x04, 0x01, 0x28, 0x02, 0x02, 0x06, 0x0C, 0x01, 0x01, 0xD5, 0x01,
-       0x01, 0xD5, 0x80, 0x2F, 0x01, 0x08, 0x09, 0xD7, 0x04, 0x01, 0x28, 0x00,
-       0x00, 0x01, 0x0E, 0xD7, 0x01, 0x00, 0xD6, 0x00, 0x03, 0x72, 0x2D, 0xC1,
-       0x05, 0x01, 0x00, 0x78, 0x2E, 0x01, 0x00, 0x9A, 0x12, 0x01, 0x01, 0x13,
-       0x5A, 0x06, 0x03, 0x5C, 0x04, 0x75, 0x03, 0x00, 0x28, 0x02, 0x00, 0x24,
-       0x29, 0x58, 0x06, 0x02, 0x36, 0x2A, 0x03, 0x01, 0x8D, 0x2D, 0x01, 0x86,
-       0x03, 0x11, 0x03, 0x02, 0x01, 0x0C, 0xD7, 0x02, 0x01, 0x7A, 0x2F, 0x08,
-       0x02, 0x02, 0x01, 0x02, 0x13, 0x08, 0x01, 0x06, 0x08, 0xD6, 0x01, 0x03,
-       0xD7, 0x02, 0x00, 0xD5, 0x79, 0x7A, 0x2F, 0xD0, 0x02, 0x02, 0x06, 0x0D,
-       0x8A, 0x2F, 0xD7, 0x72, 0x2D, 0xC2, 0x01, 0x01, 0x0C, 0x01, 0x03, 0x08,
-       0xD7, 0x02, 0x01, 0xD5, 0x7F, 0x02, 0x01, 0xCF, 0x00, 0x00, 0x51, 0x29,
-       0x01, 0x00, 0x0F, 0x06, 0x02, 0x5F, 0x00, 0xC4, 0x28, 0x04, 0x73, 0x00,
-       0x29, 0xD7, 0xCF, 0x00, 0x00, 0x01, 0x00, 0x72, 0x2D, 0xC0, 0x06, 0x0C,
-       0x5E, 0x39, 0x06, 0x08, 0x01, 0x80, 0x41, 0xD7, 0x01, 0x80, 0x42, 0xD7,
-       0x45, 0x06, 0x07, 0x5C, 0x39, 0x06, 0x03, 0x01, 0x01, 0xD7, 0x44, 0x06,
-       0x08, 0x5C, 0x39, 0x06, 0x04, 0x01, 0x80, 0x40, 0xD7, 0x46, 0x28, 0x00,
-       0x01, 0x01, 0x00, 0x03, 0x00, 0x45, 0x44, 0x38, 0x05, 0x14, 0x01, 0x01,
-       0x01, 0x80, 0x7C, 0xD3, 0x03, 0x00, 0x01, 0x03, 0x01, 0x80, 0x7C, 0xD3,
-       0x02, 0x00, 0x08, 0x46, 0x28, 0x00, 0x45, 0x06, 0x07, 0x01, 0x01, 0x43,
-       0x28, 0xD3, 0x03, 0x00, 0x44, 0x06, 0x0A, 0x01, 0x03, 0x43, 0x28, 0xD3,
-       0x02, 0x00, 0x08, 0x03, 0x00, 0x28, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00,
-       0x01, 0x04, 0xD4, 0x01, 0x05, 0xD4, 0x01, 0x06, 0xD4, 0x01, 0x03, 0xD4,
-       0x01, 0x02, 0xD4, 0x0A, 0x5F, 0x00, 0x01, 0x03, 0x00, 0x39, 0x01, 0x01,
-       0x02, 0x00, 0x0C, 0x13, 0x05, 0x01, 0x00, 0x5E, 0x01, 0x03, 0x3A, 0x06,
-       0x07, 0x02, 0x00, 0xD7, 0x01, 0x02, 0x3A, 0xD7, 0x00, 0x00, 0x29, 0x01,
-       0x08, 0x4F, 0xD7, 0xD7, 0x00, 0x00, 0x29, 0x01, 0x10, 0x4F, 0xD7, 0xD5,
-       0x00, 0x00, 0x29, 0x52, 0x06, 0x02, 0x28, 0x00, 0xC4, 0x28, 0x04, 0x76
+       0x00, 0x00, 0x09, 0x2A, 0x5B, 0x06, 0x02, 0x68, 0x2B, 0x00, 0x00, 0x01,
+       0x01, 0x00, 0x01, 0x03, 0x00, 0x99, 0x2A, 0x61, 0x47, 0x9D, 0x2A, 0x05,
+       0x04, 0x63, 0x01, 0x00, 0x00, 0x02, 0x00, 0x0F, 0x06, 0x02, 0x9D, 0x00,
+       0x61, 0x04, 0x6B, 0x00, 0x06, 0x02, 0x68, 0x2B, 0x00, 0x00, 0x2A, 0x89,
+       0x47, 0x05, 0x03, 0x01, 0x0C, 0x08, 0x47, 0x76, 0x2E, 0xA5, 0x1C, 0x83,
+       0x01, 0x0C, 0x33, 0x00, 0x00, 0x2A, 0x22, 0x01, 0x08, 0x0C, 0x47, 0x5F,
+       0x22, 0x08, 0x00, 0x01, 0x03, 0x00, 0x01, 0x00, 0x75, 0x42, 0x2C, 0x19,
+       0x38, 0x06, 0x07, 0x02, 0x00, 0xCC, 0x03, 0x00, 0x04, 0x75, 0x01, 0x00,
+       0xC4, 0x02, 0x00, 0x2A, 0x19, 0x13, 0x06, 0x02, 0x6F, 0x2B, 0xCC, 0x04,
+       0x76, 0x00, 0x01, 0x00, 0x75, 0x42, 0x01, 0x16, 0x87, 0x42, 0x01, 0x00,
+       0x8A, 0x40, 0x36, 0xAE, 0x35, 0x06, 0x02, 0x71, 0x2B, 0x06, 0x0A, 0xD3,
+       0x01, 0x00, 0xCF, 0x01, 0x00, 0xAA, 0x04, 0x80, 0x46, 0xD3, 0xD0, 0x29,
+       0xD5, 0x4E, 0x06, 0x01, 0xD1, 0xD4, 0x2C, 0x4E, 0x06, 0x31, 0x01, 0x00,
+       0xAB, 0x2A, 0x5B, 0x06, 0x0F, 0x01, 0x02, 0xA2, 0x05, 0x02, 0x37, 0x2B,
+       0x29, 0xAF, 0xAD, 0x2A, 0xC5, 0x29, 0x04, 0x19, 0x2A, 0x5D, 0x06, 0x0B,
+       0x29, 0x01, 0x02, 0xA2, 0x05, 0x02, 0x6E, 0x2B, 0xAF, 0x04, 0x0A, 0xB1,
+       0x2A, 0x05, 0x04, 0x29, 0xA8, 0x04, 0x02, 0xB0, 0xAC, 0x04, 0x01, 0xAF,
+       0x01, 0x00, 0xAA, 0x01, 0x00, 0xCF, 0x3E, 0x01, 0x01, 0x75, 0x42, 0x01,
+       0x17, 0x87, 0x42, 0x00, 0x00, 0x3A, 0x3A, 0x00, 0x01, 0x03, 0x00, 0x2C,
+       0x19, 0x38, 0x06, 0x04, 0xCB, 0x29, 0x04, 0x78, 0x01, 0x02, 0x02, 0x00,
+       0xC3, 0x19, 0x38, 0x06, 0x04, 0xCB, 0x29, 0x04, 0x78, 0x02, 0x00, 0x01,
+       0x84, 0x00, 0x08, 0x2B, 0x00, 0x00, 0x7F, 0x2F, 0x47, 0x12, 0x01, 0x01,
+       0x13, 0x37, 0x00, 0x00, 0x01, 0x7F, 0x9F, 0xCB, 0x2A, 0x01, 0x07, 0x13,
+       0x01, 0x00, 0x3A, 0x0F, 0x06, 0x09, 0x29, 0x01, 0x10, 0x13, 0x06, 0x01,
+       0xC2, 0x04, 0x2A, 0x01, 0x01, 0x3A, 0x0F, 0x06, 0x21, 0x29, 0x29, 0x88,
+       0x30, 0x01, 0x01, 0x0F, 0x01, 0x01, 0xA2, 0x39, 0x06, 0x0F, 0x2C, 0x19,
+       0x38, 0x06, 0x04, 0xCB, 0x29, 0x04, 0x78, 0x01, 0x80, 0x64, 0xC4, 0x04,
+       0x03, 0x01, 0x00, 0x9F, 0x04, 0x03, 0x71, 0x2B, 0x29, 0x04, 0x40, 0x01,
+       0x2A, 0x03, 0x00, 0x09, 0x2A, 0x5B, 0x06, 0x02, 0x68, 0x2B, 0x02, 0x00,
+       0x00, 0x00, 0x9A, 0x01, 0x0F, 0x13, 0x00, 0x00, 0x74, 0x30, 0x01, 0x00,
+       0x3A, 0x0F, 0x06, 0x10, 0x29, 0x2A, 0x01, 0x01, 0x0E, 0x06, 0x03, 0x29,
+       0x01, 0x02, 0x74, 0x42, 0x01, 0x00, 0x04, 0x22, 0x01, 0x01, 0x3A, 0x0F,
+       0x06, 0x15, 0x29, 0x01, 0x00, 0x74, 0x42, 0x2A, 0x01, 0x80, 0x64, 0x0F,
+       0x06, 0x05, 0x01, 0x82, 0x00, 0x08, 0x2B, 0x5D, 0x00, 0x04, 0x07, 0x29,
+       0x01, 0x82, 0x00, 0x08, 0x2B, 0x29, 0x00, 0x00, 0x01, 0x00, 0x31, 0x06,
+       0x05, 0x3D, 0xA6, 0x39, 0x04, 0x78, 0x2A, 0x06, 0x04, 0x01, 0x01, 0x8F,
+       0x42, 0x00, 0x00, 0x01, 0x1F, 0x13, 0x01, 0x12, 0x0F, 0x05, 0x02, 0x72,
+       0x2B, 0x76, 0x2E, 0x2A, 0xC7, 0x05, 0x02, 0x71, 0x2B, 0xA5, 0x28, 0x00,
+       0x02, 0x85, 0x2E, 0x05, 0x02, 0xB9, 0x00, 0xBD, 0xA4, 0xBD, 0xA4, 0x01,
+       0x7E, 0x03, 0x00, 0x2A, 0x06, 0x17, 0xBF, 0x2A, 0x03, 0x01, 0x83, 0x47,
+       0xB3, 0x02, 0x01, 0x4F, 0x2A, 0x02, 0x00, 0x51, 0x06, 0x04, 0x03, 0x00,
+       0x04, 0x01, 0x29, 0x04, 0x66, 0x9B, 0x9B, 0x02, 0x00, 0x5F, 0x8A, 0x40,
+       0x00, 0x00, 0x31, 0x06, 0x0B, 0x86, 0x30, 0x01, 0x14, 0x0E, 0x06, 0x02,
+       0x71, 0x2B, 0x04, 0x11, 0xCB, 0x01, 0x07, 0x13, 0x2A, 0x01, 0x02, 0x0E,
+       0x06, 0x06, 0x06, 0x02, 0x71, 0x2B, 0x04, 0x70, 0x29, 0xC0, 0x01, 0x01,
+       0x0E, 0x35, 0x39, 0x06, 0x02, 0x64, 0x2B, 0x2A, 0x01, 0x01, 0xC6, 0x38,
+       0xB2, 0x00, 0x01, 0xB7, 0x01, 0x0B, 0x0F, 0x05, 0x02, 0x71, 0x2B, 0x2A,
+       0x01, 0x03, 0x0F, 0x06, 0x08, 0xBE, 0x06, 0x02, 0x68, 0x2B, 0x47, 0x29,
+       0x00, 0x47, 0x5A, 0xBE, 0xA4, 0x2A, 0x06, 0x23, 0xBE, 0xA4, 0x2A, 0x59,
+       0x2A, 0x06, 0x18, 0x2A, 0x01, 0x82, 0x00, 0x10, 0x06, 0x05, 0x01, 0x82,
+       0x00, 0x04, 0x01, 0x2A, 0x03, 0x00, 0x83, 0x02, 0x00, 0xB3, 0x02, 0x00,
+       0x56, 0x04, 0x65, 0x9B, 0x57, 0x04, 0x5A, 0x9B, 0x9B, 0x58, 0x2A, 0x06,
+       0x02, 0x37, 0x00, 0x29, 0x2D, 0x00, 0x02, 0x2A, 0x01, 0x20, 0x13, 0x05,
+       0x02, 0x72, 0x2B, 0x01, 0x0F, 0x13, 0x03, 0x00, 0xAD, 0x93, 0x2E, 0x01,
+       0x86, 0x03, 0x11, 0x06, 0x23, 0xBD, 0x2A, 0x01, 0x81, 0x7F, 0x13, 0x5F,
+       0x01, 0x01, 0x12, 0x02, 0x00, 0x0F, 0x05, 0x02, 0x6A, 0x2B, 0x01, 0x08,
+       0x12, 0x2A, 0x01, 0x02, 0x0B, 0x3A, 0x01, 0x06, 0x10, 0x39, 0x06, 0x02,
+       0x6C, 0x2B, 0x04, 0x0D, 0x02, 0x00, 0x01, 0x01, 0x0F, 0x06, 0x04, 0x01,
+       0x00, 0x04, 0x02, 0x01, 0x02, 0x20, 0x05, 0x02, 0x6C, 0x2B, 0xBD, 0x2A,
+       0x03, 0x01, 0x2A, 0x01, 0x84, 0x00, 0x10, 0x06, 0x02, 0x6D, 0x2B, 0x83,
+       0x47, 0xB3, 0x02, 0x01, 0x53, 0x2A, 0x06, 0x01, 0x2B, 0x29, 0x9B, 0x00,
+       0x00, 0x1D, 0xB7, 0x01, 0x0F, 0x0F, 0x05, 0x02, 0x71, 0x2B, 0x00, 0x0A,
+       0xB7, 0x01, 0x01, 0x0F, 0x05, 0x02, 0x71, 0x2B, 0xBD, 0x2A, 0x03, 0x00,
+       0x77, 0x40, 0x78, 0x01, 0x20, 0xB3, 0xBF, 0x2A, 0x01, 0x20, 0x10, 0x06,
+       0x02, 0x70, 0x2B, 0x2A, 0x8E, 0x42, 0x8D, 0x47, 0xB3, 0x1A, 0x03, 0x01,
+       0xBD, 0xA4, 0x01, 0x00, 0x03, 0x02, 0x01, 0x00, 0x03, 0x03, 0x81, 0xA0,
+       0x17, 0x3A, 0x08, 0x03, 0x04, 0x03, 0x05, 0x2A, 0x06, 0x80, 0x6D, 0xBD,
+       0x2A, 0x03, 0x06, 0x02, 0x01, 0x06, 0x0A, 0x2A, 0x76, 0x2E, 0x0F, 0x06,
+       0x04, 0x01, 0x7F, 0x03, 0x03, 0x2A, 0x01, 0x81, 0x7F, 0x0F, 0x06, 0x0A,
+       0x88, 0x30, 0x06, 0x02, 0x69, 0x2B, 0x01, 0x7F, 0x03, 0x02, 0x2A, 0x01,
+       0x81, 0xAC, 0x00, 0x0F, 0x06, 0x11, 0x02, 0x00, 0x96, 0x2E, 0x11, 0x02,
+       0x00, 0x95, 0x2E, 0x0B, 0x13, 0x06, 0x04, 0x01, 0x7F, 0x03, 0x00, 0xC1,
+       0x2A, 0x5B, 0x06, 0x03, 0x29, 0x04, 0x26, 0x01, 0x00, 0xA2, 0x06, 0x0B,
+       0x01, 0x02, 0x0C, 0x79, 0x08, 0x02, 0x06, 0x47, 0x40, 0x04, 0x16, 0x29,
+       0x02, 0x05, 0x02, 0x04, 0x11, 0x06, 0x02, 0x67, 0x2B, 0x02, 0x06, 0x02,
+       0x05, 0x40, 0x02, 0x05, 0x01, 0x04, 0x08, 0x03, 0x05, 0x04, 0xFF, 0x0F,
+       0x29, 0x01, 0x00, 0x03, 0x07, 0xBF, 0xA4, 0x2A, 0x06, 0x09, 0xBF, 0x05,
+       0x04, 0x01, 0x7F, 0x03, 0x07, 0x04, 0x74, 0x9B, 0x01, 0x00, 0x8B, 0x42,
+       0x01, 0x88, 0x04, 0x80, 0x40, 0x01, 0x84, 0x80, 0x80, 0x00, 0x7C, 0x41,
+       0x2A, 0x06, 0x80, 0x4E, 0xBD, 0xA4, 0x2A, 0x06, 0x80, 0x47, 0xBD, 0x01,
+       0x00, 0x3A, 0x0F, 0x06, 0x04, 0x29, 0xB6, 0x04, 0x39, 0x01, 0x01, 0x3A,
+       0x0F, 0x06, 0x04, 0x29, 0xB4, 0x04, 0x2F, 0x01, 0x83, 0xFE, 0x01, 0x3A,
+       0x0F, 0x06, 0x04, 0x29, 0xB5, 0x04, 0x23, 0x01, 0x0D, 0x3A, 0x0F, 0x06,
+       0x04, 0x29, 0xBB, 0x04, 0x19, 0x01, 0x0A, 0x3A, 0x0F, 0x06, 0x04, 0x29,
+       0xBC, 0x04, 0x0F, 0x01, 0x10, 0x3A, 0x0F, 0x06, 0x04, 0x29, 0xA9, 0x04,
+       0x05, 0x29, 0xB9, 0x01, 0x00, 0x29, 0x04, 0xFF, 0x35, 0x9B, 0x9B, 0x02,
+       0x01, 0x02, 0x03, 0x13, 0x03, 0x01, 0x02, 0x00, 0x5B, 0x06, 0x08, 0x77,
+       0x2E, 0x97, 0x40, 0x01, 0x80, 0x56, 0xA1, 0x95, 0x2E, 0x2A, 0x02, 0x00,
+       0x10, 0x06, 0x03, 0x29, 0x02, 0x00, 0x2A, 0x01, 0x86, 0x00, 0x0B, 0x06,
+       0x02, 0x6B, 0x2B, 0x02, 0x00, 0x96, 0x2E, 0x0B, 0x06, 0x04, 0x01, 0x80,
+       0x46, 0xA1, 0x02, 0x01, 0x06, 0x10, 0x93, 0x2E, 0x02, 0x00, 0x0D, 0x06,
+       0x05, 0x29, 0x93, 0x2E, 0x04, 0x04, 0x01, 0x00, 0x03, 0x01, 0x2A, 0x93,
+       0x40, 0x2A, 0x94, 0x40, 0x2A, 0x97, 0x40, 0x01, 0x86, 0x03, 0x11, 0x03,
+       0x08, 0x02, 0x02, 0x06, 0x04, 0x01, 0x02, 0x88, 0x42, 0x02, 0x07, 0x05,
+       0x03, 0x01, 0x28, 0xA1, 0x44, 0x29, 0x01, 0x82, 0x01, 0x07, 0x80, 0x2E,
+       0x13, 0x2A, 0x80, 0x40, 0x2A, 0x01, 0x81, 0x7F, 0x13, 0x5C, 0x37, 0x47,
+       0x01, 0x08, 0x12, 0x5C, 0x01, 0x02, 0x13, 0x39, 0x01, 0x0C, 0x0C, 0x03,
+       0x09, 0x7C, 0x2F, 0x43, 0x13, 0x2A, 0x7C, 0x41, 0x05, 0x04, 0x01, 0x00,
+       0x03, 0x09, 0x02, 0x01, 0x06, 0x03, 0x01, 0x7F, 0x00, 0x8D, 0x01, 0x20,
+       0x34, 0x01, 0x20, 0x8E, 0x42, 0x79, 0x2A, 0x03, 0x05, 0x2A, 0x02, 0x04,
+       0x0B, 0x06, 0x80, 0x49, 0x2A, 0x2E, 0x2A, 0x9A, 0x2A, 0x01, 0x0C, 0x12,
+       0x2A, 0x01, 0x01, 0x0F, 0x47, 0x01, 0x02, 0x0F, 0x39, 0x06, 0x0A, 0x2A,
+       0x02, 0x09, 0x13, 0x05, 0x04, 0x63, 0x01, 0x00, 0x2A, 0x02, 0x08, 0x05,
+       0x0E, 0x2A, 0x01, 0x81, 0x70, 0x13, 0x01, 0x20, 0x0E, 0x06, 0x04, 0x63,
+       0x01, 0x00, 0x2A, 0x2A, 0x06, 0x10, 0x02, 0x05, 0x61, 0x40, 0x02, 0x05,
+       0x40, 0x02, 0x05, 0x01, 0x04, 0x08, 0x03, 0x05, 0x04, 0x01, 0x63, 0x01,
+       0x04, 0x08, 0x04, 0xFF, 0x30, 0x29, 0x02, 0x05, 0x79, 0x09, 0x01, 0x02,
+       0x12, 0x2A, 0x05, 0x03, 0x01, 0x28, 0xA1, 0x7A, 0x42, 0x8A, 0x2E, 0x01,
+       0x83, 0xFF, 0x7F, 0x0F, 0x06, 0x0D, 0x01, 0x03, 0xA2, 0x06, 0x04, 0x01,
+       0x80, 0x78, 0xA1, 0x01, 0x00, 0x8A, 0x40, 0x18, 0x05, 0x03, 0x01, 0x28,
+       0xA1, 0x01, 0x00, 0x00, 0x00, 0xB1, 0xB0, 0x00, 0x04, 0x76, 0x2E, 0xCA,
+       0x06, 0x16, 0xBD, 0x2A, 0x01, 0x84, 0x00, 0x10, 0x06, 0x02, 0x6D, 0x2B,
+       0x2A, 0x03, 0x00, 0x83, 0x47, 0xB3, 0x02, 0x00, 0x76, 0x2E, 0xA5, 0x27,
+       0x76, 0x2E, 0x2A, 0xC8, 0x47, 0xC7, 0x03, 0x01, 0x03, 0x02, 0x02, 0x01,
+       0x02, 0x02, 0x39, 0x06, 0x14, 0xBF, 0x2A, 0x03, 0x03, 0x83, 0x47, 0xB3,
+       0x02, 0x03, 0x76, 0x2E, 0xA5, 0x02, 0x02, 0x06, 0x03, 0x26, 0x04, 0x01,
+       0x24, 0x9B, 0x00, 0x00, 0xB7, 0x01, 0x10, 0x0F, 0x05, 0x02, 0x71, 0x2B,
+       0x00, 0x00, 0x9C, 0xB7, 0x01, 0x14, 0x0E, 0x06, 0x02, 0x71, 0x2B, 0x83,
+       0x01, 0x0C, 0x08, 0x01, 0x0C, 0xB3, 0x9B, 0x83, 0x2A, 0x01, 0x0C, 0x08,
+       0x01, 0x0C, 0x32, 0x05, 0x02, 0x65, 0x2B, 0x00, 0x02, 0x03, 0x00, 0x03,
+       0x01, 0x02, 0x00, 0x98, 0x02, 0x01, 0x02, 0x00, 0x3C, 0x2A, 0x01, 0x00,
+       0x0F, 0x06, 0x02, 0x63, 0x00, 0xCD, 0x04, 0x74, 0x00, 0xBD, 0x01, 0x01,
+       0x0E, 0x06, 0x02, 0x66, 0x2B, 0xBF, 0x2A, 0x2A, 0x5D, 0x47, 0x01, 0x05,
+       0x11, 0x39, 0x06, 0x02, 0x66, 0x2B, 0x01, 0x08, 0x08, 0x2A, 0x82, 0x30,
+       0x0B, 0x06, 0x0D, 0x2A, 0x01, 0x01, 0x47, 0x0C, 0x3F, 0x2A, 0x82, 0x42,
+       0x84, 0x42, 0x04, 0x01, 0x29, 0x00, 0x00, 0xBD, 0x88, 0x30, 0x01, 0x00,
+       0x3A, 0x0F, 0x06, 0x13, 0x29, 0x01, 0x01, 0x0F, 0x05, 0x02, 0x69, 0x2B,
+       0xBF, 0x06, 0x02, 0x69, 0x2B, 0x01, 0x02, 0x88, 0x42, 0x04, 0x28, 0x01,
+       0x02, 0x3A, 0x0F, 0x06, 0x1F, 0x29, 0x01, 0x0D, 0x0F, 0x05, 0x02, 0x69,
+       0x2B, 0xBF, 0x01, 0x0C, 0x0F, 0x05, 0x02, 0x69, 0x2B, 0x83, 0x01, 0x0C,
+       0xB3, 0x89, 0x83, 0x01, 0x0C, 0x32, 0x05, 0x02, 0x69, 0x2B, 0x04, 0x03,
+       0x69, 0x2B, 0x29, 0x00, 0x00, 0xBD, 0xA4, 0xBD, 0xA4, 0x2A, 0x06, 0x1D,
+       0xBF, 0x06, 0x03, 0xB9, 0x04, 0x15, 0xBD, 0x2A, 0x01, 0x81, 0x7F, 0x0D,
+       0x06, 0x0C, 0x2A, 0x8B, 0x08, 0x01, 0x00, 0x47, 0x42, 0x8B, 0x47, 0xB3,
+       0x04, 0x01, 0xC5, 0x04, 0x60, 0x9B, 0x9B, 0x00, 0x00, 0xB8, 0x2A, 0x5D,
+       0x06, 0x07, 0x29, 0x06, 0x02, 0x67, 0x2B, 0x04, 0x74, 0x00, 0x00, 0xC0,
+       0x01, 0x03, 0xBE, 0x47, 0x29, 0x47, 0x00, 0x00, 0xBD, 0xC5, 0x00, 0x03,
+       0x01, 0x00, 0x03, 0x00, 0xBD, 0xA4, 0x2A, 0x06, 0x32, 0xBF, 0x03, 0x01,
+       0xBF, 0x03, 0x02, 0x02, 0x01, 0x01, 0x02, 0x11, 0x02, 0x01, 0x01, 0x06,
+       0x0D, 0x13, 0x02, 0x02, 0x01, 0x01, 0x0F, 0x02, 0x02, 0x01, 0x03, 0x0F,
+       0x39, 0x13, 0x06, 0x11, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x60, 0x01,
+       0x02, 0x0C, 0x02, 0x01, 0x08, 0x0C, 0x39, 0x03, 0x00, 0x04, 0x4B, 0x9B,
+       0x02, 0x00, 0x00, 0x00, 0xBD, 0xA4, 0xBA, 0x80, 0x40, 0x9B, 0x00, 0x00,
+       0xBD, 0xA4, 0xBD, 0xA4, 0x01, 0x00, 0x7C, 0x41, 0x2A, 0x06, 0x15, 0xBD,
+       0x2A, 0x01, 0x20, 0x0B, 0x06, 0x0B, 0x01, 0x01, 0x47, 0x0C, 0x7C, 0x2F,
+       0x39, 0x7C, 0x41, 0x04, 0x01, 0x29, 0x04, 0x68, 0x9B, 0x9B, 0x00, 0x00,
+       0x01, 0x02, 0x98, 0xC0, 0x01, 0x08, 0x0C, 0xC0, 0x08, 0x00, 0x00, 0x01,
+       0x03, 0x98, 0xC0, 0x01, 0x08, 0x0C, 0xC0, 0x08, 0x01, 0x08, 0x0C, 0xC0,
+       0x08, 0x00, 0x00, 0x01, 0x01, 0x98, 0xC0, 0x00, 0x00, 0x3D, 0x2A, 0x5B,
+       0x05, 0x01, 0x00, 0x29, 0xCD, 0x04, 0x76, 0x02, 0x03, 0x00, 0x92, 0x30,
+       0x03, 0x01, 0x01, 0x00, 0x2A, 0x02, 0x01, 0x0B, 0x06, 0x10, 0x2A, 0x01,
+       0x01, 0x0C, 0x91, 0x08, 0x2E, 0x02, 0x00, 0x0F, 0x06, 0x01, 0x00, 0x5F,
+       0x04, 0x6A, 0x29, 0x01, 0x7F, 0x00, 0x00, 0x2C, 0x19, 0x38, 0x06, 0x04,
+       0xCB, 0x29, 0x04, 0x78, 0x01, 0x16, 0x87, 0x42, 0x01, 0x00, 0xDE, 0x01,
+       0x00, 0xDD, 0x2C, 0x01, 0x17, 0x87, 0x42, 0x00, 0x00, 0x01, 0x15, 0x87,
+       0x42, 0x47, 0x55, 0x29, 0x55, 0x29, 0x2C, 0x00, 0x00, 0x01, 0x01, 0x47,
+       0xC3, 0x00, 0x00, 0x47, 0x3A, 0x98, 0x47, 0x2A, 0x06, 0x05, 0xC0, 0x29,
+       0x60, 0x04, 0x78, 0x29, 0x00, 0x02, 0x03, 0x00, 0x76, 0x2E, 0x9A, 0x03,
+       0x01, 0x02, 0x01, 0x01, 0x0F, 0x13, 0x02, 0x01, 0x01, 0x04, 0x12, 0x01,
+       0x0F, 0x13, 0x02, 0x01, 0x01, 0x08, 0x12, 0x01, 0x0F, 0x13, 0x01, 0x00,
+       0x3A, 0x0F, 0x06, 0x10, 0x29, 0x01, 0x00, 0x01, 0x18, 0x02, 0x00, 0x06,
+       0x03, 0x4A, 0x04, 0x01, 0x4B, 0x04, 0x80, 0x68, 0x01, 0x01, 0x3A, 0x0F,
+       0x06, 0x10, 0x29, 0x01, 0x01, 0x01, 0x10, 0x02, 0x00, 0x06, 0x03, 0x4A,
+       0x04, 0x01, 0x4B, 0x04, 0x80, 0x52, 0x01, 0x02, 0x3A, 0x0F, 0x06, 0x0F,
+       0x29, 0x01, 0x01, 0x01, 0x20, 0x02, 0x00, 0x06, 0x03, 0x4A, 0x04, 0x01,
+       0x4B, 0x04, 0x3D, 0x01, 0x03, 0x3A, 0x0F, 0x06, 0x0E, 0x29, 0x29, 0x01,
+       0x10, 0x02, 0x00, 0x06, 0x03, 0x48, 0x04, 0x01, 0x49, 0x04, 0x29, 0x01,
+       0x04, 0x3A, 0x0F, 0x06, 0x0E, 0x29, 0x29, 0x01, 0x20, 0x02, 0x00, 0x06,
+       0x03, 0x48, 0x04, 0x01, 0x49, 0x04, 0x15, 0x01, 0x05, 0x3A, 0x0F, 0x06,
+       0x0C, 0x29, 0x29, 0x02, 0x00, 0x06, 0x03, 0x4C, 0x04, 0x01, 0x4D, 0x04,
+       0x03, 0x68, 0x2B, 0x29, 0x00, 0x00, 0x9A, 0x01, 0x0C, 0x12, 0x01, 0x02,
+       0x10, 0x00, 0x00, 0x9A, 0x01, 0x0C, 0x12, 0x2A, 0x5E, 0x47, 0x01, 0x03,
+       0x0B, 0x13, 0x00, 0x00, 0x9A, 0x01, 0x0C, 0x12, 0x01, 0x01, 0x0F, 0x00,
+       0x00, 0x9A, 0x01, 0x0C, 0x12, 0x5D, 0x00, 0x00, 0x1B, 0x01, 0x00, 0x73,
+       0x30, 0x2A, 0x06, 0x1F, 0x01, 0x01, 0x3A, 0x0F, 0x06, 0x06, 0x29, 0x01,
+       0x00, 0x9E, 0x04, 0x11, 0x01, 0x02, 0x3A, 0x0F, 0x06, 0x0A, 0x29, 0x75,
+       0x30, 0x06, 0x03, 0x01, 0x10, 0x39, 0x04, 0x01, 0x29, 0x04, 0x01, 0x29,
+       0x7B, 0x30, 0x05, 0x33, 0x31, 0x06, 0x30, 0x86, 0x30, 0x01, 0x14, 0x3A,
+       0x0F, 0x06, 0x06, 0x29, 0x01, 0x02, 0x39, 0x04, 0x22, 0x01, 0x15, 0x3A,
+       0x0F, 0x06, 0x09, 0x29, 0xA7, 0x06, 0x03, 0x01, 0x7F, 0x9E, 0x04, 0x13,
+       0x01, 0x16, 0x3A, 0x0F, 0x06, 0x06, 0x29, 0x01, 0x01, 0x39, 0x04, 0x07,
+       0x29, 0x01, 0x04, 0x39, 0x01, 0x00, 0x29, 0x19, 0x06, 0x03, 0x01, 0x08,
+       0x39, 0x00, 0x00, 0x1B, 0x2A, 0x05, 0x0F, 0x31, 0x06, 0x0C, 0x86, 0x30,
+       0x01, 0x15, 0x0F, 0x06, 0x04, 0x29, 0xA7, 0x04, 0x01, 0x23, 0x00, 0x00,
+       0xCB, 0x01, 0x07, 0x13, 0x01, 0x01, 0x10, 0x06, 0x02, 0x71, 0x2B, 0x00,
+       0x01, 0x03, 0x00, 0x2C, 0x19, 0x06, 0x05, 0x02, 0x00, 0x87, 0x42, 0x00,
+       0xCB, 0x29, 0x04, 0x74, 0x00, 0x01, 0x14, 0xCE, 0x01, 0x01, 0xDE, 0x2C,
+       0x2A, 0x01, 0x00, 0xC6, 0x01, 0x16, 0xCE, 0xD2, 0x2C, 0x00, 0x00, 0x01,
+       0x0B, 0xDE, 0x50, 0x2A, 0x2A, 0x01, 0x03, 0x08, 0xDD, 0xDD, 0x14, 0x2A,
+       0x5B, 0x06, 0x02, 0x29, 0x00, 0xDD, 0x1E, 0x2A, 0x06, 0x05, 0x83, 0x47,
+       0xD6, 0x04, 0x77, 0x29, 0x04, 0x6C, 0x00, 0x01, 0x00, 0xD8, 0x93, 0x2E,
+       0x01, 0x86, 0x03, 0x11, 0x06, 0x05, 0x61, 0x01, 0x00, 0xD9, 0x08, 0x4E,
+       0x08, 0x01, 0x03, 0x08, 0x01, 0x0D, 0xDE, 0xDD, 0x01, 0x00, 0xD8, 0xDE,
+       0x01, 0x01, 0xD8, 0x29, 0x93, 0x2E, 0x01, 0x86, 0x03, 0x11, 0x06, 0x08,
+       0x01, 0x00, 0xD9, 0xDC, 0x01, 0x01, 0xD9, 0x29, 0x4E, 0xDC, 0x16, 0x15,
+       0x2A, 0x5B, 0x06, 0x02, 0x29, 0x00, 0xDC, 0x1F, 0x2A, 0x06, 0x05, 0x83,
+       0x47, 0xD6, 0x04, 0x77, 0x29, 0x04, 0x6C, 0x00, 0x9C, 0x01, 0x14, 0xDE,
+       0x01, 0x0C, 0xDD, 0x83, 0x01, 0x0C, 0xD6, 0x00, 0x04, 0x03, 0x00, 0x01,
+       0x02, 0xDE, 0x01, 0x80, 0x46, 0x88, 0x30, 0x01, 0x02, 0x0F, 0x06, 0x0C,
+       0x02, 0x00, 0x06, 0x04, 0x01, 0x05, 0x04, 0x02, 0x01, 0x1D, 0x04, 0x02,
+       0x01, 0x00, 0x03, 0x01, 0x84, 0x30, 0x06, 0x04, 0x01, 0x05, 0x04, 0x02,
+       0x01, 0x00, 0x03, 0x02, 0x8A, 0x2E, 0x2A, 0x06, 0x05, 0x60, 0x21, 0x01,
+       0x07, 0x08, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x02, 0x03, 0x08,
+       0x2A, 0x06, 0x03, 0x01, 0x02, 0x08, 0x08, 0xDD, 0x93, 0x2E, 0xDC, 0x8C,
+       0x01, 0x04, 0x17, 0x8C, 0x01, 0x04, 0x08, 0x01, 0x1C, 0x34, 0x8C, 0x01,
+       0x20, 0xD6, 0x01, 0x20, 0xDE, 0x8D, 0x01, 0x20, 0xD6, 0x76, 0x2E, 0xDC,
+       0x01, 0x00, 0xDE, 0x02, 0x01, 0x02, 0x02, 0x08, 0x02, 0x03, 0x08, 0x2A,
+       0x06, 0x80, 0x40, 0xDC, 0x02, 0x01, 0x2A, 0x06, 0x10, 0x01, 0x83, 0xFE,
+       0x01, 0xDC, 0x01, 0x04, 0x09, 0x2A, 0xDC, 0x60, 0x89, 0x47, 0xD7, 0x04,
+       0x01, 0x29, 0x02, 0x02, 0x06, 0x0C, 0x01, 0x01, 0xDC, 0x01, 0x01, 0xDC,
+       0x84, 0x30, 0x01, 0x08, 0x09, 0xDE, 0x02, 0x03, 0x2A, 0x06, 0x11, 0x01,
+       0x10, 0xDC, 0x01, 0x04, 0x09, 0x2A, 0xDC, 0x62, 0x2A, 0xDC, 0x60, 0x83,
+       0x47, 0xD7, 0x04, 0x01, 0x29, 0x04, 0x01, 0x29, 0x00, 0x00, 0x01, 0x0E,
+       0xDE, 0x01, 0x00, 0xDD, 0x00, 0x03, 0x76, 0x2E, 0xC8, 0x05, 0x01, 0x00,
+       0x7C, 0x2F, 0x01, 0x00, 0xA0, 0x12, 0x01, 0x01, 0x13, 0x5D, 0x06, 0x03,
+       0x5F, 0x04, 0x75, 0x03, 0x00, 0x29, 0x02, 0x00, 0x25, 0x2A, 0x5B, 0x06,
+       0x02, 0x37, 0x2B, 0x03, 0x01, 0x93, 0x2E, 0x01, 0x86, 0x03, 0x11, 0x03,
+       0x02, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x7E, 0x30, 0x08, 0x02, 0x02, 0x01,
+       0x02, 0x13, 0x08, 0x01, 0x06, 0x08, 0xDD, 0x01, 0x03, 0xDE, 0x02, 0x00,
+       0xDC, 0x7D, 0x7E, 0x30, 0xD7, 0x02, 0x02, 0x06, 0x0D, 0x90, 0x30, 0xDE,
+       0x76, 0x2E, 0xC9, 0x01, 0x01, 0x0C, 0x01, 0x03, 0x08, 0xDE, 0x02, 0x01,
+       0xDC, 0x83, 0x02, 0x01, 0xD6, 0x00, 0x00, 0x54, 0x2A, 0x01, 0x00, 0x0F,
+       0x06, 0x02, 0x63, 0x00, 0xCB, 0x29, 0x04, 0x73, 0x00, 0x2A, 0xDE, 0xD6,
+       0x00, 0x00, 0x01, 0x00, 0x76, 0x2E, 0xC7, 0x06, 0x0C, 0x61, 0x3A, 0x06,
+       0x08, 0x01, 0x80, 0x41, 0xDE, 0x01, 0x80, 0x42, 0xDE, 0x46, 0x06, 0x07,
+       0x5F, 0x3A, 0x06, 0x03, 0x01, 0x01, 0xDE, 0x45, 0x06, 0x08, 0x5F, 0x3A,
+       0x06, 0x04, 0x01, 0x80, 0x40, 0xDE, 0x47, 0x29, 0x00, 0x01, 0x01, 0x00,
+       0x03, 0x00, 0x46, 0x45, 0x39, 0x05, 0x14, 0x01, 0x01, 0x01, 0x80, 0x7C,
+       0xDA, 0x03, 0x00, 0x01, 0x03, 0x01, 0x80, 0x7C, 0xDA, 0x02, 0x00, 0x08,
+       0x47, 0x29, 0x00, 0x46, 0x06, 0x07, 0x01, 0x01, 0x44, 0x29, 0xDA, 0x03,
+       0x00, 0x45, 0x06, 0x0A, 0x01, 0x03, 0x44, 0x29, 0xDA, 0x02, 0x00, 0x08,
+       0x03, 0x00, 0x29, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x04, 0xDB,
+       0x01, 0x05, 0xDB, 0x01, 0x06, 0xDB, 0x01, 0x03, 0xDB, 0x01, 0x02, 0xDB,
+       0x0A, 0x63, 0x00, 0x01, 0x03, 0x00, 0x3A, 0x01, 0x01, 0x02, 0x00, 0x0C,
+       0x13, 0x05, 0x01, 0x00, 0x61, 0x01, 0x03, 0x3B, 0x06, 0x07, 0x02, 0x00,
+       0xDE, 0x01, 0x02, 0x3B, 0xDE, 0x00, 0x00, 0x2A, 0x01, 0x08, 0x52, 0xDE,
+       0xDE, 0x00, 0x00, 0x2A, 0x01, 0x10, 0x52, 0xDE, 0xDC, 0x00, 0x00, 0x2A,
+       0x55, 0x06, 0x02, 0x29, 0x00, 0xCB, 0x29, 0x04, 0x76
 };
 
 static const uint16_t t0_caddr[] = {
@@ -752,22 +768,22 @@ static const uint16_t t0_caddr[] = {
        25,
        30,
        35,
-       39,
-       43,
-       47,
-       51,
-       55,
-       59,
-       63,
-       67,
-       71,
-       75,
-       79,
-       83,
-       87,
-       91,
-       95,
-       99,
+       40,
+       44,
+       48,
+       52,
+       56,
+       60,
+       64,
+       68,
+       72,
+       76,
+       80,
+       84,
+       88,
+       92,
+       96,
+       100,
        104,
        109,
        114,
@@ -782,7 +798,7 @@ static const uint16_t t0_caddr[] = {
        159,
        164,
        169,
-       175,
+       174,
        180,
        185,
        190,
@@ -803,78 +819,82 @@ static const uint16_t t0_caddr[] = {
        265,
        270,
        275,
-       284,
-       288,
-       313,
-       319,
-       338,
-       349,
-       383,
-       490,
-       494,
-       527,
-       537,
-       605,
-       619,
-       625,
-       685,
+       280,
+       285,
+       290,
+       299,
+       303,
+       328,
+       334,
+       353,
+       364,
+       398,
+       509,
+       513,
+       546,
+       556,
+       624,
+       638,
+       644,
        704,
-       726,
-       775,
-       851,
-       953,
-       964,
-       1511,
-       1515,
-       1582,
-       1592,
-       1623,
-       1647,
-       1693,
-       1763,
-       1803,
-       1817,
-       1826,
-       1830,
-       1894,
-       1902,
-       1938,
-       1949,
-       1965,
-       1971,
-       1982,
-       2017,
-       2043,
-       2055,
-       2061,
-       2076,
-       2232,
-       2241,
-       2254,
-       2263,
-       2270,
-       2373,
-       2394,
-       2407,
-       2423,
-       2441,
-       2473,
-       2546,
-       2559,
-       2698,
-       2706,
-       2803,
-       2817,
-       2822,
-       2866,
-       2923,
-       2944,
-       2971,
-       2979,
-       2987
+       723,
+       745,
+       794,
+       843,
+       919,
+       1021,
+       1032,
+       1613,
+       1617,
+       1684,
+       1694,
+       1725,
+       1749,
+       1795,
+       1865,
+       1905,
+       1919,
+       1928,
+       1932,
+       1996,
+       2004,
+       2040,
+       2051,
+       2067,
+       2073,
+       2084,
+       2119,
+       2145,
+       2157,
+       2163,
+       2178,
+       2334,
+       2343,
+       2356,
+       2365,
+       2372,
+       2475,
+       2496,
+       2509,
+       2525,
+       2543,
+       2575,
+       2648,
+       2661,
+       2842,
+       2850,
+       2947,
+       2961,
+       2966,
+       3010,
+       3067,
+       3088,
+       3115,
+       3123,
+       3131
 };
 
-#define T0_INTERPRETED   88
+#define T0_INTERPRETED   91
 
 #define T0_ENTER(ip, rp, slot)   do { \
                const unsigned char *t0_newip; \
@@ -895,7 +915,7 @@ name(void *ctx) \
        T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \
 }
 
-T0_DEFENTRY(br_ssl_hs_server_init_main, 157)
+T0_DEFENTRY(br_ssl_hs_server_init_main, 163)
 
 #define T0_NEXT(t0ipp)   (*(*(t0ipp)) ++)
 
@@ -1294,6 +1314,16 @@ br_ssl_hs_server_run(void *t0ctx)
                                }
                                break;
                        case 33: {
+                               /* copy-protocol-name */
+
+       size_t idx = T0_POP();
+       size_t len = strlen(ENG->protocol_names[idx]);
+       memcpy(ENG->pad, ENG->protocol_names[idx], len);
+       T0_PUSH(len);
+
+                               }
+                               break;
+                       case 34: {
                                /* data-get8 */
 
        size_t addr = T0_POP();
@@ -1301,14 +1331,14 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 34: {
+                       case 35: {
                                /* discard-input */
 
        ENG->hlen_in = 0;
 
                                }
                                break;
-                       case 35: {
+                       case 36: {
                                /* do-ecdh */
 
        int prf_id = T0_POPi();
@@ -1317,7 +1347,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 36: {
+                       case 37: {
                                /* do-ecdhe-part1 */
 
        int curve = T0_POPi();
@@ -1325,7 +1355,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 37: {
+                       case 38: {
                                /* do-ecdhe-part2 */
 
        int prf_id = T0_POPi();
@@ -1334,7 +1364,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 38: {
+                       case 39: {
                                /* do-rsa-decrypt */
 
        int prf_id = T0_POPi();
@@ -1343,24 +1373,24 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 39: {
+                       case 40: {
                                /* do-static-ecdh */
 
        do_static_ecdh(CTX, T0_POP());
 
                                }
                                break;
-                       case 40: {
+                       case 41: {
                                /* drop */
  (void)T0_POP(); 
                                }
                                break;
-                       case 41: {
+                       case 42: {
                                /* dup */
  T0_PUSH(T0_PEEK(0)); 
                                }
                                break;
-                       case 42: {
+                       case 43: {
                                /* fail */
 
        br_ssl_engine_fail(ENG, (int)T0_POPi());
@@ -1368,14 +1398,14 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 43: {
+                       case 44: {
                                /* flush-record */
 
        br_ssl_engine_flush_record(ENG);
 
                                }
                                break;
-                       case 44: {
+                       case 45: {
                                /* get-key-type-usages */
 
        const br_x509_class *xc;
@@ -1392,7 +1422,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 45: {
+                       case 46: {
                                /* get16 */
 
        size_t addr = (size_t)T0_POP();
@@ -1400,7 +1430,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 46: {
+                       case 47: {
                                /* get32 */
 
        size_t addr = (size_t)T0_POP();
@@ -1408,7 +1438,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 47: {
+                       case 48: {
                                /* get8 */
 
        size_t addr = (size_t)T0_POP();
@@ -1416,14 +1446,14 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 48: {
+                       case 49: {
                                /* has-input? */
 
        T0_PUSHi(-(ENG->hlen_in != 0));
 
                                }
                                break;
-                       case 49: {
+                       case 50: {
                                /* memcmp */
 
        size_t len = (size_t)T0_POP();
@@ -1434,7 +1464,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 50: {
+                       case 51: {
                                /* memcpy */
 
        size_t len = (size_t)T0_POP();
@@ -1444,7 +1474,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 51: {
+                       case 52: {
                                /* mkrand */
 
        size_t len = (size_t)T0_POP();
@@ -1453,21 +1483,21 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 52: {
+                       case 53: {
                                /* more-incoming-bytes? */
 
        T0_PUSHi(ENG->hlen_in != 0 || !br_ssl_engine_recvrec_finished(ENG));
 
                                }
                                break;
-                       case 53: {
+                       case 54: {
                                /* multihash-init */
 
        br_multihash_init(&ENG->mhash);
 
                                }
                                break;
-                       case 54: {
+                       case 55: {
                                /* neg */
 
        uint32_t a = T0_POP();
@@ -1475,7 +1505,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 55: {
+                       case 56: {
                                /* not */
 
        uint32_t a = T0_POP();
@@ -1483,7 +1513,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 56: {
+                       case 57: {
                                /* or */
 
        uint32_t b = T0_POP();
@@ -1492,17 +1522,17 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 57: {
+                       case 58: {
                                /* over */
  T0_PUSH(T0_PEEK(1)); 
                                }
                                break;
-                       case 58: {
+                       case 59: {
                                /* pick */
  T0_PICK(T0_POP()); 
                                }
                                break;
-                       case 59: {
+                       case 60: {
                                /* read-chunk-native */
 
        size_t clen = ENG->hlen_in;
@@ -1526,7 +1556,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 60: {
+                       case 61: {
                                /* read8-native */
 
        if (ENG->hlen_in > 0) {
@@ -1544,7 +1574,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 61: {
+                       case 62: {
                                /* save-session */
 
        if (CTX->cache_vtable != NULL) {
@@ -1554,7 +1584,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 62: {
+                       case 63: {
                                /* set-max-frag-len */
 
        size_t max_frag_len = T0_POP();
@@ -1573,7 +1603,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 63: {
+                       case 64: {
                                /* set16 */
 
        size_t addr = (size_t)T0_POP();
@@ -1581,7 +1611,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 64: {
+                       case 65: {
                                /* set32 */
 
        size_t addr = (size_t)T0_POP();
@@ -1589,7 +1619,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 65: {
+                       case 66: {
                                /* set8 */
 
        size_t addr = (size_t)T0_POP();
@@ -1597,7 +1627,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 66: {
+                       case 67: {
                                /* supported-curves */
 
        uint32_t x = ENG->iec == NULL ? 0 : ENG->iec->supported_curves;
@@ -1605,7 +1635,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 67: {
+                       case 68: {
                                /* supported-hash-functions */
 
        int i;
@@ -1624,26 +1654,26 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 68: {
+                       case 69: {
                                /* supports-ecdsa? */
 
        T0_PUSHi(-(ENG->iecdsa != 0));
 
                                }
                                break;
-                       case 69: {
+                       case 70: {
                                /* supports-rsa-sign? */
 
        T0_PUSHi(-(ENG->irsavrfy != 0));
 
                                }
                                break;
-                       case 70: {
+                       case 71: {
                                /* swap */
  T0_SWAP(); 
                                }
                                break;
-                       case 71: {
+                       case 72: {
                                /* switch-aesgcm-in */
 
        int is_client, prf_id;
@@ -1657,7 +1687,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 72: {
+                       case 73: {
                                /* switch-aesgcm-out */
 
        int is_client, prf_id;
@@ -1671,7 +1701,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 73: {
+                       case 74: {
                                /* switch-cbc-in */
 
        int is_client, prf_id, mac_id, aes;
@@ -1687,7 +1717,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 74: {
+                       case 75: {
                                /* switch-cbc-out */
 
        int is_client, prf_id, mac_id, aes;
@@ -1703,7 +1733,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 75: {
+                       case 76: {
                                /* switch-chapol-in */
 
        int is_client, prf_id;
@@ -1714,7 +1744,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 76: {
+                       case 77: {
                                /* switch-chapol-out */
 
        int is_client, prf_id;
@@ -1725,7 +1755,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 77: {
+                       case 78: {
                                /* ta-names-total-length */
 
        size_t u, len;
@@ -1744,7 +1774,26 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 78: {
+                       case 79: {
+                               /* test-protocol-name */
+
+       size_t len = T0_POP();
+       size_t u;
+
+       for (u = 0; u < ENG->protocol_names_num; u ++) {
+               const char *name;
+
+               name = ENG->protocol_names[u];
+               if (len == strlen(name) && memcmp(ENG->pad, name, len) == 0) {
+                       T0_PUSH(u);
+                       T0_RET();
+               }
+       }
+       T0_PUSHi(-1);
+
+                               }
+                               break;
+                       case 80: {
                                /* total-chain-length */
 
        size_t u;
@@ -1758,7 +1807,16 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 79: {
+                       case 81: {
+                               /* u< */
+
+       uint32_t b = T0_POP();
+       uint32_t a = T0_POP();
+       T0_PUSH(-(uint32_t)(a < b));
+
+                               }
+                               break;
+                       case 82: {
                                /* u>> */
 
        int c = (int)T0_POPi();
@@ -1767,7 +1825,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 80: {
+                       case 83: {
                                /* verify-CV-sig */
 
        int err;
@@ -1777,7 +1835,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 81: {
+                       case 84: {
                                /* write-blob-chunk */
 
        size_t clen = ENG->hlen_out;
@@ -1801,7 +1859,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 82: {
+                       case 85: {
                                /* write8-native */
 
        unsigned char x;
@@ -1820,7 +1878,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 83: {
+                       case 86: {
                                /* x509-append */
 
        const br_x509_class *xc;
@@ -1832,7 +1890,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 84: {
+                       case 87: {
                                /* x509-end-cert */
 
        const br_x509_class *xc;
@@ -1842,7 +1900,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 85: {
+                       case 88: {
                                /* x509-end-chain */
 
        const br_x509_class *xc;
@@ -1852,7 +1910,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 86: {
+                       case 89: {
                                /* x509-start-cert */
 
        const br_x509_class *xc;
@@ -1862,7 +1920,7 @@ br_ssl_hs_server_run(void *t0ctx)
 
                                }
                                break;
-                       case 87: {
+                       case 90: {
                                /* x509-start-chain */
 
        const br_x509_class *xc;
index 7f5fe85..4b6056b 100644 (file)
@@ -528,6 +528,41 @@ cc: set-max-frag-len ( len -- ) {
        close-elt
        close-elt ;
 
+\ Read the ALPN extension from client.
+: read-ALPN-from-client ( lim -- lim )
+       \ If we do not have configured names, then we just ignore the
+       \ extension.
+       addr-protocol_names_num get16 ifnot read-ignore-16 ret then
+
+       \ Open extension value.
+       read16 open-elt
+
+       \ Open list of protocol names.
+       read16 open-elt
+
+       \ Get all names and test for their support. We keep the one with
+       \ the lowest index (because we apply server's preferences, as
+       \ recommended by RFC 7301, section 3.2. We set the 'found' variable
+       \ to -2 and use an unsigned comparison, making -2 a huge value.
+       -2 { found }
+       begin dup while
+               read8 dup { len } addr-pad swap read-blob
+               len test-protocol-name dup found u< if
+                       >found
+               else
+                       drop
+               then
+       repeat
+
+       \ End of extension.
+       close-elt
+       close-elt
+
+       \ Write back found name index (or not). If no match was found,
+       \ then we write -1 (0xFFFF) in the index value, not 0, so that
+       \ the caller knows that we tried to match, and failed.
+       found 1+ addr-selected_protocol set16 ;
+
 \ Call policy handler to get cipher suite, hash function identifier and
 \ certificate chain. Returned value is 0 (false) on failure.
 cc: call-policy-handler ( -- bool ) {
@@ -709,6 +744,11 @@ cc: save-session ( -- ) {
                                \       read-ignore-16
                                \ endof
 
+                               \ ALPN
+                               0x0010 of
+                                       read-ALPN-from-client
+                               endof
+
                                \ Other extensions are ignored.
                                drop read-ignore-16 0
                        endcase
@@ -832,6 +872,12 @@ cc: save-session ( -- ) {
        then
        addr-client_suites_num set8
 
+       \ Check ALPN.
+       addr-selected_protocol get16 0xFFFF = if
+               3 flag? if 120 fail-alert then
+               0 addr-selected_protocol set16
+       then
+
        \ Call policy handler to obtain the cipher suite and other
        \ parameters.
        call-policy-handler ifnot 40 fail-alert then
@@ -842,20 +888,28 @@ cc: save-session ( -- ) {
 \ Write ServerHello.
 : write-ServerHello ( initial -- )
        { initial }
-       \ Compute ServerHello length. Right now we only send the
-       \ "secure renegotiation" extension.
+       \ Compute ServerHello length.
        2 write8 70
 
+       \ Compute length of Secure Renegotiation extension.
        addr-reneg get8 2 = if
                initial if 5 else 29 then
        else
                0
        then
        { ext-reneg-len }
+
+       \ Compute length of Max Fragment Length extension.
        addr-peer_log_max_frag_len get8 if 5 else 0 then
        { ext-max-frag-len }
 
-       ext-reneg-len ext-max-frag-len + dup if 2 + then +
+       \ Compute length of ALPN extension. This also copy the
+       \ selected protocol name into the pad.
+       addr-selected_protocol get16 dup if 1- copy-protocol-name 7 + then
+       { ext-ALPN-len }
+
+       \ Adjust ServerHello length to account for the extensions.
+       ext-reneg-len ext-max-frag-len + ext-ALPN-len + dup if 2 + then +
        write24
 
        \ Protocol version
@@ -880,7 +934,7 @@ cc: save-session ( -- ) {
        0 write8
 
        \ Extensions
-       ext-reneg-len ext-max-frag-len + dup if
+       ext-reneg-len ext-max-frag-len + ext-ALPN-len + dup if
                write16
                ext-reneg-len dup if
                        0xFF01 write16
@@ -893,6 +947,16 @@ cc: save-session ( -- ) {
                        0x0001 write16
                        1 write16 addr-peer_log_max_frag_len get8 8 - write8
                then
+               ext-ALPN-len dup if
+                       \ Note: the selected protocol name was previously
+                       \ copied into the pad.
+                       0x0010 write16
+                       4 - dup write16
+                       2- dup write16
+                       1- addr-pad swap write-blob-head8
+               else
+                       drop
+               then
        else
                drop
        then ;
@@ -1289,6 +1353,7 @@ cc: verify-CV-sig ( sig-len -- err ) {
 : do-handshake ( initial -- )
        0 addr-application_data set8
        22 addr-record_type_out set8
+       0 addr-selected_protocol set16
        multihash-init
        read-ClientHello
        more-incoming-bytes? if ERR_UNEXPECTED fail then
index dcf888a..200cb16 100644 (file)
@@ -420,6 +420,12 @@ static const br_ssl_client_certificate_class ccert_vtable = {
 };
 
 static void
+free_alpn(void *alpn)
+{
+       xfree(*(char **)alpn);
+}
+
+static void
 usage_client(void)
 {
        fprintf(stderr,
@@ -462,6 +468,10 @@ usage_client(void)
 "   -fallback       send the TLS_FALLBACK_SCSV (i.e. claim a downgrade)\n");
        fprintf(stderr,
 "   -noreneg        prohibit renegotiations\n");
+       fprintf(stderr,
+"   -alpn name      add protocol name to list of protocols (ALPN extension)\n");
+       fprintf(stderr,
+"   -strictalpn     fail on ALPN mismatch\n");
 }
 
 /* see brssl.h */
@@ -478,6 +488,7 @@ do_client(int argc, char *argv[])
        const char *sni;
        anchor_list anchors = VEC_INIT;
        unsigned vmin, vmax;
+       VECTOR(const char *) alpn_names = VEC_INIT;
        cipher_suite *suites;
        size_t num_suites;
        uint16_t *suite_ids;
@@ -744,6 +755,16 @@ do_client(int argc, char *argv[])
                        fallback = 1;
                } else if (eqstr(arg, "-noreneg")) {
                        flags |= BR_OPT_NO_RENEGOTIATION;
+               } else if (eqstr(arg, "-alpn")) {
+                       if (++ i >= argc) {
+                               fprintf(stderr,
+                                       "ERROR: no argument for '-alpn'\n");
+                               usage_client();
+                               goto client_exit_error;
+                       }
+                       VEC_ADD(alpn_names, xstrdup(argv[i]));
+               } else if (eqstr(arg, "-strictalpn")) {
+                       flags |= BR_OPT_FAIL_ON_ALPN_MISMATCH;
                } else {
                        fprintf(stderr, "ERROR: unknown option: '%s'\n", arg);
                        usage_client();
@@ -1002,6 +1023,10 @@ do_client(int argc, char *argv[])
                br_ssl_client_set_min_clienthello_len(&cc, minhello_len);
        }
        br_ssl_engine_set_all_flags(&cc.eng, flags);
+       if (VEC_LEN(alpn_names) != 0) {
+               br_ssl_engine_set_protocol_names(&cc.eng,
+                       &VEC_ELT(alpn_names, 0), VEC_LEN(alpn_names));
+       }
 
        if (chain != NULL) {
                zc.vtable = &ccert_vtable;
@@ -1057,6 +1082,7 @@ client_exit:
        xfree(suites);
        xfree(suite_ids);
        VEC_CLEAREXT(anchors, &free_ta_contents);
+       VEC_CLEAREXT(alpn_names, &free_alpn);
        free_certificates(chain, chain_len);
        free_private_key(sk);
        xfree(iobuf);
index 67d2fa6..7fdf524 100644 (file)
@@ -229,6 +229,12 @@ usage_server(void)
 "   -hf names       add support for some hash functions (comma-separated)\n");
        fprintf(stderr,
 "   -serverpref     enforce server's preferences for cipher suites\n");
+       fprintf(stderr,
+"   -noreneg        prohibit renegotiations\n");
+       fprintf(stderr,
+"   -alpn name      add protocol name to list of protocols (ALPN extension)\n");
+       fprintf(stderr,
+"   -strictalpn     fail on ALPN mismatch\n");
        exit(EXIT_FAILURE);
 }
 
@@ -512,6 +518,12 @@ static const br_ssl_server_policy_class policy_vtable = {
        sp_do_sign
 };
 
+void
+free_alpn(void *alpn)
+{
+       xfree(*(char **)alpn);
+}
+
 /* see brssl.h */
 int
 do_server(int argc, char *argv[])
@@ -532,6 +544,7 @@ do_server(int argc, char *argv[])
        int cert_signer_algo;
        private_key *sk;
        anchor_list anchors = VEC_INIT;
+       VECTOR(const char *) alpn_names = VEC_INIT;
        br_x509_minimal_context xc;
        const br_hash_class *dnhash;
        size_t u;
@@ -781,6 +794,16 @@ do_server(int argc, char *argv[])
                        flags |= BR_OPT_ENFORCE_SERVER_PREFERENCES;
                } else if (eqstr(arg, "-noreneg")) {
                        flags |= BR_OPT_NO_RENEGOTIATION;
+               } else if (eqstr(arg, "-alpn")) {
+                       if (++ i >= argc) {
+                               fprintf(stderr,
+                                       "ERROR: no argument for '-alpn'\n");
+                               usage_server();
+                               goto server_exit_error;
+                       }
+                       VEC_ADD(alpn_names, xstrdup(argv[i]));
+               } else if (eqstr(arg, "-strictalpn")) {
+                       flags |= BR_OPT_FAIL_ON_ALPN_MISMATCH;
                } else {
                        fprintf(stderr, "ERROR: unknown option: '%s'\n", arg);
                        usage_server();
@@ -999,6 +1022,11 @@ do_server(int argc, char *argv[])
        br_ssl_session_cache_lru_init(&lru, cache, cache_len);
        br_ssl_server_set_cache(&cc, &lru.vtable);
 
+       if (VEC_LEN(alpn_names) != 0) {
+               br_ssl_engine_set_protocol_names(&cc.eng,
+                       &VEC_ELT(alpn_names, 0), VEC_LEN(alpn_names));
+       }
+
        /*
         * Set the policy handler (that chooses the actual cipher suite,
         * selects the certificate chain, and runs the private key
@@ -1091,6 +1119,7 @@ server_exit:
        free_certificates(chain, chain_len);
        free_private_key(sk);
        VEC_CLEAREXT(anchors, &free_ta_contents);
+       VEC_CLEAREXT(alpn_names, &free_alpn);
        xfree(iobuf);
        xfree(cache);
        if (fd >= 0) {
index 7fb73ea..e2a6d56 100644 (file)
@@ -213,6 +213,7 @@ run_ssl_engine(br_ssl_engine_context *cc, int fd, unsigned flags)
                recvapp = ((st & BR_SSL_RECVAPP) != 0);
                if (verbose && sendapp && !hsdetails) {
                        char csn[80];
+                       const char *pname;
 
                        fprintf(stderr, "Handshake completed\n");
                        fprintf(stderr, "   version:               ");
@@ -240,6 +241,12 @@ run_ssl_engine(br_ssl_engine_context *cc, int fd, unsigned flags)
                        fprintf(stderr, "   cipher suite:          %s\n", csn);
                        fprintf(stderr, "   secure renegotiation:  %s\n",
                                cc->reneg == 1 ? "no" : "yes");
+                       pname = br_ssl_engine_get_selected_protocol(cc);
+                       if (pname != NULL) {
+                               fprintf(stderr,
+                                       "   protocol name (ALPN):  %s\n",
+                                       pname);
+                       }
                        hsdetails = 1;
                }