lsquic_crt_compress.c revision 229fce07
1/* Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc. See LICENSE. */ 2#include <assert.h> 3#include <stdbool.h> 4#include <string.h> 5#include <time.h> 6#include <zlib.h> 7 8#include <openssl/ssl.h> 9#ifndef WIN32 10#else 11#include <stdlib.h> 12#include <vc_compat.h> 13#endif 14 15#include "lsquic_int_types.h" 16#include "lsquic_crypto.h" 17#include "lsquic_crt_compress.h" 18#include "lsquic_util.h" 19 20#include "lsquic_str.h" 21 22#include "common_cert_set_2.c" 23#include "common_cert_set_3.c" 24 25/* 26 * common_cert_sub_strings contains ~1500 bytes of common certificate substrings 27 * as a dictionary of zlib from the Alexa Top 5000 set. 28 */ 29static const unsigned char common_cert_sub_strings[] = { 30 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 31 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 32 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 33 0x5f, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01, 34 0x06, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 0xfd, 0x6d, 0x01, 0x07, 35 0x17, 0x01, 0x30, 0x33, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 36 0x64, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 37 0x20, 0x53, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x34, 38 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 39 0x32, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, 0x72, 40 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x30, 0x2d, 0x61, 0x69, 0x61, 0x2e, 41 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 42 0x2f, 0x45, 0x2d, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 43 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x45, 0x2e, 0x63, 0x65, 44 0x72, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 45 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4a, 0x2e, 0x63, 46 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 47 0x2f, 0x63, 0x70, 0x73, 0x20, 0x28, 0x63, 0x29, 0x30, 0x30, 0x09, 0x06, 48 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x30, 0x0d, 49 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 50 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x7b, 0x30, 0x1d, 0x06, 0x03, 0x55, 51 0x1d, 0x0e, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 52 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 53 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd2, 54 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x2e, 55 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 56 0x04, 0x14, 0xb4, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 57 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x30, 0x0b, 0x06, 0x03, 58 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x30, 0x0d, 0x06, 0x09, 59 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 60 0x81, 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 61 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 62 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 63 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 64 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 65 0x55, 0x04, 0x0a, 0x13, 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 66 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x33, 67 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x68, 0x74, 0x74, 68 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 69 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 70 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 71 0x6f, 0x72, 0x79, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 72 0x13, 0x27, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x53, 73 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 74 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 75 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 76 0x04, 0x05, 0x13, 0x08, 0x30, 0x37, 0x39, 0x36, 0x39, 0x32, 0x38, 0x37, 77 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 78 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0c, 79 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 80 0x30, 0x1d, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 81 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 82 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 83 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 84 0x03, 0x02, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 85 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, 86 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86, 87 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 88 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 89 0x67, 0x64, 0x73, 0x31, 0x2d, 0x32, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 90 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 91 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 92 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 93 0x70, 0x73, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 94 0x0d, 0x31, 0x33, 0x30, 0x35, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01, 95 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a, 96 0x2f, 0x2f, 0x73, 0x30, 0x39, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01, 97 0x05, 0x05, 0x07, 0x02, 0x30, 0x44, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 98 0x3d, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 99 0xf8, 0x45, 0x01, 0x07, 0x17, 0x06, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 100 0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x1b, 0x53, 0x31, 0x17, 101 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, 0x72, 102 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 103 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56, 0x65, 104 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 105 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3b, 0x30, 0x39, 106 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65, 0x72, 0x6d, 0x73, 107 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20, 0x68, 108 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 109 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 110 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x30, 0x31, 0x10, 0x30, 0x0e, 111 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x31, 0x13, 0x30, 0x11, 112 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x47, 0x31, 0x13, 0x30, 0x11, 113 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x3c, 0x02, 0x01, 114 0x03, 0x13, 0x02, 0x55, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 115 0x03, 0x14, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 116 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0f, 0x13, 0x14, 0x50, 117 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x20, 0x4f, 0x72, 0x67, 0x61, 0x6e, 118 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x12, 0x31, 0x21, 0x30, 119 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18, 0x44, 0x6f, 0x6d, 0x61, 120 0x69, 0x6e, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x56, 121 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x31, 0x14, 0x31, 0x31, 122 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x28, 0x53, 0x65, 0x65, 123 0x20, 0x77, 0x77, 0x77, 0x2e, 0x72, 0x3a, 0x2f, 0x2f, 0x73, 0x65, 0x63, 124 0x75, 0x72, 0x65, 0x2e, 0x67, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 125 0x69, 0x67, 0x6e, 0x31, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x41, 126 0x2e, 0x63, 0x72, 0x6c, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 127 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x45, 0x63, 0x72, 128 0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 129 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x73, 0x64, 0x31, 0x1a, 130 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x68, 0x74, 0x74, 0x70, 0x3a, 131 0x2f, 0x2f, 0x45, 0x56, 0x49, 0x6e, 0x74, 0x6c, 0x2d, 0x63, 0x63, 0x72, 132 0x74, 0x2e, 0x67, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x69, 0x63, 0x65, 0x72, 133 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x31, 0x6f, 0x63, 0x73, 0x70, 0x2e, 134 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 135 0x30, 0x39, 0x72, 0x61, 0x70, 0x69, 0x64, 0x73, 0x73, 0x6c, 0x2e, 0x63, 136 0x6f, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 137 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 138 0x79, 0x2f, 0x30, 0x81, 0x80, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 139 0x07, 0x01, 0x01, 0x04, 0x74, 0x30, 0x72, 0x30, 0x24, 0x06, 0x08, 0x2b, 140 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 141 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64, 142 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x4a, 0x06, 143 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x3e, 0x68, 144 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 145 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 146 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 147 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x67, 0x64, 0x5f, 0x69, 0x6e, 0x74, 148 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x2e, 0x63, 0x72, 149 0x74, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 150 0x80, 0x14, 0xfd, 0xac, 0x61, 0x32, 0x93, 0x6c, 0x45, 0xd6, 0xe2, 0xee, 151 0x85, 0x5f, 0x9a, 0xba, 0xe7, 0x76, 0x99, 0x68, 0xcc, 0xe7, 0x30, 0x27, 152 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x86, 0x30, 153 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 154}; 155 156#define common_certs_num 2 157const common_cert_t common_cert_set[common_certs_num] = { 158 {common_certs2_num, common_certs2, common_certs2_lens, common_certs2_hash}, 159 {common_certs3_num, common_certs3, common_certs3_lens, common_certs3_hash}, 160}; 161 162 163static lsquic_str_t *s_ccsbuf; 164 165lsquic_str_t * get_common_certs_hash() 166{ 167 int i; 168 if (s_ccsbuf == NULL) 169 { 170 s_ccsbuf = lsquic_str_new(NULL, 0); 171 for (i=0 ;i<common_certs_num; ++i) 172 { 173 lsquic_str_append(s_ccsbuf, (const char *)&common_cert_set[i].hash, 8); 174 } 175 } 176 return s_ccsbuf; 177} 178 179 180/* return 0 found, -1 not found */ 181int get_common_cert(uint64_t hash, uint32_t index, lsquic_str_t *buf) 182{ 183 int i; 184 for (i = 0; i < common_certs_num; i++) 185 { 186 if (common_cert_set[i].hash == hash) 187 { 188 if (index < common_cert_set[i].num_certs) 189 { 190 lsquic_str_setto(buf, (const char *) common_cert_set[i].certs[index], 191 common_cert_set[i].lens[index]); 192 return 0; 193 } 194 break; 195 } 196 } 197 return -1; 198} 199 200 201/* result is written to dict */ 202static void 203make_zlib_dict_for_entries(cert_entry_t *entries, 204 lsquic_str_t **certs, size_t certs_count, 205 lsquic_str_t *dict) 206{ 207 int i; 208 size_t zlib_dict_size = 0; 209 for (i = certs_count - 1; i >= 0; --i) 210 { 211 if (entries[i].type != ENTRY_COMPRESSED) 212 { 213 zlib_dict_size += lsquic_str_len(certs[i]); 214 } 215 } 216 217 // At the end of the dictionary is a block of common certificate substrings. 218 zlib_dict_size += sizeof(common_cert_sub_strings); 219 220 for (i = certs_count - 1; i >= 0; --i) 221 { 222 if (entries[i].type != ENTRY_COMPRESSED) 223 { 224 lsquic_str_append(dict, lsquic_str_buf(certs[i]), lsquic_str_len(certs[i])); 225 } 226 } 227 228 lsquic_str_append(dict, (const char *)common_cert_sub_strings, sizeof(common_cert_sub_strings)); 229 assert((size_t)lsquic_str_len(dict) == zlib_dict_size); 230} 231 232 233void get_certs_hash(lsquic_str_t *certs, size_t certs_count, uint64_t *hashs) 234{ 235 size_t i; 236 for(i = 0; i < certs_count; ++i) 237 { 238 hashs[i] = fnv1a_64((const uint8_t *)lsquic_str_buf(&certs[i]), lsquic_str_len(&certs[i])); 239 } 240} 241 242 243size_t get_entries_size(cert_entry_t *entries, size_t entries_count) 244{ 245 size_t i; 246 size_t entries_size = 0; 247 for(i=0; i<entries_count; ++i) 248 { 249 entries_size++; 250 switch (entries[i].type) 251 { 252 case ENTRY_COMPRESSED: 253 break; 254 case ENTRY_CACHED: 255 entries_size += sizeof(uint64_t); 256 break; 257 case ENTRY_COMMON: 258 entries_size += sizeof(uint64_t) + sizeof(uint32_t); 259 break; 260 default: 261 break; 262 } 263 } 264 entries_size++; /* for end marker */ 265 return entries_size; 266} 267 268 269void serialize_cert_entries(uint8_t* out, int *out_len, cert_entry_t *entries, 270 size_t entries_count) 271{ 272 size_t i; 273 uint8_t *start = out; 274 for(i=0; i<entries_count; ++i) 275 { 276 *out++ = (uint8_t)(entries[i].type); 277 switch (entries[i].type) 278 { 279 case ENTRY_COMPRESSED: 280 break; 281 case ENTRY_CACHED: 282 memcpy(out, &entries[i].hash, sizeof(uint64_t)); 283 out += sizeof(uint64_t); 284 break; 285 case ENTRY_COMMON: 286 memcpy(out, &entries[i].set_hash, sizeof(uint64_t)); 287 out += sizeof(uint64_t); 288 memcpy(out, &entries[i].index, sizeof(uint32_t)); 289 out += sizeof(uint32_t); 290 break; 291 default: 292 break; 293 } 294 } 295 296 *out++ = 0; // end marker 297 *out_len = out - start; 298} 299 300 301int get_certs_count(lsquic_str_t *compressed_crt_buf) 302{ 303 char *in = lsquic_str_buf(compressed_crt_buf); 304 char *in_end = in + lsquic_str_len(compressed_crt_buf); 305 size_t idx = 0; 306 uint8_t type_byte; 307 308 for (;;) 309 { 310 if (in >= in_end) 311 return -1; 312 313 type_byte = in[0]; 314 ++in; 315 if (type_byte == 0) 316 break; 317 318 ++idx; 319 switch(type_byte) 320 { 321 case ENTRY_COMPRESSED: 322 break; 323 case ENTRY_CACHED: 324 { 325 if (in_end - in < (int)sizeof(uint64_t)) 326 return -1; 327 in += sizeof(uint64_t); 328 break; 329 } 330 case ENTRY_COMMON: 331 { 332 if (in_end - in < (int)(sizeof(uint64_t) + sizeof(uint32_t))) 333 return -1; 334 in += sizeof(uint64_t) + sizeof(uint32_t); 335 break; 336 } 337 default: 338 return -1; 339 } 340 } 341 return idx; 342} 343 344 345/* return 0: OK, -1, error */ 346static int parse_entries(const unsigned char **in_out, const unsigned char *const in_end, 347 lsquic_str_t *cached_certs, size_t cached_certs_count, 348 cert_entry_t *out_entries, 349 lsquic_str_t **out_certs, size_t *out_certs_count) 350{ 351 const unsigned char *in = *in_out; 352 size_t idx = 0; 353 uint64_t* cached_hashes; 354 cert_entry_t *entry; 355 lsquic_str_t *cert; 356 uint8_t type_byte; 357 int rv; 358 size_t i; 359 360 cached_hashes = NULL; 361 362 for (;;) 363 { 364 /* XXX potential invalid read */ 365 type_byte = in[0]; 366 ++in; 367 368 if (type_byte == 0) 369 break; 370 371 entry = &out_entries[idx]; 372 cert = out_certs[idx]; 373 /* XXX This seems dangerous -- there is no guard that `idx' does not 374 * exceed `out_certs_count'. 375 */ 376 lsquic_str_d(cert); 377 378 ++idx; 379 entry->type = type_byte; 380 switch (entry->type) 381 { 382 case ENTRY_COMPRESSED: 383 break; 384 case ENTRY_CACHED: 385 { 386 memcpy(&entry->hash, in, sizeof(uint64_t)); 387 in += sizeof(uint64_t); 388 389 if (!cached_hashes) 390 { 391 cached_hashes = malloc(cached_certs_count * sizeof(uint64_t));; 392 if (!cached_hashes) 393 goto err; 394 get_certs_hash(cached_certs, cached_certs_count, cached_hashes); 395 } 396 397 for (i=0; i<cached_certs_count; ++i) 398 { 399 if (cached_hashes[i] == entry->hash) 400 { 401 lsquic_str_append(cert, lsquic_str_buf(&cached_certs[i]), 402 lsquic_str_len(&cached_certs[i])); 403 break; 404 } 405 } 406 /* XXX: return -1 if not found? Logic removed in 407 4fd7e76bc031ac637e76c7f0930aff53f5b71705 */ 408 break; 409 } 410 case ENTRY_COMMON: 411 { 412 memcpy(&entry->set_hash, in, sizeof(uint64_t)); 413 in += sizeof(uint64_t); 414 memcpy(&entry->index, in, sizeof(uint32_t)); 415 in += sizeof(uint32_t); 416 417 if (0 == get_common_cert(entry->set_hash, entry->index, cert)) 418 break; 419 else 420 goto err; 421 } 422 default: 423 goto err; 424 } 425 } 426 427 rv = 0; 428 *in_out = in; 429 *out_certs_count = idx; 430 431 cleanup: 432 free(cached_hashes); 433 return rv; 434 435 err: 436 rv = -1; 437 goto cleanup; 438} 439 440 441/* 0: ok */ 442int decompress_certs(const unsigned char *in, const unsigned char *in_end, 443 lsquic_str_t *cached_certs, size_t cached_certs_count, 444 lsquic_str_t **out_certs, size_t *out_certs_count) 445{ 446 int ret; 447 size_t i; 448 uint8_t* uncompressed_data, *uncompressed_data_buf; 449 lsquic_str_t *dict; 450 uint32_t uncompressed_size; 451 size_t count = *out_certs_count; 452 cert_entry_t *entries; 453 z_stream z; 454 455 assert(*out_certs_count > 0 && *out_certs_count < 10000 456 && "Call get_certs_count() to get right certificates count first and make enough room for out_certs_count"); 457 458 if (count == 0 || count > 10000) 459 return -1; 460 461 dict = lsquic_str_new(NULL, 0); 462 if (!dict) 463 return -1; 464 465 uncompressed_data_buf = NULL; 466#ifdef WIN32 467 uncompressed_data = NULL; 468#endif 469 entries = malloc(count * sizeof(cert_entry_t)); 470 if (!entries) 471 goto err; 472 473 ret = parse_entries(&in, in_end, cached_certs, cached_certs_count, 474 entries, out_certs, out_certs_count); 475 if (ret) 476 goto err; 477 478 /* re-assign count with real valus */ 479 count = *out_certs_count; 480 481 if (in < in_end) 482 { 483 if (in_end - in < (int)sizeof(uint32_t)) 484 goto err; 485 486 memcpy(&uncompressed_size, in, sizeof(uncompressed_size)); 487 in += sizeof(uint32_t); 488 /* XXX Is 128 KB an arbitrary limit or is there a reason behind it? */ 489 if (uncompressed_size > 128 * 1024) 490 goto err; 491 492 uncompressed_data_buf = uncompressed_data = malloc(uncompressed_size); 493 if (!uncompressed_data) 494 goto err; 495 496 memset(&z, 0, sizeof(z)); 497 z.next_out = uncompressed_data; 498 z.avail_out = uncompressed_size; 499 z.next_in = (unsigned char *) in; 500 z.avail_in = in_end - in; 501 502 if (Z_OK != inflateInit(&z)) 503 goto err; 504 505 ret = inflate(&z, Z_FINISH); 506 if (ret == Z_NEED_DICT) 507 { 508 lsquic_str_d(dict); 509 make_zlib_dict_for_entries(entries, out_certs, count, dict); 510 if (Z_OK != inflateSetDictionary(&z, (const unsigned char *)lsquic_str_buf(dict), lsquic_str_len(dict))) 511 goto err; 512 ret = inflate(&z, Z_FINISH); 513 } 514 515 if (Z_STREAM_END != ret || z.avail_out > 0 || z.avail_in > 0) 516 goto err; 517 } 518 else 519 uncompressed_size = 0; 520 521 for (i = 0; i < count; i++) 522 { 523 switch (entries[i].type) 524 { 525 case ENTRY_COMPRESSED: 526 if (uncompressed_size < sizeof(uint32_t)) 527 goto err; 528 lsquic_str_d(out_certs[i]); 529 uint32_t cert_len; 530 memcpy(&cert_len, uncompressed_data, sizeof(cert_len)); 531 uncompressed_data += sizeof(uint32_t); 532 uncompressed_size -= sizeof(uint32_t); 533 if (uncompressed_size < cert_len) 534 goto err; 535 lsquic_str_append(out_certs[i], (const char *)uncompressed_data, cert_len); 536 uncompressed_data += cert_len; 537 uncompressed_size -= cert_len; 538 break; 539 case ENTRY_CACHED: 540 case ENTRY_COMMON: 541 default: 542 break; 543 } 544 } 545 546 cleanup: 547 lsquic_str_delete(dict); 548 free(entries); 549 if (uncompressed_data_buf) 550 inflateEnd(&z); 551 free(uncompressed_data_buf); 552 if (0 == uncompressed_size) 553 return 0; 554 else 555 return -1; 556 557 err: 558 uncompressed_size = 1; /* This triggers return -1 above */ 559 goto cleanup; 560} 561 562 563void 564lsquic_crt_cleanup (void) 565{ 566 if (s_ccsbuf) 567 { 568 lsquic_str_delete(s_ccsbuf); 569 s_ccsbuf = NULL; 570 } 571} 572