1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.jce.provider;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
34c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.io.IOException;
44c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.math.BigInteger;
54c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.interfaces.RSAPublicKey;
64c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.spec.RSAPublicKeySpec;
74c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1Sequence;
9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERNull;
10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.x509.AlgorithmIdentifier;
12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.x509.RSAPublicKeyStructure;
13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.params.RSAKeyParameters;
154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
16c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class JCERSAPublicKey
18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    implements RSAPublicKey
19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
20c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    static final long serialVersionUID = 2675817738516720772L;
21c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private BigInteger modulus;
23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private BigInteger publicExponent;
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    JCERSAPublicKey(
26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        RSAKeyParameters key)
27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.modulus = key.getModulus();
29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.publicExponent = key.getExponent();
30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    JCERSAPublicKey(
33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        RSAPublicKeySpec spec)
34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.modulus = spec.getModulus();
36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.publicExponent = spec.getPublicExponent();
37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    JCERSAPublicKey(
40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        RSAPublicKey key)
41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.modulus = key.getModulus();
43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.publicExponent = key.getPublicExponent();
44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    JCERSAPublicKey(
47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        SubjectPublicKeyInfo    info)
48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        try
50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            RSAPublicKeyStructure   pubKey = new RSAPublicKeyStructure((ASN1Sequence)info.parsePublicKey());
52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            this.modulus = pubKey.getModulus();
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            this.publicExponent = pubKey.getPublicExponent();
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        catch (IOException e)
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw new IllegalArgumentException("invalid info structure in RSA public key");
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * return the modulus.
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return the modulus.
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public BigInteger getModulus()
68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return modulus;
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * return the public exponent.
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return the public exponent.
76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public BigInteger getPublicExponent()
78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return publicExponent;
80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public String getAlgorithm()
83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return "RSA";
85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public String getFormat()
88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return "X.509";
90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public byte[] getEncoded()
93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKeyStructure(getModulus(), getPublicExponent()));
95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
97c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public int hashCode()
98c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
99c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return this.getModulus().hashCode() ^ this.getPublicExponent().hashCode();
100c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
101c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public boolean equals(Object o)
103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
104c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (o == this)
105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
106c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return true;
107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
109c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (!(o instanceof RSAPublicKey))
110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
111c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return false;
112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        RSAPublicKey key = (RSAPublicKey)o;
115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return getModulus().equals(key.getModulus())
117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            && getPublicExponent().equals(key.getPublicExponent());
118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public String toString()
121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        StringBuffer    buf = new StringBuffer();
123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        String          nl = System.getProperty("line.separator");
124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        buf.append("RSA Public Key").append(nl);
126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        buf.append("            modulus: ").append(this.getModulus().toString(16)).append(nl);
127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        buf.append("    public exponent: ").append(this.getPublicExponent().toString(16)).append(nl);
128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return buf.toString();
130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
132