watobo 0.9.21 → 0.9.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +46 -1
- data/bin/nfq_server.rb +0 -9
- data/bin/watobo_gui.rb +3 -13
- data/custom-views/prettify-json.rb +9 -18
- data/icons/watobo.ico +0 -0
- data/icons/watobo.ico.old +0 -0
- data/lib/watobo.rb +10 -19
- data/lib/watobo/adapters.rb +5 -14
- data/lib/watobo/adapters/data_store.rb +50 -59
- data/lib/watobo/adapters/file/file_store.rb +287 -296
- data/lib/watobo/adapters/file/marshal_store.rb +293 -296
- data/lib/watobo/adapters/session_store.rb +5 -14
- data/lib/watobo/ca.rb +1 -10
- data/lib/watobo/config.rb +197 -206
- data/lib/watobo/constants.rb +0 -9
- data/lib/watobo/core.rb +3 -12
- data/lib/watobo/core/active_check.rb +72 -135
- data/lib/watobo/core/active_checks.rb +49 -58
- data/lib/watobo/core/ca.rb +369 -389
- data/lib/watobo/core/cert_store.rb +34 -43
- data/lib/watobo/core/chat.rb +92 -101
- data/lib/watobo/core/chats.rb +271 -280
- data/lib/watobo/core/client_cert_store.rb +106 -35
- data/lib/watobo/core/conversation.rb +48 -57
- data/lib/watobo/core/cookie.rb +23 -32
- data/lib/watobo/core/egress_handlers.rb +98 -0
- data/lib/watobo/core/finding.rb +66 -75
- data/lib/watobo/core/findings.rb +107 -114
- data/lib/watobo/core/forwarding_proxy.rb +13 -22
- data/lib/watobo/core/fuzz_gen.rb +0 -9
- data/lib/watobo/core/intercept_carver.rb +166 -177
- data/lib/watobo/core/intercept_filter.rb +235 -244
- data/lib/watobo/core/interceptor.rb +98 -107
- data/lib/watobo/core/min_class.rb +4 -13
- data/lib/watobo/core/netfilter_queue.rb +170 -179
- data/lib/watobo/core/ott_cache.rb +132 -141
- data/lib/watobo/core/parameter.rb +43 -52
- data/lib/watobo/core/passive_check.rb +103 -102
- data/lib/watobo/core/passive_checks.rb +48 -57
- data/lib/watobo/core/passive_scanner.rb +54 -55
- data/lib/watobo/core/plugin.rb +11 -20
- data/lib/watobo/core/project.rb +3 -9
- data/lib/watobo/core/proxy.rb +43 -52
- data/lib/watobo/core/request.rb +125 -123
- data/lib/watobo/core/response.rb +44 -53
- data/lib/watobo/core/scanner.rb +0 -9
- data/lib/watobo/core/scanner3.rb +405 -414
- data/lib/watobo/core/scope.rb +83 -92
- data/lib/watobo/core/session.rb +1043 -1026
- data/lib/watobo/core/sid_cache.rb +98 -107
- data/lib/watobo/core/subscriber.rb +25 -34
- data/lib/watobo/defaults.rb +21 -30
- data/lib/watobo/external/diff/lcs.rb +0 -9
- data/lib/watobo/external/diff/lcs/array.rb +0 -9
- data/lib/watobo/external/diff/lcs/block.rb +0 -9
- data/lib/watobo/external/diff/lcs/callbacks.rb +0 -9
- data/lib/watobo/external/diff/lcs/change.rb +0 -9
- data/lib/watobo/external/diff/lcs/hunk.rb +0 -9
- data/lib/watobo/external/diff/lcs/ldiff.rb +0 -9
- data/lib/watobo/external/diff/lcs/string.rb +0 -9
- data/lib/watobo/externals.rb +6 -15
- data/lib/watobo/framework.rb +4 -13
- data/lib/watobo/framework/create_project.rb +60 -69
- data/lib/watobo/framework/init.rb +0 -9
- data/lib/watobo/framework/init_modules.rb +0 -9
- data/lib/watobo/framework/license_text.rb +28 -37
- data/lib/watobo/framework/load_chat.rb +13 -22
- data/lib/watobo/gui.rb +132 -123
- data/lib/watobo/gui/about_watobo.rb +0 -9
- data/lib/watobo/gui/browser_preview.rb +0 -9
- data/lib/watobo/gui/certificate_dialog.rb +0 -9
- data/lib/watobo/gui/chat_diff.rb +0 -9
- data/lib/watobo/gui/chatviewer_frame.rb +73 -72
- data/lib/watobo/gui/checkboxtree.rb +0 -9
- data/lib/watobo/gui/checks_policy_frame.rb +0 -9
- data/lib/watobo/gui/client_cert_dialog.rb +96 -87
- data/lib/watobo/gui/confirm_scan_dialog.rb +0 -9
- data/lib/watobo/gui/conversation_table.rb +158 -164
- data/lib/watobo/gui/conversation_table_ctrl.rb +207 -216
- data/lib/watobo/gui/conversation_table_ctrl2.rb +373 -382
- data/lib/watobo/gui/csrf_token_dialog.rb +0 -9
- data/lib/watobo/gui/custom_viewer.rb +374 -383
- data/lib/watobo/gui/dashboard.rb +296 -303
- data/lib/watobo/gui/define_scope_frame.rb +0 -9
- data/lib/watobo/gui/differ_frame.rb +215 -224
- data/lib/watobo/gui/edit_comment.rb +0 -9
- data/lib/watobo/gui/edit_scope_dialog.rb +0 -9
- data/lib/watobo/gui/export_dialog.rb +104 -113
- data/lib/watobo/gui/finding_info.rb +0 -9
- data/lib/watobo/gui/findings_tree.rb +210 -217
- data/lib/watobo/gui/full_scan_dialog.rb +0 -9
- data/lib/watobo/gui/fuzzer_gui.rb +1295 -1313
- data/lib/watobo/gui/fxsave_thread.rb +14 -0
- data/lib/watobo/gui/goto_url_dialog.rb +70 -79
- data/lib/watobo/gui/hex_viewer.rb +0 -9
- data/lib/watobo/gui/html_viewer.rb +287 -296
- data/lib/watobo/gui/intercept_filter_dialog.rb +188 -197
- data/lib/watobo/gui/interceptor_gui.rb +1041 -1051
- data/lib/watobo/gui/interceptor_settings_dialog.rb +0 -9
- data/lib/watobo/gui/json_viewer.rb +287 -0
- data/lib/watobo/gui/list_box.rb +101 -110
- data/lib/watobo/gui/log_file_viewer.rb +32 -41
- data/lib/watobo/gui/log_viewer.rb +83 -88
- data/lib/watobo/gui/login_wizzard.rb +0 -9
- data/lib/watobo/gui/main_window.rb +587 -618
- data/lib/watobo/gui/manual_request_editor.rb +620 -565
- data/lib/watobo/gui/master_pw_dialog.rb +0 -9
- data/lib/watobo/gui/mixins/gui_settings.rb +29 -38
- data/lib/watobo/gui/page_tree.rb +217 -226
- data/lib/watobo/gui/password_policy_dialog.rb +0 -9
- data/lib/watobo/gui/plugin_board.rb +0 -9
- data/lib/watobo/gui/preferences_dialog.rb +0 -9
- data/lib/watobo/gui/progress_window.rb +17 -27
- data/lib/watobo/gui/project_wizzard.rb +0 -9
- data/lib/watobo/gui/proxy_dialog.rb +1 -10
- data/lib/watobo/gui/quick_scan_dialog.rb +0 -9
- data/lib/watobo/gui/request_builder_frame.rb +102 -111
- data/lib/watobo/gui/request_editor.rb +181 -137
- data/lib/watobo/gui/rewrite_filters_dialog.rb +394 -403
- data/lib/watobo/gui/rewrite_rules_dialog.rb +372 -381
- data/lib/watobo/gui/save_chat_dialog.rb +140 -149
- data/lib/watobo/gui/scanner_settings_dialog.rb +0 -9
- data/lib/watobo/gui/select_chat_dialog.rb +0 -9
- data/lib/watobo/gui/session_management_dialog.rb +0 -9
- data/lib/watobo/gui/sites_tree.rb +0 -9
- data/lib/watobo/gui/status_bar.rb +0 -9
- data/lib/watobo/gui/table_editor.rb +0 -9
- data/lib/watobo/gui/tagless_viewer.rb +0 -9
- data/lib/watobo/gui/templates/plugin.rb +0 -9
- data/lib/watobo/gui/templates/plugin2.rb +92 -100
- data/lib/watobo/gui/templates/plugin_base.rb +144 -153
- data/lib/watobo/gui/text_viewer.rb +0 -9
- data/lib/watobo/gui/transcoder_window.rb +0 -9
- data/lib/watobo/gui/utils/gui_utils.rb +0 -9
- data/lib/watobo/gui/utils/init_icons.rb +86 -95
- data/lib/watobo/gui/utils/load_icons.rb +33 -42
- data/lib/watobo/gui/utils/load_plugins.rb +116 -119
- data/lib/watobo/gui/utils/master_password.rb +68 -77
- data/lib/watobo/gui/utils/save_default_settings.rb +113 -122
- data/lib/watobo/gui/utils/save_project_settings.rb +0 -9
- data/lib/watobo/gui/utils/save_proxy_settings.rb +41 -50
- data/lib/watobo/gui/utils/save_scanner_settings.rb +18 -27
- data/lib/watobo/gui/utils/session_history.rb +112 -121
- data/lib/watobo/gui/workspace_dialog.rb +0 -9
- data/lib/watobo/gui/www_auth_dialog.rb +0 -9
- data/lib/watobo/gui/xml_viewer_frame.rb +0 -9
- data/lib/watobo/http.rb +4 -13
- data/lib/watobo/http/cookies/cookies.rb +26 -35
- data/lib/watobo/http/data/data.rb +45 -54
- data/lib/watobo/http/data/json.rb +47 -55
- data/lib/watobo/http/url/url.rb +38 -47
- data/lib/watobo/http/xml/xml.rb +124 -130
- data/lib/watobo/interceptor.rb +3 -12
- data/lib/watobo/interceptor/proxy.rb +742 -739
- data/lib/watobo/interceptor/transparent.rb +22 -24
- data/lib/watobo/mixins.rb +10 -19
- data/lib/watobo/mixins/check_info.rb +27 -36
- data/lib/watobo/mixins/httpparser.rb +613 -637
- data/lib/watobo/mixins/request_parser.rb +88 -97
- data/lib/watobo/mixins/shapers.rb +515 -529
- data/lib/watobo/mixins/transcoders.rb +3 -11
- data/lib/watobo/parser.rb +1 -10
- data/lib/watobo/parser/html.rb +83 -92
- data/lib/watobo/patch_fxruby_setfocus.rb +26 -0
- data/lib/watobo/sockets.rb +3 -12
- data/lib/watobo/sockets/agent.rb +828 -837
- data/lib/watobo/sockets/client_socket.rb +308 -312
- data/lib/watobo/sockets/connection.rb +401 -410
- data/lib/watobo/sockets/http_socket.rb +11 -13
- data/lib/watobo/sockets/ntlm_auth.rb +129 -138
- data/lib/watobo/utils.rb +10 -19
- data/lib/watobo/utils/check_regex.rb +0 -9
- data/lib/watobo/utils/copy_object.rb +0 -9
- data/lib/watobo/utils/crypto.rb +0 -9
- data/lib/watobo/utils/expand_range.rb +23 -32
- data/lib/watobo/utils/export_xml.rb +97 -106
- data/lib/watobo/utils/file_management.rb +9 -11
- data/lib/watobo/utils/hexprint.rb +9 -18
- data/lib/watobo/utils/load_chat.rb +0 -9
- data/lib/watobo/utils/load_icon.rb +0 -9
- data/lib/watobo/utils/ntlm.rb +866 -875
- data/lib/watobo/utils/print_debug.rb +12 -21
- data/lib/watobo/utils/response_builder.rb +90 -99
- data/lib/watobo/utils/response_hash.rb +0 -9
- data/lib/watobo/utils/secure_eval.rb +0 -9
- data/lib/watobo/utils/strings.rb +10 -19
- data/lib/watobo/utils/text2request.rb +0 -9
- data/lib/watobo/utils/url.rb +23 -32
- data/lib/watobo/utils/utf16.rb +11 -20
- data/modules/active/Apache/mod_status.rb +0 -9
- data/modules/active/Apache/multiview.rb +151 -160
- data/modules/active/Flash/crossdomain.rb +0 -9
- data/modules/active/JWT/jwt_oauth2_none.rb +111 -0
- data/modules/active/cq5/cq5_default_selectors.rb +106 -115
- data/modules/active/cq5/cqp_user_enumeration.rb +125 -134
- data/modules/active/directories/dirwalker.rb +0 -9
- data/modules/active/discovery/fileextensions.rb +0 -9
- data/modules/active/discovery/http_methods.rb +0 -9
- data/modules/active/discovery/jsmapfiles.rb +79 -0
- data/modules/active/domino/domino_db.rb +68 -76
- data/modules/active/dotNET/custom_errors.rb +102 -111
- data/modules/active/dotNET/dotnet_files.rb +90 -99
- data/modules/active/fileinclusion/lfi_simple.rb +0 -9
- data/modules/active/jboss/jboss_basic.rb +0 -9
- data/modules/active/sap/business_objects.rb +51 -60
- data/modules/active/sap/its_commands.rb +0 -9
- data/modules/active/sap/its_service_parameter.rb +0 -9
- data/modules/active/sap/its_services.rb +0 -9
- data/modules/active/sap/its_xss.rb +0 -9
- data/modules/active/shell_shock/shell_shock.rb +139 -148
- data/modules/active/siebel/siebel_apps.rb +160 -169
- data/modules/active/sqlinjection/sql_boolean.rb +0 -9
- data/modules/active/sqlinjection/sql_numerical.rb +198 -0
- data/modules/active/sqlinjection/sqli_error.rb +0 -9
- data/modules/active/sqlinjection/sqli_timing.rb +220 -229
- data/modules/active/struts2/default_handler_ognl.rb +106 -115
- data/modules/active/struts2/include_params_ognl.rb +105 -114
- data/modules/active/xml/xml_xxe.rb +112 -123
- data/modules/active/xss/xss_ng.rb +214 -223
- data/modules/active/xss/xss_simple.rb +0 -9
- data/modules/passive/ajax.rb +68 -77
- data/modules/passive/autocomplete.rb +56 -65
- data/modules/passive/cookie_options.rb +0 -9
- data/modules/passive/cookie_xss.rb +0 -9
- data/modules/passive/detect_code.rb +0 -9
- data/modules/passive/detect_fileupload.rb +0 -9
- data/modules/passive/detect_infrastructure.rb +0 -9
- data/modules/passive/detect_one_time_tokens.rb +0 -9
- data/modules/passive/dirindexing.rb +0 -9
- data/modules/passive/disclosure_domino.rb +55 -64
- data/modules/passive/disclosure_emails.rb +0 -9
- data/modules/passive/disclosure_ipaddr.rb +55 -53
- data/modules/passive/filename_as_parameter.rb +0 -9
- data/modules/passive/form_spotter.rb +0 -9
- data/modules/passive/hidden_fields.rb +50 -59
- data/modules/passive/hotspots.rb +0 -9
- data/modules/passive/in_script_parameter.rb +0 -9
- data/modules/passive/json_web_token.rb +93 -0
- data/modules/passive/multiple_server_headers.rb +0 -9
- data/modules/passive/possible_login.rb +0 -9
- data/modules/passive/redirect_url.rb +0 -9
- data/modules/passive/redirectionz.rb +0 -9
- data/modules/passive/sap-headers.rb +56 -65
- data/modules/passive/xss_dom.rb +0 -9
- data/plugins/aem/aem.rb +11 -20
- data/plugins/aem/gui/main.rb +118 -127
- data/plugins/aem/gui/tree_view.rb +171 -180
- data/plugins/aem/lib/agent.rb +130 -138
- data/plugins/aem/lib/dispatcher.rb +45 -51
- data/plugins/aem/lib/engine.rb +177 -186
- data/plugins/catalog/catalog.rb +345 -355
- data/plugins/crawler/crawler.rb +4 -13
- data/plugins/crawler/gui.rb +5 -14
- data/plugins/crawler/gui/auth_frame.rb +270 -279
- data/plugins/crawler/gui/crawler_gui.rb +271 -276
- data/plugins/crawler/gui/general_settings_frame.rb +96 -105
- data/plugins/crawler/gui/hooks_frame.rb +80 -89
- data/plugins/crawler/gui/scope_frame.rb +50 -59
- data/plugins/crawler/gui/settings_tabbook.rb +38 -47
- data/plugins/crawler/gui/status_frame.rb +59 -68
- data/plugins/crawler/lib/bags.rb +18 -27
- data/plugins/crawler/lib/constants.rb +11 -20
- data/plugins/crawler/lib/engine.rb +488 -497
- data/plugins/crawler/lib/grabber.rb +68 -77
- data/plugins/crawler/lib/status.rb +71 -80
- data/plugins/crawler/lib/uri_mp.rb +12 -21
- data/plugins/filefinder/filefinder.rb +326 -333
- data/plugins/sqlmap/bin/test.rb +78 -87
- data/plugins/sqlmap/gui.rb +4 -13
- data/plugins/sqlmap/gui/main.rb +218 -227
- data/plugins/sqlmap/gui/options_frame.rb +97 -106
- data/plugins/sqlmap/lib/sqlmap_ctrl.rb +90 -100
- data/plugins/sqlmap/sqlmap.rb +2 -11
- data/plugins/sslchecker/cli/sslchecker_cli.rb +0 -9
- data/plugins/sslchecker/gui/cipher_table.rb +246 -254
- data/plugins/sslchecker/gui/gui.rb +258 -264
- data/plugins/sslchecker/gui/sslchecker.rb +4 -13
- data/plugins/sslchecker/lib/check.rb +127 -133
- data/plugins/wshell/gui/main.rb +119 -117
- data/plugins/wshell/lib/core.rb +38 -88
- data/plugins/wshell/wshell.rb +11 -20
- metadata +170 -164
data/lib/watobo/core/ca.rb
CHANGED
|
@@ -1,19 +1,10 @@
|
|
|
1
|
-
#.
|
|
2
|
-
# ca.rb
|
|
3
|
-
#.
|
|
4
|
-
# Copyright 2014 by siberas, http://www.siberas.de
|
|
5
|
-
# This file is part of WATOBO (Web Application Tool Box) http://watobo.sourceforge.com
|
|
6
|
-
# WATOBO is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation version 2 of the License.
|
|
7
|
-
# WATOBO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
8
|
-
# You should have received a copy of the GNU General Public License along with WATOBO; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
9
|
-
|
|
10
1
|
# @private
|
|
11
|
-
module Watobo#:nodoc: all
|
|
12
|
-
module CA
|
|
13
|
-
@cadir = File.join(Watobo.working_directory, "CA")
|
|
14
|
-
@crl_dir= File.join(@cadir, "crl")
|
|
15
|
-
@hostname = %x('hostname').strip
|
|
16
|
-
@hostname = "watobo" if @hostname.empty?
|
|
2
|
+
module Watobo#:nodoc: all
|
|
3
|
+
module CA
|
|
4
|
+
@cadir = File.join(Watobo.working_directory, "CA")
|
|
5
|
+
@crl_dir= File.join(@cadir, "crl")
|
|
6
|
+
@hostname = %x('hostname').strip
|
|
7
|
+
@hostname = "watobo" if @hostname.empty?
|
|
17
8
|
@domain = "#{@hostname}.watobo.local"
|
|
18
9
|
|
|
19
10
|
def self.dh_key
|
|
@@ -28,383 +19,372 @@ module Watobo#:nodoc: all
|
|
|
28
19
|
end
|
|
29
20
|
OpenSSL::PKey::DH.new(File.read(dh_filename))
|
|
30
21
|
end
|
|
31
|
-
|
|
32
|
-
def self.ca_ready?
|
|
33
|
-
return false unless File.exists? @ca_config[:CA_dir]
|
|
34
|
-
return false unless File.exists? @ca_config[:private_dir]
|
|
35
|
-
return false unless File.exists? @ca_config[:fake_certs_dir]
|
|
36
|
-
return false unless File.exists? @ca_config[:crl_dir]
|
|
37
|
-
return false unless File.exists? @ca_config[:csr_dir]
|
|
38
|
-
return true
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# return 0
|
|
42
|
-
@ca_config = {
|
|
43
|
-
:CA_dir => @cadir,
|
|
44
|
-
# need a password here .... mmmhhhhh ...,
|
|
45
|
-
:password => "watobo",
|
|
46
|
-
|
|
47
|
-
:keypair_file => File.join(@cadir, "private/cakeypair.pem"),
|
|
48
|
-
:cert_file => File.join(@cadir, "cacert.pem"),
|
|
49
|
-
:serial_file => File.join(@cadir, "serial"),
|
|
50
|
-
:fake_certs_dir => File.join(@cadir, "fake_certs"),
|
|
51
|
-
:new_keypair_dir => File.join(@cadir, "private/keypair_backup"),
|
|
52
|
-
:csr_dir => File.join(@cadir, "csr"),
|
|
53
|
-
:crl_dir => File.join(@cadir, 'crl'),
|
|
54
|
-
:private_dir => File.join(@cadir, 'private'), #, 0700
|
|
55
|
-
|
|
56
|
-
:ca_cert_days => 5 * 365, # five years
|
|
57
|
-
:ca_rsa_key_length => 2048,
|
|
58
|
-
|
|
59
|
-
:cert_days => 365, # one year
|
|
60
|
-
:cert_key_length_min => 1024,
|
|
61
|
-
:cert_key_length_max => 2048,
|
|
62
|
-
|
|
63
|
-
:crl_file => File.join(@crl_dir, "#{@hostname}.crl"),
|
|
64
|
-
:crl_pem_file => File.join(@crl_dir, "#{@hostname}.pem"),
|
|
65
|
-
:crl_days => 14,
|
|
66
|
-
:name => [
|
|
67
|
-
['C', 'DE', OpenSSL::ASN1::PRINTABLESTRING],
|
|
22
|
+
|
|
23
|
+
def self.ca_ready?
|
|
24
|
+
return false unless File.exists? @ca_config[:CA_dir]
|
|
25
|
+
return false unless File.exists? @ca_config[:private_dir]
|
|
26
|
+
return false unless File.exists? @ca_config[:fake_certs_dir]
|
|
27
|
+
return false unless File.exists? @ca_config[:crl_dir]
|
|
28
|
+
return false unless File.exists? @ca_config[:csr_dir]
|
|
29
|
+
return true
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# return 0
|
|
33
|
+
@ca_config = {
|
|
34
|
+
:CA_dir => @cadir,
|
|
35
|
+
# need a password here .... mmmhhhhh ...,
|
|
36
|
+
:password => "watobo",
|
|
37
|
+
|
|
38
|
+
:keypair_file => File.join(@cadir, "private/cakeypair.pem"),
|
|
39
|
+
:cert_file => File.join(@cadir, "cacert.pem"),
|
|
40
|
+
:serial_file => File.join(@cadir, "serial"),
|
|
41
|
+
:fake_certs_dir => File.join(@cadir, "fake_certs"),
|
|
42
|
+
:new_keypair_dir => File.join(@cadir, "private/keypair_backup"),
|
|
43
|
+
:csr_dir => File.join(@cadir, "csr"),
|
|
44
|
+
:crl_dir => File.join(@cadir, 'crl'),
|
|
45
|
+
:private_dir => File.join(@cadir, 'private'), #, 0700
|
|
46
|
+
|
|
47
|
+
:ca_cert_days => 5 * 365, # five years
|
|
48
|
+
:ca_rsa_key_length => 2048,
|
|
49
|
+
|
|
50
|
+
:cert_days => 365, # one year
|
|
51
|
+
:cert_key_length_min => 1024,
|
|
52
|
+
:cert_key_length_max => 2048,
|
|
53
|
+
|
|
54
|
+
:crl_file => File.join(@crl_dir, "#{@hostname}.crl"),
|
|
55
|
+
:crl_pem_file => File.join(@crl_dir, "#{@hostname}.pem"),
|
|
56
|
+
:crl_days => 14,
|
|
57
|
+
:name => [
|
|
58
|
+
['C', 'DE', OpenSSL::ASN1::PRINTABLESTRING],
|
|
68
59
|
#['O', @domain, OpenSSL::ASN1::UTF8STRING],
|
|
69
|
-
['O', "WATOBO", OpenSSL::ASN1::UTF8STRING],
|
|
60
|
+
['O', "WATOBO", OpenSSL::ASN1::UTF8STRING],
|
|
70
61
|
# ['OU', @hostname, OpenSSL::ASN1::UTF8STRING],
|
|
71
|
-
['OU', "WATOBO CA", OpenSSL::ASN1::UTF8STRING]
|
|
72
|
-
]
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
unless Watobo::CA.ca_ready? then
|
|
76
|
-
Dir.mkdir(@ca_config[:CA_dir])
|
|
77
|
-
Dir.mkdir @ca_config[:private_dir]
|
|
78
|
-
Dir.mkdir @ca_config[:fake_certs_dir]
|
|
79
|
-
Dir.mkdir @ca_config[:crl_dir]
|
|
80
|
-
Dir.mkdir @ca_config[:csr_dir]
|
|
81
|
-
|
|
82
|
-
#
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
#
|
|
87
|
-
|
|
88
|
-
#puts "done!"
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
cert = OpenSSL::X509::
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
cert.
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
cert.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
ef =
|
|
104
|
-
ef.
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
ef.create_extension("
|
|
108
|
-
|
|
109
|
-
ef.create_extension("
|
|
110
|
-
ef.create_extension("
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
fh.
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
puts
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
62
|
+
['OU', "WATOBO CA", OpenSSL::ASN1::UTF8STRING]
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
unless Watobo::CA.ca_ready? then
|
|
67
|
+
Dir.mkdir(@ca_config[:CA_dir])
|
|
68
|
+
Dir.mkdir @ca_config[:private_dir]
|
|
69
|
+
Dir.mkdir @ca_config[:fake_certs_dir]
|
|
70
|
+
Dir.mkdir @ca_config[:crl_dir]
|
|
71
|
+
Dir.mkdir @ca_config[:csr_dir]
|
|
72
|
+
#print "Generating CA keypair ..."
|
|
73
|
+
#puts " - rsa_key_length: " + @ca_config[:ca_rsa_key_length].to_s
|
|
74
|
+
keypair = OpenSSL::PKey::RSA.new(@ca_config[:ca_rsa_key_length])
|
|
75
|
+
#puts "done!"
|
|
76
|
+
|
|
77
|
+
#print "Create Certificate ..."
|
|
78
|
+
cert = OpenSSL::X509::Certificate.new
|
|
79
|
+
#puts "done!"
|
|
80
|
+
name = @ca_config[:name].dup << ['CN', 'Watobo']
|
|
81
|
+
|
|
82
|
+
cert.subject = cert.issuer = OpenSSL::X509::Name.new(name)
|
|
83
|
+
cert.not_before = Time.now - 24 * 60 * 60
|
|
84
|
+
cert.not_after = Time.now + @ca_config[:ca_cert_days] * 24 * 60 * 60
|
|
85
|
+
cert.public_key = keypair.public_key
|
|
86
|
+
|
|
87
|
+
serial = Time.now.to_i
|
|
88
|
+
cert.serial = serial
|
|
89
|
+
File.open @ca_config[:serial_file], 'w' do |f| f << "#{(serial + 1)}" end
|
|
90
|
+
|
|
91
|
+
cert.version = 2 # X509v3
|
|
92
|
+
# puts "Init ExtensionFactory ..."
|
|
93
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
|
94
|
+
ef.subject_certificate = cert
|
|
95
|
+
ef.issuer_certificate = cert
|
|
96
|
+
cert.extensions = [
|
|
97
|
+
ef.create_extension("basicConstraints","CA:TRUE", true),
|
|
98
|
+
# ef.create_extension("nsComment","Ruby/OpenSSL Generated Certificate"),
|
|
99
|
+
ef.create_extension("nsComment","WATOBO CA"),
|
|
100
|
+
ef.create_extension("subjectKeyIdentifier", "hash"),
|
|
101
|
+
ef.create_extension("keyUsage", "cRLSign,keyCertSign", true),
|
|
102
|
+
]
|
|
103
|
+
cert.add_extension ef.create_extension("authorityKeyIdentifier",
|
|
104
|
+
"keyid:always,issuer:always")
|
|
105
|
+
# puts "Sign Certificate ..."
|
|
106
|
+
cert.sign keypair, OpenSSL::Digest::SHA1.new
|
|
107
|
+
|
|
108
|
+
cb = proc do @ca_config[:password] end
|
|
109
|
+
keypair_export = keypair.export OpenSSL::Cipher::DES.new(:EDE3, :CBC),
|
|
110
|
+
&cb
|
|
111
|
+
|
|
112
|
+
#puts "Writing keypair to #{@ca_config[:keypair_file]}"
|
|
113
|
+
begin
|
|
114
|
+
fh = File.open(@ca_config[:keypair_file], "w+")
|
|
115
|
+
|
|
116
|
+
fh.puts keypair_export
|
|
117
|
+
fh.close
|
|
118
|
+
rescue => bang
|
|
119
|
+
puts "! Could not write keypair"
|
|
120
|
+
puts bang
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
#puts "Writing cert to #{@ca_config[:cert_file]}"
|
|
124
|
+
File.open @ca_config[:cert_file], "w", 0644 do |f|
|
|
125
|
+
f << cert.to_pem
|
|
126
|
+
end
|
|
127
|
+
|
|
138
128
|
puts "Done generating certificate for #{cert.subject}"
|
|
139
129
|
puts ">> create DH key ..."
|
|
140
|
-
dh_key
|
|
141
|
-
else
|
|
142
|
-
#puts "Open Cert File ..."
|
|
143
|
-
raw = File.read @ca_config[:cert_file] # DER- or PEM-encoded
|
|
144
|
-
cert = OpenSSL::X509::Certificate.new raw
|
|
145
|
-
# puts cert
|
|
146
|
-
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
def self.create_cert(cert_config)
|
|
150
|
-
# puts " ... keypair ..."
|
|
151
|
-
cert_keypair = create_key(cert_config)
|
|
152
|
-
# puts "... csr ..."
|
|
153
|
-
cert_csr = create_csr(cert_config, cert_keypair)
|
|
154
|
-
# puts "... signing ..."
|
|
155
|
-
signed_cert = sign_cert(cert_config, cert_keypair, cert_csr)
|
|
156
|
-
return signed_cert, cert_keypair
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
##
|
|
160
|
-
# Creates a new RSA key from +cert_config+.
|
|
161
|
-
|
|
162
|
-
def self.create_key(cert_config)
|
|
163
|
-
#passwd_cb = nil
|
|
164
|
-
target = cert_config[:hostname] || cert_config[:user]
|
|
165
|
-
# puts target
|
|
166
|
-
dest = @ca_config[:fake_certs_dir]
|
|
167
|
-
# puts dest
|
|
168
|
-
keypair_file = File.join(dest, (target + "_keypair.pem"))
|
|
169
|
-
keypair_file.gsub!(/\*/,"_")
|
|
170
|
-
|
|
171
|
-
return keypair_file if File.exist? keypair_file
|
|
172
|
-
|
|
173
|
-
#puts "create_key: #{keypair_file}"
|
|
174
|
-
begin
|
|
175
|
-
Dir.mkdir dest #, 0700
|
|
176
|
-
rescue Errno::EEXIST
|
|
177
|
-
# puts "directory exists"
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
if not File.exists?(keypair_file) then
|
|
181
|
-
#puts "Generating RSA keypair" if $DEBUG
|
|
182
|
-
keypair = OpenSSL::PKey::RSA.new 1024
|
|
183
|
-
# puts keypair.to_pem.class
|
|
184
|
-
|
|
185
|
-
if cert_config[:password].nil? then
|
|
186
|
-
# puts "no password for cert"
|
|
187
|
-
# puts "Writing keypair to #{keypair_file}" if $DEBUG
|
|
188
|
-
begin
|
|
189
|
-
dummy = keypair.to_pem.split("\n")
|
|
190
|
-
dummy.each do |line|
|
|
191
|
-
line.strip!
|
|
192
|
-
end
|
|
193
|
-
fh = File.open( keypair_file, "wb" )
|
|
194
|
-
fh.write dummy.join("\n")
|
|
195
|
-
fh.close
|
|
196
|
-
rescue => bang
|
|
197
|
-
puts "! Could not write keypair"
|
|
198
|
-
puts bang
|
|
199
|
-
puts bang.backtrace
|
|
200
|
-
end
|
|
201
|
-
else
|
|
202
|
-
# passwd_cb = proc do cert_config[:password] end
|
|
203
|
-
keypair_export = keypair.export OpenSSL::Cipher::DES.new(:EDE3, :CBC), cert_config[:password]
|
|
204
|
-
|
|
205
|
-
# puts "Writing keypair to #{keypair_file}" if $DEBUG
|
|
206
|
-
#File.open keypair_file, "w" do |f|
|
|
207
|
-
# f << keypair_export
|
|
208
|
-
#end
|
|
209
|
-
begin
|
|
210
|
-
fh = File.open( keypair_file, "w" )
|
|
211
|
-
fh.puts keypair_export
|
|
212
|
-
fh.close
|
|
213
|
-
rescue => bang
|
|
214
|
-
|
|
215
|
-
puts "! Could not write keypair"
|
|
216
|
-
puts bang
|
|
217
|
-
puts bang.backtrace
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
end
|
|
221
|
-
end
|
|
222
|
-
return keypair_file
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
##
|
|
226
|
-
# Signs the certificate described in +cert_config+ and
|
|
227
|
-
# +csr_file+, saving it to +cert_file+.
|
|
228
|
-
|
|
229
|
-
def self.sign_cert(cert_config, cert_file, csr_file)
|
|
230
|
-
|
|
231
|
-
target = cert_config[:hostname] || cert_config[:user]
|
|
232
|
-
dest = @ca_config[:fake_certs_dir]
|
|
233
|
-
cert_file = File.join dest, "#{target}_cert.pem"
|
|
234
|
-
cert_file.gsub!(/\*/,"_")
|
|
235
|
-
return cert_file if File.exist? cert_file
|
|
236
|
-
|
|
237
|
-
csr = OpenSSL::X509::Request.new File.read(csr_file)
|
|
238
|
-
|
|
239
|
-
raise "CSR sign verification failed." unless csr.verify csr.public_key
|
|
240
|
-
|
|
241
|
-
if csr.public_key.n.num_bits < @ca_config[:cert_key_length_min] then
|
|
242
|
-
raise "Key length too short"
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
if csr.public_key.n.num_bits > @ca_config[:cert_key_length_max] then
|
|
246
|
-
raise "Key length too long"
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
if csr.subject.to_a[0, @ca_config[:name].size] != @ca_config[:name] then
|
|
250
|
-
raise "DN does not match"
|
|
251
|
-
end
|
|
252
|
-
|
|
253
|
-
# Only checks signature here. You must verify CSR according to your
|
|
254
|
-
# CP/CPS.
|
|
255
|
-
|
|
256
|
-
# CA setup
|
|
257
|
-
|
|
258
|
-
puts "Reading CA cert from #{@ca_config[:cert_file]}" if $DEBUG
|
|
259
|
-
ca = OpenSSL::X509::Certificate.new File.read(@ca_config[:cert_file])
|
|
260
|
-
|
|
261
|
-
puts "Reading CA keypair from #{@ca_config[:keypair_file]}" if $DEBUG
|
|
262
|
-
ca_keypair = OpenSSL::PKey::RSA.new File.read(@ca_config[:keypair_file]),
|
|
263
|
-
@ca_config[:password]
|
|
264
|
-
|
|
265
|
-
serial = File.read(@ca_config[:serial_file]).chomp.hex
|
|
266
|
-
File.open @ca_config[:serial_file], "w" do |f|
|
|
267
|
-
f << "%04X" % (serial + 1)
|
|
268
|
-
end
|
|
269
|
-
|
|
270
|
-
puts "Generating cert" if $DEBUG
|
|
271
|
-
|
|
272
|
-
cert = OpenSSL::X509::Certificate.new
|
|
273
|
-
from = Time.now
|
|
274
|
-
cert.subject = csr.subject
|
|
275
|
-
cert.issuer = ca.subject
|
|
276
|
-
cert.not_before = from
|
|
277
|
-
cert.not_after = from + @ca_config[:cert_days] * 24 * 60 * 60
|
|
278
|
-
cert.public_key = csr.public_key
|
|
279
|
-
cert.serial = serial
|
|
280
|
-
cert.version = 2 # X509v3
|
|
281
|
-
|
|
282
|
-
basic_constraint = nil
|
|
283
|
-
key_usage = []
|
|
284
|
-
ext_key_usage = []
|
|
285
|
-
|
|
286
|
-
case cert_config[:type]
|
|
287
|
-
when "ca" then
|
|
288
|
-
basic_constraint = "CA:TRUE"
|
|
289
|
-
key_usage << "cRLSign" << "keyCertSign"
|
|
290
|
-
when "terminalsubca" then
|
|
291
|
-
basic_constraint = "CA:TRUE,pathlen:0"
|
|
292
|
-
key_usage << "cRLSign" << "keyCertSign"
|
|
293
|
-
when "server" then
|
|
294
|
-
basic_constraint = "CA:FALSE"
|
|
295
|
-
key_usage << "digitalSignature" << "keyEncipherment"
|
|
296
|
-
ext_key_usage << "serverAuth"
|
|
297
|
-
when "ocsp" then
|
|
298
|
-
basic_constraint = "CA:FALSE"
|
|
299
|
-
key_usage << "nonRepudiation" << "digitalSignature"
|
|
300
|
-
ext_key_usage << "serverAuth" << "OCSPSigning"
|
|
301
|
-
when "client" then
|
|
302
|
-
basic_constraint = "CA:FALSE"
|
|
303
|
-
key_usage << "nonRepudiation" << "digitalSignature" << "keyEncipherment"
|
|
304
|
-
ext_key_usage << "clientAuth" << "emailProtection"
|
|
305
|
-
else
|
|
306
|
-
raise "unknonw cert type \"#{cert_config[:type]}\""
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
ef = OpenSSL::X509::ExtensionFactory.new
|
|
310
|
-
ef.subject_certificate = cert
|
|
311
|
-
ef.issuer_certificate = ca
|
|
312
|
-
ex = []
|
|
313
|
-
ex << ef.create_extension("basicConstraints", basic_constraint, true)
|
|
314
|
-
ex << ef.create_extension("nsComment",
|
|
315
|
-
"Ruby/OpenSSL Generated Certificate")
|
|
316
|
-
ex << ef.create_extension("subjectKeyIdentifier", "hash")
|
|
317
|
-
#ex << ef.create_extension("nsCertType", "client,email")
|
|
318
|
-
unless key_usage.empty? then
|
|
319
|
-
ex << ef.create_extension("keyUsage", key_usage.join(","))
|
|
320
|
-
end
|
|
321
|
-
#ex << ef.create_extension("authorityKeyIdentifier",
|
|
322
|
-
# "keyid:always,issuer:always")
|
|
323
|
-
#ex << ef.create_extension("authorityKeyIdentifier", "keyid:always")
|
|
324
|
-
unless ext_key_usage.empty? then
|
|
325
|
-
ex << ef.create_extension("extendedKeyUsage", ext_key_usage.join(","))
|
|
326
|
-
end
|
|
327
|
-
|
|
328
|
-
if @ca_config[:cdp_location] then
|
|
329
|
-
ex << ef.create_extension("crlDistributionPoints",
|
|
330
|
-
@ca_config[:cdp_location])
|
|
331
|
-
end
|
|
332
|
-
|
|
333
|
-
if @ca_config[:ocsp_location] then
|
|
334
|
-
ex << ef.create_extension("authorityInfoAccess",
|
|
335
|
-
"OCSP;" << @ca_config[:ocsp_location])
|
|
336
|
-
end
|
|
337
|
-
# cert.extensions = ex
|
|
338
|
-
cert.sign ca_keypair, OpenSSL::Digest::SHA1.new
|
|
339
|
-
|
|
340
|
-
# backup_cert_file = @ca_config[:backup_certs_dir] + "/cert_#{cert.serial}.pem"
|
|
341
|
-
# puts "Writing backup cert to #{backup_cert_file}" if $DEBUG
|
|
342
|
-
# File.open backup_cert_file, "w", 0644 do |f|
|
|
343
|
-
# f << cert.to_pem
|
|
344
|
-
# end
|
|
345
|
-
|
|
346
|
-
# Write cert
|
|
347
|
-
puts "Writing cert to #{cert_file}"
|
|
348
|
-
File.open cert_file, "w", 0644 do |f|
|
|
349
|
-
f << cert.to_pem
|
|
350
|
-
end
|
|
351
|
-
|
|
352
|
-
return cert_file
|
|
353
|
-
end
|
|
354
|
-
|
|
355
|
-
##
|
|
356
|
-
# Creates a new Certificate Signing Request for the keypair in
|
|
357
|
-
# +keypair_file+, generating and saving new keypair if nil.
|
|
358
|
-
|
|
359
|
-
def self.create_csr(cert_config, keypair_file = nil)
|
|
360
|
-
keypair = nil
|
|
361
|
-
target = cert_config[:hostname] || cert_config[:user]
|
|
362
|
-
dest = @ca_config[:csr_dir]
|
|
363
|
-
csr_file = File.join dest, "csr_#{target}.pem"
|
|
364
|
-
csr_file.gsub!(/\*/,"_")
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
when 'server' then
|
|
371
|
-
# name << ['OU', 'Watobo CA']
|
|
130
|
+
dh_key
|
|
131
|
+
else
|
|
132
|
+
#puts "Open Cert File ..."
|
|
133
|
+
raw = File.read @ca_config[:cert_file] # DER- or PEM-encoded
|
|
134
|
+
cert = OpenSSL::X509::Certificate.new raw
|
|
135
|
+
# puts cert
|
|
136
|
+
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def self.create_cert(cert_config)
|
|
140
|
+
# puts " ... keypair ..."
|
|
141
|
+
cert_keypair = create_key(cert_config)
|
|
142
|
+
# puts "... csr ..."
|
|
143
|
+
cert_csr = create_csr(cert_config, cert_keypair)
|
|
144
|
+
# puts "... signing ..."
|
|
145
|
+
signed_cert = sign_cert(cert_config, cert_keypair, cert_csr)
|
|
146
|
+
return signed_cert, cert_keypair
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
##
|
|
150
|
+
# Creates a new RSA key from +cert_config+.
|
|
151
|
+
|
|
152
|
+
def self.create_key(cert_config)
|
|
153
|
+
#passwd_cb = nil
|
|
154
|
+
target = cert_config[:hostname] || cert_config[:user]
|
|
155
|
+
# puts target
|
|
156
|
+
dest = @ca_config[:fake_certs_dir]
|
|
157
|
+
# puts dest
|
|
158
|
+
keypair_file = File.join(dest, (target + "_keypair.pem"))
|
|
159
|
+
keypair_file.gsub!(/\*/,"_")
|
|
160
|
+
|
|
161
|
+
return keypair_file if File.exist? keypair_file
|
|
162
|
+
|
|
163
|
+
#puts "create_key: #{keypair_file}"
|
|
164
|
+
begin
|
|
165
|
+
Dir.mkdir dest #, 0700
|
|
166
|
+
rescue Errno::EEXIST
|
|
167
|
+
# puts "directory exists"
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
if not File.exists?(keypair_file) then
|
|
171
|
+
#puts "Generating RSA keypair" if $DEBUG
|
|
172
|
+
keypair = OpenSSL::PKey::RSA.new 1024
|
|
173
|
+
# puts keypair.to_pem.class
|
|
174
|
+
|
|
175
|
+
if cert_config[:password].nil? then
|
|
176
|
+
# puts "no password for cert"
|
|
177
|
+
# puts "Writing keypair to #{keypair_file}" if $DEBUG
|
|
178
|
+
begin
|
|
179
|
+
dummy = keypair.to_pem.split("\n")
|
|
180
|
+
dummy.each do |line|
|
|
181
|
+
line.strip!
|
|
182
|
+
end
|
|
183
|
+
fh = File.open( keypair_file, "wb" )
|
|
184
|
+
fh.write dummy.join("\n")
|
|
185
|
+
fh.close
|
|
186
|
+
rescue => bang
|
|
187
|
+
puts "! Could not write keypair"
|
|
188
|
+
puts bang
|
|
189
|
+
puts bang.backtrace
|
|
190
|
+
end
|
|
191
|
+
else
|
|
192
|
+
# passwd_cb = proc do cert_config[:password] end
|
|
193
|
+
keypair_export = keypair.export OpenSSL::Cipher::DES.new(:EDE3, :CBC), cert_config[:password]
|
|
194
|
+
|
|
195
|
+
# puts "Writing keypair to #{keypair_file}" if $DEBUG
|
|
196
|
+
#File.open keypair_file, "w" do |f|
|
|
197
|
+
# f << keypair_export
|
|
198
|
+
#end
|
|
199
|
+
begin
|
|
200
|
+
fh = File.open( keypair_file, "w" )
|
|
201
|
+
fh.puts keypair_export
|
|
202
|
+
fh.close
|
|
203
|
+
rescue => bang
|
|
204
|
+
|
|
205
|
+
puts "! Could not write keypair"
|
|
206
|
+
puts bang
|
|
207
|
+
puts bang.backtrace
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
return keypair_file
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
##
|
|
216
|
+
# Signs the certificate described in +cert_config+ and
|
|
217
|
+
# +csr_file+, saving it to +cert_file+.
|
|
218
|
+
|
|
219
|
+
def self.sign_cert(cert_config, cert_file, csr_file)
|
|
220
|
+
|
|
221
|
+
target = cert_config[:hostname] || cert_config[:user]
|
|
222
|
+
dest = @ca_config[:fake_certs_dir]
|
|
223
|
+
cert_file = File.join dest, "#{target}_cert.pem"
|
|
224
|
+
cert_file.gsub!(/\*/,"_")
|
|
225
|
+
return cert_file if File.exist? cert_file
|
|
226
|
+
|
|
227
|
+
csr = OpenSSL::X509::Request.new File.read(csr_file)
|
|
228
|
+
|
|
229
|
+
raise "CSR sign verification failed." unless csr.verify csr.public_key
|
|
230
|
+
|
|
231
|
+
if csr.public_key.n.num_bits < @ca_config[:cert_key_length_min] then
|
|
232
|
+
raise "Key length too short"
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
if csr.public_key.n.num_bits > @ca_config[:cert_key_length_max] then
|
|
236
|
+
raise "Key length too long"
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
if csr.subject.to_a[0, @ca_config[:name].size] != @ca_config[:name] then
|
|
240
|
+
raise "DN does not match"
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# Only checks signature here. You must verify CSR according to your
|
|
244
|
+
# CP/CPS.
|
|
245
|
+
|
|
246
|
+
# CA setup
|
|
247
|
+
|
|
248
|
+
puts "Reading CA cert from #{@ca_config[:cert_file]}" if $DEBUG
|
|
249
|
+
ca = OpenSSL::X509::Certificate.new File.read(@ca_config[:cert_file])
|
|
250
|
+
|
|
251
|
+
puts "Reading CA keypair from #{@ca_config[:keypair_file]}" if $DEBUG
|
|
252
|
+
ca_keypair = OpenSSL::PKey::RSA.new File.read(@ca_config[:keypair_file]),
|
|
253
|
+
@ca_config[:password]
|
|
254
|
+
|
|
255
|
+
serial = File.read(@ca_config[:serial_file]).chomp.hex
|
|
256
|
+
File.open @ca_config[:serial_file], "w" do |f|
|
|
257
|
+
f << "%04X" % (serial + 1)
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
puts "Generating cert" if $DEBUG
|
|
261
|
+
|
|
262
|
+
cert = OpenSSL::X509::Certificate.new
|
|
263
|
+
from = Time.now
|
|
264
|
+
cert.subject = csr.subject
|
|
265
|
+
cert.issuer = ca.subject
|
|
266
|
+
cert.not_before = from
|
|
267
|
+
cert.not_after = from + @ca_config[:cert_days] * 24 * 60 * 60
|
|
268
|
+
cert.public_key = csr.public_key
|
|
269
|
+
cert.serial = serial
|
|
270
|
+
cert.version = 2 # X509v3
|
|
271
|
+
|
|
272
|
+
basic_constraint = nil
|
|
273
|
+
key_usage = []
|
|
274
|
+
ext_key_usage = []
|
|
275
|
+
|
|
276
|
+
case cert_config[:type]
|
|
277
|
+
when "ca" then
|
|
278
|
+
basic_constraint = "CA:TRUE"
|
|
279
|
+
key_usage << "cRLSign" << "keyCertSign"
|
|
280
|
+
when "terminalsubca" then
|
|
281
|
+
basic_constraint = "CA:TRUE,pathlen:0"
|
|
282
|
+
key_usage << "cRLSign" << "keyCertSign"
|
|
283
|
+
when "server" then
|
|
284
|
+
basic_constraint = "CA:FALSE"
|
|
285
|
+
key_usage << "digitalSignature" << "keyEncipherment"
|
|
286
|
+
ext_key_usage << "serverAuth"
|
|
287
|
+
when "ocsp" then
|
|
288
|
+
basic_constraint = "CA:FALSE"
|
|
289
|
+
key_usage << "nonRepudiation" << "digitalSignature"
|
|
290
|
+
ext_key_usage << "serverAuth" << "OCSPSigning"
|
|
291
|
+
when "client" then
|
|
292
|
+
basic_constraint = "CA:FALSE"
|
|
293
|
+
key_usage << "nonRepudiation" << "digitalSignature" << "keyEncipherment"
|
|
294
|
+
ext_key_usage << "clientAuth" << "emailProtection"
|
|
295
|
+
else
|
|
296
|
+
raise "unknonw cert type \"#{cert_config[:type]}\""
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
|
300
|
+
ef.subject_certificate = cert
|
|
301
|
+
ef.issuer_certificate = ca
|
|
302
|
+
ex = []
|
|
303
|
+
ex << ef.create_extension("basicConstraints", basic_constraint, true)
|
|
304
|
+
ex << ef.create_extension("nsComment",
|
|
305
|
+
"Ruby/OpenSSL Generated Certificate")
|
|
306
|
+
ex << ef.create_extension("subjectKeyIdentifier", "hash")
|
|
307
|
+
#ex << ef.create_extension("nsCertType", "client,email")
|
|
308
|
+
unless key_usage.empty? then
|
|
309
|
+
ex << ef.create_extension("keyUsage", key_usage.join(","))
|
|
310
|
+
end
|
|
311
|
+
#ex << ef.create_extension("authorityKeyIdentifier",
|
|
312
|
+
# "keyid:always,issuer:always")
|
|
313
|
+
#ex << ef.create_extension("authorityKeyIdentifier", "keyid:always")
|
|
314
|
+
unless ext_key_usage.empty? then
|
|
315
|
+
ex << ef.create_extension("extendedKeyUsage", ext_key_usage.join(","))
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
if @ca_config[:cdp_location] then
|
|
319
|
+
ex << ef.create_extension("crlDistributionPoints",
|
|
320
|
+
@ca_config[:cdp_location])
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
if @ca_config[:ocsp_location] then
|
|
324
|
+
ex << ef.create_extension("authorityInfoAccess",
|
|
325
|
+
"OCSP;" << @ca_config[:ocsp_location])
|
|
326
|
+
end
|
|
327
|
+
# cert.extensions = ex
|
|
328
|
+
cert.sign ca_keypair, OpenSSL::Digest::SHA1.new
|
|
329
|
+
|
|
330
|
+
# backup_cert_file = @ca_config[:backup_certs_dir] + "/cert_#{cert.serial}.pem"
|
|
331
|
+
# puts "Writing backup cert to #{backup_cert_file}" if $DEBUG
|
|
332
|
+
# File.open backup_cert_file, "w", 0644 do |f|
|
|
333
|
+
# f << cert.to_pem
|
|
334
|
+
# end
|
|
335
|
+
|
|
336
|
+
# Write cert
|
|
337
|
+
puts "Writing cert to #{cert_file}"
|
|
338
|
+
File.open cert_file, "w", 0644 do |f|
|
|
339
|
+
f << cert.to_pem
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
return cert_file
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
##
|
|
346
|
+
# Creates a new Certificate Signing Request for the keypair in
|
|
347
|
+
# +keypair_file+, generating and saving new keypair if nil.
|
|
348
|
+
|
|
349
|
+
def self.create_csr(cert_config, keypair_file = nil)
|
|
350
|
+
keypair = nil
|
|
351
|
+
target = cert_config[:hostname] || cert_config[:user]
|
|
352
|
+
dest = @ca_config[:csr_dir]
|
|
353
|
+
csr_file = File.join dest, "csr_#{target}.pem"
|
|
354
|
+
csr_file.gsub!(/\*/,"_")
|
|
355
|
+
|
|
356
|
+
name = @ca_config[:name].dup
|
|
357
|
+
case cert_config[:type]
|
|
358
|
+
when 'server' then
|
|
359
|
+
# name << ['OU', 'Watobo CA']
|
|
372
360
|
name << ['CN', cert_config[:hostname]]
|
|
373
|
-
#name << ['CN', "WATOBO"]
|
|
374
|
-
when 'client' then
|
|
375
|
-
name << ['CN', cert_config[:user]]
|
|
376
|
-
name << ['emailAddress', cert_config[:email]]
|
|
377
|
-
end
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
f << req.to_pem
|
|
403
|
-
end
|
|
404
|
-
|
|
405
|
-
return csr_file
|
|
406
|
-
end
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
end
|
|
361
|
+
#name << ['CN', "WATOBO"]
|
|
362
|
+
when 'client' then
|
|
363
|
+
name << ['CN', cert_config[:user]]
|
|
364
|
+
name << ['emailAddress', cert_config[:email]]
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
name = OpenSSL::X509::Name.new(name)
|
|
368
|
+
|
|
369
|
+
if File.exists? keypair_file then
|
|
370
|
+
keypair = OpenSSL::PKey::RSA.new(File.read(keypair_file), cert_config[:password])
|
|
371
|
+
else
|
|
372
|
+
keypair = create_key(cert_config)
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
req = OpenSSL::X509::Request.new
|
|
376
|
+
req.version = 0
|
|
377
|
+
req.subject = name
|
|
378
|
+
req.public_key = keypair.public_key
|
|
379
|
+
req.sign keypair, OpenSSL::Digest::MD5.new
|
|
380
|
+
|
|
381
|
+
File.open csr_file, "w" do |f|
|
|
382
|
+
f << req.to_pem
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
return csr_file
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
end
|
|
410
390
|
end
|