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