1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2014 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 
wtls_pdu_create(int type)83 wtls_PDU *wtls_pdu_create(int type)
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 
wtls_payload_destroy(wtls_Payload * payload)119 void wtls_payload_destroy(wtls_Payload * payload)
120 {
121 		octstr_destroy(payload->data);
122 		gw_free(payload);
123 }
124 
wtls_pldList_destroy(List * pld_list)125 void wtls_pldList_destroy(List * pld_list)
126 {
127    gwlist_destroy(pld_list, (void *)wtls_payload_destroy);
128 }
129 
wtls_pdu_destroy(wtls_PDU * pdu)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:
140       octstr_destroy(pdu->u.alert.chksum);
141 				break;
142         case Handshake_PDU:
143                 switch (pdu->u.handshake.msg_type) {
144                 case hello_request:
145 						break;
146                 case client_hello:
147 						destroy_random(pdu->u.handshake.client_hello->random);
148          octstr_destroy(pdu->u.handshake.client_hello->
149                    session_id);
150          destroy_key_list(pdu->u.handshake.client_hello->
151                 client_key_ids);
152          destroy_key_list(pdu->u.handshake.client_hello->
153                 trusted_key_ids);
154          destroy_ciphersuite_list(pdu->u.handshake.client_hello->
155                    ciphersuites);
156          destroy_compression_method_list(pdu->u.handshake.
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:
163 						destroy_random(pdu->u.handshake.server_hello->random);
164          octstr_destroy(pdu->u.handshake.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 =
173                 pdu->u.handshake.certificates->certList;
174 
175             for (;;) {
176                cert = gwlist_consume(certList);
177                if (!cert)
178                   break;
179                switch (cert->certificateformat) {
180                         case WTLSCert:
181                   destroy_wtls_certificate(cert->
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             }
197             gwlist_destroy(pdu->u.handshake.certificates->
198                       certList, NULL);
199          }
200 						break;
201 
202                 case server_key_exchange:
203          destroy_param_spec(pdu->u.handshake.
204                   server_key_exchange->param_spec);
205                         switch (client_key_exchange_algo) {
206                         case rsa_anon:
207             destroy_rsa_pubkey(pdu->u.handshake.
208                      server_key_exchange->
209                      rsa_params);
210 								break;
211                         case dh_anon:
212             destroy_dh_pubkey(pdu->u.handshake.
213                     server_key_exchange->
214                     dh_params);
215 								break;
216                         case ecdh_anon:
217             destroy_ec_pubkey(pdu->u.handshake.
218                     server_key_exchange->
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:
230             destroy_rsa_encrypted_secret(pdu->u.handshake.
231                           client_key_exchange->
232                           rsa_params);
233                                 break;
234                         case dh_anon:
235             destroy_dh_pubkey(pdu->u.handshake.
236                     client_key_exchange->
237                     dh_anon_params);
238                                 break;
239                         case ecdh_anon:
240                         case ecdh_ecdsa:
241             destroy_ec_pubkey(pdu->u.handshake.
242                     client_key_exchange->
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:
257 				octstr_destroy(pdu->u.application.data);
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. */
wtls_pack_payloadlist(List * payloadlist,int seqnum)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 */
wtls_unpack_payloadlist(Octstr * data)313 List *wtls_unpack_payloadlist(Octstr * 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 
wtls_payload_guess_length(Octstr * data)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 
wtls_payload_unpack_from_offset(Octstr * data,int * offset)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 
wtls_payload_unpack(Octstr * data)476 wtls_Payload *wtls_payload_unpack(Octstr * data)
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
wtls_pdu_unpack(wtls_Payload * payload,WTLSMachine * wtls_machine)521 wtls_PDU *wtls_pdu_unpack(wtls_Payload * payload, WTLSMachine * wtls_machine)
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));
575          pdu->u.handshake.client_hello->clientversion =
576              octstr_get_char(buffer, charpos);
577          charpos += 1;
578          pdu->u.handshake.client_hello->random =
579              unpack_random(buffer, &charpos);
580          pdu->u.handshake.client_hello->session_id =
581              unpack_octstr(buffer, &charpos);
582 
583          /* Unpack the list of keys */
584          pdu->u.handshake.client_hello->client_key_ids =
585              unpack_key_list(buffer, &charpos);
586          pdu->u.handshake.client_hello->trusted_key_ids =
587              unpack_key_list(buffer, &charpos);
588 
589          /* Unpack the list of CipherSuites */
590          pdu->u.handshake.client_hello->ciphersuites =
591              unpack_ciphersuite_list(buffer, &charpos);
592 
593                         /* CompressionMethods */
594          pdu->u.handshake.client_hello->comp_methods =
595              unpack_compression_method_list(buffer, &charpos);
596 
597          pdu->u.handshake.client_hello->snmode =
598              octstr_get_char(buffer, charpos);
599                         charpos += 1;
600          pdu->u.handshake.client_hello->krefresh =
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));
608          pdu->u.handshake.server_hello->serverversion =
609              octstr_get_char(buffer, charpos);
610          charpos += 1;
611          pdu->u.handshake.server_hello->random =
612              unpack_random(buffer, &charpos);
613          pdu->u.handshake.server_hello->session_id =
614              unpack_octstr(buffer, &charpos);
615          pdu->u.handshake.server_hello->client_key_id =
616              octstr_get_char(buffer, charpos);
617                         charpos += 1;
618                         /* CypherSuite */
619          pdu->u.handshake.server_hello->ciphersuite->
620              bulk_cipher_algo = octstr_get_char(buffer, charpos);
621                         charpos += 1;
622          pdu->u.handshake.server_hello->ciphersuite->mac_algo =
623              octstr_get_char(buffer, charpos);
624                         charpos += 1;
625 
626                         /* CompressionMethod */
627          pdu->u.handshake.server_hello->comp_method =
628              octstr_get_char(buffer, charpos);
629                         charpos += 1;
630 
631          pdu->u.handshake.server_hello->snmode =
632              octstr_get_char(buffer, charpos);
633                         charpos += 1;
634          pdu->u.handshake.server_hello->krefresh =
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 =
655                       unpack_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             }
673             pdu->u.handshake.certificates->certList =
674                 certList;
675          }
676                         break;
677 
678                 case server_key_exchange:
679          pdu->u.handshake.server_key_exchange =
680              (ServerKeyExchange *)
681              gw_malloc(sizeof(ServerKeyExchange));
682          /* unpack the ParameterSpecifier  and ParameterSet */
683          pdu->u.handshake.server_key_exchange->param_spec =
684              unpack_param_spec(buffer, &charpos);
685                         switch (client_key_exchange_algo) {
686                         case rsa_anon:
687             pdu->u.handshake.server_key_exchange->
688                 rsa_params =
689                 unpack_rsa_pubkey(buffer, &charpos);
690                                 break;
691 
692                         case dh_anon:
693             pdu->u.handshake.server_key_exchange->
694                 dh_params =
695                 unpack_dh_pubkey(buffer, &charpos);
696                                 break;
697 
698                         case ecdh_anon:
699             pdu->u.handshake.server_key_exchange->
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:
710          pdu->u.handshake.client_key_exchange =
711              (ClientKeyExchange *)
712              gw_malloc(sizeof(ClientKeyExchange));
713                         switch (client_key_exchange_algo) {
714                         case rsa:
715                         case rsa_anon:
716             pdu->u.handshake.client_key_exchange->
717                 rsa_params =
718                 unpack_rsa_encrypted_secret(buffer,
719                         &charpos);
720                                 break;
721 
722                         case dh_anon:
723             pdu->u.handshake.client_key_exchange->
724                 dh_anon_params =
725                 unpack_dh_pubkey(buffer, &charpos);
726                                 break;
727 
728                         case ecdh_anon:
729                         case ecdh_ecdsa:
730             pdu->u.handshake.client_key_exchange->
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));
747          pdu->u.handshake.finished->verify_data =
748              unpack_octstr_fixed(buffer, &charpos, 12);
749 						octstr_dump(pdu->u.handshake.finished->verify_data, 0);
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 
wtls_payload_pack(wtls_Payload * payload,int seqnum)773 Octstr *wtls_payload_pack(wtls_Payload * payload, int seqnum)
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 
wtls_pdu_pack(wtls_PDU * pdu,WTLSMachine * wtls_machine)816 wtls_Payload *wtls_pdu_pack(wtls_PDU * pdu, WTLSMachine * wtls_machine)
817 {
818    Octstr *buffer, *encryptedbuffer;
819         wtls_Payload *payload;
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,
868                pdu->u.handshake.client_hello->random);
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,
911                pdu->u.handshake.server_hello->random);
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.
918                   server_hello->client_key_id);
919                         charpos += 1;
920                         /* CypherSuite */
921          octstr_append_char(buffer,
922                   pdu->u.handshake.
923                   server_hello->ciphersuite->
924                   bulk_cipher_algo);
925          charpos += 1;
926          octstr_append_char(buffer,
927                   pdu->u.handshake.
928                   server_hello->ciphersuite->mac_algo);
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 =
955                    gwlist_consume(pdu->u.handshake.
956                         certificates->
957                         certList);
958                if (!cert)
959                   break;
960                octstr_append_char(buffer,
961                         cert->
962                         certificateformat);
963                         charpos += 1;
964                switch (cert->certificateformat) {
965                         case WTLSCert:
966                   charpos =
967                       pack_wtls_certificate
968                       (buffer, charpos,
969                        cert->wtls_certificate);
970                   destroy_wtls_certificate(cert->
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.
1008                    server_key_exchange->param_spec);
1009 
1010                         switch (client_key_exchange_algo) {
1011                         case rsa_anon:
1012             charpos =
1013                 pack_rsa_pubkey(buffer, charpos,
1014                       pdu->u.handshake.
1015                       server_key_exchange->
1016                       rsa_params);
1017                                 break;
1018                         case dh_anon:
1019             charpos =
1020                 pack_dh_pubkey(buffer, charpos,
1021                      pdu->u.handshake.
1022                      server_key_exchange->
1023                      dh_params);
1024                                 break;
1025                         case ecdh_anon:
1026             charpos =
1027                 pack_ec_pubkey(buffer, charpos,
1028                      pdu->u.handshake.
1029                      server_key_exchange->
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.
1043                            client_key_exchange->
1044                            rsa_params);
1045                                 break;
1046                         case dh_anon:
1047             charpos =
1048                 pack_dh_pubkey(buffer, charpos,
1049                      pdu->u.handshake.
1050                      client_key_exchange->
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.
1058                      client_key_exchange->
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)");
1075          octstr_dump(pdu->u.handshake.finished->verify_data, 0);
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 
wtls_payload_dump(wtls_Payload * payload,int level)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 
wtls_pdu_dump(wtls_PDU * pdu,int level)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, "",
1204                pdu->u.handshake.client_hello->clientversion);
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, "");
1209          octstr_dump(pdu->u.handshake.client_hello->session_id,
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, "",
1235                pdu->u.handshake.client_hello->krefresh);
1236 			break;
1237 
1238 		case server_hello:
1239          debug(dbg, 0, "%*sServerHello:", level, "");
1240          debug(dbg, 0, "%*sServer version: %d", level + 1, "",
1241                pdu->u.handshake.server_hello->serverversion);
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, "",
1246                octstr_get_cstr(pdu->u.handshake.
1247                      server_hello->session_id));
1248          debug(dbg, 0, "%*sClient Key ID: %d", level + 1, "",
1249                pdu->u.handshake.server_hello->client_key_id);
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, "",
1255                pdu->u.handshake.server_hello->ciphersuite->
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, "",
1263                pdu->u.handshake.server_hello->krefresh);
1264 			break;
1265 
1266 		case certificate:
1267          debug(dbg, 0, "%*sCertificate:", level, "");
1268          {
1269             Certificate *cert;
1270             List *certList =
1271                 pdu->u.handshake.certificates->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, "");
1286                   dump_wtls_certificate(dbg,
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, "",
1318                pdu->u.handshake.server_key_exchange->
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                   "",
1325                   pdu->u.handshake.server_key_exchange->
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.
1332                   server_key_exchange->
1333                   rsa_params);
1334 				break;
1335 
1336 			case dh_anon:
1337             dump_dh_pubkey(dbg, level + 1,
1338                       pdu->u.handshake.
1339                       server_key_exchange->dh_params);
1340 				break;
1341 
1342 			case ecdh_anon:
1343             dump_ec_pubkey(dbg, level + 1,
1344                       pdu->u.handshake.
1345                       server_key_exchange->
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.
1361                        client_key_exchange->
1362                        rsa_params);
1363 				break;
1364 
1365 			case dh_anon:
1366             dump_dh_pubkey(dbg, level + 1,
1367                       pdu->u.handshake.
1368                       client_key_exchange->
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.
1376                       client_key_exchange->
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, "");
1393          octstr_dump(pdu->u.handshake.finished->verify_data,
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 */
1414