mirror of
				https://github.com/cuberite/polarssl.git
				synced 2025-11-03 20:22:59 -05:00 
			
		
		
		
	Merged support for the ALPN extension
This commit is contained in:
		
						commit
						0763a401a7
					
				@ -1,7 +1,12 @@
 | 
			
		||||
PolarSSL ChangeLog (Sorted per branch, date)
 | 
			
		||||
 | 
			
		||||
ABI Alert: ALPN changes the ABI for the next release.
 | 
			
		||||
 | 
			
		||||
= PolarSSL 1.3 branch
 | 
			
		||||
 | 
			
		||||
Features
 | 
			
		||||
   * Support for the ALPN SSL extension
 | 
			
		||||
 | 
			
		||||
Changes
 | 
			
		||||
   * x509_crt_info() now prints information about parsed extensions as well
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -860,6 +860,16 @@
 | 
			
		||||
 */
 | 
			
		||||
#define POLARSSL_SSL_PROTO_TLS1_2
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \def POLARSSL_SSL_ALPN
 | 
			
		||||
 *
 | 
			
		||||
 * Enable support for Application Layer Protocol Negotiation.
 | 
			
		||||
 * draft-ietf-tls-applayerprotoneg-05
 | 
			
		||||
 *
 | 
			
		||||
 * Comment this macro to disable support for ALPN.
 | 
			
		||||
 */
 | 
			
		||||
#define POLARSSL_SSL_ALPN
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \def POLARSSL_SSL_SESSION_TICKETS
 | 
			
		||||
 *
 | 
			
		||||
 | 
			
		||||
@ -320,6 +320,7 @@
 | 
			
		||||
#define SSL_ALERT_MSG_UNSUPPORTED_EXT      110  /* 0x6E */
 | 
			
		||||
#define SSL_ALERT_MSG_UNRECOGNIZED_NAME    112  /* 0x70 */
 | 
			
		||||
#define SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY 115  /* 0x73 */
 | 
			
		||||
#define SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL 120 /* 0x78 */
 | 
			
		||||
 | 
			
		||||
#define SSL_HS_HELLO_REQUEST            0
 | 
			
		||||
#define SSL_HS_CLIENT_HELLO             1
 | 
			
		||||
@ -348,6 +349,8 @@
 | 
			
		||||
 | 
			
		||||
#define TLS_EXT_SIG_ALG                     13
 | 
			
		||||
 | 
			
		||||
#define TLS_EXT_ALPN                        16
 | 
			
		||||
 | 
			
		||||
#define TLS_EXT_SESSION_TICKET              35
 | 
			
		||||
 | 
			
		||||
#define TLS_EXT_RENEGOTIATION_INFO      0xFF01
 | 
			
		||||
@ -762,6 +765,14 @@ struct _ssl_context
 | 
			
		||||
    size_t         hostname_len;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
    /*
 | 
			
		||||
     * ALPN extension
 | 
			
		||||
     */
 | 
			
		||||
    const char **alpn_list;     /*!<  ordered list of supported protocols   */
 | 
			
		||||
    const char *alpn_chosen;    /*!<  negotiated protocol                   */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Secure renegotiation
 | 
			
		||||
     */
 | 
			
		||||
@ -1232,6 +1243,30 @@ void ssl_set_sni( ssl_context *ssl,
 | 
			
		||||
                  void *p_sni );
 | 
			
		||||
#endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
/**
 | 
			
		||||
 * \brief          Set the supported Application Layer Protocols.
 | 
			
		||||
 *
 | 
			
		||||
 * \param ssl      SSL context
 | 
			
		||||
 * \param protos   NULL-terminated list of supported protocols,
 | 
			
		||||
 *                 in decreasing preference order.
 | 
			
		||||
 *
 | 
			
		||||
 * \return         0 on success, or POLARSSL_ERR_SSL_BAD_INPUT_DATA.
 | 
			
		||||
 */
 | 
			
		||||
int ssl_set_alpn_protocols( ssl_context *ssl, const char **protos );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief          Get the name of the negotiated Application Layer Protocol.
 | 
			
		||||
 *                 This function should be called after the handshake is
 | 
			
		||||
 *                 completed.
 | 
			
		||||
 *
 | 
			
		||||
 * \param ssl      SSL context
 | 
			
		||||
 *
 | 
			
		||||
 * \return         Protcol name, or NULL if no protocol was negotiated.
 | 
			
		||||
 */
 | 
			
		||||
const char *ssl_get_alpn_protocol( const ssl_context *ssl );
 | 
			
		||||
#endif /* POLARSSL_SSL_ALPN */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief          Set the maximum supported version sent from the client side
 | 
			
		||||
 *                 and/or accepted at the server side
 | 
			
		||||
 | 
			
		||||
@ -383,6 +383,54 @@ static void ssl_write_session_ticket_ext( ssl_context *ssl,
 | 
			
		||||
}
 | 
			
		||||
