#include <openssl/bn.h>
#include <openssl/md5.h>
-#ifndef OPENSSL_NO_SSL3_METHOD
-static const SSL_METHOD *ssl3_get_server_method(int ver);
+static STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p,
+ int num, STACK_OF(SSL_CIPHER) **skp, int sslv2format);
-static const SSL_METHOD *ssl3_get_server_method(int ver)
-{
- if (ver == SSL3_VERSION)
- return (SSLv3_server_method());
- else
- return (NULL);
-}
-IMPLEMENT_ssl3_meth_func(SSLv3_server_method,
- ssl3_accept,
- ssl_undefined_function, ssl3_get_server_method)
-#endif
#ifndef OPENSSL_NO_SRP
static int ssl_check_srp_ext_ClientHello(SSL *s, int *al)
{
int ssl3_get_client_hello(SSL *s)
{
- int i, j, ok, al = SSL_AD_INTERNAL_ERROR, ret = -1;
+ int i, complen, j, ok, al = SSL_AD_INTERNAL_ERROR, ret = -1;
unsigned int cookie_len;
long n;
unsigned long id;
unsigned char *p, *d;
SSL_CIPHER *c;
#ifndef OPENSSL_NO_COMP
- unsigned char *q;
+ unsigned char *q = NULL;
SSL_COMP *comp = NULL;
#endif
STACK_OF(SSL_CIPHER) *ciphers = NULL;
d = p = (unsigned char *)s->init_msg;
/* First lets get s->client_version set correctly */
- if (!s->read_hash && !s->enc_read_ctx
- && RECORD_LAYER_is_sslv2_record(&s->rlayer)) {
- if (n < MIN_SSL2_RECORD_LEN) {
- SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_RECORD_LENGTH_MISMATCH);
- al = SSL_AD_DECODE_ERROR;
- goto f_err;
- }
+ if (RECORD_LAYER_is_sslv2_record(&s->rlayer)) {
/*-
* An SSLv3/TLSv1 backwards-compatible CLIENT-HELLO in an SSLv2
* header is sent directly on the wire, not wrapped as a TLS
* layer in order to have determined that this is a SSLv2 record
* in the first place
*/
- al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
- goto f_err;
+ goto err;
}
if ((p[1] == 0x00) && (p[2] == 0x02)) {
/* Do SSL/TLS version negotiation if applicable */
if (!SSL_IS_DTLS(s)) {
if (s->version != TLS_ANY_VERSION) {
- if (s->client_version >= s->version
- && (((s->client_version >> 8) & 0xff) == SSL3_VERSION_MAJOR)) {
+ if (s->client_version >= s->version) {
protverr = 0;
}
- } else {
- /*
- * We already know that this is an SSL3_VERSION_MAJOR protocol,
- * so we're just testing the minor versions here
- */
+ } else if (s->client_version >= SSL3_VERSION) {
switch(s->client_version) {
default:
case TLS1_2_VERSION:
}
/* Deliberately fall through */
case SSL3_VERSION:
+#ifndef OPENSSL_NO_SSL3
if(!(s->options & SSL_OP_NO_SSLv3)) {
s->version = SSL3_VERSION;
s->method = SSLv3_server_method();
protverr = 0;
break;
}
+#else
+ break;
+#endif
}
}
- } else if (((s->client_version >> 8) & 0xff) == DTLS1_VERSION_MAJOR &&
- (s->client_version <= s->version
- || s->method->version == DTLS_ANY_VERSION)) {
+ } else if (s->client_version <= s->version
+ || s->method->version == DTLS_ANY_VERSION) {
/*
* For DTLS we just check versions are potentially compatible. Version
* negotiation comes later.
/* Set p to end of packet to ensure we don't look for extensions */
p = d + n;
- /* No compression, so set i to 0 */
- i = 0;
+ /* No compression, so set complen to 0 */
+ complen = 0;
} else {
/* If we get here we've got SSLv3+ in an SSLv3+ record */
}
/* compression */
- i = *(p++);
- if ((p + i) > (d + n)) {
+ complen = *(p++);
+ if ((p + complen) > (d + n)) {
/* not enough data */
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
#ifndef OPENSSL_NO_COMP
q = p;
#endif
- for (j = 0; j < i; j++) {
+ for (j = 0; j < complen; j++) {
if (p[j] == 0)
break;
}
- p += i;
- if (j >= i) {
+ p += complen;
+ if (j >= complen) {
/* no compress */
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_COMPRESSION_SPECIFIED);
/*
* Worst case, we will use the NULL compression, but if we have other
- * options, we will now look for them. We have i-1 compression
+ * options, we will now look for them. We have complen-1 compression
* algorithms from the client, starting at q.
*/
s->s3->tmp.new_compression = NULL;
goto f_err;
}
/* Look for resumed method in compression list */
- for (m = 0; m < i; m++) {
+ for (m = 0; m < complen; m++) {
if (q[m] == comp_id)
break;
}
- if (m >= i) {
+ if (m >= complen) {
al = SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING);
for (m = 0; m < nn; m++) {
comp = sk_SSL_COMP_value(s->ctx->comp_methods, m);
v = comp->id;
- for (o = 0; o < i; o++) {
+ for (o = 0; o < complen; o++) {
if (v == q[o]) {
done = 1;
break;
# endif
#endif
+
+#define SSLV2_CIPHER_LEN 3
+
+STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p,
+ int num,
+ STACK_OF(SSL_CIPHER) **skp,
+ int sslv2format)
+{
+ const SSL_CIPHER *c;
+ STACK_OF(SSL_CIPHER) *sk;
+ int i, n;
+
+ if (s->s3)
+ s->s3->send_connection_binding = 0;
+
+ if(sslv2format) {
+ n = SSLV2_CIPHER_LEN;
+ } else {
+ n = ssl_put_cipher_by_char(s, NULL, NULL);
+ }
+ if (n == 0 || (num % n) != 0) {
+ SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,
+ SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
+ return (NULL);
+ }
+ if ((skp == NULL) || (*skp == NULL)) {
+ sk = sk_SSL_CIPHER_new_null(); /* change perhaps later */
+ if(sk == NULL) {
+ SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ } else {
+ sk = *skp;
+ sk_SSL_CIPHER_zero(sk);
+ }
+
+ OPENSSL_free(s->s3->tmp.ciphers_raw);
+ s->s3->tmp.ciphers_raw = BUF_memdup(p, num);
+ if (s->s3->tmp.ciphers_raw == NULL) {
+ SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ s->s3->tmp.ciphers_rawlen = (size_t)num;
+
+ for (i = 0; i < num; i += n) {
+ /* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */
+ if (s->s3 && (n != 3 || !p[0]) &&
+ (p[n - 2] == ((SSL3_CK_SCSV >> 8) & 0xff)) &&
+ (p[n - 1] == (SSL3_CK_SCSV & 0xff))) {
+ /* SCSV fatal if renegotiating */
+ if (s->renegotiate) {
+ SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,
+ SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
+ ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ goto err;
+ }
+ s->s3->send_connection_binding = 1;
+ p += n;
+#ifdef OPENSSL_RI_DEBUG
+ fprintf(stderr, "SCSV received by server\n");
+#endif
+ continue;
+ }
+
+ /* Check for TLS_FALLBACK_SCSV */
+ if ((n != 3 || !p[0]) &&
+ (p[n - 2] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) &&
+ (p[n - 1] == (SSL3_CK_FALLBACK_SCSV & 0xff))) {
+ /*
+ * The SCSV indicates that the client previously tried a higher
+ * version. Fail if the current version is an unexpected
+ * downgrade.
+ */
+ if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL)) {
+ SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,
+ SSL_R_INAPPROPRIATE_FALLBACK);
+ if (s->s3)
+ ssl3_send_alert(s, SSL3_AL_FATAL,
+ SSL_AD_INAPPROPRIATE_FALLBACK);
+ goto err;
+ }
+ p += n;
+ continue;
+ }
+
+ if(sslv2format) {
+ /*
+ * We only support SSLv2 format ciphers in SSLv3+ using a
+ * SSLv2 backward compatible ClientHello. In this case the first
+ * byte is always 0 for SSLv3 compatible ciphers. Anything else
+ * is an SSLv2 cipher and we ignore it
+ */
+ if(p[0] == 0)
+ c = ssl_get_cipher_by_char(s, &p[1]);
+ else
+ c = NULL;
+ } else {
+ c = ssl_get_cipher_by_char(s, p);
+ }
+ p += n;
+ if (c != NULL) {
+ if (!sk_SSL_CIPHER_push(sk, c)) {
+ SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ }
+
+ if (skp != NULL)
+ *skp = sk;
+ return (sk);
+ err:
+ if ((skp == NULL) || (*skp == NULL))
+ sk_SSL_CIPHER_free(sk);
+ return (NULL);
+}