r509 0.10.0 → 1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.mdown +2 -2
- data/Rakefile +2 -3
- data/bin/r509 +77 -80
- data/bin/r509-parse +4 -4
- data/doc/R509.html +60 -60
- data/doc/R509/ASN1.html +158 -48
- data/doc/R509/ASN1/GeneralName.html +157 -154
- data/doc/R509/ASN1/GeneralNames.html +246 -237
- data/doc/R509/CRL.html +41 -39
- data/doc/R509/CRL/Administrator.html +105 -100
- data/doc/R509/CRL/FileReaderWriter.html +146 -98
- data/doc/R509/CRL/ReaderWriter.html +57 -54
- data/doc/R509/CRL/SQLiteReaderWriter.html +727 -0
- data/doc/R509/CRL/SignedList.html +83 -80
- data/doc/R509/CSR.html +184 -162
- data/doc/R509/Cert.html +271 -269
- data/doc/R509/Cert/Extensions.html +62 -63
- data/doc/R509/Cert/Extensions/AuthorityInfoAccess.html +138 -108
- data/doc/R509/Cert/Extensions/AuthorityKeyIdentifier.html +100 -84
- data/doc/R509/Cert/Extensions/BasicConstraints.html +89 -88
- data/doc/R509/Cert/Extensions/CRLDistributionPoints.html +87 -83
- data/doc/R509/Cert/Extensions/CertificatePolicies.html +78 -76
- data/doc/R509/Cert/Extensions/ExtendedKeyUsage.html +128 -125
- data/doc/R509/Cert/Extensions/GeneralNamesMixin.html +83 -78
- data/doc/R509/Cert/Extensions/InhibitAnyPolicy.html +69 -67
- data/doc/R509/Cert/Extensions/KeyUsage.html +138 -135
- data/doc/R509/Cert/Extensions/NameConstraints.html +82 -81
- data/doc/R509/Cert/Extensions/NoticeReference.html +59 -56
- data/doc/R509/Cert/Extensions/OCSPNoCheck.html +70 -69
- data/doc/R509/Cert/Extensions/PolicyConstraints.html +71 -69
- data/doc/R509/Cert/Extensions/PolicyInformation.html +63 -60
- data/doc/R509/Cert/Extensions/PolicyQualifiers.html +60 -57
- data/doc/R509/Cert/Extensions/SubjectAlternativeName.html +91 -87
- data/doc/R509/Cert/Extensions/SubjectKeyIdentifier.html +72 -71
- data/doc/R509/Cert/Extensions/UserNotice.html +60 -57
- data/doc/R509/Cert/Extensions/ValidationMixin.html +43 -40
- data/doc/R509/CertificateAuthority.html +39 -37
- data/doc/R509/CertificateAuthority/OptionsBuilder.html +58 -55
- data/doc/R509/CertificateAuthority/Signer.html +277 -60
- data/doc/R509/Config.html +40 -38
- data/doc/R509/Config/CAConfig.html +255 -188
- data/doc/R509/Config/CAConfigPool.html +64 -61
- data/doc/R509/Config/CertProfile.html +119 -116
- data/doc/R509/Config/SubjectItemPolicy.html +94 -93
- data/doc/R509/Engine.html +60 -56
- data/doc/R509/Helpers.html +99 -96
- data/doc/R509/MessageDigest.html +69 -68
- data/doc/R509/NameSanitizer.html +51 -48
- data/doc/R509/OCSP.html +39 -37
- data/doc/R509/OCSP/Request.html +39 -37
- data/doc/R509/OCSP/Request/Nonce.html +67 -67
- data/doc/R509/OCSP/Response.html +93 -90
- data/doc/R509/OIDMapper.html +48 -46
- data/doc/R509/PrivateKey.html +170 -169
- data/doc/R509/R509Error.html +45 -42
- data/doc/R509/SPKI.html +99 -89
- data/doc/R509/Subject.html +86 -83
- data/doc/R509/Validity.html +57 -57
- data/doc/R509/Validity/Checker.html +63 -93
- data/doc/R509/Validity/DefaultChecker.html +58 -55
- data/doc/R509/Validity/DefaultWriter.html +62 -59
- data/doc/R509/Validity/Status.html +77 -74
- data/doc/R509/Validity/Writer.html +75 -123
- data/doc/_index.html +37 -31
- data/doc/class_list.html +25 -27
- data/doc/css/full_list.css +32 -31
- data/doc/css/style.css +221 -78
- data/doc/file.CONTRIBUTING.html +29 -30
- data/doc/file.LICENSE.html +29 -30
- data/doc/file.README.html +31 -32
- data/doc/file.YAML.html +33 -34
- data/doc/file.r509.html +39 -48
- data/doc/file_list.html +39 -30
- data/doc/frames.html +10 -21
- data/doc/index.html +31 -32
- data/doc/js/app.js +100 -71
- data/doc/js/full_list.js +168 -130
- data/doc/method_list.html +1788 -1119
- data/doc/top-level-namespace.html +45 -49
- data/lib/r509.rb +21 -7
- data/lib/r509/asn1.rb +45 -32
- data/lib/r509/cert.rb +45 -51
- data/lib/r509/cert/extensions/authority_info_access.rb +49 -23
- data/lib/r509/cert/extensions/authority_key_identifier.rb +16 -11
- data/lib/r509/cert/extensions/base.rb +22 -23
- data/lib/r509/cert/extensions/basic_constraints.rb +11 -12
- data/lib/r509/cert/extensions/certificate_policies.rb +26 -26
- data/lib/r509/cert/extensions/crl_distribution_points.rb +5 -7
- data/lib/r509/cert/extensions/extended_key_usage.rb +5 -5
- data/lib/r509/cert/extensions/inhibit_any_policy.rb +4 -3
- data/lib/r509/cert/extensions/key_usage.rb +5 -5
- data/lib/r509/cert/extensions/name_constraints.rb +16 -16
- data/lib/r509/cert/extensions/ocsp_no_check.rb +3 -3
- data/lib/r509/cert/extensions/policy_constraints.rb +8 -8
- data/lib/r509/cert/extensions/subject_alternative_name.rb +5 -4
- data/lib/r509/cert/extensions/subject_key_identifier.rb +5 -5
- data/lib/r509/cert/extensions/validation_mixin.rb +11 -10
- data/lib/r509/certificate_authority/options_builder.rb +19 -21
- data/lib/r509/certificate_authority/signer.rb +26 -27
- data/lib/r509/config.rb +1 -0
- data/lib/r509/config/ca_config.rb +70 -75
- data/lib/r509/config/cert_profile.rb +9 -8
- data/lib/r509/config/subject_item_policy.rb +25 -28
- data/lib/r509/crl/administrator.rb +19 -20
- data/lib/r509/crl/reader_writer.rb +10 -8
- data/lib/r509/crl/signed_list.rb +4 -4
- data/lib/r509/crl/sqlite_reader_writer.rb +75 -0
- data/lib/r509/csr.rb +54 -60
- data/lib/r509/ec-hack.rb +3 -2
- data/lib/r509/engine.rb +5 -6
- data/lib/r509/exceptions.rb +1 -1
- data/lib/r509/helpers.rb +11 -14
- data/lib/r509/io_helpers.rb +7 -7
- data/lib/r509/message_digest.rb +5 -6
- data/lib/r509/ocsp.rb +11 -13
- data/lib/r509/oid_mapper.rb +2 -2
- data/lib/r509/private_key.rb +28 -32
- data/lib/r509/spki.rb +17 -20
- data/lib/r509/subject.rb +26 -27
- data/lib/r509/trollop.rb +1 -0
- data/lib/r509/validity.rb +30 -21
- data/lib/r509/version.rb +4 -2
- data/r509.yaml +9 -17
- data/spec/asn1_spec.rb +145 -146
- data/spec/cert/extensions/authority_info_access_spec.rb +41 -41
- data/spec/cert/extensions/authority_key_identifier_spec.rb +29 -23
- data/spec/cert/extensions/base_spec.rb +38 -34
- data/spec/cert/extensions/basic_constraints_spec.rb +21 -21
- data/spec/cert/extensions/certificate_policies_spec.rb +99 -87
- data/spec/cert/extensions/crl_distribution_points_spec.rb +24 -25
- data/spec/cert/extensions/extended_key_usage_spec.rb +40 -36
- data/spec/cert/extensions/inhibit_any_policy_spec.rb +12 -12
- data/spec/cert/extensions/key_usage_spec.rb +44 -39
- data/spec/cert/extensions/name_constraints_spec.rb +83 -83
- data/spec/cert/extensions/ocsp_no_check_spec.rb +10 -10
- data/spec/cert/extensions/policy_constraints_spec.rb +19 -19
- data/spec/cert/extensions/subject_alternative_name_spec.rb +46 -47
- data/spec/cert/extensions/subject_key_identifier_spec.rb +10 -10
- data/spec/cert_spec.rb +105 -101
- data/spec/certificate_authority/options_builder_spec.rb +90 -90
- data/spec/certificate_authority/signer_spec.rb +41 -41
- data/spec/config/ca_config_spec.rb +169 -119
- data/spec/config/cert_profile_spec.rb +33 -33
- data/spec/config/subject_item_policy_spec.rb +22 -22
- data/spec/crl/administrator_spec.rb +65 -65
- data/spec/crl/reader_writer_spec.rb +20 -19
- data/spec/crl/signed_list_spec.rb +26 -26
- data/spec/crl/sqlite_reader_writer_spec.rb +42 -0
- data/spec/csr_spec.rb +149 -145
- data/spec/engine_spec.rb +14 -14
- data/spec/fixtures.rb +56 -39
- data/spec/fixtures/crl_list.sql +13 -0
- data/spec/fixtures/csr1.der +0 -0
- data/spec/fixtures/csr1.pem +6 -6
- data/spec/message_digest_spec.rb +43 -43
- data/spec/ocsp_spec.rb +25 -25
- data/spec/oid_mapper_spec.rb +18 -19
- data/spec/private_key_spec.rb +79 -81
- data/spec/r509_spec.rb +16 -16
- data/spec/spec_helper.rb +3 -3
- data/spec/spki_spec.rb +94 -94
- data/spec/subject_spec.rb +107 -107
- data/spec/validity_spec.rb +25 -25
- metadata +113 -111
- metadata.gz.sig +0 -0
@@ -1,12 +1,12 @@
|
|
1
|
-
<!DOCTYPE html
|
2
|
-
|
3
|
-
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
4
3
|
<head>
|
5
|
-
<meta
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
6
|
<title>
|
7
7
|
Top Level Namespace
|
8
8
|
|
9
|
-
— Documentation by YARD 0.
|
9
|
+
— Documentation by YARD 0.9.5
|
10
10
|
|
11
11
|
</title>
|
12
12
|
|
@@ -15,9 +15,8 @@
|
|
15
15
|
<link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
|
16
16
|
|
17
17
|
<script type="text/javascript" charset="utf-8">
|
18
|
-
|
18
|
+
pathId = "";
|
19
19
|
relpath = '';
|
20
|
-
framesUrl = "frames.html#!" + escape(window.location.href);
|
21
20
|
</script>
|
22
21
|
|
23
22
|
|
@@ -28,58 +27,58 @@
|
|
28
27
|
|
29
28
|
</head>
|
30
29
|
<body>
|
31
|
-
<div
|
32
|
-
<
|
30
|
+
<div class="nav_wrap">
|
31
|
+
<iframe id="nav" src="class_list.html"></iframe>
|
32
|
+
<div id="resizer"></div>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div id="main" tabindex="-1">
|
36
|
+
<div id="header">
|
37
|
+
<div id="menu">
|
33
38
|
|
34
39
|
<a href="_index.html">Index</a> »
|
35
40
|
|
36
41
|
|
37
42
|
<span class="title">Top Level Namespace</span>
|
38
43
|
|
39
|
-
|
40
|
-
<div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div>
|
41
44
|
</div>
|
42
45
|
|
43
|
-
|
46
|
+
<div id="search">
|
44
47
|
|
45
48
|
<a class="full_list_link" id="class_list_link"
|
46
49
|
href="class_list.html">
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
</a>
|
54
|
-
|
55
|
-
<a class="full_list_link" id="file_list_link"
|
56
|
-
href="file_list.html">
|
57
|
-
File List
|
50
|
+
|
51
|
+
<svg width="24" height="24">
|
52
|
+
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
|
53
|
+
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
|
54
|
+
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
|
55
|
+
</svg>
|
58
56
|
</a>
|
59
57
|
|
60
58
|
</div>
|
61
|
-
|
62
|
-
|
59
|
+
<div class="clear"></div>
|
60
|
+
</div>
|
63
61
|
|
64
|
-
|
62
|
+
<iframe id="search_frame" src="class_list.html"></iframe>
|
65
63
|
|
66
|
-
|
64
|
+
<div id="content"><h1>Top Level Namespace
|
67
65
|
|
68
66
|
|
69
67
|
|
70
68
|
</h1>
|
69
|
+
<div class="box_info">
|
70
|
+
|
71
71
|
|
72
|
-
<dl class="box">
|
73
72
|
|
74
73
|
|
75
|
-
|
76
74
|
|
77
|
-
|
78
75
|
|
79
76
|
|
77
|
+
|
80
78
|
|
81
|
-
|
82
|
-
|
79
|
+
|
80
|
+
|
81
|
+
</div>
|
83
82
|
|
84
83
|
<h2>Defined Under Namespace</h2>
|
85
84
|
<p class="children">
|
@@ -101,7 +100,7 @@
|
|
101
100
|
|
102
101
|
<h2>
|
103
102
|
Instance Method Summary
|
104
|
-
<small
|
103
|
+
<small><a href="#" class="summary_toggle">collapse</a></small>
|
105
104
|
</h2>
|
106
105
|
|
107
106
|
<ul class="summary">
|
@@ -109,7 +108,7 @@
|
|
109
108
|
<li class="public ">
|
110
109
|
<span class="summary_signature">
|
111
110
|
|
112
|
-
<a href="#date-instance_method" title="#date (instance method)"
|
111
|
+
<a href="top-level-namespace.html#date-instance_method" title="#date (instance method)">#<strong>date</strong> ⇒ Object </a>
|
113
112
|
|
114
113
|
|
115
114
|
|
@@ -123,18 +122,14 @@
|
|
123
122
|
|
124
123
|
|
125
124
|
|
126
|
-
<span class="summary_desc"><div class='inline'>
|
127
|
-
<
|
128
|
-
<dl class="rdoc-list note-list"><dt>
|
129
|
-
<dd>
|
130
|
-
<p>William Morgan (mailto: wmorgan-trollop@masanjin.net)</p>
|
131
|
-
</dd><dt>Copyright
|
132
|
-
<dd>
|
133
|
-
<p>Copyright 2007 William Morgan</p>
|
134
|
-
</dd><dt>License
|
125
|
+
<span class="summary_desc"><div class='inline'><dl class="rdoc-list note-list"><dt>lib/trollop.rb – trollop command-line processing library Author
|
126
|
+
<dd><dl class="rdoc-list note-list"><dt>William Morgan (mailto: wmorgan-trollop@masanjin.net) Copyright
|
127
|
+
<dd><dl class="rdoc-list note-list"><dt>Copyright 2007 William Morgan License
|
135
128
|
<dd>
|
136
129
|
<p>the same terms as ruby itself.</p>
|
137
130
|
</dd></dl>
|
131
|
+
</dd></dl>
|
132
|
+
</dd></dl>
|
138
133
|
</div></span>
|
139
134
|
|
140
135
|
</li>
|
@@ -152,7 +147,7 @@
|
|
152
147
|
<div class="method_details first">
|
153
148
|
<h3 class="signature first" id="date-instance_method">
|
154
149
|
|
155
|
-
|
150
|
+
#<strong>date</strong> ⇒ <tt>Object</tt>
|
156
151
|
|
157
152
|
|
158
153
|
|
@@ -185,10 +180,10 @@
|
|
185
180
|
<pre class="lines">
|
186
181
|
|
187
182
|
|
188
|
-
|
183
|
+
10</pre>
|
189
184
|
</td>
|
190
185
|
<td>
|
191
|
-
<pre class="code"><span class="info file"># File 'lib/r509/trollop.rb', line
|
186
|
+
<pre class="code"><span class="info file"># File 'lib/r509/trollop.rb', line 10</span>
|
192
187
|
|
193
188
|
<span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>date</span><span class='tstring_end'>'</span></span></pre>
|
194
189
|
</td>
|
@@ -200,11 +195,12 @@
|
|
200
195
|
|
201
196
|
</div>
|
202
197
|
|
203
|
-
|
204
|
-
Generated on
|
198
|
+
<div id="footer">
|
199
|
+
Generated on Tue Dec 6 17:27:38 2016 by
|
205
200
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
206
|
-
0.
|
201
|
+
0.9.5 (ruby-2.4.0).
|
207
202
|
</div>
|
208
203
|
|
204
|
+
</div>
|
209
205
|
</body>
|
210
206
|
</html>
|
data/lib/r509.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
# A module for building an easy to use CA. Includes CSR, Certificate, and CRL
|
1
|
+
# A module for building an easy to use CA. Includes CSR, Certificate, and CRL
|
2
|
+
# support.
|
2
3
|
module R509
|
3
4
|
require('r509/certificate_authority/signer.rb')
|
4
5
|
require('r509/certificate_authority/options_builder.rb')
|
@@ -31,14 +32,27 @@ module R509
|
|
31
32
|
|
32
33
|
# Helper method to check if EC support is built-in
|
33
34
|
def self.ec_supported?
|
34
|
-
(
|
35
|
+
(!defined?(OpenSSL::PKey::EC::UNSUPPORTED))
|
35
36
|
end
|
36
37
|
end
|
37
38
|
|
38
|
-
#add some global mappings we want available throughout r509
|
39
|
+
# add some global mappings we want available throughout r509
|
39
40
|
R509::OIDMapper.batch_register([
|
40
|
-
{
|
41
|
-
|
42
|
-
|
43
|
-
|
41
|
+
{
|
42
|
+
:oid => "2.5.4.15",
|
43
|
+
:short_name => "businessCategory"
|
44
|
+
}, # extended validation related
|
45
|
+
{
|
46
|
+
:oid => "1.3.6.1.4.1.311.60.2.1.2",
|
47
|
+
:short_name => "jurisdictionOfIncorporationStateOrProvinceName"
|
48
|
+
}, # extended validation related
|
49
|
+
{
|
50
|
+
:oid => "1.3.6.1.4.1.311.60.2.1.3",
|
51
|
+
:short_name => "jurisdictionOfIncorporationCountryName"
|
52
|
+
}, # extended validation related
|
53
|
+
{
|
54
|
+
:oid => "2.5.29.37.0",
|
55
|
+
:short_name => "anyExtendedKeyUsage",
|
56
|
+
:long_name => "Any Extended Key Usage"
|
57
|
+
} # an EKU older OpenSSL frequently lacks
|
44
58
|
])
|
data/lib/r509/asn1.rb
CHANGED
@@ -24,15 +24,15 @@ module R509
|
|
24
24
|
# You can also supply a directoryName, but this must be an R509::Subject or array of arrays
|
25
25
|
# @return [R509::ASN1::GeneralNames]
|
26
26
|
def self.general_name_parser(names)
|
27
|
-
if names.nil?
|
27
|
+
if names.nil? || names.is_a?(R509::ASN1::GeneralNames)
|
28
28
|
return names
|
29
|
-
elsif
|
29
|
+
elsif !names.is_a?(Array)
|
30
30
|
raise ArgumentError, "You must supply an array or existing R509::ASN1 GeneralNames object to general_name_parser"
|
31
31
|
end
|
32
32
|
general_names = R509::ASN1::GeneralNames.new
|
33
33
|
names.uniq!
|
34
34
|
names.map do |domain|
|
35
|
-
if
|
35
|
+
if self.ip_check(domain)
|
36
36
|
ip = IPAddr.new(domain.strip)
|
37
37
|
general_names.create_item(:tag => 7, :value => ip.to_s)
|
38
38
|
else
|
@@ -40,11 +40,11 @@ module R509
|
|
40
40
|
when R509::Subject, Array
|
41
41
|
subject = R509::Subject.new(domain)
|
42
42
|
general_names.create_item(:tag => 4, :value => subject)
|
43
|
-
when /:\/\// #URI
|
43
|
+
when /:\/\// # URI
|
44
44
|
general_names.create_item(:tag => 6, :value => domain.strip)
|
45
|
-
when /@/ #rfc822Name
|
45
|
+
when /@/ # rfc822Name
|
46
46
|
general_names.create_item(:tag => 1, :value => domain.strip)
|
47
|
-
else #dNSName
|
47
|
+
else # dNSName
|
48
48
|
general_names.create_item(:tag => 2, :value => domain.strip)
|
49
49
|
end
|
50
50
|
end
|
@@ -52,6 +52,20 @@ module R509
|
|
52
52
|
general_names
|
53
53
|
end
|
54
54
|
|
55
|
+
# Checks if a given string is an IP or not.
|
56
|
+
#
|
57
|
+
# @param [String] domain The string to check
|
58
|
+
#
|
59
|
+
# @return [Boolean]
|
60
|
+
def self.ip_check(domain)
|
61
|
+
begin
|
62
|
+
IPAddr.new(domain.strip)
|
63
|
+
true
|
64
|
+
rescue
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
55
69
|
# This class parses ASN.1 GeneralName objects. At the moment it supports
|
56
70
|
# rfc822Name, dNSName, directoryName, uniformResourceIdentifier, and iPAddress
|
57
71
|
# GeneralName ::= CHOICE {
|
@@ -77,7 +91,7 @@ module R509
|
|
77
91
|
|
78
92
|
# @param [OpenSSL::ASN1::ASN1Data,Hash] asn ASN.1 input data. Can also pass a hash with (:tag or :type) and :value keys
|
79
93
|
def initialize(asn)
|
80
|
-
if asn.
|
94
|
+
if asn.is_a?(Hash)
|
81
95
|
# this is added via create_item
|
82
96
|
parse_hash(asn)
|
83
97
|
else
|
@@ -143,9 +157,9 @@ module R509
|
|
143
157
|
end
|
144
158
|
end
|
145
159
|
|
146
|
-
|
160
|
+
# @return [Hash]
|
147
161
|
def to_h
|
148
|
-
val = (@value.
|
162
|
+
val = (@value.is_a?(R509::Subject)) ? @value.to_h : @value
|
149
163
|
|
150
164
|
{ :type => @short_type, :value => val }
|
151
165
|
end
|
@@ -154,7 +168,7 @@ module R509
|
|
154
168
|
# required for #uniq comparisons
|
155
169
|
# @return [Boolean] equality between objects
|
156
170
|
def ==(other)
|
157
|
-
(other.class == self.class
|
171
|
+
(other.class == self.class && self.type == other.type && self.value == other.value)
|
158
172
|
end
|
159
173
|
alias_method :eql?, :==
|
160
174
|
|
@@ -181,7 +195,7 @@ module R509
|
|
181
195
|
@tag = asn[:tag] || R509::ASN1::GeneralName.map_type_to_tag(asn[:type])
|
182
196
|
@type = R509::ASN1::GeneralName.map_tag_to_type(@tag)
|
183
197
|
@short_type = R509::ASN1::GeneralName.map_tag_to_short_type(@tag)
|
184
|
-
@value = (@tag == 4)? R509::Subject.new(asn[:value]) : asn[:value]
|
198
|
+
@value = (@tag == 4) ? R509::Subject.new(asn[:value]) : asn[:value]
|
185
199
|
end
|
186
200
|
|
187
201
|
def parse_asn(asn)
|
@@ -190,20 +204,20 @@ module R509
|
|
190
204
|
@short_type = R509::ASN1::GeneralName.map_tag_to_short_type(@tag)
|
191
205
|
value = asn.value
|
192
206
|
case @tag
|
193
|
-
when 1,2,6 then @value = value
|
207
|
+
when 1, 2, 6 then @value = value
|
194
208
|
when 4 then @value = R509::Subject.new(value.first.to_der)
|
195
209
|
when 7
|
196
|
-
if value.size == 4
|
210
|
+
if value.size == 4 || value.size == 16
|
197
211
|
@value = parse_ip(value)
|
198
|
-
elsif value.size == 8 #IPv4 with netmask
|
199
|
-
@value = parse_ip(value[0,4],value[4,4])
|
200
|
-
elsif value.size == 32 #IPv6 with netmask
|
201
|
-
@value = parse_ip(value[0,16],value[16,16])
|
212
|
+
elsif value.size == 8 # IPv4 with netmask
|
213
|
+
@value = parse_ip(value[0, 4], value[4, 4])
|
214
|
+
elsif value.size == 32 # IPv6 with netmask
|
215
|
+
@value = parse_ip(value[0, 16], value[16, 16])
|
202
216
|
end
|
203
217
|
end
|
204
218
|
end
|
205
219
|
|
206
|
-
def parse_ip(value,mask=nil)
|
220
|
+
def parse_ip(value, mask = nil)
|
207
221
|
ip = IPAddr.new_ntoh(value)
|
208
222
|
if mask.nil?
|
209
223
|
return ip.to_s
|
@@ -231,8 +245,10 @@ module R509
|
|
231
245
|
class GeneralNames
|
232
246
|
include R509::Cert::Extensions::ValidationMixin
|
233
247
|
|
248
|
+
attr_reader :ordered_names
|
249
|
+
|
234
250
|
# @param data [Array,R509::ASN1::GeneralNames] Pass an array of hashes to create R509::ASN1::GeneralName objects or an existing R509::ASN1::GeneralNames object
|
235
|
-
def initialize(data=nil)
|
251
|
+
def initialize(data = nil)
|
236
252
|
@types = {
|
237
253
|
:otherName => [], # unimplemented
|
238
254
|
:rfc822Name => [],
|
@@ -245,8 +261,8 @@ module R509
|
|
245
261
|
:registeredID => [] # unimplemented
|
246
262
|
}
|
247
263
|
@ordered_names = []
|
248
|
-
|
249
|
-
if data.
|
264
|
+
unless data.nil?
|
265
|
+
if data.is_a?(self.class)
|
250
266
|
data.names.each { |n| add_item(n) }
|
251
267
|
else
|
252
268
|
validate_general_name_hash_array(data)
|
@@ -260,7 +276,7 @@ module R509
|
|
260
276
|
# @param [OpenSSL::ASN1::ASN1Data] asn Takes ASN.1 data in for parsing GeneralName structures
|
261
277
|
def add_item(asn)
|
262
278
|
# map general names into our hash of arrays
|
263
|
-
if asn.
|
279
|
+
if asn.is_a?(R509::ASN1::GeneralName)
|
264
280
|
@ordered_names << asn
|
265
281
|
@types[asn.type] << asn.value
|
266
282
|
else
|
@@ -273,7 +289,7 @@ module R509
|
|
273
289
|
# @param [Hash] hash A hash with (:tag or :type) and :value keys. Allows you to build GeneralName objects and add
|
274
290
|
# them to the GeneralNames object
|
275
291
|
def create_item(hash)
|
276
|
-
if
|
292
|
+
if !hash.respond_to?(:has_key?) || (!hash.key?(:tag) && !hash.key?(:type)) || !hash.key?(:value)
|
277
293
|
raise ArgumentError, "Must be a hash with (:tag or :type) and :value nodes"
|
278
294
|
end
|
279
295
|
gn = R509::ASN1::GeneralName.new(:tag => hash[:tag], :type => hash[:type], :value => hash[:value])
|
@@ -287,15 +303,13 @@ module R509
|
|
287
303
|
|
288
304
|
# @return [Array] array of GeneralName objects
|
289
305
|
# order found in the extension
|
290
|
-
|
291
|
-
@ordered_names
|
292
|
-
end
|
306
|
+
alias_method :names, :ordered_names
|
293
307
|
|
294
308
|
# @return [Array] Array of rfc822name strings
|
295
309
|
def rfc_822_names
|
296
310
|
@types[:rfc822Name]
|
297
311
|
end
|
298
|
-
|
312
|
+
alias_method :email_names, :rfc_822_names
|
299
313
|
|
300
314
|
# @return [Array] Array of dnsName strings
|
301
315
|
def dns_names
|
@@ -312,26 +326,25 @@ module R509
|
|
312
326
|
def ip_addresses
|
313
327
|
@types[:iPAddress]
|
314
328
|
end
|
315
|
-
|
329
|
+
alias_method :ips, :ip_addresses
|
316
330
|
|
317
331
|
# @return [Array] Array of directoryNames (R509::Subject objects)
|
318
332
|
def directory_names
|
319
333
|
@types[:directoryName]
|
320
334
|
end
|
321
|
-
|
335
|
+
alias_method :dir_names, :directory_names
|
322
336
|
|
323
337
|
# @return [Array] string of serialized names for OpenSSL extension creation
|
324
338
|
def serialize_names
|
325
339
|
confs = []
|
326
340
|
extension_strings = []
|
327
|
-
@ordered_names.each
|
341
|
+
@ordered_names.each do |item|
|
328
342
|
data = item.serialize_name
|
329
343
|
confs << data[:conf]
|
330
344
|
extension_strings << data[:extension_string]
|
331
|
-
|
345
|
+
end
|
332
346
|
{ :conf => confs.join("\n"), :extension_string => extension_strings.join(",") }
|
333
347
|
end
|
334
348
|
end
|
335
|
-
|
336
349
|
end
|
337
350
|
end
|
data/lib/r509/cert.rb
CHANGED
@@ -7,8 +7,8 @@ require 'r509/cert/extensions'
|
|
7
7
|
module R509
|
8
8
|
# The primary certificate object.
|
9
9
|
class Cert
|
10
|
-
|
11
|
-
|
10
|
+
include R509::IOHelpers
|
11
|
+
include R509::Helpers
|
12
12
|
|
13
13
|
attr_reader :cert, :key, :subject, :issuer
|
14
14
|
|
@@ -16,24 +16,24 @@ module R509
|
|
16
16
|
# @option opts [R509::PrivateKey,String] :key optional private key to supply. either an unencrypted PEM/DER string or an R509::PrivateKey object (use the latter if you need password/hardware support)
|
17
17
|
# @option opts [String] :pkcs12 a PKCS12 object containing both key and cert
|
18
18
|
# @option opts [String] :password password for PKCS12 or private key (if supplied)
|
19
|
-
def initialize(opts={})
|
20
|
-
|
19
|
+
def initialize(opts = {})
|
20
|
+
unless opts.is_a?(Hash)
|
21
21
|
raise ArgumentError, 'Must provide a hash of options'
|
22
22
|
end
|
23
|
-
if opts.
|
23
|
+
if opts.key?(:pkcs12) && ( opts.key?(:key) || opts.key?(:cert))
|
24
24
|
raise ArgumentError, "When providing pkcs12, do not pass cert or key"
|
25
|
-
elsif opts.
|
26
|
-
pkcs12 = OpenSSL::PKCS12.new(
|
25
|
+
elsif opts.key?(:pkcs12)
|
26
|
+
pkcs12 = OpenSSL::PKCS12.new(opts[:pkcs12], opts[:password])
|
27
27
|
parse_certificate(pkcs12.certificate)
|
28
28
|
parse_private_key(pkcs12.key)
|
29
|
-
elsif
|
29
|
+
elsif !opts.key?(:cert)
|
30
30
|
raise ArgumentError, 'Must provide :cert or :pkcs12'
|
31
31
|
else
|
32
32
|
csr_check(opts[:cert])
|
33
33
|
parse_certificate(opts[:cert])
|
34
34
|
end
|
35
35
|
|
36
|
-
if opts.
|
36
|
+
if opts.key?(:key)
|
37
37
|
parse_private_key(opts[:key], opts[:password])
|
38
38
|
end
|
39
39
|
end
|
@@ -42,11 +42,11 @@ module R509
|
|
42
42
|
#
|
43
43
|
# @param [String] filename Path to file you want to load
|
44
44
|
# @return [R509::Cert] cert object
|
45
|
-
def self.load_from_file(
|
46
|
-
|
45
|
+
def self.load_from_file(filename)
|
46
|
+
R509::Cert.new(:cert => IOHelpers.read_data(filename))
|
47
47
|
end
|
48
48
|
|
49
|
-
|
49
|
+
alias_method :to_s, :to_pem
|
50
50
|
|
51
51
|
# Returns beginning (notBefore) of certificate validity period
|
52
52
|
#
|
@@ -83,11 +83,11 @@ module R509
|
|
83
83
|
@cert.public_key
|
84
84
|
end
|
85
85
|
|
86
|
-
# Returns the certificate fingerprint with the specified algorithm (default
|
86
|
+
# Returns the certificate fingerprint with the specified algorithm (default sha256)
|
87
87
|
#
|
88
88
|
# @param [String] algorithm Which algorithm to use for the fingerprint. See R509::MessageDigest for supported algorithm names
|
89
89
|
# @return [String] hex digest of the certificate
|
90
|
-
def fingerprint(algorithm='
|
90
|
+
def fingerprint(algorithm = 'sha256')
|
91
91
|
message_digest = R509::MessageDigest.new(algorithm)
|
92
92
|
md = message_digest.digest
|
93
93
|
md.update(@cert.to_der)
|
@@ -107,11 +107,11 @@ module R509
|
|
107
107
|
# @param [Time,Integer] time Time object or integer timestamp
|
108
108
|
# @return [Boolean]
|
109
109
|
def valid_at?(time)
|
110
|
-
if time.
|
110
|
+
if time.is_a?(Integer)
|
111
111
|
time = Time.at(time)
|
112
112
|
end
|
113
113
|
|
114
|
-
if (self.not_after < time)
|
114
|
+
if (self.not_after < time) || (self.not_before > time)
|
115
115
|
false
|
116
116
|
else
|
117
117
|
true
|
@@ -120,11 +120,7 @@ module R509
|
|
120
120
|
|
121
121
|
# @return [Boolean] Boolean of whether the object contains a private key
|
122
122
|
def has_private_key?
|
123
|
-
|
124
|
-
true
|
125
|
-
else
|
126
|
-
false
|
127
|
-
end
|
123
|
+
!@key.nil?
|
128
124
|
end
|
129
125
|
|
130
126
|
# Return the CN, as well as all the subject alternative names (SANs).
|
@@ -134,9 +130,9 @@ module R509
|
|
134
130
|
def all_names
|
135
131
|
ret = []
|
136
132
|
ret << @subject.CN unless @subject.CN.nil?
|
137
|
-
ret.concat(
|
133
|
+
ret.concat(self.san.names.map { |n| n.value }) unless self.san.nil?
|
138
134
|
|
139
|
-
|
135
|
+
ret.sort.uniq
|
140
136
|
end
|
141
137
|
|
142
138
|
# Returns signature algorithm
|
@@ -151,11 +147,11 @@ module R509
|
|
151
147
|
# the file that you'd like to write, or an IO-like object.
|
152
148
|
# @param [String] password password
|
153
149
|
# @param [String] friendly_name An optional string to encode in the PKCS12 for friendlyName. defaults to "r509 pkcs12"
|
154
|
-
def write_pkcs12(filename_or_io,password,friendly_name='r509 pkcs12')
|
150
|
+
def write_pkcs12(filename_or_io, password, friendly_name = 'r509 pkcs12')
|
155
151
|
if @key.nil?
|
156
152
|
raise R509::R509Error, "Writing a PKCS12 requires both key and cert"
|
157
153
|
end
|
158
|
-
pkcs12 = OpenSSL::PKCS12.create(password,friendly_name
|
154
|
+
pkcs12 = OpenSSL::PKCS12.create(password, friendly_name, @key.key, @cert)
|
159
155
|
write_data(filename_or_io, pkcs12.to_der)
|
160
156
|
end
|
161
157
|
|
@@ -164,8 +160,8 @@ module R509
|
|
164
160
|
# so do that check yourself
|
165
161
|
#
|
166
162
|
# @param [R509::CRL::SignedList] r509_crl A CRL from the CA that issued this certificate.
|
167
|
-
def is_revoked_by_crl?(
|
168
|
-
|
163
|
+
def is_revoked_by_crl?(r509_crl)
|
164
|
+
r509_crl.revoked?(self.serial)
|
169
165
|
end
|
170
166
|
|
171
167
|
# Returns the certificate extensions as a hash of R509::Cert::Extensions
|
@@ -177,10 +173,10 @@ module R509
|
|
177
173
|
# implementation are ignored (see #get_unknown_extensions).
|
178
174
|
def extensions
|
179
175
|
if @r509_extensions.nil?
|
180
|
-
@r509_extensions = Extensions.wrap_openssl_extensions(
|
176
|
+
@r509_extensions = Extensions.wrap_openssl_extensions(self.cert.extensions)
|
181
177
|
end
|
182
178
|
|
183
|
-
|
179
|
+
@r509_extensions
|
184
180
|
end
|
185
181
|
|
186
182
|
# Returns an array of OpenSSL::X509::Extension objects representing the
|
@@ -188,7 +184,7 @@ module R509
|
|
188
184
|
#
|
189
185
|
# @return [Array] An array of OpenSSL::X509::Extension objects.
|
190
186
|
def unknown_extensions
|
191
|
-
|
187
|
+
Extensions.get_unknown_extensions(self.cert.extensions)
|
192
188
|
end
|
193
189
|
|
194
190
|
#
|
@@ -200,7 +196,7 @@ module R509
|
|
200
196
|
# @return [R509::Cert::Extensions::BasicConstraints] The object, or nil
|
201
197
|
# if this cert does not have a BasicConstraints extension.
|
202
198
|
def basic_constraints
|
203
|
-
|
199
|
+
extensions[R509::Cert::Extensions::BasicConstraints]
|
204
200
|
end
|
205
201
|
|
206
202
|
# Returns this object's KeyUsage extension as an R509 extension
|
@@ -208,7 +204,7 @@ module R509
|
|
208
204
|
# @return [R509::Cert::Extensions::KeyUsage] The object, or nil
|
209
205
|
# if this cert does not have a KeyUsage extension.
|
210
206
|
def key_usage
|
211
|
-
|
207
|
+
extensions[R509::Cert::Extensions::KeyUsage]
|
212
208
|
end
|
213
209
|
alias_method :ku, :key_usage
|
214
210
|
|
@@ -217,7 +213,7 @@ module R509
|
|
217
213
|
# @return [R509::Cert::Extensions::ExtendedKeyUsage] The object, or nil
|
218
214
|
# if this cert does not have a ExtendedKeyUsage extension.
|
219
215
|
def extended_key_usage
|
220
|
-
|
216
|
+
extensions[R509::Cert::Extensions::ExtendedKeyUsage]
|
221
217
|
end
|
222
218
|
alias_method :eku, :extended_key_usage
|
223
219
|
|
@@ -226,7 +222,7 @@ module R509
|
|
226
222
|
# @return [R509::Cert::Extensions::SubjectKeyIdentifier] The object, or nil
|
227
223
|
# if this cert does not have a SubjectKeyIdentifier extension.
|
228
224
|
def subject_key_identifier
|
229
|
-
|
225
|
+
extensions[R509::Cert::Extensions::SubjectKeyIdentifier]
|
230
226
|
end
|
231
227
|
|
232
228
|
# Returns this object's AuthorityKeyIdentifier extension as an R509 extension
|
@@ -234,7 +230,7 @@ module R509
|
|
234
230
|
# @return [R509::Cert::Extensions::AuthorityKeyIdentifier] The object, or nil
|
235
231
|
# if this cert does not have a AuthorityKeyIdentifier extension.
|
236
232
|
def authority_key_identifier
|
237
|
-
|
233
|
+
extensions[R509::Cert::Extensions::AuthorityKeyIdentifier]
|
238
234
|
end
|
239
235
|
|
240
236
|
# Returns this object's SubjectAlternativeName extension as an R509 extension
|
@@ -242,7 +238,7 @@ module R509
|
|
242
238
|
# @return [R509::Cert::Extensions::SubjectAlternativeName] The object, or nil
|
243
239
|
# if this cert does not have a SubjectAlternativeName extension.
|
244
240
|
def subject_alternative_name
|
245
|
-
|
241
|
+
extensions[R509::Cert::Extensions::SubjectAlternativeName]
|
246
242
|
end
|
247
243
|
alias_method :san, :subject_alternative_name
|
248
244
|
alias_method :subject_alt_name, :subject_alternative_name
|
@@ -252,7 +248,7 @@ module R509
|
|
252
248
|
# @return [R509::Cert::Extensions::AuthorityInfoAccess] The object, or nil
|
253
249
|
# if this cert does not have a AuthorityInfoAccess extension.
|
254
250
|
def authority_info_access
|
255
|
-
|
251
|
+
extensions[R509::Cert::Extensions::AuthorityInfoAccess]
|
256
252
|
end
|
257
253
|
alias_method :aia, :authority_info_access
|
258
254
|
|
@@ -261,7 +257,7 @@ module R509
|
|
261
257
|
# @return [R509::Cert::Extensions::CRLDistributionPoints] The object, or nil
|
262
258
|
# if this cert does not have a CRLDistributionPoints extension.
|
263
259
|
def crl_distribution_points
|
264
|
-
|
260
|
+
extensions[R509::Cert::Extensions::CRLDistributionPoints]
|
265
261
|
end
|
266
262
|
alias_method :cdp, :crl_distribution_points
|
267
263
|
|
@@ -270,7 +266,7 @@ module R509
|
|
270
266
|
#
|
271
267
|
# @return [Boolean] presence/absence of the nocheck extension
|
272
268
|
def ocsp_no_check?
|
273
|
-
|
269
|
+
(extensions.key?(R509::Cert::Extensions::OCSPNoCheck))
|
274
270
|
end
|
275
271
|
|
276
272
|
# Returns this object's CertificatePolicies extension as an R509 extension
|
@@ -278,7 +274,7 @@ module R509
|
|
278
274
|
# @return [R509::Cert::Extensions::CertificatePolicies] The object, or nil
|
279
275
|
# if this cert does not have a CertificatePolicies extension.
|
280
276
|
def certificate_policies
|
281
|
-
|
277
|
+
extensions[R509::Cert::Extensions::CertificatePolicies]
|
282
278
|
end
|
283
279
|
|
284
280
|
# Returns this object's InhibitAnyPolicy extension as an R509 extension
|
@@ -286,7 +282,7 @@ module R509
|
|
286
282
|
# @return [R509::Cert::Extensions::InhibitAnyPolicy] The object, or nil
|
287
283
|
# if this cert does not have a InhibitAnyPolicy extension.
|
288
284
|
def inhibit_any_policy
|
289
|
-
|
285
|
+
extensions[R509::Cert::Extensions::InhibitAnyPolicy]
|
290
286
|
end
|
291
287
|
|
292
288
|
# Returns this object's PolicyConstraints extension as an R509 extension
|
@@ -294,7 +290,7 @@ module R509
|
|
294
290
|
# @return [R509::Cert::Extensions::PolicyConstraints] The object, or nil
|
295
291
|
# if this cert does not have a PolicyConstraints extension.
|
296
292
|
def policy_constraints
|
297
|
-
|
293
|
+
extensions[R509::Cert::Extensions::PolicyConstraints]
|
298
294
|
end
|
299
295
|
|
300
296
|
# Returns this object's NameConstraints extension as an R509 extension
|
@@ -302,10 +298,11 @@ module R509
|
|
302
298
|
# @return [R509::Cert::Extensions::NameConstraints] The object, or nil
|
303
299
|
# if this cert does not have a NameConstraints extension.
|
304
300
|
def name_constraints
|
305
|
-
|
301
|
+
extensions[R509::Cert::Extensions::NameConstraints]
|
306
302
|
end
|
307
303
|
|
308
304
|
private
|
305
|
+
|
309
306
|
# This method exists only to provide a friendlier error msg if you attempt to
|
310
307
|
# parse a CSR as a certificate. All for Sean
|
311
308
|
def csr_check(cert)
|
@@ -323,20 +320,17 @@ module R509
|
|
323
320
|
@issuer = R509::Subject.new(@cert.issuer)
|
324
321
|
end
|
325
322
|
|
326
|
-
def parse_private_key(key, password=nil)
|
327
|
-
|
328
|
-
key = R509::PrivateKey.new(
|
323
|
+
def parse_private_key(key, password = nil)
|
324
|
+
unless key.is_a?(R509::PrivateKey)
|
325
|
+
key = R509::PrivateKey.new(:key => key, :password => password)
|
329
326
|
end
|
330
|
-
|
327
|
+
unless @cert.public_key.to_der == key.public_key.to_der
|
331
328
|
raise R509Error, 'Key does not match cert.'
|
332
329
|
end
|
333
330
|
@key = key
|
334
331
|
end
|
335
332
|
|
336
333
|
# Returns the proper instance variable
|
337
|
-
|
338
|
-
@cert
|
339
|
-
end
|
340
|
-
|
334
|
+
alias_method :internal_obj, :cert
|
341
335
|
end
|
342
336
|
end
|