Browse code

Merged PKCS#11 extensions to easy-rsa/2.0 (Alon Bar-Lev). svn merge -r 995:998 https://svn.openvpn.net/projects/openvpn/contrib/alon/easy-rsa

git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@1006 e7ae566f-a301-0410-adde-c780ea21d3b5

james authored on 2006/04/13 19:20:43
Showing 9 changed files
... ...
@@ -61,6 +61,8 @@ Release Notes for easy-rsa-2.0
61 61
   the crl.pem file to all clients as well, and have them include
62 62
   "crl-verify crl.pem" in their configuration files.
63 63
 
64
+* PKCS#11 support was added.
65
+
64 66
 INSTALL easy-rsa
65 67
 
66 68
 1. Edit vars.
... ...
@@ -80,9 +82,17 @@ INSTALL easy-rsa
80 80
    must be compatible across both peers
81 81
    participating in a secure SSL/TLS
82 82
    connection.
83
-5  . vars
84
-6. ./clean-all
85
-7. As you create certificates, keys, and
83
+5. (Optional) If you intend to use PKCS#11,
84
+   install openssl >= 0.9.7, install the 
85
+   following components from www.opensc.org:
86
+   - opensc >= 0.10.0
87
+   - engine_pkcs11 >= 0.1.3
88
+   Update the openssl.cnf to load the engine:
89
+   - Uncomment pkcs11 under engine_section.
90
+   - Validate path at dynamic_path under pkcs11_section.
91
+6. . vars
92
+7. ./clean-all
93
+8. As you create certificates, keys, and
86 94
    certificate signing requests, understand that
87 95
    only .key files should be kept confidential.
88 96
    .crt and .csr files can be sent over insecure
... ...
@@ -96,21 +106,30 @@ server, make sure to enforce some kind of server certificate
96 96
 verification by clients.  There are currently four different ways
97 97
 of accomplishing this, listed in the order of preference:
98 98
 
99
-(1) Build your server certificates with the build-key-server
100
-    script, or using the --server option to pkitool.
101
-    This will designate the certificate as a
102
-    server-only certificate by setting nsCertType=server.
99
+(1) Build your server certificates with specific key usage and
100
+    extended key usage. The RFC3280 determine that the following
101
+    attributes should be provided for TLS connections:
102
+
103
+    Mode      Key usage	                         Extended key usage
104
+    ---------------------------------------------------------------------------
105
+    Client    digitalSignature	                 TLS Web Client Authentication
106
+              keyAgreement
107
+              digitalSignature, keyAgreement
108
+	      
109
+    Server    digitalSignature, keyEncipherment  TLS Web Server Authentication
110
+              digitalSignature, keyAgreement
111
+
103 112
     Now add the following line to your client configuration:
104 113
       
105
-    ns-cert-type server
114
+    remote-cert-tls server
106 115
 
107 116
     This will block clients from connecting to any
108
-    server which lacks the nsCertType=server designation
117
+    server which lacks the required extension designation
109 118
     in its certificate, even if the certificate has been
110 119
     signed by the CA which is cited in the OpenVPN configuration
111 120
     file (--ca directive).
112 121
 
113
-(2) Use the --tls-remote directive on the client to
122
+(3) Use the --tls-remote directive on the client to
114 123
     accept/reject the server connection based on the common
115 124
     name of the server certificate.
116 125
 
... ...
@@ -134,6 +153,8 @@ pkitool 2.0
134 134
 Usage: pkitool [options...] [common-name]
135 135
 Options:
136 136
   --batch    : batch mode (default)
137
+  --keysize  : Set keysize
138
+      size   : size (default=1024)
137 139
   --interact : interactive mode
138 140
   --server   : build server cert
139 141
   --initca   : build root CA
... ...
@@ -141,13 +162,29 @@ Options:
141 141
   --pass     : encrypt private key with password
142 142
   --csr      : only generate a CSR, do not sign
143 143
   --sign     : sign an existing CSR
144
-  --pkcs12   : generate a combined pkcs12 file
144
+  --pkcs12   : generate a combined PKCS#12 file
145
+  --pkcs11   : generate certificate on PKCS#11 token
146
+      lib    : PKCS#11 library
147
+      slot   : PKCS#11 slot
148
+      id     : PKCS#11 object id (hex string)
149
+      label  : PKCS#11 object label
150
+Standalone options:
151
+  --pkcs11-slots   : list PKCS#11 slots
152
+      lib    : PKCS#11 library
153
+  --pkcs11-objects : list PKCS#11 token objects
154
+      lib    : PKCS#11 library
155
+      slot   : PKCS#11 slot
156
+  --pkcs11-init    : initialize PKCS#11 token DANGEROUS!!!
157
+      lib    : PKCS#11 library
158
+      slot   : PKCS#11 slot
159
+      label  : PKCS#11 token label
145 160
 Notes:
