certificate_authority 0.1.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +11 -0
  5. data/Gemfile +2 -8
  6. data/Gemfile.lock +71 -27
  7. data/README.rdoc +184 -89
  8. data/Rakefile +6 -41
  9. data/certificate_authority.gemspec +22 -81
  10. data/lib/certificate_authority.rb +7 -6
  11. data/lib/certificate_authority/certificate.rb +151 -71
  12. data/lib/certificate_authority/certificate_revocation_list.rb +46 -26
  13. data/lib/certificate_authority/core_extensions.rb +46 -0
  14. data/lib/certificate_authority/distinguished_name.rb +84 -17
  15. data/lib/certificate_authority/extensions.rb +483 -96
  16. data/lib/certificate_authority/key_material.rb +75 -21
  17. data/lib/certificate_authority/ocsp_handler.rb +99 -29
  18. data/lib/certificate_authority/pkcs11_key_material.rb +13 -15
  19. data/lib/certificate_authority/revocable.rb +14 -0
  20. data/lib/certificate_authority/serial_number.rb +18 -5
  21. data/lib/certificate_authority/signing_entity.rb +5 -7
  22. data/lib/certificate_authority/signing_request.rb +91 -0
  23. data/lib/certificate_authority/validations.rb +31 -0
  24. data/lib/certificate_authority/version.rb +3 -0
  25. metadata +96 -94
  26. data/VERSION.yml +0 -5
  27. data/spec/spec_helper.rb +0 -4
  28. data/spec/units/certificate_authority_spec.rb +0 -4
  29. data/spec/units/certificate_revocation_list_spec.rb +0 -68
  30. data/spec/units/certificate_spec.rb +0 -351
  31. data/spec/units/distinguished_name_spec.rb +0 -38
  32. data/spec/units/extensions_spec.rb +0 -53
  33. data/spec/units/key_material_spec.rb +0 -96
  34. data/spec/units/ocsp_handler_spec.rb +0 -104
  35. data/spec/units/serial_number_spec.rb +0 -20
  36. data/spec/units/signing_entity_spec.rb +0 -4
  37. data/spec/units/units_helper.rb +0 -1
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e413d44d788e07a95a90b5849298f41796dbd57dce8fe08a0713191ae812798c
4
+ data.tar.gz: '059b6bee928fdcc1cebd04c6dff6890f7179d66094d6af17c549db7ef1811e56'
5
+ SHA512:
6
+ metadata.gz: 718978b7b52352cee16da1e555a0b0e71d0c68543bc627ef94869b45ff43dd259ce49a19b194105f96700848535a5397e039e86fd8733de899e5b61865eac2a8
7
+ data.tar.gz: b5998a5cfe29679198f4d57995e3f3e03f0694cc238e5fbc6f75a3a65b2ab80bfe3f86caac09616cb27f64832c0b83cddd87f3aaaa8e642e817429e3ecad0b7d
@@ -0,0 +1,6 @@
1
+ pkg
2
+ development
3
+ .bundle
4
+ .rvmrc
5
+ coverage
6
+ doc
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --require spec_helper
2
+ --color
3
+ --format documentation
@@ -0,0 +1,11 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.5
7
+ - 2.6
8
+ - 2.7
9
+ before_install: gem install bundler
10
+ script:
11
+ - bundle exec rake
data/Gemfile CHANGED
@@ -1,9 +1,3 @@
1
- source 'http://rubygems.org'
1
+ source 'https://rubygems.org'
2
2
 
3
- gem 'activemodel', "~> 3.0.6"
4
-
5
- group :development do
6
- gem 'rspec'
7
- gem "jeweler", "~> 1.5.2"
8
- gem "rcov", ">= 0"
9
- end
3
+ gemspec
@@ -1,35 +1,79 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ certificate_authority (1.0.0)
5
+
1
6
  GEM
2
- remote: http://rubygems.org/
7
+ remote: https://rubygems.org/
3
8
  specs:
