s2_lib.c revision 280297
1191783Srmacklem/* ssl/s2_lib.c */
2191783Srmacklem/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3191783Srmacklem * All rights reserved.
4191783Srmacklem *
5191783Srmacklem * This package is an SSL implementation written
6191783Srmacklem * by Eric Young (eay@cryptsoft.com).
7191783Srmacklem * The implementation was written so as to conform with Netscapes SSL.
8191783Srmacklem *
9191783Srmacklem * This library is free for commercial and non-commercial use as long as
10191783Srmacklem * the following conditions are aheared to.  The following conditions
11191783Srmacklem * apply to all code found in this distribution, be it the RC4, RSA,
12191783Srmacklem * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13191783Srmacklem * included with this distribution is covered by the same copyright terms
14191783Srmacklem * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15191783Srmacklem *
16191783Srmacklem * Copyright remains Eric Young's, and as such any Copyright notices in
17191783Srmacklem * the code are not to be removed.
18191783Srmacklem * If this package is used in a product, Eric Young should be given attribution
19191783Srmacklem * as the author of the parts of the library used.
20191783Srmacklem * This can be in the form of a textual message at program startup or
21191783Srmacklem * in documentation (online or textual) provided with the package.
22191783Srmacklem *
23191783Srmacklem * Redistribution and use in source and binary forms, with or without
24191783Srmacklem * modification, are permitted provided that the following conditions
25191783Srmacklem * are met:
26191783Srmacklem * 1. Redistributions of source code must retain the copyright
27191783Srmacklem *    notice, this list of conditions and the following disclaimer.
28191783Srmacklem * 2. Redistributions in binary form must reproduce the above copyright
29191783Srmacklem *    notice, this list of conditions and the following disclaimer in the
30191783Srmacklem *    documentation and/or other materials provided with the distribution.
31191783Srmacklem * 3. All advertising materials mentioning features or use of this software
32191783Srmacklem *    must display the following acknowledgement:
33191783Srmacklem *    "This product includes cryptographic software written by
34191783Srmacklem *     Eric Young (eay@cryptsoft.com)"
35191783Srmacklem *    The word 'cryptographic' can be left out if the rouines from the library
36191783Srmacklem *    being used are not cryptographic related :-).
37191783Srmacklem * 4. If you include any Windows specific code (or a derivative thereof) from
38191783Srmacklem *    the apps directory (application code) you must include an acknowledgement:
39198289Sjh *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40191783Srmacklem *
41198289Sjh * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42191783Srmacklem * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43191783Srmacklem * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44191783Srmacklem * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45191783Srmacklem * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46191783Srmacklem * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47191783Srmacklem * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48191783Srmacklem * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49191783Srmacklem * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50191783Srmacklem * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51191783Srmacklem * SUCH DAMAGE.
52191783Srmacklem *
53198289Sjh * The licence and distribution terms for any publically available version or
54198289Sjh * derivative of this code cannot be changed.  i.e. this code cannot simply be
55191783Srmacklem * copied and put under another distribution licence
56191783Srmacklem * [including the GNU Public Licence.]
57191783Srmacklem */
58191783Srmacklem/* ====================================================================
59191783Srmacklem * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
60191783Srmacklem *
61191783Srmacklem * Redistribution and use in source and binary forms, with or without
62191783Srmacklem * modification, are permitted provided that the following conditions
63191783Srmacklem * are met:
64191783Srmacklem *
65191783Srmacklem * 1. Redistributions of source code must retain the above copyright
66191783Srmacklem *    notice, this list of conditions and the following disclaimer.
67227744Srmacklem *
68227744Srmacklem * 2. Redistributions in binary form must reproduce the above copyright
69191783Srmacklem *    notice, this list of conditions and the following disclaimer in
70191783Srmacklem *    the documentation and/or other materials provided with the
71191783Srmacklem *    distribution.
72191783Srmacklem *
73191783Srmacklem * 3. All advertising materials mentioning features or use of this
74191783Srmacklem *    software must display the following acknowledgment:
75191783Srmacklem *    "This product includes software developed by the OpenSSL Project
76191783Srmacklem *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77191783Srmacklem *
78191783Srmacklem * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79191783Srmacklem *    endorse or promote products derived from this software without
80191783Srmacklem *    prior written permission. For written permission, please contact
81191783Srmacklem *    openssl-core@openssl.org.
82191783Srmacklem *
83191783Srmacklem * 5. Products derived from this software may not be called "OpenSSL"
84191783Srmacklem *    nor may "OpenSSL" appear in their names without prior written
85191783Srmacklem *    permission of the OpenSSL Project.
86191783Srmacklem *
87191783Srmacklem * 6. Redistributions of any form whatsoever must retain the following
88191783Srmacklem *    acknowledgment:
89191783Srmacklem *    "This product includes software developed by the OpenSSL Project
90191783Srmacklem *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91191783Srmacklem *
92191783Srmacklem * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93191783Srmacklem * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94191783Srmacklem * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95191783Srmacklem * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96191783Srmacklem * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97191783Srmacklem * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98223774Srmacklem * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99191783Srmacklem * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100191783Srmacklem * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101191783Srmacklem * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102191783Srmacklem * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103191783Srmacklem * OF THE POSSIBILITY OF SUCH DAMAGE.
104191783Srmacklem * ====================================================================
105191783Srmacklem *
106191783Srmacklem * This product includes cryptographic software written by Eric Young
107191783Srmacklem * (eay@cryptsoft.com).  This product includes software written by Tim
108191783Srmacklem * Hudson (tjh@cryptsoft.com).
109191783Srmacklem *
110191783Srmacklem */
111191783Srmacklem
112191783Srmacklem#include "ssl_locl.h"
113191783Srmacklem#ifndef OPENSSL_NO_SSL2
114191783Srmacklem# include <stdio.h>
115191783Srmacklem# include <openssl/objects.h>
116191783Srmacklem# include <openssl/evp.h>
117191783Srmacklem# include <openssl/md5.h>
118201439Srmacklem
119201439Srmacklemconst char ssl2_version_str[] = "SSLv2" OPENSSL_VERSION_PTEXT;
120191783Srmacklem
121191783Srmacklem# define SSL2_NUM_CIPHERS (sizeof(ssl2_ciphers)/sizeof(SSL_CIPHER))
122191783Srmacklem
123191783Srmacklem/* list of available SSLv2 ciphers (sorted by id) */
124191783SrmacklemOPENSSL_GLOBAL const SSL_CIPHER ssl2_ciphers[] = {
125191783Srmacklem# if 0
126191783Srmacklem/* NULL_WITH_MD5 v3 */
127191783Srmacklem    {
128191783Srmacklem     1,
129191783Srmacklem     SSL2_TXT_NULL_WITH_MD5,
130191783Srmacklem     SSL2_CK_NULL_WITH_MD5,
131191783Srmacklem     SSL_kRSA,
132191783Srmacklem     SSL_aRSA,
133191783Srmacklem     SSL_eNULL,
134191783Srmacklem     SSL_MD5,
135191783Srmacklem     SSL_SSLV2,
136191783Srmacklem     SSL_EXPORT | SSL_EXP40 | SSL_STRONG_NONE,
137191783Srmacklem     0,
138191783Srmacklem     0,
139191783Srmacklem     0,
140191783Srmacklem     },
141207082Srmacklem# endif
142191783Srmacklem
143191783Srmacklem/* RC4_128_WITH_MD5 */
144191783Srmacklem    {
145191783Srmacklem     1,
146228217Srmacklem     SSL2_TXT_RC4_128_WITH_MD5,
147228217Srmacklem     SSL2_CK_RC4_128_WITH_MD5,
148191783Srmacklem     SSL_kRSA,
149191783Srmacklem     SSL_aRSA,
150191783Srmacklem     SSL_RC4,
151191783Srmacklem     SSL_MD5,
152191783Srmacklem     SSL_SSLV2,
153191783Srmacklem     SSL_NOT_EXP | SSL_MEDIUM,
154191783Srmacklem     0,
155191783Srmacklem     128,
156191783Srmacklem     128,
157191783Srmacklem     },
158191783Srmacklem
159191783Srmacklem/* RC4_128_EXPORT40_WITH_MD5 */
160191783Srmacklem    {
161191783Srmacklem     1,
162191783Srmacklem     SSL2_TXT_RC4_128_EXPORT40_WITH_MD5,
163191783Srmacklem     SSL2_CK_RC4_128_EXPORT40_WITH_MD5,
164191783Srmacklem     SSL_kRSA,
165191783Srmacklem     SSL_aRSA,
166191783Srmacklem     SSL_RC4,
167191783Srmacklem     SSL_MD5,
168191783Srmacklem     SSL_SSLV2,
169191783Srmacklem     SSL_EXPORT | SSL_EXP40,
170191783Srmacklem     SSL2_CF_5_BYTE_ENC,
171191783Srmacklem     40,
172191783Srmacklem     128,
173191783Srmacklem     },
174191783Srmacklem
175191783Srmacklem/* RC2_128_CBC_WITH_MD5 */
176191783Srmacklem    {
177191783Srmacklem     1,
178191783Srmacklem     SSL2_TXT_RC2_128_CBC_WITH_MD5,
179191783Srmacklem     SSL2_CK_RC2_128_CBC_WITH_MD5,
180191783Srmacklem     SSL_kRSA,
181191783Srmacklem     SSL_aRSA,
182191783Srmacklem     SSL_RC2,
183191783Srmacklem     SSL_MD5,
184191783Srmacklem     SSL_SSLV2,
185191783Srmacklem     SSL_NOT_EXP | SSL_MEDIUM,
186191783Srmacklem     0,
187191783Srmacklem     128,
188191783Srmacklem     128,
189191783Srmacklem     },
190191783Srmacklem
191191783Srmacklem/* RC2_128_CBC_EXPORT40_WITH_MD5 */
192191783Srmacklem    {
193191783Srmacklem     1,
194191783Srmacklem     SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5,
195191783Srmacklem     SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5,
196191783Srmacklem     SSL_kRSA,
197191783Srmacklem     SSL_aRSA,
198191783Srmacklem     SSL_RC2,
199191783Srmacklem     SSL_MD5,
200191783Srmacklem     SSL_SSLV2,
201191783Srmacklem     SSL_EXPORT | SSL_EXP40,
202191783Srmacklem     SSL2_CF_5_BYTE_ENC,
203191783Srmacklem     40,
204191783Srmacklem     128,
205191783Srmacklem     },
206191783Srmacklem
207191783Srmacklem# ifndef OPENSSL_NO_IDEA
208191783Srmacklem/* IDEA_128_CBC_WITH_MD5 */
209191783Srmacklem    {
210191783Srmacklem     1,
211191783Srmacklem     SSL2_TXT_IDEA_128_CBC_WITH_MD5,
212191783Srmacklem     SSL2_CK_IDEA_128_CBC_WITH_MD5,
213191783Srmacklem     SSL_kRSA,
214191783Srmacklem     SSL_aRSA,
215191783Srmacklem     SSL_IDEA,
216191783Srmacklem     SSL_MD5,
217191783Srmacklem     SSL_SSLV2,
218191783Srmacklem     SSL_NOT_EXP | SSL_MEDIUM,
219191783Srmacklem     0,
220191783Srmacklem     128,
221191783Srmacklem     128,
222191783Srmacklem     },
223191783Srmacklem# endif
224191783Srmacklem
225191783Srmacklem/* DES_64_CBC_WITH_MD5 */
226191783Srmacklem    {
227191783Srmacklem     1,
228191783Srmacklem     SSL2_TXT_DES_64_CBC_WITH_MD5,
229191783Srmacklem     SSL2_CK_DES_64_CBC_WITH_MD5,
230222719Srmacklem     SSL_kRSA,
231191783Srmacklem     SSL_aRSA,
232191783Srmacklem     SSL_DES,
233191783Srmacklem     SSL_MD5,
234191783Srmacklem     SSL_SSLV2,
235191783Srmacklem     SSL_NOT_EXP | SSL_LOW,
236191783Srmacklem     0,
237191783Srmacklem     56,
238191783Srmacklem     56,
239191783Srmacklem     },
240191783Srmacklem
241191783Srmacklem/* DES_192_EDE3_CBC_WITH_MD5 */
242191783Srmacklem    {
243191783Srmacklem     1,
244191783Srmacklem     SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5,
245191783Srmacklem     SSL2_CK_DES_192_EDE3_CBC_WITH_MD5,
246191783Srmacklem     SSL_kRSA,
247191783Srmacklem     SSL_aRSA,
248191783Srmacklem     SSL_3DES,
249191783Srmacklem     SSL_MD5,
250191783Srmacklem     SSL_SSLV2,
251191783Srmacklem     SSL_NOT_EXP | SSL_HIGH,
252191783Srmacklem     0,
253191783Srmacklem     112,
254191783Srmacklem     168,
255191783Srmacklem     },
256191783Srmacklem
257191783Srmacklem# if 0
258191783Srmacklem/* RC4_64_WITH_MD5 */
259191783Srmacklem    {
260191783Srmacklem     1,
261191783Srmacklem     SSL2_TXT_RC4_64_WITH_MD5,
262191783Srmacklem     SSL2_CK_RC4_64_WITH_MD5,
263191783Srmacklem     SSL_kRSA,
264191783Srmacklem     SSL_aRSA,
265191783Srmacklem     SSL_RC4,
266191783Srmacklem     SSL_MD5,
267191783Srmacklem     SSL_SSLV2,
268191783Srmacklem     SSL_NOT_EXP | SSL_LOW,
269191783Srmacklem     SSL2_CF_8_BYTE_ENC,
270191783Srmacklem     64,
271191783Srmacklem     64,
272191783Srmacklem     },
273191783Srmacklem# endif
274191783Srmacklem
275191783Srmacklem# if 0
276191783Srmacklem/* NULL SSLeay (testing) */
277191783Srmacklem    {
278206688Srmacklem     0,
279206688Srmacklem     SSL2_TXT_NULL,
280206688Srmacklem     SSL2_CK_NULL,
281206688Srmacklem     0,
282206688Srmacklem     0,
283206688Srmacklem     0,
284206688Srmacklem     0,
285191783Srmacklem     SSL_SSLV2,
286191783Srmacklem     SSL_STRONG_NONE,
287191783Srmacklem     0,
288191783Srmacklem     0,
289191783Srmacklem     0,
290191783Srmacklem     },
291191783Srmacklem# endif
292191783Srmacklem
293191783Srmacklem/* end of list :-) */
294191783Srmacklem};
295191783Srmacklem
296191783Srmacklemlong ssl2_default_timeout(void)
297191783Srmacklem{
298191783Srmacklem    return (300);
299191783Srmacklem}
300191783Srmacklem
301191783Srmacklemint ssl2_num_ciphers(void)
302191783Srmacklem{
303191783Srmacklem    return (SSL2_NUM_CIPHERS);
304191783Srmacklem}
305191783Srmacklem
306191783Srmacklemconst SSL_CIPHER *ssl2_get_cipher(unsigned int u)
307191783Srmacklem{
308191783Srmacklem    if (u < SSL2_NUM_CIPHERS)
309191783Srmacklem        return (&(ssl2_ciphers[SSL2_NUM_CIPHERS - 1 - u]));
310191783Srmacklem    else
311191783Srmacklem        return (NULL);
312191783Srmacklem}
313191783Srmacklem
314191783Srmacklemint ssl2_pending(const SSL *s)
315191783Srmacklem{
316191783Srmacklem    return SSL_in_init(s) ? 0 : s->s2->ract_data_length;
317191783Srmacklem}
318191783Srmacklem
319191783Srmacklemint ssl2_new(SSL *s)
320191783Srmacklem{
321191783Srmacklem    SSL2_STATE *s2;
322191783Srmacklem
323191783Srmacklem    if ((s2 = OPENSSL_malloc(sizeof *s2)) == NULL)
324191783Srmacklem        goto err;
325191783Srmacklem    memset(s2, 0, sizeof *s2);
326191783Srmacklem
327191783Srmacklem# if SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER + 3 > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2
328191783Srmacklem#  error "assertion failed"
329191783Srmacklem# endif
330191783Srmacklem
331191783Srmacklem    if ((s2->rbuf =
332191783Srmacklem         OPENSSL_malloc(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2)) == NULL)
333191783Srmacklem        goto err;
334191783Srmacklem    /*
335191783Srmacklem     * wbuf needs one byte more because when using two-byte headers, we leave
336191783Srmacklem     * the first byte unused in do_ssl_write (s2_pkt.c)
337191783Srmacklem     */
338191783Srmacklem    if ((s2->wbuf =
339191783Srmacklem         OPENSSL_malloc(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 3)) == NULL)
340191783Srmacklem        goto err;
341191783Srmacklem    s->s2 = s2;
342191783Srmacklem
343191783Srmacklem    ssl2_clear(s);
344191783Srmacklem    return (1);
345191783Srmacklem err:
346191783Srmacklem    if (s2 != NULL) {
347191783Srmacklem        if (s2->wbuf != NULL)
348191783Srmacklem            OPENSSL_free(s2->wbuf);
349191783Srmacklem        if (s2->rbuf != NULL)
350191783Srmacklem            OPENSSL_free(s2->rbuf);
351191783Srmacklem        OPENSSL_free(s2);
352191783Srmacklem    }
353191783Srmacklem    return (0);
354191783Srmacklem}
355191783Srmacklem
356191783Srmacklemvoid ssl2_free(SSL *s)
357191783Srmacklem{
358191783Srmacklem    SSL2_STATE *s2;
359191783Srmacklem
360191783Srmacklem    if (s == NULL)
361191783Srmacklem        return;
362191783Srmacklem
363191783Srmacklem    s2 = s->s2;
364191783Srmacklem    if (s2->rbuf != NULL)
365191783Srmacklem        OPENSSL_free(s2->rbuf);
366191783Srmacklem    if (s2->wbuf != NULL)
367191783Srmacklem        OPENSSL_free(s2->wbuf);
368191783Srmacklem    OPENSSL_cleanse(s2, sizeof *s2);
369191783Srmacklem    OPENSSL_free(s2);
370191783Srmacklem    s->s2 = NULL;
371191783Srmacklem}
372191783Srmacklem
373191783Srmacklemvoid ssl2_clear(SSL *s)
374191783Srmacklem{
375191783Srmacklem    SSL2_STATE *s2;
376191783Srmacklem    unsigned char *rbuf, *wbuf;
377191783Srmacklem
378191783Srmacklem    s2 = s->s2;
379191783Srmacklem
380191783Srmacklem    rbuf = s2->rbuf;
381191783Srmacklem    wbuf = s2->wbuf;
382191783Srmacklem
383191783Srmacklem    memset(s2, 0, sizeof *s2);
384191783Srmacklem
385191783Srmacklem    s2->rbuf = rbuf;
386191783Srmacklem    s2->wbuf = wbuf;
387191783Srmacklem    s2->clear_text = 1;
388191783Srmacklem    s->packet = s2->rbuf;
389191783Srmacklem    s->version = SSL2_VERSION;
390191783Srmacklem    s->packet_length = 0;
391191783Srmacklem}
392191783Srmacklem
393191783Srmacklemlong ssl2_ctrl(SSL *s, int cmd, long larg, void *parg)
394191783Srmacklem{
395191783Srmacklem    int ret = 0;
396191783Srmacklem
397191783Srmacklem    switch (cmd) {
398191783Srmacklem    case SSL_CTRL_GET_SESSION_REUSED:
399191783Srmacklem        ret = s->hit;
400191783Srmacklem        break;
401191783Srmacklem    case SSL_CTRL_CHECK_PROTO_VERSION:
402191783Srmacklem        return ssl3_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, larg, parg);
403191783Srmacklem    default:
404191783Srmacklem        break;
405191783Srmacklem    }
406191783Srmacklem    return (ret);
407191783Srmacklem}
408191783Srmacklem
409191783Srmacklemlong ssl2_callback_ctrl(SSL *s, int cmd, void (*fp) (void))
410191783Srmacklem{
411191783Srmacklem    return (0);
412191783Srmacklem}
413191783Srmacklem
414191783Srmacklemlong ssl2_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
415191783Srmacklem{
416191783Srmacklem    return (0);
417191783Srmacklem}
418191783Srmacklem
419191783Srmacklemlong ssl2_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void))
420191783Srmacklem{
421191783Srmacklem    return (0);
422191783Srmacklem}
423191783Srmacklem
424191783Srmacklem/*
425191783Srmacklem * This function needs to check if the ciphers required are actually
426191783Srmacklem * available
427191783Srmacklem */
428191783Srmacklemconst SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p)
429191783Srmacklem{
430191783Srmacklem    SSL_CIPHER c;
431191783Srmacklem    const SSL_CIPHER *cp;
432191783Srmacklem    unsigned long id;
433191783Srmacklem
434191783Srmacklem    id = 0x02000000L | ((unsigned long)p[0] << 16L) |
435191783Srmacklem        ((unsigned long)p[1] << 8L) | (unsigned long)p[2];
436191783Srmacklem    c.id = id;
437191783Srmacklem    cp = OBJ_bsearch_ssl_cipher_id(&c, ssl2_ciphers, SSL2_NUM_CIPHERS);
438191783Srmacklem    if ((cp == NULL) || (cp->valid == 0))
439191783Srmacklem        return NULL;
440191783Srmacklem    else
441191783Srmacklem        return cp;
442191783Srmacklem}
443191783Srmacklem
444191783Srmacklemint ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
445191783Srmacklem{
446191783Srmacklem    long l;
447191783Srmacklem
448191783Srmacklem    if (p != NULL) {
449191783Srmacklem        l = c->id;
450191783Srmacklem        if ((l & 0xff000000) != 0x02000000 && l != SSL3_CK_FALLBACK_SCSV)
451191783Srmacklem            return (0);
452191783Srmacklem        p[0] = ((unsigned char)(l >> 16L)) & 0xFF;
453191783Srmacklem        p[1] = ((unsigned char)(l >> 8L)) & 0xFF;
454191783Srmacklem        p[2] = ((unsigned char)(l)) & 0xFF;
455191783Srmacklem    }
456191783Srmacklem    return (3);
457191783Srmacklem}
458191783Srmacklem
459195510Srmacklemint ssl2_generate_key_material(SSL *s)
460191783Srmacklem{
461191783Srmacklem    unsigned int i;
462191783Srmacklem    EVP_MD_CTX ctx;
463191783Srmacklem    unsigned char *km;
464191783Srmacklem    unsigned char c = '0';
465191783Srmacklem    const EVP_MD *md5;
466191783Srmacklem    int md_size;
467191783Srmacklem
468191783Srmacklem    md5 = EVP_md5();
469191783Srmacklem
470191783Srmacklem# ifdef CHARSET_EBCDIC
471191783Srmacklem    c = os_toascii['0'];        /* Must be an ASCII '0', not EBCDIC '0', see
472191783Srmacklem                                 * SSLv2 docu */
473191783Srmacklem# endif
474191783Srmacklem    EVP_MD_CTX_init(&ctx);
475191783Srmacklem    km = s->s2->key_material;
476191783Srmacklem
477191783Srmacklem    if (s->session->master_key_length < 0 ||
478191783Srmacklem        s->session->master_key_length > (int)sizeof(s->session->master_key)) {
479191783Srmacklem        SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR);
480191783Srmacklem        return 0;
481191783Srmacklem    }
482191783Srmacklem    md_size = EVP_MD_size(md5);
483191783Srmacklem    if (md_size < 0)
484191783Srmacklem        return 0;
485206818Srmacklem    for (i = 0; i < s->s2->key_material_length; i += md_size) {
486206818Srmacklem        if (((km - s->s2->key_material) + md_size) >
487206818Srmacklem            (int)sizeof(s->s2->key_material)) {
488206818Srmacklem            /*
489206818Srmacklem             * EVP_DigestFinal_ex() below would write beyond buffer
490206818Srmacklem             */
491206818Srmacklem            SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR);
492191783Srmacklem            return 0;
493191783Srmacklem        }
494191783Srmacklem
495191783Srmacklem        EVP_DigestInit_ex(&ctx, md5, NULL);
496191783Srmacklem
497191783Srmacklem        OPENSSL_assert(s->session->master_key_length >= 0
498191783Srmacklem                       && s->session->master_key_length
499191783Srmacklem                       <= (int)sizeof(s->session->master_key));
500191783Srmacklem        EVP_DigestUpdate(&ctx, s->session->master_key,
501191783Srmacklem                         s->session->master_key_length);
502191783Srmacklem        EVP_DigestUpdate(&ctx, &c, 1);
503191783Srmacklem        c++;
504191783Srmacklem        EVP_DigestUpdate(&ctx, s->s2->challenge, s->s2->challenge_length);
505191783Srmacklem        EVP_DigestUpdate(&ctx, s->s2->conn_id, s->s2->conn_id_length);
506191783Srmacklem        EVP_DigestFinal_ex(&ctx, km, NULL);
507191783Srmacklem        km += md_size;
508191783Srmacklem    }
509191783Srmacklem
510191783Srmacklem    EVP_MD_CTX_cleanup(&ctx);
511191783Srmacklem    return 1;
512191783Srmacklem}
513191783Srmacklem
514191783Srmacklemvoid ssl2_return_error(SSL *s, int err)
515191783Srmacklem{
516191783Srmacklem    if (!s->error) {
517191783Srmacklem        s->error = 3;
518191783Srmacklem        s->error_code = err;
519191783Srmacklem
520191783Srmacklem        ssl2_write_error(s);
521191783Srmacklem    }
522191783Srmacklem}
523191783Srmacklem
524191783Srmacklemvoid ssl2_write_error(SSL *s)
525222719Srmacklem{
526223774Srmacklem    unsigned char buf[3];
527223774Srmacklem    int i, error;
528223774Srmacklem
529223774Srmacklem    buf[0] = SSL2_MT_ERROR;
530223774Srmacklem    buf[1] = (s->error_code >> 8) & 0xff;
531223774Srmacklem    buf[2] = (s->error_code) & 0xff;
532223774Srmacklem
533223774Srmacklem/*      state=s->rwstate;*/
534223774Srmacklem
535223774Srmacklem    error = s->error;           /* number of bytes left to write */
536223774Srmacklem    s->error = 0;
537223774Srmacklem    OPENSSL_assert(error >= 0 && error <= (int)sizeof(buf));
538223774Srmacklem    i = ssl2_write(s, &(buf[3 - error]), error);
539223774Srmacklem
540191783Srmacklem/*      if (i == error) s->rwstate=state; */
541195510Srmacklem
542195510Srmacklem    if (i < 0)
543195510Srmacklem        s->error = error;
544191783Srmacklem    else {
545191783Srmacklem        s->error = error - i;
546191783Srmacklem
547195510Srmacklem        if (s->error == 0)
548195510Srmacklem            if (s->msg_callback) {
549195510Srmacklem                /* ERROR */
550195510Srmacklem                s->msg_callback(1, s->version, 0, buf, 3, s,
551195510Srmacklem                                s->msg_callback_arg);
552195510Srmacklem            }
553195510Srmacklem    }
554191783Srmacklem}
555195510Srmacklem
556195510Srmacklemint ssl2_shutdown(SSL *s)
557191783Srmacklem{
558191783Srmacklem    s->shutdown = (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
559191783Srmacklem    return (1);
560191783Srmacklem}
561191783Srmacklem#else                           /* !OPENSSL_NO_SSL2 */
562231133Srmacklem
563231133Srmacklem# if PEDANTIC
564231133Srmacklemstatic void *dummy = &dummy;
565231133Srmacklem# endif
566231133Srmacklem
567231133Srmacklem#endif
568191783Srmacklem