• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of the openHiTLS project.
3  *
4  * openHiTLS is licensed under the Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *
8  *     http://license.coscl.org.cn/MulanPSL2
9  *
10  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13  * See the Mulan PSL v2 for more details.
14  */
15 
16 #ifndef HS_MSG_H
17 #define HS_MSG_H
18 
19 #include <stdint.h>
20 #include <stdbool.h>
21 #include "hitls_build.h"
22 #include "bsl_module_list.h"
23 #include "cert.h"
24 #include "hitls_crypt_type.h"
25 #include "hitls_cert_type.h"
26 #include "hitls_type.h"
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 #define HS_MSG_HEADER_SIZE 4u
33 #define DTLS_HS_MSG_HEADER_SIZE 12u
34 #define HS_RANDOM_SIZE 32u
35 #define HS_RANDOM_DOWNGRADE_SIZE 8u
36 #define TLS_HS_MAX_SESSION_ID_SIZE 32u
37 #define TLS_HS_MIN_SESSION_ID_SIZE 24u
38 #define TLS_HS_MIN_COOKIE_SIZE 1u
39 #define TLS_HS_MAX_COOKIE_SIZE 255u
40 
41 #define DTLS_HS_MSGLEN_ADDR 1u /* DTLS message length address, which is used when parsing the DTLS message header. */
42 /* DTLS message sequence number address, which is used for parsing the DTLS message header. */
43 #define DTLS_HS_MSGSEQ_ADDR 4u
44 /* DTLS message fragment offset address, which is used when the DTLS message header is parsed. */
45 #define DTLS_HS_FRAGMENT_OFFSET_ADDR 6u
46 /* DTLS message fragment length address, which is used when parsing the DTLS message header. */
47 #define DTLS_HS_FRAGMENT_LEN_ADDR 9u
48 
49 /* Handshake message type */
50 typedef enum {
51     HELLO_REQUEST = 0,
52     CLIENT_HELLO = 1,
53     SERVER_HELLO = 2,
54     HELLO_VERIFY_REQUEST = 3,
55     NEW_SESSION_TICKET = 4,
56     END_OF_EARLY_DATA = 5,
57     HELLO_RETRY_REQUEST = 6,
58     ENCRYPTED_EXTENSIONS = 8,
59     CERTIFICATE = 11,
60     SERVER_KEY_EXCHANGE = 12,
61     CERTIFICATE_REQUEST = 13,
62     SERVER_HELLO_DONE = 14,
63     CERTIFICATE_VERIFY = 15,
64     CLIENT_KEY_EXCHANGE = 16,
65     FINISHED = 20,
66     CERTIFICATE_URL = 21,
67     CERTIFICATION_STATUS = 22,
68     SUPPLEMENTAL_DATA = 23,
69     KEY_UPDATE = 24,
70     MESSAGE_HASH = 254,
71     HS_MSG_TYPE_END = 255
72 } HS_MsgType;
73 
74 typedef enum {
75     PSK_KE = 0,
76     PSK_DHE_KE = 1,
77     PSK_KEY_EXCHANGEMODE_END = 255
78 } HS_PskKeyExchMode;
79 
80 typedef struct {
81     HITLS_KeyUpdateRequest requestUpdate;
82 } KeyUpdateMsg;
83 
84 typedef struct {
85     ListHead head;
86     uint16_t group; /* Naming group of keys to be exchanged */
87     uint16_t keyExchangeSize;
88     uint8_t *keyExchange; /* Key exchange information */
89 } KeyShare;
90 
91 typedef struct OfferedPsks {
92     ListHead pskNode;  /* Multiple PSK linked lists are formed through pskNode. The actual data of this node is the
93                           following fields */
94     uint8_t *identity; /* pskid and binder are in one-to-one mapping. */
95     uint8_t *binder;   /* HMAC value */
96     uint32_t obfuscatedTicketAge; /* An obfuscated version of the age of the key */
97     uint16_t identitySize;        /* bytes of identity */
98     uint8_t binderSize;           /* bytes of binder */
99     bool isValid;                 /* is binder valid */
100 } PreSharedKey;
101 
102 typedef struct {
103     uint16_t *supportedGroups;
104     uint16_t *signatureAlgorithms;
105     uint16_t *signatureAlgorithmsCert;
106     uint8_t *pointFormats;
107     uint8_t *alpnList;      /* application-layer protocol negotiation list */
108     uint8_t *serverName;    /* serverName after parsing */
109     uint8_t *secRenegoInfo; /* renegotiation extension information */
110     uint8_t *ticket;        /* ticket information */
111 
112     uint32_t ticketSize;
113     uint16_t supportedGroupsSize;
114     uint16_t signatureAlgorithmsSize;
115     uint16_t signatureAlgorithmsCertSize;
116     uint16_t alpnListSize; /* application-layer protocol negotiation list len */
117     uint16_t serverNameSize;
118     uint8_t pointFormatsSize;
119     uint8_t serverNameType;    /* Type of the parsed serverName. */
120     uint8_t secRenegoInfoSize; /* Length of the security renegotiation information */
121     uint8_t reserved[1];       /* Four-byte alignment */
122 
123     /* TLS1.3 */
124     uint16_t *supportedVersions;
125     uint8_t *cookie;
126     uint8_t *keModes;
127     uint8_t keModesSize;
128     uint8_t supportedVersionsCount; /* Number of supported version */
129     uint16_t cookieLen;
130 
131     HITLS_TrustedCAList *caList;
132     PreSharedKey *preSharedKey;
133     KeyShare *keyShare; /* In the ClientHello message, this extension provides a set of KeyShares */
134 } ExtensionContent;
135 
136 typedef struct {
137     bool haveSupportedGroups;
138     bool haveSignatureAlgorithms;
139     bool haveSignatureAlgorithmsCert;
140     bool havePointFormats;
141     bool haveExtendedMasterSecret;
142     bool haveSupportedVers;
143     bool haveCookie;        /* Whether there is a cookie (involved in TLS1.3 ClientHello) */
144     bool haveCA;            /* Whether the CA exists (involved in TLS1.3 ClientHello) */
145     bool havePostHsAuth;    /* Indicates whether the Client (TLS1.3) is willing to receive the Certificate Request
146                                message. */
147     bool haveKeyShare;
148     bool haveEarlyData;
149     bool havePskExMode;      /* Indicates whether the TLS1.3 key exchange mode exists. */
150     bool havePreShareKey;    /* Indicates whether the pre-shared key exists. */
151     bool haveAlpn;           /* Whether there is Alpn */
152     bool haveServerName;     /* Whether the ServerName extension exists. */
153     bool haveSecRenego;      /* Whether security renegotiation exists. */
154     bool haveTicket;         /* Indicates whether a ticket is available. */
155     bool haveEncryptThenMac; /* Indicates whether EncryptThenMac is supported. */
156 } ExtensionFlag;
157 
158 typedef struct {
159     ExtensionFlag flag;
160     ExtensionContent content;
161 } ClientHelloExt;
162 
163 /* It is used to transmit client hello message */
164 typedef struct {
165     uint8_t randomValue[HS_RANDOM_SIZE]; /* random number group */
166     uint8_t *sessionId;
167     uint8_t *cookie; /* Cookie (for DTLS only) */
168     uint16_t *cipherSuites;
169     uint16_t version;
170     uint16_t cipherSuitesSize;
171     uint8_t sessionIdSize;
172     uint8_t compressionMethodsSize;
173     uint8_t *compressionMethods;
174     uint8_t cookieLen;
175     bool haveEmptyRenegoScsvCipher; /* According to RFC 5746, a special signaling cipher suite value (SCSV) can be used
176                                         to indicate that security renegotiation is supported. */
177     bool haveFallBackScsvCipher;    /* According to RFC 7507, a special signaling cipher suite value (SCSV) can be used
178                                         to indicate that a downgrade negotiation process is in progress. */
179     uint8_t refCnt;      /* Do not involve multiple threads. Process the hrr check clientHello. */
180     uint32_t truncateHelloLen; /* is used for binder calculation. */
181     ClientHelloExt extension;
182     uint64_t extensionTypeMask;
183 } ClientHelloMsg;
184 
185 /* It is used to transmit server hello message */
186 typedef struct {
187     uint16_t version;
188     uint16_t cipherSuite;
189     uint8_t randomValue[HS_RANDOM_SIZE]; /* random number group */
190     uint8_t *sessionId;
191     uint8_t *pointFormats;
192     uint8_t *alpnSelected; /* selected alpn protocol */
193     uint8_t *cookie;
194     uint8_t *secRenegoInfo;
195     KeyShare keyShare;
196     uint16_t alpnSelectedSize; /* selected alpn protocol length */
197     uint16_t supportedVersion;
198     uint16_t cookieLen;
199     uint16_t selectedIdentity; /* TLS 1.3 psk required */
200     uint8_t sessionIdSize;
201     uint8_t pointFormatsSize;
202     uint8_t secRenegoInfoSize; /* Length of the security renegotiation information */
203     uint64_t extensionTypeMask;
204     bool havePointFormats;
205     bool haveExtendedMasterSecret;
206     bool haveSupportedVersion;
207     bool haveCookie;           /* Indicates whether the cookie length is involved in TLS1.3 HelloRetryRequest. */
208     bool haveKeyShare;         /* Whether KeyShare is extended. */
209     bool haveSelectedIdentity; /* Indicates whether the Pre_PSK is selected. */
210     bool haveSelectedAlpn;     /* Whether the application layer protocol is selected. */
211     bool haveServerName;
212     bool haveSecRenego;
213     bool haveTicket;
214     bool haveEncryptThenMac;
215     bool reserved[2]; /* Four-byte alignment */
216 } ServerHelloMsg;
217 
218 /* It is used to transmit hello verify request message */
219 typedef struct {
220     uint16_t version;
221     uint8_t cookieLen;
222     uint8_t reserved[1]; /* fill with 1 byte for 4-byte alignment */
223     uint8_t *cookie;
224 } HelloVerifyRequestMsg;
225 
226 /* Transmits certificate message */
227 typedef struct {
228     CERT_Item *cert;                /* Certificate message content */
229     uint32_t certCount;             /* Number of certificates */
230     uint8_t *certificateReqCtx;     /* Used by the TLS 1.3 */
231     uint32_t certificateReqCtxSize; /* Used by the TLS 1.3 */
232     uint64_t extensionTypeMask;     /* Used by the TLS 1.3 */
233 } CertificateMsg;
234 
235 typedef struct {
236     HITLS_ECParameters ecPara; /* Elliptic curve field parameter of the ECDH public key */
237     uint32_t pubKeySize;       /* Length of the ecdh public key */
238     uint8_t *pubKey;           /* ecdh public key content */
239     uint16_t signAlgorithm;
240     uint16_t signSize;
241     uint8_t *signData;
242 } ServerEcdh;
243 typedef struct {
244     uint8_t *p;
245     uint8_t *g;
246     uint16_t plen;
247     uint16_t glen;
248     uint8_t *pubkey;
249     uint16_t pubKeyLen;
250     uint16_t signAlgorithm;
251     uint16_t signSize;
252     uint8_t *signData;
253 } ServerDh;
254 
255 /* Used to transfer the key exchange content of the server */
256 typedef struct {
257     uint8_t *pskIdentityHint; /* psk identity negotiation prompt message */
258     uint32_t hintSize;
259     HITLS_KeyExchAlgo keyExType; /* key exchange mode */
260     union {
261         ServerEcdh ecdh;
262         ServerDh dh;
263     } keyEx;
264 } ServerKeyExchangeMsg;
265 
266 /* Used to transfer the client key exchange content */
267 typedef struct {
268     uint8_t *pskIdentity;
269     uint32_t pskIdentitySize;
270     uint32_t dataSize; /* Key exchange data length */
271     uint8_t *data;     /* Key exchange data. */
272 } ClientKeyExchangeMsg;
273 
274 /* Transmits certificate request message */
275 typedef struct {
276     uint8_t *certTypes;
277     uint16_t *signatureAlgorithms;
278     uint8_t reserved;               /* Four-byte alignment */
279     uint8_t certTypesSize;
280     uint16_t signatureAlgorithmsSize;
281     HITLS_TrustedCAList *caList;
282 #ifdef HITLS_TLS_PROTO_TLS13
283     uint16_t *signatureAlgorithmsCert;
284     uint16_t signatureAlgorithmsCertSize;
285     uint8_t *certificateReqCtx;     /* Used by the TLS 1.3 */
286     uint32_t certificateReqCtxSize; /* This field is used by the TLS 1.3. The value is not 0 only for the
287                                        authentication after the handshake */
288     uint64_t extensionTypeMask;
289     bool haveSignatureAndHashAlgoCert;
290 #endif /* HITLS_TLS_PROTO_TLS13 */
291     bool haveSignatureAndHashAlgo;
292     bool haveDistinguishedName;
293 } CertificateRequestMsg;
294 
295 /* Transmits certificate verification message */
296 typedef struct {
297     uint16_t signHashAlg; /* Signature hash algorithm, which is available only for TLS1.2 and DTLS1.2 */
298     uint16_t signSize;    /* Length of the signature data. */
299     uint8_t *sign;        /* Signature data */
300 } CertificateVerifyMsg;
301 
302 /* It is used to transmit Ticket message
303     RFC5077 3.3 NewSessionTicket Handshake Message
304       struct {
305           uint32 ticket_lifetime_hint;
306           opaque ticket<0..2^16-1>;
307       } NewSessionTicket;
308 
309     TLS1.3:
310     struct {
311         uint32 ticket_lifetime;
312         uint32 ticket_age_add;
313         opaque ticket_nonce<0..255>;
314         opaque ticket<1..2^16-1>;
315         Extension extensions<0..2^16-2>;
316     } NewSessionTicket;
317 */
318 typedef struct {
319     uint32_t ticketLifetimeHint; /* ticket timeout interval, in seconds */
320     uint32_t ticketAgeAdd;       /* ticket_age_add: a random number generated each time a ticket is issued. */
321     uint32_t ticketNonceSize;    /* ticket_nonce length */
322     uint8_t *ticketNonce;        /* ticketNonce: Unique ID of the ticket issued on the connection, starting from 0 and
323                                     increasing in ascending order. */
324     uint32_t ticketSize;
325     uint8_t *ticket; /* ticket */
326     uint64_t extensionTypeMask;
327 } NewSessionTicketMsg;
328 
329 /* It is used to transmit finish message */
330 typedef struct {
331     uint32_t verifyDataSize;
332     uint8_t *verifyData;
333 } FinishedMsg;
334 
335 typedef struct {
336     uint16_t *supportedGroups;
337     uint16_t supportedGroupsSize;
338     uint16_t alpnSelectedSize; /* selected alpn protocol length */
339     uint8_t *alpnSelected; /* selected alpn protocol */
340     uint64_t extensionTypeMask;
341 
342     bool haveSupportedGroups;
343     bool haveEarlyData;
344     bool haveServerName;
345     bool haveSelectedAlpn;
346 } EncryptedExtensions;
347 
348 /* Used to parse the handshake message header. */
349 typedef struct {
350     HS_MsgType type;
351     uint32_t length;    /* handshake msg body length */
352     uint16_t sequence; /* DTLS Indicates the number of the handshake message. Each time a new handshake message is
353                           sent, one is added. Retransmission does not add up */
354     uint32_t fragmentOffset; /* Fragment offset of DTLS handshake message */
355     uint32_t fragmentLength; /* Fragment length of the DTLS handshake message */
356     const uint8_t *rawMsg;   /* Complete handshake information */
357     uint32_t headerAndBodyLen;
358 } HS_MsgInfo;
359 
360 /* It is used to transmit handshake message */
361 typedef struct {
362     HS_MsgType type;
363     uint32_t length;
364     uint16_t sequence;       /* DTLS Indicates the number of the handshake message. Each time a new handshake message is
365                           sent, one is added. Retransmission does not add up */
366     uint8_t reserved[2];     /* fill 2 bytes for 4-byte alignment. */
367     uint32_t fragmentOffset; /* Fragment offset of DTLS handshake message. */
368     uint32_t fragmentLength; /* Fragment length of the DTLS handshake message */
369     union {
370         ClientHelloMsg clientHello;
371         ServerHelloMsg serverHello;
372         HelloVerifyRequestMsg helloVerifyReq;
373         EncryptedExtensions encryptedExtensions;
374         CertificateMsg certificate;
375         ClientKeyExchangeMsg clientKeyExchange;
376         ServerKeyExchangeMsg serverKeyExchange;
377         CertificateRequestMsg certificateReq;
378         CertificateVerifyMsg certificateVerify;
379         NewSessionTicketMsg newSessionTicket;
380         FinishedMsg finished;
381         KeyUpdateMsg keyUpdate;
382     } body;
383 } HS_Msg;
384 
385 #ifdef HITLS_TLS_PROTO_DTLS12
386 /* Reassembles fragmented messages */
387 typedef struct {
388     ListHead head;
389     HS_MsgType type;
390     uint16_t sequence;    /* DTLS Indicates the number of the handshake message. Each time a new handshake message is
391                     sent, one is added. Retransmission does not add up */
392     bool isReassComplete; /* Indicates whether the message is reassembled. */
393     uint8_t reserved;     /* Padded with 1 byte for 4-byte alignment. */
394     uint8_t *reassBitMap; /* bitmap, used for processing duplicate fragmented message and calculating whether the
395                              fragmented message are completely reassembled. */
396     uint8_t *msg;         /* Used to store the handshake messages during the reassembly. */
397     uint32_t msgLen;      /* Total length of a message, including the message header. */
398 } HS_ReassQueue;
399 #endif
400 
401 #ifdef __cplusplus
402 }
403 #endif /* end __cplusplus */
404 
405 #endif /* end HS_MSG_H */
406