4
- activemodel (3.0.6)
5
- activesupport (= 3.0.6)
6
- builder (~> 2.1.2)
7
- i18n (~> 0.5.0)
8
- activesupport (3.0.6)
9
- builder (2.1.2)
10
- diff-lcs (1.1.2)
11
- git (1.2.5)
12
- i18n (0.5.0)
13
- jeweler (1.5.2)
14
- bundler (~> 1.0.0)
15
- git (>= 1.2.5)
16
- rake
17
- rake (0.8.7)
18
- rcov (0.9.9)
19
- rspec (2.5.0)
20
- rspec-core (~> 2.5.0)
21
- rspec-expectations (~> 2.5.0)
22
- rspec-mocks (~> 2.5.0)
23
- rspec-core (2.5.1)
24
- rspec-expectations (2.5.0)
25
- diff-lcs (~> 1.1.2)
26
- rspec-mocks (2.5.0)
9
+ ast (2.4.0)
10
+ coderay (1.1.2)
11
+ coveralls (0.8.23)
12
+ json (>= 1.8, < 3)
13
+ simplecov (~> 0.16.1)
14
+ term-ansicolor (~> 1.3)
15
+ thor (>= 0.19.4, < 2.0)
16
+ tins (~> 1.6)
17
+ diff-lcs (1.3)
18
+ docile (1.3.2)
19
+ json (2.3.0)
20
+ method_source (1.0.0)
21
+ parallel (1.19.1)
22
+ parser (2.7.1.3)
23
+ ast (~> 2.4.0)
24
+ pry (0.13.1)
25
+ coderay (~> 1.1)
26
+ method_source (~> 1.0)
27
+ rainbow (3.0.0)
28
+ rake (13.0.1)
29
+ rexml (3.2.4)
30
+ rspec (3.9.0)
31
+ rspec-core (~> 3.9.0)
32
+ rspec-expectations (~> 3.9.0)
33
+ rspec-mocks (~> 3.9.0)
34
+ rspec-core (3.9.2)
35
+ rspec-support (~> 3.9.3)
36
+ rspec-expectations (3.9.2)
37
+ diff-lcs (>= 1.2.0, < 2.0)
38
+ rspec-support (~> 3.9.0)
39
+ rspec-mocks (3.9.1)
40
+ diff-lcs (>= 1.2.0, < 2.0)
41
+ rspec-support (~> 3.9.0)
42
+ rspec-support (3.9.3)
43
+ rubocop (0.84.0)
44
+ parallel (~> 1.10)
45
+ parser (>= 2.7.0.1)
46
+ rainbow (>= 2.2.2, < 4.0)
47
+ rexml
48
+ rubocop-ast (>= 0.0.3)
49
+ ruby-progressbar (~> 1.7)
50
+ unicode-display_width (>= 1.4.0, < 2.0)
51
+ rubocop-ast (0.0.3)
52
+ parser (>= 2.7.0.1)
53
+ ruby-progressbar (1.10.1)
54
+ simplecov (0.16.1)
55
+ docile (~> 1.1)
56
+ json (>= 1.8, < 3)
57
+ simplecov-html (~> 0.10.0)
58
+ simplecov-html (0.10.2)
59
+ sync (0.5.0)
60
+ term-ansicolor (1.7.1)
61
+ tins (~> 1.0)
62
+ thor (1.0.1)
63
+ tins (1.25.0)
64
+ sync
65
+ unicode-display_width (1.7.0)
27
66
 
28
67
  PLATFORMS
29
68
  ruby
30
69
 
31
70
  DEPENDENCIES
32
- activemodel (~> 3.0.6)
33
- jeweler (~> 1.5.2)
34
- rcov
71
+ certificate_authority!
72
+ coveralls
73
+ pry
74
+ rake
35
75
  rspec
76
+ rubocop
77
+
78
+ BUNDLED WITH
79
+ 2.1.4
@@ -1,5 +1,9 @@
1
1
  = CertificateAuthority - Because it shouldn't be this damned complicated
2
2
 
