Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
nghttp2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
nghttp2
Commits
b7ba1baf
Commit
b7ba1baf
authored
Jun 06, 2015
by
Tatsuhiro Tsujikawa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Translate fetch-ocsp-response into Python
parent
00efa86f
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
253 additions
and
162 deletions
+253
-162
Makefile.am
Makefile.am
+2
-0
script/README.rst
script/README.rst
+10
-0
script/fetch-ocsp-response
script/fetch-ocsp-response
+241
-0
third-party/Makefile.am
third-party/Makefile.am
+0
-2
third-party/h2o/README.rst
third-party/h2o/README.rst
+0
-10
third-party/h2o/fetch-ocsp-response
third-party/h2o/fetch-ocsp-response
+0
-150
No files found.
Makefile.am
View file @
b7ba1baf
...
...
@@ -41,3 +41,5 @@ clang-format:
$
${CLANGFORMAT}
-i
lib/
*
.
{
c,h
}
lib/includes/nghttp2/
*
.h
\
src/
*
.
{
c,cc,h
}
src/includes/nghttp2/
*
.h examples/
*
.
{
c,cc
}
\
tests/
*
.
{
c,h
}
dist_pkgdata_SCRIPTS
=
script/fetch-ocsp-response
script/README.rst
0 → 100644
View file @
b7ba1baf
fetch-ocsp-response is a Python script which performs OCSP query and
get response. It uses openssl command under the hood. nghttpx uses
it to enable OCSP stapling feature.
fetch-ocsp-response is a translation from original fetch-ocsp-response
written in Perl and which has been developed as part of h2o project
(https://github.com/h2o/h2o).
fetch-ocsp-response is usually installed under $(pkgdatadir), which is
$(prefix)/share/nghttp2.
script/fetch-ocsp-response
0 → 100755
View file @
b7ba1baf
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# nghttp2 - HTTP/2 C Library
# Copyright (c) 2015 Tatsuhiro Tsujikawa
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# This program was translated from the program originally developed by
# h2o project (https://github.com/h2o/h2o), written in Perl. It had
# the following copyright notice:
# Copyright (c) 2015 DeNA Co., Ltd.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
from
__future__
import
unicode_literals
import
argparse
import
io
import
os
import
os.path
import
re
import
shutil
import
subprocess
import
sys
import
tempfile
# make this program work for both Python 3 and Python 2.
try
:
from
urllib.parse
import
urlparse
stdout_bwrite
=
sys
.
stdout
.
buffer
.
write
except
ImportError
:
from
urlparse
import
urlparse
stdout_bwrite
=
sys
.
stdout
.
write
def
die
(
msg
):
sys
.
stderr
.
write
(
msg
)
sys
.
stderr
.
write
(
'
\n
'
)
sys
.
exit
(
255
)
def
tempfail
(
msg
):
sys
.
stderr
.
write
(
msg
)
sys
.
stderr
.
write
(
'
\n
'
)
sys
.
exit
(
os
.
EX_TEMPFAIL
)
def
run_openssl
(
args
,
allow_tempfail
=
False
):
buf
=
io
.
BytesIO
()
try
:
p
=
subprocess
.
Popen
(
args
,
stdout
=
subprocess
.
PIPE
)
except
Exception
as
e
:
die
(
'failed to invoke {}:{}'
.
format
(
args
,
e
))
try
:
while
True
:
data
=
p
.
stdout
.
read
()
if
len
(
data
)
==
0
:
break
buf
.
write
(
data
)
if
p
.
wait
()
!=
0
:
raise
Exception
(
'nonzero return code {}'
.
format
(
p
.
returncode
))
return
buf
.
getvalue
()
except
Exception
as
e
:
msg
=
'OpenSSL exitted abnormally: {}:{}'
.
format
(
args
,
e
)
tempfail
(
msg
)
if
allow_tempfail
else
die
(
msg
)
def
read_file
(
path
):
with
open
(
path
,
'rb'
)
as
f
:
return
f
.
read
()
def
write_file
(
path
,
data
):
with
open
(
path
,
'wb'
)
as
f
:
f
.
write
(
data
)
def
detect_openssl_version
(
cmd
):
return
run_openssl
([
cmd
,
'version'
]).
decode
(
'utf-8'
).
strip
()
def
extract_ocsp_uri
(
cmd
,
cert_fn
):
# obtain ocsp uri
ocsp_uri
=
run_openssl
(
[
cmd
,
'x509'
,
'-in'
,
cert_fn
,
'-noout'
,
'-ocsp_uri'
]).
decode
(
'utf-8'
).
strip
()
if
not
re
.
match
(
r'^https?://'
,
ocsp_uri
):
die
(
'failed to extract ocsp URI from {}'
.
format
(
cert_fn
))
return
ocsp_uri
def
save_issuer_certificate
(
issuer_fn
,
cert_fn
):
# save issuer certificate
chain
=
read_file
(
cert_fn
).
decode
(
'utf-8'
)
m
=
re
.
match
(
r'.*?-----END CERTIFICATE-----.*?(-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----)'
,
chain
,
re
.
DOTALL
)
if
not
m
:
die
(
'--issuer option was not used, and failed to extract issuer certificate from the certificate'
)
write_file
(
issuer_fn
,
(
m
.
group
(
1
)
+
'
\n
'
).
encode
(
'utf-8'
))
def
send_and_receive_ocsp
(
respder_fn
,
cmd
,
cert_fn
,
issuer_fn
,
ocsp_uri
,
ocsp_host
,
openssl_version
):
# obtain response (without verification)
sys
.
stderr
.
write
(
'sending OCSP request to {}
\n
'
.
format
(
ocsp_uri
))
args
=
[
cmd
,
'ocsp'
,
'-issuer'
,
issuer_fn
,
'-cert'
,
cert_fn
,
'-url'
,
ocsp_uri
]
if
openssl_version
.
lower
().
startswith
(
'openssl 1.'
):
args
.
extend
([
'-header'
,
'Host'
,
ocsp_host
])
args
.
extend
([
'-noverify'
,
'-respout'
,
respder_fn
])
resp
=
run_openssl
(
args
,
allow_tempfail
=
True
)
return
resp
.
decode
(
'utf-8'
)
def
verify_response
(
cmd
,
tempdir
,
issuer_fn
,
respder_fn
):
# verify the response
sys
.
stderr
.
write
(
'verifying the response signature
\n
'
)
verify_fn
=
os
.
path
.
join
(
tempdir
,
'verify.out'
)
# try from exotic options
allextra
=
[
# for comodo
[
'-VAfile'
,
issuer_fn
],
# these options are only available in OpenSSL >= 1.0.2
[
'-partial_chain'
,
'-trusted_first'
,
'-CAfile'
,
issuer_fn
],
# for OpenSSL <= 1.0.1
[
'-CAfile'
,
issuer_fn
],
]
for
extra
in
allextra
:
with
open
(
verify_fn
,
'wb'
)
as
f
:
args
=
[
cmd
,
'ocsp'
,
'-respin'
,
respder_fn
]
args
.
extend
(
extra
)
p
=
subprocess
.
Popen
(
args
,
stdout
=
f
,
stderr
=
f
)
if
p
.
wait
()
==
0
:
sys
.
stderr
.
write
(
'verify OK (used: {})
\n
'
.
format
(
extra
))
return
True
sys
.
stderr
.
write
(
read_file
(
verify_fn
).
decode
(
'utf-8'
))
return
False
def
fetch_ocsp_response
(
cmd
,
cert_fn
,
tempdir
,
issuer_fn
=
None
):
openssl_version
=
detect_openssl_version
(
cmd
)
sys
.
stderr
.
write
(
'fetch-ocsp-response (using {})
\n
'
.
format
(
openssl_version
))
ocsp_uri
=
extract_ocsp_uri
(
cmd
,
cert_fn
)
ocsp_host
=
urlparse
(
ocsp_uri
).
hostname
if
not
issuer_fn
:
issuer_fn
=
os
.
path
.
join
(
tempdir
,
'issuer.crt'
)
save_issuer_certificate
(
issuer_fn
,
cert_fn
)
respder_fn
=
os
.
path
.
join
(
tempdir
,
'resp.der'
)
resp
=
send_and_receive_ocsp
(
respder_fn
,
cmd
,
cert_fn
,
issuer_fn
,
ocsp_uri
,
ocsp_host
,
openssl_version
)
sys
.
stderr
.
write
(
'{}
\n
'
.
format
(
resp
))
if
not
verify_response
(
cmd
,
tempdir
,
issuer_fn
,
respder_fn
):
tempfail
(
'failed to verify the response'
)
# success
res
=
read_file
(
respder_fn
)
stdout_bwrite
(
res
)
if
__name__
==
'__main__'
:
parser
=
argparse
.
ArgumentParser
(
description
=
'''The command issues an OCSP request for given server certificate, verifies the response and prints the resulting DER.'''
,
epilog
=
'''The command exits 0 if successful, or 75 (EX_TEMPFAIL) on temporary error. Other exit codes may be returned in case of hard errors.'''
)
parser
.
add_argument
(
'--issuer'
,
metavar
=
'FILE'
,
help
=
'issuer certificate (if omitted, is extracted from the certificate chain)'
)
parser
.
add_argument
(
'--openssl'
,
metavar
=
'CMD'
,
help
=
'openssl command to use (default: "openssl")'
,
default
=
'openssl'
)
parser
.
add_argument
(
'certificate'
,
help
=
'path to certificate file to validate'
)
args
=
parser
.
parse_args
()
tempdir
=
None
try
:
# Python3.2 has tempfile.TemporaryDirectory, which has nice
# feature to delete its tree by cleanup() function. We have
# to support Python2.7, so we have to do this manually.
tempdir
=
tempfile
.
mkdtemp
()
fetch_ocsp_response
(
args
.
openssl
,
args
.
certificate
,
tempdir
,
args
.
issuer
)
finally
:
if
tempdir
:
shutil
.
rmtree
(
tempdir
)
third-party/Makefile.am
View file @
b7ba1baf
...
...
@@ -32,5 +32,3 @@ libhttp_parser_la_SOURCES = \
endif
# ENABLE_THIRD_PARTY
dist_pkgdata_SCRIPTS
=
h2o/fetch-ocsp-response
third-party/h2o/README.rst
deleted
100644 → 0
View file @
00efa86f
fetch-ocsp-response is a Perl script to perform OCSP query and get
response. It uses openssl command under the hood. nghttpx uses it to
enable OCSP stapling feature.
fetch-ocsp-response has been developed as part of h2o project
(https://github.com/h2o/h2o). The script file with the same name in
this directory was copied from their github repository.
fetch-ocsp-response is usually installed under $(pkgdatadir), which is
$(prefix)/share/nghttp2.
third-party/h2o/fetch-ocsp-response
deleted
100755 → 0
View file @
00efa86f
#! /bin/sh
exec
perl
-x
$0
"
$@
"
#! perl
# Copyright (c) 2015 DeNA Co., Ltd.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
use strict
;
use warnings
;
use File::Temp qw
(
tempdir
)
;
use Getopt::Long
;
# from sysexits.h
use constant EX_TEMPFAIL
=>
75
;
my
(
$issuer_fn
,
$opt_help
)
;
my
$openssl_cmd
=
'openssl'
;
GetOptions
(
"issuer=s"
=>
\$
issuer_fn,
"openssl=s"
,
=>
\$
openssl_cmd,
help
=>
\$
opt_help,
)
or
exit
(
1
)
;
if
(
$opt_help
)
{
print
<<
"
EOT
";
Usage:
$0
[<options>] <certificate-file>
Options:
--issuer <file> issuer certificate (if omitted, is extracted from the
certificate chain)
--openssl <cmd> openssl command to use (default: "openssl")
--help prints this help
The command issues an OCSP request for given server certificate, verifies the
response and prints the resulting DER.
The command exits 0 if successful, or 75 (EX_TEMPFAIL) on temporary error.
Other exit codes may be returned in case of hard errors.
EOT
exit
(
0
)
;
}
die
"no certificate file
\n
"
if
@ARGV
==
0
;
my
$cert_fn
=
shift
@ARGV
;
my
$tempdir
=
tempdir
(
CLEANUP
=>
1
)
;
my
$openssl_version
=
run_openssl
(
"version"
)
;
chomp
$openssl_version
;
print STDERR
"fetch-ocsp-response (using
$openssl_version
)
\n
"
;
# obtain ocsp uri
my
$ocsp_uri
=
run_openssl
(
"x509 -in
$cert_fn
-noout -ocsp_uri"
)
;
chomp
$ocsp_uri
;
die
"failed to extract ocsp URI from
$cert_fn
\n
"
if
$ocsp_uri
!
~ m
{
^https?://
}
;
my
(
$ocsp_host
)
=
$ocsp_uri
=
~ m
{
^https?://
([
^/:]+
)}
;
# save issuer certificate
if
(!
defined
$issuer_fn
)
{
my
$chain
=
read_file
(
$cert_fn
)
;
$chain
=
~ m
{
-----END
CERTIFICATE-----.
*
?
(
-----BEGIN
CERTIFICATE-----.
*
?-----END CERTIFICATE-----
)}
s
or die
"--issuer option was not used, and failed to extract issuer certificate from the certificate
\n
"
;
$issuer_fn
=
"
$tempdir
/issuer.crt"
;
write_file
(
$issuer_fn
,
"
$1
\n
"
)
;
}
# obtain response (without verification)
print STDERR
"sending OCSP request to
$ocsp_uri
\n
"
;
my
$resp
=
run_openssl
(
"ocsp -issuer
$issuer_fn
-cert
$cert_fn
-url
$ocsp_uri
"
.
(
$openssl_version
=
~ /^OpenSSL 1
\.
/is ?
" -header Host
$ocsp_host
"
:
""
)
.
" -noverify -respout
$tempdir
/resp.der "
.
join
(
' '
, @ARGV
)
,
1,
)
;
print STDERR
$resp
;
# verify the response
print STDERR
"verifying the response signature
\n
"
;
my
$success
;
for
my
$args
(
# try from exotic options
"-VAfile
$issuer_fn
"
,
# for comodo
"-partial_chain -trusted_first -CAfile
$issuer_fn
"
,
# these options are only available in OpenSSL >= 1.0.2
"-CAfile
$issuer_fn
"
,
# for OpenSSL <= 1.0.1
)
{
if
(
system
(
"
$openssl_cmd
ocsp -respin
$tempdir
/resp.der
$args
>
$tempdir
/verify.out 2>&1"
)
==
0
)
{
print STDERR
"verify OK (used:
$args
)
\n
"
;
$success
=
1
;
last
;
}
}
if
(!
$success
)
{
print STDERR read_file
(
"
$tempdir
/verify.out"
)
;
tempfail
(
"failed to verify the response
\n
"
)
;
}
# success
print read_file
(
"
$tempdir
/resp.der"
)
;
exit
0
;
sub run_openssl
{
my
(
$args
,
$tempfail
)
=
@_
;
open my
$fh
,
"-|"
,
"
$openssl_cmd
$args
"
or die
"failed to invoke
$openssl_cmd
:
$!
"
;
my
$resp
=
do
{
local
$/
;
<
$fh
>
}
;
close
$fh
or
(
$tempfail
?
\&
tempfail :
\&
die
)
->
(
"OpenSSL exitted abnormally:
$openssl_cmd
$args
:
$!
"
)
;
$resp
;
}
sub read_file
{
my
$fn
=
shift
;
open my
$fh
,
"<"
,
$fn
or die
"failed to open file:
$fn
:
$!
"
;
local
$/
;
<
$fh
>
;
}
sub write_file
{
my
(
$fn
,
$data
)
=
@_
;
open my
$fh
,
">"
,
$fn
or die
"failed to open file:
$fn
:
$!
"
;
print
$fh
$data
;
close
$fh
;
}
sub tempfail
{
print STDERR @_
;
exit
EX_TEMPFAIL
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment