Implement msg_callback for SSL 2.0.
[openssl.git] / ssl / s2_lib.c
index a6f4db36c00b2a9905212f3fcd680ae353711e48..bce2b4e83f2e6b5c426219be6fed8c02580791d8 100644 (file)
  */
 
 #include "ssl_locl.h"
-#ifndef NO_SSL2
+#ifndef OPENSSL_NO_SSL2
 #include <stdio.h>
 #include <openssl/rsa.h>
 #include <openssl/objects.h>
+#include <openssl/evp.h>
 #include <openssl/md5.h>
 
 static long ssl2_default_timeout(void );
@@ -260,10 +261,7 @@ SSL_CIPHER *ssl2_get_cipher(unsigned int u)
 
 int ssl2_pending(SSL *s)
        {
-       /* Unlike ssl2_pending, this one probably works (if read-ahead
-        * is disabled), but it should be examined
-        * XXX */
-       return(s->s2->ract_data_length);
+       return SSL_in_init(s) ? 0 : s->s2->ract_data_length;
        }
 
 int ssl2_new(SSL *s)
@@ -273,10 +271,16 @@ int ssl2_new(SSL *s)
        if ((s2=OPENSSL_malloc(sizeof *s2)) == NULL) goto err;
        memset(s2,0,sizeof *s2);
 
+#if SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER + 3 > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2
+#  error "assertion failed"
+#endif
+
        if ((s2->rbuf=OPENSSL_malloc(
                SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2)) == NULL) goto err;
+       /* wbuf needs one byte more because when using two-byte headers,
+        * we leave the first byte unused in do_ssl_write (s2_pkt.c) */
        if ((s2->wbuf=OPENSSL_malloc(
-               SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2)) == NULL) goto err;
+               SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+3)) == NULL) goto err;
        s->s2=s2;
 
        ssl2_clear(s);
@@ -326,7 +330,7 @@ void ssl2_clear(SSL *s)
        s->packet_length=0;
        }
 
-long ssl2_ctrl(SSL *s, int cmd, long larg, char *parg)
+long ssl2_ctrl(SSL *s, int cmd, long larg, void *parg)
        {
        int ret=0;
 
@@ -346,7 +350,7 @@ long ssl2_callback_ctrl(SSL *s, int cmd, void (*fp)())
        return(0);
        }
 
-long ssl2_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, char *parg)
+long ssl2_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
        {
        return(0);
        }
@@ -412,7 +416,7 @@ int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
 void ssl2_generate_key_material(SSL *s)
        {
        unsigned int i;
-       MD5_CTX ctx;
+       EVP_MD_CTX ctx;
        unsigned char *km;
        unsigned char c='0';
 
@@ -420,20 +424,21 @@ void ssl2_generate_key_material(SSL *s)
        c = os_toascii['0']; /* Must be an ASCII '0', not EBCDIC '0',
                                see SSLv2 docu */
 #endif
-
+       EVP_MD_CTX_init(&ctx);
        km=s->s2->key_material;
        for (i=0; i<s->s2->key_material_length; i+=MD5_DIGEST_LENGTH)
                {
-               MD5_Init(&ctx);
+               EVP_DigestInit_ex(&ctx,EVP_md5(), NULL);
 
-               MD5_Update(&ctx,s->session->master_key,s->session->master_key_length);
-               MD5_Update(&ctx,&c,1);
+               EVP_DigestUpdate(&ctx,s->session->master_key,s->session->master_key_length);
+               EVP_DigestUpdate(&ctx,&c,1);
                c++;
-               MD5_Update(&ctx,s->s2->challenge,s->s2->challenge_length);
-               MD5_Update(&ctx,s->s2->conn_id,s->s2->conn_id_length);
-               MD5_Final(km,&ctx);
+               EVP_DigestUpdate(&ctx,s->s2->challenge,s->s2->challenge_length);
+               EVP_DigestUpdate(&ctx,s->s2->conn_id,s->s2->conn_id_length);
+               EVP_DigestFinal_ex(&ctx,km,NULL);
                km+=MD5_DIGEST_LENGTH;
                }
+       EVP_MD_CTX_cleanup(&ctx);
        }
 
 void ssl2_return_error(SSL *s, int err)
@@ -465,10 +470,14 @@ void ssl2_write_error(SSL *s)
 
        if (i < 0)
                s->error=error;
-       else if (i != s->error)
+       else
+               {
                s->error=error-i;
-       /* else
-               s->error=0; */
+
+               if (s->error == 0)
+                       if (s->msg_callback)
+                               s->msg_callback(1, s->version, 0, buf, 3, s, s->msg_callback_arg); /* ERROR */
+               }
        }
 
 int ssl2_shutdown(SSL *s)
@@ -476,7 +485,7 @@ int ssl2_shutdown(SSL *s)
        s->shutdown=(SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
        return(1);
        }
-#else /* !NO_SSL2 */
+#else /* !OPENSSL_NO_SSL2 */
 
 # if PEDANTIC
 static void *dummy=&dummy;