Skip to content

Commit

Permalink
Reduced JWE module complexity
Browse files Browse the repository at this point in the history
  • Loading branch information
francescobbo committed Sep 6, 2017
1 parent 46bb3f8 commit bb0c251
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 20 deletions.
44 changes: 28 additions & 16 deletions lib/jwe.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,37 +22,31 @@ class InvalidData < RuntimeError; end

class << self
def encrypt(payload, key, alg: 'RSA-OAEP', enc: 'A128GCM', **more_headers)
header = { alg: alg, enc: enc }.merge(more_headers)
header.delete(:zip) if header[:zip] == ''
header = generate_header(alg, enc, more_headers)
check_params(header, key)

cipher = Enc.for(enc).new
cipher.cek = key if alg == 'dir'
payload = apply_zip(header, payload, :compress)

payload = Zip.for(header[:zip]).new.compress(payload) if header[:zip]
cipher = Enc.for(enc)
cipher.cek = key if alg == 'dir'

ciphertext = cipher.encrypt(payload, Base64.jwe_encode(header.to_json))
encrypted_cek = Alg.for(alg).new(key).encrypt(cipher.cek)
json_hdr = header.to_json
ciphertext = cipher.encrypt(payload, Base64.jwe_encode(json_hdr))

Serialization::Compact.encode(header.to_json, encrypted_cek, cipher.iv, ciphertext, cipher.tag)
generate_serialization(json_hdr, Alg.encrypt_cek(alg, key, cipher.cek), ciphertext, cipher)
end

def decrypt(payload, key)
header, enc_key, iv, ciphertext, tag = Serialization::Compact.decode(payload)
header = JSON.parse(header)
check_params(header, key)

cek = Alg.for(header['alg']).new(key).decrypt(enc_key)
cipher = Enc.for(header['enc']).new(cek, iv)
cipher.tag = tag
cek = Alg.decrypt_cek(header['alg'], key, enc_key)
cipher = Enc.for(header['enc'], cek, iv, tag)

plaintext = cipher.decrypt(ciphertext, payload.split('.').first)

if header['zip']
Zip.for(header['zip']).new.decompress(plaintext)
else
plaintext
end
apply_zip(header, plaintext, :decompress)
end

def check_params(header, key)
Expand Down Expand Up @@ -82,5 +76,23 @@ def param_to_class_name(param)
klass = param.gsub(/[-\+]/, '_').downcase.sub(/^[a-z\d]*/) { $&.capitalize }
klass.gsub(/_([a-z\d]*)/i) { Regexp.last_match(1).capitalize }
end

def apply_zip(header, data, direction)
if header[:zip] || header['zip']
Zip.for(header[:zip] || header['zip']).new.send(direction, data)
else
data
end
end

def generate_header(alg, enc, more)
header = { alg: alg, enc: enc }.merge(more)
header.delete(:zip) if header[:zip] == ''
header
end

def generate_serialization(hdr, cek, content, cipher)
Serialization::Compact.encode(hdr, cek, cipher.iv, content, cipher.tag)
end
end
end
8 changes: 8 additions & 0 deletions lib/jwe/alg.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,13 @@ def self.for(alg)
rescue NameError
raise NotImplementedError.new("Unsupported alg type: #{alg}")
end

def self.encrypt_cek(alg, key, cek)
self.for(alg).new(key).encrypt(cek)
end

def self.decrypt_cek(alg, key, encrypted_cek)
self.for(alg).new(key).decrypt(encrypted_cek)
end
end
end
7 changes: 5 additions & 2 deletions lib/jwe/enc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
module JWE
# Content encryption algorithms namespace
module Enc
def self.for(enc)
const_get(JWE.param_to_class_name(enc))
def self.for(enc, cek = nil, iv = nil, tag = nil)
klass = const_get(JWE.param_to_class_name(enc))
inst = klass.new(cek, iv)
inst.tag = tag if tag
inst
rescue NameError
raise NotImplementedError.new("Unsupported enc type: #{enc}")
end
Expand Down
4 changes: 2 additions & 2 deletions spec/jwe/enc_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

describe JWE::Enc do
describe '.for' do
it 'returns a class for the specified enc' do
expect(JWE::Enc.for('A128GCM')).to eq JWE::Enc::A128gcm
it 'returns an instance for the specified enc' do
expect(JWE::Enc.for('A128GCM')).to be_a JWE::Enc::A128gcm
end

it 'raises an error for a not-implemented enc' do
Expand Down

0 comments on commit bb0c251

Please sign in to comment.