001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    
018    package org.apache.geronimo.crypto.jce.provider;
019    
020    import java.io.ByteArrayOutputStream;
021    import java.io.IOException;
022    import java.math.BigInteger;
023    import java.security.interfaces.RSAPublicKey;
024    import java.security.spec.RSAPublicKeySpec;
025    
026    import org.apache.geronimo.crypto.asn1.ASN1Sequence;
027    import org.apache.geronimo.crypto.asn1.DERNull;
028    import org.apache.geronimo.crypto.asn1.DEROutputStream;
029    import org.apache.geronimo.crypto.asn1.pkcs.PKCSObjectIdentifiers;
030    import org.apache.geronimo.crypto.asn1.x509.AlgorithmIdentifier;
031    import org.apache.geronimo.crypto.asn1.x509.RSAPublicKeyStructure;
032    import org.apache.geronimo.crypto.asn1.x509.SubjectPublicKeyInfo;
033    import org.apache.geronimo.crypto.crypto.params.RSAKeyParameters;
034    
035    public class JCERSAPublicKey
036        implements RSAPublicKey
037    {
038        private BigInteger modulus;
039        private BigInteger publicExponent;
040    
041        JCERSAPublicKey(
042            RSAKeyParameters key)
043        {
044            this.modulus = key.getModulus();
045            this.publicExponent = key.getExponent();
046        }
047    
048        JCERSAPublicKey(
049            RSAPublicKeySpec spec)
050        {
051            this.modulus = spec.getModulus();
052            this.publicExponent = spec.getPublicExponent();
053        }
054    
055        JCERSAPublicKey(
056            RSAPublicKey key)
057        {
058            this.modulus = key.getModulus();
059            this.publicExponent = key.getPublicExponent();
060        }
061    
062        JCERSAPublicKey(
063            SubjectPublicKeyInfo    info)
064        {
065            try
066            {
067                RSAPublicKeyStructure   pubKey = new RSAPublicKeyStructure((ASN1Sequence)info.getPublicKey());
068    
069                this.modulus = pubKey.getModulus();
070                this.publicExponent = pubKey.getPublicExponent();
071            }
072            catch (IOException e)
073            {
074                throw new IllegalArgumentException("invalid info structure in RSA public key", e);
075            }
076        }
077    
078        /**
079         * return the modulus.
080         *
081         * @return the modulus.
082         */
083        public BigInteger getModulus()
084        {
085            return modulus;
086        }
087    
088        /**
089         * return the public exponent.
090         *
091         * @return the public exponent.
092         */
093        public BigInteger getPublicExponent()
094        {
095            return publicExponent;
096        }
097    
098        public String getAlgorithm()
099        {
100            return "RSA";
101        }
102    
103        public String getFormat()
104        {
105            return "X.509";
106        }
107    
108        public byte[] getEncoded()
109        {
110            ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
111            DEROutputStream         dOut = new DEROutputStream(bOut);
112            SubjectPublicKeyInfo    info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, new DERNull()), new RSAPublicKeyStructure(getModulus(), getPublicExponent()).getDERObject());
113    
114            try
115            {
116                dOut.writeObject(info);
117                dOut.close();
118            }
119            catch (IOException e)
120            {
121                throw new RuntimeException("Error encoding RSA public key", e);
122            }
123    
124            return bOut.toByteArray();
125    
126        }
127    
128        public boolean equals(Object o)
129        {
130            if ( !(o instanceof RSAPublicKey) )
131            {
132                return false;
133            }
134    
135            if ( o == this )
136            {
137                return true;
138            }
139    
140            RSAPublicKey key = (RSAPublicKey)o;
141    
142            return getModulus().equals(key.getModulus())
143                && getPublicExponent().equals(key.getPublicExponent());
144        }
145    
146        public String toString()
147        {
148            StringBuffer    buf = new StringBuffer();
149            String          nl = System.getProperty("line.separator");
150    
151            buf.append("RSA Public Key" + nl);
152            buf.append("            modulus: " + this.getModulus().toString(16) + nl);
153            buf.append("    public exponent: " + this.getPublicExponent().toString(16) + nl);
154    
155            return buf.toString();
156        }
157    }