3
+ {<img src="https://travis-ci.org/cchandler/certificate_authority.png?branch=master" alt="Build Status" />}[https://travis-ci.org/cchandler/certificate_authority]
4
+ {<img src="https://codeclimate.com/github/cchandler/certificate_authority.png" alt="Code Climate" />}[https://codeclimate.com/github/cchandler/certificate_authority]
5
+ {<img src="https://coveralls.io/repos/cchandler/certificate_authority/badge.png?branch=master" alt="Code Coverage" />}[https://coveralls.io/r/cchandler/certificate_authority]
6
+
3
7
  This is meant to provide a (more) programmer-friendly implementation of all the basic functionality contained in RFC-3280 to implement your own certificate authority.
4
8
 
5
9
  You can generate root certificates, intermediate certificates, and terminal certificates. You can also generate/manage Certificate Revocation Lists (CRLs) and Online Certificate Status Protocol (OCSP) messages.
@@ -24,14 +28,15 @@ Let's look at a complete example for generating a new root certificate. Assuming
24
28
 
25
29
  Generating a self-signed root certificate is fairly easy:
26
30
 
27
- require 'certificate_authority'
28
- root = CertificateAuthority::Certificate.new
29
- root.subject.common_name= "http://mydomain.com"
30
- root.serial_number.number=1
31
- root.key_material.generate_key
32
- root.signing_entity = true
33
- root.sign!
34
-
31
+ require 'certificate_authority'
32
+ root = CertificateAuthority::Certificate.new
33
+ root.subject.common_name= "http://mydomain.com"
34
+ root.serial_number.number=1
35
+ root.key_material.generate_key
36
+ root.signing_entity = true
37
+ signing_profile = {"extensions" => {"keyUsage" => {"usage" => ["critical", "keyCertSign"] }} }
38
+ root.sign!(signing_profile)
39
+
35
40
  The required elements for the gem at this time are a common name for the subject and a serial number for the certificate. Since this is our self-signed root we're going to give it the first serial available of 1. Because certificate_authority is not designed to manage the issuance lifecycle you'll be expected to store serial numbers yourself.
36
41
 
37
42
  Next, after taking care of required fields, we will require key material for the new certificate. There's a convenience method made available on the key_material object for generating new keys. The private key will be available in:
@@ -48,29 +53,30 @@ Lastly, we declare that the certificate we're about to sign is itself a signing
48
53
 
49
54
  == Creating a new intermediate
50
55
 
51
- Maybe you don't want to actually sign certificates with your super-secret root certificate. This is actually how a good number of most public certificate authorities do it. Rather than sign with the primary root, they generate an intermediate root that is then responsible for signing the final certificates. If you wanted to create a root certificate you would do something like the following:
56
+ Maybe you don't want to actually sign certificates with your super-secret root certificate. This is actually how a good number of most public certificate authorities do it. Rather than sign with the primary root, they generate an intermediate root that is then responsible for signing the final certificates. If you wanted to create an intermediate root certificate you would do something like the following:
57
+
58
+ intermediate = CertificateAuthority::Certificate.new
59
+ intermediate.subject.common_name= "My snazzy intermediate!"
60
+ intermediate.serial_number.number=2
61
+ intermediate.key_material.generate_key
62
+ intermediate.signing_entity = true
63
+ intermediate.parent = root
64
+ signing_profile = {"extensions" => {"keyUsage" => {"usage" => ["critical", "keyCertSign"] }} }
65
+ intermediate.sign!(signing_profile)
52
66
 
53
- intermediate = CertificateAuthority::Certificate.new
54
- intermediate.subject.common_name= "My snazzy intermediate!"
55
- intermediate.serial_number.number=2
56
- intermediate.key_material.generate_key
57
- intermediate.signing_entity = true
58
- intermediate.parent = root
59
- intermediate.sign!
60
-
61
- All we have to do is create another certificate like we did with the root. In this example we gave it the next available serial number which for us, was 2. We then generate (and save!) key material for this new entity. Even the +signing_entity+ is set to true so this certificate can sign other certificates. The difference here is that the +parent+ field is set to the root. Going forward, whatever entity you want to sign a certificate, you set that entity to be the parent. In this case, our root will be responsible for signing this intermediate when we call +sign!+.
67
+ All we have to do is create another certificate like we did with the root. In this example we gave it the next available serial number, which for us, was 2. We then generate (and save!) key material for this new entity. Even the +signing_entity+ is set to true so this certificate can sign other certificates. The difference here is that the +parent+ field is set to the root. Going forward, whatever entity you want to sign a certificate, you set that entity to be the parent. In this case, our root will be responsible for signing this intermediate when we call +sign!+.
62
68
 
63
69
  = Creating new certificates (in general)
64
70
 
65
71
  Now that we have a root certificate (and possibly an intermediate) we can sign end-user certificates. It is, perhaps unsurprisingly, similar to all the others:
66
72
 
67
- plain_cert = CertificateAuthority::Certificate.new
68
- plain_cert.subject.common_name= "http://mydomain.com"
69
- plain_cert.serial_number.number=4
70
- plain_cert.key_material.generate_key
71
- plain_cert.parent = root # or intermediate
72
- plain_cert.sign!
73
-
73
+ plain_cert = CertificateAuthority::Certificate.new
74
+ plain_cert.subject.common_name= "http://mydomain.com"
75
+ plain_cert.serial_number.number=4
76
+ plain_cert.key_material.generate_key
77
+ plain_cert.parent = root # or intermediate
78
+ plain_cert.sign!
79
+
74
80
  That's all there is to it! In this example we generate the key material ourselves, but it's possible for the end-user to generate certificate signing request (CSR) that we can then parse and consume automatically (coming soon). To get the PEM formatted certificate for the user you would need to call:
75
81
 
76
82
  plain_cert.to_pem
@@ -83,27 +89,27 @@ Creating basic certificates is all well and good, but maybe you want _more_ sign
83
89
 
84
90
  Here's an example of a full signing profile for most of the common V3 extensions:
85
91
 
86
- signing_profile = {
87
- "extensions" => {
88
- "basicConstraints" => {"ca" => false},
89
- "crlDistributionPoints" => {"uri" => "http://notme.com/other.crl" },
90
- "subjectKeyIdentifier" => {},
91
- "authorityKeyIdentifier" => {},
92
- "authorityInfoAccess" => {"ocsp" => ["http://youFillThisOut/ocsp/"] },
93
- "keyUsage" => {"usage" => ["digitalSignature","nonRepudiation"] },
94
- "extendedKeyUsage" => {"usage" => [ "serverAuth","clientAuth"]},
95
- "subjectAltName" => {"uris" => ["http://subdomains.youFillThisOut/"]},
96
- "certificatePolicies" => {
97
- "policy_identifier" => "1.3.5.8", "cps_uris" => ["http://my.host.name/", "http://my.your.name/"],
98
- "user_notice" => {
99
- "explicit_text" => "Explicit Text Here",
100
- "organization" => "Organization name",
101
- "notice_numbers" => "1,2,3,4"
102
- }
103
- }
104
- }
105
- }
106
-
92
+ signing_profile = {
93
+ "extensions" => {
94
+ "basicConstraints" => {"ca" => false},
95
+ "crlDistributionPoints" => {"uri" => "http://notme.com/other.crl" },
96
+ "subjectKeyIdentifier" => {},
97
+ "authorityKeyIdentifier" => {},
98
+ "authorityInfoAccess" => {"ocsp" => ["http://youFillThisOut/ocsp/"] },
99
+ "keyUsage" => {"usage" => ["digitalSignature","nonRepudiation"] },
100
+ "extendedKeyUsage" => {"usage" => [ "serverAuth","clientAuth"]},
101
+ "subjectAltName" => {"uris" => ["http://subdomains.youFillThisOut/"]},
102
+ "certificatePolicies" => {
103
+ "policy_identifier" => "1.3.5.8", "cps_uris" => ["http://my.host.name/", "http://my.your.name/"],
104
+ "user_notice" => {
105
+ "explicit_text" => "Explicit Text Here",
106
+ "organization" => "Organization name",
107
+ "notice_numbers" => "1,2,3,4"
108
+ }
109
+ }
110
+ }
111
+ }
112
+
107
113
  Using a signing profile is done this way:
108
114
 
109
115
  certificate.sign!(signing_profile)
@@ -128,33 +134,33 @@ This extension controls where a conformant client can go to obtain a list of cer
128
134
 
129
135
  This extension is required to be present, but doesn't offer any configurable parameters. Directly from the RFC:
130
136
 
131
- The subject key identifier extension provides a means of identifying
132
- certificates that contain a particular public key.
133
-
134
- To facilitate certification path construction, this extension MUST
135
- appear in all conforming CA certificates, that is, all certificates
136
- including the basic constraints extension (section 4.2.1.10) where
137
- the value of cA is TRUE. The value of the subject key identifier
138
- MUST be the value placed in the key identifier field of the Authority
139
- Key Identifier extension (section 4.2.1.1) of certificates issued by
140
- the subject of this certificate.
141
-
137
+ The subject key identifier extension provides a means of identifying
138
+ certificates that contain a particular public key.
139
+
140
+ To facilitate certification path construction, this extension MUST
141
+ appear in all conforming CA certificates, that is, all certificates
142
+ including the basic constraints extension (section 4.2.1.10) where
143
+ the value of cA is TRUE. The value of the subject key identifier
144
+ MUST be the value placed in the key identifier field of the Authority
145
+ Key Identifier extension (section 4.2.1.1) of certificates issued by
146
+ the subject of this certificate.
147
+
142
148
  == Authority Key Identifier
143
149
 
144
150
  Just like the subject key identifier, this is required under most circumstances and doesn't contain any meaningful configuration options. From the RFC:
145
151
 
146
- The keyIdentifier field of the authorityKeyIdentifier extension MUST
147
- be included in all certificates generated by conforming CAs to
148
- facilitate certification path construction. There is one exception;
149
- where a CA distributes its public key in the form of a "self-signed"
150
- certificate, the authority key identifier MAY be omitted. The
151
- signature on a self-signed certificate is generated with the private
152
- key associated with the certificate's subject public key. (This
153
- proves that the issuer possesses both the public and private keys.)
154
- In this case, the subject and authority key identifiers would be
155
- identical, but only the subject key identifier is needed for
156
- certification path building.
157
-
152
+ The keyIdentifier field of the authorityKeyIdentifier extension MUST
153
+ be included in all certificates generated by conforming CAs to
154
+ facilitate certification path construction. There is one exception;
155
+ where a CA distributes its public key in the form of a "self-signed"
156
+ certificate, the authority key identifier MAY be omitted. The
157
+ signature on a self-signed certificate is generated with the private
158
+ key associated with the certificate's subject public key. (This
159
+ proves that the issuer possesses both the public and private keys.)
160
+ In this case, the subject and authority key identifiers would be
161
+ identical, but only the subject key identifier is needed for
162
+ certification path building.
163
+
158
164
  == Authority Info Access
159
165
 
160
166
  The authority info access extension allows a CA to sign a certificate with information a client can use to get up-to-the-minute status information on a signed certificate. This takes the form of an OCSP[link:http://en.wikipedia.org/wiki/Online_Certificate_Status_Protocol] (Online Certificate Status Protocol) endpoints.
@@ -191,27 +197,99 @@ These CPSs define what vetting criteria and maintenance practices are required t
191
197
 
192
198
  [user_notice] This is a nested field containing explicit human readable text if you want to embed a notice in the certificate body related to certification practices. It contains nested attributes of +explicit_text+ for the notice, +organization+ and +notice_numbers+. Refer to the RFC for specific implications of how these are set, but whether or not browsers implement the correct specified behavior for their presence is another issue.
193
199
 
200
+ = Certificate Signing Requests (CSRs)
201
+
202
+ If you want certificate requestors to be able to request certificates without moving the private key you'll need to generate a CSR and submit it to the certificate authority.
203
+
204
+ Here's an example of using +certificate_authority+ to generate a CSR.
205
+
206
+ csr = CertificateAuthority::SigningRequest.new
207
+ dn = CertificateAuthority::DistinguishedName.new
208
+ dn.common_name = "localhost"
209
+ csr.distinguished_name = dn
210
+ k = CertificateAuthority::MemoryKeyMaterial.new
211
+ k.generate_key(2048)
212
+ csr.key_material = k
213
+ csr.digest = "SHA256"
214
+ csr.to_x509_csr.to_pem
215
+
216
+ Similarly, reading a CSR in is as simple as providing the PEM formatted version to +SigningRequest.from_x509_csr+.
217
+
218
+ csr = CertificateAuthority::SigningRequest.from_x509_csr(@pem_csr)
219
+
220
+ Once you have the CSR in the form of a +SigningRequest+ you can transform it to a +Certificate+ with +to_cert+. At this point it works just like any other certificate. You'll have to provide a serial number to actually sign it.
221
+
222
+ = Certificate Revocation Lists (CRLs)
223
+
224
+ Revocation lists let clients know when a certificate in the wild should no longer be trusted.
225
+
226
+ Like end-user certificates, CRLs have to be signed by a signing authority to be valid. Additionally, you will need to furnish a +nextUpdate+ value that indicates to the client when it should look for updates to the CRL and how long it should consider a cached value valid.
227
+
228
+ Ideally you would place the result CRL somewhere generally accessible on the Internet and reference the URI in the +crlDistributionPoints+ extension on issued certificates.
229
+
230
+ crl = CertificateAuthority::CertificateRevocationList.new
231
+ crl << certificate # Some CertificateAuthority::Certificate
232
+ crl << serial_number # Also works with plain CertificateAuthority::SerialNumber
233
+ crl.parent = root_certificate # A valid root
234
+ crl.next_update = (60 * 60 * 10) # 10 Hours
235
+ crl.sign!
236
+ crl.to_pem
237
+
238
+ = OCSP Support
239
+
240
+ OCSP is the Online Certificate Status Protocol. It provides a mechanism to query an authority to see if a certificate is still valid without downloading an entire CRL. To use this mechanism you provide a URI in the Authority Information Access extension.
241
+ If a client wishes to check the validity of a certificate they can query this endpoint.
242
+ This request will only contain serial numbers, so you'll need to uniquely identify your authority in the AIA path.
243
+
244
+ If a client sends you a DER encoded OCSP request you can read it out via +OCSPRequestReader+
245
+
246
+ ocsp_request_reader = CertificateAuthority::OCSPRequestReader.from_der(@ocsp_request.to_der)
247
+ ocsp_request_reader.serial_numbers
248
+
249
+ Then, you can construct a response like this
250
+
251
+ response_builder = CertificateAuthority::OCSPResponseBuilder.from_request_reader(ocsp_request_reader)
252
+ response_builder.parent = root
253
+ response = response_builder.build_response # Returns OpenSSL::OCSP::Response
254
+ response.to_der
255
+
256
+ The response builder will copy a (possible) nonce from the request. By default, the +OCSPResponseBuilder+ will say that every certificate is GOOD.
257
+ You should definitely override this if you plan on revoking certificates.
258
+ If you want to override this you'll need to supply a proc/lambda that takes a serial number and returns an array of status and reason.
259
+
260
+ response_builder = CertificateAuthority::OCSPResponseBuilder.from_request_reader(ocsp_request_reader)
261
+ response_builder.verification_mechanism = lambda {|certid|
262
+ [CertificateAuthority::OCSPResponseBuilder::REVOKED,CertificateAuthority::OCSPResponseBuilder::UNSPECIFIED]
263
+ }
264
+ response_builder.parent = root
265
+ response = response_builder.build_response # Response will say everything is revoked for unspecified reasons
266
+
267
+ Lastly, you can configure a nextUpdate time in the response. This is the length of time for which a client may consider this response valid.
268
+ The default is 15 minutes.
269
+
270
+ response_builder.next_update = 30 * 60 # 30 minutes
271
+
194
272
  = PKCS#11 Support
195
273
 
196
274
  If you happen to have a PKCS#11 compliant hardware token you can use +certificate_authority+ to maintain private key materials in hardware security modules. At this point the scope of operating that hardware is out of scope of this README but it's there and it is supported.
197
275
 
198
276
  To configure a certificate to utilize PKCS#11 instead of in memory keys all you need to do is:
199
277
 
200
- root = CertificateAuthority::Certificate.new
201
- root.subject.common_name= "http://mydomain.com"
202
- root.serial_number.number=1
203
- root.signing_entity = true
204
-
205
- key_material_in_hardware = CertificateAuthority::Pkcs11KeyMaterial.new
206
- key_material_in_hardware.token_id = "46"
207
- key_material_in_hardware.pkcs11_lib = "/usr/lib/libeTPkcs11.so"
208
- key_material_in_hardware.openssl_pkcs11_engine_lib = "/usr/lib/engines/engine_pkcs11.so"
209
- key_material_in_hardware.pin = "11111111"
210
-
211
- root.key_material = key_material_in_hardware
212
- root.sign!
213
-
214
- You're current version of OpenSSL _must_ include dynamic engine support and you will need to have OpenSSL PKCS#11 engine support. You will also require the actual PKCS#11 driver from the hardware manufacturer. As of today the only tokens I've gotten to work are:
278
+ root = CertificateAuthority::Certificate.new
279
+ root.subject.common_name= "http://mydomain.com"
280
+ root.serial_number.number=1
281
+ root.signing_entity = true
282
+
283
+ key_material_in_hardware = CertificateAuthority::Pkcs11KeyMaterial.new
284
+ key_material_in_hardware.token_id = "46"
285
+ key_material_in_hardware.pkcs11_lib = "/usr/lib/libeTPkcs11.so"
286
+ key_material_in_hardware.openssl_pkcs11_engine_lib = "/usr/lib/engines/engine_pkcs11.so"
287
+ key_material_in_hardware.pin = "11111111"
288
+
289
+ root.key_material = key_material_in_hardware
290
+ root.sign!
291
+
292
+ Your current version of OpenSSL _must_ include dynamic engine support and you will need to have OpenSSL PKCS#11 engine support. You will also require the actual PKCS#11 driver from the hardware manufacturer. As of today the only tokens I've gotten to work are:
215
293
 
216
294
  [eTokenPro] Released by Aladdin (now SafeNet Inc.). I have only had success with the version 4 and 5 (32 bit only) copy of the driver. The newer authentication client released by SafeNet appears to be completely broken for interacting with the tokens outside of SafeNet's own tools. If anyone has a different experience I'd like to hear from you.
217
295
 
@@ -221,17 +299,34 @@ You're current version of OpenSSL _must_ include dynamic engine support and you
221
299
 
222
300
  Also of note, I have gotten these to work with 32-bit copies of Ubuntu 10.10 and pre-Snow Leopard versions of OS X. If you are running Snow Leopard you're out of luck since none of the companies I've contacted make a 64 bit driver.
223
301
 
224
- = Coming Soon
302
+ = Hopefully in the future
225
303
 
226
304
  * More PKCS#11 hardware (I need driver support from the manufacturers)
227
- * Configurable V3 extensions for all the extended functionality
305
+
306
+ = Todone
307
+
308
+ * Support for working with CSRs to request & issue certificates
309
+ * OCSP support
310
+
311
+ = Misc notes
312
+
313
+ * Firefox will complain about root/intermediate certificates unless both digitalSignature and keyEncipherment are specified as keyUsage attributes. Thanks diogomonica
314
+
315
+ = Special thanks and Contributions
316
+
317
+ * Diogo Monica @diogo
318
+ * Justin Cummins @sul3n3t
319
+ * @databus23
320
+ * Colin Jones @trptcolin
321
+ * Eric Monti @emonti
322
+ * TJ Vanderpoel @bougyman
228
323
 
229
324
  == Meta
230
325
 
231
- Written by Chris Chandler(http://chrischandler.name) of Flatterline(http://flatterline.com)
326
+ Written by Chris Chandler(http://chrischandler.name)
232
327
 
233
328
  Released under the MIT License: http://www.opensource.org/licenses/mit-license.php
234
329
 
235
- Main page: http://github.com/cchandler/certificateauthority
330
+ Main page: http://github.com/cchandler/certificate_authority
236
331
 
237
- Issue tracking: https://github.com/cchandler/certificateauthority/issues
332
+ Issue tracking: https://github.com/cchandler/certificate_authority/issues