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