Home | History | Annotate | Download | only in ssl
      1 /* ssl/ssl_asn1.c */
      2 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      3  * All rights reserved.
      4  *
      5  * This package is an SSL implementation written
      6  * by Eric Young (eay (at) 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 (at) 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 (at) 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 (at) 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];
    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 	unsigned char cbuf;
    131 	int v11=0;
    132 #endif
    133 	long l;
    134 	SSL_SESSION_ASN1 a;
    135 	M_ASN1_I2D_vars(in);
    136 
    137 	if ((in == NULL) || ((in->cipher == NULL) && (in->cipher_id == 0)))
    138 		return(0);
    139 
    140 	/* Note that I cheat in the following 2 assignments.  I know
    141 	 * that if the ASN1_INTEGER passed to ASN1_INTEGER_set
    142 	 * is > sizeof(long)+1, the buffer will not be re-OPENSSL_malloc()ed.
    143 	 * This is a bit evil but makes things simple, no dynamic allocation
    144 	 * to clean up :-) */
    145 	a.version.length=LSIZE2;
    146 	a.version.type=V_ASN1_INTEGER;
    147 	a.version.data=ibuf1;
    148 	ASN1_INTEGER_set(&(a.version),SSL_SESSION_ASN1_VERSION);
    149 
    150 	a.ssl_version.length=LSIZE2;
    151 	a.ssl_version.type=V_ASN1_INTEGER;
    152 	a.ssl_version.data=ibuf2;
    153 	ASN1_INTEGER_set(&(a.ssl_version),in->ssl_version);
    154 
    155 	a.cipher.type=V_ASN1_OCTET_STRING;
    156 	a.cipher.data=buf;
    157 
    158 	if (in->cipher == NULL)
    159 		l=in->cipher_id;
    160 	else
    161 		l=in->cipher->id;
    162 	if (in->ssl_version == SSL2_VERSION)
    163 		{
    164 		a.cipher.length=3;
    165 		buf[0]=((unsigned char)(l>>16L))&0xff;
    166 		buf[1]=((unsigned char)(l>> 8L))&0xff;
    167 		buf[2]=((unsigned char)(l     ))&0xff;
    168 		}
    169 	else
    170 		{
    171 		a.cipher.length=2;
    172 		buf[0]=((unsigned char)(l>>8L))&0xff;
    173 		buf[1]=((unsigned char)(l    ))&0xff;
    174 		}
    175 
    176 #ifndef OPENSSL_NO_COMP
    177 	if (in->compress_meth)
    178 		{
    179 		cbuf = (unsigned char)in->compress_meth;
    180 		a.comp_id.length = 1;
    181 		a.comp_id.type = V_ASN1_OCTET_STRING;
    182 		a.comp_id.data = &cbuf;
    183 		}
    184 #endif
    185 
    186 	a.master_key.length=in->master_key_length;
    187 	a.master_key.type=V_ASN1_OCTET_STRING;
    188 	a.master_key.data=in->master_key;
    189 
    190 	a.session_id.length=in->session_id_length;
    191 	a.session_id.type=V_ASN1_OCTET_STRING;
    192 	a.session_id.data=in->session_id;
    193 
    194 	a.session_id_context.length=in->sid_ctx_length;
    195 	a.session_id_context.type=V_ASN1_OCTET_STRING;
    196 	a.session_id_context.data=in->sid_ctx;
    197 
    198 	a.key_arg.length=in->key_arg_length;
    199 	a.key_arg.type=V_ASN1_OCTET_STRING;
    200 	a.key_arg.data=in->key_arg;
    201 
    202 #ifndef OPENSSL_NO_KRB5
    203 	if (in->krb5_client_princ_len)
    204 		{
    205 		a.krb5_princ.length=in->krb5_client_princ_len;
    206 		a.krb5_princ.type=V_ASN1_OCTET_STRING;
    207 		a.krb5_princ.data=in->krb5_client_princ;
    208 		}
    209 #endif /* OPENSSL_NO_KRB5 */
    210 
    211 	if (in->time != 0L)
    212 		{
    213 		a.time.length=LSIZE2;
    214 		a.time.type=V_ASN1_INTEGER;
    215 		a.time.data=ibuf3;
    216 		ASN1_INTEGER_set(&(a.time),in->time);
    217 		}
    218 
    219 	if (in->timeout != 0L)
    220 		{
    221 		a.timeout.length=LSIZE2;
    222 		a.timeout.type=V_ASN1_INTEGER;
    223 		a.timeout.data=ibuf4;
    224 		ASN1_INTEGER_set(&(a.timeout),in->timeout);
    225 		}
    226 
    227 	if (in->verify_result != X509_V_OK)
    228 		{
    229 		a.verify_result.length=LSIZE2;
    230 		a.verify_result.type=V_ASN1_INTEGER;
    231 		a.verify_result.data=ibuf5;
    232 		ASN1_INTEGER_set(&a.verify_result,in->verify_result);
    233 		}
    234 
    235 #ifndef OPENSSL_NO_TLSEXT
    236 	if (in->tlsext_hostname)
    237                 {
    238                 a.tlsext_hostname.length=strlen(in->tlsext_hostname);
    239                 a.tlsext_hostname.type=V_ASN1_OCTET_STRING;
    240                 a.tlsext_hostname.data=(unsigned char *)in->tlsext_hostname;
    241                 }
    242 	if (in->tlsext_tick)
    243                 {
    244                 a.tlsext_tick.length= in->tlsext_ticklen;
    245                 a.tlsext_tick.type=V_ASN1_OCTET_STRING;
    246                 a.tlsext_tick.data=(unsigned char *)in->tlsext_tick;
    247                 }
    248 	if (in->tlsext_tick_lifetime_hint > 0)
    249 		{
    250 		a.tlsext_tick_lifetime.length=LSIZE2;
    251 		a.tlsext_tick_lifetime.type=V_ASN1_INTEGER;
    252 		a.tlsext_tick_lifetime.data=ibuf6;
    253 		ASN1_INTEGER_set(&a.tlsext_tick_lifetime,in->tlsext_tick_lifetime_hint);
    254 		}
    255 #endif /* OPENSSL_NO_TLSEXT */
    256 #ifndef OPENSSL_NO_PSK
    257 	if (in->psk_identity_hint)
    258 		{
    259 		a.psk_identity_hint.length=strlen(in->psk_identity_hint);
    260 		a.psk_identity_hint.type=V_ASN1_OCTET_STRING;
    261 		a.psk_identity_hint.data=(unsigned char *)(in->psk_identity_hint);
    262 		}
    263 	if (in->psk_identity)
    264 		{
    265 		a.psk_identity.length=strlen(in->psk_identity);
    266 		a.psk_identity.type=V_ASN1_OCTET_STRING;
    267 		a.psk_identity.data=(unsigned char *)(in->psk_identity);
    268 		}
    269 #endif /* OPENSSL_NO_PSK */
    270 
    271 	M_ASN1_I2D_len(&(a.version),		i2d_ASN1_INTEGER);
    272 	M_ASN1_I2D_len(&(a.ssl_version),	i2d_ASN1_INTEGER);
    273 	M_ASN1_I2D_len(&(a.cipher),		i2d_ASN1_OCTET_STRING);
    274 	M_ASN1_I2D_len(&(a.session_id),		i2d_ASN1_OCTET_STRING);
    275 	M_ASN1_I2D_len(&(a.master_key),		i2d_ASN1_OCTET_STRING);
    276 #ifndef OPENSSL_NO_KRB5
    277 	if (in->krb5_client_princ_len)
    278         	M_ASN1_I2D_len(&(a.krb5_princ),	i2d_ASN1_OCTET_STRING);
    279 #endif /* OPENSSL_NO_KRB5 */
    280 	if (in->key_arg_length > 0)
    281 		M_ASN1_I2D_len_IMP_opt(&(a.key_arg),i2d_ASN1_OCTET_STRING);
    282 	if (in->time != 0L)
    283 		M_ASN1_I2D_len_EXP_opt(&(a.time),i2d_ASN1_INTEGER,1,v1);
    284 	if (in->timeout != 0L)
    285 		M_ASN1_I2D_len_EXP_opt(&(a.timeout),i2d_ASN1_INTEGER,2,v2);
    286 	if (in->peer != NULL)
    287 		M_ASN1_I2D_len_EXP_opt(in->peer,i2d_X509,3,v3);
    288 	M_ASN1_I2D_len_EXP_opt(&a.session_id_context,i2d_ASN1_OCTET_STRING,4,v4);
    289 	if (in->verify_result != X509_V_OK)
    290 		M_ASN1_I2D_len_EXP_opt(&(a.verify_result),i2d_ASN1_INTEGER,5,v5);
    291 
    292 #ifndef OPENSSL_NO_TLSEXT
    293 	if (in->tlsext_tick_lifetime_hint > 0)
    294       	 	M_ASN1_I2D_len_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER,9,v9);
    295 	if (in->tlsext_tick)
    296         	M_ASN1_I2D_len_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING,10,v10);
    297 	if (in->tlsext_hostname)
    298         	M_ASN1_I2D_len_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING,6,v6);
    299 #ifndef OPENSSL_NO_COMP
    300 	if (in->compress_meth)
    301         	M_ASN1_I2D_len_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING,11,v11);
    302 #endif
    303 #endif /* OPENSSL_NO_TLSEXT */
    304 #ifndef OPENSSL_NO_PSK
    305 	if (in->psk_identity_hint)
    306         	M_ASN1_I2D_len_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING,7,v7);
    307 	if (in->psk_identity)
    308         	M_ASN1_I2D_len_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING,8,v8);
    309 #endif /* OPENSSL_NO_PSK */
    310 
    311 	M_ASN1_I2D_seq_total();
    312 
    313 	M_ASN1_I2D_put(&(a.version),		i2d_ASN1_INTEGER);
    314 	M_ASN1_I2D_put(&(a.ssl_version),	i2d_ASN1_INTEGER);
    315 	M_ASN1_I2D_put(&(a.cipher),		i2d_ASN1_OCTET_STRING);
    316 	M_ASN1_I2D_put(&(a.session_id),		i2d_ASN1_OCTET_STRING);
    317 	M_ASN1_I2D_put(&(a.master_key),		i2d_ASN1_OCTET_STRING);
    318 #ifndef OPENSSL_NO_KRB5
    319 	if (in->krb5_client_princ_len)
    320         	M_ASN1_I2D_put(&(a.krb5_princ),	i2d_ASN1_OCTET_STRING);
    321 #endif /* OPENSSL_NO_KRB5 */
    322 	if (in->key_arg_length > 0)
    323 		M_ASN1_I2D_put_IMP_opt(&(a.key_arg),i2d_ASN1_OCTET_STRING,0);
    324 	if (in->time != 0L)
    325 		M_ASN1_I2D_put_EXP_opt(&(a.time),i2d_ASN1_INTEGER,1,v1);
    326 	if (in->timeout != 0L)
    327 		M_ASN1_I2D_put_EXP_opt(&(a.timeout),i2d_ASN1_INTEGER,2,v2);
    328 	if (in->peer != NULL)
    329 		M_ASN1_I2D_put_EXP_opt(in->peer,i2d_X509,3,v3);
    330 	M_ASN1_I2D_put_EXP_opt(&a.session_id_context,i2d_ASN1_OCTET_STRING,4,
    331 			       v4);
    332 	if (in->verify_result != X509_V_OK)
    333 		M_ASN1_I2D_put_EXP_opt(&a.verify_result,i2d_ASN1_INTEGER,5,v5);
    334 #ifndef OPENSSL_NO_TLSEXT
    335 	if (in->tlsext_hostname)
    336         	M_ASN1_I2D_put_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING,6,v6);
    337 #endif /* OPENSSL_NO_TLSEXT */
    338 #ifndef OPENSSL_NO_PSK
    339 	if (in->psk_identity_hint)
    340 		M_ASN1_I2D_put_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING,7,v7);
    341 	if (in->psk_identity)
    342 		M_ASN1_I2D_put_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING,8,v8);
    343 #endif /* OPENSSL_NO_PSK */
    344 #ifndef OPENSSL_NO_TLSEXT
    345 	if (in->tlsext_tick_lifetime_hint > 0)
    346       	 	M_ASN1_I2D_put_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER,9,v9);
    347 	if (in->tlsext_tick)
    348         	M_ASN1_I2D_put_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING,10,v10);
    349 #endif /* OPENSSL_NO_TLSEXT */
    350 #ifndef OPENSSL_NO_COMP
    351 	if (in->compress_meth)
    352         	M_ASN1_I2D_put_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING,11,v11);
    353 #endif
    354 	M_ASN1_I2D_finish();
    355 	}
    356 
    357 SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
    358 			     long length)
    359 	{
    360 	int version,ssl_version=0,i;
    361 	long id;
    362 	ASN1_INTEGER ai,*aip;
    363 	ASN1_OCTET_STRING os,*osp;
    364 	M_ASN1_D2I_vars(a,SSL_SESSION *,SSL_SESSION_new);
    365 
    366 	aip= &ai;
    367 	osp= &os;
    368 
    369 	M_ASN1_D2I_Init();
    370 	M_ASN1_D2I_start_sequence();
    371 
    372 	ai.data=NULL; ai.length=0;
    373 	M_ASN1_D2I_get_x(ASN1_INTEGER,aip,d2i_ASN1_INTEGER);
    374 	version=(int)ASN1_INTEGER_get(aip);
    375 	if (ai.data != NULL) { OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; }
    376 
    377 	/* we don't care about the version right now :-) */
    378 	M_ASN1_D2I_get_x(ASN1_INTEGER,aip,d2i_ASN1_INTEGER);
    379 	ssl_version=(int)ASN1_INTEGER_get(aip);
    380 	ret->ssl_version=ssl_version;
    381 	if (ai.data != NULL) { OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; }
    382 
    383 	os.data=NULL; os.length=0;
    384 	M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING);
    385 	if (ssl_version == SSL2_VERSION)
    386 		{
    387 		if (os.length != 3)
    388 			{
    389 			c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH;
    390 			goto err;
    391 			}
    392 		id=0x02000000L|
    393 			((unsigned long)os.data[0]<<16L)|
    394 			((unsigned long)os.data[1]<< 8L)|
    395 			 (unsigned long)os.data[2];
    396 		}
    397 	else if ((ssl_version>>8) >= SSL3_VERSION_MAJOR)
    398 		{
    399 		if (os.length != 2)
    400 			{
    401 			c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH;
    402 			goto err;
    403 			}
    404 		id=0x03000000L|
    405 			((unsigned long)os.data[0]<<8L)|
    406 			 (unsigned long)os.data[1];
    407 		}
    408 	else
    409 		{
    410 		c.error=SSL_R_UNKNOWN_SSL_VERSION;
    411 		goto err;
    412 		}
    413 
    414 	ret->cipher=NULL;
    415 	ret->cipher_id=id;
    416 
    417 	M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING);
    418 	if ((ssl_version>>8) >= SSL3_VERSION_MAJOR)
    419 		i=SSL3_MAX_SSL_SESSION_ID_LENGTH;
    420 	else /* if (ssl_version>>8 == SSL2_VERSION_MAJOR) */
    421 		i=SSL2_MAX_SSL_SESSION_ID_LENGTH;
    422 
    423 	if (os.length > i)
    424 		os.length = i;
    425 	if (os.length > (int)sizeof(ret->session_id)) /* can't happen */
    426 		os.length = sizeof(ret->session_id);
    427 
    428 	ret->session_id_length=os.length;
    429 	OPENSSL_assert(os.length <= (int)sizeof(ret->session_id));
    430 	memcpy(ret->session_id,os.data,os.length);
    431 
    432 	M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING);
    433 	if (os.length > SSL_MAX_MASTER_KEY_LENGTH)
    434 		ret->master_key_length=SSL_MAX_MASTER_KEY_LENGTH;
    435 	else
    436 		ret->master_key_length=os.length;
    437 	memcpy(ret->master_key,os.data,ret->master_key_length);
    438 
    439 	os.length=0;
    440 
    441 #ifndef OPENSSL_NO_KRB5
    442 	os.length=0;
    443 	M_ASN1_D2I_get_opt(osp,d2i_ASN1_OCTET_STRING,V_ASN1_OCTET_STRING);
    444 	if (os.data)
    445 		{
    446         	if (os.length > SSL_MAX_KRB5_PRINCIPAL_LENGTH)
    447             		ret->krb5_client_princ_len=0;
    448 		else
    449 			ret->krb5_client_princ_len=os.length;
    450 		memcpy(ret->krb5_client_princ,os.data,ret->krb5_client_princ_len);
    451 		OPENSSL_free(os.data);
    452 		os.data = NULL;
    453 		os.length = 0;
    454 		}
    455 	else
    456 		ret->krb5_client_princ_len=0;
    457 #endif /* OPENSSL_NO_KRB5 */
    458 
    459 	M_ASN1_D2I_get_IMP_opt(osp,d2i_ASN1_OCTET_STRING,0,V_ASN1_OCTET_STRING);
    460 	if (os.length > SSL_MAX_KEY_ARG_LENGTH)
    461 		ret->key_arg_length=SSL_MAX_KEY_ARG_LENGTH;
    462 	else
    463 		ret->key_arg_length=os.length;
    464 	memcpy(ret->key_arg,os.data,ret->key_arg_length);
    465 	if (os.data != NULL) OPENSSL_free(os.data);
    466 
    467 	ai.length=0;
    468 	M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,1);
    469 	if (ai.data != NULL)
    470 		{
    471 		ret->time=ASN1_INTEGER_get(aip);
    472 		OPENSSL_free(ai.data); ai.data=NULL; ai.length=0;
    473 		}
    474 	else
    475 		ret->time=(unsigned long)time(NULL);
    476 
    477 	ai.length=0;
    478 	M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,2);
    479 	if (ai.data != NULL)
    480 		{
    481 		ret->timeout=ASN1_INTEGER_get(aip);
    482 		OPENSSL_free(ai.data); ai.data=NULL; ai.length=0;
    483 		}
    484 	else
    485 		ret->timeout=3;
    486 
    487 	if (ret->peer != NULL)
    488 		{
    489 		X509_free(ret->peer);
    490 		ret->peer=NULL;
    491 		}
    492 	M_ASN1_D2I_get_EXP_opt(ret->peer,d2i_X509,3);
    493 
    494 	os.length=0;
    495 	os.data=NULL;
    496 	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,4);
    497 
    498 	if(os.data != NULL)
    499 	    {
    500 	    if (os.length > SSL_MAX_SID_CTX_LENGTH)
    501 		{
    502 		c.error=SSL_R_BAD_LENGTH;
    503 		goto err;
    504 		}
    505 	    else
    506 		{
    507 		ret->sid_ctx_length=os.length;
    508 		memcpy(ret->sid_ctx,os.data,os.length);
    509 		}
    510 	    OPENSSL_free(os.data); os.data=NULL; os.length=0;
    511 	    }
    512 	else
    513 	    ret->sid_ctx_length=0;
    514 
    515 	ai.length=0;
    516 	M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,5);
    517 	if (ai.data != NULL)
    518 		{
    519 		ret->verify_result=ASN1_INTEGER_get(aip);
    520 		OPENSSL_free(ai.data); ai.data=NULL; ai.length=0;
    521 		}
    522 	else
    523 		ret->verify_result=X509_V_OK;
    524 
    525 #ifndef OPENSSL_NO_TLSEXT
    526 	os.length=0;
    527 	os.data=NULL;
    528 	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,6);
    529 	if (os.data)
    530 		{
    531 		ret->tlsext_hostname = BUF_strndup((char *)os.data, os.length);
    532 		OPENSSL_free(os.data);
    533 		os.data = NULL;
    534 		os.length = 0;
    535 		}
    536 	else
    537 		ret->tlsext_hostname=NULL;
    538 #endif /* OPENSSL_NO_TLSEXT */
    539 
    540 #ifndef OPENSSL_NO_PSK
    541 	os.length=0;
    542 	os.data=NULL;
    543 	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,7);
    544 	if (os.data)
    545 		{
    546 		ret->psk_identity_hint = BUF_strndup((char *)os.data, os.length);
    547 		OPENSSL_free(os.data);
    548 		os.data = NULL;
    549 		os.length = 0;
    550 		}
    551 	else
    552 		ret->psk_identity_hint=NULL;
    553 #endif /* OPENSSL_NO_PSK */
    554 
    555 #ifndef OPENSSL_NO_TLSEXT
    556 	ai.length=0;
    557 	M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,9);
    558 	if (ai.data != NULL)
    559 		{
    560 		ret->tlsext_tick_lifetime_hint=ASN1_INTEGER_get(aip);
    561 		OPENSSL_free(ai.data); ai.data=NULL; ai.length=0;
    562 		}
    563 	else if (ret->tlsext_ticklen && ret->session_id_length)
    564 		ret->tlsext_tick_lifetime_hint = -1;
    565 	else
    566 		ret->tlsext_tick_lifetime_hint=0;
    567 	os.length=0;
    568 	os.data=NULL;
    569 	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,10);
    570 	if (os.data)
    571 		{
    572 		ret->tlsext_tick = os.data;
    573 		ret->tlsext_ticklen = os.length;
    574 		os.data = NULL;
    575 		os.length = 0;
    576 		}
    577 	else
    578 		ret->tlsext_tick=NULL;
    579 #endif /* OPENSSL_NO_TLSEXT */
    580 #ifndef OPENSSL_NO_COMP
    581 	os.length=0;
    582 	os.data=NULL;
    583 	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,11);
    584 	if (os.data)
    585 		{
    586 		ret->compress_meth = os.data[0];
    587 		OPENSSL_free(os.data);
    588 		os.data = NULL;
    589 		}
    590 #endif
    591 
    592 	M_ASN1_D2I_Finish(a,SSL_SESSION_free,SSL_F_D2I_SSL_SESSION);
    593 	}
    594