001    /**
002     *
003     *  Licensed to the Apache Software Foundation (ASF) under one or more
004     *  contributor license agreements.  See the NOTICE file distributed with
005     *  this work for additional information regarding copyright ownership.
006     *  The ASF licenses this file to You under the Apache License, Version 2.0
007     *  (the "License"); you may not use this file except in compliance with
008     *  the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    
019    package org.apache.geronimo.util.jce.provider;
020    
021    import java.io.ByteArrayInputStream;
022    import java.io.ByteArrayOutputStream;
023    import java.io.IOException;
024    import java.io.ObjectInputStream;
025    import java.io.ObjectOutputStream;
026    import java.math.BigInteger;
027    import java.security.interfaces.RSAPrivateKey;
028    import java.security.spec.RSAPrivateKeySpec;
029    import java.util.Enumeration;
030    import java.util.Hashtable;
031    import java.util.Vector;
032    
033    import org.apache.geronimo.util.asn1.ASN1InputStream;
034    import org.apache.geronimo.util.asn1.ASN1OutputStream;
035    import org.apache.geronimo.util.asn1.DEREncodable;
036    import org.apache.geronimo.util.asn1.DERObjectIdentifier;
037    import org.apache.geronimo.util.crypto.params.RSAKeyParameters;
038    import org.apache.geronimo.util.jce.interfaces.PKCS12BagAttributeCarrier;
039    
040    public class JCERSAPrivateKey
041        implements RSAPrivateKey, PKCS12BagAttributeCarrier
042    {
043        protected BigInteger modulus;
044        protected BigInteger privateExponent;
045    
046        private Hashtable   pkcs12Attributes = new Hashtable();
047        private Vector      pkcs12Ordering = new Vector();
048    
049        protected JCERSAPrivateKey()
050        {
051        }
052    
053        JCERSAPrivateKey(
054            RSAKeyParameters key)
055        {
056            this.modulus = key.getModulus();
057            this.privateExponent = key.getExponent();
058        }
059    
060        JCERSAPrivateKey(
061            RSAPrivateKeySpec spec)
062        {
063            this.modulus = spec.getModulus();
064            this.privateExponent = spec.getPrivateExponent();
065        }
066    
067        JCERSAPrivateKey(
068            RSAPrivateKey key)
069        {
070            this.modulus = key.getModulus();
071            this.privateExponent = key.getPrivateExponent();
072        }
073    
074        public BigInteger getModulus()
075        {
076            return modulus;
077        }
078    
079        public BigInteger getPrivateExponent()
080        {
081            return privateExponent;
082        }
083    
084        public String getAlgorithm()
085        {
086            return "RSA";
087        }
088    
089        public String getFormat()
090        {
091            return "NULL";
092        }
093    
094        public byte[] getEncoded()
095        {
096            return null;
097        }
098    
099        public boolean equals(Object o)
100        {
101            if ( !(o instanceof RSAPrivateKey) )
102            {
103                return false;
104            }
105    
106            if ( o == this )
107            {
108                return true;
109            }
110    
111            RSAPrivateKey key = (RSAPrivateKey)o;
112    
113            return getModulus().equals(key.getModulus())
114                && getPrivateExponent().equals(key.getPrivateExponent());
115        }
116    
117        public void setBagAttribute(
118            DERObjectIdentifier oid,
119            DEREncodable        attribute)
120        {
121            pkcs12Attributes.put(oid, attribute);
122            pkcs12Ordering.addElement(oid);
123        }
124    
125        public DEREncodable getBagAttribute(
126            DERObjectIdentifier oid)
127        {
128            return (DEREncodable)pkcs12Attributes.get(oid);
129        }
130    
131        public Enumeration getBagAttributeKeys()
132        {
133            return pkcs12Ordering.elements();
134        }
135    
136        private void readObject(
137            ObjectInputStream   in)
138            throws IOException, ClassNotFoundException
139        {
140            this.modulus = (BigInteger)in.readObject();
141    
142            Object  obj = in.readObject();
143    
144            if (obj instanceof Hashtable)
145            {
146                this.pkcs12Attributes = (Hashtable)obj;
147                this.pkcs12Ordering = (Vector)in.readObject();
148            }
149            else
150            {
151                this.pkcs12Attributes = new Hashtable();
152                this.pkcs12Ordering = new Vector();
153    
154                ByteArrayInputStream    bIn = new ByteArrayInputStream((byte[])obj);
155                ASN1InputStream         aIn = new ASN1InputStream(bIn);
156    
157                DERObjectIdentifier    oid;
158    
159                while ((oid = (DERObjectIdentifier)aIn.readObject()) != null)
160                {
161                    this.setBagAttribute(oid, aIn.readObject());
162                }
163            }
164    
165            this.privateExponent = (BigInteger)in.readObject();
166        }
167    
168        private void writeObject(
169            ObjectOutputStream  out)
170            throws IOException
171        {
172            out.writeObject(modulus);
173    
174            if (pkcs12Ordering.size() == 0)
175            {
176                out.writeObject(pkcs12Attributes);
177                out.writeObject(pkcs12Ordering);
178            }
179            else
180            {
181                ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
182                ASN1OutputStream        aOut = new ASN1OutputStream(bOut);
183    
184                Enumeration             e = this.getBagAttributeKeys();
185    
186                while (e.hasMoreElements())
187                {
188                    DEREncodable    oid = (DEREncodable)e.nextElement();
189    
190                    aOut.writeObject(oid);
191                    aOut.writeObject(pkcs12Attributes.get(oid));
192                }
193    
194                out.writeObject(bOut.toByteArray());
195            }
196    
197            out.writeObject(privateExponent);
198        }
199    }