Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/puppet/application/lookup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ def generate_scope
_, x509 = cert.get_certificate(node)
cert = OpenSSL::X509::Certificate.new(x509)
Puppet::SSL::Oids.register_puppet_oids
trusted = Puppet::Context::TrustedInformation.remote(true, facts.values['certname'] || node, Puppet::SSL::Certificate.from_instance(cert))
trusted = Puppet::Context::TrustedInformation.remote(true, facts.values['certname'] || node, cert)
Puppet.override(trusted_information: trusted) do
node = ni.find(node, facts: facts, environment: Puppet[:environment])
end
Expand Down
2 changes: 1 addition & 1 deletion lib/puppet/context/trusted_information.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def self.remote(authenticated, node_name, certificate)
if certificate.nil?
Puppet.info(_('TrustedInformation expected a certificate, but none was given.'))
else
extensions = certificate.custom_extensions.to_h do |ext|
extensions = Puppet::SSL::Oids.custom_extensions_for(certificate).to_h do |ext|
[ext['oid'].freeze, ext['value'].freeze]
end
end
Expand Down
1 change: 0 additions & 1 deletion lib/puppet/ssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ module Puppet::SSL
require_relative 'ssl/verifier'
require_relative 'ssl/ssl_provider'
require_relative 'ssl/state_machine'
require_relative 'ssl/certificate'
require_relative 'ssl/certificate_request'
require_relative 'ssl/certificate_request_attributes'
end
8 changes: 1 addition & 7 deletions lib/puppet/ssl/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,7 @@ def self.from_s(string, name = nil)

# Read content from disk appropriately.
def read(path)
# applies to Puppet::SSL::Certificate, Puppet::SSL::CertificateRequest
# nothing derives from Puppet::SSL::Certificate, but it is called by a number of other SSL Indirectors:
# Puppet::Indirector::CertificateStatus::File (.indirection.find)
# Puppet::Network::HTTP::WEBrick (.indirection.find)
# Puppet::Network::HTTP::RackREST (.from_instance)
# Puppet::Network::HTTP::WEBrickREST (.from_instance)
# Puppet::SSL::Inventory (.indirection.search, implements its own add / rebuild / serials with encoding UTF8)
# applies to Puppet::SSL::CertificateRequest
@content = wrapped_class.new(Puppet::FileSystem.read(path, :encoding => Encoding::ASCII))
end

Expand Down
98 changes: 0 additions & 98 deletions lib/puppet/ssl/certificate.rb

This file was deleted.

5 changes: 3 additions & 2 deletions lib/puppet/ssl/error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ def initialize(message, code, cert)

class CertMismatchError < Puppet::SSL::SSLError
def initialize(peer_cert, host)
valid_certnames = [peer_cert.subject.to_utf8.sub(/.*=/, ''),
*Puppet::SSL::Certificate.subject_alt_names_for(peer_cert)].uniq
alts = peer_cert.extensions.find { |ext| ext.oid == "subjectAltName" }
alt_names = alts ? alts.value.split(/\s*,\s*/) : []
valid_certnames = [peer_cert.subject.to_utf8.sub(/.*=/, ''), *alt_names].uniq
if valid_certnames.size > 1
expected_certnames = _("expected one of %{certnames}") % { certnames: valid_certnames.join(', ') }
else
Expand Down
39 changes: 39 additions & 0 deletions lib/puppet/ssl/oids.rb
Original file line number Diff line number Diff line change
Expand Up @@ -196,4 +196,43 @@ def self.subtree_of?(first, second, exclusive = false)
rescue OpenSSL::ASN1::ASN1Error, TypeError
false
end

# Extract custom Puppet certificate extensions from an OpenSSL::X509::Certificate.
#
# @param cert [OpenSSL::X509::Certificate]
# @return [Array<Hash>] array of hashes with 'oid' and 'value' keys
def self.custom_extensions_for(cert)
exts_seq = extensions_sequence(cert)

cert.extensions.select do |ext|
subtree_of?('ppRegCertExt', ext.oid) ||
subtree_of?('ppPrivCertExt', ext.oid) ||
subtree_of?('ppAuthCertExt', ext.oid)
end.map do |ext|
{ 'oid' => ext.oid, 'value' => extension_value(exts_seq, ext.oid) }
end
end

# @api private
def self.extensions_sequence(cert)
extensions_tag = 3
OpenSSL::ASN1.decode(cert.to_der).value[0].value.find do |data|
(data.tag == extensions_tag) && (data.tag_class == :CONTEXT_SPECIFIC)
end.value[0]
end
private_class_method :extensions_sequence

