The Assimilation Project  based on Assimilation version 1.1.7.1474836767
cryptcurve25519.c
Go to the documentation of this file.
1 #include <glib/gstdio.h>
2 // #include <glib.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <sys/types.h>
28 #include <pwd.h>
29 #include <errno.h>
30 #include <string.h>
31 #include <projectcommon.h>
32 #include <frameset.h>
33 #include <sodium.h>
34 #include <misc.h>
35 #include <cryptcurve25519.h>
36 #include <frametypes.h>
37 #include <generic_tlv_min.h>
38 #include <tlvhelper.h>
39 
41 
42 #define EOS '\0'
43 #define KEY_NAMING_CHECKSUM G_CHECKSUM_MD5
44 
49 
50 
52 FSTATIC gboolean _cryptcurve25519_default_isvalid(const Frame *, gconstpointer, gconstpointer);
53 FSTATIC void _cryptcurve25519_updatedata(Frame*f, gpointer tlvstart, gconstpointer pktend, FrameSet* fs);
54 FSTATIC gboolean _is_valid_curve25519_key_id(const char * key_id, enum keytype ktype);
55 FSTATIC gboolean _is_legal_curve25519_key_id(const char * key_id);
56 FSTATIC char* _cache_curve25519_key_id_to_dirname(const char * key_id, enum keytype);
58 FSTATIC gboolean _cache_curve25519_keypair(const char * key_id);
59 FSTATIC gboolean _cryptcurve25519_save_a_key(const char * key_id, enum keytype ktype, gconstpointer key);
60 FSTATIC enum keytype _cryptcurve25519_keytype_from_filename(const char *filename);
61 FSTATIC char * _cryptcurve25519_key_id_from_filename(const char *filename);
62 static void (*_parentclass_finalize)(AssimObj*) = NULL;
63 FSTATIC void dump_memory(const char * label, const guint8* start, const guint8* end);
64 FSTATIC char* cryptcurve25519_naming_checksum(const guint8* buf, size_t buflen);
65 FSTATIC void cryptcurve25519_debug_checksum(const char * function, int lineno, const char * message, const guint8* buf, size_t bufsize);
66 #define DEBUGCKSUM2(msg, buf, bufsize) {if (DEBUG >= 2) cryptcurve25519_debug_checksum(__FUNCTION__, __LINE__, msg, buf, bufsize);}
67 #define DEBUGCKSUM3(msg, buf, bufsize) {if (DEBUG >= 3) cryptcurve25519_debug_checksum(__FUNCTION__, __LINE__, msg, buf, bufsize);}
68 #define DEBUGCKSUM4(msg, buf, bufsize) {if (DEBUG >= 4) cryptcurve25519_debug_checksum(__FUNCTION__, __LINE__, msg, buf, bufsize);}
69 
70 // Simple memory dump routine
71 FSTATIC void
72 dump_memory(const char * label, const guint8* start, const guint8* end)
73 {
74  GString* gs = g_string_new(NULL);
75  const guint8* p;
76 
77  for (p=start; p < end; ++p) {
78  g_string_append_printf(gs, " %02x", (unsigned char)*p);
79  }
80  g_info("%s [%ld bytes]%s", label, (long)(end - start), gs->str);
81  g_string_free(gs, TRUE);
82  gs = NULL;
83 }
84 
85 /*
86  Our CryptCurve25519 Frame (our TLV Value) looks like this on the wire
87  +----------+---------+----------+----------+-----------------------+---------------------+------------+
88  | sender | sender | receiver | receiver | | | |
89  | key_id | key id | key name | key id | crypto_box_NONCEBYTES | crypto_box_MACBYTES | cyphertext |
90  | length | | length | | (randomeness - nonce) | MAC for cyphertext | -- |
91  | |("length" | |("length" | | | originally |
92  | (1 byte)| bytes) | (1 byte) | bytes) | | | many frames|
93  +----------+---------+----------+----------+-----------------------+---------------------+------------+
94  |<---------------------------- length() value in memory -------------------------------->|
95  |<------------------------------- TLV length on the wire -------------------------------------------->|
96  For the sender: the sender key is private, and the receiver key is public
97  For the receiver: the sender key is public, and the receiver key is private
98  */
99 // Since we allocate enough space for everything in advance, we can do encryption in place
100 #define TLVLEN(receiverkey_id, senderkey_id) \
101  (4 + strnlen(receiverkey_id, MAXCRYPTNAMELENGTH+1) + strnlen(senderkey_id, MAXCRYPTNAMELENGTH+1) \
102  + crypto_box_NONCEBYTES + crypto_box_MACBYTES)
103 
110 
111 FSTATIC char*
113  enum keytype ktype)
114 {
115  (void)key_id;
116  (void)ktype;
117  return g_strdup(CRYPTKEYDIR);
118 }
119 
120 WINEXPORT char*
121 curve25519_key_id_to_filename(const char * key_id,
122  enum keytype ktype)
123 {
124  char * dirname = _cache_curve25519_key_id_to_dirname(key_id, ktype);
125  const char * suffix = (PRIVATEKEY == ktype ? PRIVATEKEYSUFFIX : PUBKEYSUFFIX);
126  char* ret;
127  ret = g_strdup_printf("%s%s%s%s", dirname, DIRDELIM, key_id, suffix);
128  FREE(dirname);
129  return ret;
130 }
131 
134 FSTATIC gboolean
135 _is_legal_curve25519_key_id(const char * key_id)
136 {
137  static const char * validchars =
138  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.+@#";
139  int length;
140  for (length=0; length < MAXCRYPTKEYNAMELENGTH && key_id[length] != EOS; ++length) {
141  if (strchr(validchars, key_id[length]) == NULL) {
142  return FALSE;
143  }
144  }
145  if (length > MAXCRYPTKEYNAMELENGTH) {
146  return FALSE;
147  }
148  return TRUE;
149 }
150 
151 
153 FSTATIC enum keytype
155 {
156  gsize filenamesize = strlen(filename)+1;
157 
158  if (filenamesize > sizeof(PUBKEYSUFFIX)) {
159  gsize offset = filenamesize - sizeof(PUBKEYSUFFIX);
160  if (strcmp(filename+offset, PUBKEYSUFFIX) == 0) {
161  return PUBLICKEY;
162  }
163  }
164  if (filenamesize > sizeof(PRIVATEKEYSUFFIX)) {
165  gsize offset = filenamesize - sizeof(PRIVATEKEYSUFFIX);
166  if (strcmp(filename+offset, PRIVATEKEYSUFFIX) == 0) {
167  return PRIVATEKEY;
168  }
169  }
170  return NOTAKEY;
171 }
172 
174 FSTATIC char *
176 {
177  enum keytype ktype = _cryptcurve25519_keytype_from_filename(filename);
178  gsize filenamesize;
179  gsize suffixlen;
180  gsize prefixlen;
181  const char* lastslash;
182  gsize idlen;
183  char * key_id;
184 
185  if (ktype == NOTAKEY) {
186  return NULL;
187  }
188  filenamesize = strlen(filename);
189  suffixlen = (ktype == PRIVATEKEY ? sizeof(PRIVATEKEYSUFFIX) : sizeof(PUBKEYSUFFIX))-1;
190  lastslash = strrchr(filename, DIRDELIM[0]);
191  prefixlen = (lastslash == NULL ? 0 : (1+ (lastslash - filename)));
192  idlen = (filenamesize - prefixlen) - suffixlen;
193  key_id = g_strndup(filename + prefixlen, idlen);
194  if (!_is_legal_curve25519_key_id(key_id)) {
195  g_free(key_id); key_id = NULL;
196  }
197  return key_id;
198 }
199 
200 
201 
204 FSTATIC gboolean
205 _is_valid_curve25519_key_id(const char * key_id,
206  enum keytype ktype)
207 {
208  if (!_is_legal_curve25519_key_id(key_id)) {
209  g_warning("%s.%d: Key id %s is not legal.", __FUNCTION__, __LINE__, key_id);
210  return FALSE;
211  }
212  if (_cache_curve25519_keypair(key_id)) {
213  if (ktype == PRIVATEKEY) {
215  if (NULL == secret) {
216  g_warning("%s.%d: Private Key id %s is not cached."
217  , __FUNCTION__, __LINE__, key_id);
218  return FALSE;
219  }
220  }
221  return TRUE;
222  }
223  g_warning("%s.%d: Key id %s could not be cached.", __FUNCTION__, __LINE__, key_id);
224  return FALSE;
225 }
226 
229 FSTATIC gboolean
230 _cache_curve25519_keypair(const char * key_id)
231 {
232  GStatBuf statinfo;
233  char * filename;
234  gpointer public_key = NULL;
235  gpointer secret_key = NULL;
236  gboolean retval = TRUE;
237  int fd = -1;
238  int rc;
239 
240  /*
241  * Coverity CID 1262413:
242  * Coverity complains about this code with a Time of Check / Time of Use warning.
243  * The file attributes we check in the stat calls below might have changed before
244  * we read the key files.
245  *
246  * Although this is true, it is unlikely because of the permissions of the
247  * directories and files involved.
248  *
249  * We only look at two attributes:
250  * - file size
251  * - file type
252  * If the file size changes, we will detect that because we try and read one extra byte.
253  * If the file type changes, we're screwed. But that's really unlikely and
254  * unlikely to have the code succeed when reading a socket, directory, fifo or device.
255  * It might cause the program to hang (on read), but I think that's nearly inevitable
256  * and not worth the trouble to fix.
257  * If the file type changes, the open might hang too...
258  * So, we're pretty paranoid, and I judge us to be at least as paranoid as necessary.
259  */
260 
261  if (cryptframe_public_key_by_id(key_id) != NULL) {
262  return TRUE;
263  }
264  filename = curve25519_key_id_to_filename(key_id, PUBLICKEY);
265  if (g_stat(filename, &statinfo) < 0) {
266  g_warning("%s.%d: g_stat error [%s] NOT Caching key id %s [%s]"
267  , __FUNCTION__, __LINE__
268  , filename, key_id, g_strerror(errno));
269  retval = FALSE;
270  goto getout;
271  }
272  if (statinfo.st_size != crypto_box_PUBLICKEYBYTES || !S_ISREG(statinfo.st_mode)
273  || g_access(filename, R_OK) != 0) {
274  retval = FALSE;
275  g_warning("%s.%d: size/type/access error on %s NOT Caching key id %s"
276  , __FUNCTION__, __LINE__, filename, key_id);
277  goto getout;
278  }
279  fd = open(filename, O_RDONLY);
280  if (fd < 0) {
281  retval = FALSE;
282  g_warning("%s.%d: open error on %s NOT Caching key id %s", __FUNCTION__, __LINE__
283  , filename, key_id);
284  goto getout;
285  }
286  public_key = g_malloc(crypto_box_PUBLICKEYBYTES+1);
287  rc = read(fd, public_key, crypto_box_PUBLICKEYBYTES+1);
288  if (rc != crypto_box_PUBLICKEYBYTES) {
289  g_warning("%s.%d: public key read on %s returned %d instead of %d [%s]"
290  , __FUNCTION__, __LINE__, filename
291  , rc, crypto_box_PUBLICKEYBYTES, g_strerror(errno));
292  retval = FALSE;
293  goto getout;
294  }
295 
296  close(fd); fd = -1;
297  DEBUGCKSUM4(filename, public_key, crypto_box_PUBLICKEYBYTES);
298 
299  g_free(filename);
300  filename = curve25519_key_id_to_filename(key_id, PRIVATEKEY);
301  if (g_stat(filename, &statinfo) >= 0) {
302  if (statinfo.st_size != crypto_box_SECRETKEYBYTES || !S_ISREG(statinfo.st_mode)) {
303  g_warning("%s.%d: secret key stat on [%s] returned %d instead of %d [%s]"
304  , __FUNCTION__, __LINE__, filename
305  , (int)statinfo.st_size, crypto_box_SECRETKEYBYTES, g_strerror(errno));
306  goto getout;
307  }
308  if (g_access(filename, R_OK) != 0) {
309  // Someone else's secret key... Not a problem...
310  goto getout;
311  }
312  secret_key = g_malloc(crypto_box_SECRETKEYBYTES+1);
313  fd = open(filename, O_RDONLY);
314  if (fd < 0) {
315  retval = FALSE;
316  g_warning("%s.%d: open error on %s NOT Caching key id %s", __FUNCTION__, __LINE__
317  , filename, key_id);
318  goto getout;
319  }
320  rc = read(fd, secret_key, crypto_box_SECRETKEYBYTES+1);
321  if (rc != crypto_box_SECRETKEYBYTES) {
322  g_warning("%s.%d: secret key read of %s returned %d instead of %d [%s]"
323  , __FUNCTION__, __LINE__, filename
324  , rc, crypto_box_SECRETKEYBYTES, g_strerror(errno));
325  retval = FALSE;
326  goto getout;
327  }
328  DEBUGCKSUM4(filename, secret_key, crypto_box_SECRETKEYBYTES);
329  close(fd); fd = -1;
330  }
331 getout:
332  // Coverity: CID 1262410 - It doesn't like verifying non-NULL in this error leg
333  // But it's a goto error leg, and in the future the code might change.
334  // So I like it as is...
335  if (filename != NULL) {
336  g_free(filename);
337  filename = NULL;
338  }
339  if (fd >= 0) {
340  close(fd); fd = -1;
341  }
342  if (retval) {
343  g_assert(public_key != NULL);
344  (void)cryptframe_publickey_new(key_id, public_key);
345  if (secret_key) {
346  (void)cryptframe_privatekey_new(key_id, secret_key);
347  }
348  }else{
349  if (public_key) {
350  g_free(public_key);
351  public_key = NULL;
352  }
353  if (secret_key) {
354  g_free(secret_key);
355  secret_key = NULL;
356  }
357  }
358  return retval;
359 }
360 
366 WINEXPORT gboolean
367 cryptcurve25519_purge_keypair(const char* key_id)
368 {
369  char * filename;
370  gboolean retval = TRUE;
371  g_return_val_if_fail(_is_legal_curve25519_key_id(key_id), FALSE);
372 
373  filename = curve25519_key_id_to_filename(key_id, PUBLICKEY);
374  if (g_access(filename, F_OK) == 0) {
375  if (g_unlink(filename) != 0) {
376  g_warning("%s.%d: Unable to remove public key file [%s]. Reason: %s"
377  , __FUNCTION__, __LINE__, filename, g_strerror(errno));
378  retval = FALSE;
379  }
380  }
381  g_free(filename); filename = NULL;
382 
383  filename = curve25519_key_id_to_filename(key_id, PRIVATEKEY);
384  if (g_access(filename, F_OK) == 0) {
385  if (g_unlink(filename) != 0) {
386  g_warning("%s.%d: Unable to remove private key file [%s] Reason: %s"
387  , __FUNCTION__, __LINE__, filename, g_strerror(errno));
388  retval = FALSE;
389  }
390  }
391  g_free(filename); filename = NULL;
392  cryptframe_purge_key_id(key_id);
393  g_warning("%s.%d: Key ID %s has been purged.", __FUNCTION__, __LINE__, key_id);
394  return retval;
395 }
396 
398 WINEXPORT void
400 {
401  GDir* key_directory;
402  const char* filename;
403 
405  key_directory = g_dir_open(CRYPTKEYDIR, 0, NULL);
406 
407  if (NULL == key_directory) {
408  g_warning("%s.%d: Cannot open directory \"%s\" [%s]", __FUNCTION__, __LINE__
409  , CRYPTKEYDIR, g_strerror(errno));
410  return;
411  }
412 
413  while (NULL != (filename = g_dir_read_name(key_directory))) {
415  char * key_id = _cryptcurve25519_key_id_from_filename(filename);
416  if (NULL == key_id) {
417  continue;
418  }
420  g_free(key_id); key_id = NULL;
421  }
422  }
423  g_dir_close(key_directory);
424 }
425 
427 FSTATIC gboolean
429  gconstpointer tlvstart,
430  gconstpointer pktend)
431 {
432  const CryptCurve25519* self = CASTTOCONSTCLASS(CryptCurve25519, fself);
433  const guint8* valptr;
434  const char* key_id;
435  guint namelen;
436  gsize pktlen;
437  int j;
438 
439  // Validate "object" only
440  if (NULL == tlvstart) {
441  namelen = strnlen(self->baseclass.receiver_key_id, MAXCRYPTNAMELENGTH+1);
442  if (fself->length != TLVLEN(self->baseclass.receiver_key_id, self->baseclass.sender_key_id)) {
443  g_warning("%s.%d: Packet length [%d] is incorrect."
444  , __FUNCTION__, __LINE__, (int)fself->length);
445  return FALSE;
446  }
447  namelen = strnlen(self->baseclass.receiver_key_id, MAXCRYPTNAMELENGTH+1);
448  if (namelen >= MAXCRYPTNAMELENGTH || namelen < 1 ){
449  g_warning("%s.%d: Packet length [%d] is invalid."
450  , __FUNCTION__, __LINE__, (int)namelen);
451  return FALSE;
452  }
453  if (!_is_valid_curve25519_key_id(self->baseclass.receiver_key_id, self->forsending? PUBLICKEY: PRIVATEKEY)) {
454  g_warning("%s.%d: %s ID is not a valid curve25519 key ID."
455  , __FUNCTION__, __LINE__, self->forsending ? "PUBLICKEY": "PRIVATEKEY");
456  return FALSE;
457  }
458  namelen = strnlen(self->baseclass.sender_key_id, MAXCRYPTNAMELENGTH+1);
459  if (namelen >= MAXCRYPTNAMELENGTH || namelen < 1 ){
460  g_warning("%s.%d: key id length (%d) is invalid"
461  , __FUNCTION__, __LINE__, namelen);
462  return FALSE;
463  }
464  if (!_is_valid_curve25519_key_id(self->baseclass.sender_key_id, self->forsending ? PRIVATEKEY: PUBLICKEY)) {
465  g_warning("%s.%d: %s ID is not a valid curve25519 key ID."
466  , __FUNCTION__, __LINE__, self->forsending ? "PRIVATEKEY" : "PUBLICKEY");
467  return FALSE;
468  }
469  return TRUE;
470  }
471 
472  // Validate TLV
473  pktlen = get_generic_tlv_len(tlvstart, pktend);
474  // 6 == two 1-byte lengths, and two NUL-terminated strings of at least 2 bytes each
475  if (pktlen < (crypto_box_NONCEBYTES + crypto_box_MACBYTES+6)) {
476  g_warning("%s.%d: Packet length [%d] is too short."
477  , __FUNCTION__, __LINE__, (int)pktlen);
478  return FALSE;
479  }
480  valptr = get_generic_tlv_value(tlvstart, pktend);
481  // Validate both key names in the packet...
482  for (j=0; j < 2; ++ j) {
483  if ((gconstpointer)(valptr+3) >= pktend) {
484  g_warning("%s.%d: Key name (%d) extends beyond end."
485  , __FUNCTION__, __LINE__, j);
486  return FALSE;
487  }
488  namelen = tlv_get_guint8(valptr, pktend);
489  if (namelen < 2 || (namelen-1) > MAXCRYPTNAMELENGTH) {
490  g_warning("%s.%d: Name (%d) length (%d) is invalid."
491  , __FUNCTION__, __LINE__, j, namelen);
492  return FALSE;
493  }
494  valptr += 1;
495  if ((gconstpointer)(valptr+namelen) > pktend) {
496  g_warning("%s.%d: Key name (%d) extends beyond end", __FUNCTION__, __LINE__, j);
497  return FALSE;
498  }
499  key_id = (const char *)(valptr);
500  if (strnlen(key_id, namelen) != (namelen-1)) {
501  g_warning("%s.%d: Key name (%d) length %d improperly terminated"
502  , __FUNCTION__, __LINE__, j, namelen);
503  return FALSE;
504  }
505  // We say PUBLICKEY since we don't know whether we're validating this
506  // on the sender or the receiver end - and whether should be a public
507  // or a private key will depend on which end we're at - and everyone
508  // needs a public key. If we have a public key but need a private
509  // key that will get caught when we try and decrypt it.
510  // At least this catches garbage and unknown keys
511  if (!_is_valid_curve25519_key_id(key_id, PUBLICKEY)) {
512  g_warning("%s.%d: Packet encrypted using unknown key [%s]", __FUNCTION__, __LINE__
513  , key_id);
514  return FALSE;
515  }
516  valptr += namelen;
517  }
518  return TRUE;
519 }
520 
521 
524 cryptcurve25519_new(guint16 frame_type,
525  const char * sender_key_id,
526  const char * receiver_key_id,
527  gboolean forsending,
528  gsize objsize)
529 {
530  CryptFrame* baseframe;
531  CryptCurve25519* ret;
532 
534  if (objsize < sizeof(CryptCurve25519)) {
535  objsize = sizeof(CryptCurve25519);
536  }
537  if (NULL == sender_key_id) {
538  sender_key_id = cryptframe_get_signing_key_id();
539  }
540  DEBUGMSG2("%s.%d:(%s, %s, %d)", __FUNCTION__, __LINE__, sender_key_id, receiver_key_id
541  , (int)objsize);
542  g_return_val_if_fail(sender_key_id != NULL && receiver_key_id != NULL, NULL);
543  if (!_is_valid_curve25519_key_id(receiver_key_id, PUBLICKEY)) {
544  g_critical("%s.%d: public key name [%s] is invalid", __FUNCTION__, __LINE__, receiver_key_id);
545  return NULL;
546  }
547  if (!_is_valid_curve25519_key_id(sender_key_id, PUBLICKEY)) {
548  g_critical("%s.%d: public key name [%s] is invalid", __FUNCTION__, __LINE__, sender_key_id);
549  return NULL;
550  }
551  baseframe = cryptframe_new(frame_type, sender_key_id, receiver_key_id, objsize);
552  if (!_parentclass_finalize) {
553  _parentclass_finalize = baseframe->baseclass.baseclass._finalize;
554  }
557  baseframe->baseclass.length = TLVLEN(receiver_key_id, sender_key_id);
559  ret = NEWSUBCLASS(CryptCurve25519, baseframe);
560  ret->forsending = forsending;
561  ret->private_key = cryptframe_private_key_by_id(forsending ? sender_key_id : receiver_key_id);
562  ret->public_key = cryptframe_public_key_by_id(forsending ? receiver_key_id : sender_key_id);
563  if (ret->private_key && ret->public_key) {
564  DEBUGCKSUM3("private_key:", ret->private_key->private_key, crypto_box_SECRETKEYBYTES);
565  DEBUGCKSUM3("public_key:", ret->public_key->public_key, crypto_box_PUBLICKEYBYTES);
566  DUMP3(__FUNCTION__, &ret->baseclass.baseclass.baseclass, " is return value");
567  REF(ret->private_key);
568  REF(ret->public_key);
569  }else{
570  if (!ret->private_key) {
571  g_warning("%s.%d: Sender private key is NULL for key id %s", __FUNCTION__, __LINE__
572  , sender_key_id);
573  abort();
574  }
575  if (!ret->public_key) {
576  g_warning("%s.%d: Receiver public key is NULL for key id %s", __FUNCTION__, __LINE__
577  , receiver_key_id);
578  }
579  UNREF3(ret);
580  return NULL;
581  }
582  return ret;
583 }
584 
586 FSTATIC void
588 {
590 
591  if (self->public_key) {
592  UNREF(self->public_key);
593  }
594  if (self->private_key) {
595  UNREF(self->private_key);
596  }
597  _parentclass_finalize(aself);
598 }
599 
606  gconstpointer pktend,
607  gpointer* ignorednewpkt,
608  gpointer* ignoredpktend)
609 {
610  guint8* valptr = get_generic_tlv_nonconst_value(tlvstart, pktend);
611  guint8* nonce;
612  guint8* cyphertext;
613  const guint8* tlvend8 = valptr + get_generic_tlv_len(tlvstart, pktend);
614  guint8* plaintext;
615  CryptCurve25519* ret;
616  guint namelen;
617  gsize cypherlength;
618  // The first key name is in sender's key name
619  // The second key name is in receiver's key name
620  CryptFramePublicKey * sender_public_key = NULL;
621  CryptFramePrivateKey* receiver_secret_key = NULL;
622  const char* sender_pubkey_id = NULL;
623  const char* rcvr_seckey_id = NULL;
624  int j;
625 
626  (void)ignorednewpkt; (void)ignoredpktend;
627  valptr = get_generic_tlv_nonconst_value(tlvstart, pktend);
628  for (j=0; j < 2; ++j) {
629  char * key_id;
630  g_return_val_if_fail((gpointer)(valptr+2) <= pktend, NULL);
631  namelen = tlv_get_guint8(valptr, pktend);
632  valptr += 1;
633  g_return_val_if_fail((gpointer)(valptr+namelen) <= pktend, NULL);
634  key_id = (char *)valptr;
635  g_return_val_if_fail (strnlen(key_id, namelen) == namelen -1, NULL);
636  g_return_val_if_fail(_is_valid_curve25519_key_id(key_id
637  , 0 == j ? PUBLICKEY : PRIVATEKEY), NULL);
638  if (0 == j) {
639  sender_public_key = cryptframe_public_key_by_id(key_id);
640  sender_pubkey_id = key_id;
641  }else{
642  receiver_secret_key = cryptframe_private_key_by_id(key_id);
643  rcvr_seckey_id = key_id;
644  }
645  g_return_val_if_fail(key_id != NULL, NULL);
646  valptr += namelen;
647  }
648  if (NULL == sender_public_key) {
649  g_warning("%s.%d: No access to sender %s public key"
650  , __FUNCTION__, __LINE__, sender_pubkey_id);
651  return NULL;
652  }
653  if (NULL == receiver_secret_key) {
654  g_warning("%s.%d: No access to receiver %s private key"
655  , __FUNCTION__, __LINE__, rcvr_seckey_id);
656  return NULL;
657  }
658  g_return_val_if_fail((gpointer)(valptr + (crypto_box_NONCEBYTES+crypto_box_MACBYTES)) <= pktend, NULL);
659  nonce = valptr;
660  cyphertext = nonce + crypto_box_NONCEBYTES;
661  plaintext = cyphertext + crypto_box_MACBYTES;
662  cypherlength = tlvend8 - cyphertext;
663  DEBUGCKSUM4("nonce:", nonce, crypto_box_NONCEBYTES);
664  DEBUGCKSUM4("sender public key :", sender_public_key -> public_key, crypto_box_PUBLICKEYBYTES);
665  DEBUGCKSUM4("receiver private key:", receiver_secret_key->private_key, crypto_box_SECRETKEYBYTES);
666  DEBUGMSG4("cypher offset versus tlvstart: %ld", (long)(cyphertext-(guint8*)tlvstart));
667  DEBUGCKSUM4("cypher text:", cyphertext, cypherlength);
668  if (crypto_box_open_easy(plaintext, cyphertext, cypherlength, nonce
669  , sender_public_key->public_key, receiver_secret_key->private_key) != 0) {
670  g_warning("%s.%d: could not decrypt %d byte message encrypted with key pair [pub:%s, sec:%s]"
671  , __FUNCTION__, __LINE__, (int)cypherlength, sender_pubkey_id, rcvr_seckey_id);
672  return NULL;
673  }
674  DEBUGCKSUM4("plain text:", plaintext, cypherlength-crypto_box_MACBYTES);
675  // Note that our return value's size will determine where the beginning of the
676  // decrypted data is (according to it's dataspace() member function)
677  ret = cryptcurve25519_new(get_generic_tlv_type(tlvstart, pktend)
678  , (const char *)sender_pubkey_id
679  , rcvr_seckey_id, FALSE, 0);
680  return (ret ? &(ret->baseclass.baseclass) : NULL);
681 }
688 FSTATIC void
690  gpointer tlvstart,
691  gconstpointer pktend,
692  FrameSet* unused_fs)
693 {
695  const guint8* pktend8 = pktend;
696  //guint8* tlvstart8 = tlvstart;
697  guint8* tlvval;
698  guint8* valptr;
699  guint32 plaintextoffset;
700  guint32 plaintextsize;
701  guint32 cyphertextoffset;
702  guint32 nonceoffset;
703  guint32 tlvsize;
704  unsigned char* nonce;
705  int j;
706 
707  (void)unused_fs;
708 
709  // [key1, key2, nonce, MAC, plaintext]
710 
711  DUMP3(__FUNCTION__, &f->baseclass, " is CryptCurve25519 Frame being processed.");
712  DEBUGMSG3("%s.%d: tlvstart:%p, pktend:%p", __FUNCTION__, __LINE__, tlvstart, pktend);
713  // The plain text starts immediately after our (incoming) frame
714  plaintextoffset = f->length; // Plain text starts here
715  cyphertextoffset = plaintextoffset - crypto_box_MACBYTES; // Preceded by MAC
716  nonceoffset = cyphertextoffset - crypto_box_NONCEBYTES; // Preceded by nonce
717  // Our (outgoing) frame consists of the original incoming frame plus all other frames after ours
718  tlvval = get_generic_tlv_nonconst_value(tlvstart, pktend);
719  tlvsize = pktend8 - tlvval;
720  plaintextsize = (tlvsize - plaintextoffset);
721 
722  // Generate a "nonce" as part of the packet - make known plaintext attacks harder
723  // ... lots of our plaintext is easy to figure out ...
724  nonce = tlvval + nonceoffset;
725  DEBUGMSG3("%s.%d: generating random nonce (%p, %d, %p)", __FUNCTION__, __LINE__
726  , nonce, (int)crypto_box_NONCEBYTES, nonce+crypto_box_NONCEBYTES);
727  randombytes_buf(nonce, crypto_box_NONCEBYTES);
728  DEBUGMSG3("%s.%d: random nonce generated.", __FUNCTION__, __LINE__);
729 
730  DEBUGMSG3("%s.%d: public->key_id: [%s], private_key->key_id: [%s]", __FUNCTION__, __LINE__
731  , self->public_key->key_id, self->private_key->key_id);
732  DEBUGMSG3("%s.%d: calling crypto_box_easy(%p,%p,%d,%p,%p,%p)", __FUNCTION__, __LINE__
733  , tlvval+cyphertextoffset, tlvval+plaintextoffset, plaintextsize
734  , nonce, self->public_key->public_key, self->private_key->private_key);
735  DEBUGCKSUM4("plain text cksum:", tlvval+plaintextoffset, plaintextsize);
736  DEBUGCKSUM4("receiver public key cksum:",self->public_key -> public_key, crypto_box_PUBLICKEYBYTES);
737  DEBUGCKSUM4("sender private key cksum:", self->private_key->private_key, crypto_box_SECRETKEYBYTES);
738  DEBUGCKSUM4("nonce cksum:", nonce, crypto_box_NONCEBYTES);
739  // Encrypt in-place [we previously allocated enough space for authentication info]
740  g_return_if_fail(0 == crypto_box_easy(tlvval+cyphertextoffset, tlvval+plaintextoffset, plaintextsize
741  , nonce, self->public_key->public_key, self->private_key->private_key));
742  DEBUGMSG4("cypher offset versus tlvstart: %ld", (long)(tlvval+cyphertextoffset-(guint8*)tlvstart));
743  DEBUGCKSUM4("cypher text checksum:", tlvval+cyphertextoffset, plaintextsize+crypto_box_MACBYTES);
744  set_generic_tlv_type(tlvstart, self->baseclass.baseclass.type, pktend);
745  set_generic_tlv_len(tlvstart, tlvsize, pktend);
746  // Put in the frame type, length, key name length, and key name for both keys
747  // We're the sender - our [private] key name goes first, then the receiver's [public] key name
748  valptr = get_generic_tlv_nonconst_value(tlvstart, pktend);
749  for (j=0; j < 2; ++j) {
750  char * key_id = (j == 0 ? self->baseclass.sender_key_id : self->baseclass.receiver_key_id);
751  int keylen = strlen(key_id)+1;
752  tlv_set_guint8(valptr, keylen, pktend);
753  valptr += 1;
754  g_strlcpy((char *)valptr, key_id, keylen);
755  valptr += keylen;
756  }
757  DEBUGMSG3("%s.%d: returning after next assert (tlvval:%p, tlvsize%d, pktend:%p"
758  , __FUNCTION__, __LINE__, tlvval, (int)tlvsize, pktend);
759  g_assert((tlvval + tlvsize) == pktend);
760  DEBUGMSG3("%s.%d: returning (assert passed).", __FUNCTION__, __LINE__);
761 }
762 
764 WINEXPORT void
766 {
767  unsigned char* public_key = g_malloc(crypto_box_PUBLICKEYBYTES);
768  unsigned char* secret_key = g_malloc(crypto_box_SECRETKEYBYTES);
769 
770  crypto_box_keypair(public_key, secret_key);
771  (void) cryptframe_privatekey_new(key_id, secret_key);
772  (void) cryptframe_publickey_new(key_id, public_key);
773 }
774 
776 FSTATIC char*
778  size_t buflen)
779 {
780  return g_compute_checksum_for_data(KEY_NAMING_CHECKSUM, buf, buflen);
781 }
782 
784 FSTATIC void
785 cryptcurve25519_debug_checksum( const char * function,
786  int lineno,
787  const char * message,
788  const guint8* buf,
789  size_t bufsize)
790 {
791  char * checksum = cryptcurve25519_naming_checksum(buf, bufsize);
792  g_debug("%s.%d: %s [%ld]%s", function, lineno, message, (long)bufsize, checksum);
793  g_free(checksum);
794 }
795 
798 WINEXPORT char *
799 cryptcurve25519_gen_persistent_keypair(const char * giveitaname)
800 {
801  unsigned char* public_key = g_malloc(crypto_box_PUBLICKEYBYTES);
802  unsigned char* secret_key = g_malloc(crypto_box_SECRETKEYBYTES);
803  char* key_id;
804  char* sysname;
805 
806  // This is to try and keep our dummy array from being optimized out
807  // so that we get stack protection, and clang doesn't complain...
808  crypto_box_keypair(public_key, secret_key);
809  if (NULL == giveitaname) {
810  char* checksum_string;
811  // Then we'll generate one based on host name and key's checksum
812  checksum_string = cryptcurve25519_naming_checksum(public_key, crypto_box_PUBLICKEYBYTES);
813  sysname = proj_get_sysname();
814  key_id = g_strdup_printf("%s@@%s", sysname, checksum_string);
815  g_free(sysname); g_free(checksum_string);
816  }else{
817  key_id = g_strdup(giveitaname);
818  }
819  DEBUGMSG1("%s.%d: Generating permanent key pair [%s]", __FUNCTION__, __LINE__, key_id);
820  // Write out the two generated keys (the key-pair) into the correct names
821  if (!_cryptcurve25519_save_a_key(key_id, PUBLICKEY, public_key)
822  || !_cryptcurve25519_save_a_key(key_id, PRIVATEKEY, secret_key)
823  || cryptframe_privatekey_new(key_id, secret_key) == NULL
824  || cryptframe_publickey_new(key_id, public_key) == NULL) {
825  // Something didn't work :-(
827  g_free(public_key); public_key = NULL;
828  g_free(secret_key); secret_key = NULL;
829  g_free(key_id); key_id = NULL;
830  return NULL;
831  }
832 
834  return key_id;
835 }
836 
838 WINEXPORT gboolean
839 cryptcurve25519_save_public_key(const char * key_id,
840  gpointer public_key,
841  int keysize)
842 {
843  CryptFramePublicKey* pub;
844  gpointer* newpub;
845  if (keysize != crypto_box_PUBLICKEYBYTES) {
846  g_warning("%s.%d: Attempt to save a public key of %d bytes (instead of %d)"
847  , __FUNCTION__, __LINE__, keysize, crypto_box_PUBLICKEYBYTES);
848  return FALSE;
849  }
850  if ((pub = cryptframe_public_key_by_id(key_id)) != NULL) {
851  if (memcmp(public_key, pub->public_key, keysize) == 0) {
852  return TRUE;
853  }
854  g_critical("%s.%d: Attempt to modify public key with id [%s]"
855  , __FUNCTION__, __LINE__, key_id);
856  return FALSE;
857  }
858  newpub = malloc(keysize);
859  memcpy(newpub, public_key, keysize);
860  if (!_cryptcurve25519_save_a_key(key_id, PUBLICKEY, newpub)
861  || cryptframe_publickey_new(key_id, newpub) == NULL) {
863  g_free(newpub); newpub = NULL;
864  return FALSE;
865  }
866  if (DEBUG) {
868  g_return_val_if_fail(pub != NULL, FALSE);
869  g_return_val_if_fail(memcmp(public_key, pub->public_key, keysize) == 0, FALSE);
870  }
871  return TRUE;
872 }
873 
874 
876 FSTATIC void
878 {
879  struct passwd* pw;
880  char * cmd = g_strdup_printf("mkdir -p '%s'", dirname);
881  int rc = system(cmd);
882  FREE(cmd);
883  if (rc != 0) {
884  g_warning("%s.%d: Could not make directory %s"
885  , __FUNCTION__, __LINE__, dirname);
886  }
887  rc = chmod(dirname, 0700);
888  if (rc < 0) {
889  g_warning("%s.%d: Could not chmod 0700 %s [%s]"
890  , __FUNCTION__, __LINE__, dirname, g_strerror(errno));
891  }
892  pw = getpwnam(CMAUSERID);
893  if (NULL != pw) {
894  rc = chown(dirname, pw->pw_uid, pw->pw_gid);
895  if (rc < 0) {
896  g_warning("%s.%d: Could not chown %s %s [%s]"
897  , __FUNCTION__, __LINE__, CMAUSERID, dirname, g_strerror(errno));
898  }
899  }
900 }
901 
903 FSTATIC gboolean
904 _cryptcurve25519_save_a_key(const char * key_id,
905  enum keytype ktype,
906  gconstpointer key)
907 {
908  ssize_t keysize;
909  guint32 createmode;
910  int fd;
911  int rc;
912  char* filename;
913 
914  if (!_is_legal_curve25519_key_id(key_id)) {
915  g_warning("%s.%d: Key id %s is illegal", __FUNCTION__, __LINE__, key_id);
916  return FALSE;
917  }
918  filename = curve25519_key_id_to_filename(key_id, ktype);
919 
920  if (PUBLICKEY == ktype) {
921  keysize = crypto_box_PUBLICKEYBYTES;
922  createmode = 0644;
923  }else if (PRIVATEKEY == ktype) {
924  keysize = crypto_box_SECRETKEYBYTES;
925  createmode = 0600;
926  }else{
927  g_error("%s.%d: Key type %d is illegal", __FUNCTION__, __LINE__, ktype);
928  g_return_val_if_reached(FALSE);
929  }
930  // If it's a public key, it may exist but not be writable by us...
931  if (PUBLICKEY == ktype && g_access(filename, R_OK) == 0) {
932  // So, let's check and see if it's what we think it should be...
933  if (_cache_curve25519_keypair(key_id)) {
935  if (pub && memcmp(pub->public_key, key, keysize) == 0) {
936  FREE(filename); filename = NULL;
937  return TRUE;
938  }
939  }
940  }
941  fd = open(filename, O_WRONLY|O_CREAT, createmode);
942  if (fd < 0 && (ENOENT == errno)) {
943  char* dirname = _cache_curve25519_key_id_to_dirname(key_id, ktype);
945  FREE(dirname);
946  fd = open(filename, O_WRONLY|O_CREAT, createmode);
947  }
948  if (fd < 0) {
949  g_warning("%s.%d: cannot create file %s [%s]", __FUNCTION__, __LINE__
950  , filename, g_strerror(errno));
951  g_free(filename);
952  return FALSE;
953  }
954  DEBUGMSG4("Saving key to file %s", filename);
955  DEBUGCKSUM4("Saved key:", key, keysize);
956  rc = write(fd, key, keysize);
957  if (rc != keysize) {
958  g_warning("%s.%d: cannot write file %s: rc=%d [%s]", __FUNCTION__, __LINE__
959  , filename, rc, g_strerror(errno));
960  close(fd);
961  g_unlink(filename);
962  g_free(filename);
963  return FALSE;
964  }
965  if (close(fd) < 0) {
966  g_warning("%s.%d: Close of file %s failed.", __FUNCTION__, __LINE__, filename);
967  g_unlink(filename);
968  g_free(filename);
969  return FALSE;
970  }
971  chmod(filename, createmode); // Ignore umask...
972  DEBUGMSG1("%s.%d: file %s successfully created!", __FUNCTION__, __LINE__, filename);
973  g_free(filename);
974  return TRUE;
975 }
976 
979 cryptcurve25519_new_generic(const char* sender_key_id,
980  const char* receiver_key_id,
981  gboolean forsending)
982 {
983  CryptCurve25519* ret = cryptcurve25519_new(FRAMETYPE_CRYPTCURVE25519, sender_key_id, receiver_key_id, forsending, 0);
984  return (ret ? &ret->baseclass: NULL);
985 }
986 
987 
989 WINEXPORT void
991 {
993 }
994 
WINEXPORT void cryptcurve25519_gen_temp_keypair(const char *key_id)
Generate a temporary (non-persistent) key pair.
#define PRIVATEKEYSUFFIX
guint32 length
Frame Length.
Definition: frame.h:46
FSTATIC enum keytype _cryptcurve25519_keytype_from_filename(const char *filename)
Determine the type of key this might be according to its filename.
WINEXPORT void cryptcurve25519_set_encryption_method(void)
Function just to make setting the encryption method simpler from Python.
#define UNREF3(obj)
Definition: assimobj.h:37
#define DEBUGMSG1(...)
Definition: proj_classes.h:89
FSTATIC gboolean _cache_curve25519_keypair(const char *key_id)
Validate and cache the requested curve25519 keypair (or just public if no private) If it&#39;s already in...
#define KEY_NAMING_CHECKSUM
Defines miscellaneous interfaces.
CryptCurve25519 * cryptcurve25519_new(guint16 frame_type, const char *sender_key_id, const char *receiver_key_id, gboolean forsending, gsize objsize)
Construct a new CryptCurve25519 object (frame).
WINEXPORT char * cryptcurve25519_gen_persistent_keypair(const char *giveitaname)
Create a persistent keypair and write it to disk Returns a MALLOCed string with the key id for the ke...
char * proj_get_sysname(void)
Return a malloced string of the system name.
#define DEBUGCKSUM4(msg, buf, bufsize)
CryptFrame * cryptframe_new(guint16 frame_type, const char *sender_key_id, const char *receiver_key_id, gsize objsize)
Construct a new CryptFrame This can only be used directly for creating subclassed CryptFrame frames b...
Definition: cryptframe.c:82
#define DEBUGMSG4(...)
Definition: proj_classes.h:92
guint8 tlv_get_guint8(const void *vitem, const void *bufend)
Retrieve an unsigned 8 bit integer from the given location with error checking.
Definition: tlvhelper.c:31
#define MAXCRYPTNAMELENGTH
AssimObj baseclass
Base object class for our Class system.
Definition: frame.h:44
Implements minimal client-oriented Frame and Frameset capabilities.
This is our CryptCurve25519 class object - representing a Curve25519 encryption Frame class...
#define DIRDELIM
Definition: projectcommon.h:95
This is the base Frame class object (in-memory TLV (type, length, value)) for every general component...
Definition: frame.h:43
CryptFrame baseclass
WINEXPORT gboolean cryptcurve25519_purge_keypair(const char *key_id)
Purge a cryptcurve25519 key from the filesystem and from memory.
FSTATIC char * _cache_curve25519_key_id_to_dirname(const char *key_id, enum keytype)
Map a key name on the wire to a file name in the filesystem We make this a function on the idea that ...
struct _CryptCurve25519 CryptCurve25519
CryptFramePublicKey * public_key
Pointer to associated public key.
WINEXPORT CryptFramePrivateKey * cryptframe_privatekey_new(const char *key_id, gpointer private_key)
Create a new private key - or return the existing private key with this id.
Definition: cryptframe.c:245
FSTATIC void _cryptcurve25519_updatedata(Frame *f, gpointer tlvstart, gconstpointer pktend, FrameSet *fs)
We update the data in the packet from our CryptCurve25519 object with the side-effect of encrypting a...
#define WINEXPORT
Definition: projectcommon.h:45
#define FSTATIC
Definition: projectcommon.h:31
#define DEBUGMSG3(...)
Definition: proj_classes.h:91
gpointer public_key
Pointer to the (malloced) public key;.
Definition: cryptframe.h:40
gboolean forsending
TRUE if this is for sending, FALSE for receiving.
#define PUBKEYSUFFIX
guint16 get_generic_tlv_type(gconstpointer tlv_vp, gconstpointer pktend)
Return the &#39;Type&#39; of the given TLV TLV entry (first two bytes)
gpointer private_key
Pointer to the (malloced) private key.
Definition: cryptframe.h:47
#define BINDDEBUG(Cclass)
BINDDEBUG is for telling the class system where the debug variable for this class is - put it in the ...
Definition: proj_classes.h:82
FSTATIC gboolean _is_legal_curve25519_key_id(const char *key_id)
CryptCurve25519 class function to check if a given curve25519 key id is properly formatted This name ...
#define __FUNCTION__
#define DEBUG
Definition: proj_classes.h:85
#define CRYPTKEYDIR
#define DUMP3(prefix, obj, suffix)
Definition: proj_classes.h:97
FSTATIC CryptFramePublicKey * cryptframe_public_key_by_id(const char *key_id)
Return the non-const public key with the given id.
Definition: cryptframe.c:270
#define MAXCRYPTKEYNAMELENGTH
Maximum length of a crypt key name.
Definition: cryptframe.h:31
FSTATIC gboolean _cryptcurve25519_save_a_key(const char *key_id, enum keytype ktype, gconstpointer key)
Save a curve25519 key to a file.
#define DEBUGCKSUM3(msg, buf, bufsize)
#define FREE(m)
Our interface to free.
Definition: projectcommon.h:29
#define REF(obj)
Definition: assimobj.h:39
FSTATIC CryptFramePrivateKey * cryptframe_private_key_by_id(const char *key_id)
Return the non-const private key with the given id.
Definition: cryptframe.c:279
#define CASTTOCONSTCLASS(Cclass, obj)
Safely cast &#39;obj&#39; to const C-class &#39;class&#39; - verifying that it was registered as being of type class ...
Definition: proj_classes.h:71
WINEXPORT char * curve25519_key_id_to_filename(const char *key_id, enum keytype ktype)
void set_generic_tlv_type(gpointer tlv_vp, guint16 newtype, gconstpointer pktend)
Set the &#39;Type&#39; of the given TLV TLV entry (first two bytes)
guint32 get_generic_tlv_len(gconstpointer tlv_vp, gconstpointer pktend)
Return the &#39;Length&#39; of the given generic TLV entry (first 3 bytes after type) Note: return result is ...
Project common header file.
FSTATIC gboolean _cryptcurve25519_default_isvalid(const Frame *, gconstpointer, gconstpointer)
CryptCurve25519 class &#39;isvalid&#39; member function (checks for valid cryptcurve25519 objects) ...
Header file defining the data layouts for our Frames.
TLV helper interfaces definitions.
Frame baseclass
Definition: cryptframe.h:54
void tlv_set_guint8(void *vitem, guint8 item, const void *bufend)
Set an unsigned 8 bit integer to the given location with error checking.
Definition: tlvhelper.c:42
keytype
gboolean(* isvalid)(const Frame *self, gconstpointer tlvptr, gconstpointer pktend)
TRUE if TLV data looks valid...
Definition: frame.h:50
WINEXPORT void cryptframe_set_encryption_method(CryptFrame *(*method)(const char *sender_key_id, const char *receiver_key_id, gboolean forsending))
Definition: cryptframe.c:518
void set_generic_tlv_len(gpointer tlv_vp, guint32 newsize, gconstpointer pktend)
Set the &#39;Length&#39; of the given generic TLV entry (first 3 bytes after type)
#define g_unlink(arg)
Definition: projectcommon.h:61
FSTATIC void cryptcurve25519_debug_checksum(const char *function, int lineno, const char *message, const guint8 *buf, size_t bufsize)
Print a debug checksum message.
Provides definitions for using our generic TLV capabilities.
gconstpointer get_generic_tlv_value(gconstpointer tlv_vp, gconstpointer pktend)
Return a const pointer to the &#39;Value&#39; of the given generic TLV entry.
FSTATIC char * cryptcurve25519_naming_checksum(const guint8 *buf, size_t buflen)
Return a malloced string containing the KEY_NAMING_CHECKSUM type checksum of the given data...
FSTATIC char * _cryptcurve25519_key_id_from_filename(const char *filename)
Determine the key_id this might is according to its pathname.
#define CMAUSERID
#define EOS
FSTATIC gboolean _is_valid_curve25519_key_id(const char *key_id, enum keytype ktype)
CryptCurve25519 class function to check if a given curve25519 key id is valid This name might come fr...
#define g_info(...)
Definition: projectcommon.h:66
void(* updatedata)(Frame *self, gpointer tlvptr, gconstpointer pktend, FrameSet *fs)
Update packet data.
Definition: frame.h:49
WINEXPORT gboolean cryptcurve25519_save_public_key(const char *key_id, gpointer public_key, int keysize)
Save a public key away to disk so it&#39;s completely usable...
FrameSet class - used for collecting Frames when not on the wire, and for marshalling/demarshalling t...
Definition: frameset.h:46
gpointer get_generic_tlv_nonconst_value(gpointer tlv_vp, gconstpointer pktend)
Return a non-const (mutable) pointer to the &#39;Value&#39; of the given generic TLV entry.
#define DEBUGDECLARATIONS
Definition: proj_classes.h:79
#define DEBUGMSG2(...)
Definition: proj_classes.h:90
This is our CryptFrame class object - representing an encryption method.
Definition: cryptframe.h:53
FSTATIC void dump_memory(const char *label, const guint8 *start, const guint8 *end)
WINEXPORT const char * cryptframe_get_signing_key_id(void)
Return the key_id of the default signing key.
Definition: cryptframe.c:434
void(* _finalize)(AssimObj *)
Free object (private)
Definition: assimobj.h:55
#define TLVLEN(receiverkey_id, senderkey_id)
FSTATIC void _cryptcurve25519_finalize(AssimObj *aobj)
Finalize (free) a CryptCurve25519 object.
WINEXPORT void cryptcurve25519_cache_all_keypairs(void)
We read in and cache all the key pairs (or public keys) that we find in CRYPTKEYDIR.
FSTATIC void _cryptcurve25519_make_cryptdir(const char *dirname)
Make a directory for storing keys in...
WINEXPORT CryptFrame * cryptcurve25519_new_generic(const char *sender_key_id, const char *receiver_key_id, gboolean forsending)
Generic "new" function to use with cryptframe_set_encryption_method()
WINEXPORT Frame * cryptcurve25519_tlvconstructor(gpointer tlvstart, gconstpointer pktend, gpointer *ignorednewpkt, gpointer *ignoredpktend)
Given marshalled packet data corresponding to an CryptCurve25519 frame return the corresponding Frame...
#define CASTTOCLASS(Cclass, obj)
Safely cast &#39;obj&#39; to C-class &#39;class&#39; - verifying that it was registerd as being of type class ...
Definition: proj_classes.h:66
#define UNREF(obj)
Definition: assimobj.h:35
#define NEWSUBCLASS(Cclass, obj)
Definition: proj_classes.h:67
CryptFramePrivateKey * private_key
Pointer to private key.
#define FRAMETYPE_CRYPTCURVE25519
FRAMETYPE_CRYPTCURVE25519 Frame (frametype 2) Frame subclass - CryptCurve25519 class.
Definition: frametypes.h:104
WINEXPORT void cryptframe_purge_key_id(const char *key_id)
Definition: cryptframe.c:404
Describes interfaces to CryptFrame (encryption) C-Class It represents a FrameSet using libsodium (cur...
WINEXPORT CryptFramePublicKey * cryptframe_publickey_new(const char *key_id, gpointer public_key)
Create a persistent keypair and write it to disk.
Definition: cryptframe.c:220