Example #1
0
	void response_base< Timer >::handle_handshake( const json::object& request, const std::string& connection_name )
	{
        json::string error_txt;
		session_ = connector_.handshake( connection_name, request.find( ext_field_token ), error_txt );

		if ( session_ )
		{
	        static const json::object response_prototype = json::parse_single_quoted(
	            "{"
	            "   'channel':'/meta/handshake',"
	            "   'version':'1.0',"
	            "   'supportedConnectionTypes':['long-polling'],"
	            "   'successful':true"
	            "}" ).upcast< json::object >();

	        json::object response = add_session_id( response_prototype, *session_ );
            copy_id_field( request, response );

            bayeux_response_.add( response );
		}
		else
		{
	        static const json::object response_prototype = json::parse_single_quoted(
	            "{"
	            "   'channel':'/meta/handshake',"
	            "   'successful':false"
	            "}" ).upcast< json::object >();

            json::object response = response_prototype.copy().add( error_field_token, error_txt );
            copy_id_field( request, response );

            bayeux_response_.add( response );
		}
	}
Example #2
0
    json::object response_base< Timer >::build_connect_response( const json::object& request, const json::string& session_id )
    {
        static const json::object reponse_prototype = json::parse_single_quoted(
            "{"
            "   'channel'    : '/meta/connect',"
            "   'successful' : true"
            "}" ).upcast< json::object >();

        json::object response = add_session_id( reponse_prototype, session_id );
        copy_id_field( request, response );

        return response;
    }
Example #3
0
    void response_base< Timer >::handle_disconnect( const json::object& request )
    {
        static const json::object response_prototype = json::parse_single_quoted(
            "{"
            "   'channel':'/meta/disconnect',"
            "   'successful':true"
            "}" ).upcast< json::object >();

        json::object response = add_session_id( response_prototype, *session_ );
        copy_id_field( request, response );

        bayeux_response_.add( response );
    }
Example #4
0
    bool response_base< Timer >::check_connection_type( const json::object& request, const json::string& session_id )
	{
	    const json::value* const type = request.find( connection_typen_token );

	    const bool result = type != 0 && *type == json::string( "long-polling" );

	    if ( !result )
	    {
	        static const json::object response_template = json::parse_single_quoted(
                "{"
                "   'channel'    : '/meta/connect',"
                "   'successful' : false,"
                "   'error'      : 'unsupported connection type'"
                "}" ).upcast< json::object >();

	        json::object response = add_session_id( response_template, session_id );
	        copy_id_field( request, response );

	        bayeux_response_.add( response );
	    }

	    return result;
	}
