File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libpttls / pt_tls.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 09:46:44 2020 UTC (4 years, 1 month ago) by misho
Branches: strongswan, MAIN
CVS tags: v5_9_2p0, v5_8_4p7, HEAD
Strongswan

    1: /*
    2:  * Copyright (C) 2012 Martin Willi
    3:  * Copyright (C) 2012 revosec AG
    4:  *
    5:  * This program is free software; you can redistribute it and/or modify it
    6:  * under the terms of the GNU General Public License as published by the
    7:  * Free Software Foundation; either version 2 of the License, or (at your
    8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
    9:  *
   10:  * This program is distributed in the hope that it will be useful, but
   11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13:  * for more details.
   14:  */
   15: 
   16: #include "pt_tls.h"
   17: 
   18: #include <utils/debug.h>
   19: #include <pen/pen.h>
   20: 
   21: /**
   22:  * Described in header.
   23:  */
   24: void libpttls_init(void)
   25: {
   26: 	/* empty */
   27: }
   28: 
   29: /*
   30:  * PT-TNC Message format:
   31:  *                       1                   2                   3
   32:  *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   33:  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   34:  *  |    Reserved   |           Message Type Vendor ID              |
   35:  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   36:  *  |                          Message Type                         |
   37:  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   38:  *  |                         Message Length                        |
   39:  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   40:  *  |                       Message Identifier                      |
   41:  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   42:  *  |                Message Value (e.g. PB-TNC Batch) . . .        |
   43:  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   44:  */
   45: 
   46: ENUM(pt_tls_message_type_names, PT_TLS_EXPERIMENTAL, PT_TLS_ERROR,
   47: 	"Experimental",
   48: 	"Version Request",
   49: 	"Version Response",
   50: 	"SASL Mechanisms",
   51: 	"SASL Mechanism Selection",
   52: 	"SASL Authentication Data",
   53: 	"SASL Result",
   54: 	"PB-TNC Batch",
   55: 	"PT-TLS Error"
   56: );
   57: 
   58: ENUM(pt_tls_sasl_result_names, PT_TLS_SASL_RESULT_SUCCESS,
   59: 							   PT_TLS_SASL_RESULT_MECH_FAILURE,
   60: 	"Success",
   61: 	"Failure",
   62: 	"Abort",
   63: 	"Mechanism Failure"
   64: );
   65: 
   66: /**
   67:  * Read a chunk of data from TLS, returning a reader for it
   68:  */
   69: static bio_reader_t* read_tls(tls_socket_t *tls, size_t len)
   70: {
   71: 	ssize_t got, total = 0;
   72: 	char *buf;
   73: 
   74: 	buf = malloc(len);
   75: 	while (total < len)
   76: 	{
   77: 		got = tls->read(tls, buf + total, len - total, TRUE);
   78: 		if (got <= 0)
   79: 		{
   80: 			free(buf);
   81: 			return NULL;
   82: 		}
   83: 		total += got;
   84: 	}
   85: 	return bio_reader_create_own(chunk_create(buf, len));
   86: }
   87: 
   88: /**
   89:  * Read a PT-TLS message, return header data
   90:  */
   91: bio_reader_t* pt_tls_read(tls_socket_t *tls, uint32_t *vendor,
   92: 						  uint32_t *type, uint32_t *identifier)
   93: {
   94: 	bio_reader_t *reader;
   95: 	uint32_t len;
   96: 	uint8_t reserved;
   97: 
   98: 	reader = read_tls(tls, PT_TLS_HEADER_LEN);
   99: 	if (!reader)
  100: 	{
  101: 		return NULL;
  102: 	}
  103: 	if (!reader->read_uint8(reader, &reserved) ||
  104: 		!reader->read_uint24(reader, vendor) ||
  105: 		!reader->read_uint32(reader, type) ||
  106: 		!reader->read_uint32(reader, &len) ||
  107: 		!reader->read_uint32(reader, identifier))
  108: 	{
  109: 		reader->destroy(reader);
  110: 		return NULL;
  111: 	}
  112: 	reader->destroy(reader);
  113: 
  114: 	if (len < PT_TLS_HEADER_LEN)
  115: 	{
  116: 		DBG1(DBG_TNC, "received short PT-TLS header (%d bytes)", len);
  117: 		return NULL;
  118: 	}
  119: 
  120: 	if (*vendor == PEN_IETF)
  121: 	{
  122: 		DBG2(DBG_TNC, "received PT-TLS message #%d of type '%N' (%d bytes)",
  123: 					  *identifier, pt_tls_message_type_names, *type, len);
  124: 	}
  125: 	else
  126: 	{
  127: 		DBG2(DBG_TNC, "received PT-TLS message #%d of unknown type "
  128: 					  "0x%06x/0x%08x (%d bytes)",
  129: 					  *identifier, *vendor, *type, len);
  130: 	}
  131: 
  132: 	return read_tls(tls, len - PT_TLS_HEADER_LEN);
  133: }
  134: 
  135: /**
  136:  * Prepend a PT-TLS header to a writer, send data, destroy writer
  137:  */
  138: bool pt_tls_write(tls_socket_t *tls, pt_tls_message_type_t type,
  139: 				  uint32_t identifier, chunk_t data)
  140: {
  141: 	bio_writer_t *writer;
  142: 	chunk_t out;
  143: 	ssize_t len;
  144: 
  145: 	len = PT_TLS_HEADER_LEN + data.len;
  146: 	writer = bio_writer_create(len);
  147: 
  148: 	/* write PT-TLS header */
  149: 	writer->write_uint8 (writer, 0);
  150: 	writer->write_uint24(writer, 0);
  151: 	writer->write_uint32(writer, type);
  152: 	writer->write_uint32(writer, len);
  153: 	writer->write_uint32(writer, identifier);
  154: 
  155: 	/* write PT-TLS body */
  156: 	writer->write_data(writer, data);
  157: 
  158: 	DBG2(DBG_TNC, "sending PT-TLS message #%d of type '%N' (%d bytes)",
  159: 				   identifier, pt_tls_message_type_names, type, len);
  160: 
  161: 	out = writer->get_buf(writer);
  162: 	len = tls->write(tls, out.ptr, out.len);
  163: 	writer->destroy(writer);
  164: 
  165: 	return len == out.len;
  166: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>