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 }