# @api private
def self.extension_value(exts_seq, oid)
ext_obj = exts_seq.value.find do |ext_seq|
ext_seq.value[0].value == oid
end
raw_val = ext_obj.value.last.value
begin
OpenSSL::ASN1.decode(raw_val).value
rescue OpenSSL::ASN1::ASN1Error
raw_val
end
end
private_class_method :extension_value
end
4 changes: 0 additions & 4 deletions spec/integration/network/formats_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@ def self.canonical_order(s)
@format = Puppet::Network::FormatHandler.format(:s)
end

it "should support certificates" do
expect(@format).to be_supported(Puppet::SSL::Certificate)
end

it "should not support catalogs" do
expect(@format).not_to be_supported(Puppet::Resource::Catalog)
end
Expand Down
4 changes: 2 additions & 2 deletions spec/lib/puppet/test_ca.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def sign(csr, opts = {})
cert.add_extension(ext)
end
cert.sign(@key, @digest)
Puppet::SSL::Certificate.from_instance(cert)
cert
end

def revoke(cert, crl = @crl, issuer_key = @key)
Expand All @@ -122,7 +122,7 @@ def revoke(cert, crl = @crl, issuer_key = @key)

def generate(name, opts)
info = create_request(name)
cert = sign(info[:csr], opts).content
cert = sign(info[:csr], opts)
info.merge(cert: cert)
end

Expand Down
9 changes: 5 additions & 4 deletions spec/unit/certificate_factory_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
require 'puppet/test_ca'

require 'puppet/certificate_factory'
require 'puppet/ssl/oids'

describe Puppet::CertificateFactory, :unless => RUBY_PLATFORM == 'java' do
let :serial do OpenSSL::BN.new('12') end
Expand Down Expand Up @@ -136,13 +137,13 @@

cert = subject.build(:client, csr, issuer, serial)

# The cert must be signed before being later DER-decoding
# The cert must be signed before being later DER-decoded
signer = Puppet::SSL::CertificateSigner.new
signer.sign(cert, key)
wrapped_cert = Puppet::SSL::Certificate.from_instance cert
exts = Puppet::SSL::Oids.custom_extensions_for(cert)

priv_ext = wrapped_cert.custom_extensions.find {|ext| ext['oid'] == '1.3.6.1.4.1.34380.1.2.1'}
uuid_ext = wrapped_cert.custom_extensions.find {|ext| ext['oid'] == 'pp_uuid'}
priv_ext = exts.find {|ext| ext['oid'] == '1.3.6.1.4.1.34380.1.2.1'}
uuid_ext = exts.find {|ext| ext['oid'] == 'pp_uuid'}

# The expected results should be DER encoded, the Puppet cert wrapper will turn
# these into normal strings.
Expand Down
4 changes: 2 additions & 2 deletions spec/unit/context/trusted_information_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
end

let(:cert) do
cert = Puppet::SSL::Certificate.from_instance(Puppet::CertificateFactory.build('ca', csr, csr.content, 1))
cert = Puppet::CertificateFactory.build('ca', csr, csr.content, 1)

# The cert must be signed so that it can be successfully be DER-decoded later
signer = Puppet::SSL::CertificateSigner.new
signer.sign(cert.content, key)
signer.sign(cert, key)
cert
end

Expand Down
8 changes: 5 additions & 3 deletions spec/unit/ssl/base_spec.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
require 'spec_helper'

require 'puppet/ssl/certificate'
require 'puppet/ssl/certificate_request'

class TestCertificate < Puppet::SSL::Base
wraps(Puppet::SSL::Certificate)
wraps(OpenSSL::X509::Certificate)
end

describe Puppet::SSL::Certificate do
describe Puppet::SSL::Base do
before :each do
@base = TestCertificate.new("name")
@class = TestCertificate
Expand Down Expand Up @@ -46,7 +46,9 @@ class TestCertificate < Puppet::SSL::Base
describe "when initializing wrapped class from a file with #read" do
it "should open the file with ASCII encoding" do
path = '/foo/bar/cert'
cert = double('cert')
expect(Puppet::FileSystem).to receive(:read).with(path, {:encoding => Encoding::ASCII}).and_return("bar")
allow(OpenSSL::X509::Certificate).to receive(:new).with("bar").and_return(cert)
@base.read(path)
end
end
Expand Down
Loading