Class: CcipherBox::MemKey

Inherits:
Object
  • Object
show all
Includes:
TR::CondUtils
Defined in:
lib/ccipher_box/mem_key.rb

Overview

Actual data encryption key that is encrypted in memory This class represents a single encryption key

Defined Under Namespace

Classes: MemKeyException

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ring, key, name = nil) ⇒ MemKey

Returns a new instance of MemKey.



16
17
18
19
20
21
22
23
24
# File 'lib/ccipher_box/mem_key.rb', line 16

def initialize(ring, key, name = nil)
  @dataConv = Ccrypto::UtilFactory.instance(:data_conversion)
  @dataComp = Ccrypto::UtilFactory.instance(:comparator)
  self.ring = ring
  self.key = key
  self.name = name

  @activateCount = 0
end

Instance Attribute Details

#nameObject

Returns the value of attribute name.



14
15
16
# File 'lib/ccipher_box/mem_key.rb', line 14

def name
  @name
end

#ringObject

Returns the value of attribute ring.



14
15
16
# File 'lib/ccipher_box/mem_key.rb', line 14

def ring
  @ring
end

Class Method Details

.to_KeyID(val) ⇒ Object

keyID is stored as binary in the structure but was used as Hex value at application level



37
38
39
# File 'lib/ccipher_box/mem_key.rb', line 37

def self.to_KeyID(val)
  Ccrypto::UtilFactory.instance(:data_conversion).to_hex(val)
end

Instance Method Details

#decrypt(bin, &block) ⇒ Object

Raises:



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/ccipher_box/mem_key.rb', line 115

def decrypt(bin, &block)
 
  st = BinStruct.instance.struct_from_bin(bin)
  st.keyid = @dataConv.to_hex(st.keyid)

  raise MemKeyException, "Given data to decrypt is not cipher envelope" if CBTag.value_constant(st.oid) != :ccipherbox_keywrap
  raise MemKeyException, "Give cipher envelope is not meant for this key. Current key ID '#{self.keyID}' and key ID inside envelope '#{st.keyid}'" if not @dataComp.is_equals?(self.keyID, st.keyid)

  case @key
  when CcipherFactory::SymKey
    sk = @key
  else
    sk = CcipherFactory::SymKey.from_encoded(st.keyConfig) do |k|
      case k
      when :password
        mem_unseal(@key)
      end
    end
  end

  @activateCount += 1
  # refresh the in-memory protection
  if @activateCount > 5
    logger.debug "Seal refresh during decrypt ops"
    @key = mem_seal(@key) 
  end

  membuf = MemBuf.new
  dec = CcipherFactory::SymKeyCipher.att_decryptor
  dec.key = sk

  dec.output(membuf)
  dec.att_decrypt_init
  dec.att_decrypt_update(st.cipher)
  dec.att_decrypt_final

  plain = membuf.bytes.clone
  membuf.dispose

  if block
    output = block.call(:output)
  end
  output = :binary if is_empty?(output)
  
  case output
  when :hex
    @dataConv.to_hex(plain)
  when :b64
    @dataConv.to_b64(plain)
  else
    plain
  end

end

#encrypt(data, &block) ⇒ Object

Encrypt by this key is generally consider key wrap therefore data is not expected to be very big.

This is not really going to encrypt the actual data since there might have multiple key involved during data protection



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/ccipher_box/mem_key.rb', line 49

def encrypt(data, &block)

  if block
    algo = block.call(:symkey_algo)
    keysize = block.call(:symkey_length)
    mode = block.call(:symkey_mode)
    output = block.call(:output)
  end

  algo = :aes if is_empty?(algo)
  keysize = 256 if is_empty?(keysize)
  mode = :gcm if is_empty?(mode)
  output = :binary if is_empty?(output)

  key = mem_unseal(@key)
  case key
  when CcipherFactory::SymKey
    sk = key
  else
    sk = CcipherFactory::SymKeyGenerator.derive(algo, keysize) do |k|
      case k
      when :password
        key
      end
    end
  end

  @activateCount += 1
  # refresh the in-memory encryption
  if @activateCount > 5
    logger.debug "Seal refresh during encrypt ops"
    @key = mem_seal(@key) 
  end


  membuf = MemBuf.new
  enc = CcipherFactory::SymKeyCipher.att_encryptor
  enc.key = sk
  enc.mode = mode

  enc.output(membuf)
  enc.att_encrypt_init
  enc.att_encrypt_update(data)
  enc.att_encrypt_final

  encOut = membuf.bytes.clone
  membuf.dispose
  
  st = BinStruct.instance.struct(:ccipherbox_keywrap)
  st.keyid = @dataConv.from_hex(self.keyID)
  sk.attach_mode
  st.keyConfig = sk.encoded
  st.cipher = encOut
  res = st.encoded

  case output
  when :hex
    @dataConv.to_hex(res)
  when :b64
    @dataConv.to_b64(res)
  else
    res
  end
  
end

#key=(val) ⇒ Object



26
27
28
29
# File 'lib/ccipher_box/mem_key.rb', line 26

def key=(val)
  generateKeyID(val)
  @key = mem_seal(val)
end

#keyIDObject



31
32
33
# File 'lib/ccipher_box/mem_key.rb', line 31

def keyID
  @keyID
end

#plain_keyObject

def encoded

st = BinStruct.instance.struct(:mem_key)
st.value = mem_unseal(@key)
st.encoded

end



182
183
184
# File 'lib/ccipher_box/mem_key.rb', line 182

def plain_key
  mem_unseal(@key)
end