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.util.jce.provider;
019    
020    import java.io.ByteArrayInputStream;
021    import java.io.ByteArrayOutputStream;
022    import java.io.IOException;
023    import java.io.ObjectInputStream;
024    import java.io.ObjectOutputStream;
025    import java.math.BigInteger;
026    import java.security.interfaces.RSAPrivateKey;
027    import java.security.spec.RSAPrivateKeySpec;
028    import java.util.Enumeration;
029    import java.util.Hashtable;
030    import java.util.Vector;
031    
032    import org.apache.geronimo.util.asn1.ASN1InputStream;
033    import org.apache.geronimo.util.asn1.ASN1OutputStream;
034    import org.apache.geronimo.util.asn1.DEREncodable;
035    import org.apache.geronimo.util.asn1.DERObjectIdentifier;
036    import org.apache.geronimo.util.crypto.params.RSAKeyParameters;
037    import org.apache.geronimo.util.jce.interfaces.PKCS12BagAttributeCarrier;
038    
039    public class JCERSAPrivateKey
040        implements RSAPrivateKey, PKCS12BagAttributeCarrier
041    {
042        protected BigInteger modulus;
043        protected BigInteger privateExponent;
044    
045        private Hashtable   pkcs12Attributes = new Hashtable();
046        private Vector      pkcs12Ordering = new Vector();
047    
048        protected JCERSAPrivateKey()
049        {
050        }
051    
052        JCERSAPrivateKey(
053            RSAKeyParameters key)
054        {
055            this.modulus = key.getModulus();
056            this.privateExponent = key.getExponent();
057        }
058    
059        JCERSAPrivateKey(
060            RSAPrivateKeySpec spec)
061        {
062            this.modulus = spec.getModulus();
063            this.privateExponent = spec.getPrivateExponent();
064        }
065    
066        JCERSAPrivateKey(
067            RSAPrivateKey key)
068        {
069            this.modulus = key.getModulus();
070            this.privateExponent = key.getPrivateExponent();
071        }
072    
073        public BigInteger getModulus()
074        {
075            return modulus;
076        }
077    
078        public BigInteger getPrivateExponent()
079        {
080            return privateExponent;
081        }
082    
083        public String getAlgorithm()
084        {
085            return "RSA";
086        }
087    
088        public String getFormat()
089        {
090            return "NULL";
091        }
092    
093        public byte[] getEncoded()
094        {
095            return null;
096        }
097    
098        public boolean equals(Object o)
099        {
100            if ( !(o instanceof RSAPrivateKey) )
101            {
102                return false;
103            }
104    
105            if ( o == this )
106            {
107                return true;
108            }
109    
110            RSAPrivateKey key = (RSAPrivateKey)o;
111    
112            return getModulus().equals(key.getModulus())
113                && getPrivateExponent().equals(key.getPrivateExponent());
114        }
115    
116        public void setBagAttribute(
117            DERObjectIdentifier oid,
118            DEREncodable        attribute)
119        {
120            pkcs12Attributes.put(oid, attribute);
121            pkcs12Ordering.addElement(oid);
122        }
123    
124        public DEREncodable getBagAttribute(
125            DERObjectIdentifier oid)
126        {
127            return (DEREncodable)pkcs12Attributes.get(oid);
128        }
129    
130        public Enumeration getBagAttributeKeys()
131        {
132            return pkcs12Ordering.elements();
133        }
134    
135        private void readObject(
136            ObjectInputStream   in)
137            throws IOException, ClassNotFoundException
138        {
139            this.modulus = (BigInteger)in.readObject();
140    
141            Object  obj = in.readObject();
142    
143            if (obj instanceof Hashtable)
144            {
145                this.pkcs12Attributes = (Hashtable)obj;
146                this.pkcs12Ordering = (Vector)in.readObject();
147            }
148            else
149            {
150                this.pkcs12Attributes = new Hashtable();
151                this.pkcs12Ordering = new Vector();
152    
153                ByteArrayInputStream    bIn = new ByteArrayInputStream((byte[])obj);
154                ASN1InputStream         aIn = new ASN1InputStream(bIn);
155    
156                DERObjectIdentifier    oid;
157    
158                while ((oid = (DERObjectIdentifier)aIn.readObject()) != null)
159                {
160                    this.setBagAttribute(oid, aIn.readObject());
161                }
162            }
163    
164            this.privateExponent = (BigInteger)in.readObject();
165        }
166    
167        private void writeObject(
168            ObjectOutputStream  out)
169            throws IOException
170        {
171            out.writeObject(modulus);
172    
173            if (pkcs12Ordering.size() == 0)
174            {
175                out.writeObject(pkcs12Attributes);
176                out.writeObject(pkcs12Ordering);
177            }
178            else
179            {
180                ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
181                ASN1OutputStream        aOut = new ASN1OutputStream(bOut);
182    
183                Enumeration             e = this.getBagAttributeKeys();
184    
185                while (e.hasMoreElements())
186                {
187                    DEREncodable    oid = (DEREncodable)e.nextElement();
188    
189                    aOut.writeObject(oid);
190                    aOut.writeObject(pkcs12Attributes.get(oid));
191                }
192    
193                out.writeObject(bOut.toByteArray());
194            }
195    
196            out.writeObject(privateExponent);
197        }
198    }