blob: eb2d190dcc6e87fde264a2c8285076cd7142800c [file] [log] [blame]
Alexandre Lision51140e12013-12-02 10:54:09 -05001/*
2 Copyright (C) 2006-2010 Werner Dittmann
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#ifndef _ZIDRECORD_H_
19#define _ZIDRECORD_H_
20
21
22/**
23 * @file ZIDRecord.h
24 * @brief ZID record management
25 *
26 * A ZID record stores (caches) ZID (ZRTP ID) specific data that helps ZRTP
27 * to achives its key continuity feature. Please refer to the ZRTP
28 * specification to get detailed information about the ZID.
29 *
30 * @ingroup GNU_ZRTP
31 * @{
32 */
33
34#include <string.h>
35#include <stdint.h>
36
37#define IDENTIFIER_LEN 12
38#define RS_LENGTH 32
39#define TIME_LENGTH 8 // 64 bit, can hold time on 64 bit systems
40
41/**
42 * This is the recod structure of version 1 ZID records.
43 *
44 * This is not longer in use - only during migration.
45 */
46typedef struct zidrecord1 {
47 char recValid; //!< if 1 record is valid, if 0: invalid
48 char ownZid; //!< if >1 record contains own ZID, usually 1st record
49 char rs1Valid; //!< if 1 RS1 contains valid data
50 char rs2Valid; //!< if 1 RS2 contains valid data
51 unsigned char identifier[IDENTIFIER_LEN]; ///< the peer's ZID or own ZID
52 unsigned char rs1Data[RS_LENGTH], rs2Data[RS_LENGTH]; ///< the peer's RS data
53} zidrecord1_t;
54
55/**
56 * This is the recod structure of version 2 ZID records.
57 */
58typedef struct zidrecord2 {
59 char version; ///< version number of file format, this is #2
60 char flags; ///< bit field holding various flags, see below
61 char filler1; ///< round up to next 32 bit
62 char filler2; ///< round up to next 32 bit
63 unsigned char identifier[IDENTIFIER_LEN]; ///< the peer's ZID or own ZID
64 unsigned char rs1Interval[TIME_LENGTH]; ///< expiration time of RS1; -1 means indefinite
65 unsigned char rs1Data[RS_LENGTH]; ///< the peer's RS2 data
66 unsigned char rs2Interval[TIME_LENGTH]; ///< expiration time of RS2; -1 means indefinite
67 unsigned char rs2Data[RS_LENGTH]; ///< the peer's RS2 data
68 unsigned char mitmKey[RS_LENGTH]; ///< MiTM key if available
69} zidrecord2_t;
70
71
72#ifndef __EXPORT
73 #if __GNUC__ >= 4
74 #define __EXPORT __attribute__ ((visibility("default")))
75 #define __LOCAL __attribute__ ((visibility("hidden")))
76 #elif defined _WIN32 || defined __CYGWIN__
77 #define __EXPORT __declspec(dllimport)
78 #define __LOCAL
79 #else
80 #define __EXPORT
81 #define __LOCAL
82 #endif
83#endif
84
85static const int Valid = 0x1;
86static const int SASVerified = 0x2;
87static const int RS1Valid = 0x4;
88static const int RS2Valid = 0x8;
89static const int MITMKeyAvailable = 0x10;
90static const int OwnZIDRecord = 0x20;
91
92/**
93 * This class implements the ZID record.
94 *
95 * The ZID record holds data about a peer. According to ZRTP specification
96 * we use a ZID to identify a peer. ZRTP uses the RS (Retained Secret) data
97 * to construct shared secrets.
98 * <p>
99 * NOTE: ZIDRecord has ZIDFile as friend. ZIDFile knows about the private
100 * data of ZIDRecord - please keep both classes synchronized.
101 *
102 * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
103 */
104class __EXPORT ZIDRecord {
105 friend class ZIDFile;
106
107private:
108 zidrecord2_t record;
109 unsigned long position;
110
111 /*
112 * The default constructor is private
113 */
114 ZIDRecord() {
115 record.version = 2;
116 }
117
118 /**
119 * Functions for I/O availabe for ZID file handling
120 *
121 * These functions are private, thus only friends may use it.
122 */
123 void setPosition(long pos) {position = pos;}
124 long getPosition() {return position; }
125
126 zidrecord2_t* getRecordData() {return &record; }
127 int getRecordLength() {return sizeof(zidrecord2_t); }
128
129 bool isValid() { return ((record.flags & Valid) == Valid); }
130 void setValid() { record.flags |= Valid; }
131
132public:
133 /**
134 * Create a ZID Record with given ZID data
135 *
136 * The method creates a new ZID record and initializes its ZID
137 * data field. All other fields are set to null.
138 *
139 * An application can use this pre-initialized record to look
140 * up the associated record in the ZID file. If the record is
141 * available, the ZID record fields are filled with the stored
142 * data.
143 *
144 * @param idData
145 * Pointer to the fixed length ZID data
146 * @see ZIDFile::getRecord
147 */
148 ZIDRecord(const unsigned char *idData) {
149 memset(&record, 0, sizeof(zidrecord2_t));
150 memcpy(record.identifier, idData, IDENTIFIER_LEN);
151 record.version = 2;
152 }
153
154 /**
155 * Set @c valid flag in RS1
156 */
157 void setRs1Valid() { record.flags |= RS1Valid; }
158
159 /**
160 * reset @c valid flag in RS1
161 */
162 void resetRs1Valid() { record.flags &= ~RS1Valid; }
163
164 /**
165 * Check @c valid flag in RS1
166 */
167 bool isRs1Valid() { return ((record.flags & RS1Valid) == RS1Valid); }
168
169 /**
170 * Set @c valid flag in RS2
171 */
172 void setRs2Valid() { record.flags |= RS2Valid; }
173
174 /**
175 * Reset @c valid flag in RS2
176 */
177 void resetRs2Valid() { record.flags &= ~RS2Valid; }
178
179 /**
180 * Check @c valid flag in RS2
181 */
182 bool isRs2Valid() { return ((record.flags & RS2Valid) == RS2Valid); }
183
184 /**
185 * Set MITM key available
186 */
187 void setMITMKeyAvailable() { record.flags |= MITMKeyAvailable; }
188
189 /**
190 * Reset MITM key available
191 */
192 void resetMITMKeyAvailable() { record.flags &= ~MITMKeyAvailable; }
193
194 /**
195 * Check MITM key available is set
196 */
197 bool isMITMKeyAvailable() { return ((record.flags & MITMKeyAvailable) == MITMKeyAvailable); }
198
199 /**
200 * Mark this as own ZID record
201 */
202 void setOwnZIDRecord() { record.flags = OwnZIDRecord; }
203 /**
204 * Reset own ZID record marker
205 */
206 void resetOwnZIDRecord(){ record.flags = 0; }
207
208 /**
209 * Check own ZID record marker
210 */
211 bool isOwnZIDRecord() { return (record.flags == OwnZIDRecord); } // no other flag allowed if own ZID
212
213 /**
214 * Set SAS for this ZID as verified
215 */
216 void setSasVerified() { record.flags |= SASVerified; }
217 /**
218 * Reset SAS for this ZID as verified
219 */
220 void resetSasVerified() { record.flags &= ~SASVerified; }
221
222 /**
223 * Check if SAS for this ZID was verified
224 */
225 bool isSasVerified() { return ((record.flags & SASVerified) == SASVerified); }
226
227 /**
228 * Return the ZID for this record
229 */
230 const uint8_t* getIdentifier() {return record.identifier; }
231
232 /**
233 * Check if RS1 is still valid
234 *
235 * Returns true if RS1 is still valid, false otherwise.
236 *
237 * @return
238 * Returns true is RS1 is not expired (valid), false otherwise.
239 */
240 const bool isRs1NotExpired();
241
242 /**
243 * Returns pointer to RS1 data.
244 */
245 const unsigned char* getRs1() { return record.rs1Data; }
246
247 /**
248 * Check if RS2 is still valid
249 *
250 * Returns true if RS2 is still valid, false otherwise.
251 *
252 * @return
253 * Returns true is RS2 is not expired (valid), false otherwise.
254 */
255 const bool isRs2NotExpired();
256
257 /**
258 * Returns pointer to RS1 data.
259 */
260 const unsigned char* getRs2() { return record.rs2Data; }
261
262 /**
263 * Sets new RS1 data and associated expiration value.
264 *
265 * If the expiration value is >0 or -1 the method stores the new
266 * RS1. Before it stores the new RS1 it shifts the exiting RS1
267 * into RS2 (together with its expiration time). Then it computes
268 * the expiration time of the and stores the result together with
269 * the new RS1.
270 *
271 * If the expiration value is -1 then this RS will never expire.
272 *
273 * If the expiration value is 0 then the expiration value of a
274 * stored RS1 is cleared and no new RS1 value is stored. Also RS2
275 * is left unchanged.
276 *
277 * @param data
278 * Points to the new RS1 data.
279 * @param expire
280 * The expiration interval in seconds. Default is -1.
281 *
282 */
283 void setNewRs1(const unsigned char* data, int32_t expire =-1);
284
285 /**
286 * Set MiTM key data.
287 *
288 */
289 void setMiTMData(const unsigned char* data);
290
291 /**
292 * Get MiTM key data.
293 *
294 */
295 const unsigned char* getMiTMData() {return record.mitmKey; }
296};
297
298#endif // ZIDRECORD
299
300
301/** EMACS **
302 * Local variables:
303 * mode: c++
304 * c-default-style: ellemtel
305 * c-basic-offset: 4
306 * End:
307 */