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