private Class<?> getClassFromStream(
     final InputStream stream, final String classname, final File container)
     throws IOException, SecurityException {
   final ByteArrayOutputStream baos = new ByteArrayOutputStream();
   int bytesRead = -1;
   final byte[] buffer = new byte[8192];
   while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {
     baos.write(buffer, 0, bytesRead);
   }
   final byte[] classData = baos.toByteArray();
   return this.defineClassFromData(container, classData, classname);
 }
  /** Write certficate bytes into a PEM encoded string */
  public static String writePEM(byte[] bytes, String hdr, String ftr) throws IOException {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    Base64OutputStream b64os = new Base64OutputStream(bos);
    b64os.write(bytes);
    b64os.flush();
    b64os.close();

    ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
    InputStreamReader irr = new InputStreamReader(bis);
    BufferedReader r = new BufferedReader(irr);

    StringBuffer buff = new StringBuffer();
    String line;
    buff.append(hdr);

    while ((line = r.readLine()) != null) {
      buff.append(line + "\n");
    }
    buff.append(ftr);
    return buff.toString();
  }
 /**
  * Read from the stream until length bytes have been read or EOF has been reached. Return the
  * number of bytes actually read.
  */
 private static int readFully(InputStream in, ByteArrayOutputStream bout, int length)
     throws IOException {
   int read = 0;
   byte[] buffer = new byte[2048];
   while (length > 0) {
     int n = in.read(buffer, 0, length < 2048 ? length : 2048);
     if (n <= 0) {
       break;
     }
     bout.write(buffer, 0, n);
     read += n;
     length -= n;
   }
   return read;
 }
