#endif
#include <openssl/md5.h>
-static SSL_METHOD *ssl3_get_server_method(int ver);
+static const SSL_METHOD *ssl3_get_server_method(int ver);
#ifndef OPENSSL_NO_ECDH
static int nid2curve_id(int nid);
#endif
-static SSL_METHOD *ssl3_get_server_method(int ver)
+static const SSL_METHOD *ssl3_get_server_method(int ver)
{
if (ver == SSL3_VERSION)
return(SSLv3_server_method());
return(NULL);
}
-SSL_METHOD *SSLv3_server_method(void)
- {
- static int init=1;
- static SSL_METHOD SSLv3_server_data;
-
- if (init)
- {
- CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
-
- if (init)
- {
- memcpy((char *)&SSLv3_server_data,(char *)sslv3_base_method(),
- sizeof(SSL_METHOD));
- SSLv3_server_data.ssl_accept=ssl3_accept;
- SSLv3_server_data.get_ssl_method=ssl3_get_server_method;
- init=0;
- }
-
- CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
- }
- return(&SSLv3_server_data);
- }
+IMPLEMENT_ssl3_meth_func(SSLv3_server_method,
+ ssl3_accept,
+ ssl_undefined_function,
+ ssl3_get_server_method)
int ssl3_accept(SSL *s)
{
BUF_MEM *buf;
- unsigned long l,Time=time(NULL);
+ unsigned long l,Time=(unsigned long)time(NULL);
void (*cb)(const SSL *ssl,int type,int val)=NULL;
long num1;
int ret= -1;
s->shutdown=0;
ret=ssl3_get_client_hello(s);
if (ret <= 0) goto end;
+#ifndef OPENSSL_NO_TLSEXT
+ {
+ int extension_error = 0,al;
+ if ((al = ssl_check_Hello_TLS_extensions(s,&extension_error)) != SSL_ERROR_NONE){
+ ret = -1;
+ SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_CLIENTHELLO_TLS_EXT);
+ ssl3_send_alert(s,al,extension_error);
+ goto end;
+ }
+ }
+#endif
s->new_session = 2;
s->state=SSL3_ST_SW_SRVR_HELLO_A;
s->init_num=0;
unsigned long id;
unsigned char *p,*d,*q;
SSL_CIPHER *c;
+#ifndef OPENSSL_NO_COMP
SSL_COMP *comp=NULL;
+#endif
STACK_OF(SSL_CIPHER) *ciphers=NULL;
/* We do this so that we will respond with our native type.
* options, we will now look for them. We have i-1 compression
* algorithms from the client, starting at q. */
s->s3->tmp.new_compression=NULL;
- if (s->ctx->comp_methods != NULL)
+#ifndef OPENSSL_NO_COMP
+ if (!(s->options & SSL_OP_NO_COMPRESSION) && s->ctx->comp_methods)
{ /* See if we have a match */
int m,nn,o,v,done=0;
else
comp=NULL;
}
+#endif
/* TLS does not mind if there is extra stuff */
#if 0 /* SSL 3.0 does not mind either, so we should disable this test
}
}
#endif
+#ifndef OPENSSL_NO_TLSEXT
+ /* TLS extensions*/
+ if (s->version > SSL3_VERSION)
+ {
+ if ((al = ssl_parse_ClientHello_TLS_extensions(s,&p,d,n)) != SSL_ERROR_NONE){
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_PARSE_TLS_EXT);
+ ssl3_send_alert(s,SSL3_AL_WARNING,al);
+ return (ret = al);
+ }
+ }
+#endif
/* Given s->session->ciphers and SSL_get_ciphers, we must
* pick a cipher */
if (!s->hit)
{
+#ifdef OPENSSL_NO_COMP
+ s->session->compress_meth=0;
+#else
s->session->compress_meth=(comp == NULL)?0:comp->id;
+#endif
if (s->session->ciphers != NULL)
sk_SSL_CIPHER_free(s->session->ciphers);
s->session->ciphers=ciphers;
{
buf=(unsigned char *)s->init_buf->data;
p=s->s3->server_random;
- Time=time(NULL); /* Time */
+ Time=(unsigned long)time(NULL); /* Time */
l2n(Time,p);
if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
return -1;
p+=i;
/* put the compression method */
+#ifdef OPENSSL_NO_COMP
+ *(p++)=0;
+#else
if (s->s3->tmp.new_compression == NULL)
*(p++)=0;
else
*(p++)=s->s3->tmp.new_compression->id;
+#endif
+#ifndef OPENSSL_NO_TLSEXT
+ if ((p = ssl_add_ServerHello_TLS_extensions(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
+ {
+ SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+#endif
/* do the header */
l=(p-d);
/* XXX: For now, we only support named (not
* generic) curves in ECDH ephemeral key exchanges.
- * In this situation, we need three additional bytes
+ * In this situation, we need four additional bytes
* to encode the entire ServerECDHParams
* structure.
*/
- n = 3 + encodedlen;
+ n = 4 + encodedlen;
/* We'll generate the serverKeyExchange message
* explicitly so we can set these to NULLs
r[0]=NULL;
r[1]=NULL;
r[2]=NULL;
+ r[3]=NULL;
}
else
#endif /* !OPENSSL_NO_ECDH */
{
/* XXX: For now, we only support named (not generic) curves.
* In this situation, the serverKeyExchange message has:
- * [1 byte CurveType], [1 byte CurveName]
+ * [1 byte CurveType], [2 byte CurveName]
* [1 byte length of encoded point], followed by
* the actual encoded point itself
*/
*p = NAMED_CURVE_TYPE;
p += 1;
+ *p = 0;
+ p += 1;
*p = curve_id;
p += 1;
*p = encodedlen;
return(-1);
}
-
-#ifndef OPENSSL_NO_ECDH
-static const int KDF1_SHA1_len = 20;
-static void *KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen)
- {
-#ifndef OPENSSL_NO_SHA
- if (*outlen < SHA_DIGEST_LENGTH)
- return NULL;
- else
- *outlen = SHA_DIGEST_LENGTH;
- return SHA1(in, inlen, out);
-#else
- return NULL;
-#endif /* OPENSSL_NO_SHA */
- }
-#endif /* OPENSSL_NO_ECDH */
-
int ssl3_get_client_key_exchange(SSL *s)
{
int i,al,ok;
ERR_R_ECDH_LIB);
goto err;
}
- /* If field size is not more than 24 octets, then use SHA-1 hash of result;
- * otherwise, use result (see section 4.8 of draft-ietf-tls-ecc-03.txt;
- * this is new with this version of the Internet Draft).
- */
- if (field_size <= 24 * 8)
- i = ECDH_compute_key(p, KDF1_SHA1_len, clnt_ecpoint, srvr_ecdh, KDF1_SHA1);
- else
- i = ECDH_compute_key(p, (field_size+7)/8, clnt_ecpoint, srvr_ecdh, NULL);
+ i = ECDH_compute_key(p, (field_size+7)/8, clnt_ecpoint, srvr_ecdh, NULL);
if (i <= 0)
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,