1 /*
2 * Copyright 2022 The Netty Project
3 *
4 * The Netty Project licenses this file to you under the Apache License, version
5 * 2.0 (the "License"); you may not use this file except in compliance with the
6 * License. You may obtain a copy of the License at:
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
16 package io.netty5.handler.ssl;
17
18 import java.util.ArrayList;
19 import java.util.Iterator;
20 import java.util.List;
21
22 import static java.util.Objects.requireNonNull;
23
24 /**
25 * Configuration for TLS1.3 certificate compression extension.
26 */
27 public final class OpenSslCertificateCompressionConfig implements
28 Iterable<OpenSslCertificateCompressionConfig.AlgorithmConfig> {
29 private final List<AlgorithmConfig> pairList;
30
31 private OpenSslCertificateCompressionConfig(AlgorithmConfig... pairs) {
32 pairList = List.of(pairs);
33 }
34
35 @Override
36 public Iterator<AlgorithmConfig> iterator() {
37 return pairList.iterator();
38 }
39
40 /**
41 * Creates a new {@link Builder} for a config.
42 *
43 * @return a builder
44 */
45 public static Builder newBuilder() {
46 return new Builder();
47 }
48
49 /**
50 * Builder for an {@link OpenSslCertificateCompressionAlgorithm}.
51 */
52 public static final class Builder {
53 private final List<AlgorithmConfig> algorithmList = new ArrayList<>();
54
55 private Builder() { }
56
57 /**
58 * Adds a certificate compression algorithm.
59 * For servers, algorithm preference order is dictated by the order of algorithm registration.
60 * Most preferred algorithm should be registered first.
61 *
62 * @param algorithm implementation of the compression and or decompression algorithm as a
63 * {@link OpenSslCertificateCompressionAlgorithm}
64 * @param mode indicates whether decompression support should be advertized, compression should be applied
65 * for peers which support it, or both. This allows the caller to support one way compression
66 * only.
67 * @return self.
68 */
69 public Builder addAlgorithm(OpenSslCertificateCompressionAlgorithm algorithm, AlgorithmMode mode) {
70 algorithmList.add(new AlgorithmConfig(algorithm, mode));
71 return this;
72 }
73
74 /**
75 * Build a new {@link OpenSslCertificateCompressionConfig} based on the previous
76 * added {@link OpenSslCertificateCompressionAlgorithm}s.
77 *
78 * @return a new config.
79 */
80 public OpenSslCertificateCompressionConfig build() {
81 return new OpenSslCertificateCompressionConfig(algorithmList.toArray(AlgorithmConfig[]::new));
82 }
83 }
84
85 /**
86 * The configuration for the algorithm.
87 */
88 public static final class AlgorithmConfig {
89 private final OpenSslCertificateCompressionAlgorithm algorithm;
90 private final AlgorithmMode mode;
91
92 private AlgorithmConfig(OpenSslCertificateCompressionAlgorithm algorithm, AlgorithmMode mode) {
93 this.algorithm = requireNonNull(algorithm, "algorithm");
94 this.mode = requireNonNull(mode, "mode");
95 }
96
97 /**
98 * The {@link AlgorithmMode}
99 *
100 * @return the usage mode.
101 */
102 public AlgorithmMode mode() {
103 return mode;
104 }
105
106 /**
107 * The configured {@link OpenSslCertificateCompressionAlgorithm}.
108 *
109 * @return the algorithm
110 */
111 public OpenSslCertificateCompressionAlgorithm algorithm() {
112 return algorithm;
113 }
114 }
115
116 /**
117 * The usage mode of the {@link OpenSslCertificateCompressionAlgorithm}.
118 */
119 public enum AlgorithmMode {
120 /**
121 * Compression supported and should be advertised.
122 */
123 Compress,
124
125 /**
126 * Decompression supported and should be advertised.
127 */
128 Decompress,
129
130 /**
131 * Compression and Decompression are supported and both should be advertised.
132 */
133 Both
134 }
135 }