| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
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());  | 
 | 
    }  | 
 | 
}  |