-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
Copy pathopenssl-1.0.2h-sess_set_get_cb_yield.patch
233 lines (220 loc) · 9.23 KB
/
openssl-1.0.2h-sess_set_get_cb_yield.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
diff -urp openssl-1.0.2h/ssl/s3_srvr.c openssl-1.0.2h-patched/ssl/s3_srvr.c
--- openssl-1.0.2h/ssl/s3_srvr.c 2016-05-03 06:44:42.000000000 -0700
+++ openssl-1.0.2h-patched/ssl/s3_srvr.c 2016-07-19 19:18:03.779159083 -0700
@@ -358,14 +358,20 @@ int ssl3_accept(SSL *s)
case SSL3_ST_SR_CLNT_HELLO_A:
case SSL3_ST_SR_CLNT_HELLO_B:
case SSL3_ST_SR_CLNT_HELLO_C:
+ case SSL3_ST_SR_CLNT_HELLO_D:
s->shutdown = 0;
ret = ssl3_get_client_hello(s);
+ if (ret == PENDING_SESSION) {
+ s->state = SSL3_ST_SR_CLNT_HELLO_D;
+ s->rwstate = SSL_PENDING_SESSION;
+ goto end;
+ }
if (ret <= 0)
goto end;
#ifndef OPENSSL_NO_SRP
- s->state = SSL3_ST_SR_CLNT_HELLO_D;
- case SSL3_ST_SR_CLNT_HELLO_D:
+ s->state = SSL3_ST_SR_CLNT_HELLO_E;
+ case SSL3_ST_SR_CLNT_HELLO_E:
{
int al;
if ((ret = ssl_check_srp_ext_ClientHello(s, &al)) < 0) {
@@ -925,16 +931,25 @@ int ssl3_get_client_hello(SSL *s)
if (s->state == SSL3_ST_SR_CLNT_HELLO_A) {
s->state = SSL3_ST_SR_CLNT_HELLO_B;
}
- s->first_packet = 1;
- n = s->method->ssl_get_message(s,
- SSL3_ST_SR_CLNT_HELLO_B,
- SSL3_ST_SR_CLNT_HELLO_C,
- SSL3_MT_CLIENT_HELLO,
- SSL3_RT_MAX_PLAIN_LENGTH, &ok);
-
- if (!ok)
- return ((int)n);
- s->first_packet = 0;
+
+ if (s->state != SSL3_ST_SR_CLNT_HELLO_D) {
+ s->first_packet = 1;
+ n = s->method->ssl_get_message(s,
+ SSL3_ST_SR_CLNT_HELLO_B,
+ SSL3_ST_SR_CLNT_HELLO_C,
+ SSL3_MT_CLIENT_HELLO,
+ SSL3_RT_MAX_PLAIN_LENGTH, &ok);
+
+ if (!ok)
+ return ((int)n);
+ s->first_packet = 0;
+ } else {
+ /* We have previously parsed the ClientHello message, and can't
+ * call ssl_get_message again without hashing the message into
+ * the Finished digest again. */
+ n = s->init_num;
+ }
+
d = p = (unsigned char *)s->init_msg;
/*
@@ -1041,15 +1056,26 @@ int ssl3_get_client_hello(SSL *s)
if (i == 1 && s->version == s->session->ssl_version) { /* previous
* session */
s->hit = 1;
- } else if (i == -1)
+ } else if (i == -1) {
+ goto err;
+ } else if (i == PENDING_SESSION) {
+ ret = PENDING_SESSION;
goto err;
- else { /* i == 0 */
+ } else { /* i == 0 */
if (!ssl_get_new_session(s, 1))
goto err;
}
}
+ /*
+ * Switch to server state ClientHello C once the session lookup
+ * is finished so it can proceed with original state loop.
+ */
+ if (s->state == SSL3_ST_SR_CLNT_HELLO_D) {
+ s->state = SSL3_ST_SR_CLNT_HELLO_C;
+ }
+
p += j;
if (SSL_IS_DTLS(s)) {
diff -urp openssl-1.0.2h/ssl/ssl3.h openssl-1.0.2h-patched/ssl/ssl3.h
--- openssl-1.0.2h/ssl/ssl3.h 2016-05-03 06:44:42.000000000 -0700
+++ openssl-1.0.2h-patched/ssl/ssl3.h 2016-07-19 19:15:54.117778328 -0700
@@ -698,6 +698,7 @@ typedef struct ssl3_state_st {
# define SSL3_ST_SR_CLNT_HELLO_B (0x111|SSL_ST_ACCEPT)
# define SSL3_ST_SR_CLNT_HELLO_C (0x112|SSL_ST_ACCEPT)
# define SSL3_ST_SR_CLNT_HELLO_D (0x115|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_CLNT_HELLO_E (0x116|SSL_ST_ACCEPT)
/* write to client */
# define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT)
# define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT)
diff -urp openssl-1.0.2h/ssl/ssl.h openssl-1.0.2h-patched/ssl/ssl.h
--- openssl-1.0.2h/ssl/ssl.h 2016-05-03 06:44:42.000000000 -0700
+++ openssl-1.0.2h-patched/ssl/ssl.h 2016-07-19 19:19:44.699562938 -0700
@@ -1243,6 +1243,13 @@ void SSL_CTX_sess_set_get_cb(SSL_CTX *ct
SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (struct ssl_st *ssl,
unsigned char *Data,
int len, int *copy);
+
+/* SSL_magic_pending_session_ptr returns a magic SSL_SESSION* which indicates
+ * that the session isn't currently unavailable. SSL_get_error will then return
+ * SSL_ERROR_PENDING_SESSION and the handshake can be retried later when the
+ * lookup has completed. */
+SSL_SESSION *SSL_magic_pending_session_ptr(void);
+
void SSL_CTX_set_info_callback(SSL_CTX *ctx,
void (*cb) (const SSL *ssl, int type,
int val));
@@ -1408,11 +1415,14 @@ int SSL_extension_supported(unsigned int
# define SSL_READING 3
# define SSL_X509_LOOKUP 4
+# define SSL_PENDING_SESSION 7
+
/* These will only be used when doing non-blocking IO */
# define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING)
# define SSL_want_read(s) (SSL_want(s) == SSL_READING)
# define SSL_want_write(s) (SSL_want(s) == SSL_WRITING)
# define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP)
+# define SSL_want_session(s) (SSL_want(s) == SSL_PENDING_SESSION)
# define SSL_MAC_FLAG_READ_MAC_STREAM 1
# define SSL_MAC_FLAG_WRITE_MAC_STREAM 2
@@ -1865,6 +1875,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
# define SSL_ERROR_ZERO_RETURN 6
# define SSL_ERROR_WANT_CONNECT 7
# define SSL_ERROR_WANT_ACCEPT 8
+# define SSL_ERROR_PENDING_SESSION 11
# define SSL_CTRL_NEED_TMP_RSA 1
# define SSL_CTRL_SET_TMP_RSA 2
# define SSL_CTRL_SET_TMP_DH 3
diff -urp openssl-1.0.2h/ssl/ssl_lib.c openssl-1.0.2h-patched/ssl/ssl_lib.c
--- openssl-1.0.2h/ssl/ssl_lib.c 2016-05-03 06:44:42.000000000 -0700
+++ openssl-1.0.2h-patched/ssl/ssl_lib.c 2016-07-19 19:21:04.032021549 -0700
@@ -2709,6 +2709,9 @@ int SSL_get_error(const SSL *s, int i)
return (SSL_ERROR_SSL);
}
+ if ((i < 0) && SSL_want_session(s))
+ return (SSL_ERROR_PENDING_SESSION);
+
if ((i < 0) && SSL_want_read(s)) {
bio = SSL_get_rbio(s);
if (BIO_should_read(bio))
diff -urp openssl-1.0.2h/ssl/ssl_locl.h openssl-1.0.2h-patched/ssl/ssl_locl.h
--- openssl-1.0.2h/ssl/ssl_locl.h 2016-05-03 06:44:42.000000000 -0700
+++ openssl-1.0.2h-patched/ssl/ssl_locl.h 2016-07-19 19:15:54.117778328 -0700
@@ -518,6 +518,8 @@
#define CERT_PRIVATE_KEY 2
*/
+# define PENDING_SESSION -10000
+
# ifndef OPENSSL_NO_EC
/*
* From ECC-TLS draft, used in encoding the curve type in ECParameters
diff -urp openssl-1.0.2h/ssl/ssl_sess.c openssl-1.0.2h-patched/ssl/ssl_sess.c
--- openssl-1.0.2h/ssl/ssl_sess.c 2016-05-03 06:44:42.000000000 -0700
+++ openssl-1.0.2h-patched/ssl/ssl_sess.c 2016-07-19 19:15:54.118778298 -0700
@@ -143,10 +143,20 @@
#endif
#include "ssl_locl.h"
+/* The address of this is a magic value, a pointer to which is returned by
+ * SSL_magic_pending_session_ptr(). It allows a session callback to indicate
+ * that it needs to asynchronously fetch session information. */
+static char g_pending_session_magic;
+
static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s);
static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
+SSL_SESSION *SSL_magic_pending_session_ptr()
+{
+ return (SSL_SESSION*) &g_pending_session_magic;
+}
+
SSL_SESSION *SSL_get_session(const SSL *ssl)
/* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */
{
@@ -626,6 +636,12 @@ int ssl_get_prev_session(SSL *s, unsigne
int copy = 1;
if ((ret = s->session_ctx->get_session_cb(s, session_id, len, ©))) {
+ if (ret == SSL_magic_pending_session_ptr()) {
+ /* This is a magic value which indicates that
+ * the callback needs to unwind the stack and
+ * figure out the session asynchronously. */
+ return PENDING_SESSION;
+ }
s->session_ctx->stats.sess_cb_hit++;
/*
diff -urp openssl-1.0.2h/ssl/ssl_stat.c openssl-1.0.2h-patched/ssl/ssl_stat.c
--- openssl-1.0.2h/ssl/ssl_stat.c 2016-05-03 06:44:42.000000000 -0700
+++ openssl-1.0.2h-patched/ssl/ssl_stat.c 2016-07-19 19:15:54.118778298 -0700
@@ -353,6 +353,12 @@ const char *SSL_state_string_long(const
case SSL3_ST_SR_CLNT_HELLO_C:
str = "SSLv3 read client hello C";
break;
+ case SSL3_ST_SR_CLNT_HELLO_D:
+ str = "SSLv3 read client hello D";
+ break;
+ case SSL3_ST_SR_CLNT_HELLO_E:
+ str = "SSLv3 read client hello E";
+ break;
case SSL3_ST_SW_HELLO_REQ_A:
str = "SSLv3 write hello request A";
break;
@@ -737,6 +743,12 @@ const char *SSL_state_string(const SSL *
case SSL3_ST_SR_CLNT_HELLO_C:
str = "3RCH_C";
break;
+ case SSL3_ST_SR_CLNT_HELLO_D:
+ str = "3RCH_D";
+ break;
+ case SSL3_ST_SR_CLNT_HELLO_E:
+ str = "3RCH_E";
+ break;
case SSL3_ST_SW_SRVR_HELLO_A:
str = "3WSH_A";
break;