1 /*
2   Copyright (C) 2006-2013 Werner Dittmann
3 
4   This program is free software: you can redistribute it and/or modify
5   it under the terms of the GNU Lesser 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 _ZRTPPACKETHELLO_H_
19 #define _ZRTPPACKETHELLO_H_
20 
21 /**
22  * @file ZrtpPacketHello.h
23  * @brief The ZRTP Hello message
24  *
25  * @ingroup GNU_ZRTP
26  * @{
27  */
28 
29 #include <libzrtpcpp/ZrtpPacketBase.h>
30 
31 #define HELLO_FIXED_PART_LEN  22
32 
33 /**
34  * Implement the Hello packet.
35  *
36  * The ZRTP Hello message. The implementation sends this
37  * to start the ZRTP negotiation sequence. The Hello message
38  * offers crypto methods and parameters to the other party. The
39  * other party selects methods and parameters it can support
40  * and uses the Commit message to commit these.
41  *
42  * @author Werner Dittmann <Werner.Dittmann@t-online.de>
43  */
44 
45 class __EXPORT ZrtpPacketHello : public ZrtpPacketBase {
46 
47  protected:
48     Hello_t* helloHeader;   ///< Point to the Hello message part
49 
50     int32_t nHash,          ///< number of hash algorithms offered
51     nCipher,                ///< number of cipher algorithms offered
52     nPubkey,                ///< number of key agreement algorithms offered
53     nSas,                   ///< number of SAS algorithms offered
54     nAuth;                  ///< number of SRTP authentication algorithms offered
55 
56     int32_t oHash,          ///< offsets in bytes to hash algorithm names
57     oCipher,                ///< offsets in bytes to cipher algorithm names
58     oPubkey,                ///< offsets in bytes to key agreement algorithm names
59     oSas,                   ///< offsets in bytes to SAS algorithm names
60     oAuth,                  ///< offsets in bytes to SRTP authentication algorithm names
61     oHmac;                  ///< offsets in bytes to MAC of Hello message
62 
63  public:
64     /// Creates a Hello packet with default data
65     ZrtpPacketHello();
66 
67     /// Creates a Hello packet from received data
68     ZrtpPacketHello(uint8_t *data);
69 
70     virtual ~ZrtpPacketHello();
71 
72     /**
73      * Set configure data and populate Hello message data.
74      *
75      * Fill in the offered Algorithm names and compute all offset to
76      * names and MAC. An application must call this method on Hello message
77      * objects created with the standard constructor (with default data)
78      * before the application can use most of the getter and setter methods.
79      *
80      * @param config
81      *    Pointer to ZrtpConfigure data.
82      */
83     void configureHello(ZrtpConfigure* config);
84 
85     /// Get version number from Hello message, fixed ASCII character array
getVersion()86     uint8_t* getVersion()  { return helloHeader->version; };
87 
88      /// Get version number from Hello message as integer, only relvant digits converted
89     int32_t getVersionInt();
90 
91     /// Get client id from Hello message, fixed ASCII character array
getClientId()92     uint8_t* getClientId() { return helloHeader->clientId; };
93 
94     /// Get H3 hash from Hello message, fixed byte array
getH3()95     uint8_t* getH3()       { return helloHeader->hashH3; };
96 
97     /// Get client ZID from Hello message, fixed bytes array
getZid()98     uint8_t* getZid()      { return helloHeader->zid; };
99 
100     /// Set version sting in Hello message, fixed ASCII character array
setVersion(const uint8_t * text)101     void setVersion(const uint8_t *text)     { memcpy(helloHeader->version, text,ZRTP_WORD_SIZE ); }
102 
103     /// Set client id in Hello message, fixed ASCII character array
setClientId(const uint8_t * t)104     void setClientId(const uint8_t *t) { memcpy(helloHeader->clientId, t, sizeof(helloHeader->clientId)); }
105 
106     /// Set H3 hash in Hello message, fixed byte array
setH3(uint8_t * hash)107     void setH3(uint8_t *hash)          { memcpy(helloHeader->hashH3, hash, sizeof(helloHeader->hashH3)); }
108 
109     /// Set client ZID in Hello message, fixed bytes array
setZid(uint8_t * text)110     void setZid(uint8_t *text)         { memcpy(helloHeader->zid, text, sizeof(helloHeader->zid)); }
111 
112     /// Check passive mode (mode not implemented)
isPassive()113     bool isPassive()       { return (helloHeader->flags & 0x10) == 0x10 ? true : false; };
114 
115     /// Check if MitM flag is set
isMitmMode()116     bool isMitmMode()       { return (helloHeader->flags & 0x20) == 0x20 ? true : false; };
117 
118     /// Check if SAS sign flag is set
isSasSign()119     bool isSasSign()       { return (helloHeader->flags & 0x40) == 0x40 ? true : false; };
120 
121     /// Get hash algorithm name at position n, fixed ASCII character array
getHashType(int32_t n)122     uint8_t* getHashType(int32_t n)   { return ((uint8_t*)helloHeader)+oHash+(n*ZRTP_WORD_SIZE); }
123 
124     /// Get ciper algorithm name at position n, fixed ASCII character array
getCipherType(int32_t n)125     uint8_t* getCipherType(int32_t n) { return ((uint8_t*)helloHeader)+oCipher+(n*ZRTP_WORD_SIZE); }
126 
127     /// Get SRTP authentication algorithm name at position n, fixed ASCII character array
getAuthLen(int32_t n)128     uint8_t* getAuthLen(int32_t n)    { return ((uint8_t*)helloHeader)+oAuth+(n*ZRTP_WORD_SIZE); }
129 
130     /// Get key agreement algorithm name at position n, fixed ASCII character array
getPubKeyType(int32_t n)131     uint8_t* getPubKeyType(int32_t n) { return ((uint8_t*)helloHeader)+oPubkey+(n*ZRTP_WORD_SIZE); }
132 
133     /// Get SAS algorithm name at position n, fixed ASCII character array
getSasType(int32_t n)134     uint8_t* getSasType(int32_t n)    { return ((uint8_t*)helloHeader)+oSas+(n*ZRTP_WORD_SIZE); }
135 
136     /// Get Hello MAC, fixed byte array
getHMAC()137     uint8_t* getHMAC()                { return ((uint8_t*)helloHeader)+oHmac; }
138 
139     /// Set hash algorithm name at position n, fixed ASCII character array
setHashType(int32_t n,int8_t * t)140     void setHashType(int32_t n, int8_t* t)
141         { memcpy(((uint8_t*)helloHeader)+oHash+(n*ZRTP_WORD_SIZE), t, ZRTP_WORD_SIZE); }
142 
143     /// Set ciper algorithm name at position n, fixed ASCII character array
setCipherType(int32_t n,int8_t * t)144     void setCipherType(int32_t n, int8_t* t)
145         { memcpy(((uint8_t*)helloHeader)+oCipher+(n*ZRTP_WORD_SIZE), t, ZRTP_WORD_SIZE); }
146 
147     /// Set SRTP authentication algorithm name at position n, fixed ASCII character array
setAuthLen(int32_t n,int8_t * t)148     void setAuthLen(int32_t n, int8_t* t)
149         { memcpy(((uint8_t*)helloHeader)+oAuth+(n*ZRTP_WORD_SIZE), t, ZRTP_WORD_SIZE); }
150 
151     /// Set key agreement algorithm name at position n, fixed ASCII character array
setPubKeyType(int32_t n,int8_t * t)152     void setPubKeyType(int32_t n, int8_t* t)
153         { memcpy(((uint8_t*)helloHeader)+oPubkey+(n*ZRTP_WORD_SIZE), t, ZRTP_WORD_SIZE); }
154 
155     /// Set SAS algorithm name at position n, fixed ASCII character array
setSasType(int32_t n,int8_t * t)156     void setSasType(int32_t n, int8_t* t)
157         { memcpy(((uint8_t*)helloHeader)+oSas+(n*ZRTP_WORD_SIZE), t, ZRTP_WORD_SIZE); }
158 
159     /// Set Hello MAC, fixed byte array
setHMAC(uint8_t * t)160     void setHMAC(uint8_t* t)
161         { memcpy(((uint8_t*)helloHeader)+oHmac, t, 2*ZRTP_WORD_SIZE); }
162 
163     /// Get number of offered hash algorithms
getNumHashes()164     int32_t getNumHashes()   {return nHash; }
165 
166     /// Get number of offered cipher algorithms
getNumCiphers()167     int32_t getNumCiphers()  {return nCipher; }
168 
169     /// Get number of offered key agreement algorithms
getNumPubKeys()170     int32_t getNumPubKeys()  {return nPubkey; }
171 
172     /// Get number of offered SAS algorithms
getNumSas()173     int32_t getNumSas()      {return nSas; }
174 
175     /// Get number of offered SRTP authentication algorithms
getNumAuth()176     int32_t getNumAuth()     {return nAuth; }
177 
178     /// set MitM flag
setMitmMode()179     void setMitmMode()       {helloHeader->flags |= 0x20; }
180 
181     /// set SAS sign flag
setSasSign()182     void setSasSign()        {helloHeader->flags |= 0x40; }
183 
184     /// Check if packet length matches
isLengthOk()185     bool isLengthOk()        {return (computedLength == getLength());}
186 
187  private:
188      uint32_t computedLength;
189      // Hello packet is of variable length. It maximum size is 46 words:
190      // - 20 words fixed sizze
191      // - up to 35 words variable part, depending on number of algorithms
192      // leads to a maximum of 4*55=220 bytes.
193      uint8_t data[256];       // large enough to hold a full blown Hello packet
194 };
195 
196 /**
197  * @}
198  */
199 #endif // ZRTPPACKETHELLO
200 
201