lsquic_crt_compress.c revision a5fa05f9
1/* Copyright (c) 2017 - 2020 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 165static int 166match_common_cert (lsquic_str_t * cert, lsquic_str_t * common_set_hashes, 167 uint64_t* out_hash, uint32_t* out_index); 168 169lsquic_str_t * 170lsquic_get_common_certs_hash() 171{ 172 int i; 173 if (s_ccsbuf == NULL) 174 { 175 s_ccsbuf = lsquic_str_new(NULL, 0); 176 for (i=0 ;i<common_certs_num; ++i) 177 { 178 lsquic_str_append(s_ccsbuf, (const char *)&common_cert_set[i].hash, 8); 179 } 180 } 181 return s_ccsbuf; 182} 183 184 185/* return 0 found, -1 not found */ 186int 187lsquic_get_common_cert(uint64_t hash, uint32_t index, lsquic_str_t *buf) 188{ 189 int i; 190 for (i = 0; i < common_certs_num; i++) 191 { 192 if (common_cert_set[i].hash == hash) 193 { 194 if (index < common_cert_set[i].num_certs) 195 { 196 lsquic_str_setto(buf, (const char *) common_cert_set[i].certs[index], 197 common_cert_set[i].lens[index]); 198 return 0; 199 } 200 break; 201 } 202 } 203 return -1; 204} 205 206 207static int 208comp_ls_str (lsquic_str_t * a, const void * b, size_t b_len) 209{ 210 size_t a_len; 211 int r; 212 213 a_len = lsquic_str_len(a); 214 r = memcmp(lsquic_str_buf(a), b, a_len < b_len ? a_len : b_len); 215 if (r) 216 return r; 217 else 218 return (a_len > b_len) - (b_len > a_len); 219} 220 221 222/* 0, matched -1, error */ 223static int 224match_common_cert (lsquic_str_t * cert, lsquic_str_t * common_set_hashes, 225 uint64_t* out_hash, uint32_t* out_index) 226{ 227 size_t i, j; 228 int n; 229 uint64_t hash; 230 size_t min, max, mid; 231 232 if (lsquic_str_len(common_set_hashes) % sizeof(uint64_t) != 0) 233 return -1; 234 235 for (i = 0; i < lsquic_str_len(common_set_hashes) / sizeof(uint64_t); i++) 236 { 237 memcpy(&hash, lsquic_str_buf(common_set_hashes) + i * sizeof(uint64_t), 238 sizeof(uint64_t)); 239 240 for (j = 0; j < common_certs_num; j++) 241 { 242 if (common_cert_set[j].hash != hash) 243 continue; 244 245 if (common_cert_set[j].num_certs == 0) 246 continue; 247 248 min = 0; 249 max = common_cert_set[j].num_certs - 1; 250 while (max >= min) 251 { 252 mid = min + ((max - min) / 2); 253 n = comp_ls_str(cert, common_cert_set[j].certs[mid], 254 common_cert_set[j].lens[mid]); 255 if (n < 0) 256 { 257 if (mid == 0) 258 break; 259 max = mid - 1; 260 } 261 else if (n > 0) 262 min = mid + 1; 263 else 264 { 265 *out_hash = hash; 266 *out_index = mid; 267 return 0; 268 } 269 } 270 } 271 } 272 273 return -1; 274} 275 276 277/* result is written to dict */ 278static void 279make_zlib_dict_for_entries(cert_entry_t *entries, 280 lsquic_str_t **certs, size_t certs_count, 281 lsquic_str_t *dict) 282{ 283 int i; 284 size_t zlib_dict_size = 0; 285 for (i = certs_count - 1; i >= 0; --i) 286 { 287 if (entries[i].type != ENTRY_COMPRESSED) 288 { 289 zlib_dict_size += lsquic_str_len(certs[i]); 290 } 291 } 292 293 // At the end of the dictionary is a block of common certificate substrings. 294 zlib_dict_size += sizeof(common_cert_sub_strings); 295 296 for (i = certs_count - 1; i >= 0; --i) 297 { 298 if (entries[i].type != ENTRY_COMPRESSED) 299 { 300 lsquic_str_append(dict, lsquic_str_buf(certs[i]), lsquic_str_len(certs[i])); 301 } 302 } 303 304 lsquic_str_append(dict, (const char *)common_cert_sub_strings, sizeof(common_cert_sub_strings)); 305 assert((size_t)lsquic_str_len(dict) == zlib_dict_size); 306} 307 308 309static 310void get_certs_hash(lsquic_str_t *certs, size_t certs_count, uint64_t *hashs) 311{ 312 size_t i; 313 for(i = 0; i < certs_count; ++i) 314 { 315 hashs[i] = lsquic_fnv1a_64((const uint8_t *)lsquic_str_buf(&certs[i]), lsquic_str_len(&certs[i])); 316 } 317} 318 319 320static void get_certs_entries(lsquic_str_t **certs, size_t certs_count, 321 lsquic_str_t *client_common_set_hashes, 322 lsquic_str_t *client_cached_cert_hashes, 323 cert_entry_t *entries) 324{ 325 size_t i; 326 int j; 327 cert_entry_t *entry; 328 uint64_t hash, cached_hash; 329 bool cached; 330 331 const bool cached_valid = (lsquic_str_len(client_cached_cert_hashes) % sizeof(uint64_t) == 0) 332 && (lsquic_str_len(client_cached_cert_hashes) > 0); 333 334 assert(&entries[certs_count - 1]); 335 336 for (i = 0; i<certs_count; ++i) 337 { 338 entry = &entries[i]; 339 if (cached_valid) 340 { 341 cached = false; 342 hash = lsquic_fnv1a_64((const uint8_t *)lsquic_str_buf(certs[i]), lsquic_str_len(certs[i])); 343 344 for (j = 0; j < (int)lsquic_str_len(client_cached_cert_hashes); 345 j += sizeof(uint64_t)) 346 { 347 memcpy(&cached_hash, lsquic_str_buf(client_cached_cert_hashes) + j, 348 sizeof(uint64_t)); 349 if (hash != cached_hash) 350 continue; 351 352 entry->type = ENTRY_CACHED; 353 entry->hash = hash; 354 cached = true; 355 break; 356 } 357 358 if (cached) 359 continue; 360 } 361 362 if (0 == match_common_cert(certs[i], client_common_set_hashes, 363 &entry->set_hash, &entry->index)) 364 { 365 entry->type = ENTRY_COMMON; 366 continue; 367 } 368 369 entry->type = ENTRY_COMPRESSED; 370 } 371} 372 373static size_t 374get_entries_size(cert_entry_t *entries, size_t entries_count) 375{ 376 size_t i; 377 size_t entries_size = 0; 378 for(i=0; i<entries_count; ++i) 379 { 380 entries_size++; 381 switch (entries[i].type) 382 { 383 case ENTRY_COMPRESSED: 384 break; 385 case ENTRY_CACHED: 386 entries_size += sizeof(uint64_t); 387 break; 388 case ENTRY_COMMON: 389 entries_size += sizeof(uint64_t) + sizeof(uint32_t); 390 break; 391 default: 392 break; 393 } 394 } 395 entries_size++; /* for end marker */ 396 return entries_size; 397} 398 399static 400void serialize_cert_entries(uint8_t* out, int *out_len, cert_entry_t *entries, 401 size_t entries_count) 402{ 403 size_t i; 404 uint8_t *start = out; 405 for(i=0; i<entries_count; ++i) 406 { 407 *out++ = (uint8_t)(entries[i].type); 408 switch (entries[i].type) 409 { 410 case ENTRY_COMPRESSED: 411 break; 412 case ENTRY_CACHED: 413 memcpy(out, &entries[i].hash, sizeof(uint64_t)); 414 out += sizeof(uint64_t); 415 break; 416 case ENTRY_COMMON: 417 memcpy(out, &entries[i].set_hash, sizeof(uint64_t)); 418 out += sizeof(uint64_t); 419 memcpy(out, &entries[i].index, sizeof(uint32_t)); 420 out += sizeof(uint32_t); 421 break; 422 default: 423 break; 424 } 425 } 426 427 *out++ = 0; // end marker 428 *out_len = out - start; 429} 430 431 432int 433lsquic_get_certs_count(lsquic_str_t *compressed_crt_buf) 434{ 435 char *in = lsquic_str_buf(compressed_crt_buf); 436 char *in_end = in + lsquic_str_len(compressed_crt_buf); 437 size_t idx = 0; 438 uint8_t type_byte; 439 440 for (;;) 441 { 442 if (in >= in_end) 443 return -1; 444 445 type_byte = in[0]; 446 ++in; 447 if (type_byte == 0) 448 break; 449 450 ++idx; 451 switch(type_byte) 452 { 453 case ENTRY_COMPRESSED: 454 break; 455 case ENTRY_CACHED: 456 { 457 if (in_end - in < (int)sizeof(uint64_t)) 458 return -1; 459 in += sizeof(uint64_t); 460 break; 461 } 462 case ENTRY_COMMON: 463 { 464 if (in_end - in < (int)(sizeof(uint64_t) + sizeof(uint32_t))) 465 return -1; 466 in += sizeof(uint64_t) + sizeof(uint32_t); 467 break; 468 } 469 default: 470 return -1; 471 } 472 } 473 return idx; 474} 475 476 477/* return 0: OK, -1, error */ 478static int parse_entries(const unsigned char **in_out, const unsigned char *const in_end, 479 lsquic_str_t *cached_certs, size_t cached_certs_count, 480 cert_entry_t *out_entries, 481 lsquic_str_t **out_certs, size_t *out_certs_count) 482{ 483 const unsigned char *in = *in_out; 484 size_t idx = 0; 485 uint64_t* cached_hashes; 486 cert_entry_t *entry; 487 lsquic_str_t *cert; 488 uint8_t type_byte; 489 int rv; 490 size_t i; 491 492 cached_hashes = NULL; 493 494 for (;;) 495 { 496 /* XXX potential invalid read */ 497 type_byte = in[0]; 498 ++in; 499 500 if (type_byte == 0) 501 break; 502 503 entry = &out_entries[idx]; 504 cert = out_certs[idx]; 505 /* XXX This seems dangerous -- there is no guard that `idx' does not 506 * exceed `out_certs_count'. 507 */ 508 lsquic_str_d(cert); 509 510 ++idx; 511 entry->type = type_byte; 512 switch (entry->type) 513 { 514 case ENTRY_COMPRESSED: 515 break; 516 case ENTRY_CACHED: 517 { 518 memcpy(&entry->hash, in, sizeof(uint64_t)); 519 in += sizeof(uint64_t); 520 521 if (!cached_hashes) 522 { 523 cached_hashes = malloc(cached_certs_count * sizeof(uint64_t));; 524 if (!cached_hashes) 525 goto err; 526 get_certs_hash(cached_certs, cached_certs_count, cached_hashes); 527 } 528 529 for (i=0; i<cached_certs_count; ++i) 530 { 531 if (cached_hashes[i] == entry->hash) 532 { 533 lsquic_str_append(cert, lsquic_str_buf(&cached_certs[i]), 534 lsquic_str_len(&cached_certs[i])); 535 break; 536 } 537 } 538 /* XXX: return -1 if not found? Logic removed in 539 4fd7e76bc031ac637e76c7f0930aff53f5b71705 */ 540 break; 541 } 542 case ENTRY_COMMON: 543 { 544 memcpy(&entry->set_hash, in, sizeof(uint64_t)); 545 in += sizeof(uint64_t); 546 memcpy(&entry->index, in, sizeof(uint32_t)); 547 in += sizeof(uint32_t); 548 549 if (0 == lsquic_get_common_cert(entry->set_hash, entry->index, cert)) 550 break; 551 else 552 goto err; 553 } 554 default: 555 goto err; 556 } 557 } 558 559 rv = 0; 560 *in_out = in; 561 *out_certs_count = idx; 562 563 cleanup: 564 free(cached_hashes); 565 return rv; 566 567 err: 568 rv = -1; 569 goto cleanup; 570} 571 572 573/* return 0 for OK */ 574int 575lsquic_compress_certs (lsquic_str_t **certs, size_t certs_count, 576 lsquic_str_t *client_common_set_hashes, 577 lsquic_str_t *client_cached_cert_hashes, 578 lsquic_str_t *result) 579{ 580 int rv; 581 size_t i; 582 size_t uncompressed_size = 0, compressed_size = 0 ; 583 z_stream z; 584 lsquic_str_t *dict; 585 size_t entries_size, result_length; 586 int out_len; 587 uint8_t* out; 588 uint32_t tmp_size_32; 589 cert_entry_t *entries; 590 591 entries = malloc(sizeof(cert_entry_t) * certs_count); 592 if (!entries) 593 return -1; 594 595 dict = lsquic_str_new(NULL, 0); 596 if (!dict) 597 goto err; 598 599 get_certs_entries(certs, certs_count, client_common_set_hashes, 600 client_cached_cert_hashes, entries); 601 602 for (i = 0; i < certs_count; i++) 603 { 604 if (entries[i].type == ENTRY_COMPRESSED) 605 { 606 /*uint32_t length + cert content*/ 607 uncompressed_size += 4 + lsquic_str_len(certs[i]); 608 } 609 } 610 611 if (uncompressed_size > 0) 612 { 613 memset(&z, 0, sizeof(z)); 614 if (Z_OK != deflateInit(&z, Z_DEFAULT_COMPRESSION)) 615 goto err; 616 617 make_zlib_dict_for_entries(entries, certs, certs_count, dict); 618 if(Z_OK != deflateSetDictionary(&z, (const unsigned char *)lsquic_str_buf(dict), lsquic_str_len(dict))) 619 goto err; 620 compressed_size = deflateBound(&z, uncompressed_size); 621 } 622 623 entries_size = get_entries_size(entries, certs_count); 624 result_length = entries_size + (uncompressed_size > 0 ? 4 : 0) + 625 compressed_size; 626 lsquic_str_prealloc(result, result_length); 627 628 out = (unsigned char *)lsquic_str_buf(result); 629 serialize_cert_entries(out, &out_len, entries, certs_count); 630 out += entries_size; 631 632 if (uncompressed_size == 0) 633 { 634 lsquic_str_setlen(result, entries_size); 635 rv = 0; 636 goto cleanup; 637 } 638 639 tmp_size_32 = uncompressed_size; 640 memcpy(out, &tmp_size_32, sizeof(uint32_t)); 641 out += sizeof(uint32_t); 642 643 z.next_out = out; 644 z.avail_out = compressed_size; 645 646 for (i = 0; i < certs_count; ++i) 647 { 648 if (entries[i].type != ENTRY_COMPRESSED) 649 continue; 650 651 tmp_size_32 = lsquic_str_len(certs[i]); 652 z.next_in = (uint8_t*)(&tmp_size_32); 653 z.avail_in = sizeof(tmp_size_32); 654 if (Z_OK != deflate(&z, Z_NO_FLUSH) || z.avail_in) 655 goto err; 656 z.next_in = (unsigned char *)lsquic_str_buf(certs[i]); 657 z.avail_in = lsquic_str_len(certs[i]); 658 if (Z_OK != deflate(&z, Z_NO_FLUSH) || z.avail_in) 659 goto err; 660 } 661 662 z.avail_in = 0; 663 if (Z_STREAM_END != deflate(&z, Z_FINISH)) 664 goto err; 665 666 rv = 0; 667 result_length -= z.avail_out; 668 lsquic_str_setlen(result, result_length); 669 670 cleanup: 671 free(entries); 672 if (dict) 673 lsquic_str_delete(dict); 674 if (uncompressed_size) 675 deflateEnd(&z); 676 return rv; 677 678 err: 679 rv = -1; 680 goto cleanup; 681} 682 683 684/* 0: ok */ 685int 686lsquic_decompress_certs (const unsigned char *in, const unsigned char *in_end, 687 lsquic_str_t *cached_certs, size_t cached_certs_count, 688 lsquic_str_t **out_certs, size_t *out_certs_count) 689{ 690 int ret; 691 size_t i; 692 uint8_t* uncompressed_data, *uncompressed_data_buf; 693 lsquic_str_t *dict; 694 uint32_t uncompressed_size; 695 size_t count = *out_certs_count; 696 cert_entry_t *entries; 697 z_stream z; 698 699 assert(*out_certs_count > 0 && *out_certs_count < 10000 700 && "Call lsquic_get_certs_count() to get right certificates count first and make enough room for out_certs_count"); 701 702 if (count == 0 || count > 10000) 703 return -1; 704 705 dict = lsquic_str_new(NULL, 0); 706 if (!dict) 707 return -1; 708 709 uncompressed_data_buf = NULL; 710#ifdef WIN32 711 uncompressed_data = NULL; 712#endif 713 entries = malloc(count * sizeof(cert_entry_t)); 714 if (!entries) 715 goto err; 716 717 ret = parse_entries(&in, in_end, cached_certs, cached_certs_count, 718 entries, out_certs, out_certs_count); 719 if (ret) 720 goto err; 721 722 /* re-assign count with real valus */ 723 count = *out_certs_count; 724 725 if (in < in_end) 726 { 727 if (in_end - in < (int)sizeof(uint32_t)) 728 goto err; 729 730 memcpy(&uncompressed_size, in, sizeof(uncompressed_size)); 731 in += sizeof(uint32_t); 732 /* XXX Is 128 KB an arbitrary limit or is there a reason behind it? */ 733 if (uncompressed_size > 128 * 1024) 734 goto err; 735 736 uncompressed_data_buf = uncompressed_data = malloc(uncompressed_size); 737 if (!uncompressed_data) 738 goto err; 739 740 memset(&z, 0, sizeof(z)); 741 z.next_out = uncompressed_data; 742 z.avail_out = uncompressed_size; 743 z.next_in = (unsigned char *) in; 744 z.avail_in = in_end - in; 745 746 if (Z_OK != inflateInit(&z)) 747 goto err; 748 749 ret = inflate(&z, Z_FINISH); 750 if (ret == Z_NEED_DICT) 751 { 752 lsquic_str_d(dict); 753 make_zlib_dict_for_entries(entries, out_certs, count, dict); 754 if (Z_OK != inflateSetDictionary(&z, (const unsigned char *)lsquic_str_buf(dict), lsquic_str_len(dict))) 755 goto err; 756 ret = inflate(&z, Z_FINISH); 757 } 758 759 if (Z_STREAM_END != ret || z.avail_out > 0 || z.avail_in > 0) 760 goto err; 761 } 762 else 763 uncompressed_size = 0; 764 765 for (i = 0; i < count; i++) 766 { 767 switch (entries[i].type) 768 { 769 case ENTRY_COMPRESSED: 770 if (uncompressed_size < sizeof(uint32_t)) 771 goto err; 772 lsquic_str_d(out_certs[i]); 773 uint32_t cert_len; 774 memcpy(&cert_len, uncompressed_data, sizeof(cert_len)); 775 uncompressed_data += sizeof(uint32_t); 776 uncompressed_size -= sizeof(uint32_t); 777 if (uncompressed_size < cert_len) 778 goto err; 779 lsquic_str_append(out_certs[i], (const char *)uncompressed_data, cert_len); 780 uncompressed_data += cert_len; 781 uncompressed_size -= cert_len; 782 break; 783 case ENTRY_CACHED: 784 case ENTRY_COMMON: 785 default: 786 break; 787 } 788 } 789 790 cleanup: 791 lsquic_str_delete(dict); 792 free(entries); 793 if (uncompressed_data_buf) 794 inflateEnd(&z); 795 free(uncompressed_data_buf); 796 if (0 == uncompressed_size) 797 return 0; 798 else 799 return -1; 800 801 err: 802 uncompressed_size = 1; /* This triggers return -1 above */ 803 goto cleanup; 804} 805 806 807void 808lsquic_crt_cleanup (void) 809{ 810 if (s_ccsbuf) 811 { 812 lsquic_str_delete(s_ccsbuf); 813 s_ccsbuf = NULL; 814 } 815} 816