class CZTop::Certificate

Represents a CZMQ::FFI::Zcert.

Public Class Methods

check_curve_availability() click to toggle source

Warns if CURVE security isn't available. @return [void]

# File lib/cztop/certificate.rb, line 10
def self.check_curve_availability
  return if Zsys.has_curve
  warn "CZTop: CURVE isn't available. Consider installing libsodium."
end
load(filename) click to toggle source

Loads a certificate from a file. @param filename [String, Pathname, to_s] path to certificate file @return [Certificate] the loaded certificate

# File lib/cztop/certificate.rb, line 18
def self.load(filename)
  ptr = Zcert.load(filename.to_s)
  from_ffi_delegate(ptr)
end
new() click to toggle source

Initialize a new in-memory certificate with random keys.

# File lib/cztop/certificate.rb, line 47
def initialize
  attach_ffi_delegate(Zcert.new)
end
new_from(public_key, secret_key = nil) click to toggle source

Creates a new certificate from the given keys (either binary or in Z85 format). @param public_key [String] binary public key (32 or 40 bytes) @param secret_key [String, nil] binary secret key (32 or 40 bytes), or

nil to initialize a public key only certificate

@return [Certificate] the fresh certificate @raise [ArgumentError] if keys passed are invalid @raise [SystemCallError] if this fails

# File lib/cztop/certificate.rb, line 31
def self.new_from(public_key, secret_key = nil)
  raise ArgumentError, "no public key given" unless public_key
  secret_key ||= "\x00" * 32 # no secret key given, provide 32 null bytes

  # convert Z85 => binary
  public_key = Z85.decode(public_key) if public_key.bytesize == 40
  secret_key = Z85.decode(secret_key) if secret_key.bytesize == 40

  raise ArgumentError, "invalid public key size" if public_key.bytesize != 32
  raise ArgumentError, "invalid secret key size" if secret_key.bytesize != 32

  ptr = Zcert.new_from(public_key, secret_key)
  from_ffi_delegate(ptr)
end

Public Instance Methods

==(other) click to toggle source

Compares this certificate to another. @param other [Cert] other certificate @return [Boolean] whether they have the same keys

# File lib/cztop/certificate.rb, line 176
def ==(other)
  ffi_delegate.eq(other.ffi_delegate)
end
[](key) click to toggle source

Get metadata. @param key [String] metadata key @return [String] value for meta key @return [nil] if metadata key is not set

# File lib/cztop/certificate.rb, line 90
def [](key)
  ffi_delegate.meta(key)
end
[]=(key, value) click to toggle source

Set metadata. @param key [String] metadata key @param value [String] metadata value @return [value]

# File lib/cztop/certificate.rb, line 97
def []=(key, value)
  if value
    ffi_delegate.set_meta(key, "%s", :string, value)
  else
    ffi_delegate.unset_meta(key)
  end
end
apply(zocket) click to toggle source

Applies this certificate on a {Socket} or {Actor}. @param zocket [Socket, Actor] path/filename to secret file @return [void] @raise [SystemCallError] if secret key is undefined

# File lib/cztop/certificate.rb, line 158
def apply(zocket)
  raise ArgumentError, "invalid zocket argument %p" % zocket unless zocket
  return ffi_delegate.apply(zocket) unless secret_key.nil?
  raise_zmq_err("secret key is undefined")
end
dup() click to toggle source

Duplicates the certificate. @return [Certificate] @raise [SystemCallError] if this fails

# File lib/cztop/certificate.rb, line 167
def dup
  ptr = ffi_delegate.dup
  return from_ffi_delegate(ptr) unless ptr.null?
  raise_zmq_err("unable to duplicate certificate")
end
meta_keys() click to toggle source

Returns meta keys set. @return [Array<String>]

# File lib/cztop/certificate.rb, line 107
def meta_keys
  zlist = ffi_delegate.meta_keys
  first_key = zlist.first
  return [] if first_key.null?
  keys = [first_key.read_string]
  while key = zlist.next
    break if key.null?
    keys << key.read_string
  end
  keys
end
public_key(format: :z85) click to toggle source

Returns the public key either as Z85-encoded ASCII string (default) or binary string. @param format [Symbol] :z85 for Z85, :binary for binary @return [String] public key

# File lib/cztop/certificate.rb, line 55
def public_key(format: :z85)
  case format
  when :z85
    ffi_delegate.public_txt.force_encoding(Encoding::ASCII)
  when :binary
    ffi_delegate.public_key.read_string(32)
  else
    raise ArgumentError, "invalid format: %p" % format
  end
end
save(filename) click to toggle source

Save full certificate (public + secret) to files. @param filename [String, to_s] path/filename to public file @return [void] @raise [ArgumentError] if path is invalid @raise [SystemCallError] if this fails @note This will create two files: one of the public key and one for the

secret key. The secret filename is filename + "_secret".
# File lib/cztop/certificate.rb, line 126
def save(filename)
  # see https://github.com/zeromq/czmq/issues/1244
  raise ArgumentError, "filename can't be empty" if filename.to_s.empty?
  rc = ffi_delegate.save(filename.to_s)
  return if rc == 0
  raise_zmq_err("error while saving to file %p" % filename)
end
save_public(filename) click to toggle source

Saves the public key to file in ZPL ({Config}) format. @param filename [String, to_s] path/filename to public file @return [void] @raise [SystemCallError] if this fails

# File lib/cztop/certificate.rb, line 138
def save_public(filename)
  rc = ffi_delegate.save_public(filename.to_s)
  return if rc == 0
  raise_zmq_err("error while saving to the file %p" % filename)
end
save_secret(filename) click to toggle source

Saves the secret key to file in ZPL ({Config}) format. @param filename [String, to_s] path/filename to secret file @return [void] @raise [SystemCallError] if this fails

# File lib/cztop/certificate.rb, line 148
def save_secret(filename)
  rc = ffi_delegate.save_secret(filename.to_s)
  return if rc == 0
  raise_zmq_err("error while saving to the file %p" % filename)
end
secret_key(format: :z85) click to toggle source

Returns the secret key either as Z85-encoded ASCII string (default) or binary string. @param format [Symbol] :z85 for Z85, :binary for binary @return [String] secret key @return [nil] if secret key is undefined (like after loading from a file

created using {#save_public})
# File lib/cztop/certificate.rb, line 72
def secret_key(format: :z85)
  case format
  when :z85
    key = ffi_delegate.secret_txt.force_encoding(Encoding::ASCII)
    return nil if key.count("0") == 40
  when :binary
    key = ffi_delegate.secret_key.read_string(32)
    return nil if key.count("\0") == 32
  else
    raise ArgumentError, "invalid format: %p" % format
  end
  key
end