146 161
   Please edit the vars script to reflect your configuration,
147 162
   then source it with "source ./vars".
148 163
   Next, to start with a fresh PKI configuration and to delete any
149 164
   previous certificates and keys, run "./clean-all".
150 165
   Finally, you can run this tool (pkitool) to build certificates/keys.
166
+  In order to use PKCS#11 interface you must have opensc-0.10.0 or higher.
151 167
 Generated files and corresponding OpenVPN directives:
152 168
 (Files will be placed in the $KEY_DIR directory, defined in ./vars)
153 169
   ca.crt     -> root certificate (--ca)
... ...
@@ -162,11 +199,13 @@ Examples:
162 162
   pkitool --server server1  -> Build "server1" certificate/key
163 163
   pkitool client1           -> Build "client1" certificate/key
164 164
   pkitool --pass client2    -> Build password-protected "client2" certificate/key
165
-  pkitool --pkcs12 client3  -> Build "client3" certificate/key in PKCS #12 format
165
+  pkitool --pkcs12 client3  -> Build "client3" certificate/key in PKCS#12 format
166 166
   pkitool --csr client4     -> Build "client4" CSR to be signed by another CA
167 167
   pkitool --sign client4    -> Sign "client4" CSR
168 168
   pkitool --inter interca   -> Build an intermediate key-signing certificate/key
169 169
                                Also see ./inherit-inter script.
170
+  pkitool --pkcs11 /usr/lib/pkcs11/lib1 0 010203 "client5 id" client5
171
+                              -> Build "client5" certificate/key in PKCS#11 token
170 172
 Typical usage for initial PKI setup.  Build myserver, client1, and client2 cert/keys.
171 173
 Protect client2 key with a password.  Build DH parms.  Generated files in ./keys :
172 174
   [edit vars with your site-specific info]
... ...
@@ -4,7 +4,7 @@
4 4
 # of an SSL/TLS connection.
5 5
 
6 6
 if [ -d $KEY_DIR ] && [ $KEY_SIZE ]; then
7
-    openssl dhparam -out ${KEY_DIR}/dh${KEY_SIZE}.pem ${KEY_SIZE}
7
+    $OPENSSL dhparam -out ${KEY_DIR}/dh${KEY_SIZE}.pem ${KEY_SIZE}
8 8
 else
9 9
     echo 'Please source the vars script first (i.e. "source ./vars")'
10 10
     echo 'Make sure you have edited it to reflect your configuration.'
... ...
@@ -6,7 +6,7 @@ CRL="${1:-crl.pem}"
6 6
 
7 7
 if [ "$KEY_DIR" ]; then
8 8
     cd "$KEY_DIR" && \
9
-	openssl crl -text -noout -in "$CRL"
9
+	$OPENSSL crl -text -noout -in "$CRL"
10 10
 else
11 11
     echo 'Please source the vars script first (i.e. "source ./vars")'
12 12
     echo 'Make sure you have edited it to reflect your configuration.'
13 13
new file mode 100755
... ...
@@ -0,0 +1,265 @@
0
+# For use with easy-rsa version 2.0
1
+
2
+#
3
+# OpenSSL example configuration file.
4
+# This is mostly being used for generation of certificate requests.
5
+#
6
+
7
+# This definition stops the following lines choking if HOME isn't
8
+# defined.
9
+HOME			= .
10
+RANDFILE		= $ENV::HOME/.rnd
11
+
12
+# Extra OBJECT IDENTIFIER info:
13
+#oid_file		= $ENV::HOME/.oid
14
+oid_section		= new_oids
15
+
16
+# To use this configuration file with the "-extfile" option of the
17
+# "openssl x509" utility, name here the section containing the
18
+# X.509v3 extensions to use:
19
+# extensions		= 
20
+# (Alternatively, use a configuration file that has only
21
+# X.509v3 extensions in its main [= default] section.)
22
+
23
+[ new_oids ]
24
+
25
+# We can add new OIDs in here for use by 'ca' and 'req'.
26
+# Add a simple OID like this:
27
+# testoid1=1.2.3.4
28
+# Or use config file substitution like this:
29
+# testoid2=${testoid1}.5.6
30
+
31
+####################################################################
32
+[ ca ]
33
+default_ca	= CA_default		# The default ca section
34
+
35
+####################################################################
36
+[ CA_default ]
37
+
38
+dir		= $ENV::KEY_DIR		# Where everything is kept
39
+certs		= $dir			# Where the issued certs are kept
40
+crl_dir		= $dir			# Where the issued crl are kept
41
+database	= $dir/index.txt	# database index file.
42
+new_certs_dir	= $dir			# default place for new certs.
43
+
44
+certificate	= $dir/ca.crt	 	# The CA certificate
45
+serial		= $dir/serial 		# The current serial number
46
+crl		= $dir/crl.pem 		# The current CRL
47
+private_key	= $dir/ca.key	 	# The private key
48
+RANDFILE	= $dir/.rand		# private random number file
49
+
50
+x509_extensions	= usr_cert		# The extentions to add to the cert
51
+
52
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
53
+# so this is commented out by default to leave a V1 CRL.
54
+# crl_extensions	= crl_ext
55
+
56
+default_days	= 3650			# how long to certify for
57
+default_crl_days= 30			# how long before next CRL
58
+default_md	= md5			# which md to use.
59
+preserve	= no			# keep passed DN ordering
60
+
61
+# A few difference way of specifying how similar the request should look
62
+# For type CA, the listed attributes must be the same, and the optional
63
+# and supplied fields are just that :-)
64
+policy		= policy_anything
65
+
66
+# For the CA policy
67
+[ policy_match ]
68
+countryName		= match
69
+stateOrProvinceName	= match
70
+organizationName	= match
71
+organizationalUnitName	= optional
72
+commonName		= supplied
73
+emailAddress		= optional
74
+
75
+# For the 'anything' policy
76
+# At this point in time, you must list all acceptable 'object'
77
+# types.
78
+[ policy_anything ]
79
+countryName		= optional
80
+stateOrProvinceName	= optional
81
+localityName		= optional
82
+organizationName	= optional
83
+organizationalUnitName	= optional
84
+commonName		= supplied
85
+emailAddress		= optional
86
+
87
+####################################################################
88
+[ req ]
89
+default_bits		= $ENV::KEY_SIZE
90
+default_keyfile 	= privkey.pem
91
+distinguished_name	= req_distinguished_name
92
+attributes		= req_attributes
93
+x509_extensions	= v3_ca	# The extentions to add to the self signed cert
94
+
95
+# Passwords for private keys if not present they will be prompted for
96
+# input_password = secret
97
+# output_password = secret
98
+
99
+# This sets a mask for permitted string types. There are several options. 
100
+# default: PrintableString, T61String, BMPString.
101
+# pkix	 : PrintableString, BMPString.
102
+# utf8only: only UTF8Strings.
103
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
104
+# MASK:XXXX a literal mask value.
105
+# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
106
+# so use this option with caution!
107
+string_mask = nombstr
108
+
109
+# req_extensions = v3_req # The extensions to add to a certificate request
110
+
111
+[ req_distinguished_name ]
112
+countryName			= Country Name (2 letter code)
113
+countryName_default		= $ENV::KEY_COUNTRY
114
+countryName_min			= 2
115
+countryName_max			= 2
116
+
117
+stateOrProvinceName		= State or Province Name (full name)
118
+stateOrProvinceName_default	= $ENV::KEY_PROVINCE
119
+
120
+localityName			= Locality Name (eg, city)
121
+localityName_default		= $ENV::KEY_CITY
122
+
123
+0.organizationName		= Organization Name (eg, company)
124
+0.organizationName_default	= $ENV::KEY_ORG
125
+
126
+# we can do this but it is not needed normally :-)
127
+#1.organizationName		= Second Organization Name (eg, company)
128
+#1.organizationName_default	= World Wide Web Pty Ltd
129
+
130
+organizationalUnitName		= Organizational Unit Name (eg, section)
131
+#organizationalUnitName_default	=
132
+
133
+commonName			= Common Name (eg, your name or your server\'s hostname)
134
+commonName_max			= 64
135
+
136
+emailAddress			= Email Address
137
+emailAddress_default		= $ENV::KEY_EMAIL
138
+emailAddress_max		= 40
139
+
140
+# JY -- added for batch mode
141
+organizationalUnitName_default = $ENV::KEY_OU
142
+commonName_default = $ENV::KEY_CN
143
+
144
+# SET-ex3			= SET extension number 3
145
+
146
+[ req_attributes ]
147
+challengePassword		= A challenge password
148
+challengePassword_min		= 4
149
+challengePassword_max		= 20
150
+
151
+unstructuredName		= An optional company name
152
+
153
+[ usr_cert ]
154
+
155
+# These extensions are added when 'ca' signs a request.
156
+
157
+# This goes against PKIX guidelines but some CAs do it and some software
158
+# requires this to avoid interpreting an end user certificate as a CA.
159
+
160
+basicConstraints=CA:FALSE
161
+
162
+# Here are some examples of the usage of nsCertType. If it is omitted
163
+# the certificate can be used for anything *except* object signing.
164
+
165
+# This is OK for an SSL server.
166
+# nsCertType			= server
167
+
168
+# For an object signing certificate this would be used.
169
+# nsCertType = objsign
170
+
171
+# For normal client use this is typical
172
+# nsCertType = client, email
173
+
174
+# and for everything including object signing:
175
+# nsCertType = client, email, objsign
176
+
177
+# This is typical in keyUsage for a client certificate.
178
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
179
+
180
+# This will be displayed in Netscape's comment listbox.
181
+nsComment			= "Easy-RSA Generated Certificate"
182
+
183
+# PKIX recommendations harmless if included in all certificates.
184
+subjectKeyIdentifier=hash
185
+authorityKeyIdentifier=keyid,issuer:always
186
+extendedKeyUsage=clientAuth
187
+keyUsage = digitalSignature
188
+
189
+# This stuff is for subjectAltName and issuerAltname.
190
+# Import the email address.
191
+# subjectAltName=email:copy
192
+
193
+# Copy subject details
194
+# issuerAltName=issuer:copy
195
+
196
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
197
+#nsBaseUrl
198
+#nsRevocationUrl
199
+#nsRenewalUrl
200
+#nsCaPolicyUrl
201
+#nsSslServerName
202
+
203
+[ server ]
204
+
205
+# JY ADDED -- Make a cert with nsCertType set to "server"
206
+basicConstraints=CA:FALSE
207
+nsCertType			= server
208
+nsComment			= "Easy-RSA Generated Server Certificate"
209
+subjectKeyIdentifier=hash
210
+authorityKeyIdentifier=keyid,issuer:always
211
+extendedKeyUsage=serverAuth
212
+keyUsage = digitalSignature, keyEncipherment
213
+
214
+[ v3_req ]
215
+
216
+# Extensions to add to a certificate request
217
+
218
+basicConstraints = CA:FALSE
219
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
220
+
221
+[ v3_ca ]
222
+
223
+
224
+# Extensions for a typical CA
225
+
226
+
227
+# PKIX recommendation.
228
+
229
+subjectKeyIdentifier=hash
230
+
231
+authorityKeyIdentifier=keyid:always,issuer:always
232
+
233
+# This is what PKIX recommends but some broken software chokes on critical
234
+# extensions.
235
+#basicConstraints = critical,CA:true
236
+# So we do this instead.
237
+basicConstraints = CA:true
238
+
239
+# Key usage: this is typical for a CA certificate. However since it will
240
+# prevent it being used as an test self-signed certificate it is best
241
+# left out by default.
242
+# keyUsage = cRLSign, keyCertSign
243
+
244
+# Some might want this also
245
+# nsCertType = sslCA, emailCA
246
+
247
+# Include email address in subject alt name: another PKIX recommendation
248
+# subjectAltName=email:copy
249
+# Copy issuer details
250
+# issuerAltName=issuer:copy
251
+
252
+# DER hex encoding of an extension: beware experts only!
253
+# obj=DER:02:03
254
+# Where 'obj' is a standard or added object
255
+# You can even override a supported extension:
256
+# basicConstraints= critical, DER:30:03:01:01:FF
257
+
258
+[ crl_ext ]
259
+
260
+# CRL extensions.
261
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
262
+
263
+# issuerAltName=issuer:copy
264
+authorityKeyIdentifier=keyid:always,issuer:always
... ...
@@ -9,10 +9,13 @@
9 9
 # defined.
10 10
 HOME			= .
11 11
 RANDFILE		= $ENV::HOME/.rnd
12
+openssl_conf		= openssl_init
12 13
 
14
+[ openssl_init ]
13 15
 # Extra OBJECT IDENTIFIER info:
14 16
 #oid_file		= $ENV::HOME/.oid
15 17
 oid_section		= new_oids
18
+engines                 = engine_section
16 19
 
17 20
 # To use this configuration file with the "-extfile" option of the
18 21
 # "openssl x509" utility, name here the section containing the
... ...
@@ -179,11 +182,13 @@ basicConstraints=CA:FALSE
179 179
 # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
180 180
 
181 181
 # This will be displayed in Netscape's comment listbox.
182
-nsComment			= "OpenSSL Generated Certificate"
182
+nsComment			= "Easy-RSA Generated Certificate"
183 183
 
184 184
 # PKIX recommendations harmless if included in all certificates.
185 185
 subjectKeyIdentifier=hash
186 186
 authorityKeyIdentifier=keyid,issuer:always
187
+extendedKeyUsage=clientAuth
188
+keyUsage = digitalSignature
187 189
 
188 190
 # This stuff is for subjectAltName and issuerAltname.
189 191
 # Import the email address.
... ...
@@ -204,7 +209,7 @@ authorityKeyIdentifier=keyid,issuer:always
204 204
 # JY ADDED -- Make a cert with nsCertType set to "server"
205 205
 basicConstraints=CA:FALSE
206 206
 nsCertType			= server
207
-nsComment			= "OpenSSL Generated Server Certificate"
207
+nsComment			= "Easy-RSA Generated Server Certificate"
208 208
 subjectKeyIdentifier=hash
209 209
 authorityKeyIdentifier=keyid,issuer:always
210 210
 extendedKeyUsage=serverAuth
... ...
@@ -261,3 +266,20 @@ basicConstraints = CA:true
261 261
 
262 262
 # issuerAltName=issuer:copy
263 263
 authorityKeyIdentifier=keyid:always,issuer:always
264
+
265
+[ engine_section ]
266
+#
267
+# If you are using PKCS#11
268
+# Install engine_pkcs11 of opensc (www.opensc.org)
269
+# And uncomment the following
270
+# verify that dynamic_path points to the correct location
271
+#
272
+#pkcs11 = pkcs11_section
273
+
274
+[ pkcs11_section ]
275
+engine_id = pkcs11
276
+dynamic_path = /usr/lib/engines/engine_pkcs11.so
277
+MODULE_PATH = $ENV::PKCS11_MODULE_PATH
278
+PIN = $ENV::PKCS11_PIN
279
+init = 0
280
+
... ...
@@ -31,8 +31,13 @@ PROGNAME=pkitool
31 31
 VERSION=2.0
32 32
 DEBUG=0
33 33
 
34
-GREP=grep
35
-OPENSSL=openssl
34
+die()
35
+{
36
+    local m="$1"
37
+
38
+    echo "$m" >&2
39
+    exit 1
40
+}
36 41
 
37 42
 need_vars()
38 43
 {
... ...
@@ -49,6 +54,8 @@ usage()
49 49
     echo "Usage: $PROGNAME [options...] [common-name]"
50 50
     echo "Options:"
51 51
     echo "  --batch    : batch mode (default)"
52
+    echo "  --keysize  : Set keysize"
53
+    echo "      size   : size (default=1024)"
52 54
     echo "  --interact : interactive mode"
53 55
     echo "  --server   : build server cert"
54 56
     echo "  --initca   : build root CA"
... ...
@@ -56,9 +63,25 @@ usage()
56 56
     echo "  --pass     : encrypt private key with password"
57 57
     echo "  --csr      : only generate a CSR, do not sign"
58 58
     echo "  --sign     : sign an existing CSR"
59
-    echo "  --pkcs12   : generate a combined pkcs12 file"
59
+    echo "  --pkcs12   : generate a combined PKCS#12 file"
60
+    echo "  --pkcs11   : generate certificate on PKCS#11 token"
61
+    echo "      lib    : PKCS#11 library"
62
+    echo "      slot   : PKCS#11 slot"
63
+    echo "      id     : PKCS#11 object id (hex string)"
64
+    echo "      label  : PKCS#11 object label"
65
+    echo "Standalone options:"
66
+    echo "  --pkcs11-slots   : list PKCS#11 slots"
67
+    echo "      lib    : PKCS#11 library"
68
+    echo "  --pkcs11-objects : list PKCS#11 token objects"
69
+    echo "      lib    : PKCS#11 library"
70
+    echo "      slot   : PKCS#11 slot"
71
+    echo "  --pkcs11-init    : initialize PKCS#11 token DANGEROUS!!!"
72
+    echo "      lib    : PKCS#11 library"
73
+    echo "      slot   : PKCS#11 slot"
74
+    echo "      label  : PKCS#11 token label"
60 75
     echo "Notes:"
61 76
     need_vars
77
+    echo "  In order to use PKCS#11 interface you must have opensc-0.10.0 or higher."
62 78
     echo "Generated files and corresponding OpenVPN directives:"
63 79
     echo '(Files will be placed in the $KEY_DIR directory, defined in ./vars)'
64 80
     echo "  ca.crt     -> root certificate (--ca)"
... ...
@@ -73,11 +96,13 @@ usage()
73 73
     echo "  $PROGNAME --server server1  -> Build \"server1\" certificate/key"
74 74
     echo "  $PROGNAME client1           -> Build \"client1\" certificate/key"
75 75
     echo "  $PROGNAME --pass client2    -> Build password-protected \"client2\" certificate/key"
76
-    echo "  $PROGNAME --pkcs12 client3  -> Build \"client3\" certificate/key in PKCS #12 format"
76
+    echo "  $PROGNAME --pkcs12 client3  -> Build \"client3\" certificate/key in PKCS#12 format"
77 77
     echo "  $PROGNAME --csr client4     -> Build \"client4\" CSR to be signed by another CA"
78 78
     echo "  $PROGNAME --sign client4    -> Sign \"client4\" CSR"
79 79
     echo "  $PROGNAME --inter interca   -> Build an intermediate key-signing certificate/key"
80 80
     echo "                               Also see ./inherit-inter script."
81
+    echo "  $PROGNAME --pkcs11 /usr/lib/pkcs11/lib1 0 010203 \"client5 id\" client5"
82
+    echo "                              -> Build \"client5\" certificate/key in PKCS#11 token"
81 83
     echo "Typical usage for initial PKI setup.  Build myserver, client1, and client2 cert/keys."
82 84
     echo "Protect client2 key with a password.  Build DH parms.  Generated files in ./keys :"
83 85
     echo "  [edit vars with your site-specific info]"
... ...
@@ -99,15 +124,21 @@ REQ_EXT=""
99 99
 DO_CA="1"
100 100
 CA_EXT=""
101 101
 DO_P12="0"
102
+DO_P11="0"
102 103
 DO_ROOT="0"
103 104
 NODES_REQ="-nodes"
104 105
 NODES_P12=""
105 106
 BATCH="-batch"
106 107
 CA="ca"
108
+# must be set or errors of openssl.cnf
109
+PKCS11_MODULE_PATH="dummy"
110
+PKCS11_PIN="dummy"
107 111
 
108 112
 # Process options
109 113
 while [ $# -gt 0 ]; do
110 114
     case "$1" in
115
+        --keysize  ) KEY_SIZE=$2
116
+		     shift;;
111 117
 	--server   ) REQ_EXT="$REQ_EXT -extensions server"
112 118
 	             CA_EXT="$CA_EXT -extensions server" ;;
113 119
 	--batch    ) BATCH="-batch" ;;