Example #5
0
File: rf.cpp Project: rkday/ralf
// Create an ACR message from a JSON descriptor.  Most AVPs are auto-created from the
// contents parameter which should be a JSON object with keys named after AVPs.  For example
// this object could be the "event" part of the original HTTP request received by Ralf.
AccountingRequest::AccountingRequest(const Dictionary* dict,
                                     Diameter::Stack* diameter_stack,
                                     const std::string& session_id,
                                     const std::string& dest_host,
                                     const std::string& dest_realm,
                                     const uint32_t& record_number,
                                     const rapidjson::Value& contents) :
  Diameter::Message(dict, dict->ACCOUNTING_REQUEST, diameter_stack)
{
  LOG_DEBUG("Building an Accounting-Request");

  // Fill in the default fields
  if (session_id == "")
  {
    add_new_session_id();
  }
  else
  {
    add_session_id(session_id);
  }
  add_origin();
  add_app_id(Dictionary::Application::ACCT, dict->RF);

  // Fill in contributed fields
  Diameter::Dictionary::AVP dest_host_dict("Destination-Host");
  Diameter::AVP dest_host_avp(dest_host_dict);
  add(dest_host_avp.val_str(dest_host));

  Diameter::Dictionary::AVP dest_realm_dict("Destination-Realm");
  Diameter::AVP dest_realm_avp(dest_realm_dict);
  add(dest_realm_avp.val_str(dest_realm));

  Diameter::Dictionary::AVP record_number_dict("Accounting-Record-Number");
  Diameter::AVP record_number_avp(record_number_dict);
  add(record_number_avp.val_i32(record_number));

  if (contents.GetType() != rapidjson::kObjectType)
  {
    LOG_ERROR("Cannot build ACR from JSON type %d", contents.GetType());
    return;
  }

  // Fill in the dynamic fields
  for (rapidjson::Value::ConstMemberIterator it = contents.MemberBegin();
       it != contents.MemberEnd();
       ++it)
  {
    try
    {
      switch (it->value.GetType())
      {
      case rapidjson::kFalseType:
      case rapidjson::kTrueType:
      case rapidjson::kNullType:
        LOG_ERROR("Invalid format (true/false) in JSON block, ignoring");
        continue;
      case rapidjson::kStringType:
      case rapidjson::kNumberType:
      case rapidjson::kObjectType:
        {
          Diameter::Dictionary::AVP new_dict(VENDORS, it->name.GetString());
          Diameter::AVP avp(new_dict);
          add(avp.val_json(VENDORS, new_dict, it->value));
        }
        break;
      case rapidjson::kArrayType:
        for (rapidjson::Value::ConstValueIterator array_iter = it->value.Begin();
             array_iter !=  it->value.End();
             ++array_iter)
        {
          Diameter::Dictionary::AVP new_dict(VENDORS, it->name.GetString());
          Diameter::AVP avp(new_dict);
          add(avp.val_json(VENDORS, new_dict, *array_iter));
        }
        break;
      }
    }
    catch (Diameter::Stack::Exception e)
    {
      LOG_WARNING("AVP %s not recognised, ignoring", it->name.GetString());
    }
  }
}
Example #6
0
	json::object response_base< Timer >::add_session_id( const json::object& response, const session& session_id )
	{
		return add_session_id( response, session_id.session_id() );
	}
Example #7
0
static void
dissect_wtls_handshake(proto_tree *tree, tvbuff_t *tvb, guint offset, guint count)
{
	char pdu_msg_type;
	nstime_t timeValue;
	int client_size = 0;
	guint value = 0;
	int size = 0;
	guint public_key = 0;
	char valStr[1024];
	const char *valBulk = NULL;
	const char *valMac = NULL;

	proto_item *ti;
	proto_item *cli_key_item;
	proto_tree *wtls_msg_type_tree;
	proto_tree *wtls_msg_type_item_tree;
	proto_tree *wtls_msg_type_item_sub_tree;
	proto_tree *wtls_msg_type_item_sub_sub_tree;

	pdu_msg_type = tvb_get_guint8 (tvb, offset);
	ti = proto_tree_add_uint(tree, hf_wtls_hands, tvb, offset,count, pdu_msg_type);
	wtls_msg_type_tree = proto_item_add_subtree(ti, ett_wtls_msg_type);

	proto_tree_add_item (wtls_msg_type_tree, hf_wtls_hands_type,
			tvb,offset,1,ENC_BIG_ENDIAN);
	offset+=1;
	count = tvb_get_ntohs (tvb, offset);
	proto_tree_add_item (wtls_msg_type_tree, hf_wtls_hands_length,
			tvb,offset,2,ENC_BIG_ENDIAN);
	offset+=2;
	switch(pdu_msg_type) {
		case WTLS_HANDSHAKE_CLIENT_HELLO :
			ti = proto_tree_add_item(wtls_msg_type_tree, hf_wtls_hands_cli_hello, tvb, offset,
					 count, ENC_NA);
			wtls_msg_type_item_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item);
			proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_version,
					tvb,offset,1,ENC_BIG_ENDIAN);
			offset++;
			timeValue.secs = tvb_get_ntohl (tvb, offset);
			timeValue.nsecs = 0;
			proto_tree_add_time (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_gmt, tvb,
					offset, 4, &timeValue);
			offset+=4;
			proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_random,
					tvb,offset,12,ENC_NA);
			offset+=12;
			offset = add_session_id (wtls_msg_type_item_tree,
			    hf_wtls_hands_cli_hello_session,
			    hf_wtls_hands_cli_hello_session_str,
			    tvb, offset);

			/* process client_key_ids structure */
			count = tvb_get_ntohs (tvb, offset);
			ti = proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_cli_hello_cli_key_id, tvb, offset,
					 count+2, ENC_NA);
			wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub);

			/* display length of client_key_ids structure */
			proto_tree_add_item(wtls_msg_type_item_sub_tree,
					hf_wtls_hands_cli_hello_cli_key_len,
					tvb,offset,2,ENC_BIG_ENDIAN);
			offset+=2;

			/* cycle through client_key_ids entries */
			for (;count > 0;count-=client_size) {
				/* get encryption suite id (one byte) */
				value = tvb_get_guint8 (tvb, offset);
				cli_key_item = proto_tree_add_uint(wtls_msg_type_item_sub_tree,
						hf_wtls_hands_cli_hello_key_exchange, tvb, offset,1,
						value);
				client_size=1;
				wtls_msg_type_item_sub_sub_tree = proto_item_add_subtree(cli_key_item,
								  ett_wtls_msg_type_item_sub_sub);
				proto_tree_add_uint(wtls_msg_type_item_sub_sub_tree,
						hf_wtls_hands_cli_hello_key_exchange_suite,
						tvb,offset,1,value);
				offset++;
#ifdef DEBUG
				fprintf(stderr, "encryption suite = %d, client_size = %d\n", value, client_size);
#endif /* DEBUG */

				/* get parameter index (one byte) */
				value = tvb_get_guint8 (tvb, offset);
				proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
					hf_wtls_hands_cli_hello_key_parameter_index,
					tvb,offset,1,ENC_BIG_ENDIAN);
				offset++;
				client_size++;
#ifdef DEBUG
				fprintf(stderr, "parameter index = %d, client_size = %d\n", value, client_size);
#endif /* DEBUG */

				/* explicit parameters present in next field */
				if (value == 0xff) {
					size = tvb_get_ntohs (tvb, offset);
					proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
						hf_wtls_hands_cli_hello_key_parameter_set,
						tvb,offset,size+2,ENC_ASCII|ENC_NA);
					offset+=size+2;
					client_size+=size+2;
				}

				/* get identifier type */
				value = tvb_get_guint8 (tvb, offset);
				proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
						hf_wtls_hands_cli_hello_key_identifier_type,
						tvb,offset,1,ENC_BIG_ENDIAN);
				offset++;
				client_size++;
#ifdef DEBUG
				fprintf(stderr, "identifier type = %d, client_size = %d\n", value, client_size);
#endif /* DEBUG */

				/* identifier present in next field */
				/* note: value 0x0 means no identifier */
				switch(value) {
					case IDENTIFIER_TEXT :
						/* text identifier */
						/* not tested */
						size = add_text_identifier(
							tvb, offset,
							hf_wtls_hands_cli_hello_key_identifier_charset,
							hf_wtls_hands_cli_hello_key_identifier_size,
							hf_wtls_hands_cli_hello_key_identifier_str,
							wtls_msg_type_item_sub_sub_tree);
						offset += size;
						client_size += size;
						break;
					case IDENTIFIER_BIN :
						/* binary identifier */
						size = tvb_get_guint8 (tvb, offset);
						proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
								hf_wtls_hands_cli_hello_key_identifier_size,
								tvb,offset,1,ENC_BIG_ENDIAN);
						offset++;
						proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
								hf_wtls_hands_cli_hello_key_identifier,
								tvb,offset,size,ENC_NA);
						offset+=size;
						client_size+=size+1;
#ifdef DEBUG
						fprintf(stderr, "binary id size = %d, client_size = %d\n",
							size, client_size);
#endif /* DEBUG */
						break;
					case IDENTIFIER_SHA_1 :
						/* SHA-1 hash of the public key */
						proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
								hf_wtls_hands_cli_hello_key_identifier,
								tvb,offset,20,ENC_NA);
						offset+=20;
						client_size+=20;
#ifdef DEBUG
						fprintf(stderr, "SHA-1 hash size = 20, client_size = %d\n",
							client_size);
