Kannel: Open Source WAP and SMS gateway  svn-r5335
wtls_pdu.c
Go to the documentation of this file.
1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2018 Kannel Group
5  * Copyright (c) 1998-2001 WapIT Ltd.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Kannel Group (http://www.kannel.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Kannel" and "Kannel Group" must not be used to
28  * endorse or promote products derived from this software without
29  * prior written permission. For written permission, please
30  * contact org@kannel.org.
31  *
32  * 5. Products derived from this software may not be called "Kannel",
33  * nor may "Kannel" appear in their name, without prior written
34  * permission of the Kannel Group.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS
40  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
41  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
42  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
45  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
46  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Kannel Group. For more information on
51  * the Kannel Group, please see <http://www.kannel.org/>.
52  *
53  * Portions of this software are based upon software originally written at
54  * WapIT Ltd., Helsinki, Finland for the Kannel project.
55  */
56 
57 /*
58  * wtls_pdu.c: pack and unpack WTLS packets
59  *
60  * Generates packing and unpacking code from wtls_pdu.def.
61  *
62  * Nikos Balkanas, Inaccess Networks (2009)
63  *
64  */
65 
66 #include "gwlib/gwlib.h"
67 
68 #ifdef HAVE_WTLS_OPENSSL
69 
70 #include "gwlib/octstr.h"
71 #include "wtls_pdu.h"
72 #include "wtls_pdusupport.h"
73 #include "wtls_statesupport.h"
74 
75 KeyExchangeSuite client_key_exchange_algo = rsa_anon;
76 PublicKeyAlgorithm public_key_algo;
77 SignatureAlgorithm signature_algo;
78 
79 /* Function prototypes */
80 wtls_Payload *wtls_payload_unpack_from_offset(Octstr * data, int *offset);
81 int wtls_payload_guess_length(Octstr * data);
82 
84 {
85  wtls_PDU *pdu;
86 
87  pdu = gw_malloc(sizeof(*pdu));
88  pdu->type = type;
89  pdu->reserved = 0;
90  pdu->cipher = 0;
91  pdu->snMode = 0;
92  pdu->seqNum = -1;
93  pdu->rlen = 0;
94 
95  switch (pdu->type) {
96  case ChangeCipher_PDU:
97  pdu->u.cc.change = 1;
98  break;
99  case Alert_PDU:
100  pdu->u.alert.level = 0;
101  pdu->u.alert.desc = 0;
102  pdu->u.alert.chksum = 0;
103  break;
104  case Handshake_PDU:
105  pdu->u.handshake.msg_type = 0;
106  pdu->u.handshake.length = 0;
107  break;
108  case Application_PDU:
109  pdu->u.application.data = NULL;
110  break;
111  default:
112  warning(0, "Cannot create unknown WTLS PDU type %d", pdu->type);
113  break;
114  }
115 
116  return pdu;
117 }
118 
120 {
122  gw_free(payload);
123 }
124 
125 void wtls_pldList_destroy(List * pld_list)
126 {
127  gwlist_destroy(pld_list, (void *)wtls_payload_destroy);
128 }
129 
130 void wtls_pdu_destroy(wtls_PDU * pdu)
131 {
132  if (pdu == NULL)
133  return;
134 
135  switch (pdu->type) {
136  case ChangeCipher_PDU:
137  /* no memory was allocated for ChangeCipher_PDU */
138  break;
139  case Alert_PDU:
141  break;
142  case Handshake_PDU:
143  switch (pdu->u.handshake.msg_type) {
144  case hello_request:
145  break;
146  case client_hello:
149  session_id);
151  client_key_ids);
153  trusted_key_ids);
155  ciphersuites);
157  client_hello->
158  comp_methods);
159  /* destroy the client_hello struct */
160  gw_free(pdu->u.handshake.client_hello);
161  break;
162  case server_hello:
165  session_id);
166  /* destroy the server_hello struct */
167  gw_free(pdu->u.handshake.server_hello);
168  break;
169  case certificate:
170  {
171  Certificate *cert;
172  List *certList =
174 
175  for (;;) {
176  cert = gwlist_consume(certList);
177  if (!cert)
178  break;
179  switch (cert->certificateformat) {
180  case WTLSCert:
182  wtls_certificate);
183  break;
184 
185  case X509Cert:
186  octstr_destroy(cert->
187  x509_certificate);
188  break;
189 
190  case X968Cert:
191  octstr_destroy(cert->
192  x968_certificate);
193  break;
194  }
195  gw_free(cert);
196  }
198  certList, NULL);
199  }
200  break;
201 
202  case server_key_exchange:
205  switch (client_key_exchange_algo) {
206  case rsa_anon:
209  rsa_params);
210  break;
211  case dh_anon:
214  dh_params);
215  break;
216  case ecdh_anon:
219  ecdh_params);
220  break;
221  default:
222  break;
223  }
224  gw_free(pdu->u.handshake.server_key_exchange);
225  break;
226  case client_key_exchange:
227  switch (client_key_exchange_algo) {
228  case rsa:
229  case rsa_anon:
232  rsa_params);
233  break;
234  case dh_anon:
237  dh_anon_params);
238  break;
239  case ecdh_anon:
240  case ecdh_ecdsa:
243  ecdh_params);
244  break;
245  default:
246  break;
247  }
248  gw_free(pdu->u.handshake.client_key_exchange);
249  break;
250  case server_hello_done:
251  /* nothing to do here */
252  default:
253  break;
254  }
255  break;
256  case Application_PDU:
258  break;
259  }
260 
261  gw_free(pdu);
262 }
263 
264 /* This function will pack a list of WTLS PDUs into a single Octstr, and return
265  that Octstr. */
266 Octstr *wtls_pack_payloadlist(List * payloadlist, int seqnum)
267 {
268 
269  Octstr *returnData = 0, *tempData1 = 0, *tempData2 = 0;
270  wtls_Payload *retrievedPDU;
271 
272  /* Assert that our payloadlist is not NULL */
273  gw_assert(payloadlist != NULL);
274 
275  /* Initialise our return Octstr */
276  returnData = octstr_create("");
277 
278  /* While there are PDUs remaining in our list */
279  while (gwlist_len(payloadlist) > 0) {
280  /* Retrieve the next payload from the payloadlist */
281  retrievedPDU =
282  (wtls_Payload *) gwlist_extract_first(payloadlist);
283 
284  /* Pack the PDU */
285  tempData2 = wtls_payload_pack(retrievedPDU, seqnum++);
286 
287  /* Shift the current stuff in returnData to a temporary pointer */
288  tempData1 = returnData;
289 
290  /* Tack it onto our Octstr */
291  returnData = octstr_cat(tempData1, tempData2);
292 
293  /* And now, we can get rid of both tempData1 and tempData2 */
294  octstr_destroy(tempData1);
295  octstr_destroy(tempData2);
296  }
297 
298  /* Is the Octstr we finish with of length > 0? */
299  if (octstr_len(returnData) > 0) {
300  /* Return the Octstr */
301  return returnData;
302  }
303 
304  /* Otherwise, return NULL */
305  return NULL;
306 }
307 
308 /* This function will unpack an Octstr and return a list of all PDUs contained
309  within that Octstr. If the contents of the packet are garbled in some fashion,
310  and one packet fails to be decoded correctly, we will continue regardless, and
311  a partial list will be returned. NULL is returned if no PDUs can be successfully
312  decoded from the supplied data */
314 {
315 
316  List *payloadlist = NULL;
317  int offset = 0;
318  int dataLength = 0;
319  wtls_Payload *tempPayload;
320 
321  /* Has somebody passed in an unpack of a null pointer ? */
322  gw_assert(data != NULL);
323 
324  /* Initialise our list */
325  payloadlist = gwlist_create();
326  dataLength = octstr_len(data);
327 
328  /* While offset is less than the size of the data */
329  while (offset < dataLength) {
330 
331  debug("wtls:wtls_unpack_payloadlist", 0, "Offset is now : %d",
332  offset);
333  /* Unpack from the supplied offset. This will bump up the value of offset */
334  tempPayload = wtls_payload_unpack_from_offset(data, &offset);
335 
336  /* If the packet returned is not NULL */
337  if (tempPayload != NULL) {
338  /* Add the returned packet to the current list of packets */
339  gwlist_append(payloadlist, (void *)tempPayload);
340  }
341  }
342 
343  debug("wtls:wtls_unpack_payloadlist", 0, "Finished, found %ld PDUs",
344  gwlist_len(payloadlist));
345 
346  /* If the length of the list is greater than 0 */
347  if (gwlist_len(payloadlist) > 0) {
348  /* Return the List */
349  return payloadlist;
350  }
351 
352  /* Otherwise return NULL */
353  return NULL;
354 }
355 
356 /* This function tries to determine the length of the PDU at the start of the
357  supplied Octstr using (somewhat) intelligent means. If the packet is screwed
358  up in some fashion, returns length -1. Returns an int. */
359 
360 int wtls_payload_guess_length(Octstr * data)
361 {
362 
363  int type = 0, lengthFlag = 0, lengthSize = 0, pdu_length = 0;
364  long lengthOffset = 1;
365 
366  /* Is the fragment length indicator on? */
367  lengthFlag = octstr_get_bits(data, 0, 1);
368  if (lengthFlag) {
369  lengthSize = 2;
370  }
371 
372  /* Is the sequence number indicator on? */
373  if (octstr_get_bits(data, 1, 1)) {
374  /* Yes, so hop over two extra bytes when reading the length */
375  lengthOffset += 2;
376  }
377  /* the message type */
378  type = octstr_get_bits(data, 4, 4);
379 
380  /* If fragment length is turned on, jump to the necessary spot */
381  if (lengthFlag == 1) {
382  /* After this, lengthOffset + pdu_length == the total length of the PDU */
383  pdu_length = unpack_int16(data, &lengthOffset);
384  }
385 
386  /* Oh great, so it's not switched on. How considerate. We'll have to make
387  a reasonable guess as to what it might be. */
388  else {
389  switch (type) {
390  case ChangeCipher_PDU:
391  /* They're really short */
392  pdu_length = 1;
393  break;
394 
395  case Alert_PDU:
396  /* They're a bit longer */
397  pdu_length = 6;
398  break;
399 
400  default:
401  /* Otherwise just give up and play dead */
402  pdu_length = -1;
403  break;
404  }
405  }
406 
407  /* And that's the length of the contents, now just add the other doodads on */
408  if (pdu_length == -1) {
409  return -1;
410  } else {
411  /* The pdu length, plus the sequence number, plus the length of the length value,
412  plus the actual header byte */
413  return (pdu_length + lengthOffset);
414  }
415 }
416 
417 /* This function will unpack an Octstr, starting at the specified offset, and
418  return the corresponding wtls_PDU* which was generated from that offset. Offset
419  is changed during the running of this function, and ends up as the octet at the start of the
420  next pdu */
421 
422 wtls_Payload *wtls_payload_unpack_from_offset(Octstr * data, int *offset)
423 {
424  int guessedPayloadLength = 0;
425  int dataLength = 0;
426  Octstr *dataFromOffset = 0;
427  Octstr *dataFromOffsetToLength = 0;
428  wtls_Payload *returnPayload = 0;
429 
430  /* This would be a sure sign of trouble */
431  gw_assert(offset != NULL);
432  gw_assert(data != NULL);
433  gw_assert(octstr_len(data) >= *offset);
434 
435  dataLength = octstr_len(data);
436 
437  /* First, we need to figure out how long a PDU starting from
438  the specified offset is going to be. We need to peek quickly into the
439  PDU to check this */
440  dataFromOffset = octstr_copy(data, *offset, dataLength);
441  guessedPayloadLength = wtls_payload_guess_length(dataFromOffset);
442 
443  /* Ooops. Something's wrong. This requested PDU is screwed up. */
444  if (guessedPayloadLength == -1) {
445  octstr_destroy(dataFromOffset);
446  *offset = dataLength;
447  return NULL;
448  }
449 
450  /* Quit if we discover that the PDU length plus the requested offset is
451  larger than the length of the data supplied - this would mean that we
452  would overrun our data, and therefore something is corrupt in this PDU.
453  Set the offset as the data length, which will indicate we've gone as far
454  as we can */
455  if ((*offset + guessedPayloadLength) > dataLength) {
456  octstr_destroy(dataFromOffset);
457  *offset = dataLength;
458  return NULL;
459  }
460 
461  /* If we pass that test, set offset to the correct return value */
462  *offset += guessedPayloadLength;
463 
464  /* Copy the octstr again, so that we end up with an octstr containing
465  just the PDU we want */
466  dataFromOffsetToLength =
467  octstr_copy(dataFromOffset, 0, guessedPayloadLength);
468 
469  /* Submit that octstr to the wtls_message_unpack function */
470  returnPayload = wtls_payload_unpack(dataFromOffsetToLength);
471 
472  octstr_destroy(dataFromOffset);
473  return returnPayload;
474 }
475 
477 {
478  wtls_Payload *payload = NULL;
479  long bitpos = 0, charpos = 0;
480 
481  gw_assert(data != NULL);
482 
483  payload = gw_malloc(sizeof(wtls_Payload));
484 
485  /* the record field length flag */
486  payload->rlen = octstr_get_bits(data, bitpos, 1);
487  bitpos += 1;
488  /* the sequence number flag */
489  payload->snMode = octstr_get_bits(data, bitpos, 1);
490  bitpos += 1;
491  /* the cipher usage flag */
492  payload->cipher = octstr_get_bits(data, bitpos, 1);
493  bitpos += 1;
494  /* the reserved bit */
495  payload->reserved = octstr_get_bits(data, bitpos, 1);
496  bitpos += 1;
497  /* the message type */
498  payload->type = octstr_get_bits(data, bitpos, 4);
499  bitpos += 4;
500  charpos += 1;
501 
502  /* Get the sequence number if present */
503  if (payload->snMode)
504  payload->seqNum = unpack_int16(data, &charpos);
505 
506  /* consume the WTLS plaintext length if present */
507  if (payload->rlen)
508  charpos += 2;
509 
510  /* the part of data that has just been processed is not
511  * needed anymore. We delete it. What is left of data is
512  * the payload.
513  */
514  octstr_delete(data, 0, charpos);
515  payload->data = data;
516 
517  return payload;
518 }
519 
520 // Doesn't destroy input payload
522 {
523  wtls_PDU *pdu = NULL;
524  Octstr *buffer;
525  long charpos = 0;
526 
527  gw_assert(payload->data != NULL);
528 
529  pdu = gw_malloc(sizeof(wtls_PDU));
530 
531  pdu->type = payload->type;
532  pdu->reserved = payload->reserved;
533  pdu->cipher = payload->cipher;
534  pdu->snMode = payload->snMode;
535  pdu->seqNum = payload->seqNum;
536  pdu->rlen = payload->rlen;
537 
538  /* is the PDU encrypted ? */
539  /*
540  if(pdu->cipher) {
541  buffer = wtls_decrypt(payload->data, wtls_machine);
542  }
543  else {
544  */
545  buffer = payload->data;
546  /*
547  }
548  */
549 
550  switch (pdu->type) {
551  case ChangeCipher_PDU:
552  pdu->u.cc.change = octstr_get_char(buffer, charpos);
553  charpos += 1;
554  break;
555 
556  case Alert_PDU:
557  pdu->u.alert.level = octstr_get_char(buffer, charpos);
558  charpos += 1;
559  pdu->u.alert.desc = octstr_get_char(buffer, charpos);
560  charpos += 1;
561  pdu->u.alert.chksum = unpack_octstr_fixed(buffer, &charpos, 4);
562  break;
563 
564  case Handshake_PDU:
565  pdu->u.handshake.msg_type = octstr_get_char(buffer, charpos);
566  charpos += 1;
567  pdu->u.handshake.length = unpack_int16(buffer, &charpos);
568  switch (pdu->u.handshake.msg_type) {
569  case hello_request:
570  break;
571 
572  case client_hello:
573  pdu->u.handshake.client_hello =
574  (ClientHello *) gw_malloc(sizeof(ClientHello));
576  octstr_get_char(buffer, charpos);
577  charpos += 1;
579  unpack_random(buffer, &charpos);
581  unpack_octstr(buffer, &charpos);
582 
583  /* Unpack the list of keys */
585  unpack_key_list(buffer, &charpos);
587  unpack_key_list(buffer, &charpos);
588 
589  /* Unpack the list of CipherSuites */
591  unpack_ciphersuite_list(buffer, &charpos);
592 
593  /* CompressionMethods */
595  unpack_compression_method_list(buffer, &charpos);
596 
598  octstr_get_char(buffer, charpos);
599  charpos += 1;
601  octstr_get_char(buffer, charpos);
602  charpos += 1;
603  break;
604 
605  case server_hello:
606  pdu->u.handshake.server_hello =
607  (ServerHello *) gw_malloc(sizeof(ServerHello));
609  octstr_get_char(buffer, charpos);
610  charpos += 1;
612  unpack_random(buffer, &charpos);
614  unpack_octstr(buffer, &charpos);
616  octstr_get_char(buffer, charpos);
617  charpos += 1;
618  /* CypherSuite */
620  bulk_cipher_algo = octstr_get_char(buffer, charpos);
621  charpos += 1;
623  octstr_get_char(buffer, charpos);
624  charpos += 1;
625 
626  /* CompressionMethod */
628  octstr_get_char(buffer, charpos);
629  charpos += 1;
630 
632  octstr_get_char(buffer, charpos);
633  charpos += 1;
635  octstr_get_char(buffer, charpos);
636  charpos += 1;
637  break;
638 
639  case certificate:
640  {
641  List *certList = gwlist_create();
642  Certificate *cert;
643  int len = unpack_int16(buffer, &charpos);
644 
645  while (charpos <= len) {
646  cert =
647  (Certificate *)
648  gw_malloc(sizeof(Certificate));
649  cert->certificateformat =
650  octstr_get_char(buffer, charpos);
651  charpos += 1;
652  switch (cert->certificateformat) {
653  case WTLSCert:
654  cert->wtls_certificate =
656  (buffer, &charpos);
657  break;
658 
659  case X509Cert:
660  cert->x509_certificate =
661  unpack_octstr16(buffer,
662  &charpos);
663  break;
664 
665  case X968Cert:
666  cert->x968_certificate =
667  unpack_octstr16(buffer,
668  &charpos);
669  break;
670  }
671  gwlist_append(certList, cert);
672  }
674  certList;
675  }
676  break;
677 
678  case server_key_exchange:
681  gw_malloc(sizeof(ServerKeyExchange));
682  /* unpack the ParameterSpecifier and ParameterSet */
684  unpack_param_spec(buffer, &charpos);
685  switch (client_key_exchange_algo) {
686  case rsa_anon:
688  rsa_params =
689  unpack_rsa_pubkey(buffer, &charpos);
690  break;
691 
692  case dh_anon:
694  dh_params =
695  unpack_dh_pubkey(buffer, &charpos);
696  break;
697 
698  case ecdh_anon:
700  ecdh_params =
701  unpack_ec_pubkey(buffer, &charpos);
702  break;
703 
704  default:
705  break;
706  }
707  break;
708 
709  case client_key_exchange:
712  gw_malloc(sizeof(ClientKeyExchange));
713  switch (client_key_exchange_algo) {
714  case rsa:
715  case rsa_anon:
717  rsa_params =
719  &charpos);
720  break;
721 
722  case dh_anon:
724  dh_anon_params =
725  unpack_dh_pubkey(buffer, &charpos);
726  break;
727 
728  case ecdh_anon:
729  case ecdh_ecdsa:
731  ecdh_params =
732  unpack_ec_pubkey(buffer, &charpos);
733  break;
734 
735  default:
736  break;
737  }
738  break;
739 
740  case server_hello_done:
741  /* empty */
742  break;
743 
744  case finished:
745  pdu->u.handshake.finished =
746  (Finished *) gw_malloc(sizeof(Finished));
748  unpack_octstr_fixed(buffer, &charpos, 12);
750  break;
751 
752  default:
753  break;
754  }
755  break;
756 
757  case Application_PDU:
758  /* application message */
759  pdu->u.application.data = octstr_duplicate(buffer);
760  break;
761 
762  default:
763  debug("wap.wtls", 0, "%*sPDU: ", 0, "");
764  octstr_dump(buffer, 0);
765  panic(0, "Unpacking unknown WTLS PDU type %ld",
766  (long)pdu->type);
767  break;
768  }
769 
770  return (pdu);
771 }
772 
774 {
775  Octstr *data;
776  long bitpos, charpos;
777  long sizepos;
778 
779  /* We rely on octstr_set_bits to lengthen our octstr as needed. */
780  data = octstr_create("");
781  bitpos = 0;
782  charpos = 0;
783  sizepos = 0;
784 
785  /* the record field length flag - always present */
786  octstr_set_bits(data, bitpos, 1, 1);
787  bitpos += 1;
788  /* the sequence number flag */
789  octstr_set_bits(data, bitpos, 1, payload->snMode);
790  bitpos += 1;
791  /* the cipher usage flag */
792  octstr_set_bits(data, bitpos, 1, payload->cipher);
793  bitpos += 1;
794  /* the reserved bit */
795  octstr_set_bits(data, bitpos, 1, payload->reserved);
796  bitpos += 1;
797 
798  /* set the message type */
799  octstr_set_bits(data, bitpos, 4, payload->type);
800  bitpos += 4;
801  charpos += 1;
802 
803  /* set the sequence number */
804  if (payload->snMode)
805  charpos = pack_int16(data, charpos, seqnum);
806 
807  /* set the WTLS length */
808  charpos = pack_int16(data, charpos, payload->rlen);
809 
810  /* append the data from the wtls_PDU */
811  octstr_insert(data, payload->data, octstr_len(data));
812 
813  return data;
814 }
815 
816 wtls_Payload *wtls_pdu_pack(wtls_PDU * pdu, WTLSMachine * wtls_machine)
817 {
818  Octstr *buffer, *encryptedbuffer;
820  long bitpos, charpos;
821  long messageSizePos, sizepos;
822  /* Used for length calculations */
823  int size, recordType;
824 
825  /* create the wtls_PDU */
826  payload = (wtls_Payload *) gw_malloc(sizeof(wtls_Payload));
827  payload->type = pdu->type;
828  payload->reserved = pdu->reserved;
829  payload->cipher = pdu->cipher;
830  payload->snMode = pdu->snMode;
831  payload->seqNum = pdu->seqNum;
832 
833  /* We rely on octstr_set_bits to lengthen our octstr as needed. */
834  buffer = octstr_create("");
835  bitpos = 0;
836  charpos = 0;
837  sizepos = 0;
838 
839  switch (pdu->type) {
840  case ChangeCipher_PDU:
841  octstr_append_char(buffer, pdu->u.cc.change);
842  charpos += 1;
843  break;
844  case Alert_PDU:
845  octstr_append_char(buffer, pdu->u.alert.level);
846  charpos += 1;
847  octstr_append_char(buffer, pdu->u.alert.desc);
848  charpos += 1;
849  charpos =
850  pack_octstr_fixed(buffer, charpos, pdu->u.alert.chksum);
851  break;
852  case Handshake_PDU:
853  octstr_append_char(buffer, pdu->u.handshake.msg_type);
854  charpos += 1;
855  /* Save the location of the message size */
856  messageSizePos = charpos;
857  charpos = pack_int16(buffer, charpos, pdu->u.handshake.length);
858  switch (pdu->u.handshake.msg_type) {
859  case hello_request:
860  break;
861  case client_hello:
862  octstr_append_char(buffer,
863  pdu->u.handshake.client_hello->
864  clientversion);
865  charpos += 1;
866  charpos =
867  pack_random(buffer, charpos,
869  charpos =
870  pack_octstr(buffer, charpos,
871  pdu->u.handshake.client_hello->
872  session_id);
873 
874  /* pack the list of keys */
875  charpos = pack_key_list(buffer, charpos,
876  pdu->u.handshake.client_hello->
877  client_key_ids);
878  charpos =
879  pack_key_list(buffer, charpos,
880  pdu->u.handshake.client_hello->
881  trusted_key_ids);
882 
883  /* pack the list of CipherSuites */
884  charpos = pack_ciphersuite_list(buffer, charpos,
885  pdu->u.handshake.
886  client_hello->
887  ciphersuites);
888 
889  /* CompressionMethods */
890  charpos = pack_compression_method_list(buffer, charpos,
891  pdu->u.handshake.
892  client_hello->
893  comp_methods);
894 
895  octstr_append_char(buffer,
896  pdu->u.handshake.client_hello->
897  snmode);
898  charpos += 1;
899  octstr_append_char(buffer,
900  pdu->u.handshake.client_hello->
901  krefresh);
902  charpos += 1;
903  break;
904  case server_hello:
905  octstr_append_char(buffer,
906  pdu->u.handshake.server_hello->
907  serverversion);
908  charpos += 1;
909  charpos =
910  pack_random(buffer, charpos,
912  charpos =
913  pack_octstr(buffer, charpos,
914  pdu->u.handshake.server_hello->
915  session_id);
916  octstr_append_char(buffer,
917  pdu->u.handshake.
919  charpos += 1;
920  /* CypherSuite */
921  octstr_append_char(buffer,
922  pdu->u.handshake.
924  bulk_cipher_algo);
925  charpos += 1;
926  octstr_append_char(buffer,
927  pdu->u.handshake.
929  charpos += 1;
930 
931  /* CompressionMethod */
932  octstr_append_char(buffer,
933  pdu->u.handshake.server_hello->
934  comp_method);
935  charpos += 1;
936 
937  octstr_append_char(buffer,
938  pdu->u.handshake.server_hello->
939  snmode);
940  charpos += 1;
941  octstr_append_char(buffer,
942  pdu->u.handshake.server_hello->
943  krefresh);
944  charpos += 1;
945 
946  break;
947  case certificate:
948  {
949  Certificate *cert;
950  int pos = charpos, len;
951 
952  charpos = pack_int16(buffer, charpos, 0);
953  for (;;) {
954  cert =
956  certificates->
957  certList);
958  if (!cert)
959  break;
960  octstr_append_char(buffer,
961  cert->
963  charpos += 1;
964  switch (cert->certificateformat) {
965  case WTLSCert:
966  charpos =
968  (buffer, charpos,
969  cert->wtls_certificate);
971  wtls_certificate);
972  break;
973 
974  case X509Cert:
975  charpos =
976  pack_octstr16(buffer,
977  charpos,
978  cert->
979  x509_certificate);
980  octstr_destroy(cert->
981  x509_certificate);
982  break;
983 
984  case X968Cert:
985  charpos =
986  pack_octstr16(buffer,
987  charpos,
988  cert->
989  x968_certificate);
990  octstr_destroy(cert->
991  x968_certificate);
992  break;
993  }
994  gw_free(cert);
995  }
996  len = charpos - pos - 2;
997  octstr_set_char(buffer, pos,
998  (len & 0xFF00) >> 8);
999  octstr_set_char(buffer, pos + 1, len & 0xFF);
1000  }
1001  break;
1002  case server_key_exchange:
1003  debug("wtls: ", 0, "Packing ServerKeyExchange");
1004  /* pack the ParameterSpecifier */
1005  charpos =
1006  pack_param_spec(buffer, charpos,
1007  pdu->u.handshake.
1009 
1010  switch (client_key_exchange_algo) {
1011  case rsa_anon:
1012  charpos =
1013  pack_rsa_pubkey(buffer, charpos,
1014  pdu->u.handshake.
1016  rsa_params);
1017  break;
1018  case dh_anon:
1019  charpos =
1020  pack_dh_pubkey(buffer, charpos,
1021  pdu->u.handshake.
1023  dh_params);
1024  break;
1025  case ecdh_anon:
1026  charpos =
1027  pack_ec_pubkey(buffer, charpos,
1028  pdu->u.handshake.
1030  ecdh_params);
1031  break;
1032  default:
1033  break;
1034  }
1035  break;
1036  case client_key_exchange:
1037  switch (client_key_exchange_algo) {
1038  case rsa:
1039  case rsa_anon:
1040  charpos =
1041  pack_rsa_encrypted_secret(buffer, charpos,
1042  pdu->u.handshake.
1044  rsa_params);
1045  break;
1046  case dh_anon:
1047  charpos =
1048  pack_dh_pubkey(buffer, charpos,
1049  pdu->u.handshake.
1051  dh_anon_params);
1052  break;
1053  case ecdh_anon:
1054  case ecdh_ecdsa:
1055  charpos =
1056  pack_ec_pubkey(buffer, charpos,
1057  pdu->u.handshake.
1059  ecdh_params);
1060  break;
1061  default:
1062  break;
1063  }
1064  break;
1065  case server_hello_done:
1066  /* empty */
1067  default:
1068  break;
1069  case finished:
1070  charpos =
1071  pack_octstr_fixed(buffer, charpos,
1072  pdu->u.handshake.finished->
1073  verify_data);
1074  debug("wtls", 0, "verify_data (in pack)");
1076  break;
1077  }
1078  /* Change the length */
1079  size = octstr_len(buffer) - messageSizePos - 2;
1080  debug("wtls_msg.c:length", 0, "Setting msg size to : %d", size);
1081  octstr_set_char(buffer, messageSizePos, (size & 0xFF00) >> 8);
1082  messageSizePos += 1;
1083  octstr_set_char(buffer, messageSizePos, (size & 0x00FF));
1084 
1085  /* we keep the handshake data to create the Finished PDU */
1086  octstr_append(wtls_machine->handshake_data, buffer);
1087  break;
1088 
1089  case Application_PDU:
1090  /* application message */
1091  octstr_destroy(buffer);
1092  buffer = pdu->u.application.data;
1093  pdu->u.application.data = NULL;
1094  break;
1095 
1096  default:
1097  panic(0, "Packing unknown WTLS PDU type %ld", (long)pdu->type);
1098  }
1099 
1100  /* encrypt the buffer if needed */
1101  if (pdu->cipher) {
1102  /* the MAC is calculated with the record type so we need it now */
1103  recordType = 1 << 7; /* length, always present */
1104  recordType |= pdu->snMode << 6;
1105  recordType |= pdu->cipher << 5;
1106  recordType |= pdu->reserved << 4;
1107  recordType |= pdu->type;
1108  if (!(encryptedbuffer = wtls_encrypt(buffer, wtls_machine,
1109  recordType)))
1110  return (NULL);
1111 
1112  payload->data = encryptedbuffer;
1113  } else
1114  payload->data = buffer;
1115 
1116  payload->rlen = octstr_len(payload->data);
1117  debug("wtls", 0, "Packed PDU Length: %d", payload->rlen);
1118 
1119  return (payload);
1120 }
1121 
1122 void wtls_payload_dump(wtls_Payload * payload, int level)
1123 {
1124  char *dbg = "wap.wtls", type[20], *data;
1125  if (!payload)
1126  return;
1127  data = octstr_get_cstr(payload->data);
1128 
1129  /* the message type */
1130  pduName(type, payload->type);
1131  debug(dbg, 0, "%*sPayload type: %s", level, "", type);
1132  if (payload->type == Handshake_PDU) {
1133  hsName(type, *data);
1134  debug(dbg, 0, "%*sHandshake type: %s", level + 1, "", type);
1135  } else if (payload->type == Alert_PDU) {
1136  alertName(type, *(data + 1));
1137  debug(dbg, 0, "%*sAlert type: %s", level + 1, "", type);
1138  }
1139  /* the reserved bit */
1140  debug(dbg, 0, "%*sReserved bit: %d", level, "", payload->reserved);
1141  /* cipher usage flag */
1142  debug(dbg, 0, "%*sCipher in use: %d", level, "", payload->cipher);
1143  /* the sequence number flag */
1144  debug(dbg, 0, "%*sSequence number in use: %d", level, "",
1145  payload->seqNum);
1146  /* the record field length flag */
1147  debug(dbg, 0, "%*sRecord field length present: %d", level, "",
1148  payload->rlen);
1149 
1150  octstr_dump(payload->data, level + 1);
1151 }
1152 
1153 void wtls_pdu_dump(wtls_PDU * pdu, int level)
1154 {
1155  char *dbg = "wap.wtls", type[20];
1156 
1157  /* the message type */
1158  pduName(type, pdu->type);
1159  debug(dbg, 0, "%*sPDU type: %s", level, "", type);
1160  if (pdu->type == Handshake_PDU) {
1161  hsName(type, pdu->u.handshake.msg_type);
1162  debug(dbg, 0, "%*sHandshake type: %s", level + 1, "", type);
1163  }
1164  /* the reserved bit */
1165  debug(dbg, 0, "%*sReserved bit: %d", level, "", pdu->reserved);
1166  /* cipher usage flag */
1167  debug(dbg, 0, "%*sCipher in use: %d", level, "", pdu->cipher);
1168  /* the sequence number flag */
1169  debug(dbg, 0, "%*sSequence number in use: %d", level, "", pdu->seqNum);
1170  /* the record field length flag */
1171  debug(dbg, 0, "%*sRecord field length present: %d", level, "",
1172  pdu->rlen);
1173 
1174  switch (pdu->type) {
1175  case ChangeCipher_PDU:
1176  debug(dbg, 0, "%*sChangeCipher:", level, "");
1177  debug(dbg, 0, "%*sChange: %d", level + 1, "", pdu->u.cc.change);
1178  break;
1179 
1180  case Alert_PDU:
1181  debug(dbg, 0, "%*sAlert:", level, "");
1182  debug(dbg, 0, "%*sLevel: %d", level + 1, "",
1183  pdu->u.alert.level);
1184  debug(dbg, 0, "%*sDescription: %d", level + 1, "",
1185  pdu->u.alert.desc);
1186  debug(dbg, 0, "%*sChecksum: %s", level + 1, "",
1187  octstr_get_cstr(pdu->u.alert.chksum));
1188  break;
1189 
1190  case Handshake_PDU:
1191  debug(dbg, 0, "%*sHandshake:", level, "");
1192  debug(dbg, 0, "%*sMessage Type: %d", level + 1, "",
1193  pdu->u.handshake.msg_type);
1194  debug(dbg, 0, "%*sLength: %d", level + 1, "",
1195  pdu->u.handshake.length);
1196  switch (pdu->u.handshake.msg_type) {
1197  case hello_request:
1198  debug(dbg, 0, "%*sHelloRequest.", level, "");
1199  break;
1200 
1201  case client_hello:
1202  debug(dbg, 0, "%*sClientHello:", level, "");
1203  debug(dbg, 0, "%*sClient version: %d", level + 1, "",
1205  debug(dbg, 0, "%*sRandom:", level + 1, "");
1206  dump_random(dbg, level + 2,
1207  pdu->u.handshake.client_hello->random);
1208  debug(dbg, 0, "%*sSessionId: ", level, "");
1210  level + 2);
1211  /* pack the list of keys */
1212  debug(dbg, 0, "%*sClient Key IDs: ", level + 1, "");
1213  dump_key_list(dbg, level + 2,
1214  pdu->u.handshake.client_hello->
1215  client_key_ids);
1216  debug(dbg, 0, "%*sTrusted Key IDs: ", level + 1, "");
1217  dump_key_list(dbg, level + 2,
1218  pdu->u.handshake.client_hello->
1219  trusted_key_ids);
1220  /* pack the list of CipherSuites */
1221  debug(dbg, 0, "%*sCipherSuite List: ", level + 1, "");
1222  dump_ciphersuite_list(dbg, level + 2,
1223  pdu->u.handshake.client_hello->
1224  ciphersuites);
1225  /* CompressionMethods */
1226  debug(dbg, 0, "%*sCompression Method List: ", level + 1,
1227  "");
1228  dump_compression_method_list(dbg, level + 2,
1229  pdu->u.handshake.
1230  client_hello->
1231  comp_methods);
1232  debug(dbg, 0, "%*sSeq Number Mode: %d", level + 1, "",
1233  pdu->u.handshake.client_hello->snmode);
1234  debug(dbg, 0, "%*sKey Refresh: %d", level + 1, "",
1236  break;
1237 
1238  case server_hello:
1239  debug(dbg, 0, "%*sServerHello:", level, "");
1240  debug(dbg, 0, "%*sServer version: %d", level + 1, "",
1242  debug(dbg, 0, "%*sRandom:", level + 1, "");
1243  dump_random(dbg, level + 2,
1244  pdu->u.handshake.server_hello->random);
1245  debug(dbg, 0, "%*sSession ID: %s", level + 1, "",
1248  debug(dbg, 0, "%*sClient Key ID: %d", level + 1, "",
1250  /* CypherSuite */
1251  debug(dbg, 0, "%*sBulk Cipher Algo: %d", level + 1, "",
1252  pdu->u.handshake.server_hello->
1253  ciphersuite->bulk_cipher_algo);
1254  debug(dbg, 0, "%*sMAC Algo: %d", level + 1, "",
1256  mac_algo);
1257  /* CompressionMethod */
1258  debug(dbg, 0, "%*sCompression Method: %d", level + 1,
1259  "", pdu->u.handshake.server_hello->comp_method);
1260  debug(dbg, 0, "%*sSeq Number Mode: %d", level + 1, "",
1261  pdu->u.handshake.server_hello->snmode);
1262  debug(dbg, 0, "%*sKey Refresh: %d", level + 1, "",
1264  break;
1265 
1266  case certificate:
1267  debug(dbg, 0, "%*sCertificate:", level, "");
1268  {
1269  Certificate *cert;
1270  List *certList =
1272  int i = 0, len = gwlist_len(certList);
1273 
1274  for (; i < len; i++) {
1275  cert = gwlist_get(certList, i);
1276 
1277  debug(dbg, 0,
1278  "%*sCertificate Format: %d",
1279  level + 1, "",
1280  cert->certificateformat);
1281  switch (cert->certificateformat) {
1282  case WTLSCert:
1283  debug(dbg, 0,
1284  "%*sWTLS Certificate:",
1285  level + 1, "");
1287  level + 2,
1288  cert->
1289  wtls_certificate);
1290  break;
1291 
1292  case X509Cert:
1293  debug(dbg, 0,
1294  "%*sX509 Certificate:",
1295  level + 1, "");
1296  octstr_dump(cert->
1297  x509_certificate,
1298  level + 2);
1299  break;
1300 
1301  case X968Cert:
1302  debug(dbg, 0,
1303  "%*sX968 Certificate:",
1304  level + 1, "");
1305  octstr_dump(cert->
1306  x968_certificate,
1307  level + 2);
1308  break;
1309  }
1310  }
1311  }
1312  break;
1313 
1314  case server_key_exchange:
1315  debug(dbg, 0, "%*sServerKeyExchange: ", level, "");
1316  /* ParameterSpecifier */
1317  debug(dbg, 0, "%*sParameter Index: %d", level + 1, "",
1319  param_spec->param_index);
1320  if (pdu->u.handshake.server_key_exchange->
1321  param_spec->param_index == 255) {
1322  /* ParameterSet */
1323  debug(dbg, 0, "%*sParameter Set: %p", level + 1,
1324  "",
1326  param_spec->param_set);
1327  }
1328  switch (client_key_exchange_algo) {
1329  case rsa_anon:
1330  dump_rsa_pubkey(dbg, level + 1,
1331  pdu->u.handshake.
1333  rsa_params);
1334  break;
1335 
1336  case dh_anon:
1337  dump_dh_pubkey(dbg, level + 1,
1338  pdu->u.handshake.
1340  break;
1341 
1342  case ecdh_anon:
1343  dump_ec_pubkey(dbg, level + 1,
1344  pdu->u.handshake.
1346  ecdh_params);
1347  break;
1348 
1349  default:
1350  break;
1351  }
1352  break;
1353 
1354  case client_key_exchange:
1355  debug(dbg, 0, "%*sClientKeyExchange:", level, "");
1356  switch (client_key_exchange_algo) {
1357  case rsa:
1358  case rsa_anon:
1359  dump_rsa_encrypted_secret(dbg, level + 1,
1360  pdu->u.handshake.
1362  rsa_params);
1363  break;
1364 
1365  case dh_anon:
1366  dump_dh_pubkey(dbg, level + 1,
1367  pdu->u.handshake.
1369  dh_anon_params);
1370  break;
1371 
1372  case ecdh_anon:
1373  case ecdh_ecdsa:
1374  dump_ec_pubkey(dbg, level + 1,
1375  pdu->u.handshake.
1377  ecdh_params);
1378  break;
1379 
1380  default:
1381  break;
1382  }
1383  break;
1384 
1385  case server_hello_done:
1386  debug(dbg, 0, "%*sClientHelloDone.", level, "");
1387  /* empty */
1388  break;
1389 
1390  case finished:
1391  debug(dbg, 0, "%*sFinished:", level, "");
1392  debug(dbg, 0, "%*sverify_data :", level + 1, "");
1394  level + 2);
1395  break;
1396 
1397  default:
1398  break;
1399  }
1400  break;
1401 
1402  case Application_PDU:
1403  debug(dbg, 0, "%*sApplication:", level, "");
1404  /* application message */
1405  octstr_dump(pdu->u.application.data, level + 1);
1406  break;
1407 
1408  default:
1409  debug(dbg, 0, "%*sWTLS PDU at %p:", level, "", (void *)pdu);
1410  debug(dbg, 0, "%*s unknown type %u", level, "", pdu->type);
1411  }
1412 }
1413 #endif /* HAVE_WTLS_OPENSSL */
void destroy_compression_method_list(List *compmethod_list)
void dump_compression_method_list(char *dbg, int level, List *compmethod_list)
Certificates * certificates
Definition: wtls_pdu.h:426
AlertDescription desc
Definition: wtls_pdu.h:408
ServerHello * server_hello
Definition: wtls_pdu.h:424
int size
Definition: wsasm.c:84
wtls_Payload * wtls_pdu_pack(wtls_PDU *pdu, WTLSMachine *wtls_machine)
wtls_PDU * wtls_pdu_create(int type)
ClientKeyExchange * client_key_exchange
Definition: wtls_pdu.h:436
enum pubkey_algo PublicKeyAlgorithm
void dump_rsa_pubkey(char *dbg, int level, RSAPublicKey *key)
void wtls_payload_destroy(wtls_Payload *payload)
gw_assert(wtls_machine->packet_to_send !=NULL)
void gwlist_append(List *list, void *item)
Definition: list.c:179
void hsName(char *name, int handshake)
Random * random
Definition: wtls_pdu.h:303
int cipher
Definition: wtls_pdu.h:448
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
long gwlist_len(List *list)
Definition: list.c:166
void wtls_payload_dump(wtls_Payload *msg, int level)
Finished * finished
Definition: wtls_pdu.h:438
void * gwlist_get(List *list, long pos)
Definition: list.c:292
List * client_key_ids
Definition: wtls_pdu.h:305
void octstr_set_bits(Octstr *ostr, long bitpos, int numbits, unsigned long value)
Definition: octstr.c:1849
int pack_dh_pubkey(Octstr *data, long charpos, DHPublicKey *key)
int length
Definition: wtls_pdu.h:418
ECPublicKey * unpack_ec_pubkey(Octstr *data, long *charpos)
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1517
CertificateFormat certificateformat
Definition: wtls_pdu.h:325
WTLSCertificate * unpack_wtls_certificate(Octstr *data, long *charpos)
int krefresh
Definition: wtls_pdu.h:310
int type
Definition: smsc_cimd2.c:215
void alertName(char *name, int alert)
DHPublicKey * dh_params
Definition: wtls_pdu.h:339
int pack_octstr16(Octstr *data, long charpos, Octstr *opaque)
Octstr * session_id
Definition: wtls_pdu.h:316
Octstr * wtls_payload_pack(wtls_Payload *payload, int seqnum)
int pack_key_list(Octstr *data, long charpos, List *key_list)
Alert alert
Definition: wtls_pdu.h:455
List * certList
Definition: wtls_pdu.h:413
enum keyex_suite KeyExchangeSuite
void pduName(char *name, int pdu)
List * unpack_compression_method_list(Octstr *data, long *charpos)
Octstr * unpack_octstr16(Octstr *data, long *charpos)
void destroy_ec_pubkey(ECPublicKey *key)
int pack_random(Octstr *data, long charpos, Random *random)
int pack_int16(Octstr *data, long charpos, int i)
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void dump_ec_pubkey(char *dbg, int level, ECPublicKey *key)
List * comp_methods
Definition: wtls_pdu.h:308
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
int snMode
Definition: wtls_pdu.h:449
void wtls_pldList_destroy(List *pldList)
int pack_rsa_pubkey(Octstr *data, long charpos, RSAPublicKey *key)
void wtls_pdu_dump(wtls_PDU *msg, int level)
int reserved
Definition: wtls_pdu.h:447
int pack_wtls_certificate(Octstr *data, long charpos, WTLSCertificate *cert)
union wtls_pdu::@93 u
Application application
Definition: wtls_pdu.h:457
ChangeCipher cc
Definition: wtls_pdu.h:454
List * ciphersuites
Definition: wtls_pdu.h:307
ParameterSpecifier * param_spec
Definition: wtls_pdu.h:335
static Octstr * payload
Definition: mtbatch.c:104
void destroy_rsa_encrypted_secret(RSAEncryptedSecret *secret)
void destroy_param_spec(ParameterSpecifier *pspec)
Octstr * wtls_pack_payloadlist(List *payloadlist, int seqnum)
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1303
ParameterSpecifier * unpack_param_spec(Octstr *data, long *charpos)
long octstr_get_bits(Octstr *ostr, long bitpos, int numbits)
Definition: octstr.c:1803
void dump_dh_pubkey(char *dbg, int level, DHPublicKey *key)
void * gwlist_extract_first(List *list)
Definition: list.c:305
Octstr * x968_certificate
Definition: wtls_pdu.h:331
void dump_random(char *dbg, int level, Random *random)
void wtls_pdu_destroy(wtls_PDU *msg)
int pack_ciphersuite_list(Octstr *data, long charpos, List *ciphersuites)
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
void dump_wtls_certificate(char *dbg, int level, WTLSCertificate *cert)
Octstr * x509_certificate
Definition: wtls_pdu.h:329
Random * random
Definition: wtls_pdu.h:315
ServerKeyExchange * server_key_exchange
Definition: wtls_pdu.h:428
wtls_Payload * wtls_payload_unpack(Octstr *data)
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
Octstr * chksum
Definition: wtls_pdu.h:409
Octstr * verify_data
Definition: wtls_pdu.h:354
int serverversion
Definition: wtls_pdu.h:314
void warning(int err, const char *fmt,...)
Definition: log.c:660
int unpack_int16(Octstr *data, long *charpos)
Random * unpack_random(Octstr *data, long *charpos)
WTLSCertificate * wtls_certificate
Definition: wtls_pdu.h:327
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
int krefresh
Definition: wtls_pdu.h:321
#define octstr_create(cstr)
Definition: octstr.h:125
CipherSuite * ciphersuite
Definition: wtls_pdu.h:318
enum sig_algo SignatureAlgorithm
Octstr * unpack_octstr(Octstr *data, long *charpos)
void dump_key_list(char *dbg, int level, List *key_list)
List * unpack_key_list(Octstr *data, long *charpos)
int client_key_id
Definition: wtls_pdu.h:317
int level
Definition: wtls_pdu.h:407
void destroy_dh_pubkey(DHPublicKey *key)
RSAEncryptedSecret * unpack_rsa_encrypted_secret(Octstr *data, long *charpos)
int pack_rsa_encrypted_secret(Octstr *data, long charpos, RSAEncryptedSecret *secret)
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
int pack_compression_method_list(Octstr *data, long charpos, List *compmethod_list)
Definition: octstr.c:118
void * gwlist_consume(List *list)
Definition: list.c:427
List * trusted_key_ids
Definition: wtls_pdu.h:306
void destroy_key_list(List *key_list)
DHPublicKey * unpack_dh_pubkey(Octstr *data, long *charpos)
int change
Definition: wtls_pdu.h:362
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
int pack_octstr_fixed(Octstr *data, long charpos, Octstr *opaque)
serverKeyXchgPDU u handshake server_key_exchange param_spec
Handshake handshake
Definition: wtls_pdu.h:456
#define panic
Definition: log.h:87
void destroy_rsa_pubkey(RSAPublicKey *key)
void dump_rsa_encrypted_secret(char *dbg, int level, RSAEncryptedSecret *secret)
int mac_algo
Definition: wtls_pdu.h:286
Octstr * session_id
Definition: wtls_pdu.h:304
HandshakeType msg_type
Definition: wtls_pdu.h:417
Octstr * octstr_cat(Octstr *ostr1, Octstr *ostr2)
Definition: octstr.c:383
CompressionMethod comp_method
Definition: wtls_pdu.h:319
List * unpack_ciphersuite_list(Octstr *data, long *charpos)
unsigned char * data
Definition: octstr.c:120
void destroy_random(Random *random)
void destroy_wtls_certificate(WTLSCertificate *cert)
#define gwlist_create()
Definition: list.h:136
ClientHello * client_hello
Definition: wtls_pdu.h:422
int pack_octstr(Octstr *data, long charpos, Octstr *opaque)
Octstr * data
Definition: wtls_pdu.h:442
certificateformat
Definition: wtls_pdu.h:93
int pack_param_spec(Octstr *data, long charpos, ParameterSpecifier *pspec)
int rlen
Definition: wtls_pdu.h:451
RSAPublicKey * unpack_rsa_pubkey(Octstr *data, long *charpos)
Definition: wtls_pdu.h:114
int seqNum
Definition: wtls_pdu.h:450
Octstr * wtls_encrypt(Octstr *buffer, WTLSMachine *wtls_machine, int recordType)
serverKeyXchgPDU u handshake server_key_exchange rsa_params
List * wtls_unpack_payloadlist(Octstr *data)
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
int clientversion
Definition: wtls_pdu.h:302
void octstr_set_char(Octstr *ostr, long pos, int ch)
Definition: octstr.c:415
Octstr * unpack_octstr_fixed(Octstr *data, long *charpos, long length)
Definition: list.c:102
int pack_ec_pubkey(Octstr *data, long charpos, ECPublicKey *key)
void dump_ciphersuite_list(char *dbg, int level, List *ciphersuites)
int type
Definition: wtls_pdu.h:446
wtls_PDU * wtls_pdu_unpack(wtls_Payload *payload, WTLSMachine *wtls_machine)
void destroy_ciphersuite_list(List *ciphersuites)
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.