... ...
@@ -118,19 +149,76 @@ while [ $# -gt 0 ]; do
118 118
         --csr      ) DO_CA="0" ;;
119 119
         --sign     ) DO_REQ="0" ;;
120 120
         --pkcs12   ) DO_P12="1" ;;
121
-	--*        ) echo "$PROGNAME: unknown option: $1"
122
-	             exit 1 ;;
121
+	--pkcs11   ) DO_P11="1"
122
+	             PKCS11_MODULE_PATH="$2"
123
+		     PKCS11_SLOT="$3"
124
+		     PKCS11_ID="$4"
125
+		     PKCS11_LABEL="$5"
126
+		     shift 4;;
127
+
128
+	# standalone
129
+	--pkcs11-init)
130
+	             PKCS11_MODULE_PATH="$2"
131
+	             PKCS11_SLOT="$3"
132
+	             PKCS11_LABEL="$4"
133
+		     if [ -z "$PKCS11_LABEL" ]; then
134
+		       die "Please specify library name, slot and label"
135
+		     fi
136
+		     $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --init-token --slot "$PKCS11_SLOT" \
137
+		     	--label "$PKCS11_LABEL" &&
138
+			$PKCS11TOOL --module "$PKCS11_MODULE_PATH" --init-pin --slot "$PKCS11_SLOT"
139
+		     exit $?;;
140
+	--pkcs11-slots)
141
+	             PKCS11_MODULE_PATH="$2"
142
+		     if [ -z "$PKCS11_MODULE_PATH" ]; then
143
+		       die "Please specify library name"
144
+		     fi
145
+		     $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --list-slots
146
+		     exit 0;;
147
+	--pkcs11-objects)
148
+	             PKCS11_MODULE_PATH="$2"
149
+	             PKCS11_SLOT="$3"
150
+		     if [ -z "$PKCS11_SLOT" ]; then
151
+		       die "Please specify library name and slot"
152
+		     fi
153
+		     $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --list-objects --login --slot "$PKCS11_SLOT"
154
+		     exit 0;;
155
+
156
+	# errors
157
+	--*        ) die "$PROGNAME: unknown option: $1" ;;
123 158
 	*          ) break ;;
