155714Skris/* ssl/s2_lib.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.
8280304Sjkim *
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).
15280304Sjkim *
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.
22280304Sjkim *
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 :-).
37280304Sjkim * 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)"
40280304Sjkim *
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.
52280304Sjkim *
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 (c) 1998-2007 The OpenSSL Project.  All rights reserved.
60238405Sjkim *
61238405Sjkim * Redistribution and use in source and binary forms, with or without
62238405Sjkim * modification, are permitted provided that the following conditions
63238405Sjkim * are met:
64238405Sjkim *
65238405Sjkim * 1. Redistributions of source code must retain the above copyright
66280304Sjkim *    notice, this list of conditions and the following disclaimer.
67238405Sjkim *
68238405Sjkim * 2. Redistributions in binary form must reproduce the above copyright
69238405Sjkim *    notice, this list of conditions and the following disclaimer in
70238405Sjkim *    the documentation and/or other materials provided with the
71238405Sjkim *    distribution.
72238405Sjkim *
73238405Sjkim * 3. All advertising materials mentioning features or use of this
74238405Sjkim *    software must display the following acknowledgment:
75238405Sjkim *    "This product includes software developed by the OpenSSL Project
76238405Sjkim *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77238405Sjkim *
78238405Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79238405Sjkim *    endorse or promote products derived from this software without
80238405Sjkim *    prior written permission. For written permission, please contact
81238405Sjkim *    openssl-core@openssl.org.
82238405Sjkim *
83238405Sjkim * 5. Products derived from this software may not be called "OpenSSL"
84238405Sjkim *    nor may "OpenSSL" appear in their names without prior written
85238405Sjkim *    permission of the OpenSSL Project.
86238405Sjkim *
87238405Sjkim * 6. Redistributions of any form whatsoever must retain the following
88238405Sjkim *    acknowledgment:
89238405Sjkim *    "This product includes software developed by the OpenSSL Project
90238405Sjkim *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91238405Sjkim *
92238405Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93238405Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94238405Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95238405Sjkim * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96238405Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97238405Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98238405Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99238405Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100238405Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101238405Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102238405Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103238405Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE.
104238405Sjkim * ====================================================================
105238405Sjkim *
106238405Sjkim * This product includes cryptographic software written by Eric Young
107238405Sjkim * (eay@cryptsoft.com).  This product includes software written by Tim
108238405Sjkim * Hudson (tjh@cryptsoft.com).
109238405Sjkim *
110238405Sjkim */
11155714Skris
11259194Skris#include "ssl_locl.h"
113110007Smarkm#ifndef OPENSSL_NO_SSL2
114280304Sjkim# include <stdio.h>
115280304Sjkim# include <openssl/objects.h>
116280304Sjkim# include <openssl/evp.h>
117280304Sjkim# include <openssl/md5.h>
11855714Skris
119280304Sjkimconst char ssl2_version_str[] = "SSLv2" OPENSSL_VERSION_PTEXT;
12055714Skris
121280304Sjkim# define SSL2_NUM_CIPHERS (sizeof(ssl2_ciphers)/sizeof(SSL_CIPHER))
12255714Skris
123160817Ssimon/* list of available SSLv2 ciphers (sorted by id) */
124280304SjkimOPENSSL_GLOBAL const SSL_CIPHER ssl2_ciphers[] = {
125280304Sjkim# if 0
12655714Skris/* NULL_WITH_MD5 v3 */
127280304Sjkim    {
128280304Sjkim     1,
129280304Sjkim     SSL2_TXT_NULL_WITH_MD5,
130280304Sjkim     SSL2_CK_NULL_WITH_MD5,
131280304Sjkim     SSL_kRSA,
132280304Sjkim     SSL_aRSA,
133280304Sjkim     SSL_eNULL,
134280304Sjkim     SSL_MD5,
135280304Sjkim     SSL_SSLV2,
136280304Sjkim     SSL_EXPORT | SSL_EXP40 | SSL_STRONG_NONE,
137280304Sjkim     0,
138280304Sjkim     0,
139280304Sjkim     0,
140280304Sjkim     },
141280304Sjkim# endif
142238405Sjkim
143160817Ssimon/* RC4_128_WITH_MD5 */
144280304Sjkim    {
145280304Sjkim     1,
146280304Sjkim     SSL2_TXT_RC4_128_WITH_MD5,
147280304Sjkim     SSL2_CK_RC4_128_WITH_MD5,
148280304Sjkim     SSL_kRSA,
149280304Sjkim     SSL_aRSA,
150280304Sjkim     SSL_RC4,
151280304Sjkim     SSL_MD5,
152280304Sjkim     SSL_SSLV2,
153298999Sjkim     SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM,
154280304Sjkim     0,
155280304Sjkim     128,
156280304Sjkim     128,
157280304Sjkim     },
158238405Sjkim
159296317Sdelphij# if 0
16055714Skris/* RC4_128_EXPORT40_WITH_MD5 */
161280304Sjkim    {
162280304Sjkim     1,
163280304Sjkim     SSL2_TXT_RC4_128_EXPORT40_WITH_MD5,
164280304Sjkim     SSL2_CK_RC4_128_EXPORT40_WITH_MD5,
165280304Sjkim     SSL_kRSA,
166280304Sjkim     SSL_aRSA,
167280304Sjkim     SSL_RC4,
168280304Sjkim     SSL_MD5,
169280304Sjkim     SSL_SSLV2,
170298999Sjkim     SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40,
171280304Sjkim     SSL2_CF_5_BYTE_ENC,
172280304Sjkim     40,
173280304Sjkim     128,
174280304Sjkim     },
175296317Sdelphij# endif
176238405Sjkim
177160817Ssimon/* RC2_128_CBC_WITH_MD5 */
178280304Sjkim    {
179280304Sjkim     1,
180280304Sjkim     SSL2_TXT_RC2_128_CBC_WITH_MD5,
181280304Sjkim     SSL2_CK_RC2_128_CBC_WITH_MD5,
182280304Sjkim     SSL_kRSA,
183280304Sjkim     SSL_aRSA,
184280304Sjkim     SSL_RC2,
185280304Sjkim     SSL_MD5,
186280304Sjkim     SSL_SSLV2,
187298999Sjkim     SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM,
188280304Sjkim     0,
189280304Sjkim     128,
190280304Sjkim     128,
191280304Sjkim     },
192238405Sjkim
193296317Sdelphij# if 0
19455714Skris/* RC2_128_CBC_EXPORT40_WITH_MD5 */
195280304Sjkim    {
196280304Sjkim     1,
197280304Sjkim     SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5,
198280304Sjkim     SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5,
199280304Sjkim     SSL_kRSA,
200280304Sjkim     SSL_aRSA,
201280304Sjkim     SSL_RC2,
202280304Sjkim     SSL_MD5,
203280304Sjkim     SSL_SSLV2,
204298999Sjkim     SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40,
205280304Sjkim     SSL2_CF_5_BYTE_ENC,
206280304Sjkim     40,
207280304Sjkim     128,
208280304Sjkim     },
209296317Sdelphij# endif
210238405Sjkim
211280304Sjkim# ifndef OPENSSL_NO_IDEA
21255714Skris/* IDEA_128_CBC_WITH_MD5 */
213280304Sjkim    {
214280304Sjkim     1,
215280304Sjkim     SSL2_TXT_IDEA_128_CBC_WITH_MD5,
216280304Sjkim     SSL2_CK_IDEA_128_CBC_WITH_MD5,
217280304Sjkim     SSL_kRSA,
218280304Sjkim     SSL_aRSA,
219280304Sjkim     SSL_IDEA,
220280304Sjkim     SSL_MD5,
221280304Sjkim     SSL_SSLV2,
222298999Sjkim     SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM,
223280304Sjkim     0,
224280304Sjkim     128,
225280304Sjkim     128,
226280304Sjkim     },
227280304Sjkim# endif
228238405Sjkim
229296317Sdelphij# if 0
23055714Skris/* DES_64_CBC_WITH_MD5 */
231280304Sjkim    {
232280304Sjkim     1,
233280304Sjkim     SSL2_TXT_DES_64_CBC_WITH_MD5,
234280304Sjkim     SSL2_CK_DES_64_CBC_WITH_MD5,
235280304Sjkim     SSL_kRSA,
236280304Sjkim     SSL_aRSA,
237280304Sjkim     SSL_DES,
238280304Sjkim     SSL_MD5,
239280304Sjkim     SSL_SSLV2,
240298999Sjkim     SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW,
241280304Sjkim     0,
242280304Sjkim     56,
243280304Sjkim     56,
244280304Sjkim     },
245296317Sdelphij# endif
246238405Sjkim
24755714Skris/* DES_192_EDE3_CBC_WITH_MD5 */
248280304Sjkim    {
249280304Sjkim     1,
250280304Sjkim     SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5,
251280304Sjkim     SSL2_CK_DES_192_EDE3_CBC_WITH_MD5,
252280304Sjkim     SSL_kRSA,
253280304Sjkim     SSL_aRSA,
254280304Sjkim     SSL_3DES,
255280304Sjkim     SSL_MD5,
256280304Sjkim     SSL_SSLV2,
257298999Sjkim     SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH,
258280304Sjkim     0,
259280304Sjkim     112,
260280304Sjkim     168,
261280304Sjkim     },
262238405Sjkim
263280304Sjkim# if 0
26455714Skris/* RC4_64_WITH_MD5 */
265280304Sjkim    {
266280304Sjkim     1,
267280304Sjkim     SSL2_TXT_RC4_64_WITH_MD5,
268280304Sjkim     SSL2_CK_RC4_64_WITH_MD5,
269280304Sjkim     SSL_kRSA,
270280304Sjkim     SSL_aRSA,
271280304Sjkim     SSL_RC4,
272280304Sjkim     SSL_MD5,
273280304Sjkim     SSL_SSLV2,
274298999Sjkim     SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW,
275280304Sjkim     SSL2_CF_8_BYTE_ENC,
276280304Sjkim     64,
277280304Sjkim     64,
278280304Sjkim     },
279280304Sjkim# endif
280238405Sjkim
281280304Sjkim# if 0
28255714Skris/* NULL SSLeay (testing) */
283280304Sjkim    {
284280304Sjkim     0,
285280304Sjkim     SSL2_TXT_NULL,
286280304Sjkim     SSL2_CK_NULL,
287280304Sjkim     0,
288280304Sjkim     0,
289280304Sjkim     0,
290280304Sjkim     0,
291280304Sjkim     SSL_SSLV2,
292280304Sjkim     SSL_STRONG_NONE,
293280304Sjkim     0,
294280304Sjkim     0,
295280304Sjkim     0,
296280304Sjkim     },
297280304Sjkim# endif
29855714Skris
29955714Skris/* end of list :-) */
300280304Sjkim};
30155714Skris
302160817Ssimonlong ssl2_default_timeout(void)
303280304Sjkim{
304280304Sjkim    return (300);
305280304Sjkim}
30655714Skris
30755714Skrisint ssl2_num_ciphers(void)
308280304Sjkim{
309280304Sjkim    return (SSL2_NUM_CIPHERS);
310280304Sjkim}
31155714Skris
312238405Sjkimconst SSL_CIPHER *ssl2_get_cipher(unsigned int u)
313280304Sjkim{
314280304Sjkim    if (u < SSL2_NUM_CIPHERS)
315280304Sjkim        return (&(ssl2_ciphers[SSL2_NUM_CIPHERS - 1 - u]));
316280304Sjkim    else
317280304Sjkim        return (NULL);
318280304Sjkim}
31955714Skris
320160817Ssimonint ssl2_pending(const SSL *s)
321280304Sjkim{
322280304Sjkim    return SSL_in_init(s) ? 0 : s->s2->ract_data_length;
323280304Sjkim}
32455714Skris
32555714Skrisint ssl2_new(SSL *s)
326280304Sjkim{
327280304Sjkim    SSL2_STATE *s2;
32855714Skris
329280304Sjkim    if ((s2 = OPENSSL_malloc(sizeof *s2)) == NULL)
330280304Sjkim        goto err;
331280304Sjkim    memset(s2, 0, sizeof *s2);
33255714Skris
333280304Sjkim# if SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER + 3 > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2
33472616Skris#  error "assertion failed"
335280304Sjkim# endif
33672616Skris
337280304Sjkim    if ((s2->rbuf =
338280304Sjkim         OPENSSL_malloc(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2)) == NULL)
339280304Sjkim        goto err;
340280304Sjkim    /*
341280304Sjkim     * wbuf needs one byte more because when using two-byte headers, we leave
342280304Sjkim     * the first byte unused in do_ssl_write (s2_pkt.c)
343280304Sjkim     */
344280304Sjkim    if ((s2->wbuf =
345280304Sjkim         OPENSSL_malloc(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 3)) == NULL)
346280304Sjkim        goto err;
347280304Sjkim    s->s2 = s2;
34855714Skris
349280304Sjkim    ssl2_clear(s);
350280304Sjkim    return (1);
351280304Sjkim err:
352280304Sjkim    if (s2 != NULL) {
353280304Sjkim        if (s2->wbuf != NULL)
354280304Sjkim            OPENSSL_free(s2->wbuf);
355280304Sjkim        if (s2->rbuf != NULL)
356280304Sjkim            OPENSSL_free(s2->rbuf);
357280304Sjkim        OPENSSL_free(s2);
358280304Sjkim    }
359280304Sjkim    return (0);
360280304Sjkim}
36155714Skris
36255714Skrisvoid ssl2_free(SSL *s)
363280304Sjkim{
364280304Sjkim    SSL2_STATE *s2;
36555714Skris
366280304Sjkim    if (s == NULL)
367280304Sjkim        return;
36855714Skris
369280304Sjkim    s2 = s->s2;
370280304Sjkim    if (s2->rbuf != NULL)
371280304Sjkim        OPENSSL_free(s2->rbuf);
372280304Sjkim    if (s2->wbuf != NULL)
373280304Sjkim        OPENSSL_free(s2->wbuf);
374280304Sjkim    OPENSSL_cleanse(s2, sizeof *s2);
375280304Sjkim    OPENSSL_free(s2);
376280304Sjkim    s->s2 = NULL;
377280304Sjkim}
37855714Skris
37955714Skrisvoid ssl2_clear(SSL *s)
380280304Sjkim{
381280304Sjkim    SSL2_STATE *s2;
382280304Sjkim    unsigned char *rbuf, *wbuf;
38355714Skris
384280304Sjkim    s2 = s->s2;
38555714Skris
386280304Sjkim    rbuf = s2->rbuf;
387280304Sjkim    wbuf = s2->wbuf;
38855714Skris
389280304Sjkim    memset(s2, 0, sizeof *s2);
39055714Skris
391280304Sjkim    s2->rbuf = rbuf;
392280304Sjkim    s2->wbuf = wbuf;
393280304Sjkim    s2->clear_text = 1;
394280304Sjkim    s->packet = s2->rbuf;
395280304Sjkim    s->version = SSL2_VERSION;
396280304Sjkim    s->packet_length = 0;
397280304Sjkim}
39855714Skris
399110007Smarkmlong ssl2_ctrl(SSL *s, int cmd, long larg, void *parg)
400280304Sjkim{
401280304Sjkim    int ret = 0;
40255714Skris
403280304Sjkim    switch (cmd) {
404280304Sjkim    case SSL_CTRL_GET_SESSION_REUSED:
405280304Sjkim        ret = s->hit;
406280304Sjkim        break;
407280304Sjkim    case SSL_CTRL_CHECK_PROTO_VERSION:
408280304Sjkim        return ssl3_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, larg, parg);
409280304Sjkim    default:
410280304Sjkim        break;
411280304Sjkim    }
412280304Sjkim    return (ret);
413280304Sjkim}
41455714Skris
415280304Sjkimlong ssl2_callback_ctrl(SSL *s, int cmd, void (*fp) (void))
416280304Sjkim{
417280304Sjkim    return (0);
418280304Sjkim}
41959194Skris
420110007Smarkmlong ssl2_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
421280304Sjkim{
422280304Sjkim    return (0);
423280304Sjkim}
42455714Skris
425280304Sjkimlong ssl2_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void))
426280304Sjkim{
427280304Sjkim    return (0);
428280304Sjkim}
42959194Skris
430280304Sjkim/*
431280304Sjkim * This function needs to check if the ciphers required are actually
432280304Sjkim * available
433280304Sjkim */
434238405Sjkimconst SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p)
435280304Sjkim{
436280304Sjkim    SSL_CIPHER c;
437280304Sjkim    const SSL_CIPHER *cp;
438280304Sjkim    unsigned long id;
43955714Skris
440280304Sjkim    id = 0x02000000L | ((unsigned long)p[0] << 16L) |
441280304Sjkim        ((unsigned long)p[1] << 8L) | (unsigned long)p[2];
442280304Sjkim    c.id = id;
443280304Sjkim    cp = OBJ_bsearch_ssl_cipher_id(&c, ssl2_ciphers, SSL2_NUM_CIPHERS);
444280304Sjkim    if ((cp == NULL) || (cp->valid == 0))
445280304Sjkim        return NULL;
446280304Sjkim    else
447280304Sjkim        return cp;
448280304Sjkim}
44955714Skris
45055714Skrisint ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
451280304Sjkim{
452280304Sjkim    long l;
45355714Skris
454280304Sjkim    if (p != NULL) {
455280304Sjkim        l = c->id;
456280304Sjkim        if ((l & 0xff000000) != 0x02000000 && l != SSL3_CK_FALLBACK_SCSV)
457280304Sjkim            return (0);
458280304Sjkim        p[0] = ((unsigned char)(l >> 16L)) & 0xFF;
459280304Sjkim        p[1] = ((unsigned char)(l >> 8L)) & 0xFF;
460280304Sjkim        p[2] = ((unsigned char)(l)) & 0xFF;
461280304Sjkim    }
462280304Sjkim    return (3);
463280304Sjkim}
46455714Skris
465101621Snectarint ssl2_generate_key_material(SSL *s)
466280304Sjkim{
467280304Sjkim    unsigned int i;
468280304Sjkim    EVP_MD_CTX ctx;
469280304Sjkim    unsigned char *km;
470280304Sjkim    unsigned char c = '0';
471280304Sjkim    const EVP_MD *md5;
472280304Sjkim    int md_size;
47355714Skris
474280304Sjkim    md5 = EVP_md5();
475110007Smarkm
476280304Sjkim# ifdef CHARSET_EBCDIC
477280304Sjkim    c = os_toascii['0'];        /* Must be an ASCII '0', not EBCDIC '0', see
478280304Sjkim                                 * SSLv2 docu */
479280304Sjkim# endif
480280304Sjkim    EVP_MD_CTX_init(&ctx);
481280304Sjkim    km = s->s2->key_material;
482101621Snectar
483280304Sjkim    if (s->session->master_key_length < 0 ||
484280304Sjkim        s->session->master_key_length > (int)sizeof(s->session->master_key)) {
485280304Sjkim        SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR);
486280304Sjkim        return 0;
487280304Sjkim    }
488280304Sjkim    md_size = EVP_MD_size(md5);
489280304Sjkim    if (md_size < 0)
490280304Sjkim        return 0;
491280304Sjkim    for (i = 0; i < s->s2->key_material_length; i += md_size) {
492280304Sjkim        if (((km - s->s2->key_material) + md_size) >
493280304Sjkim            (int)sizeof(s->s2->key_material)) {
494280304Sjkim            /*
495280304Sjkim             * EVP_DigestFinal_ex() below would write beyond buffer
496280304Sjkim             */
497280304Sjkim            SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR);
498280304Sjkim            return 0;
499280304Sjkim        }
500101621Snectar
501280304Sjkim        EVP_DigestInit_ex(&ctx, md5, NULL);
50255714Skris
503280304Sjkim        OPENSSL_assert(s->session->master_key_length >= 0
504280304Sjkim                       && s->session->master_key_length
505280304Sjkim                       <= (int)sizeof(s->session->master_key));
506280304Sjkim        EVP_DigestUpdate(&ctx, s->session->master_key,
507280304Sjkim                         s->session->master_key_length);
508280304Sjkim        EVP_DigestUpdate(&ctx, &c, 1);
509280304Sjkim        c++;
510280304Sjkim        EVP_DigestUpdate(&ctx, s->s2->challenge, s->s2->challenge_length);
511280304Sjkim        EVP_DigestUpdate(&ctx, s->s2->conn_id, s->s2->conn_id_length);
512280304Sjkim        EVP_DigestFinal_ex(&ctx, km, NULL);
513280304Sjkim        km += md_size;
514280304Sjkim    }
515101621Snectar
516280304Sjkim    EVP_MD_CTX_cleanup(&ctx);
517280304Sjkim    return 1;
518280304Sjkim}
51955714Skris
52055714Skrisvoid ssl2_return_error(SSL *s, int err)
521280304Sjkim{
522280304Sjkim    if (!s->error) {
523280304Sjkim        s->error = 3;
524280304Sjkim        s->error_code = err;
52555714Skris
526280304Sjkim        ssl2_write_error(s);
527280304Sjkim    }
528280304Sjkim}
52955714Skris
53055714Skrisvoid ssl2_write_error(SSL *s)
531280304Sjkim{
532280304Sjkim    unsigned char buf[3];
533280304Sjkim    int i, error;
53455714Skris
535280304Sjkim    buf[0] = SSL2_MT_ERROR;
536280304Sjkim    buf[1] = (s->error_code >> 8) & 0xff;
537280304Sjkim    buf[2] = (s->error_code) & 0xff;
53855714Skris
539280304Sjkim/*      state=s->rwstate;*/
540101621Snectar
541280304Sjkim    error = s->error;           /* number of bytes left to write */
542280304Sjkim    s->error = 0;
543280304Sjkim    OPENSSL_assert(error >= 0 && error <= (int)sizeof(buf));
544280304Sjkim    i = ssl2_write(s, &(buf[3 - error]), error);
545101621Snectar
546280304Sjkim/*      if (i == error) s->rwstate=state; */
54755714Skris
548280304Sjkim    if (i < 0)
549280304Sjkim        s->error = error;
550280304Sjkim    else {
551280304Sjkim        s->error = error - i;
552110007Smarkm
553280304Sjkim        if (s->error == 0)
554280304Sjkim            if (s->msg_callback) {
555280304Sjkim                /* ERROR */
556280304Sjkim                s->msg_callback(1, s->version, 0, buf, 3, s,
557280304Sjkim                                s->msg_callback_arg);
558280304Sjkim            }
559280304Sjkim    }
560280304Sjkim}
56155714Skris
56255714Skrisint ssl2_shutdown(SSL *s)
563280304Sjkim{
564280304Sjkim    s->shutdown = (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
565280304Sjkim    return (1);
566280304Sjkim}
567280304Sjkim#else                           /* !OPENSSL_NO_SSL2 */
56859194Skris
56959194Skris# if PEDANTIC
570280304Sjkimstatic void *dummy = &dummy;
57159194Skris# endif
57259194Skris
57355714Skris#endif
574