#endif /* POLARSSL_SSL_SESSION_TICKETS */
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
static void ssl_write_alpn_ext( ssl_context *ssl,
 | 
			
		||||
                                unsigned char *buf, size_t *olen )
 | 
			
		||||
{
 | 
			
		||||
    unsigned char *p = buf;
 | 
			
		||||
    const char **cur;
 | 
			
		||||
 | 
			
		||||
    if( ssl->alpn_list == NULL )
 | 
			
		||||
    {
 | 
			
		||||
        *olen = 0;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) );
 | 
			
		||||
 | 
			
		||||
    *p++ = (unsigned char)( ( TLS_EXT_ALPN >> 8 ) & 0xFF );
 | 
			
		||||
    *p++ = (unsigned char)( ( TLS_EXT_ALPN      ) & 0xFF );
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * opaque ProtocolName<1..2^8-1>;
 | 
			
		||||
     *
 | 
			
		||||
     * struct {
 | 
			
		||||
     *     ProtocolName protocol_name_list<2..2^16-1>
 | 
			
		||||
     * } ProtocolNameList;
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /* Skip writing extension and list length for now */
 | 
			
		||||
    p += 4;
 | 
			
		||||
 | 
			
		||||
    for( cur = ssl->alpn_list; *cur != NULL; cur++ )
 | 
			
		||||
    {
 | 
			
		||||
        *p = (unsigned char)( strlen( *cur ) & 0xFF );
 | 
			
		||||
        memcpy( p + 1, *cur, *p );
 | 
			
		||||
        p += 1 + *p;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *olen = p - buf;
 | 
			
		||||
 | 
			
		||||
    /* List length = olen - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */
 | 
			
		||||
    buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF );
 | 
			
		||||
    buf[5] = (unsigned char)( ( ( *olen - 6 )      ) & 0xFF );
 | 
			
		||||
 | 
			
		||||
    /* Extension length = olen - 2 (ext_type) - 2 (ext_len) */
 | 
			
		||||
    buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF );
 | 
			
		||||
    buf[3] = (unsigned char)( ( ( *olen - 4 )      ) & 0xFF );
 | 
			
		||||
}
 | 
			
		||||
#endif /* POLARSSL_SSL_ALPN */
 | 
			
		||||
 | 
			
		||||
static int ssl_write_client_hello( ssl_context *ssl )
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
@ -595,6 +643,11 @@ static int ssl_write_client_hello( ssl_context *ssl )
 | 
			
		||||
    ext_len += olen;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
    ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen );
 | 
			
		||||
    ext_len += olen;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d",
 | 
			
		||||
                   ext_len ) );
 | 
			
		||||
 | 
			
		||||
@ -753,6 +806,54 @@ static int ssl_parse_supported_point_formats_ext( ssl_context *ssl,
 | 
			
		||||
}
 | 
			
		||||
#endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
static int ssl_parse_alpn_ext( ssl_context *ssl,
 | 
			
		||||
                               const unsigned char *buf, size_t len )
 | 
			
		||||
{
 | 
			
		||||
    size_t list_len, name_len;
 | 
			
		||||
    const char **p;
 | 
			
		||||
 | 
			
		||||
    /* If we didn't send it, the server shouldn't send it */
 | 
			
		||||
    if( ssl->alpn_list == NULL )
 | 
			
		||||
        return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * opaque ProtocolName<1..2^8-1>;
 | 
			
		||||
     *
 | 
			
		||||
     * struct {
 | 
			
		||||
     *     ProtocolName protocol_name_list<2..2^16-1>
 | 
			
		||||
     * } ProtocolNameList;
 | 
			
		||||
     *
 | 
			
		||||
     * the "ProtocolNameList" MUST contain exactly one "ProtocolName"
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */
 | 
			
		||||
    if( len < 4 )
 | 
			
		||||
        return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
 | 
			
		||||
 | 
			
		||||
    list_len = ( buf[0] << 8 ) | buf[1];
 | 
			
		||||
    if( list_len != len - 2 )
 | 
			
		||||
        return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
 | 
			
		||||
 | 
			
		||||
    name_len = buf[2];
 | 
			
		||||
    if( name_len != list_len - 1 )
 | 
			
		||||
        return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
 | 
			
		||||
 | 
			
		||||
    /* Check that the server chosen protocol was in our list and save it */
 | 
			
		||||
    for( p = ssl->alpn_list; *p != NULL; p++ )
 | 
			
		||||
    {
 | 
			
		||||
        if( name_len == strlen( *p ) &&
 | 
			
		||||
            memcmp( buf + 3, *p, name_len ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            ssl->alpn_chosen = *p;
 | 
			
		||||
            return( 0 );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
 | 
			
		||||
}
 | 
			
		||||
#endif /* POLARSSL_SSL_ALPN */
 | 
			
		||||
 | 
			
		||||
static int ssl_parse_server_hello( ssl_context *ssl )
 | 
			
		||||
{
 | 
			
		||||
    int ret, i, comp;
 | 
			
		||||
@ -1023,6 +1124,16 @@ static int ssl_parse_server_hello( ssl_context *ssl )
 | 
			
		||||
            break;
 | 
			
		||||
#endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
        case TLS_EXT_ALPN:
 | 
			
		||||
            SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
 | 
			
		||||
 | 
			
		||||
            if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 )
 | 
			
		||||
                return( ret );
 | 
			
		||||
 | 
			
		||||
            break;
 | 
			
		||||
#endif /* POLARSSL_SSL_ALPN */
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
 | 
			
		||||
                           ext_id ) );
 | 
			
		||||
 | 
			
		||||
@ -683,6 +683,69 @@ static int ssl_parse_session_ticket_ext( ssl_context *ssl,
 | 
			
		||||
}
 | 
			
		||||
#endif /* POLARSSL_SSL_SESSION_TICKETS */
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
static int ssl_parse_alpn_ext( ssl_context *ssl,
 | 
			
		||||
                               unsigned char *buf, size_t len )
 | 
			
		||||
{
 | 
			
		||||
    size_t list_len, cur_len;
 | 
			
		||||
    const unsigned char *theirs, *start, *end;
 | 
			
		||||
    const char **ours;
 | 
			
		||||
 | 
			
		||||
    /* If ALPN not configured, just ignore the extension */
 | 
			
		||||
    if( ssl->alpn_list == NULL )
 | 
			
		||||
        return( 0 );
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * opaque ProtocolName<1..2^8-1>;
 | 
			
		||||
     *
 | 
			
		||||
     * struct {
 | 
			
		||||
     *     ProtocolName protocol_name_list<2..2^16-1>
 | 
			
		||||
     * } ProtocolNameList;
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */
 | 
			
		||||
    if( len < 4 )
 | 
			
		||||
        return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
 | 
			
		||||
 | 
			
		||||
    list_len = ( buf[0] << 8 ) | buf[1];
 | 
			
		||||
    if( list_len != len - 2 )
 | 
			
		||||
        return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Use our order of preference
 | 
			
		||||
     */
 | 
			
		||||
    start = buf + 2;
 | 
			
		||||
    end = buf + len;
 | 
			
		||||
    for( ours = ssl->alpn_list; *ours != NULL; ours++ )
 | 
			
		||||
    {
 | 
			
		||||
        for( theirs = start; theirs != end; theirs += cur_len )
 | 
			
		||||
        {
 | 
			
		||||
            /* If the list is well formed, we should get equality first */
 | 
			
		||||
            if( theirs > end )
 | 
			
		||||
                return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
 | 
			
		||||
 | 
			
		||||
            cur_len = *theirs++;
 | 
			
		||||
 | 
			
		||||
            /* Empty strings MUST NOT be included */
 | 
			
		||||
            if( cur_len == 0 )
 | 
			
		||||
                return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
 | 
			
		||||
 | 
			
		||||
            if( cur_len == strlen( *ours ) &&
 | 
			
		||||
                memcmp( theirs, *ours, cur_len ) == 0 )
 | 
			
		||||
            {
 | 
			
		||||
                ssl->alpn_chosen = *ours;
 | 
			
		||||
                return( 0 );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* If we get there, no match was found */
 | 
			
		||||
    ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL,
 | 
			
		||||
                            SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL );
 | 
			
		||||
    return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
 | 
			
		||||
}
 | 
			
		||||
#endif /* POLARSSL_SSL_ALPN */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Auxiliary functions for ServerHello parsing and related actions
 | 
			
		||||
 */
 | 
			
		||||
@ -1385,6 +1448,16 @@ static int ssl_parse_client_hello( ssl_context *ssl )
 | 
			
		||||
            break;
 | 
			
		||||
#endif /* POLARSSL_SSL_SESSION_TICKETS */
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
        case TLS_EXT_ALPN:
 | 
			
		||||
            SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
 | 
			
		||||
 | 
			
		||||
            ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size );
 | 
			
		||||
            if( ret != 0 )
 | 
			
		||||
                return( ret );
 | 
			
		||||
            break;
 | 
			
		||||
#endif /* POLARSSL_SSL_SESSION_TICKETS */
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
 | 
			
		||||
                           ext_id ) );
 | 
			
		||||
@ -1625,6 +1698,42 @@ static void ssl_write_supported_point_formats_ext( ssl_context *ssl,
 | 
			
		||||
}
 | 
			
		||||
#endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN )
 | 
			
		||||
