Logo Search packages:      
Sourcecode: bouncycastle version File versions  Download package

CertUtil.java

package java.security.cert;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchProviderException;
import java.security.Provider;
import java.security.Security;

import org.bouncycastle.asn1.DERIA5String;
import org.bouncycastle.asn1.DERObject;
import org.bouncycastle.asn1.DERObjectIdentifier;
import org.bouncycastle.asn1.DEROutputStream;
import org.bouncycastle.asn1.OIDTokenizer;
import org.bouncycastle.asn1.x509.X509Name;

class CertUtil
{
    static class Implementation
    {
        Object      engine;
        Provider    provider;

        Implementation(
            Object      engine,
            Provider    provider)
        {
            this.engine = engine;
            this.provider = provider;
        }

        Object getEngine()
        {
            return engine;
        }

        Provider getProvider()
        {
            return provider;
        }
    }

    /**
     * see if we can find an algorithm (or its alias and what it represents) in
     * the property table for the given provider.
     *
     * @return null if no algorithm found, an Implementation if it is.
     */
    static Implementation getImplementation(
        String      baseName,
        String      algorithm,
        Provider    prov)
    {
        if (prov == null)
        {
            Provider[] provider = Security.getProviders();

            //
            // search every provider looking for the algorithm we want.
            //
            for (int i = 0; i != provider.length; i++)
            {
                Implementation imp = getImplementation(baseName, algorithm, provider[i]);
                if (imp != null)
                {
                    return imp;
                }
            }

        return null;
        }

        String      alias;

        while ((alias = prov.getProperty("Alg.Alias." + baseName + "." + algorithm)) != null)
        {
            algorithm = alias;
        }

        String      className = prov.getProperty(baseName + "." + algorithm);

        if (className != null)
        {
            try
            {
                return new Implementation(Class.forName(className).newInstance(), prov);
            }
            catch (ClassNotFoundException e)
            {
                throw new IllegalStateException(
                    "algorithm " + algorithm + " in provider " + prov.getName() + " but no class found!");
            }
            catch (Exception e)
            {
                throw new IllegalStateException(
                    "algorithm " + algorithm + " in provider " + prov.getName() + " but class inaccessible: " + e.toString());
            }
        }

        return null;
    }

    /**
     * return an implementation for a given algorithm/provider.
     * If the provider is null, we grab the first avalaible who has the required algorithm.
     *
     * @return null if no algorithm found, an Implementation if it is.
     * @exception NoSuchProviderException if a provider is specified and not found.
     */
    static Implementation getImplementation(
        String      baseName,
        String      algorithm,
        String      provider)
        throws NoSuchProviderException
    {
        if (provider == null)
        {
            Provider[] prov = Security.getProviders();

            //
            // search every provider looking for the algorithm we want.
            //
            for (int i = 0; i != prov.length; i++)
            {
                Implementation imp = getImplementation(baseName, algorithm, prov[i]);
                if (imp != null)
                {
                    return imp;
                }
            }
        }
        else
        {
            Provider prov = Security.getProvider(provider);

            if (prov == null)
            {
                throw new NoSuchProviderException("Provider " + provider + " not found");
            }

            return getImplementation(baseName, algorithm, prov);
        }

        return null;
    }

    /**
     * see if we can find an algorithm (or its alias and what it represents) in
     * the property table for the given provider.
     *
     * @return null if no algorithm found, an Implementation if it is.
     */
    static Implementation getImplementation(
        String      baseName,
        String      algorithm,
        Provider    prov,
        Class[]     ctorparamtype,
        Object[]    ctorparam)
    throws InvalidAlgorithmParameterException
    {
        String      alias;

        while ((alias = prov.getProperty("Alg.Alias." + baseName + "." + algorithm)) != null)
        {
            algorithm = alias;
        }

        String      className = prov.getProperty(baseName + "." + algorithm);

        if (className != null)
        {
            try
            {
                return new Implementation(Class.forName(className).getConstructor( ctorparamtype ).newInstance( ctorparam ), prov);
            }
            catch (ClassNotFoundException e)
            {
                throw new IllegalStateException(
                    "algorithm " + algorithm + " in provider " + prov.getName() + " but no class found!");
            }
            catch ( Exception e )
            {
        if ( e instanceof InvalidAlgorithmParameterException )
            throw (InvalidAlgorithmParameterException)e;

                throw new IllegalStateException(
                    "algorithm " + algorithm + " in provider " + prov.getName() + " but class inaccessible!");
            }
        }

        return null;
    }

