Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Third Party Openssl
提交
6434abbf
T
Third Party Openssl
项目概览
OpenHarmony
/
Third Party Openssl
8 个月 前同步成功
通知
8
Star
18
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
Third Party Openssl
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
6434abbf
编写于
8月 11, 2007
作者:
D
Dr. Stephen Henson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
RFC4507 (including RFC4507bis) TLS stateless session resumption support
for OpenSSL.
上级
e45c1007
变更
19
隐藏空白更改
内联
并排
Showing
19 changed file
with
780 addition
and
22 deletion
+780
-22
CHANGES
CHANGES
+18
-0
apps/s_apps.h
apps/s_apps.h
+3
-0
apps/s_cb.c
apps/s_cb.c
+59
-0
apps/s_client.c
apps/s_client.c
+64
-0
apps/s_server.c
apps/s_server.c
+32
-0
ssl/s2_srvr.c
ssl/s2_srvr.c
+1
-1
ssl/s3_clnt.c
ssl/s3_clnt.c
+129
-1
ssl/s3_lib.c
ssl/s3_lib.c
+9
-0
ssl/s3_srvr.c
ssl/s3_srvr.c
+105
-2
ssl/ssl.h
ssl/ssl.h
+21
-0
ssl/ssl3.h
ssl/ssl3.h
+5
-0
ssl/ssl_asn1.c
ssl/ssl_asn1.c
+62
-7
ssl/ssl_err.c
ssl/ssl_err.c
+2
-0
ssl/ssl_lib.c
ssl/ssl_lib.c
+10
-0
ssl/ssl_locl.h
ssl/ssl_locl.h
+5
-1
ssl/ssl_sess.c
ssl/ssl_sess.c
+34
-6
ssl/ssl_txt.c
ssl/ssl_txt.c
+16
-0
ssl/t1_lib.c
ssl/t1_lib.c
+198
-4
ssl/tls1.h
ssl/tls1.h
+7
-0
未找到文件。
CHANGES
浏览文件 @
6434abbf
...
...
@@ -4,6 +4,24 @@
Changes between 0.9.8f and 0.9.9 [xx XXX xxxx]
*) Add RFC4507 support to OpenSSL. This includes the corrections in
RFC4507bis. The encrypted ticket format is an encrypted encoded
SSL_SESSION structure, that way new session features are automatically
supported.
If a client application caches session in an SSL_SESSION support it
should automatically be supported because an extension includes the
ticket in the structure. The SSL_CTX structure automatically generates
keys for ticket protection in servers so again support should be possible
with no application modification.
If a client or server wishes to disable RFC4507 support then the option
SSL_OP_NO_TICKET can be set.
Add a TLS extension debugging callback to allow the contents of any client
or server extensions to be examined.
[Steve Henson]
*) Final changes to avoid use of pointer pointer casts in OpenSSL.
OpenSSL should now compile cleanly on gcc 4.2
[Peter Hartley <pdh@utter.chaos.org.uk>, Steve Henson]
...
...
apps/s_apps.h
浏览文件 @
6434abbf
...
...
@@ -167,4 +167,7 @@ long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp,
#ifdef HEADER_SSL_H
void
MS_CALLBACK
apps_ssl_info_callback
(
const
SSL
*
s
,
int
where
,
int
ret
);
void
MS_CALLBACK
msg_cb
(
int
write_p
,
int
version
,
int
content_type
,
const
void
*
buf
,
size_t
len
,
SSL
*
ssl
,
void
*
arg
);
void
MS_CALLBACK
tlsext_cb
(
SSL
*
s
,
int
client_server
,
int
type
,
unsigned
char
*
data
,
int
len
,
void
*
arg
);
#endif
apps/s_cb.c
浏览文件 @
6434abbf
...
...
@@ -592,3 +592,62 @@ void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *
}
BIO_flush
(
bio
);
}
void
MS_CALLBACK
tlsext_cb
(
SSL
*
s
,
int
client_server
,
int
type
,
unsigned
char
*
data
,
int
len
,
void
*
arg
)
{
BIO
*
bio
=
arg
;
char
*
extname
;
switch
(
type
)
{
case
TLSEXT_TYPE_server_name
:
extname
=
"server name"
;
break
;
case
TLSEXT_TYPE_max_fragment_length
:
extname
=
"max fragment length"
;
break
;
case
TLSEXT_TYPE_client_certificate_url
:
extname
=
"client certificate URL"
;
break
;
case
TLSEXT_TYPE_trusted_ca_keys
:
extname
=
"trusted CA keys"
;
break
;
case
TLSEXT_TYPE_truncated_hmac
:
extname
=
"truncated HMAC"
;
break
;
case
TLSEXT_TYPE_status_request
:
extname
=
"status request"
;
break
;
case
TLSEXT_TYPE_elliptic_curves
:
extname
=
"elliptic curves"
;
break
;
case
TLSEXT_TYPE_ec_point_formats
:
extname
=
"EC point formats"
;
break
;
case
TLSEXT_TYPE_session_ticket
:
extname
=
"server ticket"
;
break
;
default:
extname
=
"unknown"
;
break
;
}
BIO_printf
(
bio
,
"TLS %s extension
\"
%s
\"
(id=%d), len=%d
\n
"
,
client_server
?
"server"
:
"client"
,
extname
,
type
,
len
);
BIO_dump
(
bio
,
data
,
len
);
BIO_flush
(
bio
);
}
apps/s_client.c
浏览文件 @
6434abbf
...
...
@@ -194,6 +194,9 @@ static int c_nbio=0;
#endif
static
int
c_Pause
=
0
;
static
int
c_debug
=
0
;
#ifndef OPENSSL_NO_TLSEXT
static
int
c_tlsextdebug
=
0
;
#endif
static
int
c_msg
=
0
;
static
int
c_showcerts
=
0
;
...
...
@@ -406,6 +409,8 @@ int MAIN(int argc, char **argv)
tlsextctx
tlsextcbp
=
{
NULL
,
0
};
#endif
char
*
sess_in
=
NULL
;
char
*
sess_out
=
NULL
;
struct
sockaddr
peer
;
int
peerlen
=
sizeof
(
peer
);
int
enable_timeouts
=
0
;
...
...
@@ -480,6 +485,16 @@ int MAIN(int argc, char **argv)
if
(
--
argc
<
1
)
goto
bad
;
cert_file
=
*
(
++
argv
);
}
else
if
(
strcmp
(
*
argv
,
"-sess_out"
)
==
0
)
{
if
(
--
argc
<
1
)
goto
bad
;
sess_out
=
*
(
++
argv
);
}
else
if
(
strcmp
(
*
argv
,
"-sess_in"
)
==
0
)
{
if
(
--
argc
<
1
)
goto
bad
;
sess_in
=
*
(
++
argv
);
}
else
if
(
strcmp
(
*
argv
,
"-certform"
)
==
0
)
{
if
(
--
argc
<
1
)
goto
bad
;
...
...
@@ -506,6 +521,10 @@ int MAIN(int argc, char **argv)
c_Pause
=
1
;
else
if
(
strcmp
(
*
argv
,
"-debug"
)
==
0
)
c_debug
=
1
;
#ifndef OPENSSL_NO_TLSEXT
else
if
(
strcmp
(
*
argv
,
"-tlsextdebug"
)
==
0
)
c_tlsextdebug
=
1
;
#endif
#ifdef WATT32
else
if
(
strcmp
(
*
argv
,
"-wdebug"
)
==
0
)
dbug_init
();
...
...
@@ -604,6 +623,10 @@ int MAIN(int argc, char **argv)
off
|=
SSL_OP_NO_SSLv2
;
else
if
(
strcmp
(
*
argv
,
"-no_comp"
)
==
0
)
{
off
|=
SSL_OP_NO_COMPRESSION
;
}
#ifndef OPENSSL_NO_TLSEXT
else
if
(
strcmp
(
*
argv
,
"-no_ticket"
)
==
0
)
{
off
|=
SSL_OP_NO_TICKET
;
}
#endif
else
if
(
strcmp
(
*
argv
,
"-serverpref"
)
==
0
)
off
|=
SSL_OP_CIPHER_SERVER_PREFERENCE
;
else
if
(
strcmp
(
*
argv
,
"-cipher"
)
==
0
)
...
...
@@ -791,6 +814,29 @@ bad:
#endif
con
=
SSL_new
(
ctx
);
if
(
sess_in
)
{
SSL_SESSION
*
sess
;
BIO
*
stmp
=
BIO_new_file
(
sess_in
,
"r"
);
if
(
!
stmp
)
{
BIO_printf
(
bio_err
,
"Can't open session file %s
\n
"
,
sess_in
);
ERR_print_errors
(
bio_err
);
goto
end
;
}
sess
=
PEM_read_bio_SSL_SESSION
(
stmp
,
NULL
,
0
,
NULL
);
BIO_free
(
stmp
);
if
(
!
sess
)
{
BIO_printf
(
bio_err
,
"Can't open session file %s
\n
"
,
sess_in
);
ERR_print_errors
(
bio_err
);
goto
end
;
}
SSL_set_session
(
con
,
sess
);
SSL_SESSION_free
(
sess
);
}
#ifndef OPENSSL_NO_TLSEXT
if
(
servername
!=
NULL
)
{
...
...
@@ -893,6 +939,13 @@ re_start:
SSL_set_msg_callback
(
con
,
msg_cb
);
SSL_set_msg_callback_arg
(
con
,
bio_c_out
);
}
#ifndef OPENSSL_NO_TLSEXT
if
(
c_tlsextdebug
)
{
SSL_set_tlsext_debug_callback
(
con
,
tlsext_cb
);
SSL_set_tlsext_debug_arg
(
con
,
bio_c_out
);
}
#endif
SSL_set_bio
(
con
,
sbio
,
sbio
);
SSL_set_connect_state
(
con
);
...
...
@@ -1022,6 +1075,17 @@ re_start:
BIO_printf
(
bio_c_out
,
"Server did %sacknowledge servername extension.
\n
"
,
tlsextcbp
.
ack
?
""
:
"not "
);
}
#endif
if
(
sess_out
)
{
BIO
*
stmp
=
BIO_new_file
(
sess_out
,
"w"
);
if
(
stmp
)
{
PEM_write_bio_SSL_SESSION
(
stmp
,
SSL_get_session
(
con
));
BIO_free
(
stmp
);
}
else
BIO_printf
(
bio_err
,
"Error writing session file %s
\n
"
,
sess_out
);
}
print_stuff
(
bio_c_out
,
con
,
full_log
);
if
(
full_log
>
0
)
full_log
--
;
...
...
apps/s_server.c
浏览文件 @
6434abbf
...
...
@@ -281,6 +281,9 @@ static int www=0;
static
BIO
*
bio_s_out
=
NULL
;
static
int
s_debug
=
0
;
#ifndef OPENSSL_NO_TLSEXT
static
int
s_tlsextdebug
=
0
;
#endif
static
int
s_msg
=
0
;
static
int
s_quiet
=
0
;
...
...
@@ -869,6 +872,10 @@ int MAIN(int argc, char *argv[])
}
else
if
(
strcmp
(
*
argv
,
"-debug"
)
==
0
)
{
s_debug
=
1
;
}
#ifndef OPENSSL_NO_TLSEXT
else
if
(
strcmp
(
*
argv
,
"-tlsextdebug"
)
==
0
)
s_tlsextdebug
=
1
;
#endif
else
if
(
strcmp
(
*
argv
,
"-msg"
)
==
0
)
{
s_msg
=
1
;
}
else
if
(
strcmp
(
*
argv
,
"-hack"
)
==
0
)
...
...
@@ -922,6 +929,10 @@ int MAIN(int argc, char *argv[])
{
off
|=
SSL_OP_NO_TLSv1
;
}
else
if
(
strcmp
(
*
argv
,
"-no_comp"
)
==
0
)
{
off
|=
SSL_OP_NO_COMPRESSION
;
}
#ifndef OPENSSL_NO_TLSEXT
else
if
(
strcmp
(
*
argv
,
"-no_ticket"
)
==
0
)
{
off
|=
SSL_OP_NO_TICKET
;
}
#endif
#ifndef OPENSSL_NO_SSL2
else
if
(
strcmp
(
*
argv
,
"-ssl2"
)
==
0
)
{
meth
=
SSLv2_server_method
();
}
...
...
@@ -1541,6 +1552,13 @@ static int sv_body(char *hostname, int s, unsigned char *context)
if
(
con
==
NULL
)
{
con
=
SSL_new
(
ctx
);
#ifndef OPENSSL_NO_TLSEXT
if
(
s_tlsextdebug
)
{
SSL_set_tlsext_debug_callback
(
con
,
tlsext_cb
);
SSL_set_tlsext_debug_arg
(
con
,
bio_s_out
);
}
#endif
#ifndef OPENSSL_NO_KRB5
if
((
con
->
kssl_ctx
=
kssl_ctx_new
())
!=
NULL
)
{
...
...
@@ -1610,6 +1628,13 @@ static int sv_body(char *hostname, int s, unsigned char *context)
SSL_set_msg_callback
(
con
,
msg_cb
);
SSL_set_msg_callback_arg
(
con
,
bio_s_out
);
}
#ifndef OPENSSL_NO_TLSEXT
if
(
s_tlsextdebug
)
{
SSL_set_tlsext_debug_callback
(
con
,
tlsext_cb
);
SSL_set_tlsext_debug_arg
(
con
,
bio_s_out
);
}
#endif
width
=
s
+
1
;
for
(;;)
...
...
@@ -1989,6 +2014,13 @@ static int www_body(char *hostname, int s, unsigned char *context)
if
(
!
BIO_set_write_buffer_size
(
io
,
bufsize
))
goto
err
;
if
((
con
=
SSL_new
(
ctx
))
==
NULL
)
goto
err
;
#ifndef OPENSSL_NO_TLSEXT
if
(
s_tlsextdebug
)
{
SSL_set_tlsext_debug_callback
(
con
,
tlsext_cb
);
SSL_set_tlsext_debug_arg
(
con
,
bio_s_out
);
}
#endif
#ifndef OPENSSL_NO_KRB5
if
((
con
->
kssl_ctx
=
kssl_ctx_new
())
!=
NULL
)
{
...
...
ssl/s2_srvr.c
浏览文件 @
6434abbf
...
...
@@ -607,7 +607,7 @@ static int get_client_hello(SSL *s)
else
{
i
=
ssl_get_prev_session
(
s
,
&
(
p
[
s
->
s2
->
tmp
.
cipher_spec_length
]),
s
->
s2
->
tmp
.
session_id_length
);
s
->
s2
->
tmp
.
session_id_length
,
NULL
);
if
(
i
==
1
)
{
/* previous session */
s
->
hit
=
1
;
...
...
ssl/s3_clnt.c
浏览文件 @
6434abbf
...
...
@@ -163,6 +163,9 @@
static
const
SSL_METHOD
*
ssl3_get_client_method
(
int
ver
);
static
int
ca_dn_cmp
(
const
X509_NAME
*
const
*
a
,
const
X509_NAME
*
const
*
b
);
#ifndef OPENSSL_NO_TLSEXT
static
int
ssl3_check_finished
(
SSL
*
s
);
#endif
static
const
SSL_METHOD
*
ssl3_get_client_method
(
int
ver
)
{
...
...
@@ -286,6 +289,17 @@ int ssl3_connect(SSL *s)
case
SSL3_ST_CR_CERT_A
:
case
SSL3_ST_CR_CERT_B
:
#ifndef OPENSSL_NO_TLSEXT
ret
=
ssl3_check_finished
(
s
);
if
(
ret
<=
0
)
goto
end
;
if
(
ret
==
2
)
{
s
->
hit
=
1
;
s
->
state
=
SSL3_ST_CR_FINISHED_A
;
s
->
init_num
=
0
;
break
;
}
#endif
/* Check if it is anon DH/ECDH */
/* or PSK */
if
(
!
(
s
->
s3
->
tmp
.
new_cipher
->
algorithm_auth
&
SSL_aNULL
)
&&
...
...
@@ -439,11 +453,27 @@ int ssl3_connect(SSL *s)
}
else
{
#ifndef OPENSSL_NO_TLSEXT
/* Allow NewSessionTicket if ticket expected */
if
(
s
->
tlsext_ticket_expected
)
s
->
s3
->
tmp
.
next_state
=
SSL3_ST_CR_SESSION_TICKET_A
;
else
#endif
s
->
s3
->
tmp
.
next_state
=
SSL3_ST_CR_FINISHED_A
;
}
s
->
init_num
=
0
;
break
;
#ifndef OPENSSL_NO_TLSEXT
case
SSL3_ST_CR_SESSION_TICKET_A
:
case
SSL3_ST_CR_SESSION_TICKET_B
:
ret
=
ssl3_get_new_session_ticket
(
s
);
s
->
state
=
SSL3_ST_CR_FINISHED_A
;
s
->
init_num
=
0
;
break
;
#endif
case
SSL3_ST_CR_FINISHED_A
:
case
SSL3_ST_CR_FINISHED_B
:
...
...
@@ -671,7 +701,7 @@ int ssl3_get_server_hello(SSL *s)
SSL3_ST_CR_SRVR_HELLO_A
,
SSL3_ST_CR_SRVR_HELLO_B
,
-
1
,
3
00
,
/* ?? */
200
00
,
/* ?? */
&
ok
);
if
(
!
ok
)
return
((
int
)
n
);
...
...
@@ -1693,6 +1723,74 @@ static int ca_dn_cmp(const X509_NAME * const *a, const X509_NAME * const *b)
{
return
(
X509_NAME_cmp
(
*
a
,
*
b
));
}
#ifndef OPENSSL_NO_TLSEXT
int
ssl3_get_new_session_ticket
(
SSL
*
s
)
{
int
ok
,
al
,
ret
=
0
,
ticklen
;
long
n
;
const
unsigned
char
*
p
;
unsigned
char
*
d
;
n
=
s
->
method
->
ssl_get_message
(
s
,
SSL3_ST_CR_SESSION_TICKET_A
,
SSL3_ST_CR_SESSION_TICKET_B
,
-
1
,
16384
,
&
ok
);
if
(
!
ok
)
return
((
int
)
n
);
if
(
s
->
s3
->
tmp
.
message_type
==
SSL3_MT_FINISHED
)
{
s
->
s3
->
tmp
.
reuse_message
=
1
;
return
(
1
);
}
if
(
s
->
s3
->
tmp
.
message_type
!=
SSL3_MT_NEWSESSION_TICKET
)
{
al
=
SSL_AD_UNEXPECTED_MESSAGE
;
SSLerr
(
SSL_F_SSL3_GET_NEW_SESSION_TICKET
,
SSL_R_BAD_MESSAGE_TYPE
);
goto
f_err
;
}
if
(
n
<
6
)
{
/* need at least ticket_lifetime_hint + ticket length */
al
=
SSL3_AL_FATAL
,
SSL_AD_DECODE_ERROR
;
SSLerr
(
SSL_F_SSL3_GET_NEW_SESSION_TICKET
,
SSL_R_LENGTH_MISMATCH
);
goto
f_err
;
}
p
=
d
=
(
unsigned
char
*
)
s
->
init_msg
;
n2l
(
p
,
s
->
session
->
tlsext_tick_lifetime_hint
);
n2s
(
p
,
ticklen
);
/* ticket_lifetime_hint + ticket_length + ticket */
if
(
ticklen
+
6
!=
n
)
{
al
=
SSL3_AL_FATAL
,
SSL_AD_DECODE_ERROR
;
SSLerr
(
SSL_F_SSL3_NEW_SESSION_TICKET
,
SSL_R_LENGTH_MISMATCH
);
goto
f_err
;
}
if
(
s
->
session
->
tlsext_tick
)
{
OPENSSL_free
(
s
->
session
->
tlsext_tick
);
s
->
session
->
tlsext_ticklen
=
0
;
}
s
->
session
->
tlsext_tick
=
OPENSSL_malloc
(
ticklen
);
if
(
!
s
->
session
->
tlsext_tick
)
{
SSLerr
(
SSL_F_SSL3_NEW_SESSION_TICKET
,
ERR_R_MALLOC_FAILURE
);
goto
err
;
}
memcpy
(
s
->
session
->
tlsext_tick
,
p
,
ticklen
);
s
->
session
->
tlsext_ticklen
=
ticklen
;
ret
=
1
;
return
(
ret
);
f_err:
ssl3_send_alert
(
s
,
SSL3_AL_FATAL
,
al
);
err:
return
(
-
1
);
}
#endif
int
ssl3_get_server_done
(
SSL
*
s
)
{
...
...
@@ -2600,3 +2698,33 @@ f_err:
err:
return
(
0
);
}
/* Check to see if handshake is full or resumed. Usually this is just a
* case of checking to see if a cache hit has occurred. In the case of
* session tickets we have to check the next message to be sure.
*/
#ifndef OPENSSL_NO_TLSEXT
static
int
ssl3_check_finished
(
SSL
*
s
)
{
int
ok
;
long
n
;
if
(
!
s
->
session
->
tlsext_tick
)
return
1
;
/* this function is called when we really expect a Certificate
* message, so permit appropriate message length */
n
=
s
->
method
->
ssl_get_message
(
s
,
SSL3_ST_CR_CERT_A
,
SSL3_ST_CR_CERT_B
,
-
1
,
s
->
max_cert_list
,
&
ok
);
if
(
!
ok
)
return
((
int
)
n
);
s
->
s3
->
tmp
.
reuse_message
=
1
;
if
((
s
->
s3
->
tmp
.
message_type
==
SSL3_MT_FINISHED
)
||
(
s
->
s3
->
tmp
.
message_type
==
SSL3_MT_NEWSESSION_TICKET
))
return
2
;
return
1
;
}
#endif
ssl/s3_lib.c
浏览文件 @
6434abbf
...
...
@@ -2338,6 +2338,9 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
}
s
->
options
|=
SSL_OP_NO_SSLv2
;
/* can't use extension w/ SSL 2.0 format */
break
;
case
SSL_CTRL_SET_TLSEXT_DEBUG_ARG
:
s
->
tlsext_debug_arg
=
parg
;
break
;
#endif
/* !OPENSSL_NO_TLSEXT */
default:
break
;
...
...
@@ -2389,6 +2392,12 @@ long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp)(void))
s
->
cert
->
ecdh_tmp_cb
=
(
EC_KEY
*
(
*
)(
SSL
*
,
int
,
int
))
fp
;
}
break
;
#endif
#ifndef OPENSSL_NO_TLSEXT
case
SSL_CTRL_SET_TLSEXT_DEBUG_CB
:
s
->
tlsext_debug_cb
=
(
void
(
*
)(
SSL
*
,
int
,
int
,
unsigned
char
*
,
int
,
void
*
))
fp
;
break
;
#endif
default:
break
;
...
...
ssl/s3_srvr.c
浏览文件 @
6434abbf
...
...
@@ -158,6 +158,7 @@
#include <openssl/rand.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/x509.h>
#ifndef OPENSSL_NO_DH
#include <openssl/dh.h>
...
...
@@ -529,11 +530,26 @@ int ssl3_accept(SSL *s)
if
(
ret
<=
0
)
goto
end
;
if
(
s
->
hit
)
s
->
state
=
SSL_ST_OK
;
#ifndef OPENSSL_NO_TLSEXT
else
if
(
s
->
tlsext_ticket_expected
)
s
->
state
=
SSL3_ST_SW_SESSION_TICKET_A
;
#endif
else
s
->
state
=
SSL3_ST_SW_CHANGE_A
;
s
->
init_num
=
0
;
break
;
#ifndef OPENSSL_NO_TLSEXT
case
SSL3_ST_SW_SESSION_TICKET_A
:
case
SSL3_ST_SW_SESSION_TICKET_B
:
ret
=
ssl3_send_newsession_ticket
(
s
);
if
(
ret
<=
0
)
goto
end
;
s
->
state
=
SSL3_ST_SW_CHANGE_A
;
s
->
init_num
=
0
;
break
;
#endif
case
SSL3_ST_SW_CHANGE_A
:
case
SSL3_ST_SW_CHANGE_B
:
...
...
@@ -762,14 +778,14 @@ int ssl3_get_client_hello(SSL *s)
* might be written that become totally unsecure when compiled with
* an earlier library version)
*/
if
(
j
==
0
||
(
s
->
new_session
&&
(
s
->
options
&
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
)))
if
((
s
->
new_session
&&
(
s
->
options
&
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
)))
{
if
(
!
ssl_get_new_session
(
s
,
1
))
goto
err
;
}
else
{
i
=
ssl_get_prev_session
(
s
,
p
,
j
);
i
=
ssl_get_prev_session
(
s
,
p
,
j
,
d
+
n
);
if
(
i
==
1
)
{
/* previous session */
s
->
hit
=
1
;
...
...
@@ -2714,3 +2730,90 @@ int ssl3_send_server_certificate(SSL *s)
/* SSL3_ST_SW_CERT_B */
return
(
ssl3_do_write
(
s
,
SSL3_RT_HANDSHAKE
));
}
#ifndef OPENSSLP_NO_TLSEXT
int
ssl3_send_newsession_ticket
(
SSL
*
s
)
{
if
(
s
->
state
==
SSL3_ST_SW_SESSION_TICKET_A
)
{
unsigned
char
*
p
,
*
senc
,
*
macstart
;
int
len
,
slen
;
unsigned
int
hlen
;
EVP_CIPHER_CTX
ctx
;
HMAC_CTX
hctx
;
/* get session encoding length */
slen
=
i2d_SSL_SESSION
(
s
->
session
,
NULL
);
/* Some length values are 16 bits, so forget it if session is
* too long
*/
if
(
slen
>
0xFF00
)
return
-
1
;
/* Grow buffer if need be: the length calculation is as
* follows 1 (size of message name) + 3 (message length
* bytes) + 4 (ticket lifetime hint) + 2 (ticket length) +
* 16 (key name) + max_iv_len (iv length) +
* session_length + max_enc_block_size (max encrypted session
* length) + max_md_size (HMAC).
*/
if
(
!
BUF_MEM_grow
(
s
->
init_buf
,
26
+
EVP_MAX_IV_LENGTH
+
EVP_MAX_BLOCK_LENGTH
+
EVP_MAX_MD_SIZE
+
slen
))
return
-
1
;
senc
=
OPENSSL_malloc
(
slen
);
if
(
!
senc
)
return
-
1
;
p
=
senc
;
i2d_SSL_SESSION
(
s
->
session
,
&
p
);
p
=
(
unsigned
char
*
)
s
->
init_buf
->
data
;
/* do the header */
*
(
p
++
)
=
SSL3_MT_NEWSESSION_TICKET
;
/* Skip message length for now */
p
+=
3
;
l2n
(
s
->
session
->
tlsext_tick_lifetime_hint
,
p
);
/* Skip ticket length for now */
p
+=
2
;
/* Output key name */
macstart
=
p
;
memcpy
(
p
,
s
->
ctx
->
tlsext_tick_key_name
,
16
);
p
+=
16
;
/* Generate and output IV */
RAND_pseudo_bytes
(
p
,
16
);
EVP_CIPHER_CTX_init
(
&
ctx
);
/* Encrypt session data */
EVP_EncryptInit_ex
(
&
ctx
,
EVP_aes_128_cbc
(),
NULL
,
s
->
ctx
->
tlsext_tick_aes_key
,
p
);
p
+=
16
;
EVP_EncryptUpdate
(
&
ctx
,
p
,
&
len
,
senc
,
slen
);
p
+=
len
;
EVP_EncryptFinal
(
&
ctx
,
p
,
&
len
);
p
+=
len
;
EVP_CIPHER_CTX_cleanup
(
&
ctx
);
HMAC_CTX_init
(
&
hctx
);
HMAC_Init_ex
(
&
hctx
,
s
->
ctx
->
tlsext_tick_hmac_key
,
16
,
EVP_sha1
(),
NULL
);
HMAC_Update
(
&
hctx
,
macstart
,
p
-
macstart
);
HMAC_Final
(
&
hctx
,
p
,
&
hlen
);
HMAC_CTX_cleanup
(
&
hctx
);
p
+=
hlen
;
/* Now write out lengths: p points to end of data written */
/* Total length */
len
=
p
-
(
unsigned
char
*
)
s
->
init_buf
->
data
;
p
=
(
unsigned
char
*
)
s
->
init_buf
->
data
+
1
;
l2n3
(
len
-
4
,
p
);
/* Message length */
p
+=
4
;
s2n
(
len
-
10
,
p
);
/* Ticket length */
/* number of bytes to write */
s
->
init_num
=
len
;
s
->
state
=
SSL3_ST_SW_SESSION_TICKET_B
;
s
->
init_off
=
0
;
OPENSSL_free
(
senc
);
}
/* SSL3_ST_SW_SESSION_TICKET_B */
return
(
ssl3_do_write
(
s
,
SSL3_RT_HANDSHAKE
));
}
#endif
ssl/ssl.h
浏览文件 @
6434abbf
...
...
@@ -500,6 +500,10 @@ typedef struct ssl_session_st
size_t
tlsext_ellipticcurvelist_length
;
unsigned
char
*
tlsext_ellipticcurvelist
;
/* peer's list */
#endif
/* OPENSSL_NO_EC */
/* RFC4507 info */
unsigned
char
*
tlsext_tick
;
/* Session ticket */
size_t
tlsext_ticklen
;
/* Session ticket length */
long
tlsext_tick_lifetime_hint
;
/* Session lifetime hint in seconds */
#endif
}
SSL_SESSION
;
...
...
@@ -529,6 +533,8 @@ typedef struct ssl_session_st
#define SSL_OP_NO_QUERY_MTU 0x00001000L
/* Turn on Cookie Exchange (on relevant for servers) */
#define SSL_OP_COOKIE_EXCHANGE 0x00002000L
/* Don't use RFC4507 ticket extension */
#define SSL_OP_NO_TICKET 0x00004000L
/* As server, disallow session resumption on renegotiation */
#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000L
...
...
@@ -789,6 +795,10 @@ struct ssl_ctx_st
/* TLS extensions servername callback */
int
(
*
tlsext_servername_callback
)(
SSL
*
,
int
*
,
void
*
);
void
*
tlsext_servername_arg
;
/* RFC 4507 session ticket keys */
unsigned
char
tlsext_tick_key_name
[
16
];
unsigned
char
tlsext_tick_hmac_key
[
16
];
unsigned
char
tlsext_tick_aes_key
[
16
];
#endif
#ifndef OPENSSL_NO_PSK
char
*
psk_identity_hint
;
...
...
@@ -1057,12 +1067,19 @@ struct ssl_st
* SSLv3/TLS rollback check */
unsigned
int
max_send_fragment
;
#ifndef OPENSSL_NO_TLSEXT
/* TLS extension debug callback */
void
(
*
tlsext_debug_cb
)(
SSL
*
s
,
int
client_server
,
int
type
,
unsigned
char
*
data
,
int
len
,
void
*
arg
);
void
*
tlsext_debug_arg
;
char
*
tlsext_hostname
;
int
servername_done
;
/* no further mod of servername
0 : call the servername extension callback.
1 : prepare 2, allow last ack just after in server callback.
2 : don't call servername callback, no ack in server hello
*/
/* RFC4507 session ticket expected to be received or sent */
int
tlsext_ticket_expected
;
#ifndef OPENSSL_NO_EC
size_t
tlsext_ecpointformatlist_length
;
unsigned
char
*
tlsext_ecpointformatlist
;
/* our list */
...
...
@@ -1283,6 +1300,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 53
#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG 54
#define SSL_CTRL_SET_TLSEXT_HOSTNAME 55
#define SSL_CTRL_SET_TLSEXT_DEBUG_CB 56
#define SSL_CTRL_SET_TLSEXT_DEBUG_ARG 57
#endif
#define SSL_session_reused(ssl) \
...
...
@@ -1739,10 +1758,12 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL3_GET_FINISHED 140
#define SSL_F_SSL3_GET_KEY_EXCHANGE 141
#define SSL_F_SSL3_GET_MESSAGE 142
#define SSL_F_SSL3_GET_NEW_SESSION_TICKET 283
#define SSL_F_SSL3_GET_RECORD 143
#define SSL_F_SSL3_GET_SERVER_CERTIFICATE 144
#define SSL_F_SSL3_GET_SERVER_DONE 145
#define SSL_F_SSL3_GET_SERVER_HELLO 146
#define SSL_F_SSL3_NEW_SESSION_TICKET 284
#define SSL_F_SSL3_OUTPUT_CERT_CHAIN 147
#define SSL_F_SSL3_PEEK 235
#define SSL_F_SSL3_READ_BYTES 148
...
...
ssl/ssl3.h
浏览文件 @
6434abbf
...
...
@@ -533,6 +533,8 @@ typedef struct ssl3_state_st
#define SSL3_ST_CR_CHANGE_B (0x1C1|SSL_ST_CONNECT)
#define SSL3_ST_CR_FINISHED_A (0x1D0|SSL_ST_CONNECT)
#define SSL3_ST_CR_FINISHED_B (0x1D1|SSL_ST_CONNECT)
#define SSL3_ST_CR_SESSION_TICKET_A (0x1E0|SSL_ST_CONNECT)
#define SSL3_ST_CR_SESSION_TICKET_B (0x1E1|SSL_ST_CONNECT)
/* server */
/* extra state */
...
...
@@ -574,10 +576,13 @@ typedef struct ssl3_state_st
#define SSL3_ST_SW_CHANGE_B (0x1D1|SSL_ST_ACCEPT)
#define SSL3_ST_SW_FINISHED_A (0x1E0|SSL_ST_ACCEPT)
#define SSL3_ST_SW_FINISHED_B (0x1E1|SSL_ST_ACCEPT)
#define SSL3_ST_SW_SESSION_TICKET_A (0x1F0|SSL_ST_CONNECT)
#define SSL3_ST_SW_SESSION_TICKET_B (0x1F1|SSL_ST_CONNECT)
#define SSL3_MT_HELLO_REQUEST 0
#define SSL3_MT_CLIENT_HELLO 1
#define SSL3_MT_SERVER_HELLO 2
#define SSL3_MT_NEWSESSION_TICKET 4
#define SSL3_MT_CERTIFICATE 11
#define SSL3_MT_SERVER_KEY_EXCHANGE 12
#define SSL3_MT_CERTIFICATE_REQUEST 13
...
...
ssl/ssl_asn1.c
浏览文件 @
6434abbf
...
...
@@ -106,6 +106,8 @@ typedef struct ssl_session_asn1_st
ASN1_INTEGER
verify_result
;
#ifndef OPENSSL_NO_TLSEXT
ASN1_OCTET_STRING
tlsext_hostname
;
ASN1_INTEGER
tlsext_tick_lifetime
;
ASN1_OCTET_STRING
tlsext_tick
;
#endif
/* OPENSSL_NO_TLSEXT */
#ifndef OPENSSL_NO_PSK
ASN1_OCTET_STRING
psk_identity_hint
;
...
...
@@ -116,9 +118,10 @@ typedef struct ssl_session_asn1_st
int
i2d_SSL_SESSION
(
SSL_SESSION
*
in
,
unsigned
char
**
pp
)
{
#define LSIZE2 (sizeof(long)*2)
int
v1
=
0
,
v2
=
0
,
v3
=
0
,
v4
=
0
,
v5
=
0
,
v6
=
0
,
v7
=
0
,
v8
=
0
;
int
v1
=
0
,
v2
=
0
,
v3
=
0
,
v4
=
0
,
v5
=
0
,
v6
=
0
,
v7
=
0
,
v8
=
0
,
v9
=
0
,
v10
=
0
;
unsigned
char
buf
[
4
],
ibuf1
[
LSIZE2
],
ibuf2
[
LSIZE2
];
unsigned
char
ibuf3
[
LSIZE2
],
ibuf4
[
LSIZE2
],
ibuf5
[
LSIZE2
];
unsigned
char
ibuf6
[
LSIZE2
];
long
l
;
SSL_SESSION_ASN1
a
;
M_ASN1_I2D_vars
(
in
);
...
...
@@ -217,7 +220,25 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
a
.
tlsext_hostname
.
length
=
strlen
(
in
->
tlsext_hostname
);
a
.
tlsext_hostname
.
type
=
V_ASN1_OCTET_STRING
;
a
.
tlsext_hostname
.
data
=
(
unsigned
char
*
)
in
->
tlsext_hostname
;
}
}
if
(
in
->
tlsext_tick
)
{
a
.
tlsext_tick
.
length
=
in
->
tlsext_ticklen
;
a
.
tlsext_tick
.
type
=
V_ASN1_OCTET_STRING
;
a
.
tlsext_tick
.
data
=
(
unsigned
char
*
)
in
->
tlsext_tick
;
/* If we have a ticket set session ID to empty because
* it will be bogus.
*/
if
(
in
->
tlsext_ticklen
)
a
.
session_id
.
length
=
0
;
}
if
(
in
->
tlsext_tick_lifetime_hint
!=
0
)
{
a
.
tlsext_tick_lifetime
.
length
=
LSIZE2
;
a
.
tlsext_tick_lifetime
.
type
=
V_ASN1_INTEGER
;
a
.
tlsext_tick_lifetime
.
data
=
ibuf6
;
ASN1_INTEGER_set
(
&
a
.
tlsext_tick_lifetime
,
in
->
tlsext_tick_lifetime_hint
);
}
#endif
/* OPENSSL_NO_TLSEXT */
#ifndef OPENSSL_NO_PSK
if
(
in
->
psk_identity_hint
)
...
...
@@ -256,6 +277,10 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
M_ASN1_I2D_len_EXP_opt
(
&
(
a
.
verify_result
),
i2d_ASN1_INTEGER
,
5
,
v5
);
#ifndef OPENSSL_NO_TLSEXT
if
(
in
->
tlsext_tick_lifetime_hint
)
M_ASN1_I2D_len_EXP_opt
(
&
a
.
tlsext_tick_lifetime
,
i2d_ASN1_INTEGER
,
9
,
v9
);
if
(
in
->
tlsext_tick
)
M_ASN1_I2D_len_EXP_opt
(
&
(
a
.
tlsext_tick
),
i2d_ASN1_OCTET_STRING
,
10
,
v10
);
if
(
in
->
tlsext_hostname
)
M_ASN1_I2D_len_EXP_opt
(
&
(
a
.
tlsext_hostname
),
i2d_ASN1_OCTET_STRING
,
6
,
v6
);
#endif
/* OPENSSL_NO_TLSEXT */
...
...
@@ -299,6 +324,12 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
if
(
in
->
psk_identity
)
M_ASN1_I2D_put_EXP_opt
(
&
(
a
.
psk_identity
),
i2d_ASN1_OCTET_STRING
,
8
,
v8
);
#endif
/* OPENSSL_NO_PSK */
#ifndef OPENSSL_NO_TLSEXT
if
(
in
->
tlsext_tick_lifetime_hint
)
M_ASN1_I2D_put_EXP_opt
(
&
a
.
tlsext_tick_lifetime
,
i2d_ASN1_INTEGER
,
9
,
v9
);
if
(
in
->
tlsext_tick
)
M_ASN1_I2D_put_EXP_opt
(
&
(
a
.
tlsext_tick
),
i2d_ASN1_OCTET_STRING
,
10
,
v10
);
#endif
/* OPENSSL_NO_TLSEXT */
M_ASN1_I2D_finish
();
}
...
...
@@ -488,7 +519,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
#ifndef OPENSSL_NO_PSK
os
.
length
=
0
;
os
.
data
=
NULL
;
M_ASN1_D2I_get_EXP_opt
(
osp
,
d2i_ASN1_OCTET_STRING
,
9
);
M_ASN1_D2I_get_EXP_opt
(
osp
,
d2i_ASN1_OCTET_STRING
,
7
);
if
(
os
.
data
)
{
ret
->
psk_identity_hint
=
BUF_strndup
((
char
*
)
os
.
data
,
os
.
length
);
...
...
@@ -498,20 +529,44 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
}
else
ret
->
psk_identity_hint
=
NULL
;
#endif
/* OPENSSL_NO_PSK */
#ifndef OPENSSL_NO_TLSEXT
ai
.
length
=
0
;
M_ASN1_D2I_get_EXP_opt
(
aip
,
d2i_ASN1_INTEGER
,
9
);
if
(
ai
.
data
!=
NULL
)
{
ret
->
tlsext_tick_lifetime_hint
=
ASN1_INTEGER_get
(
aip
);
OPENSSL_free
(
ai
.
data
);
ai
.
data
=
NULL
;
ai
.
length
=
0
;
}
else
ret
->
tlsext_tick_lifetime_hint
=
0
;
os
.
length
=
0
;
os
.
data
=
NULL
;
M_ASN1_D2I_get_EXP_opt
(
osp
,
d2i_ASN1_OCTET_STRING
,
10
);
if
(
os
.
data
)
{
ret
->
psk_identity
=
BUF_strndup
((
char
*
)
os
.
data
,
os
.
length
)
;
OPENSSL_free
(
os
.
data
)
;
ret
->
tlsext_tick
=
os
.
data
;
ret
->
tlsext_ticklen
=
os
.
length
;
os
.
data
=
NULL
;
os
.
length
=
0
;
#if 0
/* There are two ways to detect a resumed ticket sesion.
* One is to set a random session ID and then the server
* must return a match in ServerHello. This allows the normal
* client session ID matching to work.
*/
if (ret->session_id_length == 0)
{
ret->session_id_length=SSL3_MAX_SSL_SESSION_ID_LENGTH;
RAND_pseudo_bytes(ret->session_id,
ret->session_id_length);
}
#endif
}
else
ret
->
psk_identity
=
NULL
;
#endif
/* OPENSSL_NO_
KRB5
*/
ret
->
tlsext_tick
=
NULL
;
#endif
/* OPENSSL_NO_
TLSEXT
*/
M_ASN1_D2I_Finish
(
a
,
SSL_SESSION_free
,
SSL_F_D2I_SSL_SESSION
);
}
ssl/ssl_err.c
浏览文件 @
6434abbf
...
...
@@ -147,10 +147,12 @@ static ERR_STRING_DATA SSL_str_functs[]=
{
ERR_FUNC
(
SSL_F_SSL3_GET_FINISHED
),
"SSL3_GET_FINISHED"
},
{
ERR_FUNC
(
SSL_F_SSL3_GET_KEY_EXCHANGE
),
"SSL3_GET_KEY_EXCHANGE"
},
{
ERR_FUNC
(
SSL_F_SSL3_GET_MESSAGE
),
"SSL3_GET_MESSAGE"
},
{
ERR_FUNC
(
SSL_F_SSL3_GET_NEW_SESSION_TICKET
),
"SSL3_GET_NEW_SESSION_TICKET"
},
{
ERR_FUNC
(
SSL_F_SSL3_GET_RECORD
),
"SSL3_GET_RECORD"
},
{
ERR_FUNC
(
SSL_F_SSL3_GET_SERVER_CERTIFICATE
),
"SSL3_GET_SERVER_CERTIFICATE"
},
{
ERR_FUNC
(
SSL_F_SSL3_GET_SERVER_DONE
),
"SSL3_GET_SERVER_DONE"
},
{
ERR_FUNC
(
SSL_F_SSL3_GET_SERVER_HELLO
),
"SSL3_GET_SERVER_HELLO"
},
{
ERR_FUNC
(
SSL_F_SSL3_NEW_SESSION_TICKET
),
"SSL3_NEW_SESSION_TICKET"
},
{
ERR_FUNC
(
SSL_F_SSL3_OUTPUT_CERT_CHAIN
),
"SSL3_OUTPUT_CERT_CHAIN"
},
{
ERR_FUNC
(
SSL_F_SSL3_PEEK
),
"SSL3_PEEK"
},
{
ERR_FUNC
(
SSL_F_SSL3_READ_BYTES
),
"SSL3_READ_BYTES"
},
...
...
ssl/ssl_lib.c
浏览文件 @
6434abbf
...
...
@@ -151,6 +151,7 @@
#include <openssl/objects.h>
#include <openssl/lhash.h>
#include <openssl/x509v3.h>
#include <openssl/rand.h>
#ifndef OPENSSL_NO_DH
#include <openssl/dh.h>
#endif
...
...
@@ -336,6 +337,9 @@ SSL *SSL_new(SSL_CTX *ctx)
CRYPTO_add
(
&
ctx
->
references
,
1
,
CRYPTO_LOCK_SSL_CTX
);
s
->
ctx
=
ctx
;
#ifndef OPENSSL_NO_TLSEXT
s
->
tlsext_debug_cb
=
0
;
s
->
tlsext_debug_arg
=
NULL
;
s
->
tlsext_ticket_expected
=
0
;
CRYPTO_add
(
&
ctx
->
references
,
1
,
CRYPTO_LOCK_SSL_CTX
);
s
->
initial_ctx
=
ctx
;
#endif
...
...
@@ -1545,6 +1549,12 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
#ifndef OPENSSL_NO_TLSEXT
ret
->
tlsext_servername_callback
=
0
;
ret
->
tlsext_servername_arg
=
NULL
;
/* Setup RFC4507 ticket keys */
if
((
RAND_pseudo_bytes
(
ret
->
tlsext_tick_key_name
,
16
)
<=
0
)
||
(
RAND_bytes
(
ret
->
tlsext_tick_hmac_key
,
16
)
<=
0
)
||
(
RAND_bytes
(
ret
->
tlsext_tick_aes_key
,
16
)
<=
0
))
ret
->
options
|=
SSL_OP_NO_TICKET
;
#endif
#ifndef OPENSSL_NO_PSK
ret
->
psk_identity_hint
=
NULL
;
...
...
ssl/ssl_locl.h
浏览文件 @
6434abbf
...
...
@@ -740,7 +740,7 @@ SESS_CERT *ssl_sess_cert_new(void);
void
ssl_sess_cert_free
(
SESS_CERT
*
sc
);
int
ssl_set_peer_cert_type
(
SESS_CERT
*
c
,
int
type
);
int
ssl_get_new_session
(
SSL
*
s
,
int
session
);
int
ssl_get_prev_session
(
SSL
*
s
,
unsigned
char
*
session
,
int
len
);
int
ssl_get_prev_session
(
SSL
*
s
,
unsigned
char
*
session
,
int
len
,
const
unsigned
char
*
limit
);
int
ssl_cipher_id_cmp
(
const
SSL_CIPHER
*
a
,
const
SSL_CIPHER
*
b
);
int
ssl_cipher_ptr_id_cmp
(
const
SSL_CIPHER
*
const
*
ap
,
const
SSL_CIPHER
*
const
*
bp
);
...
...
@@ -800,6 +800,7 @@ SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p);
int
ssl3_put_cipher_by_char
(
const
SSL_CIPHER
*
c
,
unsigned
char
*
p
);
void
ssl3_init_finished_mac
(
SSL
*
s
);
int
ssl3_send_server_certificate
(
SSL
*
s
);
int
ssl3_send_newsession_ticket
(
SSL
*
s
);
int
ssl3_get_finished
(
SSL
*
s
,
int
state_a
,
int
state_b
);
int
ssl3_setup_key_block
(
SSL
*
s
);
int
ssl3_send_change_cipher_spec
(
SSL
*
s
,
int
state_a
,
int
state_b
);
...
...
@@ -890,6 +891,7 @@ long dtls1_default_timeout(void);
int
ssl3_client_hello
(
SSL
*
s
);
int
ssl3_get_server_hello
(
SSL
*
s
);
int
ssl3_get_certificate_request
(
SSL
*
s
);
int
ssl3_get_new_session_ticket
(
SSL
*
s
);
int
ssl3_get_server_done
(
SSL
*
s
);
int
ssl3_send_client_verify
(
SSL
*
s
);
int
ssl3_send_client_certificate
(
SSL
*
s
);
...
...
@@ -985,6 +987,8 @@ int ssl_prepare_clienthello_tlsext(SSL *s);
int
ssl_prepare_serverhello_tlsext
(
SSL
*
s
);
int
ssl_check_clienthello_tlsext
(
SSL
*
s
);
int
ssl_check_serverhello_tlsext
(
SSL
*
s
);
int
tls1_process_ticket
(
SSL
*
s
,
unsigned
char
*
session_id
,
int
len
,
const
unsigned
char
*
limit
,
SSL_SESSION
**
ret
);
EVP_MD_CTX
*
ssl_replace_hash
(
EVP_MD_CTX
**
hash
,
const
EVP_MD
*
md
)
;
void
ssl_clear_hash_ctx
(
EVP_MD_CTX
**
hash
);
#endif
...
...
ssl/ssl_sess.c
浏览文件 @
6434abbf
...
...
@@ -308,6 +308,14 @@ int ssl_get_new_session(SSL *s, int session)
SSL_SESSION_free
(
ss
);
return
(
0
);
}
#ifndef OPENSSL_NO_TLSEXT
/* If RFC4507 ticket use empty session ID */
if
(
s
->
tlsext_ticket_expected
)
{
ss
->
session_id_length
=
0
;
goto
sess_id_done
;
}
#endif
/* Choose which callback will set the session ID */
CRYPTO_r_lock
(
CRYPTO_LOCK_SSL_CTX
);
if
(
s
->
generate_session_id
)
...
...
@@ -350,6 +358,7 @@ int ssl_get_new_session(SSL *s, int session)
return
(
0
);
}
#ifndef OPENSSL_NO_TLSEXT
sess_id_done:
if
(
s
->
tlsext_hostname
)
{
ss
->
tlsext_hostname
=
BUF_strdup
(
s
->
tlsext_hostname
);
if
(
ss
->
tlsext_hostname
==
NULL
)
{
...
...
@@ -406,21 +415,39 @@ int ssl_get_new_session(SSL *s, int session)
return
(
1
);
}
int
ssl_get_prev_session
(
SSL
*
s
,
unsigned
char
*
session_id
,
int
len
)
int
ssl_get_prev_session
(
SSL
*
s
,
unsigned
char
*
session_id
,
int
len
,
const
unsigned
char
*
limit
)
{
/* This is used only by servers. */
SSL_SESSION
*
ret
=
NULL
,
data
;
SSL_SESSION
*
ret
=
NULL
;
int
fatal
=
0
;
#ifndef OPENSSL_NO_TLSEXT
int
r
;
#endif
data
.
ssl_version
=
s
->
version
;
data
.
session_id_length
=
len
;
if
(
len
>
SSL_MAX_SSL_SESSION_ID_LENGTH
)
goto
err
;
memcpy
(
data
.
session_id
,
session_id
,
len
);
#ifndef OPENSSL_NO_TLSEXT
r
=
tls1_process_ticket
(
s
,
session_id
,
len
,
limit
,
&
ret
);
if
(
r
==
-
1
)
{
fatal
=
1
;
goto
err
;
}
else
if
(
r
==
0
)
goto
err
;
else
if
(
!
ret
&&
!
(
s
->
session_ctx
->
session_cache_mode
&
SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
))
#else
if
(
!
(
s
->
session_ctx
->
session_cache_mode
&
SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
))
#endif
{
SSL_SESSION
data
;
data
.
ssl_version
=
s
->
version
;
data
.
session_id_length
=
len
;
if
(
len
==
0
)
return
0
;
memcpy
(
data
.
session_id
,
session_id
,
len
);
CRYPTO_r_lock
(
CRYPTO_LOCK_SSL_CTX
);
ret
=
(
SSL_SESSION
*
)
lh_retrieve
(
s
->
session_ctx
->
sessions
,
&
data
);
if
(
ret
!=
NULL
)
...
...
@@ -678,6 +705,7 @@ void SSL_SESSION_free(SSL_SESSION *ss)
if
(
ss
->
ciphers
!=
NULL
)
sk_SSL_CIPHER_free
(
ss
->
ciphers
);
#ifndef OPENSSL_NO_TLSEXT
if
(
ss
->
tlsext_hostname
!=
NULL
)
OPENSSL_free
(
ss
->
tlsext_hostname
);
if
(
ss
->
tlsext_tick
!=
NULL
)
OPENSSL_free
(
ss
->
tlsext_tick
);
#ifndef OPENSSL_NO_EC
ss
->
tlsext_ecpointformatlist_length
=
0
;
if
(
ss
->
tlsext_ecpointformatlist
!=
NULL
)
OPENSSL_free
(
ss
->
tlsext_ecpointformatlist
);
...
...
ssl/ssl_txt.c
浏览文件 @
6434abbf
...
...
@@ -183,6 +183,22 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
if
(
BIO_puts
(
bp
,
"
\n
PSK identity hint: "
)
<=
0
)
goto
err
;
if
(
BIO_printf
(
bp
,
"%s"
,
x
->
psk_identity_hint
?
x
->
psk_identity_hint
:
"None"
)
<=
0
)
goto
err
;
#endif
#ifndef OPENSSL_NO_TLSEXT
if
(
x
->
tlsext_tick_lifetime_hint
)
{
if
(
BIO_printf
(
bp
,
"
\n
TLS session ticket lifetime hint: %ld (seconds)"
,
x
->
tlsext_tick_lifetime_hint
)
<=
0
)
goto
err
;
}
if
(
x
->
tlsext_tick
)
{
if
(
BIO_puts
(
bp
,
"
\n
TLS session ticket:
\n
"
)
<=
0
)
goto
err
;
if
(
BIO_dump_indent
(
bp
,
(
char
*
)
x
->
tlsext_tick
,
x
->
tlsext_ticklen
,
4
)
<=
0
)
goto
err
;
}
#endif
#ifndef OPENSSL_NO_COMP
if
(
x
->
compress_meth
!=
0
)
{
...
...
ssl/t1_lib.c
浏览文件 @
6434abbf
...
...
@@ -111,10 +111,16 @@
#include <stdio.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include "ssl_locl.h"
const
char
tls1_version_str
[]
=
"TLSv1"
OPENSSL_VERSION_PTEXT
;
static
int
tls_decrypt_ticket
(
SSL
*
s
,
const
unsigned
char
*
tick
,
int
ticklen
,
const
unsigned
char
*
sess_id
,
int
sesslen
,
SSL_SESSION
**
psess
);
SSL3_ENC_METHOD
TLSv1_enc_data
=
{
tls1_enc
,
tls1_mac
,
...
...
@@ -164,6 +170,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
ret
+=
2
;
if
(
ret
>=
limit
)
return
NULL
;
/* this really never occurs, but ... */
if
(
s
->
tlsext_hostname
!=
NULL
)
{
/* Add TLS extension servername to the Client Hello message */
...
...
@@ -243,6 +250,27 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
}
#endif
/* OPENSSL_NO_EC */
if
(
!
(
SSL_get_options
(
s
)
&
SSL_OP_NO_TICKET
))
{
int
ticklen
;
if
(
s
->
session
&&
s
->
session
->
tlsext_tick
)
ticklen
=
s
->
session
->
tlsext_ticklen
;
else
ticklen
=
0
;
/* Check for enough room 2 for extension type, 2 for len
* rest for ticket
*/
if
(
limit
-
p
-
4
-
ticklen
<
0
)
return
NULL
;
s2n
(
TLSEXT_TYPE_session_ticket
,
ret
);
s2n
(
ticklen
,
ret
);
if
(
ticklen
)
{
memcpy
(
ret
,
s
->
session
->
tlsext_tick
,
ticklen
);
ret
+=
ticklen
;
}
}
if
((
extdatalen
=
ret
-
p
-
2
)
==
0
)
return
p
;
...
...
@@ -289,6 +317,14 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
/* Currently the server should not respond with a SupportedCurves extension */
#endif
/* OPENSSL_NO_EC */
if
(
s
->
tlsext_ticket_expected
&&
!
(
SSL_get_options
(
s
)
&
SSL_OP_NO_TICKET
))
{
if
(
limit
-
p
-
4
<
0
)
return
NULL
;
s2n
(
TLSEXT_TYPE_session_ticket
,
ret
);
s2n
(
0
,
ret
);
}
if
((
extdatalen
=
ret
-
p
-
2
)
==
0
)
return
p
;
...
...
@@ -318,7 +354,10 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
if
(
data
+
size
>
(
d
+
n
))
return
1
;
if
(
s
->
tlsext_debug_cb
)
s
->
tlsext_debug_cb
(
s
,
0
,
type
,
data
,
size
,
s
->
tlsext_debug_arg
);
/* The servername extension is treated as follows:
- Only the hostname type is supported with a maximum length of 255.
...
...
@@ -472,9 +511,10 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
#endif
}
#endif
/* OPENSSL_NO_EC */
data
+=
size
;
/* session ticket processed earlier */
data
+=
size
;
}
*
p
=
data
;
return
1
;
}
...
...
@@ -501,6 +541,10 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
if
(
data
+
size
>
(
d
+
n
))
return
1
;
if
(
s
->
tlsext_debug_cb
)
s
->
tlsext_debug_cb
(
s
,
1
,
type
,
data
,
size
,
s
->
tlsext_debug_arg
);
if
(
type
==
TLSEXT_TYPE_server_name
)
{
if
(
s
->
tlsext_hostname
==
NULL
||
size
>
0
)
...
...
@@ -540,6 +584,17 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
#endif
}
#endif
/* OPENSSL_NO_EC */
else
if
(
type
==
TLSEXT_TYPE_session_ticket
)
{
if
((
SSL_get_options
(
s
)
&
SSL_OP_NO_TICKET
)
||
(
size
>
0
))
{
*
al
=
TLS1_AD_UNSUPPORTED_EXTENSION
;
return
0
;
}
s
->
tlsext_ticket_expected
=
1
;
}
data
+=
size
;
}
...
...
@@ -854,5 +909,144 @@ int ssl_check_serverhello_tlsext(SSL *s)
return
1
;
}
}
#endif
/* Since the server cache lookup is done early on in the processing of client
* hello and other operations depend on the result we need to handle any TLS
* session ticket extension at the same time.
*/
int
tls1_process_ticket
(
SSL
*
s
,
unsigned
char
*
session_id
,
int
len
,
const
unsigned
char
*
limit
,
SSL_SESSION
**
ret
)
{
/* Point after session ID in client hello */
const
unsigned
char
*
p
=
session_id
+
len
;
unsigned
short
i
;
if
((
s
->
version
<=
SSL3_VERSION
)
||
!
limit
)
return
1
;
if
(
p
>=
limit
)
return
-
1
;
/* Skip past cipher list */
n2s
(
p
,
i
);
p
+=
i
;
if
(
p
>=
limit
)
return
-
1
;
/* Skip past compression algorithm list */
i
=
*
(
p
++
);
p
+=
i
;
if
(
p
>
limit
)
return
-
1
;
/* Now at start of extensions */
if
((
p
+
2
)
>=
limit
)
return
1
;
n2s
(
p
,
i
);
while
((
p
+
4
)
<=
limit
)
{
unsigned
short
type
,
size
;
n2s
(
p
,
type
);
n2s
(
p
,
size
);
if
(
p
+
size
>
limit
)
return
1
;
if
(
type
==
TLSEXT_TYPE_session_ticket
)
{
/* If tickets disabled indicate cache miss which will
* trigger a full handshake
*/
if
(
SSL_get_options
(
s
)
&
SSL_OP_NO_TICKET
)
return
0
;
/* If zero length not client will accept a ticket
* and indicate cache miss to trigger full handshake
*/
if
(
size
==
0
)
{
s
->
tlsext_ticket_expected
=
1
;
return
0
;
/* Cache miss */
}
return
tls_decrypt_ticket
(
s
,
p
,
size
,
session_id
,
len
,
ret
);
}
p
+=
size
;
}
return
1
;
}
static
int
tls_decrypt_ticket
(
SSL
*
s
,
const
unsigned
char
*
etick
,
int
eticklen
,
const
unsigned
char
*
sess_id
,
int
sesslen
,
SSL_SESSION
**
psess
)
{
SSL_SESSION
*
sess
;
unsigned
char
*
sdec
;
const
unsigned
char
*
p
;
int
slen
,
mlen
;
unsigned
char
tick_hmac
[
EVP_MAX_MD_SIZE
];
HMAC_CTX
hctx
;
EVP_CIPHER_CTX
ctx
;
/* Attempt to process session ticket, first conduct sanity and
* integrity checks on ticket.
*/
mlen
=
EVP_MD_size
(
EVP_sha1
());
eticklen
-=
mlen
;
/* Need at least keyname + iv + some encrypted data */
if
(
eticklen
<
48
)
goto
tickerr
;
/* Check key name matches */
if
(
memcmp
(
etick
,
s
->
ctx
->
tlsext_tick_key_name
,
16
))
goto
tickerr
;
fprintf
(
stderr
,
"Ticket match OK
\n
"
);
/* Check HMAC of encrypted ticket */
HMAC_CTX_init
(
&
hctx
);
HMAC_Init_ex
(
&
hctx
,
s
->
ctx
->
tlsext_tick_hmac_key
,
16
,
EVP_sha1
(),
NULL
);
HMAC_Update
(
&
hctx
,
etick
,
eticklen
);
HMAC_Final
(
&
hctx
,
tick_hmac
,
NULL
);
HMAC_CTX_cleanup
(
&
hctx
);
if
(
memcmp
(
tick_hmac
,
etick
+
eticklen
,
mlen
))
goto
tickerr
;
fprintf
(
stderr
,
"HMAC match OK
\n
"
);
/* Set p to start of IV */
p
=
etick
+
16
;
EVP_CIPHER_CTX_init
(
&
ctx
);
/* Attempt to decrypt session data */
EVP_DecryptInit_ex
(
&
ctx
,
EVP_aes_128_cbc
(),
NULL
,
s
->
ctx
->
tlsext_tick_aes_key
,
p
);
/* Move p after IV to start of encrypted ticket, update length */
p
+=
16
;
eticklen
-=
32
;
sdec
=
OPENSSL_malloc
(
eticklen
);
if
(
!
sdec
)
{
EVP_CIPHER_CTX_cleanup
(
&
ctx
);
return
-
1
;
}
EVP_DecryptUpdate
(
&
ctx
,
sdec
,
&
slen
,
p
,
eticklen
);
if
(
EVP_DecryptFinal
(
&
ctx
,
sdec
+
slen
,
&
mlen
)
<=
0
)
goto
tickerr
;
fprintf
(
stderr
,
"Decrypt OK
\n
"
);
slen
+=
mlen
;
EVP_CIPHER_CTX_cleanup
(
&
ctx
);
p
=
sdec
;
sess
=
d2i_SSL_SESSION
(
NULL
,
&
p
,
slen
);
OPENSSL_free
(
sdec
);
if
(
sess
)
{
/* The session ID if non-empty is used by some clients to
* detect that the ticket has been accepted. So we copy it to
* the session structure. If it is empty set length to zero
* as required by standard.
*/
if
(
sesslen
)
memcpy
(
sess
->
session_id
,
sess_id
,
sesslen
);
sess
->
session_id_length
=
sesslen
;
*
psess
=
sess
;
return
1
;
}
/* If session decrypt failure indicate a cache miss and set state to
* send a new ticket
*/
tickerr:
s
->
tlsext_ticket_expected
=
1
;
return
0
;
}
#endif
ssl/tls1.h
浏览文件 @
6434abbf
...
...
@@ -192,6 +192,7 @@ extern "C" {
#define TLSEXT_TYPE_status_request 5
#define TLSEXT_TYPE_elliptic_curves 10
#define TLSEXT_TYPE_ec_point_formats 11
#define TLSEXT_TYPE_session_ticket 35
/* NameType value from RFC 3546 */
#define TLSEXT_NAMETYPE_host_name 0
...
...
@@ -213,6 +214,12 @@ int SSL_get_servername_type(const SSL *s) ;
#define SSL_set_tlsext_host_name(s,name) \
SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name)
#define SSL_set_tlsext_debug_callback(ssl, cb) \
SSL_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_CB,(void (*)(void))cb)
#define SSL_set_tlsext_debug_arg(ssl, arg) \
SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_ARG,0, (void *)arg)
#define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \
SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,(void (*)(void))cb)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录