ssl/statem/extensions_srvr.c:738: error: MEMORY_LEAK
  memory dynamically allocated by call to `EVP_MD_CTX_new()` at line 733, column 12 is not reachable after line 738, column 9.
Showing all 67 steps of the trace


ssl/statem/extensions_srvr.c:696:1: start of procedure tls_parse_ctos_cookie()
694.   }
695.   
696. > int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
697.                             size_t chainidx)
698.   {

ssl/statem/extensions_srvr.c:711:9: Taking false branch
709.   
710.       /* Ignore any cookie if we're not set up to verify it */
711.       if (s->ctx->app_verify_cookie_cb == NULL
               ^
712.               || (s->s3->flags & TLS1_FLAGS_STATELESS) == 0)
713.           return 1;

ssl/statem/extensions_srvr.c:712:16: Taking false branch
710.       /* Ignore any cookie if we're not set up to verify it */
711.       if (s->ctx->app_verify_cookie_cb == NULL
712.               || (s->s3->flags & TLS1_FLAGS_STATELESS) == 0)
                      ^
713.           return 1;
714.   

ssl/statem/extensions_srvr.c:715:10: Taking false branch
713.           return 1;
714.   
715.       if (!PACKET_as_length_prefixed_2(pkt, &cookie)) {
                ^
716.           SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
717.                    SSL_R_LENGTH_MISMATCH);

ssl/statem/extensions_srvr.c:721:5: 
719.       }
720.   
721. >     raw = cookie;
722.       data = PACKET_data(&raw);
723.       rawlen = PACKET_remaining(&raw);