static void ssl_write_alpn_ext( ssl_context *ssl,
 | 
			
		||||
                                unsigned char *buf, size_t *olen )
 | 
			
		||||
{
 | 
			
		||||
    if( ssl->alpn_chosen == NULL )
 | 
			
		||||
    {
 | 
			
		||||
        *olen = 0;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SSL_DEBUG_MSG( 3, ( "server hello, adding alpn extension" ) );
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * 0 . 1    ext identifier
 | 
			
		||||
     * 2 . 3    ext length
 | 
			
		||||
     * 4 . 5    protocol list length
 | 
			
		||||
     * 6 . 6    protocol name length
 | 
			
		||||
     * 7 . 7+n  protocol name
 | 
			
		||||
     */
 | 
			
		||||
    buf[0] = (unsigned char)( ( TLS_EXT_ALPN >> 8 ) & 0xFF );
 | 
			
		||||
    buf[1] = (unsigned char)( ( TLS_EXT_ALPN      ) & 0xFF );
 | 
			
		||||
 | 
			
		||||
    *olen = 7 + strlen( ssl->alpn_chosen );
 | 
			
		||||
 | 
			
		||||
    buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF );
 | 
			
		||||
    buf[3] = (unsigned char)( ( ( *olen - 4 )      ) & 0xFF );
 | 
			
		||||
 | 
			
		||||
    buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF );
 | 
			
		||||
    buf[5] = (unsigned char)( ( ( *olen - 6 )      ) & 0xFF );
 | 
			
		||||
 | 
			
		||||
    buf[6] = (unsigned char)( ( ( *olen - 7 )      ) & 0xFF );
 | 
			
		||||
 | 
			
		||||
    memcpy( buf + 7, ssl->alpn_chosen, *olen - 7 );
 | 
			
		||||
}
 | 
			
		||||
#endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */
 | 
			
		||||
 | 
			
		||||
static int ssl_write_server_hello( ssl_context *ssl )
 | 
			
		||||
{
 | 
			
		||||
#if defined(POLARSSL_HAVE_TIME)
 | 
			
		||||
@ -1791,6 +1900,11 @@ static int ssl_write_server_hello( ssl_context *ssl )
 | 
			
		||||
    ext_len += olen;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
    ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen );
 | 
			
		||||
    ext_len += olen;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %d", ext_len ) );
 | 
			
		||||
 | 
			
		||||
    *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
 | 
			
		||||
 | 
			
		||||
@ -3521,6 +3521,10 @@ int ssl_session_reset( ssl_context *ssl )
 | 
			
		||||
        ssl->session = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
    ssl->alpn_chosen = NULL;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
 | 
			
		||||
        return( ret );
 | 
			
		||||
 | 
			
		||||
@ -3915,6 +3919,37 @@ void ssl_set_sni( ssl_context *ssl,
 | 
			
		||||
}
 | 
			
		||||
#endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
int ssl_set_alpn_protocols( ssl_context *ssl, const char **protos )
 | 
			
		||||
{
 | 
			
		||||
    size_t cur_len, tot_len;
 | 
			
		||||
    const char **p;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * "Empty strings MUST NOT be included and byte strings MUST NOT be
 | 
			
		||||
     * truncated". Check lengths now rather than later.
 | 
			
		||||
     */
 | 
			
		||||
    tot_len = 0;
 | 
			
		||||
    for( p = protos; *p != NULL; p++ )
 | 
			
		||||
    {
 | 
			
		||||
        cur_len = strlen( *p );
 | 
			
		||||
        tot_len += cur_len;
 | 
			
		||||
 | 
			
		||||
        if( cur_len == 0 || cur_len > 255 || tot_len > 65535 )
 | 
			
		||||
            return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ssl->alpn_list = protos;
 | 
			
		||||
 | 
			
		||||
    return( 0 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *ssl_get_alpn_protocol( const ssl_context *ssl )
 | 
			
		||||
{
 | 
			
		||||
    return ssl->alpn_chosen;
 | 
			
		||||
}
 | 
			
		||||
#endif /* POLARSSL_SSL_ALPN */
 | 
			
		||||
 | 
			
		||||
void ssl_set_max_version( ssl_context *ssl, int major, int minor )
 | 
			
		||||
{
 | 
			
		||||
    if( major >= SSL_MIN_MAJOR_VERSION && major <= SSL_MAX_MAJOR_VERSION &&
 | 
			
		||||
 | 
			
		||||
@ -65,6 +65,7 @@
 | 
			
		||||
#define DFL_RECONNECT           0
 | 
			
		||||
#define DFL_RECO_DELAY          0
 | 
			
		||||
#define DFL_TICKETS             SSL_SESSION_TICKETS_ENABLED
 | 
			
		||||
#define DFL_ALPN_STRING         NULL
 | 
			
		||||
 | 
			
		||||
#define LONG_HEADER "User-agent: blah-blah-blah-blah-blah-blah-blah-blah-"   \
 | 
			
		||||
    "-01--blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-" \
 | 
			
		||||
@ -108,6 +109,7 @@ struct options
 | 
			
		||||
    int reconnect;              /* attempt to resume session                */
 | 
			
		||||
    int reco_delay;             /* delay in seconds before resuming session */
 | 
			
		||||
    int tickets;                /* enable / disable session tickets         */
 | 
			
		||||
    const char *alpn_string;    /* ALPN supported protocols                 */
 | 
			
		||||
} opt;
 | 
			
		||||
 | 
			
		||||
static void my_debug( void *ctx, int level, const char *str )
 | 
			
		||||
@ -248,11 +250,19 @@ static int my_verify( void *data, x509_crt *crt, int depth, int *flags )
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_TIMING_C)
 | 
			
		||||
#define USAGE_TIME \
 | 
			
		||||
    "    reco_delay=%%d      default: 0 seconds\n"
 | 
			
		||||
    "    reco_delay=%%d       default: 0 seconds\n"
 | 
			
		||||
#else
 | 
			
		||||
#define USAGE_TIME ""
 | 
			
		||||
#endif /* POLARSSL_TIMING_C */
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
#define USAGE_ALPN \
 | 
			
		||||
    "    alpn=%%s             default: \"\" (disabled)\n"   \
 | 
			
		||||
    "                        example: spdy/1,http/1.1\n"
 | 
			
		||||
#else
 | 
			
		||||
#define USAGE_ALPN ""
 | 
			
		||||
#endif /* POLARSSL_SSL_ALPN */
 | 
			
		||||
 | 
			
		||||
#define USAGE \
 | 
			
		||||
    "\n usage: ssl_client2 param=<>...\n"                   \
 | 
			
		||||
    "\n acceptable parameters:\n"                           \
 | 
			
		||||
@ -278,6 +288,7 @@ static int my_verify( void *data, x509_crt *crt, int depth, int *flags )
 | 
			
		||||
    USAGE_TICKETS                                           \
 | 
			
		||||
    USAGE_MAX_FRAG_LEN                                      \
 | 
			
		||||
    USAGE_TRUNC_HMAC                                        \
 | 
			
		||||
    USAGE_ALPN                                              \
 | 
			
		||||
    "\n"                                                    \
 | 
			
		||||
    "    min_version=%%s      default: \"\" (ssl3)\n"       \
 | 
			
		||||
    "    max_version=%%s      default: \"\" (tls1_2)\n"     \
 | 
			
		||||
@ -310,6 +321,9 @@ int main( int argc, char *argv[] )
 | 
			
		||||
#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
 | 
			
		||||
    unsigned char psk[256];
 | 
			
		||||
    size_t psk_len = 0;
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
    const char *alpn_list[10];
 | 
			
		||||
#endif
 | 
			
		||||
    const char *pers = "ssl_client2";
 | 
			
		||||
 | 
			
		||||
@ -336,6 +350,9 @@ int main( int argc, char *argv[] )
 | 
			
		||||
    x509_crt_init( &clicert );
 | 
			
		||||
    pk_init( &pkey );
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
    memset( alpn_list, 0, sizeof alpn_list );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if( argc == 0 )
 | 
			
		||||
    {
 | 
			
		||||
@ -383,6 +400,7 @@ int main( int argc, char *argv[] )
 | 
			
		||||
    opt.reconnect           = DFL_RECONNECT;
 | 
			
		||||
    opt.reco_delay          = DFL_RECO_DELAY;
 | 
			
		||||
    opt.tickets             = DFL_TICKETS;
 | 
			
		||||
    opt.alpn_string         = DFL_ALPN_STRING;
 | 
			
		||||
 | 
			
		||||
    for( i = 1; i < argc; i++ )
 | 
			
		||||
    {
 | 
			
		||||
@ -475,6 +493,10 @@ int main( int argc, char *argv[] )
 | 
			
		||||
            if( opt.tickets < 0 || opt.tickets > 2 )
 | 
			
		||||
                goto usage;
 | 
			
		||||
        }
 | 
			
		||||
        else if( strcmp( p, "alpn" ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            opt.alpn_string = q;
 | 
			
		||||
        }
 | 
			
		||||
        else if( strcmp( p, "min_version" ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            if( strcmp( q, "ssl3" ) == 0 )
 | 
			
		||||
@ -635,6 +657,26 @@ int main( int argc, char *argv[] )
 | 
			
		||||
    }
 | 
			
		||||
#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
    if( opt.alpn_string != NULL )
 | 
			
		||||
    {
 | 
			
		||||
        p = (char *) opt.alpn_string;
 | 
			
		||||
        i = 0;
 | 
			
		||||
 | 
			
		||||
        /* Leave room for a final NULL in alpn_list */
 | 
			
		||||
        while( i < (int) sizeof alpn_list - 1 && *p != '\0' )
 | 
			
		||||
        {
 | 
			
		||||
            alpn_list[i++] = p;
 | 
			
		||||
 | 
			
		||||
            /* Terminate the current string and move on to next one */
 | 
			
		||||
            while( *p != ',' && *p != '\0' )
 | 
			
		||||
                p++;
 | 
			
		||||
            if( *p == ',' )
 | 
			
		||||
                *p++ = '\0';
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif /* POLARSSL_SSL_ALPN */
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * 0. Initialize the RNG and the session data
 | 
			
		||||
     */
 | 
			
		||||
@ -806,6 +848,11 @@ int main( int argc, char *argv[] )
 | 
			
		||||
        ssl_set_truncated_hmac( &ssl, SSL_TRUNC_HMAC_ENABLED );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
    if( opt.alpn_string != NULL )
 | 
			
		||||
        ssl_set_alpn_protocols( &ssl, alpn_list );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    ssl_set_rng( &ssl, ctr_drbg_random, &ctr_drbg );
 | 
			
		||||
    ssl_set_dbg( &ssl, my_debug, stdout );
 | 
			
		||||
 | 
			
		||||
@ -878,6 +925,15 @@ int main( int argc, char *argv[] )
 | 
			
		||||
    printf( " ok\n    [ Protocol is %s ]\n    [ Ciphersuite is %s ]\n",
 | 
			
		||||
            ssl_get_version( &ssl ), ssl_get_ciphersuite( &ssl ) );
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
    if( opt.alpn_string != NULL )
 | 
			
		||||
    {
 | 
			
		||||
        const char *alp = ssl_get_alpn_protocol( &ssl );
 | 
			
		||||
        printf( "    [ Application Layer Protocol is %s ]\n",
 | 
			
		||||
                alp ? alp : "(none)" );
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if( opt.reconnect != 0 )
 | 
			
		||||
    {
 | 
			
		||||
        printf("  . Saving session for reuse..." );
 | 
			
		||||
 | 
			
		||||
@ -85,6 +85,7 @@
 | 
			
		||||
#define DFL_CACHE_MAX           -1
 | 
			
		||||
#define DFL_CACHE_TIMEOUT       -1
 | 
			
		||||
#define DFL_SNI                 NULL
 | 
			
		||||
#define DFL_ALPN_STRING         NULL
 | 
			
		||||
 | 
			
		||||
#define LONG_RESPONSE "<p>01-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
 | 
			
		||||
    "02-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n"  \
 | 
			
		||||
@ -131,6 +132,7 @@ struct options
 | 
			
		||||
    int cache_max;              /* max number of session cache entries      */
 | 
			
		||||
    int cache_timeout;          /* expiration delay of session cache entries */
 | 
			
		||||
    char *sni;                  /* string decribing sni information         */
 | 
			
		||||
    const char *alpn_string;    /* ALPN supported protocols                 */
 | 
			
		||||
} opt;
 | 
			
		||||
 | 
			
		||||
static void my_debug( void *ctx, int level, const char *str )
 | 
			
		||||
@ -245,6 +247,14 @@ static int my_send( void *ctx, const unsigned char *buf, size_t len )
 | 
			
		||||
#define USAGE_MAX_FRAG_LEN ""
 | 
			
		||||
#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
#define USAGE_ALPN \
 | 
			
		||||
    "    alpn=%%s             default: \"\" (disabled)\n"   \
 | 
			
		||||
    "                        example: spdy/1,http/1.1\n"
 | 
			
		||||
#else
 | 
			
		||||
#define USAGE_ALPN ""
 | 
			
		||||
#endif /* POLARSSL_SSL_ALPN */
 | 
			
		||||
 | 
			
		||||
#define USAGE \
 | 
			
		||||
    "\n usage: ssl_server2 param=<>...\n"                   \
 | 
			
		||||
    "\n acceptable parameters:\n"                           \
 | 
			
		||||
@ -267,6 +277,7 @@ static int my_send( void *ctx, const unsigned char *buf, size_t len )
 | 
			
		||||
    USAGE_TICKETS                                           \
 | 
			
		||||
    USAGE_CACHE                                             \
 | 
			
		||||
    USAGE_MAX_FRAG_LEN                                      \
 | 
			
		||||
    USAGE_ALPN                                              \
 | 
			
		||||
    "\n"                                                    \
 | 
			
		||||
    "    min_version=%%s      default: \"ssl3\"\n"          \
 | 
			
		||||
    "    max_version=%%s      default: \"tls1_2\"\n"        \
 | 
			
		||||
@ -429,6 +440,9 @@ int main( int argc, char *argv[] )
 | 
			
		||||
#if defined(POLARSSL_SNI)
 | 
			
		||||
    sni_entry *sni_info = NULL;
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
    const char *alpn_list[10];
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
 | 
			
		||||
    unsigned char alloc_buf[100000];
 | 
			
		||||
#endif
 | 
			
		||||
@ -456,6 +470,9 @@ int main( int argc, char *argv[] )
 | 
			
		||||
#if defined(POLARSSL_SSL_CACHE_C)
 | 
			
		||||
    ssl_cache_init( &cache );
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
    memset( alpn_list, 0, sizeof alpn_list );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if( argc == 0 )
 | 
			
		||||
    {
 | 
			
		||||
@ -504,6 +521,7 @@ int main( int argc, char *argv[] )
 | 
			
		||||
    opt.cache_max           = DFL_CACHE_MAX;
 | 
			
		||||
    opt.cache_timeout       = DFL_CACHE_TIMEOUT;
 | 
			
		||||
    opt.sni                 = DFL_SNI;
 | 
			
		||||
    opt.alpn_string         = DFL_ALPN_STRING;
 | 
			
		||||
 | 
			
		||||
    for( i = 1; i < argc; i++ )
 | 
			
		||||
    {
 | 
			
		||||
@ -653,6 +671,10 @@ int main( int argc, char *argv[] )
 | 
			
		||||
            else
 | 
			
		||||
                goto usage;
 | 
			
		||||
        }
 | 
			
		||||
        else if( strcmp( p, "alpn" ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            opt.alpn_string = q;
 | 
			
		||||
        }
 | 
			
		||||
        else if( strcmp( p, "tickets" ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            opt.tickets = atoi( q );
 | 
			
		||||
@ -760,6 +782,26 @@ int main( int argc, char *argv[] )
 | 
			
		||||
    }
 | 
			
		||||
#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
    if( opt.alpn_string != NULL )
 | 
			
		||||
    {
 | 
			
		||||
        p = (char *) opt.alpn_string;
 | 
			
		||||
        i = 0;
 | 
			
		||||
 | 
			
		||||
        /* Leave room for a final NULL in alpn_list */
 | 
			
		||||
        while( i < (int) sizeof alpn_list - 1 && *p != '\0' )
 | 
			
		||||
        {
 | 
			
		||||
            alpn_list[i++] = p;
 | 
			
		||||
 | 
			
		||||
            /* Terminate the current string and move on to next one */
 | 
			
		||||
            while( *p != ',' && *p != '\0' )
 | 
			
		||||
                p++;
 | 
			
		||||
            if( *p == ',' )
 | 
			
		||||
                *p++ = '\0';
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif /* POLARSSL_SSL_ALPN */
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * 0. Initialize the RNG and the session data
 | 
			
		||||
     */
 | 
			
		||||
@ -974,6 +1016,11 @@ int main( int argc, char *argv[] )
 | 
			
		||||
    ssl_set_max_frag_len( &ssl, opt.mfl_code );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
    if( opt.alpn_string != NULL )
 | 
			
		||||
        ssl_set_alpn_protocols( &ssl, alpn_list );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    ssl_set_rng( &ssl, ctr_drbg_random, &ctr_drbg );
 | 
			
		||||
    ssl_set_dbg( &ssl, my_debug, stdout );
 | 
			
		||||
 | 
			
		||||
@ -1103,6 +1150,15 @@ reset:
 | 
			
		||||
    printf( " ok\n    [ Protocol is %s ]\n    [ Ciphersuite is %s ]\n",
 | 
			
		||||
            ssl_get_version( &ssl ), ssl_get_ciphersuite( &ssl ) );
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_SSL_ALPN)
 | 
			
		||||
    if( opt.alpn_string != NULL )
 | 
			
		||||
    {
 | 
			
		||||
        const char *alp = ssl_get_alpn_protocol( &ssl );
 | 
			
		||||
        printf( "    [ Application Layer Protocol is %s ]\n",
 | 
			
		||||
                alp ? alp : "(none)" );
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
 | 
			
		||||
    /*
 | 
			
		||||
     * 5. Verify the server certificate
 | 
			
		||||
 | 
			
		||||
@ -21,6 +21,8 @@ O_CLI="echo 'GET / HTTP/1.0' | $OPENSSL_CMD s_client"
 | 
			
		||||
TESTS=0
 | 
			
		||||
FAILS=0
 | 
			
		||||
 | 
			
		||||
CONFIG_H='../include/polarssl/config.h'
 | 
			
		||||
 | 
			
		||||
MEMCHECK=0
 | 
			
		||||
FILTER='.*'
 | 
			
		||||
EXCLUDE='SSLv2' # disabled by default, needs OpenSSL compiled with SSLv2
 | 
			
		||||
@ -804,6 +806,8 @@ run_test    "Non-blocking I/O #7 (session-id resume)" \
 | 
			
		||||
            -C "ssl_handshake returned" \
 | 
			
		||||
            -c "Read from server: .* bytes read"
 | 
			
		||||
 | 
			
		||||
# Tests for version negotiation
 | 
			
		||||
 | 
			
		||||
run_test    "Version check #1 (all -> 1.2)" \
 | 
			
		||||
            "$P_SRV" \
 | 
			
		||||
            "$P_CLI" \
 | 
			
		||||
@ -874,6 +878,96 @@ run_test    "Version check #8 (srv min 1.2, cli max 1.1 -> fail)" \
 | 
			
		||||
            -c "ssl_handshake returned" \
 | 
			
		||||
            -s "SSL - Handshake protocol not within min/max boundaries"
 | 
			
		||||
 | 
			
		||||
# Tests for ALPN extension
 | 
			
		||||
 | 
			
		||||
if grep '^#define POLARSSL_SSL_ALPN' $CONFIG_H >/dev/null; then
 | 
			
		||||
 | 
			
		||||
run_test    "ALPN #0 (none)" \
 | 
			
		||||
            "$P_SRV debug_level=4" \
 | 
			
		||||
            "$P_CLI debug_level=4" \
 | 
			
		||||
            0 \
 | 
			
		||||
            -C "client hello, adding alpn extension" \
 | 
			
		||||
            -S "found alpn extension" \
 | 
			
		||||
            -C "got an alert message, type: \\[2:120]" \
 | 
			
		||||
            -S "server hello, adding alpn extension" \
 | 
			
		||||
            -C "found alpn extension " \
 | 
			
		||||
            -C "Application Layer Protocol is" \
 | 
			
		||||
            -S "Application Layer Protocol is"
 | 
			
		||||
 | 
			
		||||
run_test    "ALPN #1 (client only)" \
 | 
			
		||||
            "$P_SRV debug_level=4" \
 | 
			
		||||
            "$P_CLI debug_level=4 alpn=abc,1234" \
 | 
			
		||||
            0 \
 | 
			
		||||
            -c "client hello, adding alpn extension" \
 | 
			
		||||
            -s "found alpn extension" \
 | 
			
		||||
            -C "got an alert message, type: \\[2:120]" \
 | 
			
		||||
            -S "server hello, adding alpn extension" \
 | 
			
		||||
            -C "found alpn extension " \
 | 
			
		||||
            -c "Application Layer Protocol is (none)" \
 | 
			
		||||
            -S "Application Layer Protocol is"
 | 
			
		||||
 | 
			
		||||
run_test    "ALPN #2 (server only)" \
 | 
			
		||||
            "$P_SRV debug_level=4 alpn=abc,1234" \
 | 
			
		||||
            "$P_CLI debug_level=4" \
 | 
			
		||||
            0 \
 | 
			
		||||
            -C "client hello, adding alpn extension" \
 | 
			
		||||
            -S "found alpn extension" \
 | 
			
		||||
            -C "got an alert message, type: \\[2:120]" \
 | 
			
		||||
            -S "server hello, adding alpn extension" \
 | 
			
		||||
            -C "found alpn extension " \
 | 
			
		||||
            -C "Application Layer Protocol is" \
 | 
			
		||||
            -s "Application Layer Protocol is (none)"
 | 
			
		||||
 | 
			
		||||
run_test    "ALPN #3 (both, common cli1-srv1)" \
 | 
			
		||||
            "$P_SRV debug_level=4 alpn=abc,1234" \
 | 
			
		||||
            "$P_CLI debug_level=4 alpn=abc,1234" \
 | 
			
		||||
            0 \
 | 
			
		||||
            -c "client hello, adding alpn extension" \
 | 
			
		||||
            -s "found alpn extension" \
 | 
			
		||||
            -C "got an alert message, type: \\[2:120]" \
 | 
			
		||||
            -s "server hello, adding alpn extension" \
 | 
			
		||||
            -c "found alpn extension" \
 | 
			
		||||
            -c "Application Layer Protocol is abc" \
 | 
			
		||||
            -s "Application Layer Protocol is abc"
 | 
			
		||||
 | 
			
		||||
run_test    "ALPN #4 (both, common cli2-srv1)" \
 | 
			
		||||
            "$P_SRV debug_level=4 alpn=abc,1234" \
 | 
			
		||||
            "$P_CLI debug_level=4 alpn=1234,abc" \
 | 
			
		||||
            0 \
 | 
			
		||||
            -c "client hello, adding alpn extension" \
 | 
			
		||||
            -s "found alpn extension" \
 | 
			
		||||
            -C "got an alert message, type: \\[2:120]" \
 | 
			
		||||
            -s "server hello, adding alpn extension" \
 | 
			
		||||
            -c "found alpn extension" \
 | 
			
		||||
            -c "Application Layer Protocol is abc" \
 | 
			
		||||
            -s "Application Layer Protocol is abc"
 | 
			
		||||
 | 
			
		||||
run_test    "ALPN #5 (both, common cli1-srv2)" \
 | 
			
		||||
            "$P_SRV debug_level=4 alpn=abc,1234" \
 | 
			
		||||
            "$P_CLI debug_level=4 alpn=1234,abcde" \
 | 
			
		||||
            0 \
 | 
			
		||||
            -c "client hello, adding alpn extension" \
 | 
			
		||||
            -s "found alpn extension" \
 | 
			
		||||
            -C "got an alert message, type: \\[2:120]" \
 | 
			
		||||
            -s "server hello, adding alpn extension" \
 | 
			
		||||
            -c "found alpn extension" \
 | 
			
		||||
            -c "Application Layer Protocol is 1234" \
 | 
			
		||||
            -s "Application Layer Protocol is 1234"
 | 
			
		||||
 | 
			
		||||
run_test    "ALPN #6 (both, no common)" \
 | 
			
		||||
            "$P_SRV debug_level=4 alpn=abc,123" \
 | 
			
		||||
            "$P_CLI debug_level=4 alpn=1234,abcde" \
 | 
			
		||||
            1 \
 | 
			
		||||
            -c "client hello, adding alpn extension" \
 | 
			
		||||
            -s "found alpn extension" \
 | 
			
		||||
            -c "got an alert message, type: \\[2:120]" \
 | 
			
		||||
            -S "server hello, adding alpn extension" \
 | 
			
		||||
            -C "found alpn extension" \
 | 
			
		||||
            -C "Application Layer Protocol is 1234" \
 | 
			
		||||
            -S "Application Layer Protocol is 1234"
 | 
			
		||||
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Final report
 | 
			
		||||
 | 
			
		||||
echo "------------------------------------------------------------------------"
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user