124 159
     esac
125 160
     shift   
126 161
 done
127 162
 
163
+if ! [ -z "$BATCH" ]; then
164
+	if $OPENSSL version | grep 0.9.6 > /dev/null; then
165
+		die "Batch mode is unsupported in openssl<0.9.7"
166
+	fi
167
+fi
168
+
169
+if [ $DO_P12 -eq 1 -a $DO_P11 -eq 1 ]; then
170
+	die "PKCS#11 and PKCS#12 cannot be specified together"
171
+fi
172
+
173
+if [ $DO_P11 -eq 1 ]; then
174
+	if ! grep "^pkcs11.*=" "$KEY_CONFIG" > /dev/null; then
175
+		die "Please edit $KEY_CONFIG and setup PKCS#11 engine"
176
+	fi
177
+fi
178
+
128 179
 # If we are generating pkcs12, only encrypt the final step
129 180
 if [ $DO_P12 -eq 1 ]; then
130 181
     NODES_P12="$NODES_REQ"
131 182
     NODES_REQ="-nodes"
132 183
 fi
133 184
 
185
+if [ $DO_P11 -eq 1 ]; then
186
+	if [ -z "$PKCS11_LABEL" ]; then
187
+		die "PKCS#11 arguments incomplete"
188
+	fi
189
+fi
190
+
134 191
 # If undefined, set default key expiration intervals
