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.netty.handler.ssl;
17
18 import io.netty.util.internal.ObjectUtil;
19
20 import java.util.ArrayList;
21 import java.util.Arrays;
22 import java.util.Collections;
23 import java.util.Iterator;
24 import java.util.List;
25
26 /**
27 * Configuration for TLS1.3 certificate compression extension.
28 */
29 public final class OpenSslCertificateCompressionConfig implements
30 Iterable<OpenSslCertificateCompressionConfig.AlgorithmConfig> {
31 private final List<AlgorithmConfig> pairList;
32
33 private OpenSslCertificateCompressionConfig(AlgorithmConfig... pairs) {
34 pairList = Collections.unmodifiableList(Arrays.asList(pairs));
35 }
36
37 @Override
38 public Iterator<AlgorithmConfig> iterator() {
39 return pairList.iterator();
40 }
41
42 /**
43 * Creates a new {@link Builder} for a config.
44 *
45 * @return a bulder
46 */
47 public static Builder newBuilder() {
48 return new Builder();
49 }
50
51 /**
52 * Builder for an {@link OpenSslCertificateCompressionAlgorithm}.
53 */
54 public static final class Builder {
55 private final List<AlgorithmConfig> algorithmList = new ArrayList<AlgorithmConfig>();
56
57 private Builder() { }
58
59 /**
60 * Adds a certificate compression algorithm.
61 * For servers, algorithm preference order is dictated by the order of algorithm registration.
62 * Most preferred algorithm should be registered first.
63 *
64 * @param algorithm implementation of the compression and or decompression algorithm as a
65 * {@link OpenSslCertificateCompressionAlgorithm}
66 * @param mode indicates whether decompression support should be advertized, compression should be applied
67 * for peers which support it, or both. This allows the caller to support one way compression
68 * only.
69 * @return self.
70 */
71 public Builder addAlgorithm(OpenSslCertificateCompressionAlgorithm algorithm, AlgorithmMode mode) {
72 algorithmList.add(new AlgorithmConfig(algorithm, mode));
73 return this;
74 }
75
76 /**
77 * Build a new {@link OpenSslCertificateCompressionConfig} based on the previous
78 * added {@link OpenSslCertificateCompressionAlgorithm}s.
79 *
80 * @return a new config.
81 */
82 public OpenSslCertificateCompressionConfig build() {
83 return new OpenSslCertificateCompressionConfig(algorithmList.toArray(new AlgorithmConfig[0]));
84 }
85 }
86
87 /**
88 * The configuration for algorithm.
89 */
90 public static final class AlgorithmConfig {
91 private final OpenSslCertificateCompressionAlgorithm algorithm;
92 private final AlgorithmMode mode;
93
94 private AlgorithmConfig(OpenSslCertificateCompressionAlgorithm algorithm, AlgorithmMode mode) {
95 this.algorithm = ObjectUtil.checkNotNull(algorithm, "algorithm");
96 this.mode = ObjectUtil.checkNotNull(mode, "mode");
97 }
98
99 /**
100 * The {@link AlgorithmMode}
101 *
102 * @return the usage mode.
103 */
104 public AlgorithmMode mode() {
105 return mode;
106 }
107
108 /**
109 * The configured {@link OpenSslCertificateCompressionAlgorithm}.
110 *
111 * @return the algorithm
112 */
113 public OpenSslCertificateCompressionAlgorithm algorithm() {
114 return algorithm;
115 }
116 }
117
118 /**
119 * The usage mode of the {@link OpenSslCertificateCompressionAlgorithm}.
120 */
121 public enum AlgorithmMode {
122 /**
123 * Compression supported and should be advertized.
124 */
125 Compress,
126
127 /**
128 * Decompression supported and should be advertized.
129 */
130 Decompress,
131
132 /**
133 * Compression and Decompression are supported and both should be advertized.
134 */
135 Both
136 }
137 }