001/*
002 * nimbus-jose-jwt
003 *
004 * Copyright 2012-2016, 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.jwk.gen;
019
020
021import java.security.SecureRandom;
022
023import com.nimbusds.jose.JOSEException;
024import com.nimbusds.jose.jwk.OctetSequenceKey;
025import com.nimbusds.jose.util.Base64URL;
026
027
028/**
029 * Octet sequence JSON Web Key (JWK) generator.
030 *
031 * @author Vladimir Dzhuvinov
032 * @version 2018-07-20
033 */
034public class OctetSequenceKeyGenerator extends JWKGenerator<OctetSequenceKey> {
035        
036        
037        /**
038         * The minimum size of generated keys.
039         */
040        public static final int MIN_KEY_SIZE_BITS = 112;
041        
042        
043        /**
044         * The key size, in bits.
045         */
046        private final int size;
047        
048        
049        /**
050         * The secure random generator to use, {@code null} to use the default
051         * one.
052         */
053        private SecureRandom secureRandom;
054        
055        
056        /**
057         * Creates a new octet sequence JWK generator.
058         *
059         * @param size The key size, in bits. Must be at least 112 bits long
060         *             for sufficient entropy.
061         */
062        public OctetSequenceKeyGenerator(final int size) {
063                if (size < MIN_KEY_SIZE_BITS) {
064                        throw new IllegalArgumentException("The key size must be at least " + MIN_KEY_SIZE_BITS + " bits");
065                }
066                if (size % 8 != 0) {
067                        throw new IllegalArgumentException("The key size in bits must be divisible by 8");
068                }
069                this.size = size;
070        }
071        
072        
073        /**
074         * Sets the secure random generator to use.
075         *
076         * @param secureRandom The secure random generator to use, {@code null}
077         *                     to use the default one.
078         *
079         * @return This generator.
080         */
081        public OctetSequenceKeyGenerator secureRandom(final SecureRandom secureRandom) {
082                
083                this.secureRandom = secureRandom;
084                return this;
085        }
086        
087        
088        @Override
089        public OctetSequenceKey generate()
090                throws JOSEException {
091                
092                byte[] keyMaterial = new byte[size / 8];
093                
094                if (secureRandom != null) {
095                        secureRandom.nextBytes(keyMaterial);
096                } else {
097                        // The default random gen
098                        new SecureRandom().nextBytes(keyMaterial);
099                }
100                
101                OctetSequenceKey.Builder builder = new OctetSequenceKey.Builder(Base64URL.encode(keyMaterial))
102                        .keyUse(use)
103                        .keyOperations(ops)
104                        .algorithm(alg)
105                        .keyStore(keyStore);
106                
107                if (x5tKid) {
108                        builder.keyIDFromThumbprint();
109                } else {
110                        builder.keyID(kid);
111                }
112                
113                return builder.build();
114        }
115}