135 192
 if [ -z "$KEY_EXPIRE" ]; then
136 193
     KEY_EXPIRE=3650
... ...
@@ -166,7 +254,8 @@ else
166 166
 	KEY_CN="$1"
167 167
     fi
168 168
 fi
169
-export CA_EXPIRE KEY_EXPIRE KEY_OU KEY_CN
169
+
170
+export CA_EXPIRE KEY_EXPIRE KEY_OU KEY_CN PKCS11_MODULE_PATH PKCS11_PIN
170 171
 
171 172
 # Show parameters (debugging)
172 173
 if [ $DEBUG -eq 1 ]; then
... ...
@@ -183,6 +272,11 @@ if [ $DEBUG -eq 1 ]; then
183 183
     echo KEY_EXPIRE $KEY_EXPIRE
184 184
     echo CA_EXPIRE $CA_EXPIRE
185 185
     echo KEY_OU $KEY_OU
186
+    echo DO_P11 $DO_P11
187
+    echo PKCS11_MODULE_PATH $PKCS11_MODULE_PATH
188
+    echo PKCS11_SLOT $PKCS11_SLOT
189
+    echo PKCS11_ID $PKCS11_ID
190
+    echo PKCS11_LABEL $PKCS11_LABEL
186 191
 fi
187 192
 
