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