Class: CZTop::Certificate

Inherits:
Object
  • Object
show all
Extended by:
HasFFIDelegate::ClassMethods
Includes:
CZMQ::FFI, HasFFIDelegate
Defined in:
lib/cztop/certificate.rb

Overview

Represents a CZMQ::FFI::Zcert.

Instance Attribute Summary

Attributes included from HasFFIDelegate

#ffi_delegate

Class Method Summary collapse

Instance Method Summary collapse

Methods included from HasFFIDelegate::ClassMethods

ffi_delegate, from_ffi_delegate

Methods included from HasFFIDelegate

#attach_ffi_delegate, #from_ffi_delegate, #raise_zmq_err, raise_zmq_err, #to_ptr

Constructor Details

#initializeCertificate

Initialize a new in-memory certificate with random keys.


47
48
49
# File 'lib/cztop/certificate.rb', line 47

def initialize
  attach_ffi_delegate(Zcert.new)
end

Class Method Details

.check_curve_availabilityvoid

This method returns an undefined value.

Warns if CURVE security isn't available.


10
11
12
13
# 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) ⇒ Certificate

Loads a certificate from a file.

Parameters:

  • filename (String, Pathname, #to_s)

    path to certificate file

Returns:


18
19
20
21
# File 'lib/cztop/certificate.rb', line 18

def self.load(filename)
  ptr = Zcert.load(filename.to_s)
  from_ffi_delegate(ptr)
end

.new_from(public_key, secret_key = nil) ⇒ Certificate

Creates a new certificate from the given keys (either binary or in Z85 format).

Parameters:

  • public_key (String)

    binary public key (32 or 40 bytes)

  • secret_key (String, nil) (defaults to: nil)

    binary secret key (32 or 40 bytes), or nil to initialize a public key only certificate

Returns:

Raises:

  • (ArgumentError)

    if keys passed are invalid

  • (SystemCallError)

    if this fails


31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 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

Instance Method Details

#==(other) ⇒ Boolean

Compares this certificate to another.

Parameters:

  • other (Cert)

    other certificate

Returns:

  • (Boolean)

    whether they have the same keys


176
177
178
# File 'lib/cztop/certificate.rb', line 176

def ==(other)
  ffi_delegate.eq(other.ffi_delegate)
end

#[](key) ⇒ String?

Get metadata.

Parameters:

  • key (String)

    metadata key

Returns:

  • (String)

    value for meta key

  • (nil)

    if metadata key is not set


90
91
92
# File 'lib/cztop/certificate.rb', line 90

def [](key)
  ffi_delegate.meta(key)
end

#[]=(key, value) ⇒ value

Set metadata.

Parameters:

  • key (String)

    metadata key

  • value (String)

    metadata value

Returns:

  • (value)

97
98
99
100
101
102
103
# 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) ⇒ void

This method returns an undefined value.

Applies this certificate on a Socket or Actor.

Parameters:

  • zocket (Socket, Actor)

    path/filename to secret file

Raises:

  • (SystemCallError)

    if secret key is undefined


158
159
160
161
162
# 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

#dupCertificate

Duplicates the certificate.

Returns:

Raises:

  • (SystemCallError)

    if this fails


167
168
169
170
171
# 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_keysArray<String>

Returns meta keys set.

Returns:

  • (Array<String>)

107
108
109
110
111
112
113
114
115
116
117
# 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) ⇒ String

Returns the public key either as Z85-encoded ASCII string (default) or binary string.

Parameters:

  • format (Symbol) (defaults to: :z85)

    :z85 for Z85, :binary for binary

Returns:

  • (String)

    public key


55
56
57
58
59
60
61
62
63
64
# 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) ⇒ void

Note:

This will create two files: one of the public key and one for the secret key. The secret filename is filename + “_secret”.

This method returns an undefined value.

Save full certificate (public + secret) to files.

Parameters:

  • filename (String, #to_s)

    path/filename to public file

Raises:

  • (ArgumentError)

    if path is invalid

  • (SystemCallError)

    if this fails


126
127
128
129
130
131
132
# 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) ⇒ void

This method returns an undefined value.

Saves the public key to file in ZPL (CZTop::Config) format.

Parameters:

  • filename (String, #to_s)

    path/filename to public file

Raises:

  • (SystemCallError)

    if this fails


138
139
140
141
142
# 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) ⇒ void

This method returns an undefined value.

Saves the secret key to file in ZPL (CZTop::Config) format.

Parameters:

  • filename (String, #to_s)

    path/filename to secret file

Raises:

  • (SystemCallError)

    if this fails


148
149
150
151
152
# 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) ⇒ String?

Returns the secret key either as Z85-encoded ASCII string (default) or binary string.

Parameters:

  • format (Symbol) (defaults to: :z85)

    :z85 for Z85, :binary for binary

Returns:

  • (String)

    secret key

  • (nil)

    if secret key is undefined (like after loading from a file created using #save_public)


72
73
74
75
76
77
78
79
80
81
82
83
84
# 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