Return to pt_tls.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libpttls |
1.1 ! misho 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: }