diff --git a/app/models/dnskey.rb b/app/models/dnskey.rb index 2f249c0fd..ef0459f35 100644 --- a/app/models/dnskey.rb +++ b/app/models/dnskey.rb @@ -8,7 +8,7 @@ class Dnskey < ActiveRecord::Base validate :validate_protocol validate :validate_flags - # after_validation :generate_epp_errors + before_save -> { generate_digest unless digest.present? } ALGORITHMS = %w(3 5 6 7 8 252 253 254 255) PROTOCOLS = %w(3) @@ -22,7 +22,7 @@ class Dnskey < ActiveRecord::Base [:flags, :invalid, { value: { obj: 'flags', val: flags }, values: FLAGS.join(', ') }] ], '2302' => [ - [:public_key, :taken, { value: { obj: 'pubKye', val: public_key } }] + [:public_key, :taken, { value: { obj: 'pubKey', val: public_key } }] ], '2303' => [ [:base, :dnskey_not_found, { value: { obj: 'pubKey', val: public_key } }] @@ -53,4 +53,33 @@ class Dnskey < ActiveRecord::Base return if FLAGS.include?(flags.to_s) errors.add(:flags, :invalid, values: FLAGS.join(', ')) end + + def generate_digest + flags_hex = self.class.int_to_hex(flags) + protocol_hex = self.class.int_to_hex(protocol) + alg_hex = self.class.int_to_hex(alg) + + hex = [domain.name_in_wire_format, flags_hex, protocol_hex, alg_hex, public_key_hex].join + bin = self.class.hex_to_bin(hex) + self.digest = Digest::SHA256.hexdigest(bin).upcase + end + + def public_key_hex + self.class.bin_to_hex(Base64.decode64(public_key)) + end + + class << self + def int_to_hex(s) + s = s.to_s(16) + s.prepend('0') if s.length.odd? + end + + def hex_to_bin(s) + s.scan(/../).map(&:hex).pack('c*') + end + + def bin_to_hex(s) + s.each_byte.map { |b| sprintf('%02X', b) }.join + end + end end diff --git a/app/models/domain.rb b/app/models/domain.rb index 19ff9f421..636bd607b 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -210,6 +210,19 @@ class Domain < ActiveRecord::Base ## SHARED + def name_in_wire_format + res = '' + parts = name.split('.') + parts.each do |x| + res += sprintf('%02X', x.length) + res += x.each_byte.map { |b| sprintf('%02X', b) }.join + end + + res += '00' + + res + end + def to_s name end diff --git a/app/models/epp/epp_domain.rb b/app/models/epp/epp_domain.rb index 1019247e6..382309aff 100644 --- a/app/models/epp/epp_domain.rb +++ b/app/models/epp/epp_domain.rb @@ -218,7 +218,6 @@ class Epp::EppDomain < Domain }.merge(x)) end - errors.any? end diff --git a/db/migrate/20141014073435_change_public_key_type_to_text.rb b/db/migrate/20141014073435_change_public_key_type_to_text.rb new file mode 100644 index 000000000..a4deafde1 --- /dev/null +++ b/db/migrate/20141014073435_change_public_key_type_to_text.rb @@ -0,0 +1,5 @@ +class ChangePublicKeyTypeToText < ActiveRecord::Migration + def change + change_column :dnskeys, :public_key, :text + end +end diff --git a/db/schema.rb b/db/schema.rb index a5819e711..0f22ad577 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20141010130412) do +ActiveRecord::Schema.define(version: 20141014073435) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -104,7 +104,7 @@ ActiveRecord::Schema.define(version: 20141010130412) do t.integer "flags" t.integer "protocol" t.integer "alg" - t.string "public_key" + t.text "public_key" t.integer "delegation_signer_id" t.string "ds_key_tag" t.integer "ds_alg"