1   /*
2    * Title:        S/MIME Project
3    * Description:  S/MIME email sending capabilities
4    * @Author       Vladimir Radisic
5    * @Version      2.0.1
6    */
7   
8   
9   package  org.webdocwf.util.smime.der;
10  
11  
12  import  org.webdocwf.util.smime.exception.SMIMEException;
13  import  org.webdocwf.util.smime.exception.ErrorStorage;
14  
15  
16  /***
17   * DERObjectIdentifier is primitive type of DER encoded object which represents
18   * Object Identifier type in ASN.1 notation. A value (distinguishable from all
19   * other such values) which is associated with an information object. For
20   * example object identifier for RSA algorithm is 1.2.840.113549.1.1.1.
21   * Implemented object identifiers are stored in class IdentifierStorage.
22   */
23  public class DERObjectIdentifier extends DERObject {
24  
25      /***
26       * This constructor has two different forms, depend on parameter typeConstruction0,
27       * which can be: DOT_SEPARATED_ARRAY or NAME_STRING. If typeConstruction0 parameter
28       * is DOT_SEPARATED_ARRAY then id0 definition is represented by numbers separated
29       * with dots (example: "1.2.840.113549.1.1.1"). In the case of NAME_STRING, id0
30       * definition is name of object identifier (example: "RSA").
31       * @param id0 defines Object Identifier in representation determined by the
32       * second parameter - typeConstruction0.
33       * @param typeConstruction0 can take values DOT_SEPARATED_ARRAY and NAME_STRING
34       * @exception SMIMEException if wrong type of parameters are passed to the
35       * constructor. Also, exception could be thrown in super class constructor or
36       * in super class addContent method.
37       */
38      public DERObjectIdentifier(String id0, String typeConstruction0) throws SMIMEException {
39          super(6);
40          byte[] contentID;           // For storing content of ID identifiers byte string
41  
42          if (typeConstruction0.equalsIgnoreCase("DOT_SEPARATED_ARRAY"))              // Construction with dot separated string of numbers
43          {
44              int[] temp;
45              int[] dotPosition;
46              int j = -1, i = 0;
47  
48              do        // Counting number of dots to find out how many integers will contain Object Identificator string
49              {
50                  j = id0.indexOf('.', j + 1);
51                  i++;
52              }
53              while (j != -1);
54              if (i == 1)
55                  throw  new SMIMEException(this, 1008);
56              temp = new int[i];
57              dotPosition = new int[i - 1];
58              i = 0;
59              j = -1;
60              do        // Filling dot position
61              {
62                  j = id0.indexOf('.', j + 1);
63                  if (j != -1)
64                      dotPosition[i] = j;
65                  i++;
66              }
67              while (j != -1);
68              temp[0] = Integer.decode(id0.substring(0, dotPosition[0])).intValue();                    // First number in Identificator object string
69              temp[temp.length - 1] = Integer.decode(id0.substring(dotPosition[dotPosition.length - 1] + 1)).intValue();                // Last number in Identificator object string
70              for (i = 1; i != temp.length - 1; i++)
71                  temp[i] = Integer.decode(id0.substring(dotPosition[i - 1] + 1, dotPosition[i])).intValue();             // Numbers between first and last number in Identificator object string
72              contentID = formatID(temp);
73              super.addContent(contentID);              // Formating DER value of Object identificator
74          } else if (typeConstruction0.equalsIgnoreCase("NAME_STRING")) {
75              contentID = formatID(IdentifierStorage.getID(id0.toUpperCase()));
76              super.addContent(contentID);              // Formating DER value of Object identificator
77          } else
78              throw  new SMIMEException(this, 1009);
79      }
80  
81      /***
82       * Array of numbers is used for construction of DERObjectIdentifier. Every number in
83       * array represents one number between dots in the object identifier string.
84       * @param arrayID0 array of given numbers (example: for RSA algorithm those
85       * numbers are 1, 2, 840, 113549, 1, 1, and 1).
86       * @exception SMIMEException if wrong type of parameters are passed to the
87       * constructor. Also, exception could be thrown in super class constructor or
88       * in super class addContent method.
89       */
90      public DERObjectIdentifier(int[] arrayID0) throws SMIMEException {
91          super(6);
92          super.addContent(formatID(arrayID0));
93      }
94  
95      /***
96       * Creats Object Identifier octet string from discret number identifiers
97       * @param id0 array of defined numbers for defined Object Identifier
98       * @return Byte array representation of the DER encoded content of the Object
99       * Identifier
100      * @exception SMIMEException in case that unknown type of object identifier is
101      * submited to constructors dealing with DOT_SEPARATED_ARRAY and NAME_STRING.
102      * Also, it can be caused by non SMIMEException which is:
103      * UnsupportedEncodingException.
104      */
105     private byte[] formatID(int[] id0) throws SMIMEException {
106         int[] temp = new int[id0.length - 1];
107         String s = new String();
108         byte[] returnByteArray = null;
109 
110         if (id0[0] == -1)
111             throw  new SMIMEException(this, 1010);
112         temp[0] = 40 * id0[0] + id0[1];               // First byte is constructed from the first and second discret numbers (that`s a rule)
113         for (int i = 2; i != id0.length; i++)
114             temp[i - 1] = id0[i];
115         try {
116             for (int i = 0; i != temp.length; i++) {
117                 int j = 1;              // j: Number of required bits for particular element of array "temp"
118 
119                 for (int a = 1; (a * 2) <= temp[i]; j++)                  // Counting number of required bits
120                     a = a * 2;
121                 j = (int) Math.ceil((double) j / 7);        // j: Number of required bytes for particular element of array "temp"
122                 byte[] tempElement = new byte[j];
123 
124                 for (j = tempElement.length - 1; j >= 0; j--) {
125                     tempElement[j] = (byte) ((temp[i] >> (7 * (tempElement.length - 1 - j))) & 0x7F);
126                     if (j != (tempElement.length - 1))
127                         tempElement[j] = (byte) (tempElement[j] | (0x80));
128                 }
129                 s = s.concat(new String(tempElement, "ISO-8859-1"));
130             }
131             returnByteArray = s.getBytes("ISO-8859-1");
132         } catch (Exception e) {
133             throw SMIMEException.getInstance(this, e, "formatID");
134         }
135         return  returnByteArray;
136     }
137 }
138 
This page was automatically generated by Maven