188 193
 # Make sure ./vars was sourced beforehand
... ...
@@ -202,8 +296,8 @@ if [ -d "$KEY_DIR" ] && [ "$KEY_CONFIG" ]; then
202 202
 
203 203
     # Build root CA
204 204
     if [ $DO_ROOT -eq 1 ]; then
205
-	$OPENSSL req $BATCH -days $CA_EXPIRE $NODES_REQ -new -x509 \
206
-	    -keyout "$CA.key" -out "$CA.crt" -config "$KEY_CONFIG" && \
205
+	$OPENSSL req $BATCH -days $CA_EXPIRE $NODES_REQ -new -newkey rsa:$KEY_SIZE -sha1 \
206
+	    -x509 -keyout "$CA.key" -out "$CA.crt" -config "$KEY_CONFIG" && \
207 207
 	    chmod 0600 "$CA.key"
208 208
     else        
209 209
         # Make sure CA key/cert is available
... ...
@@ -215,16 +309,42 @@ if [ -d "$KEY_DIR" ] && [ "$KEY_CONFIG" ]; then
215 215
 	    fi
216 216
 	fi
217 217
 
218
+	# Generate key for PKCS#11 token
219
+	PKCS11_ARGS=
220
+	if [ $DO_P11 -eq 1 ]; then
221
+	        stty -echo
222
+	        echo -n "User PIN: "
223
+	        read -r PKCS11_PIN
224
+	        stty echo
225
+		export PKCS11_PIN
226
+
227
+		echo "Generating key pair on PKCS#11 token..."
228
+		$PKCS11TOOL --module "$PKCS11_MODULE_PATH" --keypairgen \
229
+			--login --pin "$PKCS11_PIN" \
230
+			--key-type rsa:1024 \
231
+			--slot "$PKCS11_SLOT" --id "$PKCS11_ID" --label "$PKCS11_LABEL" || exit 1
232
+		PKCS11_ARGS="-engine pkcs11 -keyform engine -key $PKCS11_SLOT:$PKCS11_ID"
233
+	fi
234
+
218 235
         # Build cert/key