ssl/statem/extensions_srvr.c:722:5: 
720.   
721.       raw = cookie;
722. >     data = PACKET_data(&raw);
723.       rawlen = PACKET_remaining(&raw);
724.       if (rawlen < SHA256_DIGEST_LENGTH

ssl/packet_locl.h:62:1: start of procedure PACKET_data()
  60.    * For use in non-PACKETized APIs.
  61.    */
  62. > static ossl_inline const unsigned char *PACKET_data(const PACKET *pkt)
  63.   {
  64.       return pkt->curr;

ssl/packet_locl.h:64:5: 
  62.   static ossl_inline const unsigned char *PACKET_data(const PACKET *pkt)
  63.   {
  64. >     return pkt->curr;
  65.   }
  66.   

ssl/packet_locl.h:65:1: return from a call to PACKET_data
  63.   {
  64.       return pkt->curr;
  65. > }
  66.   
  67.   /*

ssl/statem/extensions_srvr.c:723:5: 
721.       raw = cookie;
722.       data = PACKET_data(&raw);
723. >     rawlen = PACKET_remaining(&raw);
724.       if (rawlen < SHA256_DIGEST_LENGTH
725.               || !PACKET_forward(&raw, rawlen - SHA256_DIGEST_LENGTH)) {

ssl/packet_locl.h:42:1: start of procedure PACKET_remaining()
  40.    * Returns the number of bytes remaining to be read in the PACKET
  41.    */
  42. > static ossl_inline size_t PACKET_remaining(const PACKET *pkt)
  43.   {
  44.       return pkt->remaining;

ssl/packet_locl.h:44:5: 
  42.   static ossl_inline size_t PACKET_remaining(const PACKET *pkt)
  43.   {
  44. >     return pkt->remaining;
  45.   }
  46.   

ssl/packet_locl.h:45:1: return from a call to PACKET_remaining
  43.   {
  44.       return pkt->remaining;
  45. > }
  46.   
  47.   /*

ssl/statem/extensions_srvr.c:724:9: Taking false branch
722.       data = PACKET_data(&raw);
723.       rawlen = PACKET_remaining(&raw);
724.       if (rawlen < SHA256_DIGEST_LENGTH
               ^
725.               || !PACKET_forward(&raw, rawlen - SHA256_DIGEST_LENGTH)) {
726.           SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,

ssl/statem/extensions_srvr.c:725:17: 
723.       rawlen = PACKET_remaining(&raw);
724.       if (rawlen < SHA256_DIGEST_LENGTH
725. >             || !PACKET_forward(&raw, rawlen - SHA256_DIGEST_LENGTH)) {
726.           SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
727.                    SSL_R_LENGTH_MISMATCH);

ssl/packet_locl.h:467:8: start of procedure PACKET_forward()
  465.   
  466.   /* Move the current reading position forward |len| bytes */
  467.   __owur static ossl_inline int PACKET_forward(PACKET *pkt, size_t len)
                ^
  468.   {
  469.       if (PACKET_remaining(pkt) < len)

ssl/packet_locl.h:469:9: 
  467.   __owur static ossl_inline int PACKET_forward(PACKET *pkt, size_t len)
  468.   {
  469. >     if (PACKET_remaining(pkt) < len)
  470.           return 0;
  471.   

ssl/packet_locl.h:42:1: start of procedure PACKET_remaining()
    40.    * Returns the number of bytes remaining to be read in the PACKET
    41.    */
    42. > static ossl_inline size_t PACKET_remaining(const PACKET *pkt)
    43.   {
    44.       return pkt->remaining;

ssl/packet_locl.h:44:5: 
    42.   static ossl_inline size_t PACKET_remaining(const PACKET *pkt)
    43.   {
    44. >     return pkt->remaining;
    45.   }
    46.   

ssl/packet_locl.h:45:1: return from a call to PACKET_remaining
    43.   {
    44.       return pkt->remaining;
    45. > }
    46.   
    47.   /*

ssl/packet_locl.h:469:9: Taking false branch
  467.   __owur static ossl_inline int PACKET_forward(PACKET *pkt, size_t len)
  468.   {
  469.       if (PACKET_remaining(pkt) < len)
                 ^
  470.           return 0;
  471.   

ssl/packet_locl.h:472:5: 
  470.           return 0;
  471.   
  472. >     packet_forward(pkt, len);
  473.   
  474.       return 1;

ssl/packet_locl.h:33:1: start of procedure packet_forward()
    31.   
    32.   /* Internal unchecked shorthand; don't use outside this file. */
    33. > static ossl_inline void packet_forward(PACKET *pkt, size_t len)
    34.   {
    35.       pkt->curr += len;

ssl/packet_locl.h:35:5: 
    33.   static ossl_inline void packet_forward(PACKET *pkt, size_t len)
    34.   {
    35. >     pkt->curr += len;
    36.       pkt->remaining -= len;
    37.   }

ssl/packet_locl.h:36:5: 
    34.   {
    35.       pkt->curr += len;
    36. >     pkt->remaining -= len;
    37.   }
    38.   

ssl/packet_locl.h:37:1: return from a call to packet_forward
    35.       pkt->curr += len;
    36.       pkt->remaining -= len;
    37. > }
    38.   
    39.   /*

ssl/packet_locl.h:474:5: 
  472.       packet_forward(pkt, len);
  473.   
  474. >     return 1;
  475.   }
  476.   

ssl/packet_locl.h:475:1: return from a call to PACKET_forward
  473.   
  474.       return 1;
  475. > }
  476.   
  477.   /*

ssl/statem/extensions_srvr.c:725:17: Taking false branch
723.       rawlen = PACKET_remaining(&raw);
724.       if (rawlen < SHA256_DIGEST_LENGTH
725.               || !PACKET_forward(&raw, rawlen - SHA256_DIGEST_LENGTH)) {
                       ^
726.           SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
727.                    SSL_R_LENGTH_MISMATCH);

ssl/statem/extensions_srvr.c:730:5: 
728.           return 0;
729.       }
730. >     mdin = PACKET_data(&raw);
731.   
732.       /* Verify the HMAC of the cookie */

ssl/packet_locl.h:62:1: start of procedure PACKET_data()
  60.    * For use in non-PACKETized APIs.
  61.    */
  62. > static ossl_inline const unsigned char *PACKET_data(const PACKET *pkt)
  63.   {
  64.       return pkt->curr;

ssl/packet_locl.h:64:5: 
  62.   static ossl_inline const unsigned char *PACKET_data(const PACKET *pkt)
  63.   {
  64. >     return pkt->curr;
  65.   }
  66.   

ssl/packet_locl.h:65:1: return from a call to PACKET_data
  63.   {
  64.       return pkt->curr;
  65. > }
  66.   
  67.   /*

ssl/statem/extensions_srvr.c:733:5: 
731.   
732.       /* Verify the HMAC of the cookie */
733. >     hctx = EVP_MD_CTX_create();
734.       pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
735.                                   s->session_ctx->ext.cookie_hmac_key,

crypto/evp/digest.c:44:1: start of procedure EVP_MD_CTX_new()
  42.   }
  43.   
  44. > EVP_MD_CTX *EVP_MD_CTX_new(void)
  45.   {
  46.       return OPENSSL_zalloc(sizeof(EVP_MD_CTX));

crypto/evp/digest.c:46:5: 
  44.   EVP_MD_CTX *EVP_MD_CTX_new(void)
  45.   {
  46. >     return OPENSSL_zalloc(sizeof(EVP_MD_CTX));
  47.   }
  48.   

crypto/mem.c:221:1: start of procedure CRYPTO_zalloc()
    219.   }
    220.   
    221. > void *CRYPTO_zalloc(size_t num, const char *file, int line)
    222.   {
    223.       void *ret = CRYPTO_malloc(num, file, line);

crypto/mem.c:223:5: 
    221.   void *CRYPTO_zalloc(size_t num, const char *file, int line)
    222.   {
    223. >     void *ret = CRYPTO_malloc(num, file, line);
    224.   
    225.       FAILTEST();

crypto/mem.c:192:1: start of procedure CRYPTO_malloc()
      190.   #endif
      191.   
      192. > void *CRYPTO_malloc(size_t num, const char *file, int line)
      193.   {
      194.       void *ret = NULL;

crypto/mem.c:194:5: 
      192.   void *CRYPTO_malloc(size_t num, const char *file, int line)
      193.   {
      194. >     void *ret = NULL;
      195.   
      196.       INCREMENT(malloc_count);

crypto/mem.c:197:9: Taking false branch
      195.   
      196.       INCREMENT(malloc_count);
      197.       if (malloc_impl != NULL && malloc_impl != CRYPTO_malloc)
                     ^
      198.           return malloc_impl(num, file, line);
      199.   

crypto/mem.c:200:9: Taking false branch
      198.           return malloc_impl(num, file, line);
      199.   
      200.       if (num == 0)
                     ^
      201.           return NULL;
      202.   

crypto/mem.c:204:5: 
      202.   
      203.       FAILTEST();
      204. >     allow_customize = 0;
      205.   #ifndef OPENSSL_NO_CRYPTO_MDEBUG
      206.       if (call_malloc_debug) {

crypto/mem.c:214:5: 
      212.       }
      213.   #else
      214. >     (void)(file); (void)(line);
      215.       ret = malloc(num);
      216.   #endif

crypto/mem.c:214:19: 
      212.       }
      213.   #else
      214. >     (void)(file); (void)(line);
      215.       ret = malloc(num);
      216.   #endif

crypto/mem.c:215:5: 
      213.   #else
      214.       (void)(file); (void)(line);
      215. >     ret = malloc(num);
      216.   #endif
      217.   

crypto/mem.c:218:5: 
      216.   #endif
      217.   
      218. >     return ret;
      219.   }
      220.   

crypto/mem.c:219:1: return from a call to CRYPTO_malloc
      217.   
      218.       return ret;
      219. > }
      220.   
      221.   void *CRYPTO_zalloc(size_t num, const char *file, int line)

crypto/mem.c:226:9: Taking true branch
    224.   
    225.       FAILTEST();
    226.       if (ret != NULL)
                   ^
    227.           memset(ret, 0, num);
    228.       return ret;

crypto/mem.c:227:9: 
    225.       FAILTEST();
    226.       if (ret != NULL)
    227. >         memset(ret, 0, num);
    228.       return ret;
    229.   }

crypto/mem.c:228:5: 
    226.       if (ret != NULL)
    227.           memset(ret, 0, num);
    228. >     return ret;
    229.   }
    230.   

crypto/mem.c:229:1: return from a call to CRYPTO_zalloc
    227.           memset(ret, 0, num);
    228.       return ret;
    229. > }
    230.   
    231.   void *CRYPTO_realloc(void *str, size_t num, const char *file, int line)

crypto/evp/digest.c:47:1: return from a call to EVP_MD_CTX_new
  45.   {
  46.       return OPENSSL_zalloc(sizeof(EVP_MD_CTX));
  47. > }
  48.   
  49.   void EVP_MD_CTX_free(EVP_MD_CTX *ctx)

ssl/statem/extensions_srvr.c:734:5: Skipping EVP_PKEY_new_mac_key(): empty list of specs
732.       /* Verify the HMAC of the cookie */
733.       hctx = EVP_MD_CTX_create();
734.       pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
           ^
735.                                   s->session_ctx->ext.cookie_hmac_key,
736.                                   sizeof(s->session_ctx->ext.cookie_hmac_key));

ssl/statem/extensions_srvr.c:737:9: Taking false branch
735.                                   s->session_ctx->ext.cookie_hmac_key,
736.                                   sizeof(s->session_ctx->ext.cookie_hmac_key));
737.       if (hctx == NULL || pkey == NULL) {
               ^
738.           EVP_MD_CTX_free(hctx);
739.           EVP_PKEY_free(pkey);

ssl/statem/extensions_srvr.c:737:25: Taking true branch
735.                                   s->session_ctx->ext.cookie_hmac_key,
736.                                   sizeof(s->session_ctx->ext.cookie_hmac_key));
737.       if (hctx == NULL || pkey == NULL) {
                               ^
738.           EVP_MD_CTX_free(hctx);
739.           EVP_PKEY_free(pkey);

ssl/statem/extensions_srvr.c:738:9: 
736.                                   sizeof(s->session_ctx->ext.cookie_hmac_key));
737.       if (hctx == NULL || pkey == NULL) {
738. >         EVP_MD_CTX_free(hctx);
739.           EVP_PKEY_free(pkey);
740.           SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,

crypto/evp/digest.c:49:1: start of procedure EVP_MD_CTX_free()
  47.   }
  48.   
  49. > void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
  50.   {
  51.       EVP_MD_CTX_reset(ctx);

crypto/evp/digest.c:51:5: Skipping EVP_MD_CTX_reset(): empty list of specs
  49.   void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
  50.   {
  51.       EVP_MD_CTX_reset(ctx);
            ^
  52.       OPENSSL_free(ctx);
  53.   }

crypto/evp/digest.c:52:5: 
  50.   {
  51.       EVP_MD_CTX_reset(ctx);
  52. >     OPENSSL_free(ctx);
  53.   }
  54.   

crypto/mem.c:289:1: start of procedure CRYPTO_free()
    287.   }
    288.   
    289. > void CRYPTO_free(void *str, const char *file, int line)
    290.   {
    291.       INCREMENT(free_count);

crypto/mem.c:292:9: Taking true branch
    290.   {
    291.       INCREMENT(free_count);
    292.       if (free_impl != NULL && free_impl != &CRYPTO_free) {
                   ^
    293.           free_impl(str, file, line);
    294.           return;

crypto/mem.c:292:30: Taking true branch
    290.   {
    291.       INCREMENT(free_count);
    292.       if (free_impl != NULL && free_impl != &CRYPTO_free) {
                                        ^
    293.           free_impl(str, file, line);
    294.           return;

crypto/mem.c:293:9: Skipping __function_pointer__(): unresolved function pointer
    291.       INCREMENT(free_count);
    292.       if (free_impl != NULL && free_impl != &CRYPTO_free) {
    293.           free_impl(str, file, line);
                   ^
    294.           return;
    295.       }

crypto/mem.c:294:9: 
    292.       if (free_impl != NULL && free_impl != &CRYPTO_free) {
    293.           free_impl(str, file, line);
    294. >         return;
    295.       }
    296.   

crypto/mem.c:308:1: return from a call to CRYPTO_free
    306.       free(str);
    307.   #endif
    308. > }
    309.   
    310.   void CRYPTO_clear_free(void *str, size_t num, const char *file, int line)

crypto/evp/digest.c:53:1: return from a call to EVP_MD_CTX_free
  51.       EVP_MD_CTX_reset(ctx);
  52.       OPENSSL_free(ctx);
  53. > }
  54.   
  55.   int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)

int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
                          size_t chainidx)
{
    unsigned int format, version, key_share, group_id;
    EVP_MD_CTX *hctx;
    EVP_PKEY *pkey;
    PACKET cookie, raw, chhash, appcookie;
    WPACKET hrrpkt;
    const unsigned char *data, *mdin, *ciphdata;
    unsigned char hmac[SHA256_DIGEST_LENGTH];
    unsigned char hrr[MAX_HRR_SIZE];
    size_t rawlen, hmaclen, hrrlen, ciphlen;
    unsigned long tm, now;
    if (s->ctx->app_verify_cookie_cb == NULL
            || (s->s3->flags & TLS1_FLAGS_STATELESS) == 0)
        return 1;
    if (!PACKET_as_length_prefixed_2(pkt, &cookie)) {
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_LENGTH_MISMATCH);
        return 0;
    }
    raw = cookie;
    data = PACKET_data(&raw);
    rawlen = PACKET_remaining(&raw);
    if (rawlen < SHA256_DIGEST_LENGTH
            || !PACKET_forward(&raw, rawlen - SHA256_DIGEST_LENGTH)) {
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_LENGTH_MISMATCH);
        return 0;
    }
    mdin = PACKET_data(&raw);
    hctx = EVP_MD_CTX_create();
    pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
                                s->session_ctx->ext.cookie_hmac_key,
                                sizeof(s->session_ctx->ext.cookie_hmac_key));
    if (hctx == NULL || pkey == NULL) {
        EVP_MD_CTX_free(hctx);
        EVP_PKEY_free(pkey);
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 ERR_R_MALLOC_FAILURE);
        return 0;
    }
    hmaclen = SHA256_DIGEST_LENGTH;
    if (EVP_DigestSignInit(hctx, NULL, EVP_sha256(), NULL, pkey) <= 0
            || EVP_DigestSign(hctx, hmac, &hmaclen, data,
                              rawlen - SHA256_DIGEST_LENGTH) <= 0
            || hmaclen != SHA256_DIGEST_LENGTH) {
        EVP_MD_CTX_free(hctx);
        EVP_PKEY_free(pkey);
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 ERR_R_INTERNAL_ERROR);
        return 0;
    }
    EVP_MD_CTX_free(hctx);
    EVP_PKEY_free(pkey);
    if (CRYPTO_memcmp(hmac, mdin, SHA256_DIGEST_LENGTH) != 0) {
        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_COOKIE_MISMATCH);
        return 0;
    }
    if (!PACKET_get_net_2(&cookie, &format)) {
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_LENGTH_MISMATCH);
        return 0;
    }
    if (format != COOKIE_STATE_FORMAT_VERSION)
        return 1;
    if (!PACKET_get_net_2(&cookie, &version)) {
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_LENGTH_MISMATCH);
        return 0;
    }
    if (version != TLS1_3_VERSION) {
        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_BAD_PROTOCOL_VERSION_NUMBER);
        return 0;
    }
    if (!PACKET_get_net_2(&cookie, &group_id)) {
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_LENGTH_MISMATCH);
        return 0;
    }
    ciphdata = PACKET_data(&cookie);
    if (!PACKET_forward(&cookie, 2)) {
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_LENGTH_MISMATCH);
        return 0;
    }
    if (group_id != s->s3->group_id
            || s->s3->tmp.new_cipher
               != ssl_get_cipher_by_char(s, ciphdata, 0)) {
        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_BAD_CIPHER);
        return 0;
    }
    if (!PACKET_get_1(&cookie, &key_share)
            || !PACKET_get_net_4(&cookie, &tm)
            || !PACKET_get_length_prefixed_2(&cookie, &chhash)
            || !PACKET_get_length_prefixed_1(&cookie, &appcookie)
            || PACKET_remaining(&cookie) != SHA256_DIGEST_LENGTH) {
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_LENGTH_MISMATCH);
        return 0;
    }
    now = (unsigned long)time(NULL);
    if (tm > now || (now - tm) > 600) {
        return 1;
    }
    if (s->ctx->app_verify_cookie_cb(s, PACKET_data(&appcookie),
                                     PACKET_remaining(&appcookie)) == 0) {
        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 SSL_R_COOKIE_MISMATCH);
        return 0;
    }
    if (!WPACKET_init_static_len(&hrrpkt, hrr, sizeof(hrr), 0)) {
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 ERR_R_INTERNAL_ERROR);
        return 0;
    }
    if (!WPACKET_put_bytes_u8(&hrrpkt, SSL3_MT_SERVER_HELLO)
            || !WPACKET_start_sub_packet_u24(&hrrpkt)
            || !WPACKET_put_bytes_u16(&hrrpkt, TLS1_2_VERSION)
            || !WPACKET_memcpy(&hrrpkt, hrrrandom, SSL3_RANDOM_SIZE)
            || !WPACKET_sub_memcpy_u8(&hrrpkt, s->tmp_session_id,
                                      s->tmp_session_id_len)
            || !s->method->put_cipher_by_char(s->s3->tmp.new_cipher, &hrrpkt,
                                              &ciphlen)
            || !WPACKET_put_bytes_u8(&hrrpkt, 0)
            || !WPACKET_start_sub_packet_u16(&hrrpkt)) {
        WPACKET_cleanup(&hrrpkt);
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 ERR_R_INTERNAL_ERROR);
        return 0;
    }
    if (!WPACKET_put_bytes_u16(&hrrpkt, TLSEXT_TYPE_supported_versions)
            || !WPACKET_start_sub_packet_u16(&hrrpkt)
            || !WPACKET_put_bytes_u16(&hrrpkt, TLS1_3_VERSION_DRAFT)
            || !WPACKET_close(&hrrpkt)) {
        WPACKET_cleanup(&hrrpkt);
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 ERR_R_INTERNAL_ERROR);
        return 0;
    }
    if (key_share) {
        if (!WPACKET_put_bytes_u16(&hrrpkt, TLSEXT_TYPE_key_share)
                || !WPACKET_start_sub_packet_u16(&hrrpkt)
                || !WPACKET_put_bytes_u16(&hrrpkt, s->s3->group_id)
                || !WPACKET_close(&hrrpkt)) {
            WPACKET_cleanup(&hrrpkt);
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                     ERR_R_INTERNAL_ERROR);
            return 0;
        }
    }
    if (!WPACKET_put_bytes_u16(&hrrpkt, TLSEXT_TYPE_cookie)
            || !WPACKET_start_sub_packet_u16(&hrrpkt)
            || !WPACKET_sub_memcpy_u16(&hrrpkt, data, rawlen)
            || !WPACKET_close(&hrrpkt)
            || !WPACKET_close(&hrrpkt)
            || !WPACKET_close(&hrrpkt)
            || !WPACKET_get_total_written(&hrrpkt, &hrrlen)
            || !WPACKET_finish(&hrrpkt)) {
        WPACKET_cleanup(&hrrpkt);
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,
                 ERR_R_INTERNAL_ERROR);
        return 0;
    }
    if (!create_synthetic_message_hash(s, PACKET_data(&chhash),
                                       PACKET_remaining(&chhash), hrr,
                                       hrrlen)) {
        return 0;
    }
    s->hello_retry_request = 1;
    s->ext.cookieok = 1;
    return 1;
}
['int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x,\n                          size_t chainidx)\n{\n    unsigned int format, version, key_share, group_id;\n    EVP_MD_CTX *hctx;\n    EVP_PKEY *pkey;\n    PACKET cookie, raw, chhash, appcookie;\n    WPACKET hrrpkt;\n    const unsigned char *data, *mdin, *ciphdata;\n    unsigned char hmac[SHA256_DIGEST_LENGTH];\n    unsigned char hrr[MAX_HRR_SIZE];\n    size_t rawlen, hmaclen, hrrlen, ciphlen;\n    unsigned long tm, now;\n    if (s->ctx->app_verify_cookie_cb == NULL\n            || (s->s3->flags & TLS1_FLAGS_STATELESS) == 0)\n        return 1;\n    if (!PACKET_as_length_prefixed_2(pkt, &cookie)) {\n        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_LENGTH_MISMATCH);\n        return 0;\n    }\n    raw = cookie;\n    data = PACKET_data(&raw);\n    rawlen = PACKET_remaining(&raw);\n    if (rawlen < SHA256_DIGEST_LENGTH\n            || !PACKET_forward(&raw, rawlen - SHA256_DIGEST_LENGTH)) {\n        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_LENGTH_MISMATCH);\n        return 0;\n    }\n    mdin = PACKET_data(&raw);\n    hctx = EVP_MD_CTX_create();\n    pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,\n                                s->session_ctx->ext.cookie_hmac_key,\n                                sizeof(s->session_ctx->ext.cookie_hmac_key));\n    if (hctx == NULL || pkey == NULL) {\n        EVP_MD_CTX_free(hctx);\n        EVP_PKEY_free(pkey);\n        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 ERR_R_MALLOC_FAILURE);\n        return 0;\n    }\n    hmaclen = SHA256_DIGEST_LENGTH;\n    if (EVP_DigestSignInit(hctx, NULL, EVP_sha256(), NULL, pkey) <= 0\n            || EVP_DigestSign(hctx, hmac, &hmaclen, data,\n                              rawlen - SHA256_DIGEST_LENGTH) <= 0\n            || hmaclen != SHA256_DIGEST_LENGTH) {\n        EVP_MD_CTX_free(hctx);\n        EVP_PKEY_free(pkey);\n        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 ERR_R_INTERNAL_ERROR);\n        return 0;\n    }\n    EVP_MD_CTX_free(hctx);\n    EVP_PKEY_free(pkey);\n    if (CRYPTO_memcmp(hmac, mdin, SHA256_DIGEST_LENGTH) != 0) {\n        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_COOKIE_MISMATCH);\n        return 0;\n    }\n    if (!PACKET_get_net_2(&cookie, &format)) {\n        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_LENGTH_MISMATCH);\n        return 0;\n    }\n    if (format != COOKIE_STATE_FORMAT_VERSION)\n        return 1;\n    if (!PACKET_get_net_2(&cookie, &version)) {\n        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_LENGTH_MISMATCH);\n        return 0;\n    }\n    if (version != TLS1_3_VERSION) {\n        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_BAD_PROTOCOL_VERSION_NUMBER);\n        return 0;\n    }\n    if (!PACKET_get_net_2(&cookie, &group_id)) {\n        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_LENGTH_MISMATCH);\n        return 0;\n    }\n    ciphdata = PACKET_data(&cookie);\n    if (!PACKET_forward(&cookie, 2)) {\n        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_LENGTH_MISMATCH);\n        return 0;\n    }\n    if (group_id != s->s3->group_id\n            || s->s3->tmp.new_cipher\n               != ssl_get_cipher_by_char(s, ciphdata, 0)) {\n        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_BAD_CIPHER);\n        return 0;\n    }\n    if (!PACKET_get_1(&cookie, &key_share)\n            || !PACKET_get_net_4(&cookie, &tm)\n            || !PACKET_get_length_prefixed_2(&cookie, &chhash)\n            || !PACKET_get_length_prefixed_1(&cookie, &appcookie)\n            || PACKET_remaining(&cookie) != SHA256_DIGEST_LENGTH) {\n        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_LENGTH_MISMATCH);\n        return 0;\n    }\n    now = (unsigned long)time(NULL);\n    if (tm > now || (now - tm) > 600) {\n        return 1;\n    }\n    if (s->ctx->app_verify_cookie_cb(s, PACKET_data(&appcookie),\n                                     PACKET_remaining(&appcookie)) == 0) {\n        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 SSL_R_COOKIE_MISMATCH);\n        return 0;\n    }\n    if (!WPACKET_init_static_len(&hrrpkt, hrr, sizeof(hrr), 0)) {\n        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 ERR_R_INTERNAL_ERROR);\n        return 0;\n    }\n    if (!WPACKET_put_bytes_u8(&hrrpkt, SSL3_MT_SERVER_HELLO)\n            || !WPACKET_start_sub_packet_u24(&hrrpkt)\n            || !WPACKET_put_bytes_u16(&hrrpkt, TLS1_2_VERSION)\n            || !WPACKET_memcpy(&hrrpkt, hrrrandom, SSL3_RANDOM_SIZE)\n            || !WPACKET_sub_memcpy_u8(&hrrpkt, s->tmp_session_id,\n                                      s->tmp_session_id_len)\n            || !s->method->put_cipher_by_char(s->s3->tmp.new_cipher, &hrrpkt,\n                                              &ciphlen)\n            || !WPACKET_put_bytes_u8(&hrrpkt, 0)\n            || !WPACKET_start_sub_packet_u16(&hrrpkt)) {\n        WPACKET_cleanup(&hrrpkt);\n        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 ERR_R_INTERNAL_ERROR);\n        return 0;\n    }\n    if (!WPACKET_put_bytes_u16(&hrrpkt, TLSEXT_TYPE_supported_versions)\n            || !WPACKET_start_sub_packet_u16(&hrrpkt)\n            || !WPACKET_put_bytes_u16(&hrrpkt, TLS1_3_VERSION_DRAFT)\n            || !WPACKET_close(&hrrpkt)) {\n        WPACKET_cleanup(&hrrpkt);\n        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 ERR_R_INTERNAL_ERROR);\n        return 0;\n    }\n    if (key_share) {\n        if (!WPACKET_put_bytes_u16(&hrrpkt, TLSEXT_TYPE_key_share)\n                || !WPACKET_start_sub_packet_u16(&hrrpkt)\n                || !WPACKET_put_bytes_u16(&hrrpkt, s->s3->group_id)\n                || !WPACKET_close(&hrrpkt)) {\n            WPACKET_cleanup(&hrrpkt);\n            SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                     ERR_R_INTERNAL_ERROR);\n            return 0;\n        }\n    }\n    if (!WPACKET_put_bytes_u16(&hrrpkt, TLSEXT_TYPE_cookie)\n            || !WPACKET_start_sub_packet_u16(&hrrpkt)\n            || !WPACKET_sub_memcpy_u16(&hrrpkt, data, rawlen)\n            || !WPACKET_close(&hrrpkt)\n            || !WPACKET_close(&hrrpkt)\n            || !WPACKET_close(&hrrpkt)\n            || !WPACKET_get_total_written(&hrrpkt, &hrrlen)\n            || !WPACKET_finish(&hrrpkt)) {\n        WPACKET_cleanup(&hrrpkt);\n        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE,\n                 ERR_R_INTERNAL_ERROR);\n        return 0;\n    }\n    if (!create_synthetic_message_hash(s, PACKET_data(&chhash),\n                                       PACKET_remaining(&chhash), hrr,\n                                       hrrlen)) {\n        return 0;\n    }\n    s->hello_retry_request = 1;\n    s->ext.cookieok = 1;\n    return 1;\n}', 'static ossl_inline const unsigned char *PACKET_data(const PACKET *pkt)\n{\n    return pkt->curr;\n}', 'static ossl_inline size_t PACKET_remaining(const PACKET *pkt)\n{\n    return pkt->remaining;\n}', 'static ossl_inline int PACKET_forward(PACKET *pkt, size_t len)\n{\n    if (PACKET_remaining(pkt) < len)\n        return 0;\n    packet_forward(pkt, len);\n    return 1;\n}', 'static ossl_inline void packet_forward(PACKET *pkt, size_t len)\n{\n    pkt->curr += len;\n    pkt->remaining -= len;\n}', 'EVP_MD_CTX *EVP_MD_CTX_new(void)\n{\n    return OPENSSL_zalloc(sizeof(EVP_MD_CTX));\n}', 'void *CRYPTO_zalloc(size_t num, const char *file, int line)\n{\n    void *ret = CRYPTO_malloc(num, file, line);\n    FAILTEST();\n    if (ret != NULL)\n        memset(ret, 0, num);\n    return ret;\n}', 'void *CRYPTO_malloc(size_t num, const char *file, int line)\n{\n    void *ret = NULL;\n    INCREMENT(malloc_count);\n    if (malloc_impl != NULL && malloc_impl != CRYPTO_malloc)\n        return malloc_impl(num, file, line);\n    if (num == 0)\n        return NULL;\n    FAILTEST();\n    allow_customize = 0;\n#ifndef OPENSSL_NO_CRYPTO_MDEBUG\n    if (call_malloc_debug) {\n        CRYPTO_mem_debug_malloc(NULL, num, 0, file, line);\n        ret = malloc(num);\n        CRYPTO_mem_debug_malloc(ret, num, 1, file, line);\n    } else {\n        ret = malloc(num);\n    }\n#else\n    (void)(file); (void)(line);\n    ret = malloc(num);\n#endif\n    return ret;\n}', 'void EVP_MD_CTX_free(EVP_MD_CTX *ctx)\n{\n    EVP_MD_CTX_reset(ctx);\n    OPENSSL_free(ctx);\n}', 'void CRYPTO_free(void *str, const char *file, int line)\n{\n    INCREMENT(free_count);\n    if (free_impl != NULL && free_impl != &CRYPTO_free) {\n        free_impl(str, file, line);\n        return;\n    }\n#ifndef OPENSSL_NO_CRYPTO_MDEBUG\n    if (call_malloc_debug) {\n        CRYPTO_mem_debug_free(str, 0, file, line);\n        free(str);\n        CRYPTO_mem_debug_free(str, 1, file, line);\n    } else {\n        free(str);\n    }\n#else\n    free(str);\n#endif\n}']