aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelijah <elijah@riseup.net>2013-01-21 22:51:01 -0800
committerelijah <elijah@riseup.net>2013-01-21 22:51:01 -0800
commit1591a04c8a053b8d1e37c589d6e967b86c68c983 (patch)
treef1a13eb51260f7a0a384e8e02a965402aede37ee
parent0621d780676c8f78a7205a4350f9e5d6b6a6ec5e (diff)
downloadleap_cli-1591a04c8a053b8d1e37c589d6e967b86c68c983.tar.gz
leap_cli-1591a04c8a053b8d1e37c589d6e967b86c68c983.tar.bz2
added client ca in addition to normal ca (used only to generate client certificates)
-rw-r--r--lib/leap_cli/commands/ca.rb117
-rw-r--r--lib/leap_cli/path.rb2
2 files changed, 66 insertions, 53 deletions
diff --git a/lib/leap_cli/commands/ca.rb b/lib/leap_cli/commands/ca.rb
index 20a5fa7..7c6fc4d 100644
--- a/lib/leap_cli/commands/ca.rb
+++ b/lib/leap_cli/commands/ca.rb
@@ -8,42 +8,12 @@ module LeapCli; module Commands
desc "Manage X.509 certificates"
command :cert do |cert|
- cert.desc 'Creates a Certificate Authority (private key and CA certificate)'
+ cert.desc 'Creates two Certificate Authorities (one for validating servers and one for validating clients).'
cert.command :ca do |ca|
ca.action do |global_options,options,args|
- assert_files_missing! :ca_cert, :ca_key
assert_config! 'provider.ca.name'
- assert_config! 'provider.ca.bit_size'
- assert_config! 'provider.ca.life_span'
-
- provider = manager.provider
- root = CertificateAuthority::Certificate.new
-
- # set subject
- root.subject.common_name = provider.ca.name
- possible = ['country', 'state', 'locality', 'organization', 'organizational_unit', 'email_address']
- provider.ca.keys.each do |key|
- if possible.include?(key)
- root.subject.send(key + '=', provider.ca[key])
- end
- end
-
- # set expiration
- root.not_before = yesterday
- root.not_after = years_from_yesterday(provider.ca.life_span.to_i)
-
- # generate private key
- root.serial_number.number = 1
- root.key_material.generate_key(provider.ca.bit_size)
-
- # sign self
- root.signing_entity = true
- root.parent = root
- root.sign!(ca_root_signing_profile)
-
- # save
- write_file!(:ca_key, root.key_material.private_key.to_pem)
- write_file!(:ca_cert, root.to_pem)
+ generate_new_certificate_authority(:ca_key, :ca_cert, provider.ca.name)
+ generate_new_certificate_authority(:client_ca_key, :client_ca_cert, provider.ca.name + ' (client certificates only!)')
end
end
@@ -118,29 +88,29 @@ module LeapCli; module Commands
assert_config! 'provider.default_language'
assert_config! 'provider.ca.server_certificates.bit_size'
assert_config! 'provider.ca.server_certificates.digest'
- assert_files_missing! [:commercial_key, manager.provider.domain], [:commercial_csr, manager.provider.domain], :msg => 'If you really want to create a new key and CSR, remove these files first.'
- if options[:sign]
- assert_files_exist! :ca_cert, :ca_key, :msg => 'Run `leap cert ca` to create them'
- end
+ assert_files_missing! [:commercial_key, provider.domain], [:commercial_csr, provider.domain], :msg => 'If you really want to create a new key and CSR, remove these files first.'
+ #if options[:sign]
+ # assert_files_exist! :ca_cert, :ca_key, :msg => 'Run `leap cert ca` to create them'
+ #end
# RSA key
keypair = CertificateAuthority::MemoryKeyMaterial.new
- log :generating, "%s bit RSA key" % manager.provider.ca.server_certificates.bit_size do
- keypair.generate_key(manager.provider.ca.server_certificates.bit_size)
- write_file! [:commercial_key, manager.provider.domain], keypair.private_key.to_pem
+ log :generating, "%s bit RSA key" % provider.ca.server_certificates.bit_size do
+ keypair.generate_key(provider.ca.server_certificates.bit_size)
+ write_file! [:commercial_key, provider.domain], keypair.private_key.to_pem
end
# CSR
dn = CertificateAuthority::DistinguishedName.new
csr = CertificateAuthority::SigningRequest.new
- dn.common_name = manager.provider.domain
- dn.organization = manager.provider.name[manager.provider.default_language]
+ dn.common_name = provider.domain
+ dn.organization = provider.name[provider.default_language]
log :generating, "CSR with commonName => '%s', organization => '%s'" % [dn.common_name, dn.organization] do
csr.distinguished_name = dn
csr.key_material = keypair
- csr.digest = manager.provider.ca.server_certificates.digest
+ csr.digest = provider.ca.server_certificates.digest
request = csr.to_x509_csr
- write_file! [:commercial_csr, manager.provider.domain], csr.to_pem
+ write_file! [:commercial_csr, provider.domain], csr.to_pem
end
# Sign using our own CA, for use in testing but hopefully not production.
@@ -149,13 +119,13 @@ module LeapCli; module Commands
#if options[:sign]
log :generating, "self-signed x509 server certificate for testing purposes" do
cert = csr.to_cert
- cert.serial_number.number = cert_serial_number(manager.provider.domain)
+ cert.serial_number.number = cert_serial_number(provider.domain)
cert.not_before = yesterday
cert.not_after = years_from_yesterday(1)
cert.parent = ca_root
cert.sign! domain_test_signing_profile
- write_file! [:commercial_cert, manager.provider.domain], cert.to_pem
- log "please replace this file with the real certificate you get from a CA using #{Path.relative_path([:commercial_csr, manager.provider.domain])}"
+ write_file! [:commercial_cert, provider.domain], cert.to_pem
+ log "please replace this file with the real certificate you get from a CA using #{Path.relative_path([:commercial_csr, provider.domain])}"
end
#end
@@ -172,6 +142,41 @@ module LeapCli; module Commands
private
+ def generate_new_certificate_authority(key_file, cert_file, common_name)
+ assert_files_missing! key_file, cert_file
+ assert_config! 'provider.ca.name'
+ assert_config! 'provider.ca.bit_size'
+ assert_config! 'provider.ca.life_span'
+
+ root = CertificateAuthority::Certificate.new
+
+ # set subject
+ root.subject.common_name = common_name
+ possible = ['country', 'state', 'locality', 'organization', 'organizational_unit', 'email_address']
+ provider.ca.keys.each do |key|
+ if possible.include?(key)
+ root.subject.send(key + '=', provider.ca[key])
+ end
+ end
+
+ # set expiration
+ root.not_before = yesterday
+ root.not_after = years_from_yesterday(provider.ca.life_span.to_i)
+
+ # generate private key
+ root.serial_number.number = 1
+ root.key_material.generate_key(provider.ca.bit_size)
+
+ # sign self
+ root.signing_entity = true
+ root.parent = root
+ root.sign!(ca_root_signing_profile)
+
+ # save
+ write_file!(key_file, root.key_material.private_key.to_pem)
+ write_file!(cert_file, root.to_pem)
+ end
+
def cert_needs_updating?(node)
if !file_exists?([:node_x509_cert, node.name], [:node_x509_key, node.name])
return true
@@ -218,10 +223,10 @@ module LeapCli; module Commands
# set expiration
cert.not_before = yesterday
- cert.not_after = years_from_yesterday(manager.provider.ca.server_certificates.life_span.to_i)
+ cert.not_after = years_from_yesterday(provider.ca.server_certificates.life_span.to_i)
# generate key
- cert.key_material.generate_key(manager.provider.ca.server_certificates.bit_size)
+ cert.key_material.generate_key(provider.ca.server_certificates.bit_size)
# sign
cert.parent = ca_root
@@ -234,12 +239,12 @@ module LeapCli; module Commands
def generate_test_client_cert
cert = CertificateAuthority::Certificate.new
- cert.serial_number.number = cert_serial_number(manager.provider.domain)
- cert.subject.common_name = random_common_name(manager.provider.domain)
+ cert.serial_number.number = cert_serial_number(provider.domain)
+ cert.subject.common_name = random_common_name(provider.domain)
cert.not_before = yesterday
cert.not_after = years_from_yesterday(1)
cert.key_material.generate_key(1024) # just for testing, remember!
- cert.parent = ca_root
+ cert.parent = client_ca_root
cert.sign! client_test_signing_profile
write_file! :test_client_key, cert.key_material.private_key.to_pem
write_file! :test_client_cert, cert.to_pem
@@ -251,6 +256,12 @@ module LeapCli; module Commands
end
end
+ def client_ca_root
+ @client_ca_root ||= begin
+ load_certificate_file(:client_ca_cert, :client_ca_key)
+ end
+ end
+
def load_certificate_file(crt_file, key_file=nil, password=nil)
crt = read_file!(crt_file)
openssl_cert = OpenSSL::X509::Certificate.new(crt)
@@ -302,7 +313,7 @@ module LeapCli; module Commands
#
def server_signing_profile(node)
{
- "digest" => manager.provider.ca.server_certificates.digest,
+ "digest" => provider.ca.server_certificates.digest,
"extensions" => {
"keyUsage" => {
"usage" => ["digitalSignature", "keyEncipherment"]
diff --git a/lib/leap_cli/path.rb b/lib/leap_cli/path.rb
index e7626b5..bfd3c9a 100644
--- a/lib/leap_cli/path.rb
+++ b/lib/leap_cli/path.rb
@@ -33,6 +33,8 @@ module LeapCli; module Path
:authorized_keys => 'files/ssh/authorized_keys',
:ca_key => 'files/ca/ca.key',
:ca_cert => 'files/ca/ca.crt',
+ :client_ca_key => 'files/ca/client_ca.key',
+ :client_ca_cert => 'files/ca/client_ca.crt',
:dh_params => 'files/ca/dh.pem',
:commercial_key => 'files/cert/#{arg}.key',
:commercial_csr => 'files/cert/#{arg}.csr',