Method: JOSE::JWA::PKCS1#emsa_pss_encode

Defined in:
lib/jose/jwa/pkcs1.rb

#emsa_pss_encode(hash, message, salt, em_bits) ⇒ Object



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
# File 'lib/jose/jwa/pkcs1.rb', line 58

def emsa_pss_encode(hash, message, salt, em_bits)
  if hash.is_a?(String)
    hash = OpenSSL::Digest.new(hash)
  end
  salt ||= -2
  if salt.is_a?(Integer)
    salt_len = salt
    if salt_len == -2
      hash_len = hash.digest('').bytesize
      em_len = (em_bits / 8.0).ceil
      salt_len = em_len - hash_len - 2
      if salt_len < 0
        raise ArgumentError, "encoding_error"
      end
    elsif salt_len == -1
      hash_len = hash.digest('').bytesize
      salt_len = hash_len
    end
    if salt_len < 0
      raise ArgumentError, "unhandled salt length: #{salt_len.inspect}"
    end
    salt = SecureRandom.random_bytes(salt_len)
  end
  m_hash = hash.digest(message)
  hash_len = m_hash.bytesize
  salt_len = salt.bytesize
  em_len = (em_bits / 8.0).ceil
  if em_len < (hash_len + salt_len + 2)
    raise ArgumentError, "encoding_error"
  else
    m_prime = [0x00].pack('Q').concat(m_hash).concat(salt)
    h = hash.digest(m_prime)
    ps = ([0x00] * (em_len - salt_len - hash_len - 2)).pack('C*')
    db = [ps, 0x01, salt].pack('a*Ca*')
    db_mask = mgf1(hash, h, em_len - hash_len - 1)
    left_bits = (em_len * 8) - em_bits
    masked_db_right = exor(db, db_mask).unpack('B*')[0][left_bits..-1]
    masked_db = [('0' * left_bits).concat(masked_db_right)].pack('B*')
    em = [masked_db, h, 0xBC].pack('a*a*C')
    return em
  end
end