001package org.apache.commons.ssl.org.bouncycastle.asn1.eac;
002
003import java.math.BigInteger;
004import java.util.Enumeration;
005
006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector;
007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1ObjectIdentifier;
008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive;
009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence;
010import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence;
011
012
013/**
014 * an Iso7816RSAPublicKeyStructure structure.
015 * <pre>
016 *  Certificate Holder Authorization ::= SEQUENCE {
017 *      // modulus should be at least 1024bit and a multiple of 512.
018 *      DERTaggedObject        modulus,
019 *      // access rights    exponent
020 *      DERTaggedObject    accessRights,
021 *  }
022 * </pre>
023 */
024public class RSAPublicKey
025    extends PublicKeyDataObject
026{
027    private ASN1ObjectIdentifier usage;
028    private BigInteger modulus;
029    private BigInteger exponent;
030    private int valid = 0;
031    private static int modulusValid = 0x01;
032    private static int exponentValid = 0x02;
033
034    RSAPublicKey(ASN1Sequence seq)
035    {
036        Enumeration en = seq.getObjects();
037
038        this.usage = ASN1ObjectIdentifier.getInstance(en.nextElement());
039
040        while (en.hasMoreElements())
041        {
042            UnsignedInteger val = UnsignedInteger.getInstance(en.nextElement());
043
044            switch (val.getTagNo())
045            {
046            case 0x1:
047                setModulus(val);
048                break;
049            case 0x2:
050                setExponent(val);
051                break;
052            default:
053                throw new IllegalArgumentException("Unknown DERTaggedObject :" + val.getTagNo() + "-> not an Iso7816RSAPublicKeyStructure");
054            }
055        }
056        if (valid != 0x3)
057        {
058            throw new IllegalArgumentException("missing argument -> not an Iso7816RSAPublicKeyStructure");
059        }
060    }
061
062    public RSAPublicKey(ASN1ObjectIdentifier usage, BigInteger modulus, BigInteger exponent)
063    {
064        this.usage = usage;
065        this.modulus = modulus;
066        this.exponent = exponent;
067    }
068
069    public ASN1ObjectIdentifier getUsage()
070    {
071        return usage;
072    }
073
074    public BigInteger getModulus()
075    {
076        return modulus;
077    }
078
079    public BigInteger getPublicExponent()
080    {
081        return exponent;
082    }
083
084    private void setModulus(UnsignedInteger modulus)
085    {
086        if ((valid & modulusValid) == 0)
087        {
088            valid |= modulusValid;
089            this.modulus = modulus.getValue();
090        }
091        else
092        {
093            throw new IllegalArgumentException("Modulus already set");
094        }
095    }
096
097    private void setExponent(UnsignedInteger exponent)
098    {
099        if ((valid & exponentValid) == 0)
100        {
101            valid |= exponentValid;
102            this.exponent = exponent.getValue();
103        }
104        else
105        {
106            throw new IllegalArgumentException("Exponent already set");
107        }
108    }
109
110    public ASN1Primitive toASN1Primitive()
111    {
112        ASN1EncodableVector v = new ASN1EncodableVector();
113
114        v.add(usage);
115        v.add(new UnsignedInteger(0x01, getModulus()));
116        v.add(new UnsignedInteger(0x02, getPublicExponent()));
117
118        return new DERSequence(v);
119    }
120}