1*72c33676SMaxim Ag /* $OpenBSD: ssl_asn1.c,v 1.57 2018/08/27 16:42:48 jsing Exp $ */ 2*72c33676SMaxim Ag /* 3*72c33676SMaxim Ag * Copyright (c) 2016 Joel Sing <jsing@openbsd.org> 4f5b1c8a1SJohn Marino * 5*72c33676SMaxim Ag * Permission to use, copy, modify, and distribute this software for any 6*72c33676SMaxim Ag * purpose with or without fee is hereby granted, provided that the above 7*72c33676SMaxim Ag * copyright notice and this permission notice appear in all copies. 8f5b1c8a1SJohn Marino * 9*72c33676SMaxim Ag * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10*72c33676SMaxim Ag * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11*72c33676SMaxim Ag * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12*72c33676SMaxim Ag * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13*72c33676SMaxim Ag * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14*72c33676SMaxim Ag * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15*72c33676SMaxim Ag * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16f5b1c8a1SJohn Marino */ 17f5b1c8a1SJohn Marino 18*72c33676SMaxim Ag #include <limits.h> 19*72c33676SMaxim Ag 20*72c33676SMaxim Ag #include <openssl/ssl.h> 21*72c33676SMaxim Ag #include <openssl/x509.h> 22f5b1c8a1SJohn Marino 23f5b1c8a1SJohn Marino #include "ssl_locl.h" 24f5b1c8a1SJohn Marino 25*72c33676SMaxim Ag #include "bytestring.h" 26f5b1c8a1SJohn Marino 27*72c33676SMaxim Ag #define SSLASN1_TAG (CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC) 28*72c33676SMaxim Ag #define SSLASN1_TIME_TAG (SSLASN1_TAG | 1) 29*72c33676SMaxim Ag #define SSLASN1_TIMEOUT_TAG (SSLASN1_TAG | 2) 30*72c33676SMaxim Ag #define SSLASN1_PEER_CERT_TAG (SSLASN1_TAG | 3) 31*72c33676SMaxim Ag #define SSLASN1_SESSION_ID_CTX_TAG (SSLASN1_TAG | 4) 32*72c33676SMaxim Ag #define SSLASN1_VERIFY_RESULT_TAG (SSLASN1_TAG | 5) 33*72c33676SMaxim Ag #define SSLASN1_HOSTNAME_TAG (SSLASN1_TAG | 6) 34*72c33676SMaxim Ag #define SSLASN1_LIFETIME_TAG (SSLASN1_TAG | 9) 35*72c33676SMaxim Ag #define SSLASN1_TICKET_TAG (SSLASN1_TAG | 10) 36f5b1c8a1SJohn Marino 37*72c33676SMaxim Ag static uint64_t 38*72c33676SMaxim Ag time_max(void) 39*72c33676SMaxim Ag { 40*72c33676SMaxim Ag if (sizeof(time_t) == sizeof(int32_t)) 41*72c33676SMaxim Ag return INT32_MAX; 42*72c33676SMaxim Ag if (sizeof(time_t) == sizeof(int64_t)) 43*72c33676SMaxim Ag return INT64_MAX; 44*72c33676SMaxim Ag return 0; 45*72c33676SMaxim Ag } 46*72c33676SMaxim Ag 47*72c33676SMaxim Ag static int 48*72c33676SMaxim Ag SSL_SESSION_encode(SSL_SESSION *s, unsigned char **out, size_t *out_len, 49*72c33676SMaxim Ag int ticket_encoding) 50*72c33676SMaxim Ag { 51*72c33676SMaxim Ag CBB cbb, session, cipher_suite, session_id, master_key, time, timeout; 52*72c33676SMaxim Ag CBB peer_cert, sidctx, verify_result, hostname, lifetime, ticket, value; 53*72c33676SMaxim Ag unsigned char *peer_cert_bytes = NULL; 54*72c33676SMaxim Ag int len, rv = 0; 55*72c33676SMaxim Ag uint16_t cid; 56*72c33676SMaxim Ag 57*72c33676SMaxim Ag if (!CBB_init(&cbb, 0)) 58*72c33676SMaxim Ag goto err; 59*72c33676SMaxim Ag 60*72c33676SMaxim Ag if (!CBB_add_asn1(&cbb, &session, CBS_ASN1_SEQUENCE)) 61*72c33676SMaxim Ag goto err; 62*72c33676SMaxim Ag 63*72c33676SMaxim Ag /* Session ASN1 version. */ 64*72c33676SMaxim Ag if (!CBB_add_asn1_uint64(&session, SSL_SESSION_ASN1_VERSION)) 65*72c33676SMaxim Ag goto err; 66*72c33676SMaxim Ag 67*72c33676SMaxim Ag /* TLS/SSL protocol version. */ 68*72c33676SMaxim Ag if (s->ssl_version < 0) 69*72c33676SMaxim Ag goto err; 70*72c33676SMaxim Ag if (!CBB_add_asn1_uint64(&session, s->ssl_version)) 71*72c33676SMaxim Ag goto err; 72*72c33676SMaxim Ag 73*72c33676SMaxim Ag /* Cipher suite ID. */ 74*72c33676SMaxim Ag /* XXX - require cipher to be non-NULL or always/only use cipher_id. */ 75*72c33676SMaxim Ag cid = (uint16_t)(s->cipher_id & 0xffff); 76*72c33676SMaxim Ag if (s->cipher != NULL) 77*72c33676SMaxim Ag cid = ssl3_cipher_get_value(s->cipher); 78*72c33676SMaxim Ag if (!CBB_add_asn1(&session, &cipher_suite, CBS_ASN1_OCTETSTRING)) 79*72c33676SMaxim Ag goto err; 80*72c33676SMaxim Ag if (!CBB_add_u16(&cipher_suite, cid)) 81*72c33676SMaxim Ag goto err; 82*72c33676SMaxim Ag 83*72c33676SMaxim Ag /* Session ID - zero length for a ticket. */ 84*72c33676SMaxim Ag if (!CBB_add_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING)) 85*72c33676SMaxim Ag goto err; 86*72c33676SMaxim Ag if (!CBB_add_bytes(&session_id, s->session_id, 87*72c33676SMaxim Ag ticket_encoding ? 0 : s->session_id_length)) 88*72c33676SMaxim Ag goto err; 89*72c33676SMaxim Ag 90*72c33676SMaxim Ag /* Master key. */ 91*72c33676SMaxim Ag if (!CBB_add_asn1(&session, &master_key, CBS_ASN1_OCTETSTRING)) 92*72c33676SMaxim Ag goto err; 93*72c33676SMaxim Ag if (!CBB_add_bytes(&master_key, s->master_key, s->master_key_length)) 94*72c33676SMaxim Ag goto err; 95*72c33676SMaxim Ag 96*72c33676SMaxim Ag /* Time [1]. */ 97*72c33676SMaxim Ag if (s->time != 0) { 98*72c33676SMaxim Ag if (s->time < 0) 99*72c33676SMaxim Ag goto err; 100*72c33676SMaxim Ag if (!CBB_add_asn1(&session, &time, SSLASN1_TIME_TAG)) 101*72c33676SMaxim Ag goto err; 102*72c33676SMaxim Ag if (!CBB_add_asn1_uint64(&time, s->time)) 103*72c33676SMaxim Ag goto err; 104*72c33676SMaxim Ag } 105*72c33676SMaxim Ag 106*72c33676SMaxim Ag /* Timeout [2]. */ 107*72c33676SMaxim Ag if (s->timeout != 0) { 108*72c33676SMaxim Ag if (s->timeout < 0) 109*72c33676SMaxim Ag goto err; 110*72c33676SMaxim Ag if (!CBB_add_asn1(&session, &timeout, SSLASN1_TIMEOUT_TAG)) 111*72c33676SMaxim Ag goto err; 112*72c33676SMaxim Ag if (!CBB_add_asn1_uint64(&timeout, s->timeout)) 113*72c33676SMaxim Ag goto err; 114*72c33676SMaxim Ag } 115*72c33676SMaxim Ag 116*72c33676SMaxim Ag /* Peer certificate [3]. */ 117*72c33676SMaxim Ag if (s->peer != NULL) { 118*72c33676SMaxim Ag if ((len = i2d_X509(s->peer, &peer_cert_bytes)) <= 0) 119*72c33676SMaxim Ag goto err; 120*72c33676SMaxim Ag if (!CBB_add_asn1(&session, &peer_cert, SSLASN1_PEER_CERT_TAG)) 121*72c33676SMaxim Ag goto err; 122*72c33676SMaxim Ag if (!CBB_add_bytes(&peer_cert, peer_cert_bytes, len)) 123*72c33676SMaxim Ag goto err; 124*72c33676SMaxim Ag } 125*72c33676SMaxim Ag 126*72c33676SMaxim Ag /* Session ID context [4]. */ 127*72c33676SMaxim Ag /* XXX - Actually handle this as optional? */ 128*72c33676SMaxim Ag if (!CBB_add_asn1(&session, &sidctx, SSLASN1_SESSION_ID_CTX_TAG)) 129*72c33676SMaxim Ag goto err; 130*72c33676SMaxim Ag if (!CBB_add_asn1(&sidctx, &value, CBS_ASN1_OCTETSTRING)) 131*72c33676SMaxim Ag goto err; 132*72c33676SMaxim Ag if (!CBB_add_bytes(&value, s->sid_ctx, s->sid_ctx_length)) 133*72c33676SMaxim Ag goto err; 134*72c33676SMaxim Ag 135*72c33676SMaxim Ag /* Verify result [5]. */ 136*72c33676SMaxim Ag if (s->verify_result != X509_V_OK) { 137*72c33676SMaxim Ag if (s->verify_result < 0) 138*72c33676SMaxim Ag goto err; 139*72c33676SMaxim Ag if (!CBB_add_asn1(&session, &verify_result, 140*72c33676SMaxim Ag SSLASN1_VERIFY_RESULT_TAG)) 141*72c33676SMaxim Ag goto err; 142*72c33676SMaxim Ag if (!CBB_add_asn1_uint64(&verify_result, s->verify_result)) 143*72c33676SMaxim Ag goto err; 144*72c33676SMaxim Ag } 145*72c33676SMaxim Ag 146*72c33676SMaxim Ag /* Hostname [6]. */ 147*72c33676SMaxim Ag if (s->tlsext_hostname != NULL) { 148*72c33676SMaxim Ag if (!CBB_add_asn1(&session, &hostname, SSLASN1_HOSTNAME_TAG)) 149*72c33676SMaxim Ag goto err; 150*72c33676SMaxim Ag if (!CBB_add_asn1(&hostname, &value, CBS_ASN1_OCTETSTRING)) 151*72c33676SMaxim Ag goto err; 152*72c33676SMaxim Ag if (!CBB_add_bytes(&value, (const uint8_t *)s->tlsext_hostname, 153*72c33676SMaxim Ag strlen(s->tlsext_hostname))) 154*72c33676SMaxim Ag goto err; 155*72c33676SMaxim Ag } 156*72c33676SMaxim Ag 157*72c33676SMaxim Ag /* PSK identity hint [7]. */ 158*72c33676SMaxim Ag /* PSK identity [8]. */ 159*72c33676SMaxim Ag 160*72c33676SMaxim Ag /* Ticket lifetime hint [9]. */ 161*72c33676SMaxim Ag if (s->tlsext_tick_lifetime_hint > 0) { 162*72c33676SMaxim Ag if (!CBB_add_asn1(&session, &lifetime, SSLASN1_LIFETIME_TAG)) 163*72c33676SMaxim Ag goto err; 164*72c33676SMaxim Ag if (!CBB_add_asn1_uint64(&lifetime, 165*72c33676SMaxim Ag s->tlsext_tick_lifetime_hint)) 166*72c33676SMaxim Ag goto err; 167*72c33676SMaxim Ag } 168*72c33676SMaxim Ag 169*72c33676SMaxim Ag /* Ticket [10]. */ 170*72c33676SMaxim Ag if (s->tlsext_tick != NULL) { 171*72c33676SMaxim Ag if (!CBB_add_asn1(&session, &ticket, SSLASN1_TICKET_TAG)) 172*72c33676SMaxim Ag goto err; 173*72c33676SMaxim Ag if (!CBB_add_asn1(&ticket, &value, CBS_ASN1_OCTETSTRING)) 174*72c33676SMaxim Ag goto err; 175*72c33676SMaxim Ag if (!CBB_add_bytes(&value, s->tlsext_tick, s->tlsext_ticklen)) 176*72c33676SMaxim Ag goto err; 177*72c33676SMaxim Ag } 178*72c33676SMaxim Ag 179*72c33676SMaxim Ag /* Compression method [11]. */ 180*72c33676SMaxim Ag /* SRP username [12]. */ 181*72c33676SMaxim Ag 182*72c33676SMaxim Ag if (!CBB_finish(&cbb, out, out_len)) 183*72c33676SMaxim Ag goto err; 184*72c33676SMaxim Ag 185*72c33676SMaxim Ag rv = 1; 186*72c33676SMaxim Ag 187*72c33676SMaxim Ag err: 188*72c33676SMaxim Ag CBB_cleanup(&cbb); 189*72c33676SMaxim Ag free(peer_cert_bytes); 190*72c33676SMaxim Ag 191*72c33676SMaxim Ag return rv; 192*72c33676SMaxim Ag } 193f5b1c8a1SJohn Marino 194f5b1c8a1SJohn Marino int 195*72c33676SMaxim Ag SSL_SESSION_ticket(SSL_SESSION *ss, unsigned char **out, size_t *out_len) 196f5b1c8a1SJohn Marino { 197*72c33676SMaxim Ag if (ss == NULL) 198*72c33676SMaxim Ag return 0; 199f5b1c8a1SJohn Marino 200*72c33676SMaxim Ag if (ss->cipher == NULL && ss->cipher_id == 0) 201*72c33676SMaxim Ag return 0; 202f5b1c8a1SJohn Marino 203*72c33676SMaxim Ag return SSL_SESSION_encode(ss, out, out_len, 1); 204f5b1c8a1SJohn Marino } 205f5b1c8a1SJohn Marino 206*72c33676SMaxim Ag int 207*72c33676SMaxim Ag i2d_SSL_SESSION(SSL_SESSION *ss, unsigned char **pp) 208*72c33676SMaxim Ag { 209*72c33676SMaxim Ag unsigned char *data = NULL; 210*72c33676SMaxim Ag size_t data_len = 0; 211*72c33676SMaxim Ag int rv = -1; 212*72c33676SMaxim Ag 213*72c33676SMaxim Ag if (ss == NULL) 214*72c33676SMaxim Ag return 0; 215*72c33676SMaxim Ag 216*72c33676SMaxim Ag if (ss->cipher == NULL && ss->cipher_id == 0) 217*72c33676SMaxim Ag return 0; 218*72c33676SMaxim Ag 219*72c33676SMaxim Ag if (!SSL_SESSION_encode(ss, &data, &data_len, 0)) 220*72c33676SMaxim Ag goto err; 221*72c33676SMaxim Ag 222*72c33676SMaxim Ag if (data_len > INT_MAX) 223*72c33676SMaxim Ag goto err; 224*72c33676SMaxim Ag 225*72c33676SMaxim Ag if (pp != NULL) { 226*72c33676SMaxim Ag if (*pp == NULL) { 227*72c33676SMaxim Ag *pp = data; 228*72c33676SMaxim Ag data = NULL; 229*72c33676SMaxim Ag } else { 230*72c33676SMaxim Ag memcpy(*pp, data, data_len); 231*72c33676SMaxim Ag *pp += data_len; 232*72c33676SMaxim Ag } 233f5b1c8a1SJohn Marino } 234f5b1c8a1SJohn Marino 235*72c33676SMaxim Ag rv = (int)data_len; 236f5b1c8a1SJohn Marino 237*72c33676SMaxim Ag err: 238*72c33676SMaxim Ag freezero(data, data_len); 239f5b1c8a1SJohn Marino 240*72c33676SMaxim Ag return rv; 241f5b1c8a1SJohn Marino } 242f5b1c8a1SJohn Marino 243f5b1c8a1SJohn Marino SSL_SESSION * 244f5b1c8a1SJohn Marino d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length) 245f5b1c8a1SJohn Marino { 246*72c33676SMaxim Ag CBS cbs, session, cipher_suite, session_id, master_key, peer_cert; 247*72c33676SMaxim Ag CBS hostname, ticket; 248*72c33676SMaxim Ag uint64_t version, tls_version, stime, timeout, verify_result, lifetime; 249*72c33676SMaxim Ag const unsigned char *peer_cert_bytes; 250*72c33676SMaxim Ag uint16_t cipher_value; 251*72c33676SMaxim Ag SSL_SESSION *s = NULL; 252*72c33676SMaxim Ag size_t data_len; 253*72c33676SMaxim Ag int present; 254f5b1c8a1SJohn Marino 255f5b1c8a1SJohn Marino if (a != NULL) 256*72c33676SMaxim Ag s = *a; 257f5b1c8a1SJohn Marino 258*72c33676SMaxim Ag if (s == NULL) { 259*72c33676SMaxim Ag if ((s = SSL_SESSION_new()) == NULL) { 260*72c33676SMaxim Ag SSLerrorx(ERR_R_MALLOC_FAILURE); 261*72c33676SMaxim Ag return (NULL); 262*72c33676SMaxim Ag } 263*72c33676SMaxim Ag } 264*72c33676SMaxim Ag 265*72c33676SMaxim Ag CBS_init(&cbs, *pp, length); 266*72c33676SMaxim Ag 267*72c33676SMaxim Ag if (!CBS_get_asn1(&cbs, &session, CBS_ASN1_SEQUENCE)) 268*72c33676SMaxim Ag goto err; 269*72c33676SMaxim Ag 270*72c33676SMaxim Ag /* Session ASN1 version. */ 271*72c33676SMaxim Ag if (!CBS_get_asn1_uint64(&session, &version)) 272*72c33676SMaxim Ag goto err; 273*72c33676SMaxim Ag if (version != SSL_SESSION_ASN1_VERSION) 274*72c33676SMaxim Ag goto err; 275*72c33676SMaxim Ag 276*72c33676SMaxim Ag /* TLS/SSL Protocol Version. */ 277*72c33676SMaxim Ag if (!CBS_get_asn1_uint64(&session, &tls_version)) 278*72c33676SMaxim Ag goto err; 279*72c33676SMaxim Ag if (tls_version > INT_MAX) 280*72c33676SMaxim Ag goto err; 281*72c33676SMaxim Ag s->ssl_version = (int)tls_version; 282*72c33676SMaxim Ag 283*72c33676SMaxim Ag /* Cipher suite. */ 284*72c33676SMaxim Ag if (!CBS_get_asn1(&session, &cipher_suite, CBS_ASN1_OCTETSTRING)) 285*72c33676SMaxim Ag goto err; 286*72c33676SMaxim Ag if (!CBS_get_u16(&cipher_suite, &cipher_value)) 287*72c33676SMaxim Ag goto err; 288*72c33676SMaxim Ag if (CBS_len(&cipher_suite) != 0) 289*72c33676SMaxim Ag goto err; 290*72c33676SMaxim Ag 291*72c33676SMaxim Ag /* XXX - populate cipher instead? */ 292*72c33676SMaxim Ag s->cipher = NULL; 293*72c33676SMaxim Ag s->cipher_id = SSL3_CK_ID | cipher_value; 294*72c33676SMaxim Ag 295*72c33676SMaxim Ag /* Session ID. */ 296*72c33676SMaxim Ag if (!CBS_get_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING)) 297*72c33676SMaxim Ag goto err; 298*72c33676SMaxim Ag if (!CBS_write_bytes(&session_id, s->session_id, sizeof(s->session_id), 299*72c33676SMaxim Ag &data_len)) 300*72c33676SMaxim Ag goto err; 301*72c33676SMaxim Ag if (data_len > UINT_MAX) 302*72c33676SMaxim Ag goto err; 303*72c33676SMaxim Ag s->session_id_length = (unsigned int)data_len; 304*72c33676SMaxim Ag 305*72c33676SMaxim Ag /* Master key. */ 306*72c33676SMaxim Ag if (!CBS_get_asn1(&session, &master_key, CBS_ASN1_OCTETSTRING)) 307*72c33676SMaxim Ag goto err; 308*72c33676SMaxim Ag if (!CBS_write_bytes(&master_key, s->master_key, sizeof(s->master_key), 309*72c33676SMaxim Ag &data_len)) 310*72c33676SMaxim Ag goto err; 311*72c33676SMaxim Ag if (data_len > INT_MAX) 312*72c33676SMaxim Ag goto err; 313*72c33676SMaxim Ag s->master_key_length = (int)data_len; 314*72c33676SMaxim Ag 315*72c33676SMaxim Ag /* Time [1]. */ 316*72c33676SMaxim Ag s->time = time(NULL); 317*72c33676SMaxim Ag if (!CBS_get_optional_asn1_uint64(&session, &stime, SSLASN1_TIME_TAG, 318*72c33676SMaxim Ag 0)) 319*72c33676SMaxim Ag goto err; 320*72c33676SMaxim Ag if (stime > time_max()) 321*72c33676SMaxim Ag goto err; 322*72c33676SMaxim Ag if (stime != 0) 323*72c33676SMaxim Ag s->time = (time_t)stime; 324*72c33676SMaxim Ag 325*72c33676SMaxim Ag /* Timeout [2]. */ 326*72c33676SMaxim Ag s->timeout = 3; 327*72c33676SMaxim Ag if (!CBS_get_optional_asn1_uint64(&session, &timeout, 328*72c33676SMaxim Ag SSLASN1_TIMEOUT_TAG, 0)) 329*72c33676SMaxim Ag goto err; 330*72c33676SMaxim Ag if (timeout > LONG_MAX) 331*72c33676SMaxim Ag goto err; 332*72c33676SMaxim Ag if (timeout != 0) 333*72c33676SMaxim Ag s->timeout = (long)timeout; 334*72c33676SMaxim Ag 335*72c33676SMaxim Ag /* Peer certificate [3]. */ 336*72c33676SMaxim Ag X509_free(s->peer); 337*72c33676SMaxim Ag s->peer = NULL; 338*72c33676SMaxim Ag if (!CBS_get_optional_asn1(&session, &peer_cert, &present, 339*72c33676SMaxim Ag SSLASN1_PEER_CERT_TAG)) 340*72c33676SMaxim Ag goto err; 341*72c33676SMaxim Ag if (present) { 342*72c33676SMaxim Ag data_len = CBS_len(&peer_cert); 343*72c33676SMaxim Ag if (data_len > LONG_MAX) 344*72c33676SMaxim Ag goto err; 345*72c33676SMaxim Ag peer_cert_bytes = CBS_data(&peer_cert); 346*72c33676SMaxim Ag if (d2i_X509(&s->peer, &peer_cert_bytes, 347*72c33676SMaxim Ag (long)data_len) == NULL) 348*72c33676SMaxim Ag goto err; 349*72c33676SMaxim Ag } 350*72c33676SMaxim Ag 351*72c33676SMaxim Ag /* Session ID context [4]. */ 352*72c33676SMaxim Ag s->sid_ctx_length = 0; 353*72c33676SMaxim Ag if (!CBS_get_optional_asn1_octet_string(&session, &session_id, &present, 354*72c33676SMaxim Ag SSLASN1_SESSION_ID_CTX_TAG)) 355*72c33676SMaxim Ag goto err; 356*72c33676SMaxim Ag if (present) { 357*72c33676SMaxim Ag if (!CBS_write_bytes(&session_id, (uint8_t *)&s->sid_ctx, 358*72c33676SMaxim Ag sizeof(s->sid_ctx), &data_len)) 359*72c33676SMaxim Ag goto err; 360*72c33676SMaxim Ag if (data_len > UINT_MAX) 361*72c33676SMaxim Ag goto err; 362*72c33676SMaxim Ag s->sid_ctx_length = (unsigned int)data_len; 363*72c33676SMaxim Ag } 364*72c33676SMaxim Ag 365*72c33676SMaxim Ag /* Verify result [5]. */ 366*72c33676SMaxim Ag s->verify_result = X509_V_OK; 367*72c33676SMaxim Ag if (!CBS_get_optional_asn1_uint64(&session, &verify_result, 368*72c33676SMaxim Ag SSLASN1_VERIFY_RESULT_TAG, X509_V_OK)) 369*72c33676SMaxim Ag goto err; 370*72c33676SMaxim Ag if (verify_result > LONG_MAX) 371*72c33676SMaxim Ag goto err; 372*72c33676SMaxim Ag s->verify_result = (long)verify_result; 373*72c33676SMaxim Ag 374*72c33676SMaxim Ag /* Hostname [6]. */ 375*72c33676SMaxim Ag free(s->tlsext_hostname); 376*72c33676SMaxim Ag s->tlsext_hostname = NULL; 377*72c33676SMaxim Ag if (!CBS_get_optional_asn1_octet_string(&session, &hostname, &present, 378*72c33676SMaxim Ag SSLASN1_HOSTNAME_TAG)) 379*72c33676SMaxim Ag goto err; 380*72c33676SMaxim Ag if (present) { 381*72c33676SMaxim Ag if (CBS_contains_zero_byte(&hostname)) 382*72c33676SMaxim Ag goto err; 383*72c33676SMaxim Ag if (!CBS_strdup(&hostname, &s->tlsext_hostname)) 384*72c33676SMaxim Ag goto err; 385*72c33676SMaxim Ag } 386*72c33676SMaxim Ag 387*72c33676SMaxim Ag /* PSK identity hint [7]. */ 388*72c33676SMaxim Ag /* PSK identity [8]. */ 389*72c33676SMaxim Ag 390*72c33676SMaxim Ag /* Ticket lifetime [9]. */ 391*72c33676SMaxim Ag s->tlsext_tick_lifetime_hint = 0; 392*72c33676SMaxim Ag /* XXX - tlsext_ticklen is not yet set... */ 393*72c33676SMaxim Ag if (s->tlsext_ticklen > 0 && s->session_id_length > 0) 394*72c33676SMaxim Ag s->tlsext_tick_lifetime_hint = -1; 395*72c33676SMaxim Ag if (!CBS_get_optional_asn1_uint64(&session, &lifetime, 396*72c33676SMaxim Ag SSLASN1_LIFETIME_TAG, 0)) 397*72c33676SMaxim Ag goto err; 398*72c33676SMaxim Ag if (lifetime > LONG_MAX) 399*72c33676SMaxim Ag goto err; 400*72c33676SMaxim Ag if (lifetime > 0) 401*72c33676SMaxim Ag s->tlsext_tick_lifetime_hint = (long)lifetime; 402*72c33676SMaxim Ag 403*72c33676SMaxim Ag /* Ticket [10]. */ 404*72c33676SMaxim Ag free(s->tlsext_tick); 405*72c33676SMaxim Ag s->tlsext_tick = NULL; 406*72c33676SMaxim Ag if (!CBS_get_optional_asn1_octet_string(&session, &ticket, &present, 407*72c33676SMaxim Ag SSLASN1_TICKET_TAG)) 408*72c33676SMaxim Ag goto err; 409*72c33676SMaxim Ag if (present) { 410*72c33676SMaxim Ag if (!CBS_stow(&ticket, &s->tlsext_tick, &s->tlsext_ticklen)) 411*72c33676SMaxim Ag goto err; 412*72c33676SMaxim Ag } 413*72c33676SMaxim Ag 414*72c33676SMaxim Ag /* Compression method [11]. */ 415*72c33676SMaxim Ag /* SRP username [12]. */ 416*72c33676SMaxim Ag 417*72c33676SMaxim Ag *pp = CBS_data(&cbs); 418*72c33676SMaxim Ag 419*72c33676SMaxim Ag if (a != NULL) 420*72c33676SMaxim Ag *a = s; 421*72c33676SMaxim Ag 422*72c33676SMaxim Ag return (s); 423f5b1c8a1SJohn Marino 424f5b1c8a1SJohn Marino err: 425*72c33676SMaxim Ag ERR_asprintf_error_data("offset=%d", (int)(CBS_data(&cbs) - *pp)); 426*72c33676SMaxim Ag 427*72c33676SMaxim Ag if (s != NULL && (a == NULL || *a != s)) 428*72c33676SMaxim Ag SSL_SESSION_free(s); 429f5b1c8a1SJohn Marino 430f5b1c8a1SJohn Marino return (NULL); 431f5b1c8a1SJohn Marino } 432