Learn more  » Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

vistahigherlearning / logstash   deb

Repository URL to install this package:

/ opt / logstash / vendor / bundle / jruby / 1.9 / gems / rbnacl-2.0.0 / lib / rbnacl / util.rb

# encoding: binary
module RbNaCl
  # Various utility functions
  module Util
    extend Sodium

    sodium_function :c_verify16, :crypto_verify_16, [:pointer, :pointer]
    sodium_function :c_verify32, :crypto_verify_32, [:pointer, :pointer]
    module_function
    # Returns a string of n zeros
    #
    # Lots of the functions require us to create strings to pass into functions of a specified size.
    #
    # @param [Integer] n the size of the string to make
    #
    # @return [String] A nice collection of zeros
    def zeros(n=32)
      zeros = "\0" * n
      # make sure they're 8-bit zeros, not 7-bit zeros.  Otherwise we might get
      # encoding errors later
      zeros.respond_to?(:force_encoding) ? zeros.force_encoding('ASCII-8BIT') : zeros
    end

    # Prepends a message with zeros
    #
    # Many functions require a string with some zeros prepended.
    #
    # @param [Integer] n The number of zeros to prepend
    # @param [String] message The string to be prepended
    #
    # @return [String] a bunch of zeros
    def prepend_zeros(n, message)
      zeros(n) + message
    end

    # Remove zeros from the start of a message
    #
    # Many functions require a string with some zeros prepended, then need them removing after.  Note, this modifies the passed in string
    #
    # @param [Integer] n The number of zeros to remove
    # @param [String] message The string to be slice
    #
    # @return [String] less a bunch of zeros
    def remove_zeros(n, message)
      message.slice!(n, message.bytesize - n)
    end

    # Check the length of the passed in string
    #
    # In several places through the codebase we have to be VERY strict with
    # what length of string we accept.  This method supports that.
    #
    # @raise [RbNaCl::LengthError] If the string is not the right length
    #
    # @param string [String] The string to compare
    # @param length [Integer] The desired length
    # @param description [String] Description of the string (used in the error)
    def check_length(string, length, description)
      if string.nil?
        raise LengthError,
          "#{description} was nil (Expected #{length.to_int})",
          caller
      end

      if string.bytesize != length.to_int
        raise LengthError,
              "#{description} was #{string.bytesize} bytes (Expected #{length.to_int})",
              caller
      end
      true
    end

    # Check a passed in string, converting the argument if necessary
    #
    # In several places through the codebase we have to be VERY strict with
    # the strings we accept.  This method supports that.
    #
    # @raise [ArgumentError] If we cannot convert to a string with #to_str
    # @raise [RbNaCl::LengthError] If the string is not the right length
    #
    # @param string [#to_str] The input string
    # @param length [Integer] The only acceptable length of the string
    # @param description [String] Description of the string (used in the error)
    def check_string(string, length, description)
      unless string.respond_to? :to_str
        raise TypeError, "can't convert #{string.class} into String with #to_str"
      end

      string = string.to_str
      check_length(string, length, description)

      string
    end

    # Compare two 32 byte strings in constant time
    #
    # This should help to avoid timing attacks for string comparisons in your
    # application.  Note that many of the functions (such as HmacSha256#verify)
    # use this method under the hood already.
    #
    # @param [String] one String #1
    # @param [String] two String #2
    #
    # @return [Boolean] Well, are they equal?
    def verify32(one, two)
      return false unless two.bytesize == 32 && one.bytesize == 32
      c_verify32(one, two)
    end

    # Compare two 32 byte strings in constant time
    #
    # This should help to avoid timing attacks for string comparisons in your
    # application.  Note that many of the functions (such as HmacSha256#verify)
    # use this method under the hood already.
    #
    # @param [String] one String #1
    # @param [String] two String #2
    #
    # @raise [ArgumentError] If the strings are not equal in length
    #
    # @return [Boolean] Well, are they equal?
    def verify32!(one, two)
      check_length(one, 32, "First message")
      check_length(two, 32, "Second message")
      c_verify32(one, two)
    end

    # Compare two 16 byte strings in constant time
    #
    # This should help to avoid timing attacks for string comparisons in your
    # application.  Note that many of the functions (such as OneTime#verify)
    # use this method under the hood already.
    #
    # @param [String] one String #1
    # @param [String] two String #2
    #
    # @return [Boolean] Well, are they equal?
    def verify16(one, two)
      return false unless two.bytesize == 16 && one.bytesize == 16
      c_verify16(one, two)
    end

    # Compare two 16 byte strings in constant time
    #
    # This should help to avoid timing attacks for string comparisons in your
    # application.  Note that many of the functions (such as OneTime#verify)
    # use this method under the hood already.
    #
    # @param [String] one String #1
    # @param [String] two String #2
    #
    # @raise [ArgumentError] If the strings are not equal in length
    #
    # @return [Boolean] Well, are they equal?
    def verify16!(one, two)
      check_length(one, 16, "First message")
      check_length(two, 16, "Second message")
      c_verify16(one, two)
    end

    # Hex encodes a message
    #
    # @param [String] bytes The bytes to encode
    #
    # @return [String] Tasty, tasty hexadecimal
    def bin2hex(bytes)
      bytes.to_s.unpack("H*").first
    end

    # Hex decodes a message
    #
    # @param [String] hex hex to decode.
    #
    # @return [String] crisp and clean bytes
    def hex2bin(hex)
      [hex.to_s].pack("H*")
    end
  end
end