Source for gnu.javax.net.ssl.provider.CertificateStatusRequest

   1: /* CertificateStatusRequest.java --
   2:    Copyright (C) 2006  Free Software Foundation, Inc.
   3: 
   4: This file is a part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2 of the License, or (at
   9: your option) any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; if not, write to the Free Software
  18: Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
  19: USA
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version.  */
  37: 
  38: 
  39: package gnu.javax.net.ssl.provider;
  40: 
  41: import gnu.javax.net.ssl.provider.Extension.Value;
  42: 
  43: import java.io.PrintWriter;
  44: import java.io.StringWriter;
  45: import java.nio.ByteBuffer;
  46: import java.util.Iterator;
  47: import java.util.List;
  48: import java.util.NoSuchElementException;
  49: 
  50: /**
  51:  * <pre>
  52: struct {
  53:   CertificateStatusType status_type;
  54:   select (status_type) {
  55:     case ocsp: OCSPStatusRequest;
  56:   } request;
  57: } CertificateStatusRequest;
  58: 
  59: enum { ocsp(1), (255) } CertificateStatusType;
  60: 
  61: struct {
  62:   ResponderID responder_id_list&lt;0..2^16-1&gt;;
  63:   Extensions  request_extensions;
  64: } OCSPStatusRequest;
  65: 
  66: opaque ResponderID&lt;1..2^16-1&gt;;
  67: opaque Extensions&lt;0..2^16-1&gt;;</pre>
  68:  *
  69:  * @author csm
  70:  */
  71: public class CertificateStatusRequest extends Value implements Iterable<byte[]>
  72: {
  73:   private ByteBuffer buffer;
  74: 
  75:   public CertificateStatusRequest(final ByteBuffer buffer)
  76:   {
  77:     this.buffer = buffer;
  78:   }
  79: 
  80:   public CertificateStatusRequest(CertificateStatusType type,
  81:                                   List<byte[]> responderIdList,
  82:                                   byte[] requestExtensions)
  83:   {
  84:     if (type != CertificateStatusType.OCSP)
  85:       throw new IllegalArgumentException();
  86:     int length = 3;
  87:     int idsLength = 0;
  88:     for (byte[] responderId : responderIdList)
  89:       {
  90:         length += 2 + responderId.length;
  91:         idsLength += 2 + responderId.length;
  92:       }
  93:     length += 2 + requestExtensions.length;
  94:     buffer = ByteBuffer.allocate(length);
  95:     buffer.put((byte) 1);
  96:     buffer.putShort((short) idsLength);
  97:     for (byte[] responderId : responderIdList)
  98:       buffer.putShort((short) responderId.length).put(responderId);
  99:     buffer.putShort((short) requestExtensions.length);
 100:     buffer.put(requestExtensions);
 101:     buffer.rewind();
 102:   }
 103: 
 104:   public int length()
 105:   {
 106:     int l = 3 + (buffer.getShort(1) & 0xFFFF);
 107:     return l + (buffer.getShort(l) & 0xFFFF) + 2;
 108:   }
 109: 
 110:   public ByteBuffer buffer()
 111:   {
 112:     return (ByteBuffer) buffer.duplicate().limit(length());
 113:   }
 114: 
 115:   public CertificateStatusType statusType()
 116:   {
 117:     int x = buffer.get(0) & 0xFF;
 118:     if (x == 1)
 119:       return CertificateStatusType.OCSP;
 120:     throw new IllegalArgumentException ("invalid type: " + x);
 121:   }
 122: 
 123:   public int size()
 124:   {
 125:     int len = buffer.getShort(1) & 0xFFFF;
 126:     int n = 0;
 127:     for (int i = 3; i < len; )
 128:       {
 129:         int l = buffer.getShort(i);
 130:         i += l + 2;
 131:         n++;
 132:       }
 133:     return n;
 134:   }
 135: 
 136:   public byte[] responderId(int index)
 137:   {
 138:     int len = buffer.getShort(1) & 0xFFFF;
 139:     int n = 0;
 140:     int i = 3;
 141:     while (i < len && n <= index)
 142:       {
 143:         int l = buffer.getShort(i) & 0xFFFF;
 144:         if (n == index)
 145:           {
 146:             byte[] b = new byte[l];
 147:             ((ByteBuffer) buffer.duplicate().position(i+2)).get(b);
 148:             return b;
 149:           }
 150:         i += l + 2;
 151:         n++;
 152:       }
 153:     throw new IndexOutOfBoundsException();
 154:   }
 155: 
 156:   public byte[] requestExtensions()
 157:   {
 158:     int l = 2 + (buffer.getShort(0) & 0xFFFF);
 159:     int ll = buffer.getShort(l) & 0xFFFF;
 160:     byte[] b = new byte[ll];
 161:     ((ByteBuffer) buffer.duplicate().position(ll+2)).get(b);
 162:     return b;
 163:   }
 164: 
 165:   public void setStatusType(CertificateStatusType type)
 166:   {
 167:     buffer.put(0, (byte) type.value);
 168:   }
 169: 
 170:   public void setRequestIdListLength(int newLength)
 171:   {
 172:     if (newLength < 0 || newLength > 0xFFFF)
 173:       throw new IllegalArgumentException("length out of range");
 174:     buffer.putShort(1, (short) newLength);
 175:   }
 176: 
 177:   public void putRequestId(int index, byte[] id)
 178:   {
 179:     if (id.length > 0xFFFF)
 180:       throw new IllegalArgumentException("request ID too large");
 181:     int len = buffer.getShort(1) & 0xFFFF;
 182:     int n = 0;
 183:     int i = 3;
 184:     while (i < len && n < index)
 185:       {
 186:         int l = buffer.getShort(i) & 0xFFFF;
 187:         i += l + 2;
 188:         n++;
 189:       }
 190:     if (n < index)
 191:       throw new IndexOutOfBoundsException();
 192:     buffer.putShort(i, (short) id.length);
 193:     ((ByteBuffer) buffer.duplicate().position(i)).put(id);
 194:   }
 195: 
 196:   public void setRequestExtensions(int index, byte[] ext)
 197:   {
 198:     if (ext.length > 0xFFFF)
 199:       throw new IllegalArgumentException("exceptions too large");
 200:     int off = 3 + (buffer.getShort(1) & 0xFFFF);
 201:     buffer.putShort(off, (short) ext.length);
 202:     ((ByteBuffer) buffer.duplicate().position(off+2)).put(ext);
 203:   }
 204: 
 205:   public Iterator<byte[]> iterator()
 206:   {
 207:     return new ResponderIdIterator();
 208:   }
 209: 
 210:   public String toString()
 211:   {
 212:     return toString(null);
 213:   }
 214: 
 215:   public String toString(String prefix)
 216:   {
 217:     StringWriter str = new StringWriter();
 218:     PrintWriter out = new PrintWriter(str);
 219:     if (prefix != null) out.print(prefix);
 220:     out.println("struct {");
 221:     if (prefix != null) out.print(prefix);
 222:     out.print("  status_type = ");
 223:     out.print(statusType());
 224:     out.println(";");
 225:     String subprefix = "    ";
 226:     if (prefix != null) subprefix = prefix + subprefix;
 227:     if (prefix != null) out.print(prefix);
 228:     out.println("  responder_id_list = {");
 229:     for (byte[] b : this)
 230:       out.print(Util.hexDump(b, subprefix));
 231:     if (prefix != null) out.print(prefix);
 232:     out.println("  };");
 233:     if (prefix != null) out.print(prefix);
 234:     out.println("  request_extensions =");
 235:     out.print(Util.hexDump(requestExtensions(), subprefix));
 236:     if (prefix != null) out.print(prefix);
 237:     out.print("} CertificateStatus;");
 238:     return str.toString();
 239:   }
 240: 
 241:   public class ResponderIdIterator implements Iterator<byte[]>
 242:   {
 243:     private int index;
 244: 
 245:     public ResponderIdIterator()
 246:     {
 247:       index = 0;
 248:     }
 249: 
 250:     public byte[] next() throws NoSuchElementException
 251:     {
 252:       try
 253:         {
 254:           return responderId(index++);
 255:         }
 256:       catch (IndexOutOfBoundsException ioobe)
 257:         {
 258:           throw new NoSuchElementException();
 259:         }
 260:     }
 261: 
 262:     public boolean hasNext()
 263:     {
 264:       return index < size();
 265:     }
 266: 
 267:     public void remove()
 268:     {
 269:       throw new UnsupportedOperationException();
 270:     }
 271:   }
 272: }