* [including the GNU Public Licence.]
*/
+#include <string.h>
#include <stdio.h>
-#include "buffer.h"
-#include "rand.h"
-#include "objects.h"
-#include "evp.h"
-#include "x509.h"
+#include <openssl/buffer.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
#include "ssl_locl.h"
-#define BREAK break
-
-/* SSL3err(SSL_F_SSL3_GET_FINISHED,SSL_R_EXCESSIVE_MESSAGE_SIZE);
- */
-
-int ssl3_send_finished(s,a,b,sender,slen)
-SSL *s;
-int a;
-int b;
-unsigned char *sender;
-int slen;
+int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
{
unsigned char *p,*d;
int i;
i=s->method->ssl3_enc->final_finish_mac(s,
&(s->s3->finish_dgst1),
&(s->s3->finish_dgst2),
- sender,slen,p);
+ sender,slen,s->s3->tmp.finish_md);
+ s->s3->tmp.finish_md_len = i;
+ memcpy(p, s->s3->tmp.finish_md, i);
p+=i;
l=i;
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
}
-int ssl3_get_finished(s,a,b)
-SSL *s;
-int a;
-int b;
+int ssl3_get_finished(SSL *s, int a, int b)
{
int al,i,ok;
long n;
unsigned char *p;
/* the mac has already been generated when we received the
- * change cipher spec message and is in s->s3->tmp.in_dgst[12]
+ * change cipher spec message and is in s->s3->tmp.peer_finish_md
*/
n=ssl3_get_message(s,
if (!ok) return((int)n);
- /* If this occurs if we has missed a message */
+ /* If this occurs, we have missed a message */
if (!s->s3->change_cipher_spec)
{
al=SSL_AD_UNEXPECTED_MESSAGE;
}
s->s3->change_cipher_spec=0;
- p=(unsigned char *)s->init_buf->data;
-
- i=s->method->ssl3_enc->finish_mac_length;
+ p = (unsigned char *)s->init_buf->data;
+ i = s->s3->tmp.peer_finish_md_len;
if (i != n)
{
goto f_err;
}
- if (memcmp( p, (char *)&(s->s3->tmp.finish_md[0]),i) != 0)
+ if (memcmp(p, s->s3->tmp.peer_finish_md, i) != 0)
{
al=SSL_AD_DECRYPT_ERROR;
SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_DIGEST_CHECK_FAILED);
* ssl->session->read_compression assign
* ssl->session->read_hash assign
*/
-int ssl3_send_change_cipher_spec(s,a,b)
-SSL *s;
-int a,b;
+int ssl3_send_change_cipher_spec(SSL *s, int a, int b)
{
unsigned char *p;
return(ssl3_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC));
}
-unsigned long ssl3_output_cert_chain(s,x)
-SSL *s;
-X509 *x;
+unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
{
unsigned char *p;
int n,i;
X509_STORE_CTX_cleanup(&xs_ctx);
}
- /* Thwate special :-) */
+ /* Thawte special :-) */
if (s->ctx->extra_certs != NULL)
- for (i=0; i<sk_num(s->ctx->extra_certs); i++)
+ for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
{
- x=(X509 *)sk_value(s->ctx->extra_certs,i);
+ x=sk_X509_value(s->ctx->extra_certs,i);
n=i2d_X509(x,NULL);
if (!BUF_MEM_grow(buf,(int)(n+l+3)))
{
return(l);
}
-long ssl3_get_message(s,st1,stn,mt,max,ok)
-SSL *s;
-int st1,stn,mt;
-long max;
-int *ok;
+/* Obtain handshake message of message type 'mt' (any if mt == -1),
+ * maximum acceptable body length 'max'.
+ * The first four bytes (msg_type and length) are read in state 'st1',
+ * the body is read in state 'stn'.
+ */
+long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
{
unsigned char *p;
unsigned long l;
p=(unsigned char *)s->init_buf->data;
- if (s->state == st1)
+ if (s->state == st1) /* s->init_num < 4 */
{
- i=ssl3_read_bytes(s,SSL3_RT_HANDSHAKE,
- (char *)&(p[s->init_num]),
- 4-s->init_num);
- if (i < (4-s->init_num))
+ int skip_message;
+
+ do
{
- *ok=0;
- return(ssl3_part_read(s,i));
+ while (s->init_num < 4)
+ {
+ i=ssl3_read_bytes(s,SSL3_RT_HANDSHAKE,&p[s->init_num],
+ 4-s->init_num);
+ if (i <= 0)
+ {
+ s->rwstate=SSL_READING;
+ *ok = 0;
+ return i;
+ }
+ s->init_num+=i;
+ }
+
+ skip_message = 0;
+ if (!s->server)
+ if (p[0] == SSL3_MT_HELLO_REQUEST)
+ /* The server may always send 'Hello Request' messages --
+ * we are doing a handshake anyway now, so ignore them
+ * if their format is correct */
+ if (p[1] == 0 && p[2] == 0 &&p[3] == 0)
+ skip_message = 1;
}
+ while (skip_message);
if ((mt >= 0) && (*p != mt))
{
SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
}
+ if((mt < 0) && (*p == SSL3_MT_CLIENT_HELLO) &&
+ (st1 == SSL3_ST_SR_CERT_A) &&
+ (stn == SSL3_ST_SR_CERT_B))
+ {
+ /* At this point we have got an MS SGC second client
+ * hello. We need to restart the mac and mac the data
+ * currently received.
+ */
+ ssl3_init_finished_mac(s);
+ ssl3_finish_mac(s, p + s->init_num, i);
+ }
+
s->s3->tmp.message_type= *(p++);
n2l3(p,l);
/* next state (stn) */
p=(unsigned char *)s->init_buf->data;
n=s->s3->tmp.message_size;
- if (n > 0)
+ while (n > 0)
{
- i=ssl3_read_bytes(s,SSL3_RT_HANDSHAKE,
- (char *)&(p[s->init_num]),(int)n);
- if (i != (int)n)
+ i=ssl3_read_bytes(s,SSL3_RT_HANDSHAKE,&p[s->init_num],n);
+ if (i <= 0)
{
- *ok=0;
- return(ssl3_part_read(s,i));
+ s->rwstate=SSL_READING;
+ *ok = 0;
+ return i;
}
+ s->init_num += i;
+ n -= i;
}
*ok=1;
- return(n);
+ return s->init_num;
f_err:
ssl3_send_alert(s,SSL3_AL_FATAL,al);
err:
return(-1);
}
-int ssl_cert_type(x,pkey)
-X509 *x;
-EVP_PKEY *pkey;
+int ssl_cert_type(X509 *x, EVP_PKEY *pkey)
{
EVP_PKEY *pk;
int ret= -1,i,j;
ret= -1;
err:
+ if(!pkey) EVP_PKEY_free(pk);
return(ret);
}
-int ssl_verify_alarm_type(type)
-long type;
+int ssl_verify_alarm_type(long type)
{
int al;
return(al);
}
-int ssl3_setup_buffers(s)
-SSL *s;
+int ssl3_setup_buffers(SSL *s)
{
unsigned char *p;
unsigned int extra;
extra=SSL3_RT_MAX_EXTRA;
else
extra=0;
- if ((p=(unsigned char *)Malloc(SSL3_RT_MAX_PACKET_SIZE+extra))
+ if ((p=Malloc(SSL3_RT_MAX_PACKET_SIZE+extra))
== NULL)
goto err;
s->s3->rbuf.buf=p;
if (s->s3->wbuf.buf == NULL)
{
- if ((p=(unsigned char *)Malloc(SSL3_RT_MAX_PACKET_SIZE))
+ if ((p=Malloc(SSL3_RT_MAX_PACKET_SIZE))
== NULL)
goto err;
s->s3->wbuf.buf=p;