155714Skris/* ssl/ssl_asn1.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8296465Sdelphij *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15296465Sdelphij *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22296465Sdelphij *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37296465Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40296465Sdelphij *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52296465Sdelphij *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include <stdio.h>
6055714Skris#include <stdlib.h>
61109998Smarkm#include "ssl_locl.h"
6255714Skris#include <openssl/asn1_mac.h>
6355714Skris#include <openssl/objects.h>
6459191Skris#include <openssl/x509.h>
6555714Skris
66296465Sdelphijtypedef struct ssl_session_asn1_st {
67296465Sdelphij    ASN1_INTEGER version;
68296465Sdelphij    ASN1_INTEGER ssl_version;
69296465Sdelphij    ASN1_OCTET_STRING cipher;
70296465Sdelphij    ASN1_OCTET_STRING comp_id;
71296465Sdelphij    ASN1_OCTET_STRING master_key;
72296465Sdelphij    ASN1_OCTET_STRING session_id;
73296465Sdelphij    ASN1_OCTET_STRING session_id_context;
74296465Sdelphij    ASN1_OCTET_STRING key_arg;
75109998Smarkm#ifndef OPENSSL_NO_KRB5
76296465Sdelphij    ASN1_OCTET_STRING krb5_princ;
77296465Sdelphij#endif                          /* OPENSSL_NO_KRB5 */
78296465Sdelphij    ASN1_INTEGER time;
79296465Sdelphij    ASN1_INTEGER timeout;
80296465Sdelphij    ASN1_INTEGER verify_result;
81194206Ssimon#ifndef OPENSSL_NO_TLSEXT
82296465Sdelphij    ASN1_OCTET_STRING tlsext_hostname;
83296465Sdelphij    ASN1_INTEGER tlsext_tick_lifetime;
84296465Sdelphij    ASN1_OCTET_STRING tlsext_tick;
85296465Sdelphij#endif                          /* OPENSSL_NO_TLSEXT */
86296465Sdelphij} SSL_SESSION_ASN1;
8755714Skris
8855714Skrisint i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
89296465Sdelphij{
9055714Skris#define LSIZE2 (sizeof(long)*2)
91296465Sdelphij    int v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0;
92296465Sdelphij    unsigned char buf[4], ibuf1[LSIZE2], ibuf2[LSIZE2];
93296465Sdelphij    unsigned char ibuf3[LSIZE2], ibuf4[LSIZE2], ibuf5[LSIZE2];
94194206Ssimon#ifndef OPENSSL_NO_TLSEXT
95296465Sdelphij    int v6 = 0, v9 = 0, v10 = 0;
96296465Sdelphij    unsigned char ibuf6[LSIZE2];
97194206Ssimon#endif
98205128Ssimon#ifndef OPENSSL_NO_COMP
99296465Sdelphij    int v11 = 0;
100296465Sdelphij    unsigned char cbuf;
101205128Ssimon#endif
102296465Sdelphij    long l;
103296465Sdelphij    SSL_SESSION_ASN1 a;
104296465Sdelphij    M_ASN1_I2D_vars(in);
10555714Skris
106296465Sdelphij    if ((in == NULL) || ((in->cipher == NULL) && (in->cipher_id == 0)))
107296465Sdelphij        return (0);
10855714Skris
109296465Sdelphij    /*
110296465Sdelphij     * Note that I cheat in the following 2 assignments.  I know that if the
111296465Sdelphij     * ASN1_INTEGER passed to ASN1_INTEGER_set is > sizeof(long)+1, the
112296465Sdelphij     * buffer will not be re-OPENSSL_malloc()ed. This is a bit evil but makes
113296465Sdelphij     * things simple, no dynamic allocation to clean up :-)
114296465Sdelphij     */
115296465Sdelphij    a.version.length = LSIZE2;
116296465Sdelphij    a.version.type = V_ASN1_INTEGER;
117296465Sdelphij    a.version.data = ibuf1;
118296465Sdelphij    ASN1_INTEGER_set(&(a.version), SSL_SESSION_ASN1_VERSION);
11955714Skris
120296465Sdelphij    a.ssl_version.length = LSIZE2;
121296465Sdelphij    a.ssl_version.type = V_ASN1_INTEGER;
122296465Sdelphij    a.ssl_version.data = ibuf2;
123296465Sdelphij    ASN1_INTEGER_set(&(a.ssl_version), in->ssl_version);
12455714Skris
125296465Sdelphij    a.cipher.type = V_ASN1_OCTET_STRING;
126296465Sdelphij    a.cipher.data = buf;
12755714Skris
128296465Sdelphij    if (in->cipher == NULL)
129296465Sdelphij        l = in->cipher_id;
130296465Sdelphij    else
131296465Sdelphij        l = in->cipher->id;
132296465Sdelphij    if (in->ssl_version == SSL2_VERSION) {
133296465Sdelphij        a.cipher.length = 3;
134296465Sdelphij        buf[0] = ((unsigned char)(l >> 16L)) & 0xff;
135296465Sdelphij        buf[1] = ((unsigned char)(l >> 8L)) & 0xff;
136296465Sdelphij        buf[2] = ((unsigned char)(l)) & 0xff;
137296465Sdelphij    } else {
138296465Sdelphij        a.cipher.length = 2;
139296465Sdelphij        buf[0] = ((unsigned char)(l >> 8L)) & 0xff;
140296465Sdelphij        buf[1] = ((unsigned char)(l)) & 0xff;
141296465Sdelphij    }
14255714Skris
143205128Ssimon#ifndef OPENSSL_NO_COMP
144296465Sdelphij    if (in->compress_meth) {
145296465Sdelphij        cbuf = (unsigned char)in->compress_meth;
146296465Sdelphij        a.comp_id.length = 1;
147296465Sdelphij        a.comp_id.type = V_ASN1_OCTET_STRING;
148296465Sdelphij        a.comp_id.data = &cbuf;
149296465Sdelphij    }
150205128Ssimon#endif
151205128Ssimon
152296465Sdelphij    a.master_key.length = in->master_key_length;
153296465Sdelphij    a.master_key.type = V_ASN1_OCTET_STRING;
154296465Sdelphij    a.master_key.data = in->master_key;
15555714Skris
156296465Sdelphij    a.session_id.length = in->session_id_length;
157296465Sdelphij    a.session_id.type = V_ASN1_OCTET_STRING;
158296465Sdelphij    a.session_id.data = in->session_id;
15955714Skris
160296465Sdelphij    a.session_id_context.length = in->sid_ctx_length;
161296465Sdelphij    a.session_id_context.type = V_ASN1_OCTET_STRING;
162296465Sdelphij    a.session_id_context.data = in->sid_ctx;
16355714Skris
164296465Sdelphij    a.key_arg.length = in->key_arg_length;
165296465Sdelphij    a.key_arg.type = V_ASN1_OCTET_STRING;
166296465Sdelphij    a.key_arg.data = in->key_arg;
16755714Skris
168109998Smarkm#ifndef OPENSSL_NO_KRB5
169296465Sdelphij    if (in->krb5_client_princ_len) {
170296465Sdelphij        a.krb5_princ.length = in->krb5_client_princ_len;
171296465Sdelphij        a.krb5_princ.type = V_ASN1_OCTET_STRING;
172296465Sdelphij        a.krb5_princ.data = in->krb5_client_princ;
173296465Sdelphij    }
174296465Sdelphij#endif                          /* OPENSSL_NO_KRB5 */
17555714Skris
176296465Sdelphij    if (in->time != 0L) {
177296465Sdelphij        a.time.length = LSIZE2;
178296465Sdelphij        a.time.type = V_ASN1_INTEGER;
179296465Sdelphij        a.time.data = ibuf3;
180296465Sdelphij        ASN1_INTEGER_set(&(a.time), in->time);
181296465Sdelphij    }
18255714Skris
183296465Sdelphij    if (in->timeout != 0L) {
184296465Sdelphij        a.timeout.length = LSIZE2;
185296465Sdelphij        a.timeout.type = V_ASN1_INTEGER;
186296465Sdelphij        a.timeout.data = ibuf4;
187296465Sdelphij        ASN1_INTEGER_set(&(a.timeout), in->timeout);
188296465Sdelphij    }
18959191Skris
190296465Sdelphij    if (in->verify_result != X509_V_OK) {
191296465Sdelphij        a.verify_result.length = LSIZE2;
192296465Sdelphij        a.verify_result.type = V_ASN1_INTEGER;
193296465Sdelphij        a.verify_result.data = ibuf5;
194296465Sdelphij        ASN1_INTEGER_set(&a.verify_result, in->verify_result);
195296465Sdelphij    }
196194206Ssimon#ifndef OPENSSL_NO_TLSEXT
197296465Sdelphij    if (in->tlsext_hostname) {
198296465Sdelphij        a.tlsext_hostname.length = strlen(in->tlsext_hostname);
199296465Sdelphij        a.tlsext_hostname.type = V_ASN1_OCTET_STRING;
200296465Sdelphij        a.tlsext_hostname.data = (unsigned char *)in->tlsext_hostname;
201296465Sdelphij    }
202296465Sdelphij    if (in->tlsext_tick) {
203296465Sdelphij        a.tlsext_tick.length = in->tlsext_ticklen;
204296465Sdelphij        a.tlsext_tick.type = V_ASN1_OCTET_STRING;
205296465Sdelphij        a.tlsext_tick.data = (unsigned char *)in->tlsext_tick;
206296465Sdelphij    }
207296465Sdelphij    if (in->tlsext_tick_lifetime_hint > 0) {
208296465Sdelphij        a.tlsext_tick_lifetime.length = LSIZE2;
209296465Sdelphij        a.tlsext_tick_lifetime.type = V_ASN1_INTEGER;
210296465Sdelphij        a.tlsext_tick_lifetime.data = ibuf6;
211296465Sdelphij        ASN1_INTEGER_set(&a.tlsext_tick_lifetime,
212296465Sdelphij                         in->tlsext_tick_lifetime_hint);
213296465Sdelphij    }
214296465Sdelphij#endif                          /* OPENSSL_NO_TLSEXT */
215296465Sdelphij    M_ASN1_I2D_len(&(a.version), i2d_ASN1_INTEGER);
216296465Sdelphij    M_ASN1_I2D_len(&(a.ssl_version), i2d_ASN1_INTEGER);
217296465Sdelphij    M_ASN1_I2D_len(&(a.cipher), i2d_ASN1_OCTET_STRING);
218296465Sdelphij    M_ASN1_I2D_len(&(a.session_id), i2d_ASN1_OCTET_STRING);
219296465Sdelphij    M_ASN1_I2D_len(&(a.master_key), i2d_ASN1_OCTET_STRING);
220109998Smarkm#ifndef OPENSSL_NO_KRB5
221296465Sdelphij    if (in->krb5_client_princ_len)
222296465Sdelphij        M_ASN1_I2D_len(&(a.krb5_princ), i2d_ASN1_OCTET_STRING);
223296465Sdelphij#endif                          /* OPENSSL_NO_KRB5 */
224296465Sdelphij    if (in->key_arg_length > 0)
225296465Sdelphij        M_ASN1_I2D_len_IMP_opt(&(a.key_arg), i2d_ASN1_OCTET_STRING);
226296465Sdelphij    if (in->time != 0L)
227296465Sdelphij        M_ASN1_I2D_len_EXP_opt(&(a.time), i2d_ASN1_INTEGER, 1, v1);
228296465Sdelphij    if (in->timeout != 0L)
229296465Sdelphij        M_ASN1_I2D_len_EXP_opt(&(a.timeout), i2d_ASN1_INTEGER, 2, v2);
230296465Sdelphij    if (in->peer != NULL)
231296465Sdelphij        M_ASN1_I2D_len_EXP_opt(in->peer, i2d_X509, 3, v3);
232296465Sdelphij    M_ASN1_I2D_len_EXP_opt(&a.session_id_context, i2d_ASN1_OCTET_STRING, 4,
233296465Sdelphij                           v4);
234296465Sdelphij    if (in->verify_result != X509_V_OK)
235296465Sdelphij        M_ASN1_I2D_len_EXP_opt(&(a.verify_result), i2d_ASN1_INTEGER, 5, v5);
23655714Skris
237194206Ssimon#ifndef OPENSSL_NO_TLSEXT
238296465Sdelphij    if (in->tlsext_tick_lifetime_hint > 0)
239296465Sdelphij        M_ASN1_I2D_len_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER, 9,
240296465Sdelphij                               v9);
241296465Sdelphij    if (in->tlsext_tick)
242296465Sdelphij        M_ASN1_I2D_len_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING, 10,
243296465Sdelphij                               v10);
244296465Sdelphij    if (in->tlsext_hostname)
245296465Sdelphij        M_ASN1_I2D_len_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING, 6,
246296465Sdelphij                               v6);
247296465Sdelphij# ifndef OPENSSL_NO_COMP
248296465Sdelphij    if (in->compress_meth)
249296465Sdelphij        M_ASN1_I2D_len_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING, 11, v11);
250296465Sdelphij# endif
251296465Sdelphij#endif                          /* OPENSSL_NO_TLSEXT */
252296465Sdelphij    M_ASN1_I2D_seq_total();
25355714Skris
254296465Sdelphij    M_ASN1_I2D_put(&(a.version), i2d_ASN1_INTEGER);
255296465Sdelphij    M_ASN1_I2D_put(&(a.ssl_version), i2d_ASN1_INTEGER);
256296465Sdelphij    M_ASN1_I2D_put(&(a.cipher), i2d_ASN1_OCTET_STRING);
257296465Sdelphij    M_ASN1_I2D_put(&(a.session_id), i2d_ASN1_OCTET_STRING);
258296465Sdelphij    M_ASN1_I2D_put(&(a.master_key), i2d_ASN1_OCTET_STRING);
259109998Smarkm#ifndef OPENSSL_NO_KRB5
260296465Sdelphij    if (in->krb5_client_princ_len)
261296465Sdelphij        M_ASN1_I2D_put(&(a.krb5_princ), i2d_ASN1_OCTET_STRING);
262296465Sdelphij#endif                          /* OPENSSL_NO_KRB5 */
263296465Sdelphij    if (in->key_arg_length > 0)
264296465Sdelphij        M_ASN1_I2D_put_IMP_opt(&(a.key_arg), i2d_ASN1_OCTET_STRING, 0);
265296465Sdelphij    if (in->time != 0L)
266296465Sdelphij        M_ASN1_I2D_put_EXP_opt(&(a.time), i2d_ASN1_INTEGER, 1, v1);
267296465Sdelphij    if (in->timeout != 0L)
268296465Sdelphij        M_ASN1_I2D_put_EXP_opt(&(a.timeout), i2d_ASN1_INTEGER, 2, v2);
269296465Sdelphij    if (in->peer != NULL)
270296465Sdelphij        M_ASN1_I2D_put_EXP_opt(in->peer, i2d_X509, 3, v3);
271296465Sdelphij    M_ASN1_I2D_put_EXP_opt(&a.session_id_context, i2d_ASN1_OCTET_STRING, 4,
272296465Sdelphij                           v4);
273296465Sdelphij    if (in->verify_result != X509_V_OK)
274296465Sdelphij        M_ASN1_I2D_put_EXP_opt(&a.verify_result, i2d_ASN1_INTEGER, 5, v5);
275194206Ssimon#ifndef OPENSSL_NO_TLSEXT
276296465Sdelphij    if (in->tlsext_hostname)
277296465Sdelphij        M_ASN1_I2D_put_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING, 6,
278296465Sdelphij                               v6);
279296465Sdelphij    if (in->tlsext_tick_lifetime_hint > 0)
280296465Sdelphij        M_ASN1_I2D_put_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER, 9,
281296465Sdelphij                               v9);
282296465Sdelphij    if (in->tlsext_tick)
283296465Sdelphij        M_ASN1_I2D_put_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING, 10,
284296465Sdelphij                               v10);
285296465Sdelphij#endif                          /* OPENSSL_NO_TLSEXT */
286205128Ssimon#ifndef OPENSSL_NO_COMP
287296465Sdelphij    if (in->compress_meth)
288296465Sdelphij        M_ASN1_I2D_put_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING, 11, v11);
289205128Ssimon#endif
290296465Sdelphij    M_ASN1_I2D_finish();
291296465Sdelphij}
29255714Skris
293160814SsimonSSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
294296465Sdelphij                             long length)
295296465Sdelphij{
296296465Sdelphij    int ssl_version = 0, i;
297296465Sdelphij    long id;
298296465Sdelphij    ASN1_INTEGER ai, *aip;
299296465Sdelphij    ASN1_OCTET_STRING os, *osp;
300296465Sdelphij    M_ASN1_D2I_vars(a, SSL_SESSION *, SSL_SESSION_new);
30155714Skris
302296465Sdelphij    aip = &ai;
303296465Sdelphij    osp = &os;
30455714Skris
305296465Sdelphij    M_ASN1_D2I_Init();
306296465Sdelphij    M_ASN1_D2I_start_sequence();
30755714Skris
308296465Sdelphij    ai.data = NULL;
309296465Sdelphij    ai.length = 0;
310296465Sdelphij    M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
311296465Sdelphij    if (ai.data != NULL) {
312296465Sdelphij        OPENSSL_free(ai.data);
313296465Sdelphij        ai.data = NULL;
314296465Sdelphij        ai.length = 0;
315296465Sdelphij    }
31655714Skris
317296465Sdelphij    /* we don't care about the version right now :-) */
318296465Sdelphij    M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
319296465Sdelphij    ssl_version = (int)ASN1_INTEGER_get(aip);
320296465Sdelphij    ret->ssl_version = ssl_version;
321296465Sdelphij    if (ai.data != NULL) {
322296465Sdelphij        OPENSSL_free(ai.data);
323296465Sdelphij        ai.data = NULL;
324296465Sdelphij        ai.length = 0;
325296465Sdelphij    }
32655714Skris
327296465Sdelphij    os.data = NULL;
328296465Sdelphij    os.length = 0;
329296465Sdelphij    M_ASN1_D2I_get_x(ASN1_OCTET_STRING, osp, d2i_ASN1_OCTET_STRING);
330296465Sdelphij    if (ssl_version == SSL2_VERSION) {
331296465Sdelphij        if (os.length != 3) {
332296465Sdelphij            c.error = SSL_R_CIPHER_CODE_WRONG_LENGTH;
333296465Sdelphij            goto err;
334296465Sdelphij        }
335296465Sdelphij        id = 0x02000000L |
336296465Sdelphij            ((unsigned long)os.data[0] << 16L) |
337296465Sdelphij            ((unsigned long)os.data[1] << 8L) | (unsigned long)os.data[2];
338296465Sdelphij    } else if ((ssl_version >> 8) >= SSL3_VERSION_MAJOR) {
339296465Sdelphij        if (os.length != 2) {
340296465Sdelphij            c.error = SSL_R_CIPHER_CODE_WRONG_LENGTH;
341296465Sdelphij            goto err;
342296465Sdelphij        }
343296465Sdelphij        id = 0x03000000L |
344296465Sdelphij            ((unsigned long)os.data[0] << 8L) | (unsigned long)os.data[1];
345296465Sdelphij    } else {
346296465Sdelphij        c.error = SSL_R_UNKNOWN_SSL_VERSION;
347296465Sdelphij        goto err;
348296465Sdelphij    }
34955714Skris
350296465Sdelphij    ret->cipher = NULL;
351296465Sdelphij    ret->cipher_id = id;
35255714Skris
353296465Sdelphij    M_ASN1_D2I_get_x(ASN1_OCTET_STRING, osp, d2i_ASN1_OCTET_STRING);
354296465Sdelphij    if ((ssl_version >> 8) >= SSL3_VERSION_MAJOR)
355296465Sdelphij        i = SSL3_MAX_SSL_SESSION_ID_LENGTH;
356296465Sdelphij    else                        /* if (ssl_version>>8 == SSL2_VERSION_MAJOR) */
357296465Sdelphij        i = SSL2_MAX_SSL_SESSION_ID_LENGTH;
35855714Skris
359296465Sdelphij    if (os.length > i)
360296465Sdelphij        os.length = i;
361296465Sdelphij    if (os.length > (int)sizeof(ret->session_id)) /* can't happen */
362296465Sdelphij        os.length = sizeof(ret->session_id);
36355714Skris
364296465Sdelphij    ret->session_id_length = os.length;
365296465Sdelphij    OPENSSL_assert(os.length <= (int)sizeof(ret->session_id));
366296465Sdelphij    memcpy(ret->session_id, os.data, os.length);
36755714Skris
368296465Sdelphij    M_ASN1_D2I_get_x(ASN1_OCTET_STRING, osp, d2i_ASN1_OCTET_STRING);
369296465Sdelphij    if (os.length > SSL_MAX_MASTER_KEY_LENGTH)
370296465Sdelphij        ret->master_key_length = SSL_MAX_MASTER_KEY_LENGTH;
371296465Sdelphij    else
372296465Sdelphij        ret->master_key_length = os.length;
373296465Sdelphij    memcpy(ret->master_key, os.data, ret->master_key_length);
374109998Smarkm
375296465Sdelphij    os.length = 0;
376296465Sdelphij
377109998Smarkm#ifndef OPENSSL_NO_KRB5
378296465Sdelphij    os.length = 0;
379296465Sdelphij    M_ASN1_D2I_get_opt(osp, d2i_ASN1_OCTET_STRING, V_ASN1_OCTET_STRING);
380296465Sdelphij    if (os.data) {
381296465Sdelphij        if (os.length > SSL_MAX_KRB5_PRINCIPAL_LENGTH)
382296465Sdelphij            ret->krb5_client_princ_len = 0;
383296465Sdelphij        else
384296465Sdelphij            ret->krb5_client_princ_len = os.length;
385296465Sdelphij        memcpy(ret->krb5_client_princ, os.data, ret->krb5_client_princ_len);
386296465Sdelphij        OPENSSL_free(os.data);
387296465Sdelphij        os.data = NULL;
388296465Sdelphij        os.length = 0;
389296465Sdelphij    } else
390296465Sdelphij        ret->krb5_client_princ_len = 0;
391296465Sdelphij#endif                          /* OPENSSL_NO_KRB5 */
392109998Smarkm
393296465Sdelphij    M_ASN1_D2I_get_IMP_opt(osp, d2i_ASN1_OCTET_STRING, 0,
394296465Sdelphij                           V_ASN1_OCTET_STRING);
395296465Sdelphij    if (os.length > SSL_MAX_KEY_ARG_LENGTH)
396296465Sdelphij        ret->key_arg_length = SSL_MAX_KEY_ARG_LENGTH;
397296465Sdelphij    else
398296465Sdelphij        ret->key_arg_length = os.length;
399296465Sdelphij    memcpy(ret->key_arg, os.data, ret->key_arg_length);
400296465Sdelphij    if (os.data != NULL)
401296465Sdelphij        OPENSSL_free(os.data);
40255714Skris
403296465Sdelphij    ai.length = 0;
404296465Sdelphij    M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 1);
405296465Sdelphij    if (ai.data != NULL) {
406296465Sdelphij        ret->time = ASN1_INTEGER_get(aip);
407296465Sdelphij        OPENSSL_free(ai.data);
408296465Sdelphij        ai.data = NULL;
409296465Sdelphij        ai.length = 0;
410296465Sdelphij    } else
411296465Sdelphij        ret->time = (unsigned long)time(NULL);
41255714Skris
413296465Sdelphij    ai.length = 0;
414296465Sdelphij    M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 2);
415296465Sdelphij    if (ai.data != NULL) {
416296465Sdelphij        ret->timeout = ASN1_INTEGER_get(aip);
417296465Sdelphij        OPENSSL_free(ai.data);
418296465Sdelphij        ai.data = NULL;
419296465Sdelphij        ai.length = 0;
420296465Sdelphij    } else
421296465Sdelphij        ret->timeout = 3;
42255714Skris
423296465Sdelphij    if (ret->peer != NULL) {
424296465Sdelphij        X509_free(ret->peer);
425296465Sdelphij        ret->peer = NULL;
426296465Sdelphij    }
427296465Sdelphij    M_ASN1_D2I_get_EXP_opt(ret->peer, d2i_X509, 3);
42855714Skris
429296465Sdelphij    os.length = 0;
430296465Sdelphij    os.data = NULL;
431296465Sdelphij    M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 4);
43255714Skris
433296465Sdelphij    if (os.data != NULL) {
434296465Sdelphij        if (os.length > SSL_MAX_SID_CTX_LENGTH) {
435296465Sdelphij            c.error = SSL_R_BAD_LENGTH;
436296465Sdelphij            goto err;
437296465Sdelphij        } else {
438296465Sdelphij            ret->sid_ctx_length = os.length;
439296465Sdelphij            memcpy(ret->sid_ctx, os.data, os.length);
440296465Sdelphij        }
441296465Sdelphij        OPENSSL_free(os.data);
442296465Sdelphij        os.data = NULL;
443296465Sdelphij        os.length = 0;
444296465Sdelphij    } else
445296465Sdelphij        ret->sid_ctx_length = 0;
44655714Skris
447296465Sdelphij    ai.length = 0;
448296465Sdelphij    M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 5);
449296465Sdelphij    if (ai.data != NULL) {
450296465Sdelphij        ret->verify_result = ASN1_INTEGER_get(aip);
451296465Sdelphij        OPENSSL_free(ai.data);
452296465Sdelphij        ai.data = NULL;
453296465Sdelphij        ai.length = 0;
454296465Sdelphij    } else
455296465Sdelphij        ret->verify_result = X509_V_OK;
45659191Skris
457194206Ssimon#ifndef OPENSSL_NO_TLSEXT
458296465Sdelphij    os.length = 0;
459296465Sdelphij    os.data = NULL;
460296465Sdelphij    M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 6);
461296465Sdelphij    if (os.data) {
462296465Sdelphij        ret->tlsext_hostname = BUF_strndup((char *)os.data, os.length);
463296465Sdelphij        OPENSSL_free(os.data);
464296465Sdelphij        os.data = NULL;
465296465Sdelphij        os.length = 0;
466296465Sdelphij    } else
467296465Sdelphij        ret->tlsext_hostname = NULL;
468296465Sdelphij    ai.length = 0;
469296465Sdelphij    M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 9);
470296465Sdelphij    if (ai.data != NULL) {
471296465Sdelphij        ret->tlsext_tick_lifetime_hint = ASN1_INTEGER_get(aip);
472296465Sdelphij        OPENSSL_free(ai.data);
473296465Sdelphij        ai.data = NULL;
474296465Sdelphij        ai.length = 0;
475296465Sdelphij    } else if (ret->tlsext_ticklen && ret->session_id_length)
476296465Sdelphij        ret->tlsext_tick_lifetime_hint = -1;
477296465Sdelphij    else
478296465Sdelphij        ret->tlsext_tick_lifetime_hint = 0;
479296465Sdelphij    os.length = 0;
480296465Sdelphij    os.data = NULL;
481296465Sdelphij    M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 10);
482296465Sdelphij    if (os.data) {
483296465Sdelphij        ret->tlsext_tick = os.data;
484296465Sdelphij        ret->tlsext_ticklen = os.length;
485296465Sdelphij        os.data = NULL;
486296465Sdelphij        os.length = 0;
487296465Sdelphij    } else
488296465Sdelphij        ret->tlsext_tick = NULL;
489296465Sdelphij#endif                          /* OPENSSL_NO_TLSEXT */
490205128Ssimon#ifndef OPENSSL_NO_COMP
491296465Sdelphij    os.length = 0;
492296465Sdelphij    os.data = NULL;
493296465Sdelphij    M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 11);
494296465Sdelphij    if (os.data) {
495296465Sdelphij        ret->compress_meth = os.data[0];
496296465Sdelphij        OPENSSL_free(os.data);
497296465Sdelphij        os.data = NULL;
498296465Sdelphij    }
499205128Ssimon#endif
500194206Ssimon
501296465Sdelphij    M_ASN1_D2I_Finish(a, SSL_SESSION_free, SSL_F_D2I_SSL_SESSION);
502296465Sdelphij}
503