kgio-monkey.git  about / heads / tags
kinder, gentler SSL/TLS I/O for Ruby
blob df606af681710b9c318b9514561d2f9b2b5a1905 3784 bytes (raw)
$ git show HEAD:lib/kgio/ssl.rb	# shows this blob on the CLI

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 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
115
116
117
118
119
120
121
122
123
124
125
126
127
 
# -*- encoding: binary -*-
class Kgio::SSL
  # Returns an array of klass objects from a PEM file in path.
  # klass should either be OpenSSL::X509::Certificate or OpenSSL::RSA::PKey
  # This method is used internally by Flipper.ssl_context.  We may change or
  # remove it in the future; do not rely on it directly
  def self.split_pem(klass, path) # :nodoc:
    rv = []
    IO.read(path).gsub!(/^-----BEGIN.+?-----END[^\n]+-----$/m) do |m|
      rv << klass.new(m)
    end
    rv
  end

  # See Kgio::PipeMethods#kgio_write
  def kgio_write(string)
    case rc = kgio_trywrite(string)
    when :wait_writable
      @to_io.kgio_wait_writable
    when :wait_readable
      @to_io.kgio_wait_readable
    when nil
      return
    when String
      string = rc
    end while true
  end

  # See Kgio::PipeMethods#kgio_peek
  def kgio_peek(maxlen, buffer = "")
    case rc = kgio_trypeek(maxlen, buffer)
    when :wait_writable
      @to_io.kgio_wait_writable
    when :wait_readable
      @to_io.kgio_wait_readable
    else
      return rc
    end while true
  end

  # See Kgio::PipeMethods#kgio_read
  def kgio_read(maxlen, buffer = "")
    case rc = kgio_tryread(maxlen, buffer)
    when :wait_writable
      @to_io.kgio_wait_writable
    when :wait_readable
      @to_io.kgio_wait_readable
    else
      return rc
    end while true
  end

  # See Kgio::PipeMethods#kgio_read!
  def kgio_read!(maxlen, buffer = "")
    kgio_read(maxlen, buffer) || raise(EOFError, "end of file reached", [])
  end

  # Synchronously closes the SSL connection, waiting up to +limit+
  # seconds for an orderly shutdown before doing a hard shutdown.
  #
  # Returns +nil+ on success, will raise IOError if descriptor is
  # already closed.
  def kgio_close(limit = 30)
    expires = Time.now + limit
    case kgio_tryclose
    when :wait_readable
      limit = expires - Time.now
      0 > limit and return @to_io.close
      @to_io.kgio_wait_readable(limit)
    when :wait_writable
      limit = expires - Time.now
      0 > limit and return @to_io.close
      @to_io.kgio_wait_writable(limit)
    else # nil or false, return nil regardless for IO#close compat
      return
    end while true
  end

  # :stopdoc:
  # constants for garbage reduction
  HEXFMT = "%02X"
  HEXPACK = "H*"
  LFTAB = "\n\t"
  # :startdoc:

  # Returns the SSL client certificate serial number as a hexadecimal string
  # Raises NoMethodError if client did not send a peer certificate
  # This matches the nginx variable of the same name.
  def ssl_client_serial
    sprintf(HEXFMT, peer_cert.serial.to_i)
  end

  # Returns the subject Distinguished Name of the client peer certificate
  # Raises NoMethodError if client did not send a peer certificate
  # This matches the nginx variable of the same name.
  def ssl_client_s_dn
    peer_cert.subject.to_s
  end

  # Returns the issuer Distinguished Name of the client peer certificate
  # Raises NoMethodError if client did not send a peer certificate
  # This matches the nginx variable of the same name.
  def ssl_client_i_dn
    peer_cert.issuer.to_s
  end

  # Returns a hex-encoded string representing the SSL session ID
  # This matches the nginx variable of the same name.
  def ssl_session_id
    session.to_der.unpack(HEXPACK)[0]
  end

  # Returns the client certificate in PEM format.
  # Raises NoMethodError if client did not send a peer certificate
  # This matches the nginx variable of the same name.
  def ssl_client_raw_cert
    peer_cert.to_pem
  end

  # Returns the client certificate in PEM format in a format suitable for
  # including in HTTP headers
  # Raises NoMethodError if client did not send a peer certificate
  # This matches the nginx variable of the same name.
  def ssl_client_cert
    ssl_client_raw_cert.gsub!(/\n/, LFTAB)
  end
end

git clone https://yhbt.net/kgio-monkey.git