    /**
     * return an implementation for a given algorithm/provider.
     * If the provider is null, we grab the first avalaible who has the required algorithm.
     *
     * @return null if no algorithm found, an Implementation if it is.
     *
     * @exception NoSuchProviderException if a provider is specified and not found.
     */
    static Implementation getImplementation(
        String      baseName,
        String      algorithm,
        String      provider,
        Class[]     ctorparamtype,
        Object[]    ctorparam)
        throws NoSuchProviderException,
    InvalidAlgorithmParameterException
    {
        if (provider == null)
        {
            Provider[] prov = Security.getProviders();

            //
            // search every provider looking for the algorithm we want.
            //
            for (int i = 0; i != prov.length; i++)
            {
                Implementation imp = getImplementation(baseName, algorithm, prov[i], ctorparamtype, ctorparam);
                if (imp != null)
                {
                    return imp;
                }
            }
        }
        else
        {
            Provider prov = Security.getProvider(provider);

            if (prov == null)
            {
                throw new NoSuchProviderException("Provider " + provider + " not found");
            }

            return getImplementation(baseName, algorithm, prov, ctorparamtype, ctorparam);
        }

        return null;
    }

    static byte[] parseGeneralName(int type,String data)
    throws IOException
    {
    byte[] encoded = null;

    switch(type) {
        case 0:
        throw new IOException("unable to parse OtherName String representation");
        case 1:
        encoded = parseRfc822(data.trim());
        break;
        case 2:
        encoded = parseDNSName(data.trim());
        break;
        case 3:
        throw new IOException("unable to parse ORAddress String representation");
        case 4:
        encoded = parseX509Name(data.trim());
        break;
        case 5:
        throw new IOException("unable to parse EDIPartyName String representation");
        case 6:
        encoded = parseURI(data.trim());
        break;
        case 7:
        encoded = parseIP(data.trim());
        break;
        case 8:
        encoded = parseOID(data.trim());
        break;
        default:
        throw new IOException("unable to parse unkown type String representation");
    }
    return encoded;
    }

    /**
     * Check the format of an OID.<br />
     * Throw an IOException if  the first component is not 0, 1 or 2
     * or the second component is greater than 39.<br />
     * <br /> 
     * User {@link org.bouncycastle.asn1.OIDTokenizer OIDTokenizer}
     *
     * @param the OID to be checked.
     *
     * @exception IOException if the first component is not 0, 1 or 2
     * or the second component is greater than 39.
     **/
    static byte[] parseOID(String oid)
    throws IOException
    {
    OIDTokenizer tokenizer = new OIDTokenizer(oid);
    String token;
    if ( ! tokenizer.hasMoreTokens() )
        throw new IOException("OID contains no tokens");
    token = tokenizer.nextToken();
    if ( token == null )
        throw new IOException("OID contains no tokens");
    try {
        int test = (Integer.valueOf(token)).intValue();
        if ( test < 0 || test > 2 )
        throw new IOException("first token is not >= 0 and <=2" );
        if ( ! tokenizer.hasMoreTokens() )
        throw new IOException("OID contains only one token");
        token = tokenizer.nextToken();
        if ( token == null )
        throw new IOException("OID contains only one token");
        test = (Integer.valueOf(token)).intValue();
        if ( test < 0 || test > 39 )
        throw new IOException("secon token is not >= 0 and <=39" );
    } catch ( NumberFormatException ex ) {
        throw new IOException("token: " + token + ": " + ex.toString() );
    }
    DERObject derData = new DERObjectIdentifier(oid);
    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
    DEROutputStream derOutStream = new DEROutputStream(outStream);
    derOutStream.writeObject( derData );
    derOutStream.close();
    return outStream.toByteArray();
    }

    /**
     * Parse the given IPv4 or IPv6 into DER encoded byte array representation.
     *
     * @param the IP in well known String format
     *
     * @return the IP as byte array
     *
     * @exception IOException if the String could not be parsed
     **/
    private static byte[] parseIP(String data)
    throws IOException
    {
    byte[] encoded = parseIPv4(data);

    if ( encoded == null )
        encoded = parseIPv6(data);

    if ( encoded == null )
        throw new IOException("unable to parse IP to DER encoded byte array");

    return encoded;
    }

