contrib/OCSP_check/OCSP_check.sh:
New barebone script to demonstrate how to use $tls_serial_{n}
to perform simple OCSP queries using OpenSSL command line
"openssl ocsp". Minimal sanity checks to fail if user tries to
use it without customizing.
openvpn.8:
Added some notes about $tls_serial_{n} format and usage to the
existing description.
ssl.c:
correctly manage and export serial numbers of any size (as
parsed by OpenSSL) into the environment. Set to empty string
in case of errors, as 0 and negative numbers are all possible
(although illegal) certificate serial numbers. Use an OpenSSL
BIO object to do the job. Conforms to coding style guidelines.
See the discussion at
http://article.gmane.org/gmane.network.openvpn.devel/3588
for more details.
Signed-off-by: Davide Brini <dave_br@gmx.com>
Signed-off-by: David Sommerseth <dazo@users.sourceforge.net>
Acked-by: David Sommerseth <dazo@users.sourceforge.net>
1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,89 @@ |
0 |
+#!/bin/sh |
|
1 |
+ |
|
2 |
+# Sample script to perform OCSP queries with OpenSSL |
|
3 |
+# given a certificate serial number. |
|
4 |
+ |
|
5 |
+# If you run your own CA, you can set up a very simple |
|
6 |
+# OCSP server using the -port option to "openssl ocsp". |
|
7 |
+ |
|
8 |
+# Full documentation and examples: |
|
9 |
+# http://www.openssl.org/docs/apps/ocsp.html |
|
10 |
+ |
|
11 |
+ |
|
12 |
+# Edit the following values to suit your needs |
|
13 |
+ |
|
14 |
+# OCSP responder URL (mandatory) |
|
15 |
+# YOU MUST UNCOMMENT ONE OF THESE AND SET IT TO A VALID SERVER |
|
16 |
+#ocsp_url="http://ocsp.example.com/" |
|
17 |
+#ocsp_url="https://ocsp.secure.example.com/" |
|
18 |
+ |
|
19 |
+# Path to issuer certificate (mandatory) |
|
20 |
+# YOU MUST SET THIS TO THE PATH TO THE CA CERTIFICATE |
|
21 |
+issuer="/path/to/CAcert.crt" |
|
22 |
+ |
|
23 |
+# use a nonce in the query, set to "-no_nonce" to not use it |
|
24 |
+nonce="-nonce" |
|
25 |
+ |
|
26 |
+# Verify the response |
|
27 |
+# YOU MUST SET THIS TO THE PATH TO THE RESPONSE VERIFICATION CERT |
|
28 |
+verify="/path/to/CAcert.crt" |
|
29 |
+ |
|
30 |
+# Depth in the certificate chain where the cert to verify is. |
|
31 |
+# Set to -1 to run the verification at every level (NOTE that |
|
32 |
+# in that case you need a more complex script as the various |
|
33 |
+# parameters for the query will likely be different at each level) |
|
34 |
+# "0" is the usual value here, where the client certificate is |
|
35 |
+check_depth=0 |
|
36 |
+ |
|
37 |
+cur_depth=$1 # this is the *CURRENT* depth |
|
38 |
+common_name=$2 # CN in case you need it |
|
39 |
+ |
|
40 |
+# minimal sanity checks |
|
41 |
+ |
|
42 |
+err=0 |
|
43 |
+if [ -z "$issuer" ] || [ ! -e "$issuer" ]; then |
|
44 |
+ echo "Error: issuer certificate undefined or not found!" >&2 |
|
45 |
+ err=1 |
|
46 |
+fi |
|
47 |
+ |
|
48 |
+if [ -z "$verify" ] || [ ! -e "$verify" ]; then |
|
49 |
+ echo "Error: verification certificate undefined or not found!" >&2 |
|
50 |
+ err=1 |
|
51 |
+fi |
|
52 |
+ |
|
53 |
+if [ -z "$ocsp_url" ]; then |
|
54 |
+ echo "Error: OCSP server URL not defined!" >&2 |
|
55 |
+ err=1 |
|
56 |
+fi |
|
57 |
+ |
|
58 |
+if [ $err -eq 1 ]; then |
|
59 |
+ echo "Did you forget to customize the variables in the script?" >&2 |
|
60 |
+ exit 1 |
|
61 |
+fi |
|
62 |
+ |
|
63 |
+# begin |
|
64 |
+if [ $check_depth -eq -1 ] || [ $cur_depth -eq $check_depth ]; then |
|
65 |
+ eval serial="\$tls_serial_${cur_depth}" |
|
66 |
+ |
|
67 |
+ # Check that the serial is not empty |
|
68 |
+ if [ -n "$serial" ]; then |
|
69 |
+ |
|
70 |
+ # This is only an example; you are encouraged to run this command (without |
|
71 |
+ # redirections) manually against your or your CA's OCSP server to see how |
|
72 |
+ # it responds, and adapt accordingly. |
|
73 |
+ # Sample output: |
|
74 |
+ # |
|
75 |
+ # Response verify OK |
|
76 |
+ # 0x428740A5: good |
|
77 |
+ # This Update: Apr 24 19:38:49 2010 GMT |
|
78 |
+ # Next Update: May 2 14:23:42 2010 GMT |
|
79 |
+ |
|
80 |
+ openssl ocsp -issuer "$issuer" \ |
|
81 |
+ "$nonce" \ |
|
82 |
+ -CAfile "$verify" \ |
|
83 |
+ -url "$ocsp_url" \ |
|
84 |
+ -serial "0x${serial}" >/dev/null 2>&1 |
|
85 |
+ else |
|
86 |
+ exit 1 |
|
87 |
+ fi |
|
88 |
+fi |
... | ... |
@@ -5355,7 +5355,12 @@ where |
5355 | 5355 |
is the verification level. Only set for TLS connections. Set prior |
5356 | 5356 |
to execution of |
5357 | 5357 |
.B \-\-tls-verify |
5358 |
-script. |
|
5358 |
+script. This is in the form of a hex string like "37AB46E0", which is |
|
5359 |
+suitable for doing serial-based OCSP queries (with OpenSSL, you have |
|
5360 |
+to prepend "0x" to the string). If something goes wrong while reading |
|
5361 |
+the value from the certificate it will be an empty string, so your |
|
5362 |
+code should check that. |
|
5363 |
+See the contrib/OCSP_check/OCSP_check.sh script for an example. |
|
5359 | 5364 |
.\"********************************************************* |
5360 | 5365 |
.TP |
5361 | 5366 |
.B tun_mtu |
... | ... |
@@ -788,9 +788,30 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx) |
788 | 788 |
|
789 | 789 |
/* export serial number as environmental variable */ |
790 | 790 |
{ |
791 |
- const int serial = (int) ASN1_INTEGER_get (X509_get_serialNumber (ctx->current_cert)); |
|
792 |
- openvpn_snprintf (envname, sizeof(envname), "tls_serial_%d", ctx->error_depth); |
|
793 |
- setenv_int (opt->es, envname, serial); |
|
791 |
+ BIO *bio = NULL; |
|
792 |
+ char serial[100]; |
|
793 |
+ int n1, n2; |
|
794 |
+ |
|
795 |
+ CLEAR (serial); |
|
796 |
+ if ((bio = BIO_new (BIO_s_mem ())) == NULL) |
|
797 |
+ { |
|
798 |
+ msg (M_WARN, "CALLBACK: Cannot create BIO (for tls_serial_%d)", ctx->error_depth); |
|
799 |
+ } |
|
800 |
+ else |
|
801 |
+ { |
|
802 |
+ /* "prints" the serial number onto the BIO and read it back */ |
|
803 |
+ if ( ! ( ( (n1 = i2a_ASN1_INTEGER(bio, X509_get_serialNumber (ctx->current_cert))) >= 0 ) && |
|
804 |
+ ( (n2 = BIO_read (bio, serial, sizeof (serial)-1)) >= 0 ) && |
|
805 |
+ ( n1 == n2 ) ) ) |
|
806 |
+ { |
|
807 |
+ msg (M_WARN, "CALLBACK: Error reading/writing BIO (for tls_serial_%d)", ctx->error_depth); |
|
808 |
+ CLEAR (serial); /* empty string */ |
|
809 |
+ } |
|
810 |
+ |
|
811 |
+ openvpn_snprintf (envname, sizeof(envname), "tls_serial_%d", ctx->error_depth); |
|
812 |
+ setenv_str (opt->es, envname, serial); |
|
813 |
+ BIO_free(bio); |
|
814 |
+ } |
|
794 | 815 |
} |
795 | 816 |
|
796 | 817 |
/* export current untrusted IP */ |