Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/crypto/provider/CipherWithWrappingSpi.java
38922 views
/*1* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.crypto.provider;2627import java.security.Key;28import java.security.PublicKey;29import java.security.PrivateKey;30import java.security.KeyFactory;31import java.security.InvalidKeyException;32import java.security.NoSuchProviderException;33import java.security.NoSuchAlgorithmException;34import java.security.spec.PKCS8EncodedKeySpec;35import java.security.spec.X509EncodedKeySpec;36import java.security.spec.InvalidKeySpecException;3738import javax.crypto.Cipher;39import javax.crypto.CipherSpi;40import javax.crypto.SecretKey;41import javax.crypto.IllegalBlockSizeException;42import javax.crypto.BadPaddingException;43import javax.crypto.spec.SecretKeySpec;4445/**46* This class entends the javax.crypto.CipherSpi class with a concrete47* implementation of the methods for wrapping and unwrapping48* keys.49*50* @author Sharon Liu51*52*53* @see javax.crypto.CipherSpi54* @see BlowfishCipher55* @see DESCipher56* @see PBEWithMD5AndDESCipher57*/5859public abstract class CipherWithWrappingSpi extends CipherSpi {6061/**62* Wrap a key.63*64* @param key the key to be wrapped.65*66* @return the wrapped key.67*68* @exception IllegalBlockSizeException if this cipher is a block69* cipher, no padding has been requested, and the length of the70* encoding of the key to be wrapped is not a71* multiple of the block size.72*73* @exception InvalidKeyException if it is impossible or unsafe to74* wrap the key with this cipher (e.g., a hardware protected key is75* being passed to a software only cipher).76*/77protected final byte[] engineWrap(Key key)78throws IllegalBlockSizeException, InvalidKeyException79{80byte[] result = null;8182try {83byte[] encodedKey = key.getEncoded();84if ((encodedKey == null) || (encodedKey.length == 0)) {85throw new InvalidKeyException("Cannot get an encoding of " +86"the key to be wrapped");87}8889result = engineDoFinal(encodedKey, 0, encodedKey.length);90} catch (BadPaddingException e) {91// Should never happen92}9394return result;95}9697/**98* Unwrap a previously wrapped key.99*100* @param wrappedKey the key to be unwrapped.101*102* @param wrappedKeyAlgorithm the algorithm the wrapped key is for.103*104* @param wrappedKeyType the type of the wrapped key.105* This is one of <code>Cipher.SECRET_KEY</code>,106* <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>.107*108* @return the unwrapped key.109*110* @exception InvalidKeyException if <code>wrappedKey</code> does not111* represent a wrapped key, or if the algorithm associated with the112* wrapped key is different from <code>wrappedKeyAlgorithm</code>113* and/or its key type is different from <code>wrappedKeyType</code>.114*115* @exception NoSuchAlgorithmException if no installed providers116* can create keys for the <code>wrappedKeyAlgorithm</code>.117*/118protected final Key engineUnwrap(byte[] wrappedKey,119String wrappedKeyAlgorithm,120int wrappedKeyType)121throws InvalidKeyException, NoSuchAlgorithmException122{123byte[] encodedKey;124Key result = null;125126try {127encodedKey = engineDoFinal(wrappedKey, 0,128wrappedKey.length);129} catch (BadPaddingException ePadding) {130throw new InvalidKeyException();131} catch (IllegalBlockSizeException eBlockSize) {132throw new InvalidKeyException();133}134135switch (wrappedKeyType) {136case Cipher.SECRET_KEY:137result = constructSecretKey(encodedKey,138wrappedKeyAlgorithm);139break;140case Cipher.PRIVATE_KEY:141result = constructPrivateKey(encodedKey,142wrappedKeyAlgorithm);143break;144case Cipher.PUBLIC_KEY:145result = constructPublicKey(encodedKey,146wrappedKeyAlgorithm);147break;148}149150return result;151152}153154/**155* Construct a public key from its encoding.156*157* @param encodedKey the encoding of a public key.158*159* @param encodedKeyAlgorithm the algorithm the encodedKey is for.160*161* @return a public key constructed from the encodedKey.162*/163private final PublicKey constructPublicKey(byte[] encodedKey,164String encodedKeyAlgorithm)165throws InvalidKeyException, NoSuchAlgorithmException166{167PublicKey key = null;168169try {170KeyFactory keyFactory =171KeyFactory.getInstance(encodedKeyAlgorithm,172SunJCE.getInstance());173X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey);174key = keyFactory.generatePublic(keySpec);175} catch (NoSuchAlgorithmException nsae) {176// Try to see whether there is another177// provider which supports this algorithm178try {179KeyFactory keyFactory =180KeyFactory.getInstance(encodedKeyAlgorithm);181X509EncodedKeySpec keySpec =182new X509EncodedKeySpec(encodedKey);183key = keyFactory.generatePublic(keySpec);184} catch (NoSuchAlgorithmException nsae2) {185throw new NoSuchAlgorithmException("No installed providers " +186"can create keys for the " +187encodedKeyAlgorithm +188"algorithm");189} catch (InvalidKeySpecException ikse2) {190// Should never happen.191}192} catch (InvalidKeySpecException ikse) {193// Should never happen.194}195196return key;197}198199/**200* Construct a private key from its encoding.201*202* @param encodedKey the encoding of a private key.203*204* @param encodedKeyAlgorithm the algorithm the wrapped key is for.205*206* @return a private key constructed from the encodedKey.207*/208private final PrivateKey constructPrivateKey(byte[] encodedKey,209String encodedKeyAlgorithm)210throws InvalidKeyException, NoSuchAlgorithmException211{212PrivateKey key = null;213214try {215KeyFactory keyFactory =216KeyFactory.getInstance(encodedKeyAlgorithm,217SunJCE.getInstance());218PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);219return keyFactory.generatePrivate(keySpec);220} catch (NoSuchAlgorithmException nsae) {221// Try to see whether there is another222// provider which supports this algorithm223try {224KeyFactory keyFactory =225KeyFactory.getInstance(encodedKeyAlgorithm);226PKCS8EncodedKeySpec keySpec =227new PKCS8EncodedKeySpec(encodedKey);228key = keyFactory.generatePrivate(keySpec);229} catch (NoSuchAlgorithmException nsae2) {230throw new NoSuchAlgorithmException("No installed providers " +231"can create keys for the " +232encodedKeyAlgorithm +233"algorithm");234} catch (InvalidKeySpecException ikse2) {235// Should never happen.236}237} catch (InvalidKeySpecException ikse) {238// Should never happen.239}240241return key;242}243244/**245* Construct a secret key from its encoding.246*247* @param encodedKey the encoding of a secret key.248*249* @param encodedKeyAlgorithm the algorithm the secret key is for.250*251* @return a secret key constructed from the encodedKey.252*/253private final SecretKey constructSecretKey(byte[] encodedKey,254String encodedKeyAlgorithm)255{256return (new SecretKeySpec(encodedKey, encodedKeyAlgorithm));257}258}259260261