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. 855714Skris * 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). 1555714Skris * 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. 2255714Skris * 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 :-). 3755714Skris * 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)" 4055714Skris * 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. 5255714Skris * 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 */ 58238405Sjkim/* ==================================================================== 59238405Sjkim * Copyright 2005 Nokia. All rights reserved. 60238405Sjkim * 61238405Sjkim * The portions of the attached software ("Contribution") is developed by 62238405Sjkim * Nokia Corporation and is licensed pursuant to the OpenSSL open source 63238405Sjkim * license. 64238405Sjkim * 65238405Sjkim * The Contribution, originally written by Mika Kousa and Pasi Eronen of 66238405Sjkim * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites 67238405Sjkim * support (see RFC 4279) to OpenSSL. 68238405Sjkim * 69238405Sjkim * No patent licenses or other rights except those expressly stated in 70238405Sjkim * the OpenSSL open source license shall be deemed granted or received 71238405Sjkim * expressly, by implication, estoppel, or otherwise. 72238405Sjkim * 73238405Sjkim * No assurances are provided by Nokia that the Contribution does not 74238405Sjkim * infringe the patent or other intellectual property rights of any third 75238405Sjkim * party or that the license provides you with all the necessary rights 76238405Sjkim * to make use of the Contribution. 77238405Sjkim * 78238405Sjkim * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN 79238405Sjkim * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA 80238405Sjkim * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY 81238405Sjkim * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR 82238405Sjkim * OTHERWISE. 83238405Sjkim */ 8455714Skris 8555714Skris#include <stdio.h> 8655714Skris#include <stdlib.h> 87109998Smarkm#include "ssl_locl.h" 8855714Skris#include <openssl/asn1_mac.h> 8955714Skris#include <openssl/objects.h> 9059191Skris#include <openssl/x509.h> 9155714Skris 9255714Skristypedef struct ssl_session_asn1_st 9355714Skris { 9455714Skris ASN1_INTEGER version; 9555714Skris ASN1_INTEGER ssl_version; 9655714Skris ASN1_OCTET_STRING cipher; 97205128Ssimon ASN1_OCTET_STRING comp_id; 9855714Skris ASN1_OCTET_STRING master_key; 9955714Skris ASN1_OCTET_STRING session_id; 10055714Skris ASN1_OCTET_STRING session_id_context; 10155714Skris ASN1_OCTET_STRING key_arg; 102109998Smarkm#ifndef OPENSSL_NO_KRB5 103109998Smarkm ASN1_OCTET_STRING krb5_princ; 104109998Smarkm#endif /* OPENSSL_NO_KRB5 */ 10555714Skris ASN1_INTEGER time; 10655714Skris ASN1_INTEGER timeout; 10759191Skris ASN1_INTEGER verify_result; 108194206Ssimon#ifndef OPENSSL_NO_TLSEXT 109194206Ssimon ASN1_OCTET_STRING tlsext_hostname; 110194206Ssimon ASN1_INTEGER tlsext_tick_lifetime; 111194206Ssimon ASN1_OCTET_STRING tlsext_tick; 112194206Ssimon#endif /* OPENSSL_NO_TLSEXT */ 113238405Sjkim#ifndef OPENSSL_NO_PSK 114238405Sjkim ASN1_OCTET_STRING psk_identity_hint; 115238405Sjkim ASN1_OCTET_STRING psk_identity; 116238405Sjkim#endif /* OPENSSL_NO_PSK */ 117238405Sjkim#ifndef OPENSSL_NO_SRP 118238405Sjkim ASN1_OCTET_STRING srp_username; 119238405Sjkim#endif /* OPENSSL_NO_SRP */ 12055714Skris } SSL_SESSION_ASN1; 12155714Skris 12255714Skrisint i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) 12355714Skris { 12455714Skris#define LSIZE2 (sizeof(long)*2) 125238405Sjkim int v1=0,v2=0,v3=0,v4=0,v5=0,v7=0,v8=0; 12655714Skris unsigned char buf[4],ibuf1[LSIZE2],ibuf2[LSIZE2]; 12759191Skris unsigned char ibuf3[LSIZE2],ibuf4[LSIZE2],ibuf5[LSIZE2]; 128194206Ssimon#ifndef OPENSSL_NO_TLSEXT 129194206Ssimon int v6=0,v9=0,v10=0; 130194206Ssimon unsigned char ibuf6[LSIZE2]; 131194206Ssimon#endif 132205128Ssimon#ifndef OPENSSL_NO_COMP 133238405Sjkim unsigned char cbuf; 134205128Ssimon int v11=0; 135205128Ssimon#endif 136238405Sjkim#ifndef OPENSSL_NO_SRP 137238405Sjkim int v12=0; 138238405Sjkim#endif 13955714Skris long l; 14055714Skris SSL_SESSION_ASN1 a; 14155714Skris M_ASN1_I2D_vars(in); 14255714Skris 14355714Skris if ((in == NULL) || ((in->cipher == NULL) && (in->cipher_id == 0))) 14455714Skris return(0); 14555714Skris 14655714Skris /* Note that I cheat in the following 2 assignments. I know 14759191Skris * that if the ASN1_INTEGER passed to ASN1_INTEGER_set 14868651Skris * is > sizeof(long)+1, the buffer will not be re-OPENSSL_malloc()ed. 14955714Skris * This is a bit evil but makes things simple, no dynamic allocation 15055714Skris * to clean up :-) */ 15155714Skris a.version.length=LSIZE2; 15255714Skris a.version.type=V_ASN1_INTEGER; 15355714Skris a.version.data=ibuf1; 15455714Skris ASN1_INTEGER_set(&(a.version),SSL_SESSION_ASN1_VERSION); 15555714Skris 15655714Skris a.ssl_version.length=LSIZE2; 15755714Skris a.ssl_version.type=V_ASN1_INTEGER; 15855714Skris a.ssl_version.data=ibuf2; 15955714Skris ASN1_INTEGER_set(&(a.ssl_version),in->ssl_version); 16055714Skris 16155714Skris a.cipher.type=V_ASN1_OCTET_STRING; 16255714Skris a.cipher.data=buf; 16355714Skris 16455714Skris if (in->cipher == NULL) 16555714Skris l=in->cipher_id; 16655714Skris else 16755714Skris l=in->cipher->id; 16855714Skris if (in->ssl_version == SSL2_VERSION) 16955714Skris { 17055714Skris a.cipher.length=3; 17155714Skris buf[0]=((unsigned char)(l>>16L))&0xff; 17255714Skris buf[1]=((unsigned char)(l>> 8L))&0xff; 17355714Skris buf[2]=((unsigned char)(l ))&0xff; 17455714Skris } 17555714Skris else 17655714Skris { 17755714Skris a.cipher.length=2; 17855714Skris buf[0]=((unsigned char)(l>>8L))&0xff; 17955714Skris buf[1]=((unsigned char)(l ))&0xff; 18055714Skris } 18155714Skris 182205128Ssimon#ifndef OPENSSL_NO_COMP 183205128Ssimon if (in->compress_meth) 184205128Ssimon { 185205128Ssimon cbuf = (unsigned char)in->compress_meth; 186205128Ssimon a.comp_id.length = 1; 187205128Ssimon a.comp_id.type = V_ASN1_OCTET_STRING; 188205128Ssimon a.comp_id.data = &cbuf; 189205128Ssimon } 190205128Ssimon#endif 191205128Ssimon 19255714Skris a.master_key.length=in->master_key_length; 19355714Skris a.master_key.type=V_ASN1_OCTET_STRING; 19455714Skris a.master_key.data=in->master_key; 19555714Skris 19655714Skris a.session_id.length=in->session_id_length; 19755714Skris a.session_id.type=V_ASN1_OCTET_STRING; 19855714Skris a.session_id.data=in->session_id; 19955714Skris 20055714Skris a.session_id_context.length=in->sid_ctx_length; 20155714Skris a.session_id_context.type=V_ASN1_OCTET_STRING; 20255714Skris a.session_id_context.data=in->sid_ctx; 20355714Skris 20455714Skris a.key_arg.length=in->key_arg_length; 20555714Skris a.key_arg.type=V_ASN1_OCTET_STRING; 20655714Skris a.key_arg.data=in->key_arg; 20755714Skris 208109998Smarkm#ifndef OPENSSL_NO_KRB5 209109998Smarkm if (in->krb5_client_princ_len) 210109998Smarkm { 211109998Smarkm a.krb5_princ.length=in->krb5_client_princ_len; 212109998Smarkm a.krb5_princ.type=V_ASN1_OCTET_STRING; 213109998Smarkm a.krb5_princ.data=in->krb5_client_princ; 214109998Smarkm } 215109998Smarkm#endif /* OPENSSL_NO_KRB5 */ 216238405Sjkim 21755714Skris if (in->time != 0L) 21855714Skris { 21955714Skris a.time.length=LSIZE2; 22055714Skris a.time.type=V_ASN1_INTEGER; 22155714Skris a.time.data=ibuf3; 22255714Skris ASN1_INTEGER_set(&(a.time),in->time); 22355714Skris } 22455714Skris 22555714Skris if (in->timeout != 0L) 22655714Skris { 22755714Skris a.timeout.length=LSIZE2; 22855714Skris a.timeout.type=V_ASN1_INTEGER; 22955714Skris a.timeout.data=ibuf4; 23055714Skris ASN1_INTEGER_set(&(a.timeout),in->timeout); 23155714Skris } 23255714Skris 23359191Skris if (in->verify_result != X509_V_OK) 23459191Skris { 23559191Skris a.verify_result.length=LSIZE2; 23659191Skris a.verify_result.type=V_ASN1_INTEGER; 23759191Skris a.verify_result.data=ibuf5; 23859191Skris ASN1_INTEGER_set(&a.verify_result,in->verify_result); 23959191Skris } 24059191Skris 241194206Ssimon#ifndef OPENSSL_NO_TLSEXT 242194206Ssimon if (in->tlsext_hostname) 243194206Ssimon { 244194206Ssimon a.tlsext_hostname.length=strlen(in->tlsext_hostname); 245194206Ssimon a.tlsext_hostname.type=V_ASN1_OCTET_STRING; 246194206Ssimon a.tlsext_hostname.data=(unsigned char *)in->tlsext_hostname; 247194206Ssimon } 248194206Ssimon if (in->tlsext_tick) 249194206Ssimon { 250194206Ssimon a.tlsext_tick.length= in->tlsext_ticklen; 251194206Ssimon a.tlsext_tick.type=V_ASN1_OCTET_STRING; 252194206Ssimon a.tlsext_tick.data=(unsigned char *)in->tlsext_tick; 253194206Ssimon } 254194206Ssimon if (in->tlsext_tick_lifetime_hint > 0) 255194206Ssimon { 256194206Ssimon a.tlsext_tick_lifetime.length=LSIZE2; 257194206Ssimon a.tlsext_tick_lifetime.type=V_ASN1_INTEGER; 258194206Ssimon a.tlsext_tick_lifetime.data=ibuf6; 259194206Ssimon ASN1_INTEGER_set(&a.tlsext_tick_lifetime,in->tlsext_tick_lifetime_hint); 260194206Ssimon } 261194206Ssimon#endif /* OPENSSL_NO_TLSEXT */ 262238405Sjkim#ifndef OPENSSL_NO_PSK 263238405Sjkim if (in->psk_identity_hint) 264238405Sjkim { 265238405Sjkim a.psk_identity_hint.length=strlen(in->psk_identity_hint); 266238405Sjkim a.psk_identity_hint.type=V_ASN1_OCTET_STRING; 267238405Sjkim a.psk_identity_hint.data=(unsigned char *)(in->psk_identity_hint); 268238405Sjkim } 269238405Sjkim if (in->psk_identity) 270238405Sjkim { 271238405Sjkim a.psk_identity.length=strlen(in->psk_identity); 272238405Sjkim a.psk_identity.type=V_ASN1_OCTET_STRING; 273238405Sjkim a.psk_identity.data=(unsigned char *)(in->psk_identity); 274238405Sjkim } 275238405Sjkim#endif /* OPENSSL_NO_PSK */ 276238405Sjkim#ifndef OPENSSL_NO_SRP 277238405Sjkim if (in->srp_username) 278238405Sjkim { 279238405Sjkim a.srp_username.length=strlen(in->srp_username); 280238405Sjkim a.srp_username.type=V_ASN1_OCTET_STRING; 281238405Sjkim a.srp_username.data=(unsigned char *)(in->srp_username); 282238405Sjkim } 283238405Sjkim#endif /* OPENSSL_NO_SRP */ 284238405Sjkim 28555714Skris M_ASN1_I2D_len(&(a.version), i2d_ASN1_INTEGER); 28655714Skris M_ASN1_I2D_len(&(a.ssl_version), i2d_ASN1_INTEGER); 28755714Skris M_ASN1_I2D_len(&(a.cipher), i2d_ASN1_OCTET_STRING); 28855714Skris M_ASN1_I2D_len(&(a.session_id), i2d_ASN1_OCTET_STRING); 28955714Skris M_ASN1_I2D_len(&(a.master_key), i2d_ASN1_OCTET_STRING); 290109998Smarkm#ifndef OPENSSL_NO_KRB5 291109998Smarkm if (in->krb5_client_princ_len) 292109998Smarkm M_ASN1_I2D_len(&(a.krb5_princ), i2d_ASN1_OCTET_STRING); 293109998Smarkm#endif /* OPENSSL_NO_KRB5 */ 29455714Skris if (in->key_arg_length > 0) 29555714Skris M_ASN1_I2D_len_IMP_opt(&(a.key_arg),i2d_ASN1_OCTET_STRING); 29655714Skris if (in->time != 0L) 29755714Skris M_ASN1_I2D_len_EXP_opt(&(a.time),i2d_ASN1_INTEGER,1,v1); 29855714Skris if (in->timeout != 0L) 29955714Skris M_ASN1_I2D_len_EXP_opt(&(a.timeout),i2d_ASN1_INTEGER,2,v2); 30055714Skris if (in->peer != NULL) 30155714Skris M_ASN1_I2D_len_EXP_opt(in->peer,i2d_X509,3,v3); 30255714Skris M_ASN1_I2D_len_EXP_opt(&a.session_id_context,i2d_ASN1_OCTET_STRING,4,v4); 30359191Skris if (in->verify_result != X509_V_OK) 30459191Skris M_ASN1_I2D_len_EXP_opt(&(a.verify_result),i2d_ASN1_INTEGER,5,v5); 30555714Skris 306194206Ssimon#ifndef OPENSSL_NO_TLSEXT 307194206Ssimon if (in->tlsext_tick_lifetime_hint > 0) 308194206Ssimon M_ASN1_I2D_len_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER,9,v9); 309194206Ssimon if (in->tlsext_tick) 310194206Ssimon M_ASN1_I2D_len_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING,10,v10); 311194206Ssimon if (in->tlsext_hostname) 312194206Ssimon M_ASN1_I2D_len_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING,6,v6); 313205128Ssimon#ifndef OPENSSL_NO_COMP 314205128Ssimon if (in->compress_meth) 315205128Ssimon M_ASN1_I2D_len_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING,11,v11); 316205128Ssimon#endif 317194206Ssimon#endif /* OPENSSL_NO_TLSEXT */ 318238405Sjkim#ifndef OPENSSL_NO_PSK 319238405Sjkim if (in->psk_identity_hint) 320238405Sjkim M_ASN1_I2D_len_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING,7,v7); 321238405Sjkim if (in->psk_identity) 322238405Sjkim M_ASN1_I2D_len_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING,8,v8); 323238405Sjkim#endif /* OPENSSL_NO_PSK */ 324238405Sjkim#ifndef OPENSSL_NO_SRP 325238405Sjkim if (in->srp_username) 326238405Sjkim M_ASN1_I2D_len_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING,12,v12); 327238405Sjkim#endif /* OPENSSL_NO_SRP */ 328238405Sjkim 32955714Skris M_ASN1_I2D_seq_total(); 33055714Skris 33155714Skris M_ASN1_I2D_put(&(a.version), i2d_ASN1_INTEGER); 33255714Skris M_ASN1_I2D_put(&(a.ssl_version), i2d_ASN1_INTEGER); 33355714Skris M_ASN1_I2D_put(&(a.cipher), i2d_ASN1_OCTET_STRING); 33455714Skris M_ASN1_I2D_put(&(a.session_id), i2d_ASN1_OCTET_STRING); 33555714Skris M_ASN1_I2D_put(&(a.master_key), i2d_ASN1_OCTET_STRING); 336109998Smarkm#ifndef OPENSSL_NO_KRB5 337109998Smarkm if (in->krb5_client_princ_len) 338109998Smarkm M_ASN1_I2D_put(&(a.krb5_princ), i2d_ASN1_OCTET_STRING); 339109998Smarkm#endif /* OPENSSL_NO_KRB5 */ 34055714Skris if (in->key_arg_length > 0) 34155714Skris M_ASN1_I2D_put_IMP_opt(&(a.key_arg),i2d_ASN1_OCTET_STRING,0); 34255714Skris if (in->time != 0L) 34355714Skris M_ASN1_I2D_put_EXP_opt(&(a.time),i2d_ASN1_INTEGER,1,v1); 34455714Skris if (in->timeout != 0L) 34555714Skris M_ASN1_I2D_put_EXP_opt(&(a.timeout),i2d_ASN1_INTEGER,2,v2); 34655714Skris if (in->peer != NULL) 34755714Skris M_ASN1_I2D_put_EXP_opt(in->peer,i2d_X509,3,v3); 34855714Skris M_ASN1_I2D_put_EXP_opt(&a.session_id_context,i2d_ASN1_OCTET_STRING,4, 34955714Skris v4); 35059191Skris if (in->verify_result != X509_V_OK) 35159191Skris M_ASN1_I2D_put_EXP_opt(&a.verify_result,i2d_ASN1_INTEGER,5,v5); 352194206Ssimon#ifndef OPENSSL_NO_TLSEXT 353194206Ssimon if (in->tlsext_hostname) 354194206Ssimon M_ASN1_I2D_put_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING,6,v6); 355238405Sjkim#endif /* OPENSSL_NO_TLSEXT */ 356238405Sjkim#ifndef OPENSSL_NO_PSK 357238405Sjkim if (in->psk_identity_hint) 358238405Sjkim M_ASN1_I2D_put_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING,7,v7); 359238405Sjkim if (in->psk_identity) 360238405Sjkim M_ASN1_I2D_put_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING,8,v8); 361238405Sjkim#endif /* OPENSSL_NO_PSK */ 362238405Sjkim#ifndef OPENSSL_NO_TLSEXT 363194206Ssimon if (in->tlsext_tick_lifetime_hint > 0) 364194206Ssimon M_ASN1_I2D_put_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER,9,v9); 365194206Ssimon if (in->tlsext_tick) 366194206Ssimon M_ASN1_I2D_put_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING,10,v10); 367194206Ssimon#endif /* OPENSSL_NO_TLSEXT */ 368205128Ssimon#ifndef OPENSSL_NO_COMP 369205128Ssimon if (in->compress_meth) 370205128Ssimon M_ASN1_I2D_put_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING,11,v11); 371205128Ssimon#endif 372238405Sjkim#ifndef OPENSSL_NO_SRP 373238405Sjkim if (in->srp_username) 374238405Sjkim M_ASN1_I2D_put_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING,12,v12); 375238405Sjkim#endif /* OPENSSL_NO_SRP */ 37655714Skris M_ASN1_I2D_finish(); 37755714Skris } 37855714Skris 379160814SsimonSSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, 380238405Sjkim long length) 38155714Skris { 382215697Ssimon int ssl_version=0,i; 38355714Skris long id; 38455714Skris ASN1_INTEGER ai,*aip; 38555714Skris ASN1_OCTET_STRING os,*osp; 38655714Skris M_ASN1_D2I_vars(a,SSL_SESSION *,SSL_SESSION_new); 38755714Skris 38855714Skris aip= &ai; 38955714Skris osp= &os; 39055714Skris 39155714Skris M_ASN1_D2I_Init(); 39255714Skris M_ASN1_D2I_start_sequence(); 39355714Skris 39455714Skris ai.data=NULL; ai.length=0; 395160814Ssimon M_ASN1_D2I_get_x(ASN1_INTEGER,aip,d2i_ASN1_INTEGER); 39668651Skris if (ai.data != NULL) { OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; } 39755714Skris 39855714Skris /* we don't care about the version right now :-) */ 399160814Ssimon M_ASN1_D2I_get_x(ASN1_INTEGER,aip,d2i_ASN1_INTEGER); 40055714Skris ssl_version=(int)ASN1_INTEGER_get(aip); 40155714Skris ret->ssl_version=ssl_version; 40268651Skris if (ai.data != NULL) { OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; } 40355714Skris 40455714Skris os.data=NULL; os.length=0; 405160814Ssimon M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING); 40655714Skris if (ssl_version == SSL2_VERSION) 40755714Skris { 40855714Skris if (os.length != 3) 40955714Skris { 41055714Skris c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH; 411279264Sdelphij c.line=__LINE__; 41255714Skris goto err; 41355714Skris } 41455714Skris id=0x02000000L| 41555714Skris ((unsigned long)os.data[0]<<16L)| 41655714Skris ((unsigned long)os.data[1]<< 8L)| 41755714Skris (unsigned long)os.data[2]; 41855714Skris } 419205128Ssimon else if ((ssl_version>>8) >= SSL3_VERSION_MAJOR) 42055714Skris { 42155714Skris if (os.length != 2) 42255714Skris { 42355714Skris c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH; 424279264Sdelphij c.line=__LINE__; 42555714Skris goto err; 42655714Skris } 42755714Skris id=0x03000000L| 42855714Skris ((unsigned long)os.data[0]<<8L)| 42955714Skris (unsigned long)os.data[1]; 43055714Skris } 43155714Skris else 43255714Skris { 433205128Ssimon c.error=SSL_R_UNKNOWN_SSL_VERSION; 434279264Sdelphij c.line=__LINE__; 435205128Ssimon goto err; 43655714Skris } 43755714Skris 43855714Skris ret->cipher=NULL; 43955714Skris ret->cipher_id=id; 44055714Skris 441160814Ssimon M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING); 442205128Ssimon if ((ssl_version>>8) >= SSL3_VERSION_MAJOR) 44355714Skris i=SSL3_MAX_SSL_SESSION_ID_LENGTH; 444160814Ssimon else /* if (ssl_version>>8 == SSL2_VERSION_MAJOR) */ 44555714Skris i=SSL2_MAX_SSL_SESSION_ID_LENGTH; 44655714Skris 44755714Skris if (os.length > i) 448101615Snectar os.length = i; 449160814Ssimon if (os.length > (int)sizeof(ret->session_id)) /* can't happen */ 450160814Ssimon os.length = sizeof(ret->session_id); 45155714Skris 45255714Skris ret->session_id_length=os.length; 453160814Ssimon OPENSSL_assert(os.length <= (int)sizeof(ret->session_id)); 45455714Skris memcpy(ret->session_id,os.data,os.length); 45555714Skris 456160814Ssimon M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING); 457194206Ssimon if (os.length > SSL_MAX_MASTER_KEY_LENGTH) 45855714Skris ret->master_key_length=SSL_MAX_MASTER_KEY_LENGTH; 45955714Skris else 46055714Skris ret->master_key_length=os.length; 46155714Skris memcpy(ret->master_key,os.data,ret->master_key_length); 46255714Skris 46355714Skris os.length=0; 464109998Smarkm 465109998Smarkm#ifndef OPENSSL_NO_KRB5 466109998Smarkm os.length=0; 467109998Smarkm M_ASN1_D2I_get_opt(osp,d2i_ASN1_OCTET_STRING,V_ASN1_OCTET_STRING); 468109998Smarkm if (os.data) 469109998Smarkm { 470109998Smarkm if (os.length > SSL_MAX_KRB5_PRINCIPAL_LENGTH) 471109998Smarkm ret->krb5_client_princ_len=0; 472109998Smarkm else 473109998Smarkm ret->krb5_client_princ_len=os.length; 474109998Smarkm memcpy(ret->krb5_client_princ,os.data,ret->krb5_client_princ_len); 475109998Smarkm OPENSSL_free(os.data); 476109998Smarkm os.data = NULL; 477109998Smarkm os.length = 0; 478109998Smarkm } 479109998Smarkm else 480109998Smarkm ret->krb5_client_princ_len=0; 481109998Smarkm#endif /* OPENSSL_NO_KRB5 */ 482109998Smarkm 48355714Skris M_ASN1_D2I_get_IMP_opt(osp,d2i_ASN1_OCTET_STRING,0,V_ASN1_OCTET_STRING); 48455714Skris if (os.length > SSL_MAX_KEY_ARG_LENGTH) 48555714Skris ret->key_arg_length=SSL_MAX_KEY_ARG_LENGTH; 48655714Skris else 48755714Skris ret->key_arg_length=os.length; 48855714Skris memcpy(ret->key_arg,os.data,ret->key_arg_length); 48968651Skris if (os.data != NULL) OPENSSL_free(os.data); 49055714Skris 49155714Skris ai.length=0; 49255714Skris M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,1); 49355714Skris if (ai.data != NULL) 49455714Skris { 49555714Skris ret->time=ASN1_INTEGER_get(aip); 49668651Skris OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; 49755714Skris } 49855714Skris else 499160814Ssimon ret->time=(unsigned long)time(NULL); 50055714Skris 50155714Skris ai.length=0; 50255714Skris M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,2); 50355714Skris if (ai.data != NULL) 50455714Skris { 50555714Skris ret->timeout=ASN1_INTEGER_get(aip); 50668651Skris OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; 50755714Skris } 50855714Skris else 50955714Skris ret->timeout=3; 51055714Skris 51155714Skris if (ret->peer != NULL) 51255714Skris { 51355714Skris X509_free(ret->peer); 51455714Skris ret->peer=NULL; 51555714Skris } 51655714Skris M_ASN1_D2I_get_EXP_opt(ret->peer,d2i_X509,3); 51755714Skris 51855714Skris os.length=0; 51955714Skris os.data=NULL; 52055714Skris M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,4); 52155714Skris 52255714Skris if(os.data != NULL) 52355714Skris { 52455714Skris if (os.length > SSL_MAX_SID_CTX_LENGTH) 525109998Smarkm { 526205128Ssimon c.error=SSL_R_BAD_LENGTH; 527279264Sdelphij c.line=__LINE__; 528205128Ssimon goto err; 529109998Smarkm } 530109998Smarkm else 531109998Smarkm { 532109998Smarkm ret->sid_ctx_length=os.length; 533109998Smarkm memcpy(ret->sid_ctx,os.data,os.length); 534109998Smarkm } 53568651Skris OPENSSL_free(os.data); os.data=NULL; os.length=0; 53655714Skris } 53755714Skris else 53855714Skris ret->sid_ctx_length=0; 53955714Skris 54059191Skris ai.length=0; 54159191Skris M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,5); 54259191Skris if (ai.data != NULL) 54359191Skris { 54459191Skris ret->verify_result=ASN1_INTEGER_get(aip); 54568651Skris OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; 54659191Skris } 54759191Skris else 54859191Skris ret->verify_result=X509_V_OK; 54959191Skris 550194206Ssimon#ifndef OPENSSL_NO_TLSEXT 551194206Ssimon os.length=0; 552194206Ssimon os.data=NULL; 553194206Ssimon M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,6); 554194206Ssimon if (os.data) 555194206Ssimon { 556194206Ssimon ret->tlsext_hostname = BUF_strndup((char *)os.data, os.length); 557194206Ssimon OPENSSL_free(os.data); 558194206Ssimon os.data = NULL; 559194206Ssimon os.length = 0; 560194206Ssimon } 561194206Ssimon else 562194206Ssimon ret->tlsext_hostname=NULL; 563238405Sjkim#endif /* OPENSSL_NO_TLSEXT */ 564238405Sjkim 565238405Sjkim#ifndef OPENSSL_NO_PSK 566238405Sjkim os.length=0; 567238405Sjkim os.data=NULL; 568238405Sjkim M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,7); 569238405Sjkim if (os.data) 570238405Sjkim { 571238405Sjkim ret->psk_identity_hint = BUF_strndup((char *)os.data, os.length); 572238405Sjkim OPENSSL_free(os.data); 573238405Sjkim os.data = NULL; 574238405Sjkim os.length = 0; 575238405Sjkim } 576238405Sjkim else 577238405Sjkim ret->psk_identity_hint=NULL; 578238405Sjkim 579238405Sjkim os.length=0; 580238405Sjkim os.data=NULL; 581238405Sjkim M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,8); 582238405Sjkim if (os.data) 583238405Sjkim { 584238405Sjkim ret->psk_identity = BUF_strndup((char *)os.data, os.length); 585238405Sjkim OPENSSL_free(os.data); 586238405Sjkim os.data = NULL; 587238405Sjkim os.length = 0; 588238405Sjkim } 589238405Sjkim else 590238405Sjkim ret->psk_identity=NULL; 591238405Sjkim#endif /* OPENSSL_NO_PSK */ 592238405Sjkim 593238405Sjkim#ifndef OPENSSL_NO_TLSEXT 594194206Ssimon ai.length=0; 595194206Ssimon M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,9); 596194206Ssimon if (ai.data != NULL) 597194206Ssimon { 598194206Ssimon ret->tlsext_tick_lifetime_hint=ASN1_INTEGER_get(aip); 599194206Ssimon OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; 600194206Ssimon } 601194206Ssimon else if (ret->tlsext_ticklen && ret->session_id_length) 602194206Ssimon ret->tlsext_tick_lifetime_hint = -1; 603194206Ssimon else 604238405Sjkim ret->tlsext_tick_lifetime_hint=0; 605238405Sjkim os.length=0; 606238405Sjkim os.data=NULL; 607238405Sjkim M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,10); 608238405Sjkim if (os.data) 609238405Sjkim { 610194206Ssimon ret->tlsext_tick = os.data; 611194206Ssimon ret->tlsext_ticklen = os.length; 612238405Sjkim os.data = NULL; 613238405Sjkim os.length = 0; 614238405Sjkim } 615194206Ssimon else 616194206Ssimon ret->tlsext_tick=NULL; 617194206Ssimon#endif /* OPENSSL_NO_TLSEXT */ 618205128Ssimon#ifndef OPENSSL_NO_COMP 619205128Ssimon os.length=0; 620205128Ssimon os.data=NULL; 621205128Ssimon M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,11); 622205128Ssimon if (os.data) 623205128Ssimon { 624205128Ssimon ret->compress_meth = os.data[0]; 625205128Ssimon OPENSSL_free(os.data); 626205128Ssimon os.data = NULL; 627205128Ssimon } 628205128Ssimon#endif 629194206Ssimon 630238405Sjkim#ifndef OPENSSL_NO_SRP 631238405Sjkim os.length=0; 632238405Sjkim os.data=NULL; 633238405Sjkim M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,12); 634238405Sjkim if (os.data) 635238405Sjkim { 636238405Sjkim ret->srp_username = BUF_strndup((char *)os.data, os.length); 637238405Sjkim OPENSSL_free(os.data); 638238405Sjkim os.data = NULL; 639238405Sjkim os.length = 0; 640238405Sjkim } 641238405Sjkim else 642238405Sjkim ret->srp_username=NULL; 643238405Sjkim#endif /* OPENSSL_NO_SRP */ 644238405Sjkim 64555714Skris M_ASN1_D2I_Finish(a,SSL_SESSION_free,SSL_F_D2I_SSL_SESSION); 64655714Skris } 647