int num;
enum { READFUNC, WRITEFUNC, OTHERFUNC } type;
union {
- int (*func_read) (SSL *, void *, int);
- int (*func_write) (SSL *, const void *, int);
+ int (*func_read) (SSL *, void *, size_t, size_t *);
+ int (*func_write) (SSL *, const void *, size_t, size_t *);
int (*func_other) (SSL *);
} f;
};
num = args->num;
switch (args->type) {
case READFUNC:
- return args->f.func_read(s, buf, num);
+ return args->f.func_read(s, buf, num, &s->asyncrw);
case WRITEFUNC:
- return args->f.func_write(s, buf, num);
+ return args->f.func_write(s, buf, num, &s->asyncrw);
case OTHERFUNC:
return args->f.func_other(s);
}
}
int SSL_read(SSL *s, void *buf, int num)
+{
+ int ret;
+ size_t read;
+
+ if (num < 0) {
+ SSLerr(SSL_F_SSL_READ, SSL_R_BAD_LENGTH);
+ return -1;
+ }
+
+ ret = SSL_read_ex(s, buf, (size_t)num, &read);
+
+ /*
+ * The cast is safe here because ret should be <= INT_MAX because num is
+ * <= INT_MAX
+ */
+ if (ret > 0)
+ ret = (int)read;
+
+ return ret;
+}
+
+int SSL_read_ex(SSL *s, void *buf, size_t num, size_t *read)
{
if (s->handshake_func == NULL) {
- SSLerr(SSL_F_SSL_READ, SSL_R_UNINITIALIZED);
+ SSLerr(SSL_F_SSL_READ_EX, SSL_R_UNINITIALIZED);
return -1;
}
if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
struct ssl_async_args args;
+ int ret;
args.s = s;
args.buf = buf;
args.type = READFUNC;
args.f.func_read = s->method->ssl_read;
- return ssl_start_async_job(s, &args, ssl_io_intern);
+ ret = ssl_start_async_job(s, &args, ssl_io_intern);
+ *read = s->asyncrw;
+ return ret;
} else {
- return s->method->ssl_read(s, buf, num);
+ return s->method->ssl_read(s, buf, num, read);
}
}
int SSL_peek(SSL *s, void *buf, int num)
+{
+ int ret;
+ size_t read;
+
+ if (num < 0) {
+ SSLerr(SSL_F_SSL_PEEK, SSL_R_BAD_LENGTH);
+ return -1;
+ }
+
+ ret = SSL_peek_ex(s, buf, (size_t)num, &read);
+
+ /*
+ * The cast is safe here because ret should be <= INT_MAX because num is
+ * <= INT_MAX
+ */
+ if (ret > 0)
+ ret = (int)read;
+
+ return ret;
+}
+
+int SSL_peek_ex(SSL *s, void *buf, size_t num, size_t *read)
{
if (s->handshake_func == NULL) {
- SSLerr(SSL_F_SSL_PEEK, SSL_R_UNINITIALIZED);
+ SSLerr(SSL_F_SSL_PEEK_EX, SSL_R_UNINITIALIZED);
return -1;
}
}
if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
struct ssl_async_args args;
+ int ret;
args.s = s;
args.buf = buf;
args.type = READFUNC;
args.f.func_read = s->method->ssl_peek;
- return ssl_start_async_job(s, &args, ssl_io_intern);
+ ret = ssl_start_async_job(s, &args, ssl_io_intern);
+ *read = s->asyncrw;
+ return ret;
} else {
- return s->method->ssl_peek(s, buf, num);
+ return s->method->ssl_peek(s, buf, num, read);
}
}
int SSL_write(SSL *s, const void *buf, int num)
+{
+ int ret;
+ size_t written;
+
+ if (num < 0) {
+ SSLerr(SSL_F_SSL_WRITE, SSL_R_BAD_LENGTH);
+ return -1;
+ }
+
+ ret = SSL_write_ex(s, buf, (size_t)num, &written);
+
+ /*
+ * The cast is safe here because ret should be <= INT_MAX because num is
+ * <= INT_MAX
+ */
+ if (ret > 0)
+ ret = (int)written;
+
+ return ret;
+}
+
+int SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *written)
{
if (s->handshake_func == NULL) {
- SSLerr(SSL_F_SSL_WRITE, SSL_R_UNINITIALIZED);
+ SSLerr(SSL_F_SSL_WRITE_EX, SSL_R_UNINITIALIZED);
return -1;
}
if (s->shutdown & SSL_SENT_SHUTDOWN) {
s->rwstate = SSL_NOTHING;
- SSLerr(SSL_F_SSL_WRITE, SSL_R_PROTOCOL_IS_SHUTDOWN);
+ SSLerr(SSL_F_SSL_WRITE_EX, SSL_R_PROTOCOL_IS_SHUTDOWN);
return (-1);
}
if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
+ int ret;
struct ssl_async_args args;
args.s = s;
args.type = WRITEFUNC;
args.f.func_write = s->method->ssl_write;
- return ssl_start_async_job(s, &args, ssl_io_intern);
+ ret = ssl_start_async_job(s, &args, ssl_io_intern);
+ *written = s->asyncrw;
+ return ret;
} else {
- return s->method->ssl_write(s, buf, num);
+ return s->method->ssl_write(s, buf, num, written);
}
}
s->split_send_fragment = s->max_send_fragment;
return 1;
case SSL_CTRL_SET_SPLIT_SEND_FRAGMENT:
- if ((unsigned int)larg > s->max_send_fragment || larg == 0)
+ if ((size_t)larg > s->max_send_fragment || larg == 0)
return 0;
s->split_send_fragment = larg;
return 1;
ctx->split_send_fragment = ctx->max_send_fragment;
return 1;
case SSL_CTRL_SET_SPLIT_SEND_FRAGMENT:
- if ((unsigned int)larg > ctx->max_send_fragment || larg == 0)
+ if ((size_t)larg > ctx->max_send_fragment || larg == 0)
return 0;
ctx->split_send_fragment = larg;
return 1;
const char *ssl_protocol_to_string(int version)
{
- if (version == TLS1_2_VERSION)
+ switch(version)
+ {
+ case TLS1_3_VERSION:
+ return "TLSv1.3";
+
+ case TLS1_2_VERSION:
return "TLSv1.2";
- else if (version == TLS1_1_VERSION)
+
+ case TLS1_1_VERSION:
return "TLSv1.1";
- else if (version == TLS1_VERSION)
+
+ case TLS1_VERSION:
return "TLSv1";
- else if (version == SSL3_VERSION)
+
+ case SSL3_VERSION:
return "SSLv3";
- else if (version == DTLS1_BAD_VER)
+
+ case DTLS1_BAD_VER:
return "DTLSv0.9";
- else if (version == DTLS1_VERSION)
+
+ case DTLS1_VERSION:
return "DTLSv1";
- else if (version == DTLS1_2_VERSION)
+
+ case DTLS1_2_VERSION:
return "DTLSv1.2";
- else
- return ("unknown");
+
+ default:
+ return "unknown";
+ }
}
const char *SSL_get_version(const SSL *s)
ctx->cert_store = store;
}
+void SSL_CTX_set1_cert_store(SSL_CTX *ctx, X509_STORE *store)
+{
+ if (store != NULL)
+ X509_STORE_up_ref(store);
+ SSL_CTX_set_cert_store(ctx, store);
+}
+
int SSL_want(const SSL *s)
{
return (s->rwstate);