001: /*
002: * Title: Oyster Project
003: * Description: S/MIME email transport capabilities.
004: * @Author Vladimir Radisic
005: * @Version 2.1.6
006: */
007:
008: package org.enhydra.oyster.der;
009:
010: import org.enhydra.oyster.exception.SMIMEException;
011:
012: /**
013: * DERBitString is primitive type of DER encoded object which represents bit
014: * string (array of bits) in ASN.1 notation.
015: */
016: public class DERBitString extends DERObject {
017:
018: /**
019: * Constructs DERBitString object from string which has only two values of his
020: * elements: 0 and 1
021: * @param bitStr0 String consisting of 0 and 1 elements
022: * @exception SMIMEException thrown in super class constructor or in super class
023: * method addContent.
024: */
025: public DERBitString(String bitStr0) throws SMIMEException {
026: super (3);
027: super .addContent(this .UnusedBitsFromString(bitStr0));
028: super .addContent(this .ConvertStringBitsToByteArray(bitStr0));
029: }
030:
031: /**
032: * Constructs DERBitString object from boolean array which has only two values
033: * of his elements: true and false.
034: * @param bitsArray0 array consisting of boolean elements
035: * @exception SMIMEException thrown in super class constructor or in super class
036: * method addContent.
037: */
038: public DERBitString(boolean[] bitsArray0) throws SMIMEException {
039: super (3);
040: String temp = "";
041: for (int i = 0; i != bitsArray0.length; i++) {
042: if (bitsArray0[i])
043: temp = temp.concat("1");
044: else
045: temp = temp.concat("0");
046: }
047: super .addContent(this .UnusedBitsFromString(temp));
048: super .addContent(this .ConvertStringBitsToByteArray(temp));
049: }
050:
051: /**
052: * Constructs DERBitString object from bits organised in bytes with information
053: * about last few unused bits. This information is important in generation of
054: * DER object because first byte in Content Octets part of DERBitString
055: * represents number of DERBitString.
056: * @param bitStr0 bit string represented as byte array
057: * @param unused0 number of last few unused bits from last input byte
058: * (must be in range 0-7)
059: * @exception SMIMEException if number of unused bits isn't between 0-7. Also,
060: * it can be thrown in super class constructor or addContent method.
061: */
062: public DERBitString(byte[] bitStr0, int unused0)
063: throws SMIMEException {
064: super (3);
065: if (unused0 > 7 || unused0 < 0)
066: throw new SMIMEException(1006);
067: byte[] temp = new byte[1];
068: temp[0] = (byte) unused0; // Number of a last few unused bits
069: super .addContent(temp);
070: super .addContent(bitStr0); // bitStr0 is a byte array containing the two's-complement binary representation of a bit String
071: }
072:
073: /**
074: * Constructs bit string represented as byte array without information about
075: * unused bits (no bits are unused).
076: * @param bitStr0 bit string represented as byte array
077: * @exception SMIMEException thrown in super class constructor or addContent
078: * method of super class.
079: */
080: public DERBitString(byte[] bitStr0) throws SMIMEException {
081: this (bitStr0, 0);
082: }
083:
084: /**
085: * Finds number of unused last bits (0-7) from bit string converted into byte array
086: * @param bitStr0 bit string for verification number of unused bits.
087: * @return Number between 0-7
088: */
089: private byte[] UnusedBitsFromString(String bitStr0) {
090: byte[] temp = new byte[1];
091: int len = bitStr0.length();
092: temp[0] = (byte) (8 - len % 8); // Number of unused bits
093: if (temp[0] == 8)
094: temp[0] = 0;
095: return temp;
096: }
097:
098: /**
099: * Converts String consisting of 0 and 1 into byte array
100: * @param bitStr0 bit string for transformation in byte array of the Content
101: * Octets
102: * @return Content Octets of DER encoded bit string object
103: * @exception SMIMEException if bit string has values other than 0 and 1
104: */
105: private byte[] ConvertStringBitsToByteArray(String bitStr0)
106: throws SMIMEException {
107: int len = bitStr0.length();
108: if (len % 8 == 0)
109: len = len / 8;
110: else
111: len = len / 8 + 1;
112: int[] temp = new int[len];
113: for (int i = 0; i != bitStr0.length(); i++) {
114: if (!(bitStr0.charAt(i) == '0' || bitStr0.charAt(i) == '1'))
115: throw new SMIMEException(1007);
116: if ((i % 8) == 0)
117: temp[i / 8] = 0;
118: temp[i / 8] = temp[i / 8]
119: + (int) ((byte) bitStr0.charAt(i) - 48)
120: * (int) Math
121: .pow((double) 2, (double) (7 - (i % 8)));
122: }
123: byte[] ret = new byte[temp.length];
124: for (int i = 0; i != ret.length; i++)
125: ret[i] = (byte) temp[i];
126: return ret;
127: }
128: }
|