Class: Ubiq::Encryption
- Inherits:
-
Object
- Object
- Ubiq::Encryption
- Defined in:
- lib/ubiq/encrypt.rb
Overview
Ubiq Encryption object This object represents a single data encryption key and can be used to encrypt several separate plain texts using the same key
Instance Method Summary collapse
- #begin ⇒ Object
- #close ⇒ Object
- #end ⇒ Object
- #endpoint ⇒ Object
- #endpoint_base ⇒ Object
-
#initialize(creds, uses) ⇒ Encryption
constructor
A new instance of Encryption.
- #update(data) ⇒ Object
- #validate_creds(credentials) ⇒ Object
Constructor Details
#initialize(creds, uses) ⇒ Encryption
Returns a new instance of Encryption.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 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 |
# File 'lib/ubiq/encrypt.rb', line 16 def initialize(creds, uses) raise 'Some of your credentials are missing, please check!' unless validate_creds(creds) # Set host, either the default or the one given by caller @host = creds.host.blank? ? UBIQ_HOST : creds.host # Set the credentials in instance varibales to be used among methods # The client's public API key (used to identify the client to the server @papi = creds.access_key_id # The client's secret API key (used to authenticate HTTP requests) @sapi = creds.secret_signing_key # The client's secret RSA encryption key/password (used to decrypt the # client's RSA key from the server). This key is not retained by this object. @srsa = creds.secret_crypto_access_key # Build the endpoint URL url = endpoint_base + '/encryption/key' # Build the Request Body with the number of uses of key query = { uses: uses } # Retrieve the necessary headers to make the request using Auth Object headers = Auth.build_headers(@papi, @sapi, endpoint, query, @host, 'post') @encryption_started = false @encryption_ready = true # Request a new encryption key from the server. if the request # fails, the function raises a HTTPError indicating # the status code returned by the server. this exception is # propagated back to the caller begin response = HTTParty.post( url, body: query.to_json, headers: headers ) rescue HTTParty::Error raise 'Cant reach server' end # Response status is 201 Created if response.code == WEBrick::HTTPStatus::RC_CREATED # The code below largely assumes that the server returns # a json object that contains the members and is formatted # according to the Ubiq REST specification. # Build the key object @key = {} @key['id'] = response['key_fingerprint'] @key['session'] = response['encryption_session'] @key['security_model'] = response['security_model'] @key['algorithm'] = response['security_model']['algorithm'].downcase @key['max_uses'] = response['max_uses'] @key['uses'] = 0 @key['encrypted'] = Base64.strict_decode64(response['encrypted_data_key']) # Get encrypted private key from response body encrypted_private_key = response['encrypted_private_key'] # Get wrapped data key from response body wrapped_data_key = response['wrapped_data_key'] # Decrypt the encryped private key using @srsa supplied private_key = OpenSSL::PKey::RSA.new(encrypted_private_key, @srsa) # Decode WDK from base64 format wdk = Base64.strict_decode64(wrapped_data_key) # Use private key to decrypt the wrapped data key dk = private_key.private_decrypt(wdk, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING) @key['raw'] = dk # Build the algorithm object @algo = Algo.new.get_algo(@key['algorithm']) else # Raise the error if response is not 201 raise "HTTPError Response: Expected 201, got #{response.code}" end end |
Instance Method Details
#begin ⇒ Object
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/ubiq/encrypt.rb', line 95 def begin # Begin the encryption process # When this function is called, the encryption object increments # the number of uses of the key and creates a new internal context # to be used to encrypt the data. # If the encryption object is not yet ready to be used, throw an error raise 'Encryption not ready' unless @encryption_ready # if Encryption cipher context already exists raise 'Encryption already in progress' if @encryption_started # If max uses > uses raise 'Maximum key uses exceeded' if @key['uses'] >= @key['max_uses'] @key['uses'] += 1 # create a new Encryption context and initialization vector @enc, @iv = Algo.new.encryptor(@algo, @key['raw']) # Pack the result into bytes to get a byte string struct = [0, Algo::UBIQ_HEADER_V0_FLAG_AAD, @algo[:id], @iv.length, @key['encrypted'].length].pack('CCCCn') @enc.auth_data = struct + @iv + @key['encrypted'] @encryption_started = true return struct + @iv + @key['encrypted'] end |
#close ⇒ Object
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/ubiq/encrypt.rb', line 148 def close raise 'Encryption currently running' if @encryption_started # If the key was used less times than was requested, send an update to the server if @key['uses'] < @key['max_uses'] query_url = "#{endpoint}/#{@key['id']}/#{@key['session']}" url = "#{endpoint_base}/encryption/key/#{@key['id']}/#{@key['session']}" query = { actual: @key['uses'], requested: @key['max_uses'] } headers = Auth.build_headers(@papi, @sapi, query_url, query, @host, 'patch') response = HTTParty.patch( url, body: query.to_json, headers: headers ) remove_instance_variable(:@key) @encryption_ready = false end end |
#end ⇒ Object
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/ubiq/encrypt.rb', line 129 def end raise 'Encryption is not Started' unless @encryption_started # This function finalizes the encryption (producing the final # cipher text for the encryption, if necessary) and adds any # authentication information (if required by the algorithm). # Any data produced is returned by the function. # Finalize an encryption res = @enc.final if @algo[:tag_length] != 0 # Add the tag to the cipher text res += @enc.auth_tag end @encryption_started = false # Return the encrypted result return res end |
#endpoint ⇒ Object
171 172 173 |
# File 'lib/ubiq/encrypt.rb', line 171 def endpoint '/api/v0/encryption/key' end |
#endpoint_base ⇒ Object
167 168 169 |
# File 'lib/ubiq/encrypt.rb', line 167 def endpoint_base @host + '/api/v0' end |
#update(data) ⇒ Object
121 122 123 124 125 126 127 |
# File 'lib/ubiq/encrypt.rb', line 121 def update(data) raise 'Encryption is not Started' unless @encryption_started # Encryption of some plain text is perfomed here # Any cipher text produced by the operation is returned @enc.update(data) end |
#validate_creds(credentials) ⇒ Object
175 176 177 178 179 180 |
# File 'lib/ubiq/encrypt.rb', line 175 def validate_creds(credentials) # This method checks for the presence of the credentials !credentials.access_key_id.blank? && !credentials.secret_signing_key.blank? && !credentials.secret_crypto_access_key.blank? end |