mirror of
https://github.com/inspec/inspec
synced 2025-02-17 06:28:40 +00:00
refactor x509 resources and rsa key
Signed-off-by: Christoph Hartmann <chris@lollyrock.com>
This commit is contained in:
parent
f66f0b3a18
commit
d2f000e435
9 changed files with 246 additions and 220 deletions
70
docs/resources/key_rsa.md
Normal file
70
docs/resources/key_rsa.md
Normal file
|
@ -0,0 +1,70 @@
|
|||
---
|
||||
title: The key_rsa Resource
|
||||
---
|
||||
|
||||
# key_rsa
|
||||
|
||||
Use the `key_rsa` InSpec audit resource to test RSA public/private keypairs.
|
||||
|
||||
This resource is mainly useful when used in conjunction with the x509_certificate resource but it can also be used for checking SSH keys.
|
||||
|
||||
|
||||
## Syntax
|
||||
|
||||
An `key_rsa` resource block declares a `key file` to be tested.
|
||||
|
||||
describe key_rsa('mycertificate.key') do
|
||||
it { should be_private }
|
||||
it { should be_public }
|
||||
its('public_key') { should match "-----BEGIN PUBLIC KEY-----\n3597459df9f3982" }
|
||||
its('key_length') { should eq 2048 }
|
||||
end
|
||||
|
||||
You can use an optional passphrase with `key_rsa`
|
||||
|
||||
describe key_rsa('mycertificate.key', 'passphrase') do
|
||||
it { should be_private }
|
||||
end
|
||||
|
||||
## Supported Properties
|
||||
|
||||
### public?
|
||||
|
||||
To verify if a key is public use the following:
|
||||
|
||||
describe key_rsa('/etc/pki/www.mywebsite.com.key') do
|
||||
it { should be_public }
|
||||
end
|
||||
|
||||
### public_key (String)
|
||||
|
||||
The `public_key` property returns the public part of the RSA key pair
|
||||
|
||||
describe key_rsa('/etc/pki/www.mywebsite.com.key') do
|
||||
its('public_key') { should match "-----BEGIN PUBLIC KEY-----\n3597459df9f3982......" }
|
||||
end
|
||||
|
||||
### private?
|
||||
|
||||
This property verifies that the key includes a private key:
|
||||
|
||||
describe key_rsa('/etc/pki/www.mywebsite.com.key') do
|
||||
it { should be_private }
|
||||
end
|
||||
|
||||
|
||||
### private_key (String)
|
||||
|
||||
The `private_key` property returns the private key or the RSA key pair.
|
||||
|
||||
describe key_rsa('/etc/pki/www.mywebsite.com.key') do
|
||||
its('private_key') { should match "-----BEGIN RSA PRIVATE KEY-----\nMIIJJwIBAAK......" }
|
||||
end
|
||||
|
||||
### key_length
|
||||
|
||||
The `key_length` property allows testing the number of bits in the key pair.
|
||||
|
||||
describe key_rsa('/etc/pki/www.mywebsite.com.key') do
|
||||
its('key_length') { should eq 2048 }
|
||||
end
|
|
@ -1,41 +0,0 @@
|
|||
---
|
||||
title: The rsa_key Resource
|
||||
---
|
||||
|
||||
# rsa_key
|
||||
|
||||
Use the `rsa_key` InSpec audit resource to test RSA public/private keypairs.
|
||||
|
||||
This resource is mainly useful when used in conjunction with the x509_certificate resource but it can also be used for checking SSH keys.
|
||||
|
||||
|
||||
## Syntax
|
||||
|
||||
An `rsa_key` resource block declares a `key file` to be tested.
|
||||
|
||||
describe rsa_key('mycertificate.key') do
|
||||
its('public_key') { should match "-----BEGIN PUBLIC KEY-----\n3597459df9f3982" }
|
||||
its('key_length') { should eq 2048 }
|
||||
end
|
||||
|
||||
## Supported Properties
|
||||
|
||||
### public_key (String)
|
||||
|
||||
The `public_key` property returns the public part of the RSA keypair
|
||||
|
||||
describe rsa_key('/etc/pki/www.mywebsite.com.key') do
|
||||
its('public_key') { should match "-----BEGIN PUBLIC KEY-----\n3597459df9f3982......" }
|
||||
end
|
||||
|
||||
### private_key (String)
|
||||
|
||||
See the `public key` property
|
||||
|
||||
### key_length
|
||||
|
||||
The key_length` property allows testing the number of bits in the keypair.
|
||||
|
||||
describe rsa_key('/etc/pki/www.mywebsite.com.key') do
|
||||
its('key_length') { should eq 2048 }
|
||||
end
|
|
@ -17,55 +17,47 @@ certificates.
|
|||
An `x509_certificate` resource block declares a certificate `key file` to be tested.
|
||||
|
||||
describe x509_certificate('mycertificate.pem') do
|
||||
its('days_remaining') { should be > 30 }
|
||||
end
|
||||
|
||||
It can optionally specify a private key file and a ca public key file for key verification
|
||||
|
||||
describe x509_certificate('mycertificate.cert','mycertificate.key','ca_key.pub') do
|
||||
its('private_key_matches?') { should be true }
|
||||
its('ca_key_matches?') { should be true }
|
||||
its('validity_in_days') { should be > 30 }
|
||||
end
|
||||
|
||||
## Supported Properties
|
||||
|
||||
### subject (String)
|
||||
### subject.XX
|
||||
|
||||
The `subject` string contains several fields seperated by forward slashes. The
|
||||
field identifiers are the same ones used by OpenSSL to generate CSR's and certs.
|
||||
`subject` property makes it easier to access individual subject elements.
|
||||
|
||||
describe x509_certificate('/etc/pki/www.mywebsite.com.pem') do
|
||||
its('subject.CN') { should eq "www.mywebsite.com" }
|
||||
end
|
||||
|
||||
### subject_dn (String)
|
||||
|
||||
The `subject_dn` string returns the distinguished name of the subject field. It contains several fields separated by forward slashes. The field identifiers are the same ones used by OpenSSL to generate CSR's and certs. Use `subject.XX` instead to access the parsed version.
|
||||
|
||||
e.g. `/C=US/L=Seattle/O=Chef Software Inc/OU=Chefs/CN=Richard Nixon`
|
||||
|
||||
describe x509_certificate('/etc/pki/www.mywebsite.com.pem') do
|
||||
its('subject') { should match "CN=www.mywebsite.com" }
|
||||
its('subject_dn') { should match "CN=www.mywebsite.com" }
|
||||
end
|
||||
|
||||
### parsed_subject.XX
|
||||
### issuer.XX
|
||||
|
||||
`parsed_subject` property makes it easier to access individual subject elements.
|
||||
`issuer` makes it easier to access individual issuer elements.
|
||||
|
||||
describe x509_certificate('/etc/pki/www.mywebsite.com.pem') do
|
||||
its('parsed_subject.CN') { should eq "www.mywebsite.com" }
|
||||
its('issuer.CN') { should eq "Acme Trust CA" }
|
||||
end
|
||||
|
||||
### issuer (String)
|
||||
### issuer_dn (String)
|
||||
|
||||
The `issuer` string is copied from a CA (certificate authority) during the
|
||||
The `issuer_dn` is the distinguished name from a CA (certificate authority) during the
|
||||
certificate signing process. It describes which authority is guaranteeing the
|
||||
identity of our certificate.
|
||||
|
||||
e.g. `/C=US/L=Seattle/CN=Acme Trust CA/emailAddress=support@acmetrust.org`
|
||||
|
||||
describe x509_certificate('/etc/pki/www.mywebsite.com.pem') do
|
||||
its('issuer') { should match "CN=Acme Trust CA" }
|
||||
end
|
||||
|
||||
### parsed_issuer.XX
|
||||
|
||||
`parsed_issuer` makes it easier to access individual issuer elements.
|
||||
|
||||
describe x509_certificate('/etc/pki/www.mywebsite.com.pem') do
|
||||
its('parsed_issuer.CN') { should eq "Acme Trust CA" }
|
||||
its('issuer_cn') { should match "CN=Acme Trust CA" }
|
||||
end
|
||||
|
||||
### public_key (String)
|
||||
|
@ -81,7 +73,7 @@ The `public_key` property returns a base64 encoded public key in PEM format.
|
|||
The `key_length` property calculates the number of bits in the public key.
|
||||
More bits increase security, but at the cost of speed and in extreme cases, compatibility.
|
||||
|
||||
describe x509_certificate('mycert.pem') do
|
||||
describe x509_certificate('/etc/pki/www.mywebsite.com.pem') do
|
||||
its('key_length') { should be 2048 }
|
||||
end
|
||||
|
||||
|
@ -94,27 +86,14 @@ sign the certificate.
|
|||
its('signature_algorithm') { should be 'sha256WithRSAEncryption' }
|
||||
end
|
||||
|
||||
### private_key_matches? (Boolean) ca_key_matches? (Boolean)
|
||||
|
||||
The `private_key_matches?` and `ca_key_matches?` methods check
|
||||
### validity_in_days (Float)
|
||||
|
||||
* If the supplied private key matches the certificate
|
||||
* If the CA public key belongs to the CA that signed the certificate
|
||||
|
||||
|
||||
describe x509_certificate('mycertificate.cert','mycertificate.key','ca_key.pub') do
|
||||
its('private_key_matches?') { should be true }
|
||||
its('ca_key_matches?') { should be true }
|
||||
end
|
||||
|
||||
|
||||
### days_remaining (Float)
|
||||
|
||||
The `days_remaining` property can be used to check that certificates are not in
|
||||
The `validity_in_days` property can be used to check that certificates are not in
|
||||
danger of expiring soon.
|
||||
|
||||
describe x509_certificate('/etc/pki/www.mywebsite.com.pem') do
|
||||
its('days_remaining') { should be > 30 }
|
||||
its('validity_in_days') { should be > 30 }
|
||||
end
|
||||
|
||||
### not_before and not_after (Time)
|
||||
|
@ -131,31 +110,37 @@ validity. They are exposed as ruby Time class so that date arithmetic can be eas
|
|||
|
||||
The `serial` property exposes the serial number of the certificate. The serial number is set by the CA during the signing process and should be unique within that CA.
|
||||
|
||||
describe x509_certificate('/etc/pki/www.mywebsite.com.pem') do
|
||||
its('serial') { should eq 9623283588743302433 }
|
||||
end
|
||||
|
||||
### version (Integer)
|
||||
|
||||
The `version` property exposes the certificate version.
|
||||
|
||||
describe x509_certificate('/etc/pki/www.mywebsite.com.pem') do
|
||||
its('version') { should eq 2 }
|
||||
end
|
||||
|
||||
### extensions (Hash)
|
||||
|
||||
The `extensions` hash property is mainly used to determine what the certificate can be used for.
|
||||
|
||||
describe x509_certificate('/etc/pki/www.mywebsite.com.pem') do
|
||||
its('extensions').length) {should eq 3 }
|
||||
|
||||
# Check what extension categories we have
|
||||
its('extensions')) { should include 'keyUsage' }
|
||||
its('extensions')) { should include 'extendedKeyUsage' }
|
||||
its('extensions')) { should include 'subjectAltName' }
|
||||
its('extensions') { should include 'keyUsage' }
|
||||
its('extensions') { should include 'extendedKeyUsage' }
|
||||
its('extensions') { should include 'subjectAltName' }
|
||||
|
||||
# Check examples of basic 'keyUsage'
|
||||
its('extensions')['keyUsage']) { should include "Digital Signature" }
|
||||
its('extensions')['keyUsage']).must_include "Non Repudiation"
|
||||
its('extensions')['keyUsage']).must_include "Data Encipherment"
|
||||
its('extensions.keyUsage') { should include 'Digital Signature' }
|
||||
its('extensions.keyUsage') { should include 'Non Repudiation' }
|
||||
its('extensions.keyUsage') { should include 'Data Encipherment' }
|
||||
|
||||
# Check examples of newer 'extendedKeyUsage'
|
||||
its('extensions')['extendedKeyUsage']) { should include "TLS Web Server Authentication" }
|
||||
its('extensions')['extendedKeyUsage']) { should include "Code Signing" }
|
||||
its('extensions.extendedKeyUsage') { should include 'TLS Web Server Authentication' }
|
||||
its('extensions.extendedKeyUsage') { should include 'Code Signing' }
|
||||
|
||||
# Check examples of 'subjectAltName'
|
||||
its('extensions')['subjectAltName']) { should include "email:support@chef.io" }
|
||||
its('extensions.subjectAltName') { should include 'email:support@chef.io' }
|
||||
end
|
||||
|
|
|
@ -95,6 +95,7 @@ require 'resources/iptables'
|
|||
require 'resources/json'
|
||||
require 'resources/kernel_module'
|
||||
require 'resources/kernel_parameter'
|
||||
require 'resources/key_rsa'
|
||||
require 'resources/limits_conf'
|
||||
require 'resources/login_def'
|
||||
require 'resources/mount'
|
||||
|
@ -119,7 +120,6 @@ require 'resources/postgres_session'
|
|||
require 'resources/powershell'
|
||||
require 'resources/processes'
|
||||
require 'resources/registry_key'
|
||||
require 'resources/rsa_key'
|
||||
require 'resources/security_policy'
|
||||
require 'resources/service'
|
||||
require 'resources/shadow'
|
||||
|
|
67
lib/resources/key_rsa.rb
Normal file
67
lib/resources/key_rsa.rb
Normal file
|
@ -0,0 +1,67 @@
|
|||
# encoding: utf-8
|
||||
# author: Richard Nixon
|
||||
# author: Christoph Hartmann
|
||||
|
||||
require 'openssl'
|
||||
require 'hashie/mash'
|
||||
|
||||
module Inspec::Resources
|
||||
class RsaKey < Inspec.resource(1)
|
||||
name 'key_rsa'
|
||||
desc 'public/private RSA key pair test'
|
||||
example "
|
||||
describe rsa_key('/etc/pki/www.mywebsite.com.key') do
|
||||
its('public_key') { should match /BEGIN RSA PUBLIC KEY/ }
|
||||
end
|
||||
|
||||
describe rsa_key('/etc/pki/www.mywebsite.com.key', 'passphrase') do
|
||||
it { should be_private }
|
||||
it { should be_public }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(keypath, passphrase = nil)
|
||||
@key_path = keypath
|
||||
@key_file = inspec.file(@key_path)
|
||||
@key = nil
|
||||
@passphrase = passphrase
|
||||
|
||||
return skip_resource "Unable to find key file #{@key_path}" unless @key_file.exist?
|
||||
|
||||
begin
|
||||
@key = OpenSSL::PKey.read(@key_file.content, @passphrase)
|
||||
rescue OpenSSL::PKey::RSAError => _
|
||||
return skip_resource "Unable to load key file #{@key_path}"
|
||||
end
|
||||
end
|
||||
|
||||
def public?
|
||||
return if @key.nil?
|
||||
@key.public?
|
||||
end
|
||||
|
||||
def public_key
|
||||
return if @key.nil?
|
||||
@key.public_key.to_s
|
||||
end
|
||||
|
||||
def private?
|
||||
return if @key.nil?
|
||||
@key.private?
|
||||
end
|
||||
|
||||
def private_key
|
||||
return if @key.nil?
|
||||
@key.to_s
|
||||
end
|
||||
|
||||
def key_length
|
||||
return if @key.nil?
|
||||
@key.public_key.n.num_bytes * 8
|
||||
end
|
||||
|
||||
def to_s
|
||||
"rsa_key #{@key_path}"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,57 +0,0 @@
|
|||
# encoding: utf-8
|
||||
# author: Richard Nixon
|
||||
|
||||
require 'openssl'
|
||||
require 'hashie/mash'
|
||||
|
||||
module Inspec::Resources
|
||||
class RsaKey < Inspec.resource(1)
|
||||
name 'rsa_key'
|
||||
desc 'Used to test RSA keys'
|
||||
example "
|
||||
describe rsa_key('/etc/pki/www.mywebsite.com.key') do
|
||||
its('public_key') { should match /BEGIN RSA PUBLIC KEY/ }
|
||||
end
|
||||
"
|
||||
def initialize(keypath)
|
||||
@keypath = keypath
|
||||
@keyfile = inspec.backend.file(@keypath)
|
||||
if @keyfile.exist?
|
||||
load_key
|
||||
else
|
||||
@key = RuntimeError.new('Key file not found')
|
||||
end
|
||||
end
|
||||
|
||||
private def load_key
|
||||
@keyraw ||= @keyfile.content
|
||||
@key ||= OpenSSL::PKey::RSA.new(@keyraw)
|
||||
rescue OpenSSL::X509::RSAError => error_code
|
||||
@key ||= error_code
|
||||
end
|
||||
|
||||
def public_key
|
||||
@key.public_key.to_s
|
||||
end
|
||||
|
||||
def private_key
|
||||
@key.to_s
|
||||
end
|
||||
|
||||
def key_length
|
||||
n.num_bytes * 8 # Answer in bits
|
||||
end
|
||||
|
||||
def exist?
|
||||
@keyfile.exist?
|
||||
end
|
||||
|
||||
def key_length
|
||||
@key.public_key.n.num_bytes * 8
|
||||
end
|
||||
|
||||
def to_s
|
||||
"rsa_key #{@keypath}"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,93 +1,97 @@
|
|||
# encoding: utf-8
|
||||
# author: Richard Nixon
|
||||
# author: Christoph Hartmann
|
||||
|
||||
require 'openssl'
|
||||
require 'hashie/mash'
|
||||
|
||||
module Inspec::Resources
|
||||
class X509CertificateResource < Inspec.resource(1)
|
||||
class X509CertificateResource < Inspec.resource(1) # rubocop:disable Metrics/ClassLength
|
||||
name 'x509_certificate'
|
||||
desc 'Used to test x.509 certificates'
|
||||
example "
|
||||
describe x509_certificate('/etc/pki/www.mywebsite.com.pem') do
|
||||
its('subject') { should match /CN=My Website/ }
|
||||
its('days_remaining') { should be > 30 }
|
||||
its('validity_in_days') { should be > 30 }
|
||||
end
|
||||
|
||||
describe x509_certificate('trials/x509/cert.pem') do
|
||||
it { should be_certificate }
|
||||
it { should be_valid }
|
||||
its('fingerprint') { should eq '62b137bdf427e7273dc2e487877b3033e4c8ce17' }
|
||||
its('signature_algorithm') { should eq 'sha1WithRSAEncryption' }
|
||||
its('validity_in_days') { should_not be < 100 }
|
||||
its('validity_in_days') { should be >= 100 }
|
||||
its('subject_dn') { should eq '/C=DE/ST=Berlin/L=Berlin/O=InSpec/OU=Chef Software, Inc/CN=inspec.io/emailAddress=support@chef.io' }
|
||||
its('subject.C') { should eq 'DE' }
|
||||
its('subject.emailAddress') { should_not be_empty }
|
||||
its('subject.emailAddress') { should eq 'support@chef.io' }
|
||||
its('issuer_dn') { should eq '/C=DE/ST=Berlin/L=Berlin/O=InSpec/OU=Chef Software, Inc/CN=inspec.io/emailAddress=support@chef.io' }
|
||||
its('key_length') { should be >= 2048 }
|
||||
its('extensions.subjectKeyIdentifier') { should cmp 'A5:16:0B:12:F4:48:0F:06:6C:32:29:67:98:12:DF:3D:0D:75:9D:5C' }
|
||||
end
|
||||
"
|
||||
|
||||
def initialize(certpath,private_keypath=nil,ca_public_keypath=nil)
|
||||
@certpath = certpath
|
||||
# @see https://tools.ietf.org/html/rfc5280#page-23
|
||||
def initialize(filename)
|
||||
@certpath = filename
|
||||
@issuer = nil
|
||||
@parsed_subject = nil
|
||||
@parsed_issuer = nil
|
||||
@extensions = nil
|
||||
@cert = cert_from_file(certpath)
|
||||
@key = key_from_file(private_keypath)
|
||||
@cakey = key_from_file(ca_public_keypath)
|
||||
end
|
||||
|
||||
private def cert_from_file(certpath)
|
||||
certfile = inspec.backend.file(certpath)
|
||||
if certfile.exist?
|
||||
certraw = certfile.content
|
||||
certcooked = OpenSSL::X509::Certificate.new(certraw)
|
||||
else
|
||||
certcooked = RuntimeError.new("Certificate #{certpath} not found")
|
||||
file = inspec.file(@certpath)
|
||||
return skip_resource "Unable to find certificate file #{@certpath}" unless file.exist?
|
||||
|
||||
begin
|
||||
@cert = OpenSSL::X509::Certificate.new file.content
|
||||
rescue OpenSSL::X509::CertificateError
|
||||
@cert = nil
|
||||
return skip_resource "Unable to load certificate #{@certpath}"
|
||||
end
|
||||
certcooked
|
||||
rescue OpenSSL::X509::CertificateError => error_code
|
||||
error_code
|
||||
end
|
||||
|
||||
private def key_from_file(keypath)
|
||||
keyfile = inspec.backend.file(keypath)
|
||||
if keyfile.exist?
|
||||
keyraw = keyfile.content
|
||||
keycooked = OpenSSL::PKey::RSA.new(keyraw)
|
||||
else
|
||||
keycooked = RuntimeError.new("Keyfile #{keypath} not found")
|
||||
end
|
||||
keycooked
|
||||
rescue OpenSSL::PKey::RSAError => error_code
|
||||
error_code
|
||||
end
|
||||
|
||||
|
||||
# Forward these methods directly to OpenSSL::X509::Certificate instance
|
||||
%w{serial version not_before not_after signature_algorithm public_key }.each do |m|
|
||||
%w{version not_before not_after signature_algorithm public_key }.each do |m|
|
||||
define_method m.to_sym do |*args|
|
||||
@cert.method(m.to_sym).call(*args)
|
||||
end
|
||||
end
|
||||
|
||||
def exist?
|
||||
@certfile.exist?
|
||||
def certificate?
|
||||
!@cert.nil?
|
||||
end
|
||||
|
||||
def private_key_matches?
|
||||
@cert.check_private_key(@key)
|
||||
def fingerprint
|
||||
return if @cert.nil?
|
||||
OpenSSL::Digest::SHA1.new(@cert.to_der).to_s
|
||||
end
|
||||
|
||||
def ca_key_matches?
|
||||
@cert.verify(@cakey)
|
||||
def serial
|
||||
return if @cert.nil?
|
||||
@cert.serial.to_i
|
||||
end
|
||||
|
||||
def subject
|
||||
def subject_dn
|
||||
return if @cert.nil?
|
||||
@cert.subject.to_s
|
||||
end
|
||||
|
||||
def parsed_subject
|
||||
def subject
|
||||
return if @cert.nil?
|
||||
# Return cached subject if we have already parsed it
|
||||
return @parsed_subject if @parsed_subject
|
||||
# Use a Mash to make it easier to access hash elements in "its('subject') {should ...}"
|
||||
@parsed_subject = Hashie::Mash.new(Hash[@cert.subject.to_a.map { |k, v, _| [k, v] }])
|
||||
end
|
||||
|
||||
def issuer
|
||||
def issuer_dn
|
||||
return if @cert.nil?
|
||||
@cert.issuer.to_s
|
||||
end
|
||||
|
||||
def parsed_issuer
|
||||
def issuer
|
||||
return if @cert.nil?
|
||||
# Return cached subject if we have already parsed it
|
||||
return @parsed_issuer if @parsed_issuer
|
||||
# Use a Mash to make it easier to access hash elements in "its('issuer') {should ...}"
|
||||
|
@ -95,11 +99,17 @@ module Inspec::Resources
|
|||
end
|
||||
|
||||
def key_length
|
||||
return if @cert.nil?
|
||||
@cert.public_key.n.num_bytes * 8
|
||||
end
|
||||
|
||||
def days_remaining
|
||||
(@cert.not_after - Time.now.utc) / 86400
|
||||
def validity_in_days
|
||||
(not_after - Time.now.utc) / 86400
|
||||
end
|
||||
|
||||
def valid?
|
||||
now = Time.now
|
||||
certificate? && (now >= not_before && now <= not_after)
|
||||
end
|
||||
|
||||
def extensions
|
||||
|
@ -118,7 +128,7 @@ module Inspec::Resources
|
|||
policyConstraints nameConstraints noCheck tlsfeature nsComment
|
||||
}.each { |extension| @extensions[extension] ||= [] }
|
||||
# Now parse the extensions into the Mash
|
||||
extension_array = @cert.extensions.map { |e| e.to_s }
|
||||
extension_array = @cert.extensions.map(&:to_s)
|
||||
extension_array.each do |extension|
|
||||
kv = extension.split(/ *= */, 2)
|
||||
@extensions[kv.first] = kv.last.split(/ *, */)
|
||||
|
|
|
@ -5,7 +5,7 @@ require 'helper'
|
|||
require 'inspec/resource'
|
||||
|
||||
describe 'Inspec::Resources::RsaKey' do
|
||||
let (:resource_key) { load_resource('rsa_key', 'test_certificate.rsa.key.pem')}
|
||||
let (:resource_key) { load_resource('key_rsa', 'test_certificate.rsa.key.pem')}
|
||||
|
||||
it 'parses the public key' do
|
||||
_(resource_key.send('public_key')).must_match "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxi1Tp4dPQ+GU+RipsguU\nWT50a6fsBCpe+QT0YdW/7GG6kynRzR+fzQ0q1LDxpgqAH+eDIWEAFYoTPc8haAjZ\nvAYn7JlXUQpeoK7fc2BPgYA0lr33Ee0H9nqeZlnytQ+/EVUqqDx61cgeW3ARAK1I\nODwhuziuTi7XNu+HTx3feH4ohq/FppB26PYfJo1jCmt7YxHxl6AGrYrEX5zubQR0\nAtPAJzg0/aqDH5GJHJETjloIxh/KLnGlbG3DJylFU+vPxvns1TKM0dezg8UefXer\nRtxDAwSix7sNctXwa0xToc6O+e/StNPR0eLvILS8iR89fuML57Z4AGFWMNdqTYoj\nqwIDAQAB\n-----END PUBLIC KEY-----\n"
|
||||
|
@ -14,6 +14,4 @@ describe 'Inspec::Resources::RsaKey' do
|
|||
it 'decodes the key length' do
|
||||
_(resource_key.send('key_length')).must_equal 2048
|
||||
end
|
||||
|
||||
|
||||
end
|
|
@ -8,39 +8,33 @@ describe 'Inspec::Resources::X509Certificate' do
|
|||
let (:resource_cert) {
|
||||
load_resource(
|
||||
'x509_certificate',
|
||||
'test_certificate.rsa.crt.pem',
|
||||
'test_certificate.rsa.key.pem',
|
||||
'test_ca_public.key.pem'
|
||||
'test_certificate.rsa.crt.pem'
|
||||
)
|
||||
}
|
||||
|
||||
it 'decodes the subject as a string' do
|
||||
_(resource_cert.send('subject')).must_match 'Inspec Test Certificate'
|
||||
it 'verify subject distingushed name' do
|
||||
_(resource_cert.send('subject_dn')).must_match 'Inspec Test Certificate'
|
||||
end
|
||||
|
||||
it 'parses the certificate subject' do
|
||||
_(resource_cert.send('parsed_subject').CN).must_equal 'Inspec Test Certificate'
|
||||
_(resource_cert.send('parsed_subject').emailAddress).must_equal 'support@chef.io'
|
||||
_(resource_cert.send('subject').CN).must_equal 'Inspec Test Certificate'
|
||||
_(resource_cert.send('subject').emailAddress).must_equal 'support@chef.io'
|
||||
end
|
||||
|
||||
it 'decodes the issuer as a string' do
|
||||
_(resource_cert.send('issuer')).must_match 'Inspec Test CA'
|
||||
it 'verify issue distingushed name' do
|
||||
_(resource_cert.send('issuer_dn')).must_match 'Inspec Test CA'
|
||||
end
|
||||
|
||||
it 'parses the issuer' do
|
||||
_(resource_cert.send('parsed_issuer').CN).must_equal 'Inspec Test CA'
|
||||
_(resource_cert.send('issuer').CN).must_equal 'Inspec Test CA'
|
||||
end
|
||||
|
||||
it 'parses the public key' do
|
||||
_(resource_cert.send('public_key').to_s).must_match "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxi1Tp4dPQ+GU+RipsguU\nWT50a6fsBCpe+QT0YdW/7GG6kynRzR+fzQ0q1LDxpgqAH+eDIWEAFYoTPc8haAjZ\nvAYn7JlXUQpeoK7fc2BPgYA0lr33Ee0H9nqeZlnytQ+/EVUqqDx61cgeW3ARAK1I\nODwhuziuTi7XNu+HTx3feH4ohq/FppB26PYfJo1jCmt7YxHxl6AGrYrEX5zubQR0\nAtPAJzg0/aqDH5GJHJETjloIxh/KLnGlbG3DJylFU+vPxvns1TKM0dezg8UefXer\nRtxDAwSix7sNctXwa0xToc6O+e/StNPR0eLvILS8iR89fuML57Z4AGFWMNdqTYoj\nqwIDAQAB\n-----END PUBLIC KEY-----\n"
|
||||
end
|
||||
|
||||
it 'can check if the private key matches the certificate' do
|
||||
_(resource_cert.send('private_key_matches?')).must_equal true
|
||||
end
|
||||
|
||||
it 'can check if a CA key was used to sign this cert' do
|
||||
_(resource_cert.send('ca_key_matches?')).must_equal true
|
||||
it 'can determine fingerprint' do
|
||||
_(resource_cert.send('fingerprint')).must_equal '62bb500b0190ae47fd593c29a0b92ddbeb6c1eb6'
|
||||
end
|
||||
|
||||
it 'can determine the key length' do
|
||||
|
@ -82,11 +76,11 @@ describe 'Inspec::Resources::X509Certificate' do
|
|||
it 'calculates the remaining days of validity' do
|
||||
# Still valid
|
||||
Time.stub :now, Time.new(2018, 2, 1, 1, 28, 57, '+00:00') do
|
||||
_(resource_cert.send('days_remaining')).must_equal 28
|
||||
_(resource_cert.send('validity_in_days')).must_equal 28
|
||||
end
|
||||
# Expired
|
||||
Time.stub :now, Time.new(2018, 4, 1, 1, 28, 57, '+00:00') do
|
||||
_(resource_cert.send('days_remaining')).must_equal (-31)
|
||||
_(resource_cert.send('validity_in_days')).must_equal (-31)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue