|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package sun.security.rsa; |
|
|
|
import java.io.IOException; |
|
import java.math.BigInteger; |
|
|
|
import java.security.*; |
|
import java.security.spec.*; |
|
import java.security.interfaces.*; |
|
|
|
import sun.security.util.*; |
|
import sun.security.x509.X509Key; |
|
import sun.security.x509.AlgorithmId; |
|
|
|
import static sun.security.rsa.RSAUtil.KeyType; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey { |
|
|
|
private static final long serialVersionUID = 2644735423591199609L; |
|
private static final BigInteger THREE = BigInteger.valueOf(3); |
|
|
|
private BigInteger n; |
|
private BigInteger e; |
|
|
|
// optional parameters associated with this RSA key |
|
// specified in the encoding of its AlgorithmId |
|
|
|
private AlgorithmParameterSpec keyParams; |
|
|
|
|
|
|
|
|
|
*/ |
|
public static RSAPublicKey newKey(byte[] encoded) |
|
throws InvalidKeyException { |
|
return new RSAPublicKeyImpl(encoded); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public static RSAPublicKey newKey(KeyType type, |
|
AlgorithmParameterSpec params, BigInteger n, BigInteger e) |
|
throws InvalidKeyException { |
|
AlgorithmId rsaId = RSAUtil.createAlgorithmId(type, params); |
|
return new RSAPublicKeyImpl(rsaId, n, e); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
RSAPublicKeyImpl(AlgorithmId rsaId, BigInteger n, BigInteger e) |
|
throws InvalidKeyException { |
|
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e); |
|
checkExponentRange(n, e); |
|
|
|
this.n = n; |
|
this.e = e; |
|
this.keyParams = RSAUtil.getParamSpec(rsaId); |
|
|
|
|
|
algid = rsaId; |
|
try { |
|
DerOutputStream out = new DerOutputStream(); |
|
out.putInteger(n); |
|
out.putInteger(e); |
|
byte[] keyArray = |
|
new DerValue(DerValue.tag_Sequence, |
|
out.toByteArray()).toByteArray(); |
|
setKey(new BitArray(keyArray.length*8, keyArray)); |
|
} catch (IOException exc) { |
|
|
|
throw new InvalidKeyException(exc); |
|
} |
|
} |
|
|
|
|
|
|
|
*/ |
|
RSAPublicKeyImpl(byte[] encoded) throws InvalidKeyException { |
|
if (encoded == null || encoded.length == 0) { |
|
throw new InvalidKeyException("Missing key encoding"); |
|
} |
|
decode(encoded); |
|
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e); |
|
checkExponentRange(n, e); |
|
|
|
try { |
|
|
|
this.keyParams = RSAUtil.getParamSpec(algid); |
|
} catch (ProviderException e) { |
|
throw new InvalidKeyException(e); |
|
} |
|
} |
|
|
|
|
|
static void checkExponentRange(BigInteger mod, BigInteger exp) |
|
throws InvalidKeyException { |
|
|
|
if (exp.compareTo(mod) >= 0) { |
|
throw new InvalidKeyException("exponent is larger than modulus"); |
|
} |
|
|
|
|
|
if (exp.compareTo(THREE) < 0) { |
|
throw new InvalidKeyException("exponent is smaller than 3"); |
|
} |
|
} |
|
|
|
|
|
@Override |
|
public String getAlgorithm() { |
|
return algid.getName(); |
|
} |
|
|
|
|
|
@Override |
|
public BigInteger getModulus() { |
|
return n; |
|
} |
|
|
|
|
|
@Override |
|
public BigInteger getPublicExponent() { |
|
return e; |
|
} |
|
|
|
|
|
@Override |
|
public AlgorithmParameterSpec getParams() { |
|
return keyParams; |
|
} |
|
|
|
|
|
|
|
*/ |
|
protected void parseKeyBits() throws InvalidKeyException { |
|
try { |
|
DerInputStream in = new DerInputStream(getKey().toByteArray()); |
|
DerValue derValue = in.getDerValue(); |
|
if (derValue.tag != DerValue.tag_Sequence) { |
|
throw new IOException("Not a SEQUENCE"); |
|
} |
|
DerInputStream data = derValue.data; |
|
n = data.getPositiveBigInteger(); |
|
e = data.getPositiveBigInteger(); |
|
if (derValue.data.available() != 0) { |
|
throw new IOException("Extra data available"); |
|
} |
|
} catch (IOException e) { |
|
throw new InvalidKeyException("Invalid RSA public key", e); |
|
} |
|
} |
|
|
|
|
|
@Override |
|
public String toString() { |
|
return "Sun " + getAlgorithm() + " public key, " + n.bitLength() |
|
+ " bits" + "\n params: " + keyParams + "\n modulus: " + n |
|
+ "\n public exponent: " + e; |
|
} |
|
|
|
protected Object writeReplace() throws java.io.ObjectStreamException { |
|
return new KeyRep(KeyRep.Type.PUBLIC, |
|
getAlgorithm(), |
|
getFormat(), |
|
getEncoded()); |
|
} |
|
} |