zyre 0.1.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5946a8a32c3932017f3c6fc60d6a54e3a2196a5e193a769975a1c4b47cbb405e
4
- data.tar.gz: 5e51339b1fbc508dd0de7f3abc921aa7c2912cc243fda3a059d9057648c6acb9
3
+ metadata.gz: 8f9955065b8a5747d69568a305961f021969233ef249a1159ec419f81de9cf10
4
+ data.tar.gz: 382479e094fe5beb93ec78f1a3b1e2cc7dc9bf2ad6a1516fe6828a946942223e
5
5
  SHA512:
6
- metadata.gz: 5177153a30ea6f2f28ebfb7372e3055a51ec793ea5a5bd51c3afde8b41ba1909b88a5daae334ab5fd52db9858e10b1f0184e7a4f566f7f8ee7240311748e1ab4
7
- data.tar.gz: 61057878f14e360a57bf233ee5649dec9659686090d20f72461fcb955e387fa204e1afdcbadb8b5112e517a64547a27df5aa18eeea2706a9d65221724fbc89a5
6
+ metadata.gz: dcd9a759228bc18f5192066b1638dbc529b615e829ffd143001d9611c6e9e10ce1fc376fa2d10ad3bf6515a209d4724af4e82dc823f404e1991433c235a51f46
7
+ data.tar.gz: 6601536d2ede57eb152b7908839435334d936cd3cd116e4ca1805aed97fe65724c927f3252950435ff0ac094dd6e4cd017a4cb7855a3fb5a3801178a002f6521
checksums.yaml.gz.sig CHANGED
@@ -1,2 +1,3 @@
1
- b��
2
- ��ˑ�}�d��ܐk���B܆����le��Kt��'���J�~� �����Bf4xIЛx(Z9s�La��f��|c у��)�'}w���Ij�v
1
+ F
2
+ �z1�)ȍ�\�f�@^��a�u���.D��̅�\�v;%��0��I���-Y;&��YN�W��(�{g���X��>�u "�5A����:�Ļ� <p�]V����D��P��t��rG���㾎?DOx�uJp��ɒ+M�~�m��K�؈�9t{GԾ��V����DNY�����p���}bl"Ytk���*�p\qi���a͢�^fsg�zǒ�A�� (���ye芣�]9��k6)gM*=��&�אfaG[F]���,�z��[9V��`��ZI���?�,�?o %�M��ϥދ�J)��W$i���XL�
3
+ n3��K�/DXZԚ�B8��ۤ����G4>4s���[Q����u��)r�;ձ�]�=�G�N
data.tar.gz.sig CHANGED
Binary file
data/Authentication.md ADDED
@@ -0,0 +1,30 @@
1
+ # Authenticated \Zyre
2
+
3
+ Note that authentication requires API that is still in Draft, so it requires
4
+ that your libzyre be built with --enable-drafts. Also, since draft APIs are
5
+ subject to change, this documentation may be out of date. A good place to check
6
+ for the latest info is the built-in test suites in the Zyre source itself.
7
+
8
+ Authentication isn't done yet, but when it is it'll look something like:
9
+
10
+ cert = Zyre::Cert.new
11
+ cert.save( "/usr/local/var/certs/server" )
12
+
13
+ Zyre.allow( "127.0.0.1", "10.0.12.2" )
14
+ Zyre.start_authenticator( :CURVE, "/usr/local/var/certs" )
15
+
16
+ node = Zyre::Node.new
17
+ node.zap_domain = 'application_name'
18
+ node.zcert = cert
19
+ node.start
20
+
21
+ # later...
22
+
23
+ node.stop
24
+ Zyre.stop_authenticator
25
+
26
+
27
+ ## References
28
+
29
+ - ZAP (ZeroMQ Authentication Protocol) - https://rfc.zeromq.org/spec/27/
30
+ - Using ZeroMQ Security (Part 2) - https://jaxenter.com/using-zeromq-security-part-2-119353.html
data/History.md CHANGED
@@ -1,6 +1,42 @@
1
1
  # Release History for zyre
2
2
 
3
3
  ---
4
+ ## v0.4.1 [2021-03-16] Michael Granger <ged@faeriemud.org>
5
+
6
+ Bugfixes:
7
+
8
+ - Add a missing library file to the manifest.
9
+
10
+
11
+ ## v0.4.0 [2021-02-19] Michael Granger <ged@faeriemud.org>
12
+
13
+ Improvements:
14
+
15
+ - Add partial support for draft APIs
16
+ - Add a singleton method for disabling CZMQ's default SIGINT/TERM handler.
17
+
18
+
19
+ ## v0.3.1 [2020-11-23] Michael Granger <ged@faeriemud.org>
20
+
21
+ Bugfixes:
22
+
23
+ - Use cast String in rzyre_add_frames_to_zmsg()
24
+
25
+
26
+ ## v0.3.0 [2020-11-16] Michael Granger <ged@faeriemud.org>
27
+
28
+ Improvements:
29
+
30
+ - Fixed use of binary data in event frames.
31
+
32
+
33
+ ## v0.2.0 [2020-11-09] Michael Granger <ged@faeriemud.org>
34
+
35
+ Improvements:
36
+
37
+ - Add multipart messaging.
38
+ - Allow positional args for testing factory SHOUTs and WHISPERs
39
+
4
40
 
5
41
  ## v0.1.0 [2020-11-05] Michael Granger <ged@faeriemud.org>
6
42
 
data/README.md CHANGED
@@ -21,20 +21,84 @@ reliable group messaging over local area networks, an implementation of [the Zer
21
21
 
22
22
  ### Examples
23
23
 
24
- # Join the Zyre network on the network associated with the given interface
25
- # and dump events from the 'global' group to stderr.
24
+ Zyre is a P2P library which has two modes: pub/sub and direct messaging. To use it, you create a node, optionally join some groups (subscribing), and start it. Then you can send broadcast messages to all other nodes in a group, or direct messages to a particular node.
25
+
26
+ This example joins the Zyre network and dumps messages it sees in the 'global' group to stderr:
27
+
26
28
  node = Zyre::Node.new
27
- node.interface = 'igb0'
29
+ node.join( 'global' )
28
30
  node.start
29
31
 
30
- while event = node.recv
32
+ node.each_event do |event|
31
33
  event.print
32
34
  end
33
35
 
36
+ To send a direct message to a different node you need to know its `UUID`. There are number of ways to discover this:
37
+
38
+ # The UUIDs of all connected peers
39
+ node.peers
40
+ # The UUIDs of all the peers which have joined the `general` group
41
+ node.peers_by_group( 'general' )
42
+ # The UUID of the peer that sent the event
43
+ received_event.peer_uuid
44
+
45
+ You read events from the network with the Zyre::Node#recv method, but it blocks until an event arrives:
46
+
47
+ event = node.recv
48
+
49
+ You can also iterate over arriving events:
50
+
51
+ node.each do |event|
52
+ ...
53
+ end
54
+
55
+ or use Zyre::Node#each as an Enumerator:
56
+
57
+ five_events = node.each_event.take( 5 )
58
+
59
+ You can also wait for a certain type of event:
60
+
61
+ event = node.wait_for( :SHOUT )
62
+
63
+ and time out if it doesn't arrive within a certain length of time:
64
+
65
+ event = node.wait_for( :ENTER, timeout: 2.0 ) or
66
+ raise "No one else on the network!"
67
+
68
+ You can join a group with Zyre::Node#join:
69
+
70
+ node.join( 'alerts' )
71
+
72
+ and you can detect other nodes joining one of your groups by looking for JOIN events (Zyre::Event::Join objects):
73
+
74
+ node.wait_for( :JOIN )
75
+
76
+ You can publish a message to all nodes in a group with Zyre::Node#shout:
77
+
78
+ node.shout( "group1", "This is a message." )
79
+
80
+ and read it:
81
+
82
+ event = other_node.recv
83
+ event.is_multipart? # => false
84
+ event.msg # => "This is a message."
85
+ event.multipart_msg # => ["This is a message."]
86
+
87
+
88
+ Or publish a message with multiple parts:
89
+
90
+ node.shout( "group1", 'message.type', "This is a message." )
91
+
92
+ and read it:
93
+
94
+ event = other_node.recv
95
+ event.is_multipart? # => true
96
+ event.msg # => "message.type"
97
+ event.multipart_msg # => ["message.type", "This is a message."]
98
+
34
99
 
35
100
  ### To-Do
36
101
 
37
- * Implement Zyre::Node#peer_groups and Zyre::Node#peer_address
38
102
  * Implement the draft API methods on Zyre::Node
39
103
  * Hook up logging via `zsys_set_logsender`
40
104
  * Add richer matching to Zyre::Event#match.
@@ -71,7 +135,7 @@ development.
71
135
 
72
136
  ## License
73
137
 
74
- Copyright (c) 2020, Ravn Group
138
+ Copyright (c) 2020-2021, Ravn Group
75
139
  All rights reserved.
76
140
 
77
141
  Redistribution and use in source and binary forms, with or without
@@ -0,0 +1,504 @@
1
+ /*
2
+ * cert.c - A curve certificate for use with Zyre.
3
+ * $Id$
4
+ *
5
+ * Authors:
6
+ * * Michael Granger <ged@FaerieMUD.org>
7
+ *
8
+ */
9
+
10
+ #include "zyre_ext.h"
11
+
12
+ VALUE rzyre_cZyreCert;
13
+
14
+ // Forward declarations
15
+ static void rzyre_cert_free( void *ptr );
16
+
17
+
18
+ static const rb_data_type_t rzyre_cert_t = {
19
+ .wrap_struct_name = "Zyre::Cert",
20
+ .function = {
21
+ .dmark = NULL,
22
+ .dfree = rzyre_cert_free,
23
+ },
24
+ .data = NULL,
25
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
26
+ };
27
+
28
+
29
+ /*
30
+ * Free function
31
+ */
32
+ static void
33
+ rzyre_cert_free( void *ptr )
34
+ {
35
+ if ( ptr ) {
36
+ zcert_destroy( (zcert_t **)&ptr );
37
+ }
38
+ }
39
+
40
+
41
+ /*
42
+ * Alloc function
43
+ */
44
+ static VALUE
45
+ rzyre_cert_alloc( VALUE klass )
46
+ {
47
+ return TypedData_Wrap_Struct( klass, &rzyre_cert_t, NULL );
48
+ }
49
+
50
+
51
+ /*
52
+ * Fetch the data pointer and check it for sanity.
53
+ */
54
+ inline zcert_t *
55
+ rzyre_get_cert( VALUE self )
56
+ {
57
+ zcert_t *ptr;
58
+
59
+ if ( !IsZyreCert(self) ) {
60
+ rb_raise( rb_eTypeError, "wrong argument type %s (expected Zyre::Cert)",
61
+ rb_class2name(CLASS_OF( self )) );
62
+ }
63
+
64
+ ptr = DATA_PTR( self );
65
+ assert( ptr );
66
+
67
+ return ptr;
68
+ }
69
+
70
+
71
+ /*
72
+ * call-seq:
73
+ * Zyre::Cert.from( public_key, secret_key ) -> cert
74
+ *
75
+ * Create a certificate from the +public_key+ and +secret_key+.
76
+ *
77
+ */
78
+ static VALUE
79
+ rzyre_cert_s_from( VALUE class, VALUE public_key, VALUE secret_key )
80
+ {
81
+ VALUE self = rzyre_cert_alloc( class );
82
+ zcert_t *ptr = NULL;
83
+ const char *pub_str = StringValuePtr( public_key ),
84
+ *sec_str = StringValuePtr( secret_key );
85
+
86
+ if ( RSTRING_LEN(public_key) == 32 && RSTRING_LEN(secret_key) == 32 ) {
87
+ ptr = zcert_new_from( (const byte *)pub_str, (const byte *)sec_str );
88
+ } else if ( RSTRING_LEN(public_key) == 40 && RSTRING_LEN(secret_key) == 40 ) {
89
+ #ifdef CZMQ_BUILD_DRAFT_API
90
+ ptr = zcert_new_from_txt( pub_str, sec_str );
91
+ #else
92
+ rb_raise( rb_eNotImpError,
93
+ "can't create a key from encoded keys: Czmq was not built with Draft APIs!" );
94
+ #endif
95
+ }
96
+
97
+ if ( !ptr ) {
98
+ rb_raise( rb_eArgError, "invalid key pair" );
99
+ }
100
+
101
+ RTYPEDDATA_DATA( self ) = ptr;
102
+
103
+ return self;
104
+ }
105
+
106
+
107
+ /*
108
+ * call-seq:
109
+ * Zyre::Cert.load( filename ) -> cert
110
+ *
111
+ * Create a certificate from a saved certificate in the specified
112
+ * +filename+.
113
+ *
114
+ */
115
+ static VALUE
116
+ rzyre_cert_s_load( VALUE class, VALUE filename )
117
+ {
118
+ VALUE self = rzyre_cert_alloc( class );
119
+ zcert_t *ptr = zcert_load( StringValueCStr(filename) );
120
+
121
+ if ( !ptr ) {
122
+ rb_raise( rb_eArgError, "failed to load cert from %s", RSTRING_PTR(filename) );
123
+ }
124
+
125
+ RTYPEDDATA_DATA( self ) = ptr;
126
+
127
+ return self;
128
+ }
129
+
130
+
131
+ /*
132
+ * call-seq:
133
+ * Zyre::Cert.new -> cert
134
+ *
135
+ * Create a new certificate.
136
+ *
137
+ */
138
+ static VALUE
139
+ rzyre_cert_initialize( VALUE self )
140
+ {
141
+ zcert_t *ptr;
142
+
143
+ TypedData_Get_Struct( self, zcert_t, &rzyre_cert_t, ptr );
144
+ if ( !ptr ) {
145
+ RTYPEDDATA_DATA( self ) = ptr = zcert_new();
146
+ assert( ptr );
147
+ }
148
+
149
+ return self;
150
+ }
151
+
152
+
153
+ /*
154
+ * call-seq:
155
+ * cert.public_key -> key_data
156
+ *
157
+ * Return public part of key pair as 32-byte binary string
158
+ *
159
+ */
160
+ static VALUE
161
+ rzyre_cert_public_key( VALUE self )
162
+ {
163
+ zcert_t *ptr = rzyre_get_cert( self );
164
+ const byte *key = zcert_public_key( ptr );
165
+ VALUE rval = rb_enc_str_new( (const char *)key, 32, rb_ascii8bit_encoding() );
166
+
167
+ return rval;
168
+ }
169
+
170
+
171
+ /*
172
+ * call-seq:
173
+ * cert.secret_key -> key_data
174
+ *
175
+ * Return secret part of key pair as 32-byte binary string
176
+ *
177
+ */
178
+ static VALUE
179
+ rzyre_cert_secret_key( VALUE self )
180
+ {
181
+ zcert_t *ptr = rzyre_get_cert( self );
182
+ const byte *key = zcert_secret_key( ptr );
183
+ VALUE rval = rb_enc_str_new( (const char *)key, 32, rb_ascii8bit_encoding() );
184
+
185
+ return rval;
186
+ }
187
+
188
+
189
+ /*
190
+ * call-seq:
191
+ * cert.public_txt -> key_text
192
+ *
193
+ * Return public part of key pair as Z85 armored string
194
+ *
195
+ */
196
+ static VALUE
197
+ rzyre_cert_public_txt( VALUE self )
198
+ {
199
+ zcert_t *ptr = rzyre_get_cert( self );
200
+ const char *key = zcert_public_txt( ptr );
201
+ VALUE rval = rb_usascii_str_new( key, 40 );
202
+
203
+ return rval;
204
+ }
205
+
206
+
207
+ /*
208
+ * call-seq:
209
+ * cert.secret_txt -> key_text
210
+ *
211
+ * Return secret part of key pair as Z85 armored string
212
+ *
213
+ */
214
+ static VALUE
215
+ rzyre_cert_secret_txt( VALUE self )
216
+ {
217
+ zcert_t *ptr = rzyre_get_cert( self );
218
+ const char *key = zcert_secret_txt( ptr );
219
+ VALUE rval = rb_usascii_str_new( key, 40 );
220
+
221
+ return rval;
222
+ }
223
+
224
+
225
+ /*
226
+ * call-seq:
227
+ * cert.set_meta( name, value )
228
+ *
229
+ * Set certificate metadata +name+ to +value+.
230
+ *
231
+ */
232
+ static VALUE
233
+ rzyre_cert_set_meta( VALUE self, VALUE name, VALUE val )
234
+ {
235
+ zcert_t *ptr = rzyre_get_cert( self );
236
+ const char *key_str = StringValueCStr( name ),
237
+ *val_str = StringValueCStr( val );
238
+
239
+ #ifdef CZMQ_BUILD_DRAFT_API
240
+ zcert_unset_meta( ptr, key_str );
241
+ #endif
242
+
243
+ zcert_set_meta( ptr, key_str, "%s", val_str );
244
+
245
+ return val;
246
+ }
247
+
248
+
249
+ /*
250
+ * call-seq:
251
+ * cert.meta( name ) -> string
252
+ *
253
+ * Return the metadata value for +name+ from certificate; if the metadata
254
+ * value doesn't exist, returns +nil+.
255
+ *
256
+ */
257
+ static VALUE
258
+ rzyre_cert_meta( VALUE self, VALUE name )
259
+ {
260
+ zcert_t *ptr = rzyre_get_cert( self );
261
+ VALUE rval = Qnil;
262
+ const char *name_str = StringValuePtr( name );
263
+ const char *value = zcert_meta( ptr, name_str );
264
+
265
+ if ( value ) rval = rb_str_new_cstr( value );
266
+
267
+ return rval;
268
+ }
269
+
270
+
271
+ /*
272
+ * call-seq:
273
+ * cert.keys -> array
274
+ *
275
+ * Return an Array of metadata field names that belong to the receiver.
276
+ *
277
+ */
278
+ static VALUE
279
+ rzyre_cert_meta_keys( VALUE self )
280
+ {
281
+ zcert_t *ptr = rzyre_get_cert( self );
282
+ zlist_t *keys = zcert_meta_keys( ptr );
283
+ VALUE rary = rb_ary_new();
284
+ char *item;
285
+
286
+ assert( keys );
287
+
288
+ item = zlist_first( keys );
289
+ while ( item ) {
290
+ rb_ary_push( rary, rb_str_new_cstr(item) );
291
+ item = zlist_next( keys );
292
+ }
293
+
294
+ zlist_destroy( &keys );
295
+
296
+ return rary;
297
+ }
298
+
299
+
300
+ /*
301
+ * call-seq:
302
+ * cert.unset_meta( name )
303
+ *
304
+ * Unset certificate metadata value for the given +name.
305
+ *
306
+ * Note: this is a draft method for development use, may change without warning.
307
+ *
308
+ */
309
+ static VALUE
310
+ rzyre_cert_unset_meta( VALUE self, VALUE name )
311
+ {
312
+ #ifdef CZMQ_BUILD_DRAFT_API
313
+ zcert_t *ptr = rzyre_get_cert( self );
314
+ const char *name_str = StringValueCStr( name );
315
+
316
+ zcert_unset_meta( ptr, name_str );
317
+
318
+ return Qtrue;
319
+ #else
320
+ rb_raise( rb_eNotImpError, "Czmq was not built with Draft APIs!" );
321
+ #endif // CZMQ_BUILD_DRAFT_API
322
+ }
323
+
324
+
325
+ /*
326
+ * call-seq:
327
+ * cert.save( filename )
328
+ *
329
+ * Save the full certificate (public + secret) to the specified +filename+.
330
+ * This creates one public file and one secret file (filename + "_secret").
331
+ *
332
+ */
333
+ static VALUE
334
+ rzyre_cert_save( VALUE self, VALUE filename )
335
+ {
336
+ zcert_t *ptr = rzyre_get_cert( self );
337
+ const char *filename_str = StringValueCStr( filename );
338
+ int result;
339
+
340
+ result = zcert_save( ptr, filename_str );
341
+
342
+ if ( result != 0 )
343
+ rb_raise( rb_eRuntimeError, "failed to save cert to %s", filename_str );
344
+
345
+ return Qtrue;
346
+ }
347
+
348
+
349
+ /*
350
+ * call-seq:
351
+ * cert.save_public( filename )
352
+ *
353
+ * Save the public certificate only to the specified +filename+.
354
+ *
355
+ */
356
+ static VALUE
357
+ rzyre_cert_save_public( VALUE self, VALUE filename )
358
+ {
359
+ zcert_t *ptr = rzyre_get_cert( self );
360
+ const char *filename_str = StringValueCStr( filename );
361
+ int result;
362
+
363
+ result = zcert_save_public( ptr, filename_str );
364
+
365
+ if ( result != 0 )
366
+ rb_raise( rb_eRuntimeError, "failed to save public cert to %s", filename_str );
367
+
368
+ return Qtrue;
369
+ }
370
+
371
+
372
+ /*
373
+ * call-seq:
374
+ * cert.save_secret( filename )
375
+ *
376
+ * Save the secret certificate only to the specified +filename+.
377
+ *
378
+ */
379
+ static VALUE
380
+ rzyre_cert_save_secret( VALUE self, VALUE filename )
381
+ {
382
+ zcert_t *ptr = rzyre_get_cert( self );
383
+ const char *filename_str = StringValueCStr( filename );
384
+ int result;
385
+
386
+ result = zcert_save_secret( ptr, filename_str );
387
+
388
+ if ( result != 0 )
389
+ rb_raise( rb_eRuntimeError, "failed to save secret cert to %s", filename_str );
390
+
391
+ return Qtrue;
392
+ }
393
+
394
+
395
+ /*
396
+ * call-seq:
397
+ * cert.dup -> cert
398
+ *
399
+ * Return a copy of the certificate.
400
+ *
401
+ */
402
+ static VALUE
403
+ rzyre_cert_dup( VALUE self )
404
+ {
405
+ zcert_t *ptr = rzyre_get_cert( self );
406
+ zcert_t *other_ptr;
407
+ VALUE other = rb_call_super( 0, NULL );
408
+
409
+ RTYPEDDATA_DATA( other ) = other_ptr = zcert_dup( ptr );
410
+
411
+ if ( !other_ptr )
412
+ rb_raise( rb_eRuntimeError, "couldn't duplicate the cert" );
413
+
414
+ return other;
415
+ }
416
+
417
+
418
+ /*
419
+ * call-seq:
420
+ * cert.eql?( other_cert ) -> true or false
421
+ *
422
+ * Return true if the +other_cert+ has the same keys.
423
+ *
424
+ */
425
+ static VALUE
426
+ rzyre_cert_eql_p( VALUE self, VALUE other )
427
+ {
428
+ zcert_t *ptr = rzyre_get_cert( self ),
429
+ *other_ptr = rzyre_get_cert( other );
430
+ bool equal = zcert_eq( ptr, other_ptr );
431
+
432
+ return equal ? Qtrue : Qfalse;
433
+ }
434
+
435
+
436
+ /*
437
+ * call-seq:
438
+ * cert.print
439
+ *
440
+ * Print certificate contents to stdout.
441
+ *
442
+ */
443
+ static VALUE
444
+ rzyre_cert_print( VALUE self )
445
+ {
446
+ zcert_t *ptr = rzyre_get_cert( self );
447
+
448
+ zcert_print( ptr );
449
+
450
+ return Qtrue;
451
+ }
452
+
453
+
454
+
455
+ /*
456
+ * Initialize the Cert class.
457
+ */
458
+ void
459
+ rzyre_init_cert( void ) {
460
+
461
+ #ifdef FOR_RDOC
462
+ rb_cData = rb_define_class( "Data" );
463
+ rzyre_mZyre = rb_define_module( "Zyre" );
464
+ #endif
465
+
466
+ /*
467
+ * Document-class: Zyre::Cert
468
+ *
469
+ * A certificate for Zyre curve authentication.
470
+ *
471
+ * Refs:
472
+ * - http://api.zeromq.org/czmq4-0:zcert
473
+ *
474
+ */
475
+ rzyre_cZyreCert = rb_define_class_under( rzyre_mZyre, "Cert", rb_cObject );
476
+
477
+ rb_define_alloc_func( rzyre_cZyreCert, rzyre_cert_alloc );
478
+
479
+ rb_define_singleton_method( rzyre_cZyreCert, "from", rzyre_cert_s_from, 2 );
480
+ rb_define_singleton_method( rzyre_cZyreCert, "load", rzyre_cert_s_load, 1 );
481
+
482
+ rb_define_protected_method( rzyre_cZyreCert, "initialize", rzyre_cert_initialize, 0 );
483
+
484
+ rb_define_method( rzyre_cZyreCert, "public_key", rzyre_cert_public_key, 0 );
485
+ rb_define_method( rzyre_cZyreCert, "secret_key", rzyre_cert_secret_key, 0 );
486
+ rb_define_method( rzyre_cZyreCert, "public_txt", rzyre_cert_public_txt, 0 );
487
+ rb_define_method( rzyre_cZyreCert, "secret_txt", rzyre_cert_secret_txt, 0 );
488
+
489
+ rb_define_method( rzyre_cZyreCert, "set_meta", rzyre_cert_set_meta, 2 );
490
+ rb_define_method( rzyre_cZyreCert, "meta", rzyre_cert_meta, 1 );
491
+ rb_define_method( rzyre_cZyreCert, "meta_keys", rzyre_cert_meta_keys, 0 );
492
+ rb_define_method( rzyre_cZyreCert, "unset_meta", rzyre_cert_unset_meta, 1 ); // DRAFT
493
+
494
+ rb_define_method( rzyre_cZyreCert, "save", rzyre_cert_save, 1 );
495
+ rb_define_method( rzyre_cZyreCert, "save_public", rzyre_cert_save_public, 1 );
496
+ rb_define_method( rzyre_cZyreCert, "save_secret", rzyre_cert_save_secret, 1 );
497
+
498
+ rb_define_method( rzyre_cZyreCert, "dup", rzyre_cert_dup, 0 );
499
+ rb_define_method( rzyre_cZyreCert, "eql?", rzyre_cert_eql_p, 1 );
500
+ rb_define_method( rzyre_cZyreCert, "print", rzyre_cert_print, 0 );
501
+
502
+ rb_require( "zyre/cert" );
503
+ }
504
+