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