#ifndef SSTP_PROT_H #define SSTP_PROT_H #include /* Constants */ #define SSTP_PORT 443 #define SSTP_HTTP_METHOD "SSTP_DUPLEX_POST" #define SSTP_HTTP_URI "/sra_{BA195980-CD49-458b-9E23-C84EE0ADCD75}/" #define SSTP_VERSION 0x10 #define SSTP_MAX_PACKET_SIZE 4095 #define SSTP_NONCE_SIZE 32 #define SSTP_HLAK_SIZE 32 #define SSTP_CMK_SEED "SSTP inner method derived CMK" #define SSTP_CMK_SEED_SIZE 29 #define SSTP_NEGOTIOATION_TIMEOUT 60 #define SSTP_HELLO_TIMEOUT 60 #define SSTP_ABORT_TIMEOUT_1 3 #define SSTP_ABORT_TIMEOUT_2 1 #define SSTP_DISCONNECT_TIMEOUT_1 5 #define SSTP_DISCONNECT_TIMEOUT_2 1 /* Packet Type */ enum { SSTP_DATA_PACKET = 0x00, SSTP_CTRL_PACKET = 0x01, }; /* Message Type */ enum { SSTP_MSG_CALL_CONNECT_REQUEST = 0x0001, SSTP_MSG_CALL_CONNECT_ACK = 0x0002, SSTP_MSG_CALL_CONNECT_NAK = 0x0003, SSTP_MSG_CALL_CONNECTED = 0x0004, SSTP_MSG_CALL_ABORT = 0x0005, SSTP_MSG_CALL_DISCONNECT = 0x0006, SSTP_MSG_CALL_DISCONNECT_ACK = 0x0007, SSTP_MSG_ECHO_REQUEST = 0x0008, SSTP_MSG_ECHO_RESPONSE = 0x0009, }; /* Attribute ID */ enum { SSTP_ATTRIB_NO_ERROR = 0x00, SSTP_ATTRIB_ENCAPSULATED_PROTOCOL_ID = 0x01, SSTP_ATTRIB_STATUS_INFO = 0x02, SSTP_ATTRIB_CRYPTO_BINDING = 0x03, SSTP_ATTRIB_CRYPTO_BINDING_REQ = 0x04, }; /* Protocol ID */ enum { SSTP_ENCAPSULATED_PROTOCOL_PPP = 0x0001, }; /* Hash Protocol Bitmask */ enum { CERT_HASH_PROTOCOL_SHA1 = 0x01, CERT_HASH_PROTOCOL_SHA256 = 0x02, }; /* Status */ enum { ATTRIB_STATUS_NO_ERROR = 0x00000000, ATTRIB_STATUS_DUPLICATE_ATTRIBUTE = 0x00000001, ATTRIB_STATUS_UNRECOGNIZED_ATTRIBUTE = 0x00000002, ATTRIB_STATUS_INVALID_ATTRIB_VALUE_LENGTH = 0x00000003, ATTRIB_STATUS_VALUE_NOT_SUPPORTED = 0x00000004, ATTRIB_STATUS_UNACCEPTED_FRAME_RECEIVED = 0x00000005, ATTRIB_STATUS_RETRY_COUNT_EXCEEDED = 0x00000006, ATTRIB_STATUS_INVALID_FRAME_RECEIVED = 0x00000007, ATTRIB_STATUS_NEGOTIATION_TIMEOUT = 0x00000008, ATTRIB_STATUS_ATTRIB_NOT_SUPPORTED_IN_MSG = 0x00000009, ATTRIB_STATUS_REQUIRED_ATTRIBUTE_MISSING = 0x0000000a, ATTRIB_STATUS_STATUS_INFO_NOT_SUPPORTED_IN_MSG = 0x0000000b, }; /* State */ enum { STATE_SERVER_CALL_DISCONNECTED = 0, STATE_SERVER_CONNECT_REQUEST_PENDING, STATE_SERVER_CALL_CONNECTED_PENDING, STATE_SERVER_CALL_CONNECTED, STATE_CALL_ABORT_IN_PROGRESS_1, STATE_CALL_ABORT_IN_PROGRESS_2, STATE_CALL_ABORT_TIMEOUT_PENDING, STATE_CALL_ABORT_PENDING, STATE_CALL_DISCONNECT_IN_PROGRESS_1, STATE_CALL_DISCONNECT_IN_PROGRESS_2, STATE_CALL_DISCONNECT_TIMEOUT_PENDING, STATE_CALL_DISCONNECT_ACK_PENDING, }; /* Packets */ struct sstp_hdr { uint8_t version; uint8_t reserved; uint16_t length; uint8_t data[0]; } __attribute__((packed)); struct sstp_ctrl_hdr { uint8_t version; uint8_t reserved; uint16_t length; uint16_t message_type; uint16_t num_attributes; uint8_t data[0]; } __attribute__((packed)); struct sstp_attr_hdr { uint8_t reserved; uint8_t attribute_id; uint16_t length; uint8_t data[0]; } __attribute__((packed)); struct sstp_attrib_encapsulated_protocol { struct sstp_attr_hdr hdr; uint16_t protocol_id; } __attribute__((packed)); struct sstp_attrib_status_info { struct sstp_attr_hdr hdr; uint8_t reserved[3]; uint8_t attrib_id; uint32_t status; uint8_t attrib_value[0]; } __attribute__((packed)); struct sstp_attrib_crypto_binding { struct sstp_attr_hdr hdr; uint8_t reserved[3]; uint8_t hash_protocol_bitmask; uint8_t nonce[SSTP_NONCE_SIZE]; uint8_t cert_hash[32]; uint8_t compound_mac[32]; } __attribute__((packed)); struct sstp_attrib_crypto_binding_request { struct sstp_attr_hdr hdr; uint8_t reserved[3]; uint8_t hash_protocol_bitmask; uint8_t nonce[SSTP_NONCE_SIZE]; } __attribute__((packed)); #define SSTP_DATA_HDR(len) { \ .version = SSTP_VERSION, \ .reserved = SSTP_DATA_PACKET, \ .length = htons(len), \ } #define SSTP_CTRL_HDR(type, len, num) { \ .version = SSTP_VERSION, \ .reserved = SSTP_CTRL_PACKET, \ .length = htons(len), \ .message_type = htons(type), \ .num_attributes = htons(num) \ } #define SSTP_ATTR_HDR(id, len) { \ .attribute_id = id, \ .length = htons(len) \ } #define INIT_SSTP_DATA_HDR(hdr, len) { \ (hdr)->version = SSTP_VERSION; \ (hdr)->reserved = SSTP_DATA_PACKET; \ (hdr)->length = htons(len); \ } #define INIT_SSTP_CTRL_HDR(hdr, type, num, len) {\ (hdr)->version = SSTP_VERSION; \ (hdr)->reserved = SSTP_CTRL_PACKET; \ (hdr)->length = htons(len); \ (hdr)->message_type = htons(type); \ (hdr)->num_attributes = htons(num); \ } #define INIT_SSTP_ATTR_HDR(hdr, id, len) { \ (hdr)->attribute_id = id; \ (hdr)->length = htons(len); \ } #endif