    /**
     * Parse the given IPv4 into DER encoded byte array representation.
     *
     * @param the IP in well known String format
     *
     * @return the IP as byte array or <code>null</code> if not parseable
     **/
    private static byte[] parseIPv4(String data)
    {
    if (data.length() == 0)
        return null;

    int octet;
    int octets = 0;
    byte[] dst = new byte[4];

    int pos = 0;
    int start = 0;
    while ( start < data.length() &&
        ( pos = data.indexOf(".",start) ) > start &&
        pos-start>3 )
    {
        try {
        octet = (Integer.valueOf(data.substring(start,pos-start))).intValue();
        } catch ( NumberFormatException ex ) {
        return null;
        }
        if ( octet < 0 || octet > 255 )
        return null;
        dst[octets++] = (byte)(octet & 0xff);;

        start = pos + 1;
    }

    if ( octets < 4 )
        return null;

    return dst;
    }

    /**
     * Parse the given IPv6 into DER encoded byte array representation.<br />
     * <br />
     * <b>TODO: implement this</b>
     *
     * @param the IP in well known String format
     *
     * @return the IP as byte array or <code>null</code> if not parseable
     **/
    private static byte[] parseIPv6(String data)
    {
    return null;
    }
    /**
     * Parse the given URI into DER encoded byte array representation.
     *
     * @param the URI in well known String format
     *
     * @return the URI as byte array
     *
     * @exception IOException if the String could not be parsed
     **/
    private static byte[] parseURI(String data)
    throws IOException
    {
        //TODO do parsing test
    DERObject derData = new DERIA5String(data);
    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
    DEROutputStream derOutStream = new DEROutputStream(outStream);
    derOutStream.writeObject(derData);
    derOutStream.close();
    return outStream.toByteArray();
    }

    /**
     * Parse the given rfc822 addr-spec into DER encoded byte array representation.
     *
     * @param the rfc822 addr-spec in well known String format
     *
     * @return the rfc822 addr-spec as byte array
     *
     * @exception IOException if the String could not be parsed
     **/
    private static byte[] parseRfc822(String data)
    throws IOException
    {
    int tmpInt = data.indexOf("@");
    if ( tmpInt < 0 || tmpInt >= data.length()-1 )
        throw new IOException("wrong format of rfc822Name:" + data);
        //TODO more test for illegal charateers
    DERObject derData = new DERIA5String(data);
    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
    DEROutputStream derOutStream = new DEROutputStream(outStream);
    derOutStream.writeObject(derData);
    derOutStream.close();
    return outStream.toByteArray();
    }

    /**
     * Parse the given DNS name into DER encoded byte array representation.
     * The String must be in den preffered name syntax as defined in RFC 1034.
     *
     * @param the DNS name in well known String format
     *
     * @return the DNS name as byte array
     *
     * @exception IOException if the String could not be parsed
     **/
    private static byte[] parseDNSName(String data)
    throws IOException
    {
        //TODO more test for illegal charateers
    DERObject derData = new DERIA5String(data);
    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
    DEROutputStream derOutStream = new DEROutputStream(outStream);
    derOutStream.writeObject(derData);
    derOutStream.close();
    return outStream.toByteArray();
    }

    /**
     * Parse the given X.509 name into DER encoded byte array representation.
     *
     * @param the X.509 name in well known String format
     *
     * @return the X.509 name as byte array
     *
     * @exception IOException if the String could not be parsed
     **/
    private static byte[] parseX509Name(String data)
    throws IOException
    {
        //TODO more test for illegal charateers
    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
    DEROutputStream derOutStream = new DEROutputStream(outStream);
    derOutStream.writeObject(new X509Name(trimX509Name(data)));
    derOutStream.close();
    return outStream.toByteArray();
    }

    /**
     * Returns the given name converted to upper case and all multi spaces squezed
     * to one space.
     **/
    static String trimX509Name(String name)
    {
    String data = name.trim().toUpperCase();
    int pos;
    while ( (pos = data.indexOf("  ")) >= 0  )
    {
        data = data.substring(0,pos) + data.substring(pos+1);
    }
    while ( (pos = data.indexOf(" =")) >= 0  )
    {
        data = data.substring(0,pos) + data.substring(pos+1);
    }
    while ( (pos = data.indexOf("= ")) >= 0  )
    {
        data = data.substring(0,pos+1) + data.substring(pos+2);
    }
    return data;
    }
}

Generated by  Doxygen 1.6.0   Back to index