* evil casts, but these functions are only called if there's a library
* bug
*/
- (int (*)(SSL *, SSL3_RECORD *, unsigned int, int))ssl_undefined_function,
+ (int (*)(SSL *, SSL3_RECORD *, size_t, int))ssl_undefined_function,
(int (*)(SSL *, SSL3_RECORD *, unsigned char *, int))ssl_undefined_function,
ssl_undefined_function,
- (int (*)(SSL *, unsigned char *, unsigned char *, int))
+ (int (*)(SSL *, unsigned char *, unsigned char *, size_t, size_t *))
ssl_undefined_function,
(int (*)(SSL *, int))ssl_undefined_function,
- (int (*)(SSL *, const char *, int, unsigned char *))
+ (size_t (*)(SSL *, const char *, int, unsigned char *))
ssl_undefined_function,
0, /* finish_mac_length */
NULL, /* client_finished_label */
enum { READFUNC, WRITEFUNC, OTHERFUNC } type;
union {
int (*func_read) (SSL *, void *, size_t, size_t *);
- int (*func_write) (SSL *, const void *, int);
+ 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, &s->asyncread);
+ 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);
}
args.f.func_read = s->method->ssl_read;
ret = ssl_start_async_job(s, &args, ssl_io_intern);
- *read = s->asyncread;
+ *read = s->asyncrw;
return ret;
} else {
return s->method->ssl_read(s, buf, num, read);
args.f.func_read = s->method->ssl_peek;
ret = ssl_start_async_job(s, &args, ssl_io_intern);
- *read = s->asyncread;
+ *read = s->asyncrw;
return ret;
} else {
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;
size_t SSL_SESSION_get_master_key(const SSL_SESSION *session,
unsigned char *out, size_t outlen)
{
- if (session->master_key_length < 0) {
- /* Should never happen */
- return 0;
- }
if (outlen == 0)
return session->master_key_length;
- if (outlen > (size_t)session->master_key_length)
+ if (outlen > session->master_key_length)
outlen = session->master_key_length;
memcpy(out, session->master_key, outlen);
return outlen;
}
/* Retrieve handshake hashes */
-int ssl_handshake_hash(SSL *s, unsigned char *out, int outlen)
+int ssl_handshake_hash(SSL *s, unsigned char *out, size_t outlen,
+ size_t *hashlen)
{
EVP_MD_CTX *ctx = NULL;
EVP_MD_CTX *hdgst = s->s3->handshake_dgst;
- int ret = EVP_MD_CTX_size(hdgst);
- if (ret < 0 || ret > outlen) {
- ret = 0;
+ int hashleni = EVP_MD_CTX_size(hdgst);
+ int ret = 0;
+
+ if (hashleni < 0 || (size_t)hashleni > outlen)
goto err;
- }
+
ctx = EVP_MD_CTX_new();
- if (ctx == NULL) {
- ret = 0;
+ if (ctx == NULL)
goto err;
- }
+
if (!EVP_MD_CTX_copy_ex(ctx, hdgst)
|| EVP_DigestFinal_ex(ctx, out, NULL) <= 0)
- ret = 0;
+ goto err;
+
+ *hashlen = hashleni;
+
+ ret = 1;
err:
EVP_MD_CTX_free(ctx);
return ret;