asn1_der_decode.C
上传用户:zbbssh
上传日期:2007-01-08
资源大小:196k
文件大小:14k
源码类别:

CA认证

开发平台:

C/C++

  1. /*
  2. ------------------------------------------------------------------
  3.   Copyright
  4.   Sun Microsystems, Inc.
  5.   Copyright (C) 1994, 1995, 1996 Sun Microsystems, Inc.  All Rights
  6.   Reserved.
  7.   Permission is hereby granted, free of charge, to any person
  8.   obtaining a copy of this software and associated documentation
  9.   files (the "Software"), to deal in the Software without
  10.   restriction, including without limitation the rights to use,
  11.   copy, modify, merge, publish, distribute, sublicense, and/or sell
  12.   copies of the Software or derivatives of the Software, and to 
  13.   permit persons to whom the Software or its derivatives is furnished 
  14.   to do so, subject to the following conditions:
  15.   The above copyright notice and this permission notice shall be
  16.   included in all copies or substantial portions of the Software.
  17.   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18.   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  19.   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20.   NONINFRINGEMENT.  IN NO EVENT SHALL SUN MICROSYSTEMS, INC., BE LIABLE
  21.   FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  22.   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  23.   CONNECTION WITH THE SOFTWARE OR DERIVATES OF THIS SOFTWARE OR 
  24.   THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.   Except as contained in this notice, the name of Sun Microsystems, Inc.
  26.   shall not be used in advertising or otherwise to promote
  27.   the sale, use or other dealings in this Software or its derivatives 
  28.   without prior written authorization from Sun Microsystems, Inc.
  29. */
  30. #pragma ident "@(#)asn1_der_decode.C 1.5 96/01/29 Sun Microsystems"
  31. #include <sys/types.h>
  32. #include <stdarg.h>
  33. #include <stdlib.h>
  34. #include <stdio.h>
  35. #include "my_types.h"
  36. #include "Time.h"
  37. #include "Bigint.h"
  38. #include "Bstream.h"
  39. #include "asn1_der.h"
  40. #include "ObjId.h"
  41. /*
  42.  * Encoding decoding routines for ASN.1 using
  43.  * the Basic Encoding Rules subset DER
  44.  */
  45. void asn1_perror(int errcode)
  46. {
  47. printf("ASN.1 decoding error: ");
  48. switch(errcode) {
  49. case E_DER_DECODE_LEN_TOO_LONG:
  50. printf("length octets exceed length of buffern");
  51. break;
  52. case E_DER_DECODE_BAD_ID_OCTET:
  53. printf("unexpected ID octetn");
  54. break;
  55. case E_DER_DECODE_UNEXPECTED_EOS:
  56. printf("unexpected end-of-streamn");
  57. break;
  58. case E_DER_DECODE_BAD_BITSTRING:
  59. printf("bad bitstringn");
  60. break;
  61. case E_DER_DECODE_UNALIGNED_BS:
  62. printf("bitsring not octet alignedn");
  63. break;
  64. case E_DER_DECODE_BAD_OBJID_SUBID:
  65. printf("bad sub-identifier of OBJECT-IDENTIFIERn");
  66. break;
  67. case E_DER_DECODE_BAD_TIME_STRING:
  68. printf("bad UTCTime stringn");
  69. break;
  70. case E_DER_DECODE_BAD_NULL_VALUE:
  71. printf("bad null value, length not equal to zeron");
  72. break;
  73. default:
  74. printf("unknown error code %dn", errcode);
  75. break;
  76. }
  77. return;
  78. }
  79. int convert_bytes_to_int(byte *four_bytes)
  80. {
  81. #if defined(sparc)
  82. int val;
  83. byte *bytep = (byte *)&val;
  84. bytep[0] = four_bytes[3];
  85. bytep[1] = four_bytes[2];
  86. bytep[2] = four_bytes[1];
  87. bytep[3] = four_bytes[0];
  88. return (val);
  89. #else 
  90. #if defined(i386)
  91.         int val;
  92.         byte *bytep = (byte *)&val;
  93.  
  94.         bytep[0] = four_bytes[0];
  95.         bytep[1] = four_bytes[1];
  96.         bytep[2] = four_bytes[2];
  97.         bytep[3] = four_bytes[3];
  98.         return (val);
  99. #else
  100. return "Architecture not supported";
  101. #endif /* i386 */
  102. #endif /* sparc */
  103. }
  104. /*
  105.  * Do ASN.1 DER length octets processing.
  106.  * We assume that the number of content
  107.  * octets will never exceed 2**32 octets.
  108.  */
  109. int asn1_der_get_length(Bstream& der_stream)
  110. {
  111. byte tmp = 0;
  112. int  len;
  113. const int MAXLENBYTES = 4; /*Greater than 32 bits should not be required*/
  114. byte    lenbytes[MAXLENBYTES];
  115. int  i, ret;
  116. ret = der_stream.fetchbyte(tmp);
  117. if (ret == EOS)
  118. return (E_DER_DECODE_UNEXPECTED_EOS);
  119. #ifdef __GNUC__
  120. if ((tmp & 0x80) == 0 ) {
  121. #else
  122. if ((tmp & 0x80) == NULL ) {
  123. #endif
  124. len = tmp;
  125. } else {
  126. int  numbytes = tmp & 0x7f;
  127. if (numbytes > MAXLENBYTES)
  128. return (E_DER_DECODE_LEN_TOO_LONG);
  129. if (numbytes > der_stream.getlength())
  130. return (E_DER_DECODE_UNEXPECTED_EOS);
  131. bzero(lenbytes, sizeof(lenbytes));
  132. for (i = numbytes - 1; i >= 0; i--)
  133. (void ) der_stream.fetchbyte(lenbytes[i]);
  134. len = convert_bytes_to_int(lenbytes);
  135. }
  136. return (len);
  137. }
  138. /*
  139.  * Decode an ASN.1 DER INTEGER
  140.  */
  141. int asn1_der_decode_integer(Bstream& der_stream, Bigint& val)
  142. {
  143. byte tmp = 0;
  144. int  len;
  145. if (der_stream.getlength() < 2)
  146. return (E_DER_DECODE_UNEXPECTED_EOS);
  147. (void )der_stream.peekbyte(tmp);
  148. if (tmp != INTEGER_ID) {
  149. return (E_DER_DECODE_BAD_ID_OCTET);
  150. }
  151. (void )der_stream.fetchbyte(tmp);
  152. len = asn1_der_get_length(der_stream);
  153. if (len < 0) return len;
  154. if (len > der_stream.getlength()) 
  155. return (E_DER_DECODE_UNEXPECTED_EOS);
  156. Bigint tmpval((unsigned char *)der_stream.getdatap(), len);
  157. der_stream.consume(len);
  158. val = tmpval;
  159. return (0);
  160. }
  161. /*
  162.  * Decode the ID part of a SEQUENCE
  163.  */
  164. int asn1_der_decode_sequence(Bstream& der_stream, int &len)
  165. {
  166. byte tmp = 0;
  167. if (der_stream.getlength() < 2)
  168. return (E_DER_DECODE_UNEXPECTED_EOS);
  169. (void )der_stream.peekbyte(tmp);
  170. if (tmp != SEQUENCE_ID) {
  171. return (E_DER_DECODE_BAD_ID_OCTET);
  172. }
  173. (void )der_stream.fetchbyte(tmp);
  174. len = asn1_der_get_length(der_stream);
  175. if (len > der_stream.getlength()) {
  176. return (E_DER_DECODE_UNEXPECTED_EOS);
  177. }
  178. return (SUCCESS);
  179. }
  180. int asn1_der_decode_sequence_of(Bstream& der_stream, int &len)
  181. {
  182. return (asn1_der_decode_sequence(der_stream, len));
  183. }
  184. /*
  185.  * Decode the ID part of a SET
  186.  */
  187. int asn1_der_decode_set(Bstream& der_stream, int &len)
  188. {
  189. byte tmp = 0;
  190. if (der_stream.getlength() < 2)
  191. return (E_DER_DECODE_UNEXPECTED_EOS);
  192. (void )der_stream.peekbyte(tmp);
  193. if (tmp != SET_ID) {
  194. return (E_DER_DECODE_BAD_ID_OCTET);
  195. }
  196. (void )der_stream.fetchbyte(tmp);
  197. len = asn1_der_get_length(der_stream);
  198. if (len > der_stream.getlength()) {
  199. return (E_DER_DECODE_UNEXPECTED_EOS);
  200. }
  201. return (SUCCESS);
  202. }
  203. /*
  204.  * Decode NULL type
  205.  */
  206. int asn1_der_decode_null(Bstream& der_stream)
  207. {
  208. byte tmp = 0;
  209. int  len;
  210. if (der_stream.getlength() < 2)
  211. return (E_DER_DECODE_UNEXPECTED_EOS);
  212. (void )der_stream.peekbyte(tmp);
  213. if (tmp != NULL_ID) {
  214. return (E_DER_DECODE_BAD_ID_OCTET);
  215. }
  216. (void )der_stream.fetchbyte(tmp);
  217. len = asn1_der_get_length(der_stream);
  218. if (len != 0)
  219. return(E_DER_DECODE_BAD_NULL_VALUE);
  220. return (SUCCESS);
  221. }
  222. int asn1_der_decode_set_of(Bstream& der_stream, int &len)
  223. {
  224. return (asn1_der_decode_set(der_stream, len));
  225. }
  226. /*
  227.  * Decode a BIT-STRING
  228.  */
  229. int asn1_der_decode_bit_string(Bstream& der_stream, Bstream& bitstring)
  230. {
  231. byte tmp = 0;
  232. int  len, ret;
  233. if (der_stream.getlength() < 2)
  234. return (E_DER_DECODE_UNEXPECTED_EOS);
  235. (void )der_stream.peekbyte(tmp);
  236. if (tmp != BIT_STRING_ID) {
  237. return (E_DER_DECODE_BAD_ID_OCTET);
  238. }
  239. (void )der_stream.fetchbyte(tmp);
  240. len = asn1_der_get_length(der_stream);
  241. if (len < 0) return len;
  242. if (len == 0) return (E_DER_DECODE_BAD_BITSTRING);
  243. if (len > der_stream.getlength()) 
  244. return (E_DER_DECODE_UNEXPECTED_EOS);
  245. ret = der_stream.fetchbyte(tmp);
  246. if (ret == EOS)
  247. return (SUCCESS);
  248. if (len == 1) {
  249. if (tmp == 0) return (SUCCESS);
  250. else return (E_DER_DECODE_BAD_BITSTRING);
  251. }
  252. if (tmp > 7 ) 
  253. return (E_DER_DECODE_BAD_BITSTRING);
  254. // Special Hack for certificates, which
  255. // are assumed to produce octet aligned quantities
  256. if (tmp != 0)
  257. return (E_DER_DECODE_UNALIGNED_BS);
  258. Bstream tmpstr(len - 1, der_stream.getdatap());
  259. der_stream.consume(len - 1);
  260. bitstring = tmpstr;
  261. return (SUCCESS);
  262. }
  263. /*
  264.  * Decode an OCTET-STRING
  265.  */
  266. int asn1_der_decode_octet_string(Bstream& der_stream, Bstream& octetstring)
  267. {
  268. byte tmp = 0;
  269. int  len;
  270. if (der_stream.getlength() < 2)
  271. return (E_DER_DECODE_UNEXPECTED_EOS);
  272. (void )der_stream.peekbyte(tmp);
  273. if (tmp != OCTET_STRING_ID) {
  274. return (E_DER_DECODE_BAD_ID_OCTET);
  275. }
  276. (void )der_stream.fetchbyte(tmp);
  277. len = asn1_der_get_length(der_stream);
  278. if (len < 0) return len;
  279. if (len > der_stream.getlength()) 
  280. return (E_DER_DECODE_UNEXPECTED_EOS);
  281. Bstream tmpstr(len, der_stream.getdatap());
  282. der_stream.consume(len);
  283. octetstring = tmpstr;
  284. return (SUCCESS);
  285. }
  286. /*
  287.  * Decode a PRINTABLE-STRING
  288.  */
  289. int asn1_der_decode_printable_string(Bstream& der_stream, Bstream& prstring)
  290. {
  291. byte tmp = 0;
  292. int  len;
  293. if (der_stream.getlength() < 2)
  294. return (E_DER_DECODE_UNEXPECTED_EOS);
  295. (void )der_stream.peekbyte(tmp);
  296. if (tmp != PRINTABLE_STRING_ID) {
  297. return (E_DER_DECODE_BAD_ID_OCTET);
  298. }
  299. (void )der_stream.fetchbyte(tmp);
  300. len = asn1_der_get_length(der_stream);
  301. if (len < 0) return len;
  302. if (len > der_stream.getlength()) {
  303. return (E_DER_DECODE_UNEXPECTED_EOS);
  304. }
  305. Bstream tmpstr(len, der_stream.getdatap());
  306. der_stream.consume(len);
  307. prstring = tmpstr;
  308. return (SUCCESS);
  309. }
  310. /*
  311.  * Decode a T61-STRING
  312.  */
  313. int asn1_der_decode_T61_string(Bstream& der_stream, Bstream& prstring)
  314. {
  315. byte tmp = 0;
  316. int  len;
  317. if (der_stream.getlength() < 2)
  318. return (E_DER_DECODE_UNEXPECTED_EOS);
  319. (void )der_stream.peekbyte(tmp);
  320. if (tmp != T61_STRING_ID) {
  321. return (E_DER_DECODE_BAD_ID_OCTET);
  322. }
  323. (void )der_stream.fetchbyte(tmp);
  324. len = asn1_der_get_length(der_stream);
  325. if (len < 0) return len;
  326. if (len > der_stream.getlength()) 
  327. return (E_DER_DECODE_UNEXPECTED_EOS);
  328. Bstream tmpstr(len, der_stream.getdatap());
  329. der_stream.consume(len);
  330. prstring = tmpstr;
  331. return (SUCCESS);
  332. }
  333. inline void  get_twodigits(Bstream& tmpstr, byte *two_digits)
  334. {
  335. (void) tmpstr.fetchbyte(two_digits[0]);
  336. (void) tmpstr.fetchbyte(two_digits[1]);
  337. }
  338. /*
  339.  * Decode a UTCTime
  340.  */
  341. int asn1_der_decode_utctime(Bstream& der_stream, PCTime& time)
  342. {
  343. byte tmp = 0;
  344. int  len;
  345. byte two_digits[3];
  346. char sign;
  347. int year, month, day, hour, min, offhr, offmin;
  348. int sec = 0;
  349. if (der_stream.getlength() < 2)
  350. return (E_DER_DECODE_UNEXPECTED_EOS);
  351. (void )der_stream.peekbyte(tmp);
  352. if (tmp != UTCTime_ID) {
  353. return (E_DER_DECODE_BAD_ID_OCTET);
  354. }
  355. (void )der_stream.fetchbyte(tmp);
  356. len = asn1_der_get_length(der_stream);
  357. if (len < 0) return len;
  358. if (len > der_stream.getlength()) 
  359. return (E_DER_DECODE_UNEXPECTED_EOS);
  360. Bstream tmpstr(len, der_stream.getdatap());
  361. der_stream.consume(len);
  362. // Parse the Time string
  363. if (len < 11 || len > 17) {
  364. return (E_DER_DECODE_BAD_TIME_STRING);
  365. }
  366. two_digits[2] = 0; // null terminate 
  367. get_twodigits(tmpstr, two_digits);
  368. year = atoi((char *)two_digits);
  369. // Convert last two digits to full year, including century.
  370. // For this we assume that anything less than 80 is 20XX
  371. // and anything more than or equal to 80 is 19XX.
  372. // Is there a better way of doing this? XXXX
  373. if (year < 80) {
  374. year += 2000; // Fix this piece of code after year 2080!!
  375. } else {
  376. year += 1900;
  377. }
  378. get_twodigits(tmpstr, two_digits);
  379. month = atoi((char *)two_digits);
  380. get_twodigits(tmpstr, two_digits);
  381. day = atoi((char *)two_digits);
  382. get_twodigits(tmpstr, two_digits);
  383. hour = atoi((char *)two_digits);
  384. get_twodigits(tmpstr, two_digits);
  385. min = atoi((char *)two_digits);
  386. if (len == 13 || len == 17) { // secs present
  387. get_twodigits(tmpstr, two_digits);
  388. sec = atoi((char *)two_digits);
  389. }
  390. (void)tmpstr.peekbyte(tmp);
  391. if ((char)tmp != 'Z') {
  392. tmpstr.fetchbyte(tmp);
  393. sign = (char)tmp;
  394. if (sign != '-' || sign != '+') {
  395. return (E_DER_DECODE_BAD_TIME_STRING);
  396. }
  397. get_twodigits(tmpstr, two_digits);
  398. offhr = atoi((char *)two_digits);
  399. get_twodigits(tmpstr, two_digits);
  400. offmin = atoi((char *)two_digits);
  401. if (sign == '-') {
  402. hour -= offhr;
  403. min  -= offmin;
  404. } else {
  405. hour += offhr;
  406. min  += offmin;
  407. }
  408. }
  409. if ( (month > 12) || (day > 31) || (hour > 23) || (min > 59) ||
  410.      (sec > 59) ) {
  411. return (E_DER_DECODE_BAD_TIME_STRING);
  412. }
  413. PCTime tmptime(year, month, day, hour, min, sec);
  414. time = tmptime;
  415. return (SUCCESS);
  416. }
  417. byte num_to_mask(int i)
  418. {
  419. switch (i % 7) {
  420. case 0:
  421. return (0x80); // shifted left seven, top 1 bit significant
  422. case 1:
  423. return (0xC0); // shifted left six, top 2 bits significant
  424. case 2:
  425. return (0xE0); // shifted left five, top 3 bits significant
  426. case 3:
  427. return (0xF0); // shifted left four, top 4 bits
  428. case 4:
  429. return (0xF8); // etc.
  430. case 5:
  431. return (0xFC);
  432. case 6:
  433. return (0xFE);
  434. default:
  435. printf("num_to_mask: unreachable coden");
  436. return (0);
  437. }
  438. }
  439. /*
  440.  * Decode an OBJECT-IDENTIFIER
  441.  */
  442. int asn1_der_decode_obj_id(Bstream& der_stream, ObjId& objid)
  443. {
  444. byte tmp = 0;
  445. byte tmp1 = 0;
  446. int  len, tmp_len;
  447. int  retval;
  448. if (der_stream.getlength() < 2)
  449. return (E_DER_DECODE_UNEXPECTED_EOS);
  450. retval = der_stream.peekbyte(tmp);
  451. if (tmp != OBJECT_IDENTIFIER_ID) {
  452. return (E_DER_DECODE_BAD_ID_OCTET);
  453. }
  454. (void )der_stream.fetchbyte(tmp);
  455. len = asn1_der_get_length(der_stream);
  456. if (len < 0) return len;
  457. if (len > der_stream.getlength()) 
  458. return (E_DER_DECODE_UNEXPECTED_EOS);
  459. int first_subid = TRUE;
  460. while (len > 0) {
  461. // For each sub id, figure out size by peeking
  462. // into the stream.
  463. int subid_len = 0;
  464. for ( (void) der_stream.peekbyte(tmp); (tmp & 0x80) ; 
  465. (void)der_stream.peekbyte(tmp)) {
  466. len--; 
  467. if (len < 0) 
  468. return (E_DER_DECODE_BAD_OBJID_SUBID);
  469. if (subid_len == 0 && tmp == 0x80)
  470. return (E_DER_DECODE_BAD_OBJID_SUBID);
  471. subid_len++;
  472. }
  473. subid_len++; // account for last octet
  474. len--; 
  475. if (len < 0) 
  476. return (E_DER_DECODE_BAD_OBJID_SUBID);
  477. byte *subid_bits = new byte[subid_len];
  478. tmp_len = subid_len;
  479. while (tmp_len) {
  480. der_stream.fetchbyte(subid_bits[tmp_len - 1]);
  481. tmp_len--;
  482. }
  483. byte *subid_int = new byte[subid_len];
  484. bzero(subid_int, subid_len);
  485. tmp_len = subid_len;
  486. for (int i = 0; i < tmp_len; i++) {
  487. tmp = ((byte)(subid_bits[i] & 0x7f) >> (i % 7));
  488. if ( i == (tmp_len - 1)) { // Most significant octet 
  489. tmp1 = 0;
  490. } else {
  491. tmp1 = ((subid_bits[i+1] & 0x7f) << (7-(i%7)));
  492. tmp1 &= num_to_mask(i);
  493. }
  494. tmp |= tmp1;
  495. subid_int[tmp_len - (i+1)] = tmp;
  496. }
  497. Bigint I((unsigned char *)subid_int, subid_len);
  498. delete subid_bits;
  499. delete subid_int;
  500. if (first_subid) {
  501. Bigint X,Y; // X, Y are 1st and 2nd subids rsp.
  502. if (I < 80) { // X == 0, or X == 1
  503. if (I < 40)
  504. X = (short)0;
  505. else
  506. X = 1;
  507. } else { // X == 2
  508. X = 2;
  509. }
  510.   Y = I - X*40;
  511. objid.add_element(X);
  512. objid.add_element(Y);
  513. first_subid = FALSE;
  514. } else {
  515. objid.add_element(I);
  516. }
  517. }
  518. return (SUCCESS);
  519. }