lsquic_crt_compress.c revision 50aadb33
150aadb33SDmitri Tikhonov/* Copyright (c) 2017 LiteSpeed Technologies Inc. See LICENSE. */ 250aadb33SDmitri Tikhonov#include <assert.h> 350aadb33SDmitri Tikhonov#include <stdbool.h> 450aadb33SDmitri Tikhonov#include <string.h> 550aadb33SDmitri Tikhonov#include <time.h> 650aadb33SDmitri Tikhonov#include <zlib.h> 750aadb33SDmitri Tikhonov 850aadb33SDmitri Tikhonov#include <openssl/ssl.h> 950aadb33SDmitri Tikhonov 1050aadb33SDmitri Tikhonov#include "lsquic_int_types.h" 1150aadb33SDmitri Tikhonov#include "lsquic_crypto.h" 1250aadb33SDmitri Tikhonov#include "lsquic_crt_compress.h" 1350aadb33SDmitri Tikhonov#include "lsquic_util.h" 1450aadb33SDmitri Tikhonov 1550aadb33SDmitri Tikhonov#include "lsquic_str.h" 1650aadb33SDmitri Tikhonov 1750aadb33SDmitri Tikhonov#include "common_cert_set_2.c" 1850aadb33SDmitri Tikhonov#include "common_cert_set_3.c" 1950aadb33SDmitri Tikhonov 2050aadb33SDmitri Tikhonov/* 2150aadb33SDmitri Tikhonov * common_cert_sub_strings contains ~1500 bytes of common certificate substrings 2250aadb33SDmitri Tikhonov * as a dictionary of zlib from the Alexa Top 5000 set. 2350aadb33SDmitri Tikhonov */ 2450aadb33SDmitri Tikhonovstatic const unsigned char common_cert_sub_strings[] = { 2550aadb33SDmitri Tikhonov 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 2650aadb33SDmitri Tikhonov 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 2750aadb33SDmitri Tikhonov 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 2850aadb33SDmitri Tikhonov 0x5f, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01, 2950aadb33SDmitri Tikhonov 0x06, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 0xfd, 0x6d, 0x01, 0x07, 3050aadb33SDmitri Tikhonov 0x17, 0x01, 0x30, 0x33, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 3150aadb33SDmitri Tikhonov 0x64, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 3250aadb33SDmitri Tikhonov 0x20, 0x53, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x34, 3350aadb33SDmitri Tikhonov 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 3450aadb33SDmitri Tikhonov 0x32, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, 0x72, 3550aadb33SDmitri Tikhonov 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x30, 0x2d, 0x61, 0x69, 0x61, 0x2e, 3650aadb33SDmitri Tikhonov 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 3750aadb33SDmitri Tikhonov 0x2f, 0x45, 0x2d, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 3850aadb33SDmitri Tikhonov 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x45, 0x2e, 0x63, 0x65, 3950aadb33SDmitri Tikhonov 0x72, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 4050aadb33SDmitri Tikhonov 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4a, 0x2e, 0x63, 4150aadb33SDmitri Tikhonov 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 4250aadb33SDmitri Tikhonov 0x2f, 0x63, 0x70, 0x73, 0x20, 0x28, 0x63, 0x29, 0x30, 0x30, 0x09, 0x06, 4350aadb33SDmitri Tikhonov 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x30, 0x0d, 4450aadb33SDmitri Tikhonov 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 4550aadb33SDmitri Tikhonov 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x7b, 0x30, 0x1d, 0x06, 0x03, 0x55, 4650aadb33SDmitri Tikhonov 0x1d, 0x0e, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 4750aadb33SDmitri Tikhonov 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 4850aadb33SDmitri Tikhonov 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd2, 4950aadb33SDmitri Tikhonov 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x2e, 5050aadb33SDmitri Tikhonov 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 5150aadb33SDmitri Tikhonov 0x04, 0x14, 0xb4, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 5250aadb33SDmitri Tikhonov 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x30, 0x0b, 0x06, 0x03, 5350aadb33SDmitri Tikhonov 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x30, 0x0d, 0x06, 0x09, 5450aadb33SDmitri Tikhonov 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 5550aadb33SDmitri Tikhonov 0x81, 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 5650aadb33SDmitri Tikhonov 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 5750aadb33SDmitri Tikhonov 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 5850aadb33SDmitri Tikhonov 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 5950aadb33SDmitri Tikhonov 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 6050aadb33SDmitri Tikhonov 0x55, 0x04, 0x0a, 0x13, 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 6150aadb33SDmitri Tikhonov 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x33, 6250aadb33SDmitri Tikhonov 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x68, 0x74, 0x74, 6350aadb33SDmitri Tikhonov 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 6450aadb33SDmitri Tikhonov 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 6550aadb33SDmitri Tikhonov 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 6650aadb33SDmitri Tikhonov 0x6f, 0x72, 0x79, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 6750aadb33SDmitri Tikhonov 0x13, 0x27, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x53, 6850aadb33SDmitri Tikhonov 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 6950aadb33SDmitri Tikhonov 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 7050aadb33SDmitri Tikhonov 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 7150aadb33SDmitri Tikhonov 0x04, 0x05, 0x13, 0x08, 0x30, 0x37, 0x39, 0x36, 0x39, 0x32, 0x38, 0x37, 7250aadb33SDmitri Tikhonov 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 7350aadb33SDmitri Tikhonov 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0c, 7450aadb33SDmitri Tikhonov 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 7550aadb33SDmitri Tikhonov 0x30, 0x1d, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 7650aadb33SDmitri Tikhonov 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 7750aadb33SDmitri Tikhonov 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 7850aadb33SDmitri Tikhonov 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 7950aadb33SDmitri Tikhonov 0x03, 0x02, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 8050aadb33SDmitri Tikhonov 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, 8150aadb33SDmitri Tikhonov 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86, 8250aadb33SDmitri Tikhonov 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 8350aadb33SDmitri Tikhonov 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 8450aadb33SDmitri Tikhonov 0x67, 0x64, 0x73, 0x31, 0x2d, 0x32, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 8550aadb33SDmitri Tikhonov 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 8650aadb33SDmitri Tikhonov 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 8750aadb33SDmitri Tikhonov 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 8850aadb33SDmitri Tikhonov 0x70, 0x73, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 8950aadb33SDmitri Tikhonov 0x0d, 0x31, 0x33, 0x30, 0x35, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01, 9050aadb33SDmitri Tikhonov 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a, 9150aadb33SDmitri Tikhonov 0x2f, 0x2f, 0x73, 0x30, 0x39, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01, 9250aadb33SDmitri Tikhonov 0x05, 0x05, 0x07, 0x02, 0x30, 0x44, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 9350aadb33SDmitri Tikhonov 0x3d, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 9450aadb33SDmitri Tikhonov 0xf8, 0x45, 0x01, 0x07, 0x17, 0x06, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 9550aadb33SDmitri Tikhonov 0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x1b, 0x53, 0x31, 0x17, 9650aadb33SDmitri Tikhonov 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, 0x72, 9750aadb33SDmitri Tikhonov 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 9850aadb33SDmitri Tikhonov 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56, 0x65, 9950aadb33SDmitri Tikhonov 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 10050aadb33SDmitri Tikhonov 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3b, 0x30, 0x39, 10150aadb33SDmitri Tikhonov 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65, 0x72, 0x6d, 0x73, 10250aadb33SDmitri Tikhonov 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20, 0x68, 10350aadb33SDmitri Tikhonov 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 10450aadb33SDmitri Tikhonov 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 10550aadb33SDmitri Tikhonov 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x30, 0x31, 0x10, 0x30, 0x0e, 10650aadb33SDmitri Tikhonov 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x31, 0x13, 0x30, 0x11, 10750aadb33SDmitri Tikhonov 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x47, 0x31, 0x13, 0x30, 0x11, 10850aadb33SDmitri Tikhonov 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x3c, 0x02, 0x01, 10950aadb33SDmitri Tikhonov 0x03, 0x13, 0x02, 0x55, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 11050aadb33SDmitri Tikhonov 0x03, 0x14, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 11150aadb33SDmitri Tikhonov 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0f, 0x13, 0x14, 0x50, 11250aadb33SDmitri Tikhonov 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x20, 0x4f, 0x72, 0x67, 0x61, 0x6e, 11350aadb33SDmitri Tikhonov 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x12, 0x31, 0x21, 0x30, 11450aadb33SDmitri Tikhonov 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18, 0x44, 0x6f, 0x6d, 0x61, 11550aadb33SDmitri Tikhonov 0x69, 0x6e, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x56, 11650aadb33SDmitri Tikhonov 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x31, 0x14, 0x31, 0x31, 11750aadb33SDmitri Tikhonov 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x28, 0x53, 0x65, 0x65, 11850aadb33SDmitri Tikhonov 0x20, 0x77, 0x77, 0x77, 0x2e, 0x72, 0x3a, 0x2f, 0x2f, 0x73, 0x65, 0x63, 11950aadb33SDmitri Tikhonov 0x75, 0x72, 0x65, 0x2e, 0x67, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 12050aadb33SDmitri Tikhonov 0x69, 0x67, 0x6e, 0x31, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x41, 12150aadb33SDmitri Tikhonov 0x2e, 0x63, 0x72, 0x6c, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 12250aadb33SDmitri Tikhonov 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x45, 0x63, 0x72, 12350aadb33SDmitri Tikhonov 0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 12450aadb33SDmitri Tikhonov 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x73, 0x64, 0x31, 0x1a, 12550aadb33SDmitri Tikhonov 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x68, 0x74, 0x74, 0x70, 0x3a, 12650aadb33SDmitri Tikhonov 0x2f, 0x2f, 0x45, 0x56, 0x49, 0x6e, 0x74, 0x6c, 0x2d, 0x63, 0x63, 0x72, 12750aadb33SDmitri Tikhonov 0x74, 0x2e, 0x67, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x69, 0x63, 0x65, 0x72, 12850aadb33SDmitri Tikhonov 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x31, 0x6f, 0x63, 0x73, 0x70, 0x2e, 12950aadb33SDmitri Tikhonov 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 13050aadb33SDmitri Tikhonov 0x30, 0x39, 0x72, 0x61, 0x70, 0x69, 0x64, 0x73, 0x73, 0x6c, 0x2e, 0x63, 13150aadb33SDmitri Tikhonov 0x6f, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 13250aadb33SDmitri Tikhonov 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 13350aadb33SDmitri Tikhonov 0x79, 0x2f, 0x30, 0x81, 0x80, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 13450aadb33SDmitri Tikhonov 0x07, 0x01, 0x01, 0x04, 0x74, 0x30, 0x72, 0x30, 0x24, 0x06, 0x08, 0x2b, 13550aadb33SDmitri Tikhonov 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 13650aadb33SDmitri Tikhonov 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64, 13750aadb33SDmitri Tikhonov 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x4a, 0x06, 13850aadb33SDmitri Tikhonov 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x3e, 0x68, 13950aadb33SDmitri Tikhonov 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 14050aadb33SDmitri Tikhonov 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 14150aadb33SDmitri Tikhonov 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 14250aadb33SDmitri Tikhonov 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x67, 0x64, 0x5f, 0x69, 0x6e, 0x74, 14350aadb33SDmitri Tikhonov 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x2e, 0x63, 0x72, 14450aadb33SDmitri Tikhonov 0x74, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 14550aadb33SDmitri Tikhonov 0x80, 0x14, 0xfd, 0xac, 0x61, 0x32, 0x93, 0x6c, 0x45, 0xd6, 0xe2, 0xee, 14650aadb33SDmitri Tikhonov 0x85, 0x5f, 0x9a, 0xba, 0xe7, 0x76, 0x99, 0x68, 0xcc, 0xe7, 0x30, 0x27, 14750aadb33SDmitri Tikhonov 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x86, 0x30, 14850aadb33SDmitri Tikhonov 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 14950aadb33SDmitri Tikhonov}; 15050aadb33SDmitri Tikhonov 15150aadb33SDmitri Tikhonov#define common_certs_num 2 15250aadb33SDmitri Tikhonovconst common_cert_t common_cert_set[common_certs_num] = { 15350aadb33SDmitri Tikhonov {common_certs2_num, common_certs2, common_certs2_lens, common_certs2_hash}, 15450aadb33SDmitri Tikhonov {common_certs3_num, common_certs3, common_certs3_lens, common_certs3_hash}, 15550aadb33SDmitri Tikhonov}; 15650aadb33SDmitri Tikhonov 15750aadb33SDmitri Tikhonov 15850aadb33SDmitri Tikhonovstatic lsquic_str_t *s_ccsbuf; 15950aadb33SDmitri Tikhonov 16050aadb33SDmitri Tikhonovlsquic_str_t * get_common_certs_hash() 16150aadb33SDmitri Tikhonov{ 16250aadb33SDmitri Tikhonov int i; 16350aadb33SDmitri Tikhonov if (s_ccsbuf == NULL) 16450aadb33SDmitri Tikhonov { 16550aadb33SDmitri Tikhonov s_ccsbuf = lsquic_str_new(NULL, 0); 16650aadb33SDmitri Tikhonov for (i=0 ;i<common_certs_num; ++i) 16750aadb33SDmitri Tikhonov { 16850aadb33SDmitri Tikhonov lsquic_str_append(s_ccsbuf, (const char *)&common_cert_set[i].hash, 8); 16950aadb33SDmitri Tikhonov } 17050aadb33SDmitri Tikhonov } 17150aadb33SDmitri Tikhonov return s_ccsbuf; 17250aadb33SDmitri Tikhonov} 17350aadb33SDmitri Tikhonov 17450aadb33SDmitri Tikhonov 17550aadb33SDmitri Tikhonov/* return 0 found, -1 not found */ 17650aadb33SDmitri Tikhonovint get_common_cert(uint64_t hash, uint32_t index, lsquic_str_t *buf) 17750aadb33SDmitri Tikhonov{ 17850aadb33SDmitri Tikhonov int i; 17950aadb33SDmitri Tikhonov for (i = 0; i < common_certs_num; i++) 18050aadb33SDmitri Tikhonov { 18150aadb33SDmitri Tikhonov if (common_cert_set[i].hash == hash) 18250aadb33SDmitri Tikhonov { 18350aadb33SDmitri Tikhonov if (index < common_cert_set[i].num_certs) 18450aadb33SDmitri Tikhonov { 18550aadb33SDmitri Tikhonov lsquic_str_setto(buf, (const char *) common_cert_set[i].certs[index], 18650aadb33SDmitri Tikhonov common_cert_set[i].lens[index]); 18750aadb33SDmitri Tikhonov return 0; 18850aadb33SDmitri Tikhonov } 18950aadb33SDmitri Tikhonov break; 19050aadb33SDmitri Tikhonov } 19150aadb33SDmitri Tikhonov } 19250aadb33SDmitri Tikhonov return -1; 19350aadb33SDmitri Tikhonov} 19450aadb33SDmitri Tikhonov 19550aadb33SDmitri Tikhonov 19650aadb33SDmitri Tikhonov/* result is written to dict */ 19750aadb33SDmitri Tikhonovstatic void 19850aadb33SDmitri Tikhonovmake_zlib_dict_for_entries(cert_entry_t *entries, 19950aadb33SDmitri Tikhonov lsquic_str_t **certs, size_t certs_count, 20050aadb33SDmitri Tikhonov lsquic_str_t *dict) 20150aadb33SDmitri Tikhonov{ 20250aadb33SDmitri Tikhonov int i; 20350aadb33SDmitri Tikhonov size_t zlib_dict_size = 0; 20450aadb33SDmitri Tikhonov for (i = certs_count - 1; i >= 0; --i) 20550aadb33SDmitri Tikhonov { 20650aadb33SDmitri Tikhonov if (entries[i].type != ENTRY_COMPRESSED) 20750aadb33SDmitri Tikhonov { 20850aadb33SDmitri Tikhonov zlib_dict_size += lsquic_str_len(certs[i]); 20950aadb33SDmitri Tikhonov } 21050aadb33SDmitri Tikhonov } 21150aadb33SDmitri Tikhonov 21250aadb33SDmitri Tikhonov // At the end of the dictionary is a block of common certificate substrings. 21350aadb33SDmitri Tikhonov zlib_dict_size += sizeof(common_cert_sub_strings); 21450aadb33SDmitri Tikhonov 21550aadb33SDmitri Tikhonov for (i = certs_count - 1; i >= 0; --i) 21650aadb33SDmitri Tikhonov { 21750aadb33SDmitri Tikhonov if (entries[i].type != ENTRY_COMPRESSED) 21850aadb33SDmitri Tikhonov { 21950aadb33SDmitri Tikhonov lsquic_str_append(dict, lsquic_str_buf(certs[i]), lsquic_str_len(certs[i])); 22050aadb33SDmitri Tikhonov } 22150aadb33SDmitri Tikhonov } 22250aadb33SDmitri Tikhonov 22350aadb33SDmitri Tikhonov lsquic_str_append(dict, (const char *)common_cert_sub_strings, sizeof(common_cert_sub_strings)); 22450aadb33SDmitri Tikhonov assert((size_t)lsquic_str_len(dict) == zlib_dict_size); 22550aadb33SDmitri Tikhonov} 22650aadb33SDmitri Tikhonov 22750aadb33SDmitri Tikhonov 22850aadb33SDmitri Tikhonovvoid get_certs_hash(lsquic_str_t *certs, size_t certs_count, uint64_t *hashs) 22950aadb33SDmitri Tikhonov{ 23050aadb33SDmitri Tikhonov size_t i; 23150aadb33SDmitri Tikhonov for(i = 0; i < certs_count; ++i) 23250aadb33SDmitri Tikhonov { 23350aadb33SDmitri Tikhonov hashs[i] = fnv1a_64((const uint8_t *)lsquic_str_buf(&certs[i]), lsquic_str_len(&certs[i])); 23450aadb33SDmitri Tikhonov } 23550aadb33SDmitri Tikhonov} 23650aadb33SDmitri Tikhonov 23750aadb33SDmitri Tikhonov 23850aadb33SDmitri Tikhonovsize_t get_entries_size(cert_entry_t *entries, size_t entries_count) 23950aadb33SDmitri Tikhonov{ 24050aadb33SDmitri Tikhonov size_t i; 24150aadb33SDmitri Tikhonov size_t entries_size = 0; 24250aadb33SDmitri Tikhonov for(i=0; i<entries_count; ++i) 24350aadb33SDmitri Tikhonov { 24450aadb33SDmitri Tikhonov entries_size++; 24550aadb33SDmitri Tikhonov switch (entries[i].type) 24650aadb33SDmitri Tikhonov { 24750aadb33SDmitri Tikhonov case ENTRY_COMPRESSED: 24850aadb33SDmitri Tikhonov break; 24950aadb33SDmitri Tikhonov case ENTRY_CACHED: 25050aadb33SDmitri Tikhonov entries_size += sizeof(uint64_t); 25150aadb33SDmitri Tikhonov break; 25250aadb33SDmitri Tikhonov case ENTRY_COMMON: 25350aadb33SDmitri Tikhonov entries_size += sizeof(uint64_t) + sizeof(uint32_t); 25450aadb33SDmitri Tikhonov break; 25550aadb33SDmitri Tikhonov default: 25650aadb33SDmitri Tikhonov break; 25750aadb33SDmitri Tikhonov } 25850aadb33SDmitri Tikhonov } 25950aadb33SDmitri Tikhonov entries_size++; /* for end marker */ 26050aadb33SDmitri Tikhonov return entries_size; 26150aadb33SDmitri Tikhonov} 26250aadb33SDmitri Tikhonov 26350aadb33SDmitri Tikhonov 26450aadb33SDmitri Tikhonovvoid serialize_cert_entries(uint8_t* out, int *out_len, cert_entry_t *entries, 26550aadb33SDmitri Tikhonov size_t entries_count) 26650aadb33SDmitri Tikhonov{ 26750aadb33SDmitri Tikhonov size_t i; 26850aadb33SDmitri Tikhonov uint8_t *start = out; 26950aadb33SDmitri Tikhonov for(i=0; i<entries_count; ++i) 27050aadb33SDmitri Tikhonov { 27150aadb33SDmitri Tikhonov *out++ = (uint8_t)(entries[i].type); 27250aadb33SDmitri Tikhonov switch (entries[i].type) 27350aadb33SDmitri Tikhonov { 27450aadb33SDmitri Tikhonov case ENTRY_COMPRESSED: 27550aadb33SDmitri Tikhonov break; 27650aadb33SDmitri Tikhonov case ENTRY_CACHED: 27750aadb33SDmitri Tikhonov memcpy(out, &entries[i].hash, sizeof(uint64_t)); 27850aadb33SDmitri Tikhonov out += sizeof(uint64_t); 27950aadb33SDmitri Tikhonov break; 28050aadb33SDmitri Tikhonov case ENTRY_COMMON: 28150aadb33SDmitri Tikhonov memcpy(out, &entries[i].set_hash, sizeof(uint64_t)); 28250aadb33SDmitri Tikhonov out += sizeof(uint64_t); 28350aadb33SDmitri Tikhonov memcpy(out, &entries[i].index, sizeof(uint32_t)); 28450aadb33SDmitri Tikhonov out += sizeof(uint32_t); 28550aadb33SDmitri Tikhonov break; 28650aadb33SDmitri Tikhonov default: 28750aadb33SDmitri Tikhonov break; 28850aadb33SDmitri Tikhonov } 28950aadb33SDmitri Tikhonov } 29050aadb33SDmitri Tikhonov 29150aadb33SDmitri Tikhonov *out++ = 0; // end marker 29250aadb33SDmitri Tikhonov *out_len = out - start; 29350aadb33SDmitri Tikhonov} 29450aadb33SDmitri Tikhonov 29550aadb33SDmitri Tikhonov 29650aadb33SDmitri Tikhonovint get_certs_count(lsquic_str_t *compressed_crt_buf) 29750aadb33SDmitri Tikhonov{ 29850aadb33SDmitri Tikhonov char *in = lsquic_str_buf(compressed_crt_buf); 29950aadb33SDmitri Tikhonov char *in_end = in + lsquic_str_len(compressed_crt_buf); 30050aadb33SDmitri Tikhonov size_t idx = 0; 30150aadb33SDmitri Tikhonov uint8_t type_byte; 30250aadb33SDmitri Tikhonov 30350aadb33SDmitri Tikhonov for (;;) 30450aadb33SDmitri Tikhonov { 30550aadb33SDmitri Tikhonov if (in >= in_end) 30650aadb33SDmitri Tikhonov return -1; 30750aadb33SDmitri Tikhonov 30850aadb33SDmitri Tikhonov type_byte = in[0]; 30950aadb33SDmitri Tikhonov ++in; 31050aadb33SDmitri Tikhonov if (type_byte == 0) 31150aadb33SDmitri Tikhonov break; 31250aadb33SDmitri Tikhonov 31350aadb33SDmitri Tikhonov ++idx; 31450aadb33SDmitri Tikhonov switch(type_byte) 31550aadb33SDmitri Tikhonov { 31650aadb33SDmitri Tikhonov case ENTRY_COMPRESSED: 31750aadb33SDmitri Tikhonov break; 31850aadb33SDmitri Tikhonov case ENTRY_CACHED: 31950aadb33SDmitri Tikhonov { 32050aadb33SDmitri Tikhonov if (in_end - in < (int)sizeof(uint64_t)) 32150aadb33SDmitri Tikhonov return -1; 32250aadb33SDmitri Tikhonov in += sizeof(uint64_t); 32350aadb33SDmitri Tikhonov break; 32450aadb33SDmitri Tikhonov } 32550aadb33SDmitri Tikhonov case ENTRY_COMMON: 32650aadb33SDmitri Tikhonov { 32750aadb33SDmitri Tikhonov if (in_end - in < (int)(sizeof(uint64_t) + sizeof(uint32_t))) 32850aadb33SDmitri Tikhonov return -1; 32950aadb33SDmitri Tikhonov in += sizeof(uint64_t) + sizeof(uint32_t); 33050aadb33SDmitri Tikhonov break; 33150aadb33SDmitri Tikhonov } 33250aadb33SDmitri Tikhonov default: 33350aadb33SDmitri Tikhonov return -1; 33450aadb33SDmitri Tikhonov } 33550aadb33SDmitri Tikhonov } 33650aadb33SDmitri Tikhonov return idx; 33750aadb33SDmitri Tikhonov} 33850aadb33SDmitri Tikhonov 33950aadb33SDmitri Tikhonov 34050aadb33SDmitri Tikhonov/* return 0: OK, -1, error */ 34150aadb33SDmitri Tikhonovstatic int parse_entries(const unsigned char **in_out, const unsigned char *const in_end, 34250aadb33SDmitri Tikhonov lsquic_str_t *cached_certs, size_t cached_certs_count, 34350aadb33SDmitri Tikhonov cert_entry_t *out_entries, 34450aadb33SDmitri Tikhonov lsquic_str_t **out_certs, size_t *out_certs_count) 34550aadb33SDmitri Tikhonov{ 34650aadb33SDmitri Tikhonov const unsigned char *in = *in_out; 34750aadb33SDmitri Tikhonov size_t idx = 0; 34850aadb33SDmitri Tikhonov uint64_t* cached_hashes; 34950aadb33SDmitri Tikhonov cert_entry_t *entry; 35050aadb33SDmitri Tikhonov lsquic_str_t *cert; 35150aadb33SDmitri Tikhonov uint8_t type_byte; 35250aadb33SDmitri Tikhonov int rv; 35350aadb33SDmitri Tikhonov size_t i; 35450aadb33SDmitri Tikhonov 35550aadb33SDmitri Tikhonov cached_hashes = NULL; 35650aadb33SDmitri Tikhonov 35750aadb33SDmitri Tikhonov for (;;) 35850aadb33SDmitri Tikhonov { 35950aadb33SDmitri Tikhonov /* XXX potential invalid read */ 36050aadb33SDmitri Tikhonov type_byte = in[0]; 36150aadb33SDmitri Tikhonov ++in; 36250aadb33SDmitri Tikhonov 36350aadb33SDmitri Tikhonov if (type_byte == 0) 36450aadb33SDmitri Tikhonov break; 36550aadb33SDmitri Tikhonov 36650aadb33SDmitri Tikhonov entry = &out_entries[idx]; 36750aadb33SDmitri Tikhonov cert = out_certs[idx]; 36850aadb33SDmitri Tikhonov /* XXX This seems dangerous -- there is no guard that `idx' does not 36950aadb33SDmitri Tikhonov * exceed `out_certs_count'. 37050aadb33SDmitri Tikhonov */ 37150aadb33SDmitri Tikhonov lsquic_str_d(cert); 37250aadb33SDmitri Tikhonov 37350aadb33SDmitri Tikhonov ++idx; 37450aadb33SDmitri Tikhonov entry->type = type_byte; 37550aadb33SDmitri Tikhonov switch (entry->type) 37650aadb33SDmitri Tikhonov { 37750aadb33SDmitri Tikhonov case ENTRY_COMPRESSED: 37850aadb33SDmitri Tikhonov break; 37950aadb33SDmitri Tikhonov case ENTRY_CACHED: 38050aadb33SDmitri Tikhonov { 38150aadb33SDmitri Tikhonov memcpy(&entry->hash, in, sizeof(uint64_t)); 38250aadb33SDmitri Tikhonov in += sizeof(uint64_t); 38350aadb33SDmitri Tikhonov 38450aadb33SDmitri Tikhonov if (!cached_hashes) 38550aadb33SDmitri Tikhonov { 38650aadb33SDmitri Tikhonov cached_hashes = malloc(cached_certs_count * sizeof(uint64_t));; 38750aadb33SDmitri Tikhonov if (!cached_hashes) 38850aadb33SDmitri Tikhonov goto err; 38950aadb33SDmitri Tikhonov get_certs_hash(cached_certs, cached_certs_count, cached_hashes); 39050aadb33SDmitri Tikhonov } 39150aadb33SDmitri Tikhonov 39250aadb33SDmitri Tikhonov for (i=0; i<cached_certs_count; ++i) 39350aadb33SDmitri Tikhonov { 39450aadb33SDmitri Tikhonov if (cached_hashes[i] == entry->hash) 39550aadb33SDmitri Tikhonov { 39650aadb33SDmitri Tikhonov lsquic_str_append(cert, lsquic_str_buf(&cached_certs[i]), 39750aadb33SDmitri Tikhonov lsquic_str_len(&cached_certs[i])); 39850aadb33SDmitri Tikhonov break; 39950aadb33SDmitri Tikhonov } 40050aadb33SDmitri Tikhonov } 40150aadb33SDmitri Tikhonov /* XXX: return -1 if not found? Logic removed in 40250aadb33SDmitri Tikhonov 4fd7e76bc031ac637e76c7f0930aff53f5b71705 */ 40350aadb33SDmitri Tikhonov break; 40450aadb33SDmitri Tikhonov } 40550aadb33SDmitri Tikhonov case ENTRY_COMMON: 40650aadb33SDmitri Tikhonov { 40750aadb33SDmitri Tikhonov memcpy(&entry->set_hash, in, sizeof(uint64_t)); 40850aadb33SDmitri Tikhonov in += sizeof(uint64_t); 40950aadb33SDmitri Tikhonov memcpy(&entry->index, in, sizeof(uint32_t)); 41050aadb33SDmitri Tikhonov in += sizeof(uint32_t); 41150aadb33SDmitri Tikhonov 41250aadb33SDmitri Tikhonov if (0 == get_common_cert(entry->set_hash, entry->index, cert)) 41350aadb33SDmitri Tikhonov break; 41450aadb33SDmitri Tikhonov else 41550aadb33SDmitri Tikhonov goto err; 41650aadb33SDmitri Tikhonov } 41750aadb33SDmitri Tikhonov default: 41850aadb33SDmitri Tikhonov goto err; 41950aadb33SDmitri Tikhonov } 42050aadb33SDmitri Tikhonov } 42150aadb33SDmitri Tikhonov 42250aadb33SDmitri Tikhonov rv = 0; 42350aadb33SDmitri Tikhonov *in_out = in; 42450aadb33SDmitri Tikhonov *out_certs_count = idx; 42550aadb33SDmitri Tikhonov 42650aadb33SDmitri Tikhonov cleanup: 42750aadb33SDmitri Tikhonov free(cached_hashes); 42850aadb33SDmitri Tikhonov return rv; 42950aadb33SDmitri Tikhonov 43050aadb33SDmitri Tikhonov err: 43150aadb33SDmitri Tikhonov rv = -1; 43250aadb33SDmitri Tikhonov goto cleanup; 43350aadb33SDmitri Tikhonov} 43450aadb33SDmitri Tikhonov 43550aadb33SDmitri Tikhonov 43650aadb33SDmitri Tikhonov/* 0: ok */ 43750aadb33SDmitri Tikhonovint decompress_certs(const unsigned char *in, const unsigned char *in_end, 43850aadb33SDmitri Tikhonov lsquic_str_t *cached_certs, size_t cached_certs_count, 43950aadb33SDmitri Tikhonov lsquic_str_t **out_certs, size_t *out_certs_count) 44050aadb33SDmitri Tikhonov{ 44150aadb33SDmitri Tikhonov int ret; 44250aadb33SDmitri Tikhonov size_t i; 44350aadb33SDmitri Tikhonov uint8_t* uncompressed_data, *uncompressed_data_buf; 44450aadb33SDmitri Tikhonov lsquic_str_t *dict; 44550aadb33SDmitri Tikhonov uint32_t uncompressed_size; 44650aadb33SDmitri Tikhonov size_t count = *out_certs_count; 44750aadb33SDmitri Tikhonov cert_entry_t *entries; 44850aadb33SDmitri Tikhonov z_stream z; 44950aadb33SDmitri Tikhonov 45050aadb33SDmitri Tikhonov assert(*out_certs_count > 0 && *out_certs_count < 10000 45150aadb33SDmitri Tikhonov && "Call get_certs_count() to get right certificates count first and make enough room for out_certs_count"); 45250aadb33SDmitri Tikhonov 45350aadb33SDmitri Tikhonov if (count == 0 || count > 10000) 45450aadb33SDmitri Tikhonov return -1; 45550aadb33SDmitri Tikhonov 45650aadb33SDmitri Tikhonov dict = lsquic_str_new(NULL, 0); 45750aadb33SDmitri Tikhonov if (!dict) 45850aadb33SDmitri Tikhonov return -1; 45950aadb33SDmitri Tikhonov 46050aadb33SDmitri Tikhonov uncompressed_data_buf = NULL; 46150aadb33SDmitri Tikhonov entries = malloc(count * sizeof(cert_entry_t)); 46250aadb33SDmitri Tikhonov if (!entries) 46350aadb33SDmitri Tikhonov goto err; 46450aadb33SDmitri Tikhonov 46550aadb33SDmitri Tikhonov ret = parse_entries(&in, in_end, cached_certs, cached_certs_count, 46650aadb33SDmitri Tikhonov entries, out_certs, out_certs_count); 46750aadb33SDmitri Tikhonov if (ret) 46850aadb33SDmitri Tikhonov goto err; 46950aadb33SDmitri Tikhonov 47050aadb33SDmitri Tikhonov /* re-assign count with real valus */ 47150aadb33SDmitri Tikhonov count = *out_certs_count; 47250aadb33SDmitri Tikhonov 47350aadb33SDmitri Tikhonov if (in < in_end) 47450aadb33SDmitri Tikhonov { 47550aadb33SDmitri Tikhonov if (in_end - in < (int)sizeof(uint32_t)) 47650aadb33SDmitri Tikhonov goto err; 47750aadb33SDmitri Tikhonov 47850aadb33SDmitri Tikhonov memcpy(&uncompressed_size, in, sizeof(uncompressed_size)); 47950aadb33SDmitri Tikhonov in += sizeof(uint32_t); 48050aadb33SDmitri Tikhonov /* XXX Is 128 KB an arbitrary limit or is there a reason behind it? */ 48150aadb33SDmitri Tikhonov if (uncompressed_size > 128 * 1024) 48250aadb33SDmitri Tikhonov goto err; 48350aadb33SDmitri Tikhonov 48450aadb33SDmitri Tikhonov uncompressed_data_buf = uncompressed_data = malloc(uncompressed_size); 48550aadb33SDmitri Tikhonov memset(&z, 0, sizeof(z)); 48650aadb33SDmitri Tikhonov z.next_out = uncompressed_data; 48750aadb33SDmitri Tikhonov z.avail_out = uncompressed_size; 48850aadb33SDmitri Tikhonov z.next_in = (unsigned char *) in; 48950aadb33SDmitri Tikhonov z.avail_in = in_end - in; 49050aadb33SDmitri Tikhonov 49150aadb33SDmitri Tikhonov if (Z_OK != inflateInit(&z)) 49250aadb33SDmitri Tikhonov goto err; 49350aadb33SDmitri Tikhonov 49450aadb33SDmitri Tikhonov ret = inflate(&z, Z_FINISH); 49550aadb33SDmitri Tikhonov if (ret == Z_NEED_DICT) 49650aadb33SDmitri Tikhonov { 49750aadb33SDmitri Tikhonov lsquic_str_d(dict); 49850aadb33SDmitri Tikhonov make_zlib_dict_for_entries(entries, out_certs, count, dict); 49950aadb33SDmitri Tikhonov if (Z_OK != inflateSetDictionary(&z, (const unsigned char *)lsquic_str_buf(dict), lsquic_str_len(dict))) 50050aadb33SDmitri Tikhonov goto err; 50150aadb33SDmitri Tikhonov ret = inflate(&z, Z_FINISH); 50250aadb33SDmitri Tikhonov } 50350aadb33SDmitri Tikhonov 50450aadb33SDmitri Tikhonov if (Z_STREAM_END != ret || z.avail_out > 0 || z.avail_in > 0) 50550aadb33SDmitri Tikhonov goto err; 50650aadb33SDmitri Tikhonov } 50750aadb33SDmitri Tikhonov else 50850aadb33SDmitri Tikhonov uncompressed_size = 0; 50950aadb33SDmitri Tikhonov 51050aadb33SDmitri Tikhonov for (i = 0; i < count; i++) 51150aadb33SDmitri Tikhonov { 51250aadb33SDmitri Tikhonov switch (entries[i].type) 51350aadb33SDmitri Tikhonov { 51450aadb33SDmitri Tikhonov case ENTRY_COMPRESSED: 51550aadb33SDmitri Tikhonov if (uncompressed_size < sizeof(uint32_t)) 51650aadb33SDmitri Tikhonov goto err; 51750aadb33SDmitri Tikhonov lsquic_str_d(out_certs[i]); 51850aadb33SDmitri Tikhonov uint32_t cert_len; 51950aadb33SDmitri Tikhonov memcpy(&cert_len, uncompressed_data, sizeof(cert_len)); 52050aadb33SDmitri Tikhonov uncompressed_data += sizeof(uint32_t); 52150aadb33SDmitri Tikhonov uncompressed_size -= sizeof(uint32_t); 52250aadb33SDmitri Tikhonov if (uncompressed_size < cert_len) 52350aadb33SDmitri Tikhonov goto err; 52450aadb33SDmitri Tikhonov lsquic_str_append(out_certs[i], (const char *)uncompressed_data, cert_len); 52550aadb33SDmitri Tikhonov uncompressed_data += cert_len; 52650aadb33SDmitri Tikhonov uncompressed_size -= cert_len; 52750aadb33SDmitri Tikhonov break; 52850aadb33SDmitri Tikhonov case ENTRY_CACHED: 52950aadb33SDmitri Tikhonov case ENTRY_COMMON: 53050aadb33SDmitri Tikhonov default: 53150aadb33SDmitri Tikhonov break; 53250aadb33SDmitri Tikhonov } 53350aadb33SDmitri Tikhonov } 53450aadb33SDmitri Tikhonov 53550aadb33SDmitri Tikhonov cleanup: 53650aadb33SDmitri Tikhonov lsquic_str_delete(dict); 53750aadb33SDmitri Tikhonov free(entries); 53850aadb33SDmitri Tikhonov if (uncompressed_data_buf) 53950aadb33SDmitri Tikhonov inflateEnd(&z); 54050aadb33SDmitri Tikhonov free(uncompressed_data_buf); 54150aadb33SDmitri Tikhonov if (0 == uncompressed_size) 54250aadb33SDmitri Tikhonov return 0; 54350aadb33SDmitri Tikhonov else 54450aadb33SDmitri Tikhonov return -1; 54550aadb33SDmitri Tikhonov 54650aadb33SDmitri Tikhonov err: 54750aadb33SDmitri Tikhonov uncompressed_size = 1; /* This triggers return -1 above */ 54850aadb33SDmitri Tikhonov goto cleanup; 54950aadb33SDmitri Tikhonov} 55050aadb33SDmitri Tikhonov 55150aadb33SDmitri Tikhonov 55250aadb33SDmitri Tikhonovvoid 55350aadb33SDmitri Tikhonovlsquic_crt_cleanup (void) 55450aadb33SDmitri Tikhonov{ 55550aadb33SDmitri Tikhonov if (s_ccsbuf) 55650aadb33SDmitri Tikhonov { 55750aadb33SDmitri Tikhonov lsquic_str_delete(s_ccsbuf); 55850aadb33SDmitri Tikhonov s_ccsbuf = NULL; 55950aadb33SDmitri Tikhonov } 56050aadb33SDmitri Tikhonov} 56150aadb33SDmitri Tikhonov 56250aadb33SDmitri Tikhonov 563