219
-	( [ $DO_REQ -eq 0 ] || $OPENSSL req $BATCH -days $KEY_EXPIRE $NODES_REQ -new \
220
-	        -keyout "$KEY_CN.key" -out "$KEY_CN.csr" $REQ_EXT -config "$KEY_CONFIG" ) && \
236
+	( [ $DO_REQ -eq 0 ] || $OPENSSL req $BATCH -days $KEY_EXPIRE $NODES_REQ -new -newkey rsa:$KEY_SIZE \
237
+	        -keyout "$KEY_CN.key" -out "$KEY_CN.csr" $REQ_EXT -config "$KEY_CONFIG" $PKCS11_ARGS ) && \
221 238
 	    ( [ $DO_CA -eq 0 ]  || $OPENSSL ca $BATCH -days $KEY_EXPIRE -out "$KEY_CN.crt" \
222
-	        -in "$KEY_CN.csr" $CA_EXT -config "$KEY_CONFIG" ) && \
239
+	        -in "$KEY_CN.csr" $CA_EXT -md sha1 -config "$KEY_CONFIG" ) && \
223 240
 	    ( [ $DO_P12 -eq 0 ] || $OPENSSL pkcs12 -export -inkey "$KEY_CN.key" \
224 241
 	        -in "$KEY_CN.crt" -certfile "$CA.crt" -out "$KEY_CN.p12" $NODES_P12 ) && \
225
-	    ( [ $DO_CA -eq 0 ]  || chmod 0600 "$KEY_CN.key" ) && \
242
+	    ( [ $DO_CA -eq 0 -o $DO_P11 -eq 1 ]  || chmod 0600 "$KEY_CN.key" ) && \
226 243
 	    ( [ $DO_P12 -eq 0 ] || chmod 0600 "$KEY_CN.p12" )
227 244
 
245
+	# Load certificate into PKCS#11 token
246
+	if [ $DO_P11 -eq 1 ]; then
247
+		$OPENSSL x509 -in "$KEY_CN.crt" -inform PEM -out "$KEY_CN.crt.der" -outform DER && \
248
+		  $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --write-object "$KEY_CN.crt.der" --type cert \
249
+			--login --pin "$PKCS11_PIN" \
250
+			--slot "$PKCS11_SLOT" --id "$PKCS11_ID" --label "$PKCS11_LABEL" 
251
+		[ -e "$KEY_CN.crt.der" ]; rm "$KEY_CN.crt.der"
252
+	fi
253
+
228 254
     fi
229 255
 
230 256
 # Need definitions
... ...
@@ -20,11 +20,11 @@ if [ "$KEY_DIR" ]; then
20 20
     export KEY_OU=""
21 21
 
22 22
     # revoke key and generate a new CRL
23
-    openssl ca -revoke "$1.crt" -config "$KEY_CONFIG"
23
+    $OPENSSL ca -revoke "$1.crt" -config "$KEY_CONFIG"
24 24
 
25 25
     # generate a new CRL -- try to be compatible with
26 26
     # intermediate PKIs
27
-    openssl ca -gencrl -out "$CRL" -config "$KEY_CONFIG"
27
+    $OPENSSL ca -gencrl -out "$CRL" -config "$KEY_CONFIG"
28 28
     if [ -e export-ca.crt ]; then
29 29
 	cat export-ca.crt "$CRL" >"$RT"
30 30
     else
... ...
@@ -32,7 +32,7 @@ if [ "$KEY_DIR" ]; then
32 32
     fi
33 33
     
34 34
     # verify the revocation
35
-    openssl verify -CAfile "$RT" -crl_check "$1.crt"
35
+    $OPENSSL verify -CAfile "$RT" -crl_check "$1.crt"
36 36
 else
37 37
     echo 'Please source the vars script first (i.e. "source ./vars")'
38 38
     echo 'Make sure you have edited it to reflect your configuration.'
... ...
@@ -14,10 +14,19 @@
14 14
 # tree.
15 15
 export EASY_RSA="`pwd`"
16 16
 
17
+#
18
+# This variable should point to
19
+# the requested executables
20
+#
21
+export OPENSSL="openssl"
22
+export PKCS11TOOL="pkcs11-tool"
23
+export GREP="grep"
24
+
25
+
17 26
 # This variable should point to
18 27
 # the openssl.cnf file included
19 28
 # with easy-rsa.
20
-export KEY_CONFIG="$EASY_RSA/openssl.cnf"
29
+export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA`
21 30
 
22 31
 # Edit this variable to point to
23 32
 # your soon-to-be-created key
24 33
new file mode 100755
... ...
@@ -0,0 +1,13 @@
0
+#!/bin/sh
1
+
2
+if [ "$OPENSSL" ]; then
3
+	if $OPENSSL version | grep 0.9.6 > /dev/null; then
4
+		echo "$1/openssl-0.9.6.cnf"
5
+	else
6
+		echo "$1/openssl.cnf"
7
+	fi
8
+else
9
+	echo "$1/openssl.cnf"
10
+fi
11
+
12
+exit 0