#endif /* DEBUG */
						break;
					case IDENTIFIER_X509 :
						/* X.509 distinguished name */
						/* not tested */
						size = tvb_get_guint8 (tvb, offset);
						proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
								hf_wtls_hands_cli_hello_key_identifier_size,
								tvb,offset,1,ENC_BIG_ENDIAN);
						offset++;
						proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
								hf_wtls_hands_cli_hello_key_identifier,
								tvb,offset,size,ENC_NA);
						offset+=size;
						client_size+=size+1;
#ifdef DEBUG
						fprintf(stderr, "X.509 name size = %d, client_size = %d\n",
							size, client_size);
#endif /* DEBUG */
						break;
				}

				proto_item_set_len(cli_key_item, client_size);
			}

			/* process trusted_keys structure */
			count = tvb_get_ntohs (tvb, offset);
			ti = proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_cli_hello_trust_key_id, tvb, offset,
					 count+2, ENC_NA);
			wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub);

			/* display length of trusted_keys structure */
			proto_tree_add_item(wtls_msg_type_item_sub_tree,
					hf_wtls_hands_cli_hello_cli_key_len,
					tvb,offset,2,ENC_BIG_ENDIAN);

			offset+=2;
			for (;count > 0;count-=client_size) {
				/* get encryption suite id (one byte) */
				value = tvb_get_guint8 (tvb, offset);
				cli_key_item = proto_tree_add_uint(wtls_msg_type_item_sub_tree,
						hf_wtls_hands_cli_hello_key_exchange, tvb, offset,1,
						value);
				client_size=1;
				wtls_msg_type_item_sub_sub_tree = proto_item_add_subtree(cli_key_item,
								  ett_wtls_msg_type_item_sub_sub);
				proto_tree_add_uint(wtls_msg_type_item_sub_sub_tree,
						hf_wtls_hands_cli_hello_key_exchange_suite,
						tvb,offset,1,value);
				offset++;
#ifdef DEBUG
				fprintf(stderr, "encryption suite = %d, client_size = %d\n", value, client_size);
#endif /* DEBUG */

				/* get parameter index (one byte) */
				value = tvb_get_guint8 (tvb, offset);
				proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
					hf_wtls_hands_cli_hello_key_parameter_index,
					tvb,offset,1,ENC_BIG_ENDIAN);
				offset++;
				client_size++;
#ifdef DEBUG
				fprintf(stderr, "parameter index = %d, client_size = %d\n", value, client_size);
#endif /* DEBUG */

				/* explicit parameters present in next field */
				if (value == 0xff) {
					size = tvb_get_ntohs (tvb, offset);
					proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
						hf_wtls_hands_cli_hello_key_parameter_set,
						tvb,offset,size+2,ENC_ASCII|ENC_NA);
					offset+=size+2;
					client_size+=size+2;
				}

				/* get identifier type */
				value = tvb_get_guint8 (tvb, offset);
				proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
						hf_wtls_hands_cli_hello_key_identifier_type,
						tvb,offset,1,ENC_BIG_ENDIAN);
				offset++;
				client_size++;
#ifdef DEBUG
				fprintf(stderr, "identifier type = %d, client_size = %d\n", value, client_size);
#endif /* DEBUG */

				/* identifier present in next field */
				/* note: value 0x0 means no identifier */
				switch (value) {
					case IDENTIFIER_TEXT :
						/* text identifier */
						/* not tested */
						size = add_text_identifier(
							tvb, offset,
							hf_wtls_hands_cli_hello_key_identifier_charset,
							hf_wtls_hands_cli_hello_key_identifier_size,
							hf_wtls_hands_cli_hello_key_identifier_str,
							wtls_msg_type_item_sub_sub_tree);
						offset += size;
						client_size += size;
						break;
					case IDENTIFIER_BIN :
						/* binary identifier */
						size = tvb_get_guint8 (tvb, offset);
						proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
								hf_wtls_hands_cli_hello_key_identifier_size,
								tvb,offset,1,ENC_BIG_ENDIAN);
						offset++;
						proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
								hf_wtls_hands_cli_hello_key_identifier,
								tvb,offset,size,ENC_NA);
						offset+=size;
						client_size+=size+1;
#ifdef DEBUG
						fprintf(stderr, "binary id size = %d, client_size = %d\n",
							size, client_size);
