* [including the GNU Public Licence.]
*/
+
+#include <assert.h>
#include <stdio.h>
#include <openssl/objects.h>
#include <openssl/lhash.h>
(int (*)(SSL *, EVP_MD_CTX *, EVP_MD_CTX *, const char*, int, unsigned char *))ssl_undefined_function
};
-union rsa_fn_to_char_u
- {
- char *char_p;
- RSA *(*fn_p)(SSL *, int, int);
- };
-
-union dh_fn_to_char_u
- {
- char *char_p;
- DH *(*fn_p)(SSL *, int, int);
- };
-
int SSL_clear(SSL *s)
{
int state;
s->client_version=s->version;
s->rwstate=SSL_NOTHING;
s->rstate=SSL_ST_READ_HEADER;
+#if 0
s->read_ahead=s->ctx->read_ahead;
+#endif
if (s->init_buf != NULL)
{
return(NULL);
}
- s=(SSL *)Malloc(sizeof(SSL));
+ s=(SSL *)OPENSSL_malloc(sizeof(SSL));
if (s == NULL) goto err;
memset(s,0,sizeof(SSL));
+#ifndef NO_KRB5
+ s->kssl_ctx = kssl_ctx_new();
+#endif /* NO_KRB5 */
+
if (ctx->cert != NULL)
{
/* Earlier library versions used to copy the pointer to
s->server=(ctx->method->ssl_accept == ssl_undefined_function)?0:1;
s->options=ctx->options;
s->mode=ctx->mode;
+ s->read_ahead=ctx->read_ahead; /* used to happen in SSL_clear */
SSL_clear(s);
CRYPTO_new_ex_data(ssl_meth,s,&s->ex_data);
ssl_cert_free(s->cert);
if (s->ctx != NULL)
SSL_CTX_free(s->ctx); /* decrement reference count */
- Free(s);
+ OPENSSL_free(s);
}
SSLerr(SSL_F_SSL_NEW,ERR_R_MALLOC_FAILURE);
return(NULL);
if (s->method != NULL) s->method->ssl_free(s);
- Free(s);
+ OPENSSL_free(s);
}
void SSL_set_bio(SSL *s,BIO *rbio,BIO *wbio)
int SSL_pending(SSL *s)
{
+ /* SSL_pending cannot work properly if read-ahead is enabled
+ * (SSL_[CTX_]ctrl(..., SSL_CTRL_SET_READ_AHEAD, 1, NULL)),
+ * and it is impossible to fix since SSL_pending cannot report
+ * errors that may be observed while scanning the new data.
+ * (Note that SSL_pending() is often used as a boolean value,
+ * so we'd better not return -1.)
+ */
return(s->method->ssl_pending(s));
}
else
r=s->session->sess_cert->cert_chain;
+ /* If we are a client, cert_chain includes the peer's own
+ * certificate; if we are a server, it does not. */
+
return(r);
}
}
}
+struct lhash_st *SSL_CTX_sessions(SSL_CTX *ctx)
+ {
+ return ctx->sessions;
+ }
+
long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,char *parg)
{
long l;
}
}
-int ssl_cipher_id_cmp(SSL_CIPHER *a,SSL_CIPHER *b)
+int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b)
{
long l;
return((l > 0)?1:-1);
}
-int ssl_cipher_ptr_id_cmp(SSL_CIPHER **ap,SSL_CIPHER **bp)
+int ssl_cipher_ptr_id_cmp(const SSL_CIPHER * const *ap,
+ const SSL_CIPHER * const *bp)
{
long l;
return(NULL);
}
if ((skp == NULL) || (*skp == NULL))
- sk=sk_SSL_CIPHER_new(NULL); /* change perhaps later */
+ sk=sk_SSL_CIPHER_new_null(); /* change perhaps later */
else
{
sk= *skp;
return(memcmp(a->session_id,b->session_id,a->session_id_length));
}
+/* These wrapper functions should remain rather than redeclaring
+ * SSL_SESSION_hash and SSL_SESSION_cmp for void* types and casting each
+ * variable. The reason is that the functions aren't static, they're exposed via
+ * ssl.h. */
+static IMPLEMENT_LHASH_HASH_FN(SSL_SESSION_hash, SSL_SESSION *)
+static IMPLEMENT_LHASH_COMP_FN(SSL_SESSION_cmp, SSL_SESSION *)
+
SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)
{
SSL_CTX *ret=NULL;
SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
goto err;
}
- ret=(SSL_CTX *)Malloc(sizeof(SSL_CTX));
+ ret=(SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
if (ret == NULL)
goto err;
ret->default_passwd_callback_userdata=NULL;
ret->client_cert_cb=NULL;
- ret->sessions=lh_new(SSL_SESSION_hash,SSL_SESSION_cmp);
+ ret->sessions=lh_new(LHASH_HASH_FN(SSL_SESSION_hash),
+ LHASH_COMP_FN(SSL_SESSION_cmp));
if (ret->sessions == NULL) goto err;
ret->cert_store=X509_STORE_new();
if (ret->cert_store == NULL) goto err;
return(NULL);
}
+#if 0
static void SSL_COMP_free(SSL_COMP *comp)
- { Free(comp); }
+ { OPENSSL_free(comp); }
+#endif
void SSL_CTX_free(SSL_CTX *a)
{
sk_X509_NAME_pop_free(a->client_CA,X509_NAME_free);
if (a->extra_certs != NULL)
sk_X509_pop_free(a->extra_certs,X509_free);
+#if 0 /* This should never be done, since it removes a global database */
if (a->comp_methods != NULL)
sk_SSL_COMP_pop_free(a->comp_methods,SSL_COMP_free);
- Free(a);
+#else
+ a->comp_methods = NULL;
+#endif
+ OPENSSL_free(a);
}
void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb)
mask|=SSL_aNULL;
emask|=SSL_aNULL;
+#ifndef NO_KRB5
+ mask|=SSL_kKRB5|SSL_aKRB5;
+ emask|=SSL_kKRB5|SSL_aKRB5;
+#endif
+
c->mask=mask;
c->export_mask=emask;
c->valid=1;
else
i=SSL_PKEY_RSA_ENC;
}
+ else if (kalg & SSL_aKRB5)
+ {
+ /* VRS something else here? */
+ return(NULL);
+ }
else /* if (kalg & SSL_aNULL) */
{
SSLerr(SSL_F_SSL_GET_SERVER_SEND_CERT,SSL_R_INTERNAL_ERROR);
reason=BIO_get_retry_reason(bio);
if (reason == BIO_RR_CONNECT)
return(SSL_ERROR_WANT_CONNECT);
+ else if (reason == BIO_RR_ACCEPT)
+ return(SSL_ERROR_WANT_ACCEPT);
else
return(SSL_ERROR_SYSCALL); /* unknown */
}
reason=BIO_get_retry_reason(bio);
if (reason == BIO_RR_CONNECT)
return(SSL_ERROR_WANT_CONNECT);
+ else if (reason == BIO_RR_ACCEPT)
+ return(SSL_ERROR_WANT_ACCEPT);
else
return(SSL_ERROR_SYSCALL);
}
if (s->cert != NULL)
{
+ if (ret->cert != NULL)
+ {
+ ssl_cert_free(ret->cert);
+ }
ret->cert = ssl_cert_dup(s->cert);
if (ret->cert == NULL)
goto err;
if (s->enc_read_ctx != NULL)
{
EVP_CIPHER_CTX_cleanup(s->enc_read_ctx);
- Free(s->enc_read_ctx);
+ OPENSSL_free(s->enc_read_ctx);
s->enc_read_ctx=NULL;
}
if (s->enc_write_ctx != NULL)
{
EVP_CIPHER_CTX_cleanup(s->enc_write_ctx);
- Free(s->enc_write_ctx);
+ OPENSSL_free(s->enc_write_ctx);
s->enc_write_ctx=NULL;
}
if (s->expand != NULL)
void ssl_free_wbio_buffer(SSL *s)
{
- BIO *under;
-
if (s->bbio == NULL) return;
if (s->bbio == s->wbio)
{
/* remove buffering */
- under=BIO_pop(s->wbio);
- if (under != NULL)
- s->wbio=under;
- else
- abort(); /* ok */
- }
+ s->wbio=BIO_pop(s->wbio);
+#ifdef REF_CHECK /* not the usual REF_CHECK, but this avoids adding one more preprocessor symbol */
+ assert(s->wbio != NULL);
+#endif
+ }
BIO_free(s->bbio);
s->bbio=NULL;
}