diff --git a/app/services/pii/cipher.rb b/app/services/pii/cipher.rb index 4bea1320a9c..70f9be412f7 100644 --- a/app/services/pii/cipher.rb +++ b/app/services/pii/cipher.rb @@ -37,7 +37,13 @@ def decipher(payload) cipher.iv = iv(unpacked_payload) cipher.auth_tag = tag(unpacked_payload) cipher.auth_data = 'PII' + try_decipher(unpacked_payload) + end + + def try_decipher(unpacked_payload) cipher.update(ciphertext(unpacked_payload)) + cipher.final + rescue OpenSSL::Cipher::CipherError => err + raise EncryptionError, 'failed to decipher payload: ' + err.to_s end def unpack_payload(payload) diff --git a/app/services/pii/encryptor.rb b/app/services/pii/encryptor.rb index 9f79c97ad99..c95806e012b 100644 --- a/app/services/pii/encryptor.rb +++ b/app/services/pii/encryptor.rb @@ -35,7 +35,7 @@ def decrypt_and_test_payload(payload, cek) begin payload = cipher.decrypt(payload, cek) rescue OpenSSL::Cipher::CipherError => err - raise EncryptionError, err + raise EncryptionError, err.inspect end raise EncryptionError, 'payload is invalid' unless sane_payload?(payload) plaintext, fingerprint = split_into_segments(payload) diff --git a/app/services/user_access_key.rb b/app/services/user_access_key.rb index 391a02b7ab2..4f5ea23e5c3 100644 --- a/app/services/user_access_key.rb +++ b/app/services/user_access_key.rb @@ -56,6 +56,7 @@ def encryption_key end def unlock(random_key) + raise Pii::EncryptionError, 'Cannot unlock with nil random_key' unless random_key.present? self.unlocked = true self.random_r = random_key hash_e diff --git a/db/migrate/20161118150205_add_user_email_fingerprint.rb b/db/migrate/20161118150205_add_user_email_fingerprint.rb index 789ff11e785..124c26a33f7 100644 --- a/db/migrate/20161118150205_add_user_email_fingerprint.rb +++ b/db/migrate/20161118150205_add_user_email_fingerprint.rb @@ -8,12 +8,13 @@ def up encrypt_user_emails change_column_null :users, :email_fingerprint, false change_column_null :users, :encrypted_email, false - remove_column :users, :email + remove_index :users, :email + rename_column :users, :email, :email_plain + change_column_null :users, :email_plain, true end def down - add_column :users, :email, :string - add_index :users, :email, unique: true + rename_column :users, :email_plain, :email decrypt_user_emails change_column_null :users, :email, false remove_column :users, :email_fingerprint @@ -31,7 +32,8 @@ def encrypt_user_emails def decrypt_user_emails User.where(email: nil).each do |user| ee = EncryptedEmail.new(user.encrypted_email) - user.update!(email: ee.decrypted) + escaped = ActiveRecord::Base.connection.quote(ee.decrypted) + execute "UPDATE users set email=#{escaped} WHERE id=#{user.id}" end end end diff --git a/db/schema.rb b/db/schema.rb index 93d329c720f..e71389cfada 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -82,6 +82,7 @@ add_index "profiles", ["user_id"], name: "index_profiles_on_user_id", using: :btree create_table "users", force: :cascade do |t| + t.string "email_plain", limit: 255, default: "" t.string "encrypted_password", limit: 255, default: "" t.string "reset_password_token", limit: 255 t.datetime "reset_password_sent_at"