Beispiel #4
0
 /**
  * Generates a Payment message based on the information in the PaymentRequest. Provide
  * transactions built by the wallet. If the PaymentRequest did not specify a payment_url, returns
  * null.
  *
  * @param txns list of transactions to be included with the Payment message.
  * @param refundAddr will be used by the merchant to send money back if there was a problem.
  * @param memo is a message to include in the payment message sent to the merchant.
  */
 public @Nullable Protos.Payment getPayment(
     List<Transaction> txns, @Nullable Address refundAddr, @Nullable String memo)
     throws IOException {
   if (!paymentDetails.hasPaymentUrl()) return null;
   Protos.Payment.Builder payment = Protos.Payment.newBuilder();
   if (paymentDetails.hasMerchantData()) payment.setMerchantData(paymentDetails.getMerchantData());
   if (refundAddr != null) {
     Protos.Output.Builder refundOutput = Protos.Output.newBuilder();
     refundOutput.setAmount(totalValue.longValue());
     refundOutput.setScript(
         ByteString.copyFrom(ScriptBuilder.createOutputScript(refundAddr).getProgram()));
     payment.addRefundTo(refundOutput);
   }
   if (memo != null) {
     payment.setMemo(memo);
   }
   for (Transaction txn : txns) {
     txn.verify();
     ByteArrayOutputStream o = new ByteArrayOutputStream();
     txn.bitcoinSerialize(o);
     payment.addTransactions(ByteString.copyFrom(o.toByteArray()));
   }
   return payment.build();
 }
  /**
   * Read one BER data block. This method is aware of indefinite-length BER encoding and will read
   * all of the sub-sections in a recursive way
   *
   * @param is Read from this InputStream
   * @param bout Write into this OutputStream
   * @param tag Tag already read (-1 mean not read)
   * @returns The current tag, used to check EOC in indefinite-length BER
   * @throws IOException Any parsing error
   */
  private static int readBERInternal(InputStream is, ByteArrayOutputStream bout, int tag)
      throws IOException {

    if (tag == -1) { // Not read before the call, read now
      tag = is.read();
      if (tag == -1) {
        throw new IOException("BER/DER tag info absent");
      }
      if ((tag & 0x1f) == 0x1f) {
        throw new IOException("Multi octets tag not supported");
      }
      bout.write(tag);
    }

    int n = is.read();
    if (n == -1) {
      throw new IOException("BER/DER length info ansent");
    }
    bout.write(n);

    int length;

    if (n == 0x80) { // Indefinite-length encoding
      if ((tag & 0x20) != 0x20) {
        throw new IOException("Non constructed encoding must have definite length");
      }
      while (true) {
        int subTag = readBERInternal(is, bout, -1);
        if (subTag == 0) { // EOC, end of indefinite-length section
          break;
        }
      }
    } else {
      if (n < 0x80) {
        length = n;
      } else if (n == 0x81) {
        length = is.read();
        if (length == -1) {
          throw new IOException("Incomplete BER/DER length info");
        }
        bout.write(length);
      } else if (n == 0x82) {
        int highByte = is.read();
        int lowByte = is.read();
        if (lowByte == -1) {
          throw new IOException("Incomplete BER/DER length info");
        }
        bout.write(highByte);
        bout.write(lowByte);
        length = (highByte << 8) | lowByte;
      } else if (n == 0x83) {
        int highByte = is.read();
        int midByte = is.read();
        int lowByte = is.read();
        if (lowByte == -1) {
          throw new IOException("Incomplete BER/DER length info");
        }
        bout.write(highByte);
        bout.write(midByte);
        bout.write(lowByte);
        length = (highByte << 16) | (midByte << 8) | lowByte;
      } else if (n == 0x84) {
        int highByte = is.read();
        int nextByte = is.read();
        int midByte = is.read();
        int lowByte = is.read();
        if (lowByte == -1) {
          throw new IOException("Incomplete BER/DER length info");
        }
        if (highByte > 127) {
          throw new IOException("Invalid BER/DER data (a little huge?)");
        }
        bout.write(highByte);
        bout.write(nextByte);
        bout.write(midByte);
        bout.write(lowByte);
        length = (highByte << 24) | (nextByte << 16) | (midByte << 8) | lowByte;
      } else { // ignore longer length forms
        throw new IOException("Invalid BER/DER data (too huge?)");
      }
      if (readFully(is, bout, length) != length) {
        throw new IOException("Incomplete BER/DER data");
      }
    }
    return tag;
  }
  /**
   * Returns an ASN.1 SEQUENCE from a stream, which might be a BER-encoded binary block or a
   * PEM-style BASE64-encoded ASCII data. In the latter case, it's de-BASE64'ed before return.
   *
   * <p>After the reading, the input stream pointer is after the BER block, or after the newline
   * character after the -----END SOMETHING----- line.
   *
   * @param is the InputStream
   * @returns byte block or null if end of stream
   * @throws IOException If any parsing error
   */
  private static byte[] readOneBlock(InputStream is) throws IOException {

    // The first character of a BLOCK.
    int c = is.read();
    if (c == -1) {
      return null;
    }
    if (c == DerValue.tag_Sequence) {
      ByteArrayOutputStream bout = new ByteArrayOutputStream(2048);
      bout.write(c);
      readBERInternal(is, bout, c);
      return bout.toByteArray();
    } else {
      // Read BASE64 encoded data, might skip info at the beginning
      char[] data = new char[2048];
      int pos = 0;

      // Step 1: Read until header is found
      int hyphen = (c == '-') ? 1 : 0; // count of consequent hyphens
      int last = (c == '-') ? -1 : c; // the char before hyphen
      while (true) {
        int next = is.read();
        if (next == -1) {
          // We accept useless data after the last block,
          // say, empty lines.
          return null;
        }
        if (next == '-') {
          hyphen++;
        } else {
          hyphen = 0;
          last = next;
        }
        if (hyphen == 5 && (last == -1 || last == '\r' || last == '\n')) {
          break;
        }
      }

      // Step 2: Read the rest of header, determine the line end
      int end;
      StringBuffer header = new StringBuffer("-----");
      while (true) {
        int next = is.read();
        if (next == -1) {
          throw new IOException("Incomplete data");
        }
        if (next == '\n') {
          end = '\n';
          break;
        }
        if (next == '\r') {
          next = is.read();
          if (next == -1) {
            throw new IOException("Incomplete data");
          }
          if (next == '\n') {
            end = '\n';
          } else {
            end = '\r';
            data[pos++] = (char) next;
          }
          break;
        }
        header.append((char) next);
      }

      // Step 3: Read the data
      while (true) {
        int next = is.read();
        if (next == -1) {
          throw new IOException("Incomplete data");
        }
        if (next != '-') {
          data[pos++] = (char) next;
          if (pos >= data.length) {
            data = Arrays.copyOf(data, data.length + 1024);
          }
        } else {
          break;
        }
      }

      // Step 4: Consume the footer
      StringBuffer footer = new StringBuffer("-");
      while (true) {
        int next = is.read();
        // Add next == '\n' for maximum safety, in case endline
        // is not consistent.
        if (next == -1 || next == end || next == '\n') {
          break;
        }
        if (next != '\r') footer.append((char) next);
      }

      checkHeaderFooter(header.toString(), footer.toString());

      return Base64.getMimeDecoder().decode(new String(data, 0, pos));
    }
  }