VYPR
Moderate severityNVD Advisory· Published Jul 5, 2023· Updated Dec 4, 2024

CVE-2023-33201

CVE-2023-33201

Description

Bouncy Castle For Java before 1.74 is affected by an LDAP injection vulnerability. The vulnerability only affects applications that use an LDAP CertStore from Bouncy Castle to validate X.509 certificates. During the certificate validation process, Bouncy Castle inserts the certificate's Subject Name into an LDAP search filter without any escaping, which leads to an LDAP injection vulnerability.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Bouncy Castle for Java before 1.74 has an LDAP injection vulnerability in its LDAP CertStore, where unescaped certificate Subject Names are inserted into LDAP search filters, affecting certificate validation.

Vulnerability

Details

CVE-2023-33201 is an LDAP injection vulnerability in Bouncy Castle for Java versions before 1.74. The flaw specifically affects applications that use an LDAP CertStore from Bouncy Castle to validate X.509 certificates. During certificate validation, the library constructs an LDAP search filter that includes the certificate's Subject Name without any escaping or sanitization, allowing an attacker to inject arbitrary LDAP operations [1][3].

Exploitation

To exploit this vulnerability, an attacker must supply a specially crafted X.509 certificate containing a malicious Subject Name. When the application uses Bouncy Castle's LDAP CertStore to validate the certificate, the unescaped Subject Name is inserted into the LDAP query. The attacker does not need direct access to the LDAP server; the injection occurs on the client side as the search filter is constructed. No authentication is required beyond the ability to present a malicious certificate to the application [1][2].

Impact

A successful injection allows the attacker to modify the LDAP search filter, potentially extracting or altering data from the LDAP directory, or bypassing certificate validation entirely. This could lead to unauthorized access, information disclosure, or privilege escalation depending on how the application uses certificate validation and the LDAP server's permissions. The scope of the LDAP injection is limited by the LDAP server's access controls and the application's logic [1][2].

Mitigation

The vulnerability has been patched in Bouncy Castle version 1.74. Users should upgrade to version 1.74 or later. If upgrading is not immediately possible, as a workaround, applications should avoid using the LDAP CertStore for certificate validation, or ensure that untrusted certificates are not processed through this code path. The advisory also notes that version 1.74 has an updated LDAP CertStore that properly escapes search filters [3][4].

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.bouncycastle:bcprov-jdk18onMaven
< 1.741.74
org.bouncycastle:bcprov-jdk15to18Maven
< 1.741.74
org.bouncycastle:bcprov-jdk14Maven
>= 1.49, < 1.741.74
org.bouncycastle:bcprov-ext-jdk14Maven
>= 1.49, < 1.741.74
org.bouncycastle:bcprov-ext-jdk15to18Maven
< 1.741.74
org.bouncycastle:bcprov-ext-jdk18onMaven
< 1.741.74
org.bouncycastle:bcprov-debug-jdk14Maven
>= 1.49, < 1.741.74
org.bouncycastle:bcprov-debug-jdk15to18Maven
< 1.741.74
org.bouncycastle:bcprov-debug-jdk18onMaven
< 1.741.74
org.bouncycastle:bcprov-jdk15onMaven
>= 1.49, <= 1.70
org.bouncycastle:bcprov-ext-jdk15onMaven
>= 1.49, <= 1.70
org.bouncycastle:bcprov-debug-jdk15onMaven
>= 1.49, <= 1.70

Affected products

44

Patches

2
e8c409a8389c

added filter encode to search

https://github.com/bcgit/bc-javaroybApr 26, 2023via ghsa
1 file changed · +55 1
  • prov/src/main/java/org/bouncycastle/jce/provider/X509LDAPCertStoreSpi.java+55 1 modified
    @@ -375,6 +375,59 @@ public Collection engineGetCRLs(CRLSelector selector)
     
             return crlSet;
         }
    +    private static String[] FILTER_ESCAPE_TABLE = new String['\\' + 1];
    +
    +
    +    static {
    +
    +        // Filter encoding table -------------------------------------
    +
    +        // fill with char itself
    +        for (char c = 0; c < FILTER_ESCAPE_TABLE.length; c++) {
    +            FILTER_ESCAPE_TABLE[c] = String.valueOf(c);
    +        }
    +
    +        // escapes (RFC2254)
    +        FILTER_ESCAPE_TABLE['*'] = "\\2a";
    +        FILTER_ESCAPE_TABLE['('] = "\\28";
    +        FILTER_ESCAPE_TABLE[')'] = "\\29";
    +        FILTER_ESCAPE_TABLE['\\'] = "\\5c";
    +        FILTER_ESCAPE_TABLE[0] = "\\00";
    +
    +    }
    +
    +    /**
    +     * Escape a value for use in a filter.
    +     * @param value the value to escape.
    +     * @return a properly escaped representation of the supplied value.
    +     */
    +    private String filterEncode(String value)
    +    {
    +        if (value == null)
    +        {
    +            return null;
    +        }
    +
    +        // make buffer roomy
    +        StringBuilder encodedValue = new StringBuilder(value.length() * 2);
    +
    +        int length = value.length();
    +
    +        for (int i = 0; i < length; i++) {
    +
    +            char c = value.charAt(i);
    +
    +            if (c < FILTER_ESCAPE_TABLE.length) {
    +                encodedValue.append(FILTER_ESCAPE_TABLE[c]);
    +            }
    +            else {
    +                // default: add the char
    +                encodedValue.append(c);
    +            }
    +        }
    +
    +        return encodedValue.toString();
    +    }
     
         /**
          * Returns a Set of byte arrays with the certificate or CRL encodings.
    @@ -388,7 +441,8 @@ public Collection engineGetCRLs(CRLSelector selector)
         private Set search(String attributeName, String attributeValue,
                            String[] attrs) throws CertStoreException
         {
    -        String filter = attributeName + "=" + attributeValue;
    +        String filter = attributeName + "=" + filterEncode(attributeValue);
    +        System.out.println(filter);
             if (attributeName == null)
             {
                 filter = null;
    
ccf93ca736b8

initial reshuffle

https://github.com/bcgit/bc-javaDavid HookMay 31, 2013via ghsa
300 files changed · +33484 0
  • core/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecificParser.java+10 0 added
    @@ -0,0 +1,10 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +public interface ASN1ApplicationSpecificParser
    +    extends ASN1Encodable, InMemoryRepresentable
    +{
    +    ASN1Encodable readObject()
    +        throws IOException;
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1Boolean.java+15 0 added
    @@ -0,0 +1,15 @@
    +package org.bouncycastle.asn1;
    +
    +public class ASN1Boolean
    +    extends DERBoolean
    +{
    +    public ASN1Boolean(boolean value)
    +    {
    +        super(value);
    +    }
    +
    +    ASN1Boolean(byte[] value)
    +    {
    +        super(value);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1Choice.java+14 0 added
    @@ -0,0 +1,14 @@
    +package org.bouncycastle.asn1;
    +
    +/**
    + * Marker interface for CHOICE objects - if you implement this in a role your
    + * own object any attempt to tag the object implicitly will convert the tag to
    + * an explicit one as the encoding rules require.
    + * <p>
    + * If you use this interface your class should also implement the getInstance
    + * pattern which takes a tag object and the tagging mode used. 
    + */
    +public interface ASN1Choice
    +{
    +    // marker interface
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1Encodable.java+6 0 added
    @@ -0,0 +1,6 @@
    +package org.bouncycastle.asn1;
    +
    +public interface ASN1Encodable
    +{
    +    ASN1Primitive toASN1Primitive();
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1EncodableVector.java+36 0 added
    @@ -0,0 +1,36 @@
    +package org.bouncycastle.asn1;
    +
    +import java.util.Enumeration;
    +import java.util.Vector;
    +
    +public class ASN1EncodableVector
    +{
    +    Vector v = new Vector();
    +
    +    public ASN1EncodableVector()
    +    {
    +    }
    +
    +    public void add(ASN1Encodable obj)
    +    {
    +        v.addElement(obj);
    +    }
    +
    +    public void addAll(ASN1EncodableVector other)
    +    {
    +        for (Enumeration en = other.v.elements(); en.hasMoreElements();)
    +        {
    +            v.addElement(en.nextElement());
    +        }
    +    }
    +
    +    public ASN1Encodable get(int i)
    +    {
    +        return (ASN1Encodable)v.elementAt(i);
    +    }
    +
    +    public int size()
    +    {
    +        return v.size();
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1Encoding.java+8 0 added
    @@ -0,0 +1,8 @@
    +package org.bouncycastle.asn1;
    +
    +public interface ASN1Encoding
    +{
    +    static final String DER = "DER";
    +    static final String DL = "DL";
    +    static final String BER = "BER";
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java+22 0 added
    @@ -0,0 +1,22 @@
    +package org.bouncycastle.asn1;
    +
    +import java.math.BigInteger;
    +
    +public class ASN1Enumerated
    +    extends DEREnumerated
    +{
    +    ASN1Enumerated(byte[] bytes)
    +    {
    +        super(bytes);
    +    }
    +
    +    public ASN1Enumerated(BigInteger value)
    +    {
    +        super(value);
    +    }
    +
    +    public ASN1Enumerated(int value)
    +    {
    +        super(value);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1Exception.java+25 0 added
    @@ -0,0 +1,25 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +public class ASN1Exception
    +    extends IOException
    +{
    +    private Throwable cause;
    +
    +    ASN1Exception(String message)
    +    {
    +        super(message);
    +    }
    +
    +    ASN1Exception(String message, Throwable cause)
    +    {
    +        super(message);
    +        this.cause = cause;
    +    }
    +
    +    public Throwable getCause()
    +    {
    +        return cause;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1GeneralizedTime.java+22 0 added
    @@ -0,0 +1,22 @@
    +package org.bouncycastle.asn1;
    +
    +import java.util.Date;
    +
    +public class ASN1GeneralizedTime
    +    extends DERGeneralizedTime
    +{
    +    ASN1GeneralizedTime(byte[] bytes)
    +    {
    +        super(bytes);
    +    }
    +
    +    public ASN1GeneralizedTime(Date time)
    +    {
    +        super(time);
    +    }
    +
    +    public ASN1GeneralizedTime(String time)
    +    {
    +        super(time);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1Generator.java+15 0 added
    @@ -0,0 +1,15 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.OutputStream;
    +
    +public abstract class ASN1Generator
    +{
    +    protected OutputStream _out;
    +    
    +    public ASN1Generator(OutputStream out)
    +    {
    +        _out = out;
    +    }
    +    
    +    public abstract OutputStream getRawOutputStream();
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java+466 0 added
    @@ -0,0 +1,466 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.ByteArrayInputStream;
    +import java.io.EOFException;
    +import java.io.FilterInputStream;
    +import java.io.IOException;
    +import java.io.InputStream;
    +
    +import org.bouncycastle.util.io.Streams;
    +
    +/**
    + * a general purpose ASN.1 decoder - note: this class differs from the
    + * others in that it returns null after it has read the last object in
    + * the stream. If an ASN.1 NULL is encountered a DER/BER Null object is
    + * returned.
    + */
    +public class ASN1InputStream
    +    extends FilterInputStream
    +    implements BERTags
    +{
    +    private final int limit;
    +    private final boolean lazyEvaluate;
    +
    +    private final byte[][] tmpBuffers;
    +
    +    public ASN1InputStream(
    +        InputStream is)
    +    {
    +        this(is, StreamUtil.findLimit(is));
    +    }
    +
    +    /**
    +     * Create an ASN1InputStream based on the input byte array. The length of DER objects in
    +     * the stream is automatically limited to the length of the input array.
    +     * 
    +     * @param input array containing ASN.1 encoded data.
    +     */
    +    public ASN1InputStream(
    +        byte[] input)
    +    {
    +        this(new ByteArrayInputStream(input), input.length);
    +    }
    +
    +    /**
    +     * Create an ASN1InputStream based on the input byte array. The length of DER objects in
    +     * the stream is automatically limited to the length of the input array.
    +     *
    +     * @param input array containing ASN.1 encoded data.
    +     * @param lazyEvaluate true if parsing inside constructed objects can be delayed.
    +     */
    +    public ASN1InputStream(
    +        byte[] input,
    +        boolean lazyEvaluate)
    +    {
    +        this(new ByteArrayInputStream(input), input.length, lazyEvaluate);
    +    }
    +    
    +    /**
    +     * Create an ASN1InputStream where no DER object will be longer than limit.
    +     * 
    +     * @param input stream containing ASN.1 encoded data.
    +     * @param limit maximum size of a DER encoded object.
    +     */
    +    public ASN1InputStream(
    +        InputStream input,
    +        int         limit)
    +    {
    +        this(input, limit, false);
    +    }
    +
    +    /**
    +     * Create an ASN1InputStream where no DER object will be longer than limit, and constructed
    +     * objects such as sequences will be parsed lazily.
    +     *
    +     * @param input stream containing ASN.1 encoded data.
    +     * @param lazyEvaluate true if parsing inside constructed objects can be delayed.
    +     */
    +    public ASN1InputStream(
    +        InputStream input,
    +        boolean     lazyEvaluate)
    +    {
    +        this(input, StreamUtil.findLimit(input), lazyEvaluate);
    +    }
    +
    +    /**
    +     * Create an ASN1InputStream where no DER object will be longer than limit, and constructed
    +     * objects such as sequences will be parsed lazily.
    +     *
    +     * @param input stream containing ASN.1 encoded data.
    +     * @param limit maximum size of a DER encoded object.
    +     * @param lazyEvaluate true if parsing inside constructed objects can be delayed.
    +     */
    +    public ASN1InputStream(
    +        InputStream input,
    +        int         limit,
    +        boolean     lazyEvaluate)
    +    {
    +        super(input);
    +        this.limit = limit;
    +        this.lazyEvaluate = lazyEvaluate;
    +        this.tmpBuffers = new byte[11][];
    +    }
    +
    +    int getLimit()
    +    {
    +        return limit;
    +    }
    +
    +    protected int readLength()
    +        throws IOException
    +    {
    +        return readLength(this, limit);
    +    }
    +
    +    protected void readFully(
    +        byte[]  bytes)
    +        throws IOException
    +    {
    +        if (Streams.readFully(this, bytes) != bytes.length)
    +        {
    +            throw new EOFException("EOF encountered in middle of object");
    +        }
    +    }
    +
    +    /**
    +     * build an object given its tag and the number of bytes to construct it from.
    +     */
    +    protected ASN1Primitive buildObject(
    +        int       tag,
    +        int       tagNo,
    +        int       length)
    +        throws IOException
    +    {
    +        boolean isConstructed = (tag & CONSTRUCTED) != 0;
    +
    +        DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length);
    +
    +        if ((tag & APPLICATION) != 0)
    +        {
    +            return new DERApplicationSpecific(isConstructed, tagNo, defIn.toByteArray());
    +        }
    +
    +        if ((tag & TAGGED) != 0)
    +        {
    +            return new ASN1StreamParser(defIn).readTaggedObject(isConstructed, tagNo);
    +        }
    +
    +        if (isConstructed)
    +        {
    +            // TODO There are other tags that may be constructed (e.g. BIT_STRING)
    +            switch (tagNo)
    +            {
    +                case OCTET_STRING:
    +                    //
    +                    // yes, people actually do this...
    +                    //
    +                    ASN1EncodableVector v = buildDEREncodableVector(defIn);
    +                    ASN1OctetString[] strings = new ASN1OctetString[v.size()];
    +
    +                    for (int i = 0; i != strings.length; i++)
    +                    {
    +                        strings[i] = (ASN1OctetString)v.get(i);
    +                    }
    +
    +                    return new BEROctetString(strings);
    +                case SEQUENCE:
    +                    if (lazyEvaluate)
    +                    {
    +                        return new LazyEncodedSequence(defIn.toByteArray());
    +                    }
    +                    else
    +                    {
    +                        return DERFactory.createSequence(buildDEREncodableVector(defIn));   
    +                    }
    +                case SET:
    +                    return DERFactory.createSet(buildDEREncodableVector(defIn));
    +                case EXTERNAL:
    +                    return new DERExternal(buildDEREncodableVector(defIn));                
    +                default:
    +                    throw new IOException("unknown tag " + tagNo + " encountered");
    +            }
    +        }
    +
    +        return createPrimitiveDERObject(tagNo, defIn, tmpBuffers);
    +    }
    +
    +    ASN1EncodableVector buildEncodableVector()
    +        throws IOException
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +        ASN1Primitive o;
    +
    +        while ((o = readObject()) != null)
    +        {
    +            v.add(o);
    +        }
    +
    +        return v;
    +    }
    +
    +    ASN1EncodableVector buildDEREncodableVector(
    +        DefiniteLengthInputStream dIn) throws IOException
    +    {
    +        return new ASN1InputStream(dIn).buildEncodableVector();
    +    }
    +
    +    public ASN1Primitive readObject()
    +        throws IOException
    +    {
    +        int tag = read();
    +        if (tag <= 0)
    +        {
    +            if (tag == 0)
    +            {
    +                throw new IOException("unexpected end-of-contents marker");
    +            }
    +
    +            return null;
    +        }
    +
    +        //
    +        // calculate tag number
    +        //
    +        int tagNo = readTagNumber(this, tag);
    +
    +        boolean isConstructed = (tag & CONSTRUCTED) != 0;
    +
    +        //
    +        // calculate length
    +        //
    +        int length = readLength();
    +
    +        if (length < 0) // indefinite length method
    +        {
    +            if (!isConstructed)
    +            {
    +                throw new IOException("indefinite length primitive encoding encountered");
    +            }
    +
    +            IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(this, limit);
    +            ASN1StreamParser sp = new ASN1StreamParser(indIn, limit);
    +
    +            if ((tag & APPLICATION) != 0)
    +            {
    +                return new BERApplicationSpecificParser(tagNo, sp).getLoadedObject();
    +            }
    +
    +            if ((tag & TAGGED) != 0)
    +            {
    +                return new BERTaggedObjectParser(true, tagNo, sp).getLoadedObject();
    +            }
    +
    +            // TODO There are other tags that may be constructed (e.g. BIT_STRING)
    +            switch (tagNo)
    +            {
    +                case OCTET_STRING:
    +                    return new BEROctetStringParser(sp).getLoadedObject();
    +                case SEQUENCE:
    +                    return new BERSequenceParser(sp).getLoadedObject();
    +                case SET:
    +                    return new BERSetParser(sp).getLoadedObject();
    +                case EXTERNAL:
    +                    return new DERExternalParser(sp).getLoadedObject();
    +                default:
    +                    throw new IOException("unknown BER object encountered");
    +            }
    +        }
    +        else
    +        {
    +            try
    +            {
    +                return buildObject(tag, tagNo, length);
    +            }
    +            catch (IllegalArgumentException e)
    +            {
    +                throw new ASN1Exception("corrupted stream detected", e);
    +            }
    +        }
    +    }
    +
    +    static int readTagNumber(InputStream s, int tag) 
    +        throws IOException
    +    {
    +        int tagNo = tag & 0x1f;
    +
    +        //
    +        // with tagged object tag number is bottom 5 bits, or stored at the start of the content
    +        //
    +        if (tagNo == 0x1f)
    +        {
    +            tagNo = 0;
    +
    +            int b = s.read();
    +
    +            // X.690-0207 8.1.2.4.2
    +            // "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
    +            if ((b & 0x7f) == 0) // Note: -1 will pass
    +            {
    +                throw new IOException("corrupted stream - invalid high tag number found");
    +            }
    +
    +            while ((b >= 0) && ((b & 0x80) != 0))
    +            {
    +                tagNo |= (b & 0x7f);
    +                tagNo <<= 7;
    +                b = s.read();
    +            }
    +
    +            if (b < 0)
    +            {
    +                throw new EOFException("EOF found inside tag value.");
    +            }
    +            
    +            tagNo |= (b & 0x7f);
    +        }
    +        
    +        return tagNo;
    +    }
    +
    +    static int readLength(InputStream s, int limit)
    +        throws IOException
    +    {
    +        int length = s.read();
    +        if (length < 0)
    +        {
    +            throw new EOFException("EOF found when length expected");
    +        }
    +
    +        if (length == 0x80)
    +        {
    +            return -1;      // indefinite-length encoding
    +        }
    +
    +        if (length > 127)
    +        {
    +            int size = length & 0x7f;
    +
    +            // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
    +            if (size > 4)
    +            {
    +                throw new IOException("DER length more than 4 bytes: " + size);
    +            }
    +
    +            length = 0;
    +            for (int i = 0; i < size; i++)
    +            {
    +                int next = s.read();
    +
    +                if (next < 0)
    +                {
    +                    throw new EOFException("EOF found reading length");
    +                }
    +
    +                length = (length << 8) + next;
    +            }
    +
    +            if (length < 0)
    +            {
    +                throw new IOException("corrupted stream - negative length found");
    +            }
    +
    +            if (length >= limit)   // after all we must have read at least 1 byte
    +            {
    +                throw new IOException("corrupted stream - out of bounds length found");
    +            }
    +        }
    +
    +        return length;
    +    }
    +
    +    private static byte[] getBuffer(DefiniteLengthInputStream defIn, byte[][] tmpBuffers)
    +        throws IOException
    +    {
    +        int len = defIn.getRemaining();
    +        if (defIn.getRemaining() < tmpBuffers.length)
    +        {
    +            byte[] buf = tmpBuffers[len];
    +
    +            if (buf == null)
    +            {
    +                buf = tmpBuffers[len] = new byte[len];
    +            }
    +
    +            Streams.readFully(defIn, buf);
    +
    +            return buf;
    +        }
    +        else
    +        {
    +            return defIn.toByteArray();
    +        }
    +    }
    +
    +    private static char[] getBMPCharBuffer(DefiniteLengthInputStream defIn)
    +        throws IOException
    +    {
    +        int len = defIn.getRemaining() / 2;
    +        char[] buf = new char[len];
    +        int totalRead = 0;
    +        while (totalRead < len)
    +        {
    +            int ch1 = defIn.read();
    +            if (ch1 < 0)
    +            {
    +                break;
    +            }
    +            int ch2 = defIn.read();
    +            if (ch2 < 0)
    +            {
    +                break;
    +            }
    +            buf[totalRead++] = (char)((ch1 << 8) | (ch2 & 0xff));
    +        }
    +
    +        return buf;
    +    }
    +
    +    static ASN1Primitive createPrimitiveDERObject(
    +        int     tagNo,
    +        DefiniteLengthInputStream defIn,
    +        byte[][] tmpBuffers)
    +        throws IOException
    +    {
    +        switch (tagNo)
    +        {
    +            case BIT_STRING:
    +                return DERBitString.fromInputStream(defIn.getRemaining(), defIn);
    +            case BMP_STRING:
    +                return new DERBMPString(getBMPCharBuffer(defIn));
    +            case BOOLEAN:
    +                return ASN1Boolean.fromOctetString(getBuffer(defIn, tmpBuffers));
    +            case ENUMERATED:
    +                return ASN1Enumerated.fromOctetString(getBuffer(defIn, tmpBuffers));
    +            case GENERALIZED_TIME:
    +                return new ASN1GeneralizedTime(defIn.toByteArray());
    +            case GENERAL_STRING:
    +                return new DERGeneralString(defIn.toByteArray());
    +            case IA5_STRING:
    +                return new DERIA5String(defIn.toByteArray());
    +            case INTEGER:
    +                return new ASN1Integer(defIn.toByteArray());
    +            case NULL:
    +                return DERNull.INSTANCE;   // actual content is ignored (enforce 0 length?)
    +            case NUMERIC_STRING:
    +                return new DERNumericString(defIn.toByteArray());
    +            case OBJECT_IDENTIFIER:
    +                return ASN1ObjectIdentifier.fromOctetString(getBuffer(defIn, tmpBuffers));
    +            case OCTET_STRING:
    +                return new DEROctetString(defIn.toByteArray());
    +            case PRINTABLE_STRING:
    +                return new DERPrintableString(defIn.toByteArray());
    +            case T61_STRING:
    +                return new DERT61String(defIn.toByteArray());
    +            case UNIVERSAL_STRING:
    +                return new DERUniversalString(defIn.toByteArray());
    +            case UTC_TIME:
    +                return new ASN1UTCTime(defIn.toByteArray());
    +            case UTF8_STRING:
    +                return new DERUTF8String(defIn.toByteArray());
    +            case VISIBLE_STRING:
    +                return new DERVisibleString(defIn.toByteArray());
    +            default:
    +                throw new IOException("unknown tag " + tagNo + " encountered");
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1Integer.java+22 0 added
    @@ -0,0 +1,22 @@
    +package org.bouncycastle.asn1;
    +
    +import java.math.BigInteger;
    +
    +public class ASN1Integer
    +    extends DERInteger
    +{
    +    ASN1Integer(byte[] bytes)
    +    {
    +        super(bytes);
    +    }
    +
    +    public ASN1Integer(BigInteger value)
    +    {
    +        super(value);
    +    }
    +
    +    public ASN1Integer(long value)
    +    {
    +        super(value);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1Null.java+67 0 added
    @@ -0,0 +1,67 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +/**
    + * A NULL object.
    + */
    +public abstract class ASN1Null
    +    extends ASN1Primitive
    +{
    +    /**
    +     * @deprecated use DERNull.INSTANCE
    +     */
    +    public ASN1Null()
    +    {
    +    }
    +
    +    public static ASN1Null getInstance(Object o)
    +    {
    +        if (o instanceof ASN1Null)
    +        {
    +            return (ASN1Null)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            try
    +            {
    +                return ASN1Null.getInstance(ASN1Primitive.fromByteArray((byte[])o));
    +            }
    +            catch (IOException e)
    +            {
    +                throw new IllegalArgumentException("failed to construct NULL from byte[]: " + e.getMessage());
    +            }
    +            catch (ClassCastException e)
    +            {
    +                throw new IllegalArgumentException("unknown object in getInstance(): " + o.getClass().getName());
    +            }
    +        }
    +
    +        return null;
    +    }
    +
    +    public int hashCode()
    +    {
    +        return -1;
    +    }
    +
    +    boolean asn1Equals(
    +        ASN1Primitive o)
    +    {
    +        if (!(o instanceof ASN1Null))
    +        {
    +            return false;
    +        }
    +        
    +        return true;
    +    }
    +
    +    abstract void encode(ASN1OutputStream out)
    +        throws IOException;
    +
    +    public String toString()
    +    {
    +         return "NULL";
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java+42 0 added
    @@ -0,0 +1,42 @@
    +package org.bouncycastle.asn1;
    +
    +public class ASN1ObjectIdentifier
    +    extends DERObjectIdentifier
    +{
    +    public ASN1ObjectIdentifier(String identifier)
    +    {
    +        super(identifier);
    +    }
    +
    +    ASN1ObjectIdentifier(byte[] bytes)
    +    {
    +        super(bytes);
    +    }
    +
    +    ASN1ObjectIdentifier(ASN1ObjectIdentifier oid, String branch)
    +    {
    +        super(oid, branch);
    +    }
    +
    +    /**
    +     * Return an OID that creates a branch under the current one.
    +     *
    +     * @param branchID node numbers for the new branch.
    +     * @return the OID for the new created branch.
    +     */
    +    public ASN1ObjectIdentifier branch(String branchID)
    +    {
    +        return new ASN1ObjectIdentifier(this, branchID);
    +    }
    +
    +    /**
    +     * Return  true if this oid is an extension of the passed in branch, stem.
    +     * @param stem the arc or branch that is a possible parent.
    +     * @return  true if the branch is on the passed in stem, false otherwise.
    +     */
    +    public boolean on(ASN1ObjectIdentifier stem)
    +    {
    +        String id = getId(), stemId = stem.getId();
    +        return id.length() > stemId.length() && id.charAt(stemId.length()) == '.' && id.startsWith(stemId);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1Object.java+97 0 added
    @@ -0,0 +1,97 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.ByteArrayOutputStream;
    +import java.io.IOException;
    +
    +public abstract class ASN1Object
    +    implements ASN1Encodable
    +{
    +    /**
    +     * Return the default BER or DER encoding for this object.
    +     *
    +     * @return BER/DER byte encoded object.
    +     * @throws java.io.IOException on encoding error.
    +     */
    +    public byte[] getEncoded()
    +        throws IOException
    +    {
    +        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    +        ASN1OutputStream      aOut = new ASN1OutputStream(bOut);
    +
    +        aOut.writeObject(this);
    +
    +        return bOut.toByteArray();
    +    }
    +
    +    /**
    +     * Return either the default for "BER" or a DER encoding if "DER" is specified.
    +     *
    +     * @param encoding name of encoding to use.
    +     * @return byte encoded object.
    +     * @throws IOException on encoding error.
    +     */
    +    public byte[] getEncoded(
    +        String encoding)
    +        throws IOException
    +    {
    +        if (encoding.equals(ASN1Encoding.DER))
    +        {
    +            ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
    +            DEROutputStream         dOut = new DEROutputStream(bOut);
    +
    +            dOut.writeObject(this);
    +
    +            return bOut.toByteArray();
    +        }
    +        else if (encoding.equals(ASN1Encoding.DL))
    +        {
    +            ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
    +            DLOutputStream          dOut = new DLOutputStream(bOut);
    +
    +            dOut.writeObject(this);
    +
    +            return bOut.toByteArray();
    +        }
    +
    +        return this.getEncoded();
    +    }
    +
    +    public int hashCode()
    +    {
    +        return this.toASN1Primitive().hashCode();
    +    }
    +
    +    public boolean equals(
    +        Object  o)
    +    {
    +        if (this == o)
    +        {
    +            return true;
    +        }
    +
    +        if (!(o instanceof ASN1Encodable))
    +        {
    +            return false;
    +        }
    +
    +        ASN1Encodable other = (ASN1Encodable)o;
    +
    +        return this.toASN1Primitive().equals(other.toASN1Primitive());
    +    }
    +
    +    /**
    +     * @deprecated use toASN1Primitive()
    +     * @return the underlying primitive type.
    +     */
    +    public ASN1Primitive toASN1Object()
    +    {
    +        return this.toASN1Primitive();
    +    }
    +
    +    protected static boolean hasEncodedTagValue(Object obj, int tagValue)
    +    {
    +        return (obj instanceof byte[]) && ((byte[])obj)[0] == tagValue;
    +    }
    +
    +    public abstract ASN1Primitive toASN1Primitive();
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java+146 0 added
    @@ -0,0 +1,146 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.ByteArrayInputStream;
    +import java.io.IOException;
    +import java.io.InputStream;
    +
    +import org.bouncycastle.util.Arrays;
    +import org.bouncycastle.util.encoders.Hex;
    +
    +public abstract class ASN1OctetString
    +    extends ASN1Primitive
    +    implements ASN1OctetStringParser
    +{
    +    byte[]  string;
    +
    +    /**
    +     * return an Octet String from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want.
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the tagged object cannot
    +     *              be converted.
    +     */
    +    public static ASN1OctetString getInstance(
    +        ASN1TaggedObject    obj,
    +        boolean             explicit)
    +    {
    +        ASN1Primitive o = obj.getObject();
    +
    +        if (explicit || o instanceof ASN1OctetString)
    +        {
    +            return getInstance(o);
    +        }
    +        else
    +        {
    +            return BEROctetString.fromSequence(ASN1Sequence.getInstance(o));
    +        }
    +    }
    +    
    +    /**
    +     * return an Octet String from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static ASN1OctetString getInstance(
    +        Object  obj)
    +    {
    +        if (obj == null || obj instanceof ASN1OctetString)
    +        {
    +            return (ASN1OctetString)obj;
    +        }
    +        else if (obj instanceof byte[])
    +        {
    +            try
    +            {
    +                return ASN1OctetString.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
    +            }
    +            catch (IOException e)
    +            {
    +                throw new IllegalArgumentException("failed to construct OCTET STRING from byte[]: " + e.getMessage());
    +            }
    +        }
    +        else if (obj instanceof ASN1Encodable)
    +        {
    +            ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
    +
    +            if (primitive instanceof ASN1OctetString)
    +            {
    +                return (ASN1OctetString)primitive;
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * @param string the octets making up the octet string.
    +     */
    +    public ASN1OctetString(
    +        byte[]  string)
    +    {
    +        if (string == null)
    +        {
    +            throw new NullPointerException("string cannot be null");
    +        }
    +        this.string = string;
    +    }
    +
    +    public InputStream getOctetStream()
    +    {
    +        return new ByteArrayInputStream(string);
    +    }
    +
    +    public ASN1OctetStringParser parser()
    +    {
    +        return this;
    +    }
    +
    +    public byte[] getOctets()
    +    {
    +        return string;
    +    }
    +
    +    public int hashCode()
    +    {
    +        return Arrays.hashCode(this.getOctets());
    +    }
    +
    +    boolean asn1Equals(
    +        ASN1Primitive o)
    +    {
    +        if (!(o instanceof ASN1OctetString))
    +        {
    +            return false;
    +        }
    +
    +        ASN1OctetString  other = (ASN1OctetString)o;
    +
    +        return Arrays.areEqual(string, other.string);
    +    }
    +
    +    public ASN1Primitive getLoadedObject()
    +    {
    +        return this.toASN1Primitive();
    +    }
    +
    +    ASN1Primitive toDERObject()
    +    {
    +        return new DEROctetString(string);
    +    }
    +
    +    ASN1Primitive toDLObject()
    +    {
    +        return new DEROctetString(string);
    +    }
    +
    +    abstract void encode(ASN1OutputStream out)
    +        throws IOException;
    +
    +    public String toString()
    +    {
    +      return "#"+new String(Hex.encode(string));
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1OctetStringParser.java+9 0 added
    @@ -0,0 +1,9 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.InputStream;
    +
    +public interface ASN1OctetStringParser
    +    extends ASN1Encodable, InMemoryRepresentable
    +{
    +    public InputStream getOctetStream();
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1OutputStream.java+194 0 added
    @@ -0,0 +1,194 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.io.OutputStream;
    +
    +/**
    + * Stream that produces output based on the default encoding for the passed in objects.
    + */
    +public class ASN1OutputStream
    +{
    +    private OutputStream os;
    +
    +    public ASN1OutputStream(
    +        OutputStream    os)
    +    {
    +        this.os = os;
    +    }
    +
    +    void writeLength(
    +        int length)
    +        throws IOException
    +    {
    +        if (length > 127)
    +        {
    +            int size = 1;
    +            int val = length;
    +
    +            while ((val >>>= 8) != 0)
    +            {
    +                size++;
    +            }
    +
    +            write((byte)(size | 0x80));
    +
    +            for (int i = (size - 1) * 8; i >= 0; i -= 8)
    +            {
    +                write((byte)(length >> i));
    +            }
    +        }
    +        else
    +        {
    +            write((byte)length);
    +        }
    +    }
    +
    +    void write(int b)
    +        throws IOException
    +    {
    +        os.write(b);
    +    }
    +
    +    void write(byte[] bytes)
    +        throws IOException
    +    {
    +        os.write(bytes);
    +    }
    +
    +    void write(byte[] bytes, int off, int len)
    +        throws IOException
    +    {
    +        os.write(bytes, off, len);
    +    }
    +
    +    void writeEncoded(
    +        int     tag,
    +        byte[]  bytes)
    +        throws IOException
    +    {
    +        write(tag);
    +        writeLength(bytes.length);
    +        write(bytes);
    +    }
    +
    +    void writeTag(int flags, int tagNo)
    +        throws IOException
    +    {
    +        if (tagNo < 31)
    +        {
    +            write(flags | tagNo);
    +        }
    +        else
    +        {
    +            write(flags | 0x1f);
    +            if (tagNo < 128)
    +            {
    +                write(tagNo);
    +            }
    +            else
    +            {
    +                byte[] stack = new byte[5];
    +                int pos = stack.length;
    +
    +                stack[--pos] = (byte)(tagNo & 0x7F);
    +
    +                do
    +                {
    +                    tagNo >>= 7;
    +                    stack[--pos] = (byte)(tagNo & 0x7F | 0x80);
    +                }
    +                while (tagNo > 127);
    +
    +                write(stack, pos, stack.length - pos);
    +            }
    +        }
    +    }
    +
    +    void writeEncoded(int flags, int tagNo, byte[] bytes)
    +        throws IOException
    +    {
    +        writeTag(flags, tagNo);
    +        writeLength(bytes.length);
    +        write(bytes);
    +    }
    +
    +    protected void writeNull()
    +        throws IOException
    +    {
    +        os.write(BERTags.NULL);
    +        os.write(0x00);
    +    }
    +
    +    public void writeObject(
    +        ASN1Encodable obj)
    +        throws IOException
    +    {
    +        if (obj != null)
    +        {
    +            obj.toASN1Primitive().encode(this);
    +        }
    +        else
    +        {
    +            throw new IOException("null object detected");
    +        }
    +    }
    +
    +    void writeImplicitObject(ASN1Primitive obj)
    +        throws IOException
    +    {
    +        if (obj != null)
    +        {
    +            obj.encode(new ImplicitOutputStream(os));
    +        }
    +        else
    +        {
    +            throw new IOException("null object detected");
    +        }
    +    }
    +
    +    public void close()
    +        throws IOException
    +    {
    +        os.close();
    +    }
    +
    +    public void flush()
    +        throws IOException
    +    {
    +        os.flush();
    +    }
    +
    +    ASN1OutputStream getDERSubStream()
    +    {
    +        return new DEROutputStream(os);
    +    }
    +
    +    ASN1OutputStream getDLSubStream()
    +    {
    +        return new DLOutputStream(os);
    +    }
    +
    +    private class ImplicitOutputStream
    +        extends ASN1OutputStream
    +    {
    +        private boolean first = true;
    +
    +        public ImplicitOutputStream(OutputStream os)
    +        {
    +            super(os);
    +        }
    +
    +        public void write(int b)
    +            throws IOException
    +        {
    +            if (first)
    +            {
    +                first = false;
    +            }
    +            else
    +            {
    +                super.write(b);
    +            }
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1ParsingException.java+23 0 added
    @@ -0,0 +1,23 @@
    +package org.bouncycastle.asn1;
    +
    +public class ASN1ParsingException
    +    extends IllegalStateException
    +{
    +    private Throwable cause;
    +
    +    public ASN1ParsingException(String message)
    +    {
    +        super(message);
    +    }
    +
    +    public ASN1ParsingException(String message, Throwable cause)
    +    {
    +        super(message);
    +        this.cause = cause;
    +    }
    +
    +    public Throwable getCause()
    +    {
    +        return cause;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1Primitive.java+69 0 added
    @@ -0,0 +1,69 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +public abstract class ASN1Primitive
    +    extends ASN1Object
    +{
    +    ASN1Primitive()
    +    {
    +
    +    }
    +
    +    /**
    +     * Create a base ASN.1 object from a byte stream.
    +     *
    +     * @param data the byte stream to parse.
    +     * @return the base ASN.1 object represented by the byte stream.
    +     * @exception IOException if there is a problem parsing the data.
    +     */
    +    public static ASN1Primitive fromByteArray(byte[] data)
    +        throws IOException
    +    {
    +        ASN1InputStream aIn = new ASN1InputStream(data);
    +
    +        try
    +        {
    +            return aIn.readObject();
    +        }
    +        catch (ClassCastException e)
    +        {
    +            throw new IOException("cannot recognise object in stream");
    +        }
    +    }
    +
    +    public final boolean equals(Object o)
    +    {
    +        if (this == o)
    +        {
    +            return true;
    +        }
    +
    +        return (o instanceof ASN1Encodable) && asn1Equals(((ASN1Encodable)o).toASN1Primitive());
    +    }
    +
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        return this;
    +    }
    +
    +    ASN1Primitive toDERObject()
    +    {
    +        return this;
    +    }
    +
    +    ASN1Primitive toDLObject()
    +    {
    +        return this;
    +    }
    +
    +    public abstract int hashCode();
    +
    +    abstract boolean isConstructed();
    +
    +    abstract int encodedLength() throws IOException;
    +
    +    abstract void encode(ASN1OutputStream out) throws IOException;
    +
    +    abstract boolean asn1Equals(ASN1Primitive o);
    +}
    \ No newline at end of file
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1Sequence.java+323 0 added
    @@ -0,0 +1,323 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.util.Enumeration;
    +import java.util.Vector;
    +
    +public abstract class ASN1Sequence
    +    extends ASN1Primitive
    +{
    +    protected Vector seq = new Vector();
    +
    +    /**
    +     * return an ASN1Sequence from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static ASN1Sequence getInstance(
    +        Object  obj)
    +    {
    +        if (obj == null || obj instanceof ASN1Sequence)
    +        {
    +            return (ASN1Sequence)obj;
    +        }
    +        else if (obj instanceof ASN1SequenceParser)
    +        {
    +            return ASN1Sequence.getInstance(((ASN1SequenceParser)obj).toASN1Primitive());
    +        }
    +        else if (obj instanceof byte[])
    +        {
    +            try
    +            {
    +                return ASN1Sequence.getInstance(fromByteArray((byte[])obj));
    +            }
    +            catch (IOException e)
    +            {
    +                throw new IllegalArgumentException("failed to construct sequence from byte[]: " + e.getMessage());
    +            }
    +        }
    +        else if (obj instanceof ASN1Encodable)
    +        {
    +            ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
    +
    +            if (primitive instanceof ASN1Sequence)
    +            {
    +                return (ASN1Sequence)primitive;
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * Return an ASN1 sequence from a tagged object. There is a special
    +     * case here, if an object appears to have been explicitly tagged on 
    +     * reading but we were expecting it to be implicitly tagged in the 
    +     * normal course of events it indicates that we lost the surrounding
    +     * sequence - so we need to add it back (this will happen if the tagged
    +     * object is a sequence that contains other sequences). If you are
    +     * dealing with implicitly tagged sequences you really <b>should</b>
    +     * be using this method.
    +     *
    +     * @param obj the tagged object.
    +     * @param explicit true if the object is meant to be explicitly tagged,
    +     *          false otherwise.
    +     * @exception IllegalArgumentException if the tagged object cannot
    +     *          be converted.
    +     */
    +    public static ASN1Sequence getInstance(
    +        ASN1TaggedObject    obj,
    +        boolean             explicit)
    +    {
    +        if (explicit)
    +        {
    +            if (!obj.isExplicit())
    +            {
    +                throw new IllegalArgumentException("object implicit - explicit expected.");
    +            }
    +
    +            return ASN1Sequence.getInstance(obj.getObject().toASN1Primitive());
    +        }
    +        else
    +        {
    +            //
    +            // constructed object which appears to be explicitly tagged
    +            // when it should be implicit means we have to add the
    +            // surrounding sequence.
    +            //
    +            if (obj.isExplicit())
    +            {
    +                if (obj instanceof BERTaggedObject)
    +                {
    +                    return new BERSequence(obj.getObject());
    +                }
    +                else
    +                {
    +                    return new DLSequence(obj.getObject());
    +                }
    +            }
    +            else
    +            {
    +                if (obj.getObject() instanceof ASN1Sequence)
    +                {
    +                    return (ASN1Sequence)obj.getObject();
    +                }
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * create an empty sequence
    +     */
    +    protected ASN1Sequence()
    +    {
    +    }
    +
    +    /**
    +     * create a sequence containing one object
    +     */
    +    protected ASN1Sequence(
    +        ASN1Encodable obj)
    +    {
    +        seq.addElement(obj);
    +    }
    +
    +    /**
    +     * create a sequence containing a vector of objects.
    +     */
    +    protected ASN1Sequence(
    +        ASN1EncodableVector v)
    +    {
    +        for (int i = 0; i != v.size(); i++)
    +        {
    +            seq.addElement(v.get(i));
    +        }
    +    }
    +
    +    /**
    +     * create a sequence containing a vector of objects.
    +     */
    +    protected ASN1Sequence(
    +        ASN1Encodable[]   array)
    +    {
    +        for (int i = 0; i != array.length; i++)
    +        {
    +            seq.addElement(array[i]);
    +        }
    +    }
    +
    +    public ASN1Encodable[] toArray()
    +    {
    +        ASN1Encodable[] values = new ASN1Encodable[this.size()];
    +
    +        for (int i = 0; i != this.size(); i++)
    +        {
    +            values[i] = this.getObjectAt(i);
    +        }
    +
    +        return values;
    +    }
    +
    +    public Enumeration getObjects()
    +    {
    +        return seq.elements();
    +    }
    +
    +    public ASN1SequenceParser parser()
    +    {
    +        final ASN1Sequence outer = this;
    +
    +        return new ASN1SequenceParser()
    +        {
    +            private final int max = size();
    +
    +            private int index;
    +
    +            public ASN1Encodable readObject() throws IOException
    +            {
    +                if (index == max)
    +                {
    +                    return null;
    +                }
    +                
    +                ASN1Encodable obj = getObjectAt(index++);
    +                if (obj instanceof ASN1Sequence)
    +                {
    +                    return ((ASN1Sequence)obj).parser();
    +                }
    +                if (obj instanceof ASN1Set)
    +                {
    +                    return ((ASN1Set)obj).parser();
    +                }
    +
    +                return obj;
    +            }
    +
    +            public ASN1Primitive getLoadedObject()
    +            {
    +                return outer;
    +            }
    +            
    +            public ASN1Primitive toASN1Primitive()
    +            {
    +                return outer;
    +            }
    +        };
    +    }
    +
    +    /**
    +     * return the object at the sequence position indicated by index.
    +     *
    +     * @param index the sequence number (starting at zero) of the object
    +     * @return the object at the sequence position indicated by index.
    +     */
    +    public ASN1Encodable getObjectAt(
    +        int index)
    +    {
    +        return (ASN1Encodable)seq.elementAt(index);
    +    }
    +
    +    /**
    +     * return the number of objects in this sequence.
    +     *
    +     * @return the number of objects in this sequence.
    +     */
    +    public int size()
    +    {
    +        return seq.size();
    +    }
    +
    +    public int hashCode()
    +    {
    +        Enumeration             e = this.getObjects();
    +        int                     hashCode = size();
    +
    +        while (e.hasMoreElements())
    +        {
    +            Object o = getNext(e);
    +            hashCode *= 17;
    +
    +            hashCode ^= o.hashCode();
    +        }
    +
    +        return hashCode;
    +    }
    +
    +    boolean asn1Equals(
    +        ASN1Primitive o)
    +    {
    +        if (!(o instanceof ASN1Sequence))
    +        {
    +            return false;
    +        }
    +        
    +        ASN1Sequence   other = (ASN1Sequence)o;
    +
    +        if (this.size() != other.size())
    +        {
    +            return false;
    +        }
    +
    +        Enumeration s1 = this.getObjects();
    +        Enumeration s2 = other.getObjects();
    +
    +        while (s1.hasMoreElements())
    +        {
    +            ASN1Encodable obj1 = getNext(s1);
    +            ASN1Encodable obj2 = getNext(s2);
    +
    +            ASN1Primitive o1 = obj1.toASN1Primitive();
    +            ASN1Primitive o2 = obj2.toASN1Primitive();
    +
    +            if (o1 == o2 || o1.equals(o2))
    +            {
    +                continue;
    +            }
    +
    +            return false;
    +        }
    +
    +        return true;
    +    }
    +
    +    private ASN1Encodable getNext(Enumeration e)
    +    {
    +        ASN1Encodable encObj = (ASN1Encodable)e.nextElement();
    +
    +        return encObj;
    +    }
    +
    +    ASN1Primitive toDERObject()
    +    {
    +        ASN1Sequence derSeq = new DERSequence();
    +
    +        derSeq.seq = this.seq;
    +
    +        return derSeq;
    +    }
    +
    +    ASN1Primitive toDLObject()
    +    {
    +        ASN1Sequence dlSeq = new DLSequence();
    +
    +        dlSeq.seq = this.seq;
    +
    +        return dlSeq;
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return true;
    +    }
    +
    +    abstract void encode(ASN1OutputStream out)
    +        throws IOException;
    +
    +    public String toString() 
    +    {
    +        return seq.toString();
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1SequenceParser.java+10 0 added
    @@ -0,0 +1,10 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +public interface ASN1SequenceParser
    +    extends ASN1Encodable, InMemoryRepresentable
    +{
    +    ASN1Encodable readObject()
    +        throws IOException;
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1Set.java+460 0 added
    @@ -0,0 +1,460 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.ByteArrayOutputStream;
    +import java.io.IOException;
    +import java.util.Enumeration;
    +import java.util.Vector;
    +
    +abstract public class ASN1Set
    +    extends ASN1Primitive
    +{
    +    private Vector set = new Vector();
    +    private boolean isSorted = false;
    +
    +    /**
    +     * return an ASN1Set from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static ASN1Set getInstance(
    +        Object  obj)
    +    {
    +        if (obj == null || obj instanceof ASN1Set)
    +        {
    +            return (ASN1Set)obj;
    +        }
    +        else if (obj instanceof ASN1SetParser)
    +        {
    +            return ASN1Set.getInstance(((ASN1SetParser)obj).toASN1Primitive());
    +        }
    +        else if (obj instanceof byte[])
    +        {
    +            try
    +            {
    +                return ASN1Set.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
    +            }
    +            catch (IOException e)
    +            {
    +                throw new IllegalArgumentException("failed to construct set from byte[]: " + e.getMessage());
    +            }
    +        }
    +        else if (obj instanceof ASN1Encodable)
    +        {
    +            ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
    +
    +            if (primitive instanceof ASN1Set)
    +            {
    +                return (ASN1Set)primitive;
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * Return an ASN1 set from a tagged object. There is a special
    +     * case here, if an object appears to have been explicitly tagged on 
    +     * reading but we were expecting it to be implicitly tagged in the 
    +     * normal course of events it indicates that we lost the surrounding
    +     * set - so we need to add it back (this will happen if the tagged
    +     * object is a sequence that contains other sequences). If you are
    +     * dealing with implicitly tagged sets you really <b>should</b>
    +     * be using this method.
    +     *
    +     * @param obj the tagged object.
    +     * @param explicit true if the object is meant to be explicitly tagged
    +     *          false otherwise.
    +     * @exception IllegalArgumentException if the tagged object cannot
    +     *          be converted.
    +     */
    +    public static ASN1Set getInstance(
    +        ASN1TaggedObject    obj,
    +        boolean             explicit)
    +    {
    +        if (explicit)
    +        {
    +            if (!obj.isExplicit())
    +            {
    +                throw new IllegalArgumentException("object implicit - explicit expected.");
    +            }
    +
    +            return (ASN1Set)obj.getObject();
    +        }
    +        else
    +        {
    +            //
    +            // constructed object which appears to be explicitly tagged
    +            // and it's really implicit means we have to add the
    +            // surrounding set.
    +            //
    +            if (obj.isExplicit())
    +            {
    +                if (obj instanceof BERTaggedObject)
    +                {
    +                    return new BERSet(obj.getObject());
    +                }
    +                else
    +                {
    +                    return new DLSet(obj.getObject());
    +                }
    +            }
    +            else
    +            {
    +                if (obj.getObject() instanceof ASN1Set)
    +                {
    +                    return (ASN1Set)obj.getObject();
    +                }
    +
    +                //
    +                // in this case the parser returns a sequence, convert it
    +                // into a set.
    +                //
    +                if (obj.getObject() instanceof ASN1Sequence)
    +                {
    +                    ASN1Sequence s = (ASN1Sequence)obj.getObject();
    +
    +                    if (obj instanceof BERTaggedObject)
    +                    {
    +                        return new BERSet(s.toArray());
    +                    }
    +                    else
    +                    {
    +                        return new DLSet(s.toArray());
    +                    }
    +                }
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    protected ASN1Set()
    +    {
    +    }
    +
    +    /**
    +     * create a sequence containing one object
    +     */
    +    protected ASN1Set(
    +        ASN1Encodable obj)
    +    {
    +        set.addElement(obj);
    +    }
    +
    +    /**
    +     * create a sequence containing a vector of objects.
    +     */
    +    protected ASN1Set(
    +        ASN1EncodableVector v,
    +        boolean                  doSort)
    +    {
    +        for (int i = 0; i != v.size(); i++)
    +        {
    +            set.addElement(v.get(i));
    +        }
    +
    +        if (doSort)
    +        {
    +            this.sort();
    +        }
    +    }
    +
    +    /**
    +     * create a sequence containing a vector of objects.
    +     */
    +    protected ASN1Set(
    +        ASN1Encodable[]   array,
    +        boolean doSort)
    +    {
    +        for (int i = 0; i != array.length; i++)
    +        {
    +            set.addElement(array[i]);
    +        }
    +
    +        if (doSort)
    +        {
    +            this.sort();
    +        }
    +    }
    +
    +    public Enumeration getObjects()
    +    {
    +        return set.elements();
    +    }
    +
    +    /**
    +     * return the object at the set position indicated by index.
    +     *
    +     * @param index the set number (starting at zero) of the object
    +     * @return the object at the set position indicated by index.
    +     */
    +    public ASN1Encodable getObjectAt(
    +        int index)
    +    {
    +        return (ASN1Encodable)set.elementAt(index);
    +    }
    +
    +    /**
    +     * return the number of objects in this set.
    +     *
    +     * @return the number of objects in this set.
    +     */
    +    public int size()
    +    {
    +        return set.size();
    +    }
    +
    +    public ASN1Encodable[] toArray()
    +    {
    +        ASN1Encodable[] values = new ASN1Encodable[this.size()];
    +
    +        for (int i = 0; i != this.size(); i++)
    +        {
    +            values[i] = this.getObjectAt(i);
    +        }
    +
    +        return values;
    +    }
    +
    +    public ASN1SetParser parser()
    +    {
    +        final ASN1Set outer = this;
    +
    +        return new ASN1SetParser()
    +        {
    +            private final int max = size();
    +
    +            private int index;
    +
    +            public ASN1Encodable readObject() throws IOException
    +            {
    +                if (index == max)
    +                {
    +                    return null;
    +                }
    +
    +                ASN1Encodable obj = getObjectAt(index++);
    +                if (obj instanceof ASN1Sequence)
    +                {
    +                    return ((ASN1Sequence)obj).parser();
    +                }
    +                if (obj instanceof ASN1Set)
    +                {
    +                    return ((ASN1Set)obj).parser();
    +                }
    +
    +                return obj;
    +            }
    +
    +            public ASN1Primitive getLoadedObject()
    +            {
    +                return outer;
    +            }
    +
    +            public ASN1Primitive toASN1Primitive()
    +            {
    +                return outer;
    +            }
    +        };
    +    }
    +
    +    public int hashCode()
    +    {
    +        Enumeration             e = this.getObjects();
    +        int                     hashCode = size();
    +
    +        while (e.hasMoreElements())
    +        {
    +            Object o = getNext(e);
    +            hashCode *= 17;
    +
    +            hashCode ^= o.hashCode();
    +        }
    +
    +        return hashCode;
    +    }
    +
    +    ASN1Primitive toDERObject()
    +    {
    +        if (isSorted)
    +        {
    +            ASN1Set derSet = new DERSet();
    +
    +            derSet.set = this.set;
    +
    +            return derSet;
    +        }
    +        else
    +        {
    +            Vector v = new Vector();
    +
    +            for (int i = 0; i != set.size(); i++)
    +            {
    +                v.addElement(set.elementAt(i));
    +            }
    +
    +            ASN1Set derSet = new DERSet();
    +
    +            derSet.set = v;
    +
    +            derSet.sort();
    +
    +            return derSet;
    +        }
    +    }
    +
    +    ASN1Primitive toDLObject()
    +    {
    +        ASN1Set derSet = new DLSet();
    +
    +        derSet.set = this.set;
    +
    +        return derSet;
    +    }
    +
    +    boolean asn1Equals(
    +        ASN1Primitive o)
    +    {
    +        if (!(o instanceof ASN1Set))
    +        {
    +            return false;
    +        }
    +
    +        ASN1Set   other = (ASN1Set)o;
    +
    +        if (this.size() != other.size())
    +        {
    +            return false;
    +        }
    +
    +        Enumeration s1 = this.getObjects();
    +        Enumeration s2 = other.getObjects();
    +
    +        while (s1.hasMoreElements())
    +        {
    +            ASN1Encodable obj1 = getNext(s1);
    +            ASN1Encodable obj2 = getNext(s2);
    +
    +            ASN1Primitive o1 = obj1.toASN1Primitive();
    +            ASN1Primitive o2 = obj2.toASN1Primitive();
    +
    +            if (o1 == o2 || o1.equals(o2))
    +            {
    +                continue;
    +            }
    +
    +            return false;
    +        }
    +
    +        return true;
    +    }
    +
    +    private ASN1Encodable getNext(Enumeration e)
    +    {
    +        ASN1Encodable encObj = (ASN1Encodable)e.nextElement();
    +
    +        // unfortunately null was allowed as a substitute for DER null
    +        if (encObj == null)
    +        {
    +            return DERNull.INSTANCE;
    +        }
    +
    +        return encObj;
    +    }
    +
    +    /**
    +     * return true if a <= b (arrays are assumed padded with zeros).
    +     */
    +    private boolean lessThanOrEqual(
    +         byte[] a,
    +         byte[] b)
    +    {
    +        int len = Math.min(a.length, b.length);
    +        for (int i = 0; i != len; ++i)
    +        {
    +            if (a[i] != b[i])
    +            {
    +                return (a[i] & 0xff) < (b[i] & 0xff);
    +            }
    +        }
    +        return len == a.length;
    +    }
    +
    +    private byte[] getEncoded(
    +        ASN1Encodable obj)
    +    {
    +        ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
    +        ASN1OutputStream        aOut = new ASN1OutputStream(bOut);
    +
    +        try
    +        {
    +            aOut.writeObject(obj);
    +        }
    +        catch (IOException e)
    +        {
    +            throw new IllegalArgumentException("cannot encode object added to SET");
    +        }
    +
    +        return bOut.toByteArray();
    +    }
    +
    +    protected void sort()
    +    {
    +        if (!isSorted)
    +        {
    +            isSorted = true;
    +            if (set.size() > 1)
    +            {
    +                boolean    swapped = true;
    +                int        lastSwap = set.size() - 1;
    +
    +                while (swapped)
    +                {
    +                    int    index = 0;
    +                    int    swapIndex = 0;
    +                    byte[] a = getEncoded((ASN1Encodable)set.elementAt(0));
    +
    +                    swapped = false;
    +
    +                    while (index != lastSwap)
    +                    {
    +                        byte[] b = getEncoded((ASN1Encodable)set.elementAt(index + 1));
    +
    +                        if (lessThanOrEqual(a, b))
    +                        {
    +                            a = b;
    +                        }
    +                        else
    +                        {
    +                            Object  o = set.elementAt(index);
    +
    +                            set.setElementAt(set.elementAt(index + 1), index);
    +                            set.setElementAt(o, index + 1);
    +
    +                            swapped = true;
    +                            swapIndex = index;
    +                        }
    +
    +                        index++;
    +                    }
    +
    +                    lastSwap = swapIndex;
    +                }
    +            }
    +        }
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return true;
    +    }
    +
    +    abstract void encode(ASN1OutputStream out)
    +            throws IOException;
    +
    +    public String toString() 
    +    {
    +        return set.toString();
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1SetParser.java+10 0 added
    @@ -0,0 +1,10 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +public interface ASN1SetParser
    +    extends ASN1Encodable, InMemoryRepresentable
    +{
    +    public ASN1Encodable readObject()
    +        throws IOException;
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java+247 0 added
    @@ -0,0 +1,247 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.ByteArrayInputStream;
    +import java.io.IOException;
    +import java.io.InputStream;
    +
    +public class ASN1StreamParser
    +{
    +    private final InputStream _in;
    +    private final int         _limit;
    +    private final byte[][] tmpBuffers;
    +
    +    public ASN1StreamParser(
    +        InputStream in)
    +    {
    +        this(in, StreamUtil.findLimit(in));
    +    }
    +
    +    public ASN1StreamParser(
    +        InputStream in,
    +        int         limit)
    +    {
    +        this._in = in;
    +        this._limit = limit;
    +
    +        this.tmpBuffers = new byte[11][];
    +    }
    +
    +    public ASN1StreamParser(
    +        byte[] encoding)
    +    {
    +        this(new ByteArrayInputStream(encoding), encoding.length);
    +    }
    +
    +    ASN1Encodable readIndef(int tagValue) throws IOException
    +    {
    +        // Note: INDEF => CONSTRUCTED
    +
    +        // TODO There are other tags that may be constructed (e.g. BIT_STRING)
    +        switch (tagValue)
    +        {
    +            case BERTags.EXTERNAL:
    +                return new DERExternalParser(this);
    +            case BERTags.OCTET_STRING:
    +                return new BEROctetStringParser(this);
    +            case BERTags.SEQUENCE:
    +                return new BERSequenceParser(this);
    +            case BERTags.SET:
    +                return new BERSetParser(this);
    +            default:
    +                throw new ASN1Exception("unknown BER object encountered: 0x" + Integer.toHexString(tagValue));
    +        }
    +    }
    +
    +    ASN1Encodable readImplicit(boolean constructed, int tag) throws IOException
    +    {
    +        if (_in instanceof IndefiniteLengthInputStream)
    +        {
    +            if (!constructed)
    +            {
    +                throw new IOException("indefinite length primitive encoding encountered");
    +            }
    +            
    +            return readIndef(tag);
    +        }
    +
    +        if (constructed)
    +        {
    +            switch (tag)
    +            {
    +                case BERTags.SET:
    +                    return new DERSetParser(this);
    +                case BERTags.SEQUENCE:
    +                    return new DERSequenceParser(this);
    +                case BERTags.OCTET_STRING:
    +                    return new BEROctetStringParser(this);
    +            }
    +        }
    +        else
    +        {
    +            switch (tag)
    +            {
    +                case BERTags.SET:
    +                    throw new ASN1Exception("sequences must use constructed encoding (see X.690 8.9.1/8.10.1)");
    +                case BERTags.SEQUENCE:
    +                    throw new ASN1Exception("sets must use constructed encoding (see X.690 8.11.1/8.12.1)");
    +                case BERTags.OCTET_STRING:
    +                    return new DEROctetStringParser((DefiniteLengthInputStream)_in);
    +            }
    +        }
    +
    +        // TODO ASN1Exception
    +        throw new RuntimeException("implicit tagging not implemented");
    +    }
    +
    +    ASN1Primitive readTaggedObject(boolean constructed, int tag) throws IOException
    +    {
    +        if (!constructed)
    +        {
    +            // Note: !CONSTRUCTED => IMPLICIT
    +            DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_in;
    +            return new DERTaggedObject(false, tag, new DEROctetString(defIn.toByteArray()));
    +        }
    +
    +        ASN1EncodableVector v = readVector();
    +
    +        if (_in instanceof IndefiniteLengthInputStream)
    +        {
    +            return v.size() == 1
    +                ?   new BERTaggedObject(true, tag, v.get(0))
    +                :   new BERTaggedObject(false, tag, BERFactory.createSequence(v));
    +        }
    +
    +        return v.size() == 1
    +            ?   new DERTaggedObject(true, tag, v.get(0))
    +            :   new DERTaggedObject(false, tag, DERFactory.createSequence(v));
    +    }
    +
    +    public ASN1Encodable readObject()
    +        throws IOException
    +    {
    +        int tag = _in.read();
    +        if (tag == -1)
    +        {
    +            return null;
    +        }
    +
    +        //
    +        // turn of looking for "00" while we resolve the tag
    +        //
    +        set00Check(false);
    +
    +        //
    +        // calculate tag number
    +        //
    +        int tagNo = ASN1InputStream.readTagNumber(_in, tag);
    +
    +        boolean isConstructed = (tag & BERTags.CONSTRUCTED) != 0;
    +
    +        //
    +        // calculate length
    +        //
    +        int length = ASN1InputStream.readLength(_in, _limit);
    +
    +        if (length < 0) // indefinite length method
    +        {
    +            if (!isConstructed)
    +            {
    +                throw new IOException("indefinite length primitive encoding encountered");
    +            }
    +
    +            IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(_in, _limit);
    +            ASN1StreamParser sp = new ASN1StreamParser(indIn, _limit);
    +
    +            if ((tag & BERTags.APPLICATION) != 0)
    +            {
    +                return new BERApplicationSpecificParser(tagNo, sp);
    +            }
    +
    +            if ((tag & BERTags.TAGGED) != 0)
    +            {
    +                return new BERTaggedObjectParser(true, tagNo, sp);
    +            }
    +
    +            return sp.readIndef(tagNo);
    +        }
    +        else
    +        {
    +            DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length);
    +
    +            if ((tag & BERTags.APPLICATION) != 0)
    +            {
    +                return new DERApplicationSpecific(isConstructed, tagNo, defIn.toByteArray());
    +            }
    +
    +            if ((tag & BERTags.TAGGED) != 0)
    +            {
    +                return new BERTaggedObjectParser(isConstructed, tagNo, new ASN1StreamParser(defIn));
    +            }
    +
    +            if (isConstructed)
    +            {
    +                // TODO There are other tags that may be constructed (e.g. BIT_STRING)
    +                switch (tagNo)
    +                {
    +                    case BERTags.OCTET_STRING:
    +                        //
    +                        // yes, people actually do this...
    +                        //
    +                        return new BEROctetStringParser(new ASN1StreamParser(defIn));
    +                    case BERTags.SEQUENCE:
    +                        return new DERSequenceParser(new ASN1StreamParser(defIn));
    +                    case BERTags.SET:
    +                        return new DERSetParser(new ASN1StreamParser(defIn));
    +                    case BERTags.EXTERNAL:
    +                        return new DERExternalParser(new ASN1StreamParser(defIn));
    +                    default:
    +                        throw new IOException("unknown tag " + tagNo + " encountered");
    +                }
    +            }
    +
    +            // Some primitive encodings can be handled by parsers too...
    +            switch (tagNo)
    +            {
    +                case BERTags.OCTET_STRING:
    +                    return new DEROctetStringParser(defIn);
    +            }
    +
    +            try
    +            {
    +                return ASN1InputStream.createPrimitiveDERObject(tagNo, defIn, tmpBuffers);
    +            }
    +            catch (IllegalArgumentException e)
    +            {
    +                throw new ASN1Exception("corrupted stream detected", e);
    +            }
    +        }
    +    }
    +
    +    private void set00Check(boolean enabled)
    +    {
    +        if (_in instanceof IndefiniteLengthInputStream)
    +        {
    +            ((IndefiniteLengthInputStream)_in).setEofOn00(enabled);
    +        }
    +    }
    +
    +    ASN1EncodableVector readVector() throws IOException
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        ASN1Encodable obj;
    +        while ((obj = readObject()) != null)
    +        {
    +            if (obj instanceof InMemoryRepresentable)
    +            {
    +                v.add(((InMemoryRepresentable)obj).getLoadedObject());
    +            }
    +            else
    +            {
    +                v.add(obj.toASN1Primitive());
    +            }
    +        }
    +
    +        return v;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1String.java+6 0 added
    @@ -0,0 +1,6 @@
    +package org.bouncycastle.asn1;
    +
    +public interface ASN1String
    +{
    +    public String getString();
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java+236 0 added
    @@ -0,0 +1,236 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +/**
    + * ASN.1 TaggedObject - in ASN.1 notation this is any object preceded by
    + * a [n] where n is some number - these are assumed to follow the construction
    + * rules (as with sequences).
    + */
    +public abstract class ASN1TaggedObject
    +    extends ASN1Primitive
    +    implements ASN1TaggedObjectParser
    +{
    +    int             tagNo;
    +    boolean         empty = false;
    +    boolean         explicit = true;
    +    ASN1Encodable obj = null;
    +
    +    static public ASN1TaggedObject getInstance(
    +        ASN1TaggedObject    obj,
    +        boolean             explicit)
    +    {
    +        if (explicit)
    +        {
    +            return (ASN1TaggedObject)obj.getObject();
    +        }
    +
    +        throw new IllegalArgumentException("implicitly tagged tagged object");
    +    }
    +
    +    static public ASN1TaggedObject getInstance(
    +        Object obj) 
    +    {
    +        if (obj == null || obj instanceof ASN1TaggedObject) 
    +        {
    +                return (ASN1TaggedObject)obj;
    +        }
    +        else if (obj instanceof byte[])
    +        {
    +            try
    +            {
    +                return ASN1TaggedObject.getInstance(fromByteArray((byte[])obj));
    +            }
    +            catch (IOException e)
    +            {
    +                throw new IllegalArgumentException("failed to construct tagged object from byte[]: " + e.getMessage());
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * Create a tagged object with the style given by the value of explicit.
    +     * <p>
    +     * If the object implements ASN1Choice the tag style will always be changed
    +     * to explicit in accordance with the ASN.1 encoding rules.
    +     * </p>
    +     * @param explicit true if the object is explicitly tagged.
    +     * @param tagNo the tag number for this object.
    +     * @param obj the tagged object.
    +     */
    +    public ASN1TaggedObject(
    +        boolean         explicit,
    +        int             tagNo,
    +        ASN1Encodable   obj)
    +    {
    +        if (obj instanceof ASN1Choice)
    +        {
    +            this.explicit = true;
    +        }
    +        else
    +        {
    +            this.explicit = explicit;
    +        }
    +        
    +        this.tagNo = tagNo;
    +
    +        if (this.explicit)
    +        {
    +            this.obj = obj;
    +        }
    +        else
    +        {
    +            ASN1Primitive prim = obj.toASN1Primitive();
    +
    +            if (prim instanceof ASN1Set)
    +            {
    +                ASN1Set s = null;
    +            }
    +
    +            this.obj = obj;
    +        }
    +    }
    +    
    +    boolean asn1Equals(
    +        ASN1Primitive o)
    +    {
    +        if (!(o instanceof ASN1TaggedObject))
    +        {
    +            return false;
    +        }
    +        
    +        ASN1TaggedObject other = (ASN1TaggedObject)o;
    +        
    +        if (tagNo != other.tagNo || empty != other.empty || explicit != other.explicit)
    +        {
    +            return false;
    +        }
    +        
    +        if(obj == null)
    +        {
    +            if (other.obj != null)
    +            {
    +                return false;
    +            }
    +        }
    +        else
    +        {
    +            if (!(obj.toASN1Primitive().equals(other.obj.toASN1Primitive())))
    +            {
    +                return false;
    +            }
    +        }
    +        
    +        return true;
    +    }
    +    
    +    public int hashCode()
    +    {
    +        int code = tagNo;
    +
    +        // TODO: actually this is wrong - the problem is that a re-encoded
    +        // object may end up with a different hashCode due to implicit
    +        // tagging. As implicit tagging is ambiguous if a sequence is involved
    +        // it seems the only correct method for both equals and hashCode is to
    +        // compare the encodings...
    +        if (obj != null)
    +        {
    +            code ^= obj.hashCode();
    +        }
    +
    +        return code;
    +    }
    +
    +    public int getTagNo()
    +    {
    +        return tagNo;
    +    }
    +
    +    /**
    +     * return whether or not the object may be explicitly tagged. 
    +     * <p>
    +     * Note: if the object has been read from an input stream, the only
    +     * time you can be sure if isExplicit is returning the true state of
    +     * affairs is if it returns false. An implicitly tagged object may appear
    +     * to be explicitly tagged, so you need to understand the context under
    +     * which the reading was done as well, see getObject below.
    +     */
    +    public boolean isExplicit()
    +    {
    +        return explicit;
    +    }
    +
    +    public boolean isEmpty()
    +    {
    +        return empty;
    +    }
    +
    +    /**
    +     * return whatever was following the tag.
    +     * <p>
    +     * Note: tagged objects are generally context dependent if you're
    +     * trying to extract a tagged object you should be going via the
    +     * appropriate getInstance method.
    +     */
    +    public ASN1Primitive getObject()
    +    {
    +        if (obj != null)
    +        {
    +            return obj.toASN1Primitive();
    +        }
    +
    +        return null;
    +    }
    +
    +    /**
    +     * Return the object held in this tagged object as a parser assuming it has
    +     * the type of the passed in tag. If the object doesn't have a parser
    +     * associated with it, the base object is returned.
    +     */
    +    public ASN1Encodable getObjectParser(
    +        int     tag,
    +        boolean isExplicit)
    +    {
    +        switch (tag)
    +        {
    +        case BERTags.SET:
    +            return ASN1Set.getInstance(this, isExplicit).parser();
    +        case BERTags.SEQUENCE:
    +            return ASN1Sequence.getInstance(this, isExplicit).parser();
    +        case BERTags.OCTET_STRING:
    +            return ASN1OctetString.getInstance(this, isExplicit).parser();
    +        }
    +
    +        if (isExplicit)
    +        {
    +            return getObject();
    +        }
    +
    +        throw new RuntimeException("implicit tagging not implemented for tag: " + tag);
    +    }
    +
    +    public ASN1Primitive getLoadedObject()
    +    {
    +        return this.toASN1Primitive();
    +    }
    +
    +    ASN1Primitive toDERObject()
    +    {
    +        return new DERTaggedObject(explicit, tagNo, obj);
    +    }
    +
    +    ASN1Primitive toDLObject()
    +    {
    +        return new DLTaggedObject(explicit, tagNo, obj);
    +    }
    +
    +    abstract void encode(ASN1OutputStream out)
    +        throws IOException;
    +
    +    public String toString()
    +    {
    +        return "[" + tagNo + "]" + obj;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1TaggedObjectParser.java+12 0 added
    @@ -0,0 +1,12 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +public interface ASN1TaggedObjectParser
    +    extends ASN1Encodable, InMemoryRepresentable
    +{
    +    public int getTagNo();
    +    
    +    public ASN1Encodable getObjectParser(int tag, boolean isExplicit)
    +        throws IOException;
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ASN1UTCTime.java+22 0 added
    @@ -0,0 +1,22 @@
    +package org.bouncycastle.asn1;
    +
    +import java.util.Date;
    +
    +public class ASN1UTCTime
    +    extends DERUTCTime
    +{
    +    ASN1UTCTime(byte[] bytes)
    +    {
    +        super(bytes);
    +    }
    +
    +    public ASN1UTCTime(Date time)
    +    {
    +        super(time);
    +    }
    +
    +    public ASN1UTCTime(String time)
    +    {
    +        super(time);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java+51 0 added
    @@ -0,0 +1,51 @@
    +package org.bouncycastle.asn1.bc;
    +
    +import org.bouncycastle.asn1.ASN1ObjectIdentifier;
    +
    +public interface BCObjectIdentifiers
    +{
    +    /**
    +     *  iso.org.dod.internet.private.enterprise.legion-of-the-bouncy-castle
    +     *
    +     *  1.3.6.1.4.1.22554
    +     */
    +    public static final ASN1ObjectIdentifier bc = new ASN1ObjectIdentifier("1.3.6.1.4.1.22554");
    +
    +    /**
    +     * pbe(1) algorithms
    +     */
    +    public static final ASN1ObjectIdentifier bc_pbe = new ASN1ObjectIdentifier(bc.getId() + ".1");
    +
    +    /**
    +     * SHA-1(1)
    +     */
    +    public static final ASN1ObjectIdentifier bc_pbe_sha1 = new ASN1ObjectIdentifier(bc_pbe.getId() + ".1");
    +
    +    /**
    +     * SHA-2(2) . (SHA-256(1)|SHA-384(2)|SHA-512(3)|SHA-224(4))
    +     */
    +    public static final ASN1ObjectIdentifier bc_pbe_sha256 = new ASN1ObjectIdentifier(bc_pbe.getId() + ".2.1");
    +    public static final ASN1ObjectIdentifier bc_pbe_sha384 = new ASN1ObjectIdentifier(bc_pbe.getId() + ".2.2");
    +    public static final ASN1ObjectIdentifier bc_pbe_sha512 = new ASN1ObjectIdentifier(bc_pbe.getId() + ".2.3");
    +    public static final ASN1ObjectIdentifier bc_pbe_sha224 = new ASN1ObjectIdentifier(bc_pbe.getId() + ".2.4");
    +
    +    /**
    +     * PKCS-5(1)|PKCS-12(2)
    +     */
    +    public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs5 = new ASN1ObjectIdentifier(bc_pbe_sha1.getId() + ".1");
    +    public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12 = new ASN1ObjectIdentifier(bc_pbe_sha1.getId() + ".2");
    +
    +    public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs5 = new ASN1ObjectIdentifier(bc_pbe_sha256.getId() + ".1");
    +    public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12 = new ASN1ObjectIdentifier(bc_pbe_sha256.getId() + ".2");
    +
    +    /**
    +     * AES(1) . (CBC-128(2)|CBC-192(22)|CBC-256(42))
    +     */
    +    public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes128_cbc = new ASN1ObjectIdentifier(bc_pbe_sha1_pkcs12.getId() + ".1.2");
    +    public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes192_cbc = new ASN1ObjectIdentifier(bc_pbe_sha1_pkcs12.getId() + ".1.22");
    +    public static final ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes256_cbc = new ASN1ObjectIdentifier(bc_pbe_sha1_pkcs12.getId() + ".1.42");
    +
    +    public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes128_cbc = new ASN1ObjectIdentifier(bc_pbe_sha256_pkcs12.getId() + ".1.2");
    +    public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes192_cbc = new ASN1ObjectIdentifier(bc_pbe_sha256_pkcs12.getId() + ".1.22");
    +    public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes256_cbc = new ASN1ObjectIdentifier(bc_pbe_sha256_pkcs12.getId() + ".1.42");
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/BERApplicationSpecific.java+10 0 added
    @@ -0,0 +1,10 @@
    +package org.bouncycastle.asn1;
    +
    +public class BERApplicationSpecific
    +    extends DERApplicationSpecific
    +{
    +    public BERApplicationSpecific(int tagNo, ASN1EncodableVector vec)
    +    {
    +        super(tagNo, vec);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/BERApplicationSpecificParser.java+41 0 added
    @@ -0,0 +1,41 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +public class BERApplicationSpecificParser
    +    implements ASN1ApplicationSpecificParser
    +{
    +    private final int tag;
    +    private final ASN1StreamParser parser;
    +
    +    BERApplicationSpecificParser(int tag, ASN1StreamParser parser)
    +    {
    +        this.tag = tag;
    +        this.parser = parser;
    +    }
    +
    +    public ASN1Encodable readObject()
    +        throws IOException
    +    {
    +        return parser.readObject();
    +    }
    +
    +    public ASN1Primitive getLoadedObject()
    +        throws IOException
    +    {
    +         return new BERApplicationSpecific(tag, parser.readVector());
    +    }
    +
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        try
    +        {
    +            return getLoadedObject();
    +        }
    +        catch (IOException e)
    +        {
    +            throw new ASN1ParsingException(e.getMessage(), e);
    +        }
    +    }
    +
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/BERConstructedOctetString.java+144 0 added
    @@ -0,0 +1,144 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.ByteArrayOutputStream;
    +import java.io.IOException;
    +import java.util.Enumeration;
    +import java.util.Vector;
    +
    +/**
    + * @deprecated use BEROctetString
    + */
    +public class BERConstructedOctetString
    +    extends BEROctetString
    +{
    +    private static final int MAX_LENGTH = 1000;
    +
    +    /**
    +     * convert a vector of octet strings into a single byte string
    +     */
    +    static private byte[] toBytes(
    +        Vector  octs)
    +    {
    +        ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
    +
    +        for (int i = 0; i != octs.size(); i++)
    +        {
    +            try
    +            {
    +                DEROctetString  o = (DEROctetString)octs.elementAt(i);
    +
    +                bOut.write(o.getOctets());
    +            }
    +            catch (ClassCastException e)
    +            {
    +                throw new IllegalArgumentException(octs.elementAt(i).getClass().getName() + " found in input should only contain DEROctetString");
    +            }
    +            catch (IOException e)
    +            {
    +                throw new IllegalArgumentException("exception converting octets " + e.toString());
    +            }
    +        }
    +
    +        return bOut.toByteArray();
    +    }
    +
    +    private Vector  octs;
    +
    +    /**
    +     * @param string the octets making up the octet string.
    +     */
    +    public BERConstructedOctetString(
    +        byte[]  string)
    +    {
    +        super(string);
    +    }
    +
    +    public BERConstructedOctetString(
    +        Vector  octs)
    +    {
    +        super(toBytes(octs));
    +
    +        this.octs = octs;
    +    }
    +
    +    public BERConstructedOctetString(
    +        ASN1Primitive  obj)
    +    {
    +        super(toByteArray(obj));
    +    }
    +
    +    private static byte[] toByteArray(ASN1Primitive obj)
    +    {
    +        try
    +        {
    +            return obj.getEncoded();
    +        }
    +        catch (IOException e)
    +        {
    +            throw new IllegalArgumentException("Unable to encode object");
    +        }
    +    }
    +
    +    public BERConstructedOctetString(
    +        ASN1Encodable  obj)
    +    {
    +        this(obj.toASN1Primitive());
    +    }
    +
    +    public byte[] getOctets()
    +    {
    +        return string;
    +    }
    +
    +    /**
    +     * return the DER octets that make up this string.
    +     */
    +    public Enumeration getObjects()
    +    {
    +        if (octs == null)
    +        {
    +            return generateOcts().elements();
    +        }
    +
    +        return octs.elements();
    +    }
    +
    +    private Vector generateOcts() 
    +    { 
    +        Vector vec = new Vector(); 
    +        for (int i = 0; i < string.length; i += MAX_LENGTH) 
    +        { 
    +            int end; 
    +
    +            if (i + MAX_LENGTH > string.length) 
    +            { 
    +                end = string.length; 
    +            } 
    +            else 
    +            { 
    +                end = i + MAX_LENGTH; 
    +            } 
    +
    +            byte[] nStr = new byte[end - i]; 
    +
    +            System.arraycopy(string, i, nStr, 0, nStr.length); 
    +
    +            vec.addElement(new DEROctetString(nStr)); 
    +         } 
    +        
    +         return vec; 
    +    }
    +
    +    public static BEROctetString fromSequence(ASN1Sequence seq)
    +    {
    +        Vector      v = new Vector();
    +        Enumeration e = seq.getObjects();
    +
    +        while (e.hasMoreElements())
    +        {
    +            v.addElement(e.nextElement());
    +        }
    +
    +        return new BERConstructedOctetString(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/BERFactory.java+17 0 added
    @@ -0,0 +1,17 @@
    +package org.bouncycastle.asn1;
    +
    +class BERFactory
    +{
    +    static final BERSequence EMPTY_SEQUENCE = new BERSequence();
    +    static final BERSet EMPTY_SET = new BERSet();
    +
    +    static BERSequence createSequence(ASN1EncodableVector v)
    +    {
    +        return v.size() < 1 ? EMPTY_SEQUENCE : new BERSequence(v);
    +    }
    +
    +    static BERSet createSet(ASN1EncodableVector v)
    +    {
    +        return v.size() < 1 ? EMPTY_SET : new BERSet(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/BERGenerator.java+100 0 added
    @@ -0,0 +1,100 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.io.InputStream;
    +import java.io.OutputStream;
    +
    +public class BERGenerator
    +    extends ASN1Generator
    +{
    +    private boolean      _tagged = false;
    +    private boolean      _isExplicit;
    +    private int          _tagNo;
    +    
    +    protected BERGenerator(
    +        OutputStream out)
    +    {
    +        super(out);
    +    }
    +
    +    public BERGenerator(
    +        OutputStream out,
    +        int tagNo,
    +        boolean isExplicit) 
    +    {
    +        super(out);
    +        
    +        _tagged = true;
    +        _isExplicit = isExplicit;
    +        _tagNo = tagNo;
    +    }
    +
    +    public OutputStream getRawOutputStream()
    +    {
    +        return _out;
    +    }
    +    
    +    private void writeHdr(
    +        int tag)
    +        throws IOException
    +    {
    +        _out.write(tag);
    +        _out.write(0x80);
    +    }
    +    
    +    protected void writeBERHeader(
    +        int tag) 
    +        throws IOException
    +    {
    +        if (_tagged)
    +        {
    +            int tagNum = _tagNo | BERTags.TAGGED;
    +
    +            if (_isExplicit)
    +            {
    +                writeHdr(tagNum | BERTags.CONSTRUCTED);
    +                writeHdr(tag);
    +            }
    +            else
    +            {   
    +                if ((tag & BERTags.CONSTRUCTED) != 0)
    +                {
    +                    writeHdr(tagNum | BERTags.CONSTRUCTED);
    +                }
    +                else
    +                {
    +                    writeHdr(tagNum);
    +                }
    +            }
    +        }
    +        else
    +        {
    +            writeHdr(tag);
    +        }
    +    }
    +    
    +    protected void writeBERBody(
    +        InputStream contentStream)
    +        throws IOException
    +    {
    +        int ch;
    +        
    +        while ((ch = contentStream.read()) >= 0)
    +        {
    +            _out.write(ch);
    +        }
    +    }
    +
    +    protected void writeBEREnd()
    +        throws IOException
    +    {
    +        _out.write(0x00);
    +        _out.write(0x00);
    +        
    +        if (_tagged && _isExplicit)  // write extra end for tag header
    +        {
    +            _out.write(0x00);
    +            _out.write(0x00);
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/BEROctetStringGenerator.java+102 0 added
    @@ -0,0 +1,102 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.io.OutputStream;
    +
    +public class BEROctetStringGenerator
    +    extends BERGenerator
    +{
    +    public BEROctetStringGenerator(OutputStream out) 
    +        throws IOException
    +    {
    +        super(out);
    +        
    +        writeBERHeader(BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
    +    }
    +
    +    public BEROctetStringGenerator(
    +        OutputStream out,
    +        int tagNo,
    +        boolean isExplicit) 
    +        throws IOException
    +    {
    +        super(out, tagNo, isExplicit);
    +        
    +        writeBERHeader(BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
    +    }
    +    
    +    public OutputStream getOctetOutputStream()
    +    {
    +        return getOctetOutputStream(new byte[1000]); // limit for CER encoding.
    +    }
    +
    +    public OutputStream getOctetOutputStream(
    +        byte[] buf)
    +    {
    +        return new BufferedBEROctetStream(buf);
    +    }
    +   
    +    private class BufferedBEROctetStream
    +        extends OutputStream
    +    {
    +        private byte[] _buf;
    +        private int    _off;
    +        private DEROutputStream _derOut;
    +
    +        BufferedBEROctetStream(
    +            byte[] buf)
    +        {
    +            _buf = buf;
    +            _off = 0;
    +            _derOut = new DEROutputStream(_out);
    +        }
    +        
    +        public void write(
    +            int b)
    +            throws IOException
    +        {
    +            _buf[_off++] = (byte)b;
    +
    +            if (_off == _buf.length)
    +            {
    +                DEROctetString.encode(_derOut, _buf);
    +                _off = 0;
    +            }
    +        }
    +
    +        public void write(byte[] b, int off, int len) throws IOException
    +        {
    +            while (len > 0)
    +            {
    +                int numToCopy = Math.min(len, _buf.length - _off);
    +                System.arraycopy(b, off, _buf, _off, numToCopy);
    +
    +                _off += numToCopy;
    +                if (_off < _buf.length)
    +                {
    +                    break;
    +                }
    +
    +                DEROctetString.encode(_derOut, _buf);
    +                _off = 0;
    +
    +                off += numToCopy;
    +                len -= numToCopy;
    +            }
    +        }
    +
    +        public void close() 
    +            throws IOException
    +        {
    +            if (_off != 0)
    +            {
    +                byte[] bytes = new byte[_off];
    +                System.arraycopy(_buf, 0, bytes, 0, _off);
    +                
    +                DEROctetString.encode(_derOut, bytes);
    +            }
    +            
    +             writeBEREnd();
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/BEROctetString.java+168 0 added
    @@ -0,0 +1,168 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.ByteArrayOutputStream;
    +import java.io.IOException;
    +import java.util.Enumeration;
    +import java.util.Vector;
    +
    +public class BEROctetString
    +    extends ASN1OctetString
    +{
    +    private static final int MAX_LENGTH = 1000;
    +
    +    private ASN1OctetString[] octs;
    +
    +    /**
    +     * convert a vector of octet strings into a single byte string
    +     */
    +    static private byte[] toBytes(
    +        ASN1OctetString[]  octs)
    +    {
    +        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    +
    +        for (int i = 0; i != octs.length; i++)
    +        {
    +            try
    +            {
    +                DEROctetString o = (DEROctetString)octs[i];
    +
    +                bOut.write(o.getOctets());
    +            }
    +            catch (ClassCastException e)
    +            {
    +                throw new IllegalArgumentException(octs[i].getClass().getName() + " found in input should only contain DEROctetString");
    +            }
    +            catch (IOException e)
    +            {
    +                throw new IllegalArgumentException("exception converting octets " + e.toString());
    +            }
    +        }
    +
    +        return bOut.toByteArray();
    +    }
    +
    +    /**
    +     * @param string the octets making up the octet string.
    +     */
    +    public BEROctetString(
    +        byte[] string)
    +    {
    +        super(string);
    +    }
    +
    +    public BEROctetString(
    +        ASN1OctetString[] octs)
    +    {
    +        super(toBytes(octs));
    +
    +        this.octs = octs;
    +    }
    +
    +    public byte[] getOctets()
    +    {
    +        return string;
    +    }
    +
    +    /**
    +     * return the DER octets that make up this string.
    +     */
    +    public Enumeration getObjects()
    +    {
    +        if (octs == null)
    +        {
    +            return generateOcts().elements();
    +        }
    +
    +        return new Enumeration()
    +        {
    +            int counter = 0;
    +
    +            public boolean hasMoreElements()
    +            {
    +                return counter < octs.length;
    +            }
    +
    +            public Object nextElement()
    +            {
    +                return octs[counter++];
    +            }
    +        };
    +    }
    +
    +    private Vector generateOcts()
    +    { 
    +        Vector vec = new Vector();
    +        for (int i = 0; i < string.length; i += MAX_LENGTH) 
    +        { 
    +            int end; 
    +
    +            if (i + MAX_LENGTH > string.length) 
    +            { 
    +                end = string.length; 
    +            } 
    +            else 
    +            { 
    +                end = i + MAX_LENGTH; 
    +            } 
    +
    +            byte[] nStr = new byte[end - i]; 
    +
    +            System.arraycopy(string, i, nStr, 0, nStr.length);
    +
    +            vec.addElement(new DEROctetString(nStr));
    +         } 
    +        
    +         return vec; 
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return true;
    +    }
    +
    +    int encodedLength()
    +        throws IOException
    +    {
    +        int length = 0;
    +        for (Enumeration e = getObjects(); e.hasMoreElements();)
    +        {
    +            length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength();
    +        }
    +
    +        return 2 + length + 2;
    +    }
    +
    +    public void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        out.write(BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
    +
    +        out.write(0x80);
    +
    +        //
    +        // write out the octet array
    +        //
    +        for (Enumeration e = getObjects(); e.hasMoreElements();)
    +        {
    +            out.writeObject((ASN1Encodable)e.nextElement());
    +        }
    +
    +        out.write(0x00);
    +        out.write(0x00);
    +    }
    +
    +    static BEROctetString fromSequence(ASN1Sequence seq)
    +    {
    +        ASN1OctetString[]     v = new ASN1OctetString[seq.size()];
    +        Enumeration e = seq.getObjects();
    +        int                   index = 0;
    +
    +        while (e.hasMoreElements())
    +        {
    +            v[index++] = (ASN1OctetString)e.nextElement();
    +        }
    +
    +        return new BEROctetString(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/BEROctetStringParser.java+41 0 added
    @@ -0,0 +1,41 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.io.InputStream;
    +
    +import org.bouncycastle.util.io.Streams;
    +
    +public class BEROctetStringParser
    +    implements ASN1OctetStringParser
    +{
    +    private ASN1StreamParser _parser;
    +
    +    BEROctetStringParser(
    +        ASN1StreamParser parser)
    +    {
    +        _parser = parser;
    +    }
    +
    +    public InputStream getOctetStream()
    +    {
    +        return new ConstructedOctetStream(_parser);
    +    }
    +
    +    public ASN1Primitive getLoadedObject()
    +        throws IOException
    +    {
    +        return new BEROctetString(Streams.readAll(getOctetStream()));
    +    }
    +
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        try
    +        {
    +            return getLoadedObject();
    +        }
    +        catch (IOException e)
    +        {
    +            throw new ASN1ParsingException("IOException converting stream to byte array: " + e.getMessage(), e);
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/BEROutputStream.java+36 0 added
    @@ -0,0 +1,36 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.io.OutputStream;
    +
    +public class BEROutputStream
    +    extends DEROutputStream
    +{
    +    public BEROutputStream(
    +        OutputStream    os)
    +    {
    +        super(os);
    +    }
    +
    +    public void writeObject(
    +        Object    obj)
    +        throws IOException
    +    {
    +        if (obj == null)
    +        {
    +            writeNull();
    +        }
    +        else if (obj instanceof ASN1Primitive)
    +        {
    +            ((ASN1Primitive)obj).encode(this);
    +        }
    +        else if (obj instanceof ASN1Encodable)
    +        {
    +            ((ASN1Encodable)obj).toASN1Primitive().encode(this);
    +        }
    +        else
    +        {
    +            throw new IOException("object not BEREncodable");
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/BERSequenceGenerator.java+41 0 added
    @@ -0,0 +1,41 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.io.OutputStream;
    +
    +public class BERSequenceGenerator
    +    extends BERGenerator
    +{
    +    public BERSequenceGenerator(
    +        OutputStream out) 
    +        throws IOException
    +    {
    +        super(out);
    +
    +        writeBERHeader(BERTags.CONSTRUCTED | BERTags.SEQUENCE);
    +    }
    +
    +    public BERSequenceGenerator(
    +        OutputStream out,
    +        int tagNo,
    +        boolean isExplicit) 
    +        throws IOException
    +    {
    +        super(out, tagNo, isExplicit);
    +        
    +        writeBERHeader(BERTags.CONSTRUCTED | BERTags.SEQUENCE);
    +    }
    +
    +    public void addObject(
    +        ASN1Encodable object)
    +        throws IOException
    +    {
    +        object.toASN1Primitive().encode(new BEROutputStream(_out));
    +    }
    +    
    +    public void close() 
    +        throws IOException
    +    {
    +        writeBEREnd();
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/BERSequence.java+73 0 added
    @@ -0,0 +1,73 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.util.Enumeration;
    +
    +public class BERSequence
    +    extends ASN1Sequence
    +{
    +    /**
    +     * create an empty sequence
    +     */
    +    public BERSequence()
    +    {
    +    }
    +
    +    /**
    +     * create a sequence containing one object
    +     */
    +    public BERSequence(
    +        ASN1Encodable obj)
    +    {
    +        super(obj);
    +    }
    +
    +    /**
    +     * create a sequence containing a vector of objects.
    +     */
    +    public BERSequence(
    +        ASN1EncodableVector v)
    +    {
    +        super(v);
    +    }
    +
    +    /**
    +     * create a sequence containing an array of objects.
    +     */
    +    public BERSequence(
    +        ASN1Encodable[]   array)
    +    {
    +        super(array);
    +    }
    +
    +    int encodedLength()
    +        throws IOException
    +    {
    +        int length = 0;
    +        for (Enumeration e = getObjects(); e.hasMoreElements();)
    +        {
    +            length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength();
    +        }
    +
    +        return 2 + length + 2;
    +    }
    +
    +    /*
    +     */
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
    +        out.write(0x80);
    +
    +        Enumeration e = getObjects();
    +        while (e.hasMoreElements())
    +        {
    +            out.writeObject((ASN1Encodable)e.nextElement());
    +        }
    +
    +        out.write(0x00);
    +        out.write(0x00);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/BERSequenceParser.java+38 0 added
    @@ -0,0 +1,38 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +public class BERSequenceParser
    +    implements ASN1SequenceParser
    +{
    +    private ASN1StreamParser _parser;
    +
    +    BERSequenceParser(ASN1StreamParser parser)
    +    {
    +        this._parser = parser;
    +    }
    +
    +    public ASN1Encodable readObject()
    +        throws IOException
    +    {
    +        return _parser.readObject();
    +    }
    +
    +    public ASN1Primitive getLoadedObject()
    +        throws IOException
    +    {
    +        return new BERSequence(_parser.readVector());
    +    }
    +    
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        try
    +        {
    +            return getLoadedObject();
    +        }
    +        catch (IOException e)
    +        {
    +            throw new IllegalStateException(e.getMessage());
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/BERSet.java+73 0 added
    @@ -0,0 +1,73 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.util.Enumeration;
    +
    +public class BERSet
    +    extends ASN1Set
    +{
    +    /**
    +     * create an empty sequence
    +     */
    +    public BERSet()
    +    {
    +    }
    +
    +    /**
    +     * @param obj - a single object that makes up the set.
    +     */
    +    public BERSet(
    +        ASN1Encodable obj)
    +    {
    +        super(obj);
    +    }
    +
    +    /**
    +     * @param v - a vector of objects making up the set.
    +     */
    +    public BERSet(
    +        ASN1EncodableVector v)
    +    {
    +        super(v, false);
    +    }
    +
    +    /**
    +     * create a set from an array of objects.
    +     */
    +    public BERSet(
    +        ASN1Encodable[]   a)
    +    {
    +        super(a, false);
    +    }
    +
    +    int encodedLength()
    +        throws IOException
    +    {
    +        int length = 0;
    +        for (Enumeration e = getObjects(); e.hasMoreElements();)
    +        {
    +            length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength();
    +        }
    +
    +        return 2 + length + 2;
    +    }
    +
    +    /*
    +     */
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        out.write(BERTags.SET | BERTags.CONSTRUCTED);
    +        out.write(0x80);
    +
    +        Enumeration e = getObjects();
    +        while (e.hasMoreElements())
    +        {
    +            out.writeObject((ASN1Encodable)e.nextElement());
    +        }
    +
    +        out.write(0x00);
    +        out.write(0x00);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/BERSetParser.java+38 0 added
    @@ -0,0 +1,38 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +public class BERSetParser
    +    implements ASN1SetParser
    +{
    +    private ASN1StreamParser _parser;
    +
    +    BERSetParser(ASN1StreamParser parser)
    +    {
    +        this._parser = parser;
    +    }
    +
    +    public ASN1Encodable readObject()
    +        throws IOException
    +    {
    +        return _parser.readObject();
    +    }
    +
    +    public ASN1Primitive getLoadedObject()
    +        throws IOException
    +    {
    +        return new BERSet(_parser.readVector());
    +    }
    +
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        try
    +        {
    +            return getLoadedObject();
    +        }
    +        catch (IOException e)
    +        {
    +            throw new ASN1ParsingException(e.getMessage(), e);
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java+147 0 added
    @@ -0,0 +1,147 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.util.Enumeration;
    +
    +/**
    + * BER TaggedObject - in ASN.1 notation this is any object preceded by
    + * a [n] where n is some number - these are assumed to follow the construction
    + * rules (as with sequences).
    + */
    +public class BERTaggedObject
    +    extends ASN1TaggedObject
    +{
    +    /**
    +     * @param tagNo the tag number for this object.
    +     * @param obj the tagged object.
    +     */
    +    public BERTaggedObject(
    +        int             tagNo,
    +        ASN1Encodable    obj)
    +    {
    +        super(true, tagNo, obj);
    +    }
    +
    +    /**
    +     * @param explicit true if an explicitly tagged object.
    +     * @param tagNo the tag number for this object.
    +     * @param obj the tagged object.
    +     */
    +    public BERTaggedObject(
    +        boolean         explicit,
    +        int             tagNo,
    +        ASN1Encodable    obj)
    +    {
    +        super(explicit, tagNo, obj);
    +    }
    +
    +    /**
    +     * create an implicitly tagged object that contains a zero
    +     * length sequence.
    +     */
    +    public BERTaggedObject(
    +        int             tagNo)
    +    {
    +        super(false, tagNo, new BERSequence());
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        if (!empty)
    +        {
    +            if (explicit)
    +            {
    +                return true;
    +            }
    +            else
    +            {
    +                ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
    +
    +                return primitive.isConstructed();
    +            }
    +        }
    +        else
    +        {
    +            return true;
    +        }
    +    }
    +
    +    int encodedLength()
    +        throws IOException
    +    {
    +        if (!empty)
    +        {
    +            ASN1Primitive primitive = obj.toASN1Primitive();
    +            int length = primitive.encodedLength();
    +
    +            if (explicit)
    +            {
    +                return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
    +            }
    +            else
    +            {
    +                // header length already in calculation
    +                length = length - 1;
    +
    +                return StreamUtil.calculateTagLength(tagNo) + length;
    +            }
    +        }
    +        else
    +        {
    +            return StreamUtil.calculateTagLength(tagNo) + 1;
    +        }
    +    }
    +
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
    +        out.write(0x80);
    +
    +        if (!empty)
    +        {
    +            if (!explicit)
    +            {
    +                Enumeration e;
    +                if (obj instanceof ASN1OctetString)
    +                {
    +                    if (obj instanceof BEROctetString)
    +                    {
    +                        e = ((BEROctetString)obj).getObjects();
    +                    }
    +                    else
    +                    {
    +                        ASN1OctetString             octs = (ASN1OctetString)obj;
    +                        BEROctetString berO = new BEROctetString(octs.getOctets());
    +                        e = berO.getObjects();
    +                    }
    +                }
    +                else if (obj instanceof ASN1Sequence)
    +                {
    +                    e = ((ASN1Sequence)obj).getObjects();
    +                }
    +                else if (obj instanceof ASN1Set)
    +                {
    +                    e = ((ASN1Set)obj).getObjects();
    +                }
    +                else
    +                {
    +                    throw new RuntimeException("not implemented: " + obj.getClass().getName());
    +                }
    +
    +                while (e.hasMoreElements())
    +                {
    +                    out.writeObject((ASN1Encodable)e.nextElement());
    +                }
    +            }
    +            else
    +            {
    +                out.writeObject(obj);
    +            }
    +        }
    +
    +        out.write(0x00);
    +        out.write(0x00);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/BERTaggedObjectParser.java+66 0 added
    @@ -0,0 +1,66 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +public class BERTaggedObjectParser
    +    implements ASN1TaggedObjectParser
    +{
    +    private boolean _constructed;
    +    private int _tagNumber;
    +    private ASN1StreamParser _parser;
    +
    +    BERTaggedObjectParser(
    +        boolean             constructed,
    +        int                 tagNumber,
    +        ASN1StreamParser    parser)
    +    {
    +        _constructed = constructed;
    +        _tagNumber = tagNumber;
    +        _parser = parser;
    +    }
    +
    +    public boolean isConstructed()
    +    {
    +        return _constructed;
    +    }
    +
    +    public int getTagNo()
    +    {
    +        return _tagNumber;
    +    }
    +
    +    public ASN1Encodable getObjectParser(
    +        int     tag,
    +        boolean isExplicit)
    +        throws IOException
    +    {
    +        if (isExplicit)
    +        {
    +            if (!_constructed)
    +            {
    +                throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)");
    +            }
    +            return _parser.readObject();
    +        }
    +
    +        return _parser.readImplicit(_constructed, tag);
    +    }
    +
    +    public ASN1Primitive getLoadedObject()
    +        throws IOException
    +    {
    +        return _parser.readTaggedObject(_constructed, _tagNumber);
    +    }
    +
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        try
    +        {
    +            return this.getLoadedObject();
    +        }
    +        catch (IOException e)
    +        {
    +            throw new ASN1ParsingException(e.getMessage());
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/BERTags.java+36 0 added
    @@ -0,0 +1,36 @@
    +package org.bouncycastle.asn1;
    +
    +public interface BERTags
    +{
    +    public static final int BOOLEAN             = 0x01;
    +    public static final int INTEGER             = 0x02;
    +    public static final int BIT_STRING          = 0x03;
    +    public static final int OCTET_STRING        = 0x04;
    +    public static final int NULL                = 0x05;
    +    public static final int OBJECT_IDENTIFIER   = 0x06;
    +    public static final int EXTERNAL            = 0x08;
    +    public static final int ENUMERATED          = 0x0a;
    +    public static final int SEQUENCE            = 0x10;
    +    public static final int SEQUENCE_OF         = 0x10; // for completeness
    +    public static final int SET                 = 0x11;
    +    public static final int SET_OF              = 0x11; // for completeness
    +
    +
    +    public static final int NUMERIC_STRING      = 0x12;
    +    public static final int PRINTABLE_STRING    = 0x13;
    +    public static final int T61_STRING          = 0x14;
    +    public static final int VIDEOTEX_STRING     = 0x15;
    +    public static final int IA5_STRING          = 0x16;
    +    public static final int UTC_TIME            = 0x17;
    +    public static final int GENERALIZED_TIME    = 0x18;
    +    public static final int GRAPHIC_STRING      = 0x19;
    +    public static final int VISIBLE_STRING      = 0x1a;
    +    public static final int GENERAL_STRING      = 0x1b;
    +    public static final int UNIVERSAL_STRING    = 0x1c;
    +    public static final int BMP_STRING          = 0x1e;
    +    public static final int UTF8_STRING         = 0x0c;
    +    
    +    public static final int CONSTRUCTED         = 0x20;
    +    public static final int APPLICATION         = 0x40;
    +    public static final int TAGGED              = 0x80;
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/CAKeyUpdAnnContent.java+80 0 added
    @@ -0,0 +1,80 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +public class CAKeyUpdAnnContent
    +    extends ASN1Object
    +{
    +    private CMPCertificate oldWithNew;
    +    private CMPCertificate newWithOld;
    +    private CMPCertificate newWithNew;
    +
    +    private CAKeyUpdAnnContent(ASN1Sequence seq)
    +    {
    +        oldWithNew = CMPCertificate.getInstance(seq.getObjectAt(0));
    +        newWithOld = CMPCertificate.getInstance(seq.getObjectAt(1));
    +        newWithNew = CMPCertificate.getInstance(seq.getObjectAt(2));
    +    }
    +
    +    public static CAKeyUpdAnnContent getInstance(Object o)
    +    {
    +        if (o instanceof CAKeyUpdAnnContent)
    +        {
    +            return (CAKeyUpdAnnContent)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new CAKeyUpdAnnContent(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public CAKeyUpdAnnContent(CMPCertificate oldWithNew, CMPCertificate newWithOld, CMPCertificate newWithNew)
    +    {
    +        this.oldWithNew = oldWithNew;
    +        this.newWithOld = newWithOld;
    +        this.newWithNew = newWithNew;
    +    }
    +
    +    public CMPCertificate getOldWithNew()
    +    {
    +        return oldWithNew;
    +    }
    +
    +    public CMPCertificate getNewWithOld()
    +    {
    +        return newWithOld;
    +    }
    +
    +    public CMPCertificate getNewWithNew()
    +    {
    +        return newWithNew;
    +    }
    +
    +    /**
    +     * <pre>
    +     * CAKeyUpdAnnContent ::= SEQUENCE {
    +     *                             oldWithNew   CMPCertificate, -- old pub signed with new priv
    +     *                             newWithOld   CMPCertificate, -- new pub signed with old priv
    +     *                             newWithNew   CMPCertificate  -- new pub signed with new priv
    +     *  }
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(oldWithNew);
    +        v.add(newWithOld);
    +        v.add(newWithNew);
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/CertConfirmContent.java+54 0 added
    @@ -0,0 +1,54 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +
    +public class CertConfirmContent
    +    extends ASN1Object
    +{
    +    private ASN1Sequence content;
    +
    +    private CertConfirmContent(ASN1Sequence seq)
    +    {
    +        content = seq;
    +    }
    +
    +    public static CertConfirmContent getInstance(Object o)
    +    {
    +        if (o instanceof CertConfirmContent)
    +        {
    +            return (CertConfirmContent)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new CertConfirmContent(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public CertStatus[] toCertStatusArray()
    +    {
    +        CertStatus[] result = new CertStatus[content.size()];
    +
    +        for (int i = 0; i != result.length; i++)
    +        {
    +            result[i] = CertStatus.getInstance(content.getObjectAt(i));
    +        }
    +
    +        return result;
    +    }
    +    
    +    /**
    +     * <pre>
    +     * CertConfirmContent ::= SEQUENCE OF CertStatus
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        return content;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/CertifiedKeyPair.java+127 0 added
    @@ -0,0 +1,127 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +import org.bouncycastle.asn1.crmf.EncryptedValue;
    +import org.bouncycastle.asn1.crmf.PKIPublicationInfo;
    +
    +public class CertifiedKeyPair
    +    extends ASN1Object
    +{
    +    private CertOrEncCert certOrEncCert;
    +    private EncryptedValue privateKey;
    +    private PKIPublicationInfo  publicationInfo;
    +
    +    private CertifiedKeyPair(ASN1Sequence seq)
    +    {
    +        certOrEncCert = CertOrEncCert.getInstance(seq.getObjectAt(0));
    +
    +        if (seq.size() >= 2)
    +        {
    +            if (seq.size() == 2)
    +            {
    +                ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(seq.getObjectAt(1));
    +                if (tagged.getTagNo() == 0)
    +                {
    +                    privateKey = EncryptedValue.getInstance(tagged.getObject());
    +                }
    +                else
    +                {
    +                    publicationInfo = PKIPublicationInfo.getInstance(tagged.getObject());
    +                }
    +            }
    +            else
    +            {
    +                privateKey = EncryptedValue.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(1)));
    +                publicationInfo = PKIPublicationInfo.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(2)));
    +            }
    +        }
    +    }
    +
    +    public static CertifiedKeyPair getInstance(Object o)
    +    {
    +        if (o instanceof CertifiedKeyPair)
    +        {
    +            return (CertifiedKeyPair)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new CertifiedKeyPair(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public CertifiedKeyPair(
    +        CertOrEncCert certOrEncCert)
    +    {
    +        this(certOrEncCert, null, null);
    +    }
    +
    +    public CertifiedKeyPair(
    +        CertOrEncCert certOrEncCert,
    +        EncryptedValue privateKey,
    +        PKIPublicationInfo  publicationInfo
    +        )
    +    {
    +        if (certOrEncCert == null)
    +        {
    +            throw new IllegalArgumentException("'certOrEncCert' cannot be null");
    +        }
    +
    +        this.certOrEncCert = certOrEncCert;
    +        this.privateKey = privateKey;
    +        this.publicationInfo = publicationInfo;
    +    }
    +
    +    public CertOrEncCert getCertOrEncCert()
    +    {
    +        return certOrEncCert;
    +    }
    +
    +    public EncryptedValue getPrivateKey()
    +    {
    +        return privateKey;
    +    }
    +
    +    public PKIPublicationInfo getPublicationInfo()
    +    {
    +        return publicationInfo;
    +    }
    +
    +    /**
    +     * <pre>
    +     * CertifiedKeyPair ::= SEQUENCE {
    +     *                                  certOrEncCert       CertOrEncCert,
    +     *                                  privateKey      [0] EncryptedValue      OPTIONAL,
    +     *                                  -- see [CRMF] for comment on encoding
    +     *                                  publicationInfo [1] PKIPublicationInfo  OPTIONAL
    +     *       }
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(certOrEncCert);
    +
    +        if (privateKey != null)
    +        {
    +            v.add(new DERTaggedObject(true, 0, privateKey));
    +        }
    +
    +        if (publicationInfo != null)
    +        {
    +            v.add(new DERTaggedObject(true, 1, publicationInfo));
    +        }
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/CertOrEncCert.java+96 0 added
    @@ -0,0 +1,96 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1Choice;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +import org.bouncycastle.asn1.crmf.EncryptedValue;
    +
    +public class CertOrEncCert
    +    extends ASN1Object
    +    implements ASN1Choice
    +{
    +    private CMPCertificate certificate;
    +    private EncryptedValue encryptedCert;
    +
    +    private CertOrEncCert(ASN1TaggedObject tagged)
    +    {
    +        if (tagged.getTagNo() == 0)
    +        {
    +            certificate = CMPCertificate.getInstance(tagged.getObject());
    +        }
    +        else if (tagged.getTagNo() == 1)
    +        {
    +            encryptedCert = EncryptedValue.getInstance(tagged.getObject());
    +        }
    +        else
    +        {
    +            throw new IllegalArgumentException("unknown tag: " + tagged.getTagNo());
    +        }
    +    }
    +
    +    public static CertOrEncCert getInstance(Object o)
    +    {
    +        if (o instanceof CertOrEncCert)
    +        {
    +            return (CertOrEncCert)o;
    +        }
    +
    +        if (o instanceof ASN1TaggedObject)
    +        {
    +            return new CertOrEncCert((ASN1TaggedObject)o);
    +        }
    +
    +        return null;
    +    }
    +
    +    public CertOrEncCert(CMPCertificate certificate)
    +    {
    +        if (certificate == null)
    +        {
    +            throw new IllegalArgumentException("'certificate' cannot be null");
    +        }
    +
    +        this.certificate = certificate;
    +    }
    +
    +    public CertOrEncCert(EncryptedValue encryptedCert)
    +    {
    +        if (encryptedCert == null)
    +        {
    +            throw new IllegalArgumentException("'encryptedCert' cannot be null");
    +        }
    +
    +        this.encryptedCert = encryptedCert;
    +    }
    +
    +    public CMPCertificate getCertificate()
    +    {
    +        return certificate;
    +    }
    +
    +    public EncryptedValue getEncryptedCert()
    +    {
    +        return encryptedCert;
    +    }
    +
    +    /**
    +     * <pre>
    +     * CertOrEncCert ::= CHOICE {
    +     *                      certificate     [0] CMPCertificate,
    +     *                      encryptedCert   [1] EncryptedValue
    +     *           }
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        if (certificate != null)
    +        {
    +            return new DERTaggedObject(true, 0, certificate);
    +        }
    +
    +        return new DERTaggedObject(true, 1, encryptedCert);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/CertRepMessage.java+123 0 added
    @@ -0,0 +1,123 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +
    +public class CertRepMessage
    +    extends ASN1Object
    +{
    +    private ASN1Sequence caPubs;
    +    private ASN1Sequence response;
    +
    +    private CertRepMessage(ASN1Sequence seq)
    +    {
    +        int index = 0;
    +
    +        if (seq.size() > 1)
    +        {
    +            caPubs = ASN1Sequence.getInstance((ASN1TaggedObject)seq.getObjectAt(index++), true);
    +        }
    +
    +        response = ASN1Sequence.getInstance(seq.getObjectAt(index));
    +    }
    +
    +    public static CertRepMessage getInstance(Object o)
    +    {
    +        if (o instanceof CertRepMessage)
    +        {
    +            return (CertRepMessage)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new CertRepMessage(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public CertRepMessage(CMPCertificate[] caPubs, CertResponse[] response)
    +    {
    +        if (response == null)
    +        {
    +            throw new IllegalArgumentException("'response' cannot be null");
    +        }
    +
    +        if (caPubs != null)
    +        {
    +            ASN1EncodableVector v = new ASN1EncodableVector();
    +            for (int i = 0; i < caPubs.length; i++)
    +            {
    +                v.add(caPubs[i]);
    +            }
    +            this.caPubs = new DERSequence(v);
    +        }
    +
    +        {
    +            ASN1EncodableVector v = new ASN1EncodableVector();
    +            for (int i = 0; i < response.length; i++)
    +            {
    +                v.add(response[i]);
    +            }
    +            this.response = new DERSequence(v);
    +        }
    +    }
    +
    +    public CMPCertificate[] getCaPubs()
    +    {
    +        if (caPubs == null)
    +        {
    +            return null;
    +        }
    +
    +        CMPCertificate[] results = new CMPCertificate[caPubs.size()];
    +
    +        for (int i = 0; i != results.length; i++)
    +        {
    +            results[i] = CMPCertificate.getInstance(caPubs.getObjectAt(i));
    +        }
    +
    +        return results;
    +    }
    +
    +    public CertResponse[] getResponse()
    +    {
    +        CertResponse[] results = new CertResponse[response.size()];
    +
    +        for (int i = 0; i != results.length; i++)
    +        {
    +            results[i] = CertResponse.getInstance(response.getObjectAt(i));
    +        }
    +
    +        return results;
    +    }
    +
    +    /**
    +     * <pre>
    +     * CertRepMessage ::= SEQUENCE {
    +     *                          caPubs       [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
    +     *                                                                             OPTIONAL,
    +     *                          response         SEQUENCE OF CertResponse
    +     * }
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        if (caPubs != null)
    +        {
    +            v.add(new DERTaggedObject(true, 1, caPubs));
    +        }
    +
    +        v.add(response);
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/CertResponse.java+139 0 added
    @@ -0,0 +1,139 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +public class CertResponse
    +    extends ASN1Object
    +{
    +    private ASN1Integer certReqId;
    +    private PKIStatusInfo status;
    +    private CertifiedKeyPair certifiedKeyPair;
    +    private ASN1OctetString rspInfo;
    +
    +    private CertResponse(ASN1Sequence seq)
    +    {
    +        certReqId = ASN1Integer.getInstance(seq.getObjectAt(0));
    +        status = PKIStatusInfo.getInstance(seq.getObjectAt(1));
    +
    +        if (seq.size() >= 3)
    +        {
    +            if (seq.size() == 3)
    +            {
    +                ASN1Encodable o = seq.getObjectAt(2);
    +                if (o instanceof ASN1OctetString)
    +                {
    +                    rspInfo = ASN1OctetString.getInstance(o);
    +                }
    +                else
    +                {
    +                    certifiedKeyPair = CertifiedKeyPair.getInstance(o);
    +                }
    +            }
    +            else
    +            {
    +                certifiedKeyPair = CertifiedKeyPair.getInstance(seq.getObjectAt(2));
    +                rspInfo = ASN1OctetString.getInstance(seq.getObjectAt(3));
    +            }
    +        }
    +    }
    +
    +    public static CertResponse getInstance(Object o)
    +    {
    +        if (o instanceof CertResponse)
    +        {
    +            return (CertResponse)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new CertResponse(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public CertResponse(
    +        ASN1Integer certReqId,
    +        PKIStatusInfo status)
    +    {
    +        this(certReqId, status, null, null);
    +    }
    +
    +    public CertResponse(
    +        ASN1Integer certReqId,
    +        PKIStatusInfo status,
    +        CertifiedKeyPair certifiedKeyPair,
    +        ASN1OctetString rspInfo)
    +    {
    +        if (certReqId == null)
    +        {
    +            throw new IllegalArgumentException("'certReqId' cannot be null");
    +        }
    +        if (status == null)
    +        {
    +            throw new IllegalArgumentException("'status' cannot be null");
    +        }
    +        this.certReqId = certReqId;
    +        this.status = status;
    +        this.certifiedKeyPair = certifiedKeyPair;
    +        this.rspInfo = rspInfo;
    +    }
    +
    +    public ASN1Integer getCertReqId()
    +    {
    +        return certReqId;
    +    }
    +
    +    public PKIStatusInfo getStatus()
    +    {
    +        return status;
    +    }
    +
    +    public CertifiedKeyPair getCertifiedKeyPair()
    +    {
    +        return certifiedKeyPair;
    +    }
    +
    +    /**
    +     * <pre>
    +     * CertResponse ::= SEQUENCE {
    +     *                            certReqId           INTEGER,
    +     *                            -- to match this response with corresponding request (a value
    +     *                            -- of -1 is to be used if certReqId is not specified in the
    +     *                            -- corresponding request)
    +     *                            status              PKIStatusInfo,
    +     *                            certifiedKeyPair    CertifiedKeyPair    OPTIONAL,
    +     *                            rspInfo             OCTET STRING        OPTIONAL
    +     *                            -- analogous to the id-regInfo-utf8Pairs string defined
    +     *                            -- for regInfo in CertReqMsg [CRMF]
    +     *             }
    +     * </pre> 
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(certReqId);
    +        v.add(status);
    +
    +        if (certifiedKeyPair != null)
    +        {
    +            v.add(certifiedKeyPair);
    +        }
    +
    +        if (rspInfo != null)
    +        {
    +            v.add(rspInfo);
    +        }
    +        
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/CertStatus.java+102 0 added
    @@ -0,0 +1,102 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import java.math.BigInteger;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DEROctetString;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +public class CertStatus
    +    extends ASN1Object
    +{
    +    private ASN1OctetString certHash;
    +    private ASN1Integer certReqId;
    +    private PKIStatusInfo statusInfo;
    +
    +    private CertStatus(ASN1Sequence seq)
    +    {
    +        certHash = ASN1OctetString.getInstance(seq.getObjectAt(0));
    +        certReqId = ASN1Integer.getInstance(seq.getObjectAt(1));
    +
    +        if (seq.size() > 2)
    +        {
    +            statusInfo = PKIStatusInfo.getInstance(seq.getObjectAt(2));
    +        }
    +    }
    +
    +    public CertStatus(byte[] certHash, BigInteger certReqId)
    +    {
    +        this.certHash = new DEROctetString(certHash);
    +        this.certReqId = new ASN1Integer(certReqId);
    +    }
    +
    +    public CertStatus(byte[] certHash, BigInteger certReqId, PKIStatusInfo statusInfo)
    +    {
    +        this.certHash = new DEROctetString(certHash);
    +        this.certReqId = new ASN1Integer(certReqId);
    +        this.statusInfo = statusInfo;
    +    }
    +
    +    public static CertStatus getInstance(Object o)
    +    {
    +        if (o instanceof CertStatus)
    +        {
    +            return (CertStatus)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new CertStatus(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public ASN1OctetString getCertHash()
    +    {
    +        return certHash;
    +    }
    +
    +    public ASN1Integer getCertReqId()
    +    {
    +        return certReqId;
    +    }
    +
    +    public PKIStatusInfo getStatusInfo()
    +    {
    +        return statusInfo;
    +    }
    +
    +    /**
    +     * <pre>
    +     * CertStatus ::= SEQUENCE {
    +     *                   certHash    OCTET STRING,
    +     *                   -- the hash of the certificate, using the same hash algorithm
    +     *                   -- as is used to create and verify the certificate signature
    +     *                   certReqId   INTEGER,
    +     *                   -- to match this confirmation with the corresponding req/rep
    +     *                   statusInfo  PKIStatusInfo OPTIONAL
    +     * }
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(certHash);
    +        v.add(certReqId);
    +
    +        if (statusInfo != null)
    +        {
    +            v.add(statusInfo);
    +        }
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/Challenge.java+120 0 added
    @@ -0,0 +1,120 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DEROctetString;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
    +
    +public class Challenge
    +    extends ASN1Object
    +{
    +    private AlgorithmIdentifier owf;
    +    private ASN1OctetString witness;
    +    private ASN1OctetString challenge;
    +
    +    private Challenge(ASN1Sequence seq)
    +    {
    +        int index = 0;
    +
    +        if (seq.size() == 3)
    +        {
    +            owf = AlgorithmIdentifier.getInstance(seq.getObjectAt(index++));
    +        }
    +
    +        witness = ASN1OctetString.getInstance(seq.getObjectAt(index++));
    +        challenge = ASN1OctetString.getInstance(seq.getObjectAt(index));
    +    }
    +
    +    public static Challenge getInstance(Object o)
    +    {
    +        if (o instanceof Challenge)
    +        {
    +            return (Challenge)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new Challenge(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public Challenge(byte[] witness, byte[] challenge)
    +    {
    +        this(null, witness, challenge);
    +    }
    +
    +    public Challenge(AlgorithmIdentifier owf, byte[] witness, byte[] challenge)
    +    {
    +        this.owf = owf;
    +        this.witness = new DEROctetString(witness);
    +        this.challenge = new DEROctetString(challenge);
    +    }
    +
    +    public AlgorithmIdentifier getOwf()
    +    {
    +        return owf;
    +    }
    +
    +    public byte[] getWitness()
    +    {
    +        return witness.getOctets();
    +    }
    +
    +    public byte[] getChallenge()
    +    {
    +        return challenge.getOctets();
    +    }
    +
    +    /**
    +     * <pre>
    +     * Challenge ::= SEQUENCE {
    +     *                 owf                 AlgorithmIdentifier  OPTIONAL,
    +     *
    +     *                 -- MUST be present in the first Challenge; MAY be omitted in
    +     *                 -- any subsequent Challenge in POPODecKeyChallContent (if
    +     *                 -- omitted, then the owf used in the immediately preceding
    +     *                 -- Challenge is to be used).
    +     *
    +     *                 witness             OCTET STRING,
    +     *                 -- the result of applying the one-way function (owf) to a
    +     *                 -- randomly-generated INTEGER, A.  [Note that a different
    +     *                 -- INTEGER MUST be used for each Challenge.]
    +     *                 challenge           OCTET STRING
    +     *                 -- the encryption (under the public key for which the cert.
    +     *                 -- request is being made) of Rand, where Rand is specified as
    +     *                 --   Rand ::= SEQUENCE {
    +     *                 --      int      INTEGER,
    +     *                 --       - the randomly-generated INTEGER A (above)
    +     *                 --      sender   GeneralName
    +     *                 --       - the sender's name (as included in PKIHeader)
    +     *                 --   }
    +     *      }
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        addOptional(v, owf);
    +        v.add(witness);
    +        v.add(challenge);
    +
    +        return new DERSequence(v);
    +    }
    +
    +    private void addOptional(ASN1EncodableVector v, ASN1Encodable obj)
    +    {
    +        if (obj != null)
    +        {
    +            v.add(obj);
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/CMPCertificate.java+92 0 added
    @@ -0,0 +1,92 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1Choice;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +import org.bouncycastle.asn1.x509.AttributeCertificate;
    +import org.bouncycastle.asn1.x509.Certificate;
    +
    +public class CMPCertificate
    +    extends ASN1Object
    +    implements ASN1Choice
    +{
    +    private Certificate x509v3PKCert;
    +    private AttributeCertificate x509v2AttrCert;
    +
    +    /**
    +     * Note: the addition of attribute certificates is a BC extension.
    +     */
    +    public CMPCertificate(AttributeCertificate x509v2AttrCert)
    +    {
    +        this.x509v2AttrCert = x509v2AttrCert;
    +    }
    +
    +    public CMPCertificate(Certificate x509v3PKCert)
    +    {
    +        if (x509v3PKCert.getVersionNumber() != 3)
    +        {
    +            throw new IllegalArgumentException("only version 3 certificates allowed");
    +        }
    +
    +        this.x509v3PKCert = x509v3PKCert;
    +    }
    +
    +    public static CMPCertificate getInstance(Object o)
    +    {
    +        if (o == null || o instanceof CMPCertificate)
    +        {
    +            return (CMPCertificate)o;
    +        }
    +
    +        if (o instanceof ASN1Sequence || o instanceof byte[])
    +        {
    +            return new CMPCertificate(Certificate.getInstance(o));
    +        }
    +
    +        if (o instanceof ASN1TaggedObject)
    +        {
    +            return new CMPCertificate(AttributeCertificate.getInstance(((ASN1TaggedObject)o).getObject()));
    +        }
    +
    +        throw new IllegalArgumentException("Invalid object: " + o.getClass().getName());
    +    }
    +
    +    public boolean isX509v3PKCert()
    +    {
    +         return x509v3PKCert != null;
    +    }
    +
    +    public Certificate getX509v3PKCert()
    +    {
    +        return x509v3PKCert;
    +    }
    +
    +    public AttributeCertificate getX509v2AttrCert()
    +    {
    +        return x509v2AttrCert;
    +    }
    +
    +    /**
    +     * <pre>
    +     * CMPCertificate ::= CHOICE {
    +     *            x509v3PKCert        Certificate
    +     *            x509v2AttrCert      [1] AttributeCertificate
    +     *  }
    +     * </pre>
    +     * Note: the addition of attribute certificates is a BC extension.
    +     *
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        if (x509v2AttrCert != null)
    +        {        // explicit following CMP conventions
    +            return new DERTaggedObject(true, 1, x509v2AttrCert);
    +        }
    +
    +        return x509v3PKCert.toASN1Primitive();
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/CMPObjectIdentifiers.java+106 0 added
    @@ -0,0 +1,106 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1ObjectIdentifier;
    +
    +public interface CMPObjectIdentifiers
    +{
    +    // RFC 4210
    +
    +    // id-PasswordBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 13}
    +    static final ASN1ObjectIdentifier    passwordBasedMac        = new ASN1ObjectIdentifier("1.2.840.113533.7.66.13");
    +
    +    // id-DHBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 30}
    +    static final ASN1ObjectIdentifier    dhBasedMac              = new ASN1ObjectIdentifier("1.2.840.113533.7.66.30");
    +
    +    // Example InfoTypeAndValue contents include, but are not limited
    +    // to, the following (un-comment in this ASN.1 module and use as
    +    // appropriate for a given environment):
    +    //
    +    //   id-it-caProtEncCert    OBJECT IDENTIFIER ::= {id-it 1}
    +    //      CAProtEncCertValue      ::= CMPCertificate
    +    //   id-it-signKeyPairTypes OBJECT IDENTIFIER ::= {id-it 2}
    +    //      SignKeyPairTypesValue   ::= SEQUENCE OF AlgorithmIdentifier
    +    //   id-it-encKeyPairTypes  OBJECT IDENTIFIER ::= {id-it 3}
    +    //      EncKeyPairTypesValue    ::= SEQUENCE OF AlgorithmIdentifier
    +    //   id-it-preferredSymmAlg OBJECT IDENTIFIER ::= {id-it 4}
    +    //      PreferredSymmAlgValue   ::= AlgorithmIdentifier
    +    //   id-it-caKeyUpdateInfo  OBJECT IDENTIFIER ::= {id-it 5}
    +    //      CAKeyUpdateInfoValue    ::= CAKeyUpdAnnContent
    +    //   id-it-currentCRL       OBJECT IDENTIFIER ::= {id-it 6}
    +    //      CurrentCRLValue         ::= CertificateList
    +    //   id-it-unsupportedOIDs  OBJECT IDENTIFIER ::= {id-it 7}
    +    //      UnsupportedOIDsValue    ::= SEQUENCE OF OBJECT IDENTIFIER
    +    //   id-it-keyPairParamReq  OBJECT IDENTIFIER ::= {id-it 10}
    +    //      KeyPairParamReqValue    ::= OBJECT IDENTIFIER
    +    //   id-it-keyPairParamRep  OBJECT IDENTIFIER ::= {id-it 11}
    +    //      KeyPairParamRepValue    ::= AlgorithmIdentifer
    +    //   id-it-revPassphrase    OBJECT IDENTIFIER ::= {id-it 12}
    +    //      RevPassphraseValue      ::= EncryptedValue
    +    //   id-it-implicitConfirm  OBJECT IDENTIFIER ::= {id-it 13}
    +    //      ImplicitConfirmValue    ::= NULL
    +    //   id-it-confirmWaitTime  OBJECT IDENTIFIER ::= {id-it 14}
    +    //      ConfirmWaitTimeValue    ::= GeneralizedTime
    +    //   id-it-origPKIMessage   OBJECT IDENTIFIER ::= {id-it 15}
    +    //      OrigPKIMessageValue     ::= PKIMessages
    +    //   id-it-suppLangTags     OBJECT IDENTIFIER ::= {id-it 16}
    +    //      SuppLangTagsValue       ::= SEQUENCE OF UTF8String
    +    //
    +    // where
    +    //
    +    //   id-pkix OBJECT IDENTIFIER ::= {
    +    //      iso(1) identified-organization(3)
    +    //      dod(6) internet(1) security(5) mechanisms(5) pkix(7)}
    +    // and
    +    //   id-it   OBJECT IDENTIFIER ::= {id-pkix 4}
    +    static final ASN1ObjectIdentifier    it_caProtEncCert        = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.1");
    +    static final ASN1ObjectIdentifier    it_signKeyPairTypes     = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.2");
    +    static final ASN1ObjectIdentifier    it_encKeyPairTypes      = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.3");
    +    static final ASN1ObjectIdentifier    it_preferredSymAlg      = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.4");
    +    static final ASN1ObjectIdentifier    it_caKeyUpdateInfo      = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.5");
    +    static final ASN1ObjectIdentifier    it_currentCRL           = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.6");
    +    static final ASN1ObjectIdentifier    it_unsupportedOIDs      = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.7");
    +    static final ASN1ObjectIdentifier    it_keyPairParamReq      = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.10");
    +    static final ASN1ObjectIdentifier    it_keyPairParamRep      = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.11");
    +    static final ASN1ObjectIdentifier    it_revPassphrase        = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.12");
    +    static final ASN1ObjectIdentifier    it_implicitConfirm      = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.13");
    +    static final ASN1ObjectIdentifier    it_confirmWaitTime      = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.14");
    +    static final ASN1ObjectIdentifier    it_origPKIMessage       = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.15");
    +    static final ASN1ObjectIdentifier    it_suppLangTags         = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.4.16");
    +
    +    // RFC 4211
    +
    +    // id-pkix  OBJECT IDENTIFIER  ::= { iso(1) identified-organization(3)
    +    //     dod(6) internet(1) security(5) mechanisms(5) pkix(7) }
    +    //
    +    // arc for Internet X.509 PKI protocols and their components
    +    // id-pkip  OBJECT IDENTIFIER :: { id-pkix pkip(5) }
    +    //
    +    // arc for Registration Controls in CRMF
    +    // id-regCtrl  OBJECT IDENTIFIER ::= { id-pkip regCtrl(1) }
    +    //
    +    // arc for Registration Info in CRMF
    +    // id-regInfo       OBJECT IDENTIFIER ::= { id-pkip id-regInfo(2) }
    +
    +    static final ASN1ObjectIdentifier    regCtrl_regToken        = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.1");
    +    static final ASN1ObjectIdentifier    regCtrl_authenticator   = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.2");
    +    static final ASN1ObjectIdentifier    regCtrl_pkiPublicationInfo = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.3");
    +    static final ASN1ObjectIdentifier    regCtrl_pkiArchiveOptions  = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.4");
    +    static final ASN1ObjectIdentifier    regCtrl_oldCertID       = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.5");
    +    static final ASN1ObjectIdentifier    regCtrl_protocolEncrKey = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.6");
    +
    +    // From RFC4210:
    +    // id-regCtrl-altCertTemplate OBJECT IDENTIFIER ::= {id-regCtrl 7}
    +    static final ASN1ObjectIdentifier    regCtrl_altCertTemplate = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.1.7");
    +
    +    static final ASN1ObjectIdentifier    regInfo_utf8Pairs       = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.2.1");
    +    static final ASN1ObjectIdentifier    regInfo_certReq         = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.5.2.2");
    +
    +    // id-smime OBJECT IDENTIFIER ::= { iso(1) member-body(2)
    +    //         us(840) rsadsi(113549) pkcs(1) pkcs9(9) 16 }
    +    //
    +    // id-ct   OBJECT IDENTIFIER ::= { id-smime  1 }  -- content types
    +    //
    +    // id-ct-encKeyWithID OBJECT IDENTIFIER ::= {id-ct 21}
    +    static final ASN1ObjectIdentifier    ct_encKeyWithID         = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.1.21");
    +
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/CRLAnnContent.java+61 0 added
    @@ -0,0 +1,61 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.x509.CertificateList;
    +
    +public class CRLAnnContent
    +    extends ASN1Object
    +{
    +    private ASN1Sequence content;
    +
    +    private CRLAnnContent(ASN1Sequence seq)
    +    {
    +        content = seq;
    +    }
    +
    +    public static CRLAnnContent getInstance(Object o)
    +    {
    +        if (o instanceof CRLAnnContent)
    +        {
    +            return (CRLAnnContent)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new CRLAnnContent(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public CRLAnnContent(CertificateList crl)
    +    {
    +        this.content = new DERSequence(crl);
    +    }
    +
    +    public CertificateList[] getCertificateLists()
    +    {
    +        CertificateList[] result = new CertificateList[content.size()];
    +
    +        for (int i = 0; i != result.length; i++)
    +        {
    +            result[i] = CertificateList.getInstance(content.getObjectAt(i));
    +        }
    +
    +        return result;
    +    }
    +
    +    /**
    +     * <pre>
    +     * CRLAnnContent ::= SEQUENCE OF CertificateList
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        return content;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/ErrorMsgContent.java+121 0 added
    @@ -0,0 +1,121 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import java.util.Enumeration;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +public class ErrorMsgContent
    +    extends ASN1Object
    +{
    +    private PKIStatusInfo pkiStatusInfo;
    +    private ASN1Integer errorCode;
    +    private PKIFreeText errorDetails;
    +
    +    private ErrorMsgContent(ASN1Sequence seq)
    +    {
    +        Enumeration en = seq.getObjects();
    +
    +        pkiStatusInfo = PKIStatusInfo.getInstance(en.nextElement());
    +
    +        while (en.hasMoreElements())
    +        {
    +            Object o = en.nextElement();
    +
    +            if (o instanceof ASN1Integer)
    +            {
    +                errorCode = ASN1Integer.getInstance(o);
    +            }
    +            else
    +            {
    +                errorDetails = PKIFreeText.getInstance(o);
    +            }
    +        }
    +    }
    +
    +    public static ErrorMsgContent getInstance(Object o)
    +    {
    +        if (o instanceof ErrorMsgContent)
    +        {
    +            return (ErrorMsgContent)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new ErrorMsgContent(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public ErrorMsgContent(PKIStatusInfo pkiStatusInfo)
    +    {
    +        this(pkiStatusInfo, null, null);
    +    }
    +
    +    public ErrorMsgContent(
    +        PKIStatusInfo pkiStatusInfo,
    +        ASN1Integer errorCode,
    +        PKIFreeText errorDetails)
    +    {
    +        if (pkiStatusInfo == null)
    +        {
    +            throw new IllegalArgumentException("'pkiStatusInfo' cannot be null");
    +        }
    +
    +        this.pkiStatusInfo = pkiStatusInfo;
    +        this.errorCode = errorCode;
    +        this.errorDetails = errorDetails;
    +    }
    +
    +    public PKIStatusInfo getPKIStatusInfo()
    +    {
    +        return pkiStatusInfo;
    +    }
    +
    +    public ASN1Integer getErrorCode()
    +    {
    +        return errorCode;
    +    }
    +
    +    public PKIFreeText getErrorDetails()
    +    {
    +        return errorDetails;
    +    }
    +
    +    /**
    +     * <pre>
    +     * ErrorMsgContent ::= SEQUENCE {
    +     *                        pKIStatusInfo          PKIStatusInfo,
    +     *                        errorCode              INTEGER           OPTIONAL,
    +     *                        -- implementation-specific error codes
    +     *                        errorDetails           PKIFreeText       OPTIONAL
    +     *                        -- implementation-specific error details
    +     * }
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(pkiStatusInfo);
    +        addOptional(v, errorCode);
    +        addOptional(v, errorDetails);
    +
    +        return new DERSequence(v);
    +    }
    +
    +    private void addOptional(ASN1EncodableVector v, ASN1Encodable obj)
    +    {
    +        if (obj != null)
    +        {
    +            v.add(obj);
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/GenMsgContent.java+71 0 added
    @@ -0,0 +1,71 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +public class GenMsgContent
    +    extends ASN1Object
    +{
    +    private ASN1Sequence content;
    +
    +    private GenMsgContent(ASN1Sequence seq)
    +    {
    +        content = seq;
    +    }
    +
    +    public static GenMsgContent getInstance(Object o)
    +    {
    +        if (o instanceof GenMsgContent)
    +        {
    +            return (GenMsgContent)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new GenMsgContent(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public GenMsgContent(InfoTypeAndValue itv)
    +    {
    +        content = new DERSequence(itv);
    +    }
    +
    +    public GenMsgContent(InfoTypeAndValue[] itv)
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +        for (int i = 0; i < itv.length; i++)
    +        {
    +            v.add(itv[i]);
    +        }
    +        content = new DERSequence(v);
    +    }
    +
    +    public InfoTypeAndValue[] toInfoTypeAndValueArray()
    +    {
    +        InfoTypeAndValue[] result = new InfoTypeAndValue[content.size()];
    +
    +        for (int i = 0; i != result.length; i++)
    +        {
    +            result[i] = InfoTypeAndValue.getInstance(content.getObjectAt(i));
    +        }
    +
    +        return result;
    +    }
    +
    +    /**
    +     * <pre>
    +     * GenMsgContent ::= SEQUENCE OF InfoTypeAndValue
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        return content;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/GenRepContent.java+71 0 added
    @@ -0,0 +1,71 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +public class GenRepContent
    +    extends ASN1Object
    +{
    +    private ASN1Sequence content;
    +
    +    private GenRepContent(ASN1Sequence seq)
    +    {
    +        content = seq;
    +    }
    +
    +    public static GenRepContent getInstance(Object o)
    +    {
    +        if (o instanceof GenRepContent)
    +        {
    +            return (GenRepContent)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new GenRepContent(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public GenRepContent(InfoTypeAndValue itv)
    +    {
    +        content = new DERSequence(itv);
    +    }
    +
    +    public GenRepContent(InfoTypeAndValue[] itv)
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +        for (int i = 0; i < itv.length; i++)
    +        {
    +            v.add(itv[i]);
    +        }
    +        content = new DERSequence(v);
    +    }
    +
    +    public InfoTypeAndValue[] toInfoTypeAndValueArray()
    +    {
    +        InfoTypeAndValue[] result = new InfoTypeAndValue[content.size()];
    +
    +        for (int i = 0; i != result.length; i++)
    +        {
    +            result[i] = InfoTypeAndValue.getInstance(content.getObjectAt(i));
    +        }
    +
    +        return result;
    +    }
    +
    +    /**
    +     * <pre>
    +     * GenRepContent ::= SEQUENCE OF InfoTypeAndValue
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        return content;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/InfoTypeAndValue.java+132 0 added
    @@ -0,0 +1,132 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1ObjectIdentifier;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +/**
    + * Example InfoTypeAndValue contents include, but are not limited
    + * to, the following (un-comment in this ASN.1 module and use as
    + * appropriate for a given environment):
    + * <pre>
    + *   id-it-caProtEncCert    OBJECT IDENTIFIER ::= {id-it 1}
    + *      CAProtEncCertValue      ::= CMPCertificate
    + *   id-it-signKeyPairTypes OBJECT IDENTIFIER ::= {id-it 2}
    + *     SignKeyPairTypesValue   ::= SEQUENCE OF AlgorithmIdentifier
    + *   id-it-encKeyPairTypes  OBJECT IDENTIFIER ::= {id-it 3}
    + *     EncKeyPairTypesValue    ::= SEQUENCE OF AlgorithmIdentifier
    + *   id-it-preferredSymmAlg OBJECT IDENTIFIER ::= {id-it 4}
    + *      PreferredSymmAlgValue   ::= AlgorithmIdentifier
    + *   id-it-caKeyUpdateInfo  OBJECT IDENTIFIER ::= {id-it 5}
    + *      CAKeyUpdateInfoValue    ::= CAKeyUpdAnnContent
    + *   id-it-currentCRL       OBJECT IDENTIFIER ::= {id-it 6}
    + *      CurrentCRLValue         ::= CertificateList
    + *   id-it-unsupportedOIDs  OBJECT IDENTIFIER ::= {id-it 7}
    + *      UnsupportedOIDsValue    ::= SEQUENCE OF OBJECT IDENTIFIER
    + *   id-it-keyPairParamReq  OBJECT IDENTIFIER ::= {id-it 10}
    + *      KeyPairParamReqValue    ::= OBJECT IDENTIFIER
    + *   id-it-keyPairParamRep  OBJECT IDENTIFIER ::= {id-it 11}
    + *      KeyPairParamRepValue    ::= AlgorithmIdentifer
    + *   id-it-revPassphrase    OBJECT IDENTIFIER ::= {id-it 12}
    + *      RevPassphraseValue      ::= EncryptedValue
    + *   id-it-implicitConfirm  OBJECT IDENTIFIER ::= {id-it 13}
    + *      ImplicitConfirmValue    ::= NULL
    + *   id-it-confirmWaitTime  OBJECT IDENTIFIER ::= {id-it 14}
    + *      ConfirmWaitTimeValue    ::= GeneralizedTime
    + *   id-it-origPKIMessage   OBJECT IDENTIFIER ::= {id-it 15}
    + *      OrigPKIMessageValue     ::= PKIMessages
    + *   id-it-suppLangTags     OBJECT IDENTIFIER ::= {id-it 16}
    + *      SuppLangTagsValue       ::= SEQUENCE OF UTF8String
    + *
    + * where
    + *
    + *   id-pkix OBJECT IDENTIFIER ::= {
    + *      iso(1) identified-organization(3)
    + *      dod(6) internet(1) security(5) mechanisms(5) pkix(7)}
    + * and
    + *      id-it   OBJECT IDENTIFIER ::= {id-pkix 4}
    + * </pre>
    + */
    +public class InfoTypeAndValue
    +    extends ASN1Object
    +{
    +    private ASN1ObjectIdentifier infoType;
    +    private ASN1Encodable       infoValue;
    +
    +    private InfoTypeAndValue(ASN1Sequence seq)
    +    {
    +        infoType = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
    +
    +        if (seq.size() > 1)
    +        {
    +            infoValue = (ASN1Encodable)seq.getObjectAt(1);
    +        }
    +    }
    +
    +    public static InfoTypeAndValue getInstance(Object o)
    +    {
    +        if (o instanceof InfoTypeAndValue)
    +        {
    +            return (InfoTypeAndValue)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new InfoTypeAndValue(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public InfoTypeAndValue(
    +        ASN1ObjectIdentifier infoType)
    +    {
    +        this.infoType = infoType;
    +        this.infoValue = null;
    +    }
    +
    +    public InfoTypeAndValue(
    +        ASN1ObjectIdentifier infoType,
    +        ASN1Encodable optionalValue)
    +    {
    +        this.infoType = infoType;
    +        this.infoValue = optionalValue;
    +    }
    +
    +    public ASN1ObjectIdentifier getInfoType()
    +    {
    +        return infoType;
    +    }
    +
    +    public ASN1Encodable getInfoValue()
    +    {
    +        return infoValue;
    +    }
    +
    +    /**
    +     * <pre>
    +     * InfoTypeAndValue ::= SEQUENCE {
    +     *                         infoType               OBJECT IDENTIFIER,
    +     *                         infoValue              ANY DEFINED BY infoType  OPTIONAL
    +     * }
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(infoType);
    +
    +        if (infoValue != null)
    +        {
    +            v.add(infoValue);
    +        }
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/KeyRecRepContent.java+142 0 added
    @@ -0,0 +1,142 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import java.util.Enumeration;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +
    +public class KeyRecRepContent
    +    extends ASN1Object
    +{
    +    private PKIStatusInfo status;
    +    private CMPCertificate newSigCert;
    +    private ASN1Sequence caCerts;
    +    private ASN1Sequence keyPairHist;
    +
    +    private KeyRecRepContent(ASN1Sequence seq)
    +    {
    +        Enumeration en = seq.getObjects();
    +
    +        status = PKIStatusInfo.getInstance(en.nextElement());
    +
    +        while (en.hasMoreElements())
    +        {
    +            ASN1TaggedObject tObj = ASN1TaggedObject.getInstance(en.nextElement());
    +
    +            switch (tObj.getTagNo())
    +            {
    +            case 0:
    +                newSigCert = CMPCertificate.getInstance(tObj.getObject());
    +                break;
    +            case 1:
    +                caCerts = ASN1Sequence.getInstance(tObj.getObject());
    +                break;
    +            case 2:
    +                keyPairHist = ASN1Sequence.getInstance(tObj.getObject());
    +                break;
    +            default:
    +                throw new IllegalArgumentException("unknown tag number: " + tObj.getTagNo());
    +            }
    +        }
    +    }
    +
    +    public static KeyRecRepContent getInstance(Object o)
    +    {
    +        if (o instanceof KeyRecRepContent)
    +        {
    +            return (KeyRecRepContent)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new KeyRecRepContent(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +
    +    public PKIStatusInfo getStatus()
    +    {
    +        return status;
    +    }
    +
    +    public CMPCertificate getNewSigCert()
    +    {
    +        return newSigCert;
    +    }
    +
    +    public CMPCertificate[] getCaCerts()
    +    {
    +        if (caCerts == null)
    +        {
    +            return null;
    +        }
    +
    +        CMPCertificate[] results = new CMPCertificate[caCerts.size()];
    +
    +        for (int i = 0; i != results.length; i++)
    +        {
    +            results[i] = CMPCertificate.getInstance(caCerts.getObjectAt(i));
    +        }
    +
    +        return results;
    +    }
    +
    +    public CertifiedKeyPair[] getKeyPairHist()
    +    {
    +        if (keyPairHist == null)
    +        {
    +            return null;
    +        }
    +
    +        CertifiedKeyPair[] results = new CertifiedKeyPair[keyPairHist.size()];
    +
    +        for (int i = 0; i != results.length; i++)
    +        {
    +            results[i] = CertifiedKeyPair.getInstance(keyPairHist.getObjectAt(i));
    +        }
    +
    +        return results;
    +    }
    +
    +    /**
    +     * <pre>
    +     * KeyRecRepContent ::= SEQUENCE {
    +     *                         status                  PKIStatusInfo,
    +     *                         newSigCert          [0] CMPCertificate OPTIONAL,
    +     *                         caCerts             [1] SEQUENCE SIZE (1..MAX) OF
    +     *                                                           CMPCertificate OPTIONAL,
    +     *                         keyPairHist         [2] SEQUENCE SIZE (1..MAX) OF
    +     *                                                           CertifiedKeyPair OPTIONAL
    +     *              }
    +     * </pre> 
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(status);
    +
    +        addOptional(v, 0, newSigCert);
    +        addOptional(v, 1, caCerts);
    +        addOptional(v, 2, keyPairHist);
    +
    +        return new DERSequence(v);
    +    }
    +
    +    private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj)
    +    {
    +        if (obj != null)
    +        {
    +            v.add(new DERTaggedObject(true, tagNo, obj));
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/OOBCertHash.java+117 0 added
    @@ -0,0 +1,117 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERBitString;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +import org.bouncycastle.asn1.crmf.CertId;
    +import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
    +
    +public class OOBCertHash
    +    extends ASN1Object
    +{
    +    private AlgorithmIdentifier hashAlg;
    +    private CertId certId;
    +    private DERBitString  hashVal;
    +
    +    private OOBCertHash(ASN1Sequence seq)
    +    {
    +        int index = seq.size() - 1;
    +
    +        hashVal = DERBitString.getInstance(seq.getObjectAt(index--));
    +
    +        for (int i = index; i >= 0; i--)
    +        {
    +            ASN1TaggedObject tObj = (ASN1TaggedObject)seq.getObjectAt(i);
    +
    +            if (tObj.getTagNo() == 0)
    +            {
    +                hashAlg = AlgorithmIdentifier.getInstance(tObj, true);
    +            }
    +            else
    +            {
    +                certId = CertId.getInstance(tObj, true);
    +            }
    +        }
    +
    +    }
    +
    +    public static OOBCertHash getInstance(Object o)
    +    {
    +        if (o instanceof OOBCertHash)
    +        {
    +            return (OOBCertHash)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new OOBCertHash(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public OOBCertHash(AlgorithmIdentifier hashAlg, CertId certId, byte[] hashVal)
    +    {
    +        this(hashAlg, certId, new DERBitString(hashVal));
    +    }
    +
    +    public OOBCertHash(AlgorithmIdentifier hashAlg, CertId certId, DERBitString hashVal)
    +    {
    +        this.hashAlg = hashAlg;
    +        this.certId = certId;
    +        this.hashVal = hashVal;
    +    }
    +
    +    public AlgorithmIdentifier getHashAlg()
    +    {
    +        return hashAlg;
    +    }
    +
    +    public CertId getCertId()
    +    {
    +        return certId;
    +    }
    +
    +    public DERBitString getHashVal()
    +    {
    +        return hashVal;
    +    }
    +
    +    /**
    +     * <pre>
    +     * OOBCertHash ::= SEQUENCE {
    +     *                      hashAlg     [0] AlgorithmIdentifier     OPTIONAL,
    +     *                      certId      [1] CertId                  OPTIONAL,
    +     *                      hashVal         BIT STRING
    +     *                      -- hashVal is calculated over the DER encoding of the
    +     *                      -- self-signed certificate with the identifier certID.
    +     *       }
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        addOptional(v, 0, hashAlg);
    +        addOptional(v, 1, certId);
    +
    +        v.add(hashVal);
    +
    +        return new DERSequence(v);
    +    }
    +
    +    private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj)
    +    {
    +        if (obj != null)
    +        {
    +            v.add(new DERTaggedObject(true, tagNo, obj));
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/PBMParameter.java+117 0 added
    @@ -0,0 +1,117 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DEROctetString;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
    +
    +public class PBMParameter
    +    extends ASN1Object
    +{
    +    private ASN1OctetString salt;
    +    private AlgorithmIdentifier owf;
    +    private ASN1Integer iterationCount;
    +    private AlgorithmIdentifier mac;
    +
    +    private PBMParameter(ASN1Sequence seq)
    +    {
    +        salt = ASN1OctetString.getInstance(seq.getObjectAt(0));
    +        owf = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
    +        iterationCount = ASN1Integer.getInstance(seq.getObjectAt(2));
    +        mac = AlgorithmIdentifier.getInstance(seq.getObjectAt(3));
    +    }
    +
    +    public static PBMParameter getInstance(Object o)
    +    {
    +        if (o instanceof PBMParameter)
    +        {
    +            return (PBMParameter)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new PBMParameter(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public PBMParameter(
    +        byte[] salt,
    +        AlgorithmIdentifier owf,
    +        int iterationCount,
    +        AlgorithmIdentifier mac)
    +    {
    +        this(new DEROctetString(salt), owf,
    +             new ASN1Integer(iterationCount), mac);
    +    }
    +
    +    public PBMParameter(
    +        ASN1OctetString salt,
    +        AlgorithmIdentifier owf,
    +        ASN1Integer iterationCount,
    +        AlgorithmIdentifier mac)
    +    {
    +        this.salt = salt;
    +        this.owf = owf;
    +        this.iterationCount = iterationCount;
    +        this.mac = mac;
    +    }
    +
    +    public ASN1OctetString getSalt()
    +    {
    +        return salt;
    +    }
    +
    +    public AlgorithmIdentifier getOwf()
    +    {
    +        return owf;
    +    }
    +
    +    public ASN1Integer getIterationCount()
    +    {
    +        return iterationCount;
    +    }
    +
    +    public AlgorithmIdentifier getMac()
    +    {
    +        return mac;
    +    }
    +
    +    /**
    +     * <pre>
    +     *  PBMParameter ::= SEQUENCE {
    +     *                        salt                OCTET STRING,
    +     *                        -- note:  implementations MAY wish to limit acceptable sizes
    +     *                        -- of this string to values appropriate for their environment
    +     *                        -- in order to reduce the risk of denial-of-service attacks
    +     *                        owf                 AlgorithmIdentifier,
    +     *                        -- AlgId for a One-Way Function (SHA-1 recommended)
    +     *                        iterationCount      INTEGER,
    +     *                        -- number of times the OWF is applied
    +     *                        -- note:  implementations MAY wish to limit acceptable sizes
    +     *                        -- of this integer to values appropriate for their environment
    +     *                        -- in order to reduce the risk of denial-of-service attacks
    +     *                        mac                 AlgorithmIdentifier
    +     *                        -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11],
    +     *    }   -- or HMAC [RFC2104, RFC2202])
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(salt);
    +        v.add(owf);
    +        v.add(iterationCount);
    +        v.add(mac);
    +        
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/PKIBody.java+194 0 added
    @@ -0,0 +1,194 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1Choice;
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +import org.bouncycastle.asn1.crmf.CertReqMessages;
    +import org.bouncycastle.asn1.pkcs.CertificationRequest;
    +
    +public class PKIBody
    +    extends ASN1Object
    +    implements ASN1Choice
    +{
    +    public static final int TYPE_INIT_REQ = 0;
    +    public static final int TYPE_INIT_REP = 1;
    +    public static final int TYPE_CERT_REQ = 2;
    +    public static final int TYPE_CERT_REP = 3;
    +    public static final int TYPE_P10_CERT_REQ = 4;
    +    public static final int TYPE_POPO_CHALL = 5;
    +    public static final int TYPE_POPO_REP = 6;
    +    public static final int TYPE_KEY_UPDATE_REQ = 7;
    +    public static final int TYPE_KEY_UPDATE_REP = 8;
    +    public static final int TYPE_KEY_RECOVERY_REQ = 9;
    +    public static final int TYPE_KEY_RECOVERY_REP = 10;
    +    public static final int TYPE_REVOCATION_REQ = 11;
    +    public static final int TYPE_REVOCATION_REP = 12;
    +    public static final int TYPE_CROSS_CERT_REQ = 13;
    +    public static final int TYPE_CROSS_CERT_REP = 14;
    +    public static final int TYPE_CA_KEY_UPDATE_ANN = 15;
    +    public static final int TYPE_CERT_ANN = 16;
    +    public static final int TYPE_REVOCATION_ANN = 17;
    +    public static final int TYPE_CRL_ANN = 18;
    +    public static final int TYPE_CONFIRM = 19;
    +    public static final int TYPE_NESTED = 20;
    +    public static final int TYPE_GEN_MSG = 21;
    +    public static final int TYPE_GEN_REP = 22;
    +    public static final int TYPE_ERROR = 23;
    +    public static final int TYPE_CERT_CONFIRM = 24;
    +    public static final int TYPE_POLL_REQ = 25;
    +    public static final int TYPE_POLL_REP = 26;
    +
    +    private int tagNo;
    +    private ASN1Encodable body;
    +
    +    public static PKIBody getInstance(Object o)
    +    {
    +        if (o == null || o instanceof PKIBody)
    +        {
    +            return (PKIBody)o;
    +        }
    +
    +        if (o instanceof ASN1TaggedObject)
    +        {
    +            return new PKIBody((ASN1TaggedObject)o);
    +        }
    +
    +        throw new IllegalArgumentException("Invalid object: " + o.getClass().getName());
    +    }
    +
    +    private PKIBody(ASN1TaggedObject tagged)
    +    {
    +        tagNo = tagged.getTagNo();
    +        body = getBodyForType(tagNo, tagged.getObject());
    +    }
    +
    +    /**
    +     * Creates a new PKIBody.
    +     * @param type one of the TYPE_* constants
    +     * @param content message content
    +     */
    +    public PKIBody(
    +        int type,
    +        ASN1Encodable content)
    +    {
    +        tagNo = type;
    +        body = getBodyForType(type, content);
    +    }
    +
    +    private static ASN1Encodable getBodyForType(
    +        int type,
    +        ASN1Encodable o)
    +    {
    +        switch (type)
    +        {
    +        case TYPE_INIT_REQ:
    +            return CertReqMessages.getInstance(o);
    +        case TYPE_INIT_REP:
    +            return CertRepMessage.getInstance(o);
    +        case TYPE_CERT_REQ:
    +            return CertReqMessages.getInstance(o);
    +        case TYPE_CERT_REP:
    +            return CertRepMessage.getInstance(o);
    +        case TYPE_P10_CERT_REQ:
    +            return CertificationRequest.getInstance(o);
    +        case TYPE_POPO_CHALL:
    +            return POPODecKeyChallContent.getInstance(o);
    +        case TYPE_POPO_REP:
    +            return POPODecKeyRespContent.getInstance(o);
    +        case TYPE_KEY_UPDATE_REQ:
    +            return CertReqMessages.getInstance(o);
    +        case TYPE_KEY_UPDATE_REP:
    +            return CertRepMessage.getInstance(o);
    +        case TYPE_KEY_RECOVERY_REQ:
    +            return CertReqMessages.getInstance(o);
    +        case TYPE_KEY_RECOVERY_REP:
    +            return KeyRecRepContent.getInstance(o);
    +        case TYPE_REVOCATION_REQ:
    +            return RevReqContent.getInstance(o);
    +        case TYPE_REVOCATION_REP:
    +            return RevRepContent.getInstance(o);
    +        case TYPE_CROSS_CERT_REQ:
    +            return CertReqMessages.getInstance(o);
    +        case TYPE_CROSS_CERT_REP:
    +            return CertRepMessage.getInstance(o);
    +        case TYPE_CA_KEY_UPDATE_ANN:
    +            return CAKeyUpdAnnContent.getInstance(o);
    +        case TYPE_CERT_ANN:
    +            return CMPCertificate.getInstance(o);
    +        case TYPE_REVOCATION_ANN:
    +            return RevAnnContent.getInstance(o);
    +        case TYPE_CRL_ANN:
    +            return CRLAnnContent.getInstance(o);
    +        case TYPE_CONFIRM:
    +            return PKIConfirmContent.getInstance(o);
    +        case TYPE_NESTED:
    +            return PKIMessages.getInstance(o);
    +        case TYPE_GEN_MSG:
    +            return GenMsgContent.getInstance(o);
    +        case TYPE_GEN_REP:
    +            return GenRepContent.getInstance(o);
    +        case TYPE_ERROR:
    +            return ErrorMsgContent.getInstance(o);
    +        case TYPE_CERT_CONFIRM:
    +            return CertConfirmContent.getInstance(o);
    +        case TYPE_POLL_REQ:
    +            return PollReqContent.getInstance(o);
    +        case TYPE_POLL_REP:
    +            return PollRepContent.getInstance(o);
    +        default:
    +            throw new IllegalArgumentException("unknown tag number: " + type);
    +        }
    +    }
    +
    +    public int getType()
    +    {
    +        return tagNo;
    +    }
    +
    +    public ASN1Encodable getContent()
    +    {
    +        return body;
    +    }
    +
    +    /**
    +     * <pre>
    +     * PKIBody ::= CHOICE {       -- message-specific body elements
    +     *        ir       [0]  CertReqMessages,        --Initialization Request
    +     *        ip       [1]  CertRepMessage,         --Initialization Response
    +     *        cr       [2]  CertReqMessages,        --Certification Request
    +     *        cp       [3]  CertRepMessage,         --Certification Response
    +     *        p10cr    [4]  CertificationRequest,   --imported from [PKCS10]
    +     *        popdecc  [5]  POPODecKeyChallContent, --pop Challenge
    +     *        popdecr  [6]  POPODecKeyRespContent,  --pop Response
    +     *        kur      [7]  CertReqMessages,        --Key Update Request
    +     *        kup      [8]  CertRepMessage,         --Key Update Response
    +     *        krr      [9]  CertReqMessages,        --Key Recovery Request
    +     *        krp      [10] KeyRecRepContent,       --Key Recovery Response
    +     *        rr       [11] RevReqContent,          --Revocation Request
    +     *        rp       [12] RevRepContent,          --Revocation Response
    +     *        ccr      [13] CertReqMessages,        --Cross-Cert. Request
    +     *        ccp      [14] CertRepMessage,         --Cross-Cert. Response
    +     *        ckuann   [15] CAKeyUpdAnnContent,     --CA Key Update Ann.
    +     *        cann     [16] CertAnnContent,         --Certificate Ann.
    +     *        rann     [17] RevAnnContent,          --Revocation Ann.
    +     *        crlann   [18] CRLAnnContent,          --CRL Announcement
    +     *        pkiconf  [19] PKIConfirmContent,      --Confirmation
    +     *        nested   [20] NestedMessageContent,   --Nested Message
    +     *        genm     [21] GenMsgContent,          --General Message
    +     *        genp     [22] GenRepContent,          --General Response
    +     *        error    [23] ErrorMsgContent,        --Error Message
    +     *        certConf [24] CertConfirmContent,     --Certificate confirm
    +     *        pollReq  [25] PollReqContent,         --Polling request
    +     *        pollRep  [26] PollRepContent          --Polling response
    +     * }
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        return new DERTaggedObject(true, tagNo, body);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/PKIConfirmContent.java+48 0 added
    @@ -0,0 +1,48 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1Null;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.DERNull;
    +
    +public class PKIConfirmContent
    +    extends ASN1Object
    +{
    +    private ASN1Null val;
    +
    +    private PKIConfirmContent(ASN1Null val)
    +    {
    +        this.val = val;
    +    }
    +
    +    public static PKIConfirmContent getInstance(Object o)
    +    {
    +        if (o == null || o instanceof PKIConfirmContent)
    +        {
    +            return (PKIConfirmContent)o;
    +        }
    +
    +        if (o instanceof ASN1Null)
    +        {
    +            return new PKIConfirmContent((ASN1Null)o);
    +        }
    +
    +        throw new IllegalArgumentException("Invalid object: " + o.getClass().getName());
    +    }
    +
    +    public PKIConfirmContent()
    +    {
    +        val = DERNull.INSTANCE;
    +    }
    +
    +    /**
    +     * <pre>
    +     * PKIConfirmContent ::= NULL
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        return val;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/PKIFailureInfo.java+126 0 added
    @@ -0,0 +1,126 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.DERBitString;
    +
    +/**
    + * <pre>
    + * PKIFailureInfo ::= BIT STRING {
    + * badAlg               (0),
    + *   -- unrecognized or unsupported Algorithm Identifier
    + * badMessageCheck      (1), -- integrity check failed (e.g., signature did not verify)
    + * badRequest           (2),
    + *   -- transaction not permitted or supported
    + * badTime              (3), -- messageTime was not sufficiently close to the system time, as defined by local policy
    + * badCertId            (4), -- no certificate could be found matching the provided criteria
    + * badDataFormat        (5),
    + *   -- the data submitted has the wrong format
    + * wrongAuthority       (6), -- the authority indicated in the request is different from the one creating the response token
    + * incorrectData        (7), -- the requester's data is incorrect (for notary services)
    + * missingTimeStamp     (8), -- when the timestamp is missing but should be there (by policy)
    + * badPOP               (9)  -- the proof-of-possession failed
    + * certRevoked         (10),
    + * certConfirmed       (11),
    + * wrongIntegrity      (12),
    + * badRecipientNonce   (13), 
    + * timeNotAvailable    (14),
    + *   -- the TSA's time source is not available
    + * unacceptedPolicy    (15),
    + *   -- the requested TSA policy is not supported by the TSA
    + * unacceptedExtension (16),
    + *   -- the requested extension is not supported by the TSA
    + * addInfoNotAvailable (17)
    + *   -- the additional information requested could not be understood
    + *   -- or is not available
    + * badSenderNonce      (18),
    + * badCertTemplate     (19),
    + * signerNotTrusted    (20),
    + * transactionIdInUse  (21),
    + * unsupportedVersion  (22),
    + * notAuthorized       (23),
    + * systemUnavail       (24),    
    + * systemFailure       (25),
    + *   -- the request cannot be handled due to system failure
    + * duplicateCertReq    (26) 
    + * </pre>
    + */
    +public class PKIFailureInfo
    +    extends DERBitString
    +{
    +    public static final int badAlg               = (1 << 7); // unrecognized or unsupported Algorithm Identifier
    +    public static final int badMessageCheck      = (1 << 6); // integrity check failed (e.g., signature did not verify)
    +    public static final int badRequest           = (1 << 5);
    +    public static final int badTime              = (1 << 4); // -- messageTime was not sufficiently close to the system time, as defined by local policy
    +    public static final int badCertId            = (1 << 3); // no certificate could be found matching the provided criteria
    +    public static final int badDataFormat        = (1 << 2);
    +    public static final int wrongAuthority       = (1 << 1); // the authority indicated in the request is different from the one creating the response token
    +    public static final int incorrectData        = 1;        // the requester's data is incorrect (for notary services)
    +    public static final int missingTimeStamp     = (1 << 15); // when the timestamp is missing but should be there (by policy)
    +    public static final int badPOP               = (1 << 14); // the proof-of-possession failed
    +    public static final int certRevoked          = (1 << 13);
    +    public static final int certConfirmed        = (1 << 12);
    +    public static final int wrongIntegrity       = (1 << 11);
    +    public static final int badRecipientNonce    = (1 << 10);
    +    public static final int timeNotAvailable     = (1 << 9); // the TSA's time source is not available
    +    public static final int unacceptedPolicy     = (1 << 8); // the requested TSA policy is not supported by the TSA
    +    public static final int unacceptedExtension  = (1 << 23); //the requested extension is not supported by the TSA
    +    public static final int addInfoNotAvailable  = (1 << 22); //the additional information requested could not be understood or is not available
    +    public static final int badSenderNonce       = (1 << 21);
    +    public static final int badCertTemplate      = (1 << 20);
    +    public static final int signerNotTrusted     = (1 << 19);
    +    public static final int transactionIdInUse   = (1 << 18);
    +    public static final int unsupportedVersion   = (1 << 17);
    +    public static final int notAuthorized        = (1 << 16);
    +    public static final int systemUnavail        = (1 << 31);
    +    public static final int systemFailure        = (1 << 30); //the request cannot be handled due to system failure
    +    public static final int duplicateCertReq     = (1 << 29);
    +
    +    /** @deprecated use lower case version */
    +    public static final int BAD_ALG                   = badAlg; // unrecognized or unsupported Algorithm Identifier
    +    /** @deprecated use lower case version */
    +    public static final int BAD_MESSAGE_CHECK         = badMessageCheck;
    +    /** @deprecated use lower case version */
    +    public static final int BAD_REQUEST               = badRequest; // transaction not permitted or supported
    +    /** @deprecated use lower case version */
    +    public static final int BAD_TIME                  = badTime;
    +    /** @deprecated use lower case version */
    +    public static final int BAD_CERT_ID               = badCertId;
    +    /** @deprecated use lower case version */
    +    public static final int BAD_DATA_FORMAT           = badDataFormat; // the data submitted has the wrong format
    +    /** @deprecated use lower case version */
    +    public static final int WRONG_AUTHORITY           = wrongAuthority;
    +    /** @deprecated use lower case version */
    +    public static final int INCORRECT_DATA            = incorrectData;
    +    /** @deprecated use lower case version */
    +    public static final int MISSING_TIME_STAMP        = missingTimeStamp;
    +    /** @deprecated use lower case version */
    +    public static final int BAD_POP                   = badPOP;
    +    /** @deprecated use lower case version */
    +    public static final int TIME_NOT_AVAILABLE        = timeNotAvailable;
    +    /** @deprecated use lower case version */
    +    public static final int UNACCEPTED_POLICY         = unacceptedPolicy;
    +    /** @deprecated use lower case version */
    +    public static final int UNACCEPTED_EXTENSION      = unacceptedExtension;
    +    /** @deprecated use lower case version */
    +    public static final int ADD_INFO_NOT_AVAILABLE    = addInfoNotAvailable; 
    +    /** @deprecated use lower case version */
    +    public static final int SYSTEM_FAILURE            = systemFailure; 
    +    /**
    +     * Basic constructor.
    +     */
    +    public PKIFailureInfo(
    +        int info)
    +    {
    +        super(getBytes(info), getPadBits(info));
    +    }
    +
    +    public PKIFailureInfo(
    +        DERBitString info)
    +    {
    +        super(info.getBytes(), info.getPadBits());
    +    }
    +    
    +    public String toString()
    +    {
    +        return "PKIFailureInfo: 0x" + Integer.toHexString(this.intValue());
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/PKIFreeText.java+115 0 added
    @@ -0,0 +1,115 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import java.util.Enumeration;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.DERUTF8String;
    +
    +public class PKIFreeText
    +    extends ASN1Object
    +{
    +    ASN1Sequence strings;
    +
    +    public static PKIFreeText getInstance(
    +        ASN1TaggedObject    obj,
    +        boolean             explicit)
    +    {
    +        return getInstance(ASN1Sequence.getInstance(obj, explicit));
    +    }
    +
    +    public static PKIFreeText getInstance(
    +        Object obj)
    +    {
    +        if (obj instanceof PKIFreeText)
    +        {
    +            return (PKIFreeText)obj;
    +        }
    +        else if (obj != null)
    +        {
    +            return new PKIFreeText(ASN1Sequence.getInstance(obj));
    +        }
    +
    +        return null;
    +    }
    +
    +    private PKIFreeText(
    +        ASN1Sequence seq)
    +    {
    +        Enumeration e = seq.getObjects();
    +        while (e.hasMoreElements())
    +        {
    +            if (!(e.nextElement() instanceof DERUTF8String))
    +            {
    +                throw new IllegalArgumentException("attempt to insert non UTF8 STRING into PKIFreeText");
    +            }
    +        }
    +        
    +        strings = seq;
    +    }
    +
    +    public PKIFreeText(
    +        DERUTF8String p)
    +    {
    +        strings = new DERSequence(p);
    +    }
    +
    +    public PKIFreeText(
    +        String p)
    +    {
    +        this(new DERUTF8String(p));
    +    }
    +
    +    public PKIFreeText(
    +        DERUTF8String[] strs)
    +    {
    +        strings = new DERSequence(strs);
    +    }
    +
    +    public PKIFreeText(
    +        String[] strs)
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +        for (int i = 0; i < strs.length; i++)
    +        {
    +            v.add(new DERUTF8String(strs[i]));
    +        }
    +        strings = new DERSequence(v);
    +    }
    +
    +    /**
    +     * Return the number of string elements present.
    +     * 
    +     * @return number of elements present.
    +     */
    +    public int size()
    +    {
    +        return strings.size();
    +    }
    +    
    +    /**
    +     * Return the UTF8STRING at index i.
    +     * 
    +     * @param i index of the string of interest
    +     * @return the string at index i.
    +     */
    +    public DERUTF8String getStringAt(
    +        int i)
    +    {
    +        return (DERUTF8String)strings.getObjectAt(i);
    +    }
    +    
    +    /**
    +     * <pre>
    +     * PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        return strings;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/PKIHeaderBuilder.java+254 0 added
    @@ -0,0 +1,254 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1GeneralizedTime;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DERGeneralizedTime;
    +import org.bouncycastle.asn1.DEROctetString;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
    +import org.bouncycastle.asn1.x509.GeneralName;
    +
    +public class PKIHeaderBuilder
    +{
    +    private ASN1Integer pvno;
    +    private GeneralName sender;
    +    private GeneralName recipient;
    +    private ASN1GeneralizedTime messageTime;
    +    private AlgorithmIdentifier protectionAlg;
    +    private ASN1OctetString senderKID;       // KeyIdentifier
    +    private ASN1OctetString recipKID;        // KeyIdentifier
    +    private ASN1OctetString transactionID;
    +    private ASN1OctetString senderNonce;
    +    private ASN1OctetString recipNonce;
    +    private PKIFreeText     freeText;
    +    private ASN1Sequence    generalInfo;
    +
    +    public PKIHeaderBuilder(
    +        int pvno,
    +        GeneralName sender,
    +        GeneralName recipient)
    +    {
    +        this(new ASN1Integer(pvno), sender, recipient);
    +    }
    +
    +    private PKIHeaderBuilder(
    +        ASN1Integer pvno,
    +        GeneralName sender,
    +        GeneralName recipient)
    +    {
    +        this.pvno = pvno;
    +        this.sender = sender;
    +        this.recipient = recipient;
    +    }
    +
    +    /**
    +     * @deprecated use ASN1GeneralizedTime
    +     */
    +    public PKIHeaderBuilder setMessageTime(DERGeneralizedTime time)
    +    {
    +        messageTime = ASN1GeneralizedTime.getInstance(time);
    +
    +        return this;
    +    }
    +
    +    public PKIHeaderBuilder setMessageTime(ASN1GeneralizedTime time)
    +    {
    +        messageTime = time;
    +
    +        return this;
    +    }
    +
    +    public PKIHeaderBuilder setProtectionAlg(AlgorithmIdentifier aid)
    +    {
    +        protectionAlg = aid;
    +
    +        return this;
    +    }
    +
    +    public PKIHeaderBuilder setSenderKID(byte[] kid)
    +    {
    +        return setSenderKID(kid == null ? null : new DEROctetString(kid));
    +    }
    +
    +    public PKIHeaderBuilder setSenderKID(ASN1OctetString kid)
    +    {
    +        senderKID = kid;
    +
    +        return this;
    +    }
    +
    +    public PKIHeaderBuilder setRecipKID(byte[] kid)
    +    {
    +        return setRecipKID(kid == null ? null : new DEROctetString(kid));
    +    }
    +
    +    public PKIHeaderBuilder setRecipKID(DEROctetString kid)
    +    {
    +        recipKID = kid;
    +
    +        return this;
    +    }
    +
    +    public PKIHeaderBuilder setTransactionID(byte[] tid)
    +    {
    +        return setTransactionID(tid == null ? null : new DEROctetString(tid));
    +    }
    +
    +    public PKIHeaderBuilder setTransactionID(ASN1OctetString tid)
    +    {
    +        transactionID = tid;
    +
    +        return this;
    +    }
    +
    +    public PKIHeaderBuilder setSenderNonce(byte[] nonce)
    +    {
    +        return setSenderNonce(nonce == null ? null : new DEROctetString(nonce));
    +    }
    +
    +    public PKIHeaderBuilder setSenderNonce(ASN1OctetString nonce)
    +    {
    +        senderNonce = nonce;
    +
    +        return this;
    +    }
    +
    +    public PKIHeaderBuilder setRecipNonce(byte[] nonce)
    +    {
    +        return setRecipNonce(nonce == null ? null : new DEROctetString(nonce));
    +    }
    +
    +    public PKIHeaderBuilder setRecipNonce(ASN1OctetString nonce)
    +    {
    +        recipNonce = nonce;
    +
    +        return this;
    +    }
    +
    +    public PKIHeaderBuilder setFreeText(PKIFreeText text)
    +    {
    +        freeText = text;
    +
    +        return this;
    +    }
    +
    +    public PKIHeaderBuilder setGeneralInfo(InfoTypeAndValue genInfo)
    +    {
    +        return setGeneralInfo(makeGeneralInfoSeq(genInfo));
    +    }
    +
    +    public PKIHeaderBuilder setGeneralInfo(InfoTypeAndValue[] genInfos)
    +    {
    +        return setGeneralInfo(makeGeneralInfoSeq(genInfos));
    +    }
    +
    +    public PKIHeaderBuilder setGeneralInfo(ASN1Sequence seqOfInfoTypeAndValue)
    +    {
    +        generalInfo = seqOfInfoTypeAndValue;
    +
    +        return this;
    +    }
    +
    +    private static ASN1Sequence makeGeneralInfoSeq(
    +        InfoTypeAndValue generalInfo)
    +    {
    +        return new DERSequence(generalInfo);
    +    }
    +
    +    private static ASN1Sequence makeGeneralInfoSeq(
    +        InfoTypeAndValue[] generalInfos)
    +    {
    +        ASN1Sequence genInfoSeq = null;
    +        if (generalInfos != null)
    +        {
    +            ASN1EncodableVector v = new ASN1EncodableVector();
    +            for (int i = 0; i < generalInfos.length; i++)
    +            {
    +                v.add(generalInfos[i]);
    +            }
    +            genInfoSeq = new DERSequence(v);
    +        }
    +        return genInfoSeq;
    +    }
    +
    +    /**
    +     * <pre>
    +     *  PKIHeader ::= SEQUENCE {
    +     *            pvno                INTEGER     { cmp1999(1), cmp2000(2) },
    +     *            sender              GeneralName,
    +     *            -- identifies the sender
    +     *            recipient           GeneralName,
    +     *            -- identifies the intended recipient
    +     *            messageTime     [0] GeneralizedTime         OPTIONAL,
    +     *            -- time of production of this message (used when sender
    +     *            -- believes that the transport will be "suitable"; i.e.,
    +     *            -- that the time will still be meaningful upon receipt)
    +     *            protectionAlg   [1] AlgorithmIdentifier     OPTIONAL,
    +     *            -- algorithm used for calculation of protection bits
    +     *            senderKID       [2] KeyIdentifier           OPTIONAL,
    +     *            recipKID        [3] KeyIdentifier           OPTIONAL,
    +     *            -- to identify specific keys used for protection
    +     *            transactionID   [4] OCTET STRING            OPTIONAL,
    +     *            -- identifies the transaction; i.e., this will be the same in
    +     *            -- corresponding request, response, certConf, and PKIConf
    +     *            -- messages
    +     *            senderNonce     [5] OCTET STRING            OPTIONAL,
    +     *            recipNonce      [6] OCTET STRING            OPTIONAL,
    +     *            -- nonces used to provide replay protection, senderNonce
    +     *            -- is inserted by the creator of this message; recipNonce
    +     *            -- is a nonce previously inserted in a related message by
    +     *            -- the intended recipient of this message
    +     *            freeText        [7] PKIFreeText             OPTIONAL,
    +     *            -- this may be used to indicate context-specific instructions
    +     *            -- (this field is intended for human consumption)
    +     *            generalInfo     [8] SEQUENCE SIZE (1..MAX) OF
    +     *                                 InfoTypeAndValue     OPTIONAL
    +     *            -- this may be used to convey context-specific information
    +     *            -- (this field not primarily intended for human consumption)
    +     * }
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public PKIHeader build()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(pvno);
    +        v.add(sender);
    +        v.add(recipient);
    +        addOptional(v, 0, messageTime);
    +        addOptional(v, 1, protectionAlg);
    +        addOptional(v, 2, senderKID);
    +        addOptional(v, 3, recipKID);
    +        addOptional(v, 4, transactionID);
    +        addOptional(v, 5, senderNonce);
    +        addOptional(v, 6, recipNonce);
    +        addOptional(v, 7, freeText);
    +        addOptional(v, 8, generalInfo);
    +
    +        messageTime = null;
    +        protectionAlg = null;
    +        senderKID = null;
    +        recipKID = null;
    +        transactionID = null;
    +        senderNonce = null;
    +        recipNonce = null;
    +        freeText = null;
    +        generalInfo = null;
    +        
    +        return PKIHeader.getInstance(new DERSequence(v));
    +    }
    +
    +    private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj)
    +    {
    +        if (obj != null)
    +        {
    +            v.add(new DERTaggedObject(true, tagNo, obj));
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/PKIHeader.java+260 0 added
    @@ -0,0 +1,260 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import java.util.Enumeration;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERGeneralizedTime;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +import org.bouncycastle.asn1.x500.X500Name;
    +import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
    +import org.bouncycastle.asn1.x509.GeneralName;
    +
    +public class PKIHeader
    +    extends ASN1Object
    +{
    +    /**
    +     * Value for a "null" recipient or sender.
    +     */
    +    public static final GeneralName NULL_NAME = new GeneralName(X500Name.getInstance(new DERSequence()));
    +
    +    public static final int CMP_1999 = 1;
    +    public static final int CMP_2000 = 2;
    +
    +    private ASN1Integer pvno;
    +    private GeneralName sender;
    +    private GeneralName recipient;
    +    private DERGeneralizedTime messageTime;
    +    private AlgorithmIdentifier protectionAlg;
    +    private ASN1OctetString senderKID;       // KeyIdentifier
    +    private ASN1OctetString recipKID;        // KeyIdentifier
    +    private ASN1OctetString transactionID;
    +    private ASN1OctetString senderNonce;
    +    private ASN1OctetString recipNonce;
    +    private PKIFreeText freeText;
    +    private ASN1Sequence generalInfo;
    +
    +    private PKIHeader(ASN1Sequence seq)
    +    {
    +        Enumeration en = seq.getObjects();
    +
    +        pvno = ASN1Integer.getInstance(en.nextElement());
    +        sender = GeneralName.getInstance(en.nextElement());
    +        recipient = GeneralName.getInstance(en.nextElement());
    +
    +        while (en.hasMoreElements())
    +        {
    +            ASN1TaggedObject tObj = (ASN1TaggedObject)en.nextElement();
    +
    +            switch (tObj.getTagNo())
    +            {
    +            case 0:
    +                messageTime = DERGeneralizedTime.getInstance(tObj, true);
    +                break;
    +            case 1:
    +                protectionAlg = AlgorithmIdentifier.getInstance(tObj, true);
    +                break;
    +            case 2:
    +                senderKID = ASN1OctetString.getInstance(tObj, true);
    +                break;
    +            case 3:
    +                recipKID = ASN1OctetString.getInstance(tObj, true);
    +                break;
    +            case 4:
    +                transactionID = ASN1OctetString.getInstance(tObj, true);
    +                break;
    +            case 5:
    +                senderNonce = ASN1OctetString.getInstance(tObj, true);
    +                break;
    +            case 6:
    +                recipNonce = ASN1OctetString.getInstance(tObj, true);
    +                break;
    +            case 7:
    +                freeText = PKIFreeText.getInstance(tObj, true);
    +                break;
    +            case 8:
    +                generalInfo = ASN1Sequence.getInstance(tObj, true);
    +                break;
    +            default:
    +                throw new IllegalArgumentException("unknown tag number: " + tObj.getTagNo());
    +            }
    +        }
    +    }
    +
    +    public static PKIHeader getInstance(Object o)
    +    {
    +        if (o instanceof PKIHeader)
    +        {
    +            return (PKIHeader)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new PKIHeader(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public PKIHeader(
    +        int pvno,
    +        GeneralName sender,
    +        GeneralName recipient)
    +    {
    +        this(new ASN1Integer(pvno), sender, recipient);
    +    }
    +
    +    private PKIHeader(
    +        ASN1Integer pvno,
    +        GeneralName sender,
    +        GeneralName recipient)
    +    {
    +        this.pvno = pvno;
    +        this.sender = sender;
    +        this.recipient = recipient;
    +    }
    +
    +    public ASN1Integer getPvno()
    +    {
    +        return pvno;
    +    }
    +
    +    public GeneralName getSender()
    +    {
    +        return sender;
    +    }
    +
    +    public GeneralName getRecipient()
    +    {
    +        return recipient;
    +    }
    +
    +    public DERGeneralizedTime getMessageTime()
    +    {
    +        return messageTime;
    +    }
    +
    +    public AlgorithmIdentifier getProtectionAlg()
    +    {
    +        return protectionAlg;
    +    }
    +
    +    public ASN1OctetString getSenderKID()
    +    {
    +        return senderKID;
    +    }
    +
    +    public ASN1OctetString getRecipKID()
    +    {
    +        return recipKID;
    +    }
    +
    +    public ASN1OctetString getTransactionID()
    +    {
    +        return transactionID;
    +    }
    +
    +    public ASN1OctetString getSenderNonce()
    +    {
    +        return senderNonce;
    +    }
    +
    +    public ASN1OctetString getRecipNonce()
    +    {
    +        return recipNonce;
    +    }
    +
    +    public PKIFreeText getFreeText()
    +    {
    +        return freeText;
    +    }
    +
    +    public InfoTypeAndValue[] getGeneralInfo()
    +    {
    +        if (generalInfo == null)
    +        {
    +            return null;
    +        }
    +        InfoTypeAndValue[] results = new InfoTypeAndValue[generalInfo.size()];
    +        for (int i = 0; i < results.length; i++)
    +        {
    +            results[i]
    +                = InfoTypeAndValue.getInstance(generalInfo.getObjectAt(i));
    +        }
    +        return results;
    +    }
    +
    +    /**
    +     * <pre>
    +     *  PKIHeader ::= SEQUENCE {
    +     *            pvno                INTEGER     { cmp1999(1), cmp2000(2) },
    +     *            sender              GeneralName,
    +     *            -- identifies the sender
    +     *            recipient           GeneralName,
    +     *            -- identifies the intended recipient
    +     *            messageTime     [0] GeneralizedTime         OPTIONAL,
    +     *            -- time of production of this message (used when sender
    +     *            -- believes that the transport will be "suitable"; i.e.,
    +     *            -- that the time will still be meaningful upon receipt)
    +     *            protectionAlg   [1] AlgorithmIdentifier     OPTIONAL,
    +     *            -- algorithm used for calculation of protection bits
    +     *            senderKID       [2] KeyIdentifier           OPTIONAL,
    +     *            recipKID        [3] KeyIdentifier           OPTIONAL,
    +     *            -- to identify specific keys used for protection
    +     *            transactionID   [4] OCTET STRING            OPTIONAL,
    +     *            -- identifies the transaction; i.e., this will be the same in
    +     *            -- corresponding request, response, certConf, and PKIConf
    +     *            -- messages
    +     *            senderNonce     [5] OCTET STRING            OPTIONAL,
    +     *            recipNonce      [6] OCTET STRING            OPTIONAL,
    +     *            -- nonces used to provide replay protection, senderNonce
    +     *            -- is inserted by the creator of this message; recipNonce
    +     *            -- is a nonce previously inserted in a related message by
    +     *            -- the intended recipient of this message
    +     *            freeText        [7] PKIFreeText             OPTIONAL,
    +     *            -- this may be used to indicate context-specific instructions
    +     *            -- (this field is intended for human consumption)
    +     *            generalInfo     [8] SEQUENCE SIZE (1..MAX) OF
    +     *                                 InfoTypeAndValue     OPTIONAL
    +     *            -- this may be used to convey context-specific information
    +     *            -- (this field not primarily intended for human consumption)
    +     * }
    +     * </pre>
    +     *
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(pvno);
    +        v.add(sender);
    +        v.add(recipient);
    +        addOptional(v, 0, messageTime);
    +        addOptional(v, 1, protectionAlg);
    +        addOptional(v, 2, senderKID);
    +        addOptional(v, 3, recipKID);
    +        addOptional(v, 4, transactionID);
    +        addOptional(v, 5, senderNonce);
    +        addOptional(v, 6, recipNonce);
    +        addOptional(v, 7, freeText);
    +        addOptional(v, 8, generalInfo);
    +
    +        return new DERSequence(v);
    +    }
    +
    +    private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj)
    +    {
    +        if (obj != null)
    +        {
    +            v.add(new DERTaggedObject(true, tagNo, obj));
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/PKIMessage.java+166 0 added
    @@ -0,0 +1,166 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import java.util.Enumeration;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERBitString;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +
    +public class PKIMessage
    +    extends ASN1Object
    +{
    +    private PKIHeader header;
    +    private PKIBody body;
    +    private DERBitString protection;
    +    private ASN1Sequence extraCerts;
    +
    +    private PKIMessage(ASN1Sequence seq)
    +    {
    +        Enumeration en = seq.getObjects();
    +
    +        header = PKIHeader.getInstance(en.nextElement());
    +        body = PKIBody.getInstance(en.nextElement());
    +
    +        while (en.hasMoreElements())
    +        {
    +            ASN1TaggedObject tObj = (ASN1TaggedObject)en.nextElement();
    +
    +            if (tObj.getTagNo() == 0)
    +            {
    +                protection = DERBitString.getInstance(tObj, true);
    +            }
    +            else
    +            {
    +                extraCerts = ASN1Sequence.getInstance(tObj, true);
    +            }
    +        }
    +    }
    +
    +    public static PKIMessage getInstance(Object o)
    +    {
    +        if (o instanceof PKIMessage)
    +        {
    +            return (PKIMessage)o;
    +        }
    +        else if (o != null)
    +        {
    +            return new PKIMessage(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    /**
    +     * Creates a new PKIMessage.
    +     *
    +     * @param header     message header
    +     * @param body       message body
    +     * @param protection message protection (may be null)
    +     * @param extraCerts extra certificates (may be null)
    +     */
    +    public PKIMessage(
    +        PKIHeader header,
    +        PKIBody body,
    +        DERBitString protection,
    +        CMPCertificate[] extraCerts)
    +    {
    +        this.header = header;
    +        this.body = body;
    +        this.protection = protection;
    +        if (extraCerts != null)
    +        {
    +            ASN1EncodableVector v = new ASN1EncodableVector();
    +            for (int i = 0; i < extraCerts.length; i++)
    +            {
    +                v.add(extraCerts[i]);
    +            }
    +            this.extraCerts = new DERSequence(v);
    +        }
    +    }
    +
    +    public PKIMessage(
    +        PKIHeader header,
    +        PKIBody body,
    +        DERBitString protection)
    +    {
    +        this(header, body, protection, null);
    +    }
    +
    +    public PKIMessage(
    +        PKIHeader header,
    +        PKIBody body)
    +    {
    +        this(header, body, null, null);
    +    }
    +
    +    public PKIHeader getHeader()
    +    {
    +        return header;
    +    }
    +
    +    public PKIBody getBody()
    +    {
    +        return body;
    +    }
    +
    +    public DERBitString getProtection()
    +    {
    +        return protection;
    +    }
    +
    +    public CMPCertificate[] getExtraCerts()
    +    {
    +        if (extraCerts == null)
    +        {
    +            return null;
    +        }
    +
    +        CMPCertificate[] results = new CMPCertificate[extraCerts.size()];
    +
    +        for (int i = 0; i < results.length; i++)
    +        {
    +            results[i] = CMPCertificate.getInstance(extraCerts.getObjectAt(i));
    +        }
    +        return results;
    +    }
    +
    +    /**
    +     * <pre>
    +     * PKIMessage ::= SEQUENCE {
    +     *                  header           PKIHeader,
    +     *                  body             PKIBody,
    +     *                  protection   [0] PKIProtection OPTIONAL,
    +     *                  extraCerts   [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
    +     *                                                                     OPTIONAL
    +     * }
    +     * </pre>
    +     *
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(header);
    +        v.add(body);
    +
    +        addOptional(v, 0, protection);
    +        addOptional(v, 1, extraCerts);
    +
    +        return new DERSequence(v);
    +    }
    +
    +    private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj)
    +    {
    +        if (obj != null)
    +        {
    +            v.add(new DERTaggedObject(true, tagNo, obj));
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/PKIMessages.java+71 0 added
    @@ -0,0 +1,71 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +public class PKIMessages
    +    extends ASN1Object
    +{
    +    private ASN1Sequence content;
    +
    +    private PKIMessages(ASN1Sequence seq)
    +    {
    +        content = seq;
    +    }
    +
    +    public static PKIMessages getInstance(Object o)
    +    {
    +        if (o instanceof PKIMessages)
    +        {
    +            return (PKIMessages)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new PKIMessages(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public PKIMessages(PKIMessage msg)
    +    {
    +        content = new DERSequence(msg);
    +    }
    +
    +    public PKIMessages(PKIMessage[] msgs)
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +        for (int i = 0; i < msgs.length; i++)
    +        {
    +            v.add(msgs[i]);
    +        }
    +        content = new DERSequence(v);
    +    }
    +
    +    public PKIMessage[] toPKIMessageArray()
    +    {
    +        PKIMessage[] result = new PKIMessage[content.size()];
    +
    +        for (int i = 0; i != result.length; i++)
    +        {
    +            result[i] = PKIMessage.getInstance(content.getObjectAt(i));
    +        }
    +
    +        return result;
    +    }
    +
    +    /**
    +     * <pre>
    +     * PKIMessages ::= SEQUENCE SIZE (1..MAX) OF PKIMessage
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        return content;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/PKIStatusInfo.java+165 0 added
    @@ -0,0 +1,165 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import java.math.BigInteger;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERBitString;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +public class PKIStatusInfo
    +    extends ASN1Object
    +{
    +    ASN1Integer      status;
    +    PKIFreeText     statusString;
    +    DERBitString    failInfo;
    +
    +    public static PKIStatusInfo getInstance(
    +        ASN1TaggedObject obj,
    +        boolean explicit)
    +    {
    +        return getInstance(ASN1Sequence.getInstance(obj, explicit));
    +    }
    +
    +    public static PKIStatusInfo getInstance(
    +        Object obj)
    +    {
    +        if (obj instanceof PKIStatusInfo)
    +        {
    +            return (PKIStatusInfo)obj;
    +        }
    +        else if (obj != null)
    +        {
    +            return new PKIStatusInfo(ASN1Sequence.getInstance(obj));
    +        }
    +
    +        return null;
    +    }
    +
    +    private PKIStatusInfo(
    +        ASN1Sequence seq)
    +    {
    +        this.status = ASN1Integer.getInstance(seq.getObjectAt(0));
    +
    +        this.statusString = null;
    +        this.failInfo = null;
    +
    +        if (seq.size() > 2)
    +        {
    +            this.statusString = PKIFreeText.getInstance(seq.getObjectAt(1));
    +            this.failInfo = DERBitString.getInstance(seq.getObjectAt(2));
    +        }
    +        else if (seq.size() > 1)
    +        {
    +            Object obj = seq.getObjectAt(1); 
    +            if (obj instanceof DERBitString)
    +            {
    +                this.failInfo = DERBitString.getInstance(obj);
    +            }
    +            else
    +            {
    +                this.statusString = PKIFreeText.getInstance(obj);
    +            }
    +        }
    +    }
    +
    +    /**
    +     * @param status
    +     */
    +    public PKIStatusInfo(PKIStatus status)
    +    {
    +        this.status = ASN1Integer.getInstance(status.toASN1Primitive());
    +    }
    +
    +    /**
    +     *
    +     * @param status
    +     * @param statusString
    +     */
    +    public PKIStatusInfo(
    +        PKIStatus   status,
    +        PKIFreeText statusString)
    +    {
    +        this.status = ASN1Integer.getInstance(status.toASN1Primitive());
    +        this.statusString = statusString;
    +    }
    +
    +    public PKIStatusInfo(
    +        PKIStatus      status,
    +        PKIFreeText    statusString,
    +        PKIFailureInfo failInfo)
    +    {
    +        this.status = ASN1Integer.getInstance(status.toASN1Primitive());
    +        this.statusString = statusString;
    +        this.failInfo = failInfo;
    +    }
    +    
    +    public BigInteger getStatus()
    +    {
    +        return status.getValue();
    +    }
    +
    +    public PKIFreeText getStatusString()
    +    {
    +        return statusString;
    +    }
    +
    +    public DERBitString getFailInfo()
    +    {
    +        return failInfo;
    +    }
    +
    +    /**
    +     * <pre>
    +     * PKIStatusInfo ::= SEQUENCE {
    +     *     status        PKIStatus,                (INTEGER)
    +     *     statusString  PKIFreeText     OPTIONAL,
    +     *     failInfo      PKIFailureInfo  OPTIONAL  (BIT STRING)
    +     * }
    +     *
    +     * PKIStatus:
    +     *   granted                (0), -- you got exactly what you asked for
    +     *   grantedWithMods        (1), -- you got something like what you asked for
    +     *   rejection              (2), -- you don't get it, more information elsewhere in the message
    +     *   waiting                (3), -- the request body part has not yet been processed, expect to hear more later
    +     *   revocationWarning      (4), -- this message contains a warning that a revocation is imminent
    +     *   revocationNotification (5), -- notification that a revocation has occurred
    +     *   keyUpdateWarning       (6)  -- update already done for the oldCertId specified in CertReqMsg
    +     *
    +     * PKIFailureInfo:
    +     *   badAlg           (0), -- unrecognized or unsupported Algorithm Identifier
    +     *   badMessageCheck  (1), -- integrity check failed (e.g., signature did not verify)
    +     *   badRequest       (2), -- transaction not permitted or supported
    +     *   badTime          (3), -- messageTime was not sufficiently close to the system time, as defined by local policy
    +     *   badCertId        (4), -- no certificate could be found matching the provided criteria
    +     *   badDataFormat    (5), -- the data submitted has the wrong format
    +     *   wrongAuthority   (6), -- the authority indicated in the request is different from the one creating the response token
    +     *   incorrectData    (7), -- the requester's data is incorrect (for notary services)
    +     *   missingTimeStamp (8), -- when the timestamp is missing but should be there (by policy)
    +     *   badPOP           (9)  -- the proof-of-possession failed
    +     *
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector  v = new ASN1EncodableVector();
    +
    +        v.add(status);
    +
    +        if (statusString != null)
    +        {
    +            v.add(statusString);
    +        }
    +
    +        if (failInfo!= null)
    +        {
    +            v.add(failInfo);
    +        }
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/PKIStatus.java+64 0 added
    @@ -0,0 +1,64 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import java.math.BigInteger;
    +
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +
    +public class PKIStatus
    +    extends ASN1Object
    +{
    +    public static final int GRANTED                 = 0;
    +    public static final int GRANTED_WITH_MODS       = 1;
    +    public static final int REJECTION               = 2;
    +    public static final int WAITING                 = 3;
    +    public static final int REVOCATION_WARNING      = 4;
    +    public static final int REVOCATION_NOTIFICATION = 5;
    +    public static final int KEY_UPDATE_WARNING      = 6;
    +
    +    public static final PKIStatus granted = new PKIStatus(GRANTED);
    +    public static final PKIStatus grantedWithMods = new PKIStatus(GRANTED_WITH_MODS);
    +    public static final PKIStatus rejection = new PKIStatus(REJECTION);
    +    public static final PKIStatus waiting = new PKIStatus(WAITING);
    +    public static final PKIStatus revocationWarning = new PKIStatus(REVOCATION_WARNING);
    +    public static final PKIStatus revocationNotification = new PKIStatus(REVOCATION_NOTIFICATION);
    +    public static final PKIStatus keyUpdateWaiting = new PKIStatus(KEY_UPDATE_WARNING);
    +
    +    private ASN1Integer value;
    +
    +    private PKIStatus(int value)
    +    {
    +        this(new ASN1Integer(value));
    +    }
    +
    +    private PKIStatus(ASN1Integer value)
    +    {
    +        this.value = value;
    +    }
    +
    +    public static PKIStatus getInstance(Object o)
    +    {
    +        if (o instanceof PKIStatus)
    +        {
    +            return (PKIStatus)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new PKIStatus(ASN1Integer.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public BigInteger getValue()
    +    {
    +        return value.getValue();
    +    }
    +    
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        return value;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/PollRepContent.java+119 0 added
    @@ -0,0 +1,119 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +public class PollRepContent
    +    extends ASN1Object
    +{
    +    private ASN1Integer[] certReqId;
    +    private ASN1Integer[] checkAfter;
    +    private PKIFreeText[] reason;
    +
    +    private PollRepContent(ASN1Sequence seq)
    +    {
    +        certReqId = new ASN1Integer[seq.size()];
    +        checkAfter = new ASN1Integer[seq.size()];
    +        reason = new PKIFreeText[seq.size()];
    +
    +        for (int i = 0; i != seq.size(); i++)
    +        {
    +            ASN1Sequence s = ASN1Sequence.getInstance(seq.getObjectAt(i));
    +
    +            certReqId[i] = ASN1Integer.getInstance(s.getObjectAt(0));
    +            checkAfter[i] = ASN1Integer.getInstance(s.getObjectAt(1));
    +
    +            if (s.size() > 2)
    +            {
    +                reason[i] = PKIFreeText.getInstance(s.getObjectAt(2));
    +            }
    +        }
    +    }
    +
    +    public static PollRepContent getInstance(Object o)
    +    {
    +        if (o instanceof PollRepContent)
    +        {
    +            return (PollRepContent)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new PollRepContent(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public PollRepContent(ASN1Integer certReqId, ASN1Integer checkAfter)
    +    {
    +        this(certReqId, checkAfter, null);
    +    }
    +
    +    public PollRepContent(ASN1Integer certReqId, ASN1Integer checkAfter, PKIFreeText reason)
    +    {
    +        this.certReqId = new ASN1Integer[1];
    +        this.checkAfter = new ASN1Integer[1];
    +        this.reason = new PKIFreeText[1];
    +
    +        this.certReqId[0] = certReqId;
    +        this.checkAfter[0] = checkAfter;
    +        this.reason[0] = reason;
    +    }
    +
    +    public int size()
    +    {
    +        return certReqId.length;
    +    }
    +
    +    public ASN1Integer getCertReqId(int index)
    +    {
    +        return certReqId[index];
    +    }
    +
    +    public ASN1Integer getCheckAfter(int index)
    +    {
    +        return checkAfter[index];
    +    }
    +
    +    public PKIFreeText getReason(int index)
    +    {
    +        return reason[index];
    +    }
    +
    +    /**
    +     * <pre>
    +     * PollRepContent ::= SEQUENCE OF SEQUENCE {
    +     *         certReqId              INTEGER,
    +     *         checkAfter             INTEGER,  -- time in seconds
    +     *         reason                 PKIFreeText OPTIONAL
    +     *     }
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector outer = new ASN1EncodableVector();
    +
    +        for (int i = 0; i != certReqId.length; i++)
    +        {
    +            ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +            v.add(certReqId[i]);
    +            v.add(checkAfter[i]);
    +
    +            if (reason[i] != null)
    +            {
    +                v.add(reason[i]);
    +            }
    +
    +            outer.add(new DERSequence(v));
    +        }
    +        
    +        return new DERSequence(outer);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/PollReqContent.java+80 0 added
    @@ -0,0 +1,80 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +public class PollReqContent
    +    extends ASN1Object
    +{
    +    private ASN1Sequence content;
    +
    +    private PollReqContent(ASN1Sequence seq)
    +    {
    +        content = seq;
    +    }
    +
    +    public static PollReqContent getInstance(Object o)
    +    {
    +        if (o instanceof PollReqContent)
    +        {
    +            return (PollReqContent)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new PollReqContent(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    /**
    +     * Create a pollReqContent for a single certReqId.
    +     *
    +     * @param certReqId the certificate request ID.
    +     */
    +    public PollReqContent(ASN1Integer certReqId)
    +    {
    +        this(new DERSequence(new DERSequence(certReqId)));
    +    }
    +
    +    public ASN1Integer[][] getCertReqIds()
    +    {
    +        ASN1Integer[][] result = new ASN1Integer[content.size()][];
    +
    +        for (int i = 0; i != result.length; i++)
    +        {
    +            result[i] = sequenceToASN1IntegerArray((ASN1Sequence)content.getObjectAt(i));
    +        }
    +
    +        return result;
    +    }
    +
    +    private static ASN1Integer[] sequenceToASN1IntegerArray(ASN1Sequence seq)
    +    {
    +         ASN1Integer[] result = new ASN1Integer[seq.size()];
    +
    +        for (int i = 0; i != result.length; i++)
    +        {
    +            result[i] = ASN1Integer.getInstance(seq.getObjectAt(i));
    +        }
    +
    +        return result;
    +    }
    +
    +    /**
    +     * <pre>
    +     * PollReqContent ::= SEQUENCE OF SEQUENCE {
    +     *                        certReqId              INTEGER
    +     * }
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        return content;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/POPODecKeyChallContent.java+54 0 added
    @@ -0,0 +1,54 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +
    +public class POPODecKeyChallContent
    +    extends ASN1Object
    +{
    +    private ASN1Sequence content;
    +
    +    private POPODecKeyChallContent(ASN1Sequence seq)
    +    {
    +        content = seq;
    +    }
    +
    +    public static POPODecKeyChallContent getInstance(Object o)
    +    {
    +        if (o instanceof POPODecKeyChallContent)
    +        {
    +            return (POPODecKeyChallContent)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new POPODecKeyChallContent(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public Challenge[] toChallengeArray()
    +    {
    +        Challenge[] result = new Challenge[content.size()];
    +
    +        for (int i = 0; i != result.length; i++)
    +        {
    +            result[i] = Challenge.getInstance(content.getObjectAt(i));
    +        }
    +
    +        return result;
    +    }
    +
    +    /**
    +     * <pre>
    +     * POPODecKeyChallContent ::= SEQUENCE OF Challenge
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        return content;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/POPODecKeyRespContent.java+55 0 added
    @@ -0,0 +1,55 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +
    +public class POPODecKeyRespContent
    +    extends ASN1Object
    +{
    +    private ASN1Sequence content;
    +
    +    private POPODecKeyRespContent(ASN1Sequence seq)
    +    {
    +        content = seq;
    +    }
    +
    +    public static POPODecKeyRespContent getInstance(Object o)
    +    {
    +        if (o instanceof POPODecKeyRespContent)
    +        {
    +            return (POPODecKeyRespContent)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new POPODecKeyRespContent(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public ASN1Integer[] toASN1IntegerArray()
    +    {
    +        ASN1Integer[] result = new ASN1Integer[content.size()];
    +
    +        for (int i = 0; i != result.length; i++)
    +        {
    +            result[i] = ASN1Integer.getInstance(content.getObjectAt(i));
    +        }
    +
    +        return result;
    +    }
    +
    +    /**
    +     * <pre>
    +     * POPODecKeyRespContent ::= SEQUENCE OF INTEGER
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        return content;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/ProtectedPart.java+70 0 added
    @@ -0,0 +1,70 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +public class ProtectedPart
    +    extends ASN1Object
    +{
    +    private PKIHeader header;
    +    private PKIBody body;
    +
    +    private ProtectedPart(ASN1Sequence seq)
    +    {
    +        header = PKIHeader.getInstance(seq.getObjectAt(0));
    +        body = PKIBody.getInstance(seq.getObjectAt(1));
    +    }
    +
    +    public static ProtectedPart getInstance(Object o)
    +    {
    +        if (o instanceof ProtectedPart)
    +        {
    +            return (ProtectedPart)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new ProtectedPart(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public ProtectedPart(PKIHeader header, PKIBody body)
    +    {
    +        this.header = header;
    +        this.body = body;
    +    }
    +
    +    public PKIHeader getHeader()
    +    {
    +        return header;
    +    }
    +
    +    public PKIBody getBody()
    +    {
    +        return body;
    +    }
    +
    +    /**
    +     * <pre>
    +     * ProtectedPart ::= SEQUENCE {
    +     *                    header    PKIHeader,
    +     *                    body      PKIBody
    +     * }
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(header);
    +        v.add(body);
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/RevAnnContent.java+103 0 added
    @@ -0,0 +1,103 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1GeneralizedTime;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.crmf.CertId;
    +import org.bouncycastle.asn1.x509.Extensions;
    +
    +public class RevAnnContent
    +    extends ASN1Object
    +{
    +    private PKIStatus status;
    +    private CertId certId;
    +    private ASN1GeneralizedTime willBeRevokedAt;
    +    private ASN1GeneralizedTime badSinceDate;
    +    private Extensions crlDetails;
    +    
    +    private RevAnnContent(ASN1Sequence seq)
    +    {
    +        status = PKIStatus.getInstance(seq.getObjectAt(0));
    +        certId = CertId.getInstance(seq.getObjectAt(1));
    +        willBeRevokedAt = ASN1GeneralizedTime.getInstance(seq.getObjectAt(2));
    +        badSinceDate = ASN1GeneralizedTime.getInstance(seq.getObjectAt(3));
    +
    +        if (seq.size() > 4)
    +        {
    +            crlDetails = Extensions.getInstance(seq.getObjectAt(4));
    +        }
    +    }
    +
    +    public static RevAnnContent getInstance(Object o)
    +    {
    +        if (o instanceof RevAnnContent)
    +        {
    +            return (RevAnnContent)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new RevAnnContent(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public PKIStatus getStatus()
    +    {
    +        return status;
    +    }
    +
    +    public CertId getCertId()
    +    {
    +        return certId;
    +    }
    +
    +    public ASN1GeneralizedTime getWillBeRevokedAt()
    +    {
    +        return willBeRevokedAt;
    +    }
    +
    +    public ASN1GeneralizedTime getBadSinceDate()
    +    {
    +        return badSinceDate;
    +    }
    +
    +    public Extensions getCrlDetails()
    +    {
    +        return crlDetails;
    +    }
    +
    +    /**
    +     * <pre>
    +     * RevAnnContent ::= SEQUENCE {
    +     *       status              PKIStatus,
    +     *       certId              CertId,
    +     *       willBeRevokedAt     GeneralizedTime,
    +     *       badSinceDate        GeneralizedTime,
    +     *       crlDetails          Extensions  OPTIONAL
    +     *        -- extra CRL details (e.g., crl number, reason, location, etc.)
    +     * }
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(status);
    +        v.add(certId);
    +        v.add(willBeRevokedAt);
    +        v.add(badSinceDate);
    +
    +        if (crlDetails != null)
    +        {
    +            v.add(crlDetails);
    +        }
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/RevDetails.java+100 0 added
    @@ -0,0 +1,100 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.crmf.CertTemplate;
    +import org.bouncycastle.asn1.x509.Extensions;
    +import org.bouncycastle.asn1.x509.X509Extensions;
    +
    +public class RevDetails
    +    extends ASN1Object
    +{
    +    private CertTemplate certDetails;
    +    private Extensions crlEntryDetails;
    +
    +    private RevDetails(ASN1Sequence seq)
    +    {
    +        certDetails = CertTemplate.getInstance(seq.getObjectAt(0));
    +        if  (seq.size() > 1)
    +        {
    +            crlEntryDetails = Extensions.getInstance(seq.getObjectAt(1));
    +        }
    +    }
    +
    +    public static RevDetails getInstance(Object o)
    +    {
    +        if (o instanceof RevDetails)
    +        {
    +            return (RevDetails)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new RevDetails(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public RevDetails(CertTemplate certDetails)
    +    {
    +        this.certDetails = certDetails;
    +    }
    +
    +    /**
    +     * @deprecated use method taking Extensions
    +     * @param certDetails
    +     * @param crlEntryDetails
    +     */
    +    public RevDetails(CertTemplate certDetails, X509Extensions crlEntryDetails)
    +    {
    +        this.certDetails = certDetails;
    +        this.crlEntryDetails = Extensions.getInstance(crlEntryDetails.toASN1Primitive());
    +    }
    +
    +    public RevDetails(CertTemplate certDetails, Extensions crlEntryDetails)
    +    {
    +        this.certDetails = certDetails;
    +        this.crlEntryDetails = crlEntryDetails;
    +    }
    +
    +    public CertTemplate getCertDetails()
    +    {
    +        return certDetails;
    +    }
    +
    +    public Extensions getCrlEntryDetails()
    +    {
    +        return crlEntryDetails;
    +    }
    +
    +    /**
    +     * <pre>
    +     * RevDetails ::= SEQUENCE {
    +     *                  certDetails         CertTemplate,
    +     *                   -- allows requester to specify as much as they can about
    +     *                   -- the cert. for which revocation is requested
    +     *                   -- (e.g., for cases in which serialNumber is not available)
    +     *                   crlEntryDetails     Extensions       OPTIONAL
    +     *                   -- requested crlEntryExtensions
    +     *             }
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(certDetails);
    +
    +        if (crlEntryDetails != null)
    +        {
    +            v.add(crlEntryDetails);
    +        }
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/RevRepContentBuilder.java+59 0 added
    @@ -0,0 +1,59 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +import org.bouncycastle.asn1.crmf.CertId;
    +import org.bouncycastle.asn1.x509.CertificateList;
    +
    +public class RevRepContentBuilder
    +{
    +    private ASN1EncodableVector status = new ASN1EncodableVector();
    +    private ASN1EncodableVector revCerts = new ASN1EncodableVector();
    +    private ASN1EncodableVector crls = new ASN1EncodableVector();
    +
    +    public RevRepContentBuilder add(PKIStatusInfo status)
    +    {
    +        this.status.add(status);
    +
    +        return this;
    +    }
    +
    +    public RevRepContentBuilder add(PKIStatusInfo status, CertId certId)
    +    {
    +        if (this.status.size() != this.revCerts.size())
    +        {
    +            throw new IllegalStateException("status and revCerts sequence must be in common order");
    +        }
    +        this.status.add(status);
    +        this.revCerts.add(certId);
    +
    +        return this;
    +    }
    +
    +    public RevRepContentBuilder addCrl(CertificateList crl)
    +    {
    +        this.crls.add(crl);
    +
    +        return this;
    +    }
    +
    +    public RevRepContent build()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(new DERSequence(status));
    +
    +        if (revCerts.size() != 0)
    +        {
    +            v.add(new DERTaggedObject(true, 0, new DERSequence(revCerts)));
    +        }
    +
    +        if (crls.size() != 0)
    +        {
    +            v.add(new DERTaggedObject(true, 1, new DERSequence(crls)));
    +        }
    +
    +        return RevRepContent.getInstance(new DERSequence(v));
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/RevRepContent.java+137 0 added
    @@ -0,0 +1,137 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import java.util.Enumeration;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +import org.bouncycastle.asn1.crmf.CertId;
    +import org.bouncycastle.asn1.x509.CertificateList;
    +
    +public class RevRepContent
    +    extends ASN1Object
    +{
    +    private ASN1Sequence status;
    +    private ASN1Sequence revCerts;
    +    private ASN1Sequence crls;
    +
    +    private RevRepContent(ASN1Sequence seq)
    +    {
    +        Enumeration en = seq.getObjects();
    +
    +        status = ASN1Sequence.getInstance(en.nextElement());
    +        while (en.hasMoreElements())
    +        {
    +            ASN1TaggedObject tObj = ASN1TaggedObject.getInstance(en.nextElement());
    +
    +            if (tObj.getTagNo() == 0)
    +            {
    +                revCerts = ASN1Sequence.getInstance(tObj, true);
    +            }
    +            else
    +            {
    +                crls = ASN1Sequence.getInstance(tObj, true);
    +            }
    +        }
    +    }
    +
    +    public static RevRepContent getInstance(Object o)
    +    {
    +        if (o instanceof RevRepContent)
    +        {
    +            return (RevRepContent)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new RevRepContent(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public PKIStatusInfo[] getStatus()
    +    {
    +        PKIStatusInfo[] results = new PKIStatusInfo[status.size()];
    +
    +        for (int i = 0; i != results.length; i++)
    +        {
    +            results[i] = PKIStatusInfo.getInstance(status.getObjectAt(i));
    +        }
    +
    +        return results;
    +    }
    +
    +    public CertId[] getRevCerts()
    +    {
    +        if (revCerts == null)
    +        {
    +            return null;
    +        }
    +
    +        CertId[] results = new CertId[revCerts.size()];
    +
    +        for (int i = 0; i != results.length; i++)
    +        {
    +            results[i] = CertId.getInstance(revCerts.getObjectAt(i));
    +        }
    +
    +        return results;
    +    }
    +
    +    public CertificateList[] getCrls()
    +    {
    +        if (crls == null)
    +        {
    +            return null;
    +        }
    +
    +        CertificateList[] results = new CertificateList[crls.size()];
    +
    +        for (int i = 0; i != results.length; i++)
    +        {
    +            results[i] = CertificateList.getInstance(crls.getObjectAt(i));
    +        }
    +
    +        return results;
    +    }
    +
    +    /**
    +     * <pre>
    +     * RevRepContent ::= SEQUENCE {
    +     *        status       SEQUENCE SIZE (1..MAX) OF PKIStatusInfo,
    +     *        -- in same order as was sent in RevReqContent
    +     *        revCerts [0] SEQUENCE SIZE (1..MAX) OF CertId OPTIONAL,
    +     *        -- IDs for which revocation was requested
    +     *        -- (same order as status)
    +     *        crls     [1] SEQUENCE SIZE (1..MAX) OF CertificateList OPTIONAL
    +     *        -- the resulting CRLs (there may be more than one)
    +     *   }
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(status);
    +
    +        addOptional(v, 0, revCerts);
    +        addOptional(v, 1, crls);
    +
    +        return new DERSequence(v);
    +    }
    +
    +    private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj)
    +    {
    +        if (obj != null)
    +        {
    +            v.add(new DERTaggedObject(true, tagNo, obj));
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cmp/RevReqContent.java+73 0 added
    @@ -0,0 +1,73 @@
    +package org.bouncycastle.asn1.cmp;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +public class RevReqContent
    +    extends ASN1Object
    +{
    +    private ASN1Sequence content;
    +
    +    private RevReqContent(ASN1Sequence seq)
    +    {
    +        content = seq;
    +    }
    +
    +    public static RevReqContent getInstance(Object o)
    +    {
    +        if (o instanceof RevReqContent)
    +        {
    +            return (RevReqContent)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new RevReqContent(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public RevReqContent(RevDetails revDetails)
    +    {
    +        this.content = new DERSequence(revDetails);
    +    }
    +
    +    public RevReqContent(RevDetails[] revDetailsArray)
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        for (int i = 0; i != revDetailsArray.length; i++)
    +        {
    +            v.add(revDetailsArray[i]);
    +        }
    +
    +        this.content = new DERSequence(v);
    +    }
    +
    +    public RevDetails[] toRevDetailsArray()
    +    {
    +        RevDetails[] result = new RevDetails[content.size()];
    +
    +        for (int i = 0; i != result.length; i++)
    +        {
    +            result[i] = RevDetails.getInstance(content.getObjectAt(i));
    +        }
    +
    +        return result;
    +    }
    +
    +    /**
    +     * <pre>
    +     * RevReqContent ::= SEQUENCE OF RevDetails
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        return content;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/Attribute.java+100 0 added
    @@ -0,0 +1,100 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1ObjectIdentifier;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1Set;
    +import org.bouncycastle.asn1.DERObjectIdentifier;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +public class Attribute
    +    extends ASN1Object
    +{
    +    private ASN1ObjectIdentifier attrType;
    +    private ASN1Set             attrValues;
    +
    +    /**
    +     * return an Attribute object from the given object.
    +     *
    +     * @param o the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static Attribute getInstance(
    +        Object o)
    +    {
    +        if (o instanceof Attribute)
    +        {
    +            return (Attribute)o;
    +        }
    +        
    +        if (o != null)
    +        {
    +            return new Attribute(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +    
    +    private Attribute(
    +        ASN1Sequence seq)
    +    {
    +        attrType = (ASN1ObjectIdentifier)seq.getObjectAt(0);
    +        attrValues = (ASN1Set)seq.getObjectAt(1);
    +    }
    +
    +    /**
    +     * @deprecated use ASN1ObjectIdentifier
    +     */
    +    public Attribute(
    +        DERObjectIdentifier attrType,
    +        ASN1Set             attrValues)
    +    {
    +        this.attrType = new ASN1ObjectIdentifier(attrType.getId());
    +        this.attrValues = attrValues;
    +    }
    +
    +    public Attribute(
    +        ASN1ObjectIdentifier attrType,
    +        ASN1Set             attrValues)
    +    {
    +        this.attrType = attrType;
    +        this.attrValues = attrValues;
    +    }
    +
    +    public ASN1ObjectIdentifier getAttrType()
    +    {
    +        return attrType;
    +    }
    +    
    +    public ASN1Set getAttrValues()
    +    {
    +        return attrValues;
    +    }
    +
    +    public ASN1Encodable[] getAttributeValues()
    +    {
    +        return attrValues.toArray();
    +    }
    +
    +    /** 
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * Attribute ::= SEQUENCE {
    +     *     attrType OBJECT IDENTIFIER,
    +     *     attrValues SET OF AttributeValue
    +     * }
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(attrType);
    +        v.add(attrValues);
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/Attributes.java+61 0 added
    @@ -0,0 +1,61 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Set;
    +import org.bouncycastle.asn1.DLSet;
    +
    +public class Attributes
    +    extends ASN1Object
    +{
    +    private ASN1Set attributes;
    +
    +    private Attributes(ASN1Set set)
    +    {
    +        attributes = set;
    +    }
    +
    +    public Attributes(ASN1EncodableVector v)
    +    {
    +        attributes = new DLSet(v);
    +    }
    +
    +    public static Attributes getInstance(Object obj)
    +    {
    +        if (obj instanceof Attributes)
    +        {
    +            return (Attributes)obj;
    +        }
    +        else if (obj != null)
    +        {
    +            return new Attributes(ASN1Set.getInstance(obj));
    +        }
    +
    +        return null;
    +    }
    +
    +    public Attribute[] getAttributes()
    +    {
    +        Attribute[] rv = new Attribute[attributes.size()];
    +
    +        for (int i = 0; i != rv.length; i++)
    +        {
    +            rv[i] = Attribute.getInstance(attributes.getObjectAt(i));
    +        }
    +
    +        return rv;
    +    }
    +
    +    /**
    +     * <pre>
    +     * Attributes ::=
    +     *   SET SIZE(1..MAX) OF Attribute -- according to RFC 5652
    +     * </pre>
    +     * @return
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        return attributes;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/AttributeTable.java+254 0 added
    @@ -0,0 +1,254 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import java.util.Enumeration;
    +import java.util.Hashtable;
    +import java.util.Vector;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1ObjectIdentifier;
    +import org.bouncycastle.asn1.ASN1Set;
    +import org.bouncycastle.asn1.DERObjectIdentifier;
    +import org.bouncycastle.asn1.DERSet;
    +
    +public class AttributeTable
    +{
    +    private Hashtable attributes = new Hashtable();
    +
    +    public AttributeTable(
    +        Hashtable  attrs)
    +    {
    +        attributes = copyTable(attrs);
    +    }
    +
    +    public AttributeTable(
    +        ASN1EncodableVector v)
    +    {
    +        for (int i = 0; i != v.size(); i++)
    +        {
    +            Attribute   a = Attribute.getInstance(v.get(i));
    +
    +            addAttribute(a.getAttrType(), a);
    +        }
    +    }
    +
    +    public AttributeTable(
    +        ASN1Set    s)
    +    {
    +        for (int i = 0; i != s.size(); i++)
    +        {
    +            Attribute   a = Attribute.getInstance(s.getObjectAt(i));
    +
    +            addAttribute(a.getAttrType(), a);
    +        }
    +    }
    +
    +    public AttributeTable(
    +        Attribute    attr)
    +    {
    +        addAttribute(attr.getAttrType(), attr);
    +    }
    +
    +    public AttributeTable(
    +        Attributes    attrs)
    +    {
    +        this(ASN1Set.getInstance(attrs.toASN1Primitive()));
    +    }
    +
    +    private void addAttribute(
    +        ASN1ObjectIdentifier oid,
    +        Attribute           a)
    +    {
    +        Object value = attributes.get(oid);
    +        
    +        if (value == null)
    +        {
    +            attributes.put(oid, a);
    +        }
    +        else
    +        {
    +            Vector v;
    +            
    +            if (value instanceof Attribute)
    +            {
    +                v = new Vector();
    +                
    +                v.addElement(value);
    +                v.addElement(a);
    +            }
    +            else
    +            {
    +                v = (Vector)value;
    +            
    +                v.addElement(a);
    +            }
    +            
    +            attributes.put(oid, v);
    +        }
    +    }
    +
    +    /**
    +     * @deprecated use ASN1ObjectIdentifier
    +     */
    +    public Attribute get(DERObjectIdentifier oid)
    +    {
    +        return get(new ASN1ObjectIdentifier(oid.getId()));
    +    }
    +
    +    /**
    +     * Return the first attribute matching the OBJECT IDENTIFIER oid.
    +     * 
    +     * @param oid type of attribute required.
    +     * @return first attribute found of type oid.
    +     */
    +    public Attribute get(
    +        ASN1ObjectIdentifier oid)
    +    {
    +        Object value = attributes.get(oid);
    +        
    +        if (value instanceof Vector)
    +        {
    +            return (Attribute)((Vector)value).elementAt(0);
    +        }
    +        
    +        return (Attribute)value;
    +    }
    +
    +     /**
    +     * @deprecated use ASN1ObjectIdentifier
    +     */
    +    public ASN1EncodableVector getAll(DERObjectIdentifier oid)
    +    {
    +        return getAll(new ASN1ObjectIdentifier(oid.getId()));
    +    }
    +
    +    /**
    +     * Return all the attributes matching the OBJECT IDENTIFIER oid. The vector will be 
    +     * empty if there are no attributes of the required type present.
    +     * 
    +     * @param oid type of attribute required.
    +     * @return a vector of all the attributes found of type oid.
    +     */
    +    public ASN1EncodableVector getAll(
    +        ASN1ObjectIdentifier oid)
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +        
    +        Object value = attributes.get(oid);
    +        
    +        if (value instanceof Vector)
    +        {
    +            Enumeration e = ((Vector)value).elements();
    +            
    +            while (e.hasMoreElements())
    +            {
    +                v.add((Attribute)e.nextElement());
    +            }
    +        }
    +        else if (value != null)
    +        {
    +            v.add((Attribute)value);
    +        }
    +        
    +        return v;
    +    }
    +
    +    public int size()
    +    {
    +        int size = 0;
    +
    +        for (Enumeration en = attributes.elements(); en.hasMoreElements();)
    +        {
    +            Object o = en.nextElement();
    +
    +            if (o instanceof Vector)
    +            {
    +                size += ((Vector)o).size();
    +            }
    +            else
    +            {
    +                size++;
    +            }
    +        }
    +
    +        return size;
    +    }
    +
    +    public Hashtable toHashtable()
    +    {
    +        return copyTable(attributes);
    +    }
    +    
    +    public ASN1EncodableVector toASN1EncodableVector()
    +    {
    +        ASN1EncodableVector  v = new ASN1EncodableVector();
    +        Enumeration          e = attributes.elements();
    +        
    +        while (e.hasMoreElements())
    +        {
    +            Object value = e.nextElement();
    +            
    +            if (value instanceof Vector)
    +            {
    +                Enumeration en = ((Vector)value).elements();
    +                
    +                while (en.hasMoreElements())
    +                {
    +                    v.add(Attribute.getInstance(en.nextElement()));
    +                }
    +            }
    +            else
    +            {
    +                v.add(Attribute.getInstance(value));
    +            }
    +        }
    +        
    +        return v;
    +    }
    +
    +    public Attributes toASN1Structure()
    +    {
    +        return new Attributes(this.toASN1EncodableVector());
    +    }
    +
    +    private Hashtable copyTable(
    +        Hashtable in)
    +    {
    +        Hashtable   out = new Hashtable();
    +        Enumeration e = in.keys();
    +        
    +        while (e.hasMoreElements())
    +        {
    +            Object key = e.nextElement();
    +            
    +            out.put(key, in.get(key));
    +        }
    +        
    +        return out;
    +    }
    +
    +    /**
    +     * Return a new table with the passed in attribute added.
    +     *
    +     * @param attrType
    +     * @param attrValue
    +     * @return
    +     */
    +    public AttributeTable add(ASN1ObjectIdentifier attrType, ASN1Encodable attrValue)
    +    {
    +        AttributeTable newTable = new AttributeTable(attributes);
    +
    +        newTable.addAttribute(attrType, new Attribute(attrType, new DERSet(attrValue)));
    +
    +        return newTable;
    +    }
    +
    +    public AttributeTable remove(ASN1ObjectIdentifier attrType)
    +    {
    +        AttributeTable newTable = new AttributeTable(attributes);
    +
    +        newTable.attributes.remove(attrType);
    +
    +        return newTable;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/AuthenticatedData.java+296 0 added
    @@ -0,0 +1,296 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import java.util.Enumeration;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1Set;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.BERSequence;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
    +
    +public class AuthenticatedData
    +    extends ASN1Object
    +{
    +    private ASN1Integer version;
    +    private OriginatorInfo originatorInfo;
    +    private ASN1Set recipientInfos;
    +    private AlgorithmIdentifier macAlgorithm;
    +    private AlgorithmIdentifier digestAlgorithm;
    +    private ContentInfo encapsulatedContentInfo;
    +    private ASN1Set authAttrs;
    +    private ASN1OctetString mac;
    +    private ASN1Set unauthAttrs;
    +
    +    public AuthenticatedData(
    +        OriginatorInfo originatorInfo,
    +        ASN1Set recipientInfos,
    +        AlgorithmIdentifier macAlgorithm,
    +        AlgorithmIdentifier digestAlgorithm,
    +        ContentInfo encapsulatedContent,
    +        ASN1Set authAttrs,
    +        ASN1OctetString mac,
    +        ASN1Set unauthAttrs)
    +    {
    +        if (digestAlgorithm != null || authAttrs != null)
    +        {
    +            if (digestAlgorithm == null || authAttrs == null)
    +            {
    +                throw new IllegalArgumentException("digestAlgorithm and authAttrs must be set together");
    +            }
    +        }
    +
    +        version = new ASN1Integer(calculateVersion(originatorInfo));
    +        
    +        this.originatorInfo = originatorInfo;
    +        this.macAlgorithm = macAlgorithm;
    +        this.digestAlgorithm = digestAlgorithm;
    +        this.recipientInfos = recipientInfos;
    +        this.encapsulatedContentInfo = encapsulatedContent;
    +        this.authAttrs = authAttrs;
    +        this.mac = mac;
    +        this.unauthAttrs = unauthAttrs;
    +    }
    +
    +    public AuthenticatedData(
    +        ASN1Sequence seq)
    +    {
    +        int index = 0;
    +
    +        version = (ASN1Integer)seq.getObjectAt(index++);
    +
    +        Object tmp = seq.getObjectAt(index++);
    +
    +        if (tmp instanceof ASN1TaggedObject)
    +        {
    +            originatorInfo = OriginatorInfo.getInstance((ASN1TaggedObject)tmp, false);
    +            tmp = seq.getObjectAt(index++);
    +        }
    +
    +        recipientInfos = ASN1Set.getInstance(tmp);
    +        macAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(index++));
    +
    +        tmp = seq.getObjectAt(index++);
    +
    +        if (tmp instanceof ASN1TaggedObject)
    +        {
    +            digestAlgorithm = AlgorithmIdentifier.getInstance((ASN1TaggedObject)tmp, false);
    +            tmp = seq.getObjectAt(index++);
    +        }
    +
    +        encapsulatedContentInfo = ContentInfo.getInstance(tmp);
    +
    +        tmp = seq.getObjectAt(index++);
    +
    +        if (tmp instanceof ASN1TaggedObject)
    +        {
    +            authAttrs = ASN1Set.getInstance((ASN1TaggedObject)tmp, false);
    +            tmp = seq.getObjectAt(index++);
    +        }
    +
    +        mac = ASN1OctetString.getInstance(tmp);
    +        
    +        if (seq.size() > index)
    +        {
    +            unauthAttrs = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(index), false);
    +        }
    +    }
    +
    +    /**
    +     * return an AuthenticatedData object from a tagged object.
    +     *
    +     * @param obj      the tagged object holding the object we want.
    +     * @param explicit true if the object is meant to be explicitly
    +     *                 tagged false otherwise.
    +     * @throws IllegalArgumentException if the object held by the
    +     *                                  tagged object cannot be converted.
    +     */
    +    public static AuthenticatedData getInstance(
    +        ASN1TaggedObject obj,
    +        boolean explicit)
    +    {
    +        return getInstance(ASN1Sequence.getInstance(obj, explicit));
    +    }
    +
    +    /**
    +     * return an AuthenticatedData object from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @throws IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static AuthenticatedData getInstance(
    +        Object obj)
    +    {
    +        if (obj == null || obj instanceof AuthenticatedData)
    +        {
    +            return (AuthenticatedData)obj;
    +        }
    +
    +        if (obj instanceof ASN1Sequence)
    +        {
    +            return new AuthenticatedData((ASN1Sequence)obj);
    +        }
    +
    +        throw new IllegalArgumentException("Invalid AuthenticatedData: " + obj.getClass().getName());
    +    }
    +
    +    public ASN1Integer getVersion()
    +    {
    +        return version;
    +    }
    +
    +    public OriginatorInfo getOriginatorInfo()
    +    {
    +        return originatorInfo;
    +    }
    +
    +    public ASN1Set getRecipientInfos()
    +    {
    +        return recipientInfos;
    +    }
    +
    +    public AlgorithmIdentifier getMacAlgorithm()
    +    {
    +        return macAlgorithm;
    +    }
    +
    +    public AlgorithmIdentifier getDigestAlgorithm()
    +    {
    +        return digestAlgorithm;
    +    }
    +
    +    public ContentInfo getEncapsulatedContentInfo()
    +    {
    +        return encapsulatedContentInfo;
    +    }
    +
    +    public ASN1Set getAuthAttrs()
    +    {
    +        return authAttrs;
    +    }
    +
    +    public ASN1OctetString getMac()
    +    {
    +        return mac;
    +    }
    +
    +    public ASN1Set getUnauthAttrs()
    +    {
    +        return unauthAttrs;
    +    }
    +
    +    /**
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * AuthenticatedData ::= SEQUENCE {
    +     *       version CMSVersion,
    +     *       originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
    +     *       recipientInfos RecipientInfos,
    +     *       macAlgorithm MessageAuthenticationCodeAlgorithm,
    +     *       digestAlgorithm [1] DigestAlgorithmIdentifier OPTIONAL,
    +     *       encapContentInfo EncapsulatedContentInfo,
    +     *       authAttrs [2] IMPLICIT AuthAttributes OPTIONAL,
    +     *       mac MessageAuthenticationCode,
    +     *       unauthAttrs [3] IMPLICIT UnauthAttributes OPTIONAL }
    +     *
    +     * AuthAttributes ::= SET SIZE (1..MAX) OF Attribute
    +     *
    +     * UnauthAttributes ::= SET SIZE (1..MAX) OF Attribute
    +     *
    +     * MessageAuthenticationCode ::= OCTET STRING
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(version);
    +
    +        if (originatorInfo != null)
    +        {
    +            v.add(new DERTaggedObject(false, 0, originatorInfo));
    +        }
    +
    +        v.add(recipientInfos);
    +        v.add(macAlgorithm);
    +
    +        if (digestAlgorithm != null)
    +        {
    +            v.add(new DERTaggedObject(false, 1, digestAlgorithm));
    +        }
    +
    +        v.add(encapsulatedContentInfo);
    +
    +        if (authAttrs != null)
    +        {
    +            v.add(new DERTaggedObject(false, 2, authAttrs));
    +        }
    +
    +        v.add(mac);
    +
    +        if (unauthAttrs != null)
    +        {
    +            v.add(new DERTaggedObject(false, 3, unauthAttrs));
    +        }
    +
    +        return new BERSequence(v);
    +    }
    +
    +    public static int calculateVersion(OriginatorInfo origInfo)
    +    {
    +        if (origInfo == null)
    +        {
    +            return 0;
    +        }
    +        else
    +        {
    +            int ver = 0;
    +
    +            for (Enumeration e = origInfo.getCertificates().getObjects(); e.hasMoreElements();)
    +            {
    +                Object obj = e.nextElement();
    +
    +                if (obj instanceof ASN1TaggedObject)
    +                {
    +                    ASN1TaggedObject tag = (ASN1TaggedObject)obj;
    +
    +                    if (tag.getTagNo() == 2)
    +                    {
    +                        ver = 1;
    +                    }
    +                    else if (tag.getTagNo() == 3)
    +                    {
    +                        ver = 3;
    +                        break;
    +                    }
    +                }
    +            }
    +
    +            if (origInfo.getCRLs() != null)
    +            {
    +                for (Enumeration e = origInfo.getCRLs().getObjects(); e.hasMoreElements();)
    +                {
    +                    Object obj = e.nextElement();
    +
    +                    if (obj instanceof ASN1TaggedObject)
    +                    {
    +                        ASN1TaggedObject tag = (ASN1TaggedObject)obj;
    +
    +                        if (tag.getTagNo() == 1)
    +                        {
    +                            ver = 3;
    +                            break;
    +                        }
    +                    }
    +                }
    +            }
    +
    +            return ver;
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/AuthenticatedDataParser.java+197 0 added
    @@ -0,0 +1,197 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import java.io.IOException;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1SequenceParser;
    +import org.bouncycastle.asn1.ASN1SetParser;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.ASN1TaggedObjectParser;
    +import org.bouncycastle.asn1.BERTags;
    +import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
    +
    +/**
    + * Produce an object suitable for an ASN1OutputStream.
    + * <pre>
    + * AuthenticatedData ::= SEQUENCE {
    + *       version CMSVersion,
    + *       originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
    + *       recipientInfos RecipientInfos,
    + *       macAlgorithm MessageAuthenticationCodeAlgorithm,
    + *       digestAlgorithm [1] DigestAlgorithmIdentifier OPTIONAL,
    + *       encapContentInfo EncapsulatedContentInfo,
    + *       authAttrs [2] IMPLICIT AuthAttributes OPTIONAL,
    + *       mac MessageAuthenticationCode,
    + *       unauthAttrs [3] IMPLICIT UnauthAttributes OPTIONAL }
    + *
    + * AuthAttributes ::= SET SIZE (1..MAX) OF Attribute
    + *
    + * UnauthAttributes ::= SET SIZE (1..MAX) OF Attribute
    + *
    + * MessageAuthenticationCode ::= OCTET STRING
    + * </pre>
    + */
    +public class AuthenticatedDataParser
    +{
    +    private ASN1SequenceParser seq;
    +    private ASN1Integer version;
    +    private ASN1Encodable nextObject;
    +    private boolean originatorInfoCalled;
    +
    +    public AuthenticatedDataParser(
    +        ASN1SequenceParser seq)
    +        throws IOException
    +    {
    +        this.seq = seq;
    +        this.version = ASN1Integer.getInstance(seq.readObject());
    +    }
    +
    +    public ASN1Integer getVersion()
    +    {
    +        return version;
    +    }
    +
    +    public OriginatorInfo getOriginatorInfo()
    +        throws IOException
    +    {
    +        originatorInfoCalled = true;
    +
    +        if (nextObject == null)
    +        {
    +            nextObject = seq.readObject();
    +        }
    +
    +        if (nextObject instanceof ASN1TaggedObjectParser && ((ASN1TaggedObjectParser)nextObject).getTagNo() == 0)
    +        {
    +            ASN1SequenceParser originatorInfo = (ASN1SequenceParser) ((ASN1TaggedObjectParser)nextObject).getObjectParser(BERTags.SEQUENCE, false);
    +            nextObject = null;
    +            return OriginatorInfo.getInstance(originatorInfo.toASN1Primitive());
    +        }
    +
    +        return null;
    +    }
    +
    +    public ASN1SetParser getRecipientInfos()
    +        throws IOException
    +    {
    +        if (!originatorInfoCalled)
    +        {
    +            getOriginatorInfo();
    +        }
    +
    +        if (nextObject == null)
    +        {
    +            nextObject = seq.readObject();
    +        }
    +
    +        ASN1SetParser recipientInfos = (ASN1SetParser)nextObject;
    +        nextObject = null;
    +        return recipientInfos;
    +    }
    +
    +    public AlgorithmIdentifier getMacAlgorithm()
    +        throws IOException
    +    {
    +        if (nextObject == null)
    +        {
    +            nextObject = seq.readObject();
    +        }
    +
    +        if (nextObject != null)
    +        {
    +            ASN1SequenceParser o = (ASN1SequenceParser)nextObject;
    +            nextObject = null;
    +            return AlgorithmIdentifier.getInstance(o.toASN1Primitive());
    +        }
    +
    +        return null;
    +    }
    +
    +    public AlgorithmIdentifier getDigestAlgorithm()
    +        throws IOException
    +    {
    +        if (nextObject == null)
    +        {
    +            nextObject = seq.readObject();
    +        }
    +
    +        if (nextObject instanceof ASN1TaggedObjectParser)
    +        {
    +            AlgorithmIdentifier obj = AlgorithmIdentifier.getInstance((ASN1TaggedObject)nextObject.toASN1Primitive(), false);
    +            nextObject = null;
    +            return obj;
    +        }
    +
    +        return null;
    +    }
    +
    +    public ContentInfoParser getEnapsulatedContentInfo()
    +        throws IOException
    +    {
    +        if (nextObject == null)
    +        {
    +            nextObject = seq.readObject();
    +        }
    +
    +        if (nextObject != null)
    +        {
    +            ASN1SequenceParser o = (ASN1SequenceParser)nextObject;
    +            nextObject = null;
    +            return new ContentInfoParser(o);
    +        }
    +
    +        return null;
    +    }
    +
    +    public ASN1SetParser getAuthAttrs()
    +        throws IOException
    +    {
    +        if (nextObject == null)
    +        {
    +            nextObject = seq.readObject();
    +        }
    +
    +        if (nextObject instanceof ASN1TaggedObjectParser)
    +        {
    +            ASN1Encodable o = nextObject;
    +            nextObject = null;
    +            return (ASN1SetParser)((ASN1TaggedObjectParser)o).getObjectParser(BERTags.SET, false);
    +        }
    +
    +        return null;
    +    }
    +
    +    public ASN1OctetString getMac()
    +        throws IOException
    +    {
    +        if (nextObject == null)
    +        {
    +            nextObject = seq.readObject();
    +        }
    +
    +        ASN1Encodable o = nextObject;
    +        nextObject = null;
    +
    +        return ASN1OctetString.getInstance(o.toASN1Primitive());
    +    }
    +
    +    public ASN1SetParser getUnauthAttrs()
    +        throws IOException
    +    {
    +        if (nextObject == null)
    +        {
    +            nextObject = seq.readObject();
    +        }
    +
    +        if (nextObject != null)
    +        {
    +            ASN1Encodable o = nextObject;
    +            nextObject = null;
    +            return (ASN1SetParser)((ASN1TaggedObjectParser)o).getObjectParser(BERTags.SET, false);
    +        }
    +
    +        return null;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/AuthEnvelopedData.java+218 0 added
    @@ -0,0 +1,218 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1Set;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.BERSequence;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +
    +public class AuthEnvelopedData
    +    extends ASN1Object
    +{
    +    private ASN1Integer version;
    +    private OriginatorInfo originatorInfo;
    +    private ASN1Set recipientInfos;
    +    private EncryptedContentInfo authEncryptedContentInfo;
    +    private ASN1Set authAttrs;
    +    private ASN1OctetString mac;
    +    private ASN1Set unauthAttrs;
    +
    +    public AuthEnvelopedData(
    +        OriginatorInfo originatorInfo,
    +        ASN1Set recipientInfos,
    +        EncryptedContentInfo authEncryptedContentInfo,
    +        ASN1Set authAttrs,
    +        ASN1OctetString mac,
    +        ASN1Set unauthAttrs)
    +    {
    +        // "It MUST be set to 0."
    +        this.version = new ASN1Integer(0);
    +
    +        this.originatorInfo = originatorInfo;
    +
    +        // TODO
    +        // "There MUST be at least one element in the collection."
    +        this.recipientInfos = recipientInfos;
    +
    +        this.authEncryptedContentInfo = authEncryptedContentInfo;
    +
    +        // TODO
    +        // "The authAttrs MUST be present if the content type carried in
    +        // EncryptedContentInfo is not id-data."
    +        this.authAttrs = authAttrs;
    +
    +        this.mac = mac;
    +
    +        this.unauthAttrs = unauthAttrs;
    +    }
    +
    +    public AuthEnvelopedData(
    +        ASN1Sequence seq)
    +    {
    +        int index = 0;
    +
    +        // TODO
    +        // "It MUST be set to 0."
    +        ASN1Primitive tmp = seq.getObjectAt(index++).toASN1Primitive();
    +        version = (ASN1Integer)tmp;
    +
    +        tmp = seq.getObjectAt(index++).toASN1Primitive();
    +        if (tmp instanceof ASN1TaggedObject)
    +        {
    +            originatorInfo = OriginatorInfo.getInstance((ASN1TaggedObject)tmp, false);
    +            tmp = seq.getObjectAt(index++).toASN1Primitive();
    +        }
    +
    +        // TODO
    +        // "There MUST be at least one element in the collection."
    +        recipientInfos = ASN1Set.getInstance(tmp);
    +
    +        tmp = seq.getObjectAt(index++).toASN1Primitive();
    +        authEncryptedContentInfo = EncryptedContentInfo.getInstance(tmp);
    +
    +        tmp = seq.getObjectAt(index++).toASN1Primitive();
    +        if (tmp instanceof ASN1TaggedObject)
    +        {
    +            authAttrs = ASN1Set.getInstance((ASN1TaggedObject)tmp, false);
    +            tmp = seq.getObjectAt(index++).toASN1Primitive();
    +        }
    +        else
    +        {
    +            // TODO
    +            // "The authAttrs MUST be present if the content type carried in
    +            // EncryptedContentInfo is not id-data."
    +        }
    +
    +        mac = ASN1OctetString.getInstance(tmp);
    +
    +        if (seq.size() > index)
    +        {
    +            tmp = seq.getObjectAt(index++).toASN1Primitive();
    +            unauthAttrs = ASN1Set.getInstance((ASN1TaggedObject)tmp, false);
    +        }
    +    }
    +
    +    /**
    +     * return an AuthEnvelopedData object from a tagged object.
    +     *
    +     * @param obj      the tagged object holding the object we want.
    +     * @param explicit true if the object is meant to be explicitly
    +     *                 tagged false otherwise.
    +     * @throws IllegalArgumentException if the object held by the
    +     *                                  tagged object cannot be converted.
    +     */
    +    public static AuthEnvelopedData getInstance(
    +        ASN1TaggedObject obj,
    +        boolean explicit)
    +    {
    +        return getInstance(ASN1Sequence.getInstance(obj, explicit));
    +    }
    +
    +    /**
    +     * return an AuthEnvelopedData object from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @throws IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static AuthEnvelopedData getInstance(
    +        Object obj)
    +    {
    +        if (obj == null || obj instanceof AuthEnvelopedData)
    +        {
    +            return (AuthEnvelopedData)obj;
    +        }
    +
    +        if (obj instanceof ASN1Sequence)
    +        {
    +            return new AuthEnvelopedData((ASN1Sequence)obj);
    +        }
    +
    +        throw new IllegalArgumentException("Invalid AuthEnvelopedData: " + obj.getClass().getName());
    +    }
    +
    +    public ASN1Integer getVersion()
    +    {
    +        return version;
    +    }
    +
    +    public OriginatorInfo getOriginatorInfo()
    +    {
    +        return originatorInfo;
    +    }
    +
    +    public ASN1Set getRecipientInfos()
    +    {
    +        return recipientInfos;
    +    }
    +
    +    public EncryptedContentInfo getAuthEncryptedContentInfo()
    +    {
    +        return authEncryptedContentInfo;
    +    }
    +
    +    public ASN1Set getAuthAttrs()
    +    {
    +        return authAttrs;
    +    }
    +
    +    public ASN1OctetString getMac()
    +    {
    +        return mac;
    +    }
    +
    +    public ASN1Set getUnauthAttrs()
    +    {
    +        return unauthAttrs;
    +    }
    +
    +    /**
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * AuthEnvelopedData ::= SEQUENCE {
    +     *   version CMSVersion,
    +     *   originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
    +     *   recipientInfos RecipientInfos,
    +     *   authEncryptedContentInfo EncryptedContentInfo,
    +     *   authAttrs [1] IMPLICIT AuthAttributes OPTIONAL,
    +     *   mac MessageAuthenticationCode,
    +     *   unauthAttrs [2] IMPLICIT UnauthAttributes OPTIONAL }
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(version);
    +
    +        if (originatorInfo != null)
    +        {
    +            v.add(new DERTaggedObject(false, 0, originatorInfo));
    +        }
    +
    +        v.add(recipientInfos);
    +        v.add(authEncryptedContentInfo);
    +
    +        // "authAttrs optionally contains the authenticated attributes."
    +        if (authAttrs != null)
    +        {
    +            // "AuthAttributes MUST be DER encoded, even if the rest of the
    +            // AuthEnvelopedData structure is BER encoded."
    +            v.add(new DERTaggedObject(false, 1, authAttrs));
    +        }
    +
    +        v.add(mac);
    +
    +        // "unauthAttrs optionally contains the unauthenticated attributes."
    +        if (unauthAttrs != null)
    +        {
    +            v.add(new DERTaggedObject(false, 2, unauthAttrs));
    +        }
    +
    +        return new BERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/AuthEnvelopedDataParser.java+157 0 added
    @@ -0,0 +1,157 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import java.io.IOException;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1SequenceParser;
    +import org.bouncycastle.asn1.ASN1SetParser;
    +import org.bouncycastle.asn1.ASN1TaggedObjectParser;
    +import org.bouncycastle.asn1.BERTags;
    +
    +/**
    + * Produce an object suitable for an ASN1OutputStream.
    + * 
    + * <pre>
    + * AuthEnvelopedData ::= SEQUENCE {
    + *   version CMSVersion,
    + *   originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
    + *   recipientInfos RecipientInfos,
    + *   authEncryptedContentInfo EncryptedContentInfo,
    + *   authAttrs [1] IMPLICIT AuthAttributes OPTIONAL,
    + *   mac MessageAuthenticationCode,
    + *   unauthAttrs [2] IMPLICIT UnauthAttributes OPTIONAL }
    + * </pre>
    + */
    +public class AuthEnvelopedDataParser
    +{
    +    private ASN1SequenceParser seq;
    +    private ASN1Integer version;
    +    private ASN1Encodable nextObject;
    +    private boolean originatorInfoCalled;
    +
    +    public AuthEnvelopedDataParser(ASN1SequenceParser seq) throws IOException
    +    {
    +        this.seq = seq;
    +
    +        // TODO
    +        // "It MUST be set to 0."
    +        this.version = ASN1Integer.getInstance(seq.readObject());
    +    }
    +
    +    public ASN1Integer getVersion()
    +    {
    +        return version;
    +    }
    +
    +    public OriginatorInfo getOriginatorInfo()
    +        throws IOException
    +    {
    +        originatorInfoCalled = true;
    +
    +        if (nextObject == null)
    +        {
    +            nextObject = seq.readObject();
    +        }
    +
    +        if (nextObject instanceof ASN1TaggedObjectParser && ((ASN1TaggedObjectParser)nextObject).getTagNo() == 0)
    +        {
    +            ASN1SequenceParser originatorInfo = (ASN1SequenceParser) ((ASN1TaggedObjectParser)nextObject).getObjectParser(BERTags.SEQUENCE, false);
    +            nextObject = null;
    +            return OriginatorInfo.getInstance(originatorInfo.toASN1Primitive());
    +        }
    +
    +        return null;
    +    }
    +
    +    public ASN1SetParser getRecipientInfos()
    +        throws IOException
    +    {
    +        if (!originatorInfoCalled)
    +        {
    +            getOriginatorInfo();
    +        }
    +
    +        if (nextObject == null)
    +        {
    +            nextObject = seq.readObject();
    +        }
    +
    +        ASN1SetParser recipientInfos = (ASN1SetParser)nextObject;
    +        nextObject = null;
    +        return recipientInfos;
    +    }
    +
    +    public EncryptedContentInfoParser getAuthEncryptedContentInfo() 
    +        throws IOException
    +    {
    +        if (nextObject == null)
    +        {
    +            nextObject = seq.readObject();
    +        }
    +
    +        if (nextObject != null)
    +        {
    +            ASN1SequenceParser o = (ASN1SequenceParser) nextObject;
    +            nextObject = null;
    +            return new EncryptedContentInfoParser(o);
    +        }
    +
    +        return null;
    +    }
    +
    +    public ASN1SetParser getAuthAttrs()
    +        throws IOException
    +    {
    +        if (nextObject == null)
    +        {
    +            nextObject = seq.readObject();
    +        }
    +
    +        if (nextObject instanceof ASN1TaggedObjectParser)
    +        {
    +            ASN1Encodable o = nextObject;
    +            nextObject = null;
    +            return (ASN1SetParser)((ASN1TaggedObjectParser)o).getObjectParser(BERTags.SET, false);
    +        }
    +
    +        // TODO
    +        // "The authAttrs MUST be present if the content type carried in
    +        // EncryptedContentInfo is not id-data."
    +
    +        return null;
    +    }
    +
    +    public ASN1OctetString getMac()
    +        throws IOException
    +    {
    +        if (nextObject == null)
    +        {
    +            nextObject = seq.readObject();
    +        }
    +
    +        ASN1Encodable o = nextObject;
    +        nextObject = null;
    +
    +        return ASN1OctetString.getInstance(o.toASN1Primitive());
    +    }
    +
    +    public ASN1SetParser getUnauthAttrs()
    +        throws IOException
    +    {
    +        if (nextObject == null)
    +        {
    +            nextObject = seq.readObject();
    +        }
    +
    +        if (nextObject != null)
    +        {
    +            ASN1Encodable o = nextObject;
    +            nextObject = null;
    +            return (ASN1SetParser)((ASN1TaggedObjectParser)o).getObjectParser(BERTags.SET, false);
    +        }
    +
    +        return null;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/CMSAttributes.java+13 0 added
    @@ -0,0 +1,13 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1ObjectIdentifier;
    +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
    +
    +public interface CMSAttributes
    +{
    +    public static final ASN1ObjectIdentifier  contentType = PKCSObjectIdentifiers.pkcs_9_at_contentType;
    +    public static final ASN1ObjectIdentifier  messageDigest = PKCSObjectIdentifiers.pkcs_9_at_messageDigest;
    +    public static final ASN1ObjectIdentifier  signingTime = PKCSObjectIdentifiers.pkcs_9_at_signingTime;
    +    public static final ASN1ObjectIdentifier  counterSignature = PKCSObjectIdentifiers.pkcs_9_at_counterSignature;
    +    public static final ASN1ObjectIdentifier  contentHint = PKCSObjectIdentifiers.id_aa_contentHint;
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/CMSObjectIdentifiers.java+28 0 added
    @@ -0,0 +1,28 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1ObjectIdentifier;
    +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
    +
    +public interface CMSObjectIdentifiers
    +{
    +    static final ASN1ObjectIdentifier    data = PKCSObjectIdentifiers.data;
    +    static final ASN1ObjectIdentifier    signedData = PKCSObjectIdentifiers.signedData;
    +    static final ASN1ObjectIdentifier    envelopedData = PKCSObjectIdentifiers.envelopedData;
    +    static final ASN1ObjectIdentifier    signedAndEnvelopedData = PKCSObjectIdentifiers.signedAndEnvelopedData;
    +    static final ASN1ObjectIdentifier    digestedData = PKCSObjectIdentifiers.digestedData;
    +    static final ASN1ObjectIdentifier    encryptedData = PKCSObjectIdentifiers.encryptedData;
    +    static final ASN1ObjectIdentifier    authenticatedData = PKCSObjectIdentifiers.id_ct_authData;
    +    static final ASN1ObjectIdentifier    compressedData = PKCSObjectIdentifiers.id_ct_compressedData;
    +    static final ASN1ObjectIdentifier    authEnvelopedData = PKCSObjectIdentifiers.id_ct_authEnvelopedData;
    +    static final ASN1ObjectIdentifier    timestampedData = PKCSObjectIdentifiers.id_ct_timestampedData;
    +
    +    /**
    +     * The other Revocation Info arc
    +     * id-ri OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
    +     *                                   dod(6) internet(1) security(5) mechanisms(5) pkix(7) ri(16) }
    +     */
    +    static final ASN1ObjectIdentifier    id_ri = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.16");
    +
    +    static final ASN1ObjectIdentifier    id_ri_ocsp_response = id_ri.branch("2");
    +    static final ASN1ObjectIdentifier    id_ri_scvp = id_ri.branch("4");
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/CompressedData.java+110 0 added
    @@ -0,0 +1,110 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.BERSequence;
    +import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
    +
    +/** 
    + * RFC 3274 - CMS Compressed Data.
    + * <pre>
    + * CompressedData ::= SEQUENCE {
    + *  version CMSVersion,
    + *  compressionAlgorithm CompressionAlgorithmIdentifier,
    + *  encapContentInfo EncapsulatedContentInfo
    + * }
    + * </pre>
    + */
    +public class CompressedData
    +    extends ASN1Object
    +{
    +    private ASN1Integer           version;
    +    private AlgorithmIdentifier  compressionAlgorithm;
    +    private ContentInfo          encapContentInfo;
    +
    +    public CompressedData(
    +        AlgorithmIdentifier compressionAlgorithm,
    +        ContentInfo         encapContentInfo)
    +    {
    +        this.version = new ASN1Integer(0);
    +        this.compressionAlgorithm = compressionAlgorithm;
    +        this.encapContentInfo = encapContentInfo;
    +    }
    +    
    +    private CompressedData(
    +        ASN1Sequence seq)
    +    {
    +        this.version = (ASN1Integer)seq.getObjectAt(0);
    +        this.compressionAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
    +        this.encapContentInfo = ContentInfo.getInstance(seq.getObjectAt(2));
    +
    +    }
    +
    +    /**
    +     * return a CompressedData object from a tagged object.
    +     *
    +     * @param _ato the tagged object holding the object we want.
    +     * @param _explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the object held by the
    +     *          tagged object cannot be converted.
    +     */
    +    public static CompressedData getInstance(
    +        ASN1TaggedObject _ato,
    +        boolean _explicit)
    +    {
    +        return getInstance(ASN1Sequence.getInstance(_ato, _explicit));
    +    }
    +    
    +    /**
    +     * return a CompressedData object from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static CompressedData getInstance(
    +        Object obj)
    +    {
    +        if (obj instanceof CompressedData)
    +        {
    +            return (CompressedData)obj;
    +        }
    +
    +        if (obj != null)
    +        {
    +            return new CompressedData(ASN1Sequence.getInstance(obj));
    +        }
    +
    +        return null;
    +    }
    +
    +    public ASN1Integer getVersion()
    +    {
    +        return version;
    +    }
    +
    +    public AlgorithmIdentifier getCompressionAlgorithmIdentifier()
    +    {
    +        return compressionAlgorithm;
    +    }
    +
    +    public ContentInfo getEncapContentInfo()
    +    {
    +        return encapContentInfo;
    +    }
    +
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(version);
    +        v.add(compressionAlgorithm);
    +        v.add(encapContentInfo);
    +
    +        return new BERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/CompressedDataParser.java+48 0 added
    @@ -0,0 +1,48 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import java.io.IOException;
    +
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1SequenceParser;
    +import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
    +
    +/**
    + * RFC 3274 - CMS Compressed Data.
    + * <pre>
    + * CompressedData ::= SEQUENCE {
    + *  version CMSVersion,
    + *  compressionAlgorithm CompressionAlgorithmIdentifier,
    + *  encapContentInfo EncapsulatedContentInfo
    + * }
    + * </pre>
    + */
    +public class CompressedDataParser
    +{
    +    private ASN1Integer _version;
    +    private AlgorithmIdentifier _compressionAlgorithm;
    +    private ContentInfoParser _encapContentInfo;
    +
    +    public CompressedDataParser(
    +        ASN1SequenceParser seq)
    +        throws IOException
    +    {
    +        this._version = (ASN1Integer)seq.readObject();
    +        this._compressionAlgorithm = AlgorithmIdentifier.getInstance(seq.readObject().toASN1Primitive());
    +        this._encapContentInfo = new ContentInfoParser((ASN1SequenceParser)seq.readObject());
    +    }
    +
    +    public ASN1Integer getVersion()
    +    {
    +        return _version;
    +    }
    +
    +    public AlgorithmIdentifier getCompressionAlgorithmIdentifier()
    +    {
    +        return _compressionAlgorithm;
    +    }
    +
    +    public ContentInfoParser getEncapContentInfo()
    +    {
    +        return _encapContentInfo;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java+107 0 added
    @@ -0,0 +1,107 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1ObjectIdentifier;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.BERSequence;
    +import org.bouncycastle.asn1.BERTaggedObject;
    +
    +public class ContentInfo
    +    extends ASN1Object
    +    implements CMSObjectIdentifiers
    +{
    +    private ASN1ObjectIdentifier contentType;
    +    private ASN1Encodable        content;
    +
    +    public static ContentInfo getInstance(
    +        Object  obj)
    +    {
    +        if (obj instanceof ContentInfo)
    +        {
    +            return (ContentInfo)obj;
    +        }
    +        else if (obj != null)
    +        {
    +            return new ContentInfo(ASN1Sequence.getInstance(obj));
    +        }
    +
    +        return null;
    +    }
    +
    +    public static ContentInfo getInstance(
    +        ASN1TaggedObject obj,
    +        boolean explicit)
    +    {
    +        return getInstance(ASN1Sequence.getInstance(obj, explicit));
    +    }
    +
    +    /**
    +     * @deprecated use getInstance()
    +     */
    +    public ContentInfo(
    +        ASN1Sequence  seq)
    +    {
    +        if (seq.size() < 1 || seq.size() > 2)
    +        {
    +            throw new IllegalArgumentException("Bad sequence size: " + seq.size());
    +        }
    +
    +        contentType = (ASN1ObjectIdentifier)seq.getObjectAt(0);
    +
    +        if (seq.size() > 1)
    +        {
    +            ASN1TaggedObject tagged = (ASN1TaggedObject)seq.getObjectAt(1);
    +            if (!tagged.isExplicit() || tagged.getTagNo() != 0)
    +            {
    +                throw new IllegalArgumentException("Bad tag for 'content'");
    +            }
    +
    +            content = tagged.getObject();
    +        }
    +    }
    +
    +    public ContentInfo(
    +        ASN1ObjectIdentifier contentType,
    +        ASN1Encodable        content)
    +    {
    +        this.contentType = contentType;
    +        this.content = content;
    +    }
    +
    +    public ASN1ObjectIdentifier getContentType()
    +    {
    +        return contentType;
    +    }
    +
    +    public ASN1Encodable getContent()
    +    {
    +        return content;
    +    }
    +
    +    /**
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * ContentInfo ::= SEQUENCE {
    +     *          contentType ContentType,
    +     *          content
    +     *          [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector  v = new ASN1EncodableVector();
    +
    +        v.add(contentType);
    +
    +        if (content != null)
    +        {
    +            v.add(new BERTaggedObject(0, content));
    +        }
    +
    +        return new BERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/ContentInfoParser.java+48 0 added
    @@ -0,0 +1,48 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import java.io.IOException;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1ObjectIdentifier;
    +import org.bouncycastle.asn1.ASN1SequenceParser;
    +import org.bouncycastle.asn1.ASN1TaggedObjectParser;
    +
    +/**
    + * Produce an object suitable for an ASN1OutputStream.
    + * <pre>
    + * ContentInfo ::= SEQUENCE {
    + *          contentType ContentType,
    + *          content
    + *          [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
    + * </pre>
    + */
    +public class ContentInfoParser
    +{
    +    private ASN1ObjectIdentifier contentType;
    +    private ASN1TaggedObjectParser content;
    +
    +    public ContentInfoParser(
    +        ASN1SequenceParser seq)
    +        throws IOException
    +    {
    +        contentType = (ASN1ObjectIdentifier)seq.readObject();
    +        content = (ASN1TaggedObjectParser)seq.readObject();
    +    }
    +
    +    public ASN1ObjectIdentifier getContentType()
    +    {
    +        return contentType;
    +    }
    +
    +    public ASN1Encodable getContent(
    +        int  tag)
    +        throws IOException
    +    {
    +        if (content != null)
    +        {
    +            return content.getObjectParser(tag, true);
    +        }
    +
    +        return null;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/DigestedData.java+121 0 added
    @@ -0,0 +1,121 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.BERSequence;
    +import org.bouncycastle.asn1.DEROctetString;
    +import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
    +
    +/** 
    + * RFC 3274 - CMS Digest Data.
    + * <pre>
    + * DigestedData ::= SEQUENCE {
    + *               version CMSVersion,
    + *               digestAlgorithm DigestAlgorithmIdentifier,
    + *               encapContentInfo EncapsulatedContentInfo,
    + *               digest Digest }
    + * </pre>
    + */
    +public class DigestedData
    +    extends ASN1Object
    +{
    +    private ASN1Integer           version;
    +    private AlgorithmIdentifier  digestAlgorithm;
    +    private ContentInfo          encapContentInfo;
    +    private ASN1OctetString      digest;
    +
    +    public DigestedData(
    +        AlgorithmIdentifier digestAlgorithm,
    +        ContentInfo encapContentInfo,
    +        byte[]      digest)
    +    {
    +        this.version = new ASN1Integer(0);
    +        this.digestAlgorithm = digestAlgorithm;
    +        this.encapContentInfo = encapContentInfo;
    +        this.digest = new DEROctetString(digest);
    +    }
    +
    +    private DigestedData(
    +        ASN1Sequence seq)
    +    {
    +        this.version = (ASN1Integer)seq.getObjectAt(0);
    +        this.digestAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
    +        this.encapContentInfo = ContentInfo.getInstance(seq.getObjectAt(2));
    +        this.digest = ASN1OctetString.getInstance(seq.getObjectAt(3));
    +    }
    +
    +    /**
    +     * return a CompressedData object from a tagged object.
    +     *
    +     * @param _ato the tagged object holding the object we want.
    +     * @param _explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the object held by the
    +     *          tagged object cannot be converted.
    +     */
    +    public static DigestedData getInstance(
    +        ASN1TaggedObject _ato,
    +        boolean _explicit)
    +    {
    +        return getInstance(ASN1Sequence.getInstance(_ato, _explicit));
    +    }
    +    
    +    /**
    +     * return a CompressedData object from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static DigestedData getInstance(
    +        Object obj)
    +    {
    +        if (obj instanceof DigestedData)
    +        {
    +            return (DigestedData)obj;
    +        }
    +        
    +        if (obj != null)
    +        {
    +            return new DigestedData(ASN1Sequence.getInstance(obj));
    +        }
    +        
    +        return null;
    +    }
    +
    +    public ASN1Integer getVersion()
    +    {
    +        return version;
    +    }
    +
    +    public AlgorithmIdentifier getDigestAlgorithm()
    +    {
    +        return digestAlgorithm;
    +    }
    +
    +    public ContentInfo getEncapContentInfo()
    +    {
    +        return encapContentInfo;
    +    }
    +
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(version);
    +        v.add(digestAlgorithm);
    +        v.add(encapContentInfo);
    +        v.add(digest);
    +
    +        return new BERSequence(v);
    +    }
    +
    +    public byte[] getDigest()
    +    {
    +        return digest.getOctets();
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/ecc/MQVuserKeyingMaterial.java+112 0 added
  • core/src/main/java/org/bouncycastle/asn1/cms/EncryptedContentInfo.java+109 0 added
    @@ -0,0 +1,109 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1ObjectIdentifier;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.BERSequence;
    +import org.bouncycastle.asn1.BERTaggedObject;
    +import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
    +
    +public class EncryptedContentInfo
    +    extends ASN1Object
    +{
    +    private ASN1ObjectIdentifier contentType;
    +    private AlgorithmIdentifier contentEncryptionAlgorithm;
    +    private ASN1OctetString     encryptedContent;
    +    
    +    public EncryptedContentInfo(
    +        ASN1ObjectIdentifier contentType, 
    +        AlgorithmIdentifier contentEncryptionAlgorithm,
    +        ASN1OctetString     encryptedContent)
    +    {
    +        this.contentType = contentType;
    +        this.contentEncryptionAlgorithm = contentEncryptionAlgorithm;
    +        this.encryptedContent = encryptedContent;
    +    }
    +    
    +    private EncryptedContentInfo(
    +        ASN1Sequence seq)
    +    {
    +        if (seq.size() < 2)
    +        {
    +            throw new IllegalArgumentException("Truncated Sequence Found");
    +        }
    +
    +        contentType = (ASN1ObjectIdentifier)seq.getObjectAt(0);
    +        contentEncryptionAlgorithm = AlgorithmIdentifier.getInstance(
    +                                                        seq.getObjectAt(1));
    +        if (seq.size() > 2)
    +        {
    +            encryptedContent = ASN1OctetString.getInstance(
    +                                (ASN1TaggedObject)seq.getObjectAt(2), false);
    +        }
    +    }
    +
    +    /**
    +     * return an EncryptedContentInfo object from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static EncryptedContentInfo getInstance(
    +        Object obj)
    +    {
    +        if (obj instanceof EncryptedContentInfo)
    +        {
    +            return (EncryptedContentInfo)obj;
    +        }
    +        if (obj != null)
    +        {
    +            return new EncryptedContentInfo(ASN1Sequence.getInstance(obj));
    +        }
    +        
    +        return null;
    +    }
    +
    +    public ASN1ObjectIdentifier getContentType()
    +    {
    +        return contentType;
    +    }
    +
    +    public AlgorithmIdentifier getContentEncryptionAlgorithm()
    +    {
    +        return contentEncryptionAlgorithm;
    +    }
    +
    +    public ASN1OctetString getEncryptedContent()
    +    {
    +        return encryptedContent;
    +    }
    +
    +    /** 
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * EncryptedContentInfo ::= SEQUENCE {
    +     *     contentType ContentType,
    +     *     contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
    +     *     encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL 
    +     * }
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector  v = new ASN1EncodableVector();
    +        
    +        v.add(contentType);
    +        v.add(contentEncryptionAlgorithm);
    +
    +        if (encryptedContent != null)
    +        {
    +            v.add(new BERTaggedObject(false, 0, encryptedContent));
    +        }
    +        
    +        return new BERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/EncryptedContentInfoParser.java+51 0 added
    @@ -0,0 +1,51 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import java.io.IOException;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1ObjectIdentifier;
    +import org.bouncycastle.asn1.ASN1SequenceParser;
    +import org.bouncycastle.asn1.ASN1TaggedObjectParser;
    +import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
    +
    +/**
    + * <pre>
    + * EncryptedContentInfo ::= SEQUENCE {
    + *     contentType ContentType,
    + *     contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
    + *     encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL 
    + * }
    + * </pre>
    + */
    +public class EncryptedContentInfoParser
    +{
    +    private ASN1ObjectIdentifier    _contentType;
    +    private AlgorithmIdentifier     _contentEncryptionAlgorithm;
    +    private ASN1TaggedObjectParser _encryptedContent;
    +
    +    public EncryptedContentInfoParser(
    +        ASN1SequenceParser  seq) 
    +        throws IOException
    +    {
    +        _contentType = (ASN1ObjectIdentifier)seq.readObject();
    +        _contentEncryptionAlgorithm = AlgorithmIdentifier.getInstance(seq.readObject().toASN1Primitive());
    +        _encryptedContent = (ASN1TaggedObjectParser)seq.readObject();
    +    }
    +    
    +    public ASN1ObjectIdentifier getContentType()
    +    {
    +        return _contentType;
    +    }
    +    
    +    public AlgorithmIdentifier getContentEncryptionAlgorithm()
    +    {
    +        return _contentEncryptionAlgorithm;
    +    }
    +
    +    public ASN1Encodable getEncryptedContent(
    +        int  tag) 
    +        throws IOException
    +    {
    +        return _encryptedContent.getObjectParser(tag, false);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/EncryptedData.java+94 0 added
    @@ -0,0 +1,94 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1Set;
    +import org.bouncycastle.asn1.BERSequence;
    +import org.bouncycastle.asn1.BERTaggedObject;
    +
    +public class EncryptedData
    +    extends ASN1Object
    +{
    +    private ASN1Integer version;
    +    private EncryptedContentInfo encryptedContentInfo;
    +    private ASN1Set unprotectedAttrs;
    +
    +    public static EncryptedData getInstance(Object o)
    +    {
    +        if (o instanceof EncryptedData)
    +        {
    +            return (EncryptedData)o;
    +        }
    +
    +        if (o != null)
    +        {
    +            return new EncryptedData(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public EncryptedData(EncryptedContentInfo encInfo)
    +    {
    +        this(encInfo,  null);
    +    }
    +
    +    public EncryptedData(EncryptedContentInfo encInfo, ASN1Set unprotectedAttrs)
    +    {
    +        this.version = new ASN1Integer((unprotectedAttrs == null) ? 0 : 2);
    +        this.encryptedContentInfo = encInfo;
    +        this.unprotectedAttrs = unprotectedAttrs;
    +    }
    +
    +    private EncryptedData(ASN1Sequence seq)
    +    {
    +        this.version = ASN1Integer.getInstance(seq.getObjectAt(0));
    +        this.encryptedContentInfo = EncryptedContentInfo.getInstance(seq.getObjectAt(1));
    +
    +        if (seq.size() == 3)
    +        {
    +            this.unprotectedAttrs = ASN1Set.getInstance(seq.getObjectAt(2));
    +        }
    +    }
    +
    +    public ASN1Integer getVersion()
    +    {
    +        return version;
    +    }
    +
    +    public EncryptedContentInfo getEncryptedContentInfo()
    +    {
    +        return encryptedContentInfo;
    +    }
    +
    +    public ASN1Set getUnprotectedAttrs()
    +    {
    +        return unprotectedAttrs;
    +    }
    +
    +    /**
    +     * <pre>
    +     *       EncryptedData ::= SEQUENCE {
    +     *                     version CMSVersion,
    +     *                     encryptedContentInfo EncryptedContentInfo,
    +     *                     unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL }
    +     * </pre>
    +     * @return a basic ASN.1 object representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(version);
    +        v.add(encryptedContentInfo);
    +        if (unprotectedAttrs != null)
    +        {
    +            v.add(new BERTaggedObject(false, 1, unprotectedAttrs));
    +        }
    +
    +        return new BERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/EnvelopedData.java+205 0 added
    @@ -0,0 +1,205 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import java.util.Enumeration;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1Set;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.BERSequence;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +
    +public class EnvelopedData
    +    extends ASN1Object
    +{
    +    private ASN1Integer              version;
    +    private OriginatorInfo          originatorInfo;
    +    private ASN1Set                 recipientInfos;
    +    private EncryptedContentInfo    encryptedContentInfo;
    +    private ASN1Set                 unprotectedAttrs;
    +
    +    public EnvelopedData(
    +        OriginatorInfo          originatorInfo,
    +        ASN1Set                 recipientInfos,
    +        EncryptedContentInfo    encryptedContentInfo,
    +        ASN1Set                 unprotectedAttrs)
    +    {
    +        version = new ASN1Integer(calculateVersion(originatorInfo, recipientInfos, unprotectedAttrs));
    +
    +        this.originatorInfo = originatorInfo;
    +        this.recipientInfos = recipientInfos;
    +        this.encryptedContentInfo = encryptedContentInfo;
    +        this.unprotectedAttrs = unprotectedAttrs;
    +    }
    +
    +    public EnvelopedData(
    +        OriginatorInfo          originatorInfo,
    +        ASN1Set                 recipientInfos,
    +        EncryptedContentInfo    encryptedContentInfo,
    +        Attributes              unprotectedAttrs)
    +    {
    +        version = new ASN1Integer(calculateVersion(originatorInfo, recipientInfos, ASN1Set.getInstance(unprotectedAttrs)));
    +
    +        this.originatorInfo = originatorInfo;
    +        this.recipientInfos = recipientInfos;
    +        this.encryptedContentInfo = encryptedContentInfo;
    +        this.unprotectedAttrs = ASN1Set.getInstance(unprotectedAttrs);
    +    }
    +
    +    /**
    +     * @deprecated use getInstance()
    +     */
    +    public EnvelopedData(
    +        ASN1Sequence seq)
    +    {
    +        int     index = 0;
    +        
    +        version = (ASN1Integer)seq.getObjectAt(index++);
    +        
    +        Object  tmp = seq.getObjectAt(index++);
    +
    +        if (tmp instanceof ASN1TaggedObject)
    +        {
    +            originatorInfo = OriginatorInfo.getInstance((ASN1TaggedObject)tmp, false);
    +            tmp = seq.getObjectAt(index++);
    +        }
    +
    +        recipientInfos = ASN1Set.getInstance(tmp);
    +        
    +        encryptedContentInfo = EncryptedContentInfo.getInstance(seq.getObjectAt(index++));
    +        
    +        if(seq.size() > index)
    +        {
    +            unprotectedAttrs = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(index), false);
    +        }
    +    }
    +    
    +    /**
    +     * return an EnvelopedData object from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want.
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the object held by the
    +     *          tagged object cannot be converted.
    +     */
    +    public static EnvelopedData getInstance(
    +        ASN1TaggedObject obj,
    +        boolean explicit)
    +    {
    +        return getInstance(ASN1Sequence.getInstance(obj, explicit));
    +    }
    +    
    +    /**
    +     * return an EnvelopedData object from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static EnvelopedData getInstance(
    +        Object obj)
    +    {
    +        if (obj instanceof EnvelopedData)
    +        {
    +            return (EnvelopedData)obj;
    +        }
    +        
    +        if (obj != null)
    +        {
    +            return new EnvelopedData(ASN1Sequence.getInstance(obj));
    +        }
    +        
    +        return null;
    +    }
    +
    +    public ASN1Integer getVersion()
    +    {
    +        return version;
    +    }
    +    
    +    public OriginatorInfo getOriginatorInfo()
    +    {
    +        return originatorInfo;
    +    }
    +
    +    public ASN1Set getRecipientInfos()
    +    {
    +        return recipientInfos;
    +    }
    +
    +    public EncryptedContentInfo getEncryptedContentInfo()
    +    {
    +        return encryptedContentInfo;
    +    }
    +
    +    public ASN1Set getUnprotectedAttrs()
    +    {
    +        return unprotectedAttrs;
    +    }
    +
    +    /** 
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * EnvelopedData ::= SEQUENCE {
    +     *     version CMSVersion,
    +     *     originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
    +     *     recipientInfos RecipientInfos,
    +     *     encryptedContentInfo EncryptedContentInfo,
    +     *     unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL 
    +     * }
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector  v = new ASN1EncodableVector();
    +        
    +        v.add(version);
    +
    +        if (originatorInfo != null)
    +        {
    +            v.add(new DERTaggedObject(false, 0, originatorInfo));
    +        }
    +
    +        v.add(recipientInfos);
    +        v.add(encryptedContentInfo);
    +
    +        if (unprotectedAttrs != null)
    +        {
    +            v.add(new DERTaggedObject(false, 1, unprotectedAttrs));
    +        }
    +        
    +        return new BERSequence(v);
    +    }
    +
    +    public static int calculateVersion(OriginatorInfo originatorInfo, ASN1Set recipientInfos, ASN1Set unprotectedAttrs)
    +    {
    +        int version;
    +
    +        if (originatorInfo != null || unprotectedAttrs != null)
    +        {
    +            version = 2;
    +        }
    +        else
    +        {
    +            version = 0;
    +
    +            Enumeration e = recipientInfos.getObjects();
    +
    +            while (e.hasMoreElements())
    +            {
    +                RecipientInfo   ri = RecipientInfo.getInstance(e.nextElement());
    +
    +                if (ri.getVersion().getValue().intValue() != version)
    +                {
    +                    version = 2;
    +                    break;
    +                }
    +            }
    +        }
    +
    +        return version;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/EnvelopedDataParser.java+118 0 added
    @@ -0,0 +1,118 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import java.io.IOException;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1SequenceParser;
    +import org.bouncycastle.asn1.ASN1SetParser;
    +import org.bouncycastle.asn1.ASN1TaggedObjectParser;
    +import org.bouncycastle.asn1.BERTags;
    +
    +/** 
    + * <pre>
    + * EnvelopedData ::= SEQUENCE {
    + *     version CMSVersion,
    + *     originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
    + *     recipientInfos RecipientInfos,
    + *     encryptedContentInfo EncryptedContentInfo,
    + *     unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL 
    + * }
    + * </pre>
    + */
    +public class EnvelopedDataParser
    +{
    +    private ASN1SequenceParser _seq;
    +    private ASN1Integer        _version;
    +    private ASN1Encodable      _nextObject;
    +    private boolean            _originatorInfoCalled;
    +    
    +    public EnvelopedDataParser(
    +        ASN1SequenceParser seq)
    +        throws IOException
    +    {
    +        this._seq = seq;
    +        this._version = ASN1Integer.getInstance(seq.readObject());
    +    }
    +
    +    public ASN1Integer getVersion()
    +    {
    +        return _version;
    +    }
    +
    +    public OriginatorInfo getOriginatorInfo() 
    +        throws IOException
    +    {
    +        _originatorInfoCalled = true; 
    +        
    +        if (_nextObject == null)
    +        {
    +            _nextObject = _seq.readObject();
    +        }
    +        
    +        if (_nextObject instanceof ASN1TaggedObjectParser && ((ASN1TaggedObjectParser)_nextObject).getTagNo() == 0)
    +        {
    +            ASN1SequenceParser originatorInfo = (ASN1SequenceParser) ((ASN1TaggedObjectParser)_nextObject).getObjectParser(BERTags.SEQUENCE, false);
    +            _nextObject = null;
    +            return OriginatorInfo.getInstance(originatorInfo.toASN1Primitive());
    +        }
    +        
    +        return null;
    +    }
    +    
    +    public ASN1SetParser getRecipientInfos()
    +        throws IOException
    +    {
    +        if (!_originatorInfoCalled)
    +        {
    +            getOriginatorInfo();
    +        }
    +        
    +        if (_nextObject == null)
    +        {
    +            _nextObject = _seq.readObject();
    +        }
    +        
    +        ASN1SetParser recipientInfos = (ASN1SetParser)_nextObject;
    +        _nextObject = null;
    +        return recipientInfos;
    +    }
    +
    +    public EncryptedContentInfoParser getEncryptedContentInfo() 
    +        throws IOException
    +    {
    +        if (_nextObject == null)
    +        {
    +            _nextObject = _seq.readObject();
    +        }
    +        
    +        
    +        if (_nextObject != null)
    +        {
    +            ASN1SequenceParser o = (ASN1SequenceParser) _nextObject;
    +            _nextObject = null;
    +            return new EncryptedContentInfoParser(o);
    +        }
    +        
    +        return null;
    +    }
    +
    +    public ASN1SetParser getUnprotectedAttrs()
    +        throws IOException
    +    {
    +        if (_nextObject == null)
    +        {
    +            _nextObject = _seq.readObject();
    +        }
    +        
    +        
    +        if (_nextObject != null)
    +        {
    +            ASN1Encodable o = _nextObject;
    +            _nextObject = null;
    +            return (ASN1SetParser)((ASN1TaggedObjectParser)o).getObjectParser(BERTags.SET, false);
    +        }
    +        
    +        return null;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/Evidence.java+56 0 added
    @@ -0,0 +1,56 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1Choice;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +
    +public class Evidence
    +    extends ASN1Object
    +    implements ASN1Choice
    +{
    +    private TimeStampTokenEvidence tstEvidence;
    +
    +    public Evidence(TimeStampTokenEvidence tstEvidence)
    +    {
    +        this.tstEvidence = tstEvidence;
    +    }
    +
    +    private Evidence(ASN1TaggedObject tagged)
    +    {
    +        if (tagged.getTagNo() == 0)
    +        {
    +            this.tstEvidence = TimeStampTokenEvidence.getInstance(tagged, false);
    +        }
    +    }
    +
    +    public static Evidence getInstance(Object obj)
    +    {
    +        if (obj == null || obj instanceof Evidence)
    +        {
    +            return (Evidence)obj;
    +        }
    +        else if (obj instanceof ASN1TaggedObject)
    +        {
    +            return new Evidence(ASN1TaggedObject.getInstance(obj));
    +        }
    +
    +        throw new IllegalArgumentException("unknown object in getInstance");
    +    }
    +
    +    public TimeStampTokenEvidence getTstEvidence()
    +    {
    +        return tstEvidence;
    +    }
    +
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +       if (tstEvidence != null)
    +       {
    +           return new DERTaggedObject(false, 0, tstEvidence);
    +       }
    +
    +       return null;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/IssuerAndSerialNumber.java+111 0 added
    @@ -0,0 +1,111 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import java.math.BigInteger;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.x500.X500Name;
    +import org.bouncycastle.asn1.x509.Certificate;
    +import org.bouncycastle.asn1.x509.X509CertificateStructure;
    +import org.bouncycastle.asn1.x509.X509Name;
    +
    +public class IssuerAndSerialNumber
    +    extends ASN1Object
    +{
    +    private X500Name    name;
    +    private ASN1Integer  serialNumber;
    +
    +    public static IssuerAndSerialNumber getInstance(
    +        Object  obj)
    +    {
    +        if (obj instanceof IssuerAndSerialNumber)
    +        {
    +            return (IssuerAndSerialNumber)obj;
    +        }
    +        else if (obj != null)
    +        {
    +            return new IssuerAndSerialNumber(ASN1Sequence.getInstance(obj));
    +        }
    +
    +        return null;
    +    }
    +
    +    /**
    +     * @deprecated  use getInstance() method.
    +     * @param seq
    +     */
    +    public IssuerAndSerialNumber(
    +        ASN1Sequence    seq)
    +    {
    +        this.name = X500Name.getInstance(seq.getObjectAt(0));
    +        this.serialNumber = (ASN1Integer)seq.getObjectAt(1);
    +    }
    +
    +    public IssuerAndSerialNumber(
    +        Certificate certificate)
    +    {
    +        this.name = certificate.getIssuer();
    +        this.serialNumber = certificate.getSerialNumber();
    +    }
    +
    +    public IssuerAndSerialNumber(
    +        X509CertificateStructure certificate)
    +    {
    +        this.name = certificate.getIssuer();
    +        this.serialNumber = certificate.getSerialNumber();
    +    }
    +
    +    public IssuerAndSerialNumber(
    +        X500Name name,
    +        BigInteger  serialNumber)
    +    {
    +        this.name = name;
    +        this.serialNumber = new ASN1Integer(serialNumber);
    +    }
    +
    +    /**
    +     * @deprecated use X500Name constructor
    +     */
    +    public IssuerAndSerialNumber(
    +        X509Name    name,
    +        BigInteger  serialNumber)
    +    {
    +        this.name = X500Name.getInstance(name);
    +        this.serialNumber = new ASN1Integer(serialNumber);
    +    }
    +
    +    /**
    +     * @deprecated use X500Name constructor
    +     */
    +    public IssuerAndSerialNumber(
    +        X509Name    name,
    +        ASN1Integer  serialNumber)
    +    {
    +        this.name = X500Name.getInstance(name);
    +        this.serialNumber = serialNumber;
    +    }
    +
    +    public X500Name getName()
    +    {
    +        return name;
    +    }
    +
    +    public ASN1Integer getSerialNumber()
    +    {
    +        return serialNumber;
    +    }
    +
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector    v = new ASN1EncodableVector();
    +
    +        v.add(name);
    +        v.add(serialNumber);
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/KEKIdentifier.java+139 0 added
    @@ -0,0 +1,139 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1GeneralizedTime;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DEROctetString;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +public class KEKIdentifier
    +    extends ASN1Object
    +{
    +    private ASN1OctetString    keyIdentifier;
    +    private ASN1GeneralizedTime date;
    +    private OtherKeyAttribute  other;
    +    
    +    public KEKIdentifier(
    +        byte[]              keyIdentifier,
    +        ASN1GeneralizedTime  date,
    +        OtherKeyAttribute   other)
    +    {
    +        this.keyIdentifier = new DEROctetString(keyIdentifier);
    +        this.date = date;
    +        this.other = other;
    +    }
    +    
    +    private KEKIdentifier(
    +        ASN1Sequence seq)
    +    {
    +        keyIdentifier = (ASN1OctetString)seq.getObjectAt(0);
    +        
    +        switch (seq.size())
    +        {
    +        case 1:
    +            break;
    +        case 2:
    +            if (seq.getObjectAt(1) instanceof ASN1GeneralizedTime)
    +            {
    +                date = (ASN1GeneralizedTime)seq.getObjectAt(1); 
    +            }
    +            else
    +            {
    +                other = OtherKeyAttribute.getInstance(seq.getObjectAt(1));
    +            }
    +            break;
    +        case 3:
    +            date  = (ASN1GeneralizedTime)seq.getObjectAt(1);
    +            other = OtherKeyAttribute.getInstance(seq.getObjectAt(2));
    +            break;
    +        default:
    +                throw new IllegalArgumentException("Invalid KEKIdentifier");
    +        }
    +    }
    +
    +    /**
    +     * return a KEKIdentifier object from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want.
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the object held by the
    +     *          tagged object cannot be converted.
    +     */
    +    public static KEKIdentifier getInstance(
    +        ASN1TaggedObject obj,
    +        boolean explicit)
    +    {
    +        return getInstance(ASN1Sequence.getInstance(obj, explicit));
    +    }
    +    
    +    /**
    +     * return a KEKIdentifier object from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static KEKIdentifier getInstance(
    +        Object obj)
    +    {
    +        if (obj == null || obj instanceof KEKIdentifier)
    +        {
    +            return (KEKIdentifier)obj;
    +        }
    +        
    +        if (obj instanceof ASN1Sequence)
    +        {
    +            return new KEKIdentifier((ASN1Sequence)obj);
    +        }
    +        
    +        throw new IllegalArgumentException("Invalid KEKIdentifier: " + obj.getClass().getName());
    +    }
    +
    +    public ASN1OctetString getKeyIdentifier()
    +    {
    +        return keyIdentifier;
    +    }
    +
    +    public ASN1GeneralizedTime getDate()
    +    {
    +        return date;
    +    }
    +
    +    public OtherKeyAttribute getOther()
    +    {
    +        return other;
    +    }
    +
    +    /** 
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * KEKIdentifier ::= SEQUENCE {
    +     *     keyIdentifier OCTET STRING,
    +     *     date GeneralizedTime OPTIONAL,
    +     *     other OtherKeyAttribute OPTIONAL 
    +     * }
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector  v = new ASN1EncodableVector();
    +
    +        v.add(keyIdentifier);
    +        
    +        if (date != null)
    +        {
    +            v.add(date);
    +        }
    +
    +        if (other != null)
    +        {
    +            v.add(other);
    +        }
    +        
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/KEKRecipientInfo.java+121 0 added
    @@ -0,0 +1,121 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
    +
    +public class KEKRecipientInfo
    +    extends ASN1Object
    +{
    +    private ASN1Integer          version;
    +    private KEKIdentifier       kekid;
    +    private AlgorithmIdentifier keyEncryptionAlgorithm;
    +    private ASN1OctetString     encryptedKey;
    +
    +    public KEKRecipientInfo(
    +        KEKIdentifier       kekid,
    +        AlgorithmIdentifier keyEncryptionAlgorithm,
    +        ASN1OctetString     encryptedKey)
    +    {
    +        this.version = new ASN1Integer(4);
    +        this.kekid = kekid;
    +        this.keyEncryptionAlgorithm = keyEncryptionAlgorithm;
    +        this.encryptedKey = encryptedKey;
    +    }
    +    
    +    public KEKRecipientInfo(
    +        ASN1Sequence seq)
    +    {
    +        version = (ASN1Integer)seq.getObjectAt(0);
    +        kekid = KEKIdentifier.getInstance(seq.getObjectAt(1));
    +        keyEncryptionAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(2));
    +        encryptedKey = (ASN1OctetString)seq.getObjectAt(3);
    +    }
    +
    +    /**
    +     * return a KEKRecipientInfo object from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want.
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the object held by the
    +     *          tagged object cannot be converted.
    +     */
    +    public static KEKRecipientInfo getInstance(
    +        ASN1TaggedObject    obj,
    +        boolean             explicit)
    +    {
    +        return getInstance(ASN1Sequence.getInstance(obj, explicit));
    +    }
    +    
    +    /**
    +     * return a KEKRecipientInfo object from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static KEKRecipientInfo getInstance(
    +        Object obj)
    +    {
    +        if (obj == null || obj instanceof KEKRecipientInfo)
    +        {
    +            return (KEKRecipientInfo)obj;
    +        }
    +        
    +        if(obj instanceof ASN1Sequence)
    +        {
    +            return new KEKRecipientInfo((ASN1Sequence)obj);
    +        }
    +        
    +        throw new IllegalArgumentException("Invalid KEKRecipientInfo: " + obj.getClass().getName());
    +    }
    +
    +    public ASN1Integer getVersion()
    +    {
    +        return version;
    +    }
    +    
    +    public KEKIdentifier getKekid()
    +    {
    +        return kekid;
    +    }
    +
    +    public AlgorithmIdentifier getKeyEncryptionAlgorithm()
    +    {
    +        return keyEncryptionAlgorithm;
    +    }
    +
    +    public ASN1OctetString getEncryptedKey()
    +    {
    +        return encryptedKey;
    +    }
    +
    +    /** 
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * KEKRecipientInfo ::= SEQUENCE {
    +     *     version CMSVersion,  -- always set to 4
    +     *     kekid KEKIdentifier,
    +     *     keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
    +     *     encryptedKey EncryptedKey 
    +     * }
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector  v = new ASN1EncodableVector();
    +
    +        v.add(version);
    +        v.add(kekid);
    +        v.add(keyEncryptionAlgorithm);
    +        v.add(encryptedKey);
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientIdentifier.java+103 0 added
    @@ -0,0 +1,103 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1Choice;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +
    +public class KeyAgreeRecipientIdentifier
    +    extends ASN1Object
    +    implements ASN1Choice
    +{
    +    private IssuerAndSerialNumber issuerSerial;
    +    private RecipientKeyIdentifier rKeyID;
    +
    +    /**
    +     * return an KeyAgreeRecipientIdentifier object from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want.
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the object held by the
    +     *          tagged object cannot be converted.
    +     */
    +    public static KeyAgreeRecipientIdentifier getInstance(
    +        ASN1TaggedObject    obj,
    +        boolean             explicit)
    +    {
    +        return getInstance(ASN1Sequence.getInstance(obj, explicit));
    +    }
    +    
    +    /**
    +     * return an KeyAgreeRecipientIdentifier object from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static KeyAgreeRecipientIdentifier getInstance(
    +        Object obj)
    +    {
    +        if (obj == null || obj instanceof KeyAgreeRecipientIdentifier)
    +        {
    +            return (KeyAgreeRecipientIdentifier)obj;
    +        }
    +        
    +        if (obj instanceof ASN1Sequence)
    +        {
    +            return new KeyAgreeRecipientIdentifier(IssuerAndSerialNumber.getInstance(obj));
    +        }
    +        
    +        if (obj instanceof ASN1TaggedObject && ((ASN1TaggedObject)obj).getTagNo() == 0)
    +        {
    +            return new KeyAgreeRecipientIdentifier(RecipientKeyIdentifier.getInstance(
    +                (ASN1TaggedObject)obj, false));
    +        }
    +        
    +        throw new IllegalArgumentException("Invalid KeyAgreeRecipientIdentifier: " + obj.getClass().getName());
    +    } 
    +
    +    public KeyAgreeRecipientIdentifier(
    +        IssuerAndSerialNumber issuerSerial)
    +    {
    +        this.issuerSerial = issuerSerial;
    +        this.rKeyID = null;
    +    }
    +
    +    public KeyAgreeRecipientIdentifier(
    +         RecipientKeyIdentifier rKeyID)
    +    {
    +        this.issuerSerial = null;
    +        this.rKeyID = rKeyID;
    +    }
    +
    +    public IssuerAndSerialNumber getIssuerAndSerialNumber()
    +    {
    +        return issuerSerial;
    +    }
    +
    +    public RecipientKeyIdentifier getRKeyID()
    +    {
    +        return rKeyID;
    +    }
    +
    +    /** 
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * KeyAgreeRecipientIdentifier ::= CHOICE {
    +     *     issuerAndSerialNumber IssuerAndSerialNumber,
    +     *     rKeyId [0] IMPLICIT RecipientKeyIdentifier
    +     * }
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        if (issuerSerial != null)
    +        {
    +            return issuerSerial.toASN1Primitive();
    +        }
    +
    +        return new DERTaggedObject(false, 0, rKeyID);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientInfo.java+153 0 added
    @@ -0,0 +1,153 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
    +
    +public class KeyAgreeRecipientInfo
    +    extends ASN1Object
    +{
    +    private ASN1Integer                  version;
    +    private OriginatorIdentifierOrKey   originator;
    +    private ASN1OctetString             ukm;
    +    private AlgorithmIdentifier         keyEncryptionAlgorithm;
    +    private ASN1Sequence                recipientEncryptedKeys;
    +    
    +    public KeyAgreeRecipientInfo(
    +        OriginatorIdentifierOrKey   originator,
    +        ASN1OctetString             ukm,
    +        AlgorithmIdentifier         keyEncryptionAlgorithm,
    +        ASN1Sequence                recipientEncryptedKeys)
    +    {
    +        this.version = new ASN1Integer(3);
    +        this.originator = originator;
    +        this.ukm = ukm;
    +        this.keyEncryptionAlgorithm = keyEncryptionAlgorithm;
    +        this.recipientEncryptedKeys = recipientEncryptedKeys;
    +    }
    +    
    +    public KeyAgreeRecipientInfo(
    +        ASN1Sequence seq)
    +    {
    +        int index = 0;
    +        
    +        version = (ASN1Integer)seq.getObjectAt(index++);
    +        originator = OriginatorIdentifierOrKey.getInstance(
    +                            (ASN1TaggedObject)seq.getObjectAt(index++), true);
    +
    +        if (seq.getObjectAt(index) instanceof ASN1TaggedObject)
    +        {
    +            ukm = ASN1OctetString.getInstance(
    +                            (ASN1TaggedObject)seq.getObjectAt(index++), true);
    +        }
    +
    +        keyEncryptionAlgorithm = AlgorithmIdentifier.getInstance(
    +                                                seq.getObjectAt(index++));
    +
    +        recipientEncryptedKeys = (ASN1Sequence)seq.getObjectAt(index++);
    +    }
    +    
    +    /**
    +     * return a KeyAgreeRecipientInfo object from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want.
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the object held by the
    +     *          tagged object cannot be converted.
    +     */
    +    public static KeyAgreeRecipientInfo getInstance(
    +        ASN1TaggedObject    obj,
    +        boolean             explicit)
    +    {
    +        return getInstance(ASN1Sequence.getInstance(obj, explicit));
    +    }
    +    
    +    /**
    +     * return a KeyAgreeRecipientInfo object from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static KeyAgreeRecipientInfo getInstance(
    +        Object obj)
    +    {
    +        if (obj == null || obj instanceof KeyAgreeRecipientInfo)
    +        {
    +            return (KeyAgreeRecipientInfo)obj;
    +        }
    +        
    +        if (obj instanceof ASN1Sequence)
    +        {
    +            return new KeyAgreeRecipientInfo((ASN1Sequence)obj);
    +        }
    +        
    +        throw new IllegalArgumentException(
    +        "Illegal object in KeyAgreeRecipientInfo: " + obj.getClass().getName());
    +
    +    } 
    +
    +    public ASN1Integer getVersion()
    +    {
    +        return version;
    +    }
    +
    +    public OriginatorIdentifierOrKey getOriginator()
    +    {
    +        return originator;
    +    }
    +
    +    public ASN1OctetString getUserKeyingMaterial()
    +    {
    +        return ukm;
    +    }
    +
    +    public AlgorithmIdentifier getKeyEncryptionAlgorithm()
    +    {
    +        return keyEncryptionAlgorithm;
    +    }
    +
    +    public ASN1Sequence getRecipientEncryptedKeys()
    +    {
    +        return recipientEncryptedKeys;
    +    }
    +
    +    /** 
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * KeyAgreeRecipientInfo ::= SEQUENCE {
    +     *     version CMSVersion,  -- always set to 3
    +     *     originator [0] EXPLICIT OriginatorIdentifierOrKey,
    +     *     ukm [1] EXPLICIT UserKeyingMaterial OPTIONAL,
    +     *     keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
    +     *     recipientEncryptedKeys RecipientEncryptedKeys 
    +     * }
    +     *
    +     * UserKeyingMaterial ::= OCTET STRING
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector  v = new ASN1EncodableVector();
    +
    +        v.add(version);
    +        v.add(new DERTaggedObject(true, 0, originator));
    +        
    +        if (ukm != null)
    +        {
    +            v.add(new DERTaggedObject(true, 1, ukm));
    +        }
    +        
    +        v.add(keyEncryptionAlgorithm);
    +        v.add(recipientEncryptedKeys);
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/KeyTransRecipientInfo.java+114 0 added
    @@ -0,0 +1,114 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
    +
    +public class KeyTransRecipientInfo
    +    extends ASN1Object
    +{
    +    private ASN1Integer          version;
    +    private RecipientIdentifier rid;
    +    private AlgorithmIdentifier keyEncryptionAlgorithm;
    +    private ASN1OctetString     encryptedKey;
    +
    +    public KeyTransRecipientInfo(
    +        RecipientIdentifier rid,
    +        AlgorithmIdentifier keyEncryptionAlgorithm,
    +        ASN1OctetString     encryptedKey)
    +    {
    +        if (rid.toASN1Primitive() instanceof ASN1TaggedObject)
    +        {
    +            this.version = new ASN1Integer(2);
    +        }
    +        else
    +        {
    +            this.version = new ASN1Integer(0);
    +        }
    +
    +        this.rid = rid;
    +        this.keyEncryptionAlgorithm = keyEncryptionAlgorithm;
    +        this.encryptedKey = encryptedKey;
    +    }
    +    
    +    public KeyTransRecipientInfo(
    +        ASN1Sequence seq)
    +    {
    +        this.version = (ASN1Integer)seq.getObjectAt(0);
    +        this.rid = RecipientIdentifier.getInstance(seq.getObjectAt(1));
    +        this.keyEncryptionAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(2));
    +        this.encryptedKey = (ASN1OctetString)seq.getObjectAt(3);
    +    }
    +
    +    /**
    +     * return a KeyTransRecipientInfo object from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static KeyTransRecipientInfo getInstance(
    +        Object obj)
    +    {
    +        if (obj == null || obj instanceof KeyTransRecipientInfo)
    +        {
    +            return (KeyTransRecipientInfo)obj;
    +        }
    +        
    +        if(obj instanceof ASN1Sequence)
    +        {
    +            return new KeyTransRecipientInfo((ASN1Sequence)obj);
    +        }
    +        
    +        throw new IllegalArgumentException(
    +        "Illegal object in KeyTransRecipientInfo: " + obj.getClass().getName());
    +    } 
    +
    +    public ASN1Integer getVersion()
    +    {
    +        return version;
    +    }
    +
    +    public RecipientIdentifier getRecipientIdentifier()
    +    {
    +        return rid;
    +    }
    +
    +    public AlgorithmIdentifier getKeyEncryptionAlgorithm()
    +    {
    +        return keyEncryptionAlgorithm;
    +    }
    +
    +    public ASN1OctetString getEncryptedKey()
    +    {
    +        return encryptedKey;
    +    }
    +
    +    /** 
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * KeyTransRecipientInfo ::= SEQUENCE {
    +     *     version CMSVersion,  -- always set to 0 or 2
    +     *     rid RecipientIdentifier,
    +     *     keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
    +     *     encryptedKey EncryptedKey 
    +     * }
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector  v = new ASN1EncodableVector();
    +
    +        v.add(version);
    +        v.add(rid);
    +        v.add(keyEncryptionAlgorithm);
    +        v.add(encryptedKey);
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/MetaData.java+120 0 added
    @@ -0,0 +1,120 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1Boolean;
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DERIA5String;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.DERUTF8String;
    +
    +public class MetaData
    +    extends ASN1Object
    +{
    +    private ASN1Boolean hashProtected;
    +    private DERUTF8String fileName;
    +    private DERIA5String  mediaType;
    +    private Attributes otherMetaData;
    +
    +    public MetaData(
    +        ASN1Boolean hashProtected,
    +        DERUTF8String fileName,
    +        DERIA5String mediaType,
    +        Attributes otherMetaData)
    +    {
    +        this.hashProtected = hashProtected;
    +        this.fileName = fileName;
    +        this.mediaType = mediaType;
    +        this.otherMetaData = otherMetaData;
    +    }
    +
    +    private MetaData(ASN1Sequence seq)
    +    {
    +        this.hashProtected = ASN1Boolean.getInstance(seq.getObjectAt(0));
    +
    +        int index = 1;
    +
    +        if (index < seq.size() && seq.getObjectAt(index) instanceof DERUTF8String)
    +        {
    +            this.fileName = DERUTF8String.getInstance(seq.getObjectAt(index++));
    +        }
    +        if (index < seq.size() && seq.getObjectAt(index) instanceof DERIA5String)
    +        {
    +            this.mediaType = DERIA5String.getInstance(seq.getObjectAt(index++));
    +        }
    +        if (index < seq.size())
    +        {
    +            this.otherMetaData = Attributes.getInstance(seq.getObjectAt(index++));
    +        }
    +    }
    +
    +    public static MetaData getInstance(Object obj)
    +    {
    +        if (obj instanceof MetaData)
    +        {
    +            return (MetaData)obj;
    +        }
    +        else if (obj != null)
    +        {
    +            return new MetaData(ASN1Sequence.getInstance(obj));
    +        }
    +
    +        return null;
    +    }
    +
    +    /**
    +     * <pre>
    +     * MetaData ::= SEQUENCE {
    +     *   hashProtected        BOOLEAN,
    +     *   fileName             UTF8String OPTIONAL,
    +     *   mediaType            IA5String OPTIONAL,
    +     *   otherMetaData        Attributes OPTIONAL
    +     * }
    +     * </pre>
    +     * @return
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(hashProtected);
    +
    +        if (fileName != null)
    +        {
    +            v.add(fileName);
    +        }
    +
    +        if (mediaType != null)
    +        {
    +            v.add(mediaType);
    +        }
    +
    +        if (otherMetaData != null)
    +        {
    +            v.add(otherMetaData);
    +        }
    +        
    +        return new DERSequence(v);
    +    }
    +
    +    public boolean isHashProtected()
    +    {
    +        return hashProtected.isTrue();
    +    }
    +
    +    public DERUTF8String getFileName()
    +    {
    +        return this.fileName;
    +    }
    +
    +    public DERIA5String getMediaType()
    +    {
    +        return this.mediaType;
    +    }
    +
    +    public Attributes getOtherMetaData()
    +    {
    +        return otherMetaData;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/OriginatorIdentifierOrKey.java+165 0 added
    @@ -0,0 +1,165 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1Choice;
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
    +
    +public class OriginatorIdentifierOrKey
    +    extends ASN1Object
    +    implements ASN1Choice
    +{
    +    private ASN1Encodable id;
    +
    +    public OriginatorIdentifierOrKey(
    +        IssuerAndSerialNumber id)
    +    {
    +        this.id = id;
    +    }
    +
    +    /**
    +     * @deprecated use version taking a SubjectKeyIdentifier
    +     */
    +    public OriginatorIdentifierOrKey(
    +        ASN1OctetString id)
    +    {
    +        this(new SubjectKeyIdentifier(id.getOctets()));
    +    }
    +
    +    public OriginatorIdentifierOrKey(
    +        SubjectKeyIdentifier id)
    +    {
    +        this.id = new DERTaggedObject(false, 0, id);
    +    }
    +
    +    public OriginatorIdentifierOrKey(
    +        OriginatorPublicKey id)
    +    {
    +        this.id = new DERTaggedObject(false, 1, id);
    +    }
    +
    +    /**
    +     * @deprecated use more specific version
    +     */
    +    public OriginatorIdentifierOrKey(
    +        ASN1Primitive id)
    +    {
    +        this.id = id;
    +    }
    +
    +    /**
    +     * return an OriginatorIdentifierOrKey object from a tagged object.
    +     *
    +     * @param o the tagged object holding the object we want.
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the object held by the
    +     *          tagged object cannot be converted.
    +     */
    +    public static OriginatorIdentifierOrKey getInstance(
    +        ASN1TaggedObject    o,
    +        boolean             explicit)
    +    {
    +        if (!explicit)
    +        {
    +            throw new IllegalArgumentException(
    +                    "Can't implicitly tag OriginatorIdentifierOrKey");
    +        }
    +
    +        return getInstance(o.getObject());
    +    }
    +    
    +    /**
    +     * return an OriginatorIdentifierOrKey object from the given object.
    +     *
    +     * @param o the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static OriginatorIdentifierOrKey getInstance(
    +        Object o)
    +    {
    +        if (o == null || o instanceof OriginatorIdentifierOrKey)
    +        {
    +            return (OriginatorIdentifierOrKey)o;
    +        }
    +
    +        if (o instanceof IssuerAndSerialNumber)
    +        {
    +            return new OriginatorIdentifierOrKey((IssuerAndSerialNumber)o);
    +        }
    +
    +        if (o instanceof SubjectKeyIdentifier)
    +        {
    +            return new OriginatorIdentifierOrKey((SubjectKeyIdentifier)o);
    +        }
    +
    +        if (o instanceof OriginatorPublicKey)
    +        {
    +            return new OriginatorIdentifierOrKey((OriginatorPublicKey)o);
    +        }
    +
    +        if (o instanceof ASN1TaggedObject)
    +        {
    +            // TODO Add validation
    +            return new OriginatorIdentifierOrKey((ASN1TaggedObject)o);
    +        }
    +
    +        throw new IllegalArgumentException("Invalid OriginatorIdentifierOrKey: " + o.getClass().getName());
    +    }
    +
    +    public ASN1Encodable getId()
    +    {
    +        return id;
    +    }
    +
    +    public IssuerAndSerialNumber getIssuerAndSerialNumber()
    +    {
    +        if (id instanceof IssuerAndSerialNumber)
    +        {
    +            return (IssuerAndSerialNumber)id;
    +        }
    +
    +        return null;
    +    }
    +
    +    public SubjectKeyIdentifier getSubjectKeyIdentifier()
    +    {
    +        if (id instanceof ASN1TaggedObject && ((ASN1TaggedObject)id).getTagNo() == 0)
    +        {
    +            return SubjectKeyIdentifier.getInstance((ASN1TaggedObject)id, false);
    +        }
    +
    +        return null;
    +    }
    +
    +    public OriginatorPublicKey getOriginatorKey()
    +    {
    +        if (id instanceof ASN1TaggedObject && ((ASN1TaggedObject)id).getTagNo() == 1)
    +        {
    +            return OriginatorPublicKey.getInstance((ASN1TaggedObject)id, false);
    +        }
    +
    +        return null;
    +    }
    +
    +    /**
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * OriginatorIdentifierOrKey ::= CHOICE {
    +     *     issuerAndSerialNumber IssuerAndSerialNumber,
    +     *     subjectKeyIdentifier [0] SubjectKeyIdentifier,
    +     *     originatorKey [1] OriginatorPublicKey 
    +     * }
    +     *
    +     * SubjectKeyIdentifier ::= OCTET STRING
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        return id.toASN1Primitive();
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/OriginatorInfo.java+128 0 added
    @@ -0,0 +1,128 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1Set;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +
    +public class OriginatorInfo
    +    extends ASN1Object
    +{
    +    private ASN1Set certs;
    +    private ASN1Set crls;
    +    
    +    public OriginatorInfo(
    +        ASN1Set certs,
    +        ASN1Set crls)
    +    {
    +        this.certs = certs;
    +        this.crls = crls;
    +    }
    +    
    +    private OriginatorInfo(
    +        ASN1Sequence seq)
    +    {
    +        switch (seq.size())
    +        {
    +        case 0:     // empty
    +            break;
    +        case 1:
    +            ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(0);
    +            switch (o.getTagNo())
    +            {
    +            case 0 :
    +                certs = ASN1Set.getInstance(o, false);
    +                break;
    +            case 1 :
    +                crls = ASN1Set.getInstance(o, false);
    +                break;
    +            default:
    +                throw new IllegalArgumentException("Bad tag in OriginatorInfo: " + o.getTagNo());
    +            }
    +            break;
    +        case 2:
    +            certs = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(0), false);
    +            crls  = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(1), false);
    +            break;
    +        default:
    +            throw new IllegalArgumentException("OriginatorInfo too big");
    +        }
    +    }
    +    
    +    /**
    +     * return an OriginatorInfo object from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want.
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the object held by the
    +     *          tagged object cannot be converted.
    +     */
    +    public static OriginatorInfo getInstance(
    +        ASN1TaggedObject    obj,
    +        boolean             explicit)
    +    {
    +        return getInstance(ASN1Sequence.getInstance(obj, explicit));
    +    }
    +    
    +    /**
    +     * return an OriginatorInfo object from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static OriginatorInfo getInstance(
    +        Object obj)
    +    {
    +        if (obj instanceof OriginatorInfo)
    +        {
    +            return (OriginatorInfo)obj;
    +        }
    +        else if (obj != null)
    +        {
    +            return new OriginatorInfo(ASN1Sequence.getInstance(obj));
    +        }
    +        
    +        return null;
    +    }
    +    
    +    public ASN1Set getCertificates()
    +    {
    +        return certs;
    +    }
    +
    +    public ASN1Set getCRLs()
    +    {
    +        return crls;
    +    }
    +
    +    /** 
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * OriginatorInfo ::= SEQUENCE {
    +     *     certs [0] IMPLICIT CertificateSet OPTIONAL,
    +     *     crls [1] IMPLICIT CertificateRevocationLists OPTIONAL 
    +     * }
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector  v = new ASN1EncodableVector();
    +
    +        if (certs != null)
    +        {
    +            v.add(new DERTaggedObject(false, 0, certs));
    +        }
    +        
    +        if (crls != null)
    +        {
    +            v.add(new DERTaggedObject(false, 1, crls));
    +        }
    +        
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/OriginatorPublicKey.java+100 0 added
    @@ -0,0 +1,100 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERBitString;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
    +
    +
    +public class OriginatorPublicKey
    +    extends ASN1Object
    +{
    +    private AlgorithmIdentifier algorithm;
    +    private DERBitString        publicKey;
    +    
    +    public OriginatorPublicKey(
    +        AlgorithmIdentifier algorithm,
    +        byte[]              publicKey)
    +    {
    +        this.algorithm = algorithm;
    +        this.publicKey = new DERBitString(publicKey);
    +    }
    +    
    +    public OriginatorPublicKey(
    +        ASN1Sequence seq)
    +    {
    +        algorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(0));
    +        publicKey = (DERBitString)seq.getObjectAt(1);
    +    }
    +    
    +    /**
    +     * return an OriginatorPublicKey object from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want.
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the object held by the
    +     *          tagged object cannot be converted.
    +     */
    +    public static OriginatorPublicKey getInstance(
    +        ASN1TaggedObject    obj,
    +        boolean             explicit)
    +    {
    +        return getInstance(ASN1Sequence.getInstance(obj, explicit));
    +    }
    +    
    +    /**
    +     * return an OriginatorPublicKey object from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static OriginatorPublicKey getInstance(
    +        Object obj)
    +    {
    +        if (obj == null || obj instanceof OriginatorPublicKey)
    +        {
    +            return (OriginatorPublicKey)obj;
    +        }
    +        
    +        if (obj instanceof ASN1Sequence)
    +        {
    +            return new OriginatorPublicKey((ASN1Sequence)obj);
    +        }
    +        
    +        throw new IllegalArgumentException("Invalid OriginatorPublicKey: " + obj.getClass().getName());
    +    } 
    +
    +    public AlgorithmIdentifier getAlgorithm()
    +    {
    +        return algorithm;
    +    }
    +
    +    public DERBitString getPublicKey()
    +    {
    +        return publicKey;
    +    }
    +
    +    /** 
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * OriginatorPublicKey ::= SEQUENCE {
    +     *     algorithm AlgorithmIdentifier,
    +     *     publicKey BIT STRING 
    +     * }
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector  v = new ASN1EncodableVector();
    +
    +        v.add(algorithm);
    +        v.add(publicKey);
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/OtherKeyAttribute.java+82 0 added
    @@ -0,0 +1,82 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1ObjectIdentifier;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +public class OtherKeyAttribute
    +    extends ASN1Object
    +{
    +    private ASN1ObjectIdentifier keyAttrId;
    +    private ASN1Encodable        keyAttr;
    +
    +    /**
    +     * return an OtherKeyAttribute object from the given object.
    +     *
    +     * @param o the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static OtherKeyAttribute getInstance(
    +        Object o)
    +    {
    +        if (o == null || o instanceof OtherKeyAttribute)
    +        {
    +            return (OtherKeyAttribute)o;
    +        }
    +        
    +        if (o instanceof ASN1Sequence)
    +        {
    +            return new OtherKeyAttribute((ASN1Sequence)o);
    +        }
    +
    +        throw new IllegalArgumentException("unknown object in factory: " + o.getClass().getName());
    +    }
    +    
    +    public OtherKeyAttribute(
    +        ASN1Sequence seq)
    +    {
    +        keyAttrId = (ASN1ObjectIdentifier)seq.getObjectAt(0);
    +        keyAttr = seq.getObjectAt(1);
    +    }
    +
    +    public OtherKeyAttribute(
    +        ASN1ObjectIdentifier keyAttrId,
    +        ASN1Encodable        keyAttr)
    +    {
    +        this.keyAttrId = keyAttrId;
    +        this.keyAttr = keyAttr;
    +    }
    +
    +    public ASN1ObjectIdentifier getKeyAttrId()
    +    {
    +        return keyAttrId;
    +    }
    +    
    +    public ASN1Encodable getKeyAttr()
    +    {
    +        return keyAttr;
    +    }
    +
    +    /** 
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * OtherKeyAttribute ::= SEQUENCE {
    +     *     keyAttrId OBJECT IDENTIFIER,
    +     *     keyAttr ANY DEFINED BY keyAttrId OPTIONAL
    +     * }
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(keyAttrId);
    +        v.add(keyAttr);
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/OtherRecipientInfo.java+102 0 added
    @@ -0,0 +1,102 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1ObjectIdentifier;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +public class OtherRecipientInfo
    +    extends ASN1Object
    +{
    +    private ASN1ObjectIdentifier    oriType;
    +    private ASN1Encodable           oriValue;
    +
    +    public OtherRecipientInfo(
    +        ASN1ObjectIdentifier     oriType,
    +        ASN1Encodable            oriValue)
    +    {
    +        this.oriType = oriType;
    +        this.oriValue = oriValue;
    +    }
    +
    +    /**
    +     * @deprecated use getInstance().
    +     * @param seq
    +     */
    +    public OtherRecipientInfo(
    +        ASN1Sequence seq)
    +    {
    +        oriType = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
    +        oriValue = seq.getObjectAt(1);
    +    }
    +
    +    /**
    +     * return a OtherRecipientInfo object from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want.
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the object held by the
    +     *          tagged object cannot be converted.
    +     */
    +    public static OtherRecipientInfo getInstance(
    +        ASN1TaggedObject    obj,
    +        boolean             explicit)
    +    {
    +        return getInstance(ASN1Sequence.getInstance(obj, explicit));
    +    }
    +    
    +    /**
    +     * return a OtherRecipientInfo object from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static OtherRecipientInfo getInstance(
    +        Object obj)
    +    {
    +        if (obj instanceof OtherRecipientInfo)
    +        {
    +            return (OtherRecipientInfo)obj;
    +        }
    +        
    +        if (obj != null)
    +        {
    +            return new OtherRecipientInfo(ASN1Sequence.getInstance(obj));
    +        }
    +        
    +        return null;
    +    }
    +
    +    public ASN1ObjectIdentifier getType()
    +    {
    +        return oriType;
    +    }
    +
    +    public ASN1Encodable getValue()
    +    {
    +        return oriValue;
    +    }
    +
    +    /** 
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * OtherRecipientInfo ::= SEQUENCE {
    +     *    oriType OBJECT IDENTIFIER,
    +     *    oriValue ANY DEFINED BY oriType }
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector  v = new ASN1EncodableVector();
    +
    +        v.add(oriType);
    +        v.add(oriValue);
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/OtherRevocationInfoFormat.java+98 0 added
    @@ -0,0 +1,98 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1ObjectIdentifier;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +public class OtherRevocationInfoFormat
    +    extends ASN1Object
    +{
    +    private ASN1ObjectIdentifier otherRevInfoFormat;
    +    private ASN1Encodable otherRevInfo;
    +
    +    public OtherRevocationInfoFormat(
    +        ASN1ObjectIdentifier otherRevInfoFormat,
    +        ASN1Encodable otherRevInfo)
    +    {
    +        this.otherRevInfoFormat = otherRevInfoFormat;
    +        this.otherRevInfo = otherRevInfo;
    +    }
    +
    +    private OtherRevocationInfoFormat(
    +        ASN1Sequence seq)
    +    {
    +        otherRevInfoFormat = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
    +        otherRevInfo = seq.getObjectAt(1);
    +    }
    +
    +    /**
    +     * return a OtherRevocationInfoFormat object from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want.
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the object held by the
    +     *          tagged object cannot be converted.
    +     */
    +    public static OtherRevocationInfoFormat getInstance(
    +        ASN1TaggedObject    obj,
    +        boolean             explicit)
    +    {
    +        return getInstance(ASN1Sequence.getInstance(obj, explicit));
    +    }
    +    
    +    /**
    +     * return a OtherRevocationInfoFormat object from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static OtherRevocationInfoFormat getInstance(
    +        Object obj)
    +    {
    +        if (obj instanceof OtherRevocationInfoFormat)
    +        {
    +            return (OtherRevocationInfoFormat)obj;
    +        }
    +        
    +        if (obj != null)
    +        {
    +            return new OtherRevocationInfoFormat(ASN1Sequence.getInstance(obj));
    +        }
    +        
    +        return null;
    +    }
    +
    +    public ASN1ObjectIdentifier getInfoFormat()
    +    {
    +        return otherRevInfoFormat;
    +    }
    +
    +    public ASN1Encodable getInfo()
    +    {
    +        return otherRevInfo;
    +    }
    +
    +    /** 
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * OtherRevocationInfoFormat ::= SEQUENCE {
    +     *      otherRevInfoFormat OBJECT IDENTIFIER,
    +     *      otherRevInfo ANY DEFINED BY otherRevInfoFormat }
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector  v = new ASN1EncodableVector();
    +
    +        v.add(otherRevInfoFormat);
    +        v.add(otherRevInfo);
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/PasswordRecipientInfo.java+143 0 added
    @@ -0,0 +1,143 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
    +
    +public class PasswordRecipientInfo
    +    extends ASN1Object
    +{
    +    private ASN1Integer          version;
    +    private AlgorithmIdentifier keyDerivationAlgorithm;
    +    private AlgorithmIdentifier keyEncryptionAlgorithm;
    +    private ASN1OctetString     encryptedKey;
    +
    +    public PasswordRecipientInfo(
    +        AlgorithmIdentifier     keyEncryptionAlgorithm,
    +        ASN1OctetString         encryptedKey)
    +    {
    +        this.version = new ASN1Integer(0);
    +        this.keyEncryptionAlgorithm = keyEncryptionAlgorithm;
    +        this.encryptedKey = encryptedKey;
    +    }
    +    
    +    public PasswordRecipientInfo(
    +        AlgorithmIdentifier     keyDerivationAlgorithm,
    +        AlgorithmIdentifier     keyEncryptionAlgorithm,
    +        ASN1OctetString         encryptedKey)
    +    {
    +        this.version = new ASN1Integer(0);
    +        this.keyDerivationAlgorithm = keyDerivationAlgorithm;
    +        this.keyEncryptionAlgorithm = keyEncryptionAlgorithm;
    +        this.encryptedKey = encryptedKey;
    +    }
    +    
    +    public PasswordRecipientInfo(
    +        ASN1Sequence seq)
    +    {
    +        version = (ASN1Integer)seq.getObjectAt(0);
    +        if (seq.getObjectAt(1) instanceof ASN1TaggedObject)
    +        {
    +            keyDerivationAlgorithm = AlgorithmIdentifier.getInstance((ASN1TaggedObject)seq.getObjectAt(1), false);
    +            keyEncryptionAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(2));
    +            encryptedKey = (ASN1OctetString)seq.getObjectAt(3);
    +        }
    +        else
    +        {
    +            keyEncryptionAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(1));
    +            encryptedKey = (ASN1OctetString)seq.getObjectAt(2);
    +        }
    +    }
    +
    +    /**
    +     * return a PasswordRecipientInfo object from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want.
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the object held by the
    +     *          tagged object cannot be converted.
    +     */
    +    public static PasswordRecipientInfo getInstance(
    +        ASN1TaggedObject    obj,
    +        boolean             explicit)
    +    {
    +        return getInstance(ASN1Sequence.getInstance(obj, explicit));
    +    }
    +    
    +    /**
    +     * return a PasswordRecipientInfo object from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static PasswordRecipientInfo getInstance(
    +        Object obj)
    +    {
    +        if (obj == null || obj instanceof PasswordRecipientInfo)
    +        {
    +            return (PasswordRecipientInfo)obj;
    +        }
    +        
    +        if(obj instanceof ASN1Sequence)
    +        {
    +            return new PasswordRecipientInfo((ASN1Sequence)obj);
    +        }
    +        
    +        throw new IllegalArgumentException("Invalid PasswordRecipientInfo: " + obj.getClass().getName());
    +    }
    +
    +    public ASN1Integer getVersion()
    +    {
    +        return version;
    +    }
    +
    +    public AlgorithmIdentifier getKeyDerivationAlgorithm()
    +    {
    +        return keyDerivationAlgorithm;
    +    }
    +
    +    public AlgorithmIdentifier getKeyEncryptionAlgorithm()
    +    {
    +        return keyEncryptionAlgorithm;
    +    }
    +
    +    public ASN1OctetString getEncryptedKey()
    +    {
    +        return encryptedKey;
    +    }
    +
    +    /** 
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * PasswordRecipientInfo ::= SEQUENCE {
    +     *   version CMSVersion,   -- Always set to 0
    +     *   keyDerivationAlgorithm [0] KeyDerivationAlgorithmIdentifier
    +     *                             OPTIONAL,
    +     *  keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
    +     *  encryptedKey EncryptedKey }
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector  v = new ASN1EncodableVector();
    +
    +        v.add(version);
    +        
    +        if (keyDerivationAlgorithm != null)
    +        {
    +            v.add(new DERTaggedObject(false, 0, keyDerivationAlgorithm));
    +        }
    +        v.add(keyEncryptionAlgorithm);
    +        v.add(encryptedKey);
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/RecipientEncryptedKey.java+99 0 added
    @@ -0,0 +1,99 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +
    +public class RecipientEncryptedKey
    +    extends ASN1Object
    +{
    +    private KeyAgreeRecipientIdentifier identifier;
    +    private ASN1OctetString encryptedKey;
    +
    +    private RecipientEncryptedKey(
    +        ASN1Sequence seq)
    +    {
    +        identifier = KeyAgreeRecipientIdentifier.getInstance(seq.getObjectAt(0));
    +        encryptedKey = (ASN1OctetString)seq.getObjectAt(1);
    +    }
    +    
    +    /**
    +     * return an RecipientEncryptedKey object from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want.
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the object held by the
    +     *          tagged object cannot be converted.
    +     */
    +    public static RecipientEncryptedKey getInstance(
    +        ASN1TaggedObject    obj,
    +        boolean             explicit)
    +    {
    +        return getInstance(ASN1Sequence.getInstance(obj, explicit));
    +    }
    +    
    +    /**
    +     * return a RecipientEncryptedKey object from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static RecipientEncryptedKey getInstance(
    +        Object obj)
    +    {
    +        if (obj == null || obj instanceof RecipientEncryptedKey)
    +        {
    +            return (RecipientEncryptedKey)obj;
    +        }
    +        
    +        if (obj instanceof ASN1Sequence)
    +        {
    +            return new RecipientEncryptedKey((ASN1Sequence)obj);
    +        }
    +        
    +        throw new IllegalArgumentException("Invalid RecipientEncryptedKey: " + obj.getClass().getName());
    +    } 
    +
    +    public RecipientEncryptedKey(
    +        KeyAgreeRecipientIdentifier id,
    +        ASN1OctetString             encryptedKey)
    +    {
    +        this.identifier = id;
    +        this.encryptedKey = encryptedKey;
    +    }
    +
    +    public KeyAgreeRecipientIdentifier getIdentifier()
    +    {
    +        return identifier;
    +    }
    +
    +    public ASN1OctetString getEncryptedKey()
    +    {
    +        return encryptedKey;
    +    }
    +
    +    /** 
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * RecipientEncryptedKey ::= SEQUENCE {
    +     *     rid KeyAgreeRecipientIdentifier,
    +     *     encryptedKey EncryptedKey
    +     * }
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector  v = new ASN1EncodableVector();
    +
    +        v.add(identifier);
    +        v.add(encryptedKey);
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/RecipientIdentifier.java+98 0 added
    @@ -0,0 +1,98 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1Choice;
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +
    +public class RecipientIdentifier
    +    extends ASN1Object
    +    implements ASN1Choice
    +{
    +    private ASN1Encodable id;
    +    
    +    public RecipientIdentifier(
    +        IssuerAndSerialNumber id)
    +    {
    +        this.id = id;
    +    }
    +    
    +    public RecipientIdentifier(
    +        ASN1OctetString id)
    +    {
    +        this.id = new DERTaggedObject(false, 0, id);
    +    }
    +    
    +    public RecipientIdentifier(
    +        ASN1Primitive id)
    +    {
    +        this.id = id;
    +    }
    +    
    +    /**
    +     * return a RecipientIdentifier object from the given object.
    +     *
    +     * @param o the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static RecipientIdentifier getInstance(
    +        Object o)
    +    {
    +        if (o == null || o instanceof RecipientIdentifier)
    +        {
    +            return (RecipientIdentifier)o;
    +        }
    +        
    +        if (o instanceof IssuerAndSerialNumber)
    +        {
    +            return new RecipientIdentifier((IssuerAndSerialNumber)o);
    +        }
    +        
    +        if (o instanceof ASN1OctetString)
    +        {
    +            return new RecipientIdentifier((ASN1OctetString)o);
    +        }
    +        
    +        if (o instanceof ASN1Primitive)
    +        {
    +            return new RecipientIdentifier((ASN1Primitive)o);
    +        }
    +        
    +        throw new IllegalArgumentException(
    +          "Illegal object in RecipientIdentifier: " + o.getClass().getName());
    +    } 
    +
    +    public boolean isTagged()
    +    {
    +        return (id instanceof ASN1TaggedObject);
    +    }
    +
    +    public ASN1Encodable getId()
    +    {
    +        if (id instanceof ASN1TaggedObject)
    +        {
    +            return ASN1OctetString.getInstance((ASN1TaggedObject)id, false);
    +        }
    +
    +        return IssuerAndSerialNumber.getInstance(id);
    +    }
    +
    +    /** 
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * RecipientIdentifier ::= CHOICE {
    +     *     issuerAndSerialNumber IssuerAndSerialNumber,
    +     *     subjectKeyIdentifier [0] SubjectKeyIdentifier 
    +     * }
    +     *
    +     * SubjectKeyIdentifier ::= OCTET STRING
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        return id.toASN1Primitive();
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/RecipientInfo.java+154 0 added
    @@ -0,0 +1,154 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1Choice;
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +
    +public class RecipientInfo
    +    extends ASN1Object
    +    implements ASN1Choice
    +{
    +    ASN1Encodable    info;
    +
    +    public RecipientInfo(
    +        KeyTransRecipientInfo info)
    +    {
    +        this.info = info;
    +    }
    +
    +    public RecipientInfo(
    +        KeyAgreeRecipientInfo info)
    +    {
    +        this.info = new DERTaggedObject(false, 1, info);
    +    }
    +
    +    public RecipientInfo(
    +        KEKRecipientInfo info)
    +    {
    +        this.info = new DERTaggedObject(false, 2, info);
    +    }
    +
    +    public RecipientInfo(
    +        PasswordRecipientInfo info)
    +    {
    +        this.info = new DERTaggedObject(false, 3, info);
    +    }
    +
    +    public RecipientInfo(
    +        OtherRecipientInfo info)
    +    {
    +        this.info = new DERTaggedObject(false, 4, info);
    +    }
    +
    +    public RecipientInfo(
    +        ASN1Primitive   info)
    +    {
    +        this.info = info;
    +    }
    +
    +    public static RecipientInfo getInstance(
    +        Object  o)
    +    {
    +        if (o == null || o instanceof RecipientInfo)
    +        {
    +            return (RecipientInfo)o;
    +        }
    +        else if (o instanceof ASN1Sequence)
    +        {
    +            return new RecipientInfo((ASN1Sequence)o);
    +        }
    +        else if (o instanceof ASN1TaggedObject)
    +        {
    +            return new RecipientInfo((ASN1TaggedObject)o);
    +        }
    +
    +        throw new IllegalArgumentException("unknown object in factory: "
    +                                                    + o.getClass().getName());
    +    }
    +
    +    public ASN1Integer getVersion()
    +    {
    +        if (info instanceof ASN1TaggedObject)
    +        {
    +            ASN1TaggedObject o = (ASN1TaggedObject)info;
    +
    +            switch (o.getTagNo())
    +            {
    +            case 1:
    +                return KeyAgreeRecipientInfo.getInstance(o, false).getVersion();
    +            case 2:
    +                return getKEKInfo(o).getVersion();
    +            case 3:
    +                return PasswordRecipientInfo.getInstance(o, false).getVersion();
    +            case 4:
    +                return new ASN1Integer(0);    // no syntax version for OtherRecipientInfo
    +            default:
    +                throw new IllegalStateException("unknown tag");
    +            }
    +        }
    +
    +        return KeyTransRecipientInfo.getInstance(info).getVersion();
    +    }
    +
    +    public boolean isTagged()
    +    {
    +        return (info instanceof ASN1TaggedObject);
    +    }
    +
    +    public ASN1Encodable getInfo()
    +    {
    +        if (info instanceof ASN1TaggedObject)
    +        {
    +            ASN1TaggedObject o = (ASN1TaggedObject)info;
    +
    +            switch (o.getTagNo())
    +            {
    +            case 1:
    +                return KeyAgreeRecipientInfo.getInstance(o, false);
    +            case 2:
    +                return getKEKInfo(o);
    +            case 3:
    +                return PasswordRecipientInfo.getInstance(o, false);
    +            case 4:
    +                return OtherRecipientInfo.getInstance(o, false);
    +            default:
    +                throw new IllegalStateException("unknown tag");
    +            }
    +        }
    +
    +        return KeyTransRecipientInfo.getInstance(info);
    +    }
    +
    +    private KEKRecipientInfo getKEKInfo(ASN1TaggedObject o)
    +    {
    +        if (o.isExplicit())
    +        {                        // compatibilty with erroneous version
    +            return KEKRecipientInfo.getInstance(o, true);
    +        }
    +        else
    +        {
    +            return KEKRecipientInfo.getInstance(o, false);
    +        }
    +    }
    +
    +    /**
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * RecipientInfo ::= CHOICE {
    +     *     ktri KeyTransRecipientInfo,
    +     *     kari [1] KeyAgreeRecipientInfo,
    +     *     kekri [2] KEKRecipientInfo,
    +     *     pwri [3] PasswordRecipientInfo,
    +     *     ori [4] OtherRecipientInfo }
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        return info.toASN1Primitive();
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/RecipientKeyIdentifier.java+156 0 added
    @@ -0,0 +1,156 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERGeneralizedTime;
    +import org.bouncycastle.asn1.DEROctetString;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +public class RecipientKeyIdentifier
    +    extends ASN1Object
    +{
    +    private ASN1OctetString      subjectKeyIdentifier;
    +    private DERGeneralizedTime   date;
    +    private OtherKeyAttribute    other;
    +
    +    public RecipientKeyIdentifier(
    +        ASN1OctetString         subjectKeyIdentifier,
    +        DERGeneralizedTime      date,
    +        OtherKeyAttribute       other)
    +    {
    +        this.subjectKeyIdentifier = subjectKeyIdentifier;
    +        this.date = date;
    +        this.other = other;
    +    }
    +
    +    public RecipientKeyIdentifier(
    +        byte[]                  subjectKeyIdentifier,
    +        DERGeneralizedTime      date,
    +        OtherKeyAttribute       other)
    +    {
    +        this.subjectKeyIdentifier = new DEROctetString(subjectKeyIdentifier);
    +        this.date = date;
    +        this.other = other;
    +    }
    +
    +    public RecipientKeyIdentifier(
    +        byte[]         subjectKeyIdentifier)
    +    {
    +        this(subjectKeyIdentifier, null, null);
    +    }
    +
    +    public RecipientKeyIdentifier(
    +        ASN1Sequence seq)
    +    {
    +        subjectKeyIdentifier = ASN1OctetString.getInstance(
    +                                                    seq.getObjectAt(0));
    +        
    +        switch(seq.size())
    +        {
    +        case 1:
    +            break;
    +        case 2:
    +            if (seq.getObjectAt(1) instanceof DERGeneralizedTime)
    +            {
    +                date = (DERGeneralizedTime)seq.getObjectAt(1); 
    +            }
    +            else
    +            {
    +                other = OtherKeyAttribute.getInstance(seq.getObjectAt(2));
    +            }
    +            break;
    +        case 3:
    +            date  = (DERGeneralizedTime)seq.getObjectAt(1);
    +            other = OtherKeyAttribute.getInstance(seq.getObjectAt(2));
    +            break;
    +        default:
    +            throw new IllegalArgumentException("Invalid RecipientKeyIdentifier");
    +        }
    +    }
    +
    +    /**
    +     * return a RecipientKeyIdentifier object from a tagged object.
    +     *
    +     * @param _ato the tagged object holding the object we want.
    +     * @param _explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the object held by the
    +     *          tagged object cannot be converted.
    +     */
    +    public static RecipientKeyIdentifier getInstance(ASN1TaggedObject _ato, boolean _explicit)
    +    {
    +        return getInstance(ASN1Sequence.getInstance(_ato, _explicit));
    +    }
    +    
    +    /**
    +     * return a RecipientKeyIdentifier object from the given object.
    +     *
    +     * @param _obj the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static RecipientKeyIdentifier getInstance(Object _obj)
    +    {
    +        if(_obj == null || _obj instanceof RecipientKeyIdentifier)
    +        {
    +            return (RecipientKeyIdentifier)_obj;
    +        }
    +        
    +        if(_obj instanceof ASN1Sequence)
    +        {
    +            return new RecipientKeyIdentifier((ASN1Sequence)_obj);
    +        }
    +        
    +        throw new IllegalArgumentException("Invalid RecipientKeyIdentifier: " + _obj.getClass().getName());
    +    } 
    +
    +    public ASN1OctetString getSubjectKeyIdentifier()
    +    {
    +        return subjectKeyIdentifier;
    +    }
    +
    +    public DERGeneralizedTime getDate()
    +    {
    +        return date;
    +    }
    +
    +    public OtherKeyAttribute getOtherKeyAttribute()
    +    {
    +        return other;
    +    }
    +
    +
    +    /** 
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * RecipientKeyIdentifier ::= SEQUENCE {
    +     *     subjectKeyIdentifier SubjectKeyIdentifier,
    +     *     date GeneralizedTime OPTIONAL,
    +     *     other OtherKeyAttribute OPTIONAL 
    +     * }
    +     *
    +     * SubjectKeyIdentifier ::= OCTET STRING
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector  v = new ASN1EncodableVector();
    +
    +        v.add(subjectKeyIdentifier);
    +        
    +        if (date != null)
    +        {
    +            v.add(date);
    +        }
    +
    +        if (other != null)
    +        {
    +            v.add(other);
    +        }
    +        
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/SCVPReqRes.java+90 0 added
    @@ -0,0 +1,90 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +
    +public class SCVPReqRes
    +    extends ASN1Object
    +{
    +    private final ContentInfo request;
    +    private final ContentInfo response;
    +
    +    public static SCVPReqRes getInstance(
    +        Object  obj)
    +    {
    +        if (obj instanceof SCVPReqRes)
    +        {
    +            return (SCVPReqRes)obj;
    +        }
    +        else if (obj != null)
    +        {
    +            return new SCVPReqRes(ASN1Sequence.getInstance(obj));
    +        }
    +
    +        return null;
    +    }
    +
    +    private SCVPReqRes(
    +        ASN1Sequence seq)
    +    {
    +        if (seq.getObjectAt(0) instanceof ASN1TaggedObject)
    +        {
    +            this.request = ContentInfo.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(0)), true);
    +            this.response = ContentInfo.getInstance(seq.getObjectAt(1));
    +        }
    +        else
    +        {
    +            this.request = null;
    +            this.response = ContentInfo.getInstance(seq.getObjectAt(0));
    +        }
    +    }
    +
    +    public SCVPReqRes(ContentInfo response)
    +    {
    +        this.request = null;       // use of this confuses earlier JDKs
    +        this.response = response;
    +    }
    +
    +    public SCVPReqRes(ContentInfo request, ContentInfo response)
    +    {
    +        this.request = request;
    +        this.response = response;
    +    }
    +
    +    public ContentInfo getRequest()
    +    {
    +        return request;
    +    }
    +
    +    public ContentInfo getResponse()
    +    {
    +        return response;
    +    }
    +
    +    /**
    +     * <pre>
    +     *    SCVPReqRes ::= SEQUENCE {
    +     *    request  [0] EXPLICIT ContentInfo OPTIONAL,
    +     *    response     ContentInfo }
    +     * </pre>
    +     * @return  the ASN.1 primitive representation.
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector    v = new ASN1EncodableVector();
    +
    +        if (request != null)
    +        {
    +            v.add(new DERTaggedObject(true, 0, request));
    +        }
    +
    +        v.add(response);
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/SignedData.java+307 0 added
    @@ -0,0 +1,307 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import java.util.Enumeration;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1ObjectIdentifier;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1Set;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.BERSequence;
    +import org.bouncycastle.asn1.BERSet;
    +import org.bouncycastle.asn1.BERTaggedObject;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +
    +/**
    + * a signed data object.
    + */
    +public class SignedData
    +    extends ASN1Object
    +{
    +    private static final ASN1Integer VERSION_1 = new ASN1Integer(1);
    +    private static final ASN1Integer VERSION_3 = new ASN1Integer(3);
    +    private static final ASN1Integer VERSION_4 = new ASN1Integer(4);
    +    private static final ASN1Integer VERSION_5 = new ASN1Integer(5);
    +
    +    private ASN1Integer version;
    +    private ASN1Set     digestAlgorithms;
    +    private ContentInfo contentInfo;
    +    private ASN1Set     certificates;
    +    private ASN1Set     crls;
    +    private ASN1Set     signerInfos;
    +    private boolean certsBer;
    +    private boolean        crlsBer;
    +
    +    public static SignedData getInstance(
    +        Object  o)
    +    {
    +        if (o instanceof SignedData)
    +        {
    +            return (SignedData)o;
    +        }
    +        else if (o != null)
    +        {
    +            return new SignedData(ASN1Sequence.getInstance(o));
    +        }
    +
    +        return null;
    +    }
    +
    +    public SignedData(
    +        ASN1Set     digestAlgorithms,
    +        ContentInfo contentInfo,
    +        ASN1Set     certificates,
    +        ASN1Set     crls,
    +        ASN1Set     signerInfos)
    +    {
    +        this.version = calculateVersion(contentInfo.getContentType(), certificates, crls, signerInfos);
    +        this.digestAlgorithms = digestAlgorithms;
    +        this.contentInfo = contentInfo;
    +        this.certificates = certificates;
    +        this.crls = crls;
    +        this.signerInfos = signerInfos;
    +        this.crlsBer = crls instanceof BERSet;
    +        this.certsBer = certificates instanceof BERSet;
    +    }
    +
    +
    +    // RFC3852, section 5.1:
    +    // IF ((certificates is present) AND
    +    //    (any certificates with a type of other are present)) OR
    +    //    ((crls is present) AND
    +    //    (any crls with a type of other are present))
    +    // THEN version MUST be 5
    +    // ELSE
    +    //    IF (certificates is present) AND
    +    //       (any version 2 attribute certificates are present)
    +    //    THEN version MUST be 4
    +    //    ELSE
    +    //       IF ((certificates is present) AND
    +    //          (any version 1 attribute certificates are present)) OR
    +    //          (any SignerInfo structures are version 3) OR
    +    //          (encapContentInfo eContentType is other than id-data)
    +    //       THEN version MUST be 3
    +    //       ELSE version MUST be 1
    +    //
    +    private ASN1Integer calculateVersion(
    +        ASN1ObjectIdentifier contentOid,
    +        ASN1Set certs,
    +        ASN1Set crls,
    +        ASN1Set signerInfs)
    +    {
    +        boolean otherCert = false;
    +        boolean otherCrl = false;
    +        boolean attrCertV1Found = false;
    +        boolean attrCertV2Found = false;
    +
    +        if (certs != null)
    +        {
    +            for (Enumeration en = certs.getObjects(); en.hasMoreElements();)
    +            {
    +                Object obj = en.nextElement();
    +                if (obj instanceof ASN1TaggedObject)
    +                {
    +                    ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(obj);
    +
    +                    if (tagged.getTagNo() == 1)
    +                    {
    +                        attrCertV1Found = true;
    +                    }
    +                    else if (tagged.getTagNo() == 2)
    +                    {
    +                        attrCertV2Found = true;
    +                    }
    +                    else if (tagged.getTagNo() == 3)
    +                    {
    +                        otherCert = true;
    +                    }
    +                }
    +            }
    +        }
    +
    +        if (otherCert)
    +        {
    +            return new ASN1Integer(5);
    +        }
    +
    +        if (crls != null)         // no need to check if otherCert is true
    +        {
    +            for (Enumeration en = crls.getObjects(); en.hasMoreElements();)
    +            {
    +                Object obj = en.nextElement();
    +                if (obj instanceof ASN1TaggedObject)
    +                {
    +                    otherCrl = true;
    +                }
    +            }
    +        }
    +
    +        if (otherCrl)
    +        {
    +            return VERSION_5;
    +        }
    +
    +        if (attrCertV2Found)
    +        {
    +            return VERSION_4;
    +        }
    +
    +        if (attrCertV1Found)
    +        {
    +            return VERSION_3;
    +        }
    +
    +        if (checkForVersion3(signerInfs))
    +        {
    +            return VERSION_3;
    +        }
    +
    +        if (!CMSObjectIdentifiers.data.equals(contentOid))
    +        {
    +            return VERSION_3;
    +        }
    +
    +        return VERSION_1;
    +    }
    +
    +    private boolean checkForVersion3(ASN1Set signerInfs)
    +    {
    +        for (Enumeration e = signerInfs.getObjects(); e.hasMoreElements();)
    +        {
    +            SignerInfo s = SignerInfo.getInstance(e.nextElement());
    +
    +            if (s.getVersion().getValue().intValue() == 3)
    +            {
    +                return true;
    +            }
    +        }
    +
    +        return false;
    +    }
    +
    +    private SignedData(
    +        ASN1Sequence seq)
    +    {
    +        Enumeration     e = seq.getObjects();
    +
    +        version = ASN1Integer.getInstance(e.nextElement());
    +        digestAlgorithms = ((ASN1Set)e.nextElement());
    +        contentInfo = ContentInfo.getInstance(e.nextElement());
    +
    +        while (e.hasMoreElements())
    +        {
    +            ASN1Primitive o = (ASN1Primitive)e.nextElement();
    +
    +            //
    +            // an interesting feature of SignedData is that there appear
    +            // to be varying implementations...
    +            // for the moment we ignore anything which doesn't fit.
    +            //
    +            if (o instanceof ASN1TaggedObject)
    +            {
    +                ASN1TaggedObject tagged = (ASN1TaggedObject)o;
    +
    +                switch (tagged.getTagNo())
    +                {
    +                case 0:
    +                    certsBer = tagged instanceof BERTaggedObject;
    +                    certificates = ASN1Set.getInstance(tagged, false);
    +                    break;
    +                case 1:
    +                    crlsBer = tagged instanceof BERTaggedObject;
    +                    crls = ASN1Set.getInstance(tagged, false);
    +                    break;
    +                default:
    +                    throw new IllegalArgumentException("unknown tag value " + tagged.getTagNo());
    +                }
    +            }
    +            else
    +            {
    +                signerInfos = (ASN1Set)o;
    +            }
    +        }
    +    }
    +
    +    public ASN1Integer getVersion()
    +    {
    +        return version;
    +    }
    +
    +    public ASN1Set getDigestAlgorithms()
    +    {
    +        return digestAlgorithms;
    +    }
    +
    +    public ContentInfo getEncapContentInfo()
    +    {
    +        return contentInfo;
    +    }
    +
    +    public ASN1Set getCertificates()
    +    {
    +        return certificates;
    +    }
    +
    +    public ASN1Set getCRLs()
    +    {
    +        return crls;
    +    }
    +
    +    public ASN1Set getSignerInfos()
    +    {
    +        return signerInfos;
    +    }
    +
    +    /**
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * SignedData ::= SEQUENCE {
    +     *     version CMSVersion,
    +     *     digestAlgorithms DigestAlgorithmIdentifiers,
    +     *     encapContentInfo EncapsulatedContentInfo,
    +     *     certificates [0] IMPLICIT CertificateSet OPTIONAL,
    +     *     crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
    +     *     signerInfos SignerInfos
    +     *   }
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector  v = new ASN1EncodableVector();
    +
    +        v.add(version);
    +        v.add(digestAlgorithms);
    +        v.add(contentInfo);
    +
    +        if (certificates != null)
    +        {
    +            if (certsBer)
    +            {
    +                v.add(new BERTaggedObject(false, 0, certificates));
    +            }
    +            else
    +            {
    +                v.add(new DERTaggedObject(false, 0, certificates));
    +            }
    +        }
    +
    +        if (crls != null)
    +        {
    +            if (crlsBer)
    +            {
    +                v.add(new BERTaggedObject(false, 1, crls));
    +            }
    +            else
    +            {
    +                v.add(new DERTaggedObject(false, 1, crls));
    +            }
    +        }
    +
    +        v.add(signerInfos);
    +
    +        return new BERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/SignedDataParser.java+139 0 added
    @@ -0,0 +1,139 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import java.io.IOException;
    +
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1SequenceParser;
    +import org.bouncycastle.asn1.ASN1Set;
    +import org.bouncycastle.asn1.ASN1SetParser;
    +import org.bouncycastle.asn1.ASN1TaggedObjectParser;
    +import org.bouncycastle.asn1.BERTags;
    +
    +/**
    + * <pre>
    + * SignedData ::= SEQUENCE {
    + *     version CMSVersion,
    + *     digestAlgorithms DigestAlgorithmIdentifiers,
    + *     encapContentInfo EncapsulatedContentInfo,
    + *     certificates [0] IMPLICIT CertificateSet OPTIONAL,
    + *     crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
    + *     signerInfos SignerInfos
    + *   }
    + * </pre>
    + */
    +public class SignedDataParser
    +{
    +    private ASN1SequenceParser _seq;
    +    private ASN1Integer         _version;
    +    private Object             _nextObject;
    +    private boolean            _certsCalled;
    +    private boolean            _crlsCalled;
    +
    +    public static SignedDataParser getInstance(
    +        Object o)
    +        throws IOException
    +    {
    +        if (o instanceof ASN1Sequence)
    +        {
    +            return new SignedDataParser(((ASN1Sequence)o).parser());
    +        }
    +        if (o instanceof ASN1SequenceParser)
    +        {
    +            return new SignedDataParser((ASN1SequenceParser)o);
    +        }
    +
    +        throw new IOException("unknown object encountered: " + o.getClass().getName());
    +    }
    +
    +    private SignedDataParser(
    +        ASN1SequenceParser seq)
    +        throws IOException
    +    {
    +        this._seq = seq;
    +        this._version = (ASN1Integer)seq.readObject();
    +    }
    +
    +    public ASN1Integer getVersion()
    +    {
    +        return _version;
    +    }
    +
    +    public ASN1SetParser getDigestAlgorithms()
    +        throws IOException
    +    {
    +        Object o = _seq.readObject();
    +
    +        if (o instanceof ASN1Set)
    +        {
    +            return ((ASN1Set)o).parser();
    +        }
    +
    +        return (ASN1SetParser)o;
    +    }
    +
    +    public ContentInfoParser getEncapContentInfo()
    +        throws IOException
    +    {
    +        return new ContentInfoParser((ASN1SequenceParser)_seq.readObject());
    +    }
    +
    +    public ASN1SetParser getCertificates()
    +        throws IOException
    +    {
    +        _certsCalled = true;
    +        _nextObject = _seq.readObject();
    +
    +        if (_nextObject instanceof ASN1TaggedObjectParser && ((ASN1TaggedObjectParser)_nextObject).getTagNo() == 0)
    +        {
    +            ASN1SetParser certs = (ASN1SetParser)((ASN1TaggedObjectParser)_nextObject).getObjectParser(BERTags.SET, false);
    +            _nextObject = null;
    +
    +            return certs;
    +        }
    +
    +        return null;
    +    }
    +
    +    public ASN1SetParser getCrls()
    +        throws IOException
    +    {
    +        if (!_certsCalled)
    +        {
    +            throw new IOException("getCerts() has not been called.");
    +        }
    +
    +        _crlsCalled = true;
    +
    +        if (_nextObject == null)
    +        {
    +            _nextObject = _seq.readObject();
    +        }
    +
    +        if (_nextObject instanceof ASN1TaggedObjectParser && ((ASN1TaggedObjectParser)_nextObject).getTagNo() == 1)
    +        {
    +            ASN1SetParser crls = (ASN1SetParser)((ASN1TaggedObjectParser)_nextObject).getObjectParser(BERTags.SET, false);
    +            _nextObject = null;
    +
    +            return crls;
    +        }
    +
    +        return null;
    +    }
    +
    +    public ASN1SetParser getSignerInfos()
    +        throws IOException
    +    {
    +        if (!_certsCalled || !_crlsCalled)
    +        {
    +            throw new IOException("getCerts() and/or getCrls() has not been called.");
    +        }
    +
    +        if (_nextObject == null)
    +        {
    +            _nextObject = _seq.readObject();
    +        }
    +
    +        return (ASN1SetParser)_nextObject;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/SignerIdentifier.java+98 0 added
    @@ -0,0 +1,98 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1Choice;
    +import org.bouncycastle.asn1.ASN1Encodable;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +
    +public class SignerIdentifier
    +    extends ASN1Object
    +    implements ASN1Choice
    +{
    +    private ASN1Encodable id;
    +    
    +    public SignerIdentifier(
    +        IssuerAndSerialNumber id)
    +    {
    +        this.id = id;
    +    }
    +    
    +    public SignerIdentifier(
    +        ASN1OctetString id)
    +    {
    +        this.id = new DERTaggedObject(false, 0, id);
    +    }
    +    
    +    public SignerIdentifier(
    +        ASN1Primitive id)
    +    {
    +        this.id = id;
    +    }
    +    
    +    /**
    +     * return a SignerIdentifier object from the given object.
    +     *
    +     * @param o the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static SignerIdentifier getInstance(
    +        Object o)
    +    {
    +        if (o == null || o instanceof SignerIdentifier)
    +        {
    +            return (SignerIdentifier)o;
    +        }
    +        
    +        if (o instanceof IssuerAndSerialNumber)
    +        {
    +            return new SignerIdentifier((IssuerAndSerialNumber)o);
    +        }
    +        
    +        if (o instanceof ASN1OctetString)
    +        {
    +            return new SignerIdentifier((ASN1OctetString)o);
    +        }
    +        
    +        if (o instanceof ASN1Primitive)
    +        {
    +            return new SignerIdentifier((ASN1Primitive)o);
    +        }
    +        
    +        throw new IllegalArgumentException(
    +             "Illegal object in SignerIdentifier: " + o.getClass().getName());
    +    } 
    +
    +    public boolean isTagged()
    +    {
    +        return (id instanceof ASN1TaggedObject);
    +    }
    +
    +    public ASN1Encodable getId()
    +    {
    +        if (id instanceof ASN1TaggedObject)
    +        {
    +            return ASN1OctetString.getInstance((ASN1TaggedObject)id, false);
    +        }
    +
    +        return id;
    +    }
    +
    +    /** 
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * SignerIdentifier ::= CHOICE {
    +     *     issuerAndSerialNumber IssuerAndSerialNumber,
    +     *     subjectKeyIdentifier [0] SubjectKeyIdentifier 
    +     * }
    +     *
    +     * SubjectKeyIdentifier ::= OCTET STRING
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        return id.toASN1Primitive();
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/SignerInfo.java+211 0 added
    @@ -0,0 +1,211 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import java.util.Enumeration;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1Set;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DEROctetString;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.DERTaggedObject;
    +import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
    +
    +public class SignerInfo
    +    extends ASN1Object
    +{
    +    private ASN1Integer              version;
    +    private SignerIdentifier        sid;
    +    private AlgorithmIdentifier     digAlgorithm;
    +    private ASN1Set                 authenticatedAttributes;
    +    private AlgorithmIdentifier     digEncryptionAlgorithm;
    +    private ASN1OctetString         encryptedDigest;
    +    private ASN1Set                 unauthenticatedAttributes;
    +
    +    public static SignerInfo getInstance(
    +        Object  o)
    +        throws IllegalArgumentException
    +    {
    +        if (o == null || o instanceof SignerInfo)
    +        {
    +            return (SignerInfo)o;
    +        }
    +        else if (o instanceof ASN1Sequence)
    +        {
    +            return new SignerInfo((ASN1Sequence)o);
    +        }
    +
    +        throw new IllegalArgumentException("unknown object in factory: " + o.getClass().getName());
    +    }
    +
    +    public SignerInfo(
    +        SignerIdentifier        sid,
    +        AlgorithmIdentifier     digAlgorithm,
    +        ASN1Set                 authenticatedAttributes,
    +        AlgorithmIdentifier     digEncryptionAlgorithm,
    +        ASN1OctetString         encryptedDigest,
    +        ASN1Set                 unauthenticatedAttributes)
    +    {
    +        if (sid.isTagged())
    +        {
    +            this.version = new ASN1Integer(3);
    +        }
    +        else
    +        {
    +            this.version = new ASN1Integer(1);
    +        }
    +
    +        this.sid = sid;
    +        this.digAlgorithm = digAlgorithm;
    +        this.authenticatedAttributes = authenticatedAttributes;
    +        this.digEncryptionAlgorithm = digEncryptionAlgorithm;
    +        this.encryptedDigest = encryptedDigest;
    +        this.unauthenticatedAttributes = unauthenticatedAttributes;
    +    }
    +
    +    public SignerInfo(
    +        SignerIdentifier        sid,
    +        AlgorithmIdentifier     digAlgorithm,
    +        Attributes              authenticatedAttributes,
    +        AlgorithmIdentifier     digEncryptionAlgorithm,
    +        ASN1OctetString         encryptedDigest,
    +        Attributes              unauthenticatedAttributes)
    +    {
    +        if (sid.isTagged())
    +        {
    +            this.version = new ASN1Integer(3);
    +        }
    +        else
    +        {
    +            this.version = new ASN1Integer(1);
    +        }
    +
    +        this.sid = sid;
    +        this.digAlgorithm = digAlgorithm;
    +        this.authenticatedAttributes = ASN1Set.getInstance(authenticatedAttributes);
    +        this.digEncryptionAlgorithm = digEncryptionAlgorithm;
    +        this.encryptedDigest = encryptedDigest;
    +        this.unauthenticatedAttributes = ASN1Set.getInstance(unauthenticatedAttributes);
    +    }
    +
    +    /**
    +     * @deprecated use getInstance() method.
    +     */
    +    public SignerInfo(
    +        ASN1Sequence seq)
    +    {
    +        Enumeration     e = seq.getObjects();
    +
    +        version = (ASN1Integer)e.nextElement();
    +        sid = SignerIdentifier.getInstance(e.nextElement());
    +        digAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement());
    +
    +        Object obj = e.nextElement();
    +
    +        if (obj instanceof ASN1TaggedObject)
    +        {
    +            authenticatedAttributes = ASN1Set.getInstance((ASN1TaggedObject)obj, false);
    +
    +            digEncryptionAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement());
    +        }
    +        else
    +        {
    +            authenticatedAttributes = null;
    +            digEncryptionAlgorithm = AlgorithmIdentifier.getInstance(obj);
    +        }
    +
    +        encryptedDigest = DEROctetString.getInstance(e.nextElement());
    +
    +        if (e.hasMoreElements())
    +        {
    +            unauthenticatedAttributes = ASN1Set.getInstance((ASN1TaggedObject)e.nextElement(), false);
    +        }
    +        else
    +        {
    +            unauthenticatedAttributes = null;
    +        }
    +    }
    +
    +    public ASN1Integer getVersion()
    +    {
    +        return version;
    +    }
    +
    +    public SignerIdentifier getSID()
    +    {
    +        return sid;
    +    }
    +
    +    public ASN1Set getAuthenticatedAttributes()
    +    {
    +        return authenticatedAttributes;
    +    }
    +
    +    public AlgorithmIdentifier getDigestAlgorithm()
    +    {
    +        return digAlgorithm;
    +    }
    +
    +    public ASN1OctetString getEncryptedDigest()
    +    {
    +        return encryptedDigest;
    +    }
    +
    +    public AlgorithmIdentifier getDigestEncryptionAlgorithm()
    +    {
    +        return digEncryptionAlgorithm;
    +    }
    +
    +    public ASN1Set getUnauthenticatedAttributes()
    +    {
    +        return unauthenticatedAttributes;
    +    }
    +
    +    /**
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     *  SignerInfo ::= SEQUENCE {
    +     *      version Version,
    +     *      SignerIdentifier sid,
    +     *      digestAlgorithm DigestAlgorithmIdentifier,
    +     *      authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL,
    +     *      digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
    +     *      encryptedDigest EncryptedDigest,
    +     *      unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL
    +     *  }
    +     *
    +     *  EncryptedDigest ::= OCTET STRING
    +     *
    +     *  DigestAlgorithmIdentifier ::= AlgorithmIdentifier
    +     *
    +     *  DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(version);
    +        v.add(sid);
    +        v.add(digAlgorithm);
    +
    +        if (authenticatedAttributes != null)
    +        {
    +            v.add(new DERTaggedObject(false, 0, authenticatedAttributes));
    +        }
    +
    +        v.add(digEncryptionAlgorithm);
    +        v.add(encryptedDigest);
    +
    +        if (unauthenticatedAttributes != null)
    +        {
    +            v.add(new DERTaggedObject(false, 1, unauthenticatedAttributes));
    +        }
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/Time.java+128 0 added
    @@ -0,0 +1,128 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import java.text.ParseException;
    +import java.text.SimpleDateFormat;
    +import java.util.Date;
    +import java.util.SimpleTimeZone;
    +
    +import org.bouncycastle.asn1.ASN1Choice;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERGeneralizedTime;
    +import org.bouncycastle.asn1.DERUTCTime;
    +
    +public class Time
    +    extends ASN1Object
    +    implements ASN1Choice
    +{
    +    ASN1Primitive time;
    +
    +    public static Time getInstance(
    +        ASN1TaggedObject obj,
    +        boolean          explicit)
    +    {
    +        return getInstance(obj.getObject());
    +    }
    +
    +    public Time(
    +        ASN1Primitive   time)
    +    {
    +        if (!(time instanceof DERUTCTime)
    +            && !(time instanceof DERGeneralizedTime))
    +        {
    +            throw new IllegalArgumentException("unknown object passed to Time");
    +        }
    +
    +        this.time = time; 
    +    }
    +
    +    /**
    +     * creates a time object from a given date - if the date is between 1950
    +     * and 2049 a UTCTime object is generated, otherwise a GeneralizedTime
    +     * is used.
    +     */
    +    public Time(
    +        Date    date)
    +    {
    +        SimpleTimeZone      tz = new SimpleTimeZone(0, "Z");
    +        SimpleDateFormat    dateF = new SimpleDateFormat("yyyyMMddHHmmss");
    +
    +        dateF.setTimeZone(tz);
    +
    +        String  d = dateF.format(date) + "Z";
    +        int     year = Integer.parseInt(d.substring(0, 4));
    +
    +        if (year < 1950 || year > 2049)
    +        {
    +            time = new DERGeneralizedTime(d);
    +        }
    +        else
    +        {
    +            time = new DERUTCTime(d.substring(2));
    +        }
    +    }
    +
    +    public static Time getInstance(
    +        Object  obj)
    +    {
    +        if (obj == null || obj instanceof Time)
    +        {
    +            return (Time)obj;
    +        }
    +        else if (obj instanceof DERUTCTime)
    +        {
    +            return new Time((DERUTCTime)obj);
    +        }
    +        else if (obj instanceof DERGeneralizedTime)
    +        {
    +            return new Time((DERGeneralizedTime)obj);
    +        }
    +
    +        throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName());
    +    }
    +
    +    public String getTime()
    +    {
    +        if (time instanceof DERUTCTime)
    +        {
    +            return ((DERUTCTime)time).getAdjustedTime();
    +        }
    +        else
    +        {
    +            return ((DERGeneralizedTime)time).getTime();
    +        }
    +    }
    +
    +    public Date getDate()
    +    {
    +        try
    +        {
    +            if (time instanceof DERUTCTime)
    +            {
    +                return ((DERUTCTime)time).getAdjustedDate();
    +            }
    +            else
    +            {
    +                return ((DERGeneralizedTime)time).getDate();
    +            }
    +        }
    +        catch (ParseException e)
    +        {         // this should never happen
    +            throw new IllegalStateException("invalid date string: " + e.getMessage());
    +        }
    +    }
    +
    +    /**
    +     * Produce an object suitable for an ASN1OutputStream.
    +     * <pre>
    +     * Time ::= CHOICE {
    +     *             utcTime        UTCTime,
    +     *             generalTime    GeneralizedTime }
    +     * </pre>
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        return time;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/TimeStampAndCRL.java+82 0 added
    @@ -0,0 +1,82 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.DERSequence;
    +import org.bouncycastle.asn1.x509.CertificateList;
    +
    +public class TimeStampAndCRL
    +    extends ASN1Object
    +{
    +    private ContentInfo timeStamp;
    +    private CertificateList crl;
    +
    +    public TimeStampAndCRL(ContentInfo timeStamp)
    +    {
    +        this.timeStamp = timeStamp;
    +    }
    +
    +    private TimeStampAndCRL(ASN1Sequence seq)
    +    {
    +        this.timeStamp = ContentInfo.getInstance(seq.getObjectAt(0));
    +        if (seq.size() == 2)
    +        {
    +            this.crl = CertificateList.getInstance(seq.getObjectAt(1));
    +        }
    +    }
    +
    +    public static TimeStampAndCRL getInstance(Object obj)
    +    {
    +        if (obj instanceof TimeStampAndCRL)
    +        {
    +            return (TimeStampAndCRL)obj;
    +        }
    +        else if (obj != null)
    +        {
    +            return new TimeStampAndCRL(ASN1Sequence.getInstance(obj));
    +        }
    +
    +        return null;
    +    }
    +
    +    public ContentInfo getTimeStampToken()
    +    {
    +        return this.timeStamp;
    +    }
    +
    +    /** @deprecated use getCRL() */
    +    public CertificateList getCertificateList()
    +    {
    +        return this.crl;
    +    }
    +
    +    public CertificateList getCRL()
    +    {
    +        return this.crl;
    +    }
    +
    +    /**
    +     * <pre>
    +     * TimeStampAndCRL ::= SEQUENCE {
    +     *     timeStamp   TimeStampToken,          -- according to RFC 3161
    +     *     crl         CertificateList OPTIONAL -- according to RFC 5280
    +     *  }
    +     * </pre>
    +     * @return
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(timeStamp);
    +
    +        if (crl != null)
    +        {
    +            v.add(crl);
    +        }
    +
    +        return new DERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/TimeStampedData.java+121 0 added
    @@ -0,0 +1,121 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Integer;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1OctetString;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.BERSequence;
    +import org.bouncycastle.asn1.DERIA5String;
    +
    +public class TimeStampedData
    +    extends ASN1Object
    +{
    +    private ASN1Integer version;
    +    private DERIA5String dataUri;
    +    private MetaData metaData;
    +    private ASN1OctetString content;
    +    private Evidence temporalEvidence;
    +
    +    public TimeStampedData(DERIA5String dataUri, MetaData metaData, ASN1OctetString content, Evidence temporalEvidence)
    +    {
    +        this.version = new ASN1Integer(1);
    +        this.dataUri = dataUri;
    +        this.metaData = metaData;
    +        this.content = content;
    +        this.temporalEvidence = temporalEvidence;
    +    }
    +
    +    private TimeStampedData(ASN1Sequence seq)
    +    {
    +        this.version = ASN1Integer.getInstance(seq.getObjectAt(0));
    +
    +        int index = 1;
    +        if (seq.getObjectAt(index) instanceof DERIA5String)
    +        {
    +            this.dataUri = DERIA5String.getInstance(seq.getObjectAt(index++));
    +        }
    +        if (seq.getObjectAt(index) instanceof MetaData || seq.getObjectAt(index) instanceof ASN1Sequence)
    +        {
    +            this.metaData = MetaData.getInstance(seq.getObjectAt(index++));
    +        }
    +        if (seq.getObjectAt(index) instanceof ASN1OctetString)
    +        {
    +            this.content = ASN1OctetString.getInstance(seq.getObjectAt(index++));
    +        }
    +        this.temporalEvidence = Evidence.getInstance(seq.getObjectAt(index));
    +    }
    +
    +    public static TimeStampedData getInstance(Object obj)
    +    {
    +        if (obj instanceof TimeStampedData)
    +        {
    +            return (TimeStampedData)obj;
    +        }
    +        else if (obj != null)
    +        {
    +            return new TimeStampedData(ASN1Sequence.getInstance(obj));
    +        }
    +
    +        return null;
    +    }
    +
    +    public DERIA5String getDataUri()
    +    {
    +        return dataUri;
    +    }
    +
    +    public MetaData getMetaData()
    +    {
    +        return metaData;
    +    }
    +
    +    public ASN1OctetString getContent()
    +    {
    +        return content;
    +    }
    +
    +    public Evidence getTemporalEvidence()
    +    {
    +        return temporalEvidence;
    +    }
    +
    +    /**
    +     * <pre>
    +     * TimeStampedData ::= SEQUENCE {
    +     *   version              INTEGER { v1(1) },
    +     *   dataUri              IA5String OPTIONAL,
    +     *   metaData             MetaData OPTIONAL,
    +     *   content              OCTET STRING OPTIONAL,
    +     *   temporalEvidence     Evidence
    +     * }
    +     * </pre>
    +     * @return
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        v.add(version);
    +
    +        if (dataUri != null)
    +        {
    +            v.add(dataUri);
    +        }
    +
    +        if (metaData != null)
    +        {
    +            v.add(metaData);
    +        }
    +
    +        if (content != null)
    +        {
    +            v.add(content);
    +        }
    +
    +        v.add(temporalEvidence);
    +
    +        return new BERSequence(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/cms/TimeStampedDataParser.java+0 0 added
  • core/src/main/java/org/bouncycastle/asn1/cms/TimeStampTokenEvidence.java+84 0 added
    @@ -0,0 +1,84 @@
    +package org.bouncycastle.asn1.cms;
    +
    +import java.util.Enumeration;
    +
    +import org.bouncycastle.asn1.ASN1EncodableVector;
    +import org.bouncycastle.asn1.ASN1Object;
    +import org.bouncycastle.asn1.ASN1Primitive;
    +import org.bouncycastle.asn1.ASN1Sequence;
    +import org.bouncycastle.asn1.ASN1TaggedObject;
    +import org.bouncycastle.asn1.DERSequence;
    +
    +public class TimeStampTokenEvidence
    +    extends ASN1Object
    +{
    +    private TimeStampAndCRL[] timeStampAndCRLs;
    +
    +    public TimeStampTokenEvidence(TimeStampAndCRL[] timeStampAndCRLs)
    +    {
    +        this.timeStampAndCRLs = timeStampAndCRLs;
    +    }
    +
    +    public TimeStampTokenEvidence(TimeStampAndCRL timeStampAndCRL)
    +    {
    +        this.timeStampAndCRLs = new TimeStampAndCRL[1];
    +
    +        timeStampAndCRLs[0] = timeStampAndCRL;
    +    }
    +
    +    private TimeStampTokenEvidence(ASN1Sequence seq)
    +    {
    +        this.timeStampAndCRLs = new TimeStampAndCRL[seq.size()];
    +
    +        int count = 0;
    +
    +        for (Enumeration en = seq.getObjects(); en.hasMoreElements();)
    +        {
    +            timeStampAndCRLs[count++] = TimeStampAndCRL.getInstance(en.nextElement());
    +        }
    +    }
    +
    +    public static TimeStampTokenEvidence getInstance(ASN1TaggedObject tagged, boolean explicit)
    +    {
    +        return getInstance(ASN1Sequence.getInstance(tagged, explicit));
    +    }
    +
    +    public static TimeStampTokenEvidence getInstance(Object obj)
    +    {
    +        if (obj instanceof TimeStampTokenEvidence)
    +        {
    +            return (TimeStampTokenEvidence)obj;
    +        }
    +        else if (obj != null)
    +        {
    +            return new TimeStampTokenEvidence(ASN1Sequence.getInstance(obj));
    +        }
    +
    +        return null;
    +    }
    +
    +    public TimeStampAndCRL[] toTimeStampAndCRLArray()
    +    {
    +        return timeStampAndCRLs;
    +    }
    +    
    +    /**
    +     * <pre>
    +     * TimeStampTokenEvidence ::=
    +     *    SEQUENCE SIZE(1..MAX) OF TimeStampAndCRL
    +     * </pre>
    +     * @return
    +     */
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        ASN1EncodableVector v = new ASN1EncodableVector();
    +
    +        for (int i = 0; i != timeStampAndCRLs.length; i++)
    +        {
    +            v.add(timeStampAndCRLs[i]);
    +        }
    +
    +        return new DERSequence(v);
    +    }
    +
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/ConstructedOctetStream.java+111 0 added
    @@ -0,0 +1,111 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.io.InputStream;
    +
    +class ConstructedOctetStream
    +    extends InputStream
    +{
    +    private final ASN1StreamParser _parser;
    +
    +    private boolean                _first = true;
    +    private InputStream            _currentStream;
    +
    +    ConstructedOctetStream(
    +        ASN1StreamParser parser)
    +    {
    +        _parser = parser;
    +    }
    +
    +    public int read(byte[] b, int off, int len) throws IOException
    +    {
    +        if (_currentStream == null)
    +        {
    +            if (!_first)
    +            {
    +                return -1;
    +            }
    +
    +            ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject();
    +
    +            if (s == null)
    +            {
    +                return -1;
    +            }
    +
    +            _first = false;
    +            _currentStream = s.getOctetStream();
    +        }
    +
    +        int totalRead = 0;
    +
    +        for (;;)
    +        {
    +            int numRead = _currentStream.read(b, off + totalRead, len - totalRead);
    +
    +            if (numRead >= 0)
    +            {
    +                totalRead += numRead;
    +
    +                if (totalRead == len)
    +                {
    +                    return totalRead;
    +                }
    +            }
    +            else
    +            {
    +                ASN1OctetStringParser aos = (ASN1OctetStringParser)_parser.readObject();
    +
    +                if (aos == null)
    +                {
    +                    _currentStream = null;
    +                    return totalRead < 1 ? -1 : totalRead;
    +                }
    +
    +                _currentStream = aos.getOctetStream();
    +            }
    +        }
    +    }
    +
    +    public int read()
    +        throws IOException
    +    {
    +        if (_currentStream == null)
    +        {
    +            if (!_first)
    +            {
    +                return -1;
    +            }
    +
    +            ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject();
    +    
    +            if (s == null)
    +            {
    +                return -1;
    +            }
    +    
    +            _first = false;
    +            _currentStream = s.getOctetStream();
    +        }
    +
    +        for (;;)
    +        {
    +            int b = _currentStream.read();
    +
    +            if (b >= 0)
    +            {
    +                return b;
    +            }
    +
    +            ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject();
    +
    +            if (s == null)
    +            {
    +                _currentStream = null;
    +                return -1;
    +            }
    +
    +            _currentStream = s.getOctetStream();
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/crmf/AttributeTypeAndValue.java+80 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/CertId.java+84 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/CertReqMessages.java+74 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/CertReqMsg.java+145 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/CertRequest.java+97 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/CertTemplateBuilder.java+152 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/CertTemplate.java+163 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/Controls.java+72 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/CRMFObjectIdentifiers.java+21 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/EncKeyWithID.java+117 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/EncryptedKey.java+81 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/EncryptedValue.java+164 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/OptionalValidity.java+98 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/PKIArchiveOptions.java+116 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/PKIPublicationInfo.java+81 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/PKMACValue.java+104 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/POPOPrivKey.java+104 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/POPOSigningKeyInput.java+134 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/POPOSigningKey.java+127 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/ProofOfPossession.java+108 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/SinglePubInfo.java+72 0 added
  • core/src/main/java/org/bouncycastle/asn1/crmf/SubsequentMessage.java+29 0 added
  • core/src/main/java/org/bouncycastle/asn1/cryptopro/CryptoProObjectIdentifiers.java+48 0 added
  • core/src/main/java/org/bouncycastle/asn1/cryptopro/ECGOST3410NamedCurves.java+168 0 added
  • core/src/main/java/org/bouncycastle/asn1/cryptopro/ECGOST3410ParamSetParameters.java+99 0 added
  • core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST28147Parameters.java+72 0 added
  • core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST3410NamedParameters.java+116 0 added
  • core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST3410ParamSetParameters.java+105 0 added
  • core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST3410PublicKeyAlgParameters.java+101 0 added
  • core/src/main/java/org/bouncycastle/asn1/DefiniteLengthInputStream.java+105 0 added
    @@ -0,0 +1,105 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.EOFException;
    +import java.io.IOException;
    +import java.io.InputStream;
    +
    +import org.bouncycastle.util.io.Streams;
    +
    +class DefiniteLengthInputStream
    +        extends LimitedInputStream
    +{
    +    private static final byte[] EMPTY_BYTES = new byte[0];
    +
    +    private final int _originalLength;
    +    private int _remaining;
    +
    +    DefiniteLengthInputStream(
    +        InputStream in,
    +        int         length)
    +    {
    +        super(in, length);
    +
    +        if (length < 0)
    +        {
    +            throw new IllegalArgumentException("negative lengths not allowed");
    +        }
    +
    +        this._originalLength = length;
    +        this._remaining = length;
    +
    +        if (length == 0)
    +        {
    +            setParentEofDetect(true);
    +        }
    +    }
    +
    +    int getRemaining()
    +    {
    +        return _remaining;
    +    }
    +
    +    public int read()
    +        throws IOException
    +    {
    +        if (_remaining == 0)
    +        {
    +            return -1;
    +        }
    +
    +        int b = _in.read();
    +
    +        if (b < 0)
    +        {
    +            throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
    +        }
    +
    +        if (--_remaining == 0)
    +        {
    +            setParentEofDetect(true);
    +        }
    +
    +        return b;
    +    }
    +
    +    public int read(byte[] buf, int off, int len)
    +        throws IOException
    +    {
    +        if (_remaining == 0)
    +        {
    +            return -1;
    +        }
    +
    +        int toRead = Math.min(len, _remaining);
    +        int numRead = _in.read(buf, off, toRead);
    +
    +        if (numRead < 0)
    +        {
    +            throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
    +        }
    +
    +        if ((_remaining -= numRead) == 0)
    +        {
    +            setParentEofDetect(true);
    +        }
    +
    +        return numRead;
    +    }
    +
    +    byte[] toByteArray()
    +        throws IOException
    +    {
    +        if (_remaining == 0)
    +        {
    +            return EMPTY_BYTES;
    +        }
    +
    +        byte[] bytes = new byte[_remaining];
    +        if ((_remaining -= Streams.readFully(_in, bytes)) != 0)
    +        {
    +            throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
    +        }
    +        setParentEofDetect(true);
    +        return bytes;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERApplicationSpecific.java+276 0 added
    @@ -0,0 +1,276 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.ByteArrayOutputStream;
    +import java.io.IOException;
    +
    +import org.bouncycastle.util.Arrays;
    +
    +/**
    + * Base class for an application specific object
    + */
    +public class DERApplicationSpecific 
    +    extends ASN1Primitive
    +{
    +    private final boolean   isConstructed;
    +    private final int       tag;
    +    private final byte[]    octets;
    +
    +    DERApplicationSpecific(
    +        boolean isConstructed,
    +        int     tag,
    +        byte[]  octets)
    +    {
    +        this.isConstructed = isConstructed;
    +        this.tag = tag;
    +        this.octets = octets;
    +    }
    +
    +    public DERApplicationSpecific(
    +        int    tag,
    +        byte[] octets)
    +    {
    +        this(false, tag, octets);
    +    }
    +
    +    public DERApplicationSpecific(
    +        int                  tag, 
    +        ASN1Encodable object)
    +        throws IOException 
    +    {
    +        this(true, tag, object);
    +    }
    +
    +    public DERApplicationSpecific(
    +        boolean      explicit,
    +        int          tag,
    +        ASN1Encodable object)
    +        throws IOException
    +    {
    +        ASN1Primitive primitive = object.toASN1Primitive();
    +
    +        byte[] data = primitive.getEncoded(ASN1Encoding.DER);
    +
    +        this.isConstructed = explicit || (primitive instanceof ASN1Set || primitive instanceof ASN1Sequence);
    +        this.tag = tag;
    +
    +        if (explicit)
    +        {
    +            this.octets = data;
    +        }
    +        else
    +        {
    +            int lenBytes = getLengthOfHeader(data);
    +            byte[] tmp = new byte[data.length - lenBytes];
    +            System.arraycopy(data, lenBytes, tmp, 0, tmp.length);
    +            this.octets = tmp;
    +        }
    +    }
    +
    +    public DERApplicationSpecific(int tagNo, ASN1EncodableVector vec)
    +    {
    +        this.tag = tagNo;
    +        this.isConstructed = true;
    +        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    +
    +        for (int i = 0; i != vec.size(); i++)
    +        {
    +            try
    +            {
    +                bOut.write(((ASN1Object)vec.get(i)).getEncoded(ASN1Encoding.DER));
    +            }
    +            catch (IOException e)
    +            {
    +                throw new ASN1ParsingException("malformed object: " + e, e);
    +            }
    +        }
    +        this.octets = bOut.toByteArray();
    +    }
    +
    +    public static DERApplicationSpecific getInstance(Object obj)
    +    {
    +        if (obj == null || obj instanceof DERApplicationSpecific)
    +        {
    +            return (DERApplicationSpecific)obj;
    +        }
    +        else if (obj instanceof byte[])
    +        {
    +            try
    +            {
    +                return DERApplicationSpecific.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
    +            }
    +            catch (IOException e)
    +            {
    +                throw new IllegalArgumentException("failed to construct object from byte[]: " + e.getMessage());
    +            }
    +        }
    +        else if (obj instanceof ASN1Encodable)
    +        {
    +            ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
    +
    +            if (primitive instanceof ASN1Sequence)
    +            {
    +                return (DERApplicationSpecific)primitive;
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    private int getLengthOfHeader(byte[] data)
    +    {
    +        int length = data[1] & 0xff; // TODO: assumes 1 byte tag
    +
    +        if (length == 0x80)
    +        {
    +            return 2;      // indefinite-length encoding
    +        }
    +
    +        if (length > 127)
    +        {
    +            int size = length & 0x7f;
    +
    +            // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
    +            if (size > 4)
    +            {
    +                throw new IllegalStateException("DER length more than 4 bytes: " + size);
    +            }
    +
    +            return size + 2;
    +        }
    +
    +        return 2;
    +    }
    +
    +    public boolean isConstructed()
    +    {
    +        return isConstructed;
    +    }
    +    
    +    public byte[] getContents()
    +    {
    +        return octets;
    +    }
    +    
    +    public int getApplicationTag() 
    +    {
    +        return tag;
    +    }
    +
    +    /**
    +     * Return the enclosed object assuming explicit tagging.
    +     *
    +     * @return  the resulting object
    +     * @throws IOException if reconstruction fails.
    +     */
    +    public ASN1Primitive getObject()
    +        throws IOException 
    +    {
    +        return new ASN1InputStream(getContents()).readObject();
    +    }
    +
    +    /**
    +     * Return the enclosed object assuming implicit tagging.
    +     *
    +     * @param derTagNo the type tag that should be applied to the object's contents.
    +     * @return  the resulting object
    +     * @throws IOException if reconstruction fails.
    +     */
    +    public ASN1Primitive getObject(int derTagNo)
    +        throws IOException
    +    {
    +        if (derTagNo >= 0x1f)
    +        {
    +            throw new IOException("unsupported tag number");
    +        }
    +
    +        byte[] orig = this.getEncoded();
    +        byte[] tmp = replaceTagNumber(derTagNo, orig);
    +
    +        if ((orig[0] & BERTags.CONSTRUCTED) != 0)
    +        {
    +            tmp[0] |= BERTags.CONSTRUCTED;
    +        }
    +
    +        return new ASN1InputStream(tmp).readObject();
    +    }
    +
    +    int encodedLength()
    +        throws IOException
    +    {
    +        return StreamUtil.calculateTagLength(tag) + StreamUtil.calculateBodyLength(octets.length) + octets.length;
    +    }
    +
    +    /* (non-Javadoc)
    +     * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
    +     */
    +    void encode(ASN1OutputStream out) throws IOException
    +    {
    +        int classBits = BERTags.APPLICATION;
    +        if (isConstructed)
    +        {
    +            classBits |= BERTags.CONSTRUCTED;
    +        }
    +
    +        out.writeEncoded(classBits, tag, octets);
    +    }
    +    
    +    boolean asn1Equals(
    +        ASN1Primitive o)
    +    {
    +        if (!(o instanceof DERApplicationSpecific))
    +        {
    +            return false;
    +        }
    +
    +        DERApplicationSpecific other = (DERApplicationSpecific)o;
    +
    +        return isConstructed == other.isConstructed
    +            && tag == other.tag
    +            && Arrays.areEqual(octets, other.octets);
    +    }
    +
    +    public int hashCode()
    +    {
    +        return (isConstructed ? 1 : 0) ^ tag ^ Arrays.hashCode(octets);
    +    }
    +
    +    private byte[] replaceTagNumber(int newTag, byte[] input)
    +        throws IOException
    +    {
    +        int tagNo = input[0] & 0x1f;
    +        int index = 1;
    +        //
    +        // with tagged object tag number is bottom 5 bits, or stored at the start of the content
    +        //
    +        if (tagNo == 0x1f)
    +        {
    +            tagNo = 0;
    +
    +            int b = input[index++] & 0xff;
    +
    +            // X.690-0207 8.1.2.4.2
    +            // "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
    +            if ((b & 0x7f) == 0) // Note: -1 will pass
    +            {
    +                throw new ASN1ParsingException("corrupted stream - invalid high tag number found");
    +            }
    +
    +            while ((b >= 0) && ((b & 0x80) != 0))
    +            {
    +                tagNo |= (b & 0x7f);
    +                tagNo <<= 7;
    +                b = input[index++] & 0xff;
    +            }
    +
    +            tagNo |= (b & 0x7f);
    +        }
    +
    +        byte[] tmp = new byte[input.length - index + 1];
    +
    +        System.arraycopy(input, index, tmp, 1, tmp.length - 1);
    +
    +        tmp[0] = (byte)newTag;
    +
    +        return tmp;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERBitString.java+313 0 added
    @@ -0,0 +1,313 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.ByteArrayOutputStream;
    +import java.io.EOFException;
    +import java.io.IOException;
    +import java.io.InputStream;
    +
    +import org.bouncycastle.util.Arrays;
    +import org.bouncycastle.util.io.Streams;
    +
    +public class DERBitString
    +    extends ASN1Primitive
    +    implements ASN1String
    +{
    +    private static final char[]  table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
    +    
    +    protected byte[]      data;
    +    protected int         padBits;
    +
    +    /**
    +     * return the correct number of pad bits for a bit string defined in
    +     * a 32 bit constant
    +     */
    +    static protected int getPadBits(
    +        int bitString)
    +    {
    +        int val = 0;
    +        for (int i = 3; i >= 0; i--) 
    +        {
    +            //
    +            // this may look a little odd, but if it isn't done like this pre jdk1.2
    +            // JVM's break!
    +            //
    +            if (i != 0)
    +            {
    +                if ((bitString >> (i * 8)) != 0) 
    +                {
    +                    val = (bitString >> (i * 8)) & 0xFF;
    +                    break;
    +                }
    +            }
    +            else
    +            {
    +                if (bitString != 0)
    +                {
    +                    val = bitString & 0xFF;
    +                    break;
    +                }
    +            }
    +        }
    + 
    +        if (val == 0)
    +        {
    +            return 7;
    +        }
    +
    +
    +        int bits = 1;
    +
    +        while (((val <<= 1) & 0xFF) != 0)
    +        {
    +            bits++;
    +        }
    +
    +        return 8 - bits;
    +    }
    +
    +    /**
    +     * return the correct number of bytes for a bit string defined in
    +     * a 32 bit constant
    +     */
    +    static protected byte[] getBytes(int bitString)
    +    {
    +        int bytes = 4;
    +        for (int i = 3; i >= 1; i--)
    +        {
    +            if ((bitString & (0xFF << (i * 8))) != 0)
    +            {
    +                break;
    +            }
    +            bytes--;
    +        }
    +        
    +        byte[] result = new byte[bytes];
    +        for (int i = 0; i < bytes; i++)
    +        {
    +            result[i] = (byte) ((bitString >> (i * 8)) & 0xFF);
    +        }
    +
    +        return result;
    +    }
    +
    +    /**
    +     * return a Bit String from the passed in object
    +     *
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static DERBitString getInstance(
    +        Object  obj)
    +    {
    +        if (obj == null || obj instanceof DERBitString)
    +        {
    +            return (DERBitString)obj;
    +        }
    +
    +        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * return a Bit String from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the tagged object cannot
    +     *               be converted.
    +     */
    +    public static DERBitString getInstance(
    +        ASN1TaggedObject obj,
    +        boolean          explicit)
    +    {
    +        ASN1Primitive o = obj.getObject();
    +
    +        if (explicit || o instanceof DERBitString)
    +        {
    +            return getInstance(o);
    +        }
    +        else
    +        {
    +            return fromOctetString(((ASN1OctetString)o).getOctets());
    +        }
    +    }
    +    
    +    protected DERBitString(
    +        byte    data,
    +        int     padBits)
    +    {
    +        this.data = new byte[1];
    +        this.data[0] = data;
    +        this.padBits = padBits;
    +    }
    +
    +    /**
    +     * @param data the octets making up the bit string.
    +     * @param padBits the number of extra bits at the end of the string.
    +     */
    +    public DERBitString(
    +        byte[]  data,
    +        int     padBits)
    +    {
    +        this.data = data;
    +        this.padBits = padBits;
    +    }
    +
    +    public DERBitString(
    +        byte[]  data)
    +    {
    +        this(data, 0);
    +    }
    +
    +    public DERBitString(
    +        int value)
    +    {
    +        this.data = getBytes(value);
    +        this.padBits = getPadBits(value);
    +    }
    +
    +    public DERBitString(
    +        ASN1Encodable obj)
    +        throws IOException
    +    {
    +        this.data = obj.toASN1Primitive().getEncoded(ASN1Encoding.DER);
    +        this.padBits = 0;
    +    }
    +
    +    public byte[] getBytes()
    +    {
    +        return data;
    +    }
    +
    +    public int getPadBits()
    +    {
    +        return padBits;
    +    }
    +
    +
    +    /**
    +     * @return the value of the bit string as an int (truncating if necessary)
    +     */
    +    public int intValue()
    +    {
    +        int value = 0;
    +        
    +        for (int i = 0; i != data.length && i != 4; i++)
    +        {
    +            value |= (data[i] & 0xff) << (8 * i);
    +        }
    +        
    +        return value;
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return false;
    +    }
    +
    +    int encodedLength()
    +    {
    +        return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1;
    +    }
    +
    +    void encode(
    +        ASN1OutputStream  out)
    +        throws IOException
    +    {
    +        byte[]  bytes = new byte[getBytes().length + 1];
    +
    +        bytes[0] = (byte)getPadBits();
    +        System.arraycopy(getBytes(), 0, bytes, 1, bytes.length - 1);
    +
    +        out.writeEncoded(BERTags.BIT_STRING, bytes);
    +    }
    +
    +    public int hashCode()
    +    {
    +        return padBits ^ Arrays.hashCode(data);
    +    }
    +
    +    protected boolean asn1Equals(
    +        ASN1Primitive  o)
    +    {
    +        if (!(o instanceof DERBitString))
    +        {
    +            return false;
    +        }
    +
    +        DERBitString other = (DERBitString)o;
    +
    +        return this.padBits == other.padBits
    +            && Arrays.areEqual(this.data, other.data);
    +    }
    +
    +    public String getString()
    +    {
    +        StringBuffer          buf = new StringBuffer("#");
    +        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    +        ASN1OutputStream      aOut = new ASN1OutputStream(bOut);
    +        
    +        try
    +        {
    +            aOut.writeObject(this);
    +        }
    +        catch (IOException e)
    +        {
    +           throw new RuntimeException("internal error encoding BitString");
    +        }
    +        
    +        byte[]    string = bOut.toByteArray();
    +        
    +        for (int i = 0; i != string.length; i++)
    +        {
    +            buf.append(table[(string[i] >>> 4) & 0xf]);
    +            buf.append(table[string[i] & 0xf]);
    +        }
    +        
    +        return buf.toString();
    +    }
    +
    +    public String toString()
    +    {
    +        return getString();
    +    }
    +
    +    static DERBitString fromOctetString(byte[] bytes)
    +    {
    +        if (bytes.length < 1)
    +        {
    +            throw new IllegalArgumentException("truncated BIT STRING detected");
    +        }
    +
    +        int padBits = bytes[0];
    +        byte[] data = new byte[bytes.length - 1];
    +
    +        if (data.length != 0)
    +        {
    +            System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
    +        }
    +
    +        return new DERBitString(data, padBits);
    +    }
    +
    +    static DERBitString fromInputStream(int length, InputStream stream)
    +        throws IOException
    +    {
    +        if (length < 1)
    +        {
    +            throw new IllegalArgumentException("truncated BIT STRING detected");
    +        }
    +
    +        int padBits = stream.read();
    +        byte[] data = new byte[length - 1];
    +
    +        if (data.length != 0)
    +        {
    +            if (Streams.readFully(stream, data) != data.length)
    +            {
    +                throw new EOFException("EOF encountered in middle of BIT STRING");
    +            }
    +        }
    +
    +        return new DERBitString(data, padBits);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERBMPString.java+153 0 added
    @@ -0,0 +1,153 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +import org.bouncycastle.util.Arrays;
    +
    +/**
    + * DER BMPString object.
    + */
    +public class DERBMPString
    +    extends ASN1Primitive
    +    implements ASN1String
    +{
    +    private char[]  string;
    +
    +    /**
    +     * return a BMP String from the given object.
    +     *
    +     * @param obj the object we want converted.
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static DERBMPString getInstance(
    +        Object  obj)
    +    {
    +        if (obj == null || obj instanceof DERBMPString)
    +        {
    +            return (DERBMPString)obj;
    +        }
    +
    +        if (obj instanceof byte[])
    +        {
    +            try
    +            {
    +                return (DERBMPString)fromByteArray((byte[])obj);
    +            }
    +            catch (Exception e)
    +            {
    +                throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * return a BMP String from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the tagged object cannot
    +     *              be converted.
    +     */
    +    public static DERBMPString getInstance(
    +        ASN1TaggedObject obj,
    +        boolean          explicit)
    +    {
    +        ASN1Primitive o = obj.getObject();
    +
    +        if (explicit || o instanceof DERBMPString)
    +        {
    +            return getInstance(o);
    +        }
    +        else
    +        {
    +            return new DERBMPString(ASN1OctetString.getInstance(o).getOctets());
    +        }
    +    }
    +
    +    /**
    +     * basic constructor - byte encoded string.
    +     */
    +    DERBMPString(
    +        byte[]   string)
    +    {
    +        char[]  cs = new char[string.length / 2];
    +
    +        for (int i = 0; i != cs.length; i++)
    +        {
    +            cs[i] = (char)((string[2 * i] << 8) | (string[2 * i + 1] & 0xff));
    +        }
    +
    +        this.string = cs;
    +    }
    +
    +    DERBMPString(char[] string)
    +    {
    +        this.string = string;
    +    }
    +
    +    /**
    +     * basic constructor
    +     */
    +    public DERBMPString(
    +        String   string)
    +    {
    +        this.string = string.toCharArray();
    +    }
    +
    +    public String getString()
    +    {
    +        return new String(string);
    +    }
    +
    +    public String toString()
    +    {
    +        return getString();
    +    }
    +
    +    public int hashCode()
    +    {
    +        return Arrays.hashCode(string);
    +    }
    +
    +    protected boolean asn1Equals(
    +        ASN1Primitive o)
    +    {
    +        if (!(o instanceof DERBMPString))
    +        {
    +            return false;
    +        }
    +
    +        DERBMPString  s = (DERBMPString)o;
    +
    +        return Arrays.areEqual(string, s.string);
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return false;
    +    }
    +
    +    int encodedLength()
    +    {
    +        return 1 + StreamUtil.calculateBodyLength(string.length * 2) + (string.length * 2);
    +    }
    +
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        out.write(BERTags.BMP_STRING);
    +        out.writeLength(string.length * 2);
    +
    +        for (int i = 0; i != string.length; i++)
    +        {
    +            char c = string[i];
    +
    +            out.write((byte)(c >> 8));
    +            out.write((byte)c);
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERBoolean.java+179 0 added
    @@ -0,0 +1,179 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +import org.bouncycastle.util.Arrays;
    +
    +public class DERBoolean
    +    extends ASN1Primitive
    +{
    +    private static final byte[] TRUE_VALUE = new byte[] { (byte)0xff };
    +    private static final byte[] FALSE_VALUE = new byte[] { 0 };
    +
    +    private byte[]         value;
    +
    +    public static final ASN1Boolean FALSE = new ASN1Boolean(false);
    +    public static final ASN1Boolean TRUE  = new ASN1Boolean(true);
    +
    +
    +    /**
    +     * return a boolean from the passed in object.
    +     *
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static ASN1Boolean getInstance(
    +        Object  obj)
    +    {
    +        if (obj == null || obj instanceof ASN1Boolean)
    +        {
    +            return (ASN1Boolean)obj;
    +        }
    +
    +        if (obj instanceof DERBoolean)
    +        {
    +            return ((DERBoolean)obj).isTrue() ? DERBoolean.TRUE : DERBoolean.FALSE;
    +        }
    +
    +        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * return a ASN1Boolean from the passed in boolean.
    +     */
    +    public static ASN1Boolean getInstance(
    +        boolean  value)
    +    {
    +        return (value ? TRUE : FALSE);
    +    }
    +
    +    /**
    +     * return a ASN1Boolean from the passed in boolean.
    +     */
    +    public static ASN1Boolean getInstance(
    +        int value)
    +    {
    +        return (value != 0 ? TRUE : FALSE);
    +    }
    +
    +    /**
    +     * return a Boolean from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the tagged object cannot
    +     *               be converted.
    +     */
    +    public static ASN1Boolean getInstance(
    +        ASN1TaggedObject obj,
    +        boolean          explicit)
    +    {
    +        ASN1Primitive o = obj.getObject();
    +
    +        if (explicit || o instanceof DERBoolean)
    +        {
    +            return getInstance(o);
    +        }
    +        else
    +        {
    +            return ASN1Boolean.fromOctetString(((ASN1OctetString)o).getOctets());
    +        }
    +    }
    +    
    +    DERBoolean(
    +        byte[]       value)
    +    {
    +        if (value.length != 1)
    +        {
    +            throw new IllegalArgumentException("byte value should have 1 byte in it");
    +        }
    +
    +        if (value[0] == 0)
    +        {
    +            this.value = FALSE_VALUE;
    +        }
    +        else if (value[0] == 0xff)
    +        {
    +            this.value = TRUE_VALUE;
    +        }
    +        else
    +        {
    +            this.value = Arrays.clone(value);
    +        }
    +    }
    +
    +    /**
    +     * @deprecated use getInstance(boolean) method.
    +     * @param value
    +     */
    +    public DERBoolean(
    +        boolean     value)
    +    {
    +        this.value = (value) ? TRUE_VALUE : FALSE_VALUE;
    +    }
    +
    +    public boolean isTrue()
    +    {
    +        return (value[0] != 0);
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return false;
    +    }
    +
    +    int encodedLength()
    +    {
    +        return 3;
    +    }
    +
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        out.writeEncoded(BERTags.BOOLEAN, value);
    +    }
    +    
    +    protected boolean asn1Equals(
    +        ASN1Primitive  o)
    +    {
    +        if ((o == null) || !(o instanceof DERBoolean))
    +        {
    +            return false;
    +        }
    +
    +        return (value[0] == ((DERBoolean)o).value[0]);
    +    }
    +    
    +    public int hashCode()
    +    {
    +        return value[0];
    +    }
    +
    +
    +    public String toString()
    +    {
    +      return (value[0] != 0) ? "TRUE" : "FALSE";
    +    }
    +
    +    static ASN1Boolean fromOctetString(byte[] value)
    +    {
    +        if (value.length != 1)
    +        {
    +            throw new IllegalArgumentException("byte value should have 1 byte in it");
    +        }
    +
    +        if (value[0] == 0)
    +        {
    +            return FALSE;
    +        }
    +        else if (value[0] == 0xff)
    +        {
    +            return TRUE;
    +        }
    +        else
    +        {
    +            return new ASN1Boolean(value);
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DEREncodableVector.java+18 0 added
    @@ -0,0 +1,18 @@
    +package org.bouncycastle.asn1;
    +
    +/**
    + * a general class for building up a vector of DER encodable objects -
    + * this will eventually be superceded by ASN1EncodableVector so you should
    + * use that class in preference.
    + */
    +public class DEREncodableVector
    +    extends ASN1EncodableVector
    +{
    +    /**
    +     * @deprecated use ASN1EncodableVector instead.
    +     */
    +    public DEREncodableVector()
    +    {
    +
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DEREnumerated.java+158 0 added
    @@ -0,0 +1,158 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.math.BigInteger;
    +
    +import org.bouncycastle.util.Arrays;
    +
    +public class DEREnumerated
    +    extends ASN1Primitive
    +{
    +    byte[]      bytes;
    +
    +    /**
    +     * return an integer from the passed in object
    +     *
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static ASN1Enumerated getInstance(
    +        Object  obj)
    +    {
    +        if (obj == null || obj instanceof ASN1Enumerated)
    +        {
    +            return (ASN1Enumerated)obj;
    +        }
    +
    +        if (obj instanceof DEREnumerated)
    +        {
    +            return new ASN1Enumerated(((DEREnumerated)obj).getValue());
    +        }
    +
    +        if (obj instanceof byte[])
    +        {
    +            try
    +            {
    +                return (ASN1Enumerated)fromByteArray((byte[])obj);
    +            }
    +            catch (Exception e)
    +            {
    +                throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * return an Enumerated from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the tagged object cannot
    +     *               be converted.
    +     */
    +    public static DEREnumerated getInstance(
    +        ASN1TaggedObject obj,
    +        boolean          explicit)
    +    {
    +        ASN1Primitive o = obj.getObject();
    +
    +        if (explicit || o instanceof DEREnumerated)
    +        {
    +            return getInstance(o);
    +        }
    +        else
    +        {
    +            return fromOctetString(((ASN1OctetString)o).getOctets());
    +        }
    +    }
    +
    +    public DEREnumerated(
    +        int         value)
    +    {
    +        bytes = BigInteger.valueOf(value).toByteArray();
    +    }
    +
    +    public DEREnumerated(
    +        BigInteger   value)
    +    {
    +        bytes = value.toByteArray();
    +    }
    +
    +    public DEREnumerated(
    +        byte[]   bytes)
    +    {
    +        this.bytes = bytes;
    +    }
    +
    +    public BigInteger getValue()
    +    {
    +        return new BigInteger(bytes);
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return false;
    +    }
    +
    +    int encodedLength()
    +    {
    +        return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
    +    }
    +
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        out.writeEncoded(BERTags.ENUMERATED, bytes);
    +    }
    +    
    +    boolean asn1Equals(
    +        ASN1Primitive  o)
    +    {
    +        if (!(o instanceof DEREnumerated))
    +        {
    +            return false;
    +        }
    +
    +        DEREnumerated other = (DEREnumerated)o;
    +
    +        return Arrays.areEqual(this.bytes, other.bytes);
    +    }
    +
    +    public int hashCode()
    +    {
    +        return Arrays.hashCode(bytes);
    +    }
    +
    +    private static ASN1Enumerated[] cache = new ASN1Enumerated[12];
    +
    +    static ASN1Enumerated fromOctetString(byte[] enc)
    +    {
    +        if (enc.length > 1)
    +        {
    +            return new ASN1Enumerated(Arrays.clone(enc));
    +        }
    +
    +        if (enc.length == 0)
    +        {
    +            throw new IllegalArgumentException("ENUMERATED has zero length");
    +        }
    +        int value = enc[0] & 0xff;
    +
    +        if (value >= cache.length)
    +        {
    +            return new ASN1Enumerated(Arrays.clone(enc));
    +        }
    +
    +        ASN1Enumerated possibleMatch = cache[value];
    +
    +        if (possibleMatch == null)
    +        {
    +            possibleMatch = cache[value] = new ASN1Enumerated(Arrays.clone(enc));
    +        }
    +
    +        return possibleMatch;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERExternal.java+294 0 added
    @@ -0,0 +1,294 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.ByteArrayOutputStream;
    +import java.io.IOException;
    +
    +/**
    + * Class representing the DER-type External
    + */
    +public class DERExternal
    +    extends ASN1Primitive
    +{
    +    private ASN1ObjectIdentifier directReference;
    +    private ASN1Integer indirectReference;
    +    private ASN1Primitive dataValueDescriptor;
    +    private int encoding;
    +    private ASN1Primitive externalContent;
    +    
    +    public DERExternal(ASN1EncodableVector vector)
    +    {
    +        int offset = 0;
    +
    +        ASN1Primitive enc = getObjFromVector(vector, offset);
    +        if (enc instanceof ASN1ObjectIdentifier)
    +        {
    +            directReference = (ASN1ObjectIdentifier)enc;
    +            offset++;
    +            enc = getObjFromVector(vector, offset);
    +        }
    +        if (enc instanceof ASN1Integer)
    +        {
    +            indirectReference = (ASN1Integer) enc;
    +            offset++;
    +            enc = getObjFromVector(vector, offset);
    +        }
    +        if (!(enc instanceof DERTaggedObject))
    +        {
    +            dataValueDescriptor = (ASN1Primitive) enc;
    +            offset++;
    +            enc = getObjFromVector(vector, offset);
    +        }
    +
    +        if (vector.size() != offset + 1)
    +        {
    +            throw new IllegalArgumentException("input vector too large");
    +        }
    +
    +        if (!(enc instanceof DERTaggedObject))
    +        {
    +            throw new IllegalArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External");
    +        }
    +        DERTaggedObject obj = (DERTaggedObject)enc;
    +        setEncoding(obj.getTagNo());
    +        externalContent = obj.getObject();
    +    }
    +
    +    private ASN1Primitive getObjFromVector(ASN1EncodableVector v, int index)
    +    {
    +        if (v.size() <= index)
    +        {
    +            throw new IllegalArgumentException("too few objects in input vector");
    +        }
    +
    +        return v.get(index).toASN1Primitive();
    +    }
    +    /**
    +     * Creates a new instance of DERExternal
    +     * See X.690 for more informations about the meaning of these parameters
    +     * @param directReference The direct reference or <code>null</code> if not set.
    +     * @param indirectReference The indirect reference or <code>null</code> if not set.
    +     * @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
    +     * @param externalData The external data in its encoded form.
    +     */
    +    public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
    +    {
    +        this(directReference, indirectReference, dataValueDescriptor, externalData.getTagNo(), externalData.toASN1Primitive());
    +    }
    +
    +    /**
    +     * Creates a new instance of DERExternal.
    +     * See X.690 for more informations about the meaning of these parameters
    +     * @param directReference The direct reference or <code>null</code> if not set.
    +     * @param indirectReference The indirect reference or <code>null</code> if not set.
    +     * @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
    +     * @param encoding The encoding to be used for the external data
    +     * @param externalData The external data
    +     */
    +    public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
    +    {
    +        setDirectReference(directReference);
    +        setIndirectReference(indirectReference);
    +        setDataValueDescriptor(dataValueDescriptor);
    +        setEncoding(encoding);
    +        setExternalContent(externalData.toASN1Primitive());
    +    }
    +
    +    /* (non-Javadoc)
    +     * @see java.lang.Object#hashCode()
    +     */
    +    public int hashCode()
    +    {
    +        int ret = 0;
    +        if (directReference != null)
    +        {
    +            ret = directReference.hashCode();
    +        }
    +        if (indirectReference != null)
    +        {
    +            ret ^= indirectReference.hashCode();
    +        }
    +        if (dataValueDescriptor != null)
    +        {
    +            ret ^= dataValueDescriptor.hashCode();
    +        }
    +        ret ^= externalContent.hashCode();
    +        return ret;
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return true;
    +    }
    +
    +    int encodedLength()
    +        throws IOException
    +    {
    +        return this.getEncoded().length;
    +    }
    +
    +    /* (non-Javadoc)
    +     * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
    +     */
    +    void encode(ASN1OutputStream out)
    +        throws IOException
    +    {
    +        ByteArrayOutputStream baos = new ByteArrayOutputStream();
    +        if (directReference != null)
    +        {
    +            baos.write(directReference.getEncoded(ASN1Encoding.DER));
    +        }
    +        if (indirectReference != null)
    +        {
    +            baos.write(indirectReference.getEncoded(ASN1Encoding.DER));
    +        }
    +        if (dataValueDescriptor != null)
    +        {
    +            baos.write(dataValueDescriptor.getEncoded(ASN1Encoding.DER));
    +        }
    +        DERTaggedObject obj = new DERTaggedObject(true, encoding, externalContent);
    +        baos.write(obj.getEncoded(ASN1Encoding.DER));
    +        out.writeEncoded(BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
    +    }
    +
    +    /* (non-Javadoc)
    +     * @see org.bouncycastle.asn1.ASN1Primitive#asn1Equals(org.bouncycastle.asn1.ASN1Primitive)
    +     */
    +    boolean asn1Equals(ASN1Primitive o)
    +    {
    +        if (!(o instanceof DERExternal))
    +        {
    +            return false;
    +        }
    +        if (this == o)
    +        {
    +            return true;
    +        }
    +        DERExternal other = (DERExternal)o;
    +        if (directReference != null)
    +        {
    +            if (other.directReference == null || !other.directReference.equals(directReference))  
    +            {
    +                return false;
    +            }
    +        }
    +        if (indirectReference != null)
    +        {
    +            if (other.indirectReference == null || !other.indirectReference.equals(indirectReference))
    +            {
    +                return false;
    +            }
    +        }
    +        if (dataValueDescriptor != null)
    +        {
    +            if (other.dataValueDescriptor == null || !other.dataValueDescriptor.equals(dataValueDescriptor))
    +            {
    +                return false;
    +            }
    +        }
    +        return externalContent.equals(other.externalContent);
    +    }
    +
    +    /**
    +     * Returns the data value descriptor
    +     * @return The descriptor
    +     */
    +    public ASN1Primitive getDataValueDescriptor()
    +    {
    +        return dataValueDescriptor;
    +    }
    +
    +    /**
    +     * Returns the direct reference of the external element
    +     * @return The reference
    +     */
    +    public ASN1ObjectIdentifier getDirectReference()
    +    {
    +        return directReference;
    +    }
    +
    +    /**
    +     * Returns the encoding of the content. Valid values are
    +     * <ul>
    +     * <li><code>0</code> single-ASN1-type</li>
    +     * <li><code>1</code> OCTET STRING</li>
    +     * <li><code>2</code> BIT STRING</li>
    +     * </ul>
    +     * @return The encoding
    +     */
    +    public int getEncoding()
    +    {
    +        return encoding;
    +    }
    +    
    +    /**
    +     * Returns the content of this element
    +     * @return The content
    +     */
    +    public ASN1Primitive getExternalContent()
    +    {
    +        return externalContent;
    +    }
    +    
    +    /**
    +     * Returns the indirect reference of this element
    +     * @return The reference
    +     */
    +    public ASN1Integer getIndirectReference()
    +    {
    +        return indirectReference;
    +    }
    +    
    +    /**
    +     * Sets the data value descriptor
    +     * @param dataValueDescriptor The descriptor
    +     */
    +    private void setDataValueDescriptor(ASN1Primitive dataValueDescriptor)
    +    {
    +        this.dataValueDescriptor = dataValueDescriptor;
    +    }
    +
    +    /**
    +     * Sets the direct reference of the external element
    +     * @param directReferemce The reference
    +     */
    +    private void setDirectReference(ASN1ObjectIdentifier directReferemce)
    +    {
    +        this.directReference = directReferemce;
    +    }
    +    
    +    /**
    +     * Sets the encoding of the content. Valid values are
    +     * <ul>
    +     * <li><code>0</code> single-ASN1-type</li>
    +     * <li><code>1</code> OCTET STRING</li>
    +     * <li><code>2</code> BIT STRING</li>
    +     * </ul>
    +     * @param encoding The encoding
    +     */
    +    private void setEncoding(int encoding)
    +    {
    +        if (encoding < 0 || encoding > 2)
    +        {
    +            throw new IllegalArgumentException("invalid encoding value: " + encoding);
    +        }
    +        this.encoding = encoding;
    +    }
    +    
    +    /**
    +     * Sets the content of this element
    +     * @param externalContent The content
    +     */
    +    private void setExternalContent(ASN1Primitive externalContent)
    +    {
    +        this.externalContent = externalContent;
    +    }
    +    
    +    /**
    +     * Sets the indirect reference of this element
    +     * @param indirectReference The reference
    +     */
    +    private void setIndirectReference(ASN1Integer indirectReference)
    +    {
    +        this.indirectReference = indirectReference;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERExternalParser.java+52 0 added
    @@ -0,0 +1,52 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +public class DERExternalParser
    +    implements ASN1Encodable, InMemoryRepresentable
    +{
    +    private ASN1StreamParser _parser;
    +
    +    /**
    +     * 
    +     */
    +    public DERExternalParser(ASN1StreamParser parser)
    +    {
    +        this._parser = parser;
    +    }
    +
    +    public ASN1Encodable readObject()
    +        throws IOException
    +    {
    +        return _parser.readObject();
    +    }
    +
    +    public ASN1Primitive getLoadedObject()
    +        throws IOException
    +    {
    +        try
    +        {
    +            return new DERExternal(_parser.readVector());
    +        }
    +        catch (IllegalArgumentException e)
    +        {
    +            throw new ASN1Exception(e.getMessage(), e);
    +        }
    +    }
    +    
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        try 
    +        {
    +            return getLoadedObject();
    +        }
    +        catch (IOException ioe) 
    +        {
    +            throw new ASN1ParsingException("unable to get DER object", ioe);
    +        }
    +        catch (IllegalArgumentException ioe) 
    +        {
    +            throw new ASN1ParsingException("unable to get DER object", ioe);
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERFactory.java+17 0 added
    @@ -0,0 +1,17 @@
    +package org.bouncycastle.asn1;
    +
    +class DERFactory
    +{
    +    static final ASN1Sequence EMPTY_SEQUENCE = new DERSequence();
    +    static final ASN1Set EMPTY_SET = new DERSet();
    +
    +    static ASN1Sequence createSequence(ASN1EncodableVector v)
    +    {
    +        return v.size() < 1 ? EMPTY_SEQUENCE : new DLSequence(v);
    +    }
    +
    +    static ASN1Set createSet(ASN1EncodableVector v)
    +    {
    +        return v.size() < 1 ? EMPTY_SET : new DLSet(v);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERGeneralizedTime.java+350 0 added
    @@ -0,0 +1,350 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.text.ParseException;
    +import java.text.SimpleDateFormat;
    +import java.util.Date;
    +import java.util.SimpleTimeZone;
    +import java.util.TimeZone;
    +
    +import org.bouncycastle.util.Arrays;
    +import org.bouncycastle.util.Strings;
    +
    +/**
    + * Generalized time object.
    + */
    +public class DERGeneralizedTime
    +    extends ASN1Primitive
    +{
    +    private byte[]      time;
    +
    +    /**
    +     * return a generalized time from the passed in object
    +     *
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static ASN1GeneralizedTime getInstance(
    +        Object  obj)
    +    {
    +        if (obj == null || obj instanceof ASN1GeneralizedTime)
    +        {
    +            return (ASN1GeneralizedTime)obj;
    +        }
    +
    +        if (obj instanceof DERGeneralizedTime)
    +        {
    +            return new ASN1GeneralizedTime(((DERGeneralizedTime)obj).time);
    +        }
    +
    +        if (obj instanceof byte[])
    +        {
    +            try
    +            {
    +                return (ASN1GeneralizedTime)fromByteArray((byte[])obj);
    +            }
    +            catch (Exception e)
    +            {
    +                throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * return a Generalized Time object from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the tagged object cannot
    +     *               be converted.
    +     */
    +    public static ASN1GeneralizedTime getInstance(
    +        ASN1TaggedObject obj,
    +        boolean          explicit)
    +    {
    +        ASN1Primitive o = obj.getObject();
    +
    +        if (explicit || o instanceof DERGeneralizedTime)
    +        {
    +            return getInstance(o);
    +        }
    +        else
    +        {
    +            return new ASN1GeneralizedTime(((ASN1OctetString)o).getOctets());
    +        }
    +    }
    +    
    +    /**
    +     * The correct format for this is YYYYMMDDHHMMSS[.f]Z, or without the Z
    +     * for local time, or Z+-HHMM on the end, for difference between local
    +     * time and UTC time. The fractional second amount f must consist of at
    +     * least one number with trailing zeroes removed.
    +     *
    +     * @param time the time string.
    +     * @exception IllegalArgumentException if String is an illegal format.
    +     */
    +    public DERGeneralizedTime(
    +        String  time)
    +    {
    +        this.time = Strings.toByteArray(time);
    +        try
    +        {
    +            this.getDate();
    +        }
    +        catch (ParseException e)
    +        {
    +            throw new IllegalArgumentException("invalid date string: " + e.getMessage());
    +        }
    +    }
    +
    +    /**
    +     * base constructor from a java.util.date object
    +     */
    +    public DERGeneralizedTime(
    +        Date time)
    +    {
    +        SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
    +
    +        dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
    +
    +        this.time = Strings.toByteArray(dateF.format(time));
    +    }
    +
    +    DERGeneralizedTime(
    +        byte[]  bytes)
    +    {
    +        this.time = bytes;
    +    }
    +
    +    /**
    +     * Return the time.
    +     * @return The time string as it appeared in the encoded object.
    +     */
    +    public String getTimeString()
    +    {
    +        return Strings.fromByteArray(time);
    +    }
    +    
    +    /**
    +     * return the time - always in the form of 
    +     *  YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm).
    +     * <p>
    +     * Normally in a certificate we would expect "Z" rather than "GMT",
    +     * however adding the "GMT" means we can just use:
    +     * <pre>
    +     *     dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
    +     * </pre>
    +     * To read in the time and get a date which is compatible with our local
    +     * time zone.
    +     */
    +    public String getTime()
    +    {
    +        String stime = Strings.fromByteArray(time);
    +
    +        //
    +        // standardise the format.
    +        //             
    +        if (stime.charAt(stime.length() - 1) == 'Z')
    +        {
    +            return stime.substring(0, stime.length() - 1) + "GMT+00:00";
    +        }
    +        else
    +        {
    +            int signPos = stime.length() - 5;
    +            char sign = stime.charAt(signPos);
    +            if (sign == '-' || sign == '+')
    +            {
    +                return stime.substring(0, signPos)
    +                    + "GMT"
    +                    + stime.substring(signPos, signPos + 3)
    +                    + ":"
    +                    + stime.substring(signPos + 3);
    +            }
    +            else
    +            {
    +                signPos = stime.length() - 3;
    +                sign = stime.charAt(signPos);
    +                if (sign == '-' || sign == '+')
    +                {
    +                    return stime.substring(0, signPos)
    +                        + "GMT"
    +                        + stime.substring(signPos)
    +                        + ":00";
    +                }
    +            }
    +        }            
    +        return stime + calculateGMTOffset();
    +    }
    +
    +    private String calculateGMTOffset()
    +    {
    +        String sign = "+";
    +        TimeZone timeZone = TimeZone.getDefault();
    +        int offset = timeZone.getRawOffset();
    +        if (offset < 0)
    +        {
    +            sign = "-";
    +            offset = -offset;
    +        }
    +        int hours = offset / (60 * 60 * 1000);
    +        int minutes = (offset - (hours * 60 * 60 * 1000)) / (60 * 1000);
    +
    +        try
    +        {
    +            if (timeZone.useDaylightTime() && timeZone.inDaylightTime(this.getDate()))
    +            {
    +                hours += sign.equals("+") ? 1 : -1;
    +            }
    +        }
    +        catch (ParseException e)
    +        {
    +            // we'll do our best and ignore daylight savings
    +        }
    +
    +        return "GMT" + sign + convert(hours) + ":" + convert(minutes);
    +    }
    +
    +    private String convert(int time)
    +    {
    +        if (time < 10)
    +        {
    +            return "0" + time;
    +        }
    +
    +        return Integer.toString(time);
    +    }
    +
    +    public Date getDate()
    +        throws ParseException
    +    {
    +        SimpleDateFormat dateF;
    +        String stime = Strings.fromByteArray(time);
    +        String d = stime;
    +
    +        if (stime.endsWith("Z"))
    +        {
    +            if (hasFractionalSeconds())
    +            {
    +                dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'");
    +            }
    +            else
    +            {
    +                dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
    +            }
    +
    +            dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
    +        }
    +        else if (stime.indexOf('-') > 0 || stime.indexOf('+') > 0)
    +        {
    +            d = this.getTime();
    +            if (hasFractionalSeconds())
    +            { 
    +                dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSSz");
    +            }
    +            else
    +            {
    +                dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
    +            }
    +
    +            dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
    +        }
    +        else
    +        {
    +            if (hasFractionalSeconds())
    +            {
    +                dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS");
    +            }
    +            else
    +            {
    +                dateF = new SimpleDateFormat("yyyyMMddHHmmss");
    +            }
    +
    +            dateF.setTimeZone(new SimpleTimeZone(0, TimeZone.getDefault().getID()));
    +        }
    +
    +        if (hasFractionalSeconds())
    +        {
    +            // java misinterprets extra digits as being milliseconds...
    +            String frac = d.substring(14);
    +            int    index;
    +            for (index = 1; index < frac.length(); index++)
    +            {
    +                char ch = frac.charAt(index);
    +                if (!('0' <= ch && ch <= '9'))
    +                {
    +                    break;        
    +                }
    +            }
    +
    +            if (index - 1 > 3)
    +            {
    +                frac = frac.substring(0, 4) + frac.substring(index);
    +                d = d.substring(0, 14) + frac;
    +            }
    +            else if (index - 1 == 1)
    +            {
    +                frac = frac.substring(0, index) + "00" + frac.substring(index);
    +                d = d.substring(0, 14) + frac;
    +            }
    +            else if (index - 1 == 2)
    +            {
    +                frac = frac.substring(0, index) + "0" + frac.substring(index);
    +                d = d.substring(0, 14) + frac;
    +            }
    +        }
    +
    +        return dateF.parse(d);
    +    }
    +
    +    private boolean hasFractionalSeconds()
    +    {
    +        for (int i = 0; i != time.length; i++)
    +        {
    +            if (time[i] == '.')
    +            {
    +                if (i == 14)
    +                {
    +                    return true;
    +                }
    +            }
    +        }
    +        return false;
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return false;
    +    }
    +
    +    int encodedLength()
    +    {
    +        int length = time.length;
    +
    +        return 1 + StreamUtil.calculateBodyLength(length) + length;
    +    }
    +
    +    void encode(
    +        ASN1OutputStream  out)
    +        throws IOException
    +    {
    +        out.writeEncoded(BERTags.GENERALIZED_TIME, time);
    +    }
    +    
    +    boolean asn1Equals(
    +        ASN1Primitive  o)
    +    {
    +        if (!(o instanceof DERGeneralizedTime))
    +        {
    +            return false;
    +        }
    +
    +        return Arrays.areEqual(time, ((DERGeneralizedTime)o).time);
    +    }
    +    
    +    public int hashCode()
    +    {
    +        return Arrays.hashCode(time);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERGeneralString.java+110 0 added
    @@ -0,0 +1,110 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +import org.bouncycastle.util.Arrays;
    +import org.bouncycastle.util.Strings;
    +
    +public class DERGeneralString 
    +    extends ASN1Primitive
    +    implements ASN1String
    +{
    +    private byte[] string;
    +
    +    public static DERGeneralString getInstance(
    +        Object obj) 
    +    {
    +        if (obj == null || obj instanceof DERGeneralString) 
    +        {
    +            return (DERGeneralString) obj;
    +        }
    +
    +        if (obj instanceof byte[])
    +        {
    +            try
    +            {
    +                return (DERGeneralString)fromByteArray((byte[])obj);
    +            }
    +            catch (Exception e)
    +            {
    +                throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("illegal object in getInstance: "
    +                + obj.getClass().getName());
    +    }
    +
    +    public static DERGeneralString getInstance(
    +        ASN1TaggedObject obj, 
    +        boolean explicit) 
    +    {
    +        ASN1Primitive o = obj.getObject();
    +
    +        if (explicit || o instanceof DERGeneralString)
    +        {
    +            return getInstance(o);
    +        }
    +        else
    +        {
    +            return new DERGeneralString(((ASN1OctetString)o).getOctets());
    +        }
    +    }
    +
    +    DERGeneralString(byte[] string)
    +    {
    +        this.string = string;
    +    }
    +
    +    public DERGeneralString(String string) 
    +    {
    +        this.string = Strings.toByteArray(string);
    +    }
    +    
    +    public String getString() 
    +    {
    +        return Strings.fromByteArray(string);
    +    }
    +
    +    public String toString()
    +    {
    +        return getString();
    +    }
    +
    +    public byte[] getOctets() 
    +    {
    +        return Arrays.clone(string);
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return false;
    +    }
    +
    +    int encodedLength()
    +    {
    +        return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
    +    }
    +
    +    void encode(ASN1OutputStream out)
    +        throws IOException 
    +    {
    +        out.writeEncoded(BERTags.GENERAL_STRING, string);
    +    }
    +    
    +    public int hashCode() 
    +    {
    +        return Arrays.hashCode(string);
    +    }
    +    
    +    boolean asn1Equals(ASN1Primitive o)
    +    {
    +        if (!(o instanceof DERGeneralString)) 
    +        {
    +            return false;
    +        }
    +        DERGeneralString s = (DERGeneralString)o;
    +
    +        return Arrays.areEqual(string, s.string);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERGenerator.java+119 0 added
    @@ -0,0 +1,119 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.ByteArrayOutputStream;
    +import java.io.IOException;
    +import java.io.InputStream;
    +import java.io.OutputStream;
    +
    +import org.bouncycastle.util.io.Streams;
    +
    +public abstract class DERGenerator
    +    extends ASN1Generator
    +{       
    +    private boolean      _tagged = false;
    +    private boolean      _isExplicit;
    +    private int          _tagNo;
    +    
    +    protected DERGenerator(
    +        OutputStream out)
    +    {
    +        super(out);
    +    }
    +
    +    public DERGenerator(
    +        OutputStream out,
    +        int          tagNo,
    +        boolean      isExplicit)
    +    { 
    +        super(out);
    +        
    +        _tagged = true;
    +        _isExplicit = isExplicit;
    +        _tagNo = tagNo;
    +    }
    +
    +    private void writeLength(
    +        OutputStream out,
    +        int          length)
    +        throws IOException
    +    {
    +        if (length > 127)
    +        {
    +            int size = 1;
    +            int val = length;
    +
    +            while ((val >>>= 8) != 0)
    +            {
    +                size++;
    +            }
    +
    +            out.write((byte)(size | 0x80));
    +
    +            for (int i = (size - 1) * 8; i >= 0; i -= 8)
    +            {
    +                out.write((byte)(length >> i));
    +            }
    +        }
    +        else
    +        {
    +            out.write((byte)length);
    +        }
    +    }
    +
    +    void writeDEREncoded(
    +        OutputStream out,
    +        int          tag,
    +        byte[]       bytes)
    +        throws IOException
    +    {
    +        out.write(tag);
    +        writeLength(out, bytes.length);
    +        out.write(bytes);
    +    }
    +
    +    void writeDEREncoded(
    +        int       tag,
    +        byte[]    bytes)
    +        throws IOException
    +    {
    +        if (_tagged)
    +        {
    +            int tagNum = _tagNo | BERTags.TAGGED;
    +            
    +            if (_isExplicit)
    +            {
    +                int newTag = _tagNo | BERTags.CONSTRUCTED | BERTags.TAGGED;
    +
    +                ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    +                
    +                writeDEREncoded(bOut, tag, bytes);
    +                
    +                writeDEREncoded(_out, newTag, bOut.toByteArray());
    +            }
    +            else
    +            {   
    +                if ((tag & BERTags.CONSTRUCTED) != 0)
    +                {
    +                    writeDEREncoded(_out, tagNum | BERTags.CONSTRUCTED, bytes);
    +                }
    +                else
    +                {
    +                    writeDEREncoded(_out, tagNum, bytes);
    +                }
    +            }
    +        }
    +        else
    +        {
    +            writeDEREncoded(_out, tag, bytes);
    +        }
    +    }
    +    
    +    void writeDEREncoded(
    +        OutputStream out,
    +        int          tag,
    +        InputStream  in)
    +        throws IOException
    +    {
    +        writeDEREncoded(out, tag, Streams.readAll(in));
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERIA5String.java+183 0 added
    @@ -0,0 +1,183 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +import org.bouncycastle.util.Arrays;
    +import org.bouncycastle.util.Strings;
    +
    +/**
    + * DER IA5String object - this is an ascii string.
    + */
    +public class DERIA5String
    +    extends ASN1Primitive
    +    implements ASN1String
    +{
    +    private byte[]  string;
    +
    +    /**
    +     * return a IA5 string from the passed in object
    +     *
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static DERIA5String getInstance(
    +        Object  obj)
    +    {
    +        if (obj == null || obj instanceof DERIA5String)
    +        {
    +            return (DERIA5String)obj;
    +        }
    +
    +        if (obj instanceof byte[])
    +        {
    +            try
    +            {
    +                return (DERIA5String)fromByteArray((byte[])obj);
    +            }
    +            catch (Exception e)
    +            {
    +                throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * return an IA5 String from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the tagged object cannot
    +     *               be converted.
    +     */
    +    public static DERIA5String getInstance(
    +        ASN1TaggedObject obj,
    +        boolean          explicit)
    +    {
    +        ASN1Primitive o = obj.getObject();
    +
    +        if (explicit || o instanceof DERIA5String)
    +        {
    +            return getInstance(o);
    +        }
    +        else
    +        {
    +            return new DERIA5String(((ASN1OctetString)o).getOctets());
    +        }
    +    }
    +
    +    /**
    +     * basic constructor - with bytes.
    +     */
    +    DERIA5String(
    +        byte[]   string)
    +    {
    +        this.string = string;
    +    }
    +
    +    /**
    +     * basic constructor - without validation.
    +     */
    +    public DERIA5String(
    +        String   string)
    +    {
    +        this(string, false);
    +    }
    +
    +    /**
    +     * Constructor with optional validation.
    +     *
    +     * @param string the base string to wrap.
    +     * @param validate whether or not to check the string.
    +     * @throws IllegalArgumentException if validate is true and the string
    +     * contains characters that should not be in an IA5String.
    +     */
    +    public DERIA5String(
    +        String   string,
    +        boolean  validate)
    +    {
    +        if (string == null)
    +        {
    +            throw new NullPointerException("string cannot be null");
    +        }
    +        if (validate && !isIA5String(string))
    +        {
    +            throw new IllegalArgumentException("string contains illegal characters");
    +        }
    +
    +        this.string = Strings.toByteArray(string);
    +    }
    +
    +    public String getString()
    +    {
    +        return Strings.fromByteArray(string);
    +    }
    +
    +    public String toString()
    +    {
    +        return getString();
    +    }
    +
    +    public byte[] getOctets()
    +    {
    +        return Arrays.clone(string);
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return false;
    +    }
    +
    +    int encodedLength()
    +    {
    +        return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
    +    }
    +
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        out.writeEncoded(BERTags.IA5_STRING, string);
    +    }
    +
    +    public int hashCode()
    +    {
    +        return Arrays.hashCode(string);
    +    }
    +
    +    boolean asn1Equals(
    +        ASN1Primitive o)
    +    {
    +        if (!(o instanceof DERIA5String))
    +        {
    +            return false;
    +        }
    +
    +        DERIA5String  s = (DERIA5String)o;
    +
    +        return Arrays.areEqual(string, s.string);
    +    }
    +
    +    /**
    +     * return true if the passed in String can be represented without
    +     * loss as an IA5String, false otherwise.
    +     *
    +     * @return true if in printable set, false otherwise.
    +     */
    +    public static boolean isIA5String(
    +        String  str)
    +    {
    +        for (int i = str.length() - 1; i >= 0; i--)
    +        {
    +            char    ch = str.charAt(i);
    +
    +            if (ch > 0x007f)
    +            {
    +                return false;
    +            }
    +        }
    +
    +        return true;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERInteger.java+148 0 added
    @@ -0,0 +1,148 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.math.BigInteger;
    +
    +import org.bouncycastle.util.Arrays;
    +
    +public class DERInteger
    +    extends ASN1Primitive
    +{
    +    byte[]      bytes;
    +
    +    /**
    +     * return an integer from the passed in object
    +     *
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static ASN1Integer getInstance(
    +        Object  obj)
    +    {
    +        if (obj == null || obj instanceof ASN1Integer)
    +        {
    +            return (ASN1Integer)obj;
    +        }
    +        if (obj instanceof DERInteger)
    +        {
    +            return new ASN1Integer((((DERInteger)obj).getValue()));
    +        }
    +
    +        if (obj instanceof byte[])
    +        {
    +            try
    +            {
    +                return (ASN1Integer)fromByteArray((byte[])obj);
    +            }
    +            catch (Exception e)
    +            {
    +                throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * return an Integer from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the tagged object cannot
    +     *               be converted.
    +     */
    +    public static ASN1Integer getInstance(
    +        ASN1TaggedObject obj,
    +        boolean          explicit)
    +    {
    +        ASN1Primitive o = obj.getObject();
    +
    +        if (explicit || o instanceof DERInteger)
    +        {
    +            return getInstance(o);
    +        }
    +        else
    +        {
    +            return new ASN1Integer(ASN1OctetString.getInstance(obj.getObject()).getOctets());
    +        }
    +    }
    +
    +    public DERInteger(
    +        long         value)
    +    {
    +        bytes = BigInteger.valueOf(value).toByteArray();
    +    }
    +
    +    public DERInteger(
    +        BigInteger   value)
    +    {
    +        bytes = value.toByteArray();
    +    }
    +
    +    public DERInteger(
    +        byte[]   bytes)
    +    {
    +        this.bytes = bytes;
    +    }
    +
    +    public BigInteger getValue()
    +    {
    +        return new BigInteger(bytes);
    +    }
    +
    +    /**
    +     * in some cases positive values get crammed into a space,
    +     * that's not quite big enough...
    +     */
    +    public BigInteger getPositiveValue()
    +    {
    +        return new BigInteger(1, bytes);
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return false;
    +    }
    +
    +    int encodedLength()
    +    {
    +        return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
    +    }
    +
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        out.writeEncoded(BERTags.INTEGER, bytes);
    +    }
    +    
    +    public int hashCode()
    +    {
    +         int     value = 0;
    + 
    +         for (int i = 0; i != bytes.length; i++)
    +         {
    +             value ^= (bytes[i] & 0xff) << (i % 4);
    +         }
    + 
    +         return value;
    +    }
    +
    +    boolean asn1Equals(
    +        ASN1Primitive  o)
    +    {
    +        if (!(o instanceof DERInteger))
    +        {
    +            return false;
    +        }
    +
    +        DERInteger other = (DERInteger)o;
    +
    +        return Arrays.areEqual(bytes, other.bytes);
    +    }
    +
    +    public String toString()
    +    {
    +      return getValue().toString();
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERNull.java+38 0 added
    @@ -0,0 +1,38 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +/**
    + * A NULL object.
    + */
    +public class DERNull
    +    extends ASN1Null
    +{
    +    public static final DERNull INSTANCE = new DERNull();
    +
    +    private static final byte[]  zeroBytes = new byte[0];
    +
    +    /**
    +     * @deprecated use DERNull.INSTANCE
    +     */
    +    public DERNull()
    +    {
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return false;
    +    }
    +
    +    int encodedLength()
    +    {
    +        return 2;
    +    }
    +
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        out.writeEncoded(BERTags.NULL, zeroBytes);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERNumericString.java+186 0 added
    @@ -0,0 +1,186 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +import org.bouncycastle.util.Arrays;
    +import org.bouncycastle.util.Strings;
    +
    +/**
    + * DER NumericString object - this is an ascii string of characters {0,1,2,3,4,5,6,7,8,9, }.
    + */
    +public class DERNumericString
    +    extends ASN1Primitive
    +    implements ASN1String
    +{
    +    private byte[]  string;
    +
    +    /**
    +     * return a Numeric string from the passed in object
    +     *
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static DERNumericString getInstance(
    +        Object  obj)
    +    {
    +        if (obj == null || obj instanceof DERNumericString)
    +        {
    +            return (DERNumericString)obj;
    +        }
    +
    +        if (obj instanceof byte[])
    +        {
    +            try
    +            {
    +                return (DERNumericString)fromByteArray((byte[])obj);
    +            }
    +            catch (Exception e)
    +            {
    +                throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * return an Numeric String from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the tagged object cannot
    +     *               be converted.
    +     */
    +    public static DERNumericString getInstance(
    +        ASN1TaggedObject obj,
    +        boolean          explicit)
    +    {
    +        ASN1Primitive o = obj.getObject();
    +
    +        if (explicit || o instanceof DERNumericString)
    +        {
    +            return getInstance(o);
    +        }
    +        else
    +        {
    +            return new DERNumericString(ASN1OctetString.getInstance(o).getOctets());
    +        }
    +    }
    +
    +    /**
    +     * basic constructor - with bytes.
    +     */
    +    DERNumericString(
    +        byte[]   string)
    +    {
    +        this.string = string;
    +    }
    +
    +    /**
    +     * basic constructor -  without validation..
    +     */
    +    public DERNumericString(
    +        String   string)
    +    {
    +        this(string, false);
    +    }
    +
    +    /**
    +     * Constructor with optional validation.
    +     *
    +     * @param string the base string to wrap.
    +     * @param validate whether or not to check the string.
    +     * @throws IllegalArgumentException if validate is true and the string
    +     * contains characters that should not be in a NumericString.
    +     */
    +    public DERNumericString(
    +        String   string,
    +        boolean  validate)
    +    {
    +        if (validate && !isNumericString(string))
    +        {
    +            throw new IllegalArgumentException("string contains illegal characters");
    +        }
    +
    +        this.string = Strings.toByteArray(string);
    +    }
    +
    +    public String getString()
    +    {
    +        return Strings.fromByteArray(string);
    +    }
    +
    +    public String toString()
    +    {
    +        return getString();
    +    }
    +
    +    public byte[] getOctets()
    +    {
    +        return Arrays.clone(string);
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return false;
    +    }
    +
    +    int encodedLength()
    +    {
    +        return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
    +    }
    +
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        out.writeEncoded(BERTags.NUMERIC_STRING, string);
    +    }
    +
    +    public int hashCode()
    +    {
    +        return Arrays.hashCode(string);
    +    }
    +
    +    boolean asn1Equals(
    +        ASN1Primitive o)
    +    {
    +        if (!(o instanceof DERNumericString))
    +        {
    +            return false;
    +        }
    +
    +        DERNumericString  s = (DERNumericString)o;
    +
    +        return Arrays.areEqual(string, s.string);
    +    }
    +
    +    /**
    +     * Return true if the string can be represented as a NumericString ('0'..'9', ' ')
    +     *
    +     * @param str string to validate.
    +     * @return true if numeric, fale otherwise.
    +     */
    +    public static boolean isNumericString(
    +        String  str)
    +    {
    +        for (int i = str.length() - 1; i >= 0; i--)
    +        {
    +            char    ch = str.charAt(i);
    +
    +            if (ch > 0x007f)
    +            {
    +                return false;
    +            }
    +
    +            if (('0' <= ch && ch <= '9') || ch == ' ')
    +            {
    +                continue;
    +            }
    +
    +            return false;
    +        }
    +
    +        return true;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERObjectIdentifier.java+425 0 added
    @@ -0,0 +1,425 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.ByteArrayOutputStream;
    +import java.io.IOException;
    +import java.math.BigInteger;
    +
    +import org.bouncycastle.util.Arrays;
    +
    +public class DERObjectIdentifier
    +    extends ASN1Primitive
    +{
    +    String identifier;
    +
    +    private byte[] body;
    +
    +    /**
    +     * return an OID from the passed in object
    +     *
    +     * @throws IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static ASN1ObjectIdentifier getInstance(
    +        Object obj)
    +    {
    +        if (obj == null || obj instanceof ASN1ObjectIdentifier)
    +        {
    +            return (ASN1ObjectIdentifier)obj;
    +        }
    +
    +        if (obj instanceof DERObjectIdentifier)
    +        {
    +            return new ASN1ObjectIdentifier(((DERObjectIdentifier)obj).getId());
    +        }
    +
    +        if (obj instanceof ASN1Encodable && ((ASN1Encodable)obj).toASN1Primitive() instanceof ASN1ObjectIdentifier)
    +        {
    +            return (ASN1ObjectIdentifier)((ASN1Encodable)obj).toASN1Primitive();
    +        }
    +
    +        if (obj instanceof byte[])
    +        {
    +            return ASN1ObjectIdentifier.fromOctetString((byte[])obj);
    +        }
    +
    +        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * return an Object Identifier from a tagged object.
    +     *
    +     * @param obj      the tagged object holding the object we want
    +     * @param explicit true if the object is meant to be explicitly
    +     *                 tagged false otherwise.
    +     * @throws IllegalArgumentException if the tagged object cannot
    +     * be converted.
    +     */
    +    public static ASN1ObjectIdentifier getInstance(
    +        ASN1TaggedObject obj,
    +        boolean explicit)
    +    {
    +        ASN1Primitive o = obj.getObject();
    +
    +        if (explicit || o instanceof DERObjectIdentifier)
    +        {
    +            return getInstance(o);
    +        }
    +        else
    +        {
    +            return ASN1ObjectIdentifier.fromOctetString(ASN1OctetString.getInstance(obj.getObject()).getOctets());
    +        }
    +    }
    +
    +    private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7f;
    +
    +    DERObjectIdentifier(
    +        byte[] bytes)
    +    {
    +        StringBuffer objId = new StringBuffer();
    +        long value = 0;
    +        BigInteger bigValue = null;
    +        boolean first = true;
    +
    +        for (int i = 0; i != bytes.length; i++)
    +        {
    +            int b = bytes[i] & 0xff;
    +
    +            if (value <= LONG_LIMIT)
    +            {
    +                value += (b & 0x7f);
    +                if ((b & 0x80) == 0)             // end of number reached
    +                {
    +                    if (first)
    +                    {
    +                        if (value < 40)
    +                        {
    +                            objId.append('0');
    +                        }
    +                        else if (value < 80)
    +                        {
    +                            objId.append('1');
    +                            value -= 40;
    +                        }
    +                        else
    +                        {
    +                            objId.append('2');
    +                            value -= 80;
    +                        }
    +                        first = false;
    +                    }
    +
    +                    objId.append('.');
    +                    objId.append(value);
    +                    value = 0;
    +                }
    +                else
    +                {
    +                    value <<= 7;
    +                }
    +            }
    +            else
    +            {
    +                if (bigValue == null)
    +                {
    +                    bigValue = BigInteger.valueOf(value);
    +                }
    +                bigValue = bigValue.or(BigInteger.valueOf(b & 0x7f));
    +                if ((b & 0x80) == 0)
    +                {
    +                    if (first)
    +                    {
    +                        objId.append('2');
    +                        bigValue = bigValue.subtract(BigInteger.valueOf(80));
    +                        first = false;
    +                    }
    +
    +                    objId.append('.');
    +                    objId.append(bigValue);
    +                    bigValue = null;
    +                    value = 0;
    +                }
    +                else
    +                {
    +                    bigValue = bigValue.shiftLeft(7);
    +                }
    +            }
    +        }
    +
    +        this.identifier = objId.toString();
    +        this.body = Arrays.clone(bytes);
    +    }
    +
    +    public DERObjectIdentifier(
    +        String identifier)
    +    {
    +        if (identifier == null)
    +        {
    +            throw new IllegalArgumentException("'identifier' cannot be null");
    +        }
    +        if (!isValidIdentifier(identifier))
    +        {
    +            throw new IllegalArgumentException("string " + identifier + " not an OID");
    +        }
    +
    +        this.identifier = identifier;
    +    }
    +
    +    DERObjectIdentifier(DERObjectIdentifier oid, String branchID)
    +    {
    +        if (!isValidBranchID(branchID, 0))
    +        {
    +            throw new IllegalArgumentException("string " + branchID + " not a valid OID branch");
    +        }
    +
    +        this.identifier = oid.getId() + "." + branchID;
    +    }
    +
    +    public String getId()
    +    {
    +        return identifier;
    +    }
    +
    +    private void writeField(
    +        ByteArrayOutputStream out,
    +        long fieldValue)
    +    {
    +        byte[] result = new byte[9];
    +        int pos = 8;
    +        result[pos] = (byte)((int)fieldValue & 0x7f);
    +        while (fieldValue >= (1L << 7))
    +        {
    +            fieldValue >>= 7;
    +            result[--pos] = (byte)((int)fieldValue & 0x7f | 0x80);
    +        }
    +        out.write(result, pos, 9 - pos);
    +    }
    +
    +    private void writeField(
    +        ByteArrayOutputStream out,
    +        BigInteger fieldValue)
    +    {
    +        int byteCount = (fieldValue.bitLength() + 6) / 7;
    +        if (byteCount == 0)
    +        {
    +            out.write(0);
    +        }
    +        else
    +        {
    +            BigInteger tmpValue = fieldValue;
    +            byte[] tmp = new byte[byteCount];
    +            for (int i = byteCount - 1; i >= 0; i--)
    +            {
    +                tmp[i] = (byte)((tmpValue.intValue() & 0x7f) | 0x80);
    +                tmpValue = tmpValue.shiftRight(7);
    +            }
    +            tmp[byteCount - 1] &= 0x7f;
    +            out.write(tmp, 0, tmp.length);
    +        }
    +    }
    +
    +    private void doOutput(ByteArrayOutputStream aOut)
    +    {
    +        OIDTokenizer tok = new OIDTokenizer(identifier);
    +        int first = Integer.parseInt(tok.nextToken()) * 40;
    +
    +        String secondToken = tok.nextToken();
    +        if (secondToken.length() <= 18)
    +        {
    +            writeField(aOut, first + Long.parseLong(secondToken));
    +        }
    +        else
    +        {
    +            writeField(aOut, new BigInteger(secondToken).add(BigInteger.valueOf(first)));
    +        }
    +
    +        while (tok.hasMoreTokens())
    +        {
    +            String token = tok.nextToken();
    +            if (token.length() <= 18)
    +            {
    +                writeField(aOut, Long.parseLong(token));
    +            }
    +            else
    +            {
    +                writeField(aOut, new BigInteger(token));
    +            }
    +        }
    +    }
    +
    +    protected synchronized byte[] getBody()
    +    {
    +        if (body == null)
    +        {
    +            ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    +
    +            doOutput(bOut);
    +
    +            body = bOut.toByteArray();
    +        }
    +
    +        return body;
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return false;
    +    }
    +
    +    int encodedLength()
    +        throws IOException
    +    {
    +        int length = getBody().length;
    +
    +        return 1 + StreamUtil.calculateBodyLength(length) + length;
    +    }
    +
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        byte[] enc = getBody();
    +
    +        out.write(BERTags.OBJECT_IDENTIFIER);
    +        out.writeLength(enc.length);
    +        out.write(enc);
    +    }
    +
    +    public int hashCode()
    +    {
    +        return identifier.hashCode();
    +    }
    +
    +    boolean asn1Equals(
    +        ASN1Primitive o)
    +    {
    +        if (!(o instanceof DERObjectIdentifier))
    +        {
    +            return false;
    +        }
    +
    +        return identifier.equals(((DERObjectIdentifier)o).identifier);
    +    }
    +
    +    public String toString()
    +    {
    +        return getId();
    +    }
    +
    +    private static boolean isValidBranchID(
    +        String branchID, int start)
    +    {
    +        boolean periodAllowed = false;
    +
    +        int pos = branchID.length();
    +        while (--pos >= start)
    +        {
    +            char ch = branchID.charAt(pos);
    +
    +            // TODO Leading zeroes?
    +            if ('0' <= ch && ch <= '9')
    +            {
    +                periodAllowed = true;
    +                continue;
    +            }
    +
    +            if (ch == '.')
    +            {
    +                if (!periodAllowed)
    +                {
    +                    return false;
    +                }
    +
    +                periodAllowed = false;
    +                continue;
    +            }
    +
    +            return false;
    +        }
    +
    +        return periodAllowed;
    +    }
    +
    +    private static boolean isValidIdentifier(
    +        String identifier)
    +    {
    +        if (identifier.length() < 3 || identifier.charAt(1) != '.')
    +        {
    +            return false;
    +        }
    +
    +        char first = identifier.charAt(0);
    +        if (first < '0' || first > '2')
    +        {
    +            return false;
    +        }
    +
    +        return isValidBranchID(identifier, 2);
    +    }
    +
    +    private static ASN1ObjectIdentifier[][] cache = new ASN1ObjectIdentifier[256][];
    +
    +    static ASN1ObjectIdentifier fromOctetString(byte[] enc)
    +    {
    +        if (enc.length < 3)
    +        {
    +            return new ASN1ObjectIdentifier(enc);
    +        }
    +
    +        int idx1 = enc[enc.length - 2] & 0xff;
    +        // in this case top bit is always zero
    +        int idx2 = enc[enc.length - 1] & 0x7f;
    +
    +        ASN1ObjectIdentifier possibleMatch;
    +
    +        synchronized (cache)
    +        {
    +            ASN1ObjectIdentifier[] first = cache[idx1];
    +            if (first == null)
    +            {
    +                first = cache[idx1] = new ASN1ObjectIdentifier[128];
    +            }
    +
    +            possibleMatch = first[idx2];
    +            if (possibleMatch == null)
    +            {
    +                return first[idx2] = new ASN1ObjectIdentifier(enc);
    +            }
    +
    +            if (Arrays.areEqual(enc, possibleMatch.getBody()))
    +            {
    +                return possibleMatch;
    +            }
    +
    +            idx1 = (idx1 + 1) & 0xff;
    +            first = cache[idx1];
    +            if (first == null)
    +            {
    +                first = cache[idx1] = new ASN1ObjectIdentifier[128];
    +            }
    +
    +            possibleMatch = first[idx2];
    +            if (possibleMatch == null)
    +            {
    +                return first[idx2] = new ASN1ObjectIdentifier(enc);
    +            }
    +
    +            if (Arrays.areEqual(enc, possibleMatch.getBody()))
    +            {
    +                return possibleMatch;
    +            }
    +
    +            idx2 = (idx2 + 1) & 0x7f;
    +            possibleMatch = first[idx2];
    +            if (possibleMatch == null)
    +            {
    +                return first[idx2] = new ASN1ObjectIdentifier(enc);
    +            }
    +        }
    +
    +        if (Arrays.areEqual(enc, possibleMatch.getBody()))
    +        {
    +            return possibleMatch;
    +        }
    +
    +        return new ASN1ObjectIdentifier(enc);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DEROctetString.java+48 0 added
    @@ -0,0 +1,48 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +public class DEROctetString
    +    extends ASN1OctetString
    +{
    +    /**
    +     * @param string the octets making up the octet string.
    +     */
    +    public DEROctetString(
    +        byte[]  string)
    +    {
    +        super(string);
    +    }
    +
    +    public DEROctetString(
    +        ASN1Encodable obj)
    +        throws IOException
    +    {
    +        super(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER));
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return false;
    +    }
    +
    +    int encodedLength()
    +    {
    +        return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
    +    }
    +
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        out.writeEncoded(BERTags.OCTET_STRING, string);
    +    }
    +
    +    static void encode(
    +        DEROutputStream derOut,
    +        byte[]          bytes)
    +        throws IOException
    +    {
    +        derOut.writeEncoded(BERTags.OCTET_STRING, bytes);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DEROctetStringParser.java+39 0 added
    @@ -0,0 +1,39 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.io.InputStream;
    +
    +public class DEROctetStringParser
    +    implements ASN1OctetStringParser
    +{
    +    private DefiniteLengthInputStream stream;
    +
    +    DEROctetStringParser(
    +        DefiniteLengthInputStream stream)
    +    {
    +        this.stream = stream;
    +    }
    +
    +    public InputStream getOctetStream()
    +    {
    +        return stream;
    +    }
    +
    +    public ASN1Primitive getLoadedObject()
    +        throws IOException
    +    {
    +        return new DEROctetString(stream.toByteArray());
    +    }
    +    
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        try
    +        {
    +            return getLoadedObject();
    +        }
    +        catch (IOException e)
    +        {
    +            throw new ASN1ParsingException("IOException converting stream to byte array: " + e.getMessage(), e);
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DEROutputStream.java+41 0 added
    @@ -0,0 +1,41 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.io.OutputStream;
    +
    +/**
    + * Stream that outputs encoding based on distinguished encoding rules.
    + */
    +public class DEROutputStream
    +    extends ASN1OutputStream
    +{
    +    public DEROutputStream(
    +        OutputStream    os)
    +    {
    +        super(os);
    +    }
    +
    +    public void writeObject(
    +        ASN1Encodable obj)
    +        throws IOException
    +    {
    +        if (obj != null)
    +        {
    +            obj.toASN1Primitive().toDERObject().encode(this);
    +        }
    +        else
    +        {
    +            throw new IOException("null object detected");
    +        }
    +    }
    +
    +    ASN1OutputStream getDERSubStream()
    +    {
    +        return this;
    +    }
    +
    +    ASN1OutputStream getDLSubStream()
    +    {
    +        return this;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERPrintableString.java+213 0 added
    @@ -0,0 +1,213 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +import org.bouncycastle.util.Arrays;
    +import org.bouncycastle.util.Strings;
    +
    +/**
    + * DER PrintableString object.
    + */
    +public class DERPrintableString
    +    extends ASN1Primitive
    +    implements ASN1String
    +{
    +    private byte[]  string;
    +
    +    /**
    +     * return a printable string from the passed in object.
    +     * 
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static DERPrintableString getInstance(
    +        Object  obj)
    +    {
    +        if (obj == null || obj instanceof DERPrintableString)
    +        {
    +            return (DERPrintableString)obj;
    +        }
    +
    +        if (obj instanceof byte[])
    +        {
    +            try
    +            {
    +                return (DERPrintableString)fromByteArray((byte[])obj);
    +            }
    +            catch (Exception e)
    +            {
    +                throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * return a Printable String from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the tagged object cannot
    +     *               be converted.
    +     */
    +    public static DERPrintableString getInstance(
    +        ASN1TaggedObject obj,
    +        boolean          explicit)
    +    {
    +        ASN1Primitive o = obj.getObject();
    +
    +        if (explicit || o instanceof DERPrintableString)
    +        {
    +            return getInstance(o);
    +        }
    +        else
    +        {
    +            return new DERPrintableString(ASN1OctetString.getInstance(o).getOctets());
    +        }
    +    }
    +
    +    /**
    +     * basic constructor - byte encoded string.
    +     */
    +    DERPrintableString(
    +        byte[]   string)
    +    {
    +        this.string = string;
    +    }
    +
    +    /**
    +     * basic constructor - this does not validate the string
    +     */
    +    public DERPrintableString(
    +        String   string)
    +    {
    +        this(string, false);
    +    }
    +
    +    /**
    +     * Constructor with optional validation.
    +     *
    +     * @param string the base string to wrap.
    +     * @param validate whether or not to check the string.
    +     * @throws IllegalArgumentException if validate is true and the string
    +     * contains characters that should not be in a PrintableString.
    +     */
    +    public DERPrintableString(
    +        String   string,
    +        boolean  validate)
    +    {
    +        if (validate && !isPrintableString(string))
    +        {
    +            throw new IllegalArgumentException("string contains illegal characters");
    +        }
    +
    +        this.string = Strings.toByteArray(string);
    +    }
    +
    +    public String getString()
    +    {
    +        return Strings.fromByteArray(string);
    +    }
    +
    +    public byte[] getOctets()
    +    {
    +        return Arrays.clone(string);
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return false;
    +    }
    +
    +    int encodedLength()
    +    {
    +        return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
    +    }
    +
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        out.writeEncoded(BERTags.PRINTABLE_STRING, string);
    +    }
    +
    +    public int hashCode()
    +    {
    +        return Arrays.hashCode(string);
    +    }
    +
    +    boolean asn1Equals(
    +        ASN1Primitive o)
    +    {
    +        if (!(o instanceof DERPrintableString))
    +        {
    +            return false;
    +        }
    +
    +        DERPrintableString  s = (DERPrintableString)o;
    +
    +        return Arrays.areEqual(string, s.string);
    +    }
    +
    +    public String toString()
    +    {
    +        return getString();
    +    }
    +
    +    /**
    +     * return true if the passed in String can be represented without
    +     * loss as a PrintableString, false otherwise.
    +     *
    +     * @return true if in printable set, false otherwise.
    +     */
    +    public static boolean isPrintableString(
    +        String  str)
    +    {
    +        for (int i = str.length() - 1; i >= 0; i--)
    +        {
    +            char    ch = str.charAt(i);
    +
    +            if (ch > 0x007f)
    +            {
    +                return false;
    +            }
    +
    +            if ('a' <= ch && ch <= 'z')
    +            {
    +                continue;
    +            }
    +
    +            if ('A' <= ch && ch <= 'Z')
    +            {
    +                continue;
    +            }
    +
    +            if ('0' <= ch && ch <= '9')
    +            {
    +                continue;
    +            }
    +
    +            switch (ch)
    +            {
    +            case ' ':
    +            case '\'':
    +            case '(':
    +            case ')':
    +            case '+':
    +            case '-':
    +            case '.':
    +            case ':':
    +            case '=':
    +            case '?':
    +            case '/':
    +            case ',':
    +                continue;
    +            }
    +
    +            return false;
    +        }
    +
    +        return true;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERSequenceGenerator.java+45 0 added
    @@ -0,0 +1,45 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.ByteArrayOutputStream;
    +import java.io.IOException;
    +import java.io.OutputStream;
    +
    +public class DERSequenceGenerator
    +    extends DERGenerator
    +{
    +    private final ByteArrayOutputStream _bOut = new ByteArrayOutputStream();
    +
    +    public DERSequenceGenerator(
    +        OutputStream out)
    +        throws IOException
    +    {
    +        super(out);
    +    }
    +
    +    public DERSequenceGenerator(
    +        OutputStream out,
    +        int          tagNo,
    +        boolean      isExplicit)
    +        throws IOException
    +    {
    +        super(out, tagNo, isExplicit);
    +    }
    +
    +    public void addObject(
    +        ASN1Encodable object)
    +        throws IOException
    +    {
    +        object.toASN1Primitive().encode(new DEROutputStream(_bOut));
    +    }
    +    
    +    public OutputStream getRawOutputStream()
    +    {
    +        return _bOut;
    +    }
    +    
    +    public void close() 
    +        throws IOException
    +    {
    +        writeDEREncoded(BERTags.CONSTRUCTED | BERTags.SEQUENCE, _bOut.toByteArray());
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERSequence.java+98 0 added
    @@ -0,0 +1,98 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.util.Enumeration;
    +
    +public class DERSequence
    +    extends ASN1Sequence
    +{
    +    private int bodyLength = -1;
    +
    +    /**
    +     * create an empty sequence
    +     */
    +    public DERSequence()
    +    {
    +    }
    +
    +    /**
    +     * create a sequence containing one object
    +     */
    +    public DERSequence(
    +        ASN1Encodable obj)
    +    {
    +        super(obj);
    +    }
    +
    +    /**
    +     * create a sequence containing a vector of objects.
    +     */
    +    public DERSequence(
    +        ASN1EncodableVector v)
    +    {
    +        super(v);
    +    }
    +
    +    /**
    +     * create a sequence containing an array of objects.
    +     */
    +    public DERSequence(
    +        ASN1Encodable[]   array)
    +    {
    +        super(array);
    +    }
    +
    +    private int getBodyLength()
    +        throws IOException
    +    {
    +        if (bodyLength < 0)
    +        {
    +            int length = 0;
    +
    +            for (Enumeration e = this.getObjects(); e.hasMoreElements();)
    +            {
    +                Object    obj = e.nextElement();
    +
    +                length += ((ASN1Encodable)obj).toASN1Primitive().toDERObject().encodedLength();
    +            }
    +
    +            bodyLength = length;
    +        }
    +
    +        return bodyLength;
    +    }
    +
    +    int encodedLength()
    +        throws IOException
    +    {
    +        int length = getBodyLength();
    +
    +        return 1 + StreamUtil.calculateBodyLength(length) + length;
    +    }
    +
    +    /*
    +     * A note on the implementation:
    +     * <p>
    +     * As DER requires the constructed, definite-length model to
    +     * be used for structured types, this varies slightly from the
    +     * ASN.1 descriptions given. Rather than just outputting SEQUENCE,
    +     * we also have to specify CONSTRUCTED, and the objects length.
    +     */
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        ASN1OutputStream        dOut = out.getDERSubStream();
    +        int                     length = getBodyLength();
    +
    +        out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
    +        out.writeLength(length);
    +
    +        for (Enumeration e = this.getObjects(); e.hasMoreElements();)
    +        {
    +            Object    obj = e.nextElement();
    +
    +            dOut.writeObject((ASN1Encodable)obj);
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERSequenceParser.java+38 0 added
    @@ -0,0 +1,38 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +public class DERSequenceParser
    +    implements ASN1SequenceParser
    +{
    +    private ASN1StreamParser _parser;
    +
    +    DERSequenceParser(ASN1StreamParser parser)
    +    {
    +        this._parser = parser;
    +    }
    +
    +    public ASN1Encodable readObject()
    +        throws IOException
    +    {
    +        return _parser.readObject();
    +    }
    +
    +    public ASN1Primitive getLoadedObject()
    +        throws IOException
    +    {
    +         return new DERSequence(_parser.readVector());
    +    }
    +
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        try
    +        {
    +            return getLoadedObject();
    +        }
    +        catch (IOException e)
    +        {
    +            throw new IllegalStateException(e.getMessage());
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERSet.java+108 0 added
    @@ -0,0 +1,108 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.util.Enumeration;
    +
    +/**
    + * A DER encoded set object
    + */
    +public class DERSet
    +    extends ASN1Set
    +{
    +    private int bodyLength = -1;
    +
    +    /**
    +     * create an empty set
    +     */
    +    public DERSet()
    +    {
    +    }
    +
    +    /**
    +     * @param obj - a single object that makes up the set.
    +     */
    +    public DERSet(
    +        ASN1Encodable obj)
    +    {
    +        super(obj);
    +    }
    +
    +    /**
    +     * @param v - a vector of objects making up the set.
    +     */
    +    public DERSet(
    +        ASN1EncodableVector v)
    +    {
    +        super(v, true);
    +    }
    +    
    +    /**
    +     * create a set from an array of objects.
    +     */
    +    public DERSet(
    +        ASN1Encodable[]   a)
    +    {
    +        super(a, true);
    +    }
    +
    +    DERSet(
    +        ASN1EncodableVector v,
    +        boolean                  doSort)
    +    {
    +        super(v, doSort);
    +    }
    +
    +    private int getBodyLength()
    +        throws IOException
    +    {
    +        if (bodyLength < 0)
    +        {
    +            int length = 0;
    +
    +            for (Enumeration e = this.getObjects(); e.hasMoreElements();)
    +            {
    +                Object    obj = e.nextElement();
    +
    +                length += ((ASN1Encodable)obj).toASN1Primitive().toDERObject().encodedLength();
    +            }
    +
    +            bodyLength = length;
    +        }
    +
    +        return bodyLength;
    +    }
    +
    +    int encodedLength()
    +        throws IOException
    +    {
    +        int length = getBodyLength();
    +
    +        return 1 + StreamUtil.calculateBodyLength(length) + length;
    +    }
    +
    +    /*
    +     * A note on the implementation:
    +     * <p>
    +     * As DER requires the constructed, definite-length model to
    +     * be used for structured types, this varies slightly from the
    +     * ASN.1 descriptions given. Rather than just outputting SET,
    +     * we also have to specify CONSTRUCTED, and the objects length.
    +     */
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        ASN1OutputStream        dOut = out.getDERSubStream();
    +        int                     length = getBodyLength();
    +
    +        out.write(BERTags.SET | BERTags.CONSTRUCTED);
    +        out.writeLength(length);
    +
    +        for (Enumeration e = this.getObjects(); e.hasMoreElements();)
    +        {
    +            Object    obj = e.nextElement();
    +
    +            dOut.writeObject((ASN1Encodable)obj);
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERSetParser.java+38 0 added
    @@ -0,0 +1,38 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +public class DERSetParser
    +    implements ASN1SetParser
    +{
    +    private ASN1StreamParser _parser;
    +
    +    DERSetParser(ASN1StreamParser parser)
    +    {
    +        this._parser = parser;
    +    }
    +
    +    public ASN1Encodable readObject()
    +        throws IOException
    +    {
    +        return _parser.readObject();
    +    }
    +
    +    public ASN1Primitive getLoadedObject()
    +        throws IOException
    +    {
    +        return new DERSet(_parser.readVector(), false);
    +    }
    +
    +    public ASN1Primitive toASN1Primitive()
    +    {
    +        try
    +        {
    +            return getLoadedObject();
    +        }
    +        catch (IOException e)
    +        {
    +            throw new ASN1ParsingException(e.getMessage(), e);
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERT61String.java+144 0 added
    @@ -0,0 +1,144 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +import org.bouncycastle.util.Arrays;
    +import org.bouncycastle.util.Strings;
    +
    +/**
    + * DER T61String (also the teletex string), try not to use this if you don't need to. The standard support the encoding for
    + * this has been withdrawn.
    + */
    +public class DERT61String
    +    extends ASN1Primitive
    +    implements ASN1String
    +{
    +    private byte[] string;
    +
    +    /**
    +     * return a T61 string from the passed in object.
    +     *
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static DERT61String getInstance(
    +        Object  obj)
    +    {
    +        if (obj == null || obj instanceof DERT61String)
    +        {
    +            return (DERT61String)obj;
    +        }
    +
    +        if (obj instanceof byte[])
    +        {
    +            try
    +            {
    +                return (DERT61String)fromByteArray((byte[])obj);
    +            }
    +            catch (Exception e)
    +            {
    +                throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * return an T61 String from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the tagged object cannot
    +     *               be converted.
    +     */
    +    public static DERT61String getInstance(
    +        ASN1TaggedObject obj,
    +        boolean          explicit)
    +    {
    +        ASN1Primitive o = obj.getObject();
    +
    +        if (explicit || o instanceof DERT61String)
    +        {
    +            return getInstance(o);
    +        }
    +        else
    +        {
    +            return new DERT61String(ASN1OctetString.getInstance(o).getOctets());
    +        }
    +    }
    +
    +    /**
    +     * basic constructor - string encoded as a sequence of bytes.
    +     */
    +    public DERT61String(
    +        byte[]   string)
    +    {
    +        this.string = string;
    +    }
    +
    +    /**
    +     * basic constructor - with string 8 bit assumed.
    +     */
    +    public DERT61String(
    +        String   string)
    +    {
    +        this(Strings.toByteArray(string));
    +    }
    +
    +    /**
    +     * Decode the encoded string and return it, 8 bit encoding assumed.
    +     * @return the decoded String
    +     */
    +    public String getString()
    +    {
    +        return Strings.fromByteArray(string);
    +    }
    +
    +    public String toString()
    +    {
    +        return getString();
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return false;
    +    }
    +
    +    int encodedLength()
    +    {
    +        return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
    +    }
    +
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        out.writeEncoded(BERTags.T61_STRING, string);
    +    }
    +
    +    /**
    +     * Return the encoded string as a byte array.
    +     * @return the actual bytes making up the encoded body of the T61 string.
    +     */
    +    public byte[] getOctets()
    +    {
    +        return Arrays.clone(string);
    +    }
    +
    +    boolean asn1Equals(
    +        ASN1Primitive o)
    +    {
    +        if (!(o instanceof DERT61String))
    +        {
    +            return false;
    +        }
    +
    +        return Arrays.areEqual(string, ((DERT61String)o).string);
    +    }
    +    
    +    public int hashCode()
    +    {
    +        return Arrays.hashCode(string);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERT61UTF8String.java+151 0 added
    @@ -0,0 +1,151 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +import org.bouncycastle.util.Arrays;
    +import org.bouncycastle.util.Strings;
    +
    +/**
    + * DER T61String (also the teletex string) - a "modern" encapsulation that uses UTF-8. If at all possible, avoid this one! It's only for emergencies.
    + * Use UTF8String instead.
    + */
    +public class DERT61UTF8String
    +    extends ASN1Primitive
    +    implements ASN1String
    +{
    +    private byte[] string;
    +
    +    /**
    +     * return a T61 string from the passed in object. UTF-8 Encoding is assumed in this case.
    +     *
    +     * @throws IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static DERT61UTF8String getInstance(
    +        Object obj)
    +    {
    +        if (obj instanceof DERT61String)
    +        {
    +            return new DERT61UTF8String(((DERT61String)obj).getOctets());
    +        }
    +
    +        if (obj == null || obj instanceof DERT61UTF8String)
    +        {
    +            return (DERT61UTF8String)obj;
    +        }
    +
    +        if (obj instanceof byte[])
    +        {
    +            try
    +            {
    +                return new DERT61UTF8String(((DERT61String)fromByteArray((byte[])obj)).getOctets());
    +            }
    +            catch (Exception e)
    +            {
    +                throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * return an T61 String from a tagged object. UTF-8 encoding is assumed in this case.
    +     *
    +     * @param obj      the tagged object holding the object we want
    +     * @param explicit true if the object is meant to be explicitly
    +     *                 tagged false otherwise.
    +     * @throws IllegalArgumentException if the tagged object cannot
    +     * be converted.
    +     */
    +    public static DERT61UTF8String getInstance(
    +        ASN1TaggedObject obj,
    +        boolean explicit)
    +    {
    +        ASN1Primitive o = obj.getObject();
    +
    +        if (explicit || o instanceof DERT61String || o instanceof DERT61UTF8String)
    +        {
    +            return getInstance(o);
    +        }
    +        else
    +        {
    +            return new DERT61UTF8String(ASN1OctetString.getInstance(o).getOctets());
    +        }
    +    }
    +
    +    /**
    +     * basic constructor - string encoded as a sequence of bytes.
    +     */
    +    public DERT61UTF8String(
    +        byte[] string)
    +    {
    +        this.string = string;
    +    }
    +
    +    /**
    +     * basic constructor - with string UTF8 conversion assumed.
    +     */
    +    public DERT61UTF8String(
    +        String string)
    +    {
    +        this(Strings.toUTF8ByteArray(string));
    +    }
    +
    +    /**
    +     * Decode the encoded string and return it, UTF8 assumed.
    +     *
    +     * @return the decoded String
    +     */
    +    public String getString()
    +    {
    +        return Strings.fromUTF8ByteArray(string);
    +    }
    +
    +    public String toString()
    +    {
    +        return getString();
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return false;
    +    }
    +
    +    int encodedLength()
    +    {
    +        return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
    +    }
    +
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        out.writeEncoded(BERTags.T61_STRING, string);
    +    }
    +
    +    /**
    +     * Return the encoded string as a byte array.
    +     *
    +     * @return the actual bytes making up the encoded body of the T61 string.
    +     */
    +    public byte[] getOctets()
    +    {
    +        return Arrays.clone(string);
    +    }
    +
    +    boolean asn1Equals(
    +        ASN1Primitive o)
    +    {
    +        if (!(o instanceof DERT61UTF8String))
    +        {
    +            return false;
    +        }
    +
    +        return Arrays.areEqual(string, ((DERT61UTF8String)o).string);
    +    }
    +
    +    public int hashCode()
    +    {
    +        return Arrays.hashCode(string);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERTaggedObject.java+118 0 added
    @@ -0,0 +1,118 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +/**
    + * DER TaggedObject - in ASN.1 notation this is any object preceded by
    + * a [n] where n is some number - these are assumed to follow the construction
    + * rules (as with sequences).
    + */
    +public class DERTaggedObject
    +    extends ASN1TaggedObject
    +{
    +    private static final byte[] ZERO_BYTES = new byte[0];
    +
    +    /**
    +     * @param explicit true if an explicitly tagged object.
    +     * @param tagNo the tag number for this object.
    +     * @param obj the tagged object.
    +     */
    +    public DERTaggedObject(
    +        boolean       explicit,
    +        int           tagNo,
    +        ASN1Encodable obj)
    +    {
    +        super(explicit, tagNo, obj);
    +    }
    +
    +    public DERTaggedObject(int tagNo, ASN1Encodable encodable)
    +    {
    +        super(true, tagNo, encodable);
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        if (!empty)
    +        {
    +            if (explicit)
    +            {
    +                return true;
    +            }
    +            else
    +            {
    +                ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
    +
    +                return primitive.isConstructed();
    +            }
    +        }
    +        else
    +        {
    +            return true;
    +        }
    +    }
    +
    +    int encodedLength()
    +        throws IOException
    +    {
    +        if (!empty)
    +        {
    +            ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
    +            int length = primitive.encodedLength();
    +
    +            if (explicit)
    +            {
    +                return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
    +            }
    +            else
    +            {
    +                // header length already in calculation
    +                length = length - 1;
    +
    +                return StreamUtil.calculateTagLength(tagNo) + length;
    +            }
    +        }
    +        else
    +        {
    +            return StreamUtil.calculateTagLength(tagNo) + 1;
    +        }
    +    }
    +
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        if (!empty)
    +        {
    +            ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
    +
    +            if (explicit)
    +            {
    +                out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
    +                out.writeLength(primitive.encodedLength());
    +                out.writeObject(primitive);
    +            }
    +            else
    +            {
    +                //
    +                // need to mark constructed types...
    +                //
    +                int flags;
    +                if (primitive.isConstructed())
    +                {
    +                    flags = BERTags.CONSTRUCTED | BERTags.TAGGED;
    +                }
    +                else
    +                {
    +                    flags = BERTags.TAGGED;
    +                }
    +
    +                out.writeTag(flags, tagNo);
    +                out.writeImplicitObject(primitive);
    +            }
    +        }
    +        else
    +        {
    +            out.writeEncoded(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo, ZERO_BYTES);
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERTags.java+9 0 added
    @@ -0,0 +1,9 @@
    +package org.bouncycastle.asn1;
    +
    +/**
    + * @deprecated use BERTags
    + */
    +public interface DERTags
    +    extends BERTags
    +{
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERUniversalString.java+148 0 added
    @@ -0,0 +1,148 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.ByteArrayOutputStream;
    +import java.io.IOException;
    +
    +import org.bouncycastle.util.Arrays;
    +
    +/**
    + * DER UniversalString object.
    + */
    +public class DERUniversalString
    +    extends ASN1Primitive
    +    implements ASN1String
    +{
    +    private static final char[]  table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
    +    private byte[] string;
    +    
    +    /**
    +     * return a Universal String from the passed in object.
    +     *
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static DERUniversalString getInstance(
    +        Object  obj)
    +    {
    +        if (obj == null || obj instanceof DERUniversalString)
    +        {
    +            return (DERUniversalString)obj;
    +        }
    +
    +        if (obj instanceof byte[])
    +        {
    +            try
    +            {
    +                return (DERUniversalString)fromByteArray((byte[])obj);
    +            }
    +            catch (Exception e)
    +            {
    +                throw new IllegalArgumentException("encoding error getInstance: " + e.toString());
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * return a Universal String from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the tagged object cannot
    +     *               be converted.
    +     */
    +    public static DERUniversalString getInstance(
    +        ASN1TaggedObject obj,
    +        boolean          explicit)
    +    {
    +        ASN1Primitive o = obj.getObject();
    +
    +        if (explicit || o instanceof DERUniversalString)
    +        {
    +            return getInstance(o);
    +        }
    +        else
    +        {
    +            return new DERUniversalString(((ASN1OctetString)o).getOctets());
    +        }
    +    }
    +
    +    /**
    +     * basic constructor - byte encoded string.
    +     */
    +    public DERUniversalString(
    +        byte[]   string)
    +    {
    +        this.string = string;
    +    }
    +
    +    public String getString()
    +    {
    +        StringBuffer    buf = new StringBuffer("#");
    +        ByteArrayOutputStream    bOut = new ByteArrayOutputStream();
    +        ASN1OutputStream            aOut = new ASN1OutputStream(bOut);
    +        
    +        try
    +        {
    +            aOut.writeObject(this);
    +        }
    +        catch (IOException e)
    +        {
    +           throw new RuntimeException("internal error encoding BitString");
    +        }
    +        
    +        byte[]    string = bOut.toByteArray();
    +        
    +        for (int i = 0; i != string.length; i++)
    +        {
    +            buf.append(table[(string[i] >>> 4) & 0xf]);
    +            buf.append(table[string[i] & 0xf]);
    +        }
    +        
    +        return buf.toString();
    +    }
    +
    +    public String toString()
    +    {
    +        return getString();
    +    }
    +
    +    public byte[] getOctets()
    +    {
    +        return string;
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return false;
    +    }
    +
    +    int encodedLength()
    +    {
    +        return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
    +    }
    +
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        out.writeEncoded(BERTags.UNIVERSAL_STRING, this.getOctets());
    +    }
    +    
    +    boolean asn1Equals(
    +        ASN1Primitive o)
    +    {
    +        if (!(o instanceof DERUniversalString))
    +        {
    +            return false;
    +        }
    +
    +        return Arrays.areEqual(string, ((DERUniversalString)o).string);
    +    }
    +    
    +    public int hashCode()
    +    {
    +        return Arrays.hashCode(string);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERUTCTime.java+278 0 added
    @@ -0,0 +1,278 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.text.ParseException;
    +import java.text.SimpleDateFormat;
    +import java.util.Date;
    +import java.util.SimpleTimeZone;
    +
    +import org.bouncycastle.util.Arrays;
    +import org.bouncycastle.util.Strings;
    +
    +/**
    + * UTC time object.
    + */
    +public class DERUTCTime
    +    extends ASN1Primitive
    +{
    +    private byte[]      time;
    +
    +    /**
    +     * return an UTC Time from the passed in object.
    +     *
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static ASN1UTCTime getInstance(
    +        Object  obj)
    +    {
    +        if (obj == null || obj instanceof ASN1UTCTime)
    +        {
    +            return (ASN1UTCTime)obj;
    +        }
    +
    +        if (obj instanceof DERUTCTime)
    +        {
    +            return new ASN1UTCTime(((DERUTCTime)obj).time);
    +        }
    +
    +        if (obj instanceof byte[])
    +        {
    +            try
    +            {
    +                return (ASN1UTCTime)fromByteArray((byte[])obj);
    +            }
    +            catch (Exception e)
    +            {
    +                throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * return an UTC Time from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the tagged object cannot
    +     *               be converted.
    +     */
    +    public static ASN1UTCTime getInstance(
    +        ASN1TaggedObject obj,
    +        boolean          explicit)
    +    {
    +        ASN1Object o = obj.getObject();
    +
    +        if (explicit || o instanceof ASN1UTCTime)
    +        {
    +            return getInstance(o);
    +        }
    +        else
    +        {
    +            return new ASN1UTCTime(((ASN1OctetString)o).getOctets());
    +        }
    +    }
    +    
    +    /**
    +     * The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were
    +     * never encoded. When you're creating one of these objects from scratch, that's
    +     * what you want to use, otherwise we'll try to deal with whatever gets read from
    +     * the input stream... (this is why the input format is different from the getTime()
    +     * method output).
    +     * <p>
    +     *
    +     * @param time the time string.
    +     */
    +    public DERUTCTime(
    +        String  time)
    +    {
    +        this.time = Strings.toByteArray(time);
    +        try
    +        {
    +            this.getDate();
    +        }
    +        catch (ParseException e)
    +        {
    +            throw new IllegalArgumentException("invalid date string: " + e.getMessage());
    +        }
    +    }
    +
    +    /**
    +     * base constructer from a java.util.date object
    +     */
    +    public DERUTCTime(
    +        Date time)
    +    {
    +        SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'");
    +
    +        dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
    +
    +        this.time = Strings.toByteArray(dateF.format(time));
    +    }
    +
    +    DERUTCTime(
    +        byte[]  time)
    +    {
    +        this.time = time;
    +    }
    +
    +    /**
    +     * return the time as a date based on whatever a 2 digit year will return. For
    +     * standardised processing use getAdjustedDate().
    +     *
    +     * @return the resulting date
    +     * @exception ParseException if the date string cannot be parsed.
    +     */
    +    public Date getDate()
    +        throws ParseException
    +    {
    +        SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmssz");
    +
    +        return dateF.parse(getTime());
    +    }
    +
    +    /**
    +     * return the time as an adjusted date
    +     * in the range of 1950 - 2049.
    +     *
    +     * @return a date in the range of 1950 to 2049.
    +     * @exception ParseException if the date string cannot be parsed.
    +     */
    +    public Date getAdjustedDate()
    +        throws ParseException
    +    {
    +        SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
    +
    +        dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
    +
    +        return dateF.parse(getAdjustedTime());
    +    }
    +
    +    /**
    +     * return the time - always in the form of 
    +     *  YYMMDDhhmmssGMT(+hh:mm|-hh:mm).
    +     * <p>
    +     * Normally in a certificate we would expect "Z" rather than "GMT",
    +     * however adding the "GMT" means we can just use:
    +     * <pre>
    +     *     dateF = new SimpleDateFormat("yyMMddHHmmssz");
    +     * </pre>
    +     * To read in the time and get a date which is compatible with our local
    +     * time zone.
    +     * <p>
    +     * <b>Note:</b> In some cases, due to the local date processing, this
    +     * may lead to unexpected results. If you want to stick the normal
    +     * convention of 1950 to 2049 use the getAdjustedTime() method.
    +     */
    +    public String getTime()
    +    {
    +        String stime = Strings.fromByteArray(time);
    +
    +        //
    +        // standardise the format.
    +        //
    +        if (stime.indexOf('-') < 0 && stime.indexOf('+') < 0)
    +        {
    +            if (stime.length() == 11)
    +            {
    +                return stime.substring(0, 10) + "00GMT+00:00";
    +            }
    +            else
    +            {
    +                return stime.substring(0, 12) + "GMT+00:00";
    +            }
    +        }
    +        else
    +        {
    +            int index = stime.indexOf('-');
    +            if (index < 0)
    +            {
    +                index = stime.indexOf('+');
    +            }
    +            String d = stime;
    +
    +            if (index == stime.length() - 3)
    +            {
    +                d += "00";
    +            }
    +
    +            if (index == 10)
    +            {
    +                return d.substring(0, 10) + "00GMT" + d.substring(10, 13) + ":" + d.substring(13, 15);
    +            }
    +            else
    +            {
    +                return d.substring(0, 12) + "GMT" + d.substring(12, 15) + ":" +  d.substring(15, 17);
    +            }
    +        }
    +    }
    +
    +    /**
    +     * return a time string as an adjusted date with a 4 digit year. This goes
    +     * in the range of 1950 - 2049.
    +     */
    +    public String getAdjustedTime()
    +    {
    +        String   d = this.getTime();
    +
    +        if (d.charAt(0) < '5')
    +        {
    +            return "20" + d;
    +        }
    +        else
    +        {
    +            return "19" + d;
    +        }
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return false;
    +    }
    +
    +    int encodedLength()
    +    {
    +        int length = time.length;
    +
    +        return 1 + StreamUtil.calculateBodyLength(length) + length;
    +    }
    +
    +    void encode(
    +        ASN1OutputStream  out)
    +        throws IOException
    +    {
    +        out.write(BERTags.UTC_TIME);
    +
    +        int length = time.length;
    +
    +        out.writeLength(length);
    +
    +        for (int i = 0; i != length; i++)
    +        {
    +            out.write((byte)time[i]);
    +        }
    +    }
    +    
    +    boolean asn1Equals(
    +        ASN1Primitive o)
    +    {
    +        if (!(o instanceof DERUTCTime))
    +        {
    +            return false;
    +        }
    +
    +        return Arrays.areEqual(time, ((DERUTCTime)o).time);
    +    }
    +    
    +    public int hashCode()
    +    {
    +        return Arrays.hashCode(time);
    +    }
    +
    +    public String toString() 
    +    {
    +      return Strings.fromByteArray(time);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERUTF8String.java+132 0 added
    @@ -0,0 +1,132 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +import org.bouncycastle.util.Arrays;
    +import org.bouncycastle.util.Strings;
    +
    +/**
    + * DER UTF8String object.
    + */
    +public class DERUTF8String
    +    extends ASN1Primitive
    +    implements ASN1String
    +{
    +    private byte[]  string;
    +
    +    /**
    +     * return an UTF8 string from the passed in object.
    +     * 
    +     * @exception IllegalArgumentException
    +     *                if the object cannot be converted.
    +     */
    +    public static DERUTF8String getInstance(Object obj)
    +    {
    +        if (obj == null || obj instanceof DERUTF8String)
    +        {
    +            return (DERUTF8String)obj;
    +        }
    +
    +        if (obj instanceof byte[])
    +        {
    +            try
    +            {
    +                return (DERUTF8String)fromByteArray((byte[])obj);
    +            }
    +            catch (Exception e)
    +            {
    +                throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("illegal object in getInstance: "
    +                + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * return an UTF8 String from a tagged object.
    +     * 
    +     * @param obj
    +     *            the tagged object holding the object we want
    +     * @param explicit
    +     *            true if the object is meant to be explicitly tagged false
    +     *            otherwise.
    +     * @exception IllegalArgumentException
    +     *                if the tagged object cannot be converted.
    +     */
    +    public static DERUTF8String getInstance(
    +        ASN1TaggedObject obj,
    +        boolean explicit)
    +    {
    +        ASN1Primitive o = obj.getObject();
    +
    +        if (explicit || o instanceof DERUTF8String)
    +        {
    +            return getInstance(o);
    +        }
    +        else
    +        {
    +            return new DERUTF8String(ASN1OctetString.getInstance(o).getOctets());
    +        }
    +    }
    +
    +    /**
    +     * basic constructor - byte encoded string.
    +     */
    +    DERUTF8String(byte[] string)
    +    {
    +        this.string = string;
    +    }
    +
    +    /**
    +     * basic constructor
    +     */
    +    public DERUTF8String(String string)
    +    {
    +        this.string = Strings.toUTF8ByteArray(string);
    +    }
    +
    +    public String getString()
    +    {
    +        return Strings.fromUTF8ByteArray(string);
    +    }
    +
    +    public String toString()
    +    {
    +        return getString();
    +    }
    +
    +    public int hashCode()
    +    {
    +        return Arrays.hashCode(string);
    +    }
    +
    +    boolean asn1Equals(ASN1Primitive o)
    +    {
    +        if (!(o instanceof DERUTF8String))
    +        {
    +            return false;
    +        }
    +
    +        DERUTF8String s = (DERUTF8String)o;
    +
    +        return Arrays.areEqual(string, s.string);
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return false;
    +    }
    +
    +    int encodedLength()
    +        throws IOException
    +    {
    +        return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
    +    }
    +
    +    void encode(ASN1OutputStream out)
    +        throws IOException
    +    {
    +        out.writeEncoded(BERTags.UTF8_STRING, string);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DERVisibleString.java+135 0 added
    @@ -0,0 +1,135 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +import org.bouncycastle.util.Arrays;
    +import org.bouncycastle.util.Strings;
    +
    +/**
    + * DER VisibleString object.
    + */
    +public class DERVisibleString
    +    extends ASN1Primitive
    +    implements ASN1String
    +{
    +    private byte[]  string;
    +
    +    /**
    +     * return a Visible String from the passed in object.
    +     *
    +     * @exception IllegalArgumentException if the object cannot be converted.
    +     */
    +    public static DERVisibleString getInstance(
    +        Object  obj)
    +    {
    +        if (obj == null || obj instanceof DERVisibleString)
    +        {
    +            return (DERVisibleString)obj;
    +        }
    +
    +        if (obj instanceof byte[])
    +        {
    +            try
    +            {
    +                return (DERVisibleString)fromByteArray((byte[])obj);
    +            }
    +            catch (Exception e)
    +            {
    +                throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
    +            }
    +        }
    +
    +        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
    +    }
    +
    +    /**
    +     * return a Visible String from a tagged object.
    +     *
    +     * @param obj the tagged object holding the object we want
    +     * @param explicit true if the object is meant to be explicitly
    +     *              tagged false otherwise.
    +     * @exception IllegalArgumentException if the tagged object cannot
    +     *               be converted.
    +     */
    +    public static DERVisibleString getInstance(
    +        ASN1TaggedObject obj,
    +        boolean          explicit)
    +    {
    +        ASN1Primitive o = obj.getObject();
    +
    +        if (explicit || o instanceof DERVisibleString)
    +        {
    +            return getInstance(o);
    +        }
    +        else
    +        {
    +            return new DERVisibleString(ASN1OctetString.getInstance(o).getOctets());
    +        }
    +    }
    +
    +    /**
    +     * basic constructor - byte encoded string.
    +     */
    +    DERVisibleString(
    +        byte[]   string)
    +    {
    +        this.string = string;
    +    }
    +
    +    /**
    +     * basic constructor
    +     */
    +    public DERVisibleString(
    +        String   string)
    +    {
    +        this.string = Strings.toByteArray(string);
    +    }
    +
    +    public String getString()
    +    {
    +        return Strings.fromByteArray(string);
    +    }
    +
    +    public String toString()
    +    {
    +        return getString();
    +    }
    +
    +    public byte[] getOctets()
    +    {
    +        return Arrays.clone(string);
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        return false;
    +    }
    +
    +    int encodedLength()
    +    {
    +        return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
    +    }
    +
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        out.writeEncoded(BERTags.VISIBLE_STRING, this.string);
    +    }
    +    
    +    boolean asn1Equals(
    +        ASN1Primitive o)
    +    {
    +        if (!(o instanceof DERVisibleString))
    +        {
    +            return false;
    +        }
    +
    +        return Arrays.areEqual(string, ((DERVisibleString)o).string);
    +    }
    +    
    +    public int hashCode()
    +    {
    +        return Arrays.hashCode(string);
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DLOutputStream.java+31 0 added
    @@ -0,0 +1,31 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.io.OutputStream;
    +
    +/**
    + * Stream that outputs encoding based on definite length.
    + */
    +public class DLOutputStream
    +    extends ASN1OutputStream
    +{
    +    public DLOutputStream(
    +        OutputStream os)
    +    {
    +        super(os);
    +    }
    +
    +    public void writeObject(
    +        ASN1Encodable obj)
    +        throws IOException
    +    {
    +        if (obj != null)
    +        {
    +            obj.toASN1Primitive().toDLObject().encode(this);
    +        }
    +        else
    +        {
    +            throw new IOException("null object detected");
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DLSequence.java+98 0 added
    @@ -0,0 +1,98 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.util.Enumeration;
    +
    +public class DLSequence
    +    extends ASN1Sequence
    +{
    +    private int bodyLength = -1;
    +
    +    /**
    +     * create an empty sequence
    +     */
    +    public DLSequence()
    +    {
    +    }
    +
    +    /**
    +     * create a sequence containing one object
    +     */
    +    public DLSequence(
    +        ASN1Encodable obj)
    +    {
    +        super(obj);
    +    }
    +
    +    /**
    +     * create a sequence containing a vector of objects.
    +     */
    +    public DLSequence(
    +        ASN1EncodableVector v)
    +    {
    +        super(v);
    +    }
    +
    +    /**
    +     * create a sequence containing an array of objects.
    +     */
    +    public DLSequence(
    +        ASN1Encodable[] array)
    +    {
    +        super(array);
    +    }
    +
    +    private int getBodyLength()
    +        throws IOException
    +    {
    +        if (bodyLength < 0)
    +        {
    +            int length = 0;
    +
    +            for (Enumeration e = this.getObjects(); e.hasMoreElements();)
    +            {
    +                Object    obj = e.nextElement();
    +
    +                length += ((ASN1Encodable)obj).toASN1Primitive().toDLObject().encodedLength();
    +            }
    +
    +            bodyLength = length;
    +        }
    +
    +        return bodyLength;
    +    }
    +
    +    int encodedLength()
    +        throws IOException
    +    {
    +        int    length = getBodyLength();
    +
    +        return 1 + StreamUtil.calculateBodyLength(length) + length;
    +    }
    +
    +    /*
    +     * A note on the implementation:
    +     * <p>
    +     * As DL requires the constructed, definite-length model to
    +     * be used for structured types, this varies slightly from the
    +     * ASN.1 descriptions given. Rather than just outputting SEQUENCE,
    +     * we also have to specify CONSTRUCTED, and the objects length.
    +     */
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        ASN1OutputStream       dOut = out.getDLSubStream();
    +        int                    length = getBodyLength();
    +
    +        out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
    +        out.writeLength(length);
    +
    +        for (Enumeration e = this.getObjects(); e.hasMoreElements();)
    +        {
    +            Object    obj = e.nextElement();
    +
    +            dOut.writeObject((ASN1Encodable)obj);
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DLSet.java+101 0 added
    @@ -0,0 +1,101 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.util.Enumeration;
    +
    +/**
    + * A DER encoded set object
    + */
    +public class DLSet
    +    extends ASN1Set
    +{
    +    private int bodyLength = -1;
    +
    +    /**
    +     * create an empty set
    +     */
    +    public DLSet()
    +    {
    +    }
    +
    +    /**
    +     * @param obj - a single object that makes up the set.
    +     */
    +    public DLSet(
    +        ASN1Encodable obj)
    +    {
    +        super(obj);
    +    }
    +
    +    /**
    +     * @param v - a vector of objects making up the set.
    +     */
    +    public DLSet(
    +        ASN1EncodableVector v)
    +    {
    +        super(v, false);
    +    }
    +
    +    /**
    +     * create a set from an array of objects.
    +     */
    +    public DLSet(
    +        ASN1Encodable[] a)
    +    {
    +        super(a, false);
    +    }
    +
    +    private int getBodyLength()
    +        throws IOException
    +    {
    +        if (bodyLength < 0)
    +        {
    +            int length = 0;
    +
    +            for (Enumeration e = this.getObjects(); e.hasMoreElements();)
    +            {
    +                Object    obj = e.nextElement();
    +
    +                length += ((ASN1Encodable)obj).toASN1Primitive().toDLObject().encodedLength();
    +            }
    +
    +            bodyLength = length;
    +        }
    +
    +        return bodyLength;
    +    }
    +
    +    int encodedLength()
    +        throws IOException
    +    {
    +        int                     length = getBodyLength();
    +
    +        return 1 + StreamUtil.calculateBodyLength(length) + length;
    +    }
    +
    +    /*
    +     * A note on the implementation:
    +     * <p>
    +     * As DL requires the constructed, definite-length model to
    +     * be used for structured types, this varies slightly from the
    +     * ASN.1 descriptions given. Rather than just outputting SET,
    +     * we also have to specify CONSTRUCTED, and the objects length.
    +     */
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        ASN1OutputStream        dOut = out.getDLSubStream();
    +        int                     length = getBodyLength();
    +
    +        out.write(BERTags.SET | BERTags.CONSTRUCTED);
    +        out.writeLength(length);
    +
    +        for (Enumeration e = this.getObjects(); e.hasMoreElements();)
    +        {
    +            Object    obj = e.nextElement();
    +
    +            dOut.writeObject((ASN1Encodable)obj);
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/DLTaggedObject.java+112 0 added
    @@ -0,0 +1,112 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +/**
    + * Definite Length TaggedObject - in ASN.1 notation this is any object preceded by
    + * a [n] where n is some number - these are assumed to follow the construction
    + * rules (as with sequences).
    + */
    +public class DLTaggedObject
    +    extends ASN1TaggedObject
    +{
    +    private static final byte[] ZERO_BYTES = new byte[0];
    +
    +    /**
    +     * @param explicit true if an explicitly tagged object.
    +     * @param tagNo the tag number for this object.
    +     * @param obj the tagged object.
    +     */
    +    public DLTaggedObject(
    +        boolean explicit,
    +        int tagNo,
    +        ASN1Encodable obj)
    +    {
    +        super(explicit, tagNo, obj);
    +    }
    +
    +    boolean isConstructed()
    +    {
    +        if (!empty)
    +        {
    +            if (explicit)
    +            {
    +                return true;
    +            }
    +            else
    +            {
    +                ASN1Primitive primitive = obj.toASN1Primitive().toDLObject();
    +
    +                return primitive.isConstructed();
    +            }
    +        }
    +        else
    +        {
    +            return true;
    +        }
    +    }
    +
    +    int encodedLength()
    +        throws IOException
    +    {
    +        if (!empty)
    +        {
    +            int length = obj.toASN1Primitive().toDLObject().encodedLength();
    +
    +            if (explicit)
    +            {
    +                return  StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
    +            }
    +            else
    +            {
    +                // header length already in calculation
    +                length = length - 1;
    +
    +                return StreamUtil.calculateTagLength(tagNo) + length;
    +            }
    +        }
    +        else
    +        {
    +            return StreamUtil.calculateTagLength(tagNo) + 1;
    +        }
    +    }
    +
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        if (!empty)
    +        {
    +            ASN1Primitive primitive = obj.toASN1Primitive().toDLObject();
    +
    +            if (explicit)
    +            {
    +                out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
    +                out.writeLength(primitive.encodedLength());
    +                out.writeObject(primitive);
    +            }
    +            else
    +            {
    +                //
    +                // need to mark constructed types...
    +                //
    +                int flags;
    +                if (primitive.isConstructed())
    +                {
    +                    flags = BERTags.CONSTRUCTED | BERTags.TAGGED;
    +                }
    +                else
    +                {
    +                    flags = BERTags.TAGGED;
    +                }
    +
    +                out.writeTag(flags, tagNo);
    +                out.writeImplicitObject(primitive);
    +            }
    +        }
    +        else
    +        {
    +            out.writeEncoded(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo, ZERO_BYTES);
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/dvcs/CertEtcToken.java+171 0 added
  • core/src/main/java/org/bouncycastle/asn1/dvcs/Data.java+149 0 added
  • core/src/main/java/org/bouncycastle/asn1/dvcs/DVCSCertInfoBuilder.java+151 0 added
  • core/src/main/java/org/bouncycastle/asn1/dvcs/DVCSCertInfo.java+302 0 added
  • core/src/main/java/org/bouncycastle/asn1/dvcs/DVCSErrorNotice.java+96 0 added
  • core/src/main/java/org/bouncycastle/asn1/dvcs/DVCSObjectIdentifiers.java+36 0 added
  • core/src/main/java/org/bouncycastle/asn1/dvcs/DVCSRequestInformationBuilder.java+224 0 added
  • core/src/main/java/org/bouncycastle/asn1/dvcs/DVCSRequestInformation.java+271 0 added
  • core/src/main/java/org/bouncycastle/asn1/dvcs/DVCSRequest.java+107 0 added
  • core/src/main/java/org/bouncycastle/asn1/dvcs/DVCSResponse.java+117 0 added
  • core/src/main/java/org/bouncycastle/asn1/dvcs/DVCSTime.java+111 0 added
  • core/src/main/java/org/bouncycastle/asn1/dvcs/PathProcInput.java+180 0 added
  • core/src/main/java/org/bouncycastle/asn1/dvcs/ServiceType.java+92 0 added
  • core/src/main/java/org/bouncycastle/asn1/dvcs/TargetEtcChain.java+191 0 added
  • core/src/main/java/org/bouncycastle/asn1/eac/BidirectionalMap.java+23 0 added
  • core/src/main/java/org/bouncycastle/asn1/eac/CertificateBody.java+475 0 added
  • core/src/main/java/org/bouncycastle/asn1/eac/CertificateHolderAuthorization.java+185 0 added
  • core/src/main/java/org/bouncycastle/asn1/eac/CertificateHolderReference.java+66 0 added
  • core/src/main/java/org/bouncycastle/asn1/eac/CertificationAuthorityReference.java+15 0 added
  • core/src/main/java/org/bouncycastle/asn1/eac/CVCertificate.java+317 0 added
  • core/src/main/java/org/bouncycastle/asn1/eac/CVCertificateRequest.java+170 0 added
  • core/src/main/java/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java+55 0 added
  • core/src/main/java/org/bouncycastle/asn1/eac/EACTags.java+209 0 added
  • core/src/main/java/org/bouncycastle/asn1/eac/ECDSAPublicKey.java+341 0 added
  • core/src/main/java/org/bouncycastle/asn1/eac/Flags.java+96 0 added
  • core/src/main/java/org/bouncycastle/asn1/eac/PackedDate.java+103 0 added
  • core/src/main/java/org/bouncycastle/asn1/eac/PublicKeyDataObject.java+35 0 added
  • core/src/main/java/org/bouncycastle/asn1/eac/RSAPublicKey.java+121 0 added
  • core/src/main/java/org/bouncycastle/asn1/eac/UnsignedInteger.java+74 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/CommitmentTypeIdentifier.java+14 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/CommitmentTypeIndication.java+83 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/CommitmentTypeQualifier.java+108 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/CompleteRevocationRefs.java+65 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/CrlIdentifier.java+106 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/CrlListID.java+66 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/CrlOcspRef.java+106 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/CrlValidatedID.java+82 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/ESFAttributes.java+22 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/OcspIdentifier.java+73 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/OcspListID.java+72 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/OcspResponsesID.java+83 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/OtherHashAlgAndValue.java+81 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/OtherHash.java+81 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/OtherRevRefs.java+87 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/OtherRevVals.java+89 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/RevocationValues.java+151 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/SignaturePolicyIdentifier.java+76 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/SignaturePolicyId.java+103 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/SignerAttribute.java+123 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/SignerLocation.java+162 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/SigPolicyQualifierInfo.java+75 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/SigPolicyQualifiers.java+77 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/SPuri.java+45 0 added
  • core/src/main/java/org/bouncycastle/asn1/esf/SPUserNotice.java+99 0 added
  • core/src/main/java/org/bouncycastle/asn1/ess/ContentHints.java+114 0 added
  • core/src/main/java/org/bouncycastle/asn1/ess/ContentIdentifier.java+63 0 added
  • core/src/main/java/org/bouncycastle/asn1/ess/ESSCertID.java+95 0 added
  • core/src/main/java/org/bouncycastle/asn1/ess/ESSCertIDv2.java+155 0 added
  • core/src/main/java/org/bouncycastle/asn1/ess/OtherCertID.java+137 0 added
  • core/src/main/java/org/bouncycastle/asn1/ess/OtherSigningCertificate.java+109 0 added
  • core/src/main/java/org/bouncycastle/asn1/ess/SigningCertificate.java+109 0 added
  • core/src/main/java/org/bouncycastle/asn1/ess/SigningCertificateV2.java+136 0 added
  • core/src/main/java/org/bouncycastle/asn1/gnu/GNUObjectIdentifiers.java+30 0 added
  • core/src/main/java/org/bouncycastle/asn1/iana/IANAObjectIdentifiers.java+20 0 added
  • core/src/main/java/org/bouncycastle/asn1/icao/CscaMasterList.java+114 0 added
  • core/src/main/java/org/bouncycastle/asn1/icao/DataGroupHash.java+97 0 added
  • core/src/main/java/org/bouncycastle/asn1/icao/ICAOObjectIdentifiers.java+33 0 added
  • core/src/main/java/org/bouncycastle/asn1/icao/LDSSecurityObject.java+159 0 added
  • core/src/main/java/org/bouncycastle/asn1/icao/LDSVersionInfo.java+75 0 added
  • core/src/main/java/org/bouncycastle/asn1/IndefiniteLengthInputStream.java+111 0 added
    @@ -0,0 +1,111 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.EOFException;
    +import java.io.IOException;
    +import java.io.InputStream;
    +
    +class IndefiniteLengthInputStream
    +    extends LimitedInputStream
    +{
    +    private int _b1;
    +    private int _b2;
    +    private boolean _eofReached = false;
    +    private boolean _eofOn00 = true;
    +
    +    IndefiniteLengthInputStream(
    +        InputStream in,
    +        int         limit)
    +        throws IOException
    +    {
    +        super(in, limit);
    +
    +        _b1 = in.read();
    +        _b2 = in.read();
    +
    +        if (_b2 < 0)
    +        {
    +            // Corrupted stream
    +            throw new EOFException();
    +        }
    +
    +        checkForEof();
    +    }
    +
    +    void setEofOn00(
    +        boolean eofOn00)
    +    {
    +        _eofOn00 = eofOn00;
    +        checkForEof();
    +    }
    +
    +    private boolean checkForEof()
    +    {
    +        if (!_eofReached && _eofOn00 && (_b1 == 0x00 && _b2 == 0x00))
    +        {
    +            _eofReached = true;
    +            setParentEofDetect(true);
    +        }
    +        return _eofReached;
    +    }
    +
    +    public int read(byte[] b, int off, int len)
    +        throws IOException
    +    {
    +        // Only use this optimisation if we aren't checking for 00
    +        if (_eofOn00 || len < 3)
    +        {
    +            return super.read(b, off, len);
    +        }
    +
    +        if (_eofReached)
    +        {
    +            return -1;
    +        }
    +
    +        int numRead = _in.read(b, off + 2, len - 2);
    +
    +        if (numRead < 0)
    +        {
    +            // Corrupted stream
    +            throw new EOFException();
    +        }
    +
    +        b[off] = (byte)_b1;
    +        b[off + 1] = (byte)_b2;
    +
    +        _b1 = _in.read();
    +        _b2 = _in.read();
    +
    +        if (_b2 < 0)
    +        {
    +            // Corrupted stream
    +            throw new EOFException();
    +        }
    +
    +        return numRead + 2;
    +    }
    +
    +    public int read()
    +        throws IOException
    +    {
    +        if (checkForEof())
    +        {
    +            return -1;
    +        }
    +
    +        int b = _in.read();
    +
    +        if (b < 0)
    +        {
    +            // Corrupted stream
    +            throw new EOFException();
    +        }
    +
    +        int v = _b1;
    +
    +        _b1 = _b2;
    +        _b2 = b;
    +
    +        return v;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/InMemoryRepresentable.java+9 0 added
    @@ -0,0 +1,9 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +
    +public interface InMemoryRepresentable
    +{
    +    ASN1Primitive getLoadedObject()
    +        throws IOException;
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/isismtt/ISISMTTObjectIdentifiers.java+180 0 added
  • core/src/main/java/org/bouncycastle/asn1/isismtt/ocsp/CertHash.java+124 0 added
  • core/src/main/java/org/bouncycastle/asn1/isismtt/ocsp/RequestedCertificate.java+183 0 added
  • core/src/main/java/org/bouncycastle/asn1/isismtt/x509/AdditionalInformationSyntax.java+70 0 added
  • core/src/main/java/org/bouncycastle/asn1/isismtt/x509/Admissions.java+189 0 added
  • core/src/main/java/org/bouncycastle/asn1/isismtt/x509/AdmissionSyntax.java+280 0 added
  • core/src/main/java/org/bouncycastle/asn1/isismtt/x509/DeclarationOfMajority.java+164 0 added
  • core/src/main/java/org/bouncycastle/asn1/isismtt/x509/MonetaryLimit.java+131 0 added
  • core/src/main/java/org/bouncycastle/asn1/isismtt/x509/NamingAuthority.java+244 0 added
  • core/src/main/java/org/bouncycastle/asn1/isismtt/x509/ProcurationSyntax.java+240 0 added
  • core/src/main/java/org/bouncycastle/asn1/isismtt/x509/ProfessionInfo.java+408 0 added
  • core/src/main/java/org/bouncycastle/asn1/isismtt/x509/Restriction.java+81 0 added
  • core/src/main/java/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java+9 0 added
  • core/src/main/java/org/bouncycastle/asn1/LazyConstructionEnumeration.java+43 0 added
    @@ -0,0 +1,43 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.util.Enumeration;
    +
    +class LazyConstructionEnumeration
    +    implements Enumeration
    +{
    +    private ASN1InputStream aIn;
    +    private Object          nextObj;
    +
    +    public LazyConstructionEnumeration(byte[] encoded)
    +    {
    +        aIn = new ASN1InputStream(encoded, true);
    +        nextObj = readObject();
    +    }
    +
    +    public boolean hasMoreElements()
    +    {
    +        return nextObj != null;
    +    }
    +
    +    public Object nextElement()
    +    {
    +        Object o = nextObj;
    +
    +        nextObj = readObject();
    +
    +        return o;
    +    }
    +
    +    private Object readObject()
    +    {
    +        try
    +        {
    +            return aIn.readObject();
    +        }
    +        catch (IOException e)
    +        {
    +            throw new ASN1ParsingException("malformed DER construction: " + e, e);
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/LazyEncodedSequence.java+109 0 added
    @@ -0,0 +1,109 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.IOException;
    +import java.util.Enumeration;
    +
    +/**
    + * Note: this class is for processing DER/DL encoded sequences only.
    + */
    +class LazyEncodedSequence
    +    extends ASN1Sequence
    +{
    +    private byte[] encoded;
    +
    +    LazyEncodedSequence(
    +        byte[] encoded)
    +        throws IOException
    +    {
    +        this.encoded = encoded;
    +    }
    +
    +    private void parse()
    +    {
    +        Enumeration en = new LazyConstructionEnumeration(encoded);
    +
    +        while (en.hasMoreElements())
    +        {
    +            seq.addElement(en.nextElement());
    +        }
    +
    +        encoded = null;
    +    }
    +
    +    public synchronized ASN1Encodable getObjectAt(int index)
    +    {
    +        if (encoded != null)
    +        {
    +            parse();
    +        }
    +
    +        return super.getObjectAt(index);
    +    }
    +
    +    public synchronized Enumeration getObjects()
    +    {
    +        if (encoded == null)
    +        {
    +            return super.getObjects();
    +        }
    +
    +        return new LazyConstructionEnumeration(encoded);
    +    }
    +
    +    public synchronized int size()
    +    {
    +        if (encoded != null)
    +        {
    +            parse();
    +        }
    +
    +        return super.size();
    +    }
    +
    +    ASN1Primitive toDERObject()
    +    {
    +        if (encoded != null)
    +        {
    +            parse();
    +        }
    +
    +        return super.toDERObject();
    +    }
    +
    +    ASN1Primitive toDLObject()
    +    {
    +        if (encoded != null)
    +        {
    +            parse();
    +        }
    +
    +        return super.toDLObject();
    +    }
    +
    +    int encodedLength()
    +        throws IOException
    +    {
    +        if (encoded != null)
    +        {
    +            return 1 + StreamUtil.calculateBodyLength(encoded.length) + encoded.length;
    +        }
    +        else
    +        {
    +            return super.toDLObject().encodedLength();
    +        }
    +    }
    +
    +    void encode(
    +        ASN1OutputStream out)
    +        throws IOException
    +    {
    +        if (encoded != null)
    +        {
    +            out.writeEncoded(BERTags.SEQUENCE | BERTags.CONSTRUCTED, encoded);
    +        }
    +        else
    +        {
    +            super.toDLObject().encode(out);
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/LimitedInputStream.java+32 0 added
    @@ -0,0 +1,32 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.InputStream;
    +
    +abstract class LimitedInputStream
    +        extends InputStream
    +{
    +    protected final InputStream _in;
    +    private int _limit;
    +
    +    LimitedInputStream(
    +        InputStream in,
    +        int         limit)
    +    {
    +        this._in = in;
    +        this._limit = limit;
    +    }
    +
    +    int getRemaining()
    +    {
    +        // TODO: maybe one day this can become more accurate
    +        return _limit;
    +    }
    +    
    +    protected void setParentEofDetect(boolean on)
    +    {
    +        if (_in instanceof IndefiniteLengthInputStream)
    +        {
    +            ((IndefiniteLengthInputStream)_in).setEofOn00(on);
    +        }
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/microsoft/MicrosoftObjectIdentifiers.java+17 0 added
  • core/src/main/java/org/bouncycastle/asn1/misc/CAST5CBCParameters.java+78 0 added
  • core/src/main/java/org/bouncycastle/asn1/misc/IDEACBCPar.java+81 0 added
  • core/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java+47 0 added
  • core/src/main/java/org/bouncycastle/asn1/misc/NetscapeCertType.java+54 0 added
  • core/src/main/java/org/bouncycastle/asn1/misc/NetscapeRevocationURL.java+18 0 added
  • core/src/main/java/org/bouncycastle/asn1/misc/VerisignCzagExtension.java+18 0 added
  • core/src/main/java/org/bouncycastle/asn1/OIDTokenizer.java+48 0 added
    @@ -0,0 +1,48 @@
    +package org.bouncycastle.asn1;
    +
    +/**
    + * class for breaking up an OID into it's component tokens, ala
    + * java.util.StringTokenizer. We need this class as some of the
    + * lightweight Java environment don't support classes like
    + * StringTokenizer.
    + */
    +public class OIDTokenizer
    +{
    +    private String  oid;
    +    private int     index;
    +
    +    public OIDTokenizer(
    +        String oid)
    +    {
    +        this.oid = oid;
    +        this.index = 0;
    +    }
    +
    +    public boolean hasMoreTokens()
    +    {
    +        return (index != -1);
    +    }
    +
    +    public String nextToken()
    +    {
    +        if (index == -1)
    +        {
    +            return null;
    +        }
    +
    +        String  token;
    +        int     end = oid.indexOf('.', index);
    +
    +        if (end == -1)
    +        {
    +            token = oid.substring(index);
    +            index = -1;
    +            return token;
    +        }
    +
    +        token = oid.substring(index, end);
    +
    +        index = end + 1;
    +        return token;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/asn1/StreamUtil.java+114 0 added
    @@ -0,0 +1,114 @@
    +package org.bouncycastle.asn1;
    +
    +import java.io.ByteArrayInputStream;
    +import java.io.FileInputStream;
    +import java.io.IOException;
    +import java.io.InputStream;
    +import java.nio.channels.FileChannel;
    +
    +class StreamUtil
    +{
    +    private static final long  MAX_MEMORY = Runtime.getRuntime().maxMemory();
    +
    +    /**
    +     * Find out possible longest length...
    +     *
    +     * @param in input stream of interest
    +     * @return length calculation or MAX_VALUE.
    +     */
    +    static int findLimit(InputStream in)
    +    {
    +        if (in instanceof LimitedInputStream)
    +        {
    +            return ((LimitedInputStream)in).getRemaining();
    +        }
    +        else if (in instanceof ASN1InputStream)
    +        {
    +            return ((ASN1InputStream)in).getLimit();
    +        }
    +        else if (in instanceof ByteArrayInputStream)
    +        {
    +            return ((ByteArrayInputStream)in).available();
    +        }
    +        else if (in instanceof FileInputStream)
    +        {
    +            try
    +            {
    +                FileChannel channel = ((FileInputStream)in).getChannel();
    +                long  size = (channel != null) ? channel.size() : Integer.MAX_VALUE;
    +
    +                if (size < Integer.MAX_VALUE)
    +                {
    +                    return (int)size;
    +                }
    +            }
    +            catch (IOException e)
    +            {
    +                // ignore - they'll find out soon enough!
    +            }
    +        }
    +
    +        if (MAX_MEMORY > Integer.MAX_VALUE)
    +        {
    +            return Integer.MAX_VALUE;
    +        }
    +
    +        return (int)MAX_MEMORY;
    +    }
    +
    +    static int calculateBodyLength(
    +        int length)
    +    {
    +        int count = 1;
    +
    +        if (length > 127)
    +        {
    +            int size = 1;
    +            int val = length;
    +
    +            while ((val >>>= 8) != 0)
    +            {
    +                size++;
    +            }
    +
    +            for (int i = (size - 1) * 8; i >= 0; i -= 8)
    +            {
    +                count++;
    +            }
    +        }
    +
    +        return count;
    +    }
    +
    +    static int calculateTagLength(int tagNo)
    +        throws IOException
    +    {
    +        int length = 1;
    +
    +        if (tagNo >= 31)
    +        {
    +            if (tagNo < 128)
    +            {
    +                length++;
    +            }
    +            else
    +            {
    +                byte[] stack = new byte[5];
    +                int pos = stack.length;
    +
    +                stack[--pos] = (byte)(tagNo & 0x7F);
    +
    +                do
    +                {
    +                    tagNo >>= 7;
    +                    stack[--pos] = (byte)(tagNo & 0x7F | 0x80);
    +                }
    +                while (tagNo > 127);
    +
    +                length += stack.length - pos;
    +            }
    +        }
    +
    +        return length;
    +    }
    +}
    
  • core/src/main/java/org/bouncycastle/LICENSE.java+63 0 added
    @@ -0,0 +1,63 @@
    +package org.bouncycastle;
    +
    +/**
    + * The Bouncy Castle License
    + *
    + * Copyright (c) 2000-2012 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
    + * <p>
    + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
    + * and associated documentation files (the "Software"), to deal in the Software without restriction, 
    + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
    + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
    + * subject to the following conditions:
    + * <p>
    + * The above copyright notice and this permission notice shall be included in all copies or substantial
    + * portions of the Software.
    + * <p>
    + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
    + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
    + * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
    + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    + * DEALINGS IN THE SOFTWARE.
    + */
    +public class LICENSE
    +{
    +    public static String licenseText =
    +      "Copyright (c) 2000-2012 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) "
    +      + System.getProperty("line.separator")
    +      + System.getProperty("line.separator")
    +      + "Permission is hereby granted, free of charge, to any person obtaining a copy of this software "
    +      + System.getProperty("line.separator")
    +      + "and associated documentation files (the \"Software\"), to deal in the Software without restriction, "
    +      + System.getProperty("line.separator")
    +      + "including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, "
    +      + System.getProperty("line.separator")
    +      + "and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,"
    +      + System.getProperty("line.separator")
    +      + "subject to the following conditions:"
    +      + System.getProperty("line.separator")
    +      + System.getProperty("line.separator")
    +      + "The above copyright notice and this permission notice shall be included in all copies or substantial"
    +      + System.getProperty("line.separator")
    +      + "portions of the Software."
    +      + System.getProperty("line.separator")
    +      + System.getProperty("line.separator")
    +      + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,"
    +      + System.getProperty("line.separator")
    +      + "INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR"
    +      + System.getProperty("line.separator")
    +      + "PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE"
    +      + System.getProperty("line.separator")
    +      + "LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR"
    +      + System.getProperty("line.separator")
    +      + "OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER"
    +      + System.getProperty("line.separator")
    +      + "DEALINGS IN THE SOFTWARE.";
    +
    +    public static void main(
    +        String[]    args)
    +    {
    +        System.out.println(licenseText);
    +    }
    +}
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

10

News mentions

0

No linked articles in our index yet.