1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59: #include <stdio.h>
60: #include <stdlib.h>
61: #include "ssl_locl.h"
62: #include <openssl/asn1_mac.h>
63: #include <openssl/objects.h>
64: #include <openssl/x509.h>
65:
66: typedef struct ssl_session_asn1_st
67: {
68: ASN1_INTEGER version;
69: ASN1_INTEGER ssl_version;
70: ASN1_OCTET_STRING cipher;
71: ASN1_OCTET_STRING master_key;
72: ASN1_OCTET_STRING session_id;
73: ASN1_OCTET_STRING session_id_context;
74: ASN1_OCTET_STRING key_arg;
75: #ifndef OPENSSL_NO_KRB5
76: ASN1_OCTET_STRING krb5_princ;
77: #endif
78: ASN1_INTEGER time;
79: ASN1_INTEGER timeout;
80: ASN1_INTEGER verify_result;
81: #ifndef OPENSSL_NO_TLSEXT
82: ASN1_OCTET_STRING tlsext_hostname;
83: ASN1_INTEGER tlsext_tick_lifetime;
84: ASN1_OCTET_STRING tlsext_tick;
85: #endif
86: } SSL_SESSION_ASN1;
87:
88: int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
89: {
90: #define LSIZE2 (sizeof(long)*2)
91: int v1=0,v2=0,v3=0,v4=0,v5=0;
92: unsigned char buf[4],ibuf1[LSIZE2],ibuf2[LSIZE2];
93: unsigned char ibuf3[LSIZE2],ibuf4[LSIZE2],ibuf5[LSIZE2];
94: #ifndef OPENSSL_NO_TLSEXT
95: int v6=0,v9=0,v10=0;
96: unsigned char ibuf6[LSIZE2];
97: #endif
98: long l;
99: SSL_SESSION_ASN1 a;
100: M_ASN1_I2D_vars(in);
101:
102: if ((in == NULL) || ((in->cipher == NULL) && (in->cipher_id == 0)))
103: return(0);
104:
105:
106:
107:
108:
109:
110: a.version.length=LSIZE2;
111: a.version.type=V_ASN1_INTEGER;
112: a.version.data=ibuf1;
113: ASN1_INTEGER_set(&(a.version),SSL_SESSION_ASN1_VERSION);
114:
115: a.ssl_version.length=LSIZE2;
116: a.ssl_version.type=V_ASN1_INTEGER;
117: a.ssl_version.data=ibuf2;
118: ASN1_INTEGER_set(&(a.ssl_version),in->ssl_version);
119:
120: a.cipher.type=V_ASN1_OCTET_STRING;
121: a.cipher.data=buf;
122:
123: if (in->cipher == NULL)
124: l=in->cipher_id;
125: else
126: l=in->cipher->id;
127: if (in->ssl_version == SSL2_VERSION)
128: {
129: a.cipher.length=3;
130: buf[0]=((unsigned char)(l>>16L))&0xff;
131: buf[1]=((unsigned char)(l>> 8L))&0xff;
132: buf[2]=((unsigned char)(l ))&0xff;
133: }
134: else
135: {
136: a.cipher.length=2;
137: buf[0]=((unsigned char)(l>>8L))&0xff;
138: buf[1]=((unsigned char)(l ))&0xff;
139: }
140:
141: a.master_key.length=in->master_key_length;
142: a.master_key.type=V_ASN1_OCTET_STRING;
143: a.master_key.data=in->master_key;
144:
145: a.session_id.length=in->session_id_length;
146: a.session_id.type=V_ASN1_OCTET_STRING;
147: a.session_id.data=in->session_id;
148:
149: a.session_id_context.length=in->sid_ctx_length;
150: a.session_id_context.type=V_ASN1_OCTET_STRING;
151: a.session_id_context.data=in->sid_ctx;
152:
153: a.key_arg.length=in->key_arg_length;
154: a.key_arg.type=V_ASN1_OCTET_STRING;
155: a.key_arg.data=in->key_arg;
156:
157: #ifndef OPENSSL_NO_KRB5
158: if (in->krb5_client_princ_len)
159: {
160: a.krb5_princ.length=in->krb5_client_princ_len;
161: a.krb5_princ.type=V_ASN1_OCTET_STRING;
162: a.krb5_princ.data=in->krb5_client_princ;
163: }
164: #endif
165:
166: if (in->time != 0L)
167: {
168: a.time.length=LSIZE2;
169: a.time.type=V_ASN1_INTEGER;
170: a.time.data=ibuf3;
171: ASN1_INTEGER_set(&(a.time),in->time);
172: }
173:
174: if (in->timeout != 0L)
175: {
176: a.timeout.length=LSIZE2;
177: a.timeout.type=V_ASN1_INTEGER;
178: a.timeout.data=ibuf4;
179: ASN1_INTEGER_set(&(a.timeout),in->timeout);
180: }
181:
182: if (in->verify_result != X509_V_OK)
183: {
184: a.verify_result.length=LSIZE2;
185: a.verify_result.type=V_ASN1_INTEGER;
186: a.verify_result.data=ibuf5;
187: ASN1_INTEGER_set(&a.verify_result,in->verify_result);
188: }
189:
190: #ifndef OPENSSL_NO_TLSEXT
191: if (in->tlsext_hostname)
192: {
193: a.tlsext_hostname.length=strlen(in->tlsext_hostname);
194: a.tlsext_hostname.type=V_ASN1_OCTET_STRING;
195: a.tlsext_hostname.data=(unsigned char *)in->tlsext_hostname;
196: }
197: if (in->tlsext_tick)
198: {
199: a.tlsext_tick.length= in->tlsext_ticklen;
200: a.tlsext_tick.type=V_ASN1_OCTET_STRING;
201: a.tlsext_tick.data=(unsigned char *)in->tlsext_tick;
202:
203:
204:
205: if (in->tlsext_ticklen)
206: a.session_id.length=0;
207: }
208: if (in->tlsext_tick_lifetime_hint != 0)
209: {
210: a.tlsext_tick_lifetime.length=LSIZE2;
211: a.tlsext_tick_lifetime.type=V_ASN1_INTEGER;
212: a.tlsext_tick_lifetime.data=ibuf6;
213: ASN1_INTEGER_set(&a.tlsext_tick_lifetime,in->tlsext_tick_lifetime_hint);
214: }
215: #endif
216: M_ASN1_I2D_len(&(a.version), i2d_ASN1_INTEGER);
217: M_ASN1_I2D_len(&(a.ssl_version), i2d_ASN1_INTEGER);
218: M_ASN1_I2D_len(&(a.cipher), i2d_ASN1_OCTET_STRING);
219: M_ASN1_I2D_len(&(a.session_id), i2d_ASN1_OCTET_STRING);
220: M_ASN1_I2D_len(&(a.master_key), i2d_ASN1_OCTET_STRING);
221: #ifndef OPENSSL_NO_KRB5
222: if (in->krb5_client_princ_len)
223: M_ASN1_I2D_len(&(a.krb5_princ), i2d_ASN1_OCTET_STRING);
224: #endif
225: if (in->key_arg_length > 0)
226: M_ASN1_I2D_len_IMP_opt(&(a.key_arg),i2d_ASN1_OCTET_STRING);
227: if (in->time != 0L)
228: M_ASN1_I2D_len_EXP_opt(&(a.time),i2d_ASN1_INTEGER,1,v1);
229: if (in->timeout != 0L)
230: M_ASN1_I2D_len_EXP_opt(&(a.timeout),i2d_ASN1_INTEGER,2,v2);
231: if (in->peer != NULL)
232: M_ASN1_I2D_len_EXP_opt(in->peer,i2d_X509,3,v3);
233: M_ASN1_I2D_len_EXP_opt(&a.session_id_context,i2d_ASN1_OCTET_STRING,4,v4);
234: if (in->verify_result != X509_V_OK)
235: M_ASN1_I2D_len_EXP_opt(&(a.verify_result),i2d_ASN1_INTEGER,5,v5);
236:
237: #ifndef OPENSSL_NO_TLSEXT
238: if (in->tlsext_tick_lifetime_hint)
239: M_ASN1_I2D_len_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER,9,v9);
240: if (in->tlsext_tick)
241: M_ASN1_I2D_len_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING,10,v10);
242: if (in->tlsext_hostname)
243: M_ASN1_I2D_len_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING,6,v6);
244: #endif
245: M_ASN1_I2D_seq_total();
246:
247: M_ASN1_I2D_put(&(a.version), i2d_ASN1_INTEGER);
248: M_ASN1_I2D_put(&(a.ssl_version), i2d_ASN1_INTEGER);
249: M_ASN1_I2D_put(&(a.cipher), i2d_ASN1_OCTET_STRING);
250: M_ASN1_I2D_put(&(a.session_id), i2d_ASN1_OCTET_STRING);
251: M_ASN1_I2D_put(&(a.master_key), i2d_ASN1_OCTET_STRING);
252: #ifndef OPENSSL_NO_KRB5
253: if (in->krb5_client_princ_len)
254: M_ASN1_I2D_put(&(a.krb5_princ), i2d_ASN1_OCTET_STRING);
255: #endif
256: if (in->key_arg_length > 0)
257: M_ASN1_I2D_put_IMP_opt(&(a.key_arg),i2d_ASN1_OCTET_STRING,0);
258: if (in->time != 0L)
259: M_ASN1_I2D_put_EXP_opt(&(a.time),i2d_ASN1_INTEGER,1,v1);
260: if (in->timeout != 0L)
261: M_ASN1_I2D_put_EXP_opt(&(a.timeout),i2d_ASN1_INTEGER,2,v2);
262: if (in->peer != NULL)
263: M_ASN1_I2D_put_EXP_opt(in->peer,i2d_X509,3,v3);
264: M_ASN1_I2D_put_EXP_opt(&a.session_id_context,i2d_ASN1_OCTET_STRING,4,
265: v4);
266: if (in->verify_result != X509_V_OK)
267: M_ASN1_I2D_put_EXP_opt(&a.verify_result,i2d_ASN1_INTEGER,5,v5);
268: #ifndef OPENSSL_NO_TLSEXT
269: if (in->tlsext_hostname)
270: M_ASN1_I2D_put_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING,6,v6);
271: if (in->tlsext_tick_lifetime_hint)
272: M_ASN1_I2D_put_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER,9,v9);
273: if (in->tlsext_tick)
274: M_ASN1_I2D_put_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING,10,v10);
275: #endif
276: M_ASN1_I2D_finish();
277: }
278:
279: SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
280: long length)
281: {
282: int version,ssl_version=0,i;
283: long id;
284: ASN1_INTEGER ai,*aip;
285: ASN1_OCTET_STRING os,*osp;
286: M_ASN1_D2I_vars(a,SSL_SESSION *,SSL_SESSION_new);
287:
288: aip= &ai;
289: osp= &os;
290:
291: M_ASN1_D2I_Init();
292: M_ASN1_D2I_start_sequence();
293:
294: ai.data=NULL; ai.length=0;
295: M_ASN1_D2I_get_x(ASN1_INTEGER,aip,d2i_ASN1_INTEGER);
296: version=(int)ASN1_INTEGER_get(aip);
297: if (ai.data != NULL) { OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; }
298:
299:
300: M_ASN1_D2I_get_x(ASN1_INTEGER,aip,d2i_ASN1_INTEGER);
301: ssl_version=(int)ASN1_INTEGER_get(aip);
302: ret->ssl_version=ssl_version;
303: if (ai.data != NULL) { OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; }
304:
305: os.data=NULL; os.length=0;
306: M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING);
307: if (ssl_version == SSL2_VERSION)
308: {
309: if (os.length != 3)
310: {
311: c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH;
312: goto err;
313: }
314: id=0x02000000L|
315: ((unsigned long)os.data[0]<<16L)|
316: ((unsigned long)os.data[1]<< 8L)|
317: (unsigned long)os.data[2];
318: }
319: else if ((ssl_version>>8) == SSL3_VERSION_MAJOR)
320: {
321: if (os.length != 2)
322: {
323: c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH;
324: goto err;
325: }
326: id=0x03000000L|
327: ((unsigned long)os.data[0]<<8L)|
328: (unsigned long)os.data[1];
329: }
330: else
331: {
332: SSLerr(SSL_F_D2I_SSL_SESSION,SSL_R_UNKNOWN_SSL_VERSION);
333: return(NULL);
334: }
335:
336: ret->cipher=NULL;
337: ret->cipher_id=id;
338:
339: M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING);
340: if ((ssl_version>>8) == SSL3_VERSION_MAJOR)
341: i=SSL3_MAX_SSL_SESSION_ID_LENGTH;
342: else
343: i=SSL2_MAX_SSL_SESSION_ID_LENGTH;
344:
345: if (os.length > i)
346: os.length = i;
347: if (os.length > (int)sizeof(ret->session_id))
348: os.length = sizeof(ret->session_id);
349:
350: ret->session_id_length=os.length;
351: OPENSSL_assert(os.length <= (int)sizeof(ret->session_id));
352: memcpy(ret->session_id,os.data,os.length);
353:
354: M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING);
355: if (ret->master_key_length > SSL_MAX_MASTER_KEY_LENGTH)
356: ret->master_key_length=SSL_MAX_MASTER_KEY_LENGTH;
357: else
358: ret->master_key_length=os.length;
359: memcpy(ret->master_key,os.data,ret->master_key_length);
360:
361: os.length=0;
362:
363: #ifndef OPENSSL_NO_KRB5
364: os.length=0;
365: M_ASN1_D2I_get_opt(osp,d2i_ASN1_OCTET_STRING,V_ASN1_OCTET_STRING);
366: if (os.data)
367: {
368: if (os.length > SSL_MAX_KRB5_PRINCIPAL_LENGTH)
369: ret->krb5_client_princ_len=0;
370: else
371: ret->krb5_client_princ_len=os.length;
372: memcpy(ret->krb5_client_princ,os.data,ret->krb5_client_princ_len);
373: OPENSSL_free(os.data);
374: os.data = NULL;
375: os.length = 0;
376: }
377: else
378: ret->krb5_client_princ_len=0;
379: #endif
380:
381: M_ASN1_D2I_get_IMP_opt(osp,d2i_ASN1_OCTET_STRING,0,V_ASN1_OCTET_STRING);
382: if (os.length > SSL_MAX_KEY_ARG_LENGTH)
383: ret->key_arg_length=SSL_MAX_KEY_ARG_LENGTH;
384: else
385: ret->key_arg_length=os.length;
386: memcpy(ret->key_arg,os.data,ret->key_arg_length);
387: if (os.data != NULL) OPENSSL_free(os.data);
388:
389: ai.length=0;
390: M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,1);
391: if (ai.data != NULL)
392: {
393: ret->time=ASN1_INTEGER_get(aip);
394: OPENSSL_free(ai.data); ai.data=NULL; ai.length=0;
395: }
396: else
397: ret->time=(unsigned long)time(NULL);
398:
399: ai.length=0;
400: M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,2);
401: if (ai.data != NULL)
402: {
403: ret->timeout=ASN1_INTEGER_get(aip);
404: OPENSSL_free(ai.data); ai.data=NULL; ai.length=0;
405: }
406: else
407: ret->timeout=3;
408:
409: if (ret->peer != NULL)
410: {
411: X509_free(ret->peer);
412: ret->peer=NULL;
413: }
414: M_ASN1_D2I_get_EXP_opt(ret->peer,d2i_X509,3);
415:
416: os.length=0;
417: os.data=NULL;
418: M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,4);
419:
420: if(os.data != NULL)
421: {
422: if (os.length > SSL_MAX_SID_CTX_LENGTH)
423: {
424: ret->sid_ctx_length=os.length;
425: SSLerr(SSL_F_D2I_SSL_SESSION,SSL_R_BAD_LENGTH);
426: }
427: else
428: {
429: ret->sid_ctx_length=os.length;
430: memcpy(ret->sid_ctx,os.data,os.length);
431: }
432: OPENSSL_free(os.data); os.data=NULL; os.length=0;
433: }
434: else
435: ret->sid_ctx_length=0;
436:
437: ai.length=0;
438: M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,5);
439: if (ai.data != NULL)
440: {
441: ret->verify_result=ASN1_INTEGER_get(aip);
442: OPENSSL_free(ai.data); ai.data=NULL; ai.length=0;
443: }
444: else
445: ret->verify_result=X509_V_OK;
446:
447: #ifndef OPENSSL_NO_TLSEXT
448: os.length=0;
449: os.data=NULL;
450: M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,6);
451: if (os.data)
452: {
453: ret->tlsext_hostname = BUF_strndup((char *)os.data, os.length);
454: OPENSSL_free(os.data);
455: os.data = NULL;
456: os.length = 0;
457: }
458: else
459: ret->tlsext_hostname=NULL;
460: ai.length=0;
461: M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,9);
462: if (ai.data != NULL)
463: {
464: ret->tlsext_tick_lifetime_hint=ASN1_INTEGER_get(aip);
465: OPENSSL_free(ai.data); ai.data=NULL; ai.length=0;
466: }
467: else
468: ret->tlsext_tick_lifetime_hint=0;
469: os.length=0;
470: os.data=NULL;
471: M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,10);
472: if (os.data)
473: {
474: ret->tlsext_tick = os.data;
475: ret->tlsext_ticklen = os.length;
476: os.data = NULL;
477: os.length = 0;
478: #if 0
479:
480:
481:
482:
483:
484: if (ret->session_id_length == 0)
485: {
486: ret->session_id_length=SSL3_MAX_SSL_SESSION_ID_LENGTH;
487: RAND_pseudo_bytes(ret->session_id,
488: ret->session_id_length);
489: }
490: #endif
491: }
492: else
493: ret->tlsext_tick=NULL;
494: #endif
495:
496: M_ASN1_D2I_Finish(a,SSL_SESSION_free,SSL_F_D2I_SSL_SESSION);
497: }