Skip to content

Commit

Permalink
Make public key file an RSA public key instead of a certificate
Browse files Browse the repository at this point in the history
OpenSSL PKCS7 encrypt function needs a list of X509 certs to encrypt
and sign data. However, in the context of hiera-eyaml, the certificate
serves no purpose. For the user, it is easier to understand that eyaml
deals with a keypair. Internally, we wrap the public key in a X509 dummy
certificate to call PKCS7 encrypt but the user does not have to be exposed
to it.
  • Loading branch information
cmd-ntrf committed May 1, 2024
1 parent 9c599aa commit 123169a
Showing 1 changed file with 17 additions and 41 deletions.
58 changes: 17 additions & 41 deletions lib/hiera/backend/eyaml/encryptors/pkcs7.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,26 @@ class Pkcs7 < Encryptor
type: :string, },
public_key_env_var: { desc: 'Name of environment variable to read public key from',
type: :string, },
subject: { desc: 'Subject to use for certificate when creating keys',
type: :string,
default: '/', },
keysize: { desc: 'Key size used for encryption',
type: :integer,
default: 2048, },
digest: { desc: 'Hash function used for PKCS7',
type: :string,
default: 'SHA256', },
}

self.tag = 'PKCS7'

# The public certificate serial could be any number,
# but the tests encrypted data were signed with a certificate with the
# serial number 0. It was later changed to 1 in f9fde79,
# but tests data were not re-generated.
X509_SERIAL_NUMBER = 0

def self.encrypt(plaintext)
LoggingHelper.trace 'PKCS7 encrypt'

public_key_pem = self.load_public_key_pem()
public_key_x509 = OpenSSL::X509::Certificate.new(public_key_pem)
public_key_rsa = OpenSSL::PKey::RSA.new(public_key_pem)
public_key_x509 = OpenSSL::X509::Certificate.new
public_key_x509.serial = Pkcs7::X509_SERIAL_NUMBER
public_key_x509.public_key = public_key_rsa.public_key

cipher = OpenSSL::Cipher.new('aes-256-cbc')
OpenSSL::PKCS7.encrypt([public_key_x509], plaintext, cipher, OpenSSL::PKCS7::BINARY).to_der
Expand All @@ -56,54 +57,29 @@ def self.decrypt(ciphertext)
if Gem::Version::new(OpenSSL::VERSION) >= Gem::Version::new('2.2.0')
public_key_x509 = nil
else
public_key_pem = self.load_public_key_pem()
public_key_x509 = OpenSSL::X509::Certificate.new(public_key_pem)
public_key_x509 = OpenSSL::X509::Certificate.new
public_key_x509.serial = Pkcs7::X509_SERIAL_NUMBER
public_key_x509.public_key = private_key_rsa.public_key
end

pkcs7 = OpenSSL::PKCS7.new(ciphertext)
pkcs7.decrypt(private_key_rsa, public_key_x509)
end

def self.create_keys
# Try to do equivalent of:
# openssl req -x509 -nodes -days 100000 -newkey rsa:2048 -keyout privatekey.pem -out publickey.pem -subj '/'

public_key = option :public_key
# Equivalent of:
# openssl genrsa -out private_key.pem 2048
# openssl rsa -in private_key.pem -pubout -out public_key.pem
private_key = option :private_key
subject = option :subject
public_key = option :public_key
keysize = option :keysize
digest = option :digest

key = OpenSSL::PKey::RSA.new(keysize)
EncryptHelper.ensure_key_dir_exists private_key
EncryptHelper.write_important_file filename: private_key, content: key.to_pem, mode: 0o600

cert = OpenSSL::X509::Certificate.new
cert.subject = OpenSSL::X509::Name.parse(subject)
cert.serial = 1
cert.version = 2
cert.not_before = Time.now
cert.not_after = if 1.size == 8 # 64bit
Time.now + (50 * 365 * 24 * 60 * 60)
else # 32bit
Time.at(0x7fffffff)
end
cert.public_key = key.public_key

ef = OpenSSL::X509::ExtensionFactory.new
ef.subject_certificate = cert
ef.issuer_certificate = cert
cert.extensions = [
ef.create_extension('basicConstraints', 'CA:TRUE', true),
ef.create_extension('subjectKeyIdentifier', 'hash'),
]
cert.add_extension ef.create_extension('authorityKeyIdentifier',
'keyid:always,issuer:always')

cert.sign key, OpenSSL::Digest.new(digest)

EncryptHelper.ensure_key_dir_exists public_key
EncryptHelper.write_important_file filename: public_key, content: cert.to_pem
EncryptHelper.write_important_file filename: public_key, content: key.public_key.to_pem
LoggingHelper.info 'Keys created OK'
end

Expand Down

0 comments on commit 123169a

Please sign in to comment.