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