1 /* ssl/ssl_asn1.c */ 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 /* ==================================================================== 59 * Copyright 2005 Nokia. All rights reserved. 60 * 61 * The portions of the attached software ("Contribution") is developed by 62 * Nokia Corporation and is licensed pursuant to the OpenSSL open source 63 * license. 64 * 65 * The Contribution, originally written by Mika Kousa and Pasi Eronen of 66 * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites 67 * support (see RFC 4279) to OpenSSL. 68 * 69 * No patent licenses or other rights except those expressly stated in 70 * the OpenSSL open source license shall be deemed granted or received 71 * expressly, by implication, estoppel, or otherwise. 72 * 73 * No assurances are provided by Nokia that the Contribution does not 74 * infringe the patent or other intellectual property rights of any third 75 * party or that the license provides you with all the necessary rights 76 * to make use of the Contribution. 77 * 78 * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN 79 * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA 80 * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY 81 * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR 82 * OTHERWISE. 83 */ 84 85 #include <stdio.h> 86 #include <stdlib.h> 87 #include "ssl_locl.h" 88 #include <openssl/asn1_mac.h> 89 #include <openssl/objects.h> 90 #include <openssl/x509.h> 91 92 typedef struct ssl_session_asn1_st 93 { 94 ASN1_INTEGER version; 95 ASN1_INTEGER ssl_version; 96 ASN1_OCTET_STRING cipher; 97 ASN1_OCTET_STRING comp_id; 98 ASN1_OCTET_STRING master_key; 99 ASN1_OCTET_STRING session_id; 100 ASN1_OCTET_STRING session_id_context; 101 ASN1_OCTET_STRING key_arg; 102 #ifndef OPENSSL_NO_KRB5 103 ASN1_OCTET_STRING krb5_princ; 104 #endif /* OPENSSL_NO_KRB5 */ 105 ASN1_INTEGER time; 106 ASN1_INTEGER timeout; 107 ASN1_INTEGER verify_result; 108 #ifndef OPENSSL_NO_TLSEXT 109 ASN1_OCTET_STRING tlsext_hostname; 110 ASN1_INTEGER tlsext_tick_lifetime; 111 ASN1_OCTET_STRING tlsext_tick; 112 #endif /* OPENSSL_NO_TLSEXT */ 113 #ifndef OPENSSL_NO_PSK 114 ASN1_OCTET_STRING psk_identity_hint; 115 ASN1_OCTET_STRING psk_identity; 116 #endif /* OPENSSL_NO_PSK */ 117 } SSL_SESSION_ASN1; 118 119 int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) 120 { 121 #define LSIZE2 (sizeof(long)*2) 122 int v1=0,v2=0,v3=0,v4=0,v5=0,v7=0,v8=0; 123 unsigned char buf[4],ibuf1[LSIZE2],ibuf2[LSIZE2], cbuf; 124 unsigned char ibuf3[LSIZE2],ibuf4[LSIZE2],ibuf5[LSIZE2]; 125 #ifndef OPENSSL_NO_TLSEXT 126 int v6=0,v9=0,v10=0; 127 unsigned char ibuf6[LSIZE2]; 128 #endif 129 #ifndef OPENSSL_NO_COMP 130 int v11=0; 131 #endif 132 long l; 133 SSL_SESSION_ASN1 a; 134 M_ASN1_I2D_vars(in); 135 136 if ((in == NULL) || ((in->cipher == NULL) && (in->cipher_id == 0))) 137 return(0); 138 139 /* Note that I cheat in the following 2 assignments. I know 140 * that if the ASN1_INTEGER passed to ASN1_INTEGER_set 141 * is > sizeof(long)+1, the buffer will not be re-OPENSSL_malloc()ed. 142 * This is a bit evil but makes things simple, no dynamic allocation 143 * to clean up :-) */ 144 a.version.length=LSIZE2; 145 a.version.type=V_ASN1_INTEGER; 146 a.version.data=ibuf1; 147 ASN1_INTEGER_set(&(a.version),SSL_SESSION_ASN1_VERSION); 148 149 a.ssl_version.length=LSIZE2; 150 a.ssl_version.type=V_ASN1_INTEGER; 151 a.ssl_version.data=ibuf2; 152 ASN1_INTEGER_set(&(a.ssl_version),in->ssl_version); 153 154 a.cipher.type=V_ASN1_OCTET_STRING; 155 a.cipher.data=buf; 156 157 if (in->cipher == NULL) 158 l=in->cipher_id; 159 else 160 l=in->cipher->id; 161 if (in->ssl_version == SSL2_VERSION) 162 { 163 a.cipher.length=3; 164 buf[0]=((unsigned char)(l>>16L))&0xff; 165 buf[1]=((unsigned char)(l>> 8L))&0xff; 166 buf[2]=((unsigned char)(l ))&0xff; 167 } 168 else 169 { 170 a.cipher.length=2; 171 buf[0]=((unsigned char)(l>>8L))&0xff; 172 buf[1]=((unsigned char)(l ))&0xff; 173 } 174 175 #ifndef OPENSSL_NO_COMP 176 if (in->compress_meth) 177 { 178 cbuf = (unsigned char)in->compress_meth; 179 a.comp_id.length = 1; 180 a.comp_id.type = V_ASN1_OCTET_STRING; 181 a.comp_id.data = &cbuf; 182 } 183 #endif 184 185 a.master_key.length=in->master_key_length; 186 a.master_key.type=V_ASN1_OCTET_STRING; 187 a.master_key.data=in->master_key; 188 189 a.session_id.length=in->session_id_length; 190 a.session_id.type=V_ASN1_OCTET_STRING; 191 a.session_id.data=in->session_id; 192 193 a.session_id_context.length=in->sid_ctx_length; 194 a.session_id_context.type=V_ASN1_OCTET_STRING; 195 a.session_id_context.data=in->sid_ctx; 196 197 a.key_arg.length=in->key_arg_length; 198 a.key_arg.type=V_ASN1_OCTET_STRING; 199 a.key_arg.data=in->key_arg; 200 201 #ifndef OPENSSL_NO_KRB5 202 if (in->krb5_client_princ_len) 203 { 204 a.krb5_princ.length=in->krb5_client_princ_len; 205 a.krb5_princ.type=V_ASN1_OCTET_STRING; 206 a.krb5_princ.data=in->krb5_client_princ; 207 } 208 #endif /* OPENSSL_NO_KRB5 */ 209 210 if (in->time != 0L) 211 { 212 a.time.length=LSIZE2; 213 a.time.type=V_ASN1_INTEGER; 214 a.time.data=ibuf3; 215 ASN1_INTEGER_set(&(a.time),in->time); 216 } 217 218 if (in->timeout != 0L) 219 { 220 a.timeout.length=LSIZE2; 221 a.timeout.type=V_ASN1_INTEGER; 222 a.timeout.data=ibuf4; 223 ASN1_INTEGER_set(&(a.timeout),in->timeout); 224 } 225 226 if (in->verify_result != X509_V_OK) 227 { 228 a.verify_result.length=LSIZE2; 229 a.verify_result.type=V_ASN1_INTEGER; 230 a.verify_result.data=ibuf5; 231 ASN1_INTEGER_set(&a.verify_result,in->verify_result); 232 } 233 234 #ifndef OPENSSL_NO_TLSEXT 235 if (in->tlsext_hostname) 236 { 237 a.tlsext_hostname.length=strlen(in->tlsext_hostname); 238 a.tlsext_hostname.type=V_ASN1_OCTET_STRING; 239 a.tlsext_hostname.data=(unsigned char *)in->tlsext_hostname; 240 } 241 if (in->tlsext_tick) 242 { 243 a.tlsext_tick.length= in->tlsext_ticklen; 244 a.tlsext_tick.type=V_ASN1_OCTET_STRING; 245 a.tlsext_tick.data=(unsigned char *)in->tlsext_tick; 246 /* If we have a ticket set session ID to empty because 247 * it will be bogus. If liftime hint is -1 treat as a special 248 * case because the session is being used as a container 249 */ 250 if (in->tlsext_ticklen && (in->tlsext_tick_lifetime_hint != -1)) 251 a.session_id.length=0; 252 } 253 if (in->tlsext_tick_lifetime_hint > 0) 254 { 255 a.tlsext_tick_lifetime.length=LSIZE2; 256 a.tlsext_tick_lifetime.type=V_ASN1_INTEGER; 257 a.tlsext_tick_lifetime.data=ibuf6; 258 ASN1_INTEGER_set(&a.tlsext_tick_lifetime,in->tlsext_tick_lifetime_hint); 259 } 260 #endif /* OPENSSL_NO_TLSEXT */ 261 #ifndef OPENSSL_NO_PSK 262 if (in->psk_identity_hint) 263 { 264 a.psk_identity_hint.length=strlen(in->psk_identity_hint); 265 a.psk_identity_hint.type=V_ASN1_OCTET_STRING; 266 a.psk_identity_hint.data=(unsigned char *)(in->psk_identity_hint); 267 } 268 if (in->psk_identity) 269 { 270 a.psk_identity.length=strlen(in->psk_identity); 271 a.psk_identity.type=V_ASN1_OCTET_STRING; 272 a.psk_identity.data=(unsigned char *)(in->psk_identity); 273 } 274 #endif /* OPENSSL_NO_PSK */ 275 276 M_ASN1_I2D_len(&(a.version), i2d_ASN1_INTEGER); 277 M_ASN1_I2D_len(&(a.ssl_version), i2d_ASN1_INTEGER); 278 M_ASN1_I2D_len(&(a.cipher), i2d_ASN1_OCTET_STRING); 279 M_ASN1_I2D_len(&(a.session_id), i2d_ASN1_OCTET_STRING); 280 M_ASN1_I2D_len(&(a.master_key), i2d_ASN1_OCTET_STRING); 281 #ifndef OPENSSL_NO_KRB5 282 if (in->krb5_client_princ_len) 283 M_ASN1_I2D_len(&(a.krb5_princ), i2d_ASN1_OCTET_STRING); 284 #endif /* OPENSSL_NO_KRB5 */ 285 if (in->key_arg_length > 0) 286 M_ASN1_I2D_len_IMP_opt(&(a.key_arg),i2d_ASN1_OCTET_STRING); 287 if (in->time != 0L) 288 M_ASN1_I2D_len_EXP_opt(&(a.time),i2d_ASN1_INTEGER,1,v1); 289 if (in->timeout != 0L) 290 M_ASN1_I2D_len_EXP_opt(&(a.timeout),i2d_ASN1_INTEGER,2,v2); 291 if (in->peer != NULL) 292 M_ASN1_I2D_len_EXP_opt(in->peer,i2d_X509,3,v3); 293 M_ASN1_I2D_len_EXP_opt(&a.session_id_context,i2d_ASN1_OCTET_STRING,4,v4); 294 if (in->verify_result != X509_V_OK) 295 M_ASN1_I2D_len_EXP_opt(&(a.verify_result),i2d_ASN1_INTEGER,5,v5); 296 297 #ifndef OPENSSL_NO_TLSEXT 298 if (in->tlsext_tick_lifetime_hint > 0) 299 M_ASN1_I2D_len_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER,9,v9); 300 if (in->tlsext_tick) 301 M_ASN1_I2D_len_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING,10,v10); 302 if (in->tlsext_hostname) 303 M_ASN1_I2D_len_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING,6,v6); 304 #ifndef OPENSSL_NO_COMP 305 if (in->compress_meth) 306 M_ASN1_I2D_len_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING,11,v11); 307 #endif 308 #endif /* OPENSSL_NO_TLSEXT */ 309 #ifndef OPENSSL_NO_PSK 310 if (in->psk_identity_hint) 311 M_ASN1_I2D_len_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING,7,v7); 312 if (in->psk_identity) 313 M_ASN1_I2D_len_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING,8,v8); 314 #endif /* OPENSSL_NO_PSK */ 315 316 M_ASN1_I2D_seq_total(); 317 318 M_ASN1_I2D_put(&(a.version), i2d_ASN1_INTEGER); 319 M_ASN1_I2D_put(&(a.ssl_version), i2d_ASN1_INTEGER); 320 M_ASN1_I2D_put(&(a.cipher), i2d_ASN1_OCTET_STRING); 321 M_ASN1_I2D_put(&(a.session_id), i2d_ASN1_OCTET_STRING); 322 M_ASN1_I2D_put(&(a.master_key), i2d_ASN1_OCTET_STRING); 323 #ifndef OPENSSL_NO_KRB5 324 if (in->krb5_client_princ_len) 325 M_ASN1_I2D_put(&(a.krb5_princ), i2d_ASN1_OCTET_STRING); 326 #endif /* OPENSSL_NO_KRB5 */ 327 if (in->key_arg_length > 0) 328 M_ASN1_I2D_put_IMP_opt(&(a.key_arg),i2d_ASN1_OCTET_STRING,0); 329 if (in->time != 0L) 330 M_ASN1_I2D_put_EXP_opt(&(a.time),i2d_ASN1_INTEGER,1,v1); 331 if (in->timeout != 0L) 332 M_ASN1_I2D_put_EXP_opt(&(a.timeout),i2d_ASN1_INTEGER,2,v2); 333 if (in->peer != NULL) 334 M_ASN1_I2D_put_EXP_opt(in->peer,i2d_X509,3,v3); 335 M_ASN1_I2D_put_EXP_opt(&a.session_id_context,i2d_ASN1_OCTET_STRING,4, 336 v4); 337 if (in->verify_result != X509_V_OK) 338 M_ASN1_I2D_put_EXP_opt(&a.verify_result,i2d_ASN1_INTEGER,5,v5); 339 #ifndef OPENSSL_NO_TLSEXT 340 if (in->tlsext_hostname) 341 M_ASN1_I2D_put_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING,6,v6); 342 #endif /* OPENSSL_NO_TLSEXT */ 343 #ifndef OPENSSL_NO_PSK 344 if (in->psk_identity_hint) 345 M_ASN1_I2D_put_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING,7,v7); 346 if (in->psk_identity) 347 M_ASN1_I2D_put_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING,8,v8); 348 #endif /* OPENSSL_NO_PSK */ 349 #ifndef OPENSSL_NO_TLSEXT 350 if (in->tlsext_tick_lifetime_hint > 0) 351 M_ASN1_I2D_put_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER,9,v9); 352 if (in->tlsext_tick) 353 M_ASN1_I2D_put_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING,10,v10); 354 #endif /* OPENSSL_NO_TLSEXT */ 355 #ifndef OPENSSL_NO_COMP 356 if (in->compress_meth) 357 M_ASN1_I2D_put_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING,11,v11); 358 #endif 359 M_ASN1_I2D_finish(); 360 } 361 362 SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, 363 long length) 364 { 365 int version,ssl_version=0,i; 366 long id; 367 ASN1_INTEGER ai,*aip; 368 ASN1_OCTET_STRING os,*osp; 369 M_ASN1_D2I_vars(a,SSL_SESSION *,SSL_SESSION_new); 370 371 aip= &ai; 372 osp= &os; 373 374 M_ASN1_D2I_Init(); 375 M_ASN1_D2I_start_sequence(); 376 377 ai.data=NULL; ai.length=0; 378 M_ASN1_D2I_get_x(ASN1_INTEGER,aip,d2i_ASN1_INTEGER); 379 version=(int)ASN1_INTEGER_get(aip); 380 if (ai.data != NULL) { OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; } 381 382 /* we don't care about the version right now :-) */ 383 M_ASN1_D2I_get_x(ASN1_INTEGER,aip,d2i_ASN1_INTEGER); 384 ssl_version=(int)ASN1_INTEGER_get(aip); 385 ret->ssl_version=ssl_version; 386 if (ai.data != NULL) { OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; } 387 388 os.data=NULL; os.length=0; 389 M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING); 390 if (ssl_version == SSL2_VERSION) 391 { 392 if (os.length != 3) 393 { 394 c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH; 395 goto err; 396 } 397 id=0x02000000L| 398 ((unsigned long)os.data[0]<<16L)| 399 ((unsigned long)os.data[1]<< 8L)| 400 (unsigned long)os.data[2]; 401 } 402 else if ((ssl_version>>8) == SSL3_VERSION_MAJOR) 403 { 404 if (os.length != 2) 405 { 406 c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH; 407 goto err; 408 } 409 id=0x03000000L| 410 ((unsigned long)os.data[0]<<8L)| 411 (unsigned long)os.data[1]; 412 } 413 else 414 { 415 SSLerr(SSL_F_D2I_SSL_SESSION,SSL_R_UNKNOWN_SSL_VERSION); 416 return(NULL); 417 } 418 419 ret->cipher=NULL; 420 ret->cipher_id=id; 421 422 M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING); 423 if ((ssl_version>>8) == SSL3_VERSION_MAJOR) 424 i=SSL3_MAX_SSL_SESSION_ID_LENGTH; 425 else /* if (ssl_version>>8 == SSL2_VERSION_MAJOR) */ 426 i=SSL2_MAX_SSL_SESSION_ID_LENGTH; 427 428 if (os.length > i) 429 os.length = i; 430 if (os.length > (int)sizeof(ret->session_id)) /* can't happen */ 431 os.length = sizeof(ret->session_id); 432 433 ret->session_id_length=os.length; 434 OPENSSL_assert(os.length <= (int)sizeof(ret->session_id)); 435 memcpy(ret->session_id,os.data,os.length); 436 437 M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING); 438 if (os.length > SSL_MAX_MASTER_KEY_LENGTH) 439 ret->master_key_length=SSL_MAX_MASTER_KEY_LENGTH; 440 else 441 ret->master_key_length=os.length; 442 memcpy(ret->master_key,os.data,ret->master_key_length); 443 444 os.length=0; 445 446 #ifndef OPENSSL_NO_KRB5 447 os.length=0; 448 M_ASN1_D2I_get_opt(osp,d2i_ASN1_OCTET_STRING,V_ASN1_OCTET_STRING); 449 if (os.data) 450 { 451 if (os.length > SSL_MAX_KRB5_PRINCIPAL_LENGTH) 452 ret->krb5_client_princ_len=0; 453 else 454 ret->krb5_client_princ_len=os.length; 455 memcpy(ret->krb5_client_princ,os.data,ret->krb5_client_princ_len); 456 OPENSSL_free(os.data); 457 os.data = NULL; 458 os.length = 0; 459 } 460 else 461 ret->krb5_client_princ_len=0; 462 #endif /* OPENSSL_NO_KRB5 */ 463 464 M_ASN1_D2I_get_IMP_opt(osp,d2i_ASN1_OCTET_STRING,0,V_ASN1_OCTET_STRING); 465 if (os.length > SSL_MAX_KEY_ARG_LENGTH) 466 ret->key_arg_length=SSL_MAX_KEY_ARG_LENGTH; 467 else 468 ret->key_arg_length=os.length; 469 memcpy(ret->key_arg,os.data,ret->key_arg_length); 470 if (os.data != NULL) OPENSSL_free(os.data); 471 472 ai.length=0; 473 M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,1); 474 if (ai.data != NULL) 475 { 476 ret->time=ASN1_INTEGER_get(aip); 477 OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; 478 } 479 else 480 ret->time=(unsigned long)time(NULL); 481 482 ai.length=0; 483 M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,2); 484 if (ai.data != NULL) 485 { 486 ret->timeout=ASN1_INTEGER_get(aip); 487 OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; 488 } 489 else 490 ret->timeout=3; 491 492 if (ret->peer != NULL) 493 { 494 X509_free(ret->peer); 495 ret->peer=NULL; 496 } 497 M_ASN1_D2I_get_EXP_opt(ret->peer,d2i_X509,3); 498 499 os.length=0; 500 os.data=NULL; 501 M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,4); 502 503 if(os.data != NULL) 504 { 505 if (os.length > SSL_MAX_SID_CTX_LENGTH) 506 { 507 ret->sid_ctx_length=os.length; 508 SSLerr(SSL_F_D2I_SSL_SESSION,SSL_R_BAD_LENGTH); 509 } 510 else 511 { 512 ret->sid_ctx_length=os.length; 513 memcpy(ret->sid_ctx,os.data,os.length); 514 } 515 OPENSSL_free(os.data); os.data=NULL; os.length=0; 516 } 517 else 518 ret->sid_ctx_length=0; 519 520 ai.length=0; 521 M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,5); 522 if (ai.data != NULL) 523 { 524 ret->verify_result=ASN1_INTEGER_get(aip); 525 OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; 526 } 527 else 528 ret->verify_result=X509_V_OK; 529 530 #ifndef OPENSSL_NO_TLSEXT 531 os.length=0; 532 os.data=NULL; 533 M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,6); 534 if (os.data) 535 { 536 ret->tlsext_hostname = BUF_strndup((char *)os.data, os.length); 537 OPENSSL_free(os.data); 538 os.data = NULL; 539 os.length = 0; 540 } 541 else 542 ret->tlsext_hostname=NULL; 543 #endif /* OPENSSL_NO_TLSEXT */ 544 545 #ifndef OPENSSL_NO_PSK 546 os.length=0; 547 os.data=NULL; 548 M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,7); 549 if (os.data) 550 { 551 ret->psk_identity_hint = BUF_strndup((char *)os.data, os.length); 552 OPENSSL_free(os.data); 553 os.data = NULL; 554 os.length = 0; 555 } 556 else 557 ret->psk_identity_hint=NULL; 558 #endif /* OPENSSL_NO_PSK */ 559 560 #ifndef OPENSSL_NO_TLSEXT 561 ai.length=0; 562 M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,9); 563 if (ai.data != NULL) 564 { 565 ret->tlsext_tick_lifetime_hint=ASN1_INTEGER_get(aip); 566 OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; 567 } 568 else if (ret->tlsext_ticklen && ret->session_id_length) 569 ret->tlsext_tick_lifetime_hint = -1; 570 else 571 ret->tlsext_tick_lifetime_hint=0; 572 os.length=0; 573 os.data=NULL; 574 M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,10); 575 if (os.data) 576 { 577 ret->tlsext_tick = os.data; 578 ret->tlsext_ticklen = os.length; 579 os.data = NULL; 580 os.length = 0; 581 #if 0 582 /* There are two ways to detect a resumed ticket sesion. 583 * One is to set a random session ID and then the server 584 * must return a match in ServerHello. This allows the normal 585 * client session ID matching to work. 586 */ 587 if (ret->session_id_length == 0) 588 { 589 ret->session_id_length=SSL3_MAX_SSL_SESSION_ID_LENGTH; 590 RAND_pseudo_bytes(ret->session_id, 591 ret->session_id_length); 592 } 593 #endif 594 } 595 else 596 ret->tlsext_tick=NULL; 597 #endif /* OPENSSL_NO_TLSEXT */ 598 #ifndef OPENSSL_NO_COMP 599 os.length=0; 600 os.data=NULL; 601 M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,11); 602 if (os.data) 603 { 604 ret->compress_meth = os.data[0]; 605 OPENSSL_free(os.data); 606 os.data = NULL; 607 } 608 #endif 609 610 M_ASN1_D2I_Finish(a,SSL_SESSION_free,SSL_F_D2I_SSL_SESSION); 611 } 612