1 /*
2 
3   silcattrs.h
4 
5   Author: Pekka Riikonen <priikone@silcnet.org>
6 
7   Copyright (C) 2002 - 2007 Pekka Riikonen
8 
9   The contents of this file are subject to one of the Licenses specified
10   in the COPYING file;  You may not use this file except in compliance
11   with the License.
12 
13   The software distributed under the License is distributed on an "AS IS"
14   basis, in the hope that it will be useful, but WITHOUT WARRANTY OF ANY
15   KIND, either expressed or implied.  See the COPYING file for more
16   information.
17 
18 */
19 
20 /****h* silccore/SILC Attribute Interface
21  *
22  * DESCRIPTION
23  *
24  * Implementation of the Attribute Payload that may be used to send and
25  * retrieve user online precense information in the SILC network.  This
26  * implements the draft-riikonen-precense-attrs draft.
27  *
28  ***/
29 
30 #ifndef SILCATTRS_H
31 #define SILCATTRS_H
32 
33 /****s* silccore/SilcAttributesAPI/SilcAttributePayload
34  *
35  * NAME
36  *
37  *    typedef struct SilcAttributePayloadStruct *SilcAttributePayload;
38  *
39  * DESCRIPTION
40  *
41  *    This context is the actual Attribute Payload and is allocated
42  *    by silc_attribute_payload_parse and given as attribute usually to
43  *    all silc_attribute_payload_* functions.  It is freed by the
44  *    silc_attribute_payload_free function.
45  *
46  ***/
47 typedef struct SilcAttributePayloadStruct *SilcAttributePayload;
48 
49 /****d* silccore/SilcAttributesAPI/SilcAttribute
50  *
51  * NAME
52  *
53  *    typedef SilcUInt8 SilcAttribute;
54  *
55  * DESCRIPTION
56  *
57  *    The SilcAttribute type definition and the attributes. The attributes
58  *    listed here are the official attributes defined in the internet
59  *    draft.  They define the contents of the attribute payload and the
60  *    type of the attribute.
61  *
62  * SOURCE
63  */
64 typedef SilcUInt8 SilcAttribute;
65 
66 /* All defined attributes.  See the specs for detailed information.  The
67    comment is the structure or data type that must be used with the
68    silc_attribute_get_object function to fetch parsed attribute. */
69 #define SILC_ATTRIBUTE_NONE                   0
70 #define SILC_ATTRIBUTE_USER_INFO              1   /* SilcVCard */
71 #define SILC_ATTRIBUTE_SERVICE                2   /* SilcAttributeObjService */
72 #define SILC_ATTRIBUTE_STATUS_MOOD            3   /* SilcAttributeMood */
73 #define SILC_ATTRIBUTE_STATUS_FREETEXT        4   /* char * (UTF-8 string) */
74 #define SILC_ATTRIBUTE_STATUS_MESSAGE         5   /* SilcMime */
75 #define SILC_ATTRIBUTE_PREFERRED_LANGUAGE     6   /* char * (UTF-8 string) */
76 #define SILC_ATTRIBUTE_PREFERRED_CONTACT      7   /* SilcAttributeContact */
77 #define SILC_ATTRIBUTE_TIMEZONE               8   /* char * (UTF-8 string) */
78 #define SILC_ATTRIBUTE_GEOLOCATION            9   /* SilcAttributeObjGeo */
79 #define SILC_ATTRIBUTE_DEVICE_INFO            10  /* SilcAttributeObjDevice */
80 #define SILC_ATTRIBUTE_EXTENSION              11  /* SilcMime */
81 #define SILC_ATTRIBUTE_USER_PUBLIC_KEY        12  /* SilcAttributeObjPk */
82 #define SILC_ATTRIBUTE_SERVER_PUBLIC_KEY      13  /* SilcAttributeObjPk */
83 #define SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE 14  /* SilcAttributeObjPk */
84 #define SILC_ATTRIBUTE_SERVER_DIGITAL_SIGNATURE 15 /* SilcAttributeObjPk */
85 #define SILC_ATTRIBUTE_USER_ICON	      16  /* SilcMime */
86 #define SILC_ATTRIBUTE_PHONE_NUMBER	      17  /* SilcAttributeObjPN */
87 /***/
88 
89 /* Maximum length of attribute request packet */
90 #define SILC_ATTRIBUTE_MAX_REQUEST_LEN (4 * 255)
91 
92 /****d* silccore/SilcAttributesAPI/SilcAttributeFlags
93  *
94  * NAME
95  *
96  *    typedef SilcUInt8 SilcAttributeFlags;
97  *
98  * DESCRIPTION
99  *
100  *    Attribute Payload flags defined by the specification.
101  *
102  * SOURCE
103  */
104 typedef SilcUInt8 SilcAttributeFlags;
105 
106 /* All defined flags */
107 #define SILC_ATTRIBUTE_FLAG_NONE          0x00    /* No flags */
108 #define SILC_ATTRIBUTE_FLAG_INVALID       0x01	  /* Invalid attribute */
109 #define SILC_ATTRIBUTE_FLAG_VALID         0x02	  /* Valid attribute */
110 /***/
111 
112 /****d* silccore/SilcAttributesAPI/SilcAttributeMood
113  *
114  * NAME
115  *
116  *    typedef enum { ... } SilcAttributeMood;
117  *
118  * DESCRIPTION
119  *
120  *    The user mood indicators defined by the specification.  This is
121  *    bit mask.
122  *
123  * SOURCE
124  */
125 typedef enum {
126   SILC_ATTRIBUTE_MOOD_NORMAL      = 0x00000000,	  /* normal mood */
127   SILC_ATTRIBUTE_MOOD_HAPPY       = 0x00000001,	  /* user feel happy */
128   SILC_ATTRIBUTE_MOOD_SAD         = 0x00000002,	  /* user feel sad */
129   SILC_ATTRIBUTE_MOOD_ANGRY       = 0x00000004,	  /* user feel angry */
130   SILC_ATTRIBUTE_MOOD_JEALOUS     = 0x00000008,	  /* user feel jealous */
131   SILC_ATTRIBUTE_MOOD_ASHAMED     = 0x00000010,	  /* user feel ashamed */
132   SILC_ATTRIBUTE_MOOD_INVINCIBLE  = 0x00000020,	  /* user feel invincible */
133   SILC_ATTRIBUTE_MOOD_INLOVE      = 0x00000040,	  /* user feel in love */
134   SILC_ATTRIBUTE_MOOD_SLEEPY      = 0x00000080,	  /* user feel sleepy */
135   SILC_ATTRIBUTE_MOOD_BORED       = 0x00000100,	  /* user feel bored */
136   SILC_ATTRIBUTE_MOOD_EXCITED     = 0x00000200,	  /* user feel exited */
137   SILC_ATTRIBUTE_MOOD_ANXIOUS     = 0x00000400,	  /* user feel anxious */
138 } SilcAttributeMood;
139 /***/
140 
141 /****d* silccore/SilcAttributesAPI/SilcAttributeContact
142  *
143  * NAME
144  *
145  *    typedef enum { ... } SilcAttributeContact;
146  *
147  * DESCRIPTION
148  *
149  *    The defined preferred contact methods defined by the specification.
150  *    This is bit mask.
151  *
152  * SOURCE
153  */
154 typedef enum {
155   SILC_ATTRIBUTE_CONTACT_NONE    = 0x00000000,	  /* no specific method */
156   SILC_ATTRIBUTE_CONTACT_EMAIL   = 0x00000001,	  /* email preferred */
157   SILC_ATTRIBUTE_CONTACT_CALL    = 0x00000002,	  /* phone call preferred */
158   SILC_ATTRIBUTE_CONTACT_PAGE    = 0x00000004,	  /* "paging" preferred */
159   SILC_ATTRIBUTE_CONTACT_SMS     = 0x00000008,	  /* SMS preferred */
160   SILC_ATTRIBUTE_CONTACT_MMS     = 0x00000010,	  /* MMS preferred */
161   SILC_ATTRIBUTE_CONTACT_CHAT    = 0x00000020,	  /* chatting preferred */
162   SILC_ATTRIBUTE_CONTACT_VIDEO   = 0x00000040,	  /* video conferencing */
163 } SilcAttributeContact;
164 /***/
165 
166 /****d* silccore/SilcAttributesAPI/SilcAttributeDevice
167  *
168  * NAME
169  *
170  *    typedef enum { ... } SilcAttributeDevice;
171  *
172  * DESCRIPTION
173  *
174  *    The defined device types defined by the specification.
175  *
176  * SOURCE
177  */
178 typedef enum {
179   SILC_ATTRIBUTE_DEVICE_COMPUTER      = 0,	  /* device is computer */
180   SILC_ATTRIBUTE_DEVICE_MOBILE_PHONE  = 1,	  /* device is mobile phone */
181   SILC_ATTRIBUTE_DEVICE_PDA           = 2,	  /* device is PDA */
182   SILC_ATTRIBUTE_DEVICE_TERMINAL      = 3,	  /* device is terminal */
183 } SilcAttributeDevice;
184 /***/
185 
186 /****d* silccore/SilcAttributesAPI/SilcAttributePNFormat
187  *
188  * NAME
189  *
190  *    typedef enum { ... } SilcAttributePNFormat;
191  *
192  * DESCRIPTION
193  *
194  *    The defined phone number formats.
195  *
196  * SOURCE
197  */
198 typedef enum {
199   SILC_ATTRIBUTE_NUMBER_ITU_E164        = 0,	  /* ITU E.164 */
200   SILC_ATTRIBUTE_NUMBER_ITU_E123        = 1,	  /* ITU E.123 */
201   SILC_ATTRIBUTE_NUMBER_ENUM            = 2,	  /* ENUM, RFC 3761 */
202 } SilcAttributePNFormat;
203 /***/
204 
205 /****f* silccore/SilcAttributesAPI/silc_attribute_payload_alloc
206  *
207  * SYNOPSIS
208  *
209  *    SilcAttributesPayload
210  *    silc_attribute_payload_alloc(SilcAttribute attribute,
211  *                                 SilcAttributeFlags flags,
212  *                                 void *object,
213  *                                 SilcUInt32 object_size);
214  *
215  * DESCRIPTION
216  *
217  *    Allocates and encodes the attribute indicated by `attribute' and
218  *    returns pointer to the attribute.
219  *
220  *    The `object' must always be the same data type as defined with
221  *    SilcAttribute (see the comments) for all attributes.
222  *
223  ***/
224 SilcAttributePayload silc_attribute_payload_alloc(SilcAttribute attribute,
225 						  SilcAttributeFlags flags,
226 						  void *object,
227 						  SilcUInt32 object_size);
228 
229 /****f* silccore/SilcAttributesAPI/silc_attribute_payload_parse
230  *
231  * SYNOPSIS
232  *
233  *    SilcDList
234  *    silc_attribute_payload_parse(const unsigned char *payload,
235  *                                 SilcUInt32 payload_len);
236  *
237  * DESCRIPTION
238  *
239  *    Parses list of Attribute payloads returning list of payloads.
240  *    One entry in the returned list is SilcAttributesPayload.  You
241  *    can produce such a list with silc_attribute_payload_encode
242  *    function.
243  *
244  ***/
245 SilcDList silc_attribute_payload_parse(const unsigned char *payload,
246 				       SilcUInt32 payload_len);
247 
248 /****f* silccore/SilcAttributesAPI/silc_attribute_payload_encode
249  *
250  * SYNOPSIS
251  *
252  *    SilcBuffer silc_attribute_payload_encode(SilcBuffer attrs,
253  *                                             SilcAttribute attribute,
254  *                                             SilcAttributeFlags flags,
255  *                                             void *object,
256  *                                             SilcUInt32 object_size);
257  *
258  * DESCRIPTION
259  *
260  *    Encodes one attribute payload into the `attrs' buffer and returns
261  *    pointer to the buffer, which may be different in case the buffer
262  *    was reallocated.  If `attrs' is NULL for first attribute this
263  *    allocates the buffer and returns it.  This can be called multiple
264  *    times to add multiple attributes to the `attrs' buffer.  The `flags'
265  *    indicates the validity of the added attribute.  Returns NULL on
266  *    error.
267  *
268  *    The `object' must always be the same data type as defined with
269  *    SilcAttribute (see the comments) for all attributes.
270  *
271  ***/
272 SilcBuffer silc_attribute_payload_encode(SilcBuffer attrs,
273 					 SilcAttribute attribute,
274 					 SilcAttributeFlags flags,
275 					 void *object,
276 					 SilcUInt32 object_size);
277 
278 /****f* silccore/SilcAttributesAPI/silc_attribute_payload_encode_data
279  *
280  * SYNOPSIS
281  *
282  *    SilcBuffer
283  *    silc_attribute_payload_encode_data(SilcBuffer attrs,
284  *                                       SilcAttribute attribute,
285  *                                       SilcAttributeFlags flags,
286  *                                       const unsigned char *data,
287  *                                       SilcUInt32 data_len);
288  *
289  * DESCRIPTION
290  *
291  *    Same function as silc_attribute_payload_encode except the attribute
292  *    is already encoded into `data' of `data_len' bytes in length.
293  *    Encodes the attribute into the `attrs' buffer and returns pointer
294  *    to the buffer, which may be different in case the buffer was
295  *    reallocated.  If `attrs' is NULL for first attribute this allocates
296  *    the buffer and returns it.  Returns NULL on error.
297  *
298  ***/
299 SilcBuffer silc_attribute_payload_encode_data(SilcBuffer attrs,
300 					      SilcAttribute attribute,
301 					      SilcAttributeFlags flags,
302 					      const unsigned char *data,
303 					      SilcUInt32 data_len);
304 
305 /****f* silccore/SilcAttributesAPI/silc_attribute_payload_free
306  *
307  * SYNOPSIS
308  *
309  *    void silc_attribute_payload_free(SilcAttributePayload payload);
310  *
311  * DESCRIPTION
312  *
313  *    Frees the Attribute Payload and all data in it.
314  *
315  ***/
316 void silc_attribute_payload_free(SilcAttributePayload payload);
317 
318 /****f* silccore/SilcAttributesAPI/silc_attribute_payload_list_free
319  *
320  * SYNOPSIS
321  *
322  *    void silc_attribute_payload_list_free(SilcDList list);
323  *
324  * DESCRIPTION
325  *
326  *    Frees list of Attribute Payloads and all data in them.
327  *
328  ***/
329 void silc_attribute_payload_list_free(SilcDList list);
330 
331 /****f* silccore/SilcAttributesAPI/silc_attribute_get_attribute
332  *
333  * SYNOPSIS
334  *
335  *    SilcAttribute silc_attribute_get_attribute(SilcAttributePayload payload);
336  *
337  * DESCRIPTION
338  *
339  *    Return the attribute type from the payload indicated by `payload'.
340  *
341  ***/
342 SilcAttribute silc_attribute_get_attribute(SilcAttributePayload payload);
343 
344 /****f* silccore/SilcAttributesAPI/silc_attribute_get_flags
345  *
346  * SYNOPSIS
347  *
348  *    SilcAttributeFlags
349  *    silc_attribute_get_flags(SilcAttributePayload payload);
350  *
351  * DESCRIPTION
352  *
353  *    Return the attribute flags from the payload indicated by `payload'.
354  *
355  ***/
356 SilcAttributeFlags silc_attribute_get_flags(SilcAttributePayload payload);
357 
358 /****f* silccore/SilcAttributesAPI/silc_attribute_get_data
359  *
360  * SYNOPSIS
361  *
362  *    const unsigned char *
363  *    silc_attribute_get_data(SilcAttributePayload payload,
364  *                            SilcUInt32 *data_len);
365  *
366  * DESCRIPTION
367  *
368  *    Returns the attribute data from the payload indicated by the `payload'
369  *    The caller must not free the returned data pointer.
370  *
371  ***/
372 const unsigned char *silc_attribute_get_data(SilcAttributePayload payload,
373 					     SilcUInt32 *data_len);
374 
375 /****f* silccore/SilcAttributesAPI/silc_attribute_get_verify_data
376  *
377  * SYNOPSIS
378  *
379  *    unsigned char *
380  *    silc_attribute_get_verify_data(SilcDList attrs,
381  *                                   SilcBool server_verification,
382  *                                   SilcUInt32 *data_len);
383  *
384  * DESCRIPTION
385  *
386  *    Constructs the data to be verified with the sender's digital
387  *    signature and sender's public key.  This allocates the data from
388  *    the list of attribute payloads and returns the buffer.  The caller
389  *    must free it.  If `server_verification' is FALSE then data is
390  *    constructed for user's digital signature verification, if it is
391  *    TRUE then it is constructed for server's digital signature
392  *    verification.
393  *
394  ***/
395 unsigned char *silc_attribute_get_verify_data(SilcDList attrs,
396 					      SilcBool server_verification,
397 					      SilcUInt32 *data_len);
398 
399 /* Object structures */
400 
401 /****s* silccore/SilcAttributesAPI/SilcAttributeObjService
402  *
403  * NAME
404  *
405  *    typedef struct { ... } SilcAttributeObjService;
406  *
407  * DESCRIPTION
408  *
409  *    SILC_ATTRIBUTE_SERVICE type object structure.
410  *
411  * SOURCE
412  */
413 typedef struct SilcAttributeObjServiceStruct {
414   SilcUInt32 port;		/* IANA specified service port */
415   SilcUInt32 idle;		/* Idle time in the service */
416   char signon[64];		/* Signon date and time (UTC) */
417   char address[256];		/* service address */
418   SilcBool status;		/* online status (TRUE present in service) */
419 } SilcAttributeObjService;
420 /***/
421 
422 /****s* silccore/SilcAttributesAPI/SilcAttributeObjGeo
423  *
424  * NAME
425  *
426  *    typedef struct { ... } SilcAttributeObjGeo;
427  *
428  * DESCRIPTION
429  *
430  *    SILC_ATTRIBUTE_GEOLOCATION type object.  The caller must free the
431  *    strings inside the structure.
432  *
433  * SOURCE
434  */
435 typedef struct SilcAttributeObjGeoStruct {
436   char *longitude;		/* Longitude */
437   char *latitude;		/* Latitude */
438   char *altitude;		/* Altitude */
439   char *accuracy;		/* Accuracy in meters */
440 } SilcAttributeObjGeo;
441 /***/
442 
443 /****s* silccore/SilcAttributesAPI/SilcAttributeObjDevice
444  *
445  * NAME
446  *
447  *    typedef struct { ... } SilcAttributeObjDevice;
448  *
449  * DESCRIPTION
450  *
451  *    SILC_ATTRIBUTE_DEVICE_INFO type object.  The caller must free the
452  *    strings inside the structure.
453  *
454  * SOURCE
455  */
456 typedef struct SilcAttributeObjDeviceStruct {
457   SilcAttributeDevice type;	/* device type */
458   char *manufacturer;		/* manufacturer of the device */
459   char *version;		/* device version string */
460   char *model;			/* device model string */
461   char *language;		/* device language (ISO 639-2/T) */
462 } SilcAttributeObjDevice;
463 /***/
464 
465 /****s* silccore/SilcAttributesAPI/SilcAttributeObjPk
466  *
467  * NAME
468  *
469  *    typedef struct { ... } SilcAttributeObjPk;
470  *
471  * DESCRIPTION
472  *
473  *    Data type for public key, certificate or digital signatures.  The
474  *    caller must free the data inside the structure.  The 'type' is one
475  *    of following: "silc-rsa", "silc-dss, "ssh-rsa", "ssh-dss",
476  *    "pgp-sign-rsa", "pgp-sign-dss", "x509v3-sign-rsa", "x509v3-sign-dss".
477  *    The 'type' is NULL when this structure includes a digital signature.
478  *
479  *    In SILC, at least the "silc-rsa" must be supported.  In this case
480  *    the key is normal SILC Public key.  To verify a signature with the
481  *    SILC Public key, construct the signature data with the
482  *    silc_attribute_get_verify_data and verify the signature with
483  *    for example silc_pkcs_verify_with_hash function.  The public key
484  *    to the verification is the `data' and `data_len', and can be decoded
485  *    with silc_pkcs_public_key_decode function.
486  *
487  * SOURCE
488  */
489 typedef struct SilcAttributeObjPkStruct {
490   char *type;			/* public key/certificate type, NULL
491 				   when contains digital signature. */
492   unsigned char *data;		/* public key/cert/signature data. The
493 				   encoding depends of the `type'. */
494   SilcUInt32 data_len;		/* data length */
495 } SilcAttributeObjPk;
496 /***/
497 
498 /****s* silccore/SilcAttributesAPI/SilcAttributeObjPN
499  *
500  * NAME
501  *
502  *    typedef struct { ... } SilcAttributeObjPN;
503  *
504  * DESCRIPTION
505  *
506  *    SILC_ATTRIBUTE_PHONE_NUMBER type object.  The caller must free the
507  *    phone number string inside the structure.
508  *
509  * SOURCE
510  */
511 typedef struct SilcAttributeObjPNStruct {
512   SilcAttributePNFormat format;	/* Phone number format */
513   char *number;			/* Phone number */
514 } SilcAttributeObjPN;
515 /***/
516 
517 /****f* silccore/SilcAttributesAPI/silc_attribute_get_object
518  *
519  * SYNOPSIS
520  *
521  *    SilcBool silc_attribute_get_object(SilcAttributePayload payload,
522  *                                       void *object,
523  *                                       SilcUInt32 object_size);
524  *
525  * DESCRIPTION
526  *
527  *    Returns the already parsed attribute object from the payload
528  *    indicated by `payload'.  Copies the data into the `object' which
529  *    must be sent as argument (and must be of correct type and size).
530  *    The `object_size' indicates the size of the `*object' sent.
531  *    Returns TRUE if the `attribute' attribute was found and FALSE
532  *    if such attribute is not present in the `payload', or the `object_size'
533  *    is not sufficient.  See the definition of SilcAttribute for the
534  *    list of attributes and the required object types for attributes.
535  *    You can use silc_attribute_get_attribute to get the SilcAttribute
536  *    type from the `payload'.
537  *
538  * EXAMPLE
539  *
540  *    SilcAttributeObjDevice dev;
541  *
542  *    ...
543  *    case SILC_ATTRIBUTE_DEVICE_INFO:
544  *    memset(&dev, 0, sizeof(dev));
545  *    if (!silc_attribute_get_object(payload, (void *)&dev, sizeof(dev)))
546  *      error();
547  *
548  *    case SILC_ATTRIBUTE_USER_ICON:
549  *    mime = silc_mime_alloc();
550  *    if (!silc_attribute_get_object(payload, (void *)mime, sizeof(*mime)))
551  *      error();
552  *    ...
553  *
554  ***/
555 SilcBool silc_attribute_get_object(SilcAttributePayload payload,
556 				   void *object, SilcUInt32 object_size);
557 
558 #endif /* SILCATTRS_H */
559