zyre 0.1.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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
+