#endif /* DEBUG */
						break;
					case IDENTIFIER_SHA_1 :
						/* SHA-1 hash of the public key */
						proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
								hf_wtls_hands_cli_hello_key_identifier,
								tvb,offset,20,ENC_NA);
						offset+=20;
						client_size+=20;
#ifdef DEBUG
						fprintf(stderr, "SHA-1 hash size = 20, client_size = %d\n",
							client_size);
#endif /* DEBUG */
						break;
					case IDENTIFIER_X509 :
					 	/* X.509 distinguished name */
						/* not tested */
						size = tvb_get_guint8 (tvb, offset);
						/* need to fetch identifier and display it */
						proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
								hf_wtls_hands_cli_hello_key_identifier_size,
								tvb,offset,1,ENC_BIG_ENDIAN);
						offset++;
						proto_tree_add_item(wtls_msg_type_item_sub_sub_tree,
								hf_wtls_hands_cli_hello_key_identifier,
								tvb,offset,size,ENC_NA);
						offset+=size;
						client_size+=size+1;
#ifdef DEBUG
						fprintf(stderr, "X.509 name size = %d, client_size = %d\n",
							size, client_size);
#endif /* DEBUG */
						break;
				}
				proto_item_set_len(cli_key_item, client_size);
			}

			/* process cipher_suites structure */
			count = tvb_get_guint8 (tvb, offset);
			ti = proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_cli_hello_cipher_suite, tvb, offset,
					 count+1, ENC_NA);
			wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub);
			offset+=1;
			for (;count > 0;count-=client_size) {
			       value = tvb_get_guint8 (tvb, offset);
			       valBulk = try_val_to_str_ext(value, &wtls_vals_cipher_bulk_ext);
			       offset++;
			       client_size=1;
			       valMac = try_val_to_str_ext(tvb_get_guint8 (tvb, offset), &wtls_vals_cipher_mac_ext);
			       if (valBulk != NULL)
			       {
				       if (valMac != NULL)
				       {
					       g_snprintf(valStr,1024,"%s, %s",valBulk,valMac);
				       }
				       else
				       {
					       g_snprintf(valStr,1024,"%s, Unknown MAC (0x%02x)",valBulk,tvb_get_guint8 (tvb, offset));
				       }
			       }
			       else
			       {
				       if (valMac != NULL)
				       {
					       g_snprintf(valStr,1024,"Unknown Bulk (0x%02x), %s",value,valMac);
				       }
				       else
				       {
					       g_snprintf(valStr,1024,"Unknown Bulk (0x%02x), Unknown MAC (0x%02x)",value,
							       tvb_get_guint8 (tvb, offset));
				       }
				}
				offset++;
				client_size++;
				proto_tree_add_string(wtls_msg_type_item_sub_tree,
						      hf_wtls_hands_cli_hello_cipher_suite_item, tvb, offset-2,2,
						      valStr);
			}
			count = tvb_get_guint8 (tvb, offset);
			ti = proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_cli_hello_compression_methods, tvb, offset,
					 count+1, ENC_NA);
			wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub);
			offset+=1;
			for (;count > 0;count-=client_size) {
				client_size=0;
				proto_tree_add_item(wtls_msg_type_item_sub_tree,
						hf_wtls_hands_cli_hello_compression, tvb, offset,1,
						ENC_LITTLE_ENDIAN);
				offset++;
				client_size++;
			}
			proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_cli_hello_sequence_mode, tvb, offset,
					 1, ENC_LITTLE_ENDIAN);
			offset++;
			proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_cli_hello_key_refresh, tvb, offset,
					 1, ENC_LITTLE_ENDIAN);
			break;
		case WTLS_HANDSHAKE_SERVER_HELLO :
			ti = proto_tree_add_item(wtls_msg_type_tree, hf_wtls_hands_serv_hello, tvb, offset,
					 count, ENC_NA);
			wtls_msg_type_item_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item);
			proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_version,
					tvb,offset,1,ENC_BIG_ENDIAN);
			offset++;
			timeValue.secs = tvb_get_ntohl (tvb, offset);
			timeValue.nsecs = 0;
			proto_tree_add_time (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_gmt, tvb,
					offset, 4, &timeValue);
			offset+=4;
			proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_random,
					tvb,offset,12,ENC_NA);
			offset+=12;
			offset = add_session_id (wtls_msg_type_item_tree,
			    hf_wtls_hands_serv_hello_session,
			    hf_wtls_hands_serv_hello_session_str,
			    tvb, offset);
			proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_serv_hello_cli_key_id,
					tvb,offset,1,ENC_BIG_ENDIAN);
			offset++;
			cli_key_item = proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_serv_hello_cipher_suite_item, tvb, offset,2,
					ENC_NA);
			wtls_msg_type_item_sub_tree = proto_item_add_subtree(cli_key_item,
							  ett_wtls_msg_type_item_sub);
			proto_tree_add_item(wtls_msg_type_item_sub_tree,
					hf_wtls_hands_serv_hello_cipher_bulk,
					tvb,offset,1,ENC_BIG_ENDIAN);
			offset++;
			proto_tree_add_item(wtls_msg_type_item_sub_tree,
				hf_wtls_hands_serv_hello_cipher_mac,
				tvb,offset,1,ENC_BIG_ENDIAN);
			offset++;
			proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_serv_hello_compression, tvb, offset,1,
					ENC_LITTLE_ENDIAN);
			offset++;
			proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_serv_hello_sequence_mode, tvb, offset,
					 1, ENC_LITTLE_ENDIAN);
			offset++;
			proto_tree_add_item(wtls_msg_type_item_tree,
					hf_wtls_hands_serv_hello_key_refresh, tvb, offset,
					 1, ENC_LITTLE_ENDIAN);
			offset++;
			break;
		case WTLS_HANDSHAKE_CERTIFICATE :
			ti = proto_tree_add_item(wtls_msg_type_tree, hf_wtls_hands_certificates,
					tvb, offset,count, ENC_NA);
			wtls_msg_type_item_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item);
			count = tvb_get_ntohs (tvb, offset);
			offset+=2;
			for (;count > 0;count-=client_size) {
				cli_key_item = proto_tree_add_item(wtls_msg_type_item_tree,
						hf_wtls_hands_certificate, tvb, offset,1,
						ENC_NA);
				client_size=0;
				wtls_msg_type_item_sub_tree = proto_item_add_subtree(cli_key_item,
								  ett_wtls_msg_type_item_sub);
				proto_item_set_len(cli_key_item, client_size);
				value =  tvb_get_guint8 (tvb, offset);
				proto_tree_add_item(wtls_msg_type_item_sub_tree,
						hf_wtls_hands_certificate_type, tvb, offset,1,
						ENC_LITTLE_ENDIAN);
				offset++;
				client_size++;
				switch(value) {
					case CERTIFICATE_WTLS:
						proto_tree_add_item(wtls_msg_type_item_sub_tree,
							hf_wtls_hands_certificate_wtls_version,
							tvb, offset,1,
							ENC_LITTLE_ENDIAN);
						offset++;
						client_size++;
						proto_tree_add_item(wtls_msg_type_item_sub_tree,
							hf_wtls_hands_certificate_wtls_signature_type,
							tvb, offset,1,
							ENC_LITTLE_ENDIAN);
						offset++;
						client_size++;
						value =  tvb_get_guint8 (tvb, offset);
						proto_tree_add_item(wtls_msg_type_item_sub_tree,
							hf_wtls_hands_certificate_wtls_issuer_type,
							tvb, offset,1,
							ENC_LITTLE_ENDIAN);
						offset++;
						client_size++;
						switch (value) {
							case IDENTIFIER_NULL :
								break;
							case IDENTIFIER_TEXT :
								value = add_text_identifier(tvb, offset,
									hf_wtls_hands_certificate_wtls_issuer_charset,
									hf_wtls_hands_certificate_wtls_issuer_size,
									hf_wtls_hands_certificate_wtls_issuer_name,
									wtls_msg_type_item_sub_tree);
								offset += value;
								client_size += value;
								break;
							case IDENTIFIER_BIN :
								break;
							case IDENTIFIER_SHA_1 :
								break;
							case IDENTIFIER_X509 :
								break;
						}
						timeValue.secs = tvb_get_ntohl (tvb, offset);
						timeValue.nsecs = 0;
						proto_tree_add_time (wtls_msg_type_item_sub_tree,
								hf_wtls_hands_certificate_wtls_valid_not_before,
								tvb, offset, 4, &timeValue);
						offset+=4;
						client_size+=4;
						timeValue.secs = tvb_get_ntohl (tvb, offset);
						timeValue.nsecs = 0;
						proto_tree_add_time (wtls_msg_type_item_sub_tree,
								hf_wtls_hands_certificate_wtls_valid_not_after,
								tvb, offset, 4, &timeValue);
						offset+=4;
						client_size+=4;
						value =  tvb_get_guint8 (tvb, offset);
						proto_tree_add_item(wtls_msg_type_item_sub_tree,
							hf_wtls_hands_certificate_wtls_subject_type,
							tvb, offset,1,
							ENC_LITTLE_ENDIAN);
						offset++;
						client_size++;
						switch (value) {
							case IDENTIFIER_NULL :
								break;
							case IDENTIFIER_TEXT :
								value = add_text_identifier(tvb, offset,
									hf_wtls_hands_certificate_wtls_subject_charset,
									hf_wtls_hands_certificate_wtls_subject_size,
									hf_wtls_hands_certificate_wtls_subject_name,
									wtls_msg_type_item_sub_tree);
								offset += value;
								client_size += value;
								break;
							case IDENTIFIER_BIN :
								break;
							case IDENTIFIER_SHA_1 :
								break;
							case IDENTIFIER_X509 :
								break;
						}
						public_key =  tvb_get_guint8 (tvb, offset);
						proto_tree_add_item(wtls_msg_type_item_sub_tree,
							hf_wtls_hands_certificate_wtls_public_key_type,
							tvb, offset,1,
							ENC_LITTLE_ENDIAN);
						offset++;
						client_size++;
						value = tvb_get_guint8 (tvb, offset);
						proto_tree_add_item(wtls_msg_type_item_sub_tree,
							hf_wtls_hands_certificate_wtls_key_parameter_index,
							tvb,offset,1,ENC_BIG_ENDIAN);
						offset++;
						client_size++;
						if (value == 0xff) {
							size = tvb_get_ntohs (tvb, offset);
							proto_tree_add_item(wtls_msg_type_item_sub_tree,
								hf_wtls_hands_certificate_wtls_key_parameter_set,
								tvb,offset,size+2,ENC_ASCII|ENC_NA);
							offset+=size+2;
							client_size+=size+2;
						}
						switch (public_key) {
							case PUBLIC_KEY_RSA :
								value = tvb_get_ntohs (tvb, offset);
								proto_tree_add_uint(wtls_msg_type_item_sub_tree,
									hf_wtls_hands_certificate_wtls_rsa_exponent,
									tvb,offset,value+2,value*8);
								offset+=2+value;
								client_size+=2+value;
								value = tvb_get_ntohs (tvb, offset);
								proto_tree_add_uint(wtls_msg_type_item_sub_tree,
									hf_wtls_hands_certificate_wtls_rsa_modules,
									tvb,offset,value+2,value*8);
								offset+=2+value;
								client_size+=2+value;
								break;
							case PUBLIC_KEY_ECDH :
								break;
							case PUBLIC_KEY_ECDSA :
								break;
						}
						value = tvb_get_ntohs (tvb, offset);
						proto_tree_add_uint(wtls_msg_type_item_sub_tree,
							hf_wtls_hands_certificate_wtls_signature,
							tvb,offset,2+value,value*8);
						offset+=2+value;
						client_size+=2+value;
						break;
					case CERTIFICATE_X509:
					case CERTIFICATE_X968:
						value =  tvb_get_ntohs (tvb, offset);
						offset+=2;
						client_size+=2;
						client_size += value;
						offset += value;
						break;
					case CERTIFICATE_URL:
						value =  tvb_get_guint8 (tvb, offset);
						offset++;
						client_size++;
						client_size += value;
						offset += value;
						break;
				}
				proto_item_set_len(cli_key_item, client_size);
			}
			break;
		default:
			/*offset+=count;*/
			break;
	}
}