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.asn1.pkcs;
020    
021    import java.math.BigInteger;
022    import java.util.Enumeration;
023    
024    import org.apache.geronimo.util.asn1.ASN1Encodable;
025    import org.apache.geronimo.util.asn1.ASN1EncodableVector;
026    import org.apache.geronimo.util.asn1.ASN1Sequence;
027    import org.apache.geronimo.util.asn1.ASN1TaggedObject;
028    import org.apache.geronimo.util.asn1.DERInteger;
029    import org.apache.geronimo.util.asn1.DERObject;
030    import org.apache.geronimo.util.asn1.DERSequence;
031    
032    public class RSAPrivateKeyStructure
033        extends ASN1Encodable
034    {
035        private int         version;
036        private BigInteger  modulus;
037        private BigInteger  publicExponent;
038        private BigInteger  privateExponent;
039        private BigInteger  prime1;
040        private BigInteger  prime2;
041        private BigInteger  exponent1;
042        private BigInteger  exponent2;
043        private BigInteger  coefficient;
044        private ASN1Sequence otherPrimeInfos = null;
045    
046        public static RSAPrivateKeyStructure getInstance(
047            ASN1TaggedObject obj,
048            boolean          explicit)
049        {
050            return getInstance(ASN1Sequence.getInstance(obj, explicit));
051        }
052    
053        public static RSAPrivateKeyStructure getInstance(
054            Object  obj)
055        {
056            if (obj instanceof RSAPrivateKeyStructure)
057            {
058                return (RSAPrivateKeyStructure)obj;
059            }
060            else if (obj instanceof ASN1Sequence)
061            {
062                return new RSAPrivateKeyStructure((ASN1Sequence)obj);
063            }
064    
065            throw new IllegalArgumentException("unknown object in factory");
066        }
067    
068        public RSAPrivateKeyStructure(
069            BigInteger  modulus,
070            BigInteger  publicExponent,
071            BigInteger  privateExponent,
072            BigInteger  prime1,
073            BigInteger  prime2,
074            BigInteger  exponent1,
075            BigInteger  exponent2,
076            BigInteger  coefficient)
077        {
078            this.version = 0;
079            this.modulus = modulus;
080            this.publicExponent = publicExponent;
081            this.privateExponent = privateExponent;
082            this.prime1 = prime1;
083            this.prime2 = prime2;
084            this.exponent1 = exponent1;
085            this.exponent2 = exponent2;
086            this.coefficient = coefficient;
087        }
088    
089        public RSAPrivateKeyStructure(
090            ASN1Sequence  seq)
091        {
092            Enumeration e = seq.getObjects();
093    
094            BigInteger  v = ((DERInteger)e.nextElement()).getValue();
095            if (v.intValue() != 0 && v.intValue() != 1)
096            {
097                throw new IllegalArgumentException("wrong version for RSA private key");
098            }
099    
100            version = v.intValue();
101            modulus = ((DERInteger)e.nextElement()).getValue();
102            publicExponent = ((DERInteger)e.nextElement()).getValue();
103            privateExponent = ((DERInteger)e.nextElement()).getValue();
104            prime1 = ((DERInteger)e.nextElement()).getValue();
105            prime2 = ((DERInteger)e.nextElement()).getValue();
106            exponent1 = ((DERInteger)e.nextElement()).getValue();
107            exponent2 = ((DERInteger)e.nextElement()).getValue();
108            coefficient = ((DERInteger)e.nextElement()).getValue();
109    
110            if (e.hasMoreElements())
111            {
112                otherPrimeInfos = (ASN1Sequence)e.nextElement();
113            }
114        }
115    
116        public int getVersion()
117        {
118            return version;
119        }
120    
121        public BigInteger getModulus()
122        {
123            return modulus;
124        }
125    
126        public BigInteger getPublicExponent()
127        {
128            return publicExponent;
129        }
130    
131        public BigInteger getPrivateExponent()
132        {
133            return privateExponent;
134        }
135    
136        public BigInteger getPrime1()
137        {
138            return prime1;
139        }
140    
141        public BigInteger getPrime2()
142        {
143            return prime2;
144        }
145    
146        public BigInteger getExponent1()
147        {
148            return exponent1;
149        }
150    
151        public BigInteger getExponent2()
152        {
153            return exponent2;
154        }
155    
156        public BigInteger getCoefficient()
157        {
158            return coefficient;
159        }
160    
161        /**
162         * This outputs the key in PKCS1v2 format.
163         * <pre>
164         *      RSAPrivateKey ::= SEQUENCE {
165         *                          version Version,
166         *                          modulus INTEGER, -- n
167         *                          publicExponent INTEGER, -- e
168         *                          privateExponent INTEGER, -- d
169         *                          prime1 INTEGER, -- p
170         *                          prime2 INTEGER, -- q
171         *                          exponent1 INTEGER, -- d mod (p-1)
172         *                          exponent2 INTEGER, -- d mod (q-1)
173         *                          coefficient INTEGER, -- (inverse of q) mod p
174         *                          otherPrimeInfos OtherPrimeInfos OPTIONAL
175         *                      }
176         *
177         *      Version ::= INTEGER { two-prime(0), multi(1) }
178         *        (CONSTRAINED BY {-- version must be multi if otherPrimeInfos present --})
179         * </pre>
180         * <p>
181         * This routine is written to output PKCS1 version 2.1, private keys.
182         */
183        public DERObject toASN1Object()
184        {
185            ASN1EncodableVector  v = new ASN1EncodableVector();
186    
187            v.add(new DERInteger(version));                       // version
188            v.add(new DERInteger(getModulus()));
189            v.add(new DERInteger(getPublicExponent()));
190            v.add(new DERInteger(getPrivateExponent()));
191            v.add(new DERInteger(getPrime1()));
192            v.add(new DERInteger(getPrime2()));
193            v.add(new DERInteger(getExponent1()));
194            v.add(new DERInteger(getExponent2()));
195            v.add(new DERInteger(getCoefficient()));
196    
197            if (otherPrimeInfos != null)
198            {
199                v.add(otherPrimeInfos);
200            }
201    
202            return new DERSequence(v);
203        }
204    }