Source for gnu.javax.crypto.sasl.OutputBuffer

   1: /* OutputBuffer.java --
   2:    Copyright (C) 2003, 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.crypto.sasl;
  40: 
  41: import gnu.java.security.Registry;
  42: import gnu.java.security.util.Util;
  43: 
  44: import java.io.ByteArrayOutputStream;
  45: import java.io.IOException;
  46: import java.math.BigInteger;
  47: 
  48: /**
  49:  * The implementation of an outgoing SASL buffer.
  50:  * <p>
  51:  * The data elements this class caters for are described in [1].
  52:  * <p>
  53:  * References:
  54:  * <ol>
  55:  * <li><a
  56:  * href="http://www.ietf.org/internet-drafts/draft-burdis-cat-srp-sasl-09.txt">
  57:  * Secure Remote Password Authentication Mechanism</a>;<br/>
  58:  * draft-burdis-cat-srp-sasl-09,<br/> <a
  59:  * href="mailto:keith@rucus.ru.ac.za">Keith Burdis</a> and <a
  60:  * href="mailto:raif@forge.com.au">Ra&iuml;f S. Naffah</a>.</li>
  61:  * </ol>
  62:  */
  63: public class OutputBuffer
  64: {
  65:   /** The internal output stream. */
  66:   private ByteArrayOutputStream out;
  67: 
  68:   public OutputBuffer()
  69:   {
  70:     super();
  71: 
  72:     out = new ByteArrayOutputStream();
  73:   }
  74: 
  75:   /**
  76:    * Encodes a SASL scalar quantity, <code>count</code>-octet long, to the
  77:    * current buffer.
  78:    *
  79:    * @param count number of octets to encode <code>b</code> with.
  80:    * @param b the scalar quantity.
  81:    * @throws SaslEncodingException if an encoding size constraint is violated.
  82:    * @throws IOException if any other I/O exception occurs during the operation.
  83:    */
  84:   public void setScalar(int count, int b) throws IOException
  85:   {
  86:     if (count < 0 || count > 4)
  87:       throw new SaslEncodingException("Invalid SASL scalar octet count: "
  88:                                       + String.valueOf(count));
  89:     byte[] element = new byte[count];
  90:     for (int i = count; --i >= 0; b >>>= 8)
  91:       element[i] = (byte) b;
  92:     out.write(element);
  93:   }
  94: 
  95:   /**
  96:    * Encodes a SASL OS to the current buffer.
  97:    *
  98:    * @param b the OS element.
  99:    * @throws SaslEncodingException if an encoding size constraint is violated.
 100:    * @throws IOException if any other I/O exception occurs during the operation.
 101:    */
 102:   public void setOS(byte[] b) throws IOException
 103:   {
 104:     final int length = b.length;
 105:     if (length > Registry.SASL_ONE_BYTE_MAX_LIMIT)
 106:       throw new SaslEncodingException("SASL octet-sequence too long");
 107:     out.write(length & 0xFF);
 108:     out.write(b);
 109:   }
 110: 
 111:   /**
 112:    * Encodes a SASL EOS to the current buffer.
 113:    *
 114:    * @param b the EOS element.
 115:    * @throws SaslEncodingException if an encoding size constraint is violated.
 116:    * @throws IOException if any other I/O exception occurs during the operation.
 117:    */
 118:   public void setEOS(byte[] b) throws IOException
 119:   {
 120:     final int length = b.length;
 121:     if (length > Registry.SASL_TWO_BYTE_MAX_LIMIT)
 122:       throw new SaslEncodingException("SASL extended octet-sequence too long");
 123:     byte[] lengthBytes = { (byte)(length >>> 8), (byte) length };
 124:     out.write(lengthBytes);
 125:     out.write(b);
 126:   }
 127: 
 128:   /**
 129:    * Encodes a SASL MPI to the current buffer.
 130:    *
 131:    * @param val the MPI element.
 132:    * @throws SaslEncodingException if an encoding size constraint is violated.
 133:    * @throws IOException if any other I/O exception occurs during the operation.
 134:    */
 135:   public void setMPI(BigInteger val) throws IOException
 136:   {
 137:     byte[] b = Util.trim(val);
 138:     final int length = b.length;
 139:     if (length > Registry.SASL_TWO_BYTE_MAX_LIMIT)
 140:       throw new SaslEncodingException("SASL multi-precision integer too long");
 141:     byte[] lengthBytes = { (byte)(length >>> 8), (byte) length };
 142:     out.write(lengthBytes);
 143:     out.write(b);
 144:   }
 145: 
 146:   /**
 147:    * Encodes a SASL Text to the current buffer.
 148:    *
 149:    * @param str the Text element.
 150:    * @throws SaslEncodingException if an encoding size constraint is violated.
 151:    * @throws SaslEncodingException if the UTF-8 encoding is not supported on
 152:    *           this platform.
 153:    * @throws IOException if any other I/O exception occurs during the operation.
 154:    */
 155:   public void setText(String str) throws IOException
 156:   {
 157:     byte[] b = str.getBytes("UTF8");
 158:     final int length = b.length;
 159:     if (length > Registry.SASL_TWO_BYTE_MAX_LIMIT)
 160:       throw new SaslEncodingException("SASL text too long");
 161:     byte[] lengthBytes = { (byte)(length >>> 8), (byte) length };
 162:     out.write(lengthBytes);
 163:     out.write(b);
 164:   }
 165: 
 166:   /**
 167:    * Returns the encoded form of the current buffer including the 4-byte length
 168:    * header.
 169:    *
 170:    * @throws SaslEncodingException if an encoding size constraint is violated.
 171:    */
 172:   public byte[] encode() throws SaslEncodingException
 173:   {
 174:     byte[] buffer = wrap();
 175:     final int length = buffer.length;
 176:     byte[] result = new byte[length + 4];
 177:     result[0] = (byte)(length >>> 24);
 178:     result[1] = (byte)(length >>> 16);
 179:     result[2] = (byte)(length >>> 8);
 180:     result[3] = (byte) length;
 181:     System.arraycopy(buffer, 0, result, 4, length);
 182:     return result;
 183:   }
 184: 
 185:   /**
 186:    * Returns the encoded form of the current buffer excluding the 4-byte length
 187:    * header.
 188:    *
 189:    * @throws SaslEncodingException if an encoding size constraint is violated.
 190:    */
 191:   public byte[] wrap() throws SaslEncodingException
 192:   {
 193:     final int length = out.size();
 194:     if (length > Registry.SASL_BUFFER_MAX_LIMIT || length < 0)
 195:       throw new SaslEncodingException("SASL buffer too long");
 196:     return out.toByteArray();
 197:   }
 198: }