1*0Sstevel@tonic-gate /* ssl/s2_pkt.c */
2*0Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3*0Sstevel@tonic-gate * All rights reserved.
4*0Sstevel@tonic-gate *
5*0Sstevel@tonic-gate * This package is an SSL implementation written
6*0Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com).
7*0Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as
10*0Sstevel@tonic-gate * the following conditions are aheared to. The following conditions
11*0Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA,
12*0Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13*0Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms
14*0Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15*0Sstevel@tonic-gate *
16*0Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in
17*0Sstevel@tonic-gate * the code are not to be removed.
18*0Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution
19*0Sstevel@tonic-gate * as the author of the parts of the library used.
20*0Sstevel@tonic-gate * This can be in the form of a textual message at program startup or
21*0Sstevel@tonic-gate * in documentation (online or textual) provided with the package.
22*0Sstevel@tonic-gate *
23*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
24*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions
25*0Sstevel@tonic-gate * are met:
26*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright
27*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
28*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
29*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the
30*0Sstevel@tonic-gate * documentation and/or other materials provided with the distribution.
31*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software
32*0Sstevel@tonic-gate * must display the following acknowledgement:
33*0Sstevel@tonic-gate * "This product includes cryptographic software written by
34*0Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)"
35*0Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library
36*0Sstevel@tonic-gate * being used are not cryptographic related :-).
37*0Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from
38*0Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement:
39*0Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40*0Sstevel@tonic-gate *
41*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42*0Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44*0Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45*0Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46*0Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47*0Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49*0Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50*0Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51*0Sstevel@tonic-gate * SUCH DAMAGE.
52*0Sstevel@tonic-gate *
53*0Sstevel@tonic-gate * The licence and distribution terms for any publically available version or
54*0Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be
55*0Sstevel@tonic-gate * copied and put under another distribution licence
56*0Sstevel@tonic-gate * [including the GNU Public Licence.]
57*0Sstevel@tonic-gate */
58*0Sstevel@tonic-gate /* ====================================================================
59*0Sstevel@tonic-gate * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
60*0Sstevel@tonic-gate *
61*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
62*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions
63*0Sstevel@tonic-gate * are met:
64*0Sstevel@tonic-gate *
65*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
66*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
67*0Sstevel@tonic-gate *
68*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
69*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in
70*0Sstevel@tonic-gate * the documentation and/or other materials provided with the
71*0Sstevel@tonic-gate * distribution.
72*0Sstevel@tonic-gate *
73*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this
74*0Sstevel@tonic-gate * software must display the following acknowledgment:
75*0Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
76*0Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77*0Sstevel@tonic-gate *
78*0Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79*0Sstevel@tonic-gate * endorse or promote products derived from this software without
80*0Sstevel@tonic-gate * prior written permission. For written permission, please contact
81*0Sstevel@tonic-gate * openssl-core@openssl.org.
82*0Sstevel@tonic-gate *
83*0Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL"
84*0Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written
85*0Sstevel@tonic-gate * permission of the OpenSSL Project.
86*0Sstevel@tonic-gate *
87*0Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following
88*0Sstevel@tonic-gate * acknowledgment:
89*0Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
90*0Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91*0Sstevel@tonic-gate *
92*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93*0Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95*0Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96*0Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97*0Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98*0Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99*0Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101*0Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102*0Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103*0Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE.
104*0Sstevel@tonic-gate * ====================================================================
105*0Sstevel@tonic-gate *
106*0Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young
107*0Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim
108*0Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com).
109*0Sstevel@tonic-gate *
110*0Sstevel@tonic-gate */
111*0Sstevel@tonic-gate
112*0Sstevel@tonic-gate #include "ssl_locl.h"
113*0Sstevel@tonic-gate #ifndef OPENSSL_NO_SSL2
114*0Sstevel@tonic-gate #include <stdio.h>
115*0Sstevel@tonic-gate #include <errno.h>
116*0Sstevel@tonic-gate #define USE_SOCKETS
117*0Sstevel@tonic-gate
118*0Sstevel@tonic-gate static int read_n(SSL *s,unsigned int n,unsigned int max,unsigned int extend);
119*0Sstevel@tonic-gate static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len);
120*0Sstevel@tonic-gate static int write_pending(SSL *s, const unsigned char *buf, unsigned int len);
121*0Sstevel@tonic-gate static int ssl_mt_error(int n);
122*0Sstevel@tonic-gate
123*0Sstevel@tonic-gate
124*0Sstevel@tonic-gate /* SSL 2.0 imlementation for SSL_read/SSL_peek -
125*0Sstevel@tonic-gate * This routine will return 0 to len bytes, decrypted etc if required.
126*0Sstevel@tonic-gate */
ssl2_read_internal(SSL * s,void * buf,int len,int peek)127*0Sstevel@tonic-gate static int ssl2_read_internal(SSL *s, void *buf, int len, int peek)
128*0Sstevel@tonic-gate {
129*0Sstevel@tonic-gate int n;
130*0Sstevel@tonic-gate unsigned char mac[MAX_MAC_SIZE];
131*0Sstevel@tonic-gate unsigned char *p;
132*0Sstevel@tonic-gate int i;
133*0Sstevel@tonic-gate unsigned int mac_size;
134*0Sstevel@tonic-gate
135*0Sstevel@tonic-gate ssl2_read_again:
136*0Sstevel@tonic-gate if (SSL_in_init(s) && !s->in_handshake)
137*0Sstevel@tonic-gate {
138*0Sstevel@tonic-gate n=s->handshake_func(s);
139*0Sstevel@tonic-gate if (n < 0) return(n);
140*0Sstevel@tonic-gate if (n == 0)
141*0Sstevel@tonic-gate {
142*0Sstevel@tonic-gate SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_SSL_HANDSHAKE_FAILURE);
143*0Sstevel@tonic-gate return(-1);
144*0Sstevel@tonic-gate }
145*0Sstevel@tonic-gate }
146*0Sstevel@tonic-gate
147*0Sstevel@tonic-gate clear_sys_error();
148*0Sstevel@tonic-gate s->rwstate=SSL_NOTHING;
149*0Sstevel@tonic-gate if (len <= 0) return(len);
150*0Sstevel@tonic-gate
151*0Sstevel@tonic-gate if (s->s2->ract_data_length != 0) /* read from buffer */
152*0Sstevel@tonic-gate {
153*0Sstevel@tonic-gate if (len > s->s2->ract_data_length)
154*0Sstevel@tonic-gate n=s->s2->ract_data_length;
155*0Sstevel@tonic-gate else
156*0Sstevel@tonic-gate n=len;
157*0Sstevel@tonic-gate
158*0Sstevel@tonic-gate memcpy(buf,s->s2->ract_data,(unsigned int)n);
159*0Sstevel@tonic-gate if (!peek)
160*0Sstevel@tonic-gate {
161*0Sstevel@tonic-gate s->s2->ract_data_length-=n;
162*0Sstevel@tonic-gate s->s2->ract_data+=n;
163*0Sstevel@tonic-gate if (s->s2->ract_data_length == 0)
164*0Sstevel@tonic-gate s->rstate=SSL_ST_READ_HEADER;
165*0Sstevel@tonic-gate }
166*0Sstevel@tonic-gate
167*0Sstevel@tonic-gate return(n);
168*0Sstevel@tonic-gate }
169*0Sstevel@tonic-gate
170*0Sstevel@tonic-gate /* s->s2->ract_data_length == 0
171*0Sstevel@tonic-gate *
172*0Sstevel@tonic-gate * Fill the buffer, then goto ssl2_read_again.
173*0Sstevel@tonic-gate */
174*0Sstevel@tonic-gate
175*0Sstevel@tonic-gate if (s->rstate == SSL_ST_READ_HEADER)
176*0Sstevel@tonic-gate {
177*0Sstevel@tonic-gate if (s->first_packet)
178*0Sstevel@tonic-gate {
179*0Sstevel@tonic-gate n=read_n(s,5,SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2,0);
180*0Sstevel@tonic-gate if (n <= 0) return(n); /* error or non-blocking */
181*0Sstevel@tonic-gate s->first_packet=0;
182*0Sstevel@tonic-gate p=s->packet;
183*0Sstevel@tonic-gate if (!((p[0] & 0x80) && (
184*0Sstevel@tonic-gate (p[2] == SSL2_MT_CLIENT_HELLO) ||
185*0Sstevel@tonic-gate (p[2] == SSL2_MT_SERVER_HELLO))))
186*0Sstevel@tonic-gate {
187*0Sstevel@tonic-gate SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_NON_SSLV2_INITIAL_PACKET);
188*0Sstevel@tonic-gate return(-1);
189*0Sstevel@tonic-gate }
190*0Sstevel@tonic-gate }
191*0Sstevel@tonic-gate else
192*0Sstevel@tonic-gate {
193*0Sstevel@tonic-gate n=read_n(s,2,SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2,0);
194*0Sstevel@tonic-gate if (n <= 0) return(n); /* error or non-blocking */
195*0Sstevel@tonic-gate }
196*0Sstevel@tonic-gate /* part read stuff */
197*0Sstevel@tonic-gate
198*0Sstevel@tonic-gate s->rstate=SSL_ST_READ_BODY;
199*0Sstevel@tonic-gate p=s->packet;
200*0Sstevel@tonic-gate /* Do header */
201*0Sstevel@tonic-gate /*s->s2->padding=0;*/
202*0Sstevel@tonic-gate s->s2->escape=0;
203*0Sstevel@tonic-gate s->s2->rlength=(((unsigned int)p[0])<<8)|((unsigned int)p[1]);
204*0Sstevel@tonic-gate if ((p[0] & TWO_BYTE_BIT)) /* Two byte header? */
205*0Sstevel@tonic-gate {
206*0Sstevel@tonic-gate s->s2->three_byte_header=0;
207*0Sstevel@tonic-gate s->s2->rlength&=TWO_BYTE_MASK;
208*0Sstevel@tonic-gate }
209*0Sstevel@tonic-gate else
210*0Sstevel@tonic-gate {
211*0Sstevel@tonic-gate s->s2->three_byte_header=1;
212*0Sstevel@tonic-gate s->s2->rlength&=THREE_BYTE_MASK;
213*0Sstevel@tonic-gate
214*0Sstevel@tonic-gate /* security >s2->escape */
215*0Sstevel@tonic-gate s->s2->escape=((p[0] & SEC_ESC_BIT))?1:0;
216*0Sstevel@tonic-gate }
217*0Sstevel@tonic-gate }
218*0Sstevel@tonic-gate
219*0Sstevel@tonic-gate if (s->rstate == SSL_ST_READ_BODY)
220*0Sstevel@tonic-gate {
221*0Sstevel@tonic-gate n=s->s2->rlength+2+s->s2->three_byte_header;
222*0Sstevel@tonic-gate if (n > (int)s->packet_length)
223*0Sstevel@tonic-gate {
224*0Sstevel@tonic-gate n-=s->packet_length;
225*0Sstevel@tonic-gate i=read_n(s,(unsigned int)n,(unsigned int)n,1);
226*0Sstevel@tonic-gate if (i <= 0) return(i); /* ERROR */
227*0Sstevel@tonic-gate }
228*0Sstevel@tonic-gate
229*0Sstevel@tonic-gate p= &(s->packet[2]);
230*0Sstevel@tonic-gate s->rstate=SSL_ST_READ_HEADER;
231*0Sstevel@tonic-gate if (s->s2->three_byte_header)
232*0Sstevel@tonic-gate s->s2->padding= *(p++);
233*0Sstevel@tonic-gate else s->s2->padding=0;
234*0Sstevel@tonic-gate
235*0Sstevel@tonic-gate /* Data portion */
236*0Sstevel@tonic-gate if (s->s2->clear_text)
237*0Sstevel@tonic-gate {
238*0Sstevel@tonic-gate mac_size = 0;
239*0Sstevel@tonic-gate s->s2->mac_data=p;
240*0Sstevel@tonic-gate s->s2->ract_data=p;
241*0Sstevel@tonic-gate if (s->s2->padding)
242*0Sstevel@tonic-gate {
243*0Sstevel@tonic-gate SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_ILLEGAL_PADDING);
244*0Sstevel@tonic-gate return(-1);
245*0Sstevel@tonic-gate }
246*0Sstevel@tonic-gate }
247*0Sstevel@tonic-gate else
248*0Sstevel@tonic-gate {
249*0Sstevel@tonic-gate mac_size=EVP_MD_size(s->read_hash);
250*0Sstevel@tonic-gate OPENSSL_assert(mac_size <= MAX_MAC_SIZE);
251*0Sstevel@tonic-gate s->s2->mac_data=p;
252*0Sstevel@tonic-gate s->s2->ract_data= &p[mac_size];
253*0Sstevel@tonic-gate if (s->s2->padding + mac_size > s->s2->rlength)
254*0Sstevel@tonic-gate {
255*0Sstevel@tonic-gate SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_ILLEGAL_PADDING);
256*0Sstevel@tonic-gate return(-1);
257*0Sstevel@tonic-gate }
258*0Sstevel@tonic-gate }
259*0Sstevel@tonic-gate
260*0Sstevel@tonic-gate s->s2->ract_data_length=s->s2->rlength;
261*0Sstevel@tonic-gate /* added a check for length > max_size in case
262*0Sstevel@tonic-gate * encryption was not turned on yet due to an error */
263*0Sstevel@tonic-gate if ((!s->s2->clear_text) &&
264*0Sstevel@tonic-gate (s->s2->rlength >= mac_size))
265*0Sstevel@tonic-gate {
266*0Sstevel@tonic-gate ssl2_enc(s,0);
267*0Sstevel@tonic-gate s->s2->ract_data_length-=mac_size;
268*0Sstevel@tonic-gate ssl2_mac(s,mac,0);
269*0Sstevel@tonic-gate s->s2->ract_data_length-=s->s2->padding;
270*0Sstevel@tonic-gate if ( (memcmp(mac,s->s2->mac_data,
271*0Sstevel@tonic-gate (unsigned int)mac_size) != 0) ||
272*0Sstevel@tonic-gate (s->s2->rlength%EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0))
273*0Sstevel@tonic-gate {
274*0Sstevel@tonic-gate SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_MAC_DECODE);
275*0Sstevel@tonic-gate return(-1);
276*0Sstevel@tonic-gate }
277*0Sstevel@tonic-gate }
278*0Sstevel@tonic-gate INC32(s->s2->read_sequence); /* expect next number */
279*0Sstevel@tonic-gate /* s->s2->ract_data is now available for processing */
280*0Sstevel@tonic-gate
281*0Sstevel@tonic-gate /* Possibly the packet that we just read had 0 actual data bytes.
282*0Sstevel@tonic-gate * (SSLeay/OpenSSL itself never sends such packets; see ssl2_write.)
283*0Sstevel@tonic-gate * In this case, returning 0 would be interpreted by the caller
284*0Sstevel@tonic-gate * as indicating EOF, so it's not a good idea. Instead, we just
285*0Sstevel@tonic-gate * continue reading; thus ssl2_read_internal may have to process
286*0Sstevel@tonic-gate * multiple packets before it can return.
287*0Sstevel@tonic-gate *
288*0Sstevel@tonic-gate * [Note that using select() for blocking sockets *never* guarantees
289*0Sstevel@tonic-gate * that the next SSL_read will not block -- the available
290*0Sstevel@tonic-gate * data may contain incomplete packets, and except for SSL 2,
291*0Sstevel@tonic-gate * renegotiation can confuse things even more.] */
292*0Sstevel@tonic-gate
293*0Sstevel@tonic-gate goto ssl2_read_again; /* This should really be
294*0Sstevel@tonic-gate * "return ssl2_read(s,buf,len)",
295*0Sstevel@tonic-gate * but that would allow for
296*0Sstevel@tonic-gate * denial-of-service attacks if a
297*0Sstevel@tonic-gate * C compiler is used that does not
298*0Sstevel@tonic-gate * recognize end-recursion. */
299*0Sstevel@tonic-gate }
300*0Sstevel@tonic-gate else
301*0Sstevel@tonic-gate {
302*0Sstevel@tonic-gate SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_STATE);
303*0Sstevel@tonic-gate return(-1);
304*0Sstevel@tonic-gate }
305*0Sstevel@tonic-gate }
306*0Sstevel@tonic-gate
ssl2_read(SSL * s,void * buf,int len)307*0Sstevel@tonic-gate int ssl2_read(SSL *s, void *buf, int len)
308*0Sstevel@tonic-gate {
309*0Sstevel@tonic-gate return ssl2_read_internal(s, buf, len, 0);
310*0Sstevel@tonic-gate }
311*0Sstevel@tonic-gate
ssl2_peek(SSL * s,void * buf,int len)312*0Sstevel@tonic-gate int ssl2_peek(SSL *s, void *buf, int len)
313*0Sstevel@tonic-gate {
314*0Sstevel@tonic-gate return ssl2_read_internal(s, buf, len, 1);
315*0Sstevel@tonic-gate }
316*0Sstevel@tonic-gate
read_n(SSL * s,unsigned int n,unsigned int max,unsigned int extend)317*0Sstevel@tonic-gate static int read_n(SSL *s, unsigned int n, unsigned int max,
318*0Sstevel@tonic-gate unsigned int extend)
319*0Sstevel@tonic-gate {
320*0Sstevel@tonic-gate int i,off,newb;
321*0Sstevel@tonic-gate
322*0Sstevel@tonic-gate /* if there is stuff still in the buffer from a previous read,
323*0Sstevel@tonic-gate * and there is more than we want, take some. */
324*0Sstevel@tonic-gate if (s->s2->rbuf_left >= (int)n)
325*0Sstevel@tonic-gate {
326*0Sstevel@tonic-gate if (extend)
327*0Sstevel@tonic-gate s->packet_length+=n;
328*0Sstevel@tonic-gate else
329*0Sstevel@tonic-gate {
330*0Sstevel@tonic-gate s->packet= &(s->s2->rbuf[s->s2->rbuf_offs]);
331*0Sstevel@tonic-gate s->packet_length=n;
332*0Sstevel@tonic-gate }
333*0Sstevel@tonic-gate s->s2->rbuf_left-=n;
334*0Sstevel@tonic-gate s->s2->rbuf_offs+=n;
335*0Sstevel@tonic-gate return(n);
336*0Sstevel@tonic-gate }
337*0Sstevel@tonic-gate
338*0Sstevel@tonic-gate if (!s->read_ahead) max=n;
339*0Sstevel@tonic-gate if (max > (unsigned int)(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2))
340*0Sstevel@tonic-gate max=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2;
341*0Sstevel@tonic-gate
342*0Sstevel@tonic-gate
343*0Sstevel@tonic-gate /* Else we want more than we have.
344*0Sstevel@tonic-gate * First, if there is some left or we want to extend */
345*0Sstevel@tonic-gate off=0;
346*0Sstevel@tonic-gate if ((s->s2->rbuf_left != 0) || ((s->packet_length != 0) && extend))
347*0Sstevel@tonic-gate {
348*0Sstevel@tonic-gate newb=s->s2->rbuf_left;
349*0Sstevel@tonic-gate if (extend)
350*0Sstevel@tonic-gate {
351*0Sstevel@tonic-gate off=s->packet_length;
352*0Sstevel@tonic-gate if (s->packet != s->s2->rbuf)
353*0Sstevel@tonic-gate memcpy(s->s2->rbuf,s->packet,
354*0Sstevel@tonic-gate (unsigned int)newb+off);
355*0Sstevel@tonic-gate }
356*0Sstevel@tonic-gate else if (s->s2->rbuf_offs != 0)
357*0Sstevel@tonic-gate {
358*0Sstevel@tonic-gate memcpy(s->s2->rbuf,&(s->s2->rbuf[s->s2->rbuf_offs]),
359*0Sstevel@tonic-gate (unsigned int)newb);
360*0Sstevel@tonic-gate s->s2->rbuf_offs=0;
361*0Sstevel@tonic-gate }
362*0Sstevel@tonic-gate s->s2->rbuf_left=0;
363*0Sstevel@tonic-gate }
364*0Sstevel@tonic-gate else
365*0Sstevel@tonic-gate newb=0;
366*0Sstevel@tonic-gate
367*0Sstevel@tonic-gate /* off is the offset to start writing too.
368*0Sstevel@tonic-gate * r->s2->rbuf_offs is the 'unread data', now 0.
369*0Sstevel@tonic-gate * newb is the number of new bytes so far
370*0Sstevel@tonic-gate */
371*0Sstevel@tonic-gate s->packet=s->s2->rbuf;
372*0Sstevel@tonic-gate while (newb < (int)n)
373*0Sstevel@tonic-gate {
374*0Sstevel@tonic-gate clear_sys_error();
375*0Sstevel@tonic-gate if (s->rbio != NULL)
376*0Sstevel@tonic-gate {
377*0Sstevel@tonic-gate s->rwstate=SSL_READING;
378*0Sstevel@tonic-gate i=BIO_read(s->rbio,(char *)&(s->s2->rbuf[off+newb]),
379*0Sstevel@tonic-gate max-newb);
380*0Sstevel@tonic-gate }
381*0Sstevel@tonic-gate else
382*0Sstevel@tonic-gate {
383*0Sstevel@tonic-gate SSLerr(SSL_F_READ_N,SSL_R_READ_BIO_NOT_SET);
384*0Sstevel@tonic-gate i= -1;
385*0Sstevel@tonic-gate }
386*0Sstevel@tonic-gate #ifdef PKT_DEBUG
387*0Sstevel@tonic-gate if (s->debug & 0x01) sleep(1);
388*0Sstevel@tonic-gate #endif
389*0Sstevel@tonic-gate if (i <= 0)
390*0Sstevel@tonic-gate {
391*0Sstevel@tonic-gate s->s2->rbuf_left+=newb;
392*0Sstevel@tonic-gate return(i);
393*0Sstevel@tonic-gate }
394*0Sstevel@tonic-gate newb+=i;
395*0Sstevel@tonic-gate }
396*0Sstevel@tonic-gate
397*0Sstevel@tonic-gate /* record unread data */
398*0Sstevel@tonic-gate if (newb > (int)n)
399*0Sstevel@tonic-gate {
400*0Sstevel@tonic-gate s->s2->rbuf_offs=n+off;
401*0Sstevel@tonic-gate s->s2->rbuf_left=newb-n;
402*0Sstevel@tonic-gate }
403*0Sstevel@tonic-gate else
404*0Sstevel@tonic-gate {
405*0Sstevel@tonic-gate s->s2->rbuf_offs=0;
406*0Sstevel@tonic-gate s->s2->rbuf_left=0;
407*0Sstevel@tonic-gate }
408*0Sstevel@tonic-gate if (extend)
409*0Sstevel@tonic-gate s->packet_length+=n;
410*0Sstevel@tonic-gate else
411*0Sstevel@tonic-gate s->packet_length=n;
412*0Sstevel@tonic-gate s->rwstate=SSL_NOTHING;
413*0Sstevel@tonic-gate return(n);
414*0Sstevel@tonic-gate }
415*0Sstevel@tonic-gate
ssl2_write(SSL * s,const void * _buf,int len)416*0Sstevel@tonic-gate int ssl2_write(SSL *s, const void *_buf, int len)
417*0Sstevel@tonic-gate {
418*0Sstevel@tonic-gate const unsigned char *buf=_buf;
419*0Sstevel@tonic-gate unsigned int n,tot;
420*0Sstevel@tonic-gate int i;
421*0Sstevel@tonic-gate
422*0Sstevel@tonic-gate if (SSL_in_init(s) && !s->in_handshake)
423*0Sstevel@tonic-gate {
424*0Sstevel@tonic-gate i=s->handshake_func(s);
425*0Sstevel@tonic-gate if (i < 0) return(i);
426*0Sstevel@tonic-gate if (i == 0)
427*0Sstevel@tonic-gate {
428*0Sstevel@tonic-gate SSLerr(SSL_F_SSL2_WRITE,SSL_R_SSL_HANDSHAKE_FAILURE);
429*0Sstevel@tonic-gate return(-1);
430*0Sstevel@tonic-gate }
431*0Sstevel@tonic-gate }
432*0Sstevel@tonic-gate
433*0Sstevel@tonic-gate if (s->error)
434*0Sstevel@tonic-gate {
435*0Sstevel@tonic-gate ssl2_write_error(s);
436*0Sstevel@tonic-gate if (s->error)
437*0Sstevel@tonic-gate return(-1);
438*0Sstevel@tonic-gate }
439*0Sstevel@tonic-gate
440*0Sstevel@tonic-gate clear_sys_error();
441*0Sstevel@tonic-gate s->rwstate=SSL_NOTHING;
442*0Sstevel@tonic-gate if (len <= 0) return(len);
443*0Sstevel@tonic-gate
444*0Sstevel@tonic-gate tot=s->s2->wnum;
445*0Sstevel@tonic-gate s->s2->wnum=0;
446*0Sstevel@tonic-gate
447*0Sstevel@tonic-gate n=(len-tot);
448*0Sstevel@tonic-gate for (;;)
449*0Sstevel@tonic-gate {
450*0Sstevel@tonic-gate i=do_ssl_write(s,&(buf[tot]),n);
451*0Sstevel@tonic-gate if (i <= 0)
452*0Sstevel@tonic-gate {
453*0Sstevel@tonic-gate s->s2->wnum=tot;
454*0Sstevel@tonic-gate return(i);
455*0Sstevel@tonic-gate }
456*0Sstevel@tonic-gate if ((i == (int)n) ||
457*0Sstevel@tonic-gate (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))
458*0Sstevel@tonic-gate {
459*0Sstevel@tonic-gate return(tot+i);
460*0Sstevel@tonic-gate }
461*0Sstevel@tonic-gate
462*0Sstevel@tonic-gate n-=i;
463*0Sstevel@tonic-gate tot+=i;
464*0Sstevel@tonic-gate }
465*0Sstevel@tonic-gate }
466*0Sstevel@tonic-gate
write_pending(SSL * s,const unsigned char * buf,unsigned int len)467*0Sstevel@tonic-gate static int write_pending(SSL *s, const unsigned char *buf, unsigned int len)
468*0Sstevel@tonic-gate {
469*0Sstevel@tonic-gate int i;
470*0Sstevel@tonic-gate
471*0Sstevel@tonic-gate /* s->s2->wpend_len != 0 MUST be true. */
472*0Sstevel@tonic-gate
473*0Sstevel@tonic-gate /* check that they have given us the same buffer to
474*0Sstevel@tonic-gate * write */
475*0Sstevel@tonic-gate if ((s->s2->wpend_tot > (int)len) ||
476*0Sstevel@tonic-gate ((s->s2->wpend_buf != buf) &&
477*0Sstevel@tonic-gate !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)))
478*0Sstevel@tonic-gate {
479*0Sstevel@tonic-gate SSLerr(SSL_F_WRITE_PENDING,SSL_R_BAD_WRITE_RETRY);
480*0Sstevel@tonic-gate return(-1);
481*0Sstevel@tonic-gate }
482*0Sstevel@tonic-gate
483*0Sstevel@tonic-gate for (;;)
484*0Sstevel@tonic-gate {
485*0Sstevel@tonic-gate clear_sys_error();
486*0Sstevel@tonic-gate if (s->wbio != NULL)
487*0Sstevel@tonic-gate {
488*0Sstevel@tonic-gate s->rwstate=SSL_WRITING;
489*0Sstevel@tonic-gate i=BIO_write(s->wbio,
490*0Sstevel@tonic-gate (char *)&(s->s2->write_ptr[s->s2->wpend_off]),
491*0Sstevel@tonic-gate (unsigned int)s->s2->wpend_len);
492*0Sstevel@tonic-gate }
493*0Sstevel@tonic-gate else
494*0Sstevel@tonic-gate {
495*0Sstevel@tonic-gate SSLerr(SSL_F_WRITE_PENDING,SSL_R_WRITE_BIO_NOT_SET);
496*0Sstevel@tonic-gate i= -1;
497*0Sstevel@tonic-gate }
498*0Sstevel@tonic-gate #ifdef PKT_DEBUG
499*0Sstevel@tonic-gate if (s->debug & 0x01) sleep(1);
500*0Sstevel@tonic-gate #endif
501*0Sstevel@tonic-gate if (i == s->s2->wpend_len)
502*0Sstevel@tonic-gate {
503*0Sstevel@tonic-gate s->s2->wpend_len=0;
504*0Sstevel@tonic-gate s->rwstate=SSL_NOTHING;
505*0Sstevel@tonic-gate return(s->s2->wpend_ret);
506*0Sstevel@tonic-gate }
507*0Sstevel@tonic-gate else if (i <= 0)
508*0Sstevel@tonic-gate return(i);
509*0Sstevel@tonic-gate s->s2->wpend_off+=i;
510*0Sstevel@tonic-gate s->s2->wpend_len-=i;
511*0Sstevel@tonic-gate }
512*0Sstevel@tonic-gate }
513*0Sstevel@tonic-gate
do_ssl_write(SSL * s,const unsigned char * buf,unsigned int len)514*0Sstevel@tonic-gate static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len)
515*0Sstevel@tonic-gate {
516*0Sstevel@tonic-gate unsigned int j,k,olen,p,mac_size,bs;
517*0Sstevel@tonic-gate register unsigned char *pp;
518*0Sstevel@tonic-gate
519*0Sstevel@tonic-gate olen=len;
520*0Sstevel@tonic-gate
521*0Sstevel@tonic-gate /* first check if there is data from an encryption waiting to
522*0Sstevel@tonic-gate * be sent - it must be sent because the other end is waiting.
523*0Sstevel@tonic-gate * This will happen with non-blocking IO. We print it and then
524*0Sstevel@tonic-gate * return.
525*0Sstevel@tonic-gate */
526*0Sstevel@tonic-gate if (s->s2->wpend_len != 0) return(write_pending(s,buf,len));
527*0Sstevel@tonic-gate
528*0Sstevel@tonic-gate /* set mac_size to mac size */
529*0Sstevel@tonic-gate if (s->s2->clear_text)
530*0Sstevel@tonic-gate mac_size=0;
531*0Sstevel@tonic-gate else
532*0Sstevel@tonic-gate mac_size=EVP_MD_size(s->write_hash);
533*0Sstevel@tonic-gate
534*0Sstevel@tonic-gate /* lets set the pad p */
535*0Sstevel@tonic-gate if (s->s2->clear_text)
536*0Sstevel@tonic-gate {
537*0Sstevel@tonic-gate if (len > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER)
538*0Sstevel@tonic-gate len=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER;
539*0Sstevel@tonic-gate p=0;
540*0Sstevel@tonic-gate s->s2->three_byte_header=0;
541*0Sstevel@tonic-gate /* len=len; */
542*0Sstevel@tonic-gate }
543*0Sstevel@tonic-gate else
544*0Sstevel@tonic-gate {
545*0Sstevel@tonic-gate bs=EVP_CIPHER_CTX_block_size(s->enc_read_ctx);
546*0Sstevel@tonic-gate j=len+mac_size;
547*0Sstevel@tonic-gate /* Two-byte headers allow for a larger record length than
548*0Sstevel@tonic-gate * three-byte headers, but we can't use them if we need
549*0Sstevel@tonic-gate * padding or if we have to set the escape bit. */
550*0Sstevel@tonic-gate if ((j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) &&
551*0Sstevel@tonic-gate (!s->s2->escape))
552*0Sstevel@tonic-gate {
553*0Sstevel@tonic-gate if (j > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER)
554*0Sstevel@tonic-gate j=SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER;
555*0Sstevel@tonic-gate /* set k to the max number of bytes with 2
556*0Sstevel@tonic-gate * byte header */
557*0Sstevel@tonic-gate k=j-(j%bs);
558*0Sstevel@tonic-gate /* how many data bytes? */
559*0Sstevel@tonic-gate len=k-mac_size;
560*0Sstevel@tonic-gate s->s2->three_byte_header=0;
561*0Sstevel@tonic-gate p=0;
562*0Sstevel@tonic-gate }
563*0Sstevel@tonic-gate else if ((bs <= 1) && (!s->s2->escape))
564*0Sstevel@tonic-gate {
565*0Sstevel@tonic-gate /* j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, thus
566*0Sstevel@tonic-gate * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER */
567*0Sstevel@tonic-gate s->s2->three_byte_header=0;
568*0Sstevel@tonic-gate p=0;
569*0Sstevel@tonic-gate }
570*0Sstevel@tonic-gate else /* we may have to use a 3 byte header */
571*0Sstevel@tonic-gate {
572*0Sstevel@tonic-gate /* If s->s2->escape is not set, then
573*0Sstevel@tonic-gate * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, and thus
574*0Sstevel@tonic-gate * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER. */
575*0Sstevel@tonic-gate p=(j%bs);
576*0Sstevel@tonic-gate p=(p == 0)?0:(bs-p);
577*0Sstevel@tonic-gate if (s->s2->escape)
578*0Sstevel@tonic-gate {
579*0Sstevel@tonic-gate s->s2->three_byte_header=1;
580*0Sstevel@tonic-gate if (j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
581*0Sstevel@tonic-gate j=SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER;
582*0Sstevel@tonic-gate }
583*0Sstevel@tonic-gate else
584*0Sstevel@tonic-gate s->s2->three_byte_header=(p == 0)?0:1;
585*0Sstevel@tonic-gate }
586*0Sstevel@tonic-gate }
587*0Sstevel@tonic-gate
588*0Sstevel@tonic-gate /* Now
589*0Sstevel@tonic-gate * j <= SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER
590*0Sstevel@tonic-gate * holds, and if s->s2->three_byte_header is set, then even
591*0Sstevel@tonic-gate * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER.
592*0Sstevel@tonic-gate */
593*0Sstevel@tonic-gate
594*0Sstevel@tonic-gate /* mac_size is the number of MAC bytes
595*0Sstevel@tonic-gate * len is the number of data bytes we are going to send
596*0Sstevel@tonic-gate * p is the number of padding bytes
597*0Sstevel@tonic-gate * (if it is a two-byte header, then p == 0) */
598*0Sstevel@tonic-gate
599*0Sstevel@tonic-gate s->s2->wlength=len;
600*0Sstevel@tonic-gate s->s2->padding=p;
601*0Sstevel@tonic-gate s->s2->mac_data= &(s->s2->wbuf[3]);
602*0Sstevel@tonic-gate s->s2->wact_data= &(s->s2->wbuf[3+mac_size]);
603*0Sstevel@tonic-gate /* we copy the data into s->s2->wbuf */
604*0Sstevel@tonic-gate memcpy(s->s2->wact_data,buf,len);
605*0Sstevel@tonic-gate if (p)
606*0Sstevel@tonic-gate memset(&(s->s2->wact_data[len]),0,p); /* arbitrary padding */
607*0Sstevel@tonic-gate
608*0Sstevel@tonic-gate if (!s->s2->clear_text)
609*0Sstevel@tonic-gate {
610*0Sstevel@tonic-gate s->s2->wact_data_length=len+p;
611*0Sstevel@tonic-gate ssl2_mac(s,s->s2->mac_data,1);
612*0Sstevel@tonic-gate s->s2->wlength+=p+mac_size;
613*0Sstevel@tonic-gate ssl2_enc(s,1);
614*0Sstevel@tonic-gate }
615*0Sstevel@tonic-gate
616*0Sstevel@tonic-gate /* package up the header */
617*0Sstevel@tonic-gate s->s2->wpend_len=s->s2->wlength;
618*0Sstevel@tonic-gate if (s->s2->three_byte_header) /* 3 byte header */
619*0Sstevel@tonic-gate {
620*0Sstevel@tonic-gate pp=s->s2->mac_data;
621*0Sstevel@tonic-gate pp-=3;
622*0Sstevel@tonic-gate pp[0]=(s->s2->wlength>>8)&(THREE_BYTE_MASK>>8);
623*0Sstevel@tonic-gate if (s->s2->escape) pp[0]|=SEC_ESC_BIT;
624*0Sstevel@tonic-gate pp[1]=s->s2->wlength&0xff;
625*0Sstevel@tonic-gate pp[2]=s->s2->padding;
626*0Sstevel@tonic-gate s->s2->wpend_len+=3;
627*0Sstevel@tonic-gate }
628*0Sstevel@tonic-gate else
629*0Sstevel@tonic-gate {
630*0Sstevel@tonic-gate pp=s->s2->mac_data;
631*0Sstevel@tonic-gate pp-=2;
632*0Sstevel@tonic-gate pp[0]=((s->s2->wlength>>8)&(TWO_BYTE_MASK>>8))|TWO_BYTE_BIT;
633*0Sstevel@tonic-gate pp[1]=s->s2->wlength&0xff;
634*0Sstevel@tonic-gate s->s2->wpend_len+=2;
635*0Sstevel@tonic-gate }
636*0Sstevel@tonic-gate s->s2->write_ptr=pp;
637*0Sstevel@tonic-gate
638*0Sstevel@tonic-gate INC32(s->s2->write_sequence); /* expect next number */
639*0Sstevel@tonic-gate
640*0Sstevel@tonic-gate /* lets try to actually write the data */
641*0Sstevel@tonic-gate s->s2->wpend_tot=olen;
642*0Sstevel@tonic-gate s->s2->wpend_buf=buf;
643*0Sstevel@tonic-gate
644*0Sstevel@tonic-gate s->s2->wpend_ret=len;
645*0Sstevel@tonic-gate
646*0Sstevel@tonic-gate s->s2->wpend_off=0;
647*0Sstevel@tonic-gate return(write_pending(s,buf,olen));
648*0Sstevel@tonic-gate }
649*0Sstevel@tonic-gate
ssl2_part_read(SSL * s,unsigned long f,int i)650*0Sstevel@tonic-gate int ssl2_part_read(SSL *s, unsigned long f, int i)
651*0Sstevel@tonic-gate {
652*0Sstevel@tonic-gate unsigned char *p;
653*0Sstevel@tonic-gate int j;
654*0Sstevel@tonic-gate
655*0Sstevel@tonic-gate if (i < 0)
656*0Sstevel@tonic-gate {
657*0Sstevel@tonic-gate /* ssl2_return_error(s); */
658*0Sstevel@tonic-gate /* for non-blocking io,
659*0Sstevel@tonic-gate * this is not necessarily fatal */
660*0Sstevel@tonic-gate return(i);
661*0Sstevel@tonic-gate }
662*0Sstevel@tonic-gate else
663*0Sstevel@tonic-gate {
664*0Sstevel@tonic-gate s->init_num+=i;
665*0Sstevel@tonic-gate
666*0Sstevel@tonic-gate /* Check for error. While there are recoverable errors,
667*0Sstevel@tonic-gate * this function is not called when those must be expected;
668*0Sstevel@tonic-gate * any error detected here is fatal. */
669*0Sstevel@tonic-gate if (s->init_num >= 3)
670*0Sstevel@tonic-gate {
671*0Sstevel@tonic-gate p=(unsigned char *)s->init_buf->data;
672*0Sstevel@tonic-gate if (p[0] == SSL2_MT_ERROR)
673*0Sstevel@tonic-gate {
674*0Sstevel@tonic-gate j=(p[1]<<8)|p[2];
675*0Sstevel@tonic-gate SSLerr((int)f,ssl_mt_error(j));
676*0Sstevel@tonic-gate s->init_num -= 3;
677*0Sstevel@tonic-gate if (s->init_num > 0)
678*0Sstevel@tonic-gate memmove(p, p+3, s->init_num);
679*0Sstevel@tonic-gate }
680*0Sstevel@tonic-gate }
681*0Sstevel@tonic-gate
682*0Sstevel@tonic-gate /* If it's not an error message, we have some error anyway --
683*0Sstevel@tonic-gate * the message was shorter than expected. This too is treated
684*0Sstevel@tonic-gate * as fatal (at least if SSL_get_error is asked for its opinion). */
685*0Sstevel@tonic-gate return(0);
686*0Sstevel@tonic-gate }
687*0Sstevel@tonic-gate }
688*0Sstevel@tonic-gate
ssl2_do_write(SSL * s)689*0Sstevel@tonic-gate int ssl2_do_write(SSL *s)
690*0Sstevel@tonic-gate {
691*0Sstevel@tonic-gate int ret;
692*0Sstevel@tonic-gate
693*0Sstevel@tonic-gate ret=ssl2_write(s,&s->init_buf->data[s->init_off],s->init_num);
694*0Sstevel@tonic-gate if (ret == s->init_num)
695*0Sstevel@tonic-gate {
696*0Sstevel@tonic-gate if (s->msg_callback)
697*0Sstevel@tonic-gate s->msg_callback(1, s->version, 0, s->init_buf->data, (size_t)(s->init_off + s->init_num), s, s->msg_callback_arg);
698*0Sstevel@tonic-gate return(1);
699*0Sstevel@tonic-gate }
700*0Sstevel@tonic-gate if (ret < 0)
701*0Sstevel@tonic-gate return(-1);
702*0Sstevel@tonic-gate s->init_off+=ret;
703*0Sstevel@tonic-gate s->init_num-=ret;
704*0Sstevel@tonic-gate return(0);
705*0Sstevel@tonic-gate }
706*0Sstevel@tonic-gate
ssl_mt_error(int n)707*0Sstevel@tonic-gate static int ssl_mt_error(int n)
708*0Sstevel@tonic-gate {
709*0Sstevel@tonic-gate int ret;
710*0Sstevel@tonic-gate
711*0Sstevel@tonic-gate switch (n)
712*0Sstevel@tonic-gate {
713*0Sstevel@tonic-gate case SSL2_PE_NO_CIPHER:
714*0Sstevel@tonic-gate ret=SSL_R_PEER_ERROR_NO_CIPHER;
715*0Sstevel@tonic-gate break;
716*0Sstevel@tonic-gate case SSL2_PE_NO_CERTIFICATE:
717*0Sstevel@tonic-gate ret=SSL_R_PEER_ERROR_NO_CERTIFICATE;
718*0Sstevel@tonic-gate break;
719*0Sstevel@tonic-gate case SSL2_PE_BAD_CERTIFICATE:
720*0Sstevel@tonic-gate ret=SSL_R_PEER_ERROR_CERTIFICATE;
721*0Sstevel@tonic-gate break;
722*0Sstevel@tonic-gate case SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE:
723*0Sstevel@tonic-gate ret=SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE;
724*0Sstevel@tonic-gate break;
725*0Sstevel@tonic-gate default:
726*0Sstevel@tonic-gate ret=SSL_R_UNKNOWN_REMOTE_ERROR_TYPE;
727*0Sstevel@tonic-gate break;
728*0Sstevel@tonic-gate }
729*0Sstevel@tonic-gate return(ret);
730*0Sstevel@tonic-gate }
731*0Sstevel@tonic-gate #else /* !OPENSSL_NO_SSL2 */
732*0Sstevel@tonic-gate
733*0Sstevel@tonic-gate # if PEDANTIC
734*0Sstevel@tonic-gate static void *dummy=&dummy;
735*0Sstevel@tonic-gate # endif
736*0Sstevel@tonic-gate
737*0Sstevel@tonic-gate #endif
738