Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Third Party Openssl
提交
c1c6c0bf
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 搜索 >>
提交
c1c6c0bf
编写于
7月 17, 2006
作者:
D
Dr. Stephen Henson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
New non-blocking OCSP functionality.
上级
dff2922a
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
396 addition
and
85 deletion
+396
-85
CHANGES
CHANGES
+3
-0
crypto/ocsp/ocsp.h
crypto/ocsp/ocsp.h
+6
-0
crypto/ocsp/ocsp_err.c
crypto/ocsp/ocsp_err.c
+1
-0
crypto/ocsp/ocsp_ht.c
crypto/ocsp/ocsp_ht.c
+384
-85
crypto/ossl_typ.h
crypto/ossl_typ.h
+2
-0
未找到文件。
CHANGES
浏览文件 @
c1c6c0bf
...
...
@@ -4,6 +4,9 @@
Changes between 0.9.8b and 0.9.9 [xx XXX xxxx]
*) Non-blocking OCSP request processing.
[Steve Henson]
*) Allow digests to supply their own micalg string for S/MIME type using
the ctrl EVP_MD_CTRL_MICALG.
[Steve Henson]
...
...
crypto/ocsp/ocsp.h
浏览文件 @
c1c6c0bf
...
...
@@ -64,6 +64,7 @@
#ifndef HEADER_OCSP_H
#define HEADER_OCSP_H
#include <openssl/ossl_typ.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/safestack.h>
...
...
@@ -397,6 +398,10 @@ typedef struct ocsp_service_locator_st
(char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs))
OCSP_RESPONSE
*
OCSP_sendreq_bio
(
BIO
*
b
,
char
*
path
,
OCSP_REQUEST
*
req
);
OCSP_REQ_CTX
*
OCSP_sendreq_new
(
BIO
*
io
,
char
*
path
,
OCSP_REQUEST
*
req
,
int
maxline
);
int
OCSP_sendreq_nbio
(
OCSP_RESPONSE
**
presp
,
OCSP_REQ_CTX
*
rctx
);
void
OCSP_REQ_CTX_free
(
OCSP_REQ_CTX
*
rctx
);
OCSP_CERTID
*
OCSP_cert_to_id
(
const
EVP_MD
*
dgst
,
X509
*
subject
,
X509
*
issuer
);
...
...
@@ -574,6 +579,7 @@ void ERR_load_OCSP_strings(void);
#define OCSP_F_OCSP_REQUEST_VERIFY 116
#define OCSP_F_OCSP_RESPONSE_GET1_BASIC 111
#define OCSP_F_OCSP_SENDREQ_BIO 112
#define OCSP_F_OCSP_SENDREQ_NBIO 117
#define OCSP_F_REQUEST_VERIFY 113
/* Reason codes. */
...
...
crypto/ocsp/ocsp_err.c
浏览文件 @
c1c6c0bf
...
...
@@ -86,6 +86,7 @@ static ERR_STRING_DATA OCSP_str_functs[]=
{
ERR_FUNC
(
OCSP_F_OCSP_REQUEST_VERIFY
),
"OCSP_request_verify"
},
{
ERR_FUNC
(
OCSP_F_OCSP_RESPONSE_GET1_BASIC
),
"OCSP_response_get1_basic"
},
{
ERR_FUNC
(
OCSP_F_OCSP_SENDREQ_BIO
),
"OCSP_sendreq_bio"
},
{
ERR_FUNC
(
OCSP_F_OCSP_SENDREQ_NBIO
),
"OCSP_sendreq_nbio"
},
{
ERR_FUNC
(
OCSP_F_REQUEST_VERIFY
),
"REQUEST_VERIFY"
},
{
0
,
NULL
}
};
...
...
crypto/ocsp/ocsp_ht.c
浏览文件 @
c1c6c0bf
/* ocsp_ht.c */
/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
* project 200
0
.
* project 200
6
.
*/
/* ====================================================================
* Copyright (c) 200
0
The OpenSSL Project. All rights reserved.
* Copyright (c) 200
6
The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
...
...
@@ -68,106 +68,405 @@
#define strtoul (unsigned long)strtol
#endif
/* OPENSSL_SYS_SUNOS */
/* Quick and dirty HTTP OCSP request handler.
* Could make this a bit cleverer by adding
* support for non blocking BIOs and a few
* other refinements.
*/
/* Stateful OCSP request code, supporting non-blocking I/O */
OCSP_RESPONSE
*
OCSP_sendreq_bio
(
BIO
*
b
,
char
*
path
,
OCSP_REQUEST
*
req
)
{
BIO
*
mem
=
NULL
;
char
tmpbuf
[
1024
];
OCSP_RESPONSE
*
resp
=
NULL
;
char
*
p
,
*
q
,
*
r
;
int
len
,
retcode
;
static
char
req_txt
[]
=
"POST %s HTTP/1.0
\r\n
\
Content-Type: application/ocsp-request
\r\n
\
Content-Length: %d
\r\n\r\n
"
;
len
=
i2d_OCSP_REQUEST
(
req
,
NULL
);
if
(
BIO_printf
(
b
,
req_txt
,
path
,
len
)
<
0
)
{
OCSPerr
(
OCSP_F_OCSP_SENDREQ_BIO
,
OCSP_R_SERVER_WRITE_ERROR
);
goto
err
;
}
if
(
i2d_OCSP_REQUEST_bio
(
b
,
req
)
<=
0
)
{
OCSPerr
(
OCSP_F_OCSP_SENDREQ_BIO
,
OCSP_R_SERVER_WRITE_ERROR
);
goto
err
;
/* Opaque OCSP request status structure */
struct
ocsp_req_ctx_st
{
int
state
;
/* Current I/O state */
unsigned
char
*
iobuf
;
/* Line buffer */
int
iobuflen
;
/* Line buffer length */
BIO
*
io
;
/* BIO to perform I/O with */
BIO
*
mem
;
/* Memory BIO response is built into */
unsigned
long
asn1_len
;
/* ASN1 length of response */
};
#define OCSP_MAX_REQUEST_LENGTH (100 * 1024)
#define OCSP_MAX_LINE_LEN 4096;
/* OCSP states */
/* If set no reading should be performed */
#define OHS_NOREAD 0x1000
/* Error condition */
#define OHS_ERROR (0 | OHS_NOREAD)
/* First line being read */
#define OHS_FIRSTLINE 1
/* MIME headers being read */
#define OHS_HEADERS 2
/* OCSP initial header (tag + length) being read */
#define OHS_ASN1_HEADER 3
/* OCSP content octets being read */
#define OHS_ASN1_CONTENT 4
/* Request being sent */
#define OHS_ASN1_WRITE (6 | OHS_NOREAD)
/* Request being flushed */
#define OHS_ASN1_FLUSH (7 | OHS_NOREAD)
/* Completed */
#define OHS_DONE (8 | OHS_NOREAD)
static
int
parse_http_line1
(
char
*
line
);
void
OCSP_REQ_CTX_free
(
OCSP_REQ_CTX
*
rctx
)
{
if
(
rctx
->
mem
)
BIO_free
(
rctx
->
mem
);
if
(
rctx
->
iobuf
)
OPENSSL_free
(
rctx
->
iobuf
);
OPENSSL_free
(
rctx
);
}
if
(
!
(
mem
=
BIO_new
(
BIO_s_mem
())))
goto
err
;
/* Copy response to a memory BIO: socket bios can't do gets! */
while
((
len
=
BIO_read
(
b
,
tmpbuf
,
sizeof
tmpbuf
)))
{
if
(
len
<
0
)
{
OCSPerr
(
OCSP_F_OCSP_SENDREQ_BIO
,
OCSP_R_SERVER_READ_ERROR
);
goto
err
;
OCSP_REQ_CTX
*
OCSP_sendreq_new
(
BIO
*
io
,
char
*
path
,
OCSP_REQUEST
*
req
,
int
maxline
)
{
static
char
post_hdr
[]
=
"POST %s HTTP/1.0
\r\n
"
"Content-Type: application/ocsp-request
\r\n
"
"Content-Length: %d
\r\n\r\n
"
;
OCSP_REQ_CTX
*
rctx
;
rctx
=
OPENSSL_malloc
(
sizeof
(
OCSP_REQ_CTX
));
rctx
->
state
=
OHS_FIRSTLINE
;
rctx
->
mem
=
BIO_new
(
BIO_s_mem
());
rctx
->
io
=
io
;
if
(
maxline
>
0
)
rctx
->
iobuflen
=
maxline
;
else
rctx
->
iobuflen
=
OCSP_MAX_LINE_LEN
;
rctx
->
iobuf
=
OPENSSL_malloc
(
rctx
->
iobuflen
);
if
(
!
path
)
path
=
"/"
;
if
(
BIO_printf
(
rctx
->
mem
,
post_hdr
,
path
,
i2d_OCSP_REQUEST
(
req
,
NULL
))
<=
0
)
{
rctx
->
state
=
OHS_ERROR
;
return
0
;
}
BIO_write
(
mem
,
tmpbuf
,
len
);
}
if
(
BIO_gets
(
mem
,
tmpbuf
,
512
)
<=
0
)
{
OCSPerr
(
OCSP_F_OCSP_SENDREQ_BIO
,
OCSP_R_SERVER_RESPONSE_PARSE_ERROR
);
goto
err
;
if
(
i2d_OCSP_REQUEST_bio
(
rctx
->
mem
,
req
)
<=
0
)
{
rctx
->
state
=
OHS_ERROR
;
return
0
;
}
rctx
->
state
=
OHS_ASN1_WRITE
;
rctx
->
asn1_len
=
BIO_get_mem_data
(
rctx
->
mem
,
NULL
);
return
rctx
;
}
/* Parse the HTTP response. This will look like this:
* "HTTP/1.0 200 OK". We need to obtain the numeric code and
* (optional) informational message.
*/
/* Parse the HTTP response. This will look like this:
* "HTTP/1.0 200 OK". We need to obtain the numeric code and
* (optional) informational message.
*/
static
int
parse_http_line1
(
char
*
line
)
{
int
retcode
;
char
*
p
,
*
q
,
*
r
;
/* Skip to first white space (passed protocol info) */
for
(
p
=
tmpbuf
;
*
p
&&
!
isspace
((
unsigned
char
)
*
p
);
p
++
)
continue
;
if
(
!*
p
)
{
OCSPerr
(
OCSP_F_OCSP_SENDREQ_BIO
,
OCSP_R_SERVER_RESPONSE_PARSE_ERROR
);
goto
err
;
}
for
(
p
=
line
;
*
p
&&
!
isspace
((
unsigned
char
)
*
p
);
p
++
)
continue
;
if
(
!*
p
)
{
OCSPerr
(
OCSP_F_OCSP_SENDREQ_NBIO
,
OCSP_R_SERVER_RESPONSE_PARSE_ERROR
);
return
0
;
}
/* Skip past white space to start of response code */
while
(
*
p
&&
isspace
((
unsigned
char
)
*
p
))
p
++
;
if
(
!*
p
)
{
OCSPerr
(
OCSP_F_OCSP_SENDREQ_BIO
,
OCSP_R_SERVER_RESPONSE_PARSE_ERROR
);
goto
err
;
}
while
(
*
p
&&
isspace
((
unsigned
char
)
*
p
))
p
++
;
if
(
!*
p
)
{
OCSPerr
(
OCSP_F_OCSP_SENDREQ_NBIO
,
OCSP_R_SERVER_RESPONSE_PARSE_ERROR
);
return
0
;
}
/* Find end of response code: first whitespace after start of code */
for
(
q
=
p
;
*
q
&&
!
isspace
((
unsigned
char
)
*
q
);
q
++
)
continue
;
if
(
!*
q
)
{
OCSPerr
(
OCSP_F_OCSP_SENDREQ_BIO
,
OCSP_R_SERVER_RESPONSE_PARSE_ERROR
);
goto
err
;
}
for
(
q
=
p
;
*
q
&&
!
isspace
((
unsigned
char
)
*
q
);
q
++
)
continue
;
if
(
!*
q
)
{
OCSPerr
(
OCSP_F_OCSP_SENDREQ_NBIO
,
OCSP_R_SERVER_RESPONSE_PARSE_ERROR
);
return
0
;
}
/* Set end of response code and start of message */
*
q
++
=
0
;
/* Attempt to parse numeric code */
retcode
=
strtoul
(
p
,
&
r
,
10
);
if
(
*
r
)
goto
err
;
if
(
*
r
)
return
0
;
/* Skip over any leading white space in message */
while
(
*
q
&&
isspace
((
unsigned
char
)
*
q
))
q
++
;
if
(
*
q
)
{
/* Finally zap any trailing white space in message (include CRLF) */
/* We know q has a non white space character so this is OK */
for
(
r
=
q
+
strlen
(
q
)
-
1
;
isspace
((
unsigned
char
)
*
r
);
r
--
)
*
r
=
0
;
}
if
(
retcode
!=
200
)
{
OCSPerr
(
OCSP_F_OCSP_SENDREQ_BIO
,
OCSP_R_SERVER_RESPONSE_ERROR
);
if
(
!*
q
)
{
ERR_add_error_data
(
2
,
"Code="
,
p
);
while
(
*
q
&&
isspace
((
unsigned
char
)
*
q
))
q
++
;
if
(
*
q
)
{
/* Finally zap any trailing white space in message (include
* CRLF) */
/* We know q has a non white space character so this is OK */
for
(
r
=
q
+
strlen
(
q
)
-
1
;
isspace
((
unsigned
char
)
*
r
);
r
--
)
*
r
=
0
;
}
else
{
if
(
retcode
!=
200
)
{
OCSPerr
(
OCSP_F_OCSP_SENDREQ_NBIO
,
OCSP_R_SERVER_RESPONSE_ERROR
);
if
(
!*
q
)
ERR_add_error_data
(
2
,
"Code="
,
p
);
else
ERR_add_error_data
(
4
,
"Code="
,
p
,
",Reason="
,
q
);
return
0
;
}
goto
err
;
return
1
;
}
/* Find blank line marking beginning of content */
while
(
BIO_gets
(
mem
,
tmpbuf
,
512
)
>
0
)
int
OCSP_sendreq_nbio
(
OCSP_RESPONSE
**
presp
,
OCSP_REQ_CTX
*
rctx
)
{
for
(
p
=
tmpbuf
;
*
p
&&
isspace
((
unsigned
char
)
*
p
);
p
++
)
continue
;
if
(
!*
p
)
break
;
}
if
(
*
p
)
{
OCSPerr
(
OCSP_F_OCSP_SENDREQ_BIO
,
OCSP_R_NO_CONTENT
);
goto
err
;
int
i
,
n
;
const
unsigned
char
*
p
;
next_io:
if
(
!
(
rctx
->
state
&
OHS_NOREAD
))
{
n
=
BIO_read
(
rctx
->
io
,
rctx
->
iobuf
,
rctx
->
iobuflen
);
if
(
n
<=
0
)
{
if
(
BIO_should_retry
(
rctx
->
io
))
return
-
1
;
return
0
;
}
/* Write data to memory BIO */
if
(
BIO_write
(
rctx
->
mem
,
rctx
->
iobuf
,
n
)
!=
n
)
return
0
;
}
switch
(
rctx
->
state
)
{
case
OHS_ASN1_WRITE
:
n
=
BIO_get_mem_data
(
rctx
->
mem
,
&
p
);
i
=
BIO_write
(
rctx
->
io
,
p
+
(
n
-
rctx
->
asn1_len
),
rctx
->
asn1_len
);
if
(
i
<=
0
)
{
if
(
BIO_should_retry
(
rctx
->
io
))
return
-
1
;
rctx
->
state
=
OHS_ERROR
;
return
0
;
}
rctx
->
asn1_len
-=
i
;
if
(
rctx
->
asn1_len
>
0
)
goto
next_io
;
rctx
->
state
=
OHS_ASN1_FLUSH
;
BIO_reset
(
rctx
->
mem
);
case
OHS_ASN1_FLUSH
:
i
=
BIO_flush
(
rctx
->
io
);
if
(
i
>
0
)
{
rctx
->
state
=
OHS_FIRSTLINE
;
goto
next_io
;
}
if
(
BIO_should_retry
(
rctx
->
io
))
return
-
1
;
rctx
->
state
=
OHS_ERROR
;
return
0
;
case
OHS_ERROR
:
return
0
;
case
OHS_FIRSTLINE
:
case
OHS_HEADERS
:
/* Attempt to read a line in */
next_line:
/* Due to &%^*$" memory BIO behaviour with BIO_gets we
* have to check there's a complete line in there before
* calling BIO_gets or we'll just get a partial read.
*/
n
=
BIO_get_mem_data
(
rctx
->
mem
,
&
p
);
if
((
n
<=
0
)
||
!
memchr
(
p
,
'\n'
,
n
))
{
if
(
n
>=
rctx
->
iobuflen
)
{
rctx
->
state
=
OHS_ERROR
;
return
0
;
}
goto
next_io
;
}
n
=
BIO_gets
(
rctx
->
mem
,
(
char
*
)
rctx
->
iobuf
,
rctx
->
iobuflen
);
if
(
n
<=
0
)
{
if
(
BIO_should_retry
(
rctx
->
mem
))
goto
next_io
;
rctx
->
state
=
OHS_ERROR
;
return
0
;
}
/* Don't allow excessive lines */
if
(
n
==
rctx
->
iobuflen
)
{
rctx
->
state
=
OHS_ERROR
;
return
0
;
}
/* First line */
if
(
rctx
->
state
==
OHS_FIRSTLINE
)
{
if
(
parse_http_line1
((
char
*
)
rctx
->
iobuf
))
{
rctx
->
state
=
OHS_HEADERS
;
goto
next_line
;
}
else
{
rctx
->
state
=
OHS_ERROR
;
return
0
;
}
}
else
{
/* Look for blank line: end of headers */
for
(
p
=
rctx
->
iobuf
;
*
p
;
p
++
)
{
if
((
*
p
!=
'\r'
)
&&
(
*
p
!=
'\n'
))
break
;
}
if
(
*
p
)
goto
next_line
;
rctx
->
state
=
OHS_ASN1_HEADER
;
}
/* Fall thru */
case
OHS_ASN1_HEADER
:
/* Now reading ASN1 header: can read at least 6 bytes which
* is more than enough for any valid ASN1 SEQUENCE header
*/
n
=
BIO_get_mem_data
(
rctx
->
mem
,
&
p
);
if
(
n
<
6
)
goto
next_io
;
/* Check it is an ASN1 SEQUENCE */
if
(
*
p
++
!=
(
V_ASN1_SEQUENCE
|
V_ASN1_CONSTRUCTED
))
{
rctx
->
state
=
OHS_ERROR
;
return
0
;
}
/* Check out length field */
if
(
*
p
&
0x80
)
{
n
=
*
p
&
0x7F
;
/* Not NDEF or excessive length */
if
(
!
n
||
(
n
>
4
))
{
rctx
->
state
=
OHS_ERROR
;
return
0
;
}
p
++
;
rctx
->
asn1_len
=
0
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
rctx
->
asn1_len
<<=
8
;
rctx
->
asn1_len
|=
*
p
++
;
}
if
(
rctx
->
asn1_len
>
OCSP_MAX_REQUEST_LENGTH
)
{
rctx
->
state
=
OHS_ERROR
;
return
0
;
}
rctx
->
asn1_len
+=
n
+
2
;
}
else
rctx
->
asn1_len
=
*
p
+
2
;
rctx
->
state
=
OHS_ASN1_CONTENT
;
/* Fall thru */
case
OHS_ASN1_CONTENT
:
n
=
BIO_get_mem_data
(
rctx
->
mem
,
&
p
);
if
(
n
<
rctx
->
asn1_len
)
goto
next_io
;
*
presp
=
d2i_OCSP_RESPONSE
(
NULL
,
&
p
,
rctx
->
asn1_len
);
if
(
*
presp
)
{
rctx
->
state
=
OHS_DONE
;
return
1
;
}
rctx
->
state
=
OHS_ERROR
;
return
0
;
break
;
case
OHS_DONE
:
return
1
;
}
return
0
;
}
if
(
!
(
resp
=
d2i_OCSP_RESPONSE_bio
(
mem
,
NULL
)))
{
OCSPerr
(
OCSP_F_OCSP_SENDREQ_BIO
,
ERR_R_NESTED_ASN1_ERROR
);
goto
err
;
/* Blocking OCSP request handler: now a special case of non-blocking I/O */
OCSP_RESPONSE
*
OCSP_sendreq_bio
(
BIO
*
b
,
char
*
path
,
OCSP_REQUEST
*
req
)
{
OCSP_RESPONSE
*
resp
=
NULL
;
OCSP_REQ_CTX
*
ctx
;
int
rv
;
ctx
=
OCSP_sendreq_new
(
b
,
path
,
req
,
-
1
);
do
{
rv
=
OCSP_sendreq_nbio
(
&
resp
,
ctx
);
}
while
((
rv
==
-
1
)
&&
BIO_should_retry
(
b
));
OCSP_REQ_CTX_free
(
ctx
);
if
(
rv
)
return
resp
;
return
NULL
;
}
err:
BIO_free
(
mem
);
return
resp
;
}
crypto/ossl_typ.h
浏览文件 @
c1c6c0bf
...
...
@@ -181,4 +181,6 @@ typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
typedef
int
CRYPTO_EX_dup
(
CRYPTO_EX_DATA
*
to
,
CRYPTO_EX_DATA
*
from
,
void
*
from_d
,
int
idx
,
long
argl
,
void
*
argp
);
typedef
struct
ocsp_req_ctx_st
OCSP_REQ_CTX
;
#endif
/* def HEADER_OPENSSL_TYPES_H */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录