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.crypto.impl;
019
020
021import java.security.PrivateKey;
022import java.security.interfaces.RSAPrivateKey;
023
024import com.nimbusds.jose.JOSEException;
025import com.nimbusds.jose.jwk.RSAKey;
026
027
028/**
029 * RSA JWK conversion utility.
030 */
031public class RSAKeyUtils {
032        
033        
034        /**
035         * Returns the private RSA key of the specified RSA JWK. Supports
036         * PKCS#11 keys stores.
037         *
038         * @param rsaJWK The RSA JWK. Must not be {@code null}.
039         *
040         * @return The private RSA key.
041         *
042         * @throws JOSEException If the RSA JWK doesn't contain a private part.
043         */
044        public static PrivateKey toRSAPrivateKey(final RSAKey rsaJWK)
045                throws JOSEException {
046                
047                if (! rsaJWK.isPrivate()) {
048                        throw new JOSEException("The RSA JWK doesn't contain a private part");
049                }
050                
051                return rsaJWK.toPrivateKey();
052        }
053        
054        
055        /**
056         * Returns the length in bits of the specified RSA private key.
057         *
058         * @param privateKey The RSA private key. Must not be {@code null}.
059         *
060         * @return The key length in bits, -1 if the length couldn't be
061         *         determined, e.g. for a PKCS#11 backed key which doesn't
062         *         expose an RSAPrivateKey interface or support the
063         *         {@code getModulus()} method.
064         */
065        public static int keyBitLength(final PrivateKey privateKey) {
066                
067                if (! (privateKey instanceof RSAPrivateKey)) {
068                        return -1; // May be an PKCS#11 backed key
069                }
070                
071                RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)privateKey;
072                
073                try {
074                        return rsaPrivateKey.getModulus().bitLength();
075                } catch (Exception e) {
076                        // Some PKCS#11 backed keys still have the
077                        // RSAPrivateKey interface, but will throw an exception
078                        // here
079                        return -1;
080                }
081        }
082}