[llvm-commits] [llvm-gcc-4.2] r43913 [27/80] - in /llvm-gcc-4.2/trunk: boehm-gc/ boehm-gc/Mac_files/ boehm-gc/cord/ boehm-gc/doc/ boehm-gc/include/ boehm-gc/include/private/ boehm-gc/tests/ libffi/ libffi/include/ libffi/src/ libffi/src/alpha/ libffi/src/arm/ libffi/src/cris/ libffi/src/frv/ libffi/src/ia64/ libffi/src/m32r/ libffi/src/m68k/ libffi/src/mips/ libffi/src/pa/ libffi/src/powerpc/ libffi/src/s390/ libffi/src/sh/ libffi/src/sh64/ libffi/src/sparc/ libffi/src/x86/ libffi/testsuite/ libffi/testsuite/config/ li...

Bill Wendling isanbard at gmail.com
Thu Nov 8 14:57:11 PST 2007


Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/gif/GIFFile.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/gif/GIFFile.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/gif/GIFFile.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/gif/GIFFile.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,709 @@
+/* GIFFile.java -- GIF decoder
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.gif;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Vector;
+
+/**
+ * GIFFile - reads a GIF file.
+ * 
+ * This class only does the bare minimum work, and returns the data in raw
+ * formats (described below). The class is J2ME compatible, and hopefully
+ * we can keep it that way without any significant overhead.
+ *
+ * @author Sven de Marothy. 
+ */
+public class GIFFile 
+{
+  // "NETSCAPE2.0" - identifier
+  private final static byte[] nsBlock = new byte[]
+  {0x4e, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e, 0x30 };
+
+  /**
+   * Block identifiers
+   */
+  private final static int EXTENSION = 0x21;
+  private final static int LOCAL = 0x2C;
+  private final static int TERMINATOR = 0x3B;
+
+  /**
+   * Extension block types
+   */
+  private final static int EXTENSION_COMMENT = 254;
+  private final static int EXTENSION_GCONTROL = 249; 
+  private final static int EXTENSION_APPLICATION = 255;
+
+  /**
+   * Undraw commands for animation.
+   */
+  private final static int UNDRAW_OVERWRITE = 1;
+  private final static int UNDRAW_RESTORE_BACKGROUND = 2;
+  private final static int UNDRAW_RESTORE_PREVIOUS = 3; 
+
+  /**
+   * Image position and dimensions (images may be partial)
+   */
+  private int x, y, width, height;
+
+  /**
+   * Global dimensions
+   */
+  private int globalWidth, globalHeight;
+
+  /**
+   * Background color index.
+   */
+  private byte bgIndex;
+
+  /**
+   * Number of colors
+   */
+  private int nColors;
+
+  /**
+   * Global palette, if any
+   */
+  private byte[] globalPalette;
+
+  /**
+   * Any
+   */
+  private boolean hasGlobalColorMap;
+
+  /**
+   * Local palette, if any (used if available)
+   */
+  private byte[] localPalette;
+
+  /**
+   * Interlaced GIF or not?
+   */
+  private boolean interlaced;
+
+  /**
+   * Has transparency?
+   */
+  private boolean hasTransparency;
+  
+  /**
+   * Undraw mode (animations)
+   */
+  private int undraw;
+
+  /**
+   * Transparent index;
+   */
+  private int transparentIndex;
+
+  /**
+   * The uncompressed raster
+   */
+  private byte[] raster;
+
+  /**
+   * The compressed data (freed after uncompressing)
+   */
+  private byte[] compressedData;
+
+  /**
+   * Frame delay in 100ths of a second ( centiseconds, metrically )
+   */
+  private int duration;
+
+  /**
+   * Indices used during decompression
+   */
+  private int dataBlockIndex;
+
+  /**
+   * The file comment , if a comment block exists.
+   */
+  private String comment;
+
+  /**
+   * Fields used by getBits()
+   */
+  private int remainingBits = 0;
+  private int currentBits = 0;
+
+  /**
+   * Netscape animation extension
+   */
+  private boolean isLooped = false;
+
+  /** Number of loops, 0 = infinite */
+  private int loops;
+
+  /**
+   * Additional frames if it's an animated GIF.
+   */
+  private Vector animationFrames;
+
+  /**
+   * Loads the file from an input stream, which is not closed.
+   * @throws IOException if an I/O error occured.
+   * @throws GIFException if some file parsing error occured
+   */
+  public GIFFile(InputStream in) throws IOException, GIFException 
+  {
+    // Validate the signature
+    if( !readSignature( in ) )
+      throw new GIFException("Invalid GIF signature.");
+
+    {
+      byte[] data = new byte[7];
+      if (in.read(data) != 7)
+	throw new IOException("Couldn't read global descriptor.");
+
+      globalWidth = ((data[1] & 0xFF) << 8) | (data[0] & 0xFF);
+      globalHeight = ((data[3] & 0xFF) << 8) | (data[2] & 0xFF);
+      byte flags = data[4];
+      bgIndex = data[5];
+      nColors = (1 << (( flags & 0x07) + 1));
+      hasGlobalColorMap = ((flags & 0x80) != 0);
+    }
+
+    if( hasGlobalColorMap )
+      {
+	globalPalette = new byte[ nColors * 3 ];
+	if( in.read( globalPalette ) != nColors * 3 )
+	  throw new IOException("Couldn't read color map.");
+      }
+    
+    int c = in.read();
+    while( c == EXTENSION )
+      {
+	readExtension( in );
+	c = in.read();
+      }
+      
+    if( c != LOCAL )
+      throw new GIFException("Extension blocks not followed by a local descriptor ("+c+")");
+
+    loadImage( in );
+    c = in.read(); 
+
+    if( c == TERMINATOR ) // Not an animated GIF.
+      return;
+
+    // Load animation frames. Just quit if an error occurs instead 
+    // of throwing an exception.
+    animationFrames = new Vector();
+    try 
+      {
+	while( c != TERMINATOR )
+	  {
+	    animationFrames.add( new GIFFile( this, in, c ) );
+	    c = in.read(); 
+	  }
+      }
+    catch(IOException ioe)
+      {
+      }
+    catch(GIFException gife)
+      {
+      }
+  }
+
+  /**
+   * Constructor for additional animation frames.
+   */
+  private GIFFile(GIFFile parent, InputStream in, int c) 
+    throws IOException, GIFException 
+  {
+    // Copy global properties.
+    globalWidth = parent.globalWidth;
+    globalHeight = parent.globalHeight;
+    nColors = parent.nColors;
+    globalPalette = parent.globalPalette;
+    hasGlobalColorMap = parent.hasGlobalColorMap;
+    interlaced = parent.interlaced;
+    comment = parent.comment;
+    isLooped = parent.isLooped;
+    loops = parent.loops;
+
+    while( c == EXTENSION )
+    {
+      readExtension( in );      
+      c = in.read();
+    }
+      
+    if( c != LOCAL )
+      throw new GIFException("Extension blocks not followed by a local descriptor ("+c+")");
+
+    loadImage( in );
+  }
+
+  /**
+   * Reads a GIF file signature from an inputstream and checks it.
+   *
+   * @param in - the stream (reads 6 bytes, does not close or reset).
+   * @return true if the signature is a valid GIF signature.
+   * @throws an IOException if the signature could not be read.
+   */
+  public static boolean readSignature( InputStream in ) throws IOException
+  { 
+    byte[] data = new byte[6];
+    if (in.read(data) != 6)
+      throw new IOException("Couldn't read signature.");
+
+    if( data[0] != 0x47 || data[1] != 0x49 || data[2] != 0x46 ||
+	data[3] != 0x38 ) // GIF8
+      return false;
+
+    if( (data[4] != 0x39 && data[4] != 0x37) || // 7 | 9
+	(data[5] != 0x61 && data[5] != 0x62) ) // 'a' or 'b'
+      return false;
+    return true;
+  }
+  
+
+  /**
+   * Loads the image local descriptor and then loads/decodes the image raster,
+   * and then performs any necessary postprocessing like deinterlacing.
+   */
+  private void loadImage(InputStream in)
+    throws IOException, GIFException
+  {
+    readLocal( in );
+
+    try
+      {
+	decodeRaster( in );
+      }
+    catch(ArrayIndexOutOfBoundsException aioobe)
+      {
+	throw new GIFException("Error decompressing image.");
+      }
+    
+    if( interlaced )  // Clean up
+      deinterlace();
+    packPixels();
+  }
+
+  /**
+   * Pack the pixels if it's a 2, 4 or 16 color image.
+   * While GIF may support any number of colors from 2-256, we won't bother
+   * trying to pack pixels not resulting in even byte boundaries.
+   * (AWT doesn't support that anyway, and most apps do the same.)
+   */
+  private void packPixels()
+  {
+    if( nColors != 2 && nColors != 4 && nColors != 16 )
+      return;
+
+    int nbits = 1;
+    int ppbyte = 8; 
+    if( nColors == 4 )
+      {
+	nbits = 2;
+	ppbyte = 4;
+      }
+    else if( nColors == 16 )
+      {
+	nbits = 4;
+	ppbyte = 2;
+      }
+
+    int rem = (width & (ppbyte - 1));
+    int w = ( rem == 0 ) ? (width / ppbyte) : 
+      ((width + ppbyte - rem) / ppbyte); 
+    byte[] nr = new byte[ w * height ];
+    for(int j = 0; j < height; j++)
+      {
+	for(int i = 0; i < width - ppbyte; i += ppbyte)
+	  for(int k = 0; k < ppbyte; k++)
+	    nr[ j * w + (i / ppbyte) ] |= (byte)((raster[ width * j + i + k ]
+						  << (8 - nbits * (1 + k))));
+ 	for(int i = 0; i < rem; i++)
+ 	  nr[ j * w + w - 1 ] |= (byte)((raster[ width * j + width - rem + i ]
+					 << (nbits * (rem - i))));
+      }
+    raster = nr;
+  }
+
+  /**
+   * Returns the (global) width
+   */
+  public int getWidth()
+  {
+    return width;
+  }
+
+  /**
+   * Returns the image height
+   */
+  public int getHeight()
+  {
+    return height;
+  }
+
+  /**
+   * Returns the # of colors.
+   */
+  public int getNColors()
+  {
+    return nColors;
+  }
+
+  /**
+   * Returns whether the GIF has transparency.
+   */
+  public boolean hasTransparency()
+  {
+    return hasTransparency;
+  }
+
+  /**
+   * Returns the index of the transparent color.
+   */
+  public int getTransparentIndex()
+  {
+    return transparentIndex;
+  }
+
+  /**
+   * Retuns the GIF file comment, or null if none exists.
+   */
+  public String getComment()
+  {
+    return comment;
+  }
+
+  /**
+   * Get duration of the frame for animations.
+   */
+  public int getDuration()
+  {
+    return duration;
+  }
+
+  /**
+   * Deinterlaces the image.
+   */
+  private void deinterlace()
+  {
+    byte[] nr = new byte[ width * height ];
+    int n = 0;
+    for(int i = 0; i < ((height + 7) >> 3); i++)
+      {
+	System.arraycopy( raster, n, nr, width * i * 8, width );
+	n += width;
+      }
+    for(int i = 0; i < ((height + 3) >> 3); i++)
+      {
+	System.arraycopy( raster, n, nr, width * ( 8 * i + 4 ), width );
+	n += width;
+      }
+    for(int i = 0; i < (height >> 2); i++)
+      {
+	System.arraycopy( raster, n, nr, width * (4 * i + 2), width );
+	n += width;
+      }
+    for(int i = 0; i < (height >> 1); i++)
+      {
+	System.arraycopy( raster, n, nr, width * (2 * i + 1), width );
+	n += width;
+      }
+    raster = nr;
+  }
+
+  /**
+   * Reads the local descriptor
+   */
+  private void readLocal(InputStream in) throws IOException
+  {
+    byte[] data = new byte[9];
+    if (in.read(data) != 9)
+      throw new IOException("Couldn't read local descriptor.");
+    x = ((data[1] & 0xFF) << 8) | (data[0] & 0xFF);
+    y = ((data[3] & 0xFF) << 8) | (data[2] & 0xFF);
+    width = ((data[5] & 0xFF) << 8) | (data[4] & 0xFF);
+    height = ((data[7] & 0xFF) << 8) | (data[6] & 0xFF);
+    byte flags = data[8];
+    interlaced = (( flags & 0x40 ) != 0);
+    if( (flags & 0x80) != 0 )
+      { // has a local color map
+	int nLocalColors = (1 << (( flags & 0x07) + 1));
+	if( !hasGlobalColorMap )
+	  nColors = nLocalColors;
+	localPalette = new byte[ nLocalColors * 3 ];
+	if( in.read( localPalette ) != nLocalColors * 3 )
+	  throw new IOException("Couldn't read color map.");
+      }
+  }   
+
+  /**
+   * Returns the image's palette in raw format 
+   * (r0,g0,b0,r1,g1,b2..r(Ncolors-1),g(Ncolors-1),b(Ncolors-1))
+   */
+  public byte[] getRawPalette()
+  {
+    return hasGlobalColorMap ? globalPalette : localPalette;
+  }
+
+  /**
+   * Returns the image file for animated gifs.
+   */
+  public GIFFile getImage( int index )
+  {
+    if( index == 0 )
+      return this;
+    if( animationFrames == null )
+      throw new ArrayIndexOutOfBoundsException("Only one image in file");
+    return (GIFFile)animationFrames.elementAt( index - 1 );
+  }
+
+  /**
+   * Return the image's raw image data.
+   * If the color depth is 1,2 or 4 bits per pixel the pixels are packed
+   * and the scanlines padded up to the nearest byte if needed.
+   */
+  public byte[] getRawImage()
+  {
+    return raster;
+  }
+
+  /**
+   * Return the number of images in the GIF file
+   */
+  public int nImages()
+  {
+    if( animationFrames != null )
+      return 1 + animationFrames.size();
+    return 1;
+  }
+
+  /**
+   * Handles extension blocks.
+   */
+  private void readExtension(InputStream in) throws IOException, GIFException 
+  {
+    int functionCode = in.read();
+    byte[] data = readData(in);
+    switch( functionCode )
+      {
+      case EXTENSION_COMMENT: // comment block
+	comment = new String(data, "8859_1");
+	break;
+
+      case EXTENSION_GCONTROL: // Graphics control extension
+	undraw = (data[0] & 0x1C) >> 2;
+	// allegedly there can be bad values of this.
+	if( undraw < 1 && undraw > 3 ) undraw = 1; 
+	hasTransparency = ((data[0] & 0x01) == 1);
+	transparentIndex = (data[3] & 0xFF);
+	duration = ((data[2] & 0xFF) << 8) | (data[1] & 0xFF);
+	break;
+
+	// Application extension. We only parse the Netscape animation
+	// extension here. Which is the only one most use anyway.
+      case EXTENSION_APPLICATION:
+	boolean isNS = true;
+	for(int i = 0; i < nsBlock.length; i++ )
+	  if( nsBlock[i] != data[i] )
+	    isNS = false;
+	if( isNS )
+	  {
+	    isLooped = true;
+	    loops = ((data[12] & 0xFF) << 8) | (data[13] & 0xFF);
+	  }
+	break;
+
+      default:
+	break;
+      }
+  }
+
+  /**
+   * Reads a series of data blocks and merges them into a single one.
+   */
+  private byte[] readData(InputStream in) throws IOException
+  {
+    Vector v = new Vector();
+    int totalBytes = 0;
+
+    int n = in.read();
+    do
+      {
+	totalBytes += n;
+	byte[] block = new byte[ n ];
+	in.read(block);
+	v.add(block);
+	n = in.read();
+      }
+    while( n > 0 );
+
+    n = 0;
+    byte[] bigBuffer = new byte[ totalBytes ];
+    for( int i = 0; i < v.size(); i++ )
+      {
+	byte[] block = (byte[])v.elementAt(i);
+	System.arraycopy(block, 0, bigBuffer, n, block.length);
+	n += block.length;
+      }
+    return bigBuffer;
+  }
+
+  /**
+   * Loads a compressed image block and decompresses it.
+   */
+  private void decodeRaster(InputStream in) throws IOException
+  {
+    int initialCodeSize = in.read();
+    compressedData = readData( in );
+    dataBlockIndex = 0;
+
+    int rasterIndex = 0; // Index into the raster
+    int clearCode = (1 << initialCodeSize); // 256 usually
+    int endCode = clearCode + 1; // The stop code.
+
+    raster = new byte[ width * height ];
+
+    int codeSize = initialCodeSize + 1;
+    int code = getBits( codeSize ); // = clear
+    int nextCode = endCode + 1;
+
+    /*
+     * Initialize LZW dictionary
+     *
+     * First index - code #
+     * Second index:
+     * 0 = color index
+     * 1 = parent (-1 - no parent)
+     * 2 = first value
+     * 3 - depth
+     * The latter two aren't strictly necessary but make things faster, since
+     * copying the values forward is faster than going back and looking.
+     */
+    short[][] dictionary = new short[ 4096 ][ 4 ];
+
+    for(short i = 0; i < nColors; i ++ )
+      {
+	dictionary[i][0] = i;  // color index	
+	dictionary[i][1] = -1; // parent
+	dictionary[i][2] = i;  // first	
+	dictionary[i][3] = 1;  // depth
+      }
+
+    code = getBits( codeSize ); // get second code
+    raster[ rasterIndex++ ] = (byte)dictionary[code][0];
+    int old = code;    
+    code = getBits( codeSize ); // start at the third code
+    int c;
+
+    do
+      {
+	if( code == clearCode )
+	  {
+	    codeSize = initialCodeSize + 1;
+ 	    nextCode = endCode + 1; 
+	    // get and output second code
+	    code = getBits( codeSize ); 
+	    raster[ rasterIndex++ ] = (byte)dictionary[code][0];
+	    old = code;
+	  }
+	else
+	  {
+	    dictionary[nextCode][1] = (short)old; // parent = old
+	    dictionary[nextCode][2] = dictionary[old][2]; // first pixel
+	    dictionary[nextCode][3] = (short)(dictionary[old][3] + 1); // depth
+	
+	    // appended pixel  = first pixel of c
+	    if( code < nextCode )
+	      {
+		dictionary[nextCode][0] = dictionary[code][2]; 
+		old = code;
+	      }
+	    else // first of old
+	      {
+		dictionary[nextCode][0] = dictionary[old][2]; 
+		old = nextCode;
+	      }
+
+	    c = old;
+	    // output the code c
+	    int depth = dictionary[c][3];
+	    for( int i = depth - 1; i >= 0; i-- )
+	      {
+		raster[ rasterIndex + i ] = (byte)dictionary[c][0];
+		c = dictionary[c][1]; // go to parent.
+	      }
+	    rasterIndex += depth;
+	    nextCode ++;
+
+	    if( codeSize < 12 && nextCode >= (1 << codeSize) )
+	      codeSize++;
+	  }
+	code = getBits( codeSize );
+      }
+    while( code != endCode && dataBlockIndex < compressedData.length );
+    
+    compressedData = null; // throw away compressed data.
+  }
+
+  /**
+   * Returns nbits number of bits (in the LSBs) from compressedData
+   */
+  private int getBits( int nbits )
+  {
+    while( nbits > remainingBits )
+      {
+	int c = (compressedData[ dataBlockIndex++ ] & 0xFF) << remainingBits;
+	currentBits |= c;
+	remainingBits += 8;
+      }
+    int rval = (currentBits & ((1 << nbits) - 1));
+    currentBits = (currentBits >> nbits);
+    remainingBits -= nbits;
+    return rval;
+  }
+
+  /**
+   * Generic exception used by GIFFile to report decoding errors.
+   */
+  public static class GIFException extends Exception 
+  {
+    public GIFException(String message)
+    {
+      super(message);
+    }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/gif/GIFImageReader.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/gif/GIFImageReader.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/gif/GIFImageReader.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/gif/GIFImageReader.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,241 @@
+/* GIFImageReader.java --
+   Copyright (C)  2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.gif;
+
+import gnu.javax.imageio.IIOInputStream;
+
+import java.io.IOException;
+import java.io.InputStream;
+import javax.imageio.*;
+import javax.imageio.spi.*;
+import javax.imageio.metadata.*;
+import javax.imageio.stream.ImageInputStream;
+import java.util.Iterator;
+import java.awt.image.BufferedImage;
+import java.awt.image.IndexColorModel;
+import java.awt.image.SampleModel;
+import java.awt.image.MultiPixelPackedSampleModel;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+public class GIFImageReader extends ImageReader 
+{
+  private GIFFile file;
+
+  protected GIFImageReader(ImageReaderSpi originatingProvider)
+  {
+    super( originatingProvider );
+    file = null;
+  }
+  
+  private void readImage() throws IOException
+  {
+    if( file != null )
+      return;
+
+    try
+      {
+	if( input instanceof InputStream )
+	  file = new GIFFile( (InputStream)input );
+	else
+	  file = new GIFFile( new IIOInputStream((ImageInputStream)input) );
+      }
+    catch(GIFFile.GIFException ge)
+      {
+	throw new IIOException(ge.getMessage());
+      }
+  }
+
+  /**
+   * Returns the Global/Local palette as an IndexColorModel
+   */
+  private IndexColorModel getPalette(int index)
+  {
+    GIFFile f = file.getImage( index );
+    byte[] data = f.getRawPalette();
+    int nc = f.getNColors();
+    byte[] r = new byte[nc];
+    byte[] g = new byte[nc];
+    byte[] b = new byte[nc];
+
+    for(int i = 0; i < nc; i ++ )
+      {
+	r[i] = data[ i * 3 ];
+	g[i] = data[ i * 3 + 1 ];
+	b[i] = data[ i * 3 + 2 ];
+      }
+
+    if( f.hasTransparency() )
+      {
+	byte[] a = new byte[nc];
+	for(int i = 0; i < nc; i ++ )
+	  a[i] = (byte)0xFF;
+	a[f.getTransparentIndex()] = 0;
+	return new IndexColorModel(8, nc, r, g, b, a);
+      }
+    
+    return new IndexColorModel(8, nc, r, g, b);
+  }
+
+  private void validateIndex(int imageIndex) 
+    throws IndexOutOfBoundsException 
+  {
+    if( imageIndex < 0 || imageIndex >= getNumImages(false) )
+      throw new IndexOutOfBoundsException("Invalid image index.");
+  }
+
+  public void setInput(Object input) 
+  {
+    super.setInput(input);
+  }
+
+  public void setInput(Object input, 
+		       boolean seekForwardOnly, 
+		       boolean ignoreMetadata) 
+  {
+    super.setInput(input, seekForwardOnly, ignoreMetadata);
+  }
+	
+  public void setInput(Object input, boolean isStreamable) 
+  {
+    super.setInput(input, isStreamable);
+	
+    if (!(input instanceof ImageInputStream) && 
+	!(input instanceof InputStream))
+      throw new IllegalArgumentException("Input not an ImageInputStream.");
+  }
+
+  private void checkStream() throws IOException 
+  {
+    if (!(input instanceof ImageInputStream) &&
+	!(input instanceof InputStream))
+      throw new IllegalStateException("Input not an ImageInputStream or InputStream.");
+
+    if(input == null)
+      throw new IllegalStateException("No input stream.");
+  }
+
+  public int getWidth(int imageIndex) throws IOException 
+  {
+    validateIndex( imageIndex );
+    return file.getImage( imageIndex ).getWidth();
+  }
+
+  public int getHeight(int imageIndex) throws IOException 
+  {
+    validateIndex( imageIndex );
+    return file.getImage( imageIndex ).getHeight();
+  }
+
+  public Iterator getImageTypes(int imageIndex)
+  {
+    validateIndex( imageIndex );
+    return null;
+  }
+
+  /**
+   * Returns the number of images. 
+   */
+  public int getNumImages(boolean allowSearch)
+  {
+    try // Image should be loaded here already. But just in case:
+      {
+	readImage();
+      }
+    catch(IOException ioe)
+      {
+	return 0; // Well, now we're in trouble. But return something anyway.
+      }
+    return file.nImages();
+  }
+
+
+  // FIXME: Support metadata
+  public IIOMetadata getImageMetadata(int imageIndex)
+  {
+    validateIndex( imageIndex );
+    return null;
+  }
+
+  // FIXME: Support metadata
+  public IIOMetadata getStreamMetadata()
+  {
+    return null;
+  }
+
+  /**
+   * Reads the image indexed by imageIndex and returns it as 
+   * a complete BufferedImage, using a supplied ImageReadParam.
+   */	      
+  public BufferedImage read(int imageIndex, ImageReadParam param) 
+    throws IOException, IIOException 
+  {
+    validateIndex( imageIndex );
+    GIFFile f = file.getImage( imageIndex );
+    int width = f.getWidth();
+    int height = f.getHeight();
+    SampleModel sm;
+    switch( f.getNColors() )
+      {
+      case 16:
+	sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, 
+					     width, height, 4);
+	break;
+      case 4:
+	sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, 
+					     width, height, 2);
+	break;
+      case 2:
+	sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, 
+					     width, height, 1);
+	break;
+      default:
+	sm = new SinglePixelPackedSampleModel(DataBuffer.TYPE_BYTE, 
+					      width, height, 
+					      new int[] {0xFF});
+	break;
+      }
+    DataBuffer db = new DataBufferByte(f.getRawImage(), width * height, 0);
+    WritableRaster raster = Raster.createWritableRaster(sm, db, null);
+    
+    return new BufferedImage(getPalette( imageIndex ), raster, false, null);
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/gif/GIFImageReaderSpi.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/gif/GIFImageReaderSpi.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/gif/GIFImageReaderSpi.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/gif/GIFImageReaderSpi.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,124 @@
+/* GIFImageReaderSpi.java --
+   Copyright (C)  2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.gif;
+
+import gnu.javax.imageio.IIOInputStream;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.Locale;
+import javax.imageio.ImageReader;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.stream.ImageInputStream;
+
+public class GIFImageReaderSpi extends ImageReaderSpi 
+{
+  static final String vendorName = "GNU";
+  static final String version = "0.1";
+  static final String readerClassName =
+    "gnu.javax.imageio.gif.GIFImageReader";
+  static final String[] names = { "Compuserve GIF" };
+  static final String[] suffixes = { ".gif" };
+  static final String[] MIMETypes = {
+    "image/gif",
+    "image/x-gif"}; // Not sure this is legal, but it seems to be used a bit
+  static final String[] writerSpiNames = null;
+  static final boolean supportsStandardStreamMetadataFormat = false;
+  static final String nativeStreamMetadataFormatName = null;
+  static final String nativeStreamMetadataFormatClassName = null;
+  static final String[] extraStreamMetadataFormatNames = null;
+  static final String[] extraStreamMetadataFormatClassNames = null;
+  static final boolean supportsStandardImageMetadataFormat = false;
+  static final String nativeImageMetadataFormatName = null;
+  static final String nativeImageMetadataFormatClassName = null;
+  static final String[] extraImageMetadataFormatNames = null;
+  static final String[] extraImageMetadataFormatClassNames = null;
+    
+  public GIFImageReaderSpi() 
+  {
+    super(vendorName, version,
+	  names, suffixes, MIMETypes,
+	  readerClassName,
+	  new Class[]{ ImageInputStream.class, InputStream.class },
+	  writerSpiNames,
+	  supportsStandardStreamMetadataFormat,
+	  nativeStreamMetadataFormatName,
+	  nativeStreamMetadataFormatClassName,
+	  extraStreamMetadataFormatNames,
+	  extraStreamMetadataFormatClassNames,
+	  supportsStandardImageMetadataFormat,
+	  nativeImageMetadataFormatName,
+	  nativeImageMetadataFormatClassName,
+	  extraImageMetadataFormatNames,
+	  extraImageMetadataFormatClassNames);
+  }
+    
+  public String getDescription(Locale locale) 
+  {
+    return "Compuserve GIF";
+  }
+    
+  public boolean canDecodeInput(Object input)
+    throws IOException 
+  {
+    if( input == null )
+      throw new IllegalArgumentException("Input object cannot be null.");
+
+    if( !(input instanceof ImageInputStream) && 
+	!(input instanceof InputStream)) 
+      return false;
+
+    boolean retval;
+    InputStream in;
+    if( input instanceof ImageInputStream )
+      in = new IIOInputStream( (ImageInputStream)input );
+    else
+      in = (InputStream)input;
+
+    in.mark(10); // we read 6 bytes
+    retval = GIFFile.readSignature( in );
+    in.reset();
+
+    return retval;
+  }
+    
+  public ImageReader createReaderInstance(Object extension) 
+  {
+    return new GIFImageReader(this);
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/DCT.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/DCT.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/DCT.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/DCT.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,347 @@
+/* DCT.java --
+   Copyright (C)  2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.jpeg;
+
+/**
+ * Discrete Cosine Transformations.
+ */
+public class DCT
+{
+
+  /**
+   * Cosine matrix
+   */
+  public double c[][] = new double[8][8];
+
+  /**
+   * Transformed cosine matrix
+   */
+  public double cT[][] = new double[8][8];
+
+  public DCT()
+  {
+    initMatrix();
+  }
+
+  /**
+   * Figure A.3.3 IDCT, Cu Cv on A-5 of the ISO DIS 10918-1. Requirements and
+   * Guidelines.
+   * 
+   * @param u
+   * @return
+   */
+  public static double C(int u)
+  {
+    return ((u == 0) ? (double) 1 / (double) Math.sqrt((double) 2)
+                     : (double) 1);
+  }
+
+  /**
+   * Initialize matrix values for the fast_idct function
+   */
+  private void initMatrix()
+  {
+    for (int j = 0; j < 8; j++)
+      {
+        double nn = (double) (8);
+        c[0][j] = 1.0 / Math.sqrt(nn);
+        cT[j][0] = c[0][j];
+      }
+    for (int i = 1; i < 8; i++)
+      {
+      for (int j = 0; j < 8; j++)
+        {
+          double jj = (double) j;
+          double ii = (double) i;
+          c[i][j] =
+            Math.sqrt(2.0 / 8.0)
+            * Math.cos(((2.0 * jj + 1.0) * ii * Math.PI) / (2.0 * 8.0));
+          cT[j][i] = c[i][j];
+        }
+      }
+  }
+
+  /**
+   * slow_idct - Figure A.3.3 IDCT (informative) on A-5 of the ISO DIS
+   * 10918-1. Requirements and Guidelines. This is a slow IDCT, there are
+   * better algorithms to use, it's fairly expensive with processor speed.
+   * 
+   * @param matrix
+   * @return
+   */
+  public static double[][] slow_idct(double[][] matrix)
+  {
+    double[][] output = new double[matrix.length][matrix.length];
+    for (int y = 0; y < 8; y++)
+      {
+        for (int x = 0; x < 8; x++)
+          {
+            double val = 0;
+            for (double v = 0; v < 8; v++)
+              {
+                double innerloop = 0;
+                for (double u = 0; u < 8; u++)
+                  innerloop += (DCT.C((int) u) / (double) 2)
+                           * matrix[(int) v][(int) u]
+                           * Math.cos((2 * x + 1) * u * Math.PI / (double) 16)
+                           * Math.cos((2 * y + 1) * v * Math.PI / (double) 16);
+                val += (DCT.C((int) v) / (double) 2) * innerloop;
+              }
+            output[y][x] = (val + 128);
+          }
+      }
+    return (output);
+  }
+
+  public static float[][] slow_fdct(float[][] value)
+  {
+    float[][] buffer = new float[8][8];
+
+    for (int u = 0; u < 8; u++)
+      {
+        for (int v = 0; v < 8; v++)
+          {
+            buffer[u][v] =
+              (float) (1 / 4) * (float) C((int) u) * (float) C((int) v);
+            float innerval = 0;
+            for (int x = 0; x < 8; x++)
+              {
+                for (int y = 0; y < 8; y++)
+                  {
+                    innerval += value[y][x]
+                                  * Math.cos(((2 * x + 1) * u * Math.PI) / 16)
+                                  * Math.cos(((2 * y + 1) * v * Math.PI) / 16);
+                  }
+              }
+            buffer[u][v] *= innerval;
+          }
+      }
+    return (buffer);
+  }
+
+  public float[][] fast_fdct(float[][] input)
+  {
+    float output[][] = new float[8][8];
+    double temp[][] = new double[8][8];
+    double temp1;
+    int i;
+    int j;
+    int k;
+
+    for (i = 0; i < 8; i++)
+      {
+        for (j = 0; j < 8; j++)
+          {
+            temp[i][j] = 0.0;
+            for (k = 0; k < 8; k++)
+              {
+                temp[i][j] += (((int) (input[i][k]) - 128) * cT[k][j]);
+              }
+          }
+      }
+
+    for (i = 0; i < 8; i++)
+      {
+        for (j = 0; j < 8; j++)
+          {
+            temp1 = 0.0;
+
+            for (k = 0; k < 8; k++)
+              {
+                temp1 += (c[i][k] * temp[k][j]);
+              }
+
+            output[i][j] = (int) Math.round(temp1) * 8;
+          }
+      }
+
+    return output;
+  }
+
+  /**
+   * fast_idct - Figure A.3.3 IDCT (informative) on A-5 of the ISO DIS
+   * 10918-1. Requires and Guidelines. This is a fast IDCT, it much more
+   * effecient and only inaccurate at about 1/1000th of a percent of values
+   * analyzed. Cannot be static because initMatrix must run before any
+   * fast_idct values can be computed.
+   * 
+   * @param input
+   * @return
+   */
+  public double[][] fast_idct(double[][] input)
+  {
+    double output[][] = new double[8][8];
+    double temp[][] = new double[8][8];
+    double temp1;
+    int i, j, k;
+    for (i = 0; i < 8; i++)
+      {
+        for (j = 0; j < 8; j++)
+          {
+            temp[i][j] = 0.0;
+            for (k = 0; k < 8; k++)
+              {
+                temp[i][j] += input[i][k] * c[k][j];
+              }
+          }
+      }
+    for (i = 0; i < 8; i++)
+      {
+        for (j = 0; j < 8; j++)
+          {
+            temp1 = 0.0;
+            for (k = 0; k < 8; k++)
+              temp1 += cT[i][k] * temp[k][j];
+            temp1 += 128.0;
+            if (temp1 < 0)
+              output[i][j] = 0;
+            else if (temp1 > 255)
+              output[i][j] = 255;
+            else
+              output[i][j] = (int) Math.round(temp1);
+          }
+      }
+    return output;
+  }
+
+  public double[][] idj_fast_fdct(float input[][])
+  {
+    double output[][] = new double[8][8];
+    double tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+    double tmp10, tmp11, tmp12, tmp13;
+    double z1, z2, z3, z4, z5, z11, z13;
+    int i;
+    int j;
+
+    // Subtracts 128 from the input values
+    for (i = 0; i < 8; i++)
+      {
+        for (j = 0; j < 8; j++)
+          {
+            output[i][j] = ((double) input[i][j] - (double) 128.0);
+            //                        input[i][j] -= 128;
+            
+          }
+      }
+
+    for (i = 0; i < 8; i++)
+      {
+        tmp0 = output[i][0] + output[i][7];
+        tmp7 = output[i][0] - output[i][7];
+        tmp1 = output[i][1] + output[i][6];
+        tmp6 = output[i][1] - output[i][6];
+        tmp2 = output[i][2] + output[i][5];
+        tmp5 = output[i][2] - output[i][5];
+        tmp3 = output[i][3] + output[i][4];
+        tmp4 = output[i][3] - output[i][4];
+
+        tmp10 = tmp0 + tmp3;
+        tmp13 = tmp0 - tmp3;
+        tmp11 = tmp1 + tmp2;
+        tmp12 = tmp1 - tmp2;
+
+        output[i][0] = tmp10 + tmp11;
+        output[i][4] = tmp10 - tmp11;
+
+        z1 = (tmp12 + tmp13) * (double) 0.707106781;
+        output[i][2] = tmp13 + z1;
+        output[i][6] = tmp13 - z1;
+
+        tmp10 = tmp4 + tmp5;
+        tmp11 = tmp5 + tmp6;
+        tmp12 = tmp6 + tmp7;
+
+        z5 = (tmp10 - tmp12) * (double) 0.382683433;
+        z2 = ((double) 0.541196100) * tmp10 + z5;
+        z4 = ((double) 1.306562965) * tmp12 + z5;
+        z3 = tmp11 * ((double) 0.707106781);
+
+        z11 = tmp7 + z3;
+        z13 = tmp7 - z3;
+
+        output[i][5] = z13 + z2;
+        output[i][3] = z13 - z2;
+        output[i][1] = z11 + z4;
+        output[i][7] = z11 - z4;
+      }
+
+    for (i = 0; i < 8; i++)
+      {
+        tmp0 = output[0][i] + output[7][i];
+        tmp7 = output[0][i] - output[7][i];
+        tmp1 = output[1][i] + output[6][i];
+        tmp6 = output[1][i] - output[6][i];
+        tmp2 = output[2][i] + output[5][i];
+        tmp5 = output[2][i] - output[5][i];
+        tmp3 = output[3][i] + output[4][i];
+        tmp4 = output[3][i] - output[4][i];
+
+        tmp10 = tmp0 + tmp3;
+        tmp13 = tmp0 - tmp3;
+        tmp11 = tmp1 + tmp2;
+        tmp12 = tmp1 - tmp2;
+
+        output[0][i] = tmp10 + tmp11;
+        output[4][i] = tmp10 - tmp11;
+
+        z1 = (tmp12 + tmp13) * (double) 0.707106781;
+        output[2][i] = tmp13 + z1;
+        output[6][i] = tmp13 - z1;
+
+        tmp10 = tmp4 + tmp5;
+        tmp11 = tmp5 + tmp6;
+        tmp12 = tmp6 + tmp7;
+
+        z5 = (tmp10 - tmp12) * (double) 0.382683433;
+        z2 = ((double) 0.541196100) * tmp10 + z5;
+        z4 = ((double) 1.306562965) * tmp12 + z5;
+        z3 = tmp11 * ((double) 0.707106781);
+
+        z11 = tmp7 + z3;
+        z13 = tmp7 - z3;
+
+        output[5][i] = z13 + z2;
+        output[3][i] = z13 - z2;
+        output[1][i] = z11 + z4;
+        output[7][i] = z11 - z4;
+      }
+
+    return output;
+  }
+
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/HuffmanTable.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/HuffmanTable.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/HuffmanTable.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/HuffmanTable.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,207 @@
+/* HuffmanTable.java --
+   Copyright (C)  2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.jpeg;
+
+import java.io.IOException;
+
+import javax.imageio.plugins.jpeg.JPEGHuffmanTable;
+
+
+/**
+ * This Object construct a JPEGHuffmanTable which can be used to encode/decode
+ * a scan from a JPEG codec stream. The table must be initalized with either a
+ * BITS byte amount and a Huffman Table Value for decoding or a Huffman Size
+ * and Huffman Code table for encoding.
+ */
+public class HuffmanTable
+{
+  public final static int HUFFMAN_MAX_TABLES = 4;
+
+  private short[]  huffcode = new short[256];
+  private short[]  huffsize = new short[256];
+  private short[]  EHUFCO;
+  private short[]  EHUFSI;
+  private short[]  valptr = new short[16];
+  private short[]  mincode = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+                            -1,-1,-1};
+  private short[]  maxcode = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+                            -1, -1, -1};
+  private short[] huffval;
+  private short[] bits;
+
+  static byte JPEG_DC_TABLE = 0;
+  static byte JPEG_AC_TABLE = 1;
+
+  private short lastk = 0;
+
+  public HuffmanTable(JPEGHuffmanTable table)
+  {
+    huffcode = table.getValues();
+    bits = table.getLengths();
+  }
+
+  /**
+   * Generated from FIGURE C.1 - Generation of table of Huffman code sizes on
+   * ISO DIS 10918-1. Requirements and Guidelines
+   */
+  private void generateSizeTable()
+  {
+    short index=0;
+    for(short i=0; i < bits.length ; i++)
+      {
+        for(short j=0; j < bits[i] ; j++)
+          {
+            huffsize[index] = (short) (i+1);
+            index++;
+          }
+      }
+    lastk = index;
+  }
+
+  /**
+   * Generated from FIGURE C.2 - Generation of table of Huffman codes on
+   * ISO DIS 10918-1. Requirements and Guidelines
+   */
+  private void generateCodeTable()
+  {
+    short k=0;
+    short si = huffsize[0];
+    short code = 0;
+    for(short i=0; i < huffsize.length ; i++)
+      {
+        while(huffsize[k]==si)
+          {
+            huffcode[k] = code;
+            code++;
+            k++;
+          }
+        code <<= 1;
+        si++;
+      }
+  }
+
+  /**
+   * Generated from FIGURE F.15 - Generation of decode table generation on
+   * ISO DIS 10918-1. Requirements and Guidelines
+   */
+  private void generateDecoderTables()
+  {
+    short bitcount = 0;
+    for(int i=0; i < 16 ; i++)
+      {
+        if(bits[i]!=0)
+          valptr[i] = bitcount;
+        for(int j=0 ; j < bits[i] ; j++)
+          {
+            if(huffcode[j+bitcount] < mincode[i] || mincode[i] == -1)
+              mincode[i] = huffcode[j+bitcount];
+
+            if(huffcode[j+bitcount] > maxcode[i])
+              maxcode[i] = huffcode[j+bitcount];
+          }
+        if(mincode[i]!=-1)
+          valptr[i] = (short) (valptr[i] - mincode[i]);
+        bitcount += bits[i];
+      }
+  }
+
+  /**
+   * Generated from FIGURE C.3 - Generation of Order Codes and tables EHUFCO
+   * and EHUFSI from the ISO DIS 10918-1. Requirements and Guidelines
+   */
+  public void orderCodes(boolean isDC)
+  {
+    EHUFCO = new short[isDC ? 15 : 255];
+    EHUFSI = new short[isDC ? 15 : 255];
+
+    for (int p=0; p < lastk ; p++)
+      {
+        int i = huffval[p];
+        if(i < 0 || i > EHUFCO.length || EHUFSI[i]!=0)
+          System.err.println("Error, bad huffman table.");
+        EHUFCO[i] = huffcode[p];
+        EHUFSI[i] = huffsize[p];
+      }
+  }
+
+  /**
+   * Generated from FIGURE F.12 - Extending the sign bit of a decoded value in on
+   * ISO DIS 10918-1. Requirements and Guidelines<p>
+   *
+   * @param diff TODO
+   * @param t TODO
+   * @return TODO
+   */
+  public static int extend(int diff, int t)
+  {
+    int Vt = (int)Math.pow(2,(t-1));
+    if(diff<Vt)
+      {
+        Vt=(-1 << t)+1;
+        diff=diff+Vt;
+      }
+    return diff;
+  }
+
+  /**
+   * Generated from FIGURE F.16 - Procedure for DECODE on
+   * ISO DIS 10918-1. Requirements and Guidelines<p>
+   *
+   * This function takes in a dynamic amount of bits and using the Huffman
+   * table returns information on how many bits must be read in to a byte in
+   * order to reconstruct said byte.
+   *
+   * @param JPEGStream the bits of the data stream.
+   */
+  public int decode(JPEGImageInputStream JPEGStream)
+    throws IOException, JPEGException
+  {
+    int i=0;
+    short code = (short) JPEGStream.readBits(1);
+    while(code > maxcode[i])
+      {
+        i++;
+        code <<= 1;
+        code |= JPEGStream.readBits(1);
+      }
+    int val = huffval[code+(valptr[i])];
+    if(val < 0)
+      val = 256 + val;
+    return val;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGComponent.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGComponent.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGComponent.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGComponent.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,351 @@
+/* JPEGComponent.java --
+   Copyright (C)  2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.jpeg;
+
+import java.util.ArrayList;
+import java.io.IOException;
+import java.awt.image.WritableRaster;
+
+import javax.imageio.plugins.jpeg.JPEGHuffmanTable;
+
+/**
+ * This class holds the methods to decode and write a component information to
+ * a raster.
+ */
+public class JPEGComponent
+{
+  public byte factorH, factorV, component_id, quant_id;
+  public int width = 0, height = 0, maxV = 0, maxH = 0;
+  public HuffmanTable ACTable;
+  public HuffmanTable DCTable;
+  public int[] quantizationTable;
+  public double previousDC = 0;
+  ArrayList data = new ArrayList();
+
+  /**
+   * Initializes the component
+   * 
+   * @param id
+   * @param factorHorizontal
+   * @param factorVertical
+   * @param quantizationID
+   */
+  public JPEGComponent(byte id, byte factorHorizontal, byte factorVertical,
+                       byte quantizationID)
+  {
+    component_id = id;
+    factorH = factorHorizontal;
+    factorV = factorVertical;
+    quant_id = quantizationID;
+  }
+
+  /**
+   * If a restart marker is found with too little of an MCU count (i.e. our
+   * Restart Interval is 63 and we have 61 we copy the last MCU until it's
+   * full)
+   * 
+   * @param index
+   * @param length
+   */
+  public void padMCU(int index, int length)
+  {
+    double[] src = (double[]) data.get(index - 1);
+    for (int i = 0; i < length; i++)
+      data.add(index, src);
+  }
+
+  /**
+   * Reset the interval by setting the previous DC value
+   */
+  public void resetInterval()
+  {
+    previousDC = 0;
+  }
+
+  /**
+   * Run the Quantization backward method on all of the block data.
+   */
+  public void quantitizeData()
+  {
+    for (int i = 0; i < data.size(); i++)
+      {
+        double[] mydata = (double[]) data.get(i);
+        for (int j = 0; j < mydata.length; j++)
+          mydata[j] *= quantizationTable[j];
+      }
+  }
+
+  public void setDCTable(JPEGHuffmanTable table)
+  {
+    DCTable = new HuffmanTable(table);
+  }
+
+  public void setACTable(JPEGHuffmanTable table)
+  {
+    ACTable = new HuffmanTable(table);
+  }
+
+  /**
+   * Run the Inverse DCT method on all of the block data
+   */
+  public void idctData(DCT myDCT)
+  {
+    for (int i = 0; i < data.size(); i++)
+      data.add(i,myDCT.fast_idct(ZigZag.decode8x8_map((double[]) data.remove(i))));
+  }
+
+  /**
+   * This scales up the component size based on the factor size. This
+   * calculates everyting up automatically so it's simply ran at the end of
+   * the frame to normalize the size of all of the components.
+   */
+  public void scaleByFactors()
+  {
+    int factorUpVertical = maxV / factorV;
+    int factorUpHorizontal = maxH / factorH;
+
+    if (factorUpVertical > 1)
+      {
+        for (int i = 0; i < data.size(); i++)
+          {
+            double[][] src = (double[][]) data.remove(i);
+            double[][] dest =
+              new double[src.length * factorUpVertical][src[0].length];
+            for (int j = 0; j < src.length; j++)
+              {
+                for (int u = 0; u < factorUpVertical; u++)
+                  {
+                    dest[j * factorUpVertical + u] = src[j];
+                  }
+              }
+            data.add(i, dest);
+          }
+      }
+
+    if (factorUpHorizontal > 1)
+      {
+        for (int i = 0; i < data.size(); i++)
+          {
+            double[][] src = (double[][]) data.remove(i);
+            double[][] dest =
+              new double[src.length][src[0].length * factorUpHorizontal];
+            for (int j = 0; j < src.length; j++)
+              {
+                for (int u = 0; u < src[0].length; u++)
+                  {
+                    for (int v = 0; v < factorUpHorizontal; v++)
+                      dest[j][u * factorUpHorizontal + v] = src[j][u];
+                  }
+              }
+            data.add(i, dest);
+          }
+      }
+  }
+
+  /**
+   * This write the block of data to the raster throwing out anything that
+   * spills over the raster width or height.
+   * 
+   * @param raster
+   * @param data
+   * @param compIndex
+   * @param x
+   * @param y
+   */
+  public void writeBlock(WritableRaster raster, double[][] data,
+                         int compIndex, int x, int y)
+  {
+    for (int yIndex = 0; yIndex < data.length; yIndex++)
+      {
+        for (int xIndex = 0; xIndex < data[yIndex].length; xIndex++)
+          {
+            // The if statement is needed because blocks can spill over the
+            // frame width because they are padded to make sure we keep the
+            // height of the block the same as the width of the block
+            if (x + xIndex < raster.getWidth()
+                && y + yIndex < raster.getHeight())
+              raster.setSample(x + xIndex, y + yIndex, compIndex,
+                               data[yIndex][xIndex]);
+          }
+      }
+  }
+
+  /**
+   * This writes data to a raster block, so really it's reading not writing
+   * but it writes the data to the raster block by factor size in a zig zag
+   * fashion. This has the helper function writeBlock which does the actual
+   * writing.
+   * 
+   * @param raster
+   * @param componentIndex
+   */
+  public void writeData(WritableRaster raster, int componentIndex)
+  {
+    int x = 0, y = 0, lastblockheight = 0, incrementblock = 0;
+
+    // Keep looping through all of the blocks until there are no more.
+    while(data.size() > 0)
+      {
+        int blockwidth = 0;
+        int blockheight = 0;
+
+        if (x >= raster.getWidth())
+          {
+            x = 0;
+            y += incrementblock;
+          }
+
+        // Loop through the horizontal component blocks of the MCU first
+        // then for each horizontal line write out all of the vertical
+        // components
+        for (int factorVIndex = 0; factorVIndex < factorV; factorVIndex++)
+          {
+            blockwidth = 0;
+
+            for (int factorHIndex = 0; factorHIndex < factorH; factorHIndex++)
+              {
+                // Captures the width of this block so we can increment the
+                // X coordinate
+                double[][] blockdata = (double[][]) data.remove(0);
+
+                // Writes the data at the specific X and Y coordinate of
+                // this component
+                writeBlock(raster, blockdata, componentIndex, x, y);
+                blockwidth += blockdata[0].length;
+                x += blockdata[0].length;
+                blockheight = blockdata.length;
+              }
+            y += blockheight;
+            x -= blockwidth;
+            lastblockheight += blockheight;
+          }
+        y -= lastblockheight;
+        incrementblock = lastblockheight;
+        lastblockheight = 0;
+        x += blockwidth;
+      }
+  }
+
+  /**
+   * Set the quantization table for this component.
+   * 
+   * @param quanttable
+   */
+  public void setQuantizationTable(int[] quanttable)
+  {
+    quantizationTable = quanttable;
+  }
+
+  /**
+   * Read in a partial MCU for this component
+   * 
+   * @param stream TODO
+   * @throws JPEGException TODO
+   * @throws IOException TODO
+   */
+  public void readComponentMCU(JPEGImageInputStream stream)
+    throws JPEGException, IOException
+  {
+    for (int i = 0; i < factorH * factorV; i++)
+      {
+        double dc = decode_dc_coefficient(stream);
+        double[] datablock = decode_ac_coefficients(stream);
+        datablock[0] = dc;
+        data.add(datablock);
+      }
+  }
+
+  /**
+   * Generated from text on F-22, F.2.2.1 - Huffman decoding of DC
+   * coefficients on ISO DIS 10918-1. Requirements and Guidelines.
+   * 
+   * @param JPEGStream TODO
+   *
+   * @return TODO
+   * @throws JPEGException TODO
+   * @throws IOException TODO
+   */
+  public double decode_dc_coefficient(JPEGImageInputStream JPEGStream)
+	throws JPEGException, IOException
+  {
+    int t = DCTable.decode(JPEGStream);
+    double diff = JPEGStream.readBits(t);
+    diff = HuffmanTable.extend((int) diff, t);
+    diff = (previousDC + diff);
+    previousDC = diff;
+    return diff;
+  }
+
+  /**
+   * Generated from text on F-23, F.13 - Huffman decoded of AC coefficients
+   * on ISO DIS 10918-1. Requirements and Guidelines.
+   * 
+   * @param JPEGStream TODO
+   * @return TODO
+   *
+   * @throws JPEGException TODO
+   * @throws IOException TODO
+   */
+  public double[] decode_ac_coefficients(JPEGImageInputStream JPEGStream)
+    throws JPEGException, IOException
+  {
+    double[] zz = new double[64];
+
+    for (int k = 1; k < 64; k++)
+      {
+        int s = ACTable.decode(JPEGStream);
+        int r = s >> 4;
+        s &= 15;
+
+        if (s != 0)
+          {
+            k += r;
+            r = (int) JPEGStream.readBits(s);
+            s = (int) HuffmanTable.extend(r, s);
+            zz[k] = s;
+          }
+        else
+          {
+            if (r != 15)
+              return (zz);
+            k += 15;
+          }
+      }
+    return zz;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGDecoder.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGDecoder.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGDecoder.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGDecoder.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,630 @@
+/* JPEGDecoder.java --
+   Copyright (C)  2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.jpeg;
+
+import java.io.IOException;
+import java.nio.ByteOrder;
+
+import javax.imageio.*;
+import javax.imageio.plugins.jpeg.JPEGHuffmanTable;
+import javax.imageio.plugins.jpeg.JPEGQTable;
+import javax.imageio.spi.*;
+import javax.imageio.metadata.*;
+import javax.imageio.stream.ImageInputStream;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.awt.Point;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+public class JPEGDecoder
+{
+  byte majorVersion;
+  byte minorVersion;
+  byte units;
+  short Xdensity;
+  short Ydensity;
+  byte Xthumbnail;
+  byte Ythumbnail;
+  byte[] thumbnail;
+  BufferedImage image;
+  int width;
+  int height;
+  
+  byte marker;
+
+  /**
+   * This decoder expects JFIF 1.02 encoding.
+   */
+  public static final byte MAJOR_VERSION = (byte) 1;
+  public static final byte MINOR_VERSION = (byte) 2;
+
+  /**
+   * The length of the JFIF field not including thumbnail data.
+   */
+  public static final short JFIF_FIXED_LENGTH = 16;
+
+  /**
+   * The length of the JFIF extension field not including extension
+   * data.
+   */
+  public static final short JFXX_FIXED_LENGTH = 8;
+
+  private JPEGImageInputStream jpegStream;
+
+  ArrayList jpegFrames = new ArrayList();
+
+  JPEGHuffmanTable[] dcTables = new JPEGHuffmanTable[4];
+  JPEGHuffmanTable[] acTables = new JPEGHuffmanTable[4];
+  JPEGQTable[] qTables = new JPEGQTable[4];
+
+    public int getHeight()
+    {
+      return height;
+    }
+    
+    public int getWidth()
+    {
+        return width;
+    }
+  public JPEGDecoder(ImageInputStream in)
+    throws IOException, JPEGException
+  {
+    jpegStream = new JPEGImageInputStream(in);
+    jpegStream.setByteOrder(ByteOrder.LITTLE_ENDIAN);
+
+    if (jpegStream.findNextMarker() != JPEGMarker.SOI)
+      throw new JPEGException("Failed to find SOI marker.");
+
+    if (jpegStream.findNextMarker() != JPEGMarker.APP0)
+      throw new JPEGException("Failed to find APP0 marker.");
+
+    int length = jpegStream.readShort();
+    if (!(length >= JFIF_FIXED_LENGTH))
+      throw new JPEGException("Failed to find JFIF field.");
+
+    byte[] identifier = new byte[5];
+    jpegStream.read(identifier);
+    if (identifier[0] != JPEGMarker.JFIF_J
+        || identifier[1] != JPEGMarker.JFIF_F
+        || identifier[2] != JPEGMarker.JFIF_I
+        || identifier[3] != JPEGMarker.JFIF_F
+        || identifier[4] != JPEGMarker.X00)
+      throw new JPEGException("Failed to read JFIF identifier.");
+
+    majorVersion = jpegStream.readByte();
+    minorVersion = jpegStream.readByte();
+    if (majorVersion != MAJOR_VERSION
+        || (majorVersion == MAJOR_VERSION
+            && minorVersion < MINOR_VERSION))
+      throw new JPEGException("Unsupported JFIF version.");
+
+    units = jpegStream.readByte();
+    if (units > (byte) 2)
+      throw new JPEGException("Units field is out of range.");
+
+    Xdensity = jpegStream.readShort();
+    Ydensity = jpegStream.readShort();
+    Xthumbnail = jpegStream.readByte();
+    Ythumbnail = jpegStream.readByte();
+
+    // 3 * for RGB data
+    int thumbnailLength = 3 * Xthumbnail * Ythumbnail;
+    if (length > JFIF_FIXED_LENGTH
+        && thumbnailLength != length - JFIF_FIXED_LENGTH)
+      throw new JPEGException("Invalid length, Xthumbnail"
+                              + " or Ythumbnail field.");
+
+    if (thumbnailLength > 0)
+      {
+        thumbnail = new byte[thumbnailLength];
+        if (jpegStream.read(thumbnail) != thumbnailLength)
+          throw new IOException("Failed to read thumbnail.");
+      }
+  }
+
+  public void decode()
+    throws IOException
+  {
+    System.out.println ("DECODE!!!");
+    // The frames in this jpeg are loaded into a list. There is
+    // usually just one frame except in heirarchial progression where
+    // there are multiple frames.
+    JPEGFrame frame = null;
+
+    // The restart interval defines how many MCU's we should have
+    // between the 8-modulo restart marker. The restart markers allow
+    // us to tell whether or not our decoding process is working
+    // correctly, also if there is corruption in the image we can
+    // recover with these restart intervals. (See RSTm DRI).
+    int resetInterval = 0;
+
+    // The JPEGDecoder constructor parses the JFIF field.  At this
+    // point jpegStream points to the first byte after the JFIF field.
+
+    // Find the first marker after the JFIF field.
+    byte marker = jpegStream.findNextMarker();
+
+    // Check for a JFIF extension field directly following the JFIF
+    // header and advance the current marker to the next marker in the
+    // stream, if necessary.
+    decodeJFIFExtension();
+
+    // Loop through until there are no more markers to read in, at
+    // that point everything is loaded into the jpegFrames array and
+    // can be processed.
+    while (true)
+      {
+        switch (marker)
+          {
+            // APPn Application Reserved Information - Just throw this
+            // information away because we wont be using it.
+          case JPEGMarker.APP0:
+          case JPEGMarker.APP1:
+          case JPEGMarker.APP2:
+          case JPEGMarker.APP3:
+          case JPEGMarker.APP4:
+          case JPEGMarker.APP5:
+          case JPEGMarker.APP6:
+          case JPEGMarker.APP7:
+          case JPEGMarker.APP8:
+          case JPEGMarker.APP9:
+          case JPEGMarker.APP10:
+          case JPEGMarker.APP11:
+          case JPEGMarker.APP12:
+          case JPEGMarker.APP13:
+          case JPEGMarker.APP14:
+          case JPEGMarker.APP15:
+            jpegStream.skipBytes(jpegStream.readShort() - 2);
+            break;
+
+          case JPEGMarker.SOF0:
+            // SOFn Start of Frame Marker, Baseline DCT - This is the start
+            // of the frame header that defines certain variables that will
+            // be carried out through the rest of the encoding. Multiple
+            // frames are used in a heirarchiel system, however most JPEG's
+            // only contain a single frame.
+            jpegFrames.add(new JPEGFrame());
+            frame = (JPEGFrame) jpegFrames.get(jpegFrames.size() - 1);
+            // Skip the frame length.
+            jpegStream.readShort();
+            // Bits percision, either 8 or 12.
+            frame.setPrecision(jpegStream.readByte());
+            // Scan lines = to the height of the frame.
+            frame.setScanLines(jpegStream.readShort());
+            // Scan samples per line = to the width of the frame.
+            frame.setSamplesPerLine(jpegStream.readShort());
+            // Number of Color Components (or channels).
+            frame.setComponentCount(jpegStream.readByte());
+
+            // Set the color mode for this frame, so far only 2 color
+            // modes are supported.
+            if (frame.getComponentCount() == 1)
+              frame.setColorMode(JPEGFrame.JPEG_COLOR_GRAY);
+            else
+              frame.setColorMode(JPEGFrame.JPEG_COLOR_YCbCr);
+            // Add all of the necessary components to the frame.
+            for (int i = 0; i < frame.getComponentCount(); i++)
+              frame.addComponent(jpegStream.readByte(), jpegStream.readByte(),
+                                 jpegStream.readByte());
+            break;
+
+          case JPEGMarker.SOF2:
+            jpegFrames.add(new JPEGFrame());
+            frame = (JPEGFrame) jpegFrames.get(jpegFrames.size() - 1);
+            // Skip the frame length.
+            jpegStream.readShort();
+            // Bits percision, either 8 or 12.
+            frame.setPrecision(jpegStream.readByte());
+            // Scan lines = to the height of the frame.
+            frame.setScanLines(jpegStream.readShort());
+            // Scan samples per line = to the width of the frame.
+            frame.setSamplesPerLine(jpegStream.readShort());
+            // Number of Color Components (or channels).
+            frame.setComponentCount(jpegStream.readByte());
+
+            // Set the color mode for this frame, so far only 2 color
+            // modes are supported.
+            if (frame.getComponentCount() == 1)
+              frame.setColorMode(JPEGFrame.JPEG_COLOR_GRAY);
+            else
+              frame.setColorMode(JPEGFrame.JPEG_COLOR_YCbCr);
+
+            // Add all of the necessary components to the frame.
+            for (int i = 0; i < frame.getComponentCount(); i++)
+              frame.addComponent(jpegStream.readByte(), jpegStream.readByte(),
+                                 jpegStream.readByte());
+            break;
+
+          case JPEGMarker.DHT:
+            // DHT non-SOF Marker - Huffman Table is required for decoding
+            // the JPEG stream, when we receive a marker we load in first
+            // the table length (16 bits), the table class (4 bits), table
+            // identifier (4 bits), then we load in 16 bytes and each byte
+            // represents the count of bytes to load in for each of the 16
+            // bytes. We load this into an array to use later and move on 4
+            // huffman tables can only be used in an image.
+            int huffmanLength = (jpegStream.readShort() - 2);
+
+            // Keep looping until we are out of length.
+            int index = huffmanLength;
+
+            // Multiple tables may be defined within a DHT marker. This
+            // will keep reading until there are no tables left, most
+            // of the time there are just one tables.
+            while (index > 0)
+              {
+                // Read the identifier information and class
+                // information about the Huffman table, then read the
+                // 16 byte codelength in and read in the Huffman values
+                // and put it into table info.
+                byte huffmanInfo = jpegStream.readByte();
+                byte tableClass = (byte) (huffmanInfo >> 4);
+                byte huffmanIndex = (byte) (huffmanInfo & 0x0f);
+                short[] codeLength = new short[16];
+                jpegStream.readFully(codeLength, 0, codeLength.length);
+                int huffmanValueLen = 0;
+                for (int i = 0; i < 16; i++)
+                  huffmanValueLen += codeLength[i];
+                index -= (huffmanValueLen + 17);
+                short[] huffmanVal = new short[huffmanValueLen];
+                for (int i = 0; i < huffmanVal.length; i++)
+                  huffmanVal[i] = jpegStream.readByte();
+                // Assign DC Huffman Table.
+                if (tableClass == HuffmanTable.JPEG_DC_TABLE)
+                  dcTables[(int) huffmanIndex] = new JPEGHuffmanTable(codeLength,
+                                                                      huffmanVal);
+                // Assign AC Huffman Table.
+                else if (tableClass == HuffmanTable.JPEG_AC_TABLE)
+                  acTables[(int) huffmanIndex] = new JPEGHuffmanTable(codeLength,
+                                                                      huffmanVal);
+              }
+            break;
+          case JPEGMarker.DQT:
+            // DQT non-SOF Marker - This defines the quantization
+            // coeffecients, this allows us to figure out the quality of
+            // compression and unencode the data. The data is loaded and
+            // then stored in to an array.
+            short quantizationLength = (short) (jpegStream.readShort() - 2);
+            for (int j = 0; j < quantizationLength / 65; j++)
+              {
+                byte quantSpecs = jpegStream.readByte();
+                int[] quantData = new int[64];
+                if ((byte) (quantSpecs >> 4) == 0)
+                  // Precision 8 bit.
+                  {
+                    for (int i = 0; i < 64; i++)
+                      quantData[i] = jpegStream.readByte();
+                  
+                  }
+                else if ((byte) (quantSpecs >> 4) == 1)
+                  // Precision 16 bit.
+                  {
+                    for (int i = 0; i < 64; i++)
+                      quantData[i] = jpegStream.readShort();
+                  }
+                qTables[(int) (quantSpecs & 0x0f)] = new JPEGQTable (quantData);
+              }
+            break;
+          case JPEGMarker.SOS:
+            // SOS non-SOF Marker - Start Of Scan Marker, this is where the
+            // actual data is stored in a interlaced or non-interlaced with
+            // from 1-4 components of color data, if three components most
+            // likely a YCrCb model, this is a fairly complex process.
+
+            // Read in the scan length.
+            jpegStream.readShort();
+            // Number of components in the scan.
+            byte numberOfComponents = jpegStream.readByte();
+            byte[] componentSelector = new byte[numberOfComponents];
+            for (int i = 0; i < numberOfComponents; i++)
+              {
+                // Component ID, packed byte containing the Id for the
+                // AC table and DC table.
+                byte componentID = jpegStream.readByte();
+                byte tableInfo = jpegStream.readByte();
+                frame.setHuffmanTables(componentID,
+                                       acTables[(byte) (tableInfo >> 4)],
+                                       dcTables[(byte) (tableInfo & 0x0f)]);
+                componentSelector[i] = componentID;
+              }
+            byte startSpectralSelection = jpegStream.readByte();
+            byte endSpectralSelection = jpegStream.readByte();
+            byte successiveApproximation = jpegStream.readByte();
+
+            int mcuIndex = 0; 
+            int mcuTotalIndex = 0;
+            // This loops through until a MarkerTagFound exception is
+            // found, if the marker tag is a RST (Restart Marker) it
+            // simply skips it and moves on this system does not handle
+            // corrupt data streams very well, it could be improved by
+            // handling misplaced restart markers.
+            while (true)
+              {
+                try
+                  {
+                    // Loop though capturing MCU, instruct each
+                    // component to read in its necessary count, for
+                    // scaling factors the components automatically
+                    // read in how much they need
+                    for (int compIndex = 0; compIndex < numberOfComponents; compIndex++)
+                      {
+                        JPEGComponent comp = (JPEGComponent) frame.components.getComponentByID(componentSelector[compIndex]);
+                        comp.readComponentMCU(jpegStream);
+                      }
+                    mcuIndex++;
+                    mcuTotalIndex++;
+                  }
+                // We've found a marker, see if the marker is a restart
+                // marker or just the next marker in the stream. If
+                // it's the next marker in the stream break out of the
+                // while loop, if it's just a restart marker skip it
+                catch (JPEGMarkerFoundException bse)
+                  {
+                    // Handle JPEG Restart Markers, this is where the
+                    // count of MCU's per interval is compared with
+                    // the count actually obtained, if it's short then
+                    // pad on some MCU's ONLY for components that are
+                    // greater than one. Also restart the DC prediction
+                    // to zero.
+                    if (marker == JPEGMarker.RST0
+                        || marker == JPEGMarker.RST1
+                        || marker == JPEGMarker.RST2
+                        || marker == JPEGMarker.RST3
+                        || marker == JPEGMarker.RST4
+                        || marker == JPEGMarker.RST5
+                        || marker == JPEGMarker.RST6
+                        || marker == JPEGMarker.RST7)
+                      {
+                        for (int compIndex = 0; compIndex < numberOfComponents; compIndex++)
+                          {
+                            JPEGComponent comp = (JPEGComponent) frame.components.getComponentByID(componentSelector[compIndex]);
+                            if (compIndex > 1)
+                              comp.padMCU(mcuTotalIndex, resetInterval - mcuIndex);
+                            comp.resetInterval();
+                          }
+                        mcuTotalIndex += (resetInterval - mcuIndex);
+                        mcuIndex = 0;
+                      }
+                    else
+                      {
+                        // We're at the end of our scan, exit out.
+                        break;
+                      }
+                  }
+              }
+            break;
+          case JPEGMarker.DRI:
+            // DRI - This defines the restart interval, if we have a
+            // restart interval when we reach our restart modulo calculate
+            // whether the count of MCU's specified in the restart
+            // interval have been reached, if they havent then pad with
+            // whatever MCU was last used, this is supposed to be a form of
+            // error recovery but it turns out that some JPEG encoders
+            // purposely cause missing MCU's on repeating MCU's to compress
+            // data even more (even though it adds an extra layer of
+            // complexity.. But since when is JPEG easy?
+            jpegStream.skipBytes(2);
+            resetInterval = jpegStream.readShort();
+            break;
+          case JPEGMarker.COM:
+            // COM - This is a comment that was inserted into the JPEG, we
+            // simply skip over the comment because it's really of no
+            // importance, usually contains a verbal description of the
+            // application or author who created the JPEG.
+            jpegStream.skipBytes(jpegStream.readShort() - 2);
+            break;
+          case JPEGMarker.DNL:
+            // DNL - This sets the height of the image. This is the Define
+            // Number Lines for the image, I'm not sure exactly why we need
+            // this but, whatever we'll abide.
+            frame.setScanLines(jpegStream.readShort());
+            break;
+          case JPEGMarker.EOI:
+            // EOI - End of Image, this processes the frames and turns the
+            // frames into a buffered image.
+
+            if (jpegFrames.size() == 0)
+              {
+                return;
+              }
+            else if (jpegFrames.size() == 1)
+              {
+                // Only one frame, JPEG Non-Heirarchial Frame.
+
+                DCT myDCT = new DCT();
+                WritableRaster raster =
+                  Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+                                                 frame.width,
+                                                 frame.height,
+                                                 frame.getComponentCount(),
+                                                 new Point(0, 0));
+
+                // Unencode the data.
+                for (int i = 0; i < frame.getComponentCount(); i++)
+                  {
+                    JPEGComponent comp =
+                      (JPEGComponent) frame.components.get(i);
+                    comp.setQuantizationTable(qTables[comp.quant_id].getTable());
+                    comp.quantitizeData();
+                    comp.idctData(myDCT);
+                  }
+                // Scale the image and write the data to the raster.
+                for (int i = 0; i < frame.getComponentCount(); i++)
+                  {
+                    JPEGComponent comp = (JPEGComponent) frame.components.get(i);
+                    comp.scaleByFactors();
+                    comp.writeData(raster, i);
+                    // Ensure garbage collection.
+                    comp = null;
+                  }
+                // Grayscale Color Image (1 Component).
+                if (frame.getComponentCount() == 1)
+                  {
+                    ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
+                    ComponentColorModel ccm =
+                      new ComponentColorModel(cs, false, false,
+                                              Transparency.OPAQUE,
+                                              DataBuffer.TYPE_BYTE);
+                    image = new BufferedImage(ccm, raster, false,
+                                              new Hashtable());
+                  }
+                // YCbCr Color Image (3 Components).
+                else if (frame.getComponentCount() == 3)
+                  {
+                    ComponentColorModel ccm =
+                      new ComponentColorModel(new YCbCr_ColorSpace(), false,
+                                              false, Transparency.OPAQUE,
+                                              DataBuffer.TYPE_BYTE);
+                    image = new BufferedImage(ccm, raster, false,
+                                              new Hashtable());
+                  }
+                // Possibly CMYK or RGBA ?
+                else
+                  {
+                    throw new JPEGException("Unsupported Color Mode: 4 "
+                                            + "Component Color Mode found.");
+                  }
+                height = frame.height;
+                width = frame.width;
+              }
+            else
+              {
+                //JPEG Heirarchial Frame (progressive or baseline).
+                throw new JPEGException("Unsupported Codec Type:"
+                                        + " Hierarchial JPEG");
+              }
+            break;
+          case JPEGMarker.SOF1:
+            // ERROR - If we encounter any of the following marker codes
+            // error out with a codec exception, progressive, heirarchial,
+            // differential, arithmetic, lossless JPEG's are not supported.
+            // This is where enhancements can be made for future versions.
+            // Thankfully 99% of all JPEG's are baseline DCT.
+            throw new JPEGException("Unsupported Codec Type: Extended "
+                                    + "Sequential DCT JPEG's Not-Supported");
+            //case JPEGMarker.SOF2:
+            //	throw new JPEGException("Unsupported Codec Type: Progressive DCT JPEG's Not-Supported");
+          case JPEGMarker.SOF3:
+            throw new JPEGException("Unsupported Codec Type:"
+                                    + " Lossless (sequential)");
+          case JPEGMarker.SOF5:
+            throw new JPEGException("Unsupported Codec Type:"
+                                    + " Differential sequential DCT");
+          case JPEGMarker.SOF6:
+            throw new JPEGException("Unsupported Codec Type:"
+                                    + " Differential progressive DCT");
+          case JPEGMarker.SOF7:
+            throw new JPEGException("Unsupported Codec Type:"
+                                    + " Differential lossless");
+          case JPEGMarker.SOF9:
+          case JPEGMarker.SOF10:
+          case JPEGMarker.SOF11:
+          case JPEGMarker.SOF13:
+          case JPEGMarker.SOF14:
+          case JPEGMarker.SOF15:
+            throw new JPEGException("Unsupported Codec Type:"
+                                    + " Arithmetic Coding Frame");
+          default:
+            // Unknown marker found, ignore it.
+          }
+        marker = jpegStream.findNextMarker();
+      }
+  }
+
+  // If the current marker is APP0, tries to decode a JFIF extension
+  // and advances the current marker to the next marker in the stream.
+  private void decodeJFIFExtension() throws IOException
+  {
+    if (marker == JPEGMarker.APP0)
+      {
+        int length = jpegStream.readShort();
+
+        if (length >= JFXX_FIXED_LENGTH)
+          {
+            byte[] identifier = new byte[5];
+            jpegStream.read(identifier);
+            if (identifier[0] != JPEGMarker.JFIF_J
+                || identifier[1] != JPEGMarker.JFIF_F
+                || identifier[2] != JPEGMarker.JFIF_X
+                || identifier[3] != JPEGMarker.JFIF_X
+                || identifier[4] != JPEGMarker.X00)
+              // Not a JFXX field.  Ignore it and continue.
+              jpegStream.skipBytes(length - 7);
+            else
+              {
+                byte extension_code = jpegStream.readByte();
+
+                switch (extension_code)
+                  {
+                  case JPEGMarker.JFXX_JPEG:
+                    // FIXME: add support for JFIF Extension:
+                    // Thumbnail coded using JPEG.
+                    jpegStream.skipBytes(length - 8);
+                  case JPEGMarker.JFXX_ONE_BPP:
+                    // FIXME: add support for JFIF Extension:
+                    // Thumbnail stored using 1 byte/pixel.
+                    jpegStream.skipBytes(length - 8);
+                  case JPEGMarker.JFXX_THREE_BPP:
+                    // FIXME: add support for JFIF Extension:
+                    // Thumbnail stored using 3 bytes/pixel.
+                    jpegStream.skipBytes(length - 8);
+                  }
+              }
+          }
+        else
+          {
+            // Unknown APP0 marker.  Ignore it and continue.
+            jpegStream.skipBytes(length - 2);
+          }
+        marker = jpegStream.findNextMarker();
+      }
+  }
+
+  public BufferedImage getImage()
+  {
+    return image;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGException.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGException.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGException.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGException.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,55 @@
+/* JPEGException.java --
+   Copyright (C)  2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.jpeg;
+
+// FIXME: change to IIOException
+import java.io.IOException;
+import javax.imageio.*;
+import javax.imageio.spi.*;
+import javax.imageio.metadata.*;
+import javax.imageio.stream.ImageInputStream;
+import java.util.Iterator;
+import java.awt.image.BufferedImage;
+
+public class JPEGException extends IIOException
+{
+  public JPEGException(String message)
+  {
+     super(message);
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGFrame.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGFrame.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGFrame.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGFrame.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,108 @@
+/* JPEGFrame.java --
+   Copyright (C)  2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.jpeg;
+
+import javax.imageio.plugins.jpeg.JPEGHuffmanTable;
+
+public class JPEGFrame
+{
+  public final static byte JPEG_COLOR_GRAY = 1;
+  public final static byte JPEG_COLOR_RGB = 2;
+  public final static byte JPEG_COLOR_YCbCr = 3;
+  public final static byte JPEG_COLOR_CMYK = 4;
+
+  public byte precision = 8;
+  public byte colorMode = JPEGFrame.JPEG_COLOR_YCbCr;
+  public byte componentCount = 0;
+
+  public short width=0, height=0;
+
+  public JPEGScan components;
+
+  public JPEGFrame()
+  {
+    components = new JPEGScan();
+  }
+
+  public void addComponent(byte componentID, byte sampleFactors,
+                           byte quantizationTableID)
+  {
+    byte sampleHorizontalFactor = (byte)(sampleFactors >> 4);
+    byte sampleVerticalFactor = (byte)(sampleFactors & 0x0f);
+    components.addComponent(componentID, sampleHorizontalFactor,
+                            sampleVerticalFactor, quantizationTableID);
+  }
+
+  public void setPrecision(byte data)
+  {
+    precision = data;
+  }
+
+  public void setScanLines(short data)
+  {
+    height = data;
+  }
+
+  public void setSamplesPerLine(short data)
+  {
+    width = data;
+  }
+
+  public void setColorMode(byte data)
+  {
+    colorMode = data;
+  }
+
+  public void setComponentCount(byte data)
+  {
+    componentCount = data;
+  }
+
+  public byte getComponentCount()
+  {
+    return componentCount;
+  }
+
+  public void setHuffmanTables(byte componentID, JPEGHuffmanTable ACTable,
+                               JPEGHuffmanTable DCTable)
+  {
+    JPEGComponent comp = (JPEGComponent)components.getComponentByID(componentID);
+    comp.setACTable(ACTable);
+    comp.setDCTable(DCTable);
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGImageInputStream.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGImageInputStream.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGImageInputStream.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGImageInputStream.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,195 @@
+/* JPEGImageInputStream.java --
+   Copyright (C)  2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.jpeg;
+
+import java.io.EOFException;
+import java.io.IOException;
+import javax.imageio.*;
+import javax.imageio.spi.*;
+import javax.imageio.metadata.*;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.ImageInputStreamImpl;
+
+import java.util.Iterator;
+import java.awt.image.BufferedImage;
+
+public class JPEGImageInputStream
+  extends ImageInputStreamImpl
+{
+  private ImageInputStream in;
+
+  byte marker;
+  
+  public JPEGImageInputStream(ImageInputStream in)
+  {
+    super();
+
+    this.in = in;
+  }
+
+  public int read()
+    throws IOException
+  {
+    setBitOffset(0);
+    return in.read();
+  }
+
+  public int read(byte[] data, int offset, int len)
+    throws IOException
+  {
+    setBitOffset(0);
+    return in.read(data, offset, len);
+  }
+  
+  /**
+   * Pull a byte from the stream, this checks to see if the byte is 0xff
+   * and if the next byte isn't 0x00 (stuffed byte) it errors out. If it's
+   * 0x00 then it simply ignores the byte.
+   *
+   * @return the next byte in the buffer
+   *
+   * @throws IOException TODO
+   * @throws BitStreamException TODO
+   */
+  private byte pullByte() throws IOException, JPEGMarkerFoundException
+  {
+    byte mybyte = readByte();
+    // FIXME: handle multiple 0xff in a row
+    if(mybyte==(byte)(0xff))
+      {
+        byte secondbyte = readByte();
+        if(secondbyte != (byte)(0x00))
+          {
+            marker = secondbyte;
+            throw new JPEGMarkerFoundException();
+          }
+      }
+    return mybyte;
+  }
+
+  /**
+   * This returns the marker that was last encountered.  This should only be
+   * used if removeBit() throws a MarkerTagFound exception.
+   *
+   * @return marker as byte
+   */
+  public byte getMarker()
+  {
+    return marker;
+  }
+
+  /**
+   * Removes a bit from the buffer. (Removes from the top of a queue). This
+   * also checks for markers and throws MarkerTagFound exception if it does.
+   * If MarkerTagFound is thrown you can use getMarker() method to get the
+   * marker that caused the throw.
+   *
+   * @param l specifies how many bits you want to remove and add to the
+   *        integer
+   * @return the amount of bits specified by l as an integer
+   *
+   * @throws IOException TODO
+   * @throws JPEGMarkerFoundException 
+   * @throws BitStreamException TODO
+   */
+  public int readBit()
+  throws IOException, JPEGMarkerFoundException
+{
+  checkClosed();
+
+  // Calc new bit offset here, readByte resets it.
+  int newOffset = (bitOffset + 1) & 0x7;
+
+  byte data = pullByte();
+  
+  if (bitOffset != 0)
+    {
+        seek(getStreamPosition() - 1);
+        data = (byte) (data >> (8 - newOffset));
+    }
+
+  bitOffset = newOffset;
+  return data & 0x1;
+}
+
+
+  /**
+   * This method skips over the the data and finds the next position
+   * in the bit sequence with a X'FF' X'??' sequence.  Multiple X'FF
+   * bytes in sequence are considered padding and interpreted as one
+   * X'FF byte.
+   *
+   * @return the next marker byte in the stream
+   * @throws IOException if the end of the stream is reached
+   * unexpectedly
+   */
+  public byte findNextMarker()
+    throws IOException
+  {
+    boolean marked0xff = false;
+    byte byteinfo = JPEGMarker.X00;
+
+    setBitOffset(0);
+    while (true)
+      {
+        byteinfo = readByte();
+        if (!marked0xff)
+          {
+            if (byteinfo == JPEGMarker.XFF)
+              marked0xff = true;
+          }
+        else
+          {
+            if (byteinfo == JPEGMarker.XFF)
+              // Ignore the value 0xff when it is immediately
+              // followed by another 0xff byte.
+              continue;
+            else if (byteinfo == JPEGMarker.X00)
+              // The sequence 0xff 0x00 is used to encode the
+              // actual value 0xff.  So restart our search for a
+              // marker.
+              marked0xff = false;
+            else
+              // One or more 0xff values were follwed by a
+              // non-0x00, non-0xff value so return this as the
+              // marker byte.
+              return byteinfo;
+          }
+      }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGImageReader.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGImageReader.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGImageReader.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGImageReader.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,141 @@
+/* JPEGImageReader.java --
+   Copyright (C)  2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.jpeg;
+
+import java.io.IOException;
+import javax.imageio.*;
+import javax.imageio.spi.*;
+import javax.imageio.metadata.*;
+import javax.imageio.stream.ImageInputStream;
+import java.util.Iterator;
+import java.awt.image.BufferedImage;
+
+public class JPEGImageReader extends ImageReader
+{
+  JPEGDecoder decoder;
+
+  protected JPEGImageReader(ImageReaderSpi originatingProvider)
+  {
+    super(originatingProvider);
+    System.out.println("JPEGIMAGEREADER!!!");
+  }
+
+  // Abstract ImageReader methods.
+  public int getHeight(int imageIndex)
+    throws IOException
+  {
+    checkIndex(imageIndex);
+    decodeStream();
+    return decoder.getHeight();
+  }
+
+  public IIOMetadata getImageMetadata(int imageIndex)
+    throws IOException
+  {
+    // FIXME: handle metadata
+    checkIndex(imageIndex);
+    return null;
+  }
+
+  public Iterator getImageTypes(int imageIndex)
+    throws IOException
+  {
+    return null;
+  }
+
+  public int getNumImages(boolean allowSearch)
+    throws IOException
+  {
+    return 1;
+  }
+
+  public IIOMetadata getStreamMetadata()
+    throws IOException
+  {
+    // FIXME: handle metadata
+    return null;
+  }
+
+  public int getWidth(int imageIndex)
+    throws IOException
+  {
+    checkIndex(imageIndex);
+    decodeStream();
+    return decoder.getWidth();
+  }
+
+  public BufferedImage read(int imageIndex, ImageReadParam param)
+    throws IOException
+  {
+    checkIndex(imageIndex);
+    decodeStream();
+    return decoder.getImage();
+  }
+
+  // private helper methods
+  private void checkIndex(int imageIndex)
+    throws IndexOutOfBoundsException
+  {
+    if (imageIndex != 0)
+      throw new IndexOutOfBoundsException();
+  }
+
+  private void checkStream() throws IOException
+  {
+    if (!(input instanceof ImageInputStream)) 
+      throw new IllegalStateException("Input not an ImageInputStream.");
+    if(input == null)
+      throw new IllegalStateException("No input stream.");
+  }
+
+  private void decodeStream()
+    throws IOException, IIOException
+  {
+    System.out.println("DECONDING 1");
+    if (decoder != null)
+      return;
+
+    System.out.println("DECONDING 2");
+    checkStream();
+
+    System.out.println("DECONDING 3");
+    decoder = new JPEGDecoder((ImageInputStream)input);
+    System.out.println("DECONDING 4");
+    decoder.decode();
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGImageReaderSpi.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGImageReaderSpi.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGImageReaderSpi.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGImageReaderSpi.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,137 @@
+/* JPEGImageReaderSpi.java --
+   Copyright (C)  2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.jpeg;
+
+import java.io.IOException;
+import java.util.Locale;
+import javax.imageio.ImageReader;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.spi.IIORegistry;
+import javax.imageio.stream.ImageInputStream;
+
+public class JPEGImageReaderSpi extends ImageReaderSpi
+{
+  static final String vendorName = "GNU";
+  static final String version = "0.1";
+  static final String readerClassName =
+    "gnu.javax.imageio.jpeg.JPEGImageReader";
+  static final String[] names = { "JPEG" };
+  static final String[] suffixes = { ".jpeg", ".jpg", ".jpe" };
+  static final String[] MIMETypes = { "image/jpeg" };
+  static final String[] writerSpiNames =
+    { "gnu.javax.imageio.jpeg.JPEGImageWriterSpi" };
+
+  static final boolean supportsStandardStreamMetadataFormat = false;
+  static final String nativeStreamMetadataFormatName = null;
+  static final String nativeStreamMetadataFormatClassName = null;
+  static final String[] extraStreamMetadataFormatNames = null;
+  static final String[] extraStreamMetadataFormatClassNames = null;
+  static final boolean supportsStandardImageMetadataFormat = false;
+  static final String nativeImageMetadataFormatName = null;
+  static final String nativeImageMetadataFormatClassName = null;
+  static final String[] extraImageMetadataFormatNames = null;
+  static final String[] extraImageMetadataFormatClassNames = null;
+
+  private static JPEGImageReaderSpi readerSpi;
+
+  public JPEGImageReaderSpi()
+  {
+    super(vendorName, version,
+          names, suffixes, MIMETypes,
+          readerClassName,
+          STANDARD_INPUT_TYPE, // Accept ImageInputStreams
+          writerSpiNames,
+          supportsStandardStreamMetadataFormat,
+          nativeStreamMetadataFormatName,
+          nativeStreamMetadataFormatClassName,
+          extraStreamMetadataFormatNames,
+          extraStreamMetadataFormatClassNames,
+          supportsStandardImageMetadataFormat,
+          nativeImageMetadataFormatName,
+          nativeImageMetadataFormatClassName,
+          extraImageMetadataFormatNames,
+          extraImageMetadataFormatClassNames);
+    System.out.println ("JPEGImageReaderSPI!!!");
+  }
+    
+  public String getDescription(Locale locale)
+  {
+    return "JPEG ISO 10918-1, JFIF V1.02";
+  }
+    
+  public boolean canDecodeInput(Object input)
+    throws IOException
+  {
+    if (!(input instanceof ImageInputStream)) 
+      return false;
+
+    ImageInputStream in = (ImageInputStream) input;
+    boolean retval;
+
+    in.mark();
+    try
+      {
+        new JPEGDecoder(in);
+        retval = true;
+      }
+    catch(JPEGException e)
+      {
+        retval = false;
+      }
+    in.reset();
+
+    return retval;
+  }
+    
+  public ImageReader createReaderInstance(Object extension)
+  {
+    return new JPEGImageReader(this);
+  }
+
+  public static void registerSpis(IIORegistry reg)
+  {
+    reg.registerServiceProvider(getReaderSpi(), ImageReaderSpi.class);
+  }
+
+  public static synchronized JPEGImageReaderSpi getReaderSpi()
+  {
+    if (readerSpi == null)
+      readerSpi = new JPEGImageReaderSpi();
+    return readerSpi;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGMarker.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGMarker.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGMarker.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGMarker.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,205 @@
+/* JPEGMarker.java --
+   Copyright (C)  2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.jpeg;
+
+public class JPEGMarker
+{
+  /**
+   * JFIF identifiers.
+   */
+  public final static byte JFIF_J = (byte) 0x4a;
+  public final static byte JFIF_F = (byte) 0x46;
+  public final static byte JFIF_I = (byte) 0x49;
+  public final static byte JFIF_X = (byte) 0x46;
+
+  /**
+   * JFIF extension codes.
+   */
+  public final static byte JFXX_JPEG = (byte) 0x10;
+  public final static byte JFXX_ONE_BPP = (byte) 0x11;
+  public final static byte JFXX_THREE_BPP = (byte) 0x13;
+
+  /**
+   * Marker prefix byte.
+   */
+  public final static byte XFF = (byte) 0xff;
+
+  /**
+   * Marker byte that represents a literal 0xff.
+   */
+  public final static byte X00 = (byte) 0x00;
+
+  /**
+   *  Application Reserved Keyword.
+   */
+  public final static byte APP0 = (byte) 0xe0;
+
+  public final static byte APP1 = (byte) 0xe1;
+  public final static byte APP2 = (byte) 0xe2;
+  public final static byte APP3 = (byte) 0xe3;
+  public final static byte APP4 = (byte) 0xe4;
+  public final static byte APP5 = (byte) 0xe5;
+  public final static byte APP6 = (byte) 0xe6;
+  public final static byte APP7 = (byte) 0xe7;
+  public final static byte APP8 = (byte) 0xe8;
+  public final static byte APP9 = (byte) 0xe9;
+  public final static byte APP10 = (byte) 0xea;
+  public final static byte APP11 = (byte) 0xeb;
+  public final static byte APP12 = (byte) 0xec;
+  public final static byte APP13 = (byte) 0xed;
+  public final static byte APP14 = (byte) 0xee;
+  public final static byte APP15 = (byte) 0xef;
+
+  /**
+   * Modulo Restart Interval.
+   */
+  public final static byte RST0 = (byte) 0xd0;
+
+  public final static byte RST1 = (byte) 0xd1;
+  public final static byte RST2 = (byte) 0xd2;
+  public final static byte RST3 = (byte) 0xd3;
+  public final static byte RST4 = (byte) 0xd4;
+  public final static byte RST5 = (byte) 0xd5;
+  public final static byte RST6 = (byte) 0xd6;
+  public final static byte RST7 = (byte) 0xd7;
+
+  /**
+   * Nondifferential Huffman-coding frame (baseline dct).
+   */
+  public final static byte SOF0 = (byte) 0xc0;
+
+  /**
+   * Nondifferential Huffman-coding frame (extended dct).
+   */
+  public final static byte SOF1 = (byte) 0xc1;
+
+  /**
+   * Nondifferential Huffman-coding frame (progressive dct).
+   */
+  public final static byte SOF2 = (byte) 0xc2;
+
+  /**
+   * Nondifferential Huffman-coding frame Lossless (Sequential).
+   */
+  public final static byte SOF3 = (byte) 0xc3;
+
+  /**
+   * Differential Huffman-coding frame Sequential DCT.
+   */
+  public final static byte SOF5 = (byte) 0xc5;
+
+  /**
+   * Differential Huffman-coding frame Progressive DCT.
+   */
+  public final static byte SOF6 = (byte) 0xc6;
+
+  /**
+   * Differential Huffman-coding frame lossless.
+   */
+  public final static byte SOF7 = (byte) 0xc7;
+
+  /**
+   * Nondifferential Arithmetic-coding frame (extended dct).
+   */
+  public final static byte SOF9 = (byte) 0xc9;
+
+  /**
+   * Nondifferential Arithmetic-coding frame (progressive dct).
+   */
+  public final static byte SOF10 = (byte) 0xca;
+
+  /**
+   * Nondifferential Arithmetic-coding frame (lossless).
+   */
+  public final static byte SOF11 = (byte) 0xcb;
+
+  /**
+   * Differential Arithmetic-coding frame (sequential dct).
+   */
+  public final static byte SOF13 = (byte) 0xcd;
+
+  /**
+   * Differential Arithmetic-coding frame (progressive dct).
+   */
+  public final static byte SOF14 = (byte) 0xce;
+
+  /**
+   * Differential Arithmetic-coding frame (lossless).
+   */
+  public final static byte SOF15 = (byte) 0xcf;
+
+  /**
+   * Huffman Table.
+   */
+  public final static byte DHT = (byte) 0xc4;
+
+  /**
+   * Quantization Table.
+   */
+  public final static byte DQT = (byte) 0xdb;
+ 
+  /**
+   * Start of Scan.
+   */
+  public final static byte SOS = (byte) 0xda;
+
+  /**
+   * Defined Restart Interval.
+   */
+  public final static byte DRI = (byte) 0xdd;
+
+  /**
+   * Comment in JPEG.
+   */
+  public final static byte COM = (byte) 0xfe;
+
+  /**
+   * Start of Image.
+   */
+  public final static byte SOI = (byte) 0xd8;
+
+  /**
+   * End of Image.
+   */
+  public final static byte EOI = (byte) 0xd9;
+
+  /**
+   * Define Number of Lines.
+   */
+  public final static byte DNL = (byte) 0xdc;
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGMarkerFoundException.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGMarkerFoundException.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGMarkerFoundException.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGMarkerFoundException.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,50 @@
+/* JPEGMarkerFoundException.java -- FIXME: briefly describe file purpose
+   Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.imageio.jpeg;
+
+import java.io.IOException;
+
+public class JPEGMarkerFoundException
+    extends IOException
+{
+  public JPEGMarkerFoundException()
+  {
+    super("");
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGScan.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGScan.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGScan.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/JPEGScan.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,151 @@
+/* JPEGScan.java --
+   Copyright (C)  2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.jpeg;
+
+import java.util.ArrayList;
+
+public class JPEGScan
+{
+  private int maxHeight = 0, maxWidth = 0, maxV = 0, maxH = 0;
+  private int numOfComponents = 0, numOfComponentBlocks = 0;
+  private ArrayList components = new ArrayList();
+
+  public JPEGScan()
+  {
+    // Nothing to do here.
+  }
+
+  public JPEGScan(int h, int w)
+  {
+    maxHeight=h;
+    maxWidth=w;
+  }
+
+  private void recalculateDimensions()
+  {
+    JPEGComponent comp;
+
+    // Compute the maximum H, maximum V factors defined in Annex A of the ISO
+    // DIS 10918-1.
+    for(int i=0; i < components.size() ; i++)
+      {
+        comp = (JPEGComponent)components.get(i);
+        if(comp.factorH > maxH)
+          maxH=comp.factorH;
+        if(comp.factorV > maxV)
+          maxV=comp.factorV;
+      }
+
+    for(int i=0; i < components.size() ; i++)
+      {
+        comp = (JPEGComponent)components.get(i);
+        comp.maxH = maxH;
+        comp.maxV = maxV;
+      }
+
+  }
+
+  public void addComponent(byte id, byte factorHorizontal, byte factorVertical,
+                           byte quantizationID)
+  {
+    JPEGComponent component = new JPEGComponent(id, factorHorizontal, factorVertical, quantizationID);
+    components.add((Object)component);
+    recalculateDimensions();
+    numOfComponents++;
+    numOfComponentBlocks += factorHorizontal*factorVertical;
+  }
+
+  public JPEGComponent getComponentByID(byte id)
+  {
+    JPEGComponent comp = (JPEGComponent)components.get(0);
+    for(int i=0; i < components.size() ; i++)
+      {
+        comp=(JPEGComponent)components.get(i);
+        if(comp.component_id==id)
+          break;
+      }
+    return(comp);
+  }
+
+  public JPEGComponent get(int id)
+  {
+    return((JPEGComponent)components.get(id));
+  }
+
+  public int getX(byte id)
+  {
+    JPEGComponent comp = getComponentByID(id);
+    return(comp.width);
+  }
+
+  public int getY(byte id)
+  {
+    JPEGComponent comp = getComponentByID(id);
+    return(comp.height);
+  }
+
+  public int getMaxV()
+  {
+    return(maxV);
+  }
+
+  public int getMaxH()
+  {
+    return(maxH);
+  }
+
+  public void setWidth(int w)
+  {
+    maxWidth=w;
+  }
+
+  public void setHeight(int h)
+  {
+    maxHeight=h;
+  }
+
+  public int size()
+  {
+    return(numOfComponents);
+  }
+
+  public int sizeComponentBlocks()
+  {
+    return(numOfComponentBlocks);
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/YCbCr_ColorSpace.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/YCbCr_ColorSpace.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/YCbCr_ColorSpace.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/YCbCr_ColorSpace.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,113 @@
+/* YCbCr_ColorSpace.java --
+   Copyright (C)  2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.jpeg;
+
+import java.awt.color.ColorSpace;
+
+public class YCbCr_ColorSpace extends ColorSpace {
+  public YCbCr_ColorSpace() {
+    super(ColorSpace.TYPE_YCbCr, 3);
+  }
+
+  public float[] fromCIEXYZ(float[] data) {
+    return(new float[data.length]);
+  }
+
+  public float[] toCIEXYZ(float[] data) {
+    return(new float[data.length]);
+  }
+
+  public float[] fromRGB(float[] data) {
+    return(new float[data.length]);
+  }
+
+  /* YCbCr to RGB range 0 to 1 */
+  public float[] toRGB(float[] data) {
+    float[] dest = new float[3];
+
+    data[0] *= 255;
+    data[1] *= 255;
+    data[2] *= 255;
+
+    dest[0] = (float)data[0] + (float)1.402*((float)data[2]-(float)128);
+    dest[1] = (float)data[0] - (float)0.34414*((float)data[1]-(float)128) - (float)0.71414*((float)data[2]-(float)128);
+    dest[2] = (float)data[0] + (float)1.772*((float)data[1]-(float)128);
+
+    dest[0] /= 255;
+    dest[1] /= 255;
+    dest[2] /= 255;
+
+    //dest[0] = ((float)1.164*((float)data[0]*(float)255 - (float)16) + (float)1.596*((float)data[2]*(float)255 - (float)128))/(float)255;
+    //dest[1] = ((float)1.164*((float)data[0]*(float)255 - (float)16) - (float)0.813*((float)data[2]*(float)255 - (float)128) - (float)0.392*(data[1]*255 - 128))/(float)255;
+    //dest[2] = ((float)1.164*((float)data[0]*(float)255 - (float)16) + (float)2.017*((float)data[1]*(float)255 - (float)128))/(float)255;
+
+    //System.err.println("toRGB values received: 0: "+data[0]+" 1: "+data[1]+" 2: "+data[2]+" sent: 0: "+dest[0]+" 1: "+dest[1]+" 2: "+dest[2]);
+    if(dest[0] < (float)0)
+      dest[0] = 0;
+    if(dest[1] < (float)0)
+      dest[1] = 0;
+    if(dest[2] < (float)0)
+      dest[2] = 0;
+
+    if(dest[0] > (float)1)
+      dest[0] = 1;
+    if(dest[1] > (float)1)
+      dest[1] = 1;
+    if(dest[2] > (float)1)
+      dest[2] = 1;
+
+
+    return(dest);
+  }
+
+  /* RGB to YCbCr range 0-255 */
+  public static float[] toYCbCr(float[] data) {
+    float[] dest = new float[3];
+    //dest[0] = (float)0.257*data[0] + (float)0.504*data[1] + (float)0.098*data[2] + 16;
+    //dest[1] = (float)-0.148*data[0] - (float)0.291*data[1] + (float)0.439*data[2] + 128;
+    //dest[2] = (float)0.439*data[0] - (float)0.368*data[1] - (float)0.071*data[2] + 128;
+
+    dest[0] = (float)((0.299 * (float)data[0] + 0.587 * (float)data[1] + 0.114 * (float)data[2]));
+    dest[1] = 128 + (float)((-0.16874 * (float)data[0] - 0.33126 * (float)data[1] + 0.5 * (float)data[2]));
+    dest[2] = 128 + (float)((0.5 * (float)data[0] - 0.41869 * (float)data[1] - 0.08131 * (float)data[2]));
+
+
+    return(dest);
+
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/ZigZag.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/ZigZag.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/ZigZag.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/jpeg/ZigZag.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,520 @@
+/* ZigZag.java --
+   Copyright (C)  2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.jpeg;
+
+/**
+ * This class implements the Zig Zag Algorithm on any array with
+ * the same amount of rows and columns. It takes a matrix and in turn builds an
+ * encoded byte array (or double array) from it. The adverse is also true, this
+ * will take a byte or double array and build a matrix based on the zig zag
+ * algorithm.
+ * <p>This is used exclusively in the JPEG DCT encoding.</p>
+ */
+public class ZigZag
+{
+  public final static boolean ZIGZAG_FORWARD = true;
+  public final static boolean ZIGZAG_BACKWARD = false;
+  public final static int ZIGZAG_8X8_MAP[] =
+  {
+   0,   1,  8, 16,  9,  2,  3, 10,
+   17, 24, 32, 25, 18, 11,  4,  5,
+   12, 19, 26, 33, 40, 48, 41, 34,
+   27, 20, 13,  6,  7, 14, 21, 28,
+   35, 42, 49, 56, 57, 50, 43, 36,
+   29, 22, 15, 23, 30, 37, 44, 51,
+   58, 59, 52, 45, 38, 31, 39, 46,
+   53, 60, 61, 54, 47, 55, 62, 63
+  };
+
+  /**
+   * Encodes a matrix of equal width and height to a byte array.
+   * 
+   * @param matrix
+   *
+   * @return
+   */
+  public static byte[] encode(byte[][] matrix)
+  {
+    byte[] buffer = new byte[matrix.length ^ 2];
+    boolean direction = ZigZag.ZIGZAG_FORWARD;
+    int x = 0, y = 0, index = 0;
+    for (int zigIndex = 0; zigIndex < (matrix.length * 2 - 1);
+         zigIndex++, direction = !direction)
+      {
+        if (direction == ZigZag.ZIGZAG_FORWARD)
+          {
+            while (x >= 0 && y != matrix.length)
+              {
+                if (x == matrix.length)
+                  {
+                    x--;
+                    y++;
+                  }
+                buffer[index] = matrix[x][y];
+                y++;
+                x--;
+                index++;
+              }
+            x++;
+          }
+        else
+          {
+            while (y >= 0 && x != matrix.length)
+              {
+                if (y == matrix.length)
+                  {
+                    y--;
+                    x++;
+                  }
+                buffer[index] = matrix[x][y];
+                y--;
+                x++;
+                index++;
+              }
+            y++;
+          }
+      }
+    return (buffer);
+  }
+
+  /**
+   * Encodes a matrix of equal width and height to a double array
+   * 
+   * @param matrix
+   *
+   * @return
+   */
+  public static double[] encode(double[][] matrix)
+  {
+    double[] buffer = new double[matrix.length * matrix.length];
+    boolean direction = ZigZag.ZIGZAG_FORWARD;
+    int x = 0, y = 0, index = 0;
+    for (int zigIndex = 0; zigIndex < (matrix.length * 2 - 1);
+         zigIndex++, direction = !direction)
+      {
+        if (direction == ZigZag.ZIGZAG_FORWARD)
+          {
+            while (x >= 0 && y != matrix.length)
+              {
+                if (x == matrix.length)
+                  {
+                    x--;
+                    y++;
+                  }
+                buffer[index] = matrix[x][y];
+                y++;
+                x--;
+                index++;
+              }
+            x++;
+          }
+        else
+          {
+            while (y >= 0 && x != matrix.length)
+              {
+                if (y == matrix.length)
+                  {
+                    y--;
+                    x++;
+                  }
+                buffer[index] = matrix[x][y];
+                y--;
+                x++;
+                index++;
+              }
+            y++;
+          }
+      }
+    return (buffer);
+  }
+
+  /**
+   * Encodes a matrix of equal width and height to a float array
+   * 
+   * @param matrix
+   *
+   * @return
+   */
+  public static float[] encode(float[][] matrix)
+  {
+    float[] buffer = new float[matrix.length * matrix.length];
+    boolean direction = ZigZag.ZIGZAG_FORWARD;
+    int x = 0, y = 0, index = 0;
+    for (int zigIndex = 0; zigIndex < (matrix.length * 2 - 1);
+         zigIndex++, direction = !direction)
+      {
+        if (direction == ZigZag.ZIGZAG_FORWARD)
+          {
+            while (x >= 0 && y != matrix.length)
+              {
+                if (x == matrix.length)
+                  {
+                    x--;
+                    y++;
+                  }
+                buffer[index] = matrix[x][y];
+                y++;
+                x--;
+                index++;
+              }
+            x++;
+          }
+        else
+          {
+            while (y >= 0 && x != matrix.length)
+              {
+                if (y == matrix.length)
+                  {
+                    y--;
+                    x++;
+                  }
+                buffer[index] = matrix[x][y];
+                y--;
+                x++;
+                index++;
+              }
+            y++;
+          }
+      }
+    return (buffer);
+  }
+
+  /**
+   * Encodes a matrix of equal width and height to a float array
+   * 
+   * @param matrix
+   *
+   * @return
+   */
+  public static short[] encode(short[][] matrix)
+  {
+    short[] buffer = new short[matrix.length * matrix.length];
+    boolean direction = ZigZag.ZIGZAG_FORWARD;
+    int x = 0, y = 0, index = 0;
+    for (int zigIndex = 0; zigIndex < (matrix.length * 2 - 1);
+         zigIndex++, direction = !direction)
+      {
+        if (direction == ZigZag.ZIGZAG_FORWARD)
+          {
+            while (x >= 0 && y != matrix.length)
+              {
+                if (x == matrix.length)
+                  {
+                    x--;
+                    y++;
+                  }
+                buffer[index] = matrix[x][y];
+                y++;
+                x--;
+                index++;
+              }
+            x++;
+          }
+        else
+          {
+            while (y >= 0 && x != matrix.length)
+              {
+                if (y == matrix.length)
+                  {
+                    y--;
+                    x++;
+                  }
+                buffer[index] = matrix[x][y];
+                y--;
+                x++;
+                index++;
+              }
+            y++;
+          }
+      }
+    return (buffer);
+  }
+
+  /**
+   * Convert a double array into a matrix with the same amount of columns and
+   * rows with length sqrt(double array length)
+   * 
+   * @param data
+   *
+   * @return
+   */
+  public static double[][] decode(double[] data)
+  {
+    return decode(data, (int) Math.sqrt(data.length),
+                  (int) Math.sqrt(data.length));
+  }
+
+  /**
+   * Convert a byte array into a matrix with the same amount of columns and
+   * rows with length sqrt(double array length)
+   * 
+   * @param data
+   *
+   * @return
+   */
+  public static byte[][] decode(byte[] data)
+  {
+    return decode(data, (int) Math.sqrt(data.length),
+                  (int) Math.sqrt(data.length));
+  }
+
+  public static int[][] decode(int[] data)
+  {
+    return decode(data, (int) Math.sqrt(data.length),
+                  (int) Math.sqrt(data.length));
+  }
+
+  public static byte[][] decode(byte[] data, int width, int height)
+  {
+    byte[][] buffer = new byte[height][width];
+
+    for (int v = 0; v < height; v++)
+      for (int z = 0; z < width; z++)
+        buffer[v][z] = 11;
+
+    boolean dir = ZigZag.ZIGZAG_FORWARD;
+    int xindex = 0, yindex = 0, dataindex = 0;
+
+    while (xindex < width && yindex < height && dataindex < data.length)
+      {
+        buffer[yindex][xindex] = data[dataindex];
+        dataindex++;
+        
+        if (dir == ZigZag.ZIGZAG_FORWARD)
+          {
+            if (yindex == 0 || xindex == (width - 1))
+              {
+                dir = ZigZag.ZIGZAG_BACKWARD;
+                if (xindex == (width - 1))
+                  yindex++;
+                else
+                  xindex++;
+              }
+            else
+              {
+                yindex--;
+                xindex++;
+              }
+          }
+        else
+          { /* Backwards */
+            if (xindex == 0 || yindex == (height - 1))
+              {
+                dir = ZigZag.ZIGZAG_FORWARD;
+                if (yindex == (height - 1))
+                  xindex++;
+                else
+                  yindex++;
+              }
+            else
+              {
+                yindex++;
+                xindex--;
+              }
+          }
+      }
+    return (buffer);
+  }
+
+  public static double[][] decode(double[] data, int width, int height)
+  {
+    double[][] buffer = new double[height][width];
+
+    for (int v = 0; v < height; v++)
+      for (int z = 0; z < width; z++)
+        buffer[v][z] = 11;
+
+    boolean dir = ZigZag.ZIGZAG_FORWARD;
+    int xindex = 0, yindex = 0, dataindex = 0;
+
+    while (xindex < width && yindex < height && dataindex < data.length)
+      {
+        buffer[yindex][xindex] = data[dataindex];
+        dataindex++;
+        System.err.println("Setting " + dataindex + " to row: " + yindex
+                           + " column: " + xindex + " yourval:"
+                           + (yindex*8+xindex));
+        if (dir == ZigZag.ZIGZAG_FORWARD)
+          {
+            if (yindex == 0 || xindex == (width - 1))
+              {
+                dir = ZigZag.ZIGZAG_BACKWARD;
+                if (xindex == (width - 1))
+                  yindex++;
+                else
+                  xindex++;
+              }
+            else
+              {
+                yindex--;
+                xindex++;
+              }
+          }
+        else
+          { /* Backwards */
+            if (xindex == 0 || yindex == (height - 1))
+              {
+                dir = ZigZag.ZIGZAG_FORWARD;
+                if (yindex == (height - 1))
+                  xindex++;
+                else
+                  yindex++;
+              }
+            else
+              {
+                yindex++;
+                xindex--;
+              }
+          }
+      }
+    return (buffer);
+  }
+
+  public static float[][] decode(float[] data, int width, int height)
+  {
+    float[][] buffer = new float[height][width];
+    
+    for (int v = 0; v < height; v++)
+      for (int z = 0; z < width; z++)
+        buffer[v][z] = 11;
+    
+    boolean dir = ZigZag.ZIGZAG_FORWARD;
+    int xindex = 0, yindex = 0, dataindex = 0;
+    
+    while (xindex < width && yindex < height && dataindex < data.length)
+      {
+        buffer[yindex][xindex] = data[dataindex];
+        dataindex++;
+        
+        if (dir == ZigZag.ZIGZAG_FORWARD)
+          {
+            if (yindex == 0 || xindex == (width - 1))
+              {
+                dir = ZigZag.ZIGZAG_BACKWARD;
+                if (xindex == (width - 1))
+                  yindex++;
+                else
+                  xindex++;
+              }
+            else
+              {
+                yindex--;
+                xindex++;
+              }
+          }
+        else
+          { /* Backwards */
+            if (xindex == 0 || yindex == (height - 1))
+              {
+                dir = ZigZag.ZIGZAG_FORWARD;
+                if (yindex == (height - 1))
+                  xindex++;
+                else
+                  yindex++;
+              }
+            else
+              {
+                yindex++;
+                xindex--;
+              }
+          }
+      }
+    return (buffer);
+  }
+
+  public static int[][] decode(int[] data, int width, int height)
+  {
+    int[][] buffer = new int[height][width];
+
+    for (int v = 0; v < height; v++)
+      for (int z = 0; z < width; z++)
+        buffer[v][z] = 11;
+
+    boolean dir = ZigZag.ZIGZAG_FORWARD;
+    int xindex = 0, yindex = 0, dataindex = 0;
+
+    while (xindex < width && yindex < height && dataindex < data.length)
+      {
+        buffer[yindex][xindex] = data[dataindex];
+        dataindex++;
+
+        if (dir == ZigZag.ZIGZAG_FORWARD)
+          {
+            if (yindex == 0 || xindex == (width - 1))
+              {
+                dir = ZigZag.ZIGZAG_BACKWARD;
+                if (xindex == (width - 1))
+                  yindex++;
+                else
+                  xindex++;
+              }
+            else
+              {
+                yindex--;
+                xindex++;
+              }
+          }
+        else
+          { /* Backwards */
+            if (xindex == 0 || yindex == (height - 1))
+              {
+                dir = ZigZag.ZIGZAG_FORWARD;
+                if (yindex == (height - 1))
+                  xindex++;
+                else
+                  yindex++;
+              }
+            else
+              {
+                yindex++;
+                xindex--;
+              }
+          }
+      }
+    return (buffer);
+  }
+
+  public static double[][] decode8x8_map(double input[])
+  {
+    double[][] output = new double[8][8];
+    for(int i=0; i < 64 ; i++)
+      output[ZIGZAG_8X8_MAP[i]/8][ZIGZAG_8X8_MAP[i]%8] = input[i];
+    return (output);
+  }
+
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGChunk.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGChunk.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGChunk.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGChunk.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,284 @@
+/* PNGChunk.java -- Generic PNG chunk
+   Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.png;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Class to load and validate a generic PNG chunk.
+ */
+public class PNGChunk
+{
+
+  /**
+   * CRC table and initialization code.
+   */
+  private static long[] crcTable;
+
+  static 
+   {
+     long c;
+     crcTable = new long[256];
+   
+     for(int i = 0; i < 256; i++)
+       {
+	 c = i;
+	 for(int j = 0; j < 8; j++) 
+	   if( (c & 1) == 1 )
+	     c = 0xEDB88320L ^ (c >> 1);
+	   else
+	     c = c >> 1;
+	 crcTable[i] = c;
+       }
+   }
+
+  /**
+   * (recognized) PNG chunk types.
+   */
+  public static final int TYPE_HEADER = 0x49484452; // 'IHDR'
+  public static final int TYPE_PALETTE = 0x504c5445;// 'PLTE'
+  public static final int TYPE_DATA = 0x49444154;   // 'IDAT'
+  public static final int TYPE_TIME = 0x74494d45;   // 'tIME'
+  public static final int TYPE_END = 0x49454e44;    // 'IEND'
+  public static final int TYPE_PHYS = 0x70485973;   // 'pHYS'
+  public static final int TYPE_GAMMA = 0x67414d41;  // 'gAMA'
+  public static final int TYPE_PROFILE = 0x69434350;  // 'iCCP'
+
+  /**
+   * The chunk type - Represented in the file as 4 ASCII bytes,
+   */
+  private int type;
+
+  /**
+   * The chunk data
+   */
+  protected byte[] data;
+  
+  /**
+   * The chunk's crc
+   */
+  private int crc;
+
+  /**
+   * Constructor for reading a generic chunk.
+   */
+  protected PNGChunk( int type, byte[] data, int crc )
+  {
+    this.type = type;
+    this.data = data;
+    this.crc = crc;
+  }
+
+  /**
+   * Constructor for creating new chunks. 
+   * (only used by subclasses - creating a generic chunk is rather useless)
+   */
+  protected PNGChunk( int type )
+  {
+    this.type = type;
+  }
+
+  /**
+   * Loads a chunk from an InputStream. Does not perform validation,
+   * but will throw an IOException if the read fails.
+   * @param in - th einputstream to read from
+   * @param strict - if true, a PNGException is thrown on all invalid chunks,
+   * if false, only critical chunks will throw PNGExceptions.
+   */
+  public static PNGChunk readChunk(InputStream in, boolean strict) 
+    throws IOException, PNGException
+  {
+    byte data[] = new byte[4];
+    if( in.read( data ) != 4 )
+      throw new IOException("Could not read chunk length.");
+    int length = ((data[0] & 0xFF) << 24) | ((data[1] & 0xFF) << 16 ) | 
+      ((data[2] & 0xFF) << 8) | (data[3] & 0xFF);
+
+    if( in.read( data ) != 4 )
+      throw new IOException("Could not read chunk type.");
+    int type = ((data[0] & 0xFF) << 24) | ((data[1] & 0xFF) << 16 ) | 
+      ((data[2] & 0xFF) << 8) | (data[3] & 0xFF);
+
+    byte[] chkdata = new byte[ length ];
+    if( in.read( chkdata ) != length )
+      throw new IOException("Could not read chunk data.");
+    
+    if( in.read( data ) != 4 )
+      throw new IOException("Could not read chunk CRC.");
+    
+    int crc = ((data[0] & 0xFF) << 24) | ( (data[1] & 0xFF) << 16 ) | 
+      ((data[2] & 0xFF) << 8) | (data[3] & 0xFF);
+
+    if( strict )
+      return getChunk( type, chkdata, crc );
+    else
+      {
+	try
+	  {
+	    return getChunk( type, chkdata, crc );
+	  }
+	catch(PNGException pnge)
+	  {
+	    if( isEssentialChunk( type ) )
+	      throw pnge;
+	    return null;
+	  }
+      }
+  }
+
+  /**
+   * Returns a specialied object for a chunk, if we have one.
+   */
+  private static PNGChunk getChunk( int type, byte[] data, int crc )
+    throws PNGException
+  {
+    switch( type )
+      {
+      case TYPE_HEADER:
+	return new PNGHeader( type, data, crc );
+      case TYPE_DATA:
+	return new PNGData( type, data, crc );
+      case TYPE_PALETTE:
+	return new PNGPalette( type, data, crc );
+      case TYPE_TIME:
+	return new PNGTime( type, data, crc );
+      case TYPE_PHYS:
+	return new PNGPhys( type, data, crc );
+      case TYPE_GAMMA:
+	return new PNGGamma( type, data, crc );
+      case TYPE_PROFILE:
+	return new PNGICCProfile( type, data, crc );
+      default:
+	return new PNGChunk( type, data, crc );
+      }
+  }
+
+  /**
+   * Returns whether the chunk is essential or not
+   */
+  private static boolean isEssentialChunk( int type )
+  {
+    switch( type )
+      {
+      case TYPE_HEADER:
+      case TYPE_DATA:
+      case TYPE_PALETTE:
+      case TYPE_END:
+	return true;
+      default:
+	return false;
+      }
+  }
+
+  /**
+   * Validates the chunk
+   */
+  public boolean isValidChunk()
+  {
+    return (crc == calcCRC());
+  }
+
+  /**
+   * Returns the chunk type.
+   */
+  public int getType()
+  {
+    return type;
+  }
+
+  /**
+   * Writes a PNG chunk to an output stream, 
+   * performing the CRC calculation as well.
+   */
+  public void writeChunk(OutputStream out) throws IOException
+  {
+    out.write( getInt(data.length) );
+    out.write( getInt(type) );
+    out.write( data );
+    out.write( getInt(calcCRC()) );
+  }
+
+  /**
+   * Return whether the chunk contains any data.
+   */
+  public boolean isEmpty()
+  {
+    return ( data.length == 0 );
+  }
+
+  /**
+   * Convenience method. Cast an int to four bytes (big endian).
+   * (Now why doesn't java have a simple way of doing this?)
+   */
+  public static byte[] getInt(int intValue)
+  {
+    long i = (intValue & 0xFFFFFFFFL);
+    byte[] b = new byte[4];
+    b[0] = (byte)((i & 0xFF000000L) >> 24);
+    b[1] = (byte)((i & 0x00FF0000L) >> 16);
+    b[2] = (byte)((i & 0x0000FF00L) >> 8);
+    b[3] = (byte)(i & 0x000000FFL);
+    return b;
+  }
+
+  /**
+   * Calculates this chunk's CRC value.
+   */
+  private int calcCRC()
+  {
+    long c = 0xFFFFFFFFL;
+    byte[] t = getInt( type );
+    for(int i = 0; i < 4; i++)
+      c = crcTable[ (int)((c ^ t[i]) & 0xFF) ] ^ (c >> 8);
+      
+    for(int i = 0; i < data.length; i++)
+      c = crcTable[ (int)((c ^ data[i]) & 0xFF) ] ^ (c >> 8);
+
+    return (int)(c ^ 0xFFFFFFFFL);
+  }
+
+  public String toString()
+  {
+    return "PNG Chunk. Type: " + new String( getInt(type) ) + " , CRC: " + 
+      crc + " , calculated CRC: "+calcCRC();
+  }
+   
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGData.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGData.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGData.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGData.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,104 @@
+/* PNGData.java -- PNG IDAT chunk.
+   Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.png;
+
+import java.util.zip.Inflater;
+import java.util.zip.Deflater;
+
+/**
+ * A PNG IDAT (data) chunk.
+ */
+public class PNGData extends PNGChunk 
+{ 
+  private int offset;
+
+  protected PNGData( int type, byte[] data, int crc )
+  {
+    super( type, data, crc );
+  }
+
+  protected PNGData( int chunkSize )
+  {
+    super( PNGChunk.TYPE_DATA );
+    data = new byte[ chunkSize ];
+    offset = 0;
+  }
+
+  /**
+   * Deflates the available data in def to the chunk.
+   *
+   * @return true if the chunk is filled and no more data can be written,
+   * false otherwise.
+   */
+  public void deflateToChunk( Deflater def ) 
+  {
+    offset += def.deflate( data, offset, data.length - offset );
+  }
+
+  /**
+   * Returns true if the chunk is filled.
+   */
+  public boolean chunkFull()
+  {
+    return (offset >= data.length);
+  }
+
+  /**
+   * Shrink the chunk to offset size, used for the last chunk in a stream
+   * (no trailing data!) 
+   */
+  public void shrink()
+  {
+    byte[] newData = new byte[ offset ];
+    System.arraycopy( data, 0, newData, 0, offset );
+    data = newData;
+  }
+
+  /**
+   * Feeds the data in the chunk to a ZIP inflater object.
+   */
+  public void feedToInflater( Inflater inf ) 
+  {
+    inf.setInput( data );
+  }
+
+  public String toString()
+  {
+    return "PNG Data chunk. Length = "+data.length;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGDecoder.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGDecoder.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGDecoder.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGDecoder.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,331 @@
+/* PNGDecoder.java
+   Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.png;
+
+import java.util.zip.Inflater;
+import java.util.zip.DataFormatException;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.ComponentSampleModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferUShort;
+import java.awt.image.IndexColorModel;
+import java.awt.image.MultiPixelPackedSampleModel;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.awt.image.WritableRaster;
+import java.awt.color.ColorSpace;
+
+public class PNGDecoder
+{
+  private PNGHeader header;
+  private byte[] raster;
+  private byte[] scanline, lastScanline;
+  private byte[] filterType;
+  private int offset, length;
+  private int currentScanline;
+  private final int stride;
+  private Inflater inflater;
+  private boolean readFilter;
+  private int bpp; // bytes per pixel
+
+  /**
+   * Constructs a filter object for
+   */
+  public PNGDecoder(PNGHeader header)
+  {
+    this.header = header;
+    offset = 0;
+    inflater = new Inflater();
+    stride = header.getScanlineStride();
+    length = stride * header.getHeight();
+
+    // Allocate the output raster
+    raster = new byte[ length ];
+    scanline = new byte[ stride ];
+    lastScanline = new byte[ stride ];
+    currentScanline = 0;
+    readFilter = true;
+    bpp = header.bytesPerPixel();
+    filterType = new byte[1];
+    inflater = new Inflater();
+  }
+
+  private int getBytes( byte[] buf, int offset ) throws PNGException
+  {
+    try
+      {
+	return inflater.inflate( buf, offset, buf.length - offset);
+      }
+    catch(DataFormatException dfe)
+      {
+	throw new PNGException("Error inflating data.");
+      }
+  }
+
+  /**
+   * Decodes a data chunk.
+   */
+  public void addData( PNGData chunk ) throws PNGException
+  {
+    int n = 0;
+    if( isFinished() )
+      return;
+    chunk.feedToInflater( inflater );
+    do
+      {
+	if( readFilter )
+	  if( getBytes( filterType, 0 ) < 1 )
+	    return;
+
+	n = getBytes( scanline, offset );
+
+	if( offset + n < stride )
+	  {
+	    offset += n;
+	    readFilter = false;
+	  }
+	else
+	  {
+	    scanline = PNGFilter.unFilterScanline( filterType[0], scanline,
+						   lastScanline, bpp );
+	    System.arraycopy( scanline, 0,
+			      raster, currentScanline * stride, stride );
+	    lastScanline = scanline;
+	    scanline = new byte[scanline.length];
+	    currentScanline++;
+	    readFilter = true;
+	    offset = 0;
+	  }
+      }
+    while( n > 0 && currentScanline < header.getHeight() );
+  }
+
+  /**
+   * Parse the appropriate color type and create an AWT raster for it.
+   * @param raster - the file header.
+   */
+  public WritableRaster getRaster( PNGHeader header )
+  {
+    SampleModel sm = null;
+    DataBuffer db = null;
+    int t;
+    int width = header.getWidth();
+    int height = header.getHeight();
+    int depth = header.getDepth();
+
+    switch( header.getColorType() )
+      {
+      case PNGHeader.GRAYSCALE_WITH_ALPHA:
+	if( depth == 8 )
+	  {
+	    t = DataBuffer.TYPE_BYTE;
+	    db = getByteBuffer();
+	  }
+	else
+	  { 
+	    t = DataBuffer.TYPE_USHORT;
+	    db = getShortBuffer();
+	  }
+	sm = new ComponentSampleModel(t, width, height, 2, width * 2,
+				      new int[]{0, 1});
+	break;
+
+      case PNGHeader.GRAYSCALE:
+	switch( depth )
+	  {
+	  case 16:
+	    sm = new ComponentSampleModel(DataBuffer.TYPE_USHORT, 
+					  width, height, 1, width,
+					  new int[]{ 0 });
+	    db = getShortBuffer();
+	    break;
+	    
+	  case 8:
+	    sm = new ComponentSampleModel(DataBuffer.TYPE_BYTE, 
+					  width, height, 1, width,
+					  new int[]{ 0 });
+	    db = getByteBuffer();
+	    break;
+	    
+	  default:
+	    sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, 
+						 width, height, depth);
+	    db = getByteBuffer();
+	    break;
+	  }
+	break;
+
+      case PNGHeader.RGB:
+	if( depth == 8 )
+	  {
+	    t = DataBuffer.TYPE_BYTE;
+	    db = getByteBuffer();
+	  }
+	else
+	  { 
+	    t = DataBuffer.TYPE_USHORT;
+	    db = getShortBuffer();
+	  }
+	sm = new ComponentSampleModel(t, width, height, 3, 3 * width,
+				      new int[]{0, 1, 2});
+	break;
+
+      case PNGHeader.RGB_WITH_ALPHA:
+	if( depth == 8 )
+	  {
+	    t = DataBuffer.TYPE_BYTE;
+	    db = getByteBuffer();
+	  }
+	else
+	  { 
+	    t = DataBuffer.TYPE_USHORT;
+	    db = getShortBuffer();
+	  }
+	
+	sm = new ComponentSampleModel(t, width, height, 4, width * 4,
+				      new int[]{0, 1, 2, 3});
+	break;
+	
+      case PNGHeader.INDEXED:
+	if( depth == 8 )
+	  sm = new SinglePixelPackedSampleModel(DataBuffer.TYPE_BYTE, 
+						width, height, 
+						new int[] {0xFF});
+	else
+	  sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, 
+					       width, height, depth);
+	db = getByteBuffer();
+	break;
+      }
+
+    return Raster.createWritableRaster(sm, db, null);
+  }
+
+  /**
+   * Wrap the raster with a DataBufferUShort,
+   * conversion is big-endian (PNG native).
+   */
+  private DataBuffer getShortBuffer()
+  {
+    short[] data = new short[(raster.length >> 1)];
+    for( int i = 0; i < data.length; i++ )
+      data[i] = (short)(((raster[i * 2] & 0xFF) << 8) | 
+			(raster[i * 2 + 1] & 0xFF));
+    return new DataBufferUShort( data, data.length );
+  }
+
+  /**
+   * Wrap the raster with a DataBufferByte
+   */
+  private DataBuffer getByteBuffer()
+  {
+    return new DataBufferByte( raster, raster.length );
+  }
+
+  public ColorModel getColorModel( ColorSpace cs, 
+				   int colorType, int depth )
+  {
+    int[] bits;
+    boolean hasAlpha = false;
+    int transferType;
+
+    switch( colorType )
+      {
+      case PNGHeader.GRAYSCALE_WITH_ALPHA:
+	if( cs == null )
+	  cs = ColorSpace.getInstance( ColorSpace.CS_GRAY );
+	hasAlpha = true;
+	bits = new int[]{ depth, depth };
+	break;
+	
+      case PNGHeader.RGB:
+	bits = new int[]{ depth, depth, depth };
+	break;
+
+      case PNGHeader.RGB_WITH_ALPHA:
+	hasAlpha = true;
+	bits = new int[]{ depth, depth, depth, depth };
+	break;
+
+      case PNGHeader.GRAYSCALE:
+	if( depth < 8 )
+	  return grayPalette( depth );
+
+	if( cs == null )
+	  cs = ColorSpace.getInstance( ColorSpace.CS_GRAY );
+	bits = new int[]{ depth };
+	break;
+
+      default:
+      case PNGHeader.INDEXED:
+	return null; // Handled by the palette chunk.
+      }
+
+    if( cs == null )
+      cs = ColorSpace.getInstance( ColorSpace.CS_sRGB );
+
+
+    return new ComponentColorModel(cs, bits, hasAlpha, false, 
+				   (hasAlpha ? 
+				    ComponentColorModel.TRANSLUCENT : 
+				    ComponentColorModel.OPAQUE), 
+				   ((depth == 16) ? DataBuffer.TYPE_USHORT : 
+				    DataBuffer.TYPE_BYTE));
+  }
+
+  private IndexColorModel grayPalette(int depth)
+  { 
+    byte[] c = new byte[ (1 << depth) ];
+    for(int i = 0; i < c.length; i++)
+      c[i] = (byte)(255.0 * (((double)i) / ((double)c.length - 1.0)));
+    return new IndexColorModel(8, c.length, c, c, c);
+  }
+
+  public byte[] getRaster()
+  {
+    return raster;
+  }
+
+  public boolean isFinished()
+  {
+    return currentScanline >= header.getHeight();
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGEncoder.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGEncoder.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGEncoder.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGEncoder.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,235 @@
+/* PNGEncoder.java --
+   Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.png;
+
+import java.util.Vector;
+import java.util.zip.Deflater;
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_Profile;
+import java.awt.color.ICC_ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferUShort;
+import java.awt.image.IndexColorModel;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+public class PNGEncoder 
+{
+  /**
+   * The default data chunk size. 8 kb.
+   */
+  private static final int defaultChunkSize = 8192;
+
+  private PNGHeader header;
+  private PNGPalette palette;
+  private int stride, bpp;
+  private byte[] rawData;
+  private PNGICCProfile profile;
+
+  public PNGEncoder( BufferedImage bi ) throws PNGException
+  {
+    ColorModel c = bi.getColorModel();
+    int width = bi.getWidth(); 
+    int height = bi.getHeight();
+    int depth = 0;
+    int colorType;
+    boolean interlace = false;
+
+    if( c instanceof IndexColorModel )
+      {
+	colorType = PNGHeader.INDEXED;
+	int n = ((IndexColorModel)c).getMapSize();
+	if( n <= 2 )
+	  depth = 1;
+	else if( n <= 4 )
+	  depth = 2;
+	else if( n <= 16 )
+	  depth = 4;
+	else if( n <= 256 )
+	  depth = 8;
+	else
+	  throw new PNGException("Depth must be <= 8 bits for indexed color.");
+	palette = new PNGPalette( ((IndexColorModel)c) );
+      }
+    else
+      { 
+	ColorSpace cs = c.getColorSpace();
+	ColorSpace grayCS = ColorSpace.getInstance( ColorSpace.CS_GRAY );
+	if( cs == grayCS || bi.getType() == BufferedImage.TYPE_BYTE_GRAY 
+	    || bi.getType() == BufferedImage.TYPE_USHORT_GRAY )
+	  colorType = c.hasAlpha() ? PNGHeader.GRAYSCALE_WITH_ALPHA : 
+	    PNGHeader.GRAYSCALE;
+	else
+	  colorType = c.hasAlpha() ? PNGHeader.RGB_WITH_ALPHA : PNGHeader.RGB;
+	// Figure out the depth
+	int[] bits = c.getComponentSize();
+	depth = bits[0];
+	for(int i = 1; i < bits.length; i++ )
+	  if( bits[i] > depth ) depth = bits[i];
+	if( (cs != grayCS && !cs.isCS_sRGB()) && cs instanceof ICC_ColorSpace )
+	  profile = new PNGICCProfile( ((ICC_ColorSpace)cs).getProfile() );
+      }
+
+    header = new PNGHeader(width, height, depth, colorType, interlace);
+
+    stride = header.getScanlineStride(); // scanline stride 
+    bpp = header.bytesPerPixel(); // bytes per pixel
+    getRawData( bi );
+  }
+
+  /**
+   * Returns the generated header.
+   */ 
+  public PNGHeader getHeader()
+  {
+    return header;
+  }
+
+  /**
+   * Returns the generated palette.
+   */ 
+  public PNGPalette getPalette()
+  {
+    return palette;
+  }
+
+  /**
+   * Returns the associated ICC profile, if any.
+   */ 
+  public PNGICCProfile getProfile()
+  {
+    return profile;
+  }
+
+  /**
+   * Encodes the raster and returns a Vector of PNGData chunks.
+   */
+  public Vector encodeImage()
+  {
+    Deflater deflater = new Deflater(); // The deflater
+    boolean useFilter = PNGFilter.useFilter( header );
+    byte[] lastScanline = new byte[ stride ];
+
+    byte[] data = new byte[ rawData.length + header.getHeight() ];
+
+    byte filterByte = PNGFilter.FILTER_NONE;
+    for( int i = 0; i < header.getHeight(); i++)
+      {
+	byte[] scanline = new byte[ stride ]; 
+	System.arraycopy(rawData, (i * stride), scanline, 0, stride);
+	if( useFilter && i > 0)
+	  filterByte = PNGFilter.chooseFilter( scanline, lastScanline, bpp);
+	
+	byte[] filtered = PNGFilter.filterScanline( filterByte, scanline, 
+						    lastScanline, bpp );
+	data[i * (stride + 1)] = filterByte;
+	System.arraycopy(filtered, 0, data, 1 + (i * (stride + 1)), stride);
+
+	lastScanline = scanline;
+      }
+
+    deflater.setInput( data ); 
+    deflater.finish();
+
+    PNGData chunk;
+    Vector chunks = new Vector();
+    do
+      {
+	chunk = new PNGData( defaultChunkSize );
+	chunk.deflateToChunk( deflater );
+	chunks.add( chunk );
+      }
+    while( chunk.chunkFull() );
+    chunk.shrink(); // Shrink the last chunk.
+    return chunks;
+  }
+
+  /**
+   * Get the image's raw data.
+   * FIXME: This may need improving on.
+   */
+  private void getRawData( BufferedImage bi ) throws PNGException
+  {
+    WritableRaster raster = bi.getRaster();
+    rawData = new byte[ stride * header.getHeight() ];
+    if( header.isIndexed() )
+      {
+	DataBuffer db = raster.getDataBuffer();
+	if( !( db instanceof DataBufferByte ) )
+	  throw new PNGException("Unexpected DataBuffer for an IndexColorModel.");
+	byte[] data = ((DataBufferByte)db).getData();
+	for(int i = 0; i < header.getHeight(); i++ )
+	  System.arraycopy( data, i * stride, rawData, i * stride, stride );
+	return;
+      }
+
+    if( header.getDepth() == 16 )
+      {
+	DataBuffer db = raster.getDataBuffer();
+	if( !( db instanceof DataBufferUShort ) )
+	  throw new PNGException("Unexpected DataBuffer for 16-bit.");
+	short[] data = ((DataBufferUShort)db).getData();
+	for(int i = 0; i < header.getHeight(); i++ )
+	  for(int j = 0; j < ( stride >> 1); j++)
+	    {
+	      rawData[ j * 2 + i * stride ] = (byte)((data[j + i * (stride >> 1 )] & 0xFF00) >> 8);
+	      rawData[ j * 2 + i * stride + 1 ] = (byte)(data[j + i * (stride >> 1 )] & 0xFF);
+	    }
+	return;
+      }
+
+    int size = ( header.getColorType() == PNGHeader.RGB_WITH_ALPHA ) ? 4 : 3;
+    int width = header.getWidth();
+    int height = header.getHeight();
+    int[] pixels = bi.getRGB( 0, 0, width, height, null, 0, width );
+
+    for( int i = 0; i < width * height; i++ )
+      {
+	rawData[ i * size ] = (byte)((pixels[i] & 0xFF0000) >> 16);
+	rawData[ i * size + 1 ] = (byte)((pixels[i] & 0xFF00) >> 8);
+	rawData[ i * size + 2 ] = (byte)(pixels[i] & 0xFF);
+      }
+
+    if( size == 4 )
+      for( int i = 0; i < width * height; i++ )
+	rawData[ i * size + 3 ] = (byte)((pixels[i] & 0xFF000000) >> 24);
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGException.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGException.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGException.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGException.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,48 @@
+/* PNGException.java -- 
+   Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.png;
+
+import java.io.IOException;
+
+public class PNGException extends IOException 
+{
+  public PNGException(String msg)
+  {
+    super( msg );
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGFile.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGFile.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGFile.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGFile.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,258 @@
+/* PNGFile.java -- High-level representation of a PNG file.
+   Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.png;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.util.Vector;
+import java.awt.image.BufferedImage;
+import java.awt.image.WritableRaster;
+import java.awt.image.ColorModel;
+import java.awt.image.IndexColorModel;
+import java.awt.color.ColorSpace;
+
+public class PNGFile 
+{
+  /**
+   * The PNG file signature.
+   */
+  private static final byte[] signature = new byte[]
+  { (byte)137, 80, 78, 71, 13, 10, 26, 10 };
+
+  /**
+   * The end chunk in raw form, no need for anything fancy here, it's just
+   * 0 bytes of length, the "IEND" tag and its CRC.
+   */
+  private static final byte[] endChunk = new byte[]
+  { 0, 0, 0, 0, (byte)0x49, (byte)0x45, (byte)0x4E, (byte)0x44, 
+    (byte)0xAE, (byte)0x42, (byte)0x60, (byte)0x82 };
+
+  /**
+   * The loaded data.
+   */
+  private Vector chunks;
+
+  /**
+   * The Header chunk
+   */
+  private PNGHeader header;
+
+  /**
+   * Whether this file has a palette chunk or not.
+   */
+  private boolean hasPalette;
+
+  /**
+   * Image width and height.
+   */
+  private int width, height;
+
+  /**
+   * The decoder, if any.
+   */
+  private PNGDecoder decoder;
+
+  /**
+   * The encoder, if any. (Either this or the above must exist).
+   */
+  private PNGEncoder encoder;
+  
+  /**
+   * The source of this PNG (if encoding)
+   */
+  private BufferedImage sourceImage;
+
+  /**
+   * Creates a PNGFile object from an InputStream.
+   */
+  public PNGFile(InputStream in) throws IOException, PNGException
+  {
+    PNGChunk chunk;
+    byte[] fileHdr = new byte[8];
+    chunks = new Vector(); 
+    hasPalette = false;
+
+    if( in.read( fileHdr ) != 8 )
+      throw new IOException("Could not read file header.");
+    if( !validateHeader( fileHdr ) )
+      throw new PNGException("Invalid file header. Not a PNG file.");
+
+    chunk = PNGChunk.readChunk( in, false );
+    if( !(chunk instanceof PNGHeader) )
+      throw new PNGException("First chunk not a header chunk.");
+    header = (PNGHeader)chunk;
+    if( !header.isValidChunk() )
+      throw new PNGException("First chunk not a valid header.");
+    System.out.println(header);
+
+    decoder = new PNGDecoder( header );
+    // Read chunks.
+    do
+      {
+	chunk = PNGChunk.readChunk( in, false );
+	/*
+	 * We could exit here or output some kind of warning.
+	 * But in the meantime, we'll just silently drop invalid chunks.
+	 */
+	if( chunk.isValidChunk() )
+	  {
+	    if( chunk instanceof PNGData )
+	      decoder.addData( (PNGData)chunk );
+	    else // Silently ignore multiple headers, and use only the first.
+	      if( chunk.getType() != PNGChunk.TYPE_END )
+		{
+		  chunks.add( chunk ); 
+		  hasPalette |= ( chunk instanceof PNGPalette );
+		}
+	  }
+	else
+	  System.out.println("WARNING: Invalid chunk!");
+      }
+    while( chunk.getType() != PNGChunk.TYPE_END );
+
+    if( header.isIndexed() && !hasPalette )
+      throw new PNGException("File is indexed color and has no palette.");
+
+    width = header.getWidth();
+    height = header.getHeight();
+  }
+
+  /**
+   * Creates a PNG file from an existing BufferedImage.
+   */
+  public PNGFile(BufferedImage bi) throws PNGException
+  {
+    sourceImage = bi;
+    width = bi.getWidth();
+    height = bi.getHeight();
+    chunks = new Vector();
+    encoder = new PNGEncoder( bi );
+    header = encoder.getHeader();
+    if( header.isIndexed() ) 
+      chunks.add( encoder.getPalette() );
+
+    // Do the compression and put the data chunks in the list.
+    chunks.addAll( encoder.encodeImage() );
+  }
+
+  /**
+   * Writes a PNG file to an OutputStream
+   */
+  public void writePNG(OutputStream out) throws IOException
+  {
+    out.write( signature ); // write the signature.
+    header.writeChunk( out );
+    for( int i = 0; i < chunks.size(); i++ )
+      {
+	PNGChunk chunk = ((PNGChunk)chunks.elementAt(i));
+	chunk.writeChunk( out );
+      }
+    out.write( endChunk );
+  }
+
+  /**
+   * Check 8 bytes to see if it's a valid PNG header.
+   */
+  private boolean validateHeader( byte[] hdr )
+  {
+    if( hdr.length != 8 )
+      return false;
+    for( int i = 0; i < 8; i++ )
+      if( signature[i] != hdr[i] )
+	return false;
+    return true;
+  }
+
+  /**
+   * Return a loaded image as a bufferedimage.
+   */
+  public BufferedImage getBufferedImage()
+  {
+    if( decoder == null )
+      return sourceImage;
+
+    WritableRaster r = decoder.getRaster( header );
+    ColorModel cm;
+    if( header.isIndexed() )
+      {
+	PNGPalette pngp = getPalette();
+	cm = pngp.getPalette( getColorSpace() );
+      }
+    else
+      cm = decoder.getColorModel( getColorSpace(), 
+				  header.getColorType(), 
+				  header.getDepth() );
+    
+    return new BufferedImage(cm, r, false, null);
+  } 
+
+  /**
+   * Find the palette chunk and return it
+   */
+  private PNGPalette getPalette()
+  {
+    for(int i = 0; i < chunks.size(); i++ )
+      if( chunks.elementAt(i) instanceof PNGPalette )
+	return ((PNGPalette)chunks.elementAt(i));
+    return null;
+  }
+
+  /**
+   * Return the Color space to use, first preference is ICC profile, then
+   * a gamma chunk, or returns null for the default sRGB.
+   */
+  private ColorSpace getColorSpace()
+  {
+    PNGICCProfile icc = null;
+    PNGGamma gamma = null;
+    for(int i = 0; i < chunks.size(); i++ )
+      {
+	if( chunks.elementAt(i) instanceof PNGICCProfile )
+	  icc = ((PNGICCProfile)chunks.elementAt(i));
+	else if(chunks.elementAt(i) instanceof PNGGamma )
+	  gamma = ((PNGGamma)chunks.elementAt(i));
+      }
+
+    if( icc != null )
+      return icc.getColorSpace();
+//     if( gamma != null && !header.isGrayscale())
+//       return gamma.getColorSpace( header.isGrayscale() );
+    return null;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGFilter.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGFilter.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGFilter.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGFilter.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,237 @@
+/* PNGFilter.java -- PNG image filters.
+   Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.png;
+
+/**
+ * A utility class of static methods implementing the PNG filtering algorithms.
+ */
+public class PNGFilter
+{
+
+  public static final byte FILTER_NONE = 0;
+  public static final byte FILTER_SUB = 1;
+  public static final byte FILTER_UP = 2;
+  public static final byte FILTER_AVERAGE = 3;
+  public static final byte FILTER_PAETH = 4;
+
+  /**
+   * Return whether a filter should be used or FILTER_NONE,
+   * following the recommendations in the PNG spec.
+   */
+  public static boolean useFilter( PNGHeader header )
+  {
+    switch( header.getColorType() )
+      {
+      case PNGHeader.INDEXED:
+	return false;
+	
+      case PNGHeader.GRAYSCALE:
+      case PNGHeader.RGB:
+	if( header.bytesPerPixel() <= 1 )
+	  return false;
+      case PNGHeader.GRAYSCALE_WITH_ALPHA:
+      case PNGHeader.RGB_WITH_ALPHA:
+      default:
+	return true;
+      }
+  }
+
+  /**
+   * Heuristic for adaptively choosing a filter, following the scheme
+   * suggested in the PNG spec.
+   * @return a fiter type.
+   */
+  public static byte chooseFilter( byte[] scanline, byte[] lastScanline, 
+				  int bpp)
+    
+  {
+    long[] values = new long[5];
+    int idx = 0;
+    for( int i = 0; i < 5; i++ )
+      {
+	byte[] filtered = filterScanline((byte)i, scanline, lastScanline, bpp);
+	values[i] = 0;
+	for(int j = 0; j < filtered.length; j++ )
+	  values[i] += (int)(filtered[j] & 0xFF);
+	if( values[ idx ] > values[i] )
+	  idx = i;
+      }
+    return (byte)idx;
+  }
+
+  /**
+   * Filter a scanline.
+   */
+  public static byte[] filterScanline( byte filtertype, byte[] scanline, 
+				       byte[] lastScanline, int bpp)
+  {
+    int stride = scanline.length;
+    byte[] out = new byte[ stride ];
+    switch( filtertype )
+      {
+      case FILTER_SUB:
+	for( int i = 0; i < bpp; i++)
+	  out[ i ] = scanline[ i ];
+	
+	for( int i = bpp; i < stride; i++ )
+	  out[i] = (byte)(scanline[ i ] - 
+			  scanline[ i - bpp ]);
+	break;
+
+      case FILTER_UP:
+	for( int i = 0; i < stride; i++ )
+	  out[ i ] = (byte)(scanline[ i ] - lastScanline[ i ]);
+	break;
+
+      case FILTER_AVERAGE:
+	for( int i = 0; i < bpp; i++)
+	  out[ i ] = (byte)((scanline[ i ] & 0xFF) - ((lastScanline[ i ] & 0xFF) >> 1));
+	for( int i = bpp; i < stride; i++ )
+	  out[ i ] = (byte)((scanline[ i ] & 0xFF) - 
+			    (((scanline[ i - bpp ] & 0xFF) + 
+			      (lastScanline[ i ] & 0xFF)) >> 1));
+	break;
+
+      case FILTER_PAETH:
+	for( int i = 0; i < stride; i++ )
+	  {
+	    int x;
+	    {
+	      int a, b, c;
+	      if( i >= bpp )
+		{
+		  a = (scanline[ i - bpp ] & 0xFF); // left
+		  c = (lastScanline[ i - bpp ] & 0xFF); // upper-left
+		}
+	      else
+		a = c = 0;
+	      b = (lastScanline[ i ] & 0xFF); // up
+	      
+	      int p = (a + b - c);        // initial estimate
+	      // distances to a, b, c
+	      int pa = (p > a) ? p - a : a - p; 
+	      int pb = (p > b) ? p - b : b - p; 
+	      int pc = (p > c) ? p - c : c - p; 
+	      // return nearest of a,b,c,
+	      // breaking ties in order a,b,c.
+	      if( pa <= pb && pa <= pc ) x = a;
+	      else { if( pb <= pc ) x = b;
+		else x = c;
+	      }
+	    }
+	    out[ i ] = (byte)(scanline[ i ] - x);
+	  }
+	break;
+      default:
+      case FILTER_NONE:
+	return scanline;
+      }
+    return out;
+  }
+
+  /**
+   * Unfilter a scanline.
+   */
+  public static byte[] unFilterScanline( int filtertype, byte[] scanline, 
+					 byte[] lastScanline, int bpp)
+  {
+    int stride = scanline.length;
+    byte[] out = new byte[ stride ];
+    switch( filtertype )
+      {
+
+      case FILTER_NONE:
+	System.arraycopy( scanline, 0, out, 0, stride );
+	break;
+	
+      case FILTER_SUB:
+	for( int i = 0; i < bpp; i++)
+	  out[ i ] = scanline[ i ];
+	
+	for( int i = bpp; i < stride; i++ )
+	  out[ i ] = (byte)(scanline[ i ] + 
+			    out[ i - bpp ]);
+	break;
+
+      case FILTER_UP:
+	for( int i = 0; i < stride; i++ )
+	  out[ i ] = (byte)(scanline[ i ] + lastScanline[ i ]);
+	break;
+
+      case FILTER_AVERAGE:
+	for( int i = 0; i < bpp; i++)
+	  out[ i ] = (byte)((scanline[ i ] & 0xFF) + ((lastScanline[ i ] & 0xFF) >> 1));
+	for( int i = bpp; i < stride; i++ )
+	  out[ i ] = (byte)((scanline[ i ] & 0xFF) + 
+			    (((out[ i - bpp ] & 0xFF) + (lastScanline[ i ] & 0xFF)) >> 1));
+	break;
+
+      case FILTER_PAETH:
+	for( int i = 0; i < stride; i++ )
+	  {
+	    int x;
+	    {
+	      int a, b, c;
+	      if( i >= bpp )
+		{
+		  a = (out[ i - bpp ] & 0xFF); // left
+		  c = (lastScanline[ i - bpp ] & 0xFF); // upper-left
+		}
+	      else
+		a = c = 0;
+	      b = (lastScanline[ i ] & 0xFF); // up
+	      
+	      int p = (a + b - c);        // initial estimate
+	      // distances to a, b, c
+	      int pa = (p > a) ? p - a : a - p; 
+	      int pb = (p > b) ? p - b : b - p; 
+	      int pc = (p > c) ? p - c : c - p; 
+	      // return nearest of a,b,c,
+	      // breaking ties in order a,b,c.
+	      if( pa <= pb && pa <= pc ) x = a;
+	      else { if( pb <= pc ) x = b;
+		else x = c;
+	      }
+	    }
+	    out[ i ] = (byte)(scanline[ i ] + x);
+	  }
+	break;
+      }
+    return out;
+  }
+}
\ No newline at end of file

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGGamma.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGGamma.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGGamma.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGGamma.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,89 @@
+/* PNGGamma.java -- GAMA chunk.
+   Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.png;
+
+import java.awt.color.ICC_ProfileGray;
+import java.awt.color.ICC_ProfileRGB;
+import java.awt.color.ICC_Profile;
+import java.awt.color.ICC_ColorSpace;
+import java.awt.color.ColorSpace;
+
+/**
+ * A PNG gAMA (gamma) chunk.
+ */
+public class PNGGamma extends PNGChunk 
+{ 
+  private double gamma;
+
+  protected PNGGamma( int type, byte[] data, int crc ) throws PNGException
+  {
+    super( type, data, crc );
+    if( data.length < 4 )
+      throw new PNGException("Unexpectedly short time chunk. ("+data.length+" bytes)");
+    long g = ((data[0] & 0xFF) << 24) | ( (data[1] & 0xFF) << 16 ) | 
+      ((data[2] & 0xFF) << 8) | (data[3] & 0xFF);
+    gamma = (double)g;
+    gamma = 100000.0/gamma; 
+  }
+
+  public PNGGamma( double g )
+  {
+    super( TYPE_GAMMA );
+    data = new byte[ 4 ];
+    gamma = g;
+    long tmp = (long)(100000.0/gamma);
+    data[0] = (byte)((tmp & 0xFF000000) >> 24);
+    data[1] = (byte)((tmp & 0xFF0000) >> 16);
+    data[2] = (byte)((tmp & 0xFF00) >> 8);
+    data[3] = (byte)(tmp & 0xFF);
+  }
+
+  /**
+   * Returns a ColorSpace object corresponding to this gamma value.
+   */
+  public ColorSpace getColorSpace(boolean grayscale)
+  {
+    // FIXME.
+    return null;
+  }
+
+  public String toString()
+  {
+    return "PNG Gamma chunk, value: "+gamma;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGHeader.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGHeader.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGHeader.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGHeader.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,257 @@
+/* PNGHeader.java -- PNG Header
+   Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.png;
+
+/**
+ * A PNG Header chunk.
+ */
+public class PNGHeader extends PNGChunk 
+{ 
+  private int width, height, depth;
+  private int colorType, compression, filter, interlace;
+
+  /**
+   * The valid interlace types.
+   */
+  public static final int INTERLACE_NONE = 0;
+  public static final int INTERLACE_ADAM7 = 1;
+
+  /**
+   * The valid color types.
+   */
+  public static final int GRAYSCALE = 0;
+  public static final int RGB = 2;
+  public static final int INDEXED = 3;
+  public static final int GRAYSCALE_WITH_ALPHA = 4;
+  public static final int RGB_WITH_ALPHA = 6;
+
+  /**
+   * Parses a PNG Header chunk.
+   */
+  protected PNGHeader( int type, byte[] data, int crc ) throws PNGException
+  {
+    super( type, data, crc );
+    if( data.length < 13 )
+      throw new PNGException("Unexpectedly short header chunk. (" + data.length
+			     + " bytes)");
+
+    width = ((data[0] & 0xFF) << 24) | ( (data[1] & 0xFF) << 16 ) | 
+      ((data[2] & 0xFF) << 8) | (data[3] & 0xFF);
+    height = ((data[4] & 0xFF) << 24) | ( (data[5] & 0xFF) << 16 ) | 
+      ((data[6] & 0xFF) << 8) | (data[7] & 0xFF);
+    depth = (data[8] & 0xFF);
+    colorType = (data[9] & 0xFF);
+    compression = (data[10] & 0xFF);
+    filter = (data[11] & 0xFF);
+    interlace = (data[12] & 0xFF);
+  }
+
+  /**
+   * Create a PNG header chunk.
+   * Warning: This trusts that the parameters are valid.
+   */
+  public PNGHeader(int width, int height, int depth, 
+		   int colorType, boolean interlace)
+  {
+    super( TYPE_HEADER );
+    data = new byte[ 13 ];
+
+    this.width = width;
+    this.height = height;
+    this.depth = depth;
+    compression = filter = 0;
+    this.colorType = colorType;
+    this.interlace = interlace ? 1 : 0;
+
+    // Build the data chunk.
+    byte[] a = getInt( width );
+    byte[] b = getInt( height );
+    data[0] = a[0]; data[1] = a[1]; data[2] = a[2]; data[3] = a[3]; 
+    data[4] = b[0]; data[5] = b[1]; data[6] = b[2]; data[7] = b[3]; 
+    data[8] = (byte)depth;
+    data[9] = (byte)colorType;
+    data[10] = (byte)compression;
+    data[11] = (byte)filter;
+    data[12] = (byte)this.interlace;
+  }
+
+  /**
+   * Validates the header fields
+   */
+  public boolean isValidChunk()
+  {
+    if( !super.isValidChunk() )
+      return false;
+
+    // width and height must be nonzero
+    if( width == 0 || height == 0 )
+      return false;
+    // colorType can be 0,2,3,4,6
+    if( (colorType & 0xFFFFFFF8) != 0 || colorType == 5 || colorType == 1)
+      return false;
+    // Possible valid depths are 1,2,4,8,16
+    if( !((depth == 1) || (depth == 2) || (depth == 4) || 
+	(depth == 8) || (depth == 16)) )
+      return false;
+    if( colorType == INDEXED && depth == 16 )
+      return false;
+    if( ( colorType == RGB || colorType == GRAYSCALE_WITH_ALPHA || 
+	  colorType == RGB_WITH_ALPHA ) &&
+	depth < 8 )
+      return false;
+    // Only compression and filter methods zero are defined
+    if( compression != 0 || filter != 0 )
+      return false;
+    // Interlace methods, 0 and 1 are valid values.
+    if( (interlace & 0xFFFFFFFE) != 0 )
+      return false;
+
+    return true;
+  }
+
+  /**
+   * Returns <code>true</code> if this PNG is indexed-color
+   */
+  public boolean isIndexed()
+  {
+    return (colorType == INDEXED);
+  }
+
+  /**
+   * Returns <code>true</code> if this PNG is grayscale 
+   */
+  public boolean isGrayscale()
+  {
+    return ((colorType ==  GRAYSCALE) || (colorType == GRAYSCALE_WITH_ALPHA));
+  }
+
+  /**
+   * Returns the color type of the image.
+   */
+  public int getColorType()
+  {
+    return colorType;
+  }
+
+  /**
+   * Returns whether the image is interlaced or not.
+   */
+  public boolean isInterlaced()
+  {
+    return (interlace != 0);
+  }
+
+  /** 
+   * Returns the number of bytes per pixel.
+   */
+  public int bytesPerPixel()
+  {
+    switch( colorType )
+      {
+      case GRAYSCALE_WITH_ALPHA:
+	return ((depth * 2) >> 3);
+      case RGB:
+	return ((depth * 3) >> 3);
+      case RGB_WITH_ALPHA:
+	return ((depth * 4) >> 3);
+
+      default:
+      case GRAYSCALE:
+      case INDEXED:
+	int i = (depth >> 3);
+	if( i > 0 ) return i;
+	return 1; // if bytes per pixel < 1, return 1 anyway.
+      }
+  }
+
+  /**
+   * Returns the stride of one scanline, in bytes.
+   */
+  public int getScanlineStride()
+  {
+    long nBits = 0; // bits per scanline - scanlines are on byte offsets.
+    switch( colorType )
+      {
+      case GRAYSCALE:
+	nBits = width * depth;
+	break;
+      case RGB:
+	nBits = width * depth * 3;
+	break;
+      case INDEXED:
+	nBits = depth * width;
+	break;
+      case GRAYSCALE_WITH_ALPHA:
+	nBits = depth * width * 2;
+	break;
+      case RGB_WITH_ALPHA:
+	nBits = depth * width * 4;
+	break;
+      }
+    // Round up number of bits to the nearest byte
+    if( (nBits & 0x07) != 0 )
+      nBits += (8 - (nBits & 0x07));
+
+    return (int)(nBits >> 3); // return # of bytes.
+  }
+
+  public int getWidth()
+  {
+    return width; 
+  }
+  
+  public int getHeight()
+  { 
+    return height; 
+  }
+
+  public int getDepth()
+  { 
+    return depth; 
+  }
+
+  /**
+   * Debugging string.
+   */
+  public String toString()
+  {
+    return "Header Chunk. Image width:"+width+" height:"+height+
+      " depth:"+depth+" color type:"+colorType+" compression type:"+
+      compression+" filter type:"+ filter+" interlace:"+interlace;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGICCProfile.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGICCProfile.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGICCProfile.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGICCProfile.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,114 @@
+/* PNGICCProfile.java --
+   Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.png;
+
+import java.awt.color.ICC_Profile;
+import java.awt.color.ICC_ColorSpace;
+import java.awt.color.ColorSpace;
+import java.io.UnsupportedEncodingException;
+import java.io.IOException;
+import java.io.ByteArrayInputStream;
+import java.util.zip.InflaterInputStream;
+import java.util.zip.Deflater;
+
+/**
+ * A PNG iCCP (ICC Profile) chunk.
+ */
+public class PNGICCProfile extends PNGChunk 
+{ 
+  private String name;
+  private ICC_Profile profile;
+  // A generic profile name to use "ICC Profile"
+  private static final byte[] genericName = new byte[]
+  { 0x49, 0x43, 0x43, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65 };
+  
+  protected PNGICCProfile( int type, byte[] data, int crc ) throws PNGException
+  {
+    super( type, data, crc );
+    int i = 0;
+    while( data[i++] != 0 );
+    try
+      {
+	name = new String(data, 0, i, "8859_1");
+      }
+    catch(UnsupportedEncodingException e)
+      {
+	name = ""; // shouldn't really happen.
+      }
+    if( data[i++] != 0 )
+      throw new PNGException("Can't handle nonzero compression types with iCCP chunks.");
+    try
+      {
+	ByteArrayInputStream bos = new ByteArrayInputStream( data, i, 
+							     data.length - i );
+	profile = ICC_Profile.getInstance( new InflaterInputStream( bos ) );
+      }
+    catch(IOException ioe)
+      {
+	throw new PNGException("Couldn't read iCCP profile chunk.");
+      }
+    System.out.println("Got profile:"+profile);
+  }
+
+  public PNGICCProfile( ICC_Profile profile )
+  {
+    super( TYPE_PROFILE );
+    this.profile = profile;
+    byte[] profData = profile.getData();
+    byte[] outData = new byte[ profData.length * 2 ];
+    Deflater deflater = new Deflater();
+    deflater.setInput( profData );
+    deflater.finish();
+    int n = deflater.deflate( outData );
+    data = new byte[ n + 11 + 2 ];
+    System.arraycopy(genericName, 0, data, 0, 11 );
+    data[11] = data[12] = 0; // null separator and compression type.
+    // Copy compressed data
+    System.arraycopy(outData, 0, data, 13, n );
+  }
+
+  public ColorSpace getColorSpace()
+  {
+    return new ICC_ColorSpace( profile );
+  }
+
+  public String toString()
+  {
+    return "PNG ICC Profile, name: "+name;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGImageReader.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGImageReader.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGImageReader.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGImageReader.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,224 @@
+/* PNGImageReader.java -- The ImageIO ImageReader for PNG
+   Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.imageio.png;
+
+import gnu.javax.imageio.IIOInputStream;
+
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import javax.imageio.ImageReadParam;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.stream.ImageInputStream;
+
+/**
+ * The ImageIO ImageReader for PNG images.
+ *
+ * @author Roman Kennke (kennke at aicas.com)
+ */
+public class PNGImageReader
+  extends ImageReader
+{
+
+  /**
+   * The PNG file.
+   */
+  private PNGFile pngFile;
+
+  /**
+   * The decoded image.
+   */
+  private BufferedImage image;
+
+  /**
+   * The supported image types for PNG.
+   */
+  private ArrayList imageTypes;
+
+  /**
+   * Creates a new instance.
+   *
+   * @param spi the corresponding ImageReaderSpi
+   */
+  public PNGImageReader(PNGImageReaderSpi spi)
+  {
+    super(spi);
+  }
+
+  /**
+   * Returns the height of the image.
+   */
+  public int getHeight(int imageIndex)
+    throws IOException
+  {
+    checkIndex(imageIndex);
+    readImage();
+    return image.getHeight();
+  }
+
+  /**
+   * Returns the width of the image.
+   *
+   * @param imageIndex the index of the image
+   *
+   * @return the width of the image
+   */
+  public int getWidth(int imageIndex) throws IOException
+  {
+    checkIndex(imageIndex);
+    readImage();
+    return image.getWidth();
+  }
+
+  /**
+   * Returns the image types for the image.
+   *
+   * @see ImageReader#getImageTypes(int)
+   */
+  public Iterator getImageTypes(int imageIndex)
+    throws IOException
+  {
+    checkIndex(imageIndex);
+    readImage();
+    if (imageTypes == null)
+      {
+        imageTypes = new ArrayList();
+        imageTypes.add(new ImageTypeSpecifier(image.getColorModel(),
+                                              image.getSampleModel()));
+      }
+    return imageTypes.iterator();
+  }
+
+  /**
+   * Returns the number of images in the stream.
+   *
+   * @return the number of images in the stream
+   *
+   * @see ImageReader#getNumImages(boolean)
+   */
+  public int getNumImages(boolean allowSearch)
+    throws IOException
+  {
+    return 1;
+  }
+
+  /**
+   * Reads the image.
+   *
+   * @param imageIndex the index of the image to read
+   * @param param additional parameters
+   */
+  public BufferedImage read(int imageIndex, ImageReadParam param)
+    throws IOException
+  {
+    checkIndex(imageIndex);
+    readImage();
+    return image;
+  }
+
+  /**
+   * Sets the input and checks the input parameter.
+   *
+   * @see ImageReader#setInput(Object, boolean, boolean)
+   */
+  public void setInput(Object input, 
+                       boolean seekForwardOnly, 
+                       boolean ignoreMetadata) 
+  {
+    super.setInput(input, seekForwardOnly, ignoreMetadata);
+    if (! (input instanceof InputStream || input instanceof ImageInputStream))
+      throw new IllegalArgumentException("Input not an ImageInputStream");
+  }
+
+  public IIOMetadata getImageMetadata(int imageIndex)
+    throws IOException
+  {
+    // TODO: Not (yet) supported.
+    checkIndex(imageIndex);
+    return null;
+  }
+
+  public IIOMetadata getStreamMetadata()
+    throws IOException
+  {
+    // TODO: Not (yet) supported.
+    return null;
+  }
+
+  /**
+   * Checks the image indexa and throws and IndexOutOfBoundsException if
+   * appropriate.
+   *
+   * @param index the index to check
+   */
+  private void checkIndex(int index)
+  {
+    if (index > 0)
+      throw new IndexOutOfBoundsException("Image index out of bounds");
+  }
+
+  /**
+   * Makes sure that the image is read.
+   *
+   * @throws IOException if something goes wrong
+   */
+  private void readImage()
+    throws IOException
+  {
+    if (pngFile == null)
+      {
+        if (input instanceof InputStream)
+          pngFile = new PNGFile((InputStream) input);
+        else if (input instanceof ImageInputStream)
+          pngFile = new PNGFile(new IIOInputStream((ImageInputStream) input));
+        else
+          assert false : "Must not happen";
+      }
+
+    if (pngFile != null && image == null)
+      {
+        image = pngFile.getBufferedImage();
+      }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGImageReaderSpi.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGImageReaderSpi.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGImageReaderSpi.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGImageReaderSpi.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,128 @@
+/* PNGImageReaderSpi.java -- The ImageReader service provider for PNG
+   Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.imageio.png;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Locale;
+
+import javax.imageio.ImageReader;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.stream.ImageInputStream;
+
+/**
+ * The ImageIO ImageReader service provider for PNG images.
+ *
+ * @author Roman Kennke (kennke at aicas.com)
+ */
+public class PNGImageReaderSpi
+  extends ImageReaderSpi
+{
+
+  /**
+   * The PNG file signature.
+   */
+  private static final byte[] SIGNATURE = new byte[]
+                              { (byte) 137, 80, 78, 71, 13, 10, 26, 10 };
+
+  private static final String VENDOR_NAME = "GNU";
+  static final String VERSION = "1.0";
+  static final String READER_CLASSNAME =
+                                       "gnu.javax.imageio.png.PNGImageReader";
+  static final String[] NAMES = { "Portable Network Graphics" };
+  static final String[] SUFFIXES = { ".png" , ".PNG" };
+  static final String[] MIME_TYPES = { "image/png" };
+  static final String[] WRITER_SPI_NAMES =
+    new String[] { "gnu.javax.imageio.png.PNGWriterSpi" };
+  static final Class[] INPUT_TYPES = new Class[]{ InputStream.class,
+                                                  ImageInputStream.class};
+  public PNGImageReaderSpi()
+  {
+    super(VENDOR_NAME, VERSION, NAMES, SUFFIXES, MIME_TYPES, READER_CLASSNAME,
+          INPUT_TYPES, WRITER_SPI_NAMES, false, null, null, null, null, false,
+          null, null, null, null);
+  }
+
+  /**
+   * Determines if the PNG ImageReader can decode the specified input.
+   *
+   * @param source the source to decode
+   */
+  public boolean canDecodeInput(Object source) throws IOException
+  {
+    boolean canDecode = false;
+    if (source instanceof ImageInputStream)
+      {
+        ImageInputStream in = (ImageInputStream) source;
+        in.mark();
+        canDecode = true;
+        for (int i = 0; i < SIGNATURE.length && canDecode; i++)
+          {
+            byte sig = (byte) in.read();
+            if (sig != SIGNATURE[i]) {
+              canDecode = false;
+            }
+          }
+        in.reset();
+      }
+    return canDecode;
+  }
+
+  /**
+   * Returns a new PNGImageReader instance.
+   *
+   * @param extension the extension, ignored
+   */
+  public ImageReader createReaderInstance(Object extension)
+    throws IOException
+  {
+    return new PNGImageReader(this);
+  }
+
+  /**
+   * Returns a description.
+   *
+   * @param locale the locale
+   */
+  public String getDescription(Locale locale)
+  {
+    return "Portable Network Graphics";
+  }
+
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGPalette.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGPalette.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGPalette.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGPalette.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,127 @@
+/* PNGPalette.java --
+   Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.png;
+
+import java.awt.color.ColorSpace;
+import java.awt.image.IndexColorModel;
+
+/**
+ * A PNG Palette chunk.
+ */
+public class PNGPalette extends PNGChunk 
+{ 
+  private int[] red,green,blue;
+
+  protected PNGPalette( int type, byte[] data, int crc ) throws PNGException
+  {
+    super( type, data, crc );
+    double l = data.length;
+    l /= 3.0;
+    // Check if it's divisible by 3. (Yuck.)
+    if( l - Math.floor(l) != 0.0 )
+      throw new PNGException("Invalid size of palette chunk.");
+    int nEntries = (int)l;
+
+    red = new int[ nEntries ];
+    green = new int[ nEntries ];
+    blue = new int[ nEntries ];
+    for( int i = 0; i < nEntries; i++ )
+      {
+	red[i] = (data[ i * 3 ] & 0xFF);
+	green[i] = (data[ i * 3 + 1 ] & 0xFF);
+	blue[i] = (data[ i * 3 + 2] & 0xFF);
+      }
+  }
+
+  public PNGPalette( IndexColorModel cm )
+  {
+    super( TYPE_PALETTE );
+    int n = cm.getMapSize();
+    data = new byte[ n * 3 ];
+    red = new int[ n ];
+    green = new int[ n ];
+    blue = new int[ n ];
+    for(int i = 0; i < n; i++ )
+      {
+	red[i] = data[i * 3] = (byte)cm.getRed(i);
+	green[i] = data[i * 3 + 1] = (byte)cm.getGreen(i);
+	blue[i] = data[i * 3 + 2] = (byte)cm.getBlue(i);
+      }
+  }
+
+  public IndexColorModel getPalette( ColorSpace cs )
+  {
+    int nc = red.length;
+    byte[] r = new byte[nc];
+    byte[] g = new byte[nc];
+    byte[] b = new byte[nc];
+
+    if( cs == null )
+      {
+	for(int i = 0; i < nc; i ++ )
+	  {
+	    r[i] = (byte)red[i];
+	    g[i] = (byte)green[i];
+	    b[i] = (byte)blue[i];
+	  }
+      }
+    else
+      {
+	for(int i = 0; i < nc; i ++ )
+	  {
+	    float[] in = new float[3];
+	    in[0] = (((float)red[i]) / 255f);
+	    in[1] = (((float)green[i]) / 255f);
+	    in[2] = (((float)blue[i]) / 255f);
+	    float[] out = cs.toRGB( in );
+	    r[i] = (byte)( Math.round(out[0] * 255.0) );
+	    g[i] = (byte)( Math.round(out[1] * 255.0) );
+	    b[i] = (byte)( Math.round(out[2] * 255.0) );
+	  }
+      }	
+    return new IndexColorModel(8, nc, r, g, b);
+  }
+
+  public String toString()
+  {
+    String s = "PNG Palette:\n";
+    for( int i = 0; i < red.length; i++)
+      s = s + "Index " + i + ": ["+ red[i] +", "+green[i]+", "+blue[i]+"]\n";
+    return s;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGPhys.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGPhys.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGPhys.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGPhys.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,112 @@
+/* PNGPhys.java --
+   Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.png;
+
+/**
+ * A PNG "pHYS" chunk - pixel physical dimensions
+ */
+public class PNGPhys extends PNGChunk 
+{ 
+  long x, y;
+  double ratio;
+  boolean usesRatio;
+
+  protected PNGPhys( int type, byte[] data, int crc ) throws PNGException
+  {
+    super( type, data, crc );
+    if( data.length < 9 )
+      throw new PNGException("Unexpected size of pHYS chunk.");
+    x = ((data[0] & 0xFF) << 24) | ( (data[1] & 0xFF) << 16 ) | 
+      ((data[2] & 0xFF) << 8) | (data[3] & 0xFF);
+    y = ((data[4] & 0xFF) << 24) | ( (data[5] & 0xFF) << 16 ) | 
+      ((data[6] & 0xFF) << 8) | (data[7] & 0xFF);
+    if(data[8] == 0)
+      {
+	ratio = ((double)x)/((double)y);
+	usesRatio = true;
+      }
+  }
+
+  public PNGPhys( double ratio )
+  {
+    super( TYPE_PHYS );
+
+    this.ratio = ratio;
+    usesRatio = true;
+
+    if( ratio < 1.0 )
+      {
+	y = 0xFFFFFFFF;
+	x = (long)(0xFFFFFFFFL * ratio);
+      }
+    else
+      {
+	x = 0xFFFFFFFF;
+	y = (long)(0xFFFFFFFFL * ratio);
+      }
+    makeData();
+  }
+
+  public PNGPhys( int x, int y )
+  {
+    super( TYPE_PHYS );
+    usesRatio = false;
+    this.x = x;
+    this.y = y;
+    makeData();
+  }
+
+  private void makeData()
+  {
+    data = new byte[ 9 ];
+    byte[] a = getInt( (int)x );
+    byte[] b = getInt( (int)y );
+    data[0] = a[0]; data[1] = a[1]; data[2] = a[2]; data[3] = a[3]; 
+    data[4] = b[0]; data[5] = b[1]; data[6] = b[2]; data[7] = b[3]; 
+    data[7] = (usesRatio) ? 0 : (byte)0xFF;
+  }
+
+  public String toString()
+  {
+    String s = "PNG Physical pixel size chunk.";
+    if( usesRatio )
+      return s + " Aspect ratio (x/y): " + ratio;
+    else
+      return s + " " + x + " by " + y + " pixels per meter. (x, y).";
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGTime.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGTime.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGTime.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/imageio/png/PNGTime.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,83 @@
+/* PNGTime.java --
+   Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.imageio.png;
+
+import java.util.Date;
+
+/**
+ * A PNG tIME chunk.
+ */
+public class PNGTime extends PNGChunk 
+{ 
+  private Date date;
+
+  protected PNGTime( int type, byte[] data, int crc ) throws PNGException
+  {
+    super( type, data, crc );
+    if( data.length < 7 )
+      throw new PNGException("Unexpectedly short time chunk. ("+data.length+" bytes)");
+
+    // PNG value is absolute (2006, not 106 or 06), java is from 1900.
+    int year = ( (data[0] & 0xFF) << 8 ) | (data[1] & 0xFF);
+    int month = (data[2] & 0xFF); // java counts from 0. PNG from 1.
+    int day = (data[3] & 0xFF); 
+    int hour = (data[4] & 0xFF);
+    int minute = (data[5] & 0xFF);
+    int second = (data[6] & 0xFF);
+    date = new Date( year - 1900, month - 1, day, hour, minute, second );
+  }
+
+  public PNGTime( Date d )
+  {
+    super( TYPE_TIME );
+    data = new byte[ 7 ];
+    int tmp = d.getYear() + 1900;
+    data[0] = (byte)((tmp & 0xFF00) >> 8);
+    data[1] = (byte)(tmp & 0x00FF);
+    data[2] = (byte)(d.getMonth() + 1);
+    data[3] = (byte)(d.getDay());
+    data[4] = (byte)(d.getHours());
+    data[5] = (byte)(d.getMinutes());
+    data[6] = (byte)(d.getSeconds());
+  }
+
+  public String toString()
+  {
+    return "PNG Time chunk: "+date;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/Base64.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/Base64.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/Base64.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/Base64.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,311 @@
+/* Base64.java -- Base64 encoding and decoding.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.
+
+--
+Base64 encoding derived from ISC's DHCP. Copyright notices from DHCP
+follow. See http://www.isc.org/products/DHCP/.
+
+Copyright (c) 1996 by Internet Software Consortium.
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+--
+Portions Copyright (c) 1995 by International Business Machines, Inc.
+
+International Business Machines, Inc. (hereinafter called IBM) grants
+permission under its copyrights to use, copy, modify, and distribute
+this Software with or without fee, provided that the above copyright
+notice and all paragraphs of this notice appear in all copies, and
+that the name of IBM not be used in connection with the marketing of
+any product incorporating the Software or modifications thereof,
+without specific, written prior permission.
+
+To the extent it has a right to do so, IBM grants an immunity from
+suit under its patents, if any, for the use, sale or manufacture of
+products to the extent that such products are used for performing
+Domain Name System dynamic updates in TCP/IP networks by means of the
+Software.  No immunity is granted for any product per se or for any
+other function of any product.
+
+THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE, EVEN IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH
+DAMAGES.  */
+
+
+package gnu.javax.net.ssl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+public final class Base64
+{
+
+  // No constructor.
+  private Base64() { }
+
+  // Class methods.
+  // -------------------------------------------------------------------------
+
+  /** Base-64 characters. */
+  private static final String BASE_64 =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+  /** Base-64 padding character. */
+  private static final char BASE_64_PAD = '=';
+
+  /**
+   * Base64 encode a byte array, returning the returning string.
+   *
+   * @param buf The byte array to encode.
+   * @param tw  The total length of any line, 0 for unlimited.
+   * @return <tt>buf</tt> encoded in Base64.
+   */
+  public static String encode(byte[] buf, int tw)
+  {
+    int srcLength = buf.length;
+    byte[] input = new byte[3];
+    int[] output = new int[4];
+    StringBuffer out = new StringBuffer();
+    int i = 0;
+    int chars = 0;
+
+    while (srcLength > 2)
+      {
+        input[0] = buf[i++];
+        input[1] = buf[i++];
+        input[2] = buf[i++];
+        srcLength -= 3;
+
+        output[0] = (input[0] & 0xff) >>> 2;
+        output[1] = ((input[0] & 0x03) << 4) + ((input[1] & 0xff) >>> 4);
+        output[2] = ((input[1] & 0x0f) << 2) + ((input[2] & 0xff) >>> 6);
+        output[3] = input[2] & 0x3f;
+
+        out.append(BASE_64.charAt(output[0]));
+        if (tw > 0 && ++chars % tw == 0)
+          {
+            out.append("\n");
+          }
+        out.append(BASE_64.charAt(output[1]));
+        if (tw > 0 && ++chars % tw == 0)
+          {
+            out.append("\n");
+          }
+        out.append(BASE_64.charAt(output[2]));
+        if (tw > 0 && ++chars % tw == 0)
+          {
+            out.append("\n");
+          }
+        out.append(BASE_64.charAt(output[3]));
+        if (tw > 0 && ++chars % tw == 0)
+          {
+            out.append("\n");
+          }
+      }
+
+    if (srcLength != 0)
+      {
+        input[0] = input[1] = input[2] = 0;
+        for (int j = 0; j < srcLength; j++)
+          {
+            input[j] = buf[i+j];
+          }
+        output[0] = (input[0] & 0xff) >>> 2;
+        output[1] = ((input[0] & 0x03) << 4) + ((input[1] & 0xff) >>> 4);
+        output[2] = ((input[1] & 0x0f) << 2) + ((input[2] & 0xff) >>> 6);
+
+        out.append(BASE_64.charAt(output[0]));
+        if (tw > 0 && ++chars % tw == 0)
+          {
+            out.append("\n");
+          }
+        out.append(BASE_64.charAt(output[1]));
+        if (tw > 0 && ++chars % tw == 0)
+          {
+            out.append("\n");
+          }
+        if (srcLength == 1)
+          {
+            out.append(BASE_64_PAD);
+          }
+        else
+          {
+            out.append(BASE_64.charAt(output[2]));
+          }
+        if (tw > 0 && ++chars % tw == 0)
+          {
+            out.append("\n");
+          }
+        out.append(BASE_64_PAD);
+        if (tw > 0 && ++chars % tw == 0)
+          {
+            out.append("\n");
+          }
+      }
+    if (tw > 0)
+      {
+        out.append("\n");
+      }
+
+    return out.toString();
+  }
+
+  /**
+   * Decode a Base-64 string into a byte array.
+   *
+   * @param b64 The Base-64 encoded string.
+   * @return The decoded bytes.
+   * @throws java.io.IOException If the argument is not a valid Base-64
+   *    encoding.
+   */
+  public static byte[] decode(String b64) throws IOException
+  {
+    ByteArrayOutputStream result = new ByteArrayOutputStream(b64.length() / 3);
+    int state = 0, i;
+    byte temp = 0;
+
+    for (i = 0; i < b64.length(); i++)
+      {
+        if (Character.isWhitespace(b64.charAt(i)))
+          {
+            continue;
+          }
+        if (b64.charAt(i) == BASE_64_PAD)
+          {
+            break;
+          }
+
+        int pos = BASE_64.indexOf(b64.charAt(i));
+        if (pos < 0)
+          {
+            throw new IOException("non-Base64 character " + b64.charAt(i));
+          }
+        switch (state)
+          {
+          case 0:
+            temp = (byte) (pos - BASE_64.indexOf('A') << 2);
+            state = 1;
+            break;
+
+          case 1:
+            temp |= (byte) (pos - BASE_64.indexOf('A') >>> 4);
+            result.write(temp);
+            temp = (byte) ((pos - BASE_64.indexOf('A') & 0x0f) << 4);
+            state = 2;
+            break;
+
+          case 2:
+            temp |= (byte) ((pos - BASE_64.indexOf('A') & 0x7f) >>> 2);
+            result.write(temp);
+            temp = (byte) ((pos - BASE_64.indexOf('A') & 0x03) << 6);
+            state = 3;
+            break;
+
+          case 3:
+            temp |= (byte) (pos - BASE_64.indexOf('A') & 0xff);
+            result.write(temp);
+            state = 0;
+            break;
+
+          default:
+            throw new Error("this statement should be unreachable");
+          }
+      }
+
+    if (i < b64.length() && b64.charAt(i) == BASE_64_PAD)
+      {
+        switch (state)
+          {
+          case 0:
+          case 1:
+            throw new IOException("malformed Base64 sequence");
+
+          case 2:
+            for ( ; i < b64.length(); i++)
+              {
+                if (!Character.isWhitespace(b64.charAt(i)))
+                  {
+                    break;
+                  }
+              }
+            // We must see a second pad character here.
+            if (b64.charAt(i) != BASE_64_PAD)
+              {
+                throw new IOException("malformed Base64 sequence");
+              }
+            i++;
+            // Fall-through.
+
+          case 3:
+            i++;
+            for ( ; i < b64.length(); i++)
+              {
+                // We should only see whitespace after this.
+                if (!Character.isWhitespace(b64.charAt(i)))
+                  {
+                    System.err.println(b64.charAt(i));
+                    throw new IOException("malformed Base64 sequence");
+                  }
+              }
+          }
+      }
+    else
+      {
+        if (state != 0)
+          {
+            throw new IOException("malformed Base64 sequence");
+          }
+      }
+
+    return result.toByteArray();
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/EntropySource.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/EntropySource.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/EntropySource.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/EntropySource.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,62 @@
+/* EntropySource.java -- a source of random bits.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl;
+
+/**
+ * A generic interface for adding random bytes to an entropy pool.
+ */
+public interface EntropySource
+{
+
+  /**
+   * Returns the estimated quality of this source. This value should be
+   * between 0 and 100 (the running quality is computed as a percentage,
+   * 100 percent being perfect-quality).
+   *
+   * @return The quality.
+   */
+  double quality();
+
+  /**
+   * Returns a new buffer with the next random bytes to add.
+   *
+   * @return The next random bytes.
+   */
+  byte[] nextBytes();
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/NullManagerParameters.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/NullManagerParameters.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/NullManagerParameters.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/NullManagerParameters.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,56 @@
+/* NullManagerParameters.java -- parameters for empty managers.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl;
+
+import javax.net.ssl.ManagerFactoryParameters;
+
+/**
+ * This empty class can be used to initialize {@link
+ * javax.net.ssl.KeyManagerFactory} and {@link
+ * javax.net.ssl.TrustManagerFactory} instances for the ``JessieX509''
+ * algorithm, for cases when no keys or trusted certificates are
+ * desired or needed.
+ *
+ * <p>This is the default manager parameters object used in {@link
+ * javax.net.ssl.KeyManagerFactory} instances if no key stores are
+ * specified through security properties.
+ */
+public final class NullManagerParameters implements ManagerFactoryParameters
+{
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/PrivateCredentials.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/PrivateCredentials.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/PrivateCredentials.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/PrivateCredentials.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,360 @@
+/* PrivateCredentials.java -- private key/certificate pairs.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.io.IOException;
+
+import java.math.BigInteger;
+
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.Security;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.DSAPrivateKeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.security.spec.RSAPrivateCrtKeySpec;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.net.ssl.ManagerFactoryParameters;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import gnu.javax.security.auth.callback.ConsoleCallbackHandler;
+import gnu.java.security.hash.HashFactory;
+import gnu.java.security.hash.IMessageDigest;
+import gnu.javax.crypto.mode.IMode;
+import gnu.javax.crypto.mode.ModeFactory;
+import gnu.javax.crypto.pad.WrongPaddingException;
+
+import gnu.java.security.der.DER;
+import gnu.java.security.der.DERReader;
+
+/**
+ * An instance of a manager factory parameters for holding a single
+ * certificate/private key pair, encoded in PEM format.
+ */
+public class PrivateCredentials implements ManagerFactoryParameters
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  public static final String BEGIN_DSA = "-----BEGIN DSA PRIVATE KEY";
+  public static final String END_DSA   = "-----END DSA PRIVATE KEY";
+  public static final String BEGIN_RSA = "-----BEGIN RSA PRIVATE KEY";
+  public static final String END_RSA   = "-----END RSA PRIVATE KEY";
+
+  private List privateKeys;
+  private List certChains;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  public PrivateCredentials()
+  {
+    privateKeys = new LinkedList();
+    certChains = new LinkedList();
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public void add(InputStream certChain, InputStream privateKey)
+    throws CertificateException, InvalidKeyException, InvalidKeySpecException,
+           IOException, NoSuchAlgorithmException, WrongPaddingException
+  {
+    CertificateFactory cf = CertificateFactory.getInstance("X.509");
+    Collection certs = cf.generateCertificates(certChain);
+    X509Certificate[] chain = (X509Certificate[]) certs.toArray(new X509Certificate[0]);
+
+    String alg = null;
+    String line = readLine(privateKey);
+    String finalLine = null;
+    if (line.startsWith(BEGIN_DSA))
+      {
+        alg = "DSA";
+        finalLine = END_DSA;
+      }
+    else if (line.startsWith(BEGIN_RSA))
+      {
+        alg = "RSA";
+        finalLine = END_RSA;
+      }
+    else
+      throw new IOException("Unknown private key type.");
+
+    boolean encrypted = false;
+    String cipher = null;
+    String salt = null;
+    StringBuffer base64 = new StringBuffer();
+    while (true)
+      {
+        line = readLine(privateKey);
+        if (line == null)
+          throw new EOFException("premature end-of-file");
+        else if (line.startsWith("Proc-Type: 4,ENCRYPTED"))
+          encrypted = true;
+        else if (line.startsWith("DEK-Info: "))
+          {
+            int i = line.indexOf(',');
+            if (i < 0)
+              cipher = line.substring(10).trim();
+            else
+              {
+                cipher = line.substring(10, i).trim();
+                salt = line.substring(i + 1).trim();
+              }
+          }
+        else if (line.startsWith(finalLine))
+          break;
+        else if (line.length() > 0)
+          {
+            base64.append(line);
+            base64.append(System.getProperty("line.separator"));
+          }
+      }
+
+    byte[] enckey = Base64.decode(base64.toString());
+    if (encrypted)
+      {
+        enckey = decryptKey(enckey, cipher, toByteArray(salt));
+      }
+
+    DERReader der = new DERReader(enckey);
+    if (der.read().getTag() != DER.SEQUENCE)
+      throw new IOException("malformed DER sequence");
+    der.read(); // version
+
+    KeyFactory kf = KeyFactory.getInstance(alg);
+    KeySpec spec = null;
+    if (alg.equals("DSA"))
+      {
+        BigInteger p = (BigInteger) der.read().getValue();
+        BigInteger q = (BigInteger) der.read().getValue();
+        BigInteger g = (BigInteger) der.read().getValue();
+        der.read(); // y
+        BigInteger x = (BigInteger) der.read().getValue();
+        spec = new DSAPrivateKeySpec(x, p, q, g);
+      }
+    else
+      {
+        spec = new RSAPrivateCrtKeySpec(
+          (BigInteger) der.read().getValue(),  // modulus
+          (BigInteger) der.read().getValue(),  // pub exponent
+          (BigInteger) der.read().getValue(),  // priv expenent
+          (BigInteger) der.read().getValue(),  // prime p
+          (BigInteger) der.read().getValue(),  // prime q
+          (BigInteger) der.read().getValue(),  // d mod (p-1)
+          (BigInteger) der.read().getValue(),  // d mod (q-1)
+          (BigInteger) der.read().getValue()); // coefficient
+      }
+    privateKeys.add(kf.generatePrivate(spec));
+    certChains.add(chain);
+  }
+
+  public List getPrivateKeys()
+  {
+    if (isDestroyed())
+      {
+        throw new IllegalStateException("this object is destroyed");
+      }
+    return privateKeys;
+  }
+
+  public List getCertChains()
+  {
+    return certChains;
+  }
+
+  public void destroy()
+  {
+    privateKeys.clear();
+    privateKeys = null;
+  }
+
+  public boolean isDestroyed()
+  {
+    return (privateKeys == null);
+  }
+
+  // Own methods.
+  // -------------------------------------------------------------------------
+
+  private String readLine(InputStream in) throws IOException
+  {
+    boolean eol_is_cr = System.getProperty("line.separator").equals("\r");
+    StringBuffer str = new StringBuffer();
+    while (true)
+      {
+        int i = in.read();
+        if (i == -1)
+          {
+            if (str.length() > 0)
+              break;
+            else
+              return null;
+          }
+        else if (i == '\r')
+          {
+            if (eol_is_cr)
+              break;
+          }
+        else if (i == '\n')
+          break;
+        else
+          str.append((char) i);
+      }
+    return str.toString();
+  }
+
+  private byte[] decryptKey(byte[] ct, String cipher, byte[] salt)
+    throws IOException, InvalidKeyException, WrongPaddingException
+  {
+    byte[] pt = new byte[ct.length];
+    IMode mode = null;
+    if (cipher.equals("DES-EDE3-CBC"))
+      {
+        mode = ModeFactory.getInstance("CBC", "TripleDES", 8);
+        HashMap attr = new HashMap();
+        attr.put(IMode.KEY_MATERIAL, deriveKey(salt, 24));
+        attr.put(IMode.IV, salt);
+        attr.put(IMode.STATE, new Integer(IMode.DECRYPTION));
+        mode.init(attr);
+      }
+    else if (cipher.equals("DES-CBC"))
+      {
+        mode = ModeFactory.getInstance("CBC", "DES", 8);
+        HashMap attr = new HashMap();
+        attr.put(IMode.KEY_MATERIAL, deriveKey(salt, 8));
+        attr.put(IMode.IV, salt);
+        attr.put(IMode.STATE, new Integer(IMode.DECRYPTION));
+        mode.init(attr);
+      }
+    else
+      throw new IllegalArgumentException("unknown cipher: " + cipher);
+
+    for (int i = 0; i < ct.length; i += 8)
+      mode.update(ct, i, pt, i);
+
+    int pad = pt[pt.length-1];
+    if (pad < 1 || pad > 8)
+      throw new WrongPaddingException();
+    for (int i = pt.length - pad; i < pt.length; i++)
+      {
+        if (pt[i] != pad)
+          throw new WrongPaddingException();
+      }
+
+    byte[] result = new byte[pt.length - pad];
+    System.arraycopy(pt, 0, result, 0, result.length);
+    return result;
+  }
+
+  private byte[] deriveKey(byte[] salt, int keylen)
+    throws IOException
+  {
+    CallbackHandler passwordHandler = new ConsoleCallbackHandler();
+    try
+      {
+        Class c = Class.forName(Security.getProperty("jessie.password.handler"));
+        passwordHandler = (CallbackHandler) c.newInstance();
+      }
+    catch (Exception x) { }
+
+    PasswordCallback passwdCallback =
+      new PasswordCallback("Enter PEM passphrase: ", false);
+    try
+      {
+        passwordHandler.handle(new Callback[] { passwdCallback });
+      }
+    catch (UnsupportedCallbackException uce)
+      {
+        throw new IOException("specified handler cannot handle passwords");
+      }
+    char[] passwd = passwdCallback.getPassword();
+
+    IMessageDigest md5 = HashFactory.getInstance("MD5");
+    byte[] key = new byte[keylen];
+    int count = 0;
+    while (count < keylen)
+      {
+        for (int i = 0; i < passwd.length; i++)
+          md5.update((byte) passwd[i]);
+        md5.update(salt, 0, salt.length);
+        byte[] digest = md5.digest();
+        int len = Math.min(digest.length, keylen - count);
+        System.arraycopy(digest, 0, key, count, len);
+        count += len;
+        if (count >= keylen)
+          break;
+        md5.reset();
+        md5.update(digest, 0, digest.length);
+      }
+    passwdCallback.clearPassword();
+    return key;
+  }
+
+  private byte[] toByteArray(String hex)
+  {
+    hex = hex.toLowerCase();
+    byte[] buf = new byte[hex.length() / 2];
+    int j = 0;
+    for (int i = 0; i < buf.length; i++)
+      {
+        buf[i] = (byte) ((Character.digit(hex.charAt(j++), 16) << 4) |
+                          Character.digit(hex.charAt(j++), 16));
+      }
+    return buf;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/SRPManagerParameters.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/SRPManagerParameters.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/SRPManagerParameters.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/SRPManagerParameters.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,81 @@
+/* SRPManagerParameters.java -- Wrapper for SRP PasswordFile.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl;
+
+import javax.net.ssl.ManagerFactoryParameters;
+import gnu.javax.crypto.sasl.srp.PasswordFile;
+
+/**
+ * Instances of this class are used to initialize {@link
+ * javax.net.ssl.TrustManagerFactory} instances for the ``SRP'' algorithm.
+ */
+public class SRPManagerParameters implements ManagerFactoryParameters
+{
+
+  // Field.
+  // -------------------------------------------------------------------------
+
+  private final PasswordFile file;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  /**
+   * Initializes these parameters with the specified SRP password file.
+   *
+   * @param file The SRP password file object.
+   * @throws NullPointerException if <i>file</i> is <code>null</code>.
+   */
+  public SRPManagerParameters(PasswordFile file)
+  {
+    if (file == null)
+      {
+        throw new NullPointerException();
+      }
+    this.file = file;
+  }
+
+  // Instance method.
+  // -------------------------------------------------------------------------
+
+  public PasswordFile getPasswordFile()
+  {
+    return file;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/SRPTrustManager.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/SRPTrustManager.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/SRPTrustManager.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/SRPTrustManager.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,99 @@
+/* SRPTrustManager.java -- interface to SRP trust managers.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl;
+
+import gnu.javax.crypto.sasl.srp.PasswordFile;
+
+import java.math.BigInteger;
+import java.security.KeyPair;
+import javax.net.ssl.TrustManager;
+
+/**
+ * A trust manager for secure remote password (SRP) key exchange cipher
+ * suites. This is a read-only interface to the {@link
+ * gnu.crypto.sasl.srp.PasswordFile} class, with convenience methods to
+ * generate session key pairs.
+ */
+public interface SRPTrustManager extends TrustManager
+{
+
+  // Methods.
+  // -------------------------------------------------------------------------
+
+  /**
+   * Tests if the configured password file contains the specified user name.
+   *
+   * @param user The user name.
+   * @return True if the password file has an entry for <i>user</i>
+   */
+  boolean contains(String user);
+
+  /**
+   * Create and return a session SRP key pair for the given user name.
+   *
+   * @param user The user name to generate the key pair for.
+   * @return The session key pair, or <code>null</code> if there is no
+   *   entry for <i>user</i>.
+   */
+  KeyPair getKeyPair(String user);
+
+  /**
+   * Returns the salt value for the given user.
+   *
+   * @param user The user name.
+   * @return The salt for <i>user</i>'s entry, or <code>null</code>.
+   */
+  byte[] getSalt(String user);
+
+  /**
+   * Returns the password verifier for the given user.
+   *
+   * @param user The user name.
+   * @return <i>user</i>'s password verifier, or <code>null</code>.
+   */
+  BigInteger getVerifier(String user);
+
+  /**
+   * Returns a reference to the SRP {@link PasswordFile} used by this
+   * {@link TrustManager}.
+   *
+   * @return a reference to the SRP password file in use.
+   */
+  PasswordFile getPasswordFile();
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/StaticTrustAnchors.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/StaticTrustAnchors.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/StaticTrustAnchors.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/StaticTrustAnchors.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,1942 @@
+/* StaticTrustAnchors.java -- static list of CA certificates.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+import java.util.LinkedList;
+
+import javax.net.ssl.ManagerFactoryParameters;
+
+/**
+ * This class implements a simple set of trust anchors suitable for
+ * initializing a TrustManagerFactory for the "JessieX509" algorithm.
+ *
+ * <p>The important field of this class is the {@link #CA_CERTS}
+ * constant, which contains an array of commonly accepted CA
+ * certificates.
+ */
+public class StaticTrustAnchors implements ManagerFactoryParameters
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private X509Certificate[] certs;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  public StaticTrustAnchors(X509Certificate[] certs)
+  {
+    this.certs = (X509Certificate[]) certs.clone();
+  }
+
+  // Class method.
+  // -------------------------------------------------------------------------
+
+  public static X509Certificate generate(CertificateFactory factory,
+                                         String encoded)
+  {
+    try
+      {
+        ByteArrayInputStream in =
+          new ByteArrayInputStream(encoded.getBytes("UTF-8"));
+        return (X509Certificate) factory.generateCertificate(in);
+      }
+    catch (Exception x)
+      {
+        return null;
+      }
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public X509Certificate[] getCertificates()
+  {
+    return (X509Certificate[]) certs.clone();
+  }
+
+  // Constant.
+  // -------------------------------------------------------------------------
+
+  /**
+   * A list of known certificate authority certificates. This set of
+   * certificates is the same as the default CA certificates used by
+   * Mozilla.
+   */
+  public static final StaticTrustAnchors CA_CERTS;
+
+  // Static initializer.
+  // -------------------------------------------------------------------------
+
+  static
+  {
+    LinkedList certs = new LinkedList();
+    CertificateFactory factory = null;
+
+    try
+      {
+        factory = CertificateFactory.getInstance("X.509");
+      }
+    catch (CertificateException ce)
+      {
+        throw new Error(ce.toString());
+      }
+
+    X509Certificate cert = generate(factory,
+      // ABAecom_=sub.__Am._Bankers_Assn.=_Root_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDtTCCAp2gAwIBAgIRANAeQJAAAEZSAAAAAQAAAAQwDQYJKoZIhvcNAQEF\n" +
+      "BQAwgYkxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJEQzETMBEGA1UEBxMKV2Fz\n" +
+      "aGluZ3RvbjEXMBUGA1UEChMOQUJBLkVDT00sIElOQy4xGTAXBgNVBAMTEEFC\n" +
+      "QS5FQ09NIFJvb3QgQ0ExJDAiBgkqhkiG9w0BCQEWFWFkbWluQGRpZ3NpZ3Ry\n" +
+      "dXN0LmNvbTAeFw05OTA3MTIxNzMzNTNaFw0wOTA3MDkxNzMzNTNaMIGJMQsw\n" +
+      "CQYDVQQGEwJVUzELMAkGA1UECBMCREMxEzARBgNVBAcTCldhc2hpbmd0b24x\n" +
+      "FzAVBgNVBAoTDkFCQS5FQ09NLCBJTkMuMRkwFwYDVQQDExBBQkEuRUNPTSBS\n" +
+      "b290IENBMSQwIgYJKoZIhvcNAQkBFhVhZG1pbkBkaWdzaWd0cnVzdC5jb20w\n" +
+      "ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx0xHgeVVDBwhMywVC\n" +
+      "AOINg0Y95JO6tgbTDVm9PsHOQ2cBiiGo77zM0KLMsFWWU4RmBQDaREmA2FQK\n" +
+      "pSWGlO1jVv9wbKOhGdJ4vmgqRF4vz8wYXke8OrFGPR7wuSw0X4x8TAgpnUBV\n" +
+      "6zx9g9618PeKgw6hTLQ6pbNfWiKX7BmbwQVo/ea3qZGULOR4SCQaJRk665Wc\n" +
+      "OQqKz0Ky8BzVX/tr7WhWezkscjiw7pOp03t3POtxA6k4ShZsiSrK2jMTecJV\n" +
+      "jO2cu/LLWxD4LmE1xilMKtAqY9FlWbT4zfn0AIS2V0KFnTKo+SpU+/94Qby9\n" +
+      "cSj0u5C8/5Y0BONFnqFGKECBAgMBAAGjFjAUMBIGA1UdEwEB/wQIMAYBAf8C\n" +
+      "AQgwDQYJKoZIhvcNAQEFBQADggEBAARvJYbk5pYntNlCwNDJALF/VD6Hsm0k\n" +
+      "qS8Kfv2kRLD4VAe9G52dyntQJHsRW0mjpr8SdNWJt7cvmGQlFLdh6X9ggGvT\n" +
+      "ZOirvRrWUfrAtF13Gn9kCF55xgVM8XrdTX3O5kh7VNJhkoHWG9YA8A6eKHeg\n" +
+      "TYjHInYZw8eeG6Z3ePhfm1bR8PIXrI6dWeYf/le22V7hXZ9F7GFoGUHhsiAm\n" +
+      "/lowdiT/QHI8eZ98IkirRs3bs4Ysj78FQdPB4xTjQRcm0HyncUwZ6EoPclgx\n" +
+      "fexgeqMiKL0ZJGA/O4dzwGvky663qyVDslUte6sGDnVdNOVdc22esnVApVnJ\n" +
+      "TzFxiNmIf1Q=\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // AOL_Time_Warner_Root_Certification_Authority_1.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIID5jCCAs6gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzELMAkGA1UEBhMC\n" +
+      "VVMxHTAbBgNVBAoTFEFPTCBUaW1lIFdhcm5lciBJbmMuMRwwGgYDVQQLExNB\n" +
+      "bWVyaWNhIE9ubGluZSBJbmMuMTcwNQYDVQQDEy5BT0wgVGltZSBXYXJuZXIg\n" +
+      "Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyOTA2MDAw\n" +
+      "MFoXDTM3MTEyMDE1MDMwMFowgYMxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRB\n" +
+      "T0wgVGltZSBXYXJuZXIgSW5jLjEcMBoGA1UECxMTQW1lcmljYSBPbmxpbmUg\n" +
+      "SW5jLjE3MDUGA1UEAxMuQU9MIFRpbWUgV2FybmVyIFJvb3QgQ2VydGlmaWNh\n" +
+      "dGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n" +
+      "ggEBAJnej8Mlo2k06AX3dLm/WpcZuS+U0pPlLYnKhHw/EEMbjIt8hFj4JHxI\n" +
+      "zyr9wBXZGH6EGhfT257XyuTZ16pYUYfw8ItITuLCxFlpMGK2MKKMCxGZYTVt\n" +
+      "fu/FsRkGIBKOQuHfD5YQUqjPnF+VFNivO3ULMSAfRC+iYkGzuxgh28pxPIzs\n" +
+      "trkNn+9R7017EvILDOGsQI93f7DKeHEMXRZxcKLXwjqFzQ6axOAAsNUl6twr\n" +
+      "5JQtOJyJQVdkKGUZHLZEtMgxa44Be3ZZJX8VHIQIfHNlIAqhBC4aMqiaILGc\n" +
+      "LCFZ5/vP7nAtCMpjPiybkxlqpMKX/7eGV4iFbJ4VFitNLLMCAwEAAaNjMGEw\n" +
+      "DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUoTYwFsuGkABFgFOxj8jYPXy+\n" +
+      "XxIwHwYDVR0jBBgwFoAUoTYwFsuGkABFgFOxj8jYPXy+XxIwDgYDVR0PAQH/\n" +
+      "BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQCKIBilvrMvtKaEAEAwKfq0FHNM\n" +
+      "eUWn9nDg6H5kHgqVfGphwu9OH77/yZkfB2FK4V1Mza3u0FIy2VkyvNp5ctZ7\n" +
+      "CegCgTXTCt8RHcl5oIBN/lrXVtbtDyqvpxh1MwzqwWEFT2qaifKNuZ8u77Bf\n" +
+      "WgDrvq2g+EQFZ7zLBO+eZMXpyD8Fv8YvBxzDNnGGyjhmSs3WuEvGbKeXO/oT\n" +
+      "LW4jYYehY0KswsuXn2Fozy1MBJ3XJU8KDk2QixhWqJNIV9xvrr2eZ1d3iVCz\n" +
+      "vhGbRWeDhhmH05i9CBoWH1iCC+GWaQVLjuyDUTEH1dSf/1l7qG6Fz9NLqUmw\n" +
+      "X7A5KGgOc90lmt4S\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // AOL_Time_Warner_Root_Certification_Authority_2.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIF5jCCA86gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzELMAkGA1UEBhMC\n" +
+      "VVMxHTAbBgNVBAoTFEFPTCBUaW1lIFdhcm5lciBJbmMuMRwwGgYDVQQLExNB\n" +
+      "bWVyaWNhIE9ubGluZSBJbmMuMTcwNQYDVQQDEy5BT0wgVGltZSBXYXJuZXIg\n" +
+      "Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyOTA2MDAw\n" +
+      "MFoXDTM3MDkyODIzNDMwMFowgYMxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRB\n" +
+      "T0wgVGltZSBXYXJuZXIgSW5jLjEcMBoGA1UECxMTQW1lcmljYSBPbmxpbmUg\n" +
+      "SW5jLjE3MDUGA1UEAxMuQU9MIFRpbWUgV2FybmVyIFJvb3QgQ2VydGlmaWNh\n" +
+      "dGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC\n" +
+      "ggIBALQ3WggWmRToVbEbJGv8x4vmh6mJ7ouZzU9AhqS2TcnZsdw8TQ2FTBVs\n" +
+      "RotSeJ/4I/1n9SQ6aF3Q92RhQVSji6UI0ilbm2BPJoPRYxJWSXakFsKlnUWs\n" +
+      "i4SVqBax7J/qJBrvuVdcmiQhLE0OcR+mrF1FdAOYxFSMFkpBd4aVdQxHAWZg\n" +
+      "/BXxD+r1FHjHDtdugRxev17nOirYlxcwfACtCJ0zr7iZYYCLqJV+FNwSbKTQ\n" +
+      "2O9ASQI2+W6p1h2WVgSysy0WVoaP2SBXgM1nEG2wTPDaRrbqJS5Gr42whTg0\n" +
+      "ixQmgiusrpkLjhTXUr2eacOGAgvqdnUxCc4zGSGFQ+aJLZ8lN2fxI2rSAG2X\n" +
+      "+Z/nKcrdH9cG6rjJuQkhn8g/BsXS6RJGAE57COtCPStIbp1n3UsC5ETzkxml\n" +
+      "J85per5n0/xQpCyrw2u544BMzwVhSyvcG7mm0tCq9Stz+86QNZ8MUhy/XCFh\n" +
+      "EVsVS6kkUfykXPcXnbDS+gfpj1bkGoxoigTTfFrjnqKhynFbotSg5ymFXQNo\n" +
+      "Kk/SBtc9+cMDLz9l+WceR0DTYw/j1Y75hauXTLPXJuuWCpTehTacyH+BCQJJ\n" +
+      "Kg71ZDIMgtG6aoIbs0t0EfOMd9afv9w3pKdVBC/UMejTRrkDfNoSTllkt1Ex\n" +
+      "MVCgyhwn2RAurda9EGYrw7AiShJbAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMB\n" +
+      "Af8wHQYDVR0OBBYEFE9pbQN+nZ8HGEO8txBO1b+pxCAoMB8GA1UdIwQYMBaA\n" +
+      "FE9pbQN+nZ8HGEO8txBO1b+pxCAoMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG\n" +
+      "9w0BAQUFAAOCAgEAO/Ouyuguh4X7ZVnnrREUpVe8WJ8kEle7+z802u6teio0\n" +
+      "cnAxa8cZmIDJgt43d15Ui47y6mdPyXSEkVYJ1eV6moG2gcKtNuTxVBFT8zRF\n" +
+      "ASbI5Rq8NEQh3q0l/HYWdyGQgJhXnU7q7C+qPBR7V8F+GBRn7iTGvboVsNIY\n" +
+      "vbdVgaxTwOjdaRITQrcCtQVBynlQboIOcXKTRuidDV29rs4prWPVVRaAMCf/\n" +
+      "drr3uNZK49m1+VLQTkCpx+XCMseqdiThawVQ68W/ClTluUI8JPu3B5wwn3la\n" +
+      "5uBAUhX0/Kr0VvlEl4ftDmVyXr4m+02kLQgH3thcoNyBM5kYJRF3p+v9WAks\n" +
+      "mWsbivNSPxpNSGDxoPYzAlOL7SUJuA0t7Zdz7NeWH45gDtoQmy8YJPamTQr5\n" +
+      "O8t1wswvziRpyQoijlmn94IM19drNZxDAGrElWe6nEXLuA4399xOAU++CrYD\n" +
+      "062KRffaJ00psUjf5BHklka9bAI+1lHIlRcBFanyqqryvy9lG2/QuRqT9Y41\n" +
+      "xICHPpQvZuTpqP9BnHAqTyo5GJUefvthATxRCC4oGKQWDzH9OmwjkyB24f0H\n" +
+      "hdFbP9IcczLd+rn4jM8Ch3qaluTtT4mNU0OrDhPAARW0eTjb/G49nlG2uBOL\n" +
+      "Z8/5fNkiHfZdxRwBL5joeiQYvITX+txyW/fBOmg=\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // AddTrust_External_Root.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJT\n" +
+      "RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4\n" +
+      "dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5h\n" +
+      "bCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzEL\n" +
+      "MAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1B\n" +
+      "ZGRUcnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1\n" +
+      "c3QgRXh0ZXJuYWwgQ0EgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\n" +
+      "AQoCggEBALf3GjPm8gAELTngTlvtH7xsD821+iO2zt6bETOXpClMfZOfvUq8\n" +
+      "k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfwTz/oMp50\n" +
+      "ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504\n" +
+      "B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDez\n" +
+      "eWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5\n" +
+      "aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0WicCAwEAAaOB\n" +
+      "3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0PBAQD\n" +
+      "AgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6\n" +
+      "xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU\n" +
+      "cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdv\n" +
+      "cmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJ\n" +
+      "KoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl\n" +
+      "j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5R\n" +
+      "xNKWt9x+Tu5w/Rw56wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjT\n" +
+      "K3rMUUKhemPR5ruhxSvCNr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1\n" +
+      "n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHx\n" +
+      "REzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49O\n" +
+      "hgQ=\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // AddTrust_Low-Value_Services_Root.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJT\n" +
+      "RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRU\n" +
+      "UCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3Qw\n" +
+      "HhcNMDAwNTMwMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJT\n" +
+      "RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRU\n" +
+      "UCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3Qw\n" +
+      "ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwze\n" +
+      "xODcEyPNwTXH+9ZOEQpnXvUGW2ulCDtbKRY654eyNAbFvAWlA3yCyykQruGI\n" +
+      "gb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6ntGO0/7Gcrjyvd7ZWxbWroulpOj0O\n" +
+      "M3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyldI+Yrsj5wAYi56xz36Uu+1Lc\n" +
+      "sRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJchPXQhI2U0K7t4WaPW4XY5\n" +
+      "mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC+Mcdoq0Dlyz4zyXG\n" +
+      "9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0OBBYEFJWxtPCU\n" +
+      "tr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTADAQH/\n" +
+      "MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBlMQsw\n" +
+      "CQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk\n" +
+      "ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAx\n" +
+      "IENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0\n" +
+      "MkhHma6X7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0Ph\n" +
+      "iVYrqW9yTkkz43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9\n" +
+      "tTEv2dB8Xfjea4MYeDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL\n" +
+      "/bscVjby/rK25Xa71SJlpz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlV\n" +
+      "g3sslgf/WSxEo8bl6ancoWOAWiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6\n" +
+      "tkD9xOQ14R0WHNC8K47Wcdk=\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // AddTrust_Public_Services_Root.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJT\n" +
+      "RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRU\n" +
+      "UCBOZXR3b3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAe\n" +
+      "Fw0wMDA1MzAxMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNF\n" +
+      "MRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQ\n" +
+      "IE5ldHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIB\n" +
+      "IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+\n" +
+      "A3S72mnTRqX4jsIMEZBRpS9mVEBV6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c\n" +
+      "+OLspoH4IcUkzBEMP9smcnrHAZcHF/nXGCwwfQ56HmIexkvA/X1id9NEHif2\n" +
+      "P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnPdzRGULD4EfL+OHn3Bzn+UZKX\n" +
+      "C1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH1lWfl2royBFkuucZKT8R\n" +
+      "s3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF62WUaUC6wNW0uLp9\n" +
+      "BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQWBBSBPjfYkrAf\n" +
+      "d59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zCB\n" +
+      "jgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDELMAkG\n" +
+      "A1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU\n" +
+      "cnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENB\n" +
+      "IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmu\n" +
+      "G7jD8WS6IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL\n" +
+      "+YPoRNWyQSW/iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbj\n" +
+      "PGsye/Kf8Lb93/AoGEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bY\n" +
+      "GozH7ZxOmuASu7VqTITh4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6\n" +
+      "NVDFSMwGR+gn2HCNX2TmoUQmXiLsks3/QppEIW1cxeMiHV9HEufOX1362Kqx\n" +
+      "My3ZdvJOOjMMK7MtkAY=\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // AddTrust_Qualified_Certificates_Root.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJT\n" +
+      "RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRU\n" +
+      "UCBOZXR3b3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9v\n" +
+      "dDAeFw0wMDA1MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYT\n" +
+      "AlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3Qg\n" +
+      "VFRQIE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBS\n" +
+      "b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoek\n" +
+      "n0e+EV+vhDTbYjx5eLfpMLXsDBwqxBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKk\n" +
+      "IhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G87B4pfYOQnrjfxvM0PC3KP0q6p6z\n" +
+      "sLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i2O+tCBGaKZnhqkRFmhJePp1t\n" +
+      "UvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8UWfyEk9mHfExUE+uf0S0R\n" +
+      "+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c10cIDMzZbdSZtQvES\n" +
+      "a0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0GA1UdDgQWBBQ5\n" +
+      "lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw\n" +
+      "AwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6FrpGkw\n" +
+      "ZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL\n" +
+      "ExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVh\n" +
+      "bGlmaWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2Vh\n" +
+      "lRO6aQTvhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxG\n" +
+      "GuoYQ992zPlmhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx9\n" +
+      "5dr6h+sNNVJn0J6XdgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKF\n" +
+      "Yqa0p9m9N5xotS1WfbC3P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVA\n" +
+      "wRv1cEWw3F369nJad9Jjzc9YiQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQw\n" +
+      "dOUeqN48Jzd/g66ed8/wMLH/S5noxqE=\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // America_Online_Root_Certification_Authority_1.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJV\n" +
+      "UzEcMBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1l\n" +
+      "cmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4X\n" +
+      "DTAyMDUyODA2MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkGA1UEBhMCVVMx\n" +
+      "HDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJp\n" +
+      "Y2EgT25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIw\n" +
+      "DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCa\n" +
+      "xlCyfqXfaE0bfA+2l2h9LaaLl+lkhsmj76CGv2BlnEtUiMJIxUo5vxTjWVXl\n" +
+      "GbR0yLQFOVwWpeKVBeASrlmLojNoWBym1BW32J/X3HGrfpq/m44zDyL9Hy7n\n" +
+      "BzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsWOqMFf6Dch9Wc/HKpoH145Lcx\n" +
+      "VR5lu9RhsCFg7RAycsWSJR74kEoYeEfffjA3PlAb2xzTa5qGUwew76wGePiE\n" +
+      "mf4hjUyAtgyC9mZweRrTT6PP8c9GsEsPPt2IYriMqQkoO3rHl+Ee5fSfwMCu\n" +
+      "JKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAdBgNV\n" +
+      "HQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAUAK3Zo/Z5\n" +
+      "9m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUA\n" +
+      "A4IBAQB8itEfGDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkF\n" +
+      "Zu90821fnZmv9ov761KyBZiibyrFVL0lvV+uyIbqRizBs73B6UlwGBaXCBOM\n" +
+      "IOAbLjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft3OJvx8Fi8eNy1gTI\n" +
+      "dGcL+oiroQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43g\n" +
+      "Kd8hdIaC2y+CMMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j\n" +
+      "8uB9Gr784N/Xx6dssPmuujz9dLQR6FgNgLzTqIA6me11zEZ7\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // America_Online_Root_Certification_Authority_2.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJV\n" +
+      "UzEcMBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1l\n" +
+      "cmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4X\n" +
+      "DTAyMDUyODA2MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkGA1UEBhMCVVMx\n" +
+      "HDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJp\n" +
+      "Y2EgT25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIw\n" +
+      "DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssN\n" +
+      "t79Hc9PwVU3dxgz6sWYFas14tNwC206B89enfHG8dWOgXeMHDEjsJcQDIPT/\n" +
+      "DjsS/5uN4cbVG7RtIuOx238hZK+GvFciKtZHgVdEglZTvYYUAQv8f3SkWq7x\n" +
+      "uhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2JxhP7JsowtS013wMPgwr38oE\n" +
+      "18aO6lhOqKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9BoInLRBYBbV4Bbkv2wxr\n" +
+      "kJB+FFk4u5QkE+XRnRTf04JNRvCAOVIyD+OEsnpD8l7eXz8d3eOyG6ChKiMD\n" +
+      "bi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0gBe4lL8BPeraunzgWGcX\n" +
+      "uVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67Xnfn6KVu\n" +
+      "Y8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEqZ8A9\n" +
+      "W6Wa6897GqidFEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZ\n" +
+      "o2C7HK2JNDJiuEMhBnIMoVxtRsX6Kc8w3onccVvdtjc+31D1uAclJuW8tf48\n" +
+      "ArO3+L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnjB453cMor9H124Hhn\n" +
+      "AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3Op\n" +
+      "aaEg5+31IqEjFNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNee\n" +
+      "MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypL\n" +
+      "M7PmG2tZTiLMubekJcmnxPBUlgtk87FYT15R/LKXeydlwuXK5w0MJXti4/qf\n" +
+      "tIe3RUavg6WXSIylvfEWK5t2LHo1YGwRgJfMqZJS5ivmae2p+DYtLHe/YUjR\n" +
+      "Ywu5W1LtGLBDQiKmsXeu3mnFzcccobGlHBD7GL4acN3Bkku+KVqdPzW+5X1R\n" +
+      "+FXgJXUjhx5c3LqdsKyzadsXg8n33gy8CNyRnqjQ1xU3c6U1uPx+xURABsPr\n" +
+      "+CKAXEfOAuMRn0T//ZoyzH1kUQ7rVyZ2OuMeIjzCpjbdGe+n/BLzJsBZMYVM\n" +
+      "nNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgOZtMADjMSW7yV5TKQqLPGbIOt\n" +
+      "d+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2FAjgQ5ANh1NolNscI\n" +
+      "WC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUXOm/9riW99XJZ\n" +
+      "ZLF0KjhfGEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPbAZO1XB4Y\n" +
+      "3WRayhgoPmMEEf0cjQAPuDffZ4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQlZvqz\n" +
+      "2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuPcX/9XhmgD0uRuMRUvAaw\n" +
+      "RY8mkaKO/qk=\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Baltimore_CyberTrust_Code_Signing_Root.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDpjCCAo6gAwIBAgIEAgAAvzANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQG\n" +
+      "EwJJRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0\n" +
+      "MS8wLQYDVQQDEyZCYWx0aW1vcmUgQ3liZXJUcnVzdCBDb2RlIFNpZ25pbmcg\n" +
+      "Um9vdDAeFw0wMDA1MTcxNDAxMDBaFw0yNTA1MTcyMzU5MDBaMGcxCzAJBgNV\n" +
+      "BAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1\n" +
+      "c3QxLzAtBgNVBAMTJkJhbHRpbW9yZSBDeWJlclRydXN0IENvZGUgU2lnbmlu\n" +
+      "ZyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyHGaGBKO\n" +
+      "etv5mvxBr9jy9AmOrT/+Zzc82skmULGxPsvoTnMA8rLc88VG+wnvGJbOp+Cc\n" +
+      "hF0gDnqgqjaL+ii2eC6z7OhH8wTwkCO06q/lU7gF90ddK4bxp6TGOzW20g1S\n" +
+      "Qdf0knXhogpQVoe+lwt7M4UQuSgY7jPqSBHXW5FHdiLU7s9d56hOHJ2Wkd2c\n" +
+      "vXQJqHJhqrAhOvE9LANWCdLB3MO1x1Q3q+YmorJGcXPKEYjuvOdk99ARGnNA\n" +
+      "WshJLA+375B/aIAEOAsbDzvU9aCzwo7hNLSAmW2edtSSKUCxldI3pGcSf+Bi\n" +
+      "u641xZk2gkS45ngYM2Fxk1stjZ94lYLrbQIDAQABo1owWDATBgNVHSUEDDAK\n" +
+      "BggrBgEFBQcDAzAdBgNVHQ4EFgQUyEE0XBUVBOVA8tGrmm8kknqHQlowEgYD\n" +
+      "VR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEF\n" +
+      "BQADggEBAFJ0qpVLIozHPZak/l36L7W86/AL6VY4HdFtDaG8aIvwxYClJDT9\n" +
+      "8pYYEYahNvU351RA1WQfw19wQmstOceeUgXO52py0o1yP0dQg6vHjSXJsOOn\n" +
+      "UxaVpmpT6hidj3ipd3ca+bSXR1mIJyi1yuEu1z4Oog24IkQD49FjsEE6ofWk\n" +
+      "Lfd2HgRUmXgyQNcrfE26ppyweW4Hvozs7tc4aVvBDFZon/7r0eHIiPnyzX++\n" +
+      "hbREZwBQPvQmA2Tqd33oXj4cN0fI1uqk8zY8l8I5cgWUGSXD1zdBD8Efh4r9\n" +
+      "qr7psWRX5NuSoc/hSeg7H5ETWsOP2SVYSYBHD8YDrqzjv7fAqio=\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Baltimore_CyberTrust_Mobile_Commerce_Root.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIICfTCCAeagAwIBAgIEAgAAuDANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG\n" +
+      "EwJJRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0\n" +
+      "MSkwJwYDVQQDEyBCYWx0aW1vcmUgQ3liZXJUcnVzdCBNb2JpbGUgUm9vdDAe\n" +
+      "Fw0wMDA1MTIxODIwMDBaFw0yMDA1MTIyMzU5MDBaMGExCzAJBgNVBAYTAklF\n" +
+      "MRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxKTAn\n" +
+      "BgNVBAMTIEJhbHRpbW9yZSBDeWJlclRydXN0IE1vYmlsZSBSb290MIGfMA0G\n" +
+      "CSqGSIb3DQEBAQUAA4GNADCBiQKBgQCjbbE4Vqz8tVYh3sCQXSZHgsZ9jx+g\n" +
+      "hY8vu9ThHB3yJB8osC+5pKVvoiIgZP6ERzx+K2xparjUwJaOjFINzW9B1L8E\n" +
+      "rqeBLy2YSNLBlKO1GV1dUWT0jkGwm8AtIqBexthaEmO8EUpeJhId4iYF5g9f\n" +
+      "Ih96X3aUrs9aKA6rRdoiMQIDAQABo0IwQDAdBgNVHQ4EFgQUyeKPwAImWrbA\n" +
+      "B+N/lAcY2y6lmnAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw\n" +
+      "DQYJKoZIhvcNAQEFBQADgYEAUwgLJgl4QnPU7Hp3Rw3jCzNx764zFE37+v0a\n" +
+      "t1H15JkcBnHXKRnX5hUgUVFGbU/eGEmY0Ph4u3HojQEG1ddkj5TfR/6ghWk2\n" +
+      "qS9CemhKEtaLC3BECqQE7yaIwTVxOF0bW0hC8OeUHHCVNKir9avieK318FL9\n" +
+      "m+pCDOjYVL5TZvU=\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Baltimore_CyberTrust_Root.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQG\n" +
+      "EwJJRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0\n" +
+      "MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUx\n" +
+      "MjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNV\n" +
+      "BAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZ\n" +
+      "QmFsdGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQAD\n" +
+      "ggEPADCCAQoCggEBAKMEuyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+h\n" +
+      "Xe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gR\n" +
+      "QKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/CG9VwcPCP\n" +
+      "wBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1\n" +
+      "pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNT\n" +
+      "Px8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkC\n" +
+      "AwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1BE3wMBIGA1Ud\n" +
+      "EwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUA\n" +
+      "A4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkT\n" +
+      "I7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx\n" +
+      "jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/\n" +
+      "oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67\n" +
+      "G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H\n" +
+      "RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Digital_Signature_Trust_Co._Global_CA_1.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDKTCCApKgAwIBAgIENnAVljANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQG\n" +
+      "EwJVUzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREw\n" +
+      "DwYDVQQLEwhEU1RDQSBFMTAeFw05ODEyMTAxODEwMjNaFw0xODEyMTAxODQw\n" +
+      "MjNaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVy\n" +
+      "ZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUxMIGdMA0GCSqGSIb3DQEB\n" +
+      "AQUAA4GLADCBhwKBgQCgbIGpzzQeJN3+hijM3oMv+V7UQtLodGBmE5gGHKlR\n" +
+      "EmlvMVW5SXIACH7TpWJENySZj9mDSI+ZbZUTu0M7LklOiDfBu1h//uG9+Lth\n" +
+      "zfNHwJmm8fOR6Hh8AMthyUQncWlVSn5JTe2io74CTADKAqjuAQIxZA9SLRN0\n" +
+      "dja1erQtcQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBoBgNVHR8E\n" +
+      "YTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwg\n" +
+      "U2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTExDTALBgNV\n" +
+      "BAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5ODEyMTAxODEwMjNagQ8yMDE4MTIx\n" +
+      "MDE4MTAyM1owCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFGp5fpFpRhgTCgJ3\n" +
+      "pVlbYJglDqL4MB0GA1UdDgQWBBRqeX6RaUYYEwoCd6VZW2CYJQ6i+DAMBgNV\n" +
+      "HRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3\n" +
+      "DQEBBQUAA4GBACIS2Hod3IEGtgllsofIH160L+nEHvI8wbsEkBFKg05+k7lN\n" +
+      "QseSJqBcNJo4cvj9axY+IO6CizEqkzaFI4iKPANo08kJD038bKTaKHKTDomA\n" +
+      "sH3+gG9lbRgzl4vCa4nuYD3Im+9/KzJic5PLPON74nZ4RbyhkwS7hp86W0N6\n" +
+      "w4pl\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Digital_Signature_Trust_Co._Global_CA_2.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIID2DCCAsACEQDQHkCLAAACfAAAAAIAAAABMA0GCSqGSIb3DQEBBQUAMIGp\n" +
+      "MQswCQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBM\n" +
+      "YWtlIENpdHkxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENv\n" +
+      "LjERMA8GA1UECxMIRFNUQ0EgWDExFjAUBgNVBAMTDURTVCBSb290Q0EgWDEx\n" +
+      "ITAfBgkqhkiG9w0BCQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTAeFw05ODEyMDEx\n" +
+      "ODE4NTVaFw0wODExMjgxODE4NTVaMIGpMQswCQYDVQQGEwJ1czENMAsGA1UE\n" +
+      "CBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkxJDAiBgNVBAoTG0Rp\n" +
+      "Z2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgWDEx\n" +
+      "FjAUBgNVBAMTDURTVCBSb290Q0EgWDExITAfBgkqhkiG9w0BCQEWEmNhQGRp\n" +
+      "Z3NpZ3RydXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n" +
+      "ANLGJrbnpT3BxGjVUG9TxW9JEwm4ryxIjRRqoxdfWvnTLnUv2Chi0ZMv/E3U\n" +
+      "q4flCMeZ55I/db3rJbQVwZsZPdJEjdd0IG03Ao9pk1uKxBmd9LIO/BZsubEF\n" +
+      "koPRhSxglD5FVaDZqwgh5mDoO3TymVBRaNADLbGAvqPYUrBEzUNKcI5YhZXh\n" +
+      "TizWLUFv1oTnyJhEykfbLCSlaSbPa7gnYsP0yXqSI+0TZ4KuRS5F5X5yP4Wd\n" +
+      "lGIQ5jyRoa13AOAV7POEgHJ6jm5gl8ckWRA0g1vhpaRptlc1HHhZxtMvOnNn\n" +
+      "7pTKBBMFYgZwI7P0fO5F2WQLW0mqpEPOJsREEmy43XkCAwEAATANBgkqhkiG\n" +
+      "9w0BAQUFAAOCAQEAojeyP2n714Z5VEkxlTMr89EJFEliYIalsBHiUMIdBlc+\n" +
+      "LegzZL6bqq1fG03UmZWii5rJYnK1aerZWKs17RWiQ9a2vAd5ZWRzfdd5ynvV\n" +
+      "WlHG4VMElo04z6MXrDlxawHDi1M8Y+nuecDkvpIyZHqzH5eUYr3qsiAVlfuX\n" +
+      "8ngvYzZAOONGDx3drJXK50uQe7FLqdTF65raqtWjlBRGjS0f8zrWkzr2Pnn8\n" +
+      "6Oawde3uPclwx12qgUtGJRzHbBXjlU4PqjI3lAoXJJIThFjSY28r9+ZbYgsT\n" +
+      "F7ANUkz+/m9c4pFuHf2kYtdo+o56T9II2pPc8JIRetDccpMMc5NihWjQ9A==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Digital_Signature_Trust_Co._Global_CA_3.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDKTCCApKgAwIBAgIENm7TzjANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQG\n" +
+      "EwJVUzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREw\n" +
+      "DwYDVQQLEwhEU1RDQSBFMjAeFw05ODEyMDkxOTE3MjZaFw0xODEyMDkxOTQ3\n" +
+      "MjZaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVy\n" +
+      "ZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUyMIGdMA0GCSqGSIb3DQEB\n" +
+      "AQUAA4GLADCBhwKBgQC/k48Xku8zExjrEH9OFr//Bo8qhbxe+SSmJIi2A7fB\n" +
+      "w18DW9Fvrn5C6mYjuGODVvsoLeE4i7TuqAHhzhy2iCoiRoX7n6dwqUcUP87e\n" +
+      "ZfCocfdPJmyMvMa1795JJ/9IKn3oTQPMx7JSxhcxEzu1TdvIxPbDDyQq2gyd\n" +
+      "55FbgM2UnQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBoBgNVHR8E\n" +
+      "YTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwg\n" +
+      "U2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTIxDTALBgNV\n" +
+      "BAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5ODEyMDkxOTE3MjZagQ8yMDE4MTIw\n" +
+      "OTE5MTcyNlowCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFB6CTShlgDzJQW6s\n" +
+      "NS5ay97u+DlbMB0GA1UdDgQWBBQegk0oZYA8yUFurDUuWsve7vg5WzAMBgNV\n" +
+      "HRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3\n" +
+      "DQEBBQUAA4GBAEeNg61i8tuwnkUiBbmi1gMOOHLnnvx75pO2mqWilMg0HZHR\n" +
+      "xdf0CiUPPXiBng+xZ8SQTGPdXqfiup/1902lMXucKS1M/mQ+7LZT/uqb7YLb\n" +
+      "dHVLB3luHtgZg3Pe9T7Qtd7nS2h9Qy4qIOF+oHhEngj1mPnHfxsb1gYgAlih\n" +
+      "w6ID\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Digital_Signature_Trust_Co._Global_CA_4.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIID2DCCAsACEQDQHkCLAAB3bQAAAAEAAAAEMA0GCSqGSIb3DQEBBQUAMIGp\n" +
+      "MQswCQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBM\n" +
+      "YWtlIENpdHkxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENv\n" +
+      "LjERMA8GA1UECxMIRFNUQ0EgWDIxFjAUBgNVBAMTDURTVCBSb290Q0EgWDIx\n" +
+      "ITAfBgkqhkiG9w0BCQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTAeFw05ODExMzAy\n" +
+      "MjQ2MTZaFw0wODExMjcyMjQ2MTZaMIGpMQswCQYDVQQGEwJ1czENMAsGA1UE\n" +
+      "CBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkxJDAiBgNVBAoTG0Rp\n" +
+      "Z2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgWDIx\n" +
+      "FjAUBgNVBAMTDURTVCBSb290Q0EgWDIxITAfBgkqhkiG9w0BCQEWEmNhQGRp\n" +
+      "Z3NpZ3RydXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n" +
+      "ANx18IzAdZaawGIfJvfE4Zrq4FZzW5nNAUSoCLbVp9oaBBg5kkp4o4HC9Xd6\n" +
+      "ULRw/5qrxsfKboNPQpj7Jgva3G3WqZlVUmfpKAOS3OWwBZoPFflrWXJW8vo5\n" +
+      "/Kpo7g8fEIMv/J36F5bdguPmRX3AS4BEH+0s4IT9kVySVGkl5WJp3OXuAFK9\n" +
+      "MwutdQKFp2RQLcUZGTDAJtvJ0/0uma1ZtQtN1EGuhUhDWdy3qOKi3sOP17ih\n" +
+      "YqZoUFLkzzGnlIXan0YyF1bl8utmPRL/Q9uY73fPy4GNNLHGUEom0eQ+QVCv\n" +
+      "bK4iNC7Va26Dunm4dmVI2gkpZGMiuftHdoWMhkTLCdsCAwEAATANBgkqhkiG\n" +
+      "9w0BAQUFAAOCAQEAtTYOXeFhKFoRZcA/gwN5Tb4opgsHAlKFzfiR0BBstWog\n" +
+      "WxyQ2TA8xkieil5k+aFxd+8EJx8H6+Qm93N0yUQYGmbT4EOvkTvRyyzYdFQ6\n" +
+      "HE3K1GjNI3wdEJ5F6fYAbqbNGf9PLCmPV03Ed5K+4EwJ+11EhmYhqLkyolbV\n" +
+      "6YyDfFk/xPEL553snr2cGA4+wjl5KLcDDQjLxufZATdQEOzMYRZA1K8xdHv8\n" +
+      "PzGn0EdzMzkbzE5q10mDEQb+64JYMzJM8FasHpwvVpp7wUocpf1VNs78lk30\n" +
+      "sPDst2yC7S8xmUJMqbINuBVd8d+6ybVK1GSYsyapMMj9puyrliGtf8J4tg==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Entrust.net_Global_Secure_Personal_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIEgzCCA+ygAwIBAgIEOJ725DANBgkqhkiG9w0BAQQFADCBtDEUMBIGA1UE\n" +
+      "ChMLRW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9HQ0NB\n" +
+      "X0NQUyBpbmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsT\n" +
+      "HChjKSAyMDAwIEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1\n" +
+      "c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMDAy\n" +
+      "MDcxNjE2NDBaFw0yMDAyMDcxNjQ2NDBaMIG0MRQwEgYDVQQKEwtFbnRydXN0\n" +
+      "Lm5ldDFAMD4GA1UECxQ3d3d3LmVudHJ1c3QubmV0L0dDQ0FfQ1BTIGluY29y\n" +
+      "cC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDIwMDAg\n" +
+      "RW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xp\n" +
+      "ZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA\n" +
+      "A4GNADCBiQKBgQCTdLS25MVL1qFof2LV7PdRV7NySpj10InJrWPNTTVRaoTU\n" +
+      "rcloeW+46xHbh65cJFET8VQlhK8pK5/jgOLZy93GRUk0iJBeAZfv6lOm3fzB\n" +
+      "3ksqJeTpNfpVBQbliXrqpBFXO/x8PTbNZzVtpKklWb1m9fkn5JVn1j+SgF7y\n" +
+      "NH0rhQIDAQABo4IBnjCCAZowEQYJYIZIAYb4QgEBBAQDAgAHMIHdBgNVHR8E\n" +
+      "gdUwgdIwgc+ggcyggcmkgcYwgcMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUAw\n" +
+      "PgYDVQQLFDd3d3cuZW50cnVzdC5uZXQvR0NDQV9DUFMgaW5jb3JwLiBieSBy\n" +
+      "ZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMjAwMCBFbnRydXN0\n" +
+      "Lm5ldCBMaW1pdGVkMTMwMQYDVQQDEypFbnRydXN0Lm5ldCBDbGllbnQgQ2Vy\n" +
+      "dGlmaWNhdGlvbiBBdXRob3JpdHkxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw\n" +
+      "IoAPMjAwMDAyMDcxNjE2NDBagQ8yMDIwMDIwNzE2NDY0MFowCwYDVR0PBAQD\n" +
+      "AgEGMB8GA1UdIwQYMBaAFISLdP3FjcD/J20gN0V8/i3OutN9MB0GA1UdDgQW\n" +
+      "BBSEi3T9xY3A/ydtIDdFfP4tzrrTfTAMBgNVHRMEBTADAQH/MB0GCSqGSIb2\n" +
+      "fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQQFAAOBgQBObzWA\n" +
+      "O9GK9Q6nIMstZVXQkvTnhLUGJoMShAusO7JE7r3PQNsgDrpuFOow4DtifH+L\n" +
+      "a3xKp9U1PL6oXOpLu5OOgGarDyn9TS2/GpsKkMWr2tGzhtQvJFJcem3G8v7l\n" +
+      "TRowjJDyutdKPkN+1MhQGof4T4HHdguEOnKdzmVml64mXg==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Entrust.net_Global_Secure_Server_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIElTCCA/6gAwIBAgIEOJsRPDANBgkqhkiG9w0BAQQFADCBujEUMBIGA1UE\n" +
+      "ChMLRW50cnVzdC5uZXQxPzA9BgNVBAsUNnd3dy5lbnRydXN0Lm5ldC9TU0xf\n" +
+      "Q1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc\n" +
+      "KGMpIDIwMDAgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVz\n" +
+      "dC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe\n" +
+      "Fw0wMDAyMDQxNzIwMDBaFw0yMDAyMDQxNzUwMDBaMIG6MRQwEgYDVQQKEwtF\n" +
+      "bnRydXN0Lm5ldDE/MD0GA1UECxQ2d3d3LmVudHJ1c3QubmV0L1NTTF9DUFMg\n" +
+      "aW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykg\n" +
+      "MjAwMCBFbnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5l\n" +
+      "dCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0G\n" +
+      "CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHwV9OcfHO8GCGD9JYf9Mzly0XonUw\n" +
+      "tZZkJi9ow0SrqHXmAGc0V55lxyKbc+bT3QgON1WqJUaBbL3+qPZ1V1eMkGxK\n" +
+      "wz6LS0MKyRFWmponIpnPVZ5h2QLifLZ8OAfc439PmrkDQYC2dWcTC5/oVzbI\n" +
+      "XQA23mYU2m52H083jIITiQIDAQABo4IBpDCCAaAwEQYJYIZIAYb4QgEBBAQD\n" +
+      "AgAHMIHjBgNVHR8EgdswgdgwgdWggdKggc+kgcwwgckxFDASBgNVBAoTC0Vu\n" +
+      "dHJ1c3QubmV0MT8wPQYDVQQLFDZ3d3cuZW50cnVzdC5uZXQvU1NMX0NQUyBp\n" +
+      "bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAy\n" +
+      "MDAwIEVudHJ1c3QubmV0IExpbWl0ZWQxOjA4BgNVBAMTMUVudHJ1c3QubmV0\n" +
+      "IFNlY3VyZSBTZXJ2ZXIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxDTALBgNV\n" +
+      "BAMTBENSTDEwKwYDVR0QBCQwIoAPMjAwMDAyMDQxNzIwMDBagQ8yMDIwMDIw\n" +
+      "NDE3NTAwMFowCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFMtswGvjuz7L/CKc\n" +
+      "/vuLkpyw8m4iMB0GA1UdDgQWBBTLbMBr47s+y/winP77i5KcsPJuIjAMBgNV\n" +
+      "HRMEBTADAQH/MB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkq\n" +
+      "hkiG9w0BAQQFAAOBgQBi24GRzsiad0Iv7L0no1MPUBvqTpLwqa+poLpIYcvv\n" +
+      "yQbvH9X07t9WLebKahlzqlO+krNQAraFJnJj2HVQYnUUt7NQGj/KEQALhUVp\n" +
+      "bbalrlHhStyCP2yMNLJ3a9kC9n8O6mUE8c1UyrrJzOCE98g+EZfTYAkYvAX/\n" +
+      "bIkz8OwVDw==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Entrust.net_Premium_2048_Secure_Server_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UE\n" +
+      "ChMLRW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNf\n" +
+      "MjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsT\n" +
+      "HChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1\n" +
+      "c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEy\n" +
+      "MjQxNzUwNTFaFw0xOTEyMjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0\n" +
+      "Lm5ldDFAMD4GA1UECxQ3d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29y\n" +
+      "cC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkg\n" +
+      "RW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2Vy\n" +
+      "dGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEF\n" +
+      "AAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4\n" +
+      "QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/EC\n" +
+      "DNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuXMlBvPci6Zgzj\n" +
+      "/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzWnLLP\n" +
+      "KQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZd\n" +
+      "enoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH\n" +
+      "4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB\n" +
+      "0RGAvtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJ\n" +
+      "FrlwMB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0B\n" +
+      "AQUFAAOCAQEAWUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFh\n" +
+      "fGPjK50xA3B20qMooPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVU\n" +
+      "KcgF7bISKo30Axv/55IQh7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaoho\n" +
+      "wXkCIryqptau37AUX7iH0N18f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2\n" +
+      "+z7pnIkPFc4YsIV4IU9rTw76NmfNB/L/CNDi3tm/Kq+4h4YhPATKt5Rof888\n" +
+      "6ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVyvUxFnmG6v4SBkgPR0ml8xQ==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Entrust.net_Secure_Personal_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UE\n" +
+      "BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50\n" +
+      "cnVzdC5uZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBs\n" +
+      "aW1pdHMgbGlhYi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExp\n" +
+      "bWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0\n" +
+      "aW9uIEF1dGhvcml0eTAeFw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBa\n" +
+      "MIHJMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNV\n" +
+      "BAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5mby9DUFMgaW5jb3Jw\n" +
+      "LiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMpIDE5OTkgRW50\n" +
+      "cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50\n" +
+      "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GL\n" +
+      "ADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo6oT9n3V5z8GKUZSv\n" +
+      "x1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux5zDeg7K6PvHV\n" +
+      "iTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zmAqTmT173\n" +
+      "iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSCARkw\n" +
+      "ggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50\n" +
+      "cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0Ff\n" +
+      "SW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UE\n" +
+      "CxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50\n" +
+      "cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYD\n" +
+      "VQQDEwRDUkwxMCygKqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9D\n" +
+      "bGllbnQxLmNybDArBgNVHRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkx\n" +
+      "MDEyMTkyNDMwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW\n" +
+      "/O5bs8qZdIuV6kwwHQYDVR0OBBYEFMT7nCl7l81MlvzuW7PKmXSLlepMMAwG\n" +
+      "A1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI\n" +
+      "hvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7pFuPeJoSSJn59DXeDDYHAmsQ\n" +
+      "OokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzzwy5E97BnRqqS5TvaHBkU\n" +
+      "ODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/aEkP/TOYGJqibGapE\n" +
+      "PHayXOw=\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Entrust.net_Secure_Server_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UE\n" +
+      "BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50\n" +
+      "cnVzdC5uZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl\n" +
+      "MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UE\n" +
+      "AxMxRW50cnVzdC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1\n" +
+      "dGhvcml0eTAeFw05OTA1MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQsw\n" +
+      "CQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3\n" +
+      "dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlh\n" +
+      "Yi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVkMTow\n" +
+      "OAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp\n" +
+      "b24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQDNKIM0\n" +
+      "VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/I0dNxScZgSYMVHIN\n" +
+      "iC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3wkrYKZImZNHk\n" +
+      "mGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OCAdcwggHT\n" +
+      "MBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHboIHY\n" +
+      "pIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5\n" +
+      "BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChs\n" +
+      "aW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBM\n" +
+      "aW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENl\n" +
+      "cnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNo\n" +
+      "dHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAi\n" +
+      "gA8xOTk5MDUyNTE2MDk0MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMC\n" +
+      "AQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYE\n" +
+      "FPAXYhNVPbP/CgBr+1CEl/PtYtAaMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9\n" +
+      "B0EABAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEFBQADgYEAkNwwAvpkdMKn\n" +
+      "CqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN95K+8cPV1ZVqBLssziY2Zcgx\n" +
+      "xufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd2cNgQ4xYDiKWL2KjLB+6\n" +
+      "rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Equifax_Secure_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG\n" +
+      "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1\n" +
+      "cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4\n" +
+      "MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgx\n" +
+      "LTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0\n" +
+      "eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2R\n" +
+      "FGiYCh7+2gRvE4RiIcPRfM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO\n" +
+      "/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuv\n" +
+      "K9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAGA1UdHwRp\n" +
+      "MGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEt\n" +
+      "MCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5\n" +
+      "MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjAL\n" +
+      "BgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gjIBBPM5iQn9Qw\n" +
+      "HQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMBAf8w\n" +
+      "GgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GB\n" +
+      "AFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y\n" +
+      "7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2u\n" +
+      "FHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Equifax_Secure_Global_eBusiness_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJV\n" +
+      "UzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1\n" +
+      "aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0\n" +
+      "MDAwMFoXDTIwMDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoT\n" +
+      "E0VxdWlmYXggU2VjdXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJl\n" +
+      "IEdsb2JhbCBlQnVzaW5lc3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw\n" +
+      "gYkCgYEAuucXkAJlsTRVPEnCUdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQy\n" +
+      "td4zjTov2/KaelpzmKNc6fuKcxtc58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORR\n" +
+      "OhI8bIpaVIRw28HFkM9yRcuoWcDNM50/o5brhTMhHD4ePmBudpxnhcXIw2EC\n" +
+      "AwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAHMA8GA1UdEwEB/wQFMAMBAf8w\n" +
+      "HwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0OBBYEFL6o\n" +
+      "oHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUAA4GBADDiAVGqx+pf\n" +
+      "2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkAZ70Br83gcfxa\n" +
+      "z2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv8qIYNMR1\n" +
+      "pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Equifax_Secure_eBusiness_CA_1.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJV\n" +
+      "UzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1\n" +
+      "aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcN\n" +
+      "MjAwNjIxMDQwMDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZh\n" +
+      "eCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2lu\n" +
+      "ZXNzIENBLTEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fe\n" +
+      "k6lfWg0XTzQaDJj0ItlZ1MRoRvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5\n" +
+      "/VGcqiTZ9J2DKocKIdMSODRsjQBuWqDZQu4aIZX5UkxVWsUPOE9G+m34LjXW\n" +
+      "HXzr4vCwdYDIqROsvojvOm6rXyo4YgKwEnv+j6YDAgMBAAGjZjBkMBEGCWCG\n" +
+      "SAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEp4\n" +
+      "MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRKeDJSEdtZFjZe38EUNkBq\n" +
+      "R3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZMzfmpTMANmvPMZWnm\n" +
+      "JXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+WB5Hh1Q+WKG1\n" +
+      "tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN/Bf+KpYr\n" +
+      "tWKmpj29f5JZzVoqgrI3eQ==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Equifax_Secure_eBusiness_CA_2.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG\n" +
+      "EwJVUzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlm\n" +
+      "YXggU2VjdXJlIGVCdXNpbmVzcyBDQS0yMB4XDTk5MDYyMzEyMTQ0NVoXDTE5\n" +
+      "MDYyMzEyMTQ0NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkVxdWlmYXgg\n" +
+      "U2VjdXJlMSYwJAYDVQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0Et\n" +
+      "MjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF\n" +
+      "7Y6yEb3+6+e0dMKP/wXn2Z0GvxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKD\n" +
+      "pkWNYmi7hRsgcDKqQM2mll/EcTc/BPO3QSQ5BxoeLmFYoBIL5aXfxavqN3HM\n" +
+      "HMg3OrmXUqesxWoklE6ce8/AatbfIb0CAwEAAaOCAQkwggEFMHAGA1UdHwRp\n" +
+      "MGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORXF1aWZheCBT\n" +
+      "ZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0y\n" +
+      "MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTkwNjIzMTIxNDQ1WjAL\n" +
+      "BgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9euSBIplBqy/3YIHqngnYw\n" +
+      "HQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQFMAMBAf8w\n" +
+      "GgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GB\n" +
+      "AAyGgq3oThr1jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy\n" +
+      "0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkt\n" +
+      "y3D1E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUmV+GRMOrN\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // GTE_CyberTrust_Global_Root.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgw\n" +
+      "FgYDVQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRy\n" +
+      "dXN0IFNvbHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3Qg\n" +
+      "R2xvYmFsIFJvb3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEzMjM1OTAwWjB1\n" +
+      "MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYD\n" +
+      "VQQLEx5HVEUgQ3liZXJUcnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMT\n" +
+      "GkdURSBDeWJlclRydXN0IEdsb2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUA\n" +
+      "A4GNADCBiQKBgQCVD6C28FCc6HrHiM3dFw4usJTQGz0O9pTAipTHBsiQl8i4\n" +
+      "ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTSr41tiGeA5u2ylc9yMcqlHHK6XALn\n" +
+      "ZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X404Wqk2kmhXBIgD8SFcd5tB8F\n" +
+      "LztimQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAG3rGwnpXtlR22ciYaQqPEh3\n" +
+      "46B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l93PR2VX2bY1QY6fDq\n" +
+      "81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0PlZPvy5TYnh+d\n" +
+      "XIVtx6quTx8itc2VrbqnzPmrC3p/\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // GTE_CyberTrust_Root_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIB+jCCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgw\n" +
+      "FgYDVQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRy\n" +
+      "dXN0IFJvb3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQsw\n" +
+      "CQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQD\n" +
+      "ExNHVEUgQ3liZXJUcnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB\n" +
+      "iQKBgQC45k+625h8cXyvRLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8K\n" +
+      "DPufpz+iCWaEVh43KRuH6X4MypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPw\n" +
+      "KfWVWgkWYXcKIiXUT0Wqx73llt/51KiOQswkwB6RJ0q1bQaAYznEol44AwID\n" +
+      "AQABMA0GCSqGSIb3DQEBBAUAA4GBABKzdcZfHeFhVYAA1IFLezEPI2PnPfMD\n" +
+      "+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWlIjeaY8JIILTbcuPI9tl8vrGv\n" +
+      "U9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9ApybW1EDp3zdHSo1TRJ6V6e\n" +
+      "6bR64eVaH4QwnNOfpSXY\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // GeoTrust_Global_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYT\n" +
+      "AlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVz\n" +
+      "dCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBC\n" +
+      "MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UE\n" +
+      "AxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\n" +
+      "MIIBCgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEH\n" +
+      "CIjaWC9mOSm9BXiLnTjoBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlC\n" +
+      "GDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet8u5fa9IAjbkU+BQVNdnARqN7\n" +
+      "csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+VcT4wt/lAj\n" +
+      "Nvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdRe\n" +
+      "JivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQAB\n" +
+      "o1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9\n" +
+      "qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1luMrMTjANBgkq\n" +
+      "hkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Qzxpe\n" +
+      "R+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWV\n" +
+      "Yrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF\n" +
+      "PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot\n" +
+      "2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeX\n" +
+      "xx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm\n" +
+      "Mw==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // GlobalSign_Root_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDdTCCAl2gAwIBAgILAgAAAAAA1ni3lAUwDQYJKoZIhvcNAQEEBQAwVzEL\n" +
+      "MAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNV\n" +
+      "BAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05\n" +
+      "ODA5MDExMjAwMDBaFw0xNDAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkw\n" +
+      "FwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRsw\n" +
+      "GQYDVQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUA\n" +
+      "A4IBDwAwggEKAoIBAQDaDuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR\n" +
+      "4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc\n" +
+      "71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4\n" +
+      "bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgK\n" +
+      "OOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMW\n" +
+      "ea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DP\n" +
+      "AgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIABjAdBgNVHQ4EFgQUYHtmGkUNl8qJ\n" +
+      "UC99BM00qP/8/UswDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOC\n" +
+      "AQEArqqf/LfSyx9fOSkoGJ40yWxPbxrwZKJwSk8ThptgKJ7ogUmYfQq75bCd\n" +
+      "PTbbjwVR/wkxKh/diXeeDy5slQTthsu0AD+EAk2AaioteAuubyuig0SDH81Q\n" +
+      "gkwkr733pbTIWg/050deSY43lv6aiAU62cDbKYfmGZZHpzqmjIs8d/5GY6dT\n" +
+      "2iHRrH5Jokvmw2dZL7OKDrssvamqQnw1wdh/1acxOk5jQzmvCLBhNIzTmKlD\n" +
+      "NPYPhyk7ncJWWJh3w/cbrPad+D6qp1RF8PX51TFl/mtYnHGzHtdS6jIX/EBg\n" +
+      "Hcl5JLL2bP2oZg6C3ZjL2sJETy6ge/L3ayx2EYRGinij4w==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // RSA_Root_Certificate_1.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlD\n" +
+      "ZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu\n" +
+      "Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMgUG9saWN5IFZhbGlkYXRp\n" +
+      "b24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNv\n" +
+      "bS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYy\n" +
+      "NjAwMjIzM1oXDTE5MDYyNjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0\n" +
+      "IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4x\n" +
+      "NTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMgUG9saWN5IFZhbGlkYXRpb24g\n" +
+      "QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8x\n" +
+      "IDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3\n" +
+      "DQEBAQUAA4GNADCBiQKBgQDjmFGWHOjVsQaBalfDcnWTq8+epvzzFlLWLU2f\n" +
+      "NUSoLgRNB0mKOCn1dzfnt6td3zZxFJmP3MKS8edgkpfs2Ejcv8ECIMYkpChM\n" +
+      "MFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89HBFx1cQqYJJgpp0lZpd34\n" +
+      "t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliEZwgs3x/b\n" +
+      "e0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJn0Wu\n" +
+      "PIqpsHEzXcjFV9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/A\n" +
+      "PhmcGcwTTYJBtYze4D1gCCAPRX5ron+jjBXu\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // RSA_Security_1024_v3.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIICXDCCAcWgAwIBAgIQCgEBAQAAAnwAAAALAAAAAjANBgkqhkiG9w0BAQUF\n" +
+      "ADA6MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0Eg\n" +
+      "U2VjdXJpdHkgMTAyNCBWMzAeFw0wMTAyMjIyMTAxNDlaFw0yNjAyMjIyMDAx\n" +
+      "NDlaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJT\n" +
+      "QSBTZWN1cml0eSAxMDI0IFYzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n" +
+      "gQDV3f5mCc8kPD6ugU5OisRpgFtZO9+5TUzKtS3DJy08rwBCbbwoppbPf9dY\n" +
+      "rIMKo1W1exeQFYRMiu4mmdxY78c4pqqv0I5CyGLXq6yp+0p9v+r+Ek3d/yYt\n" +
+      "bzZUaMjShFbuklNhCbM/OZuoyZu9zp9+1BlqFikYvtc6adwlWzMaUQIDAQAB\n" +
+      "o2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSME\n" +
+      "GDAWgBTEwBykB5T9zU0B1FTapQxf3q4FWjAdBgNVHQ4EFgQUxMAcpAeU/c1N\n" +
+      "AdRU2qUMX96uBVowDQYJKoZIhvcNAQEFBQADgYEAPy1q4yZDlX2Jl2X7deRy\n" +
+      "HUZXxGFraZ8SmyzVWujAovBDleMf6XbN3Ou8k6BlCsdNT1+nr6JGFLkM88y9\n" +
+      "am63nd4lQtBU/55oc2PcJOsiv6hy8l4A4Q1OOkNumU4/iXgDmMrzVcydro7B\n" +
+      "qkWY+o8aoI2II/EVQQ2lRj6RP4vr93E=\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // RSA_Security_2048_v3.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUF\n" +
+      "ADA6MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0Eg\n" +
+      "U2VjdXJpdHkgMjA0OCBWMzAeFw0wMTAyMjIyMDM5MjNaFw0yNjAyMjIyMDM5\n" +
+      "MjNaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJT\n" +
+      "QSBTZWN1cml0eSAyMDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n" +
+      "CgKCAQEAt49VcdKA3XtpeafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37\n" +
+      "RqtBaB4Y6lXIL5F4iSj7Jylg/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E\n" +
+      "0S1PRsNO3Ng3OTsor8udGuorryGlwSMiuLgbWhOHV4PR8CDn6E8jQrAApX2J\n" +
+      "6elhc5SYcSa8LWrg903w8bYqODGBDSnhAMFRD0xS+ARaqn1y07iHKrtjEAMq\n" +
+      "s6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2PcYJk5qjEoAAVZkZR73QpXzD\n" +
+      "uvsf9/UP+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpuAWgXIszACwIDAQABo2Mw\n" +
+      "YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAW\n" +
+      "gBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4EFgQUB8NRMKSq6UWuNST6\n" +
+      "/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYcHnmYv/3V\n" +
+      "EhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/Zb5g\n" +
+      "EydxiKRz44Rj0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+\n" +
+      "f00/FGj1EVDVwfSQpQgdMWD/YIwjVAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJq\n" +
+      "aHVOrSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395nzIlQnQFgCi/vcEk\n" +
+      "llgVsRch6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kA\n" +
+      "pKnXwiJPZ9d37CAFYd4=\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // TC_TrustCenter__Germany__Class_2_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDXDCCAsWgAwIBAgICA+owDQYJKoZIhvcNAQEEBQAwgbwxCzAJBgNVBAYT\n" +
+      "AkRFMRAwDgYDVQQIEwdIYW1idXJnMRAwDgYDVQQHEwdIYW1idXJnMTowOAYD\n" +
+      "VQQKEzFUQyBUcnVzdENlbnRlciBmb3IgU2VjdXJpdHkgaW4gRGF0YSBOZXR3\n" +
+      "b3JrcyBHbWJIMSIwIAYDVQQLExlUQyBUcnVzdENlbnRlciBDbGFzcyAyIENB\n" +
+      "MSkwJwYJKoZIhvcNAQkBFhpjZXJ0aWZpY2F0ZUB0cnVzdGNlbnRlci5kZTAe\n" +
+      "Fw05ODAzMDkxMTU5NTlaFw0xMTAxMDExMTU5NTlaMIG8MQswCQYDVQQGEwJE\n" +
+      "RTEQMA4GA1UECBMHSGFtYnVyZzEQMA4GA1UEBxMHSGFtYnVyZzE6MDgGA1UE\n" +
+      "ChMxVEMgVHJ1c3RDZW50ZXIgZm9yIFNlY3VyaXR5IGluIERhdGEgTmV0d29y\n" +
+      "a3MgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTEp\n" +
+      "MCcGCSqGSIb3DQEJARYaY2VydGlmaWNhdGVAdHJ1c3RjZW50ZXIuZGUwgZ8w\n" +
+      "DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANo46O0yAClxgwENv4wB3NrGrTmk\n" +
+      "qYov1YtcaF9QxmL1Zr3KkSLsqh1R1z2zUbKDTl3LSbDwTFXlay3HhQswHJJO\n" +
+      "gtTKAu33b77c4OMUuAVT8pr0VotanoWT0bSCVq5Nu6hLVxa8/vhYnvgpjbB7\n" +
+      "zXjJT6yLZwzxnPv8V5tXXE8NAgMBAAGjazBpMA8GA1UdEwEB/wQFMAMBAf8w\n" +
+      "DgYDVR0PAQH/BAQDAgGGMDMGCWCGSAGG+EIBCAQmFiRodHRwOi8vd3d3LnRy\n" +
+      "dXN0Y2VudGVyLmRlL2d1aWRlbGluZXMwEQYJYIZIAYb4QgEBBAQDAgAHMA0G\n" +
+      "CSqGSIb3DQEBBAUAA4GBAIRS+yjf/x91AbwBvgRWl2p0QiQxg/lGsQaKic+W\n" +
+      "LDO/jLVfenKhhQbOhvgFjuj5Jcrag4wGrOs2bYWRNAQ29ELw+HkuCkhcq8xR\n" +
+      "T3h2oNmsGb0q0WkEKJHKNhAngFdb0lz1wlurZIFjdFH0l7/NEij3TWZ/p/Ac\n" +
+      "ASZ4smZHcFFk\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // TC_TrustCenter__Germany__Class_3_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDXDCCAsWgAwIBAgICA+swDQYJKoZIhvcNAQEEBQAwgbwxCzAJBgNVBAYT\n" +
+      "AkRFMRAwDgYDVQQIEwdIYW1idXJnMRAwDgYDVQQHEwdIYW1idXJnMTowOAYD\n" +
+      "VQQKEzFUQyBUcnVzdENlbnRlciBmb3IgU2VjdXJpdHkgaW4gRGF0YSBOZXR3\n" +
+      "b3JrcyBHbWJIMSIwIAYDVQQLExlUQyBUcnVzdENlbnRlciBDbGFzcyAzIENB\n" +
+      "MSkwJwYJKoZIhvcNAQkBFhpjZXJ0aWZpY2F0ZUB0cnVzdGNlbnRlci5kZTAe\n" +
+      "Fw05ODAzMDkxMTU5NTlaFw0xMTAxMDExMTU5NTlaMIG8MQswCQYDVQQGEwJE\n" +
+      "RTEQMA4GA1UECBMHSGFtYnVyZzEQMA4GA1UEBxMHSGFtYnVyZzE6MDgGA1UE\n" +
+      "ChMxVEMgVHJ1c3RDZW50ZXIgZm9yIFNlY3VyaXR5IGluIERhdGEgTmV0d29y\n" +
+      "a3MgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTEp\n" +
+      "MCcGCSqGSIb3DQEJARYaY2VydGlmaWNhdGVAdHJ1c3RjZW50ZXIuZGUwgZ8w\n" +
+      "DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALa0wTUFLg2N7KBAahwOJ6ZQkmtQ\n" +
+      "GwfeLud2zODa/ISoXoxjaitN2U4CdhHBC/KNecoAtvGwDtf7pBc9r6tpepYn\n" +
+      "v68zoZoqWarEtTcI8hKlMbZD9TKWcSgoq40oht+77uMMfTDWw1Krj10nnGvA\n" +
+      "o+cFa1dJRLNu6mTP0o56UHd3AgMBAAGjazBpMA8GA1UdEwEB/wQFMAMBAf8w\n" +
+      "DgYDVR0PAQH/BAQDAgGGMDMGCWCGSAGG+EIBCAQmFiRodHRwOi8vd3d3LnRy\n" +
+      "dXN0Y2VudGVyLmRlL2d1aWRlbGluZXMwEQYJYIZIAYb4QgEBBAQDAgAHMA0G\n" +
+      "CSqGSIb3DQEBBAUAA4GBABY9xs3Bu4VxhUafPiCPUSiZ7C1FIWMjWwS7TJC4\n" +
+      "iJIETb19AaM/9uzO8d7+feXhPrvGq14L3T2WxMup1Pkm5gZOngylerpuw3yC\n" +
+      "GdHHsbHD2w2Om0B8NwvxXej9H5CIpQ5ON2QhqE6NtJ/x3kit1VYYUimLRzQS\n" +
+      "CdS7kjXvD9s0\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Thawte_Personal_Basic_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDITCCAoqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCByzELMAkGA1UEBhMC\n" +
+      "WkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3du\n" +
+      "MRowGAYDVQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlm\n" +
+      "aWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFBl\n" +
+      "cnNvbmFsIEJhc2ljIENBMSgwJgYJKoZIhvcNAQkBFhlwZXJzb25hbC1iYXNp\n" +
+      "Y0B0aGF3dGUuY29tMB4XDTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVow\n" +
+      "gcsxCzAJBgNVBAYTAlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNV\n" +
+      "BAcTCUNhcGUgVG93bjEaMBgGA1UEChMRVGhhd3RlIENvbnN1bHRpbmcxKDAm\n" +
+      "BgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24xITAfBgNV\n" +
+      "BAMTGFRoYXd0ZSBQZXJzb25hbCBCYXNpYyBDQTEoMCYGCSqGSIb3DQEJARYZ\n" +
+      "cGVyc29uYWwtYmFzaWNAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOB\n" +
+      "jQAwgYkCgYEAvLyTU23AUE+CFeZIlDWmWr5vQvoPR+53dXLdjUmbllegeNTK\n" +
+      "P1GzaQuRdhciB5dqxFGTS+CN7zeVoQxN2jSQHReJl+A1OFdKwPQIcOk8RHtQ\n" +
+      "fmGakOMj04gRRif1CwcOu93RfyAKiLlWCy4cgNrx454p7xS9CkT7G1sY0b8j\n" +
+      "kyECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOB\n" +
+      "gQAt4plrsD16iddZopQBHyvdEktTwq1/qqcAXJFAVyVKOKqEcLnZgA+le1z7\n" +
+      "c8a914phXAPjLSeoF+CEhULcXpvGt7Jtu3Sv5D/Lp7ew4F2+eIMllNLbgQ95\n" +
+      "B21P9DkVWlIBe94y1k049hJcBlDfBVu9FEuh3ym6O0GN92NWod8isQ==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Thawte_Personal_Freemail_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDLTCCApagAwIBAgIBADANBgkqhkiG9w0BAQQFADCB0TELMAkGA1UEBhMC\n" +
+      "WkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3du\n" +
+      "MRowGAYDVQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlm\n" +
+      "aWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEkMCIGA1UEAxMbVGhhd3RlIFBl\n" +
+      "cnNvbmFsIEZyZWVtYWlsIENBMSswKQYJKoZIhvcNAQkBFhxwZXJzb25hbC1m\n" +
+      "cmVlbWFpbEB0aGF3dGUuY29tMB4XDTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIz\n" +
+      "NTk1OVowgdExCzAJBgNVBAYTAlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUx\n" +
+      "EjAQBgNVBAcTCUNhcGUgVG93bjEaMBgGA1UEChMRVGhhd3RlIENvbnN1bHRp\n" +
+      "bmcxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24x\n" +
+      "JDAiBgNVBAMTG1RoYXd0ZSBQZXJzb25hbCBGcmVlbWFpbCBDQTErMCkGCSqG\n" +
+      "SIb3DQEJARYccGVyc29uYWwtZnJlZW1haWxAdGhhd3RlLmNvbTCBnzANBgkq\n" +
+      "hkiG9w0BAQEFAAOBjQAwgYkCgYEA1GnX1LCUZFtx6UfYDFG26nKRsIRefS0N\n" +
+      "j3sS34UldSh0OkIsYyeflXtL734Zhx2G6qPduc6WZBrCFG5ErHzmj+hND3Ef\n" +
+      "QDimAKOHePb5lIZererAXnbr2RSjXW56fAylS1V/Bhkpf56aJtVquzgkCGqY\n" +
+      "x7Hao5iR/Xnb5VrEHLkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq\n" +
+      "hkiG9w0BAQQFAAOBgQDH7JJ+Tvj1lqVnYiqk8E0RYNBvjWBYYawmu1I1XAjP\n" +
+      "MPuoSpaKH2JCI4wXD/S6ZJwXrEcp352YXtJsYHFcoqzceePnbgBHH7UNKOgC\n" +
+      "neSa/RP0ptl8sfjcXyMmCZGAc9AUG95DqYMl8uacLxXK/qarigd1iwzdUYRr\n" +
+      "5PjRzneigQ==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Thawte_Personal_Premium_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDKTCCApKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBzzELMAkGA1UEBhMC\n" +
+      "WkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3du\n" +
+      "MRowGAYDVQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlm\n" +
+      "aWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEjMCEGA1UEAxMaVGhhd3RlIFBl\n" +
+      "cnNvbmFsIFByZW1pdW0gQ0ExKjAoBgkqhkiG9w0BCQEWG3BlcnNvbmFsLXBy\n" +
+      "ZW1pdW1AdGhhd3RlLmNvbTAeFw05NjAxMDEwMDAwMDBaFw0yMDEyMzEyMzU5\n" +
+      "NTlaMIHPMQswCQYDVQQGEwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIw\n" +
+      "EAYDVQQHEwlDYXBlIFRvd24xGjAYBgNVBAoTEVRoYXd0ZSBDb25zdWx0aW5n\n" +
+      "MSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMSMw\n" +
+      "IQYDVQQDExpUaGF3dGUgUGVyc29uYWwgUHJlbWl1bSBDQTEqMCgGCSqGSIb3\n" +
+      "DQEJARYbcGVyc29uYWwtcHJlbWl1bUB0aGF3dGUuY29tMIGfMA0GCSqGSIb3\n" +
+      "DQEBAQUAA4GNADCBiQKBgQDJZtn4B0TPuYwu8KHvE0VsBd/eJxZRNkERbGw7\n" +
+      "7f4QfRKe5ZtCmv5gMcNmt3M6SK5O0DI3lIi1DbbZ8/JE2dWIEt12TfIa/G8j\n" +
+      "Hnrx2JhFTgcQ7xZC0EN1bUre4qrJMf8fAHB8Zs8QJQi6+u4A6UYDZicRFTuq\n" +
+      "W/KY3TZCstqIdQIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3\n" +
+      "DQEBBAUAA4GBAGk2ifc0KjNyL2071CKyuG+axTZmDhs8obF1Wub9NdP4qPIH\n" +
+      "b4Vnjt4rueIXsDqg8A6iAJrf8xQVbrvIhVqYgPn/vnQdPfP+MCXRNzRn+qVx\n" +
+      "eTBhKXLA4CxM+1bkOqhv5TJZUtt1KFBZDPgLGeSs2a+WjS9Q2wfD6h+rM+D1\n" +
+      "KzGJ\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Thawte_Premium_Server_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMC\n" +
+      "WkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3du\n" +
+      "MR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2Vy\n" +
+      "dGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3Rl\n" +
+      "IFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNl\n" +
+      "cnZlckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1\n" +
+      "OVowgc4xCzAJBgNVBAYTAlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQ\n" +
+      "BgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMUVGhhd3RlIENvbnN1bHRpbmcg\n" +
+      "Y2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24x\n" +
+      "ITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3\n" +
+      "DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0B\n" +
+      "AQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhI\n" +
+      "NTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQug2SBhRz1JPL\n" +
+      "lyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMRuHM/qgeN\n" +
+      "9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B\n" +
+      "AQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI\n" +
+      "hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZ\n" +
+      "a4JMpAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcU\n" +
+      "Qg==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Thawte_Server_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMC\n" +
+      "WkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3du\n" +
+      "MR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2Vy\n" +
+      "dGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3Rl\n" +
+      "IFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0\n" +
+      "ZS5jb20wHhcNOTYwODAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkG\n" +
+      "A1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2Fw\n" +
+      "ZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UE\n" +
+      "CxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQ\n" +
+      "VGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRz\n" +
+      "QHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANOkUG7I\n" +
+      "/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91yekIYfUGbTBuFRkC\n" +
+      "6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCXL+eQbcAoQpnX\n" +
+      "TEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGjEzARMA8G\n" +
+      "A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG7oWD\n" +
+      "TSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e\n" +
+      "QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdni\n" +
+      "TCxZqdq5snUb9kLy78fyGPmJvKP/iiMucEc=\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Thawte_Time_Stamping_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIICoTCCAgqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBizELMAkGA1UEBhMC\n" +
+      "WkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIGA1UEBxMLRHVyYmFudmls\n" +
+      "bGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhhd3RlIENlcnRpZmlj\n" +
+      "YXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcgQ0EwHhcNOTcw\n" +
+      "MTAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBizELMAkGA1UEBhMCWkExFTAT\n" +
+      "BgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzAN\n" +
+      "BgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24x\n" +
+      "HzAdBgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcgQ0EwgZ8wDQYJKoZIhvcN\n" +
+      "AQEBBQADgY0AMIGJAoGBANYrWHhhRYZT6jR7UZztsOYuGA7+4F+oJ9O0yeB8\n" +
+      "WU4WDnNUYMF/9p8u6TqFJBU820cEY8OexJQaWt9MevPZQx08EHp5JduQ/vBR\n" +
+      "5zDWQQD9nyjfeb6Uu522FOMjhdepQeBMpHmwKxqL8vg7ij5FrHGSALSQQZj7\n" +
+      "X+36ty6K+Ig3AgMBAAGjEzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN\n" +
+      "AQEEBQADgYEAZ9viwuaHPUCDhjc1fR/OmsMMZiCouqoEiYbC9RAIDb/LogWK\n" +
+      "0E02PvTX72nGXuSwlG9KuefeW4i2e9vjJ+V2w/A1wcu1J5szedyQpgCed/r8\n" +
+      "zSeUQhac0xxo7L9c3eWpexAKMnRUEzGLhQOEkbdYATAUOK8oyvyxUBkZCayJ\n" +
+      "SdM=\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // UTN-USER_First-Network_Applications.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIEZDCCA0ygAwIBAgIQRL4Mi1AAJLQR0zYwS8AzdzANBgkqhkiG9w0BAQUF\n" +
+      "ADCBozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0\n" +
+      "IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEw\n" +
+      "HwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVU\n" +
+      "Ti1VU0VSRmlyc3QtTmV0d29yayBBcHBsaWNhdGlvbnMwHhcNOTkwNzA5MTg0\n" +
+      "ODM5WhcNMTkwNzA5MTg1NzQ5WjCBozELMAkGA1UEBhMCVVMxCzAJBgNVBAgT\n" +
+      "AlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVT\n" +
+      "RVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVz\n" +
+      "dC5jb20xKzApBgNVBAMTIlVUTi1VU0VSRmlyc3QtTmV0d29yayBBcHBsaWNh\n" +
+      "dGlvbnMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCz+5Gh5DZV\n" +
+      "hawGNFugmliy+LUPBXeDrjKxdpJo7CNKyXY/45y2N3kDuatpjQclthln5LAb\n" +
+      "GHNhSuh+zdMvZOOmfAz6F4CjDUeJT1FxL+78P/m4FoCHiZMlIJpDgmkkdihZ\n" +
+      "NaEdwH+DBmQWICzTSaSFtMBhf1EI+GgVkYDLpdXuOzr0hAReYFmnjDRy7rh4\n" +
+      "xdE7EkpvfmUnuaRVxblvQ6TFHSyZwFKkeEwVs0CYCGtDxgGwenv1axwiP8vv\n" +
+      "/6jQOkt2FZ7S0cYu49tXGzKiuG/ohqY/cKvlcJKrRB5AUPuco2LkbG6gyN7i\n" +
+      "gEL66S/ozjIEj3yNtxyjNTwV3Z7DrpelAgMBAAGjgZEwgY4wCwYDVR0PBAQD\n" +
+      "AgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFPqGydvguul49Uuo1hXf\n" +
+      "8NPhahQ8ME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly9jcmwudXNlcnRydXN0\n" +
+      "LmNvbS9VVE4tVVNFUkZpcnN0LU5ldHdvcmtBcHBsaWNhdGlvbnMuY3JsMA0G\n" +
+      "CSqGSIb3DQEBBQUAA4IBAQCk8yXM0dSRgyLQzDKrm5ZONJFUICU0YV8qAhXh\n" +
+      "i6r/fWRRzwr/vH3YIWp4yy9Rb/hCHTO967V7lMPDqaAt39EpHx3+jz+7qEUq\n" +
+      "f9FuVSTiuwL7MT++6LzsQCv4AdRWOOTKRIK1YSAhZ2X28AvnNPilwpyjXEAf\n" +
+      "hZOVBt5P1CeptqX8Fs1zMT+4ZSfP1FMa8Kxun08FDAOBp4QpxFq9ZFdyrTvP\n" +
+      "NximmMatBrTcCKME1SmklpoSZ0qMYEWd8SOasACcaLWYUNPvji6SZbFIPiG+\n" +
+      "FTAqDbUMo2s/rn9X9R+WfN9v3YIwLGUbQErNaLly7HF27FSOH4UMAWr6pjis\n" +
+      "H8SE\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // ValiCert_Class_1_VA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlD\n" +
+      "ZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu\n" +
+      "Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEgUG9saWN5IFZhbGlkYXRp\n" +
+      "b24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNv\n" +
+      "bS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYy\n" +
+      "NTIyMjM0OFoXDTE5MDYyNTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0\n" +
+      "IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4x\n" +
+      "NTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEgUG9saWN5IFZhbGlkYXRpb24g\n" +
+      "QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8x\n" +
+      "IDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3\n" +
+      "DQEBAQUAA4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9YLqdUHAZu9OqNSLwxlBfw\n" +
+      "8068srg1knaw0KWlAdcAAxIiGQj4/xEjm84H9b9pGib+TunRf50sQB1ZaG6m\n" +
+      "+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCmDuJWBQ8YTfwggtFzVXSN\n" +
+      "dnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0LBwGlN+V\n" +
+      "YH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLWI8so\n" +
+      "gTLDAHkY7FkXicnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPw\n" +
+      "nXS3qT6gpf+2SQMT2iLM7XGCK5nPOrf1LXLI\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // ValiCert_Class_2_VA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlD\n" +
+      "ZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu\n" +
+      "Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRp\n" +
+      "b24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNv\n" +
+      "bS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYy\n" +
+      "NjAwMTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0\n" +
+      "IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4x\n" +
+      "NTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24g\n" +
+      "QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8x\n" +
+      "IDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3\n" +
+      "DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc\n" +
+      "65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQ\n" +
+      "b7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QSv4dk+NoS/zcn\n" +
+      "wbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZSWI4\n" +
+      "OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZ\n" +
+      "oDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC\n" +
+      "W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // ValiCert_OCSP_Responder.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDSDCCArGgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBsjEkMCIGA1UEBxMb\n" +
+      "VmFsaUNlcnQgVmFsaWRhdGlvbiBOZXR3b3JrMRcwFQYDVQQKEw5WYWxpQ2Vy\n" +
+      "dCwgSW5jLjEsMCoGA1UECxMjQ2xhc3MgMSBWYWxpZGF0aW9uIEF1dGhvcml0\n" +
+      "eSAtIE9DU1AxITAfBgNVBAMTGGh0dHA6Ly93d3cudmFsaWNlcnQubmV0LzEg\n" +
+      "MB4GCSqGSIb3DQEJARYRaW5mb0B2YWxpY2VydC5jb20wHhcNMDAwMjEyMTE1\n" +
+      "MDA1WhcNMDUwMjEwMTE1MDA1WjCBsjEkMCIGA1UEBxMbVmFsaUNlcnQgVmFs\n" +
+      "aWRhdGlvbiBOZXR3b3JrMRcwFQYDVQQKEw5WYWxpQ2VydCwgSW5jLjEsMCoG\n" +
+      "A1UECxMjQ2xhc3MgMSBWYWxpZGF0aW9uIEF1dGhvcml0eSAtIE9DU1AxITAf\n" +
+      "BgNVBAMTGGh0dHA6Ly93d3cudmFsaWNlcnQubmV0LzEgMB4GCSqGSIb3DQEJ\n" +
+      "ARYRaW5mb0B2YWxpY2VydC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ\n" +
+      "AoGBAMeML6fDQIc7PdfEmlgUZArDCDliGs/S66nxaXSKyg5adsyiUk7Q88R6\n" +
+      "tfimHLujp6RTh1uNwAC71WYk53TGFsivyANi1TKHolKRRJSVqEdDbaVInPZM\n" +
+      "ddVPYufJ/3v0JIynvCh2tTKgJXO3Ry94+Eb5hxTwd/wKd+hP/Ywf+mLZAgMB\n" +
+      "AAGjbDBqMA8GCSsGAQUFBzABBQQCBQAwEwYDVR0lBAwwCgYIKwYBBQUHAwkw\n" +
+      "CwYDVR0PBAQDAgGGMDUGCCsGAQUFBwEBBCkwJzAlBggrBgEFBQcwAYYZaHR0\n" +
+      "cDovL29jc3AyLnZhbGljZXJ0Lm5ldDANBgkqhkiG9w0BAQUFAAOBgQAVxeC4\n" +
+      "NHISBiCoYpWT0byTupCr3E6Njo2YTOMy9Ss/s5f7qqKtQJetaL1crVMO0Kaz\n" +
+      "DawamY2qMB7PDnD/ArB3ZYPN2gdcUs1Zu6LI4rQWg4/UlXmTLei/RJMxkjDT\n" +
+      "NDTxEPshrC70w11kY3qZ4ZqrQh1IZqZ3N7hVPK3+ZbBi6Q==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Verisign_Class_1_Public_Primary_Certification_Authority.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIICPTCCAaYCEQDNun9W8N/kvFT+IqyzcqpVMA0GCSqGSIb3DQEBAgUAMF8x\n" +
+      "CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UE\n" +
+      "CxMuQ2xhc3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv\n" +
+      "cml0eTAeFw05NjAxMjkwMDAwMDBaFw0yODA4MDEyMzU5NTlaMF8xCzAJBgNV\n" +
+      "BAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xh\n" +
+      "c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCB\n" +
+      "nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5Rm/baNWYS2ZSHH2Z965jeu3\n" +
+      "noaACpEO+jglr0aIguVzqKCbJF0NH8xlbgyw0FaEGIeaBpsQoXPftFg5a27B\n" +
+      "9hXVqKg/qhIGjTGsf7A01480Z4gJzRQR4k5FVmkfeAKA2txHkSm7NsljXMXg\n" +
+      "1y2He6G3MrB7MLoqLzGq7qNn2tsCAwEAATANBgkqhkiG9w0BAQIFAAOBgQBM\n" +
+      "P7iLxmjf7kMzDl3ppssHhE16M/+SG/Q2rdiVIjZoEWx8QszznC7EBz8UsA9P\n" +
+      "/5CSdvnivErpj82ggAr3xSnxgiJduLHdgSOjeyUVRjB5FvjqBUuUfx3CHMjj\n" +
+      "t/QQQDwTw18fU+hI5Ia0e6E1sHslurjTjqs/OJ0ANACY89FxlA==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Verisign_Class_1_Public_Primary_Certification_Authority_-_G2.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcEx\n" +
+      "CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UE\n" +
+      "CxMzQ2xhc3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv\n" +
+      "cml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAt\n" +
+      "IEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBU\n" +
+      "cnVzdCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVow\n" +
+      "gcExCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoG\n" +
+      "A1UECxMzQ2xhc3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1\n" +
+      "dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5j\n" +
+      "LiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2ln\n" +
+      "biBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCq\n" +
+      "0Lq+Fi24g9TK0g+8djHKlNgdk4xWArzZbxpvUjZudVYKVdPfQ4chEWWKfo+9\n" +
+      "Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIqWpDBucSmFc/IReumXY6c\n" +
+      "PvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQIDAQABMA0G\n" +
+      "CSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0Jh9Zr\n" +
+      "bWB85a7FkCMMXErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2ul\n" +
+      "uIncrKTdcu1OofdPvAbT6shkdHvClUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4i\n" +
+      "P/68DzFc6PLZ\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Verisign_Class_1_Public_Primary_Certification_Authority_-_G3.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHK\n" +
+      "MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNV\n" +
+      "BAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5\n" +
+      "IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBD\n" +
+      "BgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlm\n" +
+      "aWNhdGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3\n" +
+      "MTYyMzU5NTlaMIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24s\n" +
+      "IEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNV\n" +
+      "BAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQg\n" +
+      "dXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFBy\n" +
+      "aW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI\n" +
+      "hvcNAQEBBQADggEPADCCAQoCggEBAN2E1Lm0+afY8wR4nN493GwTFtl63SRR\n" +
+      "ZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/EbRrsC+MO8ESlV8dAWB6j\n" +
+      "Rx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjVojYJrKsh\n" +
+      "JlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjbPG7P\n" +
+      "oBMAGrgnoeS+Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP2\n" +
+      "6KbqxzcSXKMpHgLZ2x87tNcPVkeBFQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHh\n" +
+      "v2Vrn5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAq2aN17O6x5q25lXQ\n" +
+      "BfGfMY1aqtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/N\n" +
+      "y9Sn2WCVhDr4wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUf\n" +
+      "xJM8/XmPBNQ+T+r3ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFM\n" +
+      "DSZl4kSAHsef493oCtrspSCAaWihT37ha88HQfqDjrw43bAuEbFrskLMmrz5\n" +
+      "SCJ5ShkPshw+IHTZasO+8ih4E1Z5T21Q6huwtVexN2ZYI/PcD98Kh8TvhgXV\n" +
+      "OBRgmaNL3gaWcSzy27YfpO8/7g==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Verisign_Class_1_Public_Primary_OCSP_Responder.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDnjCCAwegAwIBAgIQK2jUo0aexTsoCas4XX8nIDANBgkqhkiG9w0BAQUF\n" +
+      "ADBfMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1\n" +
+      "BgNVBAsTLkNsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBB\n" +
+      "dXRob3JpdHkwHhcNMDAwODA0MDAwMDAwWhcNMDQwODAzMjM1OTU5WjCBpzEX\n" +
+      "MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy\n" +
+      "dXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczov\n" +
+      "L3d3dy52ZXJpc2lnbi5jb20vUlBBIChjKTAwMS4wLAYDVQQDEyVDbGFzcyAx\n" +
+      "IFB1YmxpYyBQcmltYXJ5IE9DU1AgUmVzcG9uZGVyMIGfMA0GCSqGSIb3DQEB\n" +
+      "AQUAA4GNADCBiQKBgQC57V56Ondfzl86UvzNZPdxtW9qlsZZklWUXS9bLsER\n" +
+      "6iaKy6eBPPZaRN56Ey/9WlHZezcmSsAnPwQDalbBgyzhb1upVFAkSsYuekyh\n" +
+      "WzdUJCExH6F4GHansXDaItBq/gdiQMb39pt9DAa4S8co5GYjhFHvRreT2IEz\n" +
+      "y+U2rMboBQIDAQABo4IBEDCCAQwwIAYDVR0RBBkwF6QVMBMxETAPBgNVBAMT\n" +
+      "CE9DU1AgMS0xMDEGA1UdHwQqMCgwJqAkoCKGIGh0dHA6Ly9jcmwudmVyaXNp\n" +
+      "Z24uY29tL3BjYTEuY3JsMBMGA1UdJQQMMAoGCCsGAQUFBwMJMEIGCCsGAQUF\n" +
+      "BwEBBDYwNDAyBggrBgEFBQcwAaYmFiRodHRwOi8vb2NzcC52ZXJpc2lnbi5j\n" +
+      "b20vb2NzcC9zdGF0dXMwRAYDVR0gBD0wOzA5BgtghkgBhvhFAQcBATAqMCgG\n" +
+      "CCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vUlBBMAkGA1Ud\n" +
+      "EwQCMAAwCwYDVR0PBAQDAgeAMA0GCSqGSIb3DQEBBQUAA4GBAHCQ3bjkvlMX\n" +
+      "fH8C6dX3i5mTMWCNfuZgayTvYKzSzpHegG0JpNO4OOVEynJeDS3Bd5y9LAN4\n" +
+      "KY2kpXeH9fErJq3MB2w6VFoo4AnzTQoEytRYaQuns/XdAaXn3PAfusFdkI2z\n" +
+      "6k/BEVmXarIrE7HarZehs7GgIFvKMquNzxPwHynD\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Verisign_Class_2_Public_Primary_Certification_Authority.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIICPDCCAaUCEC0b/EoXjaOR6+f/9YtFvgswDQYJKoZIhvcNAQECBQAwXzEL\n" +
+      "MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQL\n" +
+      "Ey5DbGFzcyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y\n" +
+      "aXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UE\n" +
+      "BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz\n" +
+      "cyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGf\n" +
+      "MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2WoujDWojg4BrzzmH9CETMwZM\n" +
+      "JaLtVRKXxaeAufqDwSCg+i8VDXyhYGt+eSz6Bg86rvYbb7HS/y8oUl+DfUvE\n" +
+      "erf4Zh+AVPy3wo5ZShRXRtGak75BkQO7FYCTXOvnzAhsPz6zSvz/S2wj1VCC\n" +
+      "JkQZjiPDceoZJEcEnnW/yKYAHwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBAIob\n" +
+      "K/o5wXTXXtgZZKJYSi034DNHD6zt96rbHuSLBlxgJ8pFUs4W7z8GZOeUaHxg\n" +
+      "MxURaa+dYo2jA1Rrpr7l7gUYYAS/QoD90KioHgE796Ncr6Pc5iaAIzy4RHT3\n" +
+      "Cq5Ji2F4zCS/iIqnDupzGUH9TQPwiNHleI2lKk/2lw0Xd8rY\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Verisign_Class_2_Public_Primary_Certification_Authority_-_G2.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHB\n" +
+      "MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNV\n" +
+      "BAsTM0NsYXNzIDIgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRo\n" +
+      "b3JpdHkgLSBHMjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNpZ24sIEluYy4g\n" +
+      "LSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24g\n" +
+      "VHJ1c3QgTmV0d29yazAeFw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTla\n" +
+      "MIHBMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6\n" +
+      "BgNVBAsTM0NsYXNzIDIgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBB\n" +
+      "dXRob3JpdHkgLSBHMjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNpZ24sIElu\n" +
+      "Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNp\n" +
+      "Z24gVHJ1c3QgTmV0d29yazCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA\n" +
+      "p4gBIXQs5xoD8JjhlzwPIQjxnNuX6Zr8wgQGE75fUsjMHiwSViy4AWkszJkf\n" +
+      "rbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRCwiNPStjwDqL7MWzJ5m+Z\n" +
+      "Jwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cCAwEAATAN\n" +
+      "BgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9jinb3/\n" +
+      "7aHmZuovCfTK1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAX\n" +
+      "rXfMSTWqz9iP0b63GJZHc2pUIjRkLbYWm1lbtFFZOrMLFPQS32eg9K0yZF6x\n" +
+      "RnInjBJ7xUS0rg==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Verisign_Class_2_Public_Primary_Certification_Authority_-_G3.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcox\n" +
+      "CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UE\n" +
+      "CxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkg\n" +
+      "VmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMG\n" +
+      "A1UEAxM8VmVyaVNpZ24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZp\n" +
+      "Y2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcx\n" +
+      "NjIzNTk1OVowgcoxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwg\n" +
+      "SW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UE\n" +
+      "CxMxKGMpIDE5OTkgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1\n" +
+      "c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMiBQdWJsaWMgUHJp\n" +
+      "bWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMIIBIjANBgkqhkiG\n" +
+      "9w0BAQEFAAOCAQ8AMIIBCgKCAQEArwoNwtUs22e5LeWUJ92lvuCwTY+zYVY8\n" +
+      "1nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6tW8UvxDOJxOeBUebMXoT\n" +
+      "2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUYwZF7C9UT\n" +
+      "AJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9okoqQ\n" +
+      "HgiBVrKtaaNS0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjN\n" +
+      "qWm6o+sdDZykIKbBoMXRRkwXbdKsZj+WjOCE1Db/IlnF+RFgqF8EffIa9iVC\n" +
+      "YQ/ESrg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0JhU8wI1NQ0kdvekh\n" +
+      "ktdmnLfexbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf\n" +
+      "0xwLRtxyID+u7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydE\n" +
+      "p85EXdQbkJgNHkKUsQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377B\n" +
+      "MnMiIYtYgXsVkXq642RIsH/7NiXaldDxJBQX3RiAa0YjOVT1jmIJBB2UkKab\n" +
+      "5iXiQkWquJCtvgiPqQtCGJTPcjnhsUPgKM+351psE2tJs//jGHyJizNdrDPX\n" +
+      "p/naOlXJWBD5qu9ats9LS98q\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Verisign_Class_2_Public_Primary_OCSP_Responder.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDnjCCAwegAwIBAgIQCUYX5h3Y1BygDKBi6HmKpzANBgkqhkiG9w0BAQUF\n" +
+      "ADBfMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1\n" +
+      "BgNVBAsTLkNsYXNzIDIgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBB\n" +
+      "dXRob3JpdHkwHhcNMDAwODAxMDAwMDAwWhcNMDQwNzMxMjM1OTU5WjCBpzEX\n" +
+      "MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy\n" +
+      "dXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczov\n" +
+      "L3d3dy52ZXJpc2lnbi5jb20vUlBBIChjKTAwMS4wLAYDVQQDEyVDbGFzcyAy\n" +
+      "IFB1YmxpYyBQcmltYXJ5IE9DU1AgUmVzcG9uZGVyMIGfMA0GCSqGSIb3DQEB\n" +
+      "AQUAA4GNADCBiQKBgQDQymMxYX9ENHwFfQs9apDLeUt3Cj9LxyPlwGItfpx+\n" +
+      "PoiHkdCs6E1Jh6KWkIrdBKUCP4yb6Yn+YqDiWr3I3bR45qVCkwhnAcAgTddc\n" +
+      "9F3as+M3plIaLExlTYqH2aij8UlUuzxcgFFoxvtJ/wtVqxXd+5rBuR10DbKM\n" +
+      "RF2J/J/5gwIDAQABo4IBEDCCAQwwIAYDVR0RBBkwF6QVMBMxETAPBgNVBAMT\n" +
+      "CE9DU1AgMS0yMDEGA1UdHwQqMCgwJqAkoCKGIGh0dHA6Ly9jcmwudmVyaXNp\n" +
+      "Z24uY29tL3BjYTIuY3JsMBMGA1UdJQQMMAoGCCsGAQUFBwMJMEIGCCsGAQUF\n" +
+      "BwEBBDYwNDAyBggrBgEFBQcwAaYmFiRodHRwOi8vb2NzcC52ZXJpc2lnbi5j\n" +
+      "b20vb2NzcC9zdGF0dXMwRAYDVR0gBD0wOzA5BgtghkgBhvhFAQcBATAqMCgG\n" +
+      "CCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vUlBBMAkGA1Ud\n" +
+      "EwQCMAAwCwYDVR0PBAQDAgeAMA0GCSqGSIb3DQEBBQUAA4GBAB99CW4kRnUE\n" +
+      "nPMmm+M5bhfvvL2iG9IChIar0ECXLMRDiDcZayKoA3FQnSDcNmAgmnMtc1Vs\n" +
+      "WJsswrQ0LHozQsqR2elDr88e4PXEeqs/cmMeqTfhWzuIsxOGgpBXy1f/9Fa+\n" +
+      "It3jl6jhvCJDwt1N2/aBnpIUnjkPE1TegtjAXjSN\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Verisign_Class_3_Public_Primary_Certification_Authority.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzEL\n" +
+      "MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQL\n" +
+      "Ey5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y\n" +
+      "aXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UE\n" +
+      "BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz\n" +
+      "cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGf\n" +
+      "MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69q\n" +
+      "RUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94f56TuZoAqiN91qyFomNFx3In\n" +
+      "zPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Olhec9vn2a\n" +
+      "/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBALtM\n" +
+      "EivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Dolbwdj2wsqFHMc9ikwFPw\n" +
+      "TtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNycAA9WjQKZ7aKQRUzk\n" +
+      "uxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Verisign_Class_3_Public_Primary_Certification_Authority_-_G2.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcEx\n" +
+      "CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UE\n" +
+      "CxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv\n" +
+      "cml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAt\n" +
+      "IEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBU\n" +
+      "cnVzdCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVow\n" +
+      "gcExCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoG\n" +
+      "A1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1\n" +
+      "dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5j\n" +
+      "LiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2ln\n" +
+      "biBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDM\n" +
+      "XtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXX\n" +
+      "wc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg013gfqLptQ5GV\n" +
+      "j0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQABMA0G\n" +
+      "CSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01U\n" +
+      "bSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i\n" +
+      "F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo\n" +
+      "1KpYoJ2daZH9\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Verisign_Class_3_Public_Primary_Certification_Authority_-_G3.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHK\n" +
+      "MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNV\n" +
+      "BAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5\n" +
+      "IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBD\n" +
+      "BgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlm\n" +
+      "aWNhdGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3\n" +
+      "MTYyMzU5NTlaMIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24s\n" +
+      "IEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNV\n" +
+      "BAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQg\n" +
+      "dXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFBy\n" +
+      "aW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI\n" +
+      "hvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2\n" +
+      "R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2tKmFZpGcmTNDo\n" +
+      "vFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUccLwg\n" +
+      "TS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+V\n" +
+      "k7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ\n" +
+      "Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJ\n" +
+      "OxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my\n" +
+      "/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f\n" +
+      "j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoA\n" +
+      "Wii/gt/4uhMdUIaC/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8S\n" +
+      "GhJouPtmmRQURVyu565pF4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbb\n" +
+      "o27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh\n" +
+      "/sVFuq1ruQp6Tk9LhO5L8X3dEQ==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Verisign_Class_3_Public_Primary_OCSP_Responder.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDojCCAwugAwIBAgIQLpaev7ZibOx76XPM42zBhDANBgkqhkiG9w0BAQUF\n" +
+      "ADBfMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1\n" +
+      "BgNVBAsTLkNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBB\n" +
+      "dXRob3JpdHkwHhcNMDAwODA0MDAwMDAwWhcNMDQwODAzMjM1OTU5WjCBpzEX\n" +
+      "MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy\n" +
+      "dXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczov\n" +
+      "L3d3dy52ZXJpc2lnbi5jb20vUlBBIChjKTAwMS4wLAYDVQQDEyVDbGFzcyAz\n" +
+      "IFB1YmxpYyBQcmltYXJ5IE9DU1AgUmVzcG9uZGVyMIGfMA0GCSqGSIb3DQEB\n" +
+      "AQUAA4GNADCBiQKBgQDx5AgOg7t140jluNum8Lmr6Txix141W9ACVBHYydFW\n" +
+      "uXZLuat65s269gwE1n7WsAplrE454/H3LaMlOe+wi8++2wxdbnD0B81w9zrA\n" +
+      "PjUW7XiMQ8/CJi5H1oZ9nPG+1mcMIiWkymXmH3p4KC8/BdsEIb/hRWb+PLeC\n" +
+      "7Vq4FhW5VQIDAQABo4IBFDCCARAwIAYDVR0RBBkwF6QVMBMxETAPBgNVBAMT\n" +
+      "CE9DU1AgMS0zMDUGA1UdHwQuMCwwKqAooCaGJGh0dHA6Ly9jcmwudmVyaXNp\n" +
+      "Z24uY29tL3BjYTMuMS4xLmNybDATBgNVHSUEDDAKBggrBgEFBQcDCTBCBggr\n" +
+      "BgEFBQcBAQQ2MDQwMgYIKwYBBQUHMAGmJhYkaHR0cDovL29jc3AudmVyaXNp\n" +
+      "Z24uY29tL29jc3Avc3RhdHVzMEQGA1UdIAQ9MDswOQYLYIZIAYb4RQEHAQEw\n" +
+      "KjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL1JQQTAJ\n" +
+      "BgNVHRMEAjAAMAsGA1UdDwQEAwIHgDANBgkqhkiG9w0BAQUFAAOBgQAC9lNj\n" +
+      "wKke8tCLMzCPSJtMsFa0g3FKvtxQ2PW24AvbvXhP6c8JNNopSZ0Bc1qRkYJU\n" +
+      "LBMK03cjzzf8Y96n4/a3tWlFKEnDkdyqRxypiJksBSqNjYr6YuJatwAgXTnE\n" +
+      "KMLL/J6oia5bPY4S6jKy/OsU1wkVGsDNG9W1FU5B1ZbjTg==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Verisign_Class_4_Public_Primary_Certification_Authority_-_G2.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDAjCCAmsCEDKIjprS9esTR/h/xCA3JfgwDQYJKoZIhvcNAQEFBQAwgcEx\n" +
+      "CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UE\n" +
+      "CxMzQ2xhc3MgNCBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv\n" +
+      "cml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAt\n" +
+      "IEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBU\n" +
+      "cnVzdCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVow\n" +
+      "gcExCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoG\n" +
+      "A1UECxMzQ2xhc3MgNCBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1\n" +
+      "dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5j\n" +
+      "LiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2ln\n" +
+      "biBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6\n" +
+      "8OTP+cSuhVS5B1f5j8V/aBH4xBewRNzjMHPVKmIquNDMHO0oW369atyzkSTK\n" +
+      "QWI8/AIBvxwWMZQFl3Zuoq29YRdsTjCG8FE3KlDHqGKB3FtKqsGgtG7rL+VX\n" +
+      "xbErQHDbWk2hjh+9Ax/YA9SPTJlxvOKCzFjomDqG04Y48wApHwIDAQABMA0G\n" +
+      "CSqGSIb3DQEBBQUAA4GBAIWMEsGnuVAVess+rLhDityq3RS6iYF+ATwjcSGI\n" +
+      "L4LcY/oCRaxFWdcqWERbt5+BO5JoPeI3JPV7bI92NZYJqFmduc4jq3TWg/0y\n" +
+      "cyfYaT5DdPauxYma51N86Xv2S/PBZYPejYqcPIiNOVn8qj8ijaHBZlCBckzt\n" +
+      "ImRPT8qAkbYp\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Verisign_Class_4_Public_Primary_Certification_Authority_-_G3.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHK\n" +
+      "MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNV\n" +
+      "BAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5\n" +
+      "IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBD\n" +
+      "BgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlm\n" +
+      "aWNhdGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3\n" +
+      "MTYyMzU5NTlaMIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24s\n" +
+      "IEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNV\n" +
+      "BAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQg\n" +
+      "dXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFBy\n" +
+      "aW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI\n" +
+      "hvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1GQ9Wzsy1HyDkniYl\n" +
+      "S+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ+mGuqPKljYXC\n" +
+      "KtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0GbdU6LM8BDc\n" +
+      "VHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLmNxdL\n" +
+      "MEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY\n" +
+      "ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDD\n" +
+      "Zq3/ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1Wr\n" +
+      "IhVZPMq1CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXtt\n" +
+      "mhwwjIDLk5Mqg6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csK\n" +
+      "vE+MW8VLADsfKoKmfjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluP\n" +
+      "QSjA1egtTaRezarZ7c7c2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kP\n" +
+      "mF6Z6PDQpLv1U70qzlmwr25/bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr\n" +
+      "9Xgn2uf3ZkPznoM+IKrDNWCRzg==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Verisign_RSA_Secure_Server_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIICNDCCAaECEAKtZn5ORf5eV288mBle3cAwDQYJKoZIhvcNAQECBQAwXzEL\n" +
+      "MAkGA1UEBhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMu\n" +
+      "MS4wLAYDVQQLEyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9y\n" +
+      "aXR5MB4XDTk0MTEwOTAwMDAwMFoXDTEwMDEwNzIzNTk1OVowXzELMAkGA1UE\n" +
+      "BhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYD\n" +
+      "VQQLEyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGb\n" +
+      "MA0GCSqGSIb3DQEBAQUAA4GJADCBhQJ+AJLOesGugz5aqomDV6wlAXYMra6O\n" +
+      "LDfO6zV4ZFQD5YRAUcm/jwjiioII0haGN1XpsSECrXZogZoFokvJSyVmIlZs\n" +
+      "iAeP94FZbYQHZXATcXY+m3dM41CJVphIuR2nKRoTLkoRWZweFdVJVCxzOmmC\n" +
+      "sZc5nG1wZ0jl3S3WyB57AgMBAAEwDQYJKoZIhvcNAQECBQADfgBl3X7hsuyw\n" +
+      "4jrg7HFGmhkRuNPHoLQDQCYCPgmc4RKz0Vr2N6W3YQO2WxZpO8ZECAyIUwxr\n" +
+      "l0nHPjXcbLm7qt9cuzovk2C2qUtN8iD3zV9/ZHuO3ABc1/p3yjkWWW8O6tO1\n" +
+      "g39NTUJWdrTJXwT4OPjr0l91X817/OWOgHz8UA==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Verisign_Secure_Server_OCSP_Responder.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDnzCCAwygAwIBAgIRAP9F1SddJPuzwjkkU1fhT94wDQYJKoZIhvcNAQEF\n" +
+      "BQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5\n" +
+      "LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24g\n" +
+      "QXV0aG9yaXR5MB4XDTAwMDgwNDAwMDAwMFoXDTA0MDgwMzIzNTk1OVowgZ4x\n" +
+      "FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU\n" +
+      "cnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQgaHR0cHM6\n" +
+      "Ly93d3cudmVyaXNpZ24uY29tL1JQQSAoYykwMDElMCMGA1UEAxMcU2VjdXJl\n" +
+      "IFNlcnZlciBPQ1NQIFJlc3BvbmRlcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAw\n" +
+      "gYkCgYEAuFGZZIUO7rMKaPC/Y3YdU/X8oXiMM+6f9L452psPTUepjyDoS0S9\n" +
+      "zs17kNEw6JDEJXuJKN699pMd/7n/krWpjeSuzOLDB4Nqo3IQASdiIqY1Jjkt\n" +
+      "ns9gDPxHpNfQQninHWzQy08VpykKtJVFxLHnWgnXOZXYHTWewr2zXcEMSx8C\n" +
+      "AwEAAaOCAR0wggEZMCAGA1UdEQQZMBekFTATMREwDwYDVQQDEwhPQ1NQIDEt\n" +
+      "NDA+BgNVHR8ENzA1MDOgMaAvhi1odHRwOi8vY3JsLnZlcmlzaWduLmNvbS9S\n" +
+      "U0FTZWN1cmVTZXJ2ZXItcC5jcmwwEwYDVR0lBAwwCgYIKwYBBQUHAwkwQgYI\n" +
+      "KwYBBQUHAQEENjA0MDIGCCsGAQUFBzABpiYWJGh0dHA6Ly9vY3NwLnZlcmlz\n" +
+      "aWduLmNvbS9vY3NwL3N0YXR1czBEBgNVHSAEPTA7MDkGC2CGSAGG+EUBBwEB\n" +
+      "MCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9SUEEw\n" +
+      "CQYDVR0TBAIwADALBgNVHQ8EBAMCB4AwDQYJKoZIhvcNAQEFBQADfgAAsxBT\n" +
+      "ZpxJky4xoAJC0lhXfmah/huKYRhQQCweK0Gl1tv/rAgcWgVtAlwqtpZPR9u+\n" +
+      "TtvOzLqGuBjOsRKRX2P380g+zPFNE+RtCZR4AJLLoyCdBgtqoEMHztEZbI8Y\n" +
+      "dZqfFzP9qSa44+LewqjEWop/mNYHBmvMVp6GcM7U7w==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Verisign_Time_Stamping_Authority_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDzTCCAzagAwIBAgIQU2GyYK7bcY6nlLMTM/QHCTANBgkqhkiG9w0BAQUF\n" +
+      "ADCBwTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTww\n" +
+      "OgYDVQQLEzNDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24g\n" +
+      "QXV0aG9yaXR5IC0gRzIxOjA4BgNVBAsTMShjKSAxOTk4IFZlcmlTaWduLCBJ\n" +
+      "bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAsTFlZlcmlT\n" +
+      "aWduIFRydXN0IE5ldHdvcmswHhcNMDAwOTI2MDAwMDAwWhcNMTAwOTI1MjM1\n" +
+      "OTU5WjCBpTEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl\n" +
+      "cmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBh\n" +
+      "dCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTAwMSwwKgYDVQQD\n" +
+      "EyNWZXJpU2lnbiBUaW1lIFN0YW1waW5nIEF1dGhvcml0eSBDQTCBnzANBgkq\n" +
+      "hkiG9w0BAQEFAAOBjQAwgYkCgYEA0hmdZ8IAIVlizrQJIkRpivglWtvtDbc2\n" +
+      "fk7gu5Q+kCWHwmFHKdm9VLhjzCx9abQzNvQ3B5rB3UBU/OB4naCTuQk9I1F/\n" +
+      "RMIUdNsKvsvJMDRAmD7Q1yUQgZS9B0+c1lQn3y6ov8uQjI11S7zi6ESHzeZB\n" +
+      "CiVu6PQkAsVSD27smHUCAwEAAaOB3zCB3DAPBgNVHRMECDAGAQH/AgEAMEUG\n" +
+      "A1UdIAQ+MDwwOgYMYIZIAYb4RQEHFwEDMCowKAYIKwYBBQUHAgEWHGh0dHBz\n" +
+      "Oi8vd3d3LnZlcmlzaWduLmNvbS9ycGEwMQYDVR0fBCowKDAmoCSgIoYgaHR0\n" +
+      "cDovL2NybC52ZXJpc2lnbi5jb20vcGNhMy5jcmwwCwYDVR0PBAQDAgEGMEIG\n" +
+      "CCsGAQUFBwEBBDYwNDAyBggrBgEFBQcwAaYmFiRodHRwOi8vb2NzcC52ZXJp\n" +
+      "c2lnbi5jb20vb2NzcC9zdGF0dXMwDQYJKoZIhvcNAQEFBQADgYEAgnBold+2\n" +
+      "DcIBcBlK0lRWHqzyRUyHuPU163hLBanInTsZIS5wNEqi9YngFXVF5yg3ADQn\n" +
+      "Keg3S/LvRJdrF1Eaw1adPBqK9kpGRjeM+sv1ZFo4aC4cw+9wzrhGBha/937n\n" +
+      "tag+RaypJXUie28/sJyU58dzq6wf7iWbwBbtt8pb8BQ=\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Visa_International_Global_Root_2.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDgDCCAmigAwIBAgICAx4wDQYJKoZIhvcNAQEFBQAwYTELMAkGA1UEBhMC\n" +
+      "VVMxDTALBgNVBAoTBFZJU0ExLzAtBgNVBAsTJlZpc2EgSW50ZXJuYXRpb25h\n" +
+      "bCBTZXJ2aWNlIEFzc29jaWF0aW9uMRIwEAYDVQQDEwlHUCBSb290IDIwHhcN\n" +
+      "MDAwODE2MjI1MTAwWhcNMjAwODE1MjM1OTAwWjBhMQswCQYDVQQGEwJVUzEN\n" +
+      "MAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNl\n" +
+      "cnZpY2UgQXNzb2NpYXRpb24xEjAQBgNVBAMTCUdQIFJvb3QgMjCCASIwDQYJ\n" +
+      "KoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkBcLWqxEDwq2omYXkZAPy/mzdZ\n" +
+      "DK9vZBv42pWUJGkzEXDK41Z0ohdXZFwgBuHW73G3O/erwWnQSaSxBNf0V2KJ\n" +
+      "XLB1LRckaeNCYOTudNargFbYiCjh+20i/SN8RnNPflRzHqgsVVh1t0zzWkWl\n" +
+      "Ahr62p3DRcMiXvOL8WAp0sdftAw6UYPvMPjU58fy+pmjIlC++QU3o63tmsPm\n" +
+      "7IgbthknGziLgE3sucfFicv8GjLtI/C1AVj59o/ghalMCXI5Etuz9c9OYmTa\n" +
+      "xhkVOmMd6RdVoUwiPDQyRvhlV7or7zaMavrZ2UT0qt2E1w0cslSsMoW0ZA3e\n" +
+      "QbuxNMYBhjJk1Z8CAwEAAaNCMEAwHQYDVR0OBBYEFJ59SzS/ca3CBfYDdYDO\n" +
+      "qU8axCRMMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqG\n" +
+      "SIb3DQEBBQUAA4IBAQAhpXYUVfmtJ3CPPPTVbMjMCqujmAuKBiPFyWHbmQdp\n" +
+      "NSYx/scuhMKZYdQN6X0uEyt8joW2hcdLzzW2LEc9zikv2G+fiRxkk78IvXbQ\n" +
+      "kIqUs38oW26sTTMs7WXcFsziza6kPWKSBpUmv9+55CCmc2rBvveURNZNbyoL\n" +
+      "axhNdBA2aGpawWqn3TYpjLgwi08hPwAuVDAHOrqK5MOeyti12HvOdUVmB/Rt\n" +
+      "Ldh6yumJivIj2C/LbgA2T/vwLwHMD8AiZfSr4k5hLQOCfZEWtTDVFN5ex5D8\n" +
+      "ofyrEK9ca3CnB+8phuiyJccg/ybdd+95RBTEvd07xQObdyPsoOy7Wjm1zK0G\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // Visa_eCommerce_Root.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUF\n" +
+      "ADBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlz\n" +
+      "YSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMT\n" +
+      "E1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0\n" +
+      "MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UE\n" +
+      "CxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAa\n" +
+      "BgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA\n" +
+      "A4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh\n" +
+      "28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8bRaVK7362\n" +
+      "rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81\n" +
+      "q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtF\n" +
+      "Wsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0\n" +
+      "lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaLdXe6YJ2E5/4t\n" +
+      "AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G\n" +
+      "A1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOC\n" +
+      "AQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR\n" +
+      "zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKht\n" +
+      "cbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGI\n" +
+      "xHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu\n" +
+      "YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/\n" +
+      "hC3euiInlhBx6yLt398znM/jra6O1I7mT1GvFpLgXPYHDw==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // beTRUSTed_Root_CA-Baltimore_Implementation.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIFajCCBFKgAwIBAgIEPLU9RjANBgkqhkiG9w0BAQUFADBmMRIwEAYDVQQK\n" +
+      "EwliZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENBczEzMDEG\n" +
+      "A1UEAxMqYmVUUlVTVGVkIFJvb3QgQ0EtQmFsdGltb3JlIEltcGxlbWVudGF0\n" +
+      "aW9uMB4XDTAyMDQxMTA3Mzg1MVoXDTIyMDQxMTA3Mzg1MVowZjESMBAGA1UE\n" +
+      "ChMJYmVUUlVTVGVkMRswGQYDVQQLExJiZVRSVVNUZWQgUm9vdCBDQXMxMzAx\n" +
+      "BgNVBAMTKmJlVFJVU1RlZCBSb290IENBLUJhbHRpbW9yZSBJbXBsZW1lbnRh\n" +
+      "dGlvbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALx+xDmcjOPW\n" +
+      "HIb/ymKt4H8wRXqOGrO4x/nRNv8i805qX4QQ+2aBw5R5MdKR4XeOGCrDFN5R\n" +
+      "9U+jK7wYFuK13XneIviCfsuBH/0nLI/6l2Qijvj/YaOcGx6Sj8CoCd8JEey3\n" +
+      "fTGaGuqDIQY8n7pc/5TqarjDa1U0Tz0yH92BFODEPM2dMPgwqZfT7syj0B9f\n" +
+      "HBOB1BirlNFjw55/NZKeX0Tq7PQiXLfoPX2k+YmpkbIq2eszh+6l/ePazIjm\n" +
+      "iSZuxyuC0F6dWdsU7JGDBcNeDsYq0ATdcT0gTlgn/FP7eHgZFLL8kFKJOGJg\n" +
+      "B7Sg7KxrUNb9uShr71ItOrL/8QFArDcCAwEAAaOCAh4wggIaMA8GA1UdEwEB\n" +
+      "/wQFMAMBAf8wggG1BgNVHSAEggGsMIIBqDCCAaQGDysGAQQBsT4AAAEJKIOR\n" +
+      "MTCCAY8wggFIBggrBgEFBQcCAjCCAToaggE2UmVsaWFuY2Ugb24gb3IgdXNl\n" +
+      "IG9mIHRoaXMgQ2VydGlmaWNhdGUgY3JlYXRlcyBhbiBhY2tub3dsZWRnbWVu\n" +
+      "dCBhbmQgYWNjZXB0YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5k\n" +
+      "YXJkIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mIHVzZSwgdGhlIENlcnRpZmlj\n" +
+      "YXRpb24gUHJhY3RpY2UgU3RhdGVtZW50IGFuZCB0aGUgUmVseWluZyBQYXJ0\n" +
+      "eSBBZ3JlZW1lbnQsIHdoaWNoIGNhbiBiZSBmb3VuZCBhdCB0aGUgYmVUUlVT\n" +
+      "VGVkIHdlYiBzaXRlLCBodHRwOi8vd3d3LmJldHJ1c3RlZC5jb20vcHJvZHVj\n" +
+      "dHNfc2VydmljZXMvaW5kZXguaHRtbDBBBggrBgEFBQcCARY1aHR0cDovL3d3\n" +
+      "dy5iZXRydXN0ZWQuY29tL3Byb2R1Y3RzX3NlcnZpY2VzL2luZGV4Lmh0bWww\n" +
+      "HQYDVR0OBBYEFEU9w6nR3D8kVpgccxiIav+DR+22MB8GA1UdIwQYMBaAFEU9\n" +
+      "w6nR3D8kVpgccxiIav+DR+22MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0B\n" +
+      "AQUFAAOCAQEASZK8o+6svfoNyYt5hhwjdrCAWXf82n+0S9/DZEtqTg6t8n1Z\n" +
+      "dwWtColzsPq8y9yNAIiPpqCy6qxSJ7+hSHyXEHu67RMdmgduyzFiEuhjA6p9\n" +
+      "beP4G3YheBufS0OM00mG9htc9i5gFdPp43t1P9ACg9AYgkHNZTfqjjJ+vWuZ\n" +
+      "XTARyNtIVBw74acT02pIk/c9jH8F6M7ziCpjBLjqflh8AXtb4cV97yHgjQ5d\n" +
+      "UX2xZ/2jvTg2xvI4hocalmhgRvsoFEdV4aeADGvi6t9NfJBIoDa9CReJf8Py\n" +
+      "05yc493EG931t3GzUwWJBtDLSoDByFOQtTwxiBdQn8nEDovYqAJjDQ==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // beTRUSTed_Root_CA.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIFLDCCBBSgAwIBAgIEOU99hzANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQG\n" +
+      "EwJXVzESMBAGA1UEChMJYmVUUlVTVGVkMRswGQYDVQQDExJiZVRSVVNUZWQg\n" +
+      "Um9vdCBDQXMxGjAYBgNVBAMTEWJlVFJVU1RlZCBSb290IENBMB4XDTAwMDYy\n" +
+      "MDE0MjEwNFoXDTEwMDYyMDEzMjEwNFowWjELMAkGA1UEBhMCV1cxEjAQBgNV\n" +
+      "BAoTCWJlVFJVU1RlZDEbMBkGA1UEAxMSYmVUUlVTVGVkIFJvb3QgQ0FzMRow\n" +
+      "GAYDVQQDExFiZVRSVVNUZWQgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD\n" +
+      "ggEPADCCAQoCggEBANS0c3oTCjhVAb6JVuGUntS+WutKNHUbYSnE4a0IYCF4\n" +
+      "SP+00PpeQY1hRIfo7clY+vyTmt9P6j41ffgzeubx181vSUs9Ty1uDoM6GHh3\n" +
+      "o8/n9E1z2Jo7Gh2+lVPPIJfCzz4kUmwMjmVZxXH/YgmPqsWPzGCgc0rXOD8V\n" +
+      "cr+il7dw6K/ifhYGTPWqZCZyByWtNfwYsSbX2P8ZDoMbjNx4RWc0PfSvHI3k\n" +
+      "bWvtILNnmrRhyxdviTX/507AMhLn7uzf/5cwdO2NR47rtMNE5qdMf1ZD6Li8\n" +
+      "tr76g5fmu/vEtpO+GRg+jIG5c4gW9JZDnGdzF5DYCW5jrEq2I8QBoa2k5MUC\n" +
+      "AwEAAaOCAfgwggH0MA8GA1UdEwEB/wQFMAMBAf8wggFZBgNVHSAEggFQMIIB\n" +
+      "TDCCAUgGCisGAQQBsT4BAAAwggE4MIIBAQYIKwYBBQUHAgIwgfQagfFSZWxp\n" +
+      "YW5jZSBvbiB0aGlzIGNlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVz\n" +
+      "IGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0\n" +
+      "ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGFuZCBjZXJ0aWZpY2F0aW9u\n" +
+      "IHByYWN0aWNlIHN0YXRlbWVudCwgd2hpY2ggY2FuIGJlIGZvdW5kIGF0IGJl\n" +
+      "VFJVU1RlZCdzIHdlYiBzaXRlLCBodHRwczovL3d3dy5iZVRSVVNUZWQuY29t\n" +
+      "L3ZhdWx0L3Rlcm1zMDEGCCsGAQUFBwIBFiVodHRwczovL3d3dy5iZVRSVVNU\n" +
+      "ZWQuY29tL3ZhdWx0L3Rlcm1zMDQGA1UdHwQtMCswKaAnoCWkIzAhMRIwEAYD\n" +
+      "VQQKEwliZVRSVVNUZWQxCzAJBgNVBAYTAldXMB0GA1UdDgQWBBQquZtpLjub\n" +
+      "2M3eKjEENGvKBxirZzAfBgNVHSMEGDAWgBQquZtpLjub2M3eKjEENGvKBxir\n" +
+      "ZzAOBgNVHQ8BAf8EBAMCAf4wDQYJKoZIhvcNAQEFBQADggEBAHlh26Nebhax\n" +
+      "6nZR+csVm8tpvuaBa58oH2U+3RGFktToQb9+M70j5/Egv6S0phkBxoyNNXxl\n" +
+      "pE8JpNbYIxUFE6dDea/bow6be3ga8wSGWsb2jCBHOElQBp1yZzrwmAOtlmdE\n" +
+      "/D8QDYZN5AA7KXvOOzuZhmElQITcE2K3+spZ1gMe1lMBzW1MaFVA4e5rxyoA\n" +
+      "AEiCswoBw2AqDPeCNe5IhpbkdNQ96gFxugR1QKepfzk5mlWXKWWuGVUlBXJH\n" +
+      "0+gY3Ljpr0NzARJ0o+FcXxVdJPP55PS2Z2cS52QiivalQaYctmBjRYoQtLpG\n" +
+      "EK5BV2VsPyMQPyEQWbfkQN0mDCP2qq4=\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // beTRUSTed_Root_CA_-_Entrust_Implementation.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIGUTCCBTmgAwIBAgIEPLVPQDANBgkqhkiG9w0BAQUFADBmMRIwEAYDVQQK\n" +
+      "EwliZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENBczEzMDEG\n" +
+      "A1UEAxMqYmVUUlVTVGVkIFJvb3QgQ0EgLSBFbnRydXN0IEltcGxlbWVudGF0\n" +
+      "aW9uMB4XDTAyMDQxMTA4MjQyN1oXDTIyMDQxMTA4NTQyN1owZjESMBAGA1UE\n" +
+      "ChMJYmVUUlVTVGVkMRswGQYDVQQLExJiZVRSVVNUZWQgUm9vdCBDQXMxMzAx\n" +
+      "BgNVBAMTKmJlVFJVU1RlZCBSb290IENBIC0gRW50cnVzdCBJbXBsZW1lbnRh\n" +
+      "dGlvbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALr0RAOqEmq1\n" +
+      "Q+xVkrYwfTVXDNvzDSduTPdQqJtOK2/b9a0cS12zqcH+e0TrW6MFDR/FNCsw\n" +
+      "ACnxeECypP869AGIF37m1CbTukzqMvtDd5eHI8XbQ6P1KqNRXuE70mVpflUV\n" +
+      "m3rnafdE4Fe1FehmYA8NA/uCjqPoEXtsvsdjDheT389Lrm5zdeDzqrmkwAkb\n" +
+      "hepxKYhBMvnwKg5sCfJ0a2ZsUhMfGLzUPvfYbiCeyv78IZTuEyhL11xeDGbu\n" +
+      "6bsPwTSxfwh28z0mcMmLJR1iJAzqHHVOwBLkuhMdMCktVjMFu5dZfsZJT4nX\n" +
+      "LySotohAtWSSU1Yk5KKghbNekLQSM80CAwEAAaOCAwUwggMBMIIBtwYDVR0g\n" +
+      "BIIBrjCCAaowggGmBg8rBgEEAbE+AAACCSiDkTEwggGRMIIBSQYIKwYBBQUH\n" +
+      "AgIwggE7GoIBN1JlbGlhbmNlIG9uIG9yIHVzZSBvZiB0aGlzIENlcnRpZmlj\n" +
+      "YXRlIGNyZWF0ZXMgYW4gYWNrbm93bGVkZ21lbnQgYW5kIGFjY2VwdGFuY2Ug\n" +
+      "b2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29u\n" +
+      "ZGl0aW9ucyBvZiB1c2UsIHRoZSBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0\n" +
+      "YXRlbWVudCBhbmQgdGhlIFJlbHlpbmcgUGFydHkgQWdyZWVtZW50LCB3aGlj\n" +
+      "aCBjYW4gYmUgZm91bmQgYXQgdGhlIGJlVFJVU1RlZCB3ZWIgc2l0ZSwgaHR0\n" +
+      "cHM6Ly93d3cuYmV0cnVzdGVkLmNvbS9wcm9kdWN0c19zZXJ2aWNlcy9pbmRl\n" +
+      "eC5odG1sMEIGCCsGAQUFBwIBFjZodHRwczovL3d3dy5iZXRydXN0ZWQuY29t\n" +
+      "L3Byb2R1Y3RzX3NlcnZpY2VzL2luZGV4Lmh0bWwwEQYJYIZIAYb4QgEBBAQD\n" +
+      "AgAHMIGJBgNVHR8EgYEwfzB9oHugeaR3MHUxEjAQBgNVBAoTCWJlVFJVU1Rl\n" +
+      "ZDEbMBkGA1UECxMSYmVUUlVTVGVkIFJvb3QgQ0FzMTMwMQYDVQQDEypiZVRS\n" +
+      "VVNUZWQgUm9vdCBDQSAtIEVudHJ1c3QgSW1wbGVtZW50YXRpb24xDTALBgNV\n" +
+      "BAMTBENSTDEwKwYDVR0QBCQwIoAPMjAwMjA0MTEwODI0MjdagQ8yMDIyMDQx\n" +
+      "MTA4NTQyN1owCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFH1w5a44iwY/qhwa\n" +
+      "j/nPJDCqhIQWMB0GA1UdDgQWBBR9cOWuOIsGP6ocGo/5zyQwqoSEFjAMBgNV\n" +
+      "HRMEBTADAQH/MB0GCSqGSIb2fQdBAAQQMA4bCFY2LjA6NC4wAwIEkDANBgkq\n" +
+      "hkiG9w0BAQUFAAOCAQEAKrgXzh8QlOu4mre5X+za95IkrNySO8cgjfKZ5V04\n" +
+      "ocI07cUTWVwFtStPYZuR+0H8/NU8TZh2BvWBfevdkObRVlTa4y0MnxEylCIB\n" +
+      "evZsLHRnBMylj44ss0O1lKLQfelifwa+JwGDnjr9iu6YQ0pr17WXOzq/T220\n" +
+      "Y/ozADQuLW2WyXvKmWO6vvT2MKAtmJbpVkQFqUSjYRDrgqFnXbxdJ3Wqiig2\n" +
+      "KjiS2d2kXgClzMx8KSreKJCrt+G2/30lC0DYqjSjLd4H61/OCt3Kfjp9JsFi\n" +
+      "aDrmLzfzgYYhxKlkqu9FNtEaZnz46TfW1mG+oq1I59/mdP7TbX3SJdysYlep\n" +
+      "9w==\n" +
+      "-----END CERTIFICATE-----\n");
+    if (cert != null) certs.add(cert);
+
+    cert = generate(factory,
+      // beTRUSTed_Root_CA_-_RSA_Implementation.crt
+      "-----BEGIN CERTIFICATE-----\n" +
+      "MIIFaDCCBFCgAwIBAgIQO1nHe81bV569N1KsdrSqGjANBgkqhkiG9w0BAQUF\n" +
+      "ADBiMRIwEAYDVQQKEwliZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBS\n" +
+      "b290IENBczEvMC0GA1UEAxMmYmVUUlVTVGVkIFJvb3QgQ0EgLSBSU0EgSW1w\n" +
+      "bGVtZW50YXRpb24wHhcNMDIwNDExMTExODEzWhcNMjIwNDEyMTEwNzI1WjBi\n" +
+      "MRIwEAYDVQQKEwliZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290\n" +
+      "IENBczEvMC0GA1UEAxMmYmVUUlVTVGVkIFJvb3QgQ0EgLSBSU0EgSW1wbGVt\n" +
+      "ZW50YXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkujQw\n" +
+      "CY5X0LkGLG9uJIAiv11DpvpPrILnHGhwhRujbrWqeNluB0s/6d/16uhUoWGK\n" +
+      "Di9pdRi3DOUUjXFumLhV/AyV0Jtu4S2I1DpAa5LxmZZk3tv/ePTulh1HiXzU\n" +
+      "vrmIdyM6CeYEnm2qXtLIvZpOGd+J6lsOfsPktPDgaTuID0GQ+NRxQyTBjyZL\n" +
+      "O1bp/4xsN+lFrYWMU8NghpBKlsmzVLC7F/AcRdnUGxlkVgoZ98zh/4avflhe\n" +
+      "rHqQH8koOUV7orbHnB/ahdQhhlkwk75TMzf270HPM8ercmsl9fNTGwxMLvF1\n" +
+      "S++gh/f+ihXQbNXL+WhTuXAVE8L1LvtDNXUtAgMBAAGjggIYMIICFDAMBgNV\n" +
+      "HRMEBTADAQH/MIIBtQYDVR0gBIIBrDCCAagwggGkBg8rBgEEAbE+AAADCSiD\n" +
+      "kTEwggGPMEEGCCsGAQUFBwIBFjVodHRwOi8vd3d3LmJldHJ1c3RlZC5jb20v\n" +
+      "cHJvZHVjdHNfc2VydmljZXMvaW5kZXguaHRtbDCCAUgGCCsGAQUFBwICMIIB\n" +
+      "OhqCATZSZWxpYW5jZSBvbiBvciB1c2Ugb2YgdGhpcyBDZXJ0aWZpY2F0ZSBj\n" +
+      "cmVhdGVzIGFuIGFja25vd2xlZGdtZW50IGFuZCBhY2NlcHRhbmNlIG9mIHRo\n" +
+      "ZSB0aGVuIGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5kIGNvbmRpdGlv\n" +
+      "bnMgb2YgdXNlLCB0aGUgQ2VydGlmaWNhdGlvbiBQcmFjdGljZSBTdGF0ZW1l\n" +
+      "bnQgYW5kIHRoZSBSZWx5aW5nIFBhcnR5IEFncmVlbWVudCwgd2hpY2ggY2Fu\n" +
+      "IGJlIGZvdW5kIGF0IHRoZSBiZVRSVVNUZWQgd2ViIHNpdGUsIGh0dHA6Ly93\n" +
+      "d3cuYmV0cnVzdGVkLmNvbS9wcm9kdWN0c19zZXJ2aWNlcy9pbmRleC5odG1s\n" +
+      "MAsGA1UdDwQEAwIBBjAfBgNVHSMEGDAWgBSp7BR++dlDzFMrFK3P9/BZiUHN\n" +
+      "GTAdBgNVHQ4EFgQUqewUfvnZQ8xTKxStz/fwWYlBzRkwDQYJKoZIhvcNAQEF\n" +
+      "BQADggEBANuXsHXqDMTBmMpWBcCorSZIry0g6IHHtt9DwSwddUvUQo3neqh0\n" +
+      "3GZCWYez9Wlt2ames30cMcH1VOJZJEnl7r05pmuKmET7m9cqg5c0Lcd9NUwt\n" +
+      "NLg+DcTsiCevnpL9UGGCqGAHFFPMZRPB9kdEadIxyKbdLrML3kqNWz2rDcI1\n" +
+      "UqJWN8wyiyiFQpyRQHpwKzg21eFzGh/l+n5f3NacOzDq28BbJ1zTcwfBwvNM\n" +
+      "m2+fG8oeqqg4MwlYsq78B+g23FW6L09A/nq9BqaBwZMifIYRCgZ3SK41ty8y\n" +
+      "mmFei74pnykkiFY5LKjSq5YDWtRIn7lAhAuYaPsBQ9Yb4gmxlxw=\n" +
+      "-----END CERTIFICATE-----\n");
+
+    CA_CERTS = new StaticTrustAnchors((X509Certificate[]) certs.toArray(new X509Certificate[0]));
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Alert.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Alert.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Alert.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Alert.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,474 @@
+/* Alert.java -- SSL Alert message.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.EOFException;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * An alert message in the SSL protocol. Alerts are sent both as warnings
+ * which may allow execution to continue, or they may be fatal, which will
+ * halt this session. An alert object is composed of two enums -- the level,
+ * which indicates the seriousness of the alert, and the description, which
+ * indicates the reason for the alert.
+ *
+ * <pre>
+ * struct {
+ *   AlertLevel level;
+ *   AlertDescription description;
+ * }
+ * </pre>
+ */
+final class Alert implements Constructed
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  /** The alert level enumerated. */
+  private final Level level;
+
+  /** The alert description enumerated. */
+  private final Description description;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  Alert(Level level, Description description)
+  {
+    this.level = level;
+    this.description = description;
+  }
+
+  // Class method.
+  // -------------------------------------------------------------------------
+
+  static Alert read(InputStream in) throws IOException
+  {
+    Level level = Level.read(in);
+    Description desc = Description.read(in);
+    return new Alert(level, desc);
+  }
+
+  static Alert forName(String name)
+  {
+    if (name == null)
+      {
+        return new Alert(Level.FATAL, Description.INTERNAL_ERROR);
+      }
+    Description desc = Description.INTERNAL_ERROR;
+    if (name.equals("close_notify"))
+      {
+        desc = Description.CLOSE_NOTIFY;
+      }
+    else if (name.equals("unexpected_message"))
+      {
+        desc = Description.UNEXPECTED_MESSAGE;
+      }
+    else if (name.equals("bad_record_mac"))
+      {
+        desc = Description.BAD_RECORD_MAC;
+      }
+    else if (name.equals("DECRYPTION_FAILED"))
+      {
+        desc = Description.DECRYPTION_FAILED;
+      }
+    else if (name.equals("record_overflow"))
+      {
+        desc = Description.RECORD_OVERFLOW;
+      }
+    else if (name.equals("decompression_failure"))
+      {
+        desc = Description.DECOMPRESSION_FAILURE;
+      }
+    else if (name.equals("handshake_failure"))
+      {
+        desc = Description.HANDSHAKE_FAILURE;
+      }
+    else if (name.equals("no_certificate"))
+      {
+        desc = Description.NO_CERTIFICATE;
+      }
+    else if (name.equals("bad_certificate"))
+      {
+        desc = Description.BAD_CERTIFICATE;
+      }
+    else if (name.equals("unsupported_certificate"))
+      {
+        desc = Description.UNSUPPORTED_CERTIFICATE;
+      }
+    else if (name.equals("certificate_revoked"))
+      {
+        desc = Description.CERTIFICATE_REVOKED;
+      }
+    else if (name.equals("certificate_expired"))
+      {
+        desc = Description.CERTIFICATE_EXPIRED;
+      }
+    else if (name.equals("certificate_unknown"))
+      {
+        desc = Description.CERTIFICATE_UNKNOWN;
+      }
+    else if (name.equals("illegal_parameter"))
+      {
+        desc = Description.ILLEGAL_PARAMETER;
+      }
+    else if (name.equals("unknown_ca"))
+      {
+        desc = Description.UNKNOWN_CA;
+      }
+    else if (name.equals("access_denied"))
+      {
+        desc = Description.ACCESS_DENIED;
+      }
+    else if (name.equals("decode_error"))
+      {
+        desc = Description.DECODE_ERROR;
+      }
+    else if (name.equals("decrypt_error"))
+      {
+        desc = Description.DECRYPT_ERROR;
+      }
+    else if (name.equals("export_restriction"))
+      {
+        desc = Description.EXPORT_RESTRICTION;
+      }
+    else if (name.equals("protocol_version"))
+      {
+        desc = Description.PROTOCOL_VERSION;
+      }
+    else if (name.equals("insufficient_security"))
+      {
+        desc = Description.INSUFFICIENT_SECURITY;
+      }
+    else if (name.equals("internal_error"))
+      {
+        desc = Description.INTERNAL_ERROR;
+      }
+    else if (name.equals("user_canceled"))
+      {
+        desc = Description.USER_CANCELED;
+      }
+    else if (name.equals("no_renegotiation"))
+      {
+        desc = Description.NO_RENEGOTIATION;
+      }
+    else if (name.equals("unsupported_extension"))
+      {
+        desc = Description.UNSUPPORTED_EXTENSION;
+      }
+    else if (name.equals("certificate_unobtainable"))
+      {
+        desc = Description.CERTIFICATE_UNOBTAINABLE;
+      }
+    else if (name.equals("unrecognized_name"))
+      {
+        desc = Description.UNRECOGNIZED_NAME;
+      }
+    else if (name.equals("bad_certificate_status_response"))
+      {
+        desc = Description.BAD_CERTIFICATE_STATUS_RESPONSE;
+      }
+    else if (name.equals("bad_certificate_hash_value"))
+      {
+        desc = Description.BAD_CERTIFICATE_HASH_VALUE;
+      }
+    else if (name.equals("unknown_srp_username"))
+      {
+        desc = Description.UNKNOWN_SRP_USERNAME;
+      }
+    else if (name.equals("missing_srp_username"))
+      {
+        desc = Description.MISSING_SRP_USERNAME;
+      }
+    return new Alert(Level.FATAL, desc);
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public void write(OutputStream out) throws IOException
+  {
+    out.write((byte) level.getValue());
+    out.write((byte) description.getValue());
+  }
+
+  byte[] getEncoded()
+  {
+    return new byte[] { (byte) level.getValue(),
+                        (byte) description.getValue() };
+  }
+
+  Level getLevel()
+  {
+    return level;
+  }
+
+  Description getDescription()
+  {
+    return description;
+  }
+
+  public String toString()
+  {
+    String nl = System.getProperty("line.separator");
+    return "struct {" + nl +
+           "  level = " + level + ";" + nl +
+           "  description = " + description + ";" + nl +
+           "} Alert;" + nl;
+  }
+
+  // Inner classes.
+  // -------------------------------------------------------------------------
+
+  /**
+   * The level enumeration.
+   *
+   * <pre>
+   * enum { warning(1), fatal(2), (255) } AlertLevel;
+   * </pre>
+   */
+  static final class Level implements Enumerated
+  {
+
+    // Constants and fields.
+    // -----------------------------------------------------------------------
+
+    static final Level WARNING = new Level(1), FATAL = new Level(2);
+
+    private final int value;
+
+    // Constructor.
+    // -----------------------------------------------------------------------
+
+    private Level(int value)
+    {
+      this.value = value;
+    }
+
+    // Class method.
+    // -----------------------------------------------------------------------
+
+    static Level read(InputStream in) throws IOException
+    {
+      int i = in.read();
+      if (i == -1)
+        {
+          throw new EOFException("unexpected end of stream");
+        }
+      switch (i & 0xFF)
+        {
+        case 1: return WARNING;
+        case 2: return FATAL;
+        default: return new Level(i);
+        }
+    }
+
+    // Instance methods.
+    // -----------------------------------------------------------------------
+
+    public byte[] getEncoded()
+    {
+      return new byte[] { (byte) value };
+    }
+
+    public int getValue()
+    {
+      return value;
+    }
+
+    public String toString()
+    {
+      switch (value)
+        {
+        case 1: return "warning";
+        case 2: return "fatal";
+        default: return "unknown(" + value + ")";
+        }
+    }
+  }
+
+  /**
+   * The description enumeration.
+   */
+  static final class Description implements Enumerated
+  {
+
+    // Constants and fields.
+    // -----------------------------------------------------------------------
+
+    static final Description
+      CLOSE_NOTIFY                    = new Description(  0),
+      UNEXPECTED_MESSAGE              = new Description( 10),
+      BAD_RECORD_MAC                  = new Description( 20),
+      DECRYPTION_FAILED               = new Description( 21),
+      RECORD_OVERFLOW                 = new Description( 22),
+      DECOMPRESSION_FAILURE           = new Description( 30),
+      HANDSHAKE_FAILURE               = new Description( 40),
+      NO_CERTIFICATE                  = new Description( 41),
+      BAD_CERTIFICATE                 = new Description( 42),
+      UNSUPPORTED_CERTIFICATE         = new Description( 43),
+      CERTIFICATE_REVOKED             = new Description( 44),
+      CERTIFICATE_EXPIRED             = new Description( 45),
+      CERTIFICATE_UNKNOWN             = new Description( 46),
+      ILLEGAL_PARAMETER               = new Description( 47),
+      UNKNOWN_CA                      = new Description( 48),
+      ACCESS_DENIED                   = new Description( 49),
+      DECODE_ERROR                    = new Description( 50),
+      DECRYPT_ERROR                   = new Description( 51),
+      EXPORT_RESTRICTION              = new Description( 60),
+      PROTOCOL_VERSION                = new Description( 70),
+      INSUFFICIENT_SECURITY           = new Description( 71),
+      INTERNAL_ERROR                  = new Description( 80),
+      USER_CANCELED                   = new Description( 90),
+      NO_RENEGOTIATION                = new Description(100),
+      UNSUPPORTED_EXTENSION           = new Description(110),
+      CERTIFICATE_UNOBTAINABLE        = new Description(111),
+      UNRECOGNIZED_NAME               = new Description(112),
+      BAD_CERTIFICATE_STATUS_RESPONSE = new Description(113),
+      BAD_CERTIFICATE_HASH_VALUE      = new Description(114),
+      UNKNOWN_SRP_USERNAME            = new Description(120),
+      MISSING_SRP_USERNAME            = new Description(121);
+
+    private final int value;
+
+    // Constructor.
+    // -----------------------------------------------------------------------
+
+    private Description(int value)
+    {
+      this.value = value;
+    }
+
+    // Class method.
+    // -----------------------------------------------------------------------
+
+    static Description read(InputStream in) throws IOException
+    {
+      int i = in.read();
+      if (i == -1)
+        {
+          throw new EOFException("unexpected end of input stream");
+        }
+      switch (i)
+        {
+        case 0: return CLOSE_NOTIFY;
+        case 10: return UNEXPECTED_MESSAGE;
+        case 20: return BAD_RECORD_MAC;
+        case 21: return DECRYPTION_FAILED;
+        case 22: return RECORD_OVERFLOW;
+        case 30: return DECOMPRESSION_FAILURE;
+        case 40: return HANDSHAKE_FAILURE;
+        case 41: return NO_CERTIFICATE;
+        case 42: return BAD_CERTIFICATE;
+        case 43: return UNSUPPORTED_CERTIFICATE;
+        case 44: return CERTIFICATE_REVOKED;
+        case 45: return CERTIFICATE_EXPIRED;
+        case 46: return CERTIFICATE_UNKNOWN;
+        case 47: return ILLEGAL_PARAMETER;
+        case 48: return UNKNOWN_CA;
+        case 49: return ACCESS_DENIED;
+        case 50: return DECODE_ERROR;
+        case 51: return DECRYPT_ERROR;
+        case 60: return EXPORT_RESTRICTION;
+        case 70: return PROTOCOL_VERSION;
+        case 71: return INSUFFICIENT_SECURITY;
+        case 80: return INTERNAL_ERROR;
+        case 90: return USER_CANCELED;
+        case 100: return NO_RENEGOTIATION;
+        case 120: return UNKNOWN_SRP_USERNAME;
+        case 121: return MISSING_SRP_USERNAME;
+        default: return new Description(i);
+        }
+    }
+
+    // Instance methods.
+    // -----------------------------------------------------------------------
+
+    public byte[] getEncoded()
+    {
+      return new byte[] { (byte) value };
+    }
+
+    public int getValue()
+    {
+      return value;
+    }
+
+    public String toString()
+    {
+      switch (value)
+        {
+        case   0: return "close_notify";
+        case  10: return "unexpected_message";
+        case  20: return "bad_record_mac";
+        case  21: return "decryption_failed";
+        case  22: return "record_overflow";
+        case  30: return "decompression_failure";
+        case  40: return "handshake_failure";
+        case  42: return "bad_certificate";
+        case  43: return "unsupported_certificate";
+        case  44: return "certificate_revoked";
+        case  45: return "certificate_expired";
+        case  46: return "certificate_unknown";
+        case  47: return "illegal_parameter";
+        case  48: return "unknown_ca";
+        case  49: return "access_denied";
+        case  50: return "decode_error";
+        case  51: return "decrypt_error";
+        case  60: return "export_restriction";
+        case  70: return "protocol_version";
+        case  71: return "insufficient_security";
+        case  80: return "internal_error";
+        case  90: return "user_canceled";
+        case 100: return "no_renegotiation";
+        case 110: return "unsupported_extension";
+        case 111: return "certificate_unobtainable";
+        case 112: return "unrecognized_name";
+        case 113: return "bad_certificate_status_response";
+        case 114: return "bad_certificate_hash_value";
+        case 120: return "unknown_srp_username";
+        case 121: return "missing_srp_username";
+        default: return "unknown(" + value + ")";
+        }
+    }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/AlertException.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/AlertException.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/AlertException.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/AlertException.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,76 @@
+/* AlertException.java -- exceptions generated by SSL alerts.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import javax.net.ssl.SSLException;
+
+class AlertException extends SSLException
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final Alert alert;
+  private final boolean isLocal;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  AlertException(Alert alert, boolean isLocal)
+  {
+    super(alert.getDescription().toString());
+    this.alert = alert;
+    this.isLocal = isLocal;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public String getMessage()
+  {
+    return alert.getDescription() + ": " +
+      (isLocal ? "locally generated; " : "remotely generated; ") +
+      alert.getLevel();
+  }
+
+  public Alert getAlert ()
+  {
+    return alert;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Certificate.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Certificate.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Certificate.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Certificate.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,194 @@
+/* Certificate.java -- SSL Certificate message.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+import java.util.LinkedList;
+
+import javax.net.ssl.SSLProtocolException;
+
+final class Certificate implements Handshake.Body
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final X509Certificate[] certs;
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  Certificate(X509Certificate[] certs)
+  {
+    if (certs == null)
+      {
+        throw new NullPointerException();
+      }
+    this.certs = certs;
+  }
+
+  // Class methods.
+  // -------------------------------------------------------------------------
+
+  static Certificate read(InputStream in, CertificateType type)
+    throws IOException
+  {
+    if (type == CertificateType.X509)
+      {
+        int len = (in.read() & 0xFF) << 16 | (in.read() & 0xFF) << 8
+                | (in.read() & 0xFF);
+        byte[] buf = new byte[len];
+        int count = 0;
+        while (count < len)
+          {
+            int l = in.read(buf, count, len - count);
+            if (l == -1)
+              {
+                throw new EOFException("unexpected end of stream");
+              }
+            count += l;
+          }
+        try
+          {
+            LinkedList certs = new LinkedList();
+            CertificateFactory fact = CertificateFactory.getInstance("X.509");
+            ByteArrayInputStream bin = new ByteArrayInputStream(buf);
+            count = 0;
+            while (count < len)
+              {
+                int len2 = (bin.read() & 0xFF) << 16 | (bin.read() & 0xFF) << 8
+                         | (bin.read() & 0xFF);
+                certs.add(fact.generateCertificate(bin));
+                count += len2 + 3;
+              }
+            return new Certificate((X509Certificate[])
+              certs.toArray(new X509Certificate[certs.size()]));
+          }
+        catch (CertificateException ce)
+          {
+            SSLProtocolException sslpe = new SSLProtocolException(ce.getMessage());
+            sslpe.initCause (ce);
+            throw sslpe;
+          }
+      }
+    else if (type == CertificateType.OPEN_PGP)
+      {
+        throw new UnsupportedOperationException("not yet implemented");
+      }
+    else
+      throw new Error("unsupported certificate type "+type);
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public void write(OutputStream out) throws IOException
+  {
+    ByteArrayOutputStream bout = new ByteArrayOutputStream();
+    try
+      {
+        for (int i = 0; i < certs.length; i++)
+          {
+            byte[] enc = certs[i].getEncoded();
+            bout.write((enc.length >>> 16) & 0xFF);
+            bout.write((enc.length >>>  8) & 0xFF);
+            bout.write( enc.length & 0xFF);
+            bout.write(enc);
+          }
+      }
+    catch (CertificateEncodingException cee)
+      {
+        throw new Error("cannot encode certificates");
+      }
+    catch (IOException ignored)
+      {
+      }
+    out.write(bout.size() >>> 16 & 0xFF);
+    out.write(bout.size() >>>  8 & 0xFF);
+    out.write(bout.size() & 0xFF);
+    bout.writeTo(out);
+  }
+
+  X509Certificate[] getCertificates()
+  {
+    return certs;
+  }
+
+  public String toString()
+  {
+    StringWriter str = new StringWriter();
+    PrintWriter out = new PrintWriter(str);
+    out.println("struct {");
+    out.println("  certificateList =");
+    for (int i = 0; i < certs.length; i++)
+      {
+        BufferedReader r =
+          new BufferedReader(new StringReader(certs[i].toString()));
+        String s;
+        try
+          {
+            while ((s = r.readLine()) != null)
+              {
+                out.print("    ");
+                out.println(s);
+              }
+          }
+        catch (IOException ignored)
+          {
+          }
+      }
+    out.println("} Certificate;");
+    return str.toString();
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/CertificateRequest.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/CertificateRequest.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/CertificateRequest.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/CertificateRequest.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,285 @@
+/* CertificateRequest.java -- SSL CertificateRequest message.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+import java.util.LinkedList;
+import java.security.Principal;
+
+final class CertificateRequest implements Handshake.Body
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final ClientType[] types;
+  private final Principal[] authorities;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  CertificateRequest(ClientType[] types, Principal[] authorities)
+  {
+    if (types == null)
+      {
+        throw new NullPointerException();
+      }
+    this.types = types;
+    if (authorities == null)
+      {
+        throw new NullPointerException();
+      }
+    this.authorities = authorities;
+  }
+
+  // Class methods.
+  // -------------------------------------------------------------------------
+
+  static CertificateRequest read(InputStream in) throws IOException
+  {
+    DataInputStream din = new DataInputStream(in);
+    ClientType[] types = new ClientType[din.readUnsignedByte()];
+    for (int i = 0; i < types.length; i++)
+      {
+        types[i] = ClientType.read(din);
+      }
+
+    LinkedList authorities = new LinkedList();
+    byte[] buf = new byte[din.readUnsignedShort()];
+    din.readFully(buf);
+    ByteArrayInputStream bin = new ByteArrayInputStream(buf);
+    try
+      {
+        String x500name = Util.getSecurityProperty("jessie.x500.class");
+        if (x500name == null)
+          {
+            x500name = "org.metastatic.jessie.pki.X500Name";
+          }
+        Class x500class = null;
+        ClassLoader cl = ClassLoader.getSystemClassLoader();
+        if (cl != null)
+          {
+            x500class = cl.loadClass(x500name);
+          }
+        else
+          {
+            x500class = Class.forName(x500name);
+          }
+        Constructor c = x500class.getConstructor(new Class[] { new byte[0].getClass() });
+        while (bin.available() > 0)
+          {
+            buf = new byte[(bin.read() & 0xFF) << 8 | (bin.read() & 0xFF)];
+            bin.read(buf);
+            authorities.add(c.newInstance(new Object[] { buf }));
+          }
+      }
+    catch (IOException ioe)
+      {
+        throw ioe;
+      }
+    catch (Exception ex)
+      {
+        throw new Error(ex.toString());
+      }
+    return new CertificateRequest(types,
+      (Principal[]) authorities.toArray(new Principal[authorities.size()]));
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public void write(OutputStream out) throws IOException
+  {
+    ByteArrayOutputStream bout = new ByteArrayOutputStream();
+    out.write(types.length);
+    for (int i = 0; i < types.length; i++)
+      {
+        out.write(types[i].getValue());
+      }
+
+    try
+      {
+        Class x500class = authorities[0].getClass();
+        Method m = x500class.getMethod("getEncoded", null);
+        for (int i = 0; i < authorities.length; i++)
+          {
+            byte[] buf = (byte[]) m.invoke(authorities[i], null);
+            bout.write(buf.length >>> 8 & 0xFF);
+            bout.write(buf.length & 0xFF);
+            bout.write(buf, 0, buf.length);
+          }
+      }
+    catch (Exception ex)
+      {
+        throw new Error(ex.toString());
+      }
+    out.write(bout.size() >>> 8 & 0xFF);
+    out.write(bout.size() & 0xFF);
+    bout.writeTo(out);
+  }
+
+  ClientType[] getTypes()
+  {
+    return types;
+  }
+
+  String[] getTypeStrings()
+  {
+    try
+      {
+        return (String[]) Util.transform(types, String.class, "toString", null);
+      }
+    catch (Exception x)
+      {
+        return null;
+      }
+  }
+
+  Principal[] getAuthorities()
+  {
+    return authorities;
+  }
+
+  public String toString()
+  {
+    StringWriter str = new StringWriter();
+    PrintWriter out = new PrintWriter(str);
+    out.println("struct {");
+    out.print("  types = ");
+    for (int i = 0; i < types.length; i++)
+      {
+        out.print(types[i]);
+        if (i != types.length - 1)
+          out.print(", ");
+      }
+    out.println(";");
+    out.println("  authorities =");
+    for (int i = 0; i < authorities.length; i++)
+      {
+        out.print("    ");
+        out.print(authorities[i].getName());
+        if (i != types.length - 1)
+          out.println(",");
+      }
+    out.println(";");
+    out.println("} CertificateRequest;");
+    return str.toString();
+  }
+
+  // Inner class.
+  // -------------------------------------------------------------------------
+
+  static final class ClientType implements Enumerated
+  {
+
+    // Constants and fields.
+    // -----------------------------------------------------------------------
+
+    static final ClientType
+      RSA_SIGN     = new ClientType(1), DSS_SIGN     = new ClientType(2),
+      RSA_FIXED_DH = new ClientType(3), DSS_FIXED_DH = new ClientType(4);
+
+    private final int value;
+
+    // Constructor.
+    // -----------------------------------------------------------------------
+
+    private ClientType(int value)
+    {
+      this.value = value;
+    }
+
+    // Class method.
+    // -----------------------------------------------------------------------
+
+    static ClientType read(InputStream in) throws IOException
+    {
+      int i = in.read();
+      if (i == -1)
+        {
+          throw new EOFException("unexpected end of input stream");
+        }
+      switch (i & 0xFF)
+        {
+        case 1: return RSA_SIGN;
+        case 2: return DSS_SIGN;
+        case 3: return RSA_FIXED_DH;
+        case 4: return DSS_FIXED_DH;
+        default: return new ClientType(i);
+        }
+    }
+
+    // Instance methods.
+    // -----------------------------------------------------------------------
+
+    public byte[] getEncoded()
+    {
+      return new byte[] { (byte) value };
+    }
+
+    public int getValue()
+    {
+      return value;
+    }
+
+    public String toString()
+    {
+      switch (value)
+        {
+        case 1: return "rsa_sign";
+        case 2: return "dss_sign";
+        case 3: return "rsa_fixed_dh";
+        case 4: return "dss_fixed_dh";
+        default: return "unknown(" + value + ")";
+        }
+    }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/CertificateType.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/CertificateType.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/CertificateType.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/CertificateType.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,104 @@
+/* CertificateType.java -- the certificate type extension.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.EOFException;
+import java.io.InputStream;
+import java.io.IOException;
+
+final class CertificateType implements Enumerated
+{
+
+  // Constants and fields.
+  // -------------------------------------------------------------------------
+
+  static final CertificateType X509     = new CertificateType(0);
+  static final CertificateType OPEN_PGP = new CertificateType(1);
+
+  private final int value;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  private CertificateType(int value)
+  {
+    this.value = value;
+  }
+
+  // Class method.
+  // -------------------------------------------------------------------------
+
+  static CertificateType read(InputStream in) throws IOException
+  {
+    int value = in.read();
+    if (value == -1)
+      {
+        throw new EOFException("unexpected end of input stream");
+      }
+    switch (value & 0xFF)
+      {
+      case 0: return X509;
+      case 1: return OPEN_PGP;
+      default: return new CertificateType(value);
+      }
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public byte[] getEncoded()
+  {
+    return new byte[] { (byte) value };
+  }
+
+  public int getValue()
+  {
+    return value;
+  }
+
+  public String toString()
+  {
+    switch (value)
+      {
+      case 0: return "X.509";
+      case 1: return "OpenPGP";
+      default: return "unknown(" + value + ")";
+      }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/CertificateVerify.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/CertificateVerify.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/CertificateVerify.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/CertificateVerify.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,95 @@
+/* CertificateVerify.java -- SSL CertificateVerify message.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.security.PublicKey;
+
+final class CertificateVerify extends Signature implements Handshake.Body
+{
+
+  // Contstructor.
+  // -------------------------------------------------------------------------
+
+  CertificateVerify(Object sigValue, String sigAlg)
+  {
+    super(sigValue, sigAlg);
+  }
+
+  // Class method.
+  // --------------------------------------------------------------------------
+
+  static Signature read(InputStream in, CipherSuite suite, PublicKey key)
+    throws IOException
+  {
+    Signature sig = Signature.read(in, suite, key);
+    return new CertificateVerify(sig.getSigValue(), sig.getSigAlg());
+  }
+
+  // Instance method.
+  // -------------------------------------------------------------------------
+
+  public String toString()
+  {
+    StringWriter str = new StringWriter();
+    PrintWriter out = new PrintWriter(str);
+    out.println("struct {");
+    BufferedReader r = new BufferedReader(new StringReader(super.toString()));
+    String s;
+    try
+      {
+        while ((s = r.readLine()) != null)
+          {
+            out.print("  ");
+            out.println(s);
+          }
+      }
+    catch (IOException ignored)
+      {
+      }
+    out.println("} CertificateVerify;");
+    return str.toString();
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/CipherSuite.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/CipherSuite.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/CipherSuite.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/CipherSuite.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,754 @@
+/* CipherSuite.java -- Supported cipher suites.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.DataInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import java.lang.reflect.Field;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.Security;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import javax.crypto.Cipher;
+import javax.crypto.Mac;
+import javax.crypto.NoSuchPaddingException;
+
+import gnu.javax.crypto.cipher.CipherFactory;
+import gnu.javax.crypto.cipher.IBlockCipher;
+import gnu.javax.crypto.mac.IMac;
+import gnu.javax.crypto.mac.MacFactory;
+import gnu.javax.crypto.mode.IMode;
+import gnu.javax.crypto.mode.ModeFactory;
+
+final class CipherSuite implements Constructed
+{
+
+  // Constants and fields.
+  // -------------------------------------------------------------------------
+
+  private static final List tlsSuiteNames = new LinkedList();
+  private static final HashMap namesToSuites = new HashMap();
+
+  // SSL CipherSuites.
+  static final CipherSuite SSL_NULL_WITH_NULL_NULL =
+    new CipherSuite("null", "null", "null", "null", 0, 0x00, 0x00,
+                    "SSL_NULL_WITH_NULL_NULL", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_RSA_WITH_NULL_MD5 =
+    new CipherSuite("null", "RSA", "RSA", "SSLMAC-MD5", 0, 0x00, 0x01,
+                    "SSL_RSA_WITH_NULL_MD5", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_RSA_WITH_NULL_SHA =
+    new CipherSuite("null", "RSA", "RSA", "SSLMAC-SHA", 0, 0x00, 0x02,
+                    "SSL_RSA_WITH_NULL_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_RSA_EXPORT_WITH_RC4_40_MD5 =
+    new CipherSuite("RC4", "RSA", "RSA", "SSLMAC-MD5", 5, 0x00, 0x03,
+                    "SSL_RSA_EXPORT_WITH_RC4_40_MD5", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_RSA_WITH_RC4_128_MD5 =
+    new CipherSuite("RC4", "RSA", "RSA", "SSLMAC-MD5", 16, 0x00, 0x04,
+                    "SSL_RSA_WITH_RC4_128_MD5", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_RSA_WITH_RC4_128_SHA =
+    new CipherSuite("RC4", "RSA", "RSA", "SSLMAC-SHA", 16, 0x00, 0x05,
+                    "SSL_RSA_WITH_RC4_128_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_RSA_EXPORT_WITH_DES40_CBC_SHA =
+    new CipherSuite("DES", "RSA", "RSA", "SSLMAC-SHA", 5, 0x00, 0x08,
+                    "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_RSA_WITH_DES_CBC_SHA =
+    new CipherSuite("DES", "RSA", "RSA", "SSLMAC-SHA", 8, 0x00, 0x09,
+                    "SSL_RSA_WITH_DES_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_RSA_WITH_3DES_EDE_CBC_SHA =
+    new CipherSuite("TripleDES", "RSA", "RSA", "SSLMAC-SHA", 24, 0x00, 0x0A,
+                    "SSL_RSA_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA =
+    new CipherSuite("DES", "DH", "DSS", "SSLMAC-SHA", 5, 0x00, 0x0B,
+                    "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DH_DSS_WITH_DES_CBC_SHA =
+    new CipherSuite("DES", "DH", "DSS", "SSLMAC-SHA", 8, 0x00, 0x0C,
+                    "SSL_DH_DSS_WITH_DES_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA =
+    new CipherSuite("TripleDES", "DH", "DSS", "SSLMAC-SHA", 24, 0x00, 0x0D,
+                    "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA =
+    new CipherSuite("DES", "DH", "RSA", "SSLMAC-SHA", 5, 0x00, 0x0E,
+                    "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DH_RSA_WITH_DES_CBC_SHA =
+    new CipherSuite("DES", "DH", "RSA", "SSLMAC-SHA", 8, 0x00, 0x0F,
+                    "SSL_DH_RSA_WITH_DES_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA =
+    new CipherSuite("TripleDES", "DH", "RSA", "SSLMAC-SHA", 24, 0x00, 0x10,
+                    "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA =
+    new CipherSuite("DES", "DHE", "DSS", "SSLMAC-SHA", 5, 0x00, 0x11,
+                    "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DHE_DSS_WITH_DES_CBC_SHA =
+    new CipherSuite("DES", "DHE", "DSS", "SSLMAC-SHA", 8, 0x00, 0x12,
+                    "SSL_DHE_DSS_WITH_DES_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA =
+    new CipherSuite("TripleDES", "DHE", "DSS", "SSLMAC-SHA", 24, 0x00, 0x13,
+                    "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA =
+    new CipherSuite("DES", "DHE", "RSA", "SSLMAC-SHA", 5, 0x00, 0x14,
+                    "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DHE_RSA_WITH_DES_CBC_SHA =
+    new CipherSuite("DES", "DHE", "RSA", "SSLMAC-SHA", 8, 0x00, 0x15,
+                    "SSL_DHE_RSA_WITH_DES_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA =
+    new CipherSuite("TripleDES", "DHE", "RSA", "SSLMAC-SHA", 24, 0x00, 0x16,
+                    "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.SSL_3);
+
+  // AES CipherSuites.
+  static final CipherSuite SSL_RSA_WITH_AES_128_CBC_SHA =
+    new CipherSuite("AES", "RSA", "RSA", "SSLMAC-SHA", 16, 0x00, 0x2F,
+                    "SSL_RSA_WITH_AES_128_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DH_DSS_WITH_AES_128_CBC_SHA =
+    new CipherSuite("AES", "DH", "DSS", "SSLMAC-SHA", 16, 0x00, 0x30,
+                    "SSL_DH_DSS_WITH_AES_128_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DH_RSA_WITH_AES_128_CBC_SHA =
+    new CipherSuite("AES", "DH", "RSA", "SSLMAC-SHA", 16, 0x00, 0x31,
+                    "SSL_DH_RSA_WITH_AES_128_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DHE_DSS_WITH_AES_128_CBC_SHA =
+    new CipherSuite("AES", "DHE", "DSS", "SSLMAC-SHA", 16, 0x00, 0x32,
+                    "SSL_DHE_DSS_WITH_AES_128_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DHE_RSA_WITH_AES_128_CBC_SHA =
+    new CipherSuite("AES", "DHE", "RSA", "SSLMAC-SHA", 16, 0x00, 0x33,
+                    "SSL_DHE_RSA_WITH_AES_128_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_RSA_WITH_AES_256_CBC_SHA =
+    new CipherSuite("AES", "RSA", "RSA", "SSLMAC-SHA", 32, 0x00, 0x35,
+                    "SSL_RSA_WITH_AES_256_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DH_DSS_WITH_AES_256_CBC_SHA =
+    new CipherSuite("AES", "DH", "DSS", "SSLMAC-SHA", 32, 0x00, 0x36,
+                    "SSL_DH_DSS_WITH_AES_256_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DH_RSA_WITH_AES_256_CBC_SHA =
+    new CipherSuite("AES", "DH", "RSA", "SSLMAC-SHA", 32, 0x00, 0x37,
+                    "SSL_DH_RSA_WITH_AES_256_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DHE_DSS_WITH_AES_256_CBC_SHA =
+    new CipherSuite("AES", "DHE", "DSS", "SSLMAC-SHA", 32, 0x00, 0x38,
+                    "SSL_DHE_DSS_WITH_AES_256_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DHE_RSA_WITH_AES_256_CBC_SHA =
+    new CipherSuite("AES", "DHE", "RSA", "SSLMAC-SHA", 32, 0x00, 0x39,
+                    "SSL_DHE_RSA_WITH_AES_256_CBC_SHA", ProtocolVersion.SSL_3);
+
+  // Ciphersuites from the OpenPGP extension draft.
+  static final CipherSuite SSL_DHE_DSS_WITH_CAST_128_CBC_SHA =
+    new CipherSuite("CAST5", "DHE", "DSS", "HMAC-SHA", 16, 0x00, 0x70,
+                    "SSL_DHE_DSS_WITH_CAST_128_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DHE_DSS_WITH_CAST_128_CBC_RMD =
+    new CipherSuite("CAST5", "DHE", "DSS", "HMAC-RIPEMD-160", 16, 0x00, 0x71,
+                    "SSL_DHE_DSS_WITH_CAST_128_CBC_RMD", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DHE_DSS_WITH_3DES_EDE_CBC_RMD =
+    new CipherSuite("TripleDES", "DHE", "DSS", "HMAC-RIPEMD-160", 24, 0x00, 0x72,
+                    "SSL_DHE_DSS_WITH_3DES_EDE_CBC_RMD", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DHE_DSS_WITH_AES_128_CBC_RMD =
+    new CipherSuite("AES", "DHE", "DSS", "HMAC-RIPEMD-160", 16, 0x00, 0x73,
+                    "SSL_DHE_DSS_WITH_AES_128_CBC_RMD", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DHE_DSS_WITH_AES_256_CBC_RMD =
+    new CipherSuite("AES", "DHE", "DSS", "HMAC-RIPEMD-160", 32, 0x00, 0x74,
+                    "SSL_DHE_DSS_WITH_AES_256_CBC_RMD", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DHE_RSA_WITH_CAST_128_CBC_SHA =
+    new CipherSuite("CAST5", "DHE", "RSA", "HMAC-SHA", 16, 0x00, 0x75,
+                    "SSL_DHE_RSA_WITH_CAST_128_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DHE_RSA_WITH_CAST_128_CBC_RMD =
+    new CipherSuite("CAST5", "DHE", "RSA", "HMAC-RIPEMD-160", 16, 0x00, 0x76,
+                    "SSL_DHE_RSA_WITH_CAST_128_CBC_RMD", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DHE_RSA_WITH_3DES_EDE_CBC_RMD =
+    new CipherSuite("TripleDES", "DHE", "RSA", "HMAC-RIPEMD-160", 24, 0x00, 0x77,
+                    "SSL_DHE_RSA_WITH_3DES_EDE_CBC_RMD", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DHE_RSA_WITH_AES_128_CBC_RMD =
+    new CipherSuite("AES", "DHE", "RSA", "HMAC-RIPEMD-160", 16, 0x00, 0x78,
+                    "SSL_DHE_RSA_WITH_AES_128_CBC_RMD", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_DHE_RSA_WITH_AES_256_CBC_RMD =
+    new CipherSuite("AES", "DHE", "RSA", "HMAC-RIPEMD-160", 32, 0x00, 0x79,
+                    "SSL_DHE_RSA_WITH_AES_256_CBC_RMD", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_RSA_WITH_CAST_128_CBC_SHA =
+    new CipherSuite("CAST5", "RSA", "RSA", "HMAC-SHA", 16, 0x00, 0x7A,
+                    "SSL_RSA_WITH_CAST_128_CBC_SHA", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_RSA_WITH_CAST_128_CBC_RMD =
+    new CipherSuite("CAST5", "RSA", "RSA", "HMAC-RIPEMD-160", 16, 0x00, 0x7B,
+                    "SSL_RSA_WITH_CAST_128_CBC_RMD", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_RSA_WITH_3DES_EDE_CBC_RMD =
+    new CipherSuite("TripleDES", "RSA", "RSA", "HMAC-RIPEMD-160", 24, 0x00, 0x7C,
+                    "SSL_RSA_WITH_3DES_EDE_CBC_RMD", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_RSA_WITH_AES_128_CBC_RMD =
+    new CipherSuite("AES", "RSA", "RSA", "HMAC-RIPEMD-160", 16, 0x00, 0x7D,
+                    "SSL_RSA_WITH_AES_128_CBC_RMD", ProtocolVersion.SSL_3);
+  static final CipherSuite SSL_RSA_WITH_AES_256_CBC_RMD =
+    new CipherSuite("AES", "RSA", "RSA", "HMAC-RIPEMD-160", 32, 0x00, 0x7E,
+                    "SSL_RSA_WITH_AES_256_CBC_RMD", ProtocolVersion.SSL_3);
+
+  static final CipherSuite TLS_NULL_WITH_NULL_NULL =
+    new CipherSuite("null", "null", "null", "null", 0, 0x00, 0x00,
+                    "TLS_NULL_WITH_NULL_NULL", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_RSA_WITH_NULL_MD5 =
+    new CipherSuite("null", "RSA", "RSA", "HMAC-MD5", 0, 0x00, 0x01,
+                    "TLS_RSA_WITH_NULL_MD5", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_RSA_WITH_NULL_SHA =
+    new CipherSuite("null", "RSA", "RSA", "HMAC-SHA", 0, 0x00, 0x02,
+                    "TLS_RSA_WITH_NULL_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_RSA_EXPORT_WITH_RC4_40_MD5 =
+    new CipherSuite("RC4", "RSA", "RSA", "HMAC-MD5", 5, 0x00, 0x03,
+                    "TLS_RSA_EXPORT_WITH_RC4_40_MD5", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_RSA_WITH_RC4_128_MD5 =
+    new CipherSuite("RC4", "RSA", "RSA", "HMAC-MD5", 16, 0x00, 0x04,
+                    "TLS_RSA_WITH_RC4_128_MD5", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_RSA_WITH_RC4_128_SHA =
+    new CipherSuite("RC4", "RSA", "RSA", "HMAC-SHA", 16, 0x00, 0x05,
+                    "TLS_RSA_WITH_RC4_128_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_RSA_EXPORT_WITH_DES40_CBC_SHA =
+    new CipherSuite("DES", "RSA", "RSA", "HMAC-SHA", 5, 0x00, 0x08,
+                    "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_RSA_WITH_DES_CBC_SHA =
+    new CipherSuite("DES", "RSA", "RSA", "HMAC-SHA", 8, 0x00, 0x09,
+                    "TLS_RSA_WITH_DES_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_RSA_WITH_3DES_EDE_CBC_SHA =
+    new CipherSuite("TripleDES", "RSA", "RSA", "HMAC-SHA", 24, 0x00, 0x0A,
+                    "TLS_RSA_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA =
+    new CipherSuite("DES", "DH", "DSS", "HMAC-SHA", 5, 0x00, 0x0B,
+                    "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DH_DSS_WITH_DES_CBC_SHA =
+    new CipherSuite("DES", "DH", "DSS", "HMAC-SHA", 8, 0x00, 0x0C,
+                    "TLS_DH_DSS_WITH_DES_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA =
+    new CipherSuite("TripleDES", "DH", "DSS", "HMAC-SHA", 24, 0x00, 0x0D,
+                    "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA =
+    new CipherSuite("DES", "DH", "RSA", "HMAC-SHA", 5, 0x00, 0x0E,
+                    "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DH_RSA_WITH_DES_CBC_SHA =
+    new CipherSuite("DES", "DH", "RSA", "HMAC-SHA", 8, 0x00, 0x0F,
+                    "TLS_DH_RSA_WITH_DES_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA =
+    new CipherSuite("TripleDES", "DH", "RSA", "HMAC-SHA", 24, 0x00, 0x10,
+                    "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA =
+    new CipherSuite("DES", "DHE", "DSS", "HMAC-SHA", 5, 0x00, 0x11,
+                    "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DHE_DSS_WITH_DES_CBC_SHA =
+    new CipherSuite("DES", "DHE", "DSS", "HMAC-SHA", 8, 0x00, 0x12,
+                    "TLS_DHE_DSS_WITH_DES_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA =
+    new CipherSuite("TripleDES", "DHE", "DSS", "HMAC-SHA", 24, 0x00, 0x13,
+                    "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA =
+    new CipherSuite("DES", "DHE", "RSA", "HMAC-SHA", 5, 0x00, 0x14,
+                    "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DHE_RSA_WITH_DES_CBC_SHA =
+    new CipherSuite("DES", "DHE", "RSA", "HMAC-SHA", 8, 0x00, 0x15,
+                    "TLS_DHE_RSA_WITH_DES_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA =
+    new CipherSuite("TripleDES", "DHE", "RSA", "HMAC-SHA", 24, 0x00, 0x16,
+                    "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.TLS_1);
+
+  // AES CipherSuites.
+  static final CipherSuite TLS_RSA_WITH_AES_128_CBC_SHA =
+    new CipherSuite("AES", "RSA", "RSA", "HMAC-SHA", 16, 0x00, 0x2F,
+                    "TLS_RSA_WITH_AES_128_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DH_DSS_WITH_AES_128_CBC_SHA =
+    new CipherSuite("AES", "DH", "DSS", "HMAC-SHA", 16, 0x00, 0x30,
+                    "TLS_DH_DSS_WITH_AES_128_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DH_RSA_WITH_AES_128_CBC_SHA =
+    new CipherSuite("AES", "DH", "RSA", "HMAC-SHA", 16, 0x00, 0x31,
+                    "TLS_DH_RSA_WITH_AES_128_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DHE_DSS_WITH_AES_128_CBC_SHA =
+    new CipherSuite("AES", "DHE", "DSS", "HMAC-SHA", 16, 0x00, 0x32,
+                    "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DHE_RSA_WITH_AES_128_CBC_SHA =
+    new CipherSuite("AES", "DHE", "RSA", "HMAC-SHA", 16, 0x00, 0x33,
+                    "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_RSA_WITH_AES_256_CBC_SHA =
+    new CipherSuite("AES", "RSA", "RSA", "HMAC-SHA", 32, 0x00, 0x35,
+                    "TLS_RSA_WITH_AES_256_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DH_DSS_WITH_AES_256_CBC_SHA =
+    new CipherSuite("AES", "DH", "DSS", "HMAC-SHA", 32, 0x00, 0x36,
+                    "TLS_DH_DSS_WITH_AES_256_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DH_RSA_WITH_AES_256_CBC_SHA =
+    new CipherSuite("AES", "DH", "RSA", "HMAC-SHA", 32, 0x00, 0x37,
+                    "TLS_DH_RSA_WITH_AES_256_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DHE_DSS_WITH_AES_256_CBC_SHA =
+    new CipherSuite("AES", "DHE", "DSS", "HMAC-SHA", 32, 0x00, 0x38,
+                    "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DHE_RSA_WITH_AES_256_CBC_SHA =
+    new CipherSuite("AES", "DHE", "RSA", "HMAC-SHA", 32, 0x00, 0x39,
+                    "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", ProtocolVersion.TLS_1);
+
+  // Secure remote password (SRP) ciphersuites
+  static final CipherSuite TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA =
+    new CipherSuite("TripleDES", "SRP", "anon", "HMAC-SHA", 24, 0x00, 0x50,
+                    "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA =
+    new CipherSuite("TripleDES", "SRP", "RSA", "HMAC-SHA", 24, 0x00, 0x51,
+                    "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA =
+    new CipherSuite("TripleDES", "SRP", "DSS", "HMAC-SHA", 24, 0x00, 0x52,
+                    "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_SRP_SHA_WITH_AES_128_CBC_SHA =
+    new CipherSuite("AES", "SRP", "anon", "HMAC-SHA", 16, 0x00, 0x53,
+                    "TLS_SRP_SHA_WITH_AES_128_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA =
+    new CipherSuite("AES", "SRP", "RSA", "HMAC-SHA", 16, 0x00, 0x54,
+                    "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA =
+    new CipherSuite("AES", "SRP", "DSS", "HMAC-SHA", 16, 0x00, 0x55,
+                    "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_SRP_SHA_WITH_AES_256_CBC_SHA =
+    new CipherSuite("AES", "SRP", "anon", "HMAC-SHA", 32, 0x00, 0x56,
+                    "TLS_SRP_SHA_WITH_AES_256_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA =
+    new CipherSuite("AES", "SRP", "RSA", "HMAC-SHA", 32, 0x00, 0x57,
+                    "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA =
+    new CipherSuite("AES", "SRP", "DSS", "HMAC-SHA", 32, 0x00, 0x58,
+                    "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA", ProtocolVersion.TLS_1);
+
+  // Ciphersuites from the OpenPGP extension draft.
+  static final CipherSuite TLS_DHE_DSS_WITH_CAST_128_CBC_SHA =
+    new CipherSuite("CAST5", "DHE", "DSS", "HMAC-SHA", 16, 0x00, 0x70,
+                    "TLS_DHE_DSS_WITH_CAST_128_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DHE_DSS_WITH_CAST_128_CBC_RMD =
+    new CipherSuite("CAST5", "DHE", "DSS", "HMAC-RIPEMD-160", 16, 0x00, 0x71,
+                    "TLS_DHE_DSS_WITH_CAST_128_CBC_RMD", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD =
+    new CipherSuite("TripleDES", "DHE", "DSS", "HMAC-RIPEMD-160", 24, 0x00, 0x72,
+                    "TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DHE_DSS_WITH_AES_128_CBC_RMD =
+    new CipherSuite("AES", "DHE", "DSS", "HMAC-RIPEMD-160", 16, 0x00, 0x73,
+                    "TLS_DHE_DSS_WITH_AES_128_CBC_RMD", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DHE_DSS_WITH_AES_256_CBC_RMD =
+    new CipherSuite("AES", "DHE", "DSS", "HMAC-RIPEMD-160", 32, 0x00, 0x74,
+                    "TLS_DHE_DSS_WITH_AES_256_CBC_RMD", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DHE_RSA_WITH_CAST_128_CBC_SHA =
+    new CipherSuite("CAST5", "DHE", "RSA", "HMAC-SHA", 16, 0x00, 0x75,
+                    "TLS_DHE_RSA_WITH_CAST_128_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DHE_RSA_WITH_CAST_128_CBC_RMD =
+    new CipherSuite("CAST5", "DHE", "RSA", "HMAC-RIPEMD-160", 16, 0x00, 0x76,
+                    "TLS_DHE_RSA_WITH_CAST_128_CBC_RMD", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD =
+    new CipherSuite("TripleDES", "DHE", "RSA", "HMAC-RIPEMD-160", 24, 0x00, 0x77,
+                    "TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DHE_RSA_WITH_AES_128_CBC_RMD =
+    new CipherSuite("AES", "DHE", "RSA", "HMAC-RIPEMD-160", 16, 0x00, 0x78,
+                    "TLS_DHE_RSA_WITH_AES_128_CBC_RMD", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_DHE_RSA_WITH_AES_256_CBC_RMD =
+    new CipherSuite("AES", "DHE", "RSA", "HMAC-RIPEMD-160", 32, 0x00, 0x79,
+                    "TLS_DHE_RSA_WITH_AES_256_CBC_RMD", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_RSA_WITH_CAST_128_CBC_SHA =
+    new CipherSuite("CAST5", "RSA", "RSA", "HMAC-SHA", 16, 0x00, 0x7A,
+                    "TLS_RSA_WITH_CAST_128_CBC_SHA", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_RSA_WITH_CAST_128_CBC_RMD =
+    new CipherSuite("CAST5", "RSA", "RSA", "HMAC-RIPEMD-160", 16, 0x00, 0x7B,
+                    "TLS_RSA_WITH_CAST_128_CBC_RMD", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_RSA_WITH_3DES_EDE_CBC_RMD =
+    new CipherSuite("TripleDES", "RSA", "RSA", "HMAC-RIPEMD-160", 24, 0x00, 0x7C,
+                    "TLS_RSA_WITH_3DES_EDE_CBC_RMD", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_RSA_WITH_AES_128_CBC_RMD =
+    new CipherSuite("AES", "RSA", "RSA", "HMAC-RIPEMD-160", 16, 0x00, 0x7D,
+                    "TLS_RSA_WITH_AES_128_CBC_RMD", ProtocolVersion.TLS_1);
+  static final CipherSuite TLS_RSA_WITH_AES_256_CBC_RMD =
+    new CipherSuite("AES", "RSA", "RSA", "HMAC-RIPEMD-160", 32, 0x00, 0x7E,
+                    "TLS_RSA_WITH_AES_256_CBC_RMD", ProtocolVersion.TLS_1);
+
+  private final String cipherName;
+  private final String kexName;
+  private final String sigName;
+  private final String macName;
+  private final boolean exportable;
+  private final boolean isStream;
+  private final int keyLength;
+  private final byte[] id;
+  private final String name;
+  private final ProtocolVersion version;
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  private CipherSuite(String cipherName, String kexName, String sigName,
+                      String macName, int keyLength, int id1, int id2,
+                      String name, ProtocolVersion version)
+  {
+    this.cipherName = cipherName.intern();
+    this.kexName = kexName.intern();
+    this.sigName = sigName.intern();
+    this.macName = macName.intern();
+    this.exportable = keyLength <= 5;
+    this.isStream = cipherName.equals("null") || cipherName.equals("RC4");
+    this.keyLength = keyLength;
+    this.id = new byte[] { (byte) id1, (byte) id2 };
+    this.name = name.intern();
+    this.version = version;
+    namesToSuites.put(name, this);
+    if (name.startsWith("TLS"))
+      {
+        tlsSuiteNames.add(name);
+      }
+  }
+
+  private CipherSuite(byte[] id)
+  {
+    cipherName = null;
+    kexName = null;
+    sigName = null;
+    macName = null;
+    exportable = false;
+    isStream = false;
+    keyLength = 0;
+    this.id = id;
+    name = null;
+    version = null;
+  }
+
+  // Class methods.
+  // -------------------------------------------------------------------------
+
+  /**
+   * Returns the cipher suite for the given name, or null if there is no
+   * such suite.
+   *
+   * @return The named cipher suite.
+   */
+  static CipherSuite forName(String name)
+  {
+    return (CipherSuite) namesToSuites.get(name);
+  }
+
+  static List availableSuiteNames()
+  {
+    return tlsSuiteNames;
+  }
+
+  static CipherSuite read(InputStream in) throws IOException
+  {
+    DataInputStream din = new DataInputStream(in);
+    byte[] id = new byte[2];
+    din.readFully(id);
+    return new CipherSuite(id);
+  }
+
+  static IMode getCipher(String cbcCipherName)
+  {
+    IBlockCipher cipher = CipherFactory.getInstance(cbcCipherName);
+    if (cipher == null)
+      {
+        return null;
+      }
+    return ModeFactory.getInstance("CBC", cipher, cipher.defaultBlockSize());
+  }
+
+  static Cipher getJCECipher (final String name)
+    throws NoSuchAlgorithmException, NoSuchPaddingException
+  {
+    final String provider = Util.getSecurityProperty ("jessie.with.jce.provider");
+    if (name.equals ("RC4"))
+      {
+        if (provider != null)
+          {
+            try
+              {
+                return Cipher.getInstance (name, provider);
+              }
+            catch (NoSuchProviderException nsae)
+              {
+                // Fall through. Try any available provider.
+              }
+          }
+
+        return Cipher.getInstance (name);
+      }
+    else
+      {
+        // Oh, hey! Look! Something else Sun doesn't understand: SSLv3 padding
+        // is different than TLSv1 in subtle, but important, ways. But they
+        // sorta look the same, so why not make them equivalent?
+        //
+        // There should be a seperate padding "TLS1Padding".
+        if (provider != null)
+          {
+            try
+              {
+                return Cipher.getInstance (name + "/CBC/SSL3Padding", provider);
+              }
+            catch (NoSuchProviderException nspe)
+              {
+                // Fall through. Try any available provider.
+              }
+          }
+        return Cipher.getInstance (name + "/CBC/SSL3Padding");
+      }
+  }
+
+  static IMac getMac(String macName)
+  {
+    if (macName.startsWith("SSLMAC-"))
+      {
+        return new SSLHMac(macName.substring(7));
+      }
+    else
+      {
+        return MacFactory.getInstance(macName);
+      }
+  }
+
+  static Mac getJCEMac (final String name)
+    throws NoSuchAlgorithmException
+  {
+    final String provider = Util.getSecurityProperty ("jessie.with.jce.provider");
+    if (provider != null)
+      {
+        try
+          {
+            return Mac.getInstance (name, provider);
+          }
+        catch (NoSuchProviderException nspe)
+          {
+            // Fall through. Try any available provider.
+          }
+      }
+    return Mac.getInstance (name);
+  }
+
+  // Intance methods.
+  // -------------------------------------------------------------------------
+
+  public void write(OutputStream out) throws IOException
+  {
+    out.write(id);
+  }
+
+  CipherSuite resolve(ProtocolVersion version)
+  {
+    if (version == ProtocolVersion.SSL_3)
+      {
+        if (id[0] == 0x00) switch (id[1])
+          {
+          case 0x00: return SSL_NULL_WITH_NULL_NULL;
+          case 0x01: return SSL_RSA_WITH_NULL_MD5;
+          case 0x02: return SSL_RSA_WITH_NULL_SHA;
+          case 0x03: return SSL_RSA_EXPORT_WITH_RC4_40_MD5;
+          case 0x04: return SSL_RSA_WITH_RC4_128_MD5;
+          case 0x05: return SSL_RSA_WITH_RC4_128_SHA;
+          case 0x08: return SSL_RSA_EXPORT_WITH_DES40_CBC_SHA;
+          case 0x09: return SSL_RSA_WITH_DES_CBC_SHA;
+          case 0x0A: return SSL_RSA_WITH_3DES_EDE_CBC_SHA;
+          case 0x0B: return SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA;
+          case 0x0C: return SSL_DH_DSS_WITH_DES_CBC_SHA;
+          case 0x0D: return SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA;
+          case 0x0E: return SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA;
+          case 0x0F: return SSL_DH_RSA_WITH_DES_CBC_SHA;
+          case 0x10: return SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA;
+          case 0x11: return SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA;
+          case 0x12: return SSL_DHE_DSS_WITH_DES_CBC_SHA;
+          case 0x13: return SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA;
+          case 0x14: return SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA;
+          case 0x15: return SSL_DHE_RSA_WITH_DES_CBC_SHA;
+          case 0x16: return SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA;
+          case 0x2F: return SSL_RSA_WITH_AES_128_CBC_SHA;
+          case 0x30: return SSL_DH_DSS_WITH_AES_128_CBC_SHA;
+          case 0x31: return SSL_DH_RSA_WITH_AES_128_CBC_SHA;
+          case 0x32: return SSL_DHE_DSS_WITH_AES_128_CBC_SHA;
+          case 0x33: return SSL_DHE_RSA_WITH_AES_128_CBC_SHA;
+          case 0x35: return SSL_RSA_WITH_AES_256_CBC_SHA;
+          case 0x36: return SSL_DH_DSS_WITH_AES_256_CBC_SHA;
+          case 0x37: return SSL_DH_RSA_WITH_AES_256_CBC_SHA;
+          case 0x38: return SSL_DHE_DSS_WITH_AES_256_CBC_SHA;
+          case 0x39: return SSL_DHE_RSA_WITH_AES_256_CBC_SHA;
+          }
+      }
+    else if (version == ProtocolVersion.TLS_1 ||
+             version == ProtocolVersion.TLS_1_1)
+      {
+        if (id[0] == 0x00) switch (id[1])
+          {
+          case 0x00: return TLS_NULL_WITH_NULL_NULL;
+          case 0x01: return TLS_RSA_WITH_NULL_MD5;
+          case 0x02: return TLS_RSA_WITH_NULL_SHA;
+          case 0x03: return TLS_RSA_EXPORT_WITH_RC4_40_MD5;
+          case 0x04: return TLS_RSA_WITH_RC4_128_MD5;
+          case 0x05: return TLS_RSA_WITH_RC4_128_SHA;
+          case 0x08: return TLS_RSA_EXPORT_WITH_DES40_CBC_SHA;
+          case 0x09: return TLS_RSA_WITH_DES_CBC_SHA;
+          case 0x0A: return TLS_RSA_WITH_3DES_EDE_CBC_SHA;
+          case 0x0B: return TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA;
+          case 0x0C: return TLS_DH_DSS_WITH_DES_CBC_SHA;
+          case 0x0D: return TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA;
+          case 0x0E: return TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA;
+          case 0x0F: return TLS_DH_RSA_WITH_DES_CBC_SHA;
+          case 0x10: return TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA;
+          case 0x11: return TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA;
+          case 0x12: return TLS_DHE_DSS_WITH_DES_CBC_SHA;
+          case 0x13: return TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA;
+          case 0x14: return TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA;
+          case 0x15: return TLS_DHE_RSA_WITH_DES_CBC_SHA;
+          case 0x16: return TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA;
+          case 0x2F: return TLS_RSA_WITH_AES_128_CBC_SHA;
+          case 0x30: return TLS_DH_DSS_WITH_AES_128_CBC_SHA;
+          case 0x31: return TLS_DH_RSA_WITH_AES_128_CBC_SHA;
+          case 0x32: return TLS_DHE_DSS_WITH_AES_128_CBC_SHA;
+          case 0x33: return TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
+          case 0x35: return TLS_RSA_WITH_AES_256_CBC_SHA;
+          case 0x36: return TLS_DH_DSS_WITH_AES_256_CBC_SHA;
+          case 0x37: return TLS_DH_RSA_WITH_AES_256_CBC_SHA;
+          case 0x38: return TLS_DHE_DSS_WITH_AES_256_CBC_SHA;
+          case 0x39: return TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
+          case 0x50: return TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA;
+          case 0x51: return TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA;
+          case 0x52: return TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA;
+          case 0x53: return TLS_SRP_SHA_WITH_AES_128_CBC_SHA;
+          case 0x54: return TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA;
+          case 0x55: return TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA;
+          case 0x56: return TLS_SRP_SHA_WITH_AES_256_CBC_SHA;
+          case 0x57: return TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA;
+          case 0x58: return TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA;
+          case 0x70: return TLS_DHE_DSS_WITH_CAST_128_CBC_SHA;
+          case 0x71: return TLS_DHE_DSS_WITH_CAST_128_CBC_RMD;
+          case 0x72: return TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD;
+          case 0x73: return TLS_DHE_DSS_WITH_AES_128_CBC_RMD;
+          case 0x74: return TLS_DHE_DSS_WITH_AES_256_CBC_RMD;
+          case 0x75: return TLS_DHE_RSA_WITH_CAST_128_CBC_SHA;
+          case 0x76: return TLS_DHE_RSA_WITH_CAST_128_CBC_RMD;
+          case 0x77: return TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD;
+          case 0x78: return TLS_DHE_RSA_WITH_AES_128_CBC_RMD;
+          case 0x79: return TLS_DHE_RSA_WITH_AES_256_CBC_RMD;
+          case 0x7A: return TLS_RSA_WITH_CAST_128_CBC_SHA;
+          case 0x7B: return TLS_RSA_WITH_CAST_128_CBC_RMD;
+          case 0x7C: return TLS_RSA_WITH_3DES_EDE_CBC_RMD;
+          case 0x7D: return TLS_RSA_WITH_AES_128_CBC_RMD;
+          case 0x7E: return TLS_RSA_WITH_AES_256_CBC_RMD;
+          }
+      }
+    return this;
+  }
+
+  String getCipher()
+  {
+    return cipherName;
+  }
+
+  int getKeyLength()
+  {
+    return keyLength;
+  }
+
+  String getKeyExchange()
+  {
+    return kexName;
+  }
+
+  String getSignature()
+  {
+    return sigName;
+  }
+
+  String getMac()
+  {
+    return macName;
+  }
+
+  boolean isExportable()
+  {
+    return exportable;
+  }
+
+  boolean isStreamCipher()
+  {
+    return isStream;
+  }
+
+  String getAuthType()
+  {
+    if (kexName.equals("RSA"))
+      {
+        if (isExportable())
+          {
+            return "RSA_EXPORT";
+          }
+        return "RSA";
+      }
+    return kexName + "_" + sigName;
+  }
+
+  byte[] getId()
+  {
+    return id;
+  }
+
+  ProtocolVersion getVersion()
+  {
+    return version;
+  }
+
+  public boolean equals(Object o)
+  {
+    if (!(o instanceof CipherSuite))
+      {
+        return false;
+      }
+    if (o == this)
+      return true;
+    byte[] id = ((CipherSuite) o).getId();
+    return id[0] == this.id[0] &&
+           id[1] == this.id[1];
+  }
+
+  public int hashCode()
+  {
+    if (version == null)
+      {
+        return 0xFFFF0000 | (id[0] & 0xFF) << 8 | (id[1] & 0xFF);
+      }
+    return version.getMajor() << 24 | version.getMinor() << 16
+      | (id[0] & 0xFF) << 8 | (id[1] & 0xFF);
+  }
+
+  public String toString()
+  {
+    if (name == null)
+      {
+        return "UNKNOWN { " + (id[0] & 0xFF) + ", " + (id[1] & 0xFF) + " }";
+      }
+    return name;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ClientHello.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ClientHello.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ClientHello.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ClientHello.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,253 @@
+/* ClientHello.java -- SSL ClientHello message.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.net.ssl.SSLProtocolException;
+
+final class ClientHello implements Handshake.Body
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private ProtocolVersion version;
+  private Random random;
+  private byte[] sessionId;
+  private List suites;
+  private List comp;
+  private List extensions;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  ClientHello(ProtocolVersion version, Random random,
+              byte[] sessionId, List suites, List comp)
+  {
+    this(version, random, sessionId, suites, comp, null);
+  }
+
+  ClientHello(ProtocolVersion version, Random random,
+              byte[] sessionId, List suites, List comp, List extensions)
+  {
+    this.version = version;
+    this.random = random;
+    this.sessionId = sessionId;
+    this.suites = suites;
+    this.comp = comp;
+    this.extensions = extensions;
+  }
+
+  // Class methods.
+  // -------------------------------------------------------------------------
+
+  static ClientHello read(InputStream in) throws IOException
+  {
+    ProtocolVersion vers = ProtocolVersion.read(in);
+    Random rand = Random.read(in);
+    byte[] id = new byte[in.read() & 0xFF];
+    in.read(id);
+    int len = (in.read() & 0xFF) << 8 | (in.read() & 0xFF);
+    ArrayList suites = new ArrayList(len / 2);
+    for (int i = 0; i < len; i += 2)
+      {
+        suites.add(CipherSuite.read(in).resolve(vers));
+      }
+    len = in.read() & 0xFF;
+    ArrayList comp = new ArrayList(len);
+    for (int i = 0; i < len; i++)
+      {
+        comp.add(CompressionMethod.read(in));
+      }
+
+    List ext = null;
+    // Since parsing MAY need to continue into the extensions fields, or it
+    // may end here, the specified input stream MUST be a ByteArrayInputStream
+    // over all the data this hello contains. Otherwise this will mess up
+    // the data stream.
+    if (in.available() > 0) // then we have extensions.
+      {
+        ext = new LinkedList();
+        len = (in.read() & 0xFF) << 8 | (in.read() & 0xFF);
+        int count = 0;
+        while (count < len)
+          {
+            Extension e = Extension.read(in);
+            ext.add(e);
+            count += e.getValue().length + 4;
+          }
+      }
+    return new ClientHello(vers, rand, id, suites, comp, ext);
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public void write(OutputStream out) throws IOException
+  {
+    version.write(out);
+    random.write(out);
+    out.write(sessionId.length);
+    out.write(sessionId);
+    out.write((suites.size() << 1) >>> 8 & 0xFF);
+    out.write((suites.size() << 1) & 0xFF);
+    for (Iterator i = suites.iterator(); i.hasNext(); )
+      {
+        ((CipherSuite) i.next()).write(out);
+      }
+    out.write(comp.size());
+    for (Iterator i = comp.iterator(); i.hasNext(); )
+      {
+        out.write(((CompressionMethod) i.next()).getValue());
+      }
+    if (extensions != null)
+      {
+        ByteArrayOutputStream out2 = new ByteArrayOutputStream();
+        for (Iterator i = extensions.iterator(); i.hasNext(); )
+          {
+            ((Extension) i.next()).write(out2);
+          }
+        out.write(out2.size() >>> 8 & 0xFF);
+        out.write(out2.size() & 0xFF);
+        out2.writeTo(out);
+      }
+  }
+
+  ProtocolVersion getVersion()
+  {
+    return version;
+  }
+
+  Random getRandom()
+  {
+    return random;
+  }
+
+  byte[] getSessionId()
+  {
+    return sessionId;
+  }
+
+  List getCipherSuites()
+  {
+    return suites;
+  }
+
+  List getCompressionMethods()
+  {
+    return comp;
+  }
+
+  List getExtensions()
+  {
+    return extensions;
+  }
+
+  public String toString()
+  {
+    StringWriter str = new StringWriter();
+    PrintWriter out = new PrintWriter(str);
+    out.println("struct {");
+    out.println("  version = " + version + ";");
+    BufferedReader r = new BufferedReader(new StringReader(random.toString()));
+    String s;
+    try
+      {
+        while ((s = r.readLine()) != null)
+          {
+            out.print("  ");
+            out.println(s);
+          }
+      }
+    catch (IOException ignored)
+      {
+      }
+    out.println("  sessionId = " + Util.toHexString(sessionId, ':') + ";");
+    out.println("  cipherSuites = {");
+    for (Iterator i = suites.iterator(); i.hasNext(); )
+      {
+        out.print("    ");
+        out.println(i.next());
+      }
+    out.println("  };");
+    out.print("  compressionMethods = { ");
+    for (Iterator i = comp.iterator(); i.hasNext(); )
+      {
+        out.print(i.next());
+        if (i.hasNext())
+          out.print(", ");
+      }
+    out.println(" };");
+    if (extensions != null)
+      {
+        out.println("  extensions = {");
+        for (Iterator i = extensions.iterator(); i.hasNext(); )
+          {
+            r = new BufferedReader(new StringReader(i.next().toString()));
+            try
+              {
+                while ((s = r.readLine()) != null)
+                  {
+                    out.print("    ");
+                    out.println(s);
+                  }
+              }
+            catch (IOException ignored)
+              {
+              }
+          }
+        out.println("  };");
+      }
+    out.println("} ClientHello;");
+    return str.toString();
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ClientKeyExchange.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ClientKeyExchange.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ClientKeyExchange.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ClientKeyExchange.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,181 @@
+/* ClientKeyExchange.java -- SSL ClientKeyExchange message.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import java.math.BigInteger;
+
+import java.security.PublicKey;
+import java.security.interfaces.RSAKey;
+import javax.crypto.interfaces.DHPublicKey;
+
+final class ClientKeyExchange implements Handshake.Body
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final Object exObject;
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  ClientKeyExchange(byte[] encryptedSecret)
+  {
+    exObject = encryptedSecret;
+  }
+
+  ClientKeyExchange(BigInteger bigint)
+  {
+    exObject = bigint;
+  }
+
+  // Class method.
+  // -------------------------------------------------------------------------
+
+  static ClientKeyExchange read(InputStream in, CipherSuite suite,
+                                PublicKey key)
+    throws IOException
+  {
+    DataInputStream din = new DataInputStream(in);
+    if (suite.getKeyExchange().equals("RSA"))
+      {
+        int len = 0;
+        if (suite.getVersion() == ProtocolVersion.SSL_3)
+          {
+            len = (((RSAKey) key).getModulus().bitLength()+7) / 8;
+          }
+        else
+          {
+            len = din.readUnsignedShort();
+          }
+        byte[] buf = new byte[len];
+        din.readFully(buf);
+        return new ClientKeyExchange(buf);
+      }
+    else if (suite.getKeyExchange().equals("SRP"))
+      {
+        byte[] buf = new byte[din.readUnsignedShort()];
+        din.readFully(buf);
+        return new ClientKeyExchange(new BigInteger(1, buf));
+      }
+    else if (key == null || !(key instanceof DHPublicKey))  // explicit.
+      {
+        byte[] buf = new byte[din.readUnsignedShort()];
+        din.readFully(buf);
+        return new ClientKeyExchange(new BigInteger(1, buf));
+      }
+    else
+      {
+        return new ClientKeyExchange(new byte[0]);
+      }
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public void write(OutputStream out) throws IOException
+  {
+    throw new UnsupportedOperationException("use write(java.io.OutputStream,ProtocolVersion) instead");
+  }
+
+  public void write(OutputStream out, ProtocolVersion version) throws IOException
+  {
+    if (exObject instanceof byte[])
+      {
+        byte[] b = (byte[]) exObject;
+        if (b.length > 0)
+          {
+            if (version != ProtocolVersion.SSL_3)
+              {
+                out.write(b.length >>> 8 & 0xFF);
+                out.write(b.length & 0xFF);
+              }
+            out.write(b);
+          }
+      }
+    else
+      {
+        byte[] bigint = ((BigInteger) exObject).toByteArray();
+        if (bigint[0] == 0x00)
+          {
+            out.write(bigint.length - 1 >>> 8 & 0xFF);
+            out.write(bigint.length - 1 & 0xFF);
+            out.write(bigint, 1, bigint.length - 1);
+          }
+        else
+          {
+            out.write(bigint.length >>> 8 & 0xFF);
+            out.write(bigint.length & 0xFF);
+            out.write(bigint);
+          }
+      }
+  }
+
+  Object getExchangeObject()
+  {
+    return exObject;
+  }
+
+  public String toString()
+  {
+    StringWriter str = new StringWriter();
+    PrintWriter out = new PrintWriter(str);
+    out.println("struct {");
+    if (exObject instanceof byte[] && ((byte[]) exObject).length > 0)
+      {
+        out.println("  encryptedPreMasterSecret =");
+        out.print(Util.hexDump((byte[]) exObject, "    "));
+      }
+    else if (exObject instanceof BigInteger)
+      {
+        out.println("  clientPublic = " + ((BigInteger) exObject).toString(16) + ";");
+      }
+    out.println("} ClientKeyExchange;");
+    return str.toString();
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/CompressionMethod.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/CompressionMethod.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/CompressionMethod.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/CompressionMethod.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,104 @@
+/* CompressionMethod.java -- the compression method enum.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.EOFException;
+import java.io.InputStream;
+import java.io.IOException;
+
+final class CompressionMethod implements Enumerated
+{
+
+  // Constants and fields.
+  // -------------------------------------------------------------------------
+
+  static final CompressionMethod NULL = new CompressionMethod(0),
+    ZLIB = new CompressionMethod(1);
+
+  private final int value;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  private CompressionMethod(int value)
+  {
+    this.value = value;
+  }
+
+  // Class method.
+  // -------------------------------------------------------------------------
+
+  static CompressionMethod read(InputStream in) throws IOException
+  {
+    int value = in.read();
+    if (value == -1)
+      {
+        throw new EOFException("unexpected end of input stream");
+      }
+    switch (value & 0xFF)
+      {
+      case 0: return NULL;
+      case 1: return ZLIB;
+      default: return new CompressionMethod(value);
+      }
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public byte[] getEncoded()
+  {
+    return new byte[] { (byte) value };
+  }
+
+  public int getValue()
+  {
+    return value;
+  }
+
+  public String toString()
+  {
+    switch (value)
+      {
+      case 0: return "null";
+      case 1: return "zlib";
+      default: return "unknown(" + value + ")";
+      }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Constructed.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Constructed.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Constructed.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Constructed.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,57 @@
+/* Constructed.java -- constructed type.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * The base interface to SSL constructed types.
+ */
+interface Constructed
+{
+
+  /**
+   * Writes this structure's encoded form to the given output stream.
+   *
+   * @param out The output stream.
+   * @throws IOException If an I/O error occurs.
+   */
+  void write(OutputStream out) throws IOException;
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ContentType.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ContentType.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ContentType.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ContentType.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,135 @@
+/* ContentType.java -- record layer content type.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.EOFException;
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * The content type enumeration, which marks packets in the record layer.
+ *
+ * <pre>enum { change_cipher_spec(20), alert(21), handshake(22),
+ *             application_data(23), (255) } ContentType;</pre>
+ *
+ * @author Casey Marshall (rsdio at metastatic.org)
+ */
+final class ContentType implements Enumerated
+{
+
+  // Constants and fields.
+  // ------------------------------------------------------------------------
+
+  static final ContentType CLIENT_HELLO_V2    = new ContentType( 1);
+  static final ContentType CHANGE_CIPHER_SPEC = new ContentType(20);
+  static final ContentType ALERT              = new ContentType(21);
+  static final ContentType HANDSHAKE          = new ContentType(22);
+  static final ContentType APPLICATION_DATA   = new ContentType(23);
+
+  private int value;
+
+  // Constructors.
+  // ------------------------------------------------------------------------
+
+  private ContentType(int value)
+  {
+    this.value = value;
+  }
+
+  // Class methods.
+  // ------------------------------------------------------------------------
+
+  static final ContentType read(InputStream in) throws IOException
+  {
+    int value = in.read();
+    if (value == -1)
+      {
+        throw new EOFException("unexpected end of input stream");
+      }
+    switch (value & 0xFF)
+      {
+      case  1: return CLIENT_HELLO_V2;
+      case 20: return CHANGE_CIPHER_SPEC;
+      case 21: return ALERT;
+      case 22: return HANDSHAKE;
+      case 23: return APPLICATION_DATA;
+      default: return new ContentType(value);
+      }
+  }
+
+  // Instance methods.
+  // ------------------------------------------------------------------------
+
+  public byte[] getEncoded()
+  {
+    return new byte[] { (byte) value };
+  }
+
+  public int getValue()
+  {
+    return value;
+  }
+
+  public boolean equals(Object o)
+  {
+    if (o == null || !(o instanceof ContentType))
+      {
+        return false;
+      }
+    return ((ContentType) o).value == value;
+  }
+
+  public int hashCode()
+  {
+    return getValue();
+  }
+
+  public String toString()
+  {
+    switch (value)
+      {
+      case  1: return "v2_client_hello";
+      case 20: return "change_cipher_spec";
+      case 21: return "alert";
+      case 22: return "handshake";
+      case 23: return "application_data";
+      default: return "unknown(" + value + ")";
+      }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Context.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Context.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Context.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Context.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,334 @@
+/* Context.java -- SSLContext implementation.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.File;
+import java.io.InputStream;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyStoreException;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.UnrecoverableKeyException;
+import java.sql.SQLException;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContextSpi;
+import javax.net.ssl.SSLSessionContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509KeyManager;
+import javax.net.ssl.X509TrustManager;
+
+import gnu.javax.net.ssl.NullManagerParameters;
+import gnu.javax.net.ssl.SRPTrustManager;
+import gnu.javax.net.ssl.StaticTrustAnchors;
+
+/**
+ * This is Jessie's implementation of a {@link javax.net.ssl.SSLContext}
+ * engine, and is available under the algorithm names ``SSLv3'', ``SSL'',
+ * ``TLSv1'', and ``TLS''.
+ */
+public final class Context extends SSLContextSpi
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private SessionContext clientSessions;
+  private SessionContext serverSessions;
+  private X509KeyManager keyManager;
+  private X509TrustManager trustManager;
+  private SRPTrustManager srpTrustManager;
+  private SecureRandom random;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  public Context()
+  {
+    String codec = Util.getSecurityProperty("jessie.clientSessionContext.codec");
+    String codecClass = null;
+    if (codec == null)
+      {
+        codec = "null";
+      }
+    if (codec.equalsIgnoreCase("xml"))
+      {
+        codecClass = "gnu.javax.net.ssl.provider.XMLSessionContext";
+      }
+    else if (codec.equalsIgnoreCase("jdbc"))
+      {
+        codecClass = "gnu.javax.net.ssl.provider.JDBCSessionContext";
+      }
+    else if (codec.equalsIgnoreCase("null"))
+      {
+        codecClass = "gnu.javax.net.ssl.provider.SessionContext";
+      }
+    else
+      {
+        throw new IllegalArgumentException("no such codec: " + codec);
+      }
+    try
+      {
+        ClassLoader cl = Context.class.getClassLoader();
+        if (cl == null)
+          {
+            cl = ClassLoader.getSystemClassLoader();
+          }
+        clientSessions = (SessionContext) cl.loadClass(codecClass).newInstance();
+      }
+    catch (Exception ex)
+      {
+        ex.printStackTrace();
+        throw new IllegalArgumentException(ex.toString());
+      }
+
+    codec = Util.getSecurityProperty("jessie.serverSessionContext.codec");
+    if (codec == null)
+      {
+        codec = "null";
+      }
+    if (codec.equalsIgnoreCase("xml"))
+      {
+        codecClass = "gnu.javax.net.ssl.provider.XMLSessionContext";
+      }
+    else if (codec.equalsIgnoreCase("jdbc"))
+      {
+        codecClass = "gnu.javax.net.ssl.provider.JDBCSessionContext";
+      }
+    else if (codec.equalsIgnoreCase("null"))
+      {
+        codecClass = "gnu.javax.net.ssl.provider.SessionContext";
+      }
+    else
+      {
+        throw new IllegalArgumentException("no such codec: " + codec);
+      }
+    try
+      {
+        ClassLoader cl = Context.class.getClassLoader();
+        if (cl == null)
+          {
+            cl = ClassLoader.getSystemClassLoader();
+          }
+        serverSessions = (SessionContext) cl.loadClass(codecClass).newInstance();
+      }
+    catch (Exception ex)
+      {
+        ex.printStackTrace();
+        throw new IllegalArgumentException(ex.toString());
+      }
+  }
+
+  // Engine methods.
+  // -------------------------------------------------------------------------
+
+  protected SSLSessionContext engineGetClientSessionContext()
+  {
+    return clientSessions;
+  }
+
+  protected SSLSessionContext engineGetServerSessionContext()
+  {
+    return serverSessions;
+  }
+
+  protected javax.net.ssl.SSLServerSocketFactory engineGetServerSocketFactory()
+  {
+    if (keyManager == null || (trustManager == null && srpTrustManager == null)
+        || random == null)
+      {
+        throw new IllegalStateException();
+      }
+    return new SSLServerSocketFactory(trustManager, srpTrustManager, keyManager,
+                                      random, serverSessions);
+  }
+
+  protected javax.net.ssl.SSLSocketFactory engineGetSocketFactory()
+  {
+    if (keyManager == null || trustManager == null || random == null)
+      {
+        throw new IllegalStateException();
+      }
+    return new SSLSocketFactory(trustManager, keyManager, random, clientSessions);
+  }
+
+  protected void engineInit(KeyManager[] keyManagers,
+                            TrustManager[] trustManagers, SecureRandom random)
+    throws KeyManagementException
+  {
+    keyManager = null;
+    trustManager = null;
+    srpTrustManager = null;
+    if (keyManagers != null)
+      {
+        for (int i = 0; i < keyManagers.length; i++)
+          {
+            if (keyManagers[i] instanceof X509KeyManager)
+              {
+                keyManager = (X509KeyManager) keyManagers[i];
+                break;
+              }
+          }
+      }
+    if (keyManager == null)
+      {
+        keyManager = defaultKeyManager();
+      }
+    if (trustManagers != null)
+      {
+        for (int i = 0; i < trustManagers.length; i++)
+          {
+            if (trustManagers[i] instanceof X509TrustManager)
+              {
+                if (trustManager == null)
+                  {
+                    trustManager = (X509TrustManager) trustManagers[i];
+                  }
+              }
+            else if (trustManagers[i] instanceof SRPTrustManager)
+              {
+                if (srpTrustManager == null)
+                  {
+                    srpTrustManager = (SRPTrustManager) trustManagers[i];
+                  }
+              }
+          }
+      }
+    if (trustManager == null && srpTrustManager == null)
+      {
+        trustManager = defaultTrustManager();
+      }
+    if (random != null)
+      {
+        this.random = random;
+      }
+    else
+      {
+        this.random = defaultRandom();
+      }
+  }
+
+  // Own methods.
+  // -------------------------------------------------------------------------
+
+  private X509KeyManager defaultKeyManager() throws KeyManagementException
+  {
+    KeyManagerFactory fact = null;
+    try
+      {
+        fact = KeyManagerFactory.getInstance("JessieX509", "Jessie");
+      }
+    catch (NoSuchAlgorithmException nsae)
+      {
+        throw new KeyManagementException();
+      }
+    catch (NoSuchProviderException nspe)
+      {
+        throw new KeyManagementException();
+      }
+    try
+      {
+        fact.init(null, null);
+        return (X509KeyManager) fact.getKeyManagers()[0];
+      }
+    catch (NoSuchAlgorithmException nsae) { }
+    catch (KeyStoreException kse) { }
+    catch (UnrecoverableKeyException uke) { }
+    catch (IllegalStateException ise) { }
+
+    try
+      {
+        fact.init(new NullManagerParameters());
+        return (X509KeyManager) fact.getKeyManagers()[0];
+      }
+    catch (Exception shouldNotHappen)
+      {
+        throw new Error(shouldNotHappen.toString());
+      }
+  }
+
+  private X509TrustManager defaultTrustManager() throws KeyManagementException
+  {
+    try
+      {
+        TrustManagerFactory fact =
+          TrustManagerFactory.getInstance("JessieX509", "Jessie");
+        fact.init(StaticTrustAnchors.CA_CERTS);
+        return (X509TrustManager) fact.getTrustManagers()[0];
+      }
+    catch (NoSuchAlgorithmException nsae)
+      {
+        throw new KeyManagementException(nsae.toString());
+      }
+    catch (NoSuchProviderException nspe)
+      {
+        throw new KeyManagementException(nspe.toString());
+      }
+    catch (InvalidAlgorithmParameterException kse)
+      {
+        throw new KeyManagementException(kse.toString());
+      }
+  }
+
+  private SecureRandom defaultRandom() throws KeyManagementException
+  {
+    String alg = Util.getSecurityProperty("jessie.secure.random");
+    if (alg == null)
+      {
+        alg = "Fortuna";
+      }
+    SecureRandom rand = null;
+    try
+      {
+        rand = SecureRandom.getInstance(alg);
+      }
+    catch (NoSuchAlgorithmException nsae)
+      {
+        throw new KeyManagementException(nsae.toString());
+      }
+
+    return rand;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/DiffieHellman.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/DiffieHellman.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/DiffieHellman.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/DiffieHellman.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,285 @@
+/* DiffieHellman.java -- Diffie-Hellman key exchange.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.math.BigInteger;
+import gnu.javax.crypto.key.dh.GnuDHPrivateKey;
+
+/**
+ * <p>Simple implementation of two-party Diffie-Hellman key agreement.</p>
+ *
+ * <p>The primes used in this class are from the following documents:</p>
+ *
+ * <ul>
+ * <li>D. Harkins and D. Carrel, "The Internet Key Exchange (IKE)", <a
+ * href="http://www.ietf.org/rfc/rfc2409.txt">RFC 2409</a>.</li>
+ * <li>T. Kivinen and M. Kojo, "More Modular
+ * Exponential (MODP) Diffie-Hellman groups for Internet Key Exchange
+ * (IKE)", <a href="http://www.ietf.org/rfc/rfc3526.txt">RFC
+ * 3526</a>.</li>
+ * </li>
+ *
+ * <p>The generator for all these primes is 2.</p>
+ */
+final class DiffieHellman
+{
+
+  // Class method.
+  // -------------------------------------------------------------------------
+
+  /**
+   * Get the system's Diffie-Hellman parameters, in which <i>g</i> is 2
+   * and <i>p</i> is determined by the property
+   * <code>"jessie.keypool.dh.group"</code>. The default value for <i>p</i>
+   * is 18, corresponding to {@link #GROUP_18}.
+   */
+  static GnuDHPrivateKey getParams()
+  {
+    BigInteger p = DiffieHellman.GROUP_5;
+    String group = Util.getSecurityProperty("jessie.key.dh.group");
+    if (group != null)
+      {
+        group = group.trim();
+        if (group.equals("1"))
+          p = DiffieHellman.GROUP_1;
+        else if (group.equals("2"))
+          p = DiffieHellman.GROUP_2;
+        else if (group.equals("5"))
+          p = DiffieHellman.GROUP_5;
+        else if (group.equals("14"))
+          p = DiffieHellman.GROUP_14;
+        else if (group.equals("15"))
+          p = DiffieHellman.GROUP_15;
+        else if (group.equals("16"))
+          p = DiffieHellman.GROUP_16;
+        else if (group.equals("17"))
+          p = DiffieHellman.GROUP_17;
+        else if (group.equals("18"))
+          p = DiffieHellman.GROUP_18;
+      }
+    return new GnuDHPrivateKey(null, p, DH_G, null);
+  }
+
+  // Constants.
+  // -------------------------------------------------------------------------
+
+  /**
+   * The generator for all Diffie Hellman groups below.
+   */
+  static final BigInteger DH_G = BigInteger.valueOf(2L);
+
+  /**
+   * p = 2^768 - 2 ^704 - 1 + 2^64 * { [2^638 pi] + 149686 }
+   */
+  static final BigInteger GROUP_1 = new BigInteger("00" +
+    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" +
+    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" +
+    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" +
+    "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF", 16);
+
+  /**
+   * p = 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }
+   */
+  static final BigInteger GROUP_2 = new BigInteger("00" +
+    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" +
+    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" +
+    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" +
+    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" +
+    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" +
+    "FFFFFFFFFFFFFFFF", 16);
+
+  /**
+   * This prime p = 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 }.
+   */
+  static final BigInteger GROUP_5 = new BigInteger("00" +
+    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" +
+    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" +
+    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" +
+    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" +
+    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" +
+    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" +
+    "83655D23DCA3AD961C62F356208552BB9ED529077096966D" +
+    "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF", 16);
+
+  /**
+   * p = 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 }.
+   */
+  static final BigInteger GROUP_14 = new BigInteger("00" +
+    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" +
+    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" +
+    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" +
+    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" +
+    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" +
+    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" +
+    "83655D23DCA3AD961C62F356208552BB9ED529077096966D" +
+    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" +
+    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" +
+    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" +
+    "15728E5A8AACAA68FFFFFFFFFFFFFFFF", 16);
+
+  /**
+   * p = 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 }.
+   */
+  static final BigInteger GROUP_15 = new BigInteger("00" +
+    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" +
+    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" +
+    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" +
+    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" +
+    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" +
+    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" +
+    "83655D23DCA3AD961C62F356208552BB9ED529077096966D" +
+    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" +
+    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" +
+    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" +
+    "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" +
+    "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" +
+    "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" +
+    "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" +
+    "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" +
+    "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF", 16);
+
+  /**
+   * p = 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 }.
+   */
+  static final BigInteger GROUP_16 = new BigInteger("00" +
+    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" +
+    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" +
+    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" +
+    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" +
+    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" +
+    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" +
+    "83655D23DCA3AD961C62F356208552BB9ED529077096966D" +
+    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" +
+    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" +
+    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" +
+    "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" +
+    "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" +
+    "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" +
+    "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" +
+    "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" +
+    "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" +
+    "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" +
+    "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" +
+    "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" +
+    "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" +
+    "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" +
+    "FFFFFFFFFFFFFFFF", 16);
+
+  static final BigInteger GROUP_17 = new BigInteger("00" +
+    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" +
+    "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" +
+    "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" +
+    "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" +
+    "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8" +
+    "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D" +
+    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C" +
+    "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" +
+    "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D" +
+    "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D" +
+    "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226" +
+    "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C" +
+    "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" +
+    "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26" +
+    "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB" +
+    "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2" +
+    "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127" +
+    "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" +
+    "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406" +
+    "AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918" +
+    "DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151" +
+    "2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03" +
+    "F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F" +
+    "BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" +
+    "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B" +
+    "B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632" +
+    "387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E" +
+    "6DCC4024FFFFFFFFFFFFFFFF", 16);
+
+  /**
+   * p = 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 }.
+   *
+   * <p>This value, while quite large, is estimated to provide the equivalent
+   * cryptographic strength of a symmetric key between 190 and 320 bits.
+   */
+  static final BigInteger GROUP_18 = new BigInteger("00" +
+    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" +
+    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" +
+    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" +
+    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" +
+    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" +
+    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" +
+    "83655D23DCA3AD961C62F356208552BB9ED529077096966D" +
+    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" +
+    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" +
+    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" +
+    "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" +
+    "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" +
+    "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" +
+    "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" +
+    "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" +
+    "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" +
+    "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" +
+    "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" +
+    "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" +
+    "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" +
+    "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" +
+    "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD" +
+    "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831" +
+    "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B" +
+    "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF" +
+    "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6" +
+    "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3" +
+    "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" +
+    "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328" +
+    "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C" +
+    "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE" +
+    "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4" +
+    "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300" +
+    "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568" +
+    "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9" +
+    "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B" +
+    "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A" +
+    "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36" +
+    "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1" +
+    "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92" +
+    "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47" +
+    "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" +
+    "60C980DD98EDD3DFFFFFFFFFFFFFFFFF", 16);
+
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/DigestInputStream.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/DigestInputStream.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/DigestInputStream.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/DigestInputStream.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,103 @@
+/* DigestInputStream.java -- digesting input stream.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.FilterInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+
+import gnu.java.security.hash.IMessageDigest;
+
+final class DigestInputStream extends FilterInputStream
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private IMessageDigest md5, sha;
+  private boolean digesting;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  DigestInputStream(InputStream in, IMessageDigest md5, IMessageDigest sha)
+  {
+    super(in);
+    if (md5 == null || sha == null)
+      throw new NullPointerException();
+    this.md5 = md5;
+    this.sha = sha;
+    digesting = true;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  void setDigesting(boolean digesting)
+  {
+    this.digesting = digesting;
+  }
+
+  public int read() throws IOException
+  {
+    int i = in.read();
+    if (digesting && i != -1)
+      {
+        md5.update((byte) i);
+        sha.update((byte) i);
+      }
+    return i;
+  }
+
+  public int read(byte[] buf) throws IOException
+  {
+    return read(buf, 0, buf.length);
+  }
+
+  public int read(byte[] buf, int off, int len) throws IOException
+  {
+    int ret = in.read(buf, off, len);
+    if (digesting && ret != -1)
+      {
+        md5.update(buf, off, ret);
+        sha.update(buf, off, ret);
+      }
+    return ret;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/DigestOutputStream.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/DigestOutputStream.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/DigestOutputStream.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/DigestOutputStream.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,107 @@
+/* DigestOutputStream.java -- digesting output stream.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import gnu.java.security.hash.IMessageDigest;
+
+final class DigestOutputStream extends FilterOutputStream
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private IMessageDigest md5, sha;
+  private boolean digesting;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  DigestOutputStream(OutputStream out, IMessageDigest md5, IMessageDigest sha)
+  {
+    super(out);
+    this.md5 = md5;
+    this.sha = sha;
+    digesting = true;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  void setDigesting(boolean digesting)
+  {
+    this.digesting = digesting;
+  }
+
+  public void write(int b) throws IOException
+  {
+    if (digesting)
+      {
+        md5.update((byte) b);
+        sha.update((byte) b);
+      }
+    out.write(b);
+  }
+
+  public void write(byte[] buf) throws IOException
+  {
+    write(buf, 0, buf.length);
+  }
+
+  public void write(byte[] buf, int off, int len) throws IOException
+  {
+    if (buf == null)
+      {
+        throw new NullPointerException();
+      }
+    if (off < 0 || len < 0 || off+len > buf.length)
+      {
+        throw new ArrayIndexOutOfBoundsException();
+      }
+    if (digesting)
+      {
+        md5.update(buf, off, len);
+        sha.update(buf, off, len);
+      }
+    out.write(buf, off, len);
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Enumerated.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Enumerated.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Enumerated.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Enumerated.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,79 @@
+/* Enumerated.java -- Interface to enumerated types.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+/**
+ * An enumerated type in the SSL protocols. Enumerated values take on
+ * one of a set of possible numeric values, which are not specifically
+ * ordered, and may be extensible to a maximum value.
+ *
+ * <pre>enum { e1(v1), e2(v2), ... [[, (n) ]] }</pre>
+ *
+ * <p>Enumerated types are encoded as big-endian multibyte integers,
+ * which take up the least possible number of bytes. Thus, an
+ * enumeration with up to 255 values will be encoded in a single byte,
+ * and so on.
+ *
+ * @author Casey Marshall (rsdio at metastatic.org)
+ */
+interface Enumerated
+{
+
+  /**
+   * Returns the encoded value of this enumerated value, which is
+   * appropriate to send over-the-wire.
+   *
+   * @return The encoded value.
+   */
+  byte[] getEncoded();
+
+  /**
+   * Returns the numeric value of this enumerated value.
+   *
+   * @return The numeric value.
+   */
+  int getValue();
+
+  /**
+   * Returns a string representation of this enumerated value.
+   *
+   * @return The string.
+   */
+  String toString();
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Extension.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Extension.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Extension.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Extension.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,214 @@
+/* Extension.java -- A TLS hello extension.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.EOFException;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+final class Extension implements Constructed
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final Type type;
+  private final byte[] value;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  Extension(Type type, byte[] value)
+  {
+    if (type == null || value == null)
+      {
+        throw new NullPointerException();
+      }
+    this.type = type;
+    this.value = value;
+  }
+
+  // Class method.
+  // -------------------------------------------------------------------------
+
+  static Extension read(InputStream in) throws IOException
+  {
+    Type t = Type.read(in);
+    int len = (in.read() & 0xFF) << 8 | (in.read() & 0xFF);
+    byte[] v = new byte[len];
+    int count = 0;
+    while (count < len)
+      {
+        int l = in.read(v, count, len - count);
+        if (l == -1)
+          {
+            throw new EOFException("unexpected end of extension");
+          }
+        count += l;
+      }
+    return new Extension(t, v);
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public void write(OutputStream out) throws IOException
+  {
+    out.write(type.getEncoded());
+    out.write(value.length >>> 8 & 0xFF);
+    out.write(value.length & 0xFF);
+    out.write(value);
+  }
+
+  Type getType()
+  {
+    return type;
+  }
+
+  byte[] getValue()
+  {
+    return value;
+  }
+
+  public String toString()
+  {
+    StringWriter str = new StringWriter();
+    PrintWriter out = new PrintWriter(str);
+    out.println("struct {");
+    out.println("  type = " + type + ";");
+    out.println("  value =");
+    out.println(Util.hexDump(value, "    "));
+    out.println("} Extension;");
+    return str.toString();
+  }
+
+  // Inner class.
+  // -------------------------------------------------------------------------
+
+  static final class Type implements Enumerated
+  {
+
+    // Constants and fields.
+    // -----------------------------------------------------------------------
+
+    static final Type SERVER_NAME            = new Type(0);
+    static final Type MAX_FRAGMENT_LENGTH    = new Type(1);
+    static final Type CLIENT_CERTIFICATE_URL = new Type(2);
+    static final Type TRUSTED_CA_KEYS        = new Type(3);
+    static final Type TRUNCATED_HMAC         = new Type(4);
+    static final Type STATUS_REQUEST         = new Type(5);
+    static final Type SRP                    = new Type(6);
+    static final Type CERT_TYPE              = new Type(7);
+
+    private final int value;
+
+    // Constructor.
+    // -----------------------------------------------------------------------
+
+    private Type(int value)
+    {
+      this.value = value;
+    }
+
+    // Class methods.
+    // -----------------------------------------------------------------------
+
+    static Type read(InputStream in) throws IOException
+    {
+      int i = in.read();
+      if (i == -1)
+        {
+          throw new EOFException("unexpected end of input stream");
+        }
+      int value = (i & 0xFF) << 8;
+      i = in.read();
+      if (i == -1)
+        {
+          throw new EOFException("unexpected end of input stream");
+        }
+      value |= i & 0xFF;
+      switch (value)
+        {
+        case 0: return SERVER_NAME;
+        case 1: return MAX_FRAGMENT_LENGTH;
+        case 2: return CLIENT_CERTIFICATE_URL;
+        case 3: return TRUSTED_CA_KEYS;
+        case 4: return TRUNCATED_HMAC;
+        case 5: return STATUS_REQUEST;
+        case 6: return SRP;
+        case 7: return CERT_TYPE;
+        default: return new Type(value);
+        }
+    }
+
+    // Instance methods.
+    // -----------------------------------------------------------------------
+
+    public byte[] getEncoded()
+    {
+      return new byte[] {
+        (byte) (value >>> 8 & 0xFF), (byte) (value & 0xFF)
+      };
+    }
+
+    public int getValue()
+    {
+      return value;
+    }
+
+    public String toString()
+    {
+      switch (value)
+        {
+        case 0: return "server_name";
+        case 1: return "max_fragment_length";
+        case 2: return "client_certificate_url";
+        case 3: return "trusted_ca_keys";
+        case 4: return "truncated_hmac";
+        case 5: return "status_request";
+        case 6: return "srp";
+        case 7: return "cert_type";
+        default: return "unknown(" + value + ")";
+        }
+    }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Extensions.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Extensions.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Extensions.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Extensions.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,159 @@
+/* Extensions.java -- various static extension utilities.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.security.auth.x500.X500Principal;
+
+import gnu.java.security.x509.X500DistinguishedName;
+
+final class Extensions
+{
+
+  // Constants.
+  // -------------------------------------------------------------------------
+
+  private static final Integer _512  = new Integer(512),
+    _1024 = new Integer(1024), _2048 = new Integer(2048),
+    _4096 = new Integer(4096);
+
+  // Class methods only.
+  private Extensions() { }
+
+  // Class methods.
+  // -------------------------------------------------------------------------
+
+  static List getServerName(Extension ex)
+  {
+    LinkedList l = new LinkedList();
+    byte[] buf = ex.getValue();
+    int pos = 0;
+    try
+      {
+        while (pos < buf.length)
+          {
+            if (buf[pos++] != 0)
+              break;
+            int len = (buf[pos++] & 0xFF) << 8;
+            len |= buf[pos++] & 0xFF;
+            l.add(new String(buf, pos, len, "UTF-8"));
+            pos += len;
+          }
+      }
+    catch (Exception x)
+      {
+      }
+    return Collections.unmodifiableList(l);
+  }
+
+  static List getClientCertTypes(Extension ex) throws IOException
+  {
+    List l = new LinkedList();
+    ByteArrayInputStream in = new ByteArrayInputStream(ex.getValue());
+    final int len = in.read() & 0xFF;
+    for (int i = 0; i < len; i++)
+      {
+        l.add(CertificateType.read(in));
+      }
+    return Collections.unmodifiableList(l);
+  }
+
+  static CertificateType getServerCertType(Extension ex) throws IOException
+  {
+    return CertificateType.read(new ByteArrayInputStream(ex.getValue()));
+  }
+
+  static Integer getMaxFragmentLength(Extension ex)
+  {
+    switch (ex.getValue()[0] & 0xFF)
+      {
+      case 1: return _512;
+      case 2: return _1024;
+      case 3: return _2048;
+      case 4: return _4096;
+      }
+    throw new IllegalArgumentException();
+  }
+
+  static Object[] getTrustedCA(Extension ex)
+  {
+    byte[] buf = ex.getValue();
+    int type = buf[0] & 0xFF;
+    try
+      {
+        switch (type)
+          {
+          case 0:
+            return new Object[] { new Integer(type), null };
+          case 1:
+          case 3:
+            return new Object[] { new Integer(type),
+                                  Util.trim(buf, 1, 20) };
+          case 2:
+            return new Object[] { new Integer(type),
+                                  new X500Principal(Util.trim(buf, 1, 20)) };
+          }
+      }
+    catch (Exception x)
+      {
+      }
+    throw new IllegalArgumentException();
+  }
+
+  static String getSRPUsername(Extension ex)
+  {
+    int len = ex.getValue()[0] & 0xFF;
+    if (len > ex.getValue().length - 1)
+      throw new IllegalArgumentException();
+    try
+      {
+        return new String(ex.getValue(), 1, len, "UTF-8");
+      }
+    catch (UnsupportedEncodingException uee)
+      {
+        throw new Error(uee.toString());
+      }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Finished.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Finished.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Finished.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Finished.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,143 @@
+/* Finished.java -- SSL Finished message.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.DataInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+final class Finished implements Handshake.Body
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  /** TLSv1.x verify data. */
+  private final byte[] verifyData;
+
+  /** SSLv3 message digest pair. */
+  private final byte[] md5, sha;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  Finished(byte[] verifyData)
+  {
+    this.verifyData = verifyData;
+    md5 = sha = null;
+  }
+
+  Finished(byte[] md5, byte[] sha)
+  {
+    this.md5 = md5;
+    this.sha = sha;
+    verifyData = null;
+  }
+
+  // Class methods.
+  // -------------------------------------------------------------------------
+
+  static Finished read(InputStream in, CipherSuite suite)
+    throws IOException
+  {
+    DataInputStream din = new DataInputStream(in);
+    if (suite.getVersion().equals(ProtocolVersion.SSL_3))
+      {
+        byte[] md5 = new byte[16];
+        byte[] sha = new byte[20];
+        din.readFully(md5);
+        din.readFully(sha);
+        return new Finished(md5, sha);
+      }
+    else
+      {
+        byte[] buf = new byte[12];
+        din.readFully(buf);
+        return new Finished(buf);
+      }
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public void write(OutputStream out) throws IOException
+  {
+    if (verifyData != null)
+      out.write(verifyData);
+    else
+      {
+        out.write(md5);
+        out.write(sha);
+      }
+  }
+
+  byte[] getVerifyData()
+  {
+    return verifyData;
+  }
+
+  byte[] getMD5Hash()
+  {
+    return md5;
+  }
+
+  byte[] getSHAHash()
+  {
+    return sha;
+  }
+
+  public String toString()
+  {
+    String nl = System.getProperty("line.separator");
+    if (verifyData != null)
+      {
+        return "struct {" + nl +
+          "  verifyData = " + Util.toHexString(verifyData, ':') + ";" + nl +
+          "} Finished;" + nl;
+      }
+    else
+      {
+        return "struct {" + nl +
+          "  md5Hash = " + Util.toHexString(md5, ':') + ";" + nl +
+          "  shaHash = " + Util.toHexString(sha, ':') + ";" + nl +
+          "} Finished;" + nl;
+      }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/GNUSecurityParameters.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/GNUSecurityParameters.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/GNUSecurityParameters.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/GNUSecurityParameters.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,490 @@
+/* GNUSecurityParameters.java -- SSL security parameters.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+
+import java.security.SecureRandom;
+import java.security.Security;
+import java.util.Arrays;
+import java.util.zip.DataFormatException;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
+
+import javax.net.ssl.SSLException;
+
+import gnu.javax.crypto.mac.IMac;
+import gnu.javax.crypto.mode.IMode;
+import gnu.java.security.prng.IRandom;
+import gnu.java.security.prng.LimitReachedException;
+
+/**
+ * This class implements the {@link SecurityParameters} interface, using the
+ * GNU Crypto interface for ciphers and macs, and the JZlib package for
+ * record compression.
+ */
+class GNUSecurityParameters implements SecurityParameters
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private static final boolean DEBUG_RECORD_LAYER = false;
+  private static final PrintWriter debug = new PrintWriter (System.err, true);
+
+  /**
+   * The CBC block cipher, if any.
+   */
+  IMode inCipher, outCipher;
+
+  /**
+   * The RC4 PRNG, if any.
+   */
+  IRandom inRandom, outRandom;
+
+  /**
+   * The MAC algorithm.
+   */
+  IMac inMac, outMac;
+
+  long inSequence, outSequence;
+  Session session;
+  ProtocolVersion version;
+  int fragmentLength;
+  private Inflater inflater;
+  private Deflater deflater;
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  GNUSecurityParameters (Session session)
+  {
+    inSequence = 0;
+    outSequence = 0;
+    this.session = session;
+    fragmentLength = 16384;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public void reset()
+  {
+    inSequence = 0L;
+    outSequence = 0L;
+    inCipher = null;
+    outCipher = null;
+    inMac = null;
+    outMac = null;
+    inRandom = null;
+    outRandom = null;
+    deflater = null;
+    inflater = null;
+  }
+
+  public ProtocolVersion getVersion()
+  {
+    return version;
+  }
+
+  public void setVersion(ProtocolVersion version)
+  {
+    this.version = version;
+  }
+
+  public void setInCipher(Object inCipher)
+  {
+    if (inCipher instanceof IMode)
+      {
+        this.inCipher = (IMode) inCipher;
+        inRandom = null;
+      }
+    else
+      {
+        inRandom = (IRandom) inCipher;
+        this.inCipher = null;
+      }
+  }
+
+  public void setOutCipher(Object outCipher)
+  {
+    if (outCipher instanceof IMode)
+      {
+        this.outCipher = (IMode) outCipher;
+        outRandom = null;
+      }
+    else
+      {
+        outRandom = (IRandom) outCipher;
+        this.outCipher = null;
+      }
+  }
+
+  public void setInMac(Object inMac)
+  {
+    this.inMac = (IMac) inMac;
+    inSequence = 0L;
+  }
+
+  public void setOutMac(Object outMac)
+  {
+    this.outMac = (IMac) outMac;
+    outSequence = 0L;
+  }
+
+  public void setDeflating (boolean deflate)
+  {
+    if (deflate)
+      {
+        if (deflater == null)
+          deflater = new Deflater();
+      }
+    else
+      deflater = null;
+  }
+
+  public void setInflating (boolean inflate)
+  {
+    if (inflate)
+      {
+        if (inflater == null)
+          inflater = new Inflater();
+      }
+    else
+      inflater = null;
+  }
+
+  public int getFragmentLength()
+  {
+    return fragmentLength;
+  }
+
+  public void setFragmentLength (int fragmentLength)
+  {
+    this.fragmentLength = fragmentLength;
+  }
+
+  /**
+   * Decrypt, verify, and decompress a fragment, returning the transformed
+   * fragment.
+   *
+   * @param fragment The fragment to decrypt.
+   * @param version The protocol version of the fragment's record.
+   * @param type The content type of the record.
+   * @return The decrypted fragment.
+   * @throws MacException If the MAC could not be verified.
+   * @throws OverflowException If the inflated data is too large.
+   * @throws SSLException If decompressing fails.
+   */
+  public synchronized byte[] decrypt (byte[] fragment, ProtocolVersion version,
+                                      ContentType type)
+    throws MacException, OverflowException, SSLException
+  {
+    boolean badPadding = false;
+
+    // Decrypt the ciphertext, if it is encrypted.
+    if (inCipher != null)
+      {
+        int bs = inCipher.currentBlockSize ();
+        for (int i = 0; i < fragment.length; i += bs)
+          {
+            inCipher.update (fragment, i, fragment, i);
+          }
+        int padLen = fragment[fragment.length-1] & 0xFF;
+        int len = fragment.length - padLen - 1;
+        if (version == ProtocolVersion.SSL_3)
+          {
+            // SSLv3 requires that the padding length not exceed the
+            // cipher's block size.
+            if (padLen >= bs)
+              {
+                badPadding = true;
+              }
+          }
+        else
+          {
+            for (int i = len; i < fragment.length; i++)
+              {
+                // If the TLS padding is wrong, throw a MAC exception below.
+                if ((fragment[i] & 0xFF) != padLen)
+                  {
+                    badPadding = true;
+                  }
+              }
+          }
+        fragment = Util.trim (fragment, len);
+      }
+    else if (inRandom != null)
+      {
+        transformRC4 (fragment, 0, fragment.length, fragment, 0, inRandom);
+      }
+
+    // Check the MAC.
+    if (inMac != null)
+      {
+        inMac.update ((byte) (inSequence >>> 56));
+        inMac.update ((byte) (inSequence >>> 48));
+        inMac.update ((byte) (inSequence >>> 40));
+        inMac.update ((byte) (inSequence >>> 32));
+        inMac.update ((byte) (inSequence >>> 24));
+        inMac.update ((byte) (inSequence >>> 16));
+        inMac.update ((byte) (inSequence >>>  8));
+        inMac.update ((byte)  inSequence);
+        inMac.update ((byte) type.getValue());
+        if (version != ProtocolVersion.SSL_3)
+          {
+            inMac.update ((byte) version.getMajor());
+            inMac.update ((byte) version.getMinor());
+          }
+        int macLen = inMac.macSize ();
+        int fragLen = fragment.length - macLen;
+        inMac.update ((byte) (fragLen >>> 8));
+        inMac.update ((byte)  fragLen);
+        inMac.update (fragment, 0, fragLen);
+        byte[] mac = inMac.digest ();
+        inMac.reset ();
+        for (int i = 0; i < macLen; i++)
+          {
+            if (fragment[i + fragLen] != mac[i])
+              {
+                throw new MacException();
+              }
+          }
+        if (badPadding)
+          {
+            throw new MacException();
+          }
+        fragment = Util.trim (fragment, fragLen);
+      }
+
+    if (inflater != null)
+      {
+        byte[] buf = new byte[1024];
+        ByteArrayOutputStream bout = new ByteArrayOutputStream (fragment.length << 1);
+        inflater.setInput (fragment);
+        int len;
+        try
+          {
+            while ((len = inflater.inflate (buf)) > 0)
+              {
+                bout.write (buf, 0, len);
+                if (bout.size() > fragmentLength + 1024)
+                  throw new OverflowException ("inflated data too large");
+              }
+          }
+        catch (DataFormatException dfe)
+          {
+            throw new SSLException (String.valueOf (dfe));
+          }
+        fragment = bout.toByteArray();
+        inflater.reset();
+      }
+
+    inSequence++;
+    return fragment;
+  }
+
+  /**
+   * Compress, MAC, encrypt, and write a record. The fragment of the
+   * record is taken from <i>buf</i> as <i>len</i> bytes starting at
+   * <i>offset</i>. <i>len</i> <b>must</b> be smaller than or equal to
+   * the configured fragment length.
+   *
+   * @param buf The fragment bytes.
+   * @param off The offset from whence to read.
+   * @param len The size of the fragment.
+   * @param type The content-type for this record.
+   * @param out The output stream to write the record to.
+   * @throws IOException If an I/O error occurs.
+   * @throws SSLException If compression fails.
+   * @throws OverflowException If compression inflates the data beyond
+   *   the fragment length plus 1024 bytes.
+   */
+  public synchronized byte[] encrypt (byte[] buf, int off, int len,
+                                      ContentType type)
+    throws SSLException, OverflowException
+  {
+    // If we are compressing, do it.
+    if (deflater != null)
+      {
+        byte[] buf2 = new byte[1024];
+        ByteArrayOutputStream bout = new ByteArrayOutputStream (len >>> 1);
+        deflater.setInput (buf, off, len);
+        deflater.finish();
+        len = 0;
+        while ((len = deflater.deflate (buf2)) > 0)
+          bout.write (buf2, 0, len);
+        // This should technically never happen for zlib.
+        if (bout.size() > fragmentLength + 1024)
+          throw new OverflowException ("deflated data too large");
+        buf = bout.toByteArray();
+        off = 0;
+        len = buf.length;
+        deflater.reset();
+      }
+
+    // If there is a MAC, compute it.
+    byte[] mac = new byte[0];
+    if (outMac != null)
+      {
+        outMac.update((byte) (outSequence >>> 56));
+        outMac.update((byte) (outSequence >>> 48));
+        outMac.update((byte) (outSequence >>> 40));
+        outMac.update((byte) (outSequence >>> 32));
+        outMac.update((byte) (outSequence >>> 24));
+        outMac.update((byte) (outSequence >>> 16));
+        outMac.update((byte) (outSequence >>>  8));
+        outMac.update((byte)  outSequence);
+        outMac.update((byte) type.getValue());
+        if (version != ProtocolVersion.SSL_3)
+          {
+            outMac.update((byte) version.getMajor());
+            outMac.update((byte) version.getMinor());
+          }
+        outMac.update((byte) (len >>> 8));
+        outMac.update((byte)  len);
+        outMac.update(buf, off, len);
+        mac = outMac.digest();
+        outMac.reset();
+      }
+    outSequence++;
+
+    // Compute padding if needed.
+    byte[] pad = new byte[0];
+    if (outCipher != null)
+      {
+        int padLen = outCipher.currentBlockSize() -
+          ((len + mac.length + 1) % outCipher.currentBlockSize());
+        // Use a random amount of padding if the protocol is TLS.
+        if (version != ProtocolVersion.SSL_3 && session.random != null)
+          {
+            padLen += (Math.abs(session.random.nextInt ()) & 7) *
+              outCipher.currentBlockSize();
+            while (padLen > 255)
+              {
+                padLen -= outCipher.currentBlockSize();
+              }
+          }
+        pad = new byte[padLen+1];
+        Arrays.fill (pad, (byte) padLen);
+      }
+
+    // Write the record header.
+    final int fraglen = len + mac.length + pad.length;
+
+    // Encrypt and write the fragment.
+    if (outCipher != null)
+      {
+        byte[] buf2 = new byte[fraglen];
+        System.arraycopy (buf, off, buf2, 0, len);
+        System.arraycopy (mac, 0, buf2, len, mac.length);
+        System.arraycopy (pad, 0, buf2, len + mac.length, pad.length);
+        int bs = outCipher.currentBlockSize ();
+        for (int i = 0; i < fraglen; i += bs)
+          {
+            outCipher.update (buf2, i, buf2, i);
+          }
+        return buf2;
+      }
+    else if (outRandom != null)
+      {
+        byte[] buf2 = new byte[fraglen];
+        transformRC4 (buf, off, len, buf2, 0, outRandom);
+        transformRC4 (mac, 0, mac.length, buf2, len, outRandom);
+        return buf2;
+      }
+    else
+      {
+        if (mac.length == 0)
+          {
+            return Util.trim (buf, off, len);
+          }
+        else
+          {
+            return Util.concat (Util.trim (buf, off, len), mac);
+          }
+      }
+  }
+
+  // Own methods.
+  // -------------------------------------------------------------------------
+
+  /**
+   * Encrypt/decrypt a byte array with the RC4 stream cipher.
+   *
+   * @param in The input data.
+   * @param off The input offset.
+   * @param len The number of bytes to transform.
+   * @param out The output buffer.
+   * @param outOffset The offest into the output buffer.
+   * @param random The ARCFOUR PRNG.
+   */
+  private static void transformRC4(byte[] in, int off, int len,
+                                   byte[] out, int outOffset, IRandom random)
+  {
+    if (random == null)
+      {
+        throw new IllegalStateException();
+      }
+    if (in == null || out == null)
+      {
+        throw new NullPointerException();
+      }
+    if (off < 0 || off + len > in.length ||
+        outOffset < 0 || outOffset + len > out.length)
+      {
+        throw new ArrayIndexOutOfBoundsException();
+      }
+
+    try
+      {
+        for (int i = 0; i < len; i++)
+          {
+            out[outOffset+i] = (byte) (in[off+i] ^ random.nextByte());
+          }
+      }
+    catch (LimitReachedException cannotHappen)
+      {
+        throw new Error(cannotHappen.toString());
+      }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Handshake.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Handshake.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Handshake.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Handshake.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,440 @@
+/* Handshake.java -- SSL handshake message.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import java.security.PublicKey;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+import javax.net.ssl.SSLProtocolException;
+
+final class Handshake implements Constructed
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private static final buffer BUF = new buffer();
+
+  private final Type type;
+  private final Body body;
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  Handshake(Type type, Body body)
+  {
+    this.type = type;
+    this.body = body;
+  }
+
+  // Class methods.
+  // -------------------------------------------------------------------------
+
+  static Handshake read(byte[] buffer) throws IOException
+  {
+    return read(new ByteArrayInputStream(buffer));
+  }
+
+  static Handshake read(byte[] buffer, CipherSuite suite, PublicKey key)
+    throws IOException
+  {
+    return read(new ByteArrayInputStream(buffer), suite, key);
+  }
+
+  static Handshake read(InputStream in) throws IOException
+  {
+    return read(in, null, null);
+  }
+
+  static Handshake read(InputStream in, CipherSuite suite, PublicKey key)
+    throws IOException
+  {
+    return read(in, suite, key, null);
+  }
+
+  static Handshake read(InputStream in, CertificateType certType)
+    throws IOException
+  {
+    return read(in, null, null, certType);
+  }
+
+  static Handshake read(InputStream in, CipherSuite suite, PublicKey key,
+                        CertificateType certType)
+    throws IOException
+  {
+    Type type = Type.read(in);
+    byte[] lenbuf = new byte[3];
+    in.read(lenbuf);
+    int len = (lenbuf[0] & 0xFF) << 16 | (lenbuf[1] & 0xFF) << 8
+            | (lenbuf[2] & 0xFF);
+    Body body = null;
+    if (type == Type.HELLO_REQUEST)
+      {
+        body = null;
+      }
+    else if (type == Type.CLIENT_HELLO)
+      {
+        // Most likely a V2 hello. If the first byte is 0x30, and if this
+        // is not a V2 client hello, then it is a V3 client hello with
+        // at least 1.5 million cipher specs, which is unlikely.
+        if (lenbuf[0] == 3 && (lenbuf[1] >= 0 && lenbuf[1] <= 2))
+          {
+            ProtocolVersion vers = null;
+            switch (lenbuf[1])
+              {
+              case 0:
+                vers = ProtocolVersion.SSL_3;
+                break;
+              case 1:
+                vers = ProtocolVersion.TLS_1;
+                break;
+              case 2:
+                vers = ProtocolVersion.TLS_1_1;
+                break;
+              }
+            int specLen = (lenbuf[2] & 0xFF) << 8 | (in.read() & 0xFF);
+            int idLen   = (in.read() & 0xFF) << 8 | (in.read() & 0xFF);
+            int chalLen = (in.read() & 0xFF) << 8 | (in.read() & 0xFF);
+
+            ArrayList suites = new ArrayList(specLen / 3);
+            for (int i = 0; i < specLen; i += 3)
+              {
+                if (in.read() == 0)
+                  {
+                    suites.add(CipherSuite.read(in).resolve(vers));
+                  }
+                else
+                  {
+                    in.read();
+                    in.read();
+                  }
+              }
+            byte[] id = new byte[idLen];
+            in.read(id);
+            byte[] challenge = new byte[chalLen];
+            in.read(challenge);
+            if (challenge.length > 32)
+              challenge = Util.trim(challenge, 32);
+            else if (challenge.length < 32)
+              {
+                byte[] b = new byte[32];
+                System.arraycopy(challenge, 0, b, b.length - challenge.length,
+                                 challenge.length);
+                challenge = b;
+              }
+            int time = (challenge[0] & 0xFF) << 24 | (challenge[1] & 0xFF) << 16
+                     | (challenge[2] & 0xFF) <<  8 | (challenge[3] & 0xFF);
+            Random rand = new Random(time, Util.trim(challenge, 4, 28));
+            return new Handshake(Handshake.Type.CLIENT_HELLO,
+              new ClientHello(vers, rand, id, suites,
+                              Collections.singletonList(CompressionMethod.NULL)));
+          }
+        // Since hello messages may contain extensions, we read the whole
+        // thing here.
+        byte[] buf = new byte[len];
+        int count = 0;
+        while (count < len)
+          {
+            int l = in.read(buf, count, len - count);
+            if (l == -1)
+              {
+                throw new EOFException("unexpected end of input stream");
+              }
+            count += l;
+          }
+        body = ClientHello.read(new ByteArrayInputStream(buf));
+      }
+    else if (type == Type.SERVER_HELLO)
+      {
+        byte[] buf = new byte[len];
+        int count = 0;
+        while (count < len)
+          {
+            int l = in.read(buf, count, len - count);
+            if (l == -1)
+              {
+                throw new EOFException("unexpected end of input stream");
+              }
+            count += l;
+          }
+        body = ServerHello.read(new ByteArrayInputStream(buf));
+      }
+    else if (type == Type.CERTIFICATE)
+      {
+        body = Certificate.read(in, certType);
+      }
+    else if (type == Type.SERVER_KEY_EXCHANGE)
+      {
+        body = ServerKeyExchange.read(in, suite, key);
+      }
+    else if (type == Type.CERTIFICATE_REQUEST)
+      {
+        body = CertificateRequest.read(in);
+      }
+    else if (type == Type.CERTIFICATE_VERIFY)
+      {
+        body = (CertificateVerify) CertificateVerify.read(in, suite, key);
+      }
+    else if (type == Type.CLIENT_KEY_EXCHANGE)
+      {
+        body = ClientKeyExchange.read(in, suite, key);
+      }
+    else if (type == Type.SERVER_HELLO_DONE)
+      {
+        body = null;
+      }
+    else if (type == Type.FINISHED)
+      {
+        body = Finished.read(in, suite);
+      }
+    else
+      {
+        throw new SSLProtocolException("unknown HandshakeType: " +
+                                       type.getValue());
+      }
+
+    return new Handshake(type, body);
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public void write(OutputStream out)
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  public int write(OutputStream out, ProtocolVersion version)
+    throws IOException
+  {
+    out.write(type.getValue());
+    if (body == null)
+      {
+        out.write(0);
+        out.write(0);
+        out.write(0);
+        return 4;
+      }
+    else
+      {
+        ByteArrayOutputStream bout = BUF.getBuffer();
+        bout.reset();
+        if (body instanceof ServerKeyExchange)
+          {
+            ((ServerKeyExchange) body).write(bout, version);
+          }
+        else if (body instanceof ClientKeyExchange)
+          {
+            ((ClientKeyExchange) body).write(bout, version);
+          }
+        else if (body instanceof CertificateVerify)
+          {
+            ((CertificateVerify) body).write(bout, version);
+          }
+        else
+          {
+            body.write(bout);
+          }
+        out.write(bout.size() >>> 16 & 0xFF);
+        out.write(bout.size() >>>  8 & 0xFF);
+        out.write(bout.size() & 0xFF);
+        bout.writeTo(out);
+        return 4 + bout.size();
+      }
+  }
+
+  Type getType()
+  {
+    return type;
+  }
+
+  Body getBody()
+  {
+    return body;
+  }
+
+  public String toString()
+  {
+    StringWriter str = new StringWriter();
+    PrintWriter out = new PrintWriter(str);
+    String nl = System.getProperty("line.separator");
+    StringBuffer buf = new StringBuffer();
+    out.println("struct {");
+    out.println("  type = " + type + ";");
+    if (body != null)
+      {
+        BufferedReader r = new BufferedReader(new StringReader(body.toString()));
+        String s;
+        try
+          {
+            while ((s = r.readLine()) != null)
+              {
+                out.print("  ");
+                out.println(s);
+              }
+          }
+        catch (IOException ignored)
+          {
+          }
+      }
+    out.println("} Handshake;");
+    return str.toString();
+  }
+
+  // Inner class.
+  // -------------------------------------------------------------------------
+
+  static interface Body extends Constructed
+  {
+  }
+
+  static class Type implements Enumerated
+  {
+
+    // Constants and fields.
+    // -----------------------------------------------------------------------
+
+    public static final Type
+      HELLO_REQUEST       = new Type( 0), CLIENT_HELLO        = new Type( 1),
+      SERVER_HELLO        = new Type( 2), CERTIFICATE         = new Type(11),
+      SERVER_KEY_EXCHANGE = new Type(12), CERTIFICATE_REQUEST = new Type(13),
+      SERVER_HELLO_DONE   = new Type(14), CERTIFICATE_VERIFY  = new Type(15),
+      CLIENT_KEY_EXCHANGE = new Type(16), FINISHED            = new Type(20),
+      CERTIFICATE_URL     = new Type(21), CERTIFICATE_STATUS  = new Type(22);
+
+    private final int value;
+
+    // Constructor.
+    // -----------------------------------------------------------------------
+
+    private Type(int value)
+    {
+      this.value = value;
+    }
+
+    // Class methods.
+    // -----------------------------------------------------------------------
+
+    public static Type read(InputStream in) throws IOException
+    {
+      int i = in.read();
+      if (i == -1)
+        {
+          throw new EOFException("unexpected end of input stream");
+        }
+      switch (i & 0xFF)
+        {
+        case  0: return HELLO_REQUEST;
+        case  1: return CLIENT_HELLO;
+        case  2: return SERVER_HELLO;
+        case 11: return CERTIFICATE;
+        case 12: return SERVER_KEY_EXCHANGE;
+        case 13: return CERTIFICATE_REQUEST;
+        case 14: return SERVER_HELLO_DONE;
+        case 15: return CERTIFICATE_VERIFY;
+        case 16: return CLIENT_KEY_EXCHANGE;
+        case 20: return FINISHED;
+        case 21: return CERTIFICATE_URL;
+        case 22: return CERTIFICATE_STATUS;
+        default: return new Type(i);
+        }
+    }
+
+    // Instance methods.
+    // -----------------------------------------------------------------------
+
+    public byte[] getEncoded()
+    {
+      return new byte[] { (byte) value };
+    }
+
+    public int getValue()
+    {
+      return value;
+    }
+
+    public String toString()
+    {
+      switch (value)
+        {
+        case  0: return "hello_request";
+        case  1: return "client_hello";
+        case  2: return "server_hello";
+        case 11: return "certificate";
+        case 12: return "server_key_exchange";
+        case 13: return "certificate_request";
+        case 14: return "server_hello_done";
+        case 15: return "certificate_verify";
+        case 16: return "client_key_exchange";
+        case 20: return "finished";
+        case 21: return "certificate_url";
+        case 22: return "certificate_status";
+        default: return "unknown(" + value + ")";
+        }
+    }
+  }
+
+  private static class buffer extends ThreadLocal
+  {
+    static final int SIZE = 2048;
+
+    protected Object initialValue()
+    {
+      return new ByteArrayOutputStream(SIZE);
+    }
+
+    ByteArrayOutputStream getBuffer()
+    {
+      return (ByteArrayOutputStream) get();
+    }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JCESecurityParameters.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JCESecurityParameters.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JCESecurityParameters.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JCESecurityParameters.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,307 @@
+/* JCESecurityParameters.java -- JCE-based security parameters.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.ByteArrayOutputStream;
+
+import java.util.Arrays;
+import java.util.zip.DataFormatException;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.Mac;
+
+import javax.net.ssl.SSLException;
+
+class JCESecurityParameters implements SecurityParameters
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private Cipher inCipher, outCipher;
+  private Mac inMac, outMac;
+  private Inflater inflater;
+  private Deflater deflater;
+  private int fragmentLength;
+  private long inSequence, outSequence;
+  private ProtocolVersion version;
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  JCESecurityParameters ()
+  {
+    fragmentLength = 16384;
+    inSequence = 0L;
+    outSequence = 0L;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public void reset()
+  {
+    inCipher = null;
+    outCipher = null;
+    inMac = null;
+    outMac = null;
+    deflater = null;
+    inflater = null;
+  }
+
+  public void setInCipher (Object inCipher)
+  {
+    this.inCipher = (Cipher) inCipher;
+  }
+
+  public void setOutCipher (Object outCipher)
+  {
+    this.outCipher = (Cipher) outCipher;
+  }
+
+  public void setInMac (Object inMac)
+  {
+    this.inMac = (Mac) inMac;
+    inSequence = 0L;
+  }
+
+  public void setOutMac (Object outMac)
+  {
+    this.outMac = (Mac) outMac;
+    outSequence = 0L;
+  }
+
+  public void setDeflating (boolean deflate)
+  {
+    if (deflate)
+      {
+        if (deflater == null)
+          deflater = new Deflater();
+      }
+    else
+      deflater = null;
+  }
+
+  public void setInflating (boolean inflate)
+  {
+    if (inflate)
+      {
+        if (inflater == null)
+          inflater = new Inflater();
+      }
+    else
+      inflater = null;
+  }
+
+  public int getFragmentLength()
+  {
+    return fragmentLength;
+  }
+
+  public void setFragmentLength (int fragmentLength)
+  {
+    this.fragmentLength = fragmentLength;
+  }
+
+  public ProtocolVersion getVersion()
+  {
+    return version;
+  }
+
+  public void setVersion (ProtocolVersion version)
+  {
+    this.version = version;
+  }
+
+  public synchronized byte[] decrypt (byte[] fragment, ProtocolVersion version,
+                                      ContentType type)
+    throws MacException, OverflowException, SSLException
+  {
+    boolean badpad = false;
+    if (inCipher != null)
+      {
+        // We imagine that the JCE would be used in cases where hardware
+        // acceleration is available, since it isn't really that useful for
+        // pure Java crypto. We decrypt (and encrypt, below) in one go
+        // to minimize (potential) calls to native methods.
+        try
+          {
+            fragment = inCipher.doFinal (fragment);
+          }
+        catch (BadPaddingException bpe)
+          {
+            badpad = true;
+          }
+        catch (IllegalBlockSizeException ibse)
+          {
+            badpad = true;
+          }
+      }
+
+    if (inMac != null)
+      {
+        int macLen = inMac.getMacLength();
+        int fragLen = fragment.length - macLen;
+        byte[] mac = Util.trim (fragment, fragLen, macLen);
+        fragment = Util.trim (fragment, fragLen);
+        inMac.update ((byte) (inSequence >>> 56));
+        inMac.update ((byte) (inSequence >>> 48));
+        inMac.update ((byte) (inSequence >>> 40));
+        inMac.update ((byte) (inSequence >>> 32));
+        inMac.update ((byte) (inSequence >>> 24));
+        inMac.update ((byte) (inSequence >>> 16));
+        inMac.update ((byte) (inSequence >>>  8));
+        inMac.update ((byte)  inSequence);
+        inMac.update ((byte) type.getValue());
+        if (version != ProtocolVersion.SSL_3)
+          {
+            inMac.update ((byte) version.getMajor());
+            inMac.update ((byte) version.getMinor());
+          }
+        inMac.update ((byte) (fragLen >>> 8));
+        inMac.update ((byte)  fragLen);
+        inMac.update (fragment);
+        if (!Arrays.equals (mac, inMac.doFinal()) || badpad)
+          throw new MacException();
+      }
+
+    if (inflater != null)
+      {
+        byte[] buf = new byte[1024];
+        ByteArrayOutputStream bout = new ByteArrayOutputStream (fragment.length << 1);
+        inflater.setInput (fragment);
+        int len;
+        try
+          {
+            while ((len = inflater.inflate (buf)) > 0)
+              {
+                bout.write (buf, 0, len);
+                if (bout.size() > fragmentLength + 1024)
+                  throw new OverflowException ("inflated data too large");
+              }
+          }
+        catch (DataFormatException dfe)
+          {
+            throw new SSLException (String.valueOf (dfe));
+          }
+        fragment = bout.toByteArray();
+        inflater.reset();
+      }
+
+    inSequence++;
+    return fragment;
+  }
+
+  public synchronized byte[] encrypt (byte[] fragment, int off, int len,
+                                      ContentType type)
+    throws OverflowException, SSLException
+  {
+    if (deflater != null)
+      {
+        byte[] buf = new byte[1024];
+        ByteArrayOutputStream bout = new ByteArrayOutputStream (len >>> 1);
+        deflater.setInput (fragment, off, len);
+        deflater.finish();
+        len = 0;
+        while ((len = deflater.deflate (buf)) > 0)
+          bout.write (buf, 0, len);
+        // This should technically never happen for zlib.
+        if (bout.size() > fragmentLength + 1024)
+          throw new OverflowException ("deflated data too large");
+        fragment = bout.toByteArray();
+        off = 0;
+        len = fragment.length;
+        deflater.reset();
+      }
+
+    if (outMac != null)
+      {
+        outMac.update ((byte) (inSequence >>> 56));
+        outMac.update ((byte) (inSequence >>> 48));
+        outMac.update ((byte) (inSequence >>> 40));
+        outMac.update ((byte) (inSequence >>> 32));
+        outMac.update ((byte) (inSequence >>> 24));
+        outMac.update ((byte) (inSequence >>> 16));
+        outMac.update ((byte) (inSequence >>>  8));
+        outMac.update ((byte)  inSequence);
+        outMac.update ((byte) type.getValue());
+        if (version != ProtocolVersion.SSL_3)
+          {
+            outMac.update ((byte) version.getMajor());
+            outMac.update ((byte) version.getMinor());
+          }
+        outMac.update ((byte) (len >>> 8));
+        outMac.update ((byte)  len);
+        outMac.update (fragment, off, len);
+        fragment = Util.concat (fragment, outMac.doFinal());
+        off = 0;
+        len = fragment.length;
+      }
+
+    if (outCipher != null)
+      {
+        try
+          {
+            fragment = outCipher.doFinal (fragment, off, len);
+          }
+        catch (BadPaddingException shouldNeverHappen)
+          {
+            // This is nonsensical. Don't even pretend that we can handle this.
+            throw new RuntimeException ("bad padding thrown while encrypting");
+          }
+        catch (IllegalBlockSizeException ibse)
+          {
+            // Ditto.
+            throw new RuntimeException ("illegal block size thrown while encrypting");
+          }
+        off = 0;
+        len = fragment.length;
+      }
+
+    outSequence++;
+    if (off == 0 && len == fragment.length)
+      return fragment;
+    else
+      return Util.trim (fragment, off, len);
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JDBCSessionContext.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JDBCSessionContext.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JDBCSessionContext.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JDBCSessionContext.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,356 @@
+/* JDBCSessionContext.java -- database persistent sessions.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import java.security.SecureRandom;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Timestamp;
+import java.sql.Types;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Enumeration;
+import java.util.TreeSet;
+import java.util.Vector;
+
+import javax.net.ssl.SSLSession;
+
+/**
+ * The SQL table this class stores sessions in, called <tt>SESSIONS</tt>,
+ * looks like this:
+ *
+ * <blockquote><pre>
+ * TABLE SESSIONS (
+ *   ID             VARBINARY(32) PRIMARY KEY UNIQUE NOT NULL,
+ *   CREATED        TIMESTAMP NOT NULL,
+ *   LAST_ACCESSED  TIMESTAMP NOT NULL,
+ *   PROTOCOL       VARCHAR(7) NOT NULL,
+ *   SUITE          VARCHAR(255) NOT NULL,
+ *   PEER_HOST      TEXT NOT NULL,
+ *   PEER_CERT_TYPE VARCHAR(32),
+ *   PEER_CERTS     BLOB,
+ *   CERT_TYPE      VARCHAR(32),
+ *   CERTS          BLOB,
+ *   SECRET         VARBINARY(48) NOT NULL
+ * )
+ * </pre></blockquote>
+ *
+ * <p>Note that the master secret for sessions is not protected before
+ * being inserted into the database; it is up to the system to protect
+ * the stored data from unauthorized access.
+ */
+class JDBCSessionContext extends SessionContext
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  protected Connection connection;
+  protected PreparedStatement selectById;
+  protected PreparedStatement insert;
+  protected PreparedStatement selectTimestamp;
+  protected PreparedStatement updateTimestamp;
+  protected PreparedStatement deleteSession;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  JDBCSessionContext() throws SQLException
+  {
+    String url = Util.getSecurityProperty("jessie.SessionContext.jdbc.url");
+    String user = Util.getSecurityProperty("jessie.SessionContext.jdbc.user");
+    String passwd = Util.getSecurityProperty("jessie.SessionContext.jdbc.password");
+    if (url == null)
+      {
+        throw new IllegalArgumentException("no JDBC URL");
+      }
+    if (user == null || passwd == null)
+      {
+        connection = DriverManager.getConnection(url);
+      }
+    else
+      {
+        connection = DriverManager.getConnection(url, user, passwd);
+      }
+    selectById =
+      connection.prepareStatement("SELECT * FROM SESSIONS WHERE ID = ?");
+    insert = connection.prepareStatement("INSERT INTO SESSIONS VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
+    selectTimestamp =
+      connection.prepareStatement("SELECT CREATED FROM SESSIONS WHERE ID = ?");
+    updateTimestamp =
+      connection.prepareStatement("UPDATE SESSIONS SET LAST_ACCESSED = ? WHERE ID = ?");
+    deleteSession =
+      connection.prepareStatement("DELETE FROM SESSIONS WHERE ID = ?");
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public synchronized Enumeration getIds()
+  {
+    Vector ids = new Vector();
+    try
+      {
+        Statement stmt = connection.createStatement();
+        ResultSet rs = stmt.executeQuery("SELECT ID FROM SESSIONS");
+        while (rs.next())
+          {
+            byte[] id = rs.getBytes("ID");
+            ids.add(id);
+          }
+      }
+    catch (SQLException sqle)
+      {
+      }
+    return ids.elements();
+  }
+
+  public synchronized SSLSession getSession(byte[] sessionId)
+  {
+    Session session = (Session) super.getSession(sessionId);
+    if (session == null)
+      {
+        try
+          {
+            selectById.setBytes(1, sessionId);
+            ResultSet rs = selectById.executeQuery();
+            if (rs.next())
+              {
+                session = new Session(rs.getTimestamp("CREATED").getTime());
+                session.enabledSuites = new ArrayList(SSLSocket.supportedSuites);
+                session.enabledProtocols = new TreeSet(SSLSocket.supportedProtocols);
+                session.random = new SecureRandom();
+                session.context = this;
+                session.sessionId = new Session.ID(rs.getBytes("ID"));
+                session.setLastAccessedTime(rs.getTimestamp("LAST_ACCESSED").getTime());
+                long elapsed = System.currentTimeMillis() - session.getLastAccessedTime();
+                if ((int) (elapsed / 1000L) > timeout)
+                  {
+                    removeSession(session.sessionId);
+                    return null;
+                  }
+                session.peerHost = rs.getString("PEER_HOST");
+                String protocol = rs.getString("PROTOCOL");
+                if (protocol.equals("SSLv3"))
+                  {
+                    session.protocol = ProtocolVersion.SSL_3;
+                  }
+                else if (protocol.equals("TLSv1"))
+                  {
+                    session.protocol = ProtocolVersion.TLS_1;
+                  }
+                else if (protocol.equals("TLSv1.1"))
+                  {
+                    session.protocol = ProtocolVersion.TLS_1_1;
+                  }
+                else
+                  {
+                    return null;
+                  }
+                session.cipherSuite = CipherSuite.forName(rs.getString("SUITE"));
+                String type = rs.getString("PEER_CERT_TYPE");
+                boolean wasNull = rs.wasNull();
+                InputStream certs = null;
+                if (!wasNull)
+                  {
+                    certs = rs.getBinaryStream("PEER_CERTS");
+                    wasNull = rs.wasNull();
+                  }
+                if (!wasNull)
+                  {
+                    CertificateFactory cf = CertificateFactory.getInstance(type);
+                    session.peerCerts = (Certificate[])
+                      cf.generateCertificates(certs).toArray(new Certificate[0]);
+                    session.peerVerified = true;
+                  }
+                type = rs.getString("CERT_TYPE");
+                wasNull = rs.wasNull();
+                if (!wasNull)
+                  {
+                    certs = rs.getBinaryStream("CERTS");
+                    wasNull = rs.wasNull();
+                  }
+                if (!wasNull)
+                  {
+                    CertificateFactory cf = CertificateFactory.getInstance(type);
+                    session.localCerts = (Certificate[])
+                      cf.generateCertificates(certs).toArray(new Certificate[0]);
+                  }
+                session.masterSecret = rs.getBytes("SECRET");
+                if (cacheSize == 0 || sessions.size() < cacheSize)
+                  {
+                    sessions.put(session.sessionId, session);
+                  }
+              }
+          }
+        catch (Exception ex)
+          {
+          }
+      }
+    return session;
+  }
+
+  synchronized boolean addSession(Session.ID id, Session s)
+  {
+    if (containsSessionID(id))
+      {
+        return false;
+      }
+    try
+      {
+        insert.setBytes(1, id.getId());
+        insert.setTimestamp(2, new Timestamp(s.getCreationTime()));
+        insert.setTimestamp(3, new Timestamp(s.getLastAccessedTime()));
+        insert.setString(4, s.getProtocol());
+        insert.setString(5, s.getCipherSuite());
+        insert.setString(6, s.peerHost);
+        if (s.peerCerts != null && s.peerCerts.length > 0)
+          {
+            insert.setString(7, s.peerCerts[0].getType());
+            insert.setBytes(8, certs(s.peerCerts));
+          }
+        else
+          {
+            insert.setNull(7, Types.VARCHAR);
+            insert.setNull(8, Types.LONGVARBINARY);
+          }
+        if (s.localCerts != null && s.localCerts.length > 0)
+          {
+            insert.setString(9, s.localCerts[0].getType());
+            insert.setBytes(10, certs(s.localCerts));
+          }
+        else
+          {
+            insert.setNull(9,  Types.VARCHAR);
+            insert.setNull(10, Types.LONGVARBINARY);
+          }
+        insert.setBytes(11, s.masterSecret);
+        insert.executeUpdate();
+        super.addSession(id, s);
+      }
+    catch (SQLException sqle)
+      {
+        return false;
+      }
+    return true;
+  }
+
+  synchronized boolean containsSessionID(Session.ID sessionId)
+  {
+    try
+      {
+        selectTimestamp.setBytes(1, sessionId.getId());
+        ResultSet rs = selectTimestamp.executeQuery();
+        if (!rs.next())
+          {
+            return false;
+          }
+        Timestamp ts = rs.getTimestamp("CREATED");
+        if (rs.wasNull())
+          {
+            return false;
+          }
+        long elapsed = System.currentTimeMillis() - ts.getTime();
+        if ((int) (elapsed / 1000) > timeout)
+          {
+            removeSession(sessionId);
+            return false;
+          }
+        return true;
+      }
+    catch (SQLException sqle)
+      {
+        return false;
+      }
+  }
+
+  protected boolean removeSession(Session.ID sessionId)
+  {
+    super.removeSession(sessionId);
+    try
+      {
+        deleteSession.setBytes(1, sessionId.getId());
+        return deleteSession.executeUpdate() > 0;
+      }
+    catch (SQLException sqle)
+      {
+      }
+    return false;
+  }
+
+  synchronized void notifyAccess(Session session)
+  {
+    try
+      {
+        updateTimestamp.setTimestamp(1, new Timestamp(session.getLastAccessedTime()));
+        updateTimestamp.setBytes(2, session.getId());
+        updateTimestamp.executeUpdate();
+      }
+    catch (SQLException sqle)
+      {
+      }
+  }
+
+  private byte[] certs(Certificate[] certs)
+  {
+    ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
+    for (int i = 0; i < certs.length; i++)
+      {
+        try
+          {
+            out.write(certs[i].getEncoded());
+          }
+        catch (Exception x)
+          {
+          }
+      }
+    return out.toByteArray();
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Jessie.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Jessie.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Jessie.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Jessie.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,91 @@
+/* Jessie.java -- JESSIE's JSSE provider.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.Provider;
+
+/**
+ * This is the security provider for Jessie. It implements the following
+ * algorithms:
+ *
+ * <pre>
+ * {@link javax.net.ssl.SSLContext}.SSLv3
+ * {@link javax.net.ssl.SSLContext}.SSL
+ * {@link javax.net.ssl.SSLContext}.TLSv1
+ * {@link javax.net.ssl.SSLContext}.TLS
+ * {@link javax.net.ssl.KeyManagerFactory}.JessieX509
+ * {@link javax.net.ssl.TrustManagerFactory}.JessieX509
+ * {@link javax.net.ssl.TrustManagerFactory}.SRP
+ * </pre>
+ *
+ */
+public class Jessie extends Provider
+{
+
+  public static final String VERSION = "1.0.0";
+  public static final double VERSION_DOUBLE = 1.0;
+
+  public Jessie()
+  {
+    super("Jessie", VERSION_DOUBLE,
+          "Implementing SSLv3, TLSv1 SSL Contexts; X.509 Key Manager Factories;" +
+          System.getProperty("line.separator") +
+          "X.509 and SRP Trust Manager Factories, continuously-seeded secure random." );
+
+    AccessController.doPrivileged(new PrivilegedAction()
+      {
+        public Object run()
+        {
+          put("SSLContext.SSLv3", Context.class.getName());
+          put("Alg.Alias.SSLContext.SSL",     "SSLv3");
+          put("Alg.Alias.SSLContext.TLSv1",   "SSLv3");
+          put("Alg.Alias.SSLContext.TLS",     "SSLv3");
+          //put("Alg.Alias.SSLContext.TLSv1.1", "SSLv3");
+
+          put("KeyManagerFactory.JessieX509",   X509KeyManagerFactory.class.getName());
+          put("TrustManagerFactory.JessieX509", X509TrustManagerFactory.class.getName());
+          put("TrustManagerFactory.SRP",        SRPTrustManagerFactory.class.getName());
+
+          return null;
+        }
+      });
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JessieDHPrivateKey.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JessieDHPrivateKey.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JessieDHPrivateKey.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JessieDHPrivateKey.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,99 @@
+/* JessieDHPrivateKey.java -- simple DH private key.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.math.BigInteger;
+
+import javax.crypto.interfaces.DHPrivateKey;
+import javax.crypto.spec.DHParameterSpec;
+
+class JessieDHPrivateKey implements DHPrivateKey
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final DHParameterSpec params;
+  private final BigInteger x;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  JessieDHPrivateKey(DHParameterSpec params, BigInteger x)
+  {
+    this.params = params;
+    this.x = x;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public String getAlgorithm()
+  {
+    return "Diffie-Hellman";
+  }
+
+  public String getFormat()
+  {
+    return "NONE";
+  }
+
+  public byte[] getEncoded()
+  {
+    return null;
+  }
+
+  public DHParameterSpec getParams()
+  {
+    return params;
+  }
+
+  public BigInteger getX()
+  {
+    return x;
+  }
+
+  public String toString()
+  {
+    String nl = System.getProperty("line.separator");
+    return "P: " + params.getP() + nl +
+      "G: " + params.getG() + nl +
+      "X: " + x;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JessieDHPublicKey.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JessieDHPublicKey.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JessieDHPublicKey.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JessieDHPublicKey.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,99 @@
+/* JessieDHPublicKey.java -- simple DH public key.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.math.BigInteger;
+
+import javax.crypto.interfaces.DHPublicKey;
+import javax.crypto.spec.DHParameterSpec;
+
+class JessieDHPublicKey implements DHPublicKey
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final DHParameterSpec params;
+  private final BigInteger y;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  JessieDHPublicKey(DHParameterSpec params, BigInteger y)
+  {
+    this.params = params;
+    this.y = y;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public String getAlgorithm()
+  {
+    return "Diffie-Hellman";
+  }
+
+  public String getFormat()
+  {
+    return "NONE";
+  }
+
+  public byte[] getEncoded()
+  {
+    return null;
+  }
+
+  public DHParameterSpec getParams()
+  {
+    return params;
+  }
+
+  public BigInteger getY()
+  {
+    return y;
+  }
+
+  public String toString()
+  {
+    String nl = System.getProperty("line.separator");
+    return "P: " + params.getP() + nl +
+      "G: " + params.getG() + nl +
+      "Y: " + y;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JessieRSAPrivateKey.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JessieRSAPrivateKey.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JessieRSAPrivateKey.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JessieRSAPrivateKey.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,98 @@
+/* JessieRSAPrivateKey.java -- simple RSA private key.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.math.BigInteger;
+import java.security.interfaces.RSAPrivateKey;
+
+class JessieRSAPrivateKey implements RSAPrivateKey
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final BigInteger modulus;
+  private final BigInteger exponent;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  JessieRSAPrivateKey(BigInteger modulus, BigInteger exponent)
+  {
+    this.modulus = modulus;
+    this.exponent = exponent;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public String getAlgorithm()
+  {
+    return "RSA";
+  }
+
+  public String getFormat()
+  {
+    return "NONE";
+  }
+
+  public byte[] getEncoded()
+  {
+    return null;
+  }
+
+  public BigInteger getModulus()
+  {
+    return modulus;
+  }
+
+  public BigInteger getPrivateExponent()
+  {
+    return exponent;
+  }
+
+  public String toString()
+  {
+    String nl = System.getProperty("line.separator");
+    return "RSAPrivateKey {" + nl +
+      "  modulus = " + modulus.toString(16) + ";" + nl +
+      "  exponent = " + exponent.toString(16) + ";" + nl +
+      "};";
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JessieRSAPublicKey.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JessieRSAPublicKey.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JessieRSAPublicKey.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/JessieRSAPublicKey.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,98 @@
+/* JessieRSAPublicKey.java -- simple RSA public key.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.math.BigInteger;
+import java.security.interfaces.RSAPublicKey;
+
+class JessieRSAPublicKey implements RSAPublicKey
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final BigInteger modulus;
+  private final BigInteger exponent;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  JessieRSAPublicKey(BigInteger modulus, BigInteger exponent)
+  {
+    this.modulus = modulus;
+    this.exponent = exponent;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public String getAlgorithm()
+  {
+    return "RSA";
+  }
+
+  public String getFormat()
+  {
+    return "NONE";
+  }
+
+  public byte[] getEncoded()
+  {
+    return null;
+  }
+
+  public BigInteger getModulus()
+  {
+    return modulus;
+  }
+
+  public BigInteger getPublicExponent()
+  {
+    return exponent;
+  }
+
+  public String toString()
+  {
+    String nl = System.getProperty("line.separator");
+    return "RSAPublicKey {" + nl +
+      "  modulus = " + modulus.toString(16) + ";" + nl +
+      "  exponent = " + exponent.toString(16) + ";" + nl +
+      "};";
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/KeyPool.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/KeyPool.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/KeyPool.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/KeyPool.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,110 @@
+/* KeyPool.java -- A set of ephemeral key pairs.
+   Copyright (C) 2001, 2002, 2003, 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.math.BigInteger;
+import java.security.KeyPair;
+import java.security.SecureRandom;
+
+final class KeyPool
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private static final BigInteger ONE = BigInteger.ONE;
+  private static final BigInteger TWO = BigInteger.valueOf(2L);
+  private static final BigInteger E = BigInteger.valueOf(65537L);
+  private static final SecureRandom RANDOM = new SecureRandom ();
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  private KeyPool()
+  {
+  }
+
+  // Class methods.
+  // -------------------------------------------------------------------------
+
+  /**
+   * Generate an export-class (512 bit) RSA key pair.
+   *
+   * @return The new key pair.
+   */
+  static KeyPair generateRSAKeyPair()
+  {
+    BigInteger p, q, n, d;
+
+    // Simplified version of GNU Crypto's RSAKeyPairGenerator.
+
+    int M = 256;
+    BigInteger lower = TWO.pow(255);
+    BigInteger upper = TWO.pow(256).subtract(ONE);
+    byte[] kb = new byte[32];
+    while (true)
+      {
+        nextBytes(kb);
+        p = new BigInteger(1, kb).setBit(0);
+        if (p.compareTo(lower) >= 0 && p.compareTo(upper) <= 0 &&
+            p.isProbablePrime(80) && p.gcd(E).equals(ONE))
+          break;
+      }
+
+    while (true)
+      {
+        nextBytes(kb);
+        q = new BigInteger(1, kb).setBit(0);
+        n = q.multiply(p);
+        if (n.bitLength() == 512 && q.isProbablePrime(80) &&
+            q.gcd(E).equals(ONE))
+          break;
+      }
+
+    d = E.modInverse(p.subtract(ONE).multiply(q.subtract(ONE)));
+
+    return new KeyPair(new JessieRSAPublicKey(n, E),
+                       new JessieRSAPrivateKey(n, d));
+  }
+
+  private static void nextBytes(byte[] buf)
+  {
+    RANDOM.nextBytes (buf);
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/MacException.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/MacException.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/MacException.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/MacException.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,53 @@
+/* MacException.java -- signals a bad record MAC.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.IOException;
+
+class MacException extends IOException
+{
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  MacException()
+  {
+    super();
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/OverflowException.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/OverflowException.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/OverflowException.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/OverflowException.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,57 @@
+/* OverflowException.java -- signals an input overflow.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.IOException;
+
+class OverflowException extends IOException
+{
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  OverflowException()
+  {
+  }
+
+  OverflowException(String msg)
+  {
+    super(msg);
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ProtocolVersion.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ProtocolVersion.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ProtocolVersion.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ProtocolVersion.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,180 @@
+/* ProtocolVersion.java -- An SSL version number.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+final class ProtocolVersion implements Comparable, Constructed
+{
+
+  // Constants and fields.
+  // -------------------------------------------------------------------------
+
+  static final ProtocolVersion SSL_3 = new ProtocolVersion(3, 0);
+  static final ProtocolVersion TLS_1 = new ProtocolVersion(3, 1);
+  static final ProtocolVersion TLS_1_1 = new ProtocolVersion(3, 2);
+
+  private final int major;
+  private final int minor;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  private ProtocolVersion(int major, int minor)
+  {
+    this.major = major;
+    this.minor = minor;
+  }
+
+  // Class methods.
+  // -------------------------------------------------------------------------
+
+  static ProtocolVersion read(InputStream in) throws IOException
+  {
+    int major = in.read() & 0xFF;
+    int minor = in.read() & 0xFF;
+    return getInstance(major, minor);
+  }
+
+  static ProtocolVersion getInstance(int major, int minor)
+  {
+    if (major == 3)
+      {
+        switch (minor)
+          {
+          case 0: return SSL_3;
+          case 1: return TLS_1;
+          case 2: return TLS_1_1;
+          }
+      }
+    return new ProtocolVersion(major, minor);
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public void write(OutputStream out) throws IOException
+  {
+    out.write(major);
+    out.write(minor);
+  }
+
+  byte[] getEncoded()
+  {
+    return new byte[] {
+      (byte) major, (byte) minor
+    };
+  }
+
+  int getMajor()
+  {
+    return major;
+  }
+
+  int getMinor()
+  {
+    return minor;
+  }
+
+  public boolean equals(Object o)
+  {
+    if (o == null || !(o instanceof ProtocolVersion))
+      {
+        return false;
+      }
+    return ((ProtocolVersion) o).major == this.major
+        && ((ProtocolVersion) o).minor == this.minor;
+  }
+
+  public int hashCode()
+  {
+    return major << 8 | minor;
+  }
+
+  public int compareTo(Object o)
+  {
+    if (o == null || !(o instanceof ProtocolVersion))
+      {
+        return 1;
+      }
+    if (this.equals(o))
+      {
+        return 0;
+      }
+    if (major > ((ProtocolVersion) o).major)
+      {
+        return 1;
+      }
+    else if (major < ((ProtocolVersion) o).major)
+      {
+        return -1;
+      }
+    if (minor > ((ProtocolVersion) o).minor)
+      {
+        return 1;
+      }
+    else if (minor < ((ProtocolVersion) o).minor)
+      {
+        return -1;
+      }
+    return 0;
+  }
+
+  public String toString()
+  {
+    if (this == SSL_3)
+      {
+        return "SSLv3";
+      }
+    else if (this == TLS_1)
+      {
+        return "TLSv1";
+      }
+    else if (this == TLS_1_1)
+      {
+        return "TLSv1.1";
+      }
+    else
+      {
+        return "Unsupported; major=" + major + " minor=" + minor;
+      }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Random.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Random.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Random.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Random.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,124 @@
+/* Random.java -- SSL Random structure.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+class Random implements Constructed
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final int gmtUnixTime;
+  private final byte[] randomBytes;
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  Random(int gmtUnixTime, byte[] randomBytes)
+  {
+    this.gmtUnixTime = gmtUnixTime;
+    this.randomBytes = (byte[]) randomBytes.clone();
+  }
+
+  // Class methods.
+  // -------------------------------------------------------------------------
+
+  static Random read(InputStream in) throws IOException
+  {
+    int time = (in.read() & 0xFF) << 24 | (in.read() & 0xFF) << 16
+             | (in.read() & 0xFF) <<  8 | (in.read() & 0xFF);
+    byte[] buf = new byte[28];
+    in.read(buf);
+    return new Random(time, buf);
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public void write(OutputStream out) throws IOException
+  {
+    out.write((gmtUnixTime >>> 24) & 0xFF);
+    out.write((gmtUnixTime >>> 16) & 0xFF);
+    out.write((gmtUnixTime >>>  8) & 0xFF);
+    out.write(gmtUnixTime & 0xFF);
+    out.write(randomBytes);
+  }
+
+  byte[] getEncoded()
+  {
+    ByteArrayOutputStream bout = new ByteArrayOutputStream(32);
+    try
+      {
+        write(bout);
+      }
+    catch (IOException cantHappen)
+      {
+        throw new Error(cantHappen.toString());
+      }
+    return bout.toByteArray();
+  }
+
+  int getTime()
+  {
+    return gmtUnixTime;
+  }
+
+  byte[] getRandomBytes()
+  {
+    return randomBytes;
+  }
+
+  public String toString()
+  {
+    StringWriter str = new StringWriter();
+    PrintWriter out = new PrintWriter(str);
+    out.println("struct {");
+    out.println("  gmt_unix_time = " + gmtUnixTime + ";");
+    out.println("  random_bytes = " + Util.toHexString(randomBytes, ':') + ";");
+    out.println("} Random;");
+    return str.toString();
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/RecordInput.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/RecordInput.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/RecordInput.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/RecordInput.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,232 @@
+/* RecordInput.java -- record layer input.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import gnu.classpath.SystemProperties;
+import gnu.classpath.debug.Component;
+import gnu.classpath.debug.SystemLogger;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import java.util.logging.Logger;
+
+import javax.net.ssl.SSLProtocolException;
+
+class RecordInput
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private static final boolean DEBUG_RECORD_LAYER = true;
+  private static final Logger logger = SystemLogger.SYSTEM;
+
+  private byte[] fragment;
+  private int index;
+  private ContentType type;
+
+  private final DataInputStream in;
+  private Session session;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  RecordInput (final InputStream in, final Session session)
+  {
+    this.in = new DataInputStream (in);
+    this.session = session;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  synchronized int available (ContentType type) throws IOException
+  {
+    if (fragment == null)
+      {
+        readRecord ();
+      }
+    if (type != this.type)
+      {
+        return 0;
+      }
+    return fragment.length - index;
+  }
+
+  void setSession (Session session)
+  {
+    this.session = session;
+  }
+
+  synchronized int read (byte[] buf, int off, int len, ContentType type)
+    throws IOException
+  {
+    if (off < 0 || len < 0 || off + len > buf.length)
+      {
+        throw new ArrayIndexOutOfBoundsException ("size=" + buf.length +
+                                                  " off=" + off + " len=" + len);
+      }
+    if (fragment == null || index >= fragment.length)
+      {
+        readRecord ();
+      }
+    if (type != this.type)
+      {
+        return 0;
+      }
+    len = Math.min (len, fragment.length - index);
+    System.arraycopy (fragment, index, buf, off, len);
+    index += len;
+    return len;
+  }
+
+  boolean pollClose () throws IOException
+  {
+    if (fragment == null || index >= fragment.length)
+      {
+        try
+          {
+            readRecord();
+          }
+        catch (AlertException ae)
+          {
+            Alert alert = ae.getAlert();
+            if (alert.getDescription() == Alert.Description.CLOSE_NOTIFY)
+              {
+                return true;
+              }
+            throw ae;
+          }
+      }
+    return false;
+  }
+
+  private void readRecord() throws IOException
+  {
+    type = ContentType.read (in);
+    if ((type.getValue() & 0x80) != 0 || (type.getValue() & 0x40) != 0)
+      {
+        in.read();
+        if ((type.getValue() & 0x40) != 0)
+          {
+            in.read();
+          }
+        type = ContentType.read(in);
+        if (type != ContentType.CLIENT_HELLO_V2)
+          {
+            throw new SSLProtocolException("unsupported V2 message");
+          }
+        type = ContentType.HANDSHAKE;
+        // Record this message, and re-present it as a normal handshake
+        // layer message. ClientHello will handle the real parsing.
+        ByteArrayOutputStream buffer = new ByteArrayOutputStream (256);
+        buffer.write(1); // The type we just read.
+        RecordingInputStream in2 = new RecordingInputStream (in, buffer);
+        ProtocolVersion version = ProtocolVersion.read (in2);
+        if (version.compareTo (ProtocolVersion.SSL_3) < 0)
+          {
+            throw new SSLProtocolException("unsupported client version");
+          }
+        int len = (in2.read() & 0xFF) << 8 | (in2.read() & 0xFF);
+        len += (in2.read() & 0xFF) << 8 | (in2.read() & 0xFF);
+        len += (in2.read() & 0xFF) << 8 | (in2.read() & 0xFF);
+        int count = 0;
+        while (count < len)
+          {
+            int l = (int) in2.skip(len - count);
+            if (l > 0)
+              {
+                count += l;
+              }
+          }
+        fragment = buffer.toByteArray ();
+        index = 0;
+
+        // We can't be encrypted/MACed/compressed here, since a V2 message
+        // will only be sent as the first message, and only by the client.
+        return;
+      }
+    ProtocolVersion v = ProtocolVersion.read (in);
+    int len = in.readUnsignedShort ();
+    if (len > session.params.getFragmentLength() + 2048)
+      {
+        throw new OverflowException();
+      }
+    fragment = new byte [len];
+    in.readFully (fragment);
+
+    if (DEBUG_RECORD_LAYER)
+      {
+        logger.log (Component.SSL_RECORD_LAYER,
+                    ">> READ RECORD <<{4}" +
+                    "struct {{4}" +
+                    "  type = {0};{4}" +
+                    "  version = {1};{4}" +
+                    "  length = {2};{4}" +
+                    "{3}{4}" +
+                    "} TLSCiphertext;", new Object[]
+          {
+            type, v, new Integer (len),
+            Util.hexDump (fragment, "  "),
+            SystemProperties.getProperty ("line.separator")
+          });
+      }
+
+    fragment = session.params.decrypt (fragment, v, type);
+    index = 0;
+
+    if (session.random != null)
+      session.random.setSeed (fragment);
+
+    if (type == ContentType.ALERT)
+      {
+        Alert alert = Alert.read (new ByteArrayInputStream (fragment));
+        session.currentAlert = alert;
+      }
+    if (session.currentAlert != null)
+      {
+        throw new AlertException (session.currentAlert, false);
+      }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/RecordInputStream.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/RecordInputStream.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/RecordInputStream.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/RecordInputStream.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,106 @@
+/* RecordInputStream.java -- record layer input stream interface.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+class RecordInputStream extends InputStream
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  /**
+   * The record input instance.
+   */
+  private final RecordInput in;
+
+  /**
+   * The content type this stream is reading.
+   */
+  private final ContentType type;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  RecordInputStream (RecordInput in, ContentType type)
+  {
+    this.in = in;
+    this.type = type;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public int available () throws IOException
+  {
+    return in.available (type);
+  }
+
+  public int read () throws IOException
+  {
+    byte[] b = new byte[1];
+    int ret;
+    while ((ret = read (b)) != 1)
+      {
+        if (ret == -1)
+          {
+            return -1;
+          }
+        Thread.yield ();
+      }
+    return b[0] & 0xFF;
+  }
+
+  public int read (byte[] buf) throws IOException
+  {
+    return read (buf, 0, buf.length);
+  }
+
+  public int read (byte[] buf, int off, int len) throws IOException
+  {
+    return in.read (buf, off, len, type);
+  }
+
+  public String toString ()
+  {
+    return RecordInputStream.class.getName () + " [ type=" + type + " ]";
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/RecordOutputStream.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/RecordOutputStream.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/RecordOutputStream.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/RecordOutputStream.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,189 @@
+/* RecordOutputStream.java -- record layer output.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import gnu.classpath.SystemProperties;
+import gnu.classpath.debug.Component;
+import gnu.classpath.debug.SystemLogger;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+
+import java.util.logging.Logger;
+
+/**
+ * An output stream for writing data to the record layer. All data written
+ * to this stream (through any of the write methods) is immediately sent
+ * as a full record, so it is advisable to write large arrays to the stream
+ * instead of one byte at a time (alternatively, a {@link
+ * java.io.BufferedOutputStream} can be used).
+ */
+class RecordOutputStream extends FilterOutputStream
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private static final boolean DEBUG_RECORD_LAYER = true;
+  private static final Logger logger = SystemLogger.SYSTEM;
+
+  /**
+   * The content type of this output stream.
+   */
+  private final ContentType type;
+
+  /**
+   * The security parameters.
+   */
+  private final SecurityParameters params;
+
+  private final boolean emitEmpty;
+
+  private static final byte[] ZERO = new byte[0];
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  RecordOutputStream (final OutputStream out, final ContentType type,
+                      final SecurityParameters params)
+  {
+    super (out);
+    this.type = type;
+    this.params = params;
+    String empty = Util.getSecurityProperty ("jessie.emit.empty.records");
+    if (empty == null)
+      {
+        // IE panics if it gets an empty record; so, leave this false
+        // for the default.
+        empty = "false";
+      }
+    emitEmpty = Boolean.valueOf (empty).booleanValue () &&
+      type == ContentType.APPLICATION_DATA;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public void write (int b) throws IOException
+  {
+    write (new byte[] { (byte) b });
+  }
+
+  public void write (byte[] buf) throws IOException
+  {
+    write (buf, 0, buf.length);
+  }
+
+  public void write (byte[] buf, int off, int len) throws IOException
+  {
+    if (off < 0 || len < 0 || off + len > buf.length)
+      {
+        throw new ArrayIndexOutOfBoundsException ("size=" + buf.length +
+                                                  " off=" + off + " len=" + len);
+      }
+
+    int count = 0;
+    int len2 = 0;
+    do
+      {
+        if (emitEmpty)
+          {
+            byte[] fragment = params.encrypt (ZERO, 0, 0, type);
+            if (DEBUG_RECORD_LAYER)
+              {
+                logger.log (Component.SSL_RECORD_LAYER,
+                            ">> WRITING RECORD <<{4}" +
+                            "struct {{4}" +
+                            "  type = {0};{4}" +
+                            "  version = {1};{4}" +
+                            "  length = {2};{4}" +
+                            "{3}{4}" +
+                            "} TLSCiphertext;", new Object[]
+                  {
+                    type, params.getVersion (), new Integer (fragment.length),
+                    Util.hexDump (fragment, "  "),
+                    SystemProperties.getProperty ("line.separator")
+                  });
+              }
+            out.write (type.getValue());
+            params.getVersion().write (out);
+            out.write ((fragment.length >>> 8) & 0xFF);
+            out.write ( fragment.length & 0xFF);
+            out.write (fragment);
+            out.flush ();
+          }
+        len2 = Math.min (len - count, params.getFragmentLength());
+        if (DEBUG_RECORD_LAYER)
+          {
+            logger.log (Component.SSL_RECORD_LAYER,
+                        "writing chunk size={0}", new Integer (len2));
+          }
+        synchronized (out)
+          {
+            byte[] fragment = params.encrypt (buf, off + count, len2, type);
+            if (DEBUG_RECORD_LAYER)
+              {
+                logger.log (Component.SSL_RECORD_LAYER,
+                            ">> WRITING RECORD <<{4}" +
+                            "struct {{4}" +
+                            "  type = {0};{4}" +
+                            "  version = {1};{4}" +
+                            "  length = {2};{4}" +
+                            "{3}{4}" +
+                            "} TLSCiphertext;", new Object[]
+                  {
+                    type, params.getVersion (), new Integer (fragment.length),
+                    Util.hexDump (fragment, "  "),
+                    SystemProperties.getProperty ("line.separator")
+                  });
+              }
+            out.write (type.getValue());
+            params.getVersion().write (out);
+            out.write ((fragment.length >>> 8) & 0xFF);
+            out.write ( fragment.length & 0xFF);
+            out.write (fragment);
+            out.flush ();
+          }
+        count += len2;
+      }
+    while (count < len);
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/RecordingInputStream.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/RecordingInputStream.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/RecordingInputStream.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/RecordingInputStream.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,131 @@
+/* RecordingInputStream.java -- Input stream that records data.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FilterInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * A filter input stream that records every byte read from the underlying
+ * input stream. This class is useful for protocols that require portions
+ * of the communication to be saved, such as the handshake and key
+ * derivation in SSL.
+ *
+ * @author Casey Marshall (rsdio at metastatic.org)
+ */
+class RecordingInputStream extends FilterInputStream
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  protected ByteArrayOutputStream sink;
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  RecordingInputStream(InputStream in)
+  {
+    this(in, new ByteArrayOutputStream());
+  }
+
+  RecordingInputStream(InputStream in, ByteArrayOutputStream sink)
+  {
+    super(in);
+    this.sink = sink;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public synchronized int read() throws IOException
+  {
+    int i = in.read();
+    sink.write(i);
+    return i;
+  }
+
+  public synchronized int read(byte[] buf, int off, int len) throws IOException
+  {
+    int l = in.read(buf, off, len);
+    sink.write(buf, off, l);
+    return l;
+  }
+
+  public synchronized int read(byte[] buf) throws IOException
+  {
+    return read(buf, 0, buf.length);
+  }
+
+  public synchronized long skip(long len) throws IOException
+  {
+    long l = 0;
+    int i = 0;
+    byte[] buf = new byte[1024];
+    while (l < len)
+      {
+        i = read(buf, 0, (int) Math.min((long) buf.length, len - l));
+        if (i == -1)
+          break;
+        l += i;
+      }
+    return l;
+  }
+
+  /**
+   * Returns all bytes recorded after this instance was created, or the last
+   * call to {@link resetSink()}.
+   *
+   * @return The recorded bytes.
+   */
+  byte[] getBytes()
+  {
+    return sink.toByteArray();
+  }
+
+  /**
+   * Clears the recording buffer off all previously-recorded bytes.
+   */
+  void resetSink()
+  {
+    sink.reset();
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SRPTrustManagerFactory.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SRPTrustManagerFactory.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SRPTrustManagerFactory.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SRPTrustManagerFactory.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,225 @@
+/* SRPTrustManagerFactory.java -- trust manager for SRP.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.IOException;
+import java.math.BigInteger;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyPair;
+import java.security.KeyStore;
+import java.security.Security;
+
+import java.util.HashMap;
+
+import javax.net.ssl.ManagerFactoryParameters;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactorySpi;
+
+import gnu.java.security.key.IKeyPairGenerator;
+import gnu.javax.crypto.key.srp6.SRPKeyPairGenerator;
+import gnu.javax.crypto.sasl.srp.PasswordFile;
+import gnu.javax.crypto.sasl.srp.SRP;
+
+import gnu.javax.net.ssl.SRPManagerParameters;
+import gnu.javax.net.ssl.SRPTrustManager;
+
+/**
+ * This is an implementation of a {@link javax.net.ssl.TrustManagerFactory}
+ * engine for the ``SRP'' algorithm. You must initialize instances of this
+ * algorithm with {@link SRPManagerParameters}.
+ */
+public class SRPTrustManagerFactory extends TrustManagerFactorySpi
+{
+
+  // Field.
+  // -------------------------------------------------------------------------
+
+  private Manager current;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  public SRPTrustManagerFactory()
+  {
+    super();
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  protected TrustManager[] engineGetTrustManagers()
+  {
+    if (current == null)
+      throw new IllegalStateException("not initialized");
+    return new TrustManager[] { current };
+  }
+
+  protected void engineInit(KeyStore ks)
+  {
+    throw new IllegalArgumentException("only accepts SRPManagerParameters");
+  }
+
+  protected void engineInit(ManagerFactoryParameters params)
+    throws InvalidAlgorithmParameterException
+  {
+    if (params == null)
+      {
+        try
+          {
+            String srpPasswd = Util.getSecurityProperty("jessie.srp.password.file");
+            if (srpPasswd == null)
+              {
+                current = new Manager(new PasswordFile());
+                return;
+              }
+            String srpPasswd2 = Util.getSecurityProperty("jessie.srp.password.file2");
+            if (srpPasswd2 == null)
+              srpPasswd2 = srpPasswd + "2";
+            String srpConfig = Util.getSecurityProperty("jessie.srp.config");
+            if (srpConfig == null)
+              srpConfig = srpPasswd + ".conf";
+            current = new Manager(new PasswordFile(srpPasswd, srpPasswd2, srpConfig));
+            return;
+          }
+        catch (IOException ioe)
+          {
+            throw new InvalidAlgorithmParameterException("default initialization failed: "
+                                                         + ioe.toString());
+          }
+      }
+    if (params instanceof SRPManagerParameters)
+      {
+        current = new Manager(((SRPManagerParameters) params).getPasswordFile());
+        return;
+      }
+    throw new InvalidAlgorithmParameterException();
+  }
+
+  // Inner class.
+  // -------------------------------------------------------------------------
+
+  private class Manager implements SRPTrustManager
+  {
+
+    // Field.
+    // -----------------------------------------------------------------------
+
+    private final PasswordFile file;
+
+    // Constructor.
+    // -----------------------------------------------------------------------
+
+    Manager(PasswordFile file)
+    {
+      this.file = file;
+    }
+
+    // Instance methods.
+    // -----------------------------------------------------------------------
+
+    public boolean contains(String user)
+    {
+      try
+        {
+          return file.contains(user);
+        }
+      catch (IOException ioe) { }
+      return false;
+    }
+
+    public KeyPair getKeyPair(String user)
+    {
+      try
+        {
+          if (file.contains(user))
+            {
+              SRP srp = SRP.instance("SHA");
+              String[] ent = file.lookup(user, "SHA");
+              String[] cnf = file.lookupConfig(ent[2]);
+              BigInteger v, N, g;
+              v = new BigInteger(1, gnu.java.security.util.Util.fromBase64(ent[0]));
+              N = new BigInteger(1, gnu.java.security.util.Util.fromBase64(cnf[0]));
+              g = new BigInteger(1, gnu.java.security.util.Util.fromBase64(cnf[1]));
+              IKeyPairGenerator kpg = new SRPKeyPairGenerator();
+              HashMap attr = new HashMap();
+              attr.put(SRPKeyPairGenerator.SHARED_MODULUS, N);
+              attr.put(SRPKeyPairGenerator.GENERATOR, g);
+              attr.put(SRPKeyPairGenerator.USER_VERIFIER, v);
+              kpg.setup(attr);
+              return kpg.generate();
+            }
+        }
+      catch (IOException ioe) { }
+      return null;
+    }
+
+    public byte[] getSalt(String user)
+    {
+      try
+        {
+          if (file.contains(user))
+            {
+              return gnu.java.security.util.Util.fromBase64(file.lookup(user, "SHA")[1]);
+            }
+        }
+      catch (IOException ioe) { }
+      return null;
+    }
+
+    public BigInteger getVerifier(String user)
+    {
+      try
+        {
+          if (file.contains(user))
+            {
+              return new BigInteger(1,
+                gnu.java.security.util.Util.fromBase64(file.lookup(user, "SHA")[0]));
+            }
+        }
+      catch (IOException ioe) { }
+      return null;
+    }
+
+    public PasswordFile getPasswordFile()
+    {
+      return file;
+    }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLHMac.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLHMac.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLHMac.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLHMac.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,158 @@
+/* SSLHMac.java -- SSLv3's MAC algorithm.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.util.Arrays;
+import java.util.Map;
+
+import gnu.java.security.hash.HashFactory;
+import gnu.java.security.hash.IMessageDigest;
+import gnu.javax.crypto.mac.IMac;
+
+/**
+ * The MAC function in SSLv3. This mac is defined as:
+ *
+ * <pre>
+ * hash(MAC_write_secret, pad_2 +
+ *      hash(MAC_write_secret + pad_1 + data));</pre>
+ *
+ * <p><tt>hash</tt> is e.g. MD5 or SHA-1, <tt>pad_1</tt> is the value
+ * 0x36 48 times for MD5 and 40 times for SHA-1, and <tt>pad_2</tt> is
+ * the value 0x5c repeated similarly.
+ */
+class SSLHMac implements IMac, Cloneable
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  static final byte PAD1 = 0x36;
+  static final byte PAD2 = 0x5c;
+
+  protected IMessageDigest md;
+  protected byte[] key;
+  protected final byte[] pad1, pad2;
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  SSLHMac(String mdName)
+  {
+    super();
+    this.md = HashFactory.getInstance(mdName);
+    if (mdName.equalsIgnoreCase("MD5"))
+      {
+        pad1 = new byte[48];
+        pad2 = new byte[48];
+      }
+    else
+      {
+        pad1 = new byte[40];
+        pad2 = new byte[40];
+      }
+    Arrays.fill(pad1, PAD1);
+    Arrays.fill(pad2, PAD2);
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public Object clone()
+  {
+    try
+      {
+        return super.clone();
+      }
+    catch (CloneNotSupportedException cnse)
+      {
+        throw new Error();
+      }
+  }
+
+  public String name()
+  {
+    return "SSLHMac-" + md.name();
+  }
+
+  public int macSize()
+  {
+    return md.hashSize();
+  }
+
+  public void init(Map attributes)
+  {
+    key = (byte[]) attributes.get(MAC_KEY_MATERIAL);
+    if (key == null)
+      throw new NullPointerException();
+    reset();
+  }
+
+  public void reset()
+  {
+    md.reset();
+    md.update(key, 0, key.length);
+    md.update(pad1, 0, pad1.length);
+  }
+
+  public byte[] digest()
+  {
+    byte[] h1 = md.digest();
+    md.update(key, 0, key.length);
+    md.update(pad2, 0, pad2.length);
+    md.update(h1, 0, h1.length);
+    byte[] result = md.digest();
+    reset();
+    return result;
+  }
+
+  public void update(byte b)
+  {
+    md.update(b);
+  }
+
+  public void update(byte[] buf, int off, int len)
+  {
+    md.update(buf, off, len);
+  }
+
+  public boolean selfTest()
+  {
+    return true; // XXX
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLRSASignature.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLRSASignature.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLRSASignature.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLRSASignature.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,235 @@
+/* SSLRSASignature.java -- SSL's RSA signature algorithm.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.math.BigInteger;
+
+import java.security.InvalidKeyException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+
+import java.util.Arrays;
+import java.util.Map;
+
+import gnu.java.security.hash.HashFactory;
+import gnu.java.security.hash.IMessageDigest;
+import gnu.java.security.sig.ISignature;
+import gnu.java.security.sig.rsa.RSA;
+
+/**
+ * The RSA signature algorithm as used in the SSL protocol. Note that this
+ * is different from the RSA signature used to verify certificates.
+ *
+ * <p>This signature scheme works as follows:</p>
+ *
+ * <blockquote><p><pre>digitally-signed struct {
+ *     opaque md5_hash[16];
+ *     opaque sha_hash[20];
+ * }</pre></p></blockquote>
+ *
+ * <p>Where a <code>digitally-signed struct</code> is RSA-encrypted with
+ * block type 0 or 1 according to PKCS #1, version 1.5.</p>
+ */
+final class SSLRSASignature implements ISignature
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private RSAPublicKey pubkey;
+  private RSAPrivateKey privkey;
+  private final IMessageDigest md5, sha;
+  private boolean initVerify = false, initSign = false;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  SSLRSASignature()
+  {
+    this(HashFactory.getInstance("MD5"), HashFactory.getInstance("SHA-1"));
+  }
+
+  SSLRSASignature(IMessageDigest md5, IMessageDigest sha)
+  {
+    this.md5 = md5;
+    this.sha = sha;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public String name()
+  {
+    return "RSA/SSL";
+  }
+
+  public void setupVerify(Map attrib)
+  {
+    PublicKey key = (PublicKey) attrib.get(VERIFIER_KEY);
+    if (key == null)
+      {
+        if (initSign)
+          {
+            return; // re-use.
+          }
+        throw new IllegalArgumentException("no key supplied");
+      }
+    if (!(key instanceof RSAPublicKey))
+      {
+        throw new IllegalArgumentException("not an RSA key");
+      }
+    pubkey = (RSAPublicKey) key;
+    privkey = null;
+    initSign = false;
+    initVerify = true;
+  }
+
+  public void setupSign(Map attrib)
+  {
+    PrivateKey key = (PrivateKey) attrib.get(SIGNER_KEY);
+    if (key == null)
+      {
+        if (initVerify)
+          {
+            return; // re-use.
+          }
+        throw new IllegalArgumentException("no key supplied");
+      }
+    if (!(key instanceof RSAPrivateKey))
+      {
+        throw new IllegalArgumentException("not an RSA key");
+      }
+    privkey = (RSAPrivateKey) key;
+    pubkey = null;
+    initVerify = false;
+    initSign = true;
+  }
+
+  public void update(byte b)
+  {
+    if (!initVerify && !initSign)
+      {
+        throw new IllegalStateException();
+      }
+    md5.update(b);
+    sha.update(b);
+  }
+
+  public void update(byte[] buf, int off, int len)
+  {
+    if (!initVerify && !initSign)
+      {
+        throw new IllegalStateException();
+      }
+    md5.update(buf, off, len);
+    sha.update(buf, off, len);
+  }
+
+  public Object sign()
+  {
+    if (!initSign)
+      {
+        throw new IllegalStateException();
+      }
+    // Pad the hash results with RSA block type 1.
+    final int k = (privkey.getModulus().bitLength() + 7) >>> 3;
+    final byte[] d = Util.concat(md5.digest(), sha.digest());
+    if (k - 11 < d.length)
+      {
+        throw new IllegalArgumentException("message too long");
+      }
+    final byte[] eb = new byte[k];
+    eb[0] = 0x00;
+    eb[1] = 0x01;
+    for (int i = 2; i < k - d.length - 1; i++)
+      {
+        eb[i] = (byte) 0xFF;
+      }
+    System.arraycopy(d, 0, eb, k - d.length, d.length);
+    BigInteger EB = new BigInteger(eb);
+
+    // Private-key encrypt the padded hashes.
+    BigInteger EM = RSA.sign(privkey, EB);
+    return Util.trim(EM);
+  }
+
+  public boolean verify(Object signature)
+  {
+    if (!initVerify)
+      {
+        throw new IllegalStateException();
+      }
+    // Public-key decrypt the signature representative.
+    BigInteger EM = new BigInteger(1, (byte[]) signature);
+    BigInteger EB = RSA.verify(pubkey, EM);
+
+    // Unpad the decrypted message.
+    int i = 0;
+    final byte[] eb = EB.toByteArray();
+    if (eb[0] == 0x00)
+      {
+        for (i = 0; i < eb.length && eb[i] == 0x00; i++);
+      }
+    else if (eb[0] == 0x01)
+      {
+        for (i = 1; i < eb.length && eb[i] != 0x00; i++)
+          {
+            if (eb[i] != (byte) 0xFF)
+              {
+                throw new IllegalArgumentException("bad padding");
+              }
+          }
+        i++;
+      }
+    else
+      {
+        throw new IllegalArgumentException("decryption failed");
+      }
+    byte[] d1 = Util.trim(eb, i, eb.length - i);
+    byte[] d2 = Util.concat(md5.digest(), sha.digest());
+    return Arrays.equals(d1, d2);
+  }
+
+  public Object clone()
+  {
+    throw new UnsupportedOperationException();
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLRandom.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLRandom.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLRandom.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLRandom.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,165 @@
+/* SSLRandom.java -- SSLv3 pseudo-random function.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.util.Map;
+import gnu.java.security.hash.HashFactory;
+import gnu.java.security.hash.IMessageDigest;
+import gnu.java.security.prng.IRandom;
+import gnu.java.security.prng.LimitReachedException;
+
+class SSLRandom implements IRandom
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  static final String SECRET = "jessie.sslprng.secret";
+  static final String SEED = "jessie.sslprng.seed";
+
+  private final IMessageDigest md5, sha;
+  private byte[] secret;
+  private byte[] buffer;
+  private byte pad;
+  private byte[] seed;
+  private int idx;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  SSLRandom()
+  {
+    md5 = HashFactory.getInstance("MD5");
+    sha = HashFactory.getInstance("SHA-1");
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public void init(Map attrib)
+  {
+    secret = (byte[]) attrib.get(SECRET);
+    seed = (byte[]) attrib.get(SEED);
+
+    if (secret == null || seed == null)
+      throw new NullPointerException();
+
+    pad = (byte) 'A';
+    try { buffer = nextBlock(); }
+    catch (LimitReachedException cantHappen) { }
+  }
+
+  public String name()
+  {
+    return "SSLRandom";
+  }
+
+  public Object clone()
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  public byte nextByte() throws LimitReachedException
+  {
+    if (buffer == null)
+      throw new IllegalStateException();
+    if (idx >= buffer.length)
+      buffer = nextBlock();
+    return buffer[idx++];
+  }
+
+  public void nextBytes(byte[] buf, int off, int len)
+    throws LimitReachedException
+  {
+    if (buffer == null)
+      throw new IllegalStateException();
+    if (buf == null)
+      throw new NullPointerException();
+    if (off < 0 || len < 0 || off+len > buf.length)
+      throw new IndexOutOfBoundsException();
+    int count = 0;
+    while (count < len)
+      {
+        if (idx >= buffer.length)
+          buffer = nextBlock();
+        int l = Math.min(buffer.length-idx, len-count);
+        System.arraycopy(buffer, idx, buf, off+count, l);
+        count += l;
+        idx += l;
+      }
+  }
+
+  public boolean selfTest()
+  {
+    return true; // XXX
+  }
+
+  // For future versions of GNU Crypto. No-ops.
+  public void addRandomByte (byte b)
+  {
+  }
+
+  public void addRandomBytes(byte[] buffer) {
+    addRandomBytes(buffer, 0, buffer.length);
+  }
+
+  public void addRandomBytes (byte[] b, int i, int j)
+  {
+  }
+
+  // Own methods.
+  // -------------------------------------------------------------------------
+
+  private byte[] nextBlock() throws LimitReachedException
+  {
+    int count = pad - 'A' + 1;
+    if (count > 26)
+      throw new LimitReachedException();
+    for (int i = 0; i < count; i++)
+      sha.update(pad);
+    sha.update(secret, 0, secret.length);
+    sha.update(seed, 0, seed.length);
+    byte[] b = sha.digest();
+    md5.update(secret, 0, secret.length);
+    md5.update(b, 0, b.length);
+    idx = 0;
+    pad++;
+    return md5.digest();
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLServerSocket.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLServerSocket.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLServerSocket.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLServerSocket.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,283 @@
+/* SSLServerSocket.java -- SSL server socket.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.IOException;
+
+import java.net.InetAddress;
+import java.net.Socket;
+
+import java.security.SecureRandom;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import javax.net.ssl.X509KeyManager;
+import javax.net.ssl.X509TrustManager;
+
+import gnu.javax.net.ssl.SRPTrustManager;
+
+class SSLServerSocket extends javax.net.ssl.SSLServerSocket
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private SessionContext sessions;
+  private SortedSet enabledProtocols = new TreeSet(SSLSocket.supportedProtocols);
+  private List enabledSuites = new ArrayList(SSLSocket.supportedSuites);
+  private boolean clientMode = false;
+  private boolean needClientAuth = false;
+  private boolean wantClientAuth = false;
+  private boolean createSessions = true;
+  private SRPTrustManager srpTrustManager;
+  private X509TrustManager trustManager;
+  private X509KeyManager keyManager;
+  private SecureRandom random;
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  SSLServerSocket() throws IOException
+  {
+    super();
+  }
+
+  SSLServerSocket(int port) throws IOException
+  {
+    super(port);
+  }
+
+  SSLServerSocket(int port, int backlog) throws IOException
+  {
+    super(port, backlog);
+  }
+
+  SSLServerSocket(int port, int backlog, InetAddress address)
+    throws IOException
+  {
+    super(port, backlog, address);
+  }
+
+  // SSL methods.
+  // -------------------------------------------------------------------------
+
+  public String[] getSupportedCipherSuites()
+  {
+    return (String[]) CipherSuite.availableSuiteNames().toArray(new String[0]);
+  }
+
+  public String[] getEnabledCipherSuites()
+  {
+    synchronized (enabledSuites)
+      {
+        String[] s = new String[enabledSuites.size()];
+        int i = 0;
+        for (Iterator it = enabledSuites.iterator(); it.hasNext(); )
+          s[i++] = it.next().toString();
+        return s;
+      }
+  }
+
+  public void setEnabledCipherSuites(String[] suites)
+  {
+    if (suites == null || suites.length == 0)
+      throw new IllegalArgumentException();
+    for (int i = 0; i < suites.length; i++)
+      if (CipherSuite.forName(suites[i]) == null)
+        throw new IllegalArgumentException("unsupported suite: " +
+                                           suites[i]);
+    synchronized (enabledSuites)
+      {
+        enabledSuites.clear();
+        for (int i = 0; i < suites.length; i++)
+          {
+            CipherSuite suite = CipherSuite.forName(suites[i]);
+            if (!enabledSuites.contains(suite))
+              enabledSuites.add(suite);
+          }
+      }
+  }
+
+  public String[] getSupportedProtocols()
+  {
+    return new String[] { "SSLv3", "TLSv1", "TLSv1.1" };
+  }
+
+  public String[] getEnabledProtocols()
+  {
+    synchronized (enabledProtocols)
+      {
+        String[] s = new String[enabledProtocols.size()];
+        int i = 0;
+        for (Iterator it = enabledProtocols.iterator(); it.hasNext(); )
+          s[i++] = it.next().toString();
+        return s;
+      }
+  }
+
+  public void setEnabledProtocols(String[] protocols)
+  {
+    if (protocols == null || protocols.length == 0)
+      throw new IllegalArgumentException();
+    for (int i = 0; i < protocols.length; i++)
+      {
+        if (!(protocols[i].equalsIgnoreCase("SSLv3") ||
+              protocols[i].equalsIgnoreCase("TLSv1") ||
+              protocols[i].equalsIgnoreCase("TLSv1.1")))
+          {
+            throw new
+              IllegalArgumentException("unsupported protocol: " +
+                                       protocols[i]);
+          }
+      }
+    synchronized (enabledProtocols)
+      {
+        enabledProtocols.clear();
+        for (int i = 0; i < protocols.length; i++)
+          {
+            if (protocols[i].equalsIgnoreCase("SSLv3"))
+              enabledProtocols.add(ProtocolVersion.SSL_3);
+            else if (protocols[i].equalsIgnoreCase("TLSv1"))
+              enabledProtocols.add(ProtocolVersion.TLS_1);
+            else
+              enabledProtocols.add(ProtocolVersion.TLS_1_1);
+          }
+      }
+  }
+
+  public void setUseClientMode(boolean clientMode)
+  {
+    this.clientMode = clientMode;
+  }
+
+  public boolean getUseClientMode()
+  {
+    return clientMode;
+  }
+
+  public void setNeedClientAuth(boolean needClientAuth)
+  {
+    this.needClientAuth = needClientAuth;
+  }
+
+  public boolean getNeedClientAuth()
+  {
+    return needClientAuth;
+  }
+
+  public void setWantClientAuth(boolean wantClientAuth)
+  {
+    this.wantClientAuth = wantClientAuth;
+  }
+
+  public boolean getWantClientAuth()
+  {
+    return wantClientAuth;
+  }
+
+  // I misspelled this method in javax.net.SSLServerSocket, and that version
+  // made it into kaffe 1.1.4.
+  public void setEnabledSessionCreation(boolean createSessions)
+  {
+    setEnableSessionCreation(createSessions);
+  }
+
+  public void setEnableSessionCreation(boolean createSessions)
+  {
+    this.createSessions = createSessions;
+  }
+
+  public boolean getEnableSessionCreation()
+  {
+    return createSessions;
+  }
+
+  // Socket methods.
+  // -------------------------------------------------------------------------
+
+  public Socket accept() throws IOException
+  {
+    SSLSocket socket = new SSLSocket();
+    implAccept(socket);
+    socket.setUseClientMode(clientMode);
+    socket.setNeedClientAuth(needClientAuth);
+    socket.setWantClientAuth(wantClientAuth);
+    socket.setEnableSessionCreation(createSessions);
+    socket.setSessionContext(sessions);
+    socket.setEnabledCipherSuites(new ArrayList(enabledSuites));
+    socket.setEnabledProtocols(new TreeSet(enabledProtocols));
+    socket.setSRPTrustManager(srpTrustManager);
+    socket.setTrustManager(trustManager);
+    socket.setKeyManager(keyManager);
+    socket.setRandom(random);
+    return socket;
+  }
+
+  // Package methods.
+  // -------------------------------------------------------------------------
+
+  void setSessionContext(SessionContext sessions)
+  {
+    this.sessions = sessions;
+  }
+
+  void setKeyManager(X509KeyManager keyManager)
+  {
+    this.keyManager = keyManager;
+  }
+
+  void setTrustManager(X509TrustManager trustManager)
+  {
+    this.trustManager = trustManager;
+  }
+
+  void setSRPTrustManager(SRPTrustManager srpTrustManager)
+  {
+    this.srpTrustManager = srpTrustManager;
+  }
+
+  void setRandom(SecureRandom random)
+  {
+    this.random = random;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLServerSocketFactory.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLServerSocketFactory.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLServerSocketFactory.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLServerSocketFactory.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,136 @@
+/* SSLServerSocketFactory.java -- factory for SSL server sockets.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.IOException;
+
+import java.net.InetAddress;
+import java.net.ServerSocket;
+
+import java.security.SecureRandom;
+
+import javax.net.ssl.X509KeyManager;
+import javax.net.ssl.X509TrustManager;
+
+import gnu.javax.net.ssl.SRPTrustManager;
+
+class SSLServerSocketFactory extends javax.net.ssl.SSLServerSocketFactory
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final SessionContext sessions;
+  private final X509KeyManager keyManager;
+  private final X509TrustManager trustManager;
+  private final SRPTrustManager srpTrustManager;
+  private final SecureRandom random;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  SSLServerSocketFactory(X509TrustManager trustManager,
+                         SRPTrustManager srpTrustManager,
+                         X509KeyManager keyManager,
+                         SecureRandom random,
+                         SessionContext sessions)
+  {
+    super();
+    this.trustManager = trustManager;
+    this.srpTrustManager = srpTrustManager;
+    this.keyManager = keyManager;
+    this.random = random;
+    this.sessions = sessions;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public String[] getDefaultCipherSuites()
+  {
+    return getSupportedCipherSuites();
+  }
+
+  public String[] getSupportedCipherSuites()
+  {
+    return (String[]) CipherSuite.availableSuiteNames().toArray(new String[0]);
+  }
+
+  public ServerSocket createServerSocket() throws IOException
+  {
+    SSLServerSocket socket = new SSLServerSocket();
+    setup(socket);
+    return socket;
+  }
+
+  public ServerSocket createServerSocket(int port) throws IOException
+  {
+    SSLServerSocket socket = new SSLServerSocket(port);
+    setup(socket);
+    return socket;
+  }
+
+  public ServerSocket createServerSocket(int port, int backlog)
+    throws IOException
+  {
+    SSLServerSocket socket = new SSLServerSocket(port, backlog);
+    setup(socket);
+    return socket;
+  }
+
+  public ServerSocket createServerSocket(int port, int backlog, InetAddress addr)
+    throws IOException
+  {
+    SSLServerSocket socket = new SSLServerSocket(port, backlog, addr);
+    setup(socket);
+    return socket;
+  }
+
+  // Own methods.
+  // -------------------------------------------------------------------------
+
+  private void setup(SSLServerSocket socket)
+  {
+    socket.setSessionContext(sessions);
+    socket.setKeyManager(keyManager);
+    socket.setTrustManager(trustManager);
+    socket.setSRPTrustManager(srpTrustManager);
+    socket.setRandom(random);
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLSocket.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLSocket.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLSocket.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLSocket.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,3515 @@
+/* SSLSocket.java -- the SSL socket class.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.BufferedOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+import java.math.BigInteger;
+
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+
+import java.nio.channels.SocketChannel;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.DSAPrivateKey;
+import java.security.interfaces.DSAPublicKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import java.util.logging.Logger;
+
+import javax.crypto.Cipher;
+import javax.crypto.Mac;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.interfaces.DHPublicKey;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+import javax.net.ssl.HandshakeCompletedEvent;
+import javax.net.ssl.HandshakeCompletedListener;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLProtocolException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.X509KeyManager;
+import javax.net.ssl.X509TrustManager;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.ConfirmationCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.TextInputCallback;
+
+import gnu.classpath.debug.Component;
+import gnu.classpath.debug.SystemLogger;
+
+import gnu.java.security.Registry;
+import gnu.javax.security.auth.callback.DefaultCallbackHandler;
+import gnu.java.security.hash.HashFactory;
+import gnu.java.security.hash.IMessageDigest;
+import gnu.javax.crypto.key.IKeyAgreementParty;
+import gnu.javax.crypto.key.KeyAgreementFactory;
+import gnu.javax.crypto.key.KeyAgreementException;
+import gnu.javax.crypto.key.OutgoingMessage;
+import gnu.javax.crypto.key.IncomingMessage;
+import gnu.javax.crypto.key.dh.DiffieHellmanKeyAgreement;
+import gnu.javax.crypto.key.dh.ElGamalKeyAgreement;
+import gnu.javax.crypto.key.dh.GnuDHPrivateKey;
+import gnu.javax.crypto.key.dh.GnuDHPublicKey;
+import gnu.javax.crypto.key.srp6.SRPPrivateKey;
+import gnu.javax.crypto.key.srp6.SRPPublicKey;
+import gnu.javax.crypto.key.srp6.SRP6KeyAgreement;
+import gnu.javax.crypto.mac.IMac;
+import gnu.javax.crypto.mode.IMode;
+import gnu.javax.crypto.prng.ARCFour;
+import gnu.java.security.prng.IRandom;
+import gnu.java.security.prng.LimitReachedException;
+import gnu.javax.crypto.sasl.srp.SRPAuthInfoProvider;
+import gnu.javax.crypto.sasl.srp.SRPRegistry;
+import gnu.java.security.sig.ISignature;
+import gnu.java.security.sig.SignatureFactory;
+import gnu.java.security.sig.dss.DSSSignature;
+import gnu.java.security.sig.rsa.EME_PKCS1_V1_5;
+import gnu.java.security.sig.rsa.RSA;
+
+import gnu.javax.net.ssl.SRPTrustManager;
+
+/**
+ * This is the core of the Jessie SSL implementation; it implements the {@link
+ * javax.net.ssl.SSLSocket} for normal and "wrapped" sockets, and handles all
+ * protocols implemented by this library.
+ */
+final class SSLSocket extends javax.net.ssl.SSLSocket
+{
+
+  // This class is almost unbearably large and complex, but is laid out
+  // as follows:
+  //
+  // 1. Fields.
+  // 2. Constructors.
+  // 3. SSLSocket methods. These are the public methods defined in
+  //    javax.net.ssl.SSLSocket.
+  // 4. Socket methods. These override the public methods of java.net.Socket,
+  //    and delegate the method call to either the underlying socket if this is
+  //    a wrapped socket, or to the superclass.
+  // 5. Package-private methods that various pieces of Jessie use.
+  // 6. Private methods. These compose the SSL handshake.
+  //
+  // Each part is preceeded by a form feed.
+
+// Constants and fields.
+  // -------------------------------------------------------------------------
+
+  // Debuggery.
+  private static final boolean DEBUG_HANDSHAKE_LAYER = true;
+  private static final boolean DEBUG_KEY_EXCHANGE = false;
+  private static final Logger logger = SystemLogger.SYSTEM;
+
+  // Fields for using this class as a wrapped socket.
+  private Socket underlyingSocket;
+  private int underlyingPort;
+  private boolean autoClose;
+
+  // Cryptography fields.
+  SessionContext sessionContext;
+  Session session;
+  LinkedList handshakeListeners;
+  private boolean clientMode, wantClientAuth, needClientAuth, createSessions;
+  private boolean handshakeDone;
+
+  // I/O fields.
+  private String remoteHost;
+  private InputStream socketIn;
+  private OutputStream socketOut;
+  private InputStream applicationIn;
+  private OutputStream applicationOut;
+  private InputStream handshakeIn;
+  private OutputStream handshakeOut;
+//   private ThreadGroup recordLayer;
+  RecordInput recordInput;
+//  RecordOutput recordOutput;
+  private long handshakeTime;
+
+  private SocketChannel channel;
+
+  static SortedSet supportedProtocols = new TreeSet();
+  static List supportedSuites = new ArrayList(30);
+
+// Static initializer.
+  // -------------------------------------------------------------------------
+
+  static
+  {
+    //supportedProtocols.add(ProtocolVersion.TLS_1_1);
+    supportedProtocols.add(ProtocolVersion.TLS_1);
+    supportedProtocols.add(ProtocolVersion.SSL_3);
+
+    // These are in preference order. It's my preference order, but I'm not
+    // a total idiot.
+    supportedSuites.add(CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_RSA_WITH_RC4_128_MD5);
+    supportedSuites.add(CipherSuite.TLS_RSA_WITH_RC4_128_SHA);
+    supportedSuites.add(CipherSuite.TLS_DHE_DSS_WITH_DES_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_DHE_RSA_WITH_DES_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_DH_DSS_WITH_DES_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_DH_RSA_WITH_DES_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_RSA_WITH_DES_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_RSA_EXPORT_WITH_DES40_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_RSA_EXPORT_WITH_RC4_40_MD5);
+    supportedSuites.add(CipherSuite.TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA);
+    supportedSuites.add(CipherSuite.TLS_RSA_WITH_NULL_MD5);
+    supportedSuites.add(CipherSuite.TLS_RSA_WITH_NULL_SHA);
+  }
+
+// Constructors.
+  // -------------------------------------------------------------------------
+
+  SSLSocket(Socket socket, String host, int port, boolean autoClose)
+    throws IOException
+  {
+    underlyingSocket = socket;
+    remoteHost = host;
+    underlyingPort = port;
+    this.autoClose = autoClose;
+    initialize();
+  }
+
+  SSLSocket (Socket socket, SocketChannel channel) throws IOException
+  {
+    underlyingSocket = socket;
+    this.channel = channel;
+    initialize ();
+  }
+
+  SSLSocket() throws IOException
+  {
+    super();
+    initialize();
+  }
+
+  SSLSocket(InetAddress addr, int port) throws IOException
+  {
+    super(addr, port);
+    initialize();
+    remoteHost = addr.getHostName();
+    if (remoteHost == null)
+      {
+        remoteHost = addr.getHostAddress();
+      }
+  }
+
+  SSLSocket(InetAddress addr, int port, InetAddress laddr, int lport)
+    throws IOException
+  {
+    super(addr, port, laddr, lport);
+    initialize();
+    remoteHost = addr.getHostName();
+    if (remoteHost == null)
+      remoteHost = addr.getHostAddress();
+  }
+
+  SSLSocket(String host, int port) throws IOException
+  {
+    super(host, port);
+    initialize();
+    remoteHost = host;
+  }
+
+  SSLSocket(String host, int port, InetAddress laddr, int lport)
+    throws IOException
+  {
+    super(host, port, laddr, lport);
+    initialize();
+    remoteHost = host;
+  }
+
+  private void initialize()
+  {
+    session = new Session();
+    session.enabledSuites = new ArrayList(supportedSuites);
+    session.enabledProtocols = new TreeSet(supportedProtocols);
+    session.protocol = ProtocolVersion.TLS_1;
+    session.params.setVersion (ProtocolVersion.TLS_1);
+    handshakeListeners = new LinkedList();
+    handshakeDone = false;
+  }
+
+// SSL methods.
+  // -------------------------------------------------------------------------
+
+  public void addHandshakeCompletedListener(HandshakeCompletedListener l)
+  {
+    synchronized (handshakeListeners)
+      {
+        if (l == null)
+          throw new NullPointerException();
+        if (!handshakeListeners.contains(l))
+          handshakeListeners.add(l);
+      }
+  }
+
+  public void removeHandshakeCompletedListener(HandshakeCompletedListener l)
+  {
+    synchronized (handshakeListeners)
+      {
+        handshakeListeners.remove(l);
+      }
+  }
+
+  public String[] getEnabledProtocols()
+  {
+    synchronized (session.enabledProtocols)
+      {
+        try
+          {
+            return (String[]) Util.transform(session.enabledProtocols.toArray(),
+                                             String.class, "toString", null);
+          }
+        catch (Exception x)
+          {
+            RuntimeException re = new RuntimeException (x.getMessage());
+            re.initCause (x);
+            throw re;
+          }
+      }
+  }
+
+  public void setEnabledProtocols(String[] protocols)
+  {
+    if (protocols == null || protocols.length == 0)
+      throw new IllegalArgumentException();
+    for (int i = 0; i < protocols.length; i++)
+      {
+        if (!(protocols[i].equalsIgnoreCase("SSLv3") ||
+              protocols[i].equalsIgnoreCase("TLSv1") ||
+              protocols[i].equalsIgnoreCase("TLSv1.1")))
+          {
+            throw new
+              IllegalArgumentException("unsupported protocol: " +
+                                       protocols[i]);
+          }
+      }
+    synchronized (session.enabledProtocols)
+      {
+        session.enabledProtocols.clear();
+        for (int i = 0; i < protocols.length; i++)
+          {
+            if (protocols[i].equalsIgnoreCase("SSLv3"))
+              {
+                session.enabledProtocols.add(ProtocolVersion.SSL_3);
+              }
+            else if (protocols[i].equalsIgnoreCase("TLSv1"))
+              {
+                session.enabledProtocols.add(ProtocolVersion.TLS_1);
+              }
+            else
+              {
+                session.enabledProtocols.add(ProtocolVersion.TLS_1_1);
+              }
+          }
+      }
+  }
+
+  public String[] getSupportedProtocols()
+  {
+    return new String[] { /* "TLSv1.1", */ "TLSv1", "SSLv3" };
+  }
+
+  public String[] getEnabledCipherSuites()
+  {
+    synchronized (session.enabledSuites)
+      {
+        try
+          {
+            return (String[]) Util.transform(session.enabledSuites.toArray(),
+                                             String.class, "toString", null);
+          }
+        catch (Exception x)
+          {
+            RuntimeException re = new RuntimeException (x.getMessage());
+            re.initCause (x);
+            throw re;
+          }
+      }
+  }
+
+  public void setEnabledCipherSuites(String[] suites)
+  {
+    if (suites == null || suites.length == 0)
+      throw new IllegalArgumentException();
+    for (int i = 0; i < suites.length; i++)
+      if (CipherSuite.forName(suites[i]) == null)
+        throw new IllegalArgumentException("unsupported suite: " +
+                                           suites[i]);
+    synchronized (session.enabledSuites)
+      {
+        session.enabledSuites.clear();
+        for (int i = 0; i < suites.length; i++)
+          {
+            CipherSuite suite = CipherSuite.forName(suites[i]);
+            if (!session.enabledSuites.contains(suite))
+              {
+                session.enabledSuites.add(suite);
+              }
+          }
+      }
+  }
+
+  public String[] getSupportedCipherSuites()
+  {
+    return (String[]) CipherSuite.availableSuiteNames().toArray(new String[52]);
+  }
+
+  public SSLSession getSession()
+  {
+    return session;
+  }
+
+  public boolean getEnableSessionCreation()
+  {
+    return createSessions;
+  }
+
+  public void setEnableSessionCreation(boolean flag)
+  {
+    createSessions = flag;
+  }
+
+  public boolean getNeedClientAuth()
+  {
+    return needClientAuth;
+  }
+
+  public void setNeedClientAuth(boolean flag)
+  {
+    needClientAuth = flag;
+  }
+
+  public boolean getWantClientAuth()
+  {
+    return wantClientAuth;
+  }
+
+  public void setWantClientAuth(boolean flag)
+  {
+    wantClientAuth = flag;
+  }
+
+  public boolean getUseClientMode()
+  {
+    return clientMode;
+  }
+
+  public void setUseClientMode(boolean flag)
+  {
+    this.clientMode = flag;
+  }
+
+  public synchronized void startHandshake() throws IOException
+  {
+    if (DEBUG_HANDSHAKE_LAYER)
+      {
+        logger.log (Component.SSL_HANDSHAKE, "startHandshake called in {0}",
+                    Thread.currentThread());
+        handshakeTime = System.currentTimeMillis();
+      }
+    if (handshakeDone)
+      {
+        if (clientMode)
+          {
+            handshakeDone = false;
+            doClientHandshake();
+          }
+        else
+          {
+            Handshake req = new Handshake(Handshake.Type.HELLO_REQUEST, null);
+            req.write (handshakeOut, session.protocol);
+            handshakeOut.flush();
+//             recordOutput.setHandshakeAvail(req.write(handshakeOut, session.protocol));
+          }
+        return;
+      }
+    if (recordInput == null)
+      {
+        setupIO();
+      }
+    if (clientMode)
+      {
+        doClientHandshake();
+      }
+    else
+      {
+        doServerHandshake();
+      }
+  }
+
+// Socket methods.
+  // -------------------------------------------------------------------------
+
+  public InetAddress getInetAddress()
+  {
+    if (underlyingSocket != null)
+      {
+        return underlyingSocket.getInetAddress();
+      }
+    else
+      {
+        return super.getInetAddress();
+      }
+  }
+
+  public InetAddress getLocalAddress()
+  {
+    if (underlyingSocket != null)
+      {
+        return underlyingSocket.getLocalAddress();
+      }
+    else
+      {
+        return super.getLocalAddress();
+      }
+  }
+
+  public int getPort()
+  {
+    if (underlyingSocket != null)
+      {
+        return underlyingSocket.getPort();
+      }
+    else
+      {
+        return super.getPort();
+      }
+  }
+
+  public int getLocalPort()
+  {
+    if (underlyingSocket != null)
+      {
+        return underlyingSocket.getLocalPort();
+      }
+    else
+      {
+        return super.getLocalPort();
+      }
+  }
+
+  public InputStream getInputStream() throws IOException
+  {
+    if (applicationIn == null)
+      {
+        setupIO();
+      }
+    return applicationIn;
+  }
+
+  public OutputStream getOutputStream() throws IOException
+  {
+    if (applicationOut == null)
+      {
+        setupIO();
+      }
+    return applicationOut;
+  }
+
+  public void setTcpNoDelay(boolean flag) throws SocketException
+  {
+    if (underlyingSocket != null)
+      {
+        underlyingSocket.setTcpNoDelay(flag);
+      }
+    else
+      {
+        super.setTcpNoDelay(flag);
+      }
+  }
+
+  public boolean getTcpNoDelay() throws SocketException
+  {
+    if (underlyingSocket != null)
+      {
+        return underlyingSocket.getTcpNoDelay();
+      }
+    else
+      {
+        return super.getTcpNoDelay();
+      }
+  }
+
+  public void setSoLinger(boolean flag, int linger) throws SocketException
+  {
+    if (underlyingSocket != null)
+      {
+        underlyingSocket.setSoLinger(flag, linger);
+      }
+    else
+      {
+        super.setSoLinger(flag, linger);
+      }
+  }
+
+  public int getSoLinger() throws SocketException
+  {
+    if (underlyingSocket != null)
+      {
+        return underlyingSocket.getSoLinger();
+      }
+    else
+      {
+        return super.getSoLinger();
+      }
+  }
+
+  public void sendUrgentData(int data) throws IOException
+  {
+    throw new UnsupportedOperationException("not implemented");
+  }
+
+  public void setSoTimeout(int timeout) throws SocketException
+  {
+    if (underlyingSocket != null)
+      {
+        underlyingSocket.setSoTimeout(timeout);
+      }
+    else
+      {
+        super.setSoTimeout(timeout);
+      }
+  }
+
+  public int getSoTimeout() throws SocketException
+  {
+    if (underlyingSocket != null)
+      {
+        return underlyingSocket.getSoTimeout();
+      }
+    else
+      {
+        return super.getSoTimeout();
+      }
+  }
+
+  public void setSendBufferSize(int size) throws SocketException
+  {
+    if (underlyingSocket != null)
+      {
+        underlyingSocket.setSendBufferSize(size);
+      }
+    else
+      {
+        super.setSendBufferSize(size);
+      }
+  }
+
+  public int getSendBufferSize() throws SocketException
+  {
+    if (underlyingSocket != null)
+      {
+        return underlyingSocket.getSendBufferSize();
+      }
+    else
+      {
+        return super.getSendBufferSize();
+      }
+  }
+
+  public void setReceiveBufferSize(int size) throws SocketException
+  {
+    if (underlyingSocket != null)
+      {
+        underlyingSocket.setReceiveBufferSize(size);
+      }
+    else
+      {
+        super.setReceiveBufferSize(size);
+      }
+  }
+
+  public int getReceiveBufferSize() throws SocketException
+  {
+    if (underlyingSocket != null)
+      {
+        return underlyingSocket.getReceiveBufferSize();
+      }
+    else
+      {
+        return super.getReceiveBufferSize();
+      }
+  }
+
+  public synchronized void close() throws IOException
+  {
+    if (recordInput == null)
+      {
+        if (underlyingSocket != null)
+          {
+            if (autoClose)
+              underlyingSocket.close();
+          }
+        else
+          super.close();
+        return;
+      }
+//     while (recordOutput.applicationDataPending()) Thread.yield();
+    Alert close = new Alert (Alert.Level.WARNING, Alert.Description.CLOSE_NOTIFY);
+    sendAlert (close);
+    long wait = System.currentTimeMillis() + 60000L;
+    while (session.currentAlert == null && !recordInput.pollClose())
+      {
+
+        Thread.yield();
+        if (wait <= System.currentTimeMillis())
+          {
+            break;
+          }
+      }
+    boolean gotClose = session.currentAlert != null &&
+      session.currentAlert.getDescription() == Alert.Description.CLOSE_NOTIFY;
+//     recordInput.setRunning(false);
+//     recordOutput.setRunning(false);
+//     recordLayer.interrupt();
+    recordInput = null;
+//     recordOutput = null;
+//     recordLayer = null;
+    if (underlyingSocket != null)
+      {
+        if (autoClose)
+          underlyingSocket.close();
+      }
+    else
+      super.close();
+    if (!gotClose)
+      {
+        session.invalidate();
+        throw new SSLException("did not receive close notify");
+      }
+  }
+
+  public String toString()
+  {
+    if (underlyingSocket != null)
+      {
+        return SSLSocket.class.getName() + " [ " + underlyingSocket + " ]";
+      }
+    else
+      {
+        return SSLSocket.class.getName() + " [ " + super.toString() + " ]";
+      }
+  }
+
+  // Configuration insanity begins here.
+
+  public void connect(SocketAddress saddr) throws IOException
+  {
+    if (underlyingSocket != null)
+      {
+        underlyingSocket.connect(saddr);
+      }
+    else
+      {
+        super.connect(saddr);
+      }
+  }
+
+  public void connect(SocketAddress saddr, int timeout) throws IOException
+  {
+    if (underlyingSocket != null)
+      {
+        underlyingSocket.connect(saddr, timeout);
+      }
+    else
+      {
+        super.connect(saddr, timeout);
+      }
+  }
+
+  public void bind(SocketAddress saddr) throws IOException
+  {
+    if (underlyingSocket != null)
+      {
+        underlyingSocket.bind(saddr);
+      }
+    else
+      {
+        super.bind(saddr);
+      }
+  }
+
+  public SocketAddress getLocalSocketAddress()
+  {
+    if (underlyingSocket != null)
+      {
+        return underlyingSocket.getLocalSocketAddress();
+      }
+    else
+      {
+        return super.getLocalSocketAddress();
+      }
+  }
+
+  public SocketChannel getChannel()
+  {
+    return channel;
+  }
+
+  public boolean isBound()
+  {
+    if (underlyingSocket != null)
+      {
+        return underlyingSocket.isBound();
+      }
+    else
+      {
+        return super.isBound();
+      }
+  }
+
+  public boolean isClosed()
+  {
+    if (underlyingSocket != null)
+      {
+        return underlyingSocket.isClosed();
+      }
+    else
+      {
+        return super.isClosed();
+      }
+  }
+
+  public SocketAddress getRemoteSocketAddress()
+  {
+   if (underlyingSocket != null)
+     {
+       return underlyingSocket.getRemoteSocketAddress();
+     }
+   else
+     {
+       return super.getRemoteSocketAddress();
+     }
+  }
+
+  public void setOOBInline(boolean flag) throws SocketException
+  {
+    if (underlyingSocket != null)
+      {
+	underlyingSocket.setOOBInline(flag);
+      }
+    else
+      {
+	super.setOOBInline(flag);
+      }
+  }
+
+  public boolean getOOBInline() throws SocketException
+  {
+    if (underlyingSocket != null)
+      {
+	return underlyingSocket.getOOBInline();
+      }
+    else
+      {
+	return super.getOOBInline();
+      }
+  }
+
+  public void setKeepAlive(boolean flag) throws SocketException
+  {
+    if (underlyingSocket != null)
+      {
+	underlyingSocket.setKeepAlive(flag);
+      }
+    else
+      {
+	super.setKeepAlive(flag);
+      }
+  }
+
+  public boolean getKeepAlive() throws SocketException
+  {
+    if (underlyingSocket != null)
+      {
+	return underlyingSocket.getKeepAlive();
+      }
+    else
+      {
+	return super.getKeepAlive();
+      }
+  }
+
+  public void setTrafficClass(int clazz) throws SocketException
+  {
+    if (underlyingSocket != null)
+      {
+	underlyingSocket.setTrafficClass(clazz);
+      }
+    else
+      {
+	super.setTrafficClass(clazz);
+      }
+  }
+
+  public int getTrafficClass() throws SocketException
+  {
+    if (underlyingSocket != null)
+      {
+	return underlyingSocket.getTrafficClass();
+      }
+    else
+      {
+	return super.getTrafficClass();
+      }
+  }
+
+  public void setReuseAddress(boolean flag) throws SocketException
+  {
+    if (underlyingSocket != null)
+      {
+	underlyingSocket.setReuseAddress(flag);
+      }
+    else
+      {
+	super.setReuseAddress(flag);
+      }
+  }
+
+  public boolean getReuseAddress() throws SocketException
+  {
+    if (underlyingSocket != null)
+      {
+	return underlyingSocket.getReuseAddress();
+      }
+    else
+      {
+	return super.getReuseAddress();
+      }
+  }
+
+  public void shutdownInput() throws IOException
+  {
+    if (underlyingSocket != null)
+      {
+	underlyingSocket.shutdownInput();
+      }
+    else
+      {
+	super.shutdownInput();
+      }
+  }
+
+  public void shutdownOutput() throws IOException
+  {
+    if (underlyingSocket != null)
+      {
+	underlyingSocket.shutdownOutput();
+      }
+    else
+      {
+	super.shutdownOutput();
+      }
+  }
+
+  public boolean isConnected()
+  {
+    if (underlyingSocket != null)
+      {
+        return underlyingSocket.isConnected();
+      }
+    else
+      {
+        return super.isConnected();
+      }
+  }
+
+  public boolean isInputShutdown()
+  {
+    if (underlyingSocket != null)
+      {
+	return underlyingSocket.isInputShutdown();
+      }
+    else
+      {
+	return super.isInputShutdown();
+      }
+  }
+
+  public boolean isOutputShutdown()
+  {
+    if (underlyingSocket != null)
+      {
+	return underlyingSocket.isOutputShutdown();
+      }
+    else
+      {
+	return super.isOutputShutdown();
+      }
+  }
+
+  protected void finalize()
+  {
+    if (session.currentAlert == null)
+      {
+        try
+          {
+            close();
+          }
+        catch (Exception ignore) { }
+      }
+  }
+
+// Package methods.
+  // -------------------------------------------------------------------------
+
+  void setSessionContext(SessionContext sessionContext)
+  {
+    this.sessionContext = sessionContext;
+  }
+
+  void setEnabledCipherSuites(List suites)
+  {
+    session.enabledSuites = suites;
+  }
+
+  void setEnabledProtocols(SortedSet protocols)
+  {
+    session.enabledProtocols = protocols;
+  }
+
+  void setSRPTrustManager(SRPTrustManager srpTrustManager)
+  {
+    session.srpTrustManager = srpTrustManager;
+  }
+
+  void setTrustManager(X509TrustManager trustManager)
+  {
+    session.trustManager = trustManager;
+  }
+
+  void setKeyManager(X509KeyManager keyManager)
+  {
+    session.keyManager = keyManager;
+  }
+
+  void setRandom(SecureRandom random)
+  {
+    session.random = random;
+  }
+
+  void sendAlert (Alert alert) throws IOException
+  {
+    RecordOutputStream out =
+      new RecordOutputStream (socketOut, ContentType.ALERT, session.params);
+    out.write (alert.getEncoded ());
+  }
+
+  /**
+   * Gets the most-recently-received alert message.
+   *
+   * @return The alert message.
+   */
+  Alert checkAlert()
+  {
+    return session.currentAlert;
+  }
+
+  synchronized void checkHandshakeDone() throws IOException
+  {
+    if (!handshakeDone)
+      {
+        startHandshake();
+      }
+    Alert alert = session.currentAlert;
+    if (alert != null && alert.getLevel() == Alert.Level.FATAL)
+      {
+        throw new AlertException(alert, false);
+      }
+    if (handshakeIn.available() > 0 && !clientMode)
+      {
+        handshakeDone = false;
+        startHandshake();
+      }
+  }
+
+// Own methods.
+  // -------------------------------------------------------------------------
+
+  private static final byte[] SENDER_CLIENT =
+    new byte[] { 0x43, 0x4C, 0x4E, 0x54 };
+  private static final byte[] SENDER_SERVER =
+    new byte[] { 0x53, 0x52, 0x56, 0x52 };
+
+  private void changeCipherSpec () throws IOException
+  {
+    RecordOutputStream out =
+      new RecordOutputStream (socketOut, ContentType.CHANGE_CIPHER_SPEC, session.params);
+    out.write (1);
+  }
+
+  private void readChangeCipherSpec () throws IOException
+  {
+    RecordInputStream in =
+      new RecordInputStream (recordInput, ContentType.CHANGE_CIPHER_SPEC);
+    if (in.read() != 1)
+      {
+        throw new SSLProtocolException ("bad change cipher spec message");
+      }
+  }
+
+  /**
+   * Initializes the application data streams and starts the record layer
+   * threads.
+   */
+  private synchronized void setupIO() throws IOException
+  {
+    if (recordInput != null)
+      {
+        return;
+      }
+    if (underlyingSocket != null)
+      {
+        socketIn = underlyingSocket.getInputStream();
+        socketOut = underlyingSocket.getOutputStream();
+      }
+    else
+      {
+        socketIn = super.getInputStream();
+        socketOut = super.getOutputStream();
+      }
+//     recordLayer = new ThreadGroup("record_layer");
+//     recordInput = new RecordInput(in, session, recordLayer);
+//     recordOutput = new RecordOutput(out, session, recordLayer);
+//     recordInput.setRecordOutput(recordOutput);
+//     recordLayer.setDaemon(true);
+//     recordInput.start();
+//     recordOutput.start();
+    recordInput = new RecordInput (socketIn, session);
+    applicationIn = new SSLSocketInputStream(
+      new RecordInputStream (recordInput, ContentType.APPLICATION_DATA), this);
+    applicationOut = new SSLSocketOutputStream(
+      new RecordOutputStream (socketOut, ContentType.APPLICATION_DATA, session.params), this);
+    handshakeIn = new SSLSocketInputStream(
+      new RecordInputStream (recordInput, ContentType.HANDSHAKE), this, false);
+    handshakeOut = new BufferedOutputStream (new SSLSocketOutputStream(
+      new RecordOutputStream (socketOut, ContentType.HANDSHAKE, session.params), this, false), 8096);
+  }
+
+  private void handshakeCompleted ()
+  {
+    handshakeDone = true;
+    HandshakeCompletedEvent event = new HandshakeCompletedEvent (this, session);
+    for (Iterator it = handshakeListeners.iterator (); it.hasNext (); )
+      {
+        try
+          {
+            ((HandshakeCompletedListener) it.next ()).handshakeCompleted (event);
+          }
+        catch (Throwable t) { }
+      }
+    if (createSessions)
+      {
+        synchronized (session)
+          {
+            sessionContext.addSession (session.sessionId, session);
+            session.access ();
+          }
+      }
+
+    if (DEBUG_HANDSHAKE_LAYER)
+      {
+        logger.log (Component.SSL_HANDSHAKE, "Handshake finished in {0}",
+                    Thread.currentThread());
+        handshakeTime = System.currentTimeMillis() - handshakeTime;
+        logger.log (Component.SSL_HANDSHAKE, "Elapsed time {0}s",
+                    new Long (handshakeTime / 1000));
+      }
+  }
+
+  /*
+   * Perform the client handshake. The process looks like this:
+   *
+   *   ClientHello          -->
+   *   ServerHello         <--
+   *   Certificate*        <--
+   *   ServerKeyExchange*  <--
+   *   CertificateRequest* <--
+   *   ServerHelloDone*    <--
+   *   Certificate*         -->
+   *   ClientKeyExchange    -->
+   *   CertificateVerify*   -->
+   *   [ChangeCipherSpec]   -->
+   *   Finished             -->
+   *   [ChangeCipherSpec]  <--
+   *   Finished            <--
+   *
+   * With --> denoting output and <-- denoting input. * denotes optional
+   * messages.
+   *
+   * Alternatively, this may be an abbreviated handshake if we are resuming
+   * a session:
+   *
+   *   ClientHello          -->
+   *   ServerHello         <--
+   *   [ChangeCipherSpec]  <--
+   *   Finished            <--
+   *   [ChangeCipherSpec]   -->
+   *   Finished             -->
+   */
+  private void doClientHandshake() throws IOException
+  {
+    if (DEBUG_HANDSHAKE_LAYER)
+      {
+        logger.log (Component.SSL_HANDSHAKE, "starting client handshake in {0}",
+                    Thread.currentThread());
+      }
+
+    IMessageDigest md5 = HashFactory.getInstance(Registry.MD5_HASH);
+    IMessageDigest sha = HashFactory.getInstance(Registry.SHA160_HASH);
+    DigestInputStream din = new DigestInputStream(handshakeIn, md5, sha);
+    DigestOutputStream dout = new DigestOutputStream(handshakeOut, md5, sha);
+    Session continuedSession = null;
+    byte[] sessionId = new byte[0];
+    List extensions = null;
+    String user = null;
+    CertificateType certType = CertificateType.X509;
+
+    // Look through the available sessions to see if an appropriate one is
+    // available.
+    for (Enumeration e = sessionContext.getIds(); e.hasMoreElements(); )
+      {
+        byte[] id = (byte[]) e.nextElement();
+        continuedSession = (Session) sessionContext.getSession(id);
+        if (continuedSession == null)
+          {
+            continue;
+          }
+        if (!session.enabledProtocols.contains(continuedSession.protocol))
+          {
+            continue;
+          }
+        if (continuedSession.getPeerHost().equals(remoteHost))
+          {
+            sessionId = id;
+            break;
+          }
+      }
+
+    // If a SRP suite is enabled, ask for a username so we can include it
+    // with our extensions list.
+    for (Iterator i = session.enabledSuites.iterator(); i.hasNext(); )
+      {
+        CipherSuite s = (CipherSuite) i.next();
+        if (s.getKeyExchange() == "SRP")
+          {
+            extensions = new LinkedList();
+            user = askUserName(remoteHost);
+            byte[] b = user.getBytes("UTF-8");
+            if (b.length > 255)
+              {
+                handshakeFailure();
+                throw new SSLException("SRP username too long");
+              }
+            extensions.add(new Extension(Extension.Type.SRP,
+              Util.concat(new byte[] { (byte) b.length }, b)));
+
+            break;
+          }
+      }
+
+    // If the jessie.fragment.length property is set, add the appropriate
+    // extension to the list. The fragment length is only actually set if
+    // the server responds with the same extension.
+    try
+      {
+        int flen = Integer.parseInt(Util.getSecurityProperty("jessie.fragment.length"));
+        byte[] ext = new byte[1];
+        if (flen == 512)
+          ext[0] = 1;
+        else if (flen == 1024)
+          ext[0] = 2;
+        else if (flen == 2048)
+          ext[0] = 3;
+        else if (flen == 4096)
+          ext[0] = 4;
+        else
+          throw new NumberFormatException();
+        if (extensions == null)
+          extensions = new LinkedList();
+        extensions.add(new Extension(Extension.Type.MAX_FRAGMENT_LENGTH, ext));
+      }
+    catch (NumberFormatException nfe) { }
+
+    // FIXME: set certificate types.
+
+    // Send the client hello.
+    ProtocolVersion version = session.protocol;
+    Random clientRandom =
+      new Random(Util.unixTime(), session.random.generateSeed(28));
+    session.protocol = (ProtocolVersion) session.enabledProtocols.last();
+    List comp = new ArrayList(2);
+    comp.add(CompressionMethod.ZLIB);
+    comp.add(CompressionMethod.NULL);
+    ClientHello clientHello =
+      new ClientHello(session.protocol, clientRandom, sessionId,
+                      session.enabledSuites, comp, extensions);
+    Handshake msg = new Handshake(Handshake.Type.CLIENT_HELLO, clientHello);
+    if (DEBUG_HANDSHAKE_LAYER)
+      logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+    msg.write (dout, version);
+//     recordOutput.setHandshakeAvail(msg.write(dout, version));
+    dout.flush();
+//     try
+//       {
+//         Thread.sleep(150);
+//       }
+//     catch (InterruptedException ie)
+//       {
+//       }
+
+    // Receive the server hello.
+    msg = Handshake.read(din);
+    if (DEBUG_HANDSHAKE_LAYER)
+      logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+    if (msg.getType() != Handshake.Type.SERVER_HELLO)
+      {
+        throwUnexpectedMessage();
+      }
+    ServerHello serverHello = (ServerHello) msg.getBody();
+    Random serverRandom = serverHello.getRandom();
+    version = serverHello.getVersion();
+
+    // If we don't directly support the server's protocol version, choose
+    // the highest one we support that is less than the server's version.
+    if (!session.enabledProtocols.contains(version))
+      {
+        ProtocolVersion v1 = null, v2 = null;
+        for (Iterator it = session.enabledProtocols.iterator();
+             it.hasNext(); )
+          {
+            v1 = (ProtocolVersion) it.next();
+            if (v1.compareTo(version) > 0)
+              break;
+            v2 = v1;
+          }
+        version = v1;
+      }
+
+    // The server's version is either unsupported by us (unlikely) or the user
+    // has only enabled incompatible versions.
+    if (version == null)
+      {
+        Alert.Description desc = null;
+        if (serverHello.getVersion() == ProtocolVersion.SSL_3)
+          {
+            desc = Alert.Description.HANDSHAKE_FAILURE;
+          }
+        else
+          {
+            desc = Alert.Description.PROTOCOL_VERSION;
+          }
+        Alert alert = new Alert(Alert.Level.FATAL, desc);
+        sendAlert(alert);
+        session.currentAlert = alert;
+        fatal();
+        throw new AlertException(alert, true);
+      }
+
+    if (serverHello.getExtensions() != null)
+      {
+        for (Iterator it = serverHello.getExtensions().iterator();
+             it.hasNext(); )
+          {
+            Extension e = (Extension) it.next();
+            if (e.getType() == Extension.Type.MAX_FRAGMENT_LENGTH)
+              {
+                int len = Extensions.getMaxFragmentLength(e).intValue();
+                session.params.setFragmentLength(len);
+//                 recordOutput.setFragmentLength(len);
+//                 recordInput.setFragmentLength(len);
+              }
+            else if (e.getType() == Extension.Type.CERT_TYPE)
+              {
+                certType = Extensions.getServerCertType(e);
+              }
+          }
+      }
+
+    CipherSuite suite = serverHello.getCipherSuite().resolve(version);
+    boolean newSession = true;
+    if (sessionId.length > 0 &&
+        Arrays.equals(sessionId, serverHello.getSessionId()))
+      {
+        SecurityParameters params = session.params;
+        SecureRandom random = session.random;
+        session = (Session) continuedSession.clone();
+        session.params = params;
+        session.random = random;
+        recordInput.setSession(session);
+//         recordOutput.setSession(session);
+        suite = session.cipherSuite;
+        newSession = false;
+      }
+    else
+      {
+        sessionContext.removeSession(new Session.ID(sessionId));
+      }
+    if (newSession)
+      {
+        session.peerHost = remoteHost;
+        session.sessionId = new Session.ID(serverHello.getSessionId());
+        session.cipherSuite = suite;
+      }
+    session.params.reset();
+//     session.params.setInMac(null);
+//     session.params.setOutMac(null);
+//     session.params.setInRandom(null);
+//     session.params.setOutRandom(null);
+//     session.params.setInCipher(null);
+//     session.params.setOutCipher(null);
+    session.currentAlert = null;
+    session.valid = true;
+    session.protocol = version;
+
+    // If the server responded with the same session id that we sent, we
+    // assume that the session will be continued, and skip the bulk of the
+    // handshake.
+    if (newSession)
+      {
+        PublicKey serverKey = null, serverKex = null;
+        KeyPair clientKeys = null, clientKex = null;
+        CertificateRequest certReq;
+        boolean sendKeyExchange = false;
+        BigInteger srp_x = null;
+        IKeyAgreementParty clientKA = null;
+        IncomingMessage in; // used for key agreement protocol exchange
+        OutgoingMessage out = null;
+
+        if (suite.getKeyExchange() == "SRP")
+          {
+            String password = askPassword(user);
+            if (DEBUG_KEY_EXCHANGE)
+              {
+                logger.log (Component.SSL_KEY_EXCHANGE,
+                            "SRP: password read is ''{0}''", password);
+              }
+            byte[] userSrpPassword = password.getBytes("UTF-8");
+
+            // instantiate and setup client-side key agreement party
+            clientKA = KeyAgreementFactory.getPartyAInstance(Registry.SRP_TLS_KA);
+            Map clientAttributes = new HashMap();
+            clientAttributes.put(SRP6KeyAgreement.HASH_FUNCTION,
+                                 Registry.SHA160_HASH);
+            clientAttributes.put(SRP6KeyAgreement.USER_IDENTITY, user);
+            clientAttributes.put(SRP6KeyAgreement.USER_PASSWORD, userSrpPassword);
+            try
+              {
+                clientKA.init(clientAttributes);
+                // initiate the exchange
+                out = clientKA.processMessage(null);
+              }
+            catch (KeyAgreementException x)
+              {
+                if (DEBUG_KEY_EXCHANGE)
+                  {
+                    logger.log (Component.SSL_KEY_EXCHANGE, "SRP exception", x);
+                  }
+                throwHandshakeFailure();
+              }
+          }
+
+        if (suite.getSignature() != "anon")
+          {
+            msg = Handshake.read(din, certType);
+            if (DEBUG_HANDSHAKE_LAYER)
+              logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+            if (msg.getType() != Handshake.Type.CERTIFICATE)
+              {
+                throwUnexpectedMessage();
+              }
+            Certificate serverCertificate = (Certificate) msg.getBody();
+            X509Certificate[] peerCerts = serverCertificate.getCertificates();
+            try
+              {
+                session.trustManager.checkServerTrusted(peerCerts,
+                                                        suite.getAuthType());
+                if (suite.getSignature() == "RSA" &&
+                    !(peerCerts[0].getPublicKey() instanceof RSAPublicKey))
+                  throw new InvalidKeyException("improper public key");
+                if (suite.getKeyExchange() == "DH" &&
+                    !(peerCerts[0].getPublicKey() instanceof DHPublicKey))
+                  throw new InvalidKeyException("improper public key");
+                if (suite.getKeyExchange() == "DHE")
+                  {
+                    if (suite.getSignature() == "RSA" &&
+                        !(peerCerts[0].getPublicKey() instanceof RSAPublicKey))
+                      throw new InvalidKeyException("improper public key");
+                    if (suite.getSignature() == "DSS" &&
+                        !(peerCerts[0].getPublicKey() instanceof DSAPublicKey))
+                      throw new InvalidKeyException("improper public key");
+                  }
+                session.peerCerts = peerCerts;
+                session.peerVerified = true;
+              }
+            catch (InvalidKeyException ike)
+              {
+                throwHandshakeFailure();
+              }
+            catch (Exception x)
+              {
+                if (!checkCertificates(peerCerts))
+                  {
+                    peerUnverified(peerCerts);
+                    SSLPeerUnverifiedException e =
+                      new SSLPeerUnverifiedException ("could not verify peer certificate: "+
+                                                      peerCerts[0].getSubjectDN());
+                    e.initCause (x);
+                    throw e;
+                  }
+                session.peerCerts = peerCerts;
+                session.peerVerified = true;
+              }
+            serverKey = peerCerts[0].getPublicKey();
+            serverKex = serverKey;
+          }
+
+        msg = Handshake.read(din, suite, serverKey);
+
+        // Receive the server's key exchange.
+        if (msg.getType() == Handshake.Type.SERVER_KEY_EXCHANGE)
+          {
+            if (DEBUG_HANDSHAKE_LAYER)
+              logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+            ServerKeyExchange skex = (ServerKeyExchange) msg.getBody();
+            serverKex = skex.getPublicKey();
+            if (suite.getSignature() != "anon")
+              {
+                ISignature sig = null;
+                if (suite.getSignature() == "RSA")
+                  {
+                    sig = new SSLRSASignature();
+                  }
+                else if (suite.getSignature() == "DSS")
+                  {
+                    sig = SignatureFactory.getInstance(Registry.DSS_SIG);
+                  }
+                sig.setupVerify(Collections.singletonMap(
+                  ISignature.VERIFIER_KEY, serverKey));
+                byte[] buf = clientRandom.getEncoded();
+                sig.update(buf, 0, buf.length);
+                buf = serverRandom.getEncoded();
+                sig.update(buf, 0, buf.length);
+                if (suite.getKeyExchange() == "RSA")
+                  {
+                    updateSig(sig, ((RSAPublicKey) serverKex).getModulus());
+                    updateSig(sig, ((RSAPublicKey) serverKex).getPublicExponent());
+                  }
+                else if (suite.getKeyExchange() == "DHE")
+                  {
+                    updateSig(sig, ((DHPublicKey) serverKex).getParams().getP());
+                    updateSig(sig, ((DHPublicKey) serverKex).getParams().getG());
+                    updateSig(sig, ((DHPublicKey) serverKex).getY());
+                  }
+                else if (suite.getKeyExchange() == "SRP")
+                  {
+                    updateSig(sig, ((SRPPublicKey) serverKex).getN());
+                    updateSig(sig, ((SRPPublicKey) serverKex).getG());
+                    byte[] srpSalt = skex.getSRPSalt();
+                    sig.update((byte) srpSalt.length);
+                    sig.update(srpSalt, 0, srpSalt.length);
+                    updateSig(sig, ((SRPPublicKey) serverKex).getY());
+                  }
+                if (!sig.verify(skex.getSignature().getSigValue()))
+                  {
+                    throwHandshakeFailure();
+                  }
+              }
+
+            if (suite.getKeyExchange() == "SRP")
+              {
+                // use server's key exchange data to continue
+                // agreement protocol by faking a received incoming
+                // message.  again the following code can be broken
+                // into multiple blocks for more accurate exception
+                // handling
+                try
+                  {
+                    out = new OutgoingMessage();
+                    out.writeMPI(((SRPPublicKey) serverKex).getN());
+                    out.writeMPI(((SRPPublicKey) serverKex).getG());
+                    out.writeMPI(new BigInteger(1, skex.getSRPSalt()));
+                    out.writeMPI(((SRPPublicKey) serverKex).getY());
+
+                    in = new IncomingMessage(out.toByteArray());
+
+                    out = clientKA.processMessage(in);
+                    if (DEBUG_KEY_EXCHANGE)
+                      {
+                        logger.log (Component.SSL_KEY_EXCHANGE, "clientKA isComplete? {0}",
+                                    Boolean.valueOf (clientKA.isComplete()));
+                      }
+                  }
+                catch (KeyAgreementException x)
+                  {
+                    if (DEBUG_KEY_EXCHANGE)
+                      {
+                        logger.log (Component.SSL_KEY_EXCHANGE, "SRP exception", x);
+                      }
+                    throwHandshakeFailure();
+                  }
+              }
+            msg = Handshake.read(din, suite, serverKey);
+          }
+
+        // See if the server wants us to send our certificates.
+        certReq = null;
+        if (msg.getType() == Handshake.Type.CERTIFICATE_REQUEST)
+          {
+            if (suite.getSignature() == "anon")
+              {
+                throwHandshakeFailure();
+              }
+            if (DEBUG_HANDSHAKE_LAYER)
+              logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+            certReq = (CertificateRequest) msg.getBody();
+            msg = Handshake.read(din);
+          }
+
+        // Read ServerHelloDone.
+        if (msg.getType() != Handshake.Type.SERVER_HELLO_DONE)
+          {
+            throwUnexpectedMessage();
+          }
+        if (DEBUG_HANDSHAKE_LAYER)
+          logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+
+        // Send our certificate chain if the server asked for it.
+        if (certReq != null)
+          {
+            String alias = session.keyManager.chooseClientAlias(
+              certReq.getTypeStrings(), certReq.getAuthorities(), null);
+            if (alias == null && version == ProtocolVersion.SSL_3)
+              {
+                Alert alert =
+                  new Alert(Alert.Level.WARNING, Alert.Description.NO_CERTIFICATE);
+                sendAlert(alert);
+              }
+            else
+              {
+                X509Certificate[] chain =
+                  session.keyManager.getCertificateChain(alias);
+                PrivateKey key = session.keyManager.getPrivateKey(alias);
+                if (chain == null)
+                  {
+                    chain = new X509Certificate[0];
+                  }
+                Certificate cert = new Certificate(chain);
+                msg = new Handshake(Handshake.Type.CERTIFICATE, cert);
+                if (DEBUG_HANDSHAKE_LAYER)
+                  logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+                msg.write(dout, version);
+//                 recordOutput.setHandshakeAvail(msg.write(dout, version));;
+                dout.flush();
+                if (chain.length > 0)
+                  {
+                    session.localCerts = chain;
+                    clientKeys = new KeyPair(chain[0].getPublicKey(), key);
+                  }
+              }
+          }
+
+        // Send our key exchange.
+        byte[] preMasterSecret = null;
+        ClientKeyExchange ckex = null;
+        if (suite.getKeyExchange() == "RSA")
+          {
+            ProtocolVersion v =
+              (ProtocolVersion) session.enabledProtocols.last();
+            byte[] b = new byte[46];
+            session.random.nextBytes (b);
+            preMasterSecret = Util.concat(v.getEncoded(), b);
+            EME_PKCS1_V1_5 pkcs1 = EME_PKCS1_V1_5.getInstance((RSAPublicKey) serverKex);
+            BigInteger bi = new BigInteger(1,
+              pkcs1.encode(preMasterSecret, session.random));
+            bi = RSA.encrypt((RSAPublicKey) serverKex, bi);
+            ckex = new ClientKeyExchange(Util.trim(bi));
+          }
+        else if (suite.getKeyExchange().startsWith("DH"))
+          {
+            if (clientKeys == null ||
+                !(clientKeys.getPublic() instanceof DHPublicKey))
+              {
+                GnuDHPrivateKey tmpKey =
+                  new GnuDHPrivateKey(null, ((DHPublicKey) serverKex).getParams().getP(),
+                      ((DHPublicKey) serverKex).getParams().getG(), null);
+                clientKA = KeyAgreementFactory.getPartyBInstance(Registry.DH_KA);
+                Map attr = new HashMap();
+                attr.put(DiffieHellmanKeyAgreement.KA_DIFFIE_HELLMAN_OWNER_PRIVATE_KEY,
+                         tmpKey);
+                attr.put(DiffieHellmanKeyAgreement.SOURCE_OF_RANDOMNESS,
+                         session.random);
+                try
+                  {
+                    clientKA.init(attr);
+                    out = new OutgoingMessage();
+                    out.writeMPI(((DHPublicKey) serverKex).getY());
+                    in = new IncomingMessage(out.toByteArray());
+                    out = clientKA.processMessage(in);
+                    in = new IncomingMessage(out.toByteArray());
+                    ckex = new ClientKeyExchange(in.readMPI());
+                  }
+                catch (KeyAgreementException kae)
+                  {
+                    if (DEBUG_KEY_EXCHANGE)
+                      {
+                        logger.log (Component.SSL_KEY_EXCHANGE, "DH exception", kae);
+                      }
+                    internalError();
+                    RuntimeException re = new RuntimeException (kae.getMessage());
+                    re.initCause (kae);
+                    throw re;
+                  }
+              }
+            else
+              {
+                clientKA = KeyAgreementFactory.getPartyBInstance(Registry.ELGAMAL_KA);
+                Map attr = new HashMap();
+                attr.put(ElGamalKeyAgreement.KA_ELGAMAL_RECIPIENT_PRIVATE_KEY,
+                         clientKeys.getPrivate());
+                try
+                  {
+                    // The key exchange is already complete here; our public
+                    // value was sent with our certificate.
+                    clientKA.init(attr);
+                  }
+                catch (KeyAgreementException kae)
+                  {
+                    if (DEBUG_KEY_EXCHANGE)
+                      logger.log (Component.SSL_KEY_EXCHANGE, "DH exception", kae);
+                    internalError();
+                    RuntimeException re = new RuntimeException (kae.getMessage());
+                    re.initCause (kae);
+                    throw re;
+                  }
+                ckex = new ClientKeyExchange(new byte[0]);
+              }
+          }
+        else if (suite.getKeyExchange() == "SRP")
+          {
+            // at this point, out --the outgoing message-- already contains
+            // what we want. so...
+            BigInteger A = null;
+            try
+              {
+                in = new IncomingMessage(out.toByteArray());
+                A = in.readMPI();
+                if (DEBUG_KEY_EXCHANGE)
+                  {
+                    logger.log (Component.SSL_KEY_EXCHANGE, "client A:{0}", A);
+                  }
+              }
+            catch (KeyAgreementException x)
+              {
+                if (DEBUG_KEY_EXCHANGE)
+                  {
+                    logger.log (Component.SSL_KEY_EXCHANGE, "SRP exception", x);
+                  }
+                throwHandshakeFailure();
+              }
+            ckex = new ClientKeyExchange(A);
+          }
+        msg = new Handshake(Handshake.Type.CLIENT_KEY_EXCHANGE, ckex);
+        if (DEBUG_HANDSHAKE_LAYER)
+          logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+        msg.write (dout, version);
+//         recordOutput.setHandshakeAvail(msg.write(dout, version));;
+
+        // Generate the master secret.
+        if (suite.getKeyExchange().startsWith("DH"))
+          {
+            try
+              {
+                preMasterSecret = clientKA.getSharedSecret();
+              }
+            catch (KeyAgreementException kae)
+              {
+                if (DEBUG_KEY_EXCHANGE)
+                  {
+                    logger.log (Component.SSL_KEY_EXCHANGE, "DH exception", kae);
+                  }
+                internalError();
+                RuntimeException re = new RuntimeException (kae.getMessage());
+                re.initCause (kae);
+                throw re;
+              }
+          }
+        else if (suite.getKeyExchange() == "SRP")
+          {
+            try
+              {
+                preMasterSecret = clientKA.getSharedSecret();
+              }
+            catch (KeyAgreementException x)
+              {
+                if (DEBUG_KEY_EXCHANGE)
+                  {
+                    logger.log (Component.SSL_KEY_EXCHANGE, "SRP exception", x);
+                  }
+                throwHandshakeFailure();
+              }
+            finally
+              {
+                clientKA = null;
+              }
+          }
+        if (DEBUG_KEY_EXCHANGE)
+          {
+            logger.log (Component.SSL_KEY_EXCHANGE, "preMasterSecret:\n{0}",
+                        Util.toHexString (preMasterSecret, ':'));
+            logger.log (Component.SSL_KEY_EXCHANGE, "client.random:\n{0}",
+                        Util.toHexString(clientRandom.getEncoded(), ':'));
+            logger.log (Component.SSL_KEY_EXCHANGE, "server.random:\n{0}",
+                        Util.toHexString(serverRandom.getEncoded(), ':'));
+          }
+        IRandom genSecret = null;
+        if (version == ProtocolVersion.SSL_3)
+          {
+            genSecret = new SSLRandom();
+            HashMap attr = new HashMap();
+            attr.put(SSLRandom.SECRET, preMasterSecret);
+            attr.put(SSLRandom.SEED,
+              Util.concat(clientRandom.getEncoded(), serverRandom.getEncoded()));
+            genSecret.init(attr);
+          }
+        else
+          {
+            genSecret = new TLSRandom();
+            HashMap attr = new HashMap();
+            attr.put(TLSRandom.SECRET, preMasterSecret);
+            attr.put(TLSRandom.SEED,
+              Util.concat(("master secret").getBytes("UTF-8"),
+              Util.concat(clientRandom.getEncoded(), serverRandom.getEncoded())));
+            genSecret.init(attr);
+          }
+        session.masterSecret = new byte[48];
+        try
+          {
+            genSecret.nextBytes(session.masterSecret, 0, 48);
+            for (int i = 0; i < preMasterSecret.length; i++)
+              {
+                preMasterSecret[i] = 0;
+              }
+          }
+        catch (LimitReachedException shouldNotHappen)
+          {
+            internalError();
+            RuntimeException re = new RuntimeException (shouldNotHappen.getMessage());
+            re.initCause (shouldNotHappen);
+            throw re;
+          }
+
+        if (DEBUG_KEY_EXCHANGE)
+          {
+            logger.log (Component.SSL_KEY_EXCHANGE, "masterSecret: {0}",
+                        Util.toHexString(session.masterSecret, ':'));
+          }
+
+        // Send our certificate verify message.
+        if (certReq != null && clientKeys != null)
+          {
+            IMessageDigest vMD5 = (IMessageDigest) md5.clone();
+            IMessageDigest vSHA = (IMessageDigest) sha.clone();
+            PrivateKey key = clientKeys.getPrivate();
+            Object sig = null;
+            String sigAlg = null;
+            try
+              {
+                if (key instanceof DSAPrivateKey)
+                  {
+                    sig = DSSSignature.sign((DSAPrivateKey) key, vSHA.digest(),
+                                            session.random);
+                    sigAlg = "DSS";
+                  }
+                else if (key instanceof RSAPrivateKey)
+                  {
+                    SSLRSASignature rsa = new SSLRSASignature(vMD5, vSHA);
+                    rsa.setupSign(Collections.singletonMap(ISignature.SIGNER_KEY, key));
+                    sig = rsa.sign();
+                    sigAlg = "RSA";
+                  }
+                else
+                  {
+                    throw new InvalidKeyException("no appropriate key");
+                  }
+              }
+            catch (Exception x)
+              {
+                throwHandshakeFailure();
+              }
+            CertificateVerify verify = new CertificateVerify(sig, sigAlg);
+            msg = new Handshake(Handshake.Type.CERTIFICATE_VERIFY, verify);
+            if (DEBUG_HANDSHAKE_LAYER)
+              logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+            msg.write(dout, version);
+//             recordOutput.setHandshakeAvail(msg.write(dout, version));;
+          }
+        dout.flush();
+      }
+
+    byte[][] keys = null;
+    try
+      {
+        keys = generateKeys(serverRandom.getEncoded(),
+                            clientRandom.getEncoded(), version);
+      }
+    catch (Exception x)
+      {
+        internalError();
+        RuntimeException re = new RuntimeException (x.getMessage());
+        re.initCause (x);
+        throw re;
+      }
+
+    session.params.setVersion (version);
+
+    // Initialize the algorithms with the derived keys.
+    Object readMac = null, writeMac = null;
+    Object readCipher = null, writeCipher = null;
+    try
+      {
+        if (session.params instanceof GNUSecurityParameters)
+          {
+            HashMap attr = new HashMap();
+            writeMac = CipherSuite.getMac(suite.getMac());
+            readMac  = CipherSuite.getMac(suite.getMac());
+            attr.put(IMac.MAC_KEY_MATERIAL, keys[0]);
+            ((IMac) writeMac).init(attr);
+            attr.put(IMac.MAC_KEY_MATERIAL, keys[1]);
+            ((IMac) readMac).init(attr);
+            if (suite.getCipher() == "RC4")
+              {
+                writeCipher = new ARCFour();
+                readCipher = new ARCFour();
+                attr.clear();
+                attr.put(ARCFour.ARCFOUR_KEY_MATERIAL, keys[2]);
+                ((ARCFour) writeCipher).init(attr);
+                attr.put(ARCFour.ARCFOUR_KEY_MATERIAL, keys[3]);
+                ((ARCFour) readCipher).init(attr);
+              }
+            else if (!suite.isStreamCipher())
+              {
+                writeCipher = CipherSuite.getCipher(suite.getCipher());
+                readCipher = CipherSuite.getCipher(suite.getCipher());
+                attr.clear();
+                attr.put(IMode.KEY_MATERIAL, keys[2]);
+                attr.put(IMode.IV, keys[4]);
+                attr.put(IMode.STATE, new Integer(IMode.ENCRYPTION));
+                ((IMode) writeCipher).init(attr);
+                attr.put(IMode.KEY_MATERIAL, keys[3]);
+                attr.put(IMode.IV, keys[5]);
+                attr.put(IMode.STATE, new Integer(IMode.DECRYPTION));
+                ((IMode) readCipher).init(attr);
+              }
+          }
+        else // JCESecurityParameters
+          {
+            writeMac = CipherSuite.getJCEMac (suite.getMac());
+            readMac = CipherSuite.getJCEMac (suite.getMac());
+            writeCipher = CipherSuite.getJCECipher (suite.getCipher());
+            readCipher = CipherSuite.getJCECipher (suite.getCipher());
+            ((Mac) writeMac).init (new SecretKeySpec (keys[0], suite.getMac()));
+            ((Mac) readMac).init (new SecretKeySpec (keys[1], suite.getMac()));
+            if (!suite.isStreamCipher())
+              {
+                ((Cipher) writeCipher).init (Cipher.ENCRYPT_MODE,
+                                             new SecretKeySpec (keys[2], suite.getCipher()),
+                                             new IvParameterSpec (keys[4]));
+                ((Cipher) readCipher).init (Cipher.DECRYPT_MODE,
+                                            new SecretKeySpec (keys[3], suite.getCipher()),
+                                            new IvParameterSpec (keys[5]));
+              }
+            else
+              {
+                ((Cipher) writeCipher).init (Cipher.ENCRYPT_MODE,
+                                             new SecretKeySpec (keys[2], suite.getCipher()));
+                ((Cipher) readCipher).init (Cipher.DECRYPT_MODE,
+                                            new SecretKeySpec (keys[3], suite.getCipher()));
+              }
+          }
+      }
+    // These should technically never happen, if our key generation is not
+    // broken.
+    catch (InvalidKeyException ike)
+      {
+        internalError();
+        RuntimeException re = new RuntimeException (ike.getMessage());
+        re.initCause(ike);
+        throw re;
+      }
+    catch (InvalidAlgorithmParameterException iape)
+      {
+        internalError();
+        RuntimeException re = new RuntimeException (iape.getMessage());
+        re.initCause (iape);
+        throw re;
+      }
+    // These indicate a configuration error with the JCA.
+    catch (NoSuchAlgorithmException nsae)
+      {
+        session.enabledSuites.remove (suite);
+        internalError();
+        SSLException x = new SSLException ("suite " + suite + " not available in this configuration");
+        x.initCause (nsae);
+        throw x;
+      }
+    catch (NoSuchPaddingException nspe)
+      {
+        session.enabledSuites.remove (suite);
+        internalError();
+        SSLException x = new SSLException ("suite " + suite + " not available in this configuration");
+        x.initCause (nspe);
+        throw x;
+      }
+
+    Finished finis = null;
+
+    if (newSession)
+      {
+        changeCipherSpec();
+        session.params.setDeflating(serverHello.getCompressionMethod() == CompressionMethod.ZLIB);
+        session.params.setOutMac(writeMac);
+        session.params.setOutCipher(writeCipher);
+        finis = generateFinished(version, (IMessageDigest) md5.clone(),
+                                 (IMessageDigest) sha.clone(), true);
+        msg = new Handshake(Handshake.Type.FINISHED, finis);
+        if (DEBUG_HANDSHAKE_LAYER)
+          logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+        msg.write(dout, version);
+        dout.flush();
+      }
+
+    if (session.currentAlert != null &&
+        session.currentAlert.getLevel() == Alert.Level.FATAL)
+      {
+        fatal();
+        throw new AlertException(session.currentAlert, false);
+      }
+
+    synchronized (session.params)
+      {
+        readChangeCipherSpec ();
+        session.params.setInflating(serverHello.getCompressionMethod() == CompressionMethod.ZLIB);
+        session.params.setInMac(readMac);
+        session.params.setInCipher(readCipher);
+        session.params.notifyAll();
+      }
+
+    Finished verify = generateFinished(version, (IMessageDigest) md5.clone(),
+                                       (IMessageDigest) sha.clone(), false);
+
+    msg = Handshake.read(din, suite, null);
+    if (DEBUG_HANDSHAKE_LAYER)
+      logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+    if (msg.getType() != Handshake.Type.FINISHED)
+      {
+        throwUnexpectedMessage();
+      }
+    finis = (Finished) msg.getBody();
+    if (version == ProtocolVersion.SSL_3)
+      {
+        if (!Arrays.equals(finis.getMD5Hash(), verify.getMD5Hash()) ||
+            !Arrays.equals(finis.getSHAHash(), verify.getSHAHash()))
+          {
+            throwHandshakeFailure();
+          }
+      }
+    else
+      {
+        if (!Arrays.equals(finis.getVerifyData(), verify.getVerifyData()))
+          {
+            throwHandshakeFailure();
+          }
+      }
+
+    if (!newSession)
+      {
+        changeCipherSpec();
+        session.params.setDeflating(serverHello.getCompressionMethod() == CompressionMethod.ZLIB);
+        session.params.setOutMac(writeMac);
+        session.params.setOutCipher(writeCipher);
+        finis = generateFinished(version, md5, sha, true);
+        msg = new Handshake(Handshake.Type.FINISHED, finis);
+        if (DEBUG_HANDSHAKE_LAYER)
+          logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+        msg.write(dout, version);
+        dout.flush();
+      }
+
+    handshakeCompleted();
+  }
+
+  /**
+   * Perform the server handshake.
+   */
+  private void doServerHandshake() throws IOException
+  {
+    if (DEBUG_HANDSHAKE_LAYER)
+      {
+        logger.log (Component.SSL_HANDSHAKE, "doing server handshake in {0}",
+                    Thread.currentThread());
+      }
+
+    if (remoteHost == null)
+      {
+        remoteHost = getInetAddress().getHostName();
+      }
+    if (remoteHost == null)
+      {
+        remoteHost = getInetAddress().getHostAddress();
+      }
+
+    IMessageDigest md5 = HashFactory.getInstance(Registry.MD5_HASH);
+    IMessageDigest sha = HashFactory.getInstance(Registry.SHA160_HASH);
+    DigestInputStream din = new DigestInputStream(handshakeIn, md5, sha);
+    DigestOutputStream dout = new DigestOutputStream(handshakeOut, md5, sha);
+
+    // Read the client hello.
+    Handshake msg = Handshake.read(din);
+    if (DEBUG_HANDSHAKE_LAYER)
+      logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+    if (msg.getType() != Handshake.Type.CLIENT_HELLO)
+      {
+        throwUnexpectedMessage();
+      }
+    ClientHello clientHello = (ClientHello) msg.getBody();
+    Random clientRandom = clientHello.getRandom();
+    ProtocolVersion version = clientHello.getVersion();
+    ProtocolVersion server =
+      (ProtocolVersion) session.enabledProtocols.last();
+    CompressionMethod comp;
+    if (clientHello.getCompressionMethods().contains(CompressionMethod.ZLIB))
+      comp = CompressionMethod.ZLIB;
+    else
+      comp = CompressionMethod.NULL;
+    if (!session.enabledProtocols.contains(version)
+        && version.compareTo(server) < 0)
+      {
+        Alert alert = new Alert(Alert.Level.FATAL,
+                                Alert.Description.PROTOCOL_VERSION);
+        sendAlert(alert);
+        session.currentAlert = alert;
+        throw new AlertException(alert, true);
+      }
+
+    // Look through the extensions sent by the client (if any), and react to
+    // them appropriately.
+    List extensions = null;
+    String remoteUser = null;
+    if (clientHello.getExtensions() != null)
+      {
+        for (Iterator it = clientHello.getExtensions().iterator(); it.hasNext();)
+          {
+            Extension ex = (Extension) it.next();
+            if (ex.getType() == Extension.Type.SERVER_NAME)
+              {
+                if (extensions == null)
+                  {
+                    extensions = new LinkedList();
+                  }
+                extensions.add(ex);
+              }
+            else if (ex.getType() == Extension.Type.MAX_FRAGMENT_LENGTH)
+              {
+                int maxLen = Extensions.getMaxFragmentLength(ex).intValue();
+//                 recordInput.setFragmentLength(maxLen);
+//                 recordOutput.setFragmentLength(maxLen);
+                session.params.setFragmentLength(maxLen);
+                if (extensions == null)
+                  {
+                    extensions = new LinkedList();
+                  }
+                extensions.add(ex);
+              }
+            else if (ex.getType() == Extension.Type.SRP)
+              {
+                if (extensions == null)
+                  {
+                    extensions = new LinkedList();
+                  }
+                byte[] b = ex.getValue();
+                remoteUser = new String(ex.getValue(), 1, b[0] & 0xFF, "UTF-8");
+                session.putValue("srp-username", remoteUser);
+              }
+          }
+      }
+
+    CipherSuite suite = selectSuite(clientHello.getCipherSuites(), version);
+    if (suite == null)
+      {
+        return;
+      }
+
+    // If the selected suite turns out to be SRP, set up the key exchange
+    // objects.
+    IKeyAgreementParty serverKA = null;
+    IncomingMessage in;
+    OutgoingMessage out = null;
+    if (suite.getKeyExchange() == "SRP")
+      {
+        // FIXME
+        // Uhm, I don't think this can happen, because if remoteUser is null
+        // we cannot choose an SRP ciphersuite...
+        if (remoteUser == null)
+          {
+            Alert alert = new Alert(Alert.Level.FATAL,
+              Alert.Description.MISSING_SRP_USERNAME);
+            sendAlert(alert);
+            throw new AlertException(alert, true);
+          }
+
+        SRPAuthInfoProvider srpDB = new SRPAuthInfoProvider();
+        Map dbAttributes = new HashMap();
+        dbAttributes.put(SRPRegistry.PASSWORD_DB,
+          session.srpTrustManager.getPasswordFile());
+        srpDB.activate(dbAttributes);
+
+        // FIXME
+        // We can also fake that the user exists, and generate a dummy (and
+        // invalid) master secret, and let the handshake fail at the Finished
+        // message. This is better than letting the connecting side know that
+        // the username they sent isn't valid.
+        //
+        // But how to implement this?
+        if (!srpDB.contains(remoteUser))
+          {
+            Alert alert = new Alert(Alert.Level.FATAL,
+              Alert.Description.UNKNOWN_SRP_USERNAME);
+            sendAlert(alert);
+            throw new AlertException(alert, true);
+          }
+
+        serverKA = KeyAgreementFactory.getPartyBInstance(Registry.SRP_TLS_KA);
+        Map serverAttributes = new HashMap();
+        serverAttributes.put(SRP6KeyAgreement.HASH_FUNCTION,
+                             Registry.SHA160_HASH);
+        serverAttributes.put(SRP6KeyAgreement.HOST_PASSWORD_DB, srpDB);
+
+        try
+          {
+            serverKA.init(serverAttributes);
+            out = new OutgoingMessage();
+            out.writeString(remoteUser);
+            in = new IncomingMessage(out.toByteArray());
+            out = serverKA.processMessage(in);
+          }
+        catch (KeyAgreementException x)
+          {
+            throwHandshakeFailure();
+          }
+      }
+
+    // Check if the session specified by the client's ID corresponds
+    // to a saved session, and if so, continue it.
+    boolean newSession = true;
+    if (DEBUG_HANDSHAKE_LAYER)
+      {
+        logger.log (Component.SSL_HANDSHAKE, "saved sessions: {0}", sessionContext);
+      }
+    if (sessionContext.containsSessionID(
+        new Session.ID(clientHello.getSessionId())))
+      {
+        Session old = session;
+        session = (Session) sessionContext.getSession(clientHello.getSessionId());
+        if (!clientHello.getCipherSuites().contains(session.cipherSuite))
+          {
+            throwHandshakeFailure();
+          }
+        if (session.getPeerHost().equals(remoteHost) &&
+            old.enabledProtocols.contains(session.protocol))
+          {
+            session = (Session) session.clone();
+            suite = session.cipherSuite;
+            newSession = false;
+            recordInput.setSession(session);
+            session.currentAlert = null;
+            session.params = old.params;
+            session.random = old.random;
+          }
+        else
+          {
+            if (DEBUG_HANDSHAKE_LAYER)
+              {
+                logger.log (Component.SSL_HANDSHAKE, "rejected section; hosts equal? {0}, same suites? {1}",
+                            new Object[] { Boolean.valueOf (session.getPeerHost().equals(remoteHost)),
+                                           Boolean.valueOf (old.enabledProtocols.contains(session.protocol)) });
+              }
+            session = old;
+            session.peerHost = remoteHost;
+            newSession = true;
+          }
+      }
+    else if (DEBUG_HANDSHAKE_LAYER)
+      {
+        logger.log (Component.SSL_HANDSHAKE, "rejected session; have session id? {0}, saved sessions: {1}",
+                    new Object[] { Boolean.valueOf (sessionContext.containsSessionID(new Session.ID(clientHello.getSessionId()))),
+                                   sessionContext });
+      }
+    if (newSession)
+      {
+        byte[] buf = new byte[32];
+        Session.ID sid = null;
+        do
+          {
+            session.random.nextBytes(buf);
+            sid = new Session.ID(buf);
+          }
+        while (sessionContext.containsSessionID(sid));
+        session.sessionId = sid;
+      }
+    session.valid = true;
+    session.peerHost = remoteHost;
+    session.cipherSuite = suite;
+    session.protocol = version;
+    session.params.setVersion (version);
+
+    // Send the server hello.
+    Random serverRandom = new Random(Util.unixTime(),
+                                     session.random.generateSeed(28));
+    ServerHello serverHello = new ServerHello(version, serverRandom,
+                                              session.getId(), suite,
+                                              comp, extensions);
+    msg = new Handshake(Handshake.Type.SERVER_HELLO, serverHello);
+    if (DEBUG_HANDSHAKE_LAYER)
+      logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+    msg.write(dout, version);
+//     recordOutput.setHandshakeAvail(msg.write(dout, version));
+    dout.flush();
+
+    if (newSession)
+      {
+        X509Certificate[] certs = null;
+        PrivateKey serverKey = null;
+        if (suite.getSignature() != "anon")
+          {
+            // Send our CA-issued certificate to the client.
+            String alias = session.keyManager.chooseServerAlias(suite.getAuthType(),
+                                                                null, null);
+            certs = session.keyManager.getCertificateChain(alias);
+            serverKey = session.keyManager.getPrivateKey(alias);
+            if (certs == null || serverKey == null)
+              {
+                throwHandshakeFailure();
+              }
+            session.localCerts = certs;
+            Certificate serverCert = new Certificate(certs);
+            msg = new Handshake(Handshake.Type.CERTIFICATE, serverCert);
+            if (DEBUG_HANDSHAKE_LAYER)
+              logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+            msg.write(dout, version);
+//             recordOutput.setHandshakeAvail(msg.write(dout, version));;
+            dout.flush();
+          }
+
+        // If the certificate we sent does not contain enough information to
+        // do the key exchange (in the case of ephemeral Diffie-Hellman,
+        // export RSA, and SRP) we send a signed public key to be used for the
+        // key exchange.
+        KeyPair signPair = null;
+        if (certs != null)
+          {
+            signPair = new KeyPair(certs[0].getPublicKey(), serverKey);
+          }
+        KeyPair kexPair = signPair;
+        ServerKeyExchange skex = null;
+
+        // Set up our key exchange, and/or prepare our ServerKeyExchange
+        // message.
+        if ((suite.getKeyExchange() == "RSA" && suite.isExportable() &&
+             ((RSAPrivateKey) serverKey).getModulus().bitLength() > 512))
+          {
+            kexPair = KeyPool.generateRSAKeyPair();
+            RSAPublicKey pubkey = (RSAPublicKey) kexPair.getPublic();
+            Signature s = null;
+            if (suite.getSignature() != "anon")
+              {
+                SSLRSASignature sig = new SSLRSASignature();
+                sig.setupSign(Collections.singletonMap(ISignature.SIGNER_KEY,
+                                                       signPair.getPrivate()));
+                byte[] buf = clientRandom.getEncoded();
+                sig.update(buf, 0, buf.length);
+                buf = serverRandom.getEncoded();
+                sig.update(buf, 0, buf.length);
+                updateSig(sig, pubkey.getModulus());
+                updateSig(sig, pubkey.getPublicExponent());
+                s = new Signature(sig.sign(), "RSA");
+              }
+            skex = new ServerKeyExchange(pubkey, s);
+          }
+        else if (suite.getKeyExchange() == "DH")
+          {
+            serverKA = KeyAgreementFactory.getPartyBInstance(Registry.ELGAMAL_KA);
+            Map attr = new HashMap();
+            attr.put(ElGamalKeyAgreement.KA_ELGAMAL_RECIPIENT_PRIVATE_KEY,
+                     serverKey);
+            try
+              {
+                serverKA.init(attr);
+              }
+            catch (KeyAgreementException kae)
+              {
+                if (DEBUG_KEY_EXCHANGE)
+                  logger.log (Component.SSL_KEY_EXCHANGE, "DH exception", kae);
+                internalError();
+                RuntimeException re = new RuntimeException (kae.getMessage());
+                re.initCause (kae);
+                throw re;
+              }
+            // We don't send a ServerKeyExchange for this suite.
+          }
+        else if (suite.getKeyExchange() == "DHE")
+          {
+            serverKA = KeyAgreementFactory.getPartyAInstance(Registry.DH_KA);
+            Map attr = new HashMap();
+            GnuDHPrivateKey servParams = DiffieHellman.getParams();
+            attr.put(DiffieHellmanKeyAgreement.KA_DIFFIE_HELLMAN_OWNER_PRIVATE_KEY,
+                     servParams);
+            attr.put(DiffieHellmanKeyAgreement.SOURCE_OF_RANDOMNESS,
+                     session.random);
+            BigInteger serv_y = null;
+            try
+              {
+                serverKA.init(attr);
+                out = serverKA.processMessage(null);
+                in = new IncomingMessage(out.toByteArray());
+                serv_y = in.readMPI();
+              }
+            catch (KeyAgreementException kae)
+              {
+                if (DEBUG_KEY_EXCHANGE)
+                  {
+                    logger.log (Component.SSL_KEY_EXCHANGE, "DHE exception", kae);
+                  }
+                internalError();
+                RuntimeException re = new RuntimeException (kae.getMessage());
+                re.initCause (kae);
+                throw re;
+              }
+            GnuDHPublicKey pubkey =
+              new GnuDHPublicKey(null, servParams.getParams().getP(),
+                                 servParams.getParams().getG(), serv_y);
+            Signature s = null;
+            if (suite.getSignature() != "anon")
+              {
+                ISignature sig = null;
+                if (suite.getSignature() == "RSA")
+                  {
+                    sig = new SSLRSASignature();
+                  }
+                else
+                  {
+                    sig = SignatureFactory.getInstance(Registry.DSS_SIG);
+                  }
+                sig.setupSign(Collections.singletonMap(ISignature.SIGNER_KEY,
+                                                       signPair.getPrivate()));
+                byte[] buf = clientRandom.getEncoded();
+                sig.update(buf, 0, buf.length);
+                buf = serverRandom.getEncoded();
+                sig.update(buf, 0, buf.length);
+                updateSig(sig, pubkey.getParams().getP());
+                updateSig(sig, pubkey.getParams().getG());
+                updateSig(sig, pubkey.getY());
+                s = new Signature(sig.sign(), suite.getSignature());
+              }
+            skex = new ServerKeyExchange(pubkey, s);
+          }
+        else if (suite.getKeyExchange() == "SRP")
+          {
+            BigInteger N = null;
+            BigInteger g = null;
+            BigInteger salt = null;
+            BigInteger B = null;
+            try
+              {
+                in = new IncomingMessage(out.toByteArray());
+                N = in.readMPI();
+                g = in.readMPI();
+                salt = in.readMPI();
+                B = in.readMPI();
+              }
+            catch (KeyAgreementException x)
+              {
+                if (DEBUG_KEY_EXCHANGE)
+                  {
+                    logger.log (Component.SSL_KEY_EXCHANGE, "SRP exception", x);
+                  }
+                throwHandshakeFailure();
+              }
+            Signature s = null;
+            final byte[] srpSalt = Util.trim(salt);
+            if (suite.getSignature() != "anon")
+              {
+                ISignature sig = null;
+                if (suite.getSignature() == "RSA")
+                  {
+                    sig = new SSLRSASignature();
+                  }
+                else
+                  {
+                    sig = SignatureFactory.getInstance(Registry.DSS_SIG);
+                  }
+                sig.setupSign(Collections.singletonMap(ISignature.SIGNER_KEY,
+                                                       signPair.getPrivate()));
+                byte[] buf = clientRandom.getEncoded();
+                sig.update(buf, 0, buf.length);
+                buf = serverRandom.getEncoded();
+                sig.update(buf, 0, buf.length);
+                updateSig(sig, N);
+                updateSig(sig, g);
+                sig.update((byte) srpSalt.length);
+                sig.update(srpSalt, 0, srpSalt.length);
+                updateSig(sig, B);
+                s = new Signature(sig.sign(), suite.getSignature());
+              }
+            final SRPPublicKey pubkey = new SRPPublicKey(N, g, B);
+            skex = new ServerKeyExchange(pubkey, s, srpSalt);
+          }
+        if (skex != null)
+          {
+            msg = new Handshake(Handshake.Type.SERVER_KEY_EXCHANGE, skex);
+            if (DEBUG_HANDSHAKE_LAYER)
+              logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+            msg.write(dout, version);
+//             recordOutput.setHandshakeAvail(msg.write(dout, version));;
+            dout.flush();
+          }
+
+        // If we are configured to want or need client authentication, then
+        // ask for it.
+        if (wantClientAuth || needClientAuth)
+          {
+            Principal[] auths = null;
+            CertificateRequest.ClientType[] types =
+              new CertificateRequest.ClientType[] {
+                CertificateRequest.ClientType.RSA_SIGN,
+                CertificateRequest.ClientType.DSS_SIGN,
+                CertificateRequest.ClientType.RSA_FIXED_DH,
+                CertificateRequest.ClientType.DSS_FIXED_DH
+              };
+            try
+              {
+                auths = (Principal[])
+                  Util.transform(session.trustManager.getAcceptedIssuers(),
+                    Principal.class, "getSubjectDN", null);
+              }
+            catch (Exception x)
+              {
+                internalError();
+                RuntimeException re = new RuntimeException (x.getMessage());
+                re.initCause (x);
+                throw re;
+              }
+            CertificateRequest req = new CertificateRequest(types, auths);
+            msg = new Handshake(Handshake.Type.CERTIFICATE_REQUEST, req);
+            msg.write(dout, version);
+            dout.flush();
+          }
+
+        // Send our server hello done.
+        msg = new Handshake(Handshake.Type.SERVER_HELLO_DONE, null);
+        if (DEBUG_HANDSHAKE_LAYER)
+          logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+        msg.write(dout, version);
+        dout.flush();
+
+        if (suite.getKeyExchange() == "RSA")
+          {
+            msg = Handshake.read(din, suite, kexPair.getPublic());
+          }
+        else
+          {
+            msg = Handshake.read(din, suite, null);
+          }
+        boolean clientCertOk = false;
+        boolean clientCanSign = false;
+        X509Certificate[] clientChain = null;
+        PublicKey clientKey = null;
+
+        // Read the client's certificate, if sent.
+        if (msg.getType() == Handshake.Type.CERTIFICATE)
+          {
+            if (DEBUG_HANDSHAKE_LAYER)
+              logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+            Certificate cliCert = (Certificate) msg.getBody();
+            clientChain = cliCert.getCertificates();
+            try
+              {
+                session.trustManager.checkClientTrusted(clientChain,
+                                                        suite.getAuthType());
+                session.peerCerts = clientChain;
+                session.peerVerified = true;
+                clientKey = clientChain[0].getPublicKey();
+              }
+            catch (Exception x)
+              {
+              }
+            clientCanSign = ((clientKey instanceof DSAPublicKey) ||
+                             (clientKey instanceof RSAPublicKey));
+            if (suite.getKeyExchange().startsWith("DH"))
+              {
+                msg = Handshake.read(din, suite, clientKey);
+              }
+            else
+              {
+                msg = Handshake.read(din, suite, kexPair.getPublic());
+              }
+          }
+
+        // If we require client authentication, and the client sent an
+        // unverifiable certificate or no certificate at all, drop the
+        // connection.
+        if (!session.peerVerified && needClientAuth)
+          {
+            throwHandshakeFailure();
+          }
+
+        // Read the client key exchange.
+        if (msg.getType() != Handshake.Type.CLIENT_KEY_EXCHANGE)
+          {
+            throwUnexpectedMessage();
+          }
+        if (DEBUG_HANDSHAKE_LAYER)
+          logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+        ClientKeyExchange ckex = (ClientKeyExchange) msg.getBody();
+        byte[] preMasterSecret = null;
+        if (suite.getKeyExchange() == "RSA")
+          {
+            byte[] enc = (byte[]) ckex.getExchangeObject();
+            BigInteger bi = new BigInteger(1, enc);
+            try
+              {
+                bi = RSA.decrypt(kexPair.getPrivate(), bi);
+                EME_PKCS1_V1_5 pkcs1 = EME_PKCS1_V1_5.getInstance(
+                  (RSAPrivateKey) kexPair.getPrivate());
+                preMasterSecret = pkcs1.decode(Util.concat(new byte[1], bi.toByteArray()));
+                //rsa.init(kexPair);
+                //preMasterSecret = rsa.decrypt(enc);
+              }
+            catch (Exception x)
+              {
+                if (DEBUG_KEY_EXCHANGE)
+                  {
+                    logger.log (Component.SSL_KEY_EXCHANGE, "RSA exception", x);
+                  }
+                // Generate a fake pre-master secret if the RSA decryption
+                // fails.
+                byte[] b = new byte[46];
+                session.random.nextBytes (b);
+                preMasterSecret = Util.concat(version.getEncoded(), b);
+              }
+          }
+        else if (suite.getKeyExchange().startsWith("DH"))
+          {
+            try
+              {
+                out = new OutgoingMessage();
+                if (clientKey == null)
+                  out.writeMPI((BigInteger) ckex.getExchangeObject());
+                else
+                  out.writeMPI(((DHPublicKey) clientKey).getY());
+                in = new IncomingMessage(out.toByteArray());
+                serverKA.processMessage(in);
+                preMasterSecret = serverKA.getSharedSecret();
+              }
+            catch (KeyAgreementException kae)
+              {
+                if (DEBUG_KEY_EXCHANGE)
+                  {
+                    logger.log (Component.SSL_KEY_EXCHANGE, "DH exception", kae);
+                  }
+                internalError();
+                RuntimeException re = new RuntimeException (kae.getMessage());
+                re.initCause (kae);
+                throw re;
+              }
+          }
+        else if (suite.getKeyExchange() == "SRP")
+          {
+            BigInteger A = (BigInteger) ckex.getExchangeObject();
+            if (DEBUG_KEY_EXCHANGE)
+              {
+                logger.log (Component.SSL_KEY_EXCHANGE, "SRP: client A: {0}", A);
+              }
+            try
+              {
+                out = new OutgoingMessage();
+                out.writeMPI(A);
+                in = new IncomingMessage(out.toByteArray());
+                out = serverKA.processMessage(in);
+                preMasterSecret = serverKA.getSharedSecret();
+              }
+            catch (KeyAgreementException x)
+              {
+                if (DEBUG_KEY_EXCHANGE)
+                  {
+                    logger.log (Component.SSL_KEY_EXCHANGE, "SRP exception", x);
+                  }
+                throwHandshakeFailure();
+              }
+            finally
+              {
+                serverKA = null;
+              }
+          }
+
+        if (DEBUG_KEY_EXCHANGE)
+          {
+            logger.log (Component.SSL_KEY_EXCHANGE, "preMasterSecret:\n{0}",
+                        Util.toHexString(preMasterSecret, ':'));
+            logger.log (Component.SSL_KEY_EXCHANGE, "client.random:\n{0}",
+                        Util.toHexString(clientRandom.getEncoded(), ':'));
+            logger.log (Component.SSL_KEY_EXCHANGE, "server.random:\n{0}",
+                        Util.toHexString(serverRandom.getEncoded(), ':'));
+          }
+
+        // Generate the master secret.
+        IRandom genSecret = null;
+        if (version == ProtocolVersion.SSL_3)
+          {
+            genSecret = new SSLRandom();
+            HashMap attr = new HashMap();
+            attr.put(SSLRandom.SECRET, preMasterSecret);
+            attr.put(SSLRandom.SEED, Util.concat(clientRandom.getEncoded(),
+                                                 serverRandom.getEncoded()));
+            genSecret.init(attr);
+          }
+        else
+          {
+            genSecret = new TLSRandom();
+            HashMap attr = new HashMap();
+            attr.put(TLSRandom.SECRET, preMasterSecret);
+            attr.put(TLSRandom.SEED,
+                     Util.concat(("master secret").getBytes("UTF-8"),
+                                 Util.concat(clientRandom.getEncoded(),
+                                             serverRandom.getEncoded())));
+            genSecret.init(attr);
+          }
+        session.masterSecret = new byte[48];
+        try
+          {
+            genSecret.nextBytes(session.masterSecret, 0, 48);
+            for (int i = 0; i < preMasterSecret.length; i++)
+              {
+                preMasterSecret[i] = 0;
+              }
+          }
+        catch (LimitReachedException shouldNotHappen)
+          {
+            internalError();
+            RuntimeException re = new RuntimeException();
+            re.initCause (shouldNotHappen);
+            throw re;
+          }
+
+        if (DEBUG_KEY_EXCHANGE)
+          {
+            logger.log (Component.SSL_KEY_EXCHANGE, "masterSecret: {0}",
+                        Util.toHexString(session.masterSecret, ':'));
+          }
+
+        // Read the client's certificate verify message, if needed.
+        if (clientCanSign && (wantClientAuth || needClientAuth))
+          {
+            msg = Handshake.read(din);
+            if (msg.getType() != Handshake.Type.CERTIFICATE_VERIFY)
+              {
+                throwUnexpectedMessage();
+              }
+            CertificateVerify verify = (CertificateVerify) msg.getBody();
+            if (clientChain != null && clientChain.length > 0)
+              {
+                IMessageDigest cvMD5 = (IMessageDigest) md5.clone();
+                IMessageDigest cvSHA = (IMessageDigest) sha.clone();
+                clientKey = clientChain[0].getPublicKey();
+                if (clientKey instanceof RSAPublicKey)
+                  {
+                    SSLRSASignature sig = new SSLRSASignature(cvMD5, cvSHA);
+                    sig.setupVerify(Collections.singletonMap(ISignature.VERIFIER_KEY, clientKey));
+                    if (!sig.verify(verify.getSigValue()))
+                      {
+                        handshakeFailure();
+                        throw new SSLHandshakeException("client certificate verify failed");
+                      }
+                  }
+                else if (clientKey instanceof DSAPublicKey)
+                  {
+                    try
+                      {
+                        if (!DSSSignature.verify((DSAPublicKey) clientKey, cvSHA.digest(),
+                                                 (BigInteger[]) verify.getSigValue()))
+                          {
+                            throw new Exception("client's certificate could not be verified");
+                          }
+                      }
+                    catch (Exception x)
+                      {
+                        handshakeFailure();
+                        SSLHandshakeException e = new SSLHandshakeException (x.getMessage());
+                        e.initCause (x);
+                        throw e;
+                      }
+                  }
+              }
+          }
+      }
+
+    // Generate the session keys.
+    byte[][] keys = null;
+    try
+      {
+        keys = generateKeys(serverRandom.getEncoded(),
+                            clientRandom.getEncoded(), version);
+      }
+    catch (Exception x)
+      {
+        internalError();
+        RuntimeException re = new RuntimeException (x.getMessage());
+        re.initCause (x);
+        throw re;
+      }
+
+    // Initialize the algorithms with the derived keys.
+    Object readMac = null, writeMac = null;
+    Object readCipher = null, writeCipher = null;
+    try
+      {
+        if (session.params instanceof GNUSecurityParameters)
+          {
+            HashMap attr = new HashMap();
+            writeMac = CipherSuite.getMac(suite.getMac());
+            readMac  = CipherSuite.getMac(suite.getMac());
+            attr.put(IMac.MAC_KEY_MATERIAL, keys[1]);
+            ((IMac) writeMac).init(attr);
+            attr.put(IMac.MAC_KEY_MATERIAL, keys[0]);
+            ((IMac) readMac).init(attr);
+            if (suite.getCipher() == "RC4")
+              {
+                writeCipher = new ARCFour();
+                readCipher = new ARCFour();
+                attr.clear();
+                attr.put(ARCFour.ARCFOUR_KEY_MATERIAL, keys[3]);
+                ((ARCFour) writeCipher).init(attr);
+                attr.put(ARCFour.ARCFOUR_KEY_MATERIAL, keys[2]);
+                ((ARCFour) readCipher).init(attr);
+              }
+            else if (!suite.isStreamCipher())
+              {
+                writeCipher = CipherSuite.getCipher(suite.getCipher());
+                readCipher = CipherSuite.getCipher(suite.getCipher());
+                attr.clear();
+                attr.put(IMode.KEY_MATERIAL, keys[3]);
+                attr.put(IMode.IV, keys[5]);
+                attr.put(IMode.STATE, new Integer(IMode.ENCRYPTION));
+                ((IMode) writeCipher).init(attr);
+                attr.put(IMode.KEY_MATERIAL, keys[2]);
+                attr.put(IMode.IV, keys[4]);
+                attr.put(IMode.STATE, new Integer(IMode.DECRYPTION));
+                ((IMode) readCipher).init(attr);
+              }
+          }
+        else // JCESecurityParameters
+          {
+            writeMac = CipherSuite.getJCEMac (suite.getMac());
+            readMac = CipherSuite.getJCEMac (suite.getMac());
+            writeCipher = CipherSuite.getJCECipher (suite.getCipher());
+            readCipher = CipherSuite.getJCECipher (suite.getCipher());
+            ((Mac) writeMac).init (new SecretKeySpec (keys[1], suite.getMac()));
+            ((Mac) readMac).init (new SecretKeySpec (keys[0], suite.getMac()));
+            if (!suite.isStreamCipher())
+              {
+                ((Cipher) writeCipher).init (Cipher.ENCRYPT_MODE,
+                                             new SecretKeySpec (keys[3], suite.getCipher()),
+                                             new IvParameterSpec (keys[5]));
+                ((Cipher) readCipher).init (Cipher.DECRYPT_MODE,
+                                            new SecretKeySpec (keys[2], suite.getCipher()),
+                                            new IvParameterSpec (keys[4]));
+              }
+            else
+              {
+                ((Cipher) writeCipher).init (Cipher.ENCRYPT_MODE,
+                                             new SecretKeySpec (keys[3], suite.getCipher()));
+                ((Cipher) readCipher).init (Cipher.DECRYPT_MODE,
+                                            new SecretKeySpec (keys[2], suite.getCipher()));
+              }
+          }
+      }
+    // These should technically never happen, if our key generation is not
+    // broken.
+    catch (InvalidKeyException ike)
+      {
+        internalError();
+        RuntimeException re = new RuntimeException (ike.getMessage());
+        re.initCause (ike);
+        throw new RuntimeException (String.valueOf (ike));
+      }
+    catch (InvalidAlgorithmParameterException iape)
+      {
+        internalError();
+        RuntimeException re = new RuntimeException (iape.getMessage());
+        re.initCause (iape);
+        throw re;
+      }
+    // These indicate a configuration error with the JCA.
+    catch (NoSuchAlgorithmException nsae)
+      {
+        session.enabledSuites.remove (suite);
+        internalError();
+        SSLException e = new SSLException ("suite " + suite + " not available in this configuration");
+        e.initCause (nsae);
+        throw e;
+      }
+    catch (NoSuchPaddingException nspe)
+      {
+        session.enabledSuites.remove (suite);
+        internalError();
+        SSLException e = new SSLException ("suite " + suite + " not available in this configuration");
+        e.initCause (nspe);
+        throw e;
+      }
+
+    Finished finis = null;
+    // If we are continuing a session, we send our Finished message first.
+    if (!newSession)
+      {
+        changeCipherSpec();
+        session.params.setDeflating(comp == CompressionMethod.ZLIB);
+        session.params.setOutMac(writeMac);
+        session.params.setOutCipher(writeCipher);
+        finis = generateFinished(version, (IMessageDigest) md5.clone(),
+                                 (IMessageDigest) sha.clone(), false);
+        msg = new Handshake(Handshake.Type.FINISHED, finis);
+        if (DEBUG_HANDSHAKE_LAYER)
+          logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+        msg.write(dout, version);
+        dout.flush();
+      }
+
+    if (session.currentAlert != null &&
+        session.currentAlert.getLevel() == Alert.Level.FATAL)
+      {
+        fatal();
+        throw new AlertException(session.currentAlert, false);
+      }
+
+    // Wait until we receive a ChangeCipherSpec, then change the crypto
+    // algorithms for the incoming side.
+    synchronized (session.params)
+      {
+        readChangeCipherSpec ();
+        session.params.setInflating(comp == CompressionMethod.ZLIB);
+        session.params.setInMac(readMac);
+        session.params.setInCipher(readCipher);
+        session.params.notifyAll();
+      }
+
+    // Receive and verify the client's finished message.
+    Finished verify = generateFinished(version, (IMessageDigest) md5.clone(),
+                                       (IMessageDigest) sha.clone(), true);
+    msg = Handshake.read(din, suite, null);
+    if (msg.getType() != Handshake.Type.FINISHED)
+      {
+        throwUnexpectedMessage();
+      }
+    if (DEBUG_HANDSHAKE_LAYER)
+      logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+    finis = (Finished) msg.getBody();
+    if (version == ProtocolVersion.SSL_3)
+      {
+        if (!Arrays.equals(finis.getMD5Hash(), verify.getMD5Hash()) ||
+            !Arrays.equals(finis.getSHAHash(), verify.getSHAHash()))
+          {
+            throwHandshakeFailure();
+          }
+      }
+    else
+      {
+        if (!Arrays.equals(finis.getVerifyData(), verify.getVerifyData()))
+          {
+            throwHandshakeFailure();
+          }
+      }
+
+    // Send our Finished message last for new sessions.
+    if (newSession)
+      {
+        changeCipherSpec();
+        session.params.setDeflating(comp == CompressionMethod.ZLIB);
+        session.params.setOutMac(writeMac);
+        session.params.setOutCipher(writeCipher);
+        finis = generateFinished(version, md5, sha, false);
+        msg = new Handshake(Handshake.Type.FINISHED, finis);
+        if (DEBUG_HANDSHAKE_LAYER)
+          logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
+        msg.write(dout, version);
+        dout.flush();
+      }
+
+    handshakeCompleted();
+  }
+
+  /**
+   * Generate the keys from the master secret.
+   *
+   * @param server The server's random value.
+   * @param client The client's random value.
+   * @param activeVersion The negotiated protocol version.
+   * @return The generated keys.
+   */
+  private byte[][] generateKeys(byte[] server, byte[] client,
+                                ProtocolVersion activeVersion)
+    throws LimitReachedException, IOException
+  {
+    CipherSuite suite = session.cipherSuite;
+    int macLen = (suite.getMac().indexOf("MD5") >= 0) ? 16 : 20;
+    int keyLen = suite.getKeyLength();
+    int ivLen = 0;
+    if (suite.getCipher().indexOf("DES") >= 0)
+      {
+        ivLen = 8;
+      }
+    else if (suite.getCipher() == "AES")
+      {
+        ivLen = 16;
+      }
+    byte[][] keyMaterial = new byte[6][];
+    keyMaterial[0] = new byte[macLen]; // client_write_MAC_secret
+    keyMaterial[1] = new byte[macLen]; // server_write_MAC_secret
+    keyMaterial[2] = new byte[keyLen]; // client_write_key
+    keyMaterial[3] = new byte[keyLen]; // server_write_key
+    keyMaterial[4] = new byte[ivLen];  // client_write_IV
+    keyMaterial[5] = new byte[ivLen];  // server_write_IV
+    IRandom prf = null;
+    if (activeVersion == ProtocolVersion.SSL_3)
+      {
+        prf = new SSLRandom();
+        HashMap attr = new HashMap();
+        attr.put(SSLRandom.SECRET, session.masterSecret);
+        attr.put(SSLRandom.SEED, Util.concat(server, client));
+        prf.init(attr);
+      }
+    else
+      {
+        prf = new TLSRandom();
+        HashMap attr = new HashMap();
+        attr.put(TLSRandom.SECRET, session.masterSecret);
+        attr.put(TLSRandom.SEED, Util.concat("key expansion".getBytes("UTF-8"),
+                 Util.concat(server, client)));
+        prf.init(attr);
+      }
+    for (int i = 0; i < keyMaterial.length; i++)
+      {
+        prf.nextBytes(keyMaterial[i], 0, keyMaterial[i].length);
+      }
+
+    // Exportable ciphers transform their keys once more, and use a
+    // nonsecret IV for block ciphers.
+    if (suite.isExportable())
+      {
+        int finalLen = suite.getCipher() == "DES" ? 8 : 16;
+        if (activeVersion == ProtocolVersion.SSL_3)
+          {
+            IMessageDigest md5 = HashFactory.getInstance(Registry.MD5_HASH);
+            md5.update(keyMaterial[2], 0, keyMaterial[2].length);
+            md5.update(client, 0, client.length);
+            md5.update(server, 0, server.length);
+            keyMaterial[2] = Util.trim(md5.digest(), finalLen);
+            md5.update(keyMaterial[3], 0, keyMaterial[3].length);
+            md5.update(server, 0, server.length);
+            md5.update(client, 0, client.length);
+            keyMaterial[3] = Util.trim(md5.digest(), finalLen);
+            if (!suite.isStreamCipher())
+              {
+                md5.update(client, 0, client.length);
+                md5.update(server, 0, server.length);
+                keyMaterial[4] = Util.trim(md5.digest(), ivLen);
+                md5.update(server, 0, server.length);
+                md5.update(client, 0, client.length);
+                keyMaterial[5] = Util.trim(md5.digest(), ivLen);
+              }
+          }
+        else
+          {
+            HashMap attr = new HashMap();
+            attr.put(TLSRandom.SECRET, keyMaterial[2]);
+            attr.put(TLSRandom.SEED,
+                     Util.concat("client write key".getBytes("UTF-8"),
+                                 Util.concat(client, server)));
+            prf.init(attr);
+            keyMaterial[2] = new byte[finalLen];
+            prf.nextBytes(keyMaterial[2], 0, finalLen);
+            attr.put(TLSRandom.SECRET, keyMaterial[3]);
+            attr.put(TLSRandom.SEED,
+                     Util.concat("server write key".getBytes("UTF-8"),
+                                 Util.concat(client, server)));
+            prf.init(attr);
+            keyMaterial[3] = new byte[finalLen];
+            prf.nextBytes(keyMaterial[3], 0, finalLen);
+            if (!suite.isStreamCipher())
+              {
+                attr.put(TLSRandom.SECRET, new byte[0]);
+                attr.put(TLSRandom.SEED, Util.concat("IV block".getBytes("UTF-8"),
+                                                     Util.concat(client, server)));
+                prf.init(attr);
+                prf.nextBytes(keyMaterial[4], 0, keyMaterial[4].length);
+                prf.nextBytes(keyMaterial[5], 0, keyMaterial[5].length);
+              }
+          }
+      }
+
+    if (DEBUG_KEY_EXCHANGE)
+      {
+        logger.log (Component.SSL_KEY_EXCHANGE, "Generated keys:");
+        for (int i = 0; i < keyMaterial.length; i++)
+          logger.log (Component.SSL_KEY_EXCHANGE, "[{0}] {1}",
+                      new Object[] { new Integer (i),
+                                     Util.toHexString(keyMaterial[i], ':') });
+      }
+
+    return keyMaterial;
+  }
+
+  /**
+   * Generate a "finished" message, based on the hashes of the handshake
+   * messages, the agreed version, and a label.
+   *
+   * @param version The agreed version.
+   * @param md5 The current state of the handshake MD5 hash.
+   * @param sha The current state of the handshake SHA hash.
+   * @param client Should be true if the message is generated by the client.
+   */
+  private Finished generateFinished(ProtocolVersion version, IMessageDigest md5,
+                                    IMessageDigest sha, boolean client)
+  {
+    if (version == ProtocolVersion.SSL_3)
+      {
+        if (client)
+          {
+            md5.update(SENDER_CLIENT, 0, 4);
+          }
+        else
+          {
+            md5.update(SENDER_SERVER, 0, 4);
+          }
+        byte[] ms = session.masterSecret;
+        md5.update(ms, 0, ms.length);
+        for (int i = 0; i < 48; i++)
+          {
+            md5.update(SSLHMac.PAD1);
+          }
+        byte[] b = md5.digest();
+        md5.update(ms, 0, ms.length);
+        for (int i = 0; i < 48; i++)
+          {
+            md5.update(SSLHMac.PAD2);
+          }
+        md5.update(b, 0, b.length);
+
+        if (client)
+          {
+            sha.update(SENDER_CLIENT, 0, 4);
+          }
+        else
+          {
+            sha.update(SENDER_SERVER, 0, 4);
+          }
+        sha.update(ms, 0, ms.length);
+        for (int i = 0; i < 40; i++)
+          {
+            sha.update(SSLHMac.PAD1);
+          }
+        b = sha.digest();
+        sha.update(ms, 0, ms.length);
+        for (int i = 0; i < 40; i++)
+          {
+            sha.update(SSLHMac.PAD2);
+          }
+        sha.update(b, 0, b.length);
+        return new Finished(md5.digest(), sha.digest());
+      }
+    else
+      {
+        byte[] h1 = md5.digest();
+        byte[] h2 = sha.digest();
+        String label = client ? "client finished" : "server finished";
+        byte[] seed = null;
+        try
+          {
+            seed = Util.concat(label.getBytes("UTF-8"), Util.concat(h1, h2));
+          }
+        catch (java.io.UnsupportedEncodingException uee)
+          {
+            RuntimeException re = new RuntimeException (uee.getMessage());
+            re.initCause (uee);
+            throw re;
+          }
+        IRandom prf = new TLSRandom();
+        HashMap attr = new HashMap();
+        attr.put(TLSRandom.SECRET, session.masterSecret);
+        attr.put(TLSRandom.SEED, seed);
+        prf.init(attr);
+        byte[] finishedValue = new byte[12];
+        try
+          {
+            prf.nextBytes(finishedValue, 0, 12);
+          }
+        catch (LimitReachedException lre)
+          {
+            RuntimeException re = new RuntimeException (lre.getMessage());
+            re.initCause (lre);
+            throw re;
+          }
+        return new Finished(finishedValue);
+      }
+  }
+
+  /**
+   * Send a fatal unexpected_message alert.
+   */
+  private Alert unexpectedMessage() throws IOException
+  {
+    Alert alert = new Alert(Alert.Level.FATAL,
+      Alert.Description.UNEXPECTED_MESSAGE);
+    sendAlert(alert);
+    fatal();
+    return alert;
+  }
+
+  private void throwUnexpectedMessage() throws IOException
+  {
+    throw new AlertException(unexpectedMessage(), true);
+  }
+
+  /**
+   * Send a fatal handshake_failure alert.
+   */
+  private Alert handshakeFailure() throws IOException
+  {
+    Alert alert = new Alert(Alert.Level.FATAL,
+      Alert.Description.HANDSHAKE_FAILURE);
+    sendAlert(alert);
+    fatal();
+    return alert;
+  }
+
+  private void throwHandshakeFailure() throws IOException
+  {
+    throw new AlertException(handshakeFailure(), true);
+  }
+
+  /**
+   * Send an internal_error alert.
+   */
+  private Alert internalError() throws IOException
+  {
+    Alert alert = new Alert(Alert.Level.FATAL,
+      Alert.Description.INTERNAL_ERROR);
+    sendAlert(alert);
+    fatal();
+    return alert;
+  }
+
+  private void throwInternalError() throws IOException
+  {
+    throw new AlertException(internalError(), true);
+  }
+
+  private Alert peerUnverified(X509Certificate[] chain) throws IOException
+  {
+    Alert alert = new Alert(Alert.Level.FATAL,
+      Alert.Description.HANDSHAKE_FAILURE);
+    sendAlert(alert);
+    fatal();
+    return alert;
+  }
+
+  private void throwPeerUnverified(X509Certificate[] chain) throws IOException
+  {
+    peerUnverified (chain);
+    throw new SSLPeerUnverifiedException("could not verify: "+
+                                         chain[0].getSubjectDN());
+  }
+
+  /**
+   * Grab the first suite that is both in the client's requested suites
+   * and in our enabled suites, and for which we have the proper
+   * credentials.
+   *
+   * @param suites The client's requested suites.
+   * @param version The version being negotiated.
+   * @return The selected cipher suite.
+   * @throws SSLException If no appropriate suite can be selected.
+   */
+  private CipherSuite selectSuite(List suites, ProtocolVersion version)
+    throws IOException
+  {
+    if (DEBUG_HANDSHAKE_LAYER)
+      logger.log (Component.SSL_HANDSHAKE, "selectSuite req:{0} suites:{1}",
+                  new Object[] { suites, session.enabledSuites });
+    boolean srpSuiteNoUser = false;
+    for (Iterator i = suites.iterator(); i.hasNext(); )
+      {
+        CipherSuite herSuite = (CipherSuite) i.next();
+        for (Iterator j = session.enabledSuites.iterator(); j.hasNext(); )
+          {
+            CipherSuite mySuite = (CipherSuite) j.next();
+            if (!mySuite.equals(herSuite))
+              {
+                continue;
+              }
+            if (DEBUG_HANDSHAKE_LAYER)
+              logger.log (Component.SSL_HANDSHAKE, "{0} == {1}",
+                          new Object[] { mySuite, herSuite });
+            if (mySuite.getSignature() != "anon" && session.keyManager != null &&
+                session.keyManager.chooseServerAlias(mySuite.getAuthType(), null, null) == null)
+              {
+                if (DEBUG_HANDSHAKE_LAYER)
+                  logger.log (Component.SSL_HANDSHAKE, "{0}: no certificate/private key",
+                              mySuite);
+                continue;
+              }
+            if (mySuite.getKeyExchange() == "SRP")
+              {
+                if (session.getValue("srp-username") == null)
+                  {
+                    if (DEBUG_HANDSHAKE_LAYER)
+                      logger.log (Component.SSL_HANDSHAKE, "no SRP username");
+                    srpSuiteNoUser = true;
+                    continue;
+                  }
+                if (session.srpTrustManager == null)
+                  {
+                    if (DEBUG_HANDSHAKE_LAYER)
+                      logger.log (Component.SSL_HANDSHAKE, "no SRP password file");
+                    continue;
+                  }
+              }
+            return mySuite.resolve(version);
+          }
+      }
+    Alert alert = null;
+    if (srpSuiteNoUser)
+      {
+        alert = new Alert(Alert.Level.WARNING,
+                          Alert.Description.MISSING_SRP_USERNAME);
+        sendAlert(alert);
+        return null;
+      }
+    else
+      alert = new Alert(Alert.Level.FATAL,
+                        Alert.Description.INSUFFICIENT_SECURITY);
+    sendAlert(alert);
+    fatal();
+    throw new AlertException(alert, true);
+  }
+
+  /**
+   * Ask the user for their user name.
+   *
+   * @param remoteHost The remote host being connected to.
+   * @return The user name.
+   */
+  private String askUserName(String remoteHost)
+  {
+    CallbackHandler handler = new DefaultCallbackHandler();
+    try
+      {
+        Class c = Class.forName(Util.getSecurityProperty("jessie.srp.user.handler"));
+        handler = (CallbackHandler) c.newInstance();
+      }
+    catch (Exception x) { }
+    TextInputCallback user =
+      new TextInputCallback("User name for " + remoteHost + ": ",
+                            Util.getProperty("user.name"));
+    try
+      {
+        handler.handle(new Callback[] { user });
+      }
+    catch (Exception x) { }
+    return user.getText();
+  }
+
+  /**
+   * Ask the user for a password.
+   *
+   * @param user The user name.
+   * @return The password.
+   */
+  private String askPassword(String user)
+  {
+    CallbackHandler handler = new DefaultCallbackHandler();
+    try
+      {
+        Class c = Class.forName(Util.getSecurityProperty("jessie.srp.password.handler"));
+        handler = (CallbackHandler) c.newInstance();
+      }
+    catch (Exception x) { }
+    PasswordCallback passwd = new PasswordCallback(user + "'s password: ", false);
+    try
+      {
+        handler.handle(new Callback[] { passwd });
+      }
+    catch (Exception x) { }
+    return new String(passwd.getPassword());
+  }
+
+  /**
+   * Ask the user (via a callback) if they will accept a certificate that
+   * could not be verified.
+   *
+   * @param chain The certificate chain in question.
+   * @return true if the user accepts the certificate chain.
+   */
+  private boolean checkCertificates(X509Certificate[] chain)
+  {
+    CallbackHandler handler = new DefaultCallbackHandler();
+    try
+      {
+        Class c = Class.forName(Util.getSecurityProperty("jessie.certificate.handler"));
+        handler = (CallbackHandler) c.newInstance();
+      }
+    catch (Exception x)
+      {
+      }
+    String nl = Util.getProperty("line.separator");
+    ConfirmationCallback confirm = new ConfirmationCallback(
+      "The server's certificate could not be verified. There is no proof" + nl +
+      "that this server is who it claims to be, or that their certificate" + nl +
+      "is valid. Do you wish to continue connecting?",
+      ConfirmationCallback.ERROR, ConfirmationCallback.YES_NO_OPTION,
+      ConfirmationCallback.NO);
+    try
+      {
+        handler.handle(new Callback[] { confirm });
+      }
+    catch (Exception x)
+      {
+        return false;
+      }
+    return confirm.getSelectedIndex() == ConfirmationCallback.YES;
+  }
+
+  /**
+   * Update a signature object with a BigInteger, trimming the leading
+   * "00" octet if present.
+   *
+   * @param sig The signature being updated.
+   * @param bi  The integer to feed into the signature.
+   */
+  private void updateSig(ISignature sig, BigInteger bi)
+  {
+    byte[] buf = Util.trim(bi);
+    sig.update((byte) (buf.length >>> 8));
+    sig.update((byte)  buf.length);
+    sig.update(buf, 0, buf.length);
+  }
+
+  /**
+   * Teardown everything on fatal errors.
+   */
+  private void fatal() throws IOException
+  {
+    if (session != null)
+      {
+        session.invalidate();
+      }
+//     recordInput.setRunning(false);
+//     recordOutput.setRunning(false);
+    if (underlyingSocket != null)
+      {
+        underlyingSocket.close();
+      }
+    else
+      {
+        super.close();
+      }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLSocketFactory.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLSocketFactory.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLSocketFactory.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLSocketFactory.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,133 @@
+/* SSLSocketFactory.java -- factory for SSL sockets.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.security.SecureRandom;
+
+import javax.net.ssl.X509TrustManager;
+import javax.net.ssl.X509KeyManager;
+
+class SSLSocketFactory extends javax.net.ssl.SSLSocketFactory
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final X509TrustManager trustManager;
+  private final X509KeyManager keyManager;
+  private final SecureRandom random;
+  private final SessionContext sessionContext;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  SSLSocketFactory(X509TrustManager trustManager, X509KeyManager keyManager,
+                   SecureRandom random, SessionContext sessionContext)
+  {
+    this.trustManager = trustManager;
+    this.keyManager = keyManager;
+    this.random = random;
+    this.sessionContext = sessionContext;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public String[] getDefaultCipherSuites()
+  {
+    return (String[]) CipherSuite.availableSuiteNames().toArray(new String[0]);
+  }
+
+  public String[] getSupportedCipherSuites()
+  {
+    return getDefaultCipherSuites();
+  }
+
+  public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
+    throws IOException
+  {
+    return setup(new SSLSocket(socket, host, port, autoClose));
+  }
+
+  public Socket createSocket() throws IOException
+  {
+    return setup(new SSLSocket());
+  }
+
+  public Socket createSocket(String host, int port)
+    throws IOException, UnknownHostException
+  {
+    return setup(new SSLSocket(host, port));
+  }
+
+  public Socket createSocket(String host, int port, InetAddress localAddr, int localPort)
+    throws IOException, UnknownHostException
+  {
+    return setup(new SSLSocket(host, port, localAddr, localPort));
+  }
+
+  public Socket createSocket(InetAddress address, int port) throws IOException
+  {
+    return setup(new SSLSocket(address, port));
+  }
+
+  public Socket createSocket(InetAddress address, int port,
+                             InetAddress localAddr, int localPort)
+    throws IOException
+  {
+    return setup(new SSLSocket(address, port, localAddr, localPort));
+  }
+
+  // Own methods.
+  // -------------------------------------------------------------------------
+
+  private SSLSocket setup(SSLSocket s)
+  {
+    s.setTrustManager(trustManager);
+    s.setKeyManager(keyManager);
+    s.setRandom(random);
+    s.setSessionContext(sessionContext);
+    s.setUseClientMode(true);
+    return s;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLSocketInputStream.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLSocketInputStream.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLSocketInputStream.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLSocketInputStream.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,181 @@
+/* SSLSocketInputStream.java -- InputStream for SSL sockets.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.EOFException;
+import java.io.FilterInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import javax.net.ssl.SSLException;
+
+class SSLSocketInputStream extends FilterInputStream
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final SSLSocket socket;
+  private final boolean checkHandshake;
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  SSLSocketInputStream(InputStream in, SSLSocket socket)
+  {
+    this(in, socket, true);
+  }
+
+  SSLSocketInputStream(InputStream in, SSLSocket socket, boolean checkHandshake)
+  {
+    super(in);
+    this.socket = socket;
+    this.checkHandshake = checkHandshake;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public int available() throws IOException
+  {
+    if (checkHandshake)
+      {
+        socket.checkHandshakeDone();
+      }
+    int ret = 0;
+    try
+      {
+        ret = super.available();
+      }
+    catch (AlertException ae)
+      {
+        Alert alert = ae.getAlert ();
+        if (alert.getDescription () == Alert.Description.CLOSE_NOTIFY)
+          {
+            return -1;
+          }
+        else
+          {
+            throw ae;
+          }
+      }
+    return ret;
+  }
+
+  public int read() throws IOException
+  {
+    if (checkHandshake)
+      {
+        socket.checkHandshakeDone();
+      }
+    int ret = 0;
+    try
+      {
+        ret = in.read();
+      }
+    catch (AlertException ae)
+      {
+        Alert alert = ae.getAlert ();
+        if (alert.getDescription () == Alert.Description.CLOSE_NOTIFY)
+          {
+            return -1;
+          }
+        else
+          {
+            throw ae;
+          }
+      }
+    return ret;
+  }
+
+  public int read(byte[] buf) throws IOException
+  {
+    return read(buf, 0, buf.length);
+  }
+
+  public int read(byte[] buf, int off, int len) throws IOException
+  {
+    if (checkHandshake)
+      {
+        socket.checkHandshakeDone();
+      }
+    if (buf == null)
+      {
+        throw new NullPointerException();
+      }
+    if (off < 0 || len < 0 || off + len > buf.length)
+      {
+        throw new ArrayIndexOutOfBoundsException();
+      }
+    int ret = 0;
+    try
+      {
+        ret = in.read(buf, off, len);
+      }
+    catch (AlertException ae)
+      {
+        Alert alert = ae.getAlert ();
+        if (alert.getDescription () == Alert.Description.CLOSE_NOTIFY)
+          {
+            return -1;
+          }
+        else
+          {
+            throw ae;
+          }
+      }
+    return ret;
+  }
+
+  // Own methods.
+  // -------------------------------------------------------------------------
+
+  private boolean checkAlert() throws IOException
+  {
+    Alert alert = socket.checkAlert();
+    if (alert == null) return false;
+    if (alert.getLevel().equals(Alert.Level.FATAL))
+      throw new AlertException(alert, false);
+    if (alert.getDescription().equals(Alert.Description.CLOSE_NOTIFY))
+      {
+        try { return (in.available() <= 0); }
+        catch (IOException ioe) { }
+      }
+    return false;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLSocketOutputStream.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLSocketOutputStream.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLSocketOutputStream.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SSLSocketOutputStream.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,115 @@
+/* SSLSocketOutputStream.java -- output stream for SSL sockets.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import javax.net.ssl.SSLException;
+
+class SSLSocketOutputStream extends FilterOutputStream
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final SSLSocket socket;
+  private final boolean checkHandshake;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  SSLSocketOutputStream(OutputStream out, SSLSocket socket)
+  {
+    this(out, socket, true);
+  }
+
+  SSLSocketOutputStream(OutputStream out, SSLSocket socket,
+                        boolean checkHandshake)
+  {
+    super(out);
+    this.socket = socket;
+    this.checkHandshake = checkHandshake;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public void write(int b) throws IOException
+  {
+    if (checkHandshake)
+      {
+        socket.checkHandshakeDone();
+      }
+    checkAlert();
+    out.write(b);
+    checkAlert();
+  }
+
+  public void write(byte[] buf) throws IOException
+  {
+    write(buf, 0, buf.length);
+  }
+
+  public void write(byte[] buf, int off, int len) throws IOException
+  {
+    if (checkHandshake)
+      {
+        socket.checkHandshakeDone();
+      }
+    if (buf == null)
+      throw new NullPointerException();
+    if (off < 0 || len < 0 || off + len > buf.length)
+      throw new ArrayIndexOutOfBoundsException();
+    checkAlert();
+    out.write(buf, off, len);
+    checkAlert();
+  }
+
+  // Own methods.
+  // -------------------------------------------------------------------------
+
+  private synchronized void checkAlert() throws SSLException
+  {
+    Alert alert = socket.checkAlert();
+    if (alert == null) return;
+    if (alert.getLevel().equals(Alert.Level.FATAL))
+      throw new AlertException(alert, false);
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SecurityParameters.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SecurityParameters.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SecurityParameters.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SecurityParameters.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,178 @@
+/* SecurityParameters.java -- SSL security parameters.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import javax.net.ssl.SSLException;
+
+/**
+ * The interface that all security parameters used by Jessie must implement.
+ * Security parameters handle all transforming of data, including encryption,
+ * authentication, and compression.
+ */
+interface SecurityParameters
+{
+
+  // Methods.
+  // -------------------------------------------------------------------------
+
+  /**
+   * Decrypts, verifies, and inflates a fragment received. The fragment is
+   * just the data field of a text object, without the version, type, and
+   * length fields. An exception is thrown if any step fails.
+   *
+   * @param fragment The fragment being decrypted.
+   * @param version  The version field of the received text.
+   * @param type     The type field of the received text.
+   * @return The decrypted fragment.
+   * @throws MacException If the MAC could not be verified, or if the padding
+   *         on the decrypted fragment is incorrect.
+   * @throws OverflowException If the processed text overflows the configured
+   *         maximum fragment size.
+   * @throws SSLException If any other error occurs.
+   */
+  byte[] decrypt (byte[] fragment, ProtocolVersion version, ContentType type)
+    throws MacException, OverflowException, SSLException;
+
+  /**
+   * Deflates, authenticates, and encrypts a fragment to be sent.
+   *
+   * @param buf The fragment being encrypted.
+   * @param off The offset into the buffer to start at.
+   * @param len The number of bytes in this fragment.
+   * @param type The content type of this text.
+   * @return The encrypted fragment.
+   * @throws OverflowException If deflating increases the size of the fragment
+   *         too much.
+   * @throws SSLException If any other error occurs.
+   */
+  byte[] encrypt (byte[] buf, int off, int len, ContentType type)
+    throws OverflowException, SSLException;
+
+  /**
+   * Set all crypto primitives to <code>null</code>, meaning that any calls
+   * to {@link #encrypt(byte[],int,int,org.metastatic.jessie.provider.ContentType)} or
+   * {@link #decrypt(byte[],org.metastatic.jessie.provider.ProtocolVersion,org.metastatic.jessie.provider.ContentType})
+   * will perform the identity transformation.
+   */
+  void reset();
+
+  /**
+   * Returns the version of texts being sent.
+   *
+   * @return The version.
+   */
+  ProtocolVersion getVersion();
+
+  /**
+   * Sets the version of texts being sent. This affects the {@link
+   * #encrypt(byte[],int,int,org.metastatic.jessie.provider.ContentType)}
+   * method.
+   *
+   * @param version The version to set.
+   */
+  void setVersion (ProtocolVersion version);
+
+  /**
+   * Turns zlib deflating on or off.
+   *
+   * @param deflate Whether or not to deflate outgoing fragments.
+   */
+  void setDeflating (boolean deflate);
+
+  /**
+   * Turns zlib inflating on or off.
+   *
+   * @param inflate Whether or not to inflate incoming fragments.
+   */
+  void setInflating (boolean inflate);
+
+  /**
+   * Returns the maximum size that plaintext fragments may be.
+   *
+   * @return The fragment length.
+   */
+  int getFragmentLength();
+
+  /**
+   * Sets the maximum size that plaintext fragments may be.
+   *
+   * @param fragmentLength The new fragment length.
+   */
+  void setFragmentLength (int fragmentLength);
+
+  /**
+   * Set the cipher used to decrypt incoming fragments. The parameter must be
+   * appropriate for the implementation.
+   *
+   * @param cipher The cipher.
+   * @throws ClassCastException If the argument is not appropriate for the
+   *         implementation.
+   */
+  void setInCipher (Object cipher);
+
+  /**
+   * Set the cipher used to encrypt outgoing fragments. The parameter must be
+   * appropriate for the implementation.
+   *
+   * @param cipher The cipher.
+   * @throws ClassCastException If the argument is not appropriate for the
+   *         implementation.
+   */
+  void setOutCipher (Object cipher);
+
+  /**
+   * Set the MAC used to verify incoming fragments. The parameter must be
+   * appropriate for the implementation.
+   *
+   * @param mac The MAC.
+   * @throws ClassCastException If the argument is not appropriate for the
+   *         implementation.
+   */
+  void setInMac (Object mac);
+
+  /**
+   * Set the MAC used to authenticating outgoinging fragments. The parameter
+   * must be appropriate for the implementation.
+   *
+   * @param mac The MAC.
+   * @throws ClassCastException If the argument is not appropriate for the
+   *         implementation.
+   */
+  void setOutMac (Object mac);
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ServerHello.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ServerHello.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ServerHello.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ServerHello.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,216 @@
+/* ServerHello.java -- SSL ServerHello message.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.net.ssl.SSLProtocolException;
+
+class ServerHello implements Handshake.Body
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final ProtocolVersion version;
+  private final Random random;
+  private final byte[] sessionId;
+  private final CipherSuite suite;
+  private final CompressionMethod comp;
+  private final List extensions;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  ServerHello(ProtocolVersion version, Random random,
+              byte[] sessionId, CipherSuite suite,
+              CompressionMethod comp)
+  {
+    this(version, random, sessionId, suite, comp, null);
+  }
+
+  ServerHello(ProtocolVersion version, Random random,
+              byte[] sessionId, CipherSuite suite,
+              CompressionMethod comp, List extensions)
+  {
+    this.version = version;
+    this.random = random;
+    this.sessionId = sessionId;
+    this.suite = suite;
+    this.comp = comp;
+    this.extensions = extensions;
+  }
+
+  // Class methods.
+  // -------------------------------------------------------------------------
+
+  static ServerHello read(InputStream in) throws IOException
+  {
+    ProtocolVersion vers = ProtocolVersion.read(in);
+    Random rand = Random.read(in);
+    byte[] id = new byte[in.read() & 0xFF];
+    in.read(id);
+    CipherSuite suite = CipherSuite.read(in).resolve(vers);
+    CompressionMethod comp = CompressionMethod.read(in);
+    List ext = null;
+    if (in.available() > 0)
+      {
+        ext = new LinkedList();
+        int len = (in.read() >>> 8 & 0xFF) | (in.read() & 0xFF);
+        int count = 0;
+        while (count < len)
+          {
+            Extension e = Extension.read(in);
+            ext.add(e);
+            count += e.getValue().length + 4;
+          }
+      }
+    return new ServerHello(vers, rand, id, suite, comp, ext);
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public void write(OutputStream out) throws IOException
+  {
+    version.write(out);
+    random.write(out);
+    out.write(sessionId.length);
+    out.write(sessionId);
+    suite.write(out);
+    out.write(comp.getValue());
+    if (extensions != null)
+      {
+        ByteArrayOutputStream out2 = new ByteArrayOutputStream();
+        for (Iterator i = extensions.iterator(); i.hasNext(); )
+          ((Extension) i.next()).write(out2);
+        out.write(out2.size() >>> 8 & 0xFF);
+        out.write(out2.size() & 0xFF);
+        out2.writeTo(out);
+      }
+  }
+
+  ProtocolVersion getVersion()
+  {
+    return version;
+  }
+
+  Random getRandom()
+  {
+    return random;
+  }
+
+  byte[] getSessionId()
+  {
+    return (byte[]) sessionId.clone();
+  }
+
+  CipherSuite getCipherSuite()
+  {
+    return suite;
+  }
+
+  CompressionMethod getCompressionMethod()
+  {
+    return comp;
+  }
+
+  List getExtensions()
+  {
+    return extensions;
+  }
+
+  public String toString()
+  {
+    StringWriter str = new StringWriter();
+    PrintWriter out = new PrintWriter(str);
+    out.println("struct {");
+    out.println("  version = " + version + ";");
+    BufferedReader r = new BufferedReader(new StringReader(random.toString()));
+    String s;
+    try
+      {
+        while ((s = r.readLine()) != null)
+          {
+            out.print("  ");
+            out.println(s);
+          }
+      }
+    catch (IOException ignored)
+      {
+      }
+    out.println("  sessionId = " + Util.toHexString(sessionId, ':') + ";");
+    out.println("  cipherSuite = " + suite + ";");
+    out.println("  compressionMethod = " + comp + ";");
+    if (extensions != null)
+      {
+        out.println("  extensions = {");
+        for (Iterator i = extensions.iterator(); i.hasNext(); )
+          {
+            r = new BufferedReader(new StringReader(i.next().toString()));
+            try
+              {
+                while ((s = r.readLine()) != null)
+                  {
+                    out.print("    ");
+                    out.println(s);
+                  }
+              }
+            catch (IOException ignored)
+              {
+              }
+          }
+        out.println("  };");
+      }
+    out.println("} ServerHello;");
+    return str.toString();
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ServerKeyExchange.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ServerKeyExchange.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ServerKeyExchange.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/ServerKeyExchange.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,286 @@
+/* ServerKeyExchange.java -- SSL ServerKeyExchange message.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import java.math.BigInteger;
+
+import java.security.PublicKey;
+import java.security.interfaces.RSAPublicKey;
+
+import javax.crypto.interfaces.DHPublicKey;
+import javax.crypto.spec.DHParameterSpec;
+
+import javax.net.ssl.SSLProtocolException;
+
+import gnu.javax.crypto.key.dh.GnuDHPublicKey;
+import gnu.javax.crypto.key.srp6.SRPPublicKey;
+
+class ServerKeyExchange implements Handshake.Body
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private PublicKey publicKey;
+  private Signature signature;
+  private byte[] srpSalt;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  ServerKeyExchange(PublicKey publicKey, Signature signature)
+  {
+    this(publicKey, signature, null);
+  }
+
+  ServerKeyExchange(PublicKey publicKey, Signature signature, byte[] srpSalt)
+  {
+    this.publicKey = publicKey;
+    this.signature = signature;
+    this.srpSalt = srpSalt;
+  }
+
+  // Class methods.
+  // -------------------------------------------------------------------------
+
+  static ServerKeyExchange read(InputStream in, CipherSuite suite,
+                                PublicKey serverKey)
+    throws IOException
+  {
+    DataInputStream din = new DataInputStream(in);
+    PublicKey key = null;
+    byte[] salt = null;
+    String kex = suite.getKeyExchange();
+    if (kex.equals("DHE"))
+      {
+        BigInteger p, g, y;
+        byte[] buf = new byte[din.readUnsignedShort()];
+        din.readFully(buf);
+        p = new BigInteger(1, buf);
+        buf = new byte[din.readUnsignedShort()];
+        din.readFully(buf);
+        g = new BigInteger(1, buf);
+        buf = new byte[din.readUnsignedShort()];
+        din.readFully(buf);
+        y = new BigInteger(1, buf);
+        key = new GnuDHPublicKey(null, p, g, y);
+      }
+    else if (kex.equals("RSA"))
+      {
+        BigInteger n, e;
+        byte[] buf = new byte[din.readUnsignedShort()];
+        din.readFully(buf);
+        n = new BigInteger(1, buf);
+        buf = new byte[din.readUnsignedShort()];
+        din.readFully(buf);
+        e = new BigInteger(1, buf);
+        key = new JessieRSAPublicKey(n, e);
+      }
+    else if (kex.equals("SRP"))
+      {
+        BigInteger N, g, B;
+        byte[] buf = new byte[din.readUnsignedShort()];
+        din.readFully(buf);
+        N = new BigInteger(1, buf);
+        buf = new byte[din.readUnsignedShort()];
+        din.readFully(buf);
+        g = new BigInteger(1, buf);
+        salt = new byte[din.readUnsignedByte()];
+        din.readFully(salt);
+        buf = new byte[din.readUnsignedShort()];
+        din.readFully(buf);
+        B = new BigInteger(1, buf);
+        try
+          {
+            key = new SRPPublicKey(N, g, B);
+          }
+        catch (IllegalArgumentException iae)
+          {
+            throw new SSLProtocolException(iae.getMessage());
+          }
+      }
+    else
+      {
+        throw new SSLProtocolException("invalid kex algorithm");
+      }
+
+    Signature sig = null;
+    if (!suite.getSignature().equals("anon"))
+      {
+        sig = Signature.read(in, suite, serverKey);
+      }
+    return new ServerKeyExchange(key, sig, salt);
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public void write(OutputStream out) throws IOException
+  {
+    write(out, ProtocolVersion.TLS_1);
+  }
+
+  public void write(OutputStream out, ProtocolVersion version)
+    throws IOException
+  {
+    if (publicKey instanceof DHPublicKey)
+      {
+        writeBigint(out, ((DHPublicKey) publicKey).getParams().getP());
+        writeBigint(out, ((DHPublicKey) publicKey).getParams().getG());
+        writeBigint(out, ((DHPublicKey) publicKey).getY());
+      }
+    else if (publicKey instanceof RSAPublicKey)
+      {
+        writeBigint(out, ((RSAPublicKey) publicKey).getModulus());
+        writeBigint(out, ((RSAPublicKey) publicKey).getPublicExponent());
+      }
+    else if (publicKey instanceof SRPPublicKey)
+      {
+        writeBigint(out, ((SRPPublicKey) publicKey).getN());
+        writeBigint(out, ((SRPPublicKey) publicKey).getG());
+        out.write(srpSalt.length);
+        out.write(srpSalt);
+        writeBigint(out, ((SRPPublicKey) publicKey).getY());
+      }
+    if (signature != null)
+      {
+        signature.write(out, version);
+      }
+  }
+
+  PublicKey getPublicKey()
+  {
+    return publicKey;
+  }
+
+  Signature getSignature()
+  {
+    return signature;
+  }
+
+  byte[] getSRPSalt()
+  {
+    return srpSalt;
+  }
+
+  public String toString()
+  {
+    StringWriter str = new StringWriter();
+    PrintWriter out = new PrintWriter(str);
+    out.println("struct {");
+    out.println("  publicKey = struct {");
+    if (publicKey instanceof DHPublicKey)
+      {
+        out.println("    p = " +
+                   ((DHPublicKey) publicKey).getParams().getP().toString(16) +
+                   ";");
+        out.println("    g = " +
+                   ((DHPublicKey) publicKey).getParams().getG().toString(16) +
+                   ";");
+        out.println("    y = " + ((DHPublicKey) publicKey).getY().toString(16) +
+                   ";");
+        out.println("  } DHPublicKey;");
+      }
+    else if (publicKey instanceof RSAPublicKey)
+      {
+        out.println("    modulus = " +
+                   ((RSAPublicKey) publicKey).getModulus().toString(16) +
+                   ";");
+        out.println("    exponent = " +
+                   ((RSAPublicKey) publicKey).getPublicExponent().toString(16) +
+                   ";");
+        out.println("  } RSAPublicKey;");
+      }
+    else if (publicKey instanceof SRPPublicKey)
+      {
+        out.println("    N = "+((SRPPublicKey) publicKey).getN().toString(16)+";");
+        out.println("    g = "+((SRPPublicKey) publicKey).getG().toString(16)+";");
+        out.println("    salt = " + Util.toHexString(srpSalt, ':') + ";");
+        out.println("    B = "+((SRPPublicKey) publicKey).getY().toString(16)+";");
+        out.println("  } SRPPublicKey;");
+      }
+    if (signature != null)
+      {
+        out.println("  signature =");
+        BufferedReader r = new BufferedReader(new StringReader(signature.toString()));
+        String s;
+        try
+          {
+            while ((s = r.readLine()) != null)
+              {
+                out.print("    ");
+                out.println(s);
+              }
+          }
+        catch (IOException ignored)
+          {
+          }
+      }
+    out.println("} ServerKeyExchange;");
+    return str.toString();
+  }
+
+  private void writeBigint(OutputStream out, BigInteger bigint)
+    throws IOException
+  {
+    byte[] b = bigint.toByteArray();
+    if (b[0] == 0x00)
+      {
+        out.write((b.length - 1) >>> 8 & 0xFF);
+        out.write((b.length - 1) & 0xFF);
+        out.write(b, 1, b.length - 1);
+      }
+    else
+      {
+        out.write(b.length >>> 8 & 0xFF);
+        out.write(b.length & 0xFF);
+        out.write(b);
+      }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Session.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Session.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Session.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Session.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,381 @@
+/* Session.java -- SSL and TLS session data.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.security.SecureRandom;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLPermission;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionBindingEvent;
+import javax.net.ssl.SSLSessionBindingListener;
+import javax.net.ssl.SSLSessionContext;
+import javax.net.ssl.X509KeyManager;
+import javax.net.ssl.X509TrustManager;
+import javax.security.cert.X509Certificate;
+
+import gnu.javax.net.ssl.SRPTrustManager;
+
+/**
+ * A generic SSL session implementation for SSL and TLS.
+ */
+final class Session implements SSLSession
+{
+
+  // Constants and fields.
+  // -------------------------------------------------------------------------
+
+  private static final SSLPermission GET_SESSION_CONTEXT_PERMISSION =
+    new SSLPermission("getSSLSessionContext");
+
+  private final long creationTime;
+  private Date lastAccessedTime;
+  ID sessionId;
+  Certificate[] localCerts;
+  Certificate[] peerCerts;
+  X509Certificate[] peerCertChain;
+  String peerHost;
+  boolean peerVerified;
+  SessionContext context;
+  HashMap values;
+  boolean valid;
+  List enabledSuites;
+  CipherSuite cipherSuite;
+  SortedSet enabledProtocols;
+  ProtocolVersion protocol;
+  byte[] masterSecret;
+  SRPTrustManager srpTrustManager;
+  X509TrustManager trustManager;
+  X509KeyManager keyManager;
+  SecureRandom random;
+  SecurityParameters params;
+  Alert currentAlert;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  Session()
+  {
+    this(System.currentTimeMillis());
+  }
+
+  Session(long creationTime)
+  {
+    peerVerified = false;
+    valid = true;
+    this.creationTime = creationTime;
+    lastAccessedTime = new Date(0L);
+    values = new HashMap();
+    if (("true").equalsIgnoreCase (Util.getSecurityProperty ("jessie.with.jce")))
+      params = new JCESecurityParameters();
+    else
+      params = new GNUSecurityParameters (this);
+  }
+
+  // Public instance methods.
+  // -------------------------------------------------------------------------
+
+  protected Object clone()
+  {
+    Session result = new Session(creationTime);
+    result.lastAccessedTime = lastAccessedTime;
+    result.sessionId = sessionId;
+    result.localCerts = (localCerts != null ? (Certificate[]) localCerts.clone() : null);
+    result.peerCerts = (peerCerts != null ? (Certificate[]) peerCerts.clone() : null);
+    result.peerHost = peerHost;
+    result.peerVerified = peerVerified;
+    result.context = context;
+    result.values = values;
+    result.enabledSuites = new ArrayList(enabledSuites);
+    result.cipherSuite = cipherSuite;
+    result.enabledProtocols = new TreeSet(enabledProtocols);
+    result.protocol = protocol;
+    result.masterSecret = masterSecret;
+    result.keyManager = keyManager;
+    result.srpTrustManager = srpTrustManager;
+    result.trustManager = trustManager;
+    result.random = random;
+    return result;
+  }
+
+  public String getCipherSuite()
+  {
+    return cipherSuite.toString();
+  }
+
+  public long getCreationTime()
+  {
+    return creationTime;
+  }
+
+  public byte[] getId()
+  {
+    return (sessionId != null ? sessionId.getId() : null);
+  }
+
+  public long getLastAccessedTime()
+  {
+    return lastAccessedTime.getTime();
+  }
+
+  public Certificate[] getLocalCertificates()
+  {
+    return (Certificate[]) (localCerts != null ? localCerts.clone() : null);
+  }
+
+  public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException
+  {
+    if (!peerVerified)
+      {
+        throw new SSLPeerUnverifiedException("peer not verified");
+      }
+    return (Certificate[]) (peerCerts != null ? peerCerts.clone() : null);
+  }
+
+  public X509Certificate[] getPeerCertificateChain()
+    throws SSLPeerUnverifiedException
+  {
+    if (!peerVerified)
+      {
+        throw new SSLPeerUnverifiedException("peer not verified");
+      }
+    if (peerCerts == null)
+      {
+        return null;
+      }
+    if (peerCertChain != null)
+      {
+        return (X509Certificate[]) peerCertChain.clone();
+      }
+    try
+      {
+        peerCertChain = new X509Certificate[peerCerts.length];
+        for (int i = 0; i < peerCerts.length; i++)
+          {
+            peerCertChain[i] = X509Certificate.getInstance(peerCerts[i].getEncoded());
+          }
+        return (X509Certificate[]) peerCertChain.clone();
+      }
+    catch (javax.security.cert.CertificateException ce)
+      {
+        return null;
+      }
+    catch (CertificateException ce2)
+      {
+        return null;
+      }
+  }
+
+  public String getPeerHost()
+  {
+    return peerHost;
+  }
+
+  public String getProtocol()
+  {
+    return protocol.toString();
+  }
+
+  public SSLSessionContext getSessionContext()
+  {
+    SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      {
+        sm.checkPermission(GET_SESSION_CONTEXT_PERMISSION);
+      }
+    return context;
+  }
+
+  public String[] getValueNames()
+  {
+    Set names = values.keySet();
+    return (String[]) names.toArray(new String[names.size()]);
+  }
+
+  public Object getValue(String name)
+  {
+    return values.get(name);
+  }
+
+  public void putValue(String name, Object value)
+  {
+    values.put(name, value);
+    if (value instanceof SSLSessionBindingListener)
+      {
+        ((SSLSessionBindingListener) value).valueBound(
+          new SSLSessionBindingEvent(this, name));
+      }
+  }
+
+  public void removeValue(String name)
+  {
+    Object value = values.remove(name);
+    if (value != null && (value instanceof SSLSessionBindingListener))
+      {
+        ((SSLSessionBindingListener) value).valueUnbound(
+          new SSLSessionBindingEvent(this, name));
+      }
+  }
+
+  public void invalidate()
+  {
+    if (masterSecret != null)
+      {
+        for (int i = 0; i < masterSecret.length; i++)
+          {
+            masterSecret[i] = 0;
+          }
+        masterSecret = null;
+      }
+    valid = false;
+  }
+
+  synchronized void access()
+  {
+    lastAccessedTime.setTime(System.currentTimeMillis());
+    context.notifyAccess(this);
+  }
+
+  void setLastAccessedTime(long lastAccessedTime)
+  {
+    this.lastAccessedTime.setTime(lastAccessedTime);
+  }
+
+  // Inner classes.
+  // -------------------------------------------------------------------------
+
+  /**
+   * A byte array with appropriate <code>equals()</code>,
+   * <code>hashCode()</code>, and <code>compareTo()</code> semantics.
+   */
+  static final class ID implements Comparable
+  {
+
+    // Fields.
+    // -----------------------------------------------------------------------
+
+    /** The ID itself. */
+    private final byte[] id;
+
+    // Constructor.
+    // -----------------------------------------------------------------------
+
+    /**
+     * Creates a new ID.
+     *
+     * @param id The ID. The array is not cloned.
+     */
+    ID(byte[] id)
+    {
+      if (id == null)
+        {
+          throw new IllegalArgumentException();
+        }
+      this.id = id;
+    }
+
+    // Instance methods.
+    // -----------------------------------------------------------------------
+
+    public byte[] getId()
+    {
+      return (byte[]) id.clone();
+    }
+
+    public boolean equals(Object other)
+    {
+      if (other == null || !(other instanceof ID))
+        {
+          return false;
+        }
+      return Arrays.equals(id, ((ID) other).id);
+    }
+
+    public int hashCode()
+    {
+      int code = 0;
+      for (int i = 0; i < id.length; i++)
+        {
+          code |= (id[i] & 0xFF) << ((i & 3) << 3);
+        }
+      return code;
+    }
+
+    public int compareTo(Object other)
+    {
+      if (other == null || !(other instanceof ID))
+        {
+          return 1;
+        }
+      byte[] id2 = ((ID) other).id;
+      if (id.length != id2.length)
+        {
+          return (id.length < id2.length) ? -1 : 1;
+        }
+      for (int i = 0; i < id.length; i++)
+        {
+          if (id[i] < id2[i])
+            {
+              return -1;
+            }
+          else if (id[i] > id2[i])
+            {
+              return 1;
+            }
+        }
+      return 0;
+    }
+
+    public String toString()
+    {
+      return Util.toHexString(id, ':');
+    }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SessionContext.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SessionContext.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SessionContext.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SessionContext.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,250 @@
+/* SessionContext.java -- Implementation of a session context.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.security.Security;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Vector;
+
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionContext;
+
+/**
+ * A collection of SSL sessions. This implementation is a memory-only
+ * store; subclasses may implement persistent storage.
+ */
+class SessionContext implements SSLSessionContext
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  /** The map of Session.ID objects to Sessions. */
+  protected final HashMap sessions;
+
+  /** The number of sessions to cache. */
+  protected int cacheSize;
+
+  /** The session timeout, in seconds. */
+  protected int timeout;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  SessionContext()
+  {
+    sessions = new HashMap();
+    cacheSize = 0;
+    try
+      {
+        timeout = Integer.parseInt(Util.getSecurityProperty("jessie.session.timeout"));
+      }
+    catch (Exception x)
+      {
+        // Default 24-hour timeout.
+        timeout = 86400;
+      }
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public synchronized Enumeration getIds()
+  {
+    Vector ids = new Vector();
+    for(Iterator i = sessions.keySet().iterator(); i.hasNext(); )
+      {
+        Session.ID id = (Session.ID) i.next();
+        ids.add(id.getId());
+      }
+    return ids.elements();
+  }
+
+  public synchronized SSLSession getSession(byte[] sessionId)
+  {
+    Session session = (Session) sessions.get(new Session.ID(sessionId));
+    if (session == null)
+      return null;
+    long elapsed = System.currentTimeMillis() - session.getLastAccessedTime();
+    if ((int) (elapsed / 1000) > timeout)
+      {
+        removeSession(session.sessionId);
+        session.invalidate();
+        return null;
+      }
+    if (!session.valid)
+      {
+        removeSession(session.sessionId);
+        session.invalidate();
+        return null;
+      }
+    return session;
+  }
+
+  public int getSessionCacheSize()
+  {
+    return cacheSize;
+  }
+
+  public void setSessionCacheSize(int cacheSize)
+  {
+    if (cacheSize < 0)
+      throw new IllegalArgumentException();
+    this.cacheSize = cacheSize;
+  }
+
+  public int getSessionTimeout()
+  {
+    return timeout;
+  }
+
+  public void setSessionTimeout(int timeout)
+  {
+    if (timeout <= 0)
+      throw new IllegalArgumentException();
+    this.timeout = timeout;
+  }
+
+  public String toString()
+  {
+    return sessions.keySet().toString();
+  }
+
+  // Package methods.
+  // -------------------------------------------------------------------------
+
+  /**
+   * Adds a session to this context. This method:
+   *
+   * <ol>
+   * <li>Will do nothing if the cache already contains the given ID.</li>
+   * <li>Will do nothing if the cache limit has been reached (and is
+   * not zero).</li>
+   * <li>Will remove any invalid sessions in the cache before trying to insert
+   * the new one.</li>
+   * <li>Will remove any expired sessions before trying to insert the new
+   * one.</li>
+   * </ol>
+   *
+   * @param sessionId This session's ID.
+   * @param session The session to add.
+   * @return True if the session was added, false otherwise.
+   */
+  synchronized boolean addSession(Session.ID sessionId, Session session)
+  {
+    if (sessions.containsKey(sessionId))
+      return false;
+    if (cacheSize > 0 && sessions.size() > cacheSize)
+      {
+        boolean removed = false;
+        for (Iterator i = sessions.values().iterator(); i.hasNext(); )
+          {
+            Session s = (Session) i.next();
+            long elapsed = System.currentTimeMillis() - s.getCreationTime();
+            if (!s.valid)
+              {
+                removeSession(session.sessionId);
+                removed = true;
+              }
+            else if ((int) (elapsed / 1000) > timeout)
+              {
+                removeSession(session.sessionId);
+                removed = true;
+              }
+          }
+        if (removed)
+          {
+            sessions.put(sessionId, session);
+            session.context = this;
+            session.sessionId = sessionId;
+            return true;
+          }
+        return false;
+      }
+    else
+      {
+        sessions.put(sessionId, session);
+        session.context = this;
+        session.sessionId = sessionId;
+        return true;
+      }
+  }
+
+  /**
+   * Returns whether or not a session with the given ID is cached by this
+   * context.
+   */
+  synchronized boolean containsSessionID(Session.ID sessionId)
+  {
+    Session s = (Session) sessions.get(sessionId);
+    if (s == null)
+      {
+        return false;
+      }
+    long elapsed = System.currentTimeMillis() - s.getCreationTime();
+    if (!s.valid || (int) (elapsed / 1000) > timeout)
+      {
+        removeSession(sessionId);
+        return false;
+      }
+    return true;
+  }
+
+  /**
+   * Removes a session from this context.
+   *
+   * @param sessionId The ID of the session to remove.
+   */
+  synchronized boolean removeSession(Session.ID sessionId)
+  {
+    return sessions.remove(sessionId) != null;
+  }
+
+  /**
+   * Notifies this context of an access event on a session.
+   *
+   * @param session The session that was accessed.
+   */
+  void notifyAccess(Session session)
+  {
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Signature.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Signature.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Signature.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Signature.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,158 @@
+/* Signature.java -- SSL signature message.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import java.math.BigInteger;
+
+import java.security.PublicKey;
+import java.security.interfaces.RSAKey;
+
+import java.util.Arrays;
+
+import gnu.java.security.der.*;
+
+class Signature implements Constructed
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final Object sigValue;
+  private final String sigAlg;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  Signature(Object sigValue, String sigAlg)
+  {
+    this.sigValue = sigValue;
+    this.sigAlg = sigAlg;
+  }
+
+  // Class method.
+  // -------------------------------------------------------------------------
+
+  static Signature read(InputStream in, CipherSuite suite, PublicKey key)
+    throws IOException
+  {
+    Object sigValue = null;
+    DataInputStream din = new DataInputStream(in);
+    int len = din.readUnsignedShort();
+    sigValue = new byte[len];
+    din.readFully((byte[]) sigValue);
+    if (suite.getSignature() == "DSS")
+      {
+        DERReader der = new DERReader(new ByteArrayInputStream((byte[]) sigValue));
+        if (der.read().getTag() != DER.SEQUENCE)
+          {
+            throw new IOException("expecting DER SEQUENCE");
+          }
+        BigInteger r = (BigInteger) der.read().getValue();
+        BigInteger s = (BigInteger) der.read().getValue();
+        sigValue = new BigInteger[] { r, s };
+      }
+    return new Signature(sigValue, suite.getSignature());
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public void write(OutputStream out) throws IOException
+  {
+    write(out, ProtocolVersion.TLS_1);
+  }
+
+  public void write(OutputStream out, ProtocolVersion version)
+    throws IOException
+  {
+    byte[] result = null;
+    if (sigValue instanceof byte[])
+      {
+        result = (byte[]) sigValue;
+      }
+    else
+      {
+        DERValue r = new DERValue(DER.INTEGER, ((BigInteger[]) sigValue)[0]);
+        DERValue s = new DERValue(DER.INTEGER, ((BigInteger[]) sigValue)[1]);
+        DERValue sig = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED,
+                                    Arrays.asList(new Object[] { r, s }));
+        result = sig.getEncoded();
+      }
+    out.write(result.length >>> 8 & 0xFF);
+    out.write(result.length & 0xFF);
+    out.write(result);
+  }
+
+  Object getSigValue()
+  {
+    return sigValue;
+  }
+
+  String getSigAlg()
+  {
+    return sigAlg;
+  }
+
+  public String toString()
+  {
+    StringWriter str = new StringWriter();
+    PrintWriter out = new PrintWriter(str);
+    out.println("struct {");
+    if (sigAlg.equals("RSA"))
+      {
+        out.print(Util.hexDump((byte[]) sigValue, "  "));
+      }
+    else
+      {
+        out.println("  r = " + ((BigInteger[]) sigValue)[0].toString(16) + ";");
+        out.println("  s = " + ((BigInteger[]) sigValue)[1].toString(16) + ";");
+      }
+    out.println("} Signature;");
+    return str.toString();
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SynchronizedRandom.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SynchronizedRandom.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SynchronizedRandom.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/SynchronizedRandom.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,104 @@
+/* SynchronizedRandom.java -- Thread-safe IRandom wrapper.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.util.Map;
+import gnu.java.security.prng.IRandom;
+import gnu.java.security.prng.LimitReachedException;
+
+class SynchronizedRandom implements IRandom
+{
+
+  // Field.
+  // -------------------------------------------------------------------------
+
+  private final IRandom random;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  SynchronizedRandom(IRandom random)
+  {
+    this.random = random;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public String name()
+  {
+    return random.name();
+  }
+
+  public synchronized void init(Map attrib)
+  {
+    random.init(attrib);
+  }
+
+  public synchronized byte nextByte()
+    throws IllegalStateException, LimitReachedException
+  {
+    return random.nextByte();
+  }
+
+  public synchronized void nextBytes(byte[] buf, int off, int len)
+    throws IllegalStateException, LimitReachedException
+  {
+    random.nextBytes(buf, off, len);
+  }
+
+  public synchronized Object clone()
+    throws CloneNotSupportedException
+  {
+    return new SynchronizedRandom((IRandom) random.clone());
+  }
+
+  // For future versions of GNU Crypto. No-ops.
+  public void addRandomByte (byte b)
+  {
+  }
+
+  public void addRandomBytes(byte[] buffer) {
+    addRandomBytes(buffer, 0, buffer.length);
+  }
+
+  public void addRandomBytes (byte[] b, int i, int j)
+  {
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/TLSHMac.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/TLSHMac.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/TLSHMac.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/TLSHMac.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,138 @@
+/* TLSHMac.java -- HMAC used in TLS.
+   Copyright (C) 2001, 2002, 2003, 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.security.InvalidKeyException;
+import java.util.HashMap;
+import java.util.Map;
+
+import gnu.java.security.hash.IMessageDigest;
+import gnu.javax.crypto.mac.HMac;
+
+/**
+ * The operation of this HMac is identical to normal HMacs, but this one
+ * allows keys with short lengths (including zero).
+ */
+class TLSHMac extends HMac
+{
+
+  // Constants.
+  // -------------------------------------------------------------------------
+
+  private static final byte IPAD_BYTE = 0x36;
+  private static final byte OPAD_BYTE = 0x5C;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  TLSHMac(IMessageDigest hash)
+  {
+    super(hash);
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public void init(Map attributes)
+    throws InvalidKeyException, IllegalStateException
+  {
+    Integer ts = (Integer) attributes.get(TRUNCATED_SIZE);
+    truncatedSize = (ts == null ? macSize : ts.intValue());
+    if (truncatedSize < (macSize / 2)) {
+      throw new IllegalArgumentException("Truncated size too small");
+    } else if (truncatedSize < 10) {
+      throw new IllegalArgumentException("Truncated size less than 80 bits");
+    }
+
+    // we dont use/save the key outside this method
+    byte[] K = (byte[]) attributes.get(MAC_KEY_MATERIAL);
+    if (K == null) { // take it as an indication to re-use previous key if set
+      if (ipadHash == null)
+        {
+          throw new InvalidKeyException("Null key");
+        }
+      // we already went through the motions; ie. up to step #4.  re-use
+      underlyingHash = (IMessageDigest) ipadHash.clone();
+      return;
+    }
+
+    if (K.length > blockSize)
+      {
+        // (0) replace K with HASH(K) if K is larger than the hash's
+        //     block size. Then pad with zeros until it is the correct
+        //     size (the next `if').
+        underlyingHash.update(K, 0, K.length);
+        K = underlyingHash.digest();
+      }
+    if (K.length < blockSize)
+      {
+        // (1) append zeros to the end of K to create a B byte string
+        //     (e.g., if K is of length 20 bytes and B=64, then K will be
+        //     appended with 44 zero bytes 0x00)
+        int limit = (K.length > blockSize) ? blockSize : K.length;
+        byte[] newK = new byte[blockSize];
+        System.arraycopy(K, 0, newK, 0, limit);
+        K = newK;
+      }
+
+    underlyingHash.reset();
+    opadHash = (IMessageDigest) underlyingHash.clone();
+    if (ipad == null)
+      {
+        ipad = new byte[blockSize];
+      }
+    // (2) XOR (bitwise exclusive-OR) the B byte string computed in step
+    //     (1) with ipad
+    // (3) append the stream of data 'text' to the B byte string resulting
+    //     from step (2)
+    // (4) apply H to the stream generated in step (3)
+    for (int i = 0; i < blockSize; i++)
+      {
+        ipad[i] = (byte)(K[i] ^ IPAD_BYTE);
+      }
+    for (int i = 0; i < blockSize; i++)
+      {
+        opadHash.update((byte)(K[i] ^ OPAD_BYTE));
+      }
+
+    underlyingHash.update(ipad, 0, blockSize);
+    ipadHash = (IMessageDigest) underlyingHash.clone();
+    K = null;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/TLSRandom.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/TLSRandom.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/TLSRandom.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/TLSRandom.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,252 @@
+/* TLSRandom.java -- The TLS pseudo-random function.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.security.InvalidKeyException;
+import java.util.HashMap;
+import java.util.Map;
+
+import gnu.java.security.hash.HashFactory;
+import gnu.javax.crypto.mac.IMac;
+import gnu.java.security.prng.IRandom;
+
+class TLSRandom implements IRandom
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  /**
+   * Property name for the secret that will be used to initialize the HMACs.
+   */
+  static final String SECRET = "jessie.tls.prng.secret";
+
+  /**
+   * Property name for the seed.
+   */
+  static final String SEED = "jessie.tls.prng.seed";
+
+  private final IMac hmac_sha, hmac_md5;
+  private byte[] sha_a, md5_a;
+  private byte[] seed;
+  private final byte[] buffer;
+  private int idx;
+  private boolean init;
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  TLSRandom()
+  {
+    hmac_sha = new TLSHMac(HashFactory.getInstance("SHA1"));
+    hmac_md5 = new TLSHMac(HashFactory.getInstance("MD5"));
+    buffer = new byte[80];   // 80 == LCM of 16 and 20.
+    idx = 0;
+    init = false;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public Object clone()
+  {
+    try
+      {
+        return super.clone();
+      }
+    catch (CloneNotSupportedException shouldNotHappen)
+      {
+        throw new Error();
+      }
+  }
+
+  public void init(Map attributes)
+  {
+    HashMap sha_attr = new HashMap();
+    HashMap md5_attr = new HashMap();
+    byte[] secret = (byte[]) attributes.get(SECRET);
+    if (secret != null)
+      {
+        int l = (secret.length >>> 1) + (secret.length & 1);
+        byte[] s1 = Util.trim(secret, 0, l);
+        byte[] s2 = Util.trim(secret, secret.length - l, l);
+        md5_attr.put(IMac.MAC_KEY_MATERIAL, s1);
+        sha_attr.put(IMac.MAC_KEY_MATERIAL, s2);
+        try
+          {
+            hmac_md5.init(md5_attr);
+            hmac_sha.init(sha_attr);
+          }
+        catch (InvalidKeyException ike)
+          {
+            throw new Error(ike.toString());
+          }
+      }
+    else if (!init)
+      {
+        throw new IllegalArgumentException("no secret supplied");
+      }
+    // else re-use
+
+    byte[] seeed = (byte[]) attributes.get(SEED);
+    if (seeed != null)
+      {
+        seed = (byte[]) seeed.clone();
+      }
+    else if (!init)
+      {
+        throw new IllegalArgumentException("no seed supplied");
+      }
+    // else re-use
+
+    // A(0) is the seed, A(1) = HMAC_hash(secret, A(0)).
+    hmac_md5.update(seed, 0, seed.length);
+    md5_a = hmac_md5.digest();
+    hmac_md5.reset();
+    hmac_sha.update(seed, 0, seed.length);
+    sha_a = hmac_sha.digest();
+    hmac_sha.reset();
+    fillBuffer();
+    init = true;
+  }
+
+  public String name()
+  {
+    return "TLSRandom";
+  }
+
+  public byte nextByte()
+  {
+    if (!init)
+      throw new IllegalStateException();
+    if (idx >= buffer.length)
+      fillBuffer();
+    return buffer[idx++];
+  }
+
+  public void nextBytes(byte[] buf, int off, int len)
+  {
+    if (!init)
+      throw new IllegalStateException();
+    if (buf == null)
+      throw new NullPointerException();
+    if (off < 0 || off > buf.length || off + len > buf.length)
+      throw new ArrayIndexOutOfBoundsException();
+    int count = 0;
+    if (idx >= buffer.length)
+      fillBuffer();
+    while (count < len)
+      {
+        int l = Math.min(buffer.length-idx, len-count);
+        System.arraycopy(buffer, idx, buf, off+count, l);
+        idx += l;
+        count += l;
+        if (count < len && idx >= buffer.length)
+          fillBuffer();
+      }
+  }
+
+  // For future versions of GNU Crypto. No-ops.
+  public void addRandomByte (byte b)
+  {
+  }
+
+  public void addRandomBytes(byte[] buffer) {
+    addRandomBytes(buffer, 0, buffer.length);
+  }
+
+  public void addRandomBytes (byte[] b, int i, int j)
+  {
+  }
+
+  // Own methods.
+  // -------------------------------------------------------------------------
+
+  /*
+   * The PRF is defined as:
+   *
+   *   PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR
+   *                              P_SHA-1(S2, label + seed);
+   *
+   * P_hash is defined as:
+   *
+   *   P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
+   *                          HMAC_hash(secret, A(2) + seed) +
+   *                          HMAC_hash(secret, A(3) + seed) + ...
+   *
+   * And A() is defined as:
+   *
+   *   A(0) = seed
+   *   A(i) = HMAC_hash(secret, A(i-1))
+   *
+   * For simplicity, we compute an 80-byte block on each call, which
+   * corresponds to five iterations of MD5, and four of SHA-1.
+   */
+  private synchronized void fillBuffer()
+  {
+    int len = hmac_md5.macSize();
+    for (int i = 0; i < buffer.length; i += len)
+      {
+        hmac_md5.update(md5_a, 0, md5_a.length);
+        hmac_md5.update(seed, 0, seed.length);
+        byte[] b = hmac_md5.digest();
+        hmac_md5.reset();
+        System.arraycopy(b, 0, buffer, i, len);
+        hmac_md5.update(md5_a, 0, md5_a.length);
+        md5_a = hmac_md5.digest();
+        hmac_md5.reset();
+      }
+    len = hmac_sha.macSize();
+    for (int i = 0; i < buffer.length; i += len)
+      {
+        hmac_sha.update(sha_a, 0, sha_a.length);
+        hmac_sha.update(seed, 0, seed.length);
+        byte[] b = hmac_sha.digest();
+        hmac_sha.reset();
+        for (int j = 0; j < len; j++)
+          {
+            buffer[j + i] ^= b[j];
+          }
+        hmac_sha.update(sha_a, 0, sha_a.length);
+        sha_a = hmac_sha.digest();
+        hmac_sha.reset();
+      }
+    idx = 0;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Util.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Util.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Util.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/Util.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,422 @@
+/* Util.java -- Miscellaneous utility methods.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.math.BigInteger;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.Security;
+
+/**
+ * A collection of useful class methods.
+ *
+ * @author Casey Marshall (rsdio at metastatic.org)
+ */
+final class Util
+{
+
+  // Constants.
+  // -------------------------------------------------------------------------
+
+  static final String HEX = "0123456789abcdef";
+
+  // Static methods only.
+  private Util() { }
+
+  // Class methods.
+  // -------------------------------------------------------------------------
+
+  /**
+   * Convert a hexadecimal string into its byte representation.
+   *
+   * @param hex The hexadecimal string.
+   * @return The converted bytes.
+   */
+  static byte[] toByteArray(String hex)
+  {
+    hex = hex.toLowerCase();
+    byte[] buf = new byte[hex.length() / 2];
+    int j = 0;
+    for (int i = 0; i < buf.length; i++)
+      {
+        buf[i] = (byte) ((Character.digit(hex.charAt(j++), 16) << 4) |
+                          Character.digit(hex.charAt(j++), 16));
+      }
+    return buf;
+  }
+
+  /**
+   * Convert a byte array to a hexadecimal string, as though it were a
+   * big-endian arbitrarily-sized integer.
+   *
+   * @param buf The bytes to format.
+   * @param off The offset to start at.
+   * @param len The number of bytes to format.
+   * @return A hexadecimal representation of the specified bytes.
+   */
+  static String toHexString(byte[] buf, int off, int len)
+  {
+    StringBuffer str = new StringBuffer();
+    for (int i = 0; i < len; i++)
+      {
+        str.append(HEX.charAt(buf[i+off] >>> 4 & 0x0F));
+        str.append(HEX.charAt(buf[i+off] & 0x0F));
+      }
+    return str.toString();
+  }
+
+  /**
+   * See {@link #toHexString(byte[],int,int)}.
+   */
+  static String toHexString(byte[] buf)
+  {
+    return Util.toHexString(buf, 0, buf.length);
+  }
+
+  /**
+   * Convert a byte array to a hexadecimal string, separating octets
+   * with the given character.
+   *
+   * @param buf The bytes to format.
+   * @param off The offset to start at.
+   * @param len The number of bytes to format.
+   * @param sep The character to insert between octets.
+   * @return A hexadecimal representation of the specified bytes.
+   */
+  static String toHexString(byte[] buf, int off, int len, char sep)
+  {
+    StringBuffer str = new StringBuffer();
+    for (int i = 0; i < len; i++)
+      {
+        str.append(HEX.charAt(buf[i+off] >>> 4 & 0x0F));
+        str.append(HEX.charAt(buf[i+off] & 0x0F));
+        if (i < len - 1)
+          str.append(sep);
+      }
+    return str.toString();
+  }
+
+  /**
+   * See {@link #toHexString(byte[],int,int,char)}.
+   */
+  static String toHexString(byte[] buf, char sep)
+  {
+    return Util.toHexString(buf, 0, buf.length, sep);
+  }
+
+  /**
+   * Create a representation of the given byte array similar to the
+   * output of <code>`hexdump -C'</code>, which is
+   *
+   * <p><pre>OFFSET  SIXTEEN-BYTES-IN-HEX  PRINTABLE-BYTES</pre>
+   *
+   * <p>The printable bytes show up as-is if they are printable and
+   * not a newline character, otherwise showing as '.'.
+   *
+   * @param buf The bytes to format.
+   * @param off The offset to start at.
+   * @param len The number of bytes to encode.
+   * @param prefix A string to prepend to every line.
+   * @return The formatted string.
+   */
+  static String hexDump(byte[] buf, int off, int len, String prefix)
+  {
+    String nl = getProperty("line.separator");
+    StringBuffer str = new StringBuffer();
+    int i = 0;
+    while (i < len)
+      {
+        if (prefix != null)
+          str.append(prefix);
+        str.append(Util.formatInt(i+off, 16, 8));
+        str.append("  ");
+        String s = Util.toHexString(buf, i+off, Math.min(16, len-i), ' ');
+        str.append(s);
+        for (int j = 56 - (56 - s.length()); j < 56; j++)
+          str.append(" ");
+        for (int j = 0; j < Math.min(16, len - i); j++)
+          {
+            if ((buf[i+off+j] & 0xFF) < 0x20 || (buf[i+off+j] & 0xFF) > 0x7E)
+              str.append('.');
+            else
+              str.append((char) (buf[i+off+j] & 0xFF));
+          }
+        str.append(nl);
+        i += 16;
+      }
+    return str.toString();
+  }
+
+  /**
+   * See {@link #hexDump(byte[],int,int,String)}.
+   */
+  static String hexDump(byte[] buf, int off, int len)
+  {
+    return hexDump(buf, off, len, "");
+  }
+
+  /**
+   * See {@link #hexDump(byte[],int,int,String)}.
+   */
+  static String hexDump(byte[] buf, String prefix)
+  {
+    return hexDump(buf, 0, buf.length, prefix);
+  }
+
+  /**
+   * See {@link #hexDump(byte[],int,int,String)}.
+   */
+  static String hexDump(byte[] buf)
+  {
+    return hexDump(buf, 0, buf.length);
+  }
+
+  /**
+   * Format an integer into the specified radix, zero-filled.
+   *
+   * @param i The integer to format.
+   * @param radix The radix to encode to.
+   * @param len The target length of the string. The string is
+   *   zero-padded to this length, but may be longer.
+   * @return The formatted integer.
+   */
+  static String formatInt(int i, int radix, int len)
+  {
+    String s = Integer.toString(i, radix);
+    StringBuffer buf = new StringBuffer();
+    for (int j = 0; j < len - s.length(); j++)
+      buf.append("0");
+    buf.append(s);
+    return buf.toString();
+  }
+
+  /**
+   * Concatenate two byte arrays into one.
+   *
+   * @param b1 The first byte array.
+   * @param b2 The second byte array.
+   * @return The concatenation of b1 and b2.
+   */
+  static byte[] concat(byte[] b1, byte[] b2)
+  {
+    byte[] b3 = new byte[b1.length+b2.length];
+    System.arraycopy(b1, 0, b3, 0, b1.length);
+    System.arraycopy(b2, 0, b3, b1.length, b2.length);
+    return b3;
+  }
+
+  /**
+   * See {@link #trim(byte[],int,int)}.
+   */
+  static byte[] trim(byte[] buffer, int len)
+  {
+    return trim(buffer, 0, len);
+  }
+
+  /**
+   * Returns a portion of a byte array, possibly zero-filled.
+   *
+   * @param buffer The byte array to trim.
+   * @param off The offset to begin reading at.
+   * @param len The number of bytes to return. This value can be larger
+   *        than <i>buffer.length - off</i>, in which case the rest of the
+   *        returned byte array will be filled with zeros.
+   * @throws IndexOutOfBoundsException If <i>off</i> or <i>len</i> is
+   *         negative, or if <i>off</i> is larger than the byte array's
+   *         length.
+   * @return The trimmed byte array.
+   */
+  static byte[] trim(byte[] buffer, int off, int len)
+  {
+    if (off < 0 || len < 0 || off > buffer.length)
+      throw new IndexOutOfBoundsException("max=" + buffer.length +
+                                          " off=" + off + " len=" + len);
+    if (off == 0 && len == buffer.length)
+      return buffer;
+    byte[] b = new byte[len];
+    System.arraycopy(buffer, off, b, 0, Math.min(len, buffer.length - off));
+    return b;
+  }
+
+  /**
+   * Returns the byte array representation of the given big integer with
+   * the leading zero byte (if any) trimmed off.
+   *
+   * @param bi The integer to trim.
+   * @return The byte representation of the big integer, with any leading
+   *   zero removed.
+   */
+  static byte[] trim(BigInteger bi)
+  {
+    byte[] buf = bi.toByteArray();
+    if (buf[0] == 0x00 && !bi.equals(BigInteger.ZERO))
+      {
+        return trim(buf, 1, buf.length - 1);
+      }
+    else
+      {
+        return buf;
+      }
+  }
+
+  /**
+   * Returns the integer value of <code>{@link
+   * java.lang.System#currentTimeMillis()} / 1000</code>.
+   *
+   * @return The current time, in seconds.
+   */
+  static int unixTime()
+  {
+    return (int) (System.currentTimeMillis() / 1000L);
+  }
+
+  /**
+   * Transform an Object array into another by calling the given method
+   * on each object. The returned object array will have the runtime
+   * type of <i>returnType</i>. For example, the following will transform
+   * array of objects into their String representations, returning a String
+   * array. For example:
+   *
+   * <blockquote><p><code>
+   * String[] strings = (String[]) Util.transform(array, String.class,
+   * "toString", null);
+   * </code></p></blockquote>
+   *
+   * <p>If any element of the given array is <tt>null</tt>, then that
+   * entry in the returned array will also be <tt>null</tt>.
+   *
+   * @param array The array to transform. It does not need to be of
+   *        uniform type.
+   * @param returnType The desired return type of the returned array.
+   *        This must by the <i>component</i> type, not the array type.
+   * @param method The name of the method to invoke from each object.
+   * @param args The arguments to pass to the method, or <tt>null</tt>
+   *        if the method takes no arguments.
+   * @throws InvocationTargetException If an exception occurs while
+   *         calling <i>method</i> of any object.
+   * @throws NoSuchMethodException If <i>method</i> is not the name of
+   *         a valid method of any component of the array.
+   * @throws ClassCastException If the returned object from the method
+   *         is not assignable to the return type.
+   * @throws IllegalArgumentException If <i>args</i> is not appropriate
+   *         for <i>method</i>
+   * @throws IllegalAccessException If <i>method</i> is not accessible.
+   * @throws SecurityException If <i>method</i> is not accessible.
+   * @return An array containing the output of <i>method</i> called on
+   *         each element of <i>array</i> with <i>args</i>. The return type
+   *         of the array will be an array of <i>returnType</i>.
+   */
+  static Object[] transform(Object[] array, Class returnType,
+                            String method, Object[] args)
+    throws InvocationTargetException, NoSuchMethodException,
+           IllegalAccessException
+  {
+    if (args == null)
+      args = new Object[0];
+    Object[] result = (Object[]) Array.newInstance(returnType, array.length);
+    Class[] argsClasses = new Class[args.length];
+    for (int i = 0; i < args.length; i++)
+      {
+        argsClasses[i] = args[i].getClass();
+      }
+    for (int i = 0; i < array.length; i++)
+      {
+        if (array[i] == null)
+          {
+            result[i] = null;
+            continue;
+          }
+        Class objClass = array[i].getClass();
+        Method objMethod = objClass.getMethod(method, argsClasses);
+        Object o = objMethod.invoke(array[i], args);
+        if (!returnType.isAssignableFrom(o.getClass()))
+          throw new ClassCastException();
+        result[i] = o;
+      }
+    return result;
+  }
+
+  /**
+   * Get a system property as a privileged action.
+   *
+   * @param name The name of the property to get.
+   * @return The property named <i>name</i>, or null if the property is
+   *   not set.
+   * @throws SecurityException If the Jessie code still does not have
+   *   permission to read the property.
+   */
+  static String getProperty(final String name)
+  {
+    return (String) AccessController.doPrivileged(
+      new PrivilegedAction()
+      {
+        public Object run()
+        {
+          return System.getProperty(name);
+        }
+      }
+    );
+  }
+
+  /**
+   * Get a security property as a privileged action.
+   *
+   * @param name The name of the property to get.
+   * @return The property named <i>name</i>, or null if the property is
+   *   not set.
+   * @throws SecurityException If the Jessie code still does not have
+   *   permission to read the property.
+   */
+  static String getSecurityProperty(final String name)
+  {
+    return (String) AccessController.doPrivileged(
+      new PrivilegedAction()
+      {
+        public Object run()
+        {
+          return Security.getProperty(name);
+        }
+      }
+    );
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/X509KeyManagerFactory.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/X509KeyManagerFactory.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/X509KeyManagerFactory.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/X509KeyManagerFactory.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,359 @@
+/* X509KeyManagerFactory.java -- X.509 key manager factory.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.Socket;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Enumeration;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.DSAPrivateKey;
+import java.security.interfaces.DSAPublicKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.List;
+
+import javax.crypto.interfaces.DHPrivateKey;
+import javax.crypto.interfaces.DHPublicKey;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactorySpi;
+import javax.net.ssl.ManagerFactoryParameters;
+import javax.net.ssl.X509KeyManager;
+
+import gnu.javax.net.ssl.NullManagerParameters;
+import gnu.javax.net.ssl.PrivateCredentials;
+
+/**
+ * This class implements a {@link javax.net.ssl.KeyManagerFactory} engine
+ * for the ``JessieX509'' algorithm.
+ */
+public class X509KeyManagerFactory extends KeyManagerFactorySpi
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private Manager current;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  public X509KeyManagerFactory()
+  {
+    super();
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  protected KeyManager[] engineGetKeyManagers()
+  {
+    if (current == null)
+      {
+        throw new IllegalStateException();
+      }
+    return new KeyManager[] { current };
+  }
+
+  protected void engineInit(ManagerFactoryParameters params)
+    throws InvalidAlgorithmParameterException
+  {
+    if (params instanceof NullManagerParameters)
+      {
+        current = new Manager(Collections.EMPTY_MAP, Collections.EMPTY_MAP);
+      }
+    else if (params instanceof PrivateCredentials)
+      {
+        List chains = ((PrivateCredentials) params).getCertChains();
+        List keys = ((PrivateCredentials) params).getPrivateKeys();
+        int i = 0;
+        HashMap certMap = new HashMap();
+        HashMap keyMap = new HashMap();
+        Iterator c = chains.iterator();
+        Iterator k = keys.iterator();
+        while (c.hasNext() && k.hasNext())
+          {
+            certMap.put(String.valueOf(i), c.next());
+            keyMap.put(String.valueOf(i), k.next());
+            i++;
+          }
+        current = new Manager(keyMap, certMap);
+      }
+    else
+      {
+        throw new InvalidAlgorithmParameterException();
+      }
+  }
+
+  protected void engineInit(KeyStore store, char[] passwd)
+    throws KeyStoreException, NoSuchAlgorithmException,
+           UnrecoverableKeyException
+  {
+    if (store == null)
+      {
+        String s = Util.getProperty("javax.net.ssl.keyStoreType");
+        if (s == null)
+          s = KeyStore.getDefaultType();
+        store = KeyStore.getInstance(s);
+        s = Util.getProperty("javax.net.ssl.keyStore");
+        if (s == null)
+          return;
+        String p = Util.getProperty("javax.net.ssl.keyStorePassword");
+        try
+          {
+            store.load(new FileInputStream(s), p != null ? p.toCharArray() : null);
+          }
+        catch (IOException ioe)
+          {
+            throw new KeyStoreException(ioe.toString());
+          }
+        catch (CertificateException ce)
+          {
+            throw new KeyStoreException(ce.toString());
+          }
+      }
+
+    HashMap p = new HashMap();
+    HashMap c = new HashMap();
+    Enumeration aliases = store.aliases();
+    UnrecoverableKeyException exception = null;
+    while (aliases.hasMoreElements())
+      {
+        String alias = (String) aliases.nextElement();
+        if (!store.isKeyEntry(alias))
+          {
+            continue;
+          }
+        X509Certificate[] chain = null;
+        Certificate[] chain2 = store.getCertificateChain (alias);
+        if (chain2 != null && chain2.length > 0 &&
+            (chain2[0] instanceof X509Certificate))
+          {
+            chain = toX509Chain(chain2);
+          }
+        else
+          {
+            continue;
+          }
+        PrivateKey key = null;
+        try
+          {
+            key = (PrivateKey) store.getKey(alias, passwd);
+          }
+        catch (UnrecoverableKeyException uke)
+          {
+            exception = uke;
+            continue;
+          }
+        if (key == null)
+          {
+            continue;
+          }
+        p.put(alias, key);
+        c.put(alias, chain);
+      }
+    if (p.isEmpty () && c.isEmpty ())
+      {
+        if (exception != null)
+          {
+            throw exception;
+          }
+        throw new KeyStoreException ("no private credentials found");
+      }
+    current = this.new Manager(p, c);
+  }
+
+  private static X509Certificate[] toX509Chain(Certificate[] chain)
+  {
+    if (chain instanceof X509Certificate[])
+      {
+        return (X509Certificate[]) chain;
+      }
+    X509Certificate[] _chain = new X509Certificate[chain.length];
+    for (int i = 0; i < chain.length; i++)
+      _chain[i] = (X509Certificate) chain[i];
+    return _chain;
+  }
+
+  // Inner class.
+  // -------------------------------------------------------------------------
+
+  private class Manager implements X509KeyManager
+  {
+    // Fields.
+    // -----------------------------------------------------------------------
+
+    private final Map privateKeys;
+    private final Map certChains;
+
+    // Constructor.
+    // -----------------------------------------------------------------------
+
+    Manager(Map privateKeys, Map certChains)
+    {
+      this.privateKeys = privateKeys;
+      this.certChains = certChains;
+    }
+
+    // Instance methods.
+    // -----------------------------------------------------------------------
+
+    public String chooseClientAlias(String[] keyTypes, Principal[] issuers,
+                                    Socket socket)
+    {
+      for (int i = 0; i < keyTypes.length; i++)
+        {
+          String[] s = getClientAliases(keyTypes[i], issuers);
+          if (s.length > 0)
+            return s[0];
+        }
+      return null;
+    }
+
+    public String[] getClientAliases(String keyType, Principal[] issuers)
+    {
+      return getAliases(keyType, issuers);
+    }
+
+    public String chooseServerAlias(String keyType, Principal[] issuers,
+                                    Socket socket)
+    {
+      String[] s = getServerAliases(keyType, issuers);
+      if (s.length > 0)
+        return s[0];
+      return null;
+    }
+
+    public String[] getServerAliases(String keyType, Principal[] issuers)
+    {
+      return getAliases(keyType, issuers);
+    }
+
+    private String[] getAliases(String keyType, Principal[] issuers)
+    {
+      LinkedList l = new LinkedList();
+      for (Iterator i = privateKeys.keySet().iterator(); i.hasNext(); )
+        {
+          String alias = (String) i.next();
+          X509Certificate[] chain = getCertificateChain(alias);
+          if (chain.length == 0)
+            continue;
+          PrivateKey privKey = getPrivateKey(alias);
+          if (privKey == null)
+            continue;
+          PublicKey pubKey = chain[0].getPublicKey();
+          if (keyType.equals("RSA") || keyType.equals("DHE_RSA") ||
+              keyType.equals("SRP_RSA") || keyType.equals("rsa_sign"))
+            {
+              if (!(privKey instanceof RSAPrivateKey) ||
+                  !(pubKey instanceof RSAPublicKey))
+                continue;
+            }
+          if (keyType.equals("DHE_DSS") || keyType.equals("dss_sign") ||
+              keyType.equals("SRP_DSS"))
+            {
+              if (!(privKey instanceof DSAPrivateKey) ||
+                  !(pubKey instanceof DSAPublicKey))
+                continue;
+            }
+          if (keyType.equals("DH_RSA") || keyType.equals("rsa_fixed_dh"))
+            {
+              if (!(privKey instanceof DHPrivateKey) ||
+                  !(pubKey instanceof DHPublicKey))
+                continue;
+              if (!chain[0].getSigAlgName().equalsIgnoreCase("RSA"))
+                continue;
+            }
+          if (keyType.equals("DH_DSS") || keyType.equals("dss_fixed_dh"))
+            {
+              if (!(privKey instanceof DHPrivateKey) ||
+                  !(pubKey instanceof DHPublicKey))
+                continue;
+              if (!chain[0].getSigAlgName().equalsIgnoreCase("DSA"))
+                continue;
+            }
+          if (issuers == null || issuers.length == 0)
+            {
+              l.add(alias);
+              continue;
+            }
+          for (int j = 0; j < issuers.length; j++)
+            if (chain[0].getIssuerDN().equals(issuers[j]))
+              {
+                l.add(alias);
+                break;
+              }
+        }
+      return (String[]) l.toArray(new String[l.size()]);
+    }
+
+    public X509Certificate[] getCertificateChain(String alias)
+    {
+      X509Certificate[] c = (X509Certificate[]) certChains.get(alias);
+      return c != null ? (X509Certificate[]) c.clone() : null;
+    }
+
+    public PrivateKey getPrivateKey(String alias)
+    {
+      return (PrivateKey) privateKeys.get(alias);
+    }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/X509TrustManagerFactory.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/X509TrustManagerFactory.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/X509TrustManagerFactory.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/X509TrustManagerFactory.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,298 @@
+/* X509TrustManagerFactory.java -- X.509 trust manager factory.
+   Copyright (C) 2006  Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.LinkedList;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Security;
+import java.security.SignatureException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.ManagerFactoryParameters;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactorySpi;
+import javax.net.ssl.X509TrustManager;
+
+import gnu.javax.net.ssl.NullManagerParameters;
+import gnu.javax.net.ssl.StaticTrustAnchors;
+
+/**
+ * This class implements a {@link javax.net.ssl.TrustManagerFactory} engine
+ * for the ``JessieX509'' algorithm.
+ */
+public class X509TrustManagerFactory extends TrustManagerFactorySpi
+{
+
+  // Constants and fields.
+  // -------------------------------------------------------------------------
+
+  /**
+   * The location of the JSSE key store.
+   */
+  private static final String JSSE_CERTS = Util.getProperty("java.home")
+    + Util.getProperty("file.separator") + "lib"
+    + Util.getProperty("file.separator") + "security"
+    + Util.getProperty("file.separator") + "jssecerts";
+
+  /**
+   * The location of the system key store, containing the CA certs.
+   */
+  private static final String CA_CERTS = Util.getProperty("java.home")
+    + Util.getProperty("file.separator") + "lib"
+    + Util.getProperty("file.separator") + "security"
+    + Util.getProperty("file.separator") + "cacerts";
+
+  private Manager current;
+
+  // Construtors.
+  // -------------------------------------------------------------------------
+
+  public X509TrustManagerFactory()
+  {
+    super();
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  protected TrustManager[] engineGetTrustManagers()
+  {
+    if (current == null)
+      {
+        throw new IllegalStateException("not initialized");
+      }
+    return new TrustManager[] { current };
+  }
+
+  protected void engineInit(ManagerFactoryParameters params)
+    throws InvalidAlgorithmParameterException
+  {
+    if (params instanceof StaticTrustAnchors)
+      {
+        current = new Manager(((StaticTrustAnchors) params).getCertificates());
+      }
+    else if (params instanceof NullManagerParameters)
+      {
+        current = new Manager(new X509Certificate[0]);
+      }
+    else
+      {
+        throw new InvalidAlgorithmParameterException();
+      }
+  }
+
+  protected void engineInit(KeyStore store) throws KeyStoreException
+  {
+    if (store == null)
+      {
+        String s = Util.getProperty("javax.net.ssl.trustStoreType");
+        if (s == null)
+          s = KeyStore.getDefaultType();
+        store = KeyStore.getInstance(s);
+        try
+          {
+            s = Util.getProperty("javax.net.ssl.trustStore");
+            FileInputStream in = null;
+            if (s == null)
+              {
+                try
+                  {
+                    in = new FileInputStream(JSSE_CERTS);
+                  }
+                catch (IOException e)
+                  {
+                    in = new FileInputStream(CA_CERTS);
+                  }
+              }
+            else
+              {
+                in = new FileInputStream(s);
+              }
+            String p = Util.getProperty("javax.net.ssl.trustStorePassword");
+            store.load(in, p != null ? p.toCharArray() : null);
+          }
+        catch (IOException ioe)
+          {
+            throw new KeyStoreException(ioe.toString());
+          }
+        catch (CertificateException ce)
+          {
+            throw new KeyStoreException(ce.toString());
+          }
+        catch (NoSuchAlgorithmException nsae)
+          {
+            throw new KeyStoreException(nsae.toString());
+          }
+      }
+
+    LinkedList l = new LinkedList();
+    Enumeration aliases = store.aliases();
+    while (aliases.hasMoreElements())
+      {
+        String alias = (String) aliases.nextElement();
+        if (!store.isCertificateEntry(alias))
+          continue;
+        Certificate c = store.getCertificate(alias);
+        if (!(c instanceof X509Certificate))
+          continue;
+        l.add(c);
+      }
+    current = this.new Manager((X509Certificate[])
+                               l.toArray(new X509Certificate[l.size()]));
+  }
+
+  // Inner class.
+  // -------------------------------------------------------------------------
+
+  /**
+   * The actual manager implementation returned.
+   */
+  private class Manager implements X509TrustManager
+  {
+
+    // Fields.
+    // -----------------------------------------------------------------------
+
+    private final X509Certificate[] trusted;
+
+    // Constructor.
+    // -----------------------------------------------------------------------
+
+    Manager(X509Certificate[] trusted)
+    {
+      this.trusted = trusted;
+    }
+
+    // Instance methodns.
+    // -----------------------------------------------------------------------
+
+    public void checkClientTrusted(X509Certificate[] chain, String authType)
+      throws CertificateException
+    {
+      checkTrusted(chain, authType);
+    }
+
+    public void checkServerTrusted(X509Certificate[] chain, String authType)
+      throws CertificateException
+    {
+      checkTrusted(chain, authType);
+    }
+
+    public X509Certificate[] getAcceptedIssuers()
+    {
+      if (trusted == null)
+        return new X509Certificate[0];
+      return (X509Certificate[]) trusted.clone();
+    }
+
+    // Own methods.
+    // -----------------------------------------------------------------------
+
+    private void checkTrusted(X509Certificate[] chain, String authType)
+      throws CertificateException
+    {
+      // NOTE: this is not a full-featured path validation algorithm.
+      //
+      // Step 0: check if the target is valid now.
+      chain[0].checkValidity();
+
+      // Step 1: verify that the chain is complete and valid.
+      for (int i = 1; i < chain.length; i++)
+        {
+          chain[i].checkValidity();
+          try
+            {
+              chain[i-1].verify(chain[i].getPublicKey());
+            }
+          catch (NoSuchAlgorithmException nsae)
+            {
+              throw new CertificateException(nsae.toString());
+            }
+          catch (NoSuchProviderException nspe)
+            {
+              throw new CertificateException(nspe.toString());
+            }
+          catch (InvalidKeyException ike)
+            {
+              throw new CertificateException(ike.toString());
+            }
+          catch (SignatureException se)
+            {
+              throw new CertificateException(se.toString());
+            }
+        }
+
+      // Step 2: verify that the root of the chain was issued by a trust anchor.
+      if (trusted == null || trusted.length == 0)
+        throw new CertificateException("no trust anchors");
+      for (int i = 0; i < trusted.length; i++)
+        {
+          try
+            {
+              trusted[i].checkValidity();
+              chain[chain.length-1].verify(trusted[i].getPublicKey());
+              return;
+            }
+          catch (Exception e)
+            {
+            }
+          //catch (CertificateException ce) { }
+          //catch (NoSuchAlgorithmException nsae) { }
+          //catch (NoSuchProviderException nspe) { }
+          //catch (InvalidKeyException ike) { }
+          //catch (SignatureException se) { }
+        }
+      throw new CertificateException();
+    }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/XMLSessionContext.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/XMLSessionContext.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/XMLSessionContext.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/net/ssl/provider/XMLSessionContext.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,619 @@
+/* XMLSessionContext.java -- XML-encoded persistent SSL sessions.
+   Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.  */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+
+import java.security.SecureRandom;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateFactory;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeSet;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import gnu.javax.crypto.mac.IMac;
+import gnu.javax.crypto.mac.MacFactory;
+import gnu.javax.crypto.mode.IMode;
+import gnu.javax.crypto.mode.ModeFactory;
+import gnu.javax.crypto.prng.IPBE;
+import gnu.java.security.prng.IRandom;
+import gnu.java.security.prng.PRNGFactory;
+
+import gnu.javax.net.ssl.Base64;
+
+/**
+ * An implementation of session contexts that stores session data on the
+ * filesystem in a simple XML-encoded file.
+ */
+class XMLSessionContext extends SessionContext
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final File file;
+  private final IRandom pbekdf;
+  private final boolean compress;
+  private final SecureRandom random;
+  private boolean encoding;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  XMLSessionContext() throws IOException, SAXException
+  {
+    file = new File(Util.getSecurityProperty("jessie.SessionContext.xml.file"));
+    String password = Util.getSecurityProperty("jessie.SessionContext.xml.password");
+    compress = new Boolean(Util.getSecurityProperty("jessie.SessionContext.xml.compress")).booleanValue();
+    if (password == null)
+      {
+        password = "";
+      }
+    pbekdf = PRNGFactory.getInstance("PBKDF2-HMAC-SHA1");
+    HashMap kdfattr = new HashMap();
+    kdfattr.put(IPBE.PASSWORD, password.toCharArray());
+    // Dummy salt. This is replaced by a real salt when encoding.
+    kdfattr.put(IPBE.SALT, new byte[8]);
+    kdfattr.put(IPBE.ITERATION_COUNT, new Integer(1000));
+    pbekdf.init(kdfattr);
+    encoding = false;
+    if (file.exists())
+      {
+        decode();
+      }
+    encoding = true;
+    random = new SecureRandom ();
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  synchronized boolean addSession(Session.ID sessionId, Session session)
+  {
+    boolean ret = super.addSession(sessionId, session);
+    if (ret && encoding)
+      {
+        try
+          {
+            encode();
+          }
+        catch (IOException ioe)
+          {
+          }
+      }
+    return ret;
+  }
+
+  synchronized void notifyAccess(Session session)
+  {
+    try
+      {
+        encode();
+      }
+    catch (IOException ioe)
+      {
+      }
+  }
+
+  synchronized boolean removeSession(Session.ID sessionId)
+  {
+    if (super.removeSession(sessionId))
+      {
+        try
+          {
+            encode();
+          }
+        catch (Exception x)
+          {
+          }
+        return true;
+      }
+    return false;
+  }
+
+  private void decode() throws IOException, SAXException
+  {
+    SAXParser parser = null;
+    try
+      {
+        parser = SAXParserFactory.newInstance().newSAXParser();
+      }
+    catch (Exception x)
+      {
+        throw new Error(x.toString());
+      }
+    SAXHandler handler = new SAXHandler(this, pbekdf);
+    InputStream in = null;
+    if (compress)
+      in = new GZIPInputStream(new FileInputStream(file));
+    else
+      in = new FileInputStream(file);
+    parser.parse(in, handler);
+  }
+
+  private void encode() throws IOException
+  {
+    IMode cipher = ModeFactory.getInstance("CBC", "AES", 16);
+    HashMap cipherAttr = new HashMap();
+    IMac mac = MacFactory.getInstance("HMAC-SHA1");
+    HashMap macAttr = new HashMap();
+    byte[] key = new byte[32];
+    byte[] iv = new byte[16];
+    byte[] mackey = new byte[20];
+    byte[] salt = new byte[8];
+    byte[] encryptedSecret = new byte[48];
+    cipherAttr.put(IMode.KEY_MATERIAL, key);
+    cipherAttr.put(IMode.IV, iv);
+    cipherAttr.put(IMode.STATE, new Integer(IMode.ENCRYPTION));
+    macAttr.put(IMac.MAC_KEY_MATERIAL, mackey);
+    PrintStream out = null;
+    if (compress)
+      {
+        out = new PrintStream(new GZIPOutputStream(new FileOutputStream(file)));
+      }
+    else
+      {
+        out = new PrintStream(new FileOutputStream(file));
+      }
+    out.println("<?xml version=\"1.0\"?>");
+    out.println("<!DOCTYPE sessions [");
+    out.println("  <!ELEMENT sessions (session*)>");
+    out.println("  <!ATTLIST sessions size CDATA \"0\">");
+    out.println("  <!ATTLIST sessions timeout CDATA \"86400\">");
+    out.println("  <!ELEMENT session (peer, certificates?, secret)>");
+    out.println("  <!ATTLIST session id CDATA #REQUIRED>");
+    out.println("  <!ATTLIST session protocol (SSLv3|TLSv1|TLSv1.1) #REQUIRED>");
+    out.println("  <!ATTLIST session suite CDATA #REQUIRED>");
+    out.println("  <!ATTLIST session created CDATA #REQUIRED>");
+    out.println("  <!ATTLIST session timestamp CDATA #REQUIRED>");
+    out.println("  <!ELEMENT peer (certificates?)>");
+    out.println("  <!ATTLIST peer host CDATA #REQUIRED>");
+    out.println("  <!ELEMENT certificates (#PCDATA)>");
+    out.println("  <!ATTLIST certificates type CDATA \"X.509\">");
+    out.println("  <!ELEMENT secret (#PCDATA)>");
+    out.println("  <!ATTLIST secret salt CDATA #REQUIRED>");
+    out.println("]>");
+    out.println();
+    out.print("<sessions size=\"");
+    out.print(cacheSize);
+    out.print("\" timeout=\"");
+    out.print(timeout);
+    out.println("\">");
+    for (Iterator it = sessions.entrySet().iterator(); it.hasNext(); )
+      {
+        Map.Entry entry = (Map.Entry) it.next();
+        Session.ID id = (Session.ID) entry.getKey();
+        Session session = (Session) entry.getValue();
+        if (!session.valid)
+          {
+            continue;
+          }
+        out.print("<session id=\"");
+        out.print(Base64.encode(id.getId(), 0));
+        out.print("\" suite=\"");
+        out.print(session.getCipherSuite());
+        out.print("\" protocol=\"");
+        out.print(session.getProtocol());
+        out.print("\" created=\"");
+        out.print(session.getCreationTime());
+        out.print("\" timestamp=\"");
+        out.print(session.getLastAccessedTime());
+        out.println("\">");
+        out.print("<peer host=\"");
+        out.print(session.getPeerHost());
+        out.println("\">");
+        Certificate[] certs = session.getPeerCertificates();
+        if (certs != null && certs.length > 0)
+          {
+            out.print("<certificates type=\"");
+            out.print(certs[0].getType());
+            out.println("\">");
+            for (int i = 0; i < certs.length; i++)
+              {
+                out.println("-----BEGIN CERTIFICATE-----");
+                try
+                  {
+                    out.print(Base64.encode(certs[i].getEncoded(), 70));
+                  }
+                catch (CertificateEncodingException cee)
+                  {
+                    throw new IOException(cee.toString());
+                  }
+                out.println("-----END CERTIFICATE-----");
+              }
+            out.println("</certificates>");
+          }
+        out.println("</peer>");
+        certs = session.getLocalCertificates();
+        if (certs != null && certs.length > 0)
+          {
+            out.print("<certificates type=\"");
+            out.print(certs[0].getType());
+            out.println("\">");
+            for (int i = 0; i < certs.length; i++)
+              {
+                out.println("-----BEGIN CERTIFICATE-----");
+                try
+                  {
+                    out.print(Base64.encode(certs[i].getEncoded(), 70));
+                  }
+                catch (CertificateEncodingException cee)
+                  {
+                    throw new IOException(cee.toString());
+                  }
+                out.println("-----END CERTIFICATE-----");
+              }
+            out.println("</certificates>");
+          }
+        random.nextBytes (salt);
+        pbekdf.init(Collections.singletonMap(IPBE.SALT, salt));
+        try
+          {
+            pbekdf.nextBytes(key, 0, key.length);
+            pbekdf.nextBytes(iv, 0, iv.length);
+            pbekdf.nextBytes(mackey, 0, mackey.length);
+            cipher.reset();
+            cipher.init(cipherAttr);
+            mac.init(macAttr);
+          }
+        catch (Exception ex)
+          {
+            throw new Error(ex.toString());
+          }
+        for (int i = 0; i < session.masterSecret.length; i += 16)
+          {
+            cipher.update(session.masterSecret, i, encryptedSecret, i);
+          }
+        mac.update(encryptedSecret, 0, encryptedSecret.length);
+        byte[] macValue = mac.digest();
+        out.print("<secret salt=\"");
+        out.print(Base64.encode(salt, 0));
+        out.println("\">");
+        out.print(Base64.encode(Util.concat(encryptedSecret, macValue), 70));
+        out.println("</secret>");
+        out.println("</session>");
+      }
+    out.println("</sessions>");
+    out.close();
+  }
+
+  // Inner class.
+  // -------------------------------------------------------------------------
+
+  private class SAXHandler extends DefaultHandler
+  {
+
+    // Field.
+    // -----------------------------------------------------------------------
+
+    private SessionContext context;
+    private Session current;
+    private IRandom pbekdf;
+    private StringBuffer buf;
+    private String certType;
+    private int state;
+    private IMode cipher;
+    private HashMap cipherAttr;
+    private IMac mac;
+    private HashMap macAttr;
+    private byte[] key;
+    private byte[] iv;
+    private byte[] mackey;
+
+    private static final int START      = 0;
+    private static final int SESSIONS   = 1;
+    private static final int SESSION    = 2;
+    private static final int PEER       = 3;
+    private static final int PEER_CERTS = 4;
+    private static final int CERTS      = 5;
+    private static final int SECRET     = 6;
+
+    // Constructor.
+    // -----------------------------------------------------------------------
+
+    SAXHandler(SessionContext context, IRandom pbekdf)
+    {
+      this.context = context;
+      this.pbekdf = pbekdf;
+      buf = new StringBuffer();
+      state = START;
+      cipher = ModeFactory.getInstance("CBC", "AES", 16);
+      cipherAttr = new HashMap();
+      mac = MacFactory.getInstance("HMAC-SHA1");
+      macAttr = new HashMap();
+      key = new byte[32];
+      iv = new byte[16];
+      mackey = new byte[20];
+      cipherAttr.put(IMode.KEY_MATERIAL, key);
+      cipherAttr.put(IMode.IV, iv);
+      cipherAttr.put(IMode.STATE, new Integer(IMode.DECRYPTION));
+      macAttr.put(IMac.MAC_KEY_MATERIAL, mackey);
+    }
+
+    // Instance methods.
+    // -----------------------------------------------------------------------
+
+    public void startElement(String u, String n, String qname, Attributes attr)
+      throws SAXException
+    {
+      qname = qname.toLowerCase();
+      switch (state)
+        {
+        case START:
+          if (qname.equals("sessions"))
+            {
+              try
+                {
+                  timeout = Integer.parseInt(attr.getValue("timeout"));
+                  cacheSize = Integer.parseInt(attr.getValue("size"));
+                  if (timeout <= 0 || cacheSize < 0)
+                    throw new SAXException("timeout or cache size out of range");
+                }
+              catch (NumberFormatException nfe)
+                {
+                  throw new SAXException(nfe);
+                }
+              state = SESSIONS;
+            }
+          else
+            throw new SAXException("expecting sessions");
+          break;
+
+        case SESSIONS:
+          if (qname.equals("session"))
+            {
+              try
+                {
+                  current = new Session(Long.parseLong(attr.getValue("created")));
+                  current.enabledSuites = new ArrayList(SSLSocket.supportedSuites);
+                  current.enabledProtocols = new TreeSet(SSLSocket.supportedProtocols);
+                  current.context = context;
+                  current.sessionId = new Session.ID(Base64.decode(attr.getValue("id")));
+                  current.setLastAccessedTime(Long.parseLong(attr.getValue("timestamp")));
+                }
+              catch (Exception ex)
+                {
+                  throw new SAXException(ex);
+                }
+              String prot = attr.getValue("protocol");
+              if (prot.equals("SSLv3"))
+                current.protocol = ProtocolVersion.SSL_3;
+              else if (prot.equals("TLSv1"))
+                current.protocol = ProtocolVersion.TLS_1;
+              else if (prot.equals("TLSv1.1"))
+                current.protocol = ProtocolVersion.TLS_1_1;
+              else
+                throw new SAXException("bad protocol: " + prot);
+              current.cipherSuite = CipherSuite.forName(attr.getValue("suite"));
+              state = SESSION;
+            }
+          else
+            throw new SAXException("expecting session");
+          break;
+
+        case SESSION:
+          if (qname.equals("peer"))
+            {
+              current.peerHost = attr.getValue("host");
+              state = PEER;
+            }
+          else if (qname.equals("certificates"))
+            {
+              certType = attr.getValue("type");
+              state = CERTS;
+            }
+          else if (qname.equals("secret"))
+            {
+              byte[] salt = null;
+              try
+                {
+                  salt = Base64.decode(attr.getValue("salt"));
+                }
+              catch (IOException ioe)
+                {
+                  throw new SAXException(ioe);
+                }
+              pbekdf.init(Collections.singletonMap(IPBE.SALT, salt));
+              state = SECRET;
+            }
+          else
+            throw new SAXException("bad element: " + qname);
+          break;
+
+        case PEER:
+          if (qname.equals("certificates"))
+            {
+              certType = attr.getValue("type");
+              state = PEER_CERTS;
+            }
+          else
+            throw new SAXException("bad element: " + qname);
+          break;
+
+        default:
+          throw new SAXException("bad element: " + qname);
+        }
+    }
+
+    public void endElement(String uri, String name, String qname)
+      throws SAXException
+    {
+      qname = qname.toLowerCase();
+      switch (state)
+        {
+        case SESSIONS:
+          if (qname.equals("sessions"))
+            state = START;
+          else
+            throw new SAXException("expecting sessions");
+          break;
+
+        case SESSION:
+          if (qname.equals("session"))
+            {
+              current.valid = true;
+              context.addSession(current.sessionId, current);
+              state = SESSIONS;
+            }
+          else
+            throw new SAXException("expecting session");
+          break;
+
+        case PEER:
+          if (qname.equals("peer"))
+            state = SESSION;
+          else
+            throw new SAXException("unexpected element: " + qname);
+          break;
+
+        case PEER_CERTS:
+          if (qname.equals("certificates"))
+            {
+              try
+                {
+                  CertificateFactory fact = CertificateFactory.getInstance(certType);
+                  current.peerCerts = (Certificate[])
+                    fact.generateCertificates(new ByteArrayInputStream(
+                      buf.toString().getBytes())).toArray(new Certificate[0]);
+                }
+              catch (Exception ex)
+                {
+                  throw new SAXException(ex);
+                }
+              current.peerVerified = true;
+              state = PEER;
+            }
+          else
+            throw new SAXException("unexpected element: " + qname);
+          break;
+
+        case CERTS:
+          if (qname.equals("certificates"))
+            {
+              try
+                {
+                  CertificateFactory fact = CertificateFactory.getInstance(certType);
+                  current.localCerts = (Certificate[])
+                    fact.generateCertificates(new ByteArrayInputStream(
+                      buf.toString().getBytes())).toArray(new Certificate[0]);
+                }
+              catch (Exception ex)
+                {
+                  throw new SAXException(ex);
+                }
+              state = SESSION;
+            }
+          else
+            throw new SAXException("unexpected element: " + qname);
+          break;
+
+        case SECRET:
+          if (qname.equals("secret"))
+            {
+              byte[] encrypted = null;
+              try
+                {
+                  encrypted = Base64.decode(buf.toString());
+                  if (encrypted.length != 68)
+                    throw new IOException("encrypted secret not 68 bytes long");
+                  pbekdf.nextBytes(key, 0, key.length);
+                  pbekdf.nextBytes(iv, 0, iv.length);
+                  pbekdf.nextBytes(mackey, 0, mackey.length);
+                  cipher.reset();
+                  cipher.init(cipherAttr);
+                  mac.init(macAttr);
+                }
+              catch (Exception ex)
+                {
+                  throw new SAXException(ex);
+                }
+              mac.update(encrypted, 0, 48);
+              byte[] macValue = mac.digest();
+              for (int i = 0; i < macValue.length; i++)
+                {
+                  if (macValue[i] != encrypted[48+i])
+                    throw new SAXException("MAC mismatch");
+                }
+              current.masterSecret = new byte[48];
+              for (int i = 0; i < current.masterSecret.length; i += 16)
+                {
+                  cipher.update(encrypted, i, current.masterSecret, i);
+                }
+              state = SESSION;
+            }
+          else
+            throw new SAXException("unexpected element: " + qname);
+          break;
+
+        default:
+          throw new SAXException("unexpected element: " + qname);
+        }
+      buf.setLength(0);
+    }
+
+    public void characters(char[] ch, int off, int len) throws SAXException
+    {
+      if (state != CERTS && state != PEER_CERTS && state != SECRET)
+        {
+          throw new SAXException("illegal character data");
+        }
+      buf.append(ch, off, len);
+    }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/print/CupsIppOperation.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/print/CupsIppOperation.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/print/CupsIppOperation.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/print/CupsIppOperation.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,99 @@
+/* CupsIppOperation.java -- 
+   Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.print;
+
+
+/**
+ * Operations as provided by CUPS up to version 1.1
+ * <p>
+ * See: CUPS Implementation of IPP, chapter 3.2<br>
+ * http://www.cups.org/doc-1.1/ipp.html
+ * </p>
+ * 
+ * @author Wolfgang Baer (WBaer at gmx.de)
+ */
+public final class CupsIppOperation
+{
+
+  /** Get the default destination - since CUPS 1.0 */
+  public static final int CUPS_GET_DEFAULT = 0x4001;  
+ 
+  /** Get all of the available printers - since CUPS 1.0 */
+  public static final int CUPS_GET_PRINTERS =  0x4002;
+  
+  /** Add or modify a printer - since CUPS 1.0 */
+  public static final int CUPS_ADD_MODIFY_PRINTER =  0x4003;
+  
+  /** Delete a printer - since CUPS 1.0 */
+  public static final int CUPS_DELETE_PRINTER =  0x4004;
+  
+  /** Get all of the available printer classes - since CUPS 1.0 */
+  public static final int CUPS_GET_CLASSES =  0x4005;
+  
+  /** Add or modify a printer class - since CUPS 1.0 */
+  public static final int CUPS_ADD_MODIFY_CLASS =  0x4006;
+  
+  /** Delete a printer class - since CUPS 1.0 */
+  public static final int CUPS_DELETE_CLASS =  0x4007;
+  
+  /** Accept jobs on a printer or printer class - since CUPS 1.0 */
+  public static final int CUPS_ACCEPT_JOBS = 0x4008;
+  
+  /** Reject jobs on a printer or printer class - since CUPS 1.0 */
+  public static final int CUPS_REJECT_JOBS = 0x4009;
+  
+  /** Set the default destination - since CUPS 1.0 */
+  public static final int CUPS_SET_DEFAULT = 0x400A;
+  
+  /** Get all of the available PPDs - since CUPS 1.1 */
+  public static final int CUPS_GET_DEVICES = 0x400B;
+  
+  /** Get all of the available PPDs - since CUPS 1.1 */
+  public static final int CUPS_GET_PPDS = 0x400C;
+  
+  /** Move a job to a different printer - since CUPS 1.1 */
+  public static final int CUPS_MOVE_JOB = 0x400D;
+  
+  
+  private CupsIppOperation()
+  { 
+    // not to be instantiated
+  }
+  
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/print/CupsMediaMapping.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/print/CupsMediaMapping.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/print/CupsMediaMapping.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/print/CupsMediaMapping.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,176 @@
+/* CupsMediaMapping.java -- 
+   Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.print;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.print.attribute.standard.MediaSizeName;
+
+/**
+ * Provides the currently known mappings of the media attribute
+ * values of the CUPS printing system to the IPP standard values.
+ * <p>
+ * The mapping is used to build up print service specific mappings
+ * for use of media attribute translation between Java JPS API and
+ * CUPS.
+ * </p>
+ *  
+ * @author Wolfgang Baer (WBaer at gmx.de)
+ */
+public class CupsMediaMapping
+{
+  // the mapping map  
+  private static final HashMap ippByCups = new HashMap();
+
+  /**
+   * Initialize currently known mappings.
+   */
+  static
+    {
+      ippByCups.put("Postcard", MediaSizeName.JAPANESE_POSTCARD);
+      ippByCups.put("Statement", MediaSizeName.INVOICE);
+      
+      ippByCups.put("Letter", MediaSizeName.NA_LETTER);
+      ippByCups.put("Executive", MediaSizeName.EXECUTIVE);
+      ippByCups.put("Legal", MediaSizeName.NA_LEGAL);
+      
+      ippByCups.put("A0", MediaSizeName.ISO_A0);
+      ippByCups.put("A1", MediaSizeName.ISO_A1);
+      ippByCups.put("A2", MediaSizeName.ISO_A2);
+      ippByCups.put("A3", MediaSizeName.ISO_A3);
+      ippByCups.put("A4", MediaSizeName.ISO_A4);
+      ippByCups.put("A5", MediaSizeName.ISO_A5);
+      ippByCups.put("A6", MediaSizeName.ISO_A6);
+      ippByCups.put("A7", MediaSizeName.ISO_A7);
+      ippByCups.put("A8", MediaSizeName.ISO_A8);
+      ippByCups.put("A9", MediaSizeName.ISO_A9);
+      ippByCups.put("A10", MediaSizeName.ISO_A10);
+            
+      ippByCups.put("B0", MediaSizeName.JIS_B0);
+      ippByCups.put("B1", MediaSizeName.JIS_B1);
+      ippByCups.put("B2", MediaSizeName.JIS_B2);
+      ippByCups.put("B3", MediaSizeName.JIS_B3);
+      ippByCups.put("B4", MediaSizeName.JIS_B4);
+      ippByCups.put("B5", MediaSizeName.JIS_B5);
+      ippByCups.put("B6", MediaSizeName.JIS_B6);
+      ippByCups.put("B7", MediaSizeName.JIS_B7);
+      ippByCups.put("B8", MediaSizeName.JIS_B8);
+      ippByCups.put("B9", MediaSizeName.JIS_B9);
+      ippByCups.put("B10", MediaSizeName.JIS_B10);
+            
+      ippByCups.put("ISOB0", MediaSizeName.ISO_B0);
+      ippByCups.put("ISOB1", MediaSizeName.ISO_B1);
+      ippByCups.put("ISOB2", MediaSizeName.ISO_B2);
+      ippByCups.put("ISOB3", MediaSizeName.ISO_B3);
+      ippByCups.put("ISOB4", MediaSizeName.ISO_B4);
+      ippByCups.put("ISOB5", MediaSizeName.ISO_B5);
+      ippByCups.put("ISOB6", MediaSizeName.ISO_B6);
+      ippByCups.put("ISOB7", MediaSizeName.ISO_B7);
+      ippByCups.put("ISOB8", MediaSizeName.ISO_B8);
+      ippByCups.put("ISOB9", MediaSizeName.ISO_B9);
+      ippByCups.put("ISOB10", MediaSizeName.ISO_B10);
+      ippByCups.put("EnvISOB0", MediaSizeName.ISO_B0);
+      ippByCups.put("EnvISOB1", MediaSizeName.ISO_B1);
+      ippByCups.put("EnvISOB2", MediaSizeName.ISO_B2);
+      ippByCups.put("EnvISOB3", MediaSizeName.ISO_B3);
+      ippByCups.put("EnvISOB4", MediaSizeName.ISO_B4);
+      ippByCups.put("EnvISOB5", MediaSizeName.ISO_B5);
+      ippByCups.put("EnvISOB6", MediaSizeName.ISO_B6);
+      ippByCups.put("EnvISOB7", MediaSizeName.ISO_B7);
+      ippByCups.put("EnvISOB8", MediaSizeName.ISO_B8);
+      ippByCups.put("EnvISOB9", MediaSizeName.ISO_B9);
+      ippByCups.put("EnvISOB10", MediaSizeName.ISO_B10);
+      
+      ippByCups.put("C0", MediaSizeName.ISO_C0);
+      ippByCups.put("C1", MediaSizeName.ISO_C1);
+      ippByCups.put("C2", MediaSizeName.ISO_C2);
+      ippByCups.put("C3", MediaSizeName.ISO_C3);
+      ippByCups.put("C4", MediaSizeName.ISO_C4);
+      ippByCups.put("C5", MediaSizeName.ISO_C5);
+      ippByCups.put("C6", MediaSizeName.ISO_C6);
+
+      ippByCups.put("EnvPersonal", MediaSizeName.PERSONAL_ENVELOPE);
+      ippByCups.put("EnvMonarch", MediaSizeName.MONARCH_ENVELOPE);
+      ippByCups.put("Monarch", MediaSizeName.MONARCH_ENVELOPE);
+      ippByCups.put("Env9", MediaSizeName.NA_NUMBER_9_ENVELOPE);
+      ippByCups.put("Env10", MediaSizeName.NA_NUMBER_10_ENVELOPE);
+      ippByCups.put("Env11", MediaSizeName.NA_NUMBER_11_ENVELOPE);
+      ippByCups.put("Env12", MediaSizeName.NA_NUMBER_12_ENVELOPE);
+      ippByCups.put("Env14", MediaSizeName.NA_NUMBER_14_ENVELOPE);
+      ippByCups.put("c8x10", MediaSizeName.NA_8X10);
+      
+      ippByCups.put("EnvDL", MediaSizeName.ISO_DESIGNATED_LONG);
+      ippByCups.put("DL", MediaSizeName.ISO_DESIGNATED_LONG);
+      ippByCups.put("EnvC0", MediaSizeName.ISO_C0);
+      ippByCups.put("EnvC1", MediaSizeName.ISO_C1);
+      ippByCups.put("EnvC2", MediaSizeName.ISO_C2);
+      ippByCups.put("EnvC3", MediaSizeName.ISO_C3);
+      ippByCups.put("EnvC4", MediaSizeName.ISO_C4);
+      ippByCups.put("EnvC5", MediaSizeName.ISO_C5);
+      ippByCups.put("EnvC6", MediaSizeName.ISO_C6);      
+    }
+    
+  /**
+   * Returns the IPP media name of the given cups name.
+   * 
+   * @param cupsName the name in cups
+   * @return The IPP name if a mapping is known, <code>null</code> otherwise.
+   */
+  public static final String getIppName(String cupsName)
+  {
+    return (String) ippByCups.get(cupsName);
+  }
+  
+  /**
+   * Returns the mapping map for iteration.
+   * 
+   * @return The mapping map as unmodifiable map.
+   */
+  public static final Map getMappingMap()
+  {
+    return Collections.unmodifiableMap(ippByCups);
+  }
+
+  private CupsMediaMapping() 
+  {
+    // not to be instantiated
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/print/CupsPrintService.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/print/CupsPrintService.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/print/CupsPrintService.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/print/CupsPrintService.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,104 @@
+/* CupsPrintService.java -- Cups specific implementation subclass
+   Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.print;
+
+import gnu.javax.print.ipp.IppException;
+import gnu.javax.print.ipp.IppMultiDocPrintService;
+import gnu.javax.print.ipp.IppResponse;
+
+import java.net.URI;
+
+import javax.print.DocFlavor;
+import javax.print.attribute.AttributeSet;
+
+/**
+ * Implementation of the PrintService/MultiDocPrintService 
+ * interface for Cups printers (supports Cups 1.1 and up)
+ * 
+ * @author Wolfgang Baer (WBaer at gmx.de)
+ */
+public final class CupsPrintService extends IppMultiDocPrintService
+{
+
+  /**
+   * Creates a <code>CupsPrintService</code> object.
+   * 
+   * @param uri the URI of the IPP printer.
+   * @param username the user of this print service.
+   * @param password the password of the user.
+   * 
+   * @throws IppException if an error during connection occurs.
+   */
+  public CupsPrintService(URI uri, String username, String password)
+      throws IppException
+  {
+    super(uri, username, password);
+  }  
+  
+  /**
+   * Overridden for CUPS specific handling of the media attribute.
+   */
+  protected Object handleSupportedAttributeValuesResponse(IppResponse response, 
+    Class category)
+  {
+    //  TODO Implement different behaviour of cups here - actually the Media 
+    // printing attribute stuff. For now just use IPP reference implementation.
+    return super.handleSupportedAttributeValuesResponse(response, category);
+  }
+
+  /**
+   * Overridden for CUPS specific handling of the media attribute.
+   */
+  public Object getDefaultAttributeValue(Class category)
+  {
+    // TODO Implement media attribute behaviour for cups here
+    //if (category.equals(Media.class)
+    
+    return super.getDefaultAttributeValue(category);
+  }
+
+  /**
+   * Overridden as CUPS does not implement Validate-Job correctly.
+   */
+  public AttributeSet getUnsupportedAttributes(DocFlavor flavor, AttributeSet attributes)
+  {
+    // TODO Implement a heuristic unsupported attribute identification.
+    return super.getUnsupportedAttributes(flavor, attributes);
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/print/CupsPrintServiceLookup.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/print/CupsPrintServiceLookup.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/print/CupsPrintServiceLookup.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/gnu/javax/print/CupsPrintServiceLookup.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,260 @@
+/* CupsPrintServiceLookup.java -- Implementation based on CUPS
+   Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.print;
+
+import gnu.javax.print.ipp.IppException;
+
+import java.util.ArrayList;
+
+import javax.print.DocFlavor;
+import javax.print.MultiDocPrintService;
+import javax.print.PrintService;
+import javax.print.PrintServiceLookup;
+import javax.print.attribute.Attribute;
+import javax.print.attribute.AttributeSet;
+
+/**
+ * The platform default implementation based on CUPS.
+ * 
+ * @author Wolfgang Baer (WBaer at gmx.de)
+ */
+public class CupsPrintServiceLookup extends PrintServiceLookup
+{  
+  private CupsServer server; 
+
+  /**
+   * Default constructor checking security access.
+   */
+  public CupsPrintServiceLookup()
+  {
+    // security
+    SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      sm.checkPrintJobAccess();
+     
+    // use the localhost cups server
+    server = new CupsServer(null, null);
+  }
+
+  /**
+   * This is the printer marked as default in CUPS.
+   * 
+   * @return The default lookup service or
+   * <code>null</code> if there is no default.
+   */
+  public PrintService getDefaultPrintService()
+  {
+    try
+      {
+        return server.getDefaultPrinter();
+      }   
+    catch (IppException e)
+      {
+        // if discovery fails treat as if there is none
+        return null;
+      }    
+  }
+  
+  /**
+  * All printers and printer classes of the CUPS server are checked.
+  * If flavors or attributes are null the constraint is not used.
+  * 
+  * @param flavors the document flavors which have to be supported.
+  * @param attributes the attributes which have to be supported.
+  * 
+  * @return The multidoc print services of the implementing lookup service
+  * for the given parameters, or an array of length 0 if none is available.
+  */
+  public MultiDocPrintService[] getMultiDocPrintServices(DocFlavor[] flavors,
+      AttributeSet attributes)
+  {
+    ArrayList result = new ArrayList();
+    PrintService[] services = getPrintServices();   
+    
+    for (int i=0; i < services.length; i++)
+      {
+        if (checkMultiDocPrintService(flavors, attributes, services[i]))
+          result.add(services[i]);  
+      }
+    
+    return (MultiDocPrintService[]) result.toArray(
+      new MultiDocPrintService[result.size()]);
+  }
+
+  /**
+   * These are all printers and printer classes of the CUPS server.
+   * 
+   * @return All known print services regardless of supported features, 
+   * or an array of length 0 if none is available.
+   */
+  public PrintService[] getPrintServices()
+  {
+    ArrayList result = new ArrayList();
+    
+    try
+      {
+        result.addAll(server.getAllPrinters());
+        result.addAll(server.getAllClasses());
+      }
+    catch (IppException e)
+      {       
+        // ignore as this method cannot throw exceptions
+        // if print service discovery fails - bad luck
+      }
+    return (PrintService[]) result.toArray(new PrintService[result.size()]);
+  }
+  
+  
+  /**
+   * All printers and printer classes of the CUPS server are checked.
+   * If flavor or attributes are null the constraint is not used.
+   * 
+   * @param flavor the document flavor which has to be supported.
+   * @param attributes the attributes which have to be supported.
+   * 
+   * @return The print services of the implementing lookup service
+   * for the given parameters, or an array of length 0 if none is available.
+   */
+  public PrintService[] getPrintServices(DocFlavor flavor,
+      AttributeSet attributes)
+  {
+    ArrayList result = new ArrayList();
+    PrintService[] services = getPrintServices();
+    
+    for (int i=0; i < services.length; i++)
+      {
+        if (checkPrintService(flavor, attributes, services[i]))
+          result.add(services[i]);
+      }
+    
+    return (PrintService[]) result.toArray(new PrintService[result.size()]);
+  }
+  
+  /**
+   * Checks the given print service - own method so it can be used also
+   * to check application registered print services from PrintServiceLookup.
+   * 
+   * @param flavor the document flavor which has to be supported.
+   * @param attributes the attributes which have to be supported.
+   * @param service the service to check
+   * 
+   * @return <code>true</code> if all constraints match, <code>false</code> 
+   * otherwise.
+   */
+  public boolean checkPrintService(DocFlavor flavor, AttributeSet attributes,
+    PrintService service)
+  {
+    boolean allAttributesSupported = true;
+    if (flavor == null || service.isDocFlavorSupported(flavor))
+      {
+        if (attributes == null || attributes.size() == 0)
+          return allAttributesSupported;
+       
+        Attribute[] atts = attributes.toArray();
+        for (int i = 0; i < atts.length; i++)
+          {
+            if (! service.isAttributeCategorySupported(atts[i].getCategory()))
+              {
+                allAttributesSupported = false;
+                break;
+              }
+          }
+        return allAttributesSupported;
+      }
+    
+    return false;
+  }
+  
+  /**
+   * Checks the given print service - own method so it can be used also
+   * to check application registered print services from PrintServiceLookup.
+   * 
+   * @param flavors the document flavors which have to be supported.
+   * @param attributes the attributes which have to be supported.
+   * @param service the service to check
+   * 
+   * @return <code>true</code> if all constraints match, <code>false</code> 
+   * otherwise.
+   */
+  public boolean checkMultiDocPrintService(DocFlavor[] flavors, 
+    AttributeSet attributes, PrintService service)
+  {    
+    if (service instanceof MultiDocPrintService)
+      { 
+        boolean allFlavorsSupported = true;
+        boolean allAttributesSupported = true;
+        
+        if (flavors == null || flavors.length != 0)
+          allFlavorsSupported = true;
+        else
+          {
+            for (int k = 0; k < flavors.length; k++)
+              {
+                if (! service.isDocFlavorSupported(flavors[k]))
+                  {
+                    allFlavorsSupported = false;
+                    break;
+                  }
+              }
+          }
+        
+        if (attributes == null || attributes.size() == 0)
+          allAttributesSupported = true;
+        else
+          {
+            Attribute[] atts = attributes.toArray();
+            for (int j = 0; j < atts.length; j++)
+              {
+                if (! service.isAttributeCategorySupported(
+                    atts[j].getCategory()))
+                  {
+                    allAttributesSupported = false;
+                    break;
+                  }
+              }
+          }
+        
+        if (allAttributesSupported && allFlavorsSupported)
+          return true;
+      }     
+    
+    return false;
+  }
+
+}





More information about the llvm-commits mailing list