* [including the GNU Public Licence.]
*/
-#include <stdio.h>
-#include "rand.h"
-#include "buffer.h"
-#include "objects.h"
#include "ssl_locl.h"
-#include "evp.h"
+#ifndef NO_SSL2
+#include <stdio.h>
+#include <openssl/rand.h>
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
-#ifndef NOPROTO
static SSL_METHOD *ssl2_get_client_method(int ver);
static int get_server_finished(SSL *s);
static int get_server_verify(SSL *s);
static int client_master_key(SSL *s);
static int client_finished(SSL *s);
static int client_certificate(SSL *s);
-static int ssl_rsa_public_encrypt(CERT *c, int len, unsigned char *from,
+static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from,
unsigned char *to,int padding);
-#else
-static SSL_METHOD *ssl2_get_client_method();
-static int get_server_finished();
-static int get_server_verify();
-static int get_server_hello();
-static int client_hello();
-static int client_master_key();
-static int client_finished();
-static int client_certificate();
-static int ssl_rsa_public_encrypt();
-#endif
-
#define BREAK break
-static SSL_METHOD *ssl2_get_client_method(ver)
-int ver;
+static SSL_METHOD *ssl2_get_client_method(int ver)
{
if (ver == SSL2_VERSION)
return(SSLv2_client_method());
return(NULL);
}
-SSL_METHOD *SSLv2_client_method()
+SSL_METHOD *SSLv2_client_method(void)
{
static int init=1;
static SSL_METHOD SSLv2_client_data;
if (init)
{
- init=0;
memcpy((char *)&SSLv2_client_data,(char *)sslv2_base_method(),
sizeof(SSL_METHOD));
SSLv2_client_data.ssl_connect=ssl2_connect;
SSLv2_client_data.get_ssl_method=ssl2_get_client_method;
+ init=0;
}
return(&SSLv2_client_data);
}
-int ssl2_connect(s)
-SSL *s;
+int ssl2_connect(SSL *s)
{
unsigned long l=time(NULL);
BUF_MEM *buf=NULL;
void (*cb)()=NULL;
int new_state,state;
- RAND_seed(&l,sizeof(l));
+ RAND_add(&l,sizeof(l),0);
ERR_clear_error();
clear_sys_error();
/* ERR_clear_error();*/
/* If we want to cache session-ids in the client
- * and we sucessfully add the session-id to the
+ * and we successfully add the session-id to the
* cache, and there is a callback, then pass it out.
* 26/11/96 - eay - only add if not a re-used session.
*/
return(ret);
}
-static int get_server_hello(s)
-SSL *s;
+static int get_server_hello(SSL *s)
{
unsigned char *buf;
unsigned char *p;
SSL_R_PEER_ERROR);
return(-1);
}
+#ifdef __APPLE_CC__
+ /* The Rhapsody 5.5 (a.k.a. MacOS X) compiler bug
+ * workaround. <appro@fy.chalmers.se> */
+ s->hit=(i=*(p++))?1:0;
+#else
s->hit=(*(p++))?1:0;
+#endif
s->s2->tmp.cert_type= *(p++);
n2s(p,i);
if (i < s->version) s->version=i;
*/
#endif
- /* we need to do this incase we were trying to reuse a
+ /* we need to do this in case we were trying to reuse a
* client session but others are already reusing it.
* If this was a new 'blank' session ID, the session-id
* length will still be 0 */
/* In theory we could have ciphers sent back that we
* don't want to use but that does not matter since we
- * will check against the list we origionally sent and
+ * will check against the list we originally sent and
* for performance reasons we should not bother to match
* the two lists up just to check. */
for (i=0; i<sk_SSL_CIPHER_num(cl); i++)
return(-1);
}
s->session->cipher=sk_SSL_CIPHER_value(cl,i);
- }
- if ((s->session != NULL) && (s->session->peer != NULL))
- X509_free(s->session->peer);
- /* hmmm, can we have the problem of the other session with this
- * cert, Free's it before we increment the reference count. */
- CRYPTO_w_lock(CRYPTO_LOCK_X509);
- s->session->peer=s->session->cert->key->x509;
- CRYPTO_add(&s->session->peer->references,1,CRYPTO_LOCK_X509);
- CRYPTO_w_unlock(CRYPTO_LOCK_X509);
+ if (s->session->peer != NULL) /* can't happen*/
+ {
+ ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_INTERNAL_ERROR);
+ return(-1);
+ }
+
+ s->session->peer = s->session->sess_cert->peer_key->x509;
+ /* peer_key->x509 has been set by ssl2_set_certificate. */
+ CRYPTO_add(&s->session->peer->references, 1, CRYPTO_LOCK_X509);
+ }
+ if (s->session->peer != s->session->sess_cert->peer_key->x509)
+ /* can't happen */
+ {
+ ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_INTERNAL_ERROR);
+ return(-1);
+ }
+
s->s2->conn_id_length=s->s2->tmp.conn_id_length;
memcpy(s->s2->conn_id,p,s->s2->tmp.conn_id_length);
return(1);
}
-static int client_hello(s)
-SSL *s;
+static int client_hello(SSL *s)
{
unsigned char *buf;
unsigned char *p,*d;
s->s2->challenge_length=SSL2_CHALLENGE_LENGTH;
s2n(SSL2_CHALLENGE_LENGTH,p); /* challenge length */
/*challenge id data*/
- RAND_bytes(s->s2->challenge,SSL2_CHALLENGE_LENGTH);
+ RAND_pseudo_bytes(s->s2->challenge,SSL2_CHALLENGE_LENGTH);
memcpy(d,s->s2->challenge,SSL2_CHALLENGE_LENGTH);
d+=SSL2_CHALLENGE_LENGTH;
return(ssl2_do_write(s));
}
-static int client_master_key(s)
-SSL *s;
+static int client_master_key(SSL *s)
{
unsigned char *buf;
unsigned char *p,*d;
/* make key_arg data */
i=EVP_CIPHER_iv_length(c);
sess->key_arg_length=i;
- if (i > 0) RAND_bytes(sess->key_arg,i);
+ if (i > 0) RAND_pseudo_bytes(sess->key_arg,i);
/* make a master key */
i=EVP_CIPHER_key_length(c);
sess->master_key_length=i;
- if (i > 0) RAND_bytes(sess->master_key,i);
+ if (i > 0)
+ {
+ if (RAND_bytes(sess->master_key,i) <= 0)
+ {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ return(-1);
+ }
+ }
if (sess->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC)
enc=8;
memcpy(d,sess->master_key,(unsigned int)clear);
d+=clear;
- enc=ssl_rsa_public_encrypt(sess->cert,enc,
+ enc=ssl_rsa_public_encrypt(sess->sess_cert,enc,
&(sess->master_key[clear]),d,
(s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING);
if (enc <= 0)
return(ssl2_do_write(s));
}
-static int client_finished(s)
-SSL *s;
+static int client_finished(SSL *s)
{
unsigned char *p;
}
/* read the data and then respond */
-static int client_certificate(s)
-SSL *s;
+static int client_certificate(SSL *s)
{
unsigned char *buf;
unsigned char *p,*d;
EVP_SignUpdate(&ctx,s->s2->key_material,
(unsigned int)s->s2->key_material_length);
EVP_SignUpdate(&ctx,cert_ch,(unsigned int)cert_ch_len);
- n=i2d_X509(s->session->cert->key->x509,&p);
+ n=i2d_X509(s->session->sess_cert->peer_key->x509,&p);
EVP_SignUpdate(&ctx,buf,(unsigned int)n);
p=buf;
{
/* this is not good. If things have failed it
* means there so something wrong with the key.
- * We will contiune with a 0 length signature
+ * We will continue with a 0 length signature
*/
}
memset(&ctx,0,sizeof(ctx));
return(ssl2_do_write(s));
}
-static int get_server_verify(s)
-SSL *s;
+static int get_server_verify(SSL *s)
{
unsigned char *p;
int i;
return(1);
}
-static int get_server_finished(s)
-SSL *s;
+static int get_server_finished(SSL *s)
{
unsigned char *buf;
unsigned char *p;
}
/* loads in the certificate from the server */
-int ssl2_set_certificate(s, type, len, data)
-SSL *s;
-int type;
-int len;
-unsigned char *data;
+int ssl2_set_certificate(SSL *s, int type, int len, unsigned char *data)
{
STACK_OF(X509) *sk=NULL;
EVP_PKEY *pkey=NULL;
- CERT *c=NULL;
+ SESS_CERT *sc=NULL;
int i;
X509 *x509=NULL;
int ret=0;
SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED);
goto err;
}
+ ERR_clear_error(); /* but we keep s->verify_result */
+ s->session->verify_result = s->verify_result;
- /* cert for ssl */
- c=ssl_cert_new();
- if (c == NULL)
+ /* server's cert for this session */
+ sc=ssl_sess_cert_new();
+ if (sc == NULL)
{
ret= -1;
goto err;
}
+ if (s->session->sess_cert) ssl_sess_cert_free(s->session->sess_cert);
+ s->session->sess_cert=sc;
- /* cert for session */
- if (s->session->cert) ssl_cert_free(s->session->cert);
- s->session->cert=c;
-
-/* c->cert_type=type; */
-
- c->pkeys[SSL_PKEY_RSA_ENC].x509=x509;
- c->key= &(c->pkeys[SSL_PKEY_RSA_ENC]);
+ sc->peer_pkeys[SSL_PKEY_RSA_ENC].x509=x509;
+ sc->peer_key= &(sc->peer_pkeys[SSL_PKEY_RSA_ENC]);
pkey=X509_get_pubkey(x509);
x509=NULL;
goto err;
}
- if (!ssl_set_cert_type(c,SSL2_CT_X509_CERTIFICATE))
+ if (!ssl_set_peer_cert_type(sc,SSL2_CT_X509_CERTIFICATE))
goto err;
ret=1;
err:
return(ret);
}
-static int ssl_rsa_public_encrypt(c, len, from, to, padding)
-CERT *c;
-int len;
-unsigned char *from;
-unsigned char *to;
-int padding;
+static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from,
+ unsigned char *to, int padding)
{
EVP_PKEY *pkey=NULL;
int i= -1;
- if ((c == NULL) || (c->key->x509 == NULL) ||
- ((pkey=X509_get_pubkey(c->key->x509)) == NULL))
+ if ((sc == NULL) || (sc->peer_key->x509 == NULL) ||
+ ((pkey=X509_get_pubkey(sc->peer_key->x509)) == NULL))
{
SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT,SSL_R_NO_PUBLICKEY);
return(-1);
EVP_PKEY_free(pkey);
return(i);
}
+#else /* !NO_SSL2 */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+#endif