001/*
002 * nimbus-jose-jwt
003 *
004 * Copyright 2012-2025, Connect2id Ltd and contributors.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.jose.crypto.opts;
019
020
021import com.nimbusds.jose.JWSSignerOption;
022import com.nimbusds.jose.JWEObject;
023import com.nimbusds.jose.Option;
024import com.nimbusds.jose.crypto.impl.RSAKeyUtils;
025
026import java.security.PrivateKey;
027import java.util.Set;
028
029import static com.nimbusds.jose.jwk.gen.RSAKeyGenerator.MIN_KEY_SIZE_BITS;
030
031
032/**
033 * Utilities for processing JOSE options.
034 *
035 * @author Vladimir Dzhuvinov
036 * @version 2026-09-16
037 */
038public class OptionUtils {
039        
040        
041        /**
042         * Returns {@code true} if the specified set of options contains an
043         * instance of a class implementing {@link JWSSignerOption}.
044         *
045         * @param opts   The options set, may be {@code null}.
046         * @param tClass The class. Must not be {@code null}.
047         *
048         * @return {@code true} if an option is present, else {@code false}.
049         */
050        @Deprecated
051        public static <T extends Option> boolean optionIsPresent(final Set<? extends Option> opts, final Class<T> tClass) {
052                
053                if (opts == null || opts.isEmpty()) {
054                        return false;
055                }
056                
057                for (Option o: opts) {
058                        if (o.getClass().isAssignableFrom(tClass)) {
059                                return true;
060                        }
061                }
062                
063                return false;
064        }
065
066
067        /**
068         * Resolves the maximum decompressed plain text length from the
069         * specified options.
070         *
071         * @param opts The options, {@code null} if none.
072         *
073         * @return The maximum decompressed plain text length.
074         */
075        public static int resolveMaxDecompressedPlainTextLength(final Set<? extends Option> opts) {
076
077                if (opts != null) {
078                        for (Option opt : opts) {
079                                if (opt instanceof MaxDecompressedPlainTextLength) {
080                                        return ((MaxDecompressedPlainTextLength) opt).getMaxLength();
081                                }
082                        }
083                }
084
085                return JWEObject.MAX_DECOMPRESSED_PLAIN_TEXT_LENGTH;
086        }
087
088
089        /**
090         * Throws an {@link IllegalArgumentException} if the size of the
091         * specified RSA private key shorter than the minimum required.
092         *
093         * @param privateKey The RSA private key. Must not be {@code null}.
094         * @param opts       The options. Must not be {@code null}.
095         */
096        public static void ensureMinRSAPrivateKeySize(final PrivateKey privateKey, final Set<? extends Option> opts) {
097
098                if (! opts.contains(AllowWeakRSAKey.getInstance())) {
099
100                        int keyBitLength = RSAKeyUtils.keyBitLength(privateKey);
101
102                        if (keyBitLength > 0 && keyBitLength < MIN_KEY_SIZE_BITS) {
103                                throw new IllegalArgumentException("The RSA key size must be at least " + MIN_KEY_SIZE_BITS + " bits");
104                        }
105                }
106        }
107}