Class: Signature4VerifierService

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby-common/v4/Signature4VerifierService.rb

Overview

Signature4VerifierService class

Constant Summary collapse

FIELD_IDS =
{
  0x00 => Field.new('requestTime', 'ulong'),
  0x01 => Field.new('signatureTime', 'ulong'),
  0x10 => Field.new('ipv4', 'ulong'),
  0x40 => Field.new(nil, 'ushort'),
  0x80 => Field.new('masterSignType', 'uchar'),
  0x81 => Field.new('customerSignType', 'uchar'),
  0xC0 => Field.new('masterToken', 'string'),
  0xC1 => Field.new('customerToken', 'string'),
  0xC2 => Field.new('masterTokenV6', 'string'),
  0xC3 => Field.new('customerTokenV6', 'string'),
  0xc4 => Field.new('ipv6', 'string'),
  0xc5 => Field.new('masterChecksum', 'string'),
  0xd0 => Field.new('userAgent', 'string') #DEBUG FIELD
}.freeze

Class Method Summary collapse

Class Method Details

.verifySignature(signature, user_agent, key, ip_addresses, expiry, is_key_base64_encoded) ⇒ Object

Raises:



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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/ruby-common/v4/Signature4VerifierService.rb', line 43

def self.verifySignature(signature, user_agent, key, ip_addresses, expiry, is_key_base64_encoded)
  validation_result = {}

  begin
    data = parse4(signature)
  rescue VersionError
    data = parse3(signature)
  end

  sign_role_token = data["customerToken"]

  if sign_role_token.nil? || sign_role_token.empty?
    raise VerifyError, 'sign role signature mismatch'
  end

  sign_type = data["customerSignType"]

  ip_addresses.each do |ip_address|
    next if ip_address.nil? || ip_address.empty?

    token = if IpV6Utils.validate(ip_address)
              next unless data.key?("customerTokenV6")
              IpV6Utils.abbreviate(ip_address)
              data["customerTokenV6"]
            else
              next unless data.key?("customerToken")
              data["customerToken"]
            end

    signature_time = data['signatureTime'].first
    request_time = data['requestTime'].first

    VerifierConstants::RESULTS.each do |result, verdict|
      signature_base = get_base(result, request_time, signature_time, ip_address, user_agent)

      case sign_type.first
      when 1 # HASH_SHA256
        is_hashed_data_equal_to_token = SignatureVerifierUtils.encode(
          is_key_base64_encoded ? SignatureVerifierUtils.base64_decode(key) : key,
          signature_base
        ) == token
        
        if is_hashed_data_equal_to_token
          if is_expired(expiry, signature_time, request_time)
            return Signature4VerificationResult.is_expired
          end

          return Signature4VerificationResult.new(
            score: result.to_i,
            verdict: verdict,
            ip_address: ip_address,
            request_time: request_time,
            signature_time: signature_time
          )
        end
      when 2 # SIGN_SHA256
        if AsymmetricOpenSSL.verify_data(signature_base, token, key)
          return Signature4VerificationResult.new(
            score: result.to_i,
            verdict: verdict,
            ip_address: ip_address,
            request_time: request_time,
            signature_time: signature_time
          )
        end
      else
        raise VerifyError, 'unrecognized signature'
      end
    end
  end
  raise StructParseError, 'no verdict'
end