derdec.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:13k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is the Netscape security libraries.
  13.  * 
  14.  * The Initial Developer of the Original Code is Netscape
  15.  * Communications Corporation.  Portions created by Netscape are 
  16.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  17.  * Rights Reserved.
  18.  * 
  19.  * Contributor(s):
  20.  * 
  21.  * Alternatively, the contents of this file may be used under the
  22.  * terms of the GNU General Public License Version 2 or later (the
  23.  * "GPL"), in which case the provisions of the GPL are applicable 
  24.  * instead of those above.  If you wish to allow use of your 
  25.  * version of this file only under the terms of the GPL and not to
  26.  * allow others to use your version of this file under the MPL,
  27.  * indicate your decision by deleting the provisions above and
  28.  * replace them with the notice and other provisions required by
  29.  * the GPL.  If you do not delete the provisions above, a recipient
  30.  * may use your version of this file under either the MPL or the
  31.  * GPL.
  32.  */
  33. #include "secder.h"
  34. #include "secerr.h"
  35. static uint32
  36. der_indefinite_length(unsigned char *buf, unsigned char *end)
  37. {
  38.     uint32 len, ret, dataLen;
  39.     unsigned char tag, lenCode;
  40.     int dataLenLen;
  41.     len = 0;
  42.     while ( 1 ) {
  43. if ((buf + 2) > end) {
  44.     return(0);
  45. }
  46. tag = *buf++;
  47. lenCode = *buf++;
  48. len += 2;
  49. if ( ( tag == 0 ) && ( lenCode == 0 ) ) {
  50.     return(len);
  51. }
  52. if ( lenCode == 0x80 ) { /* indefinite length */
  53.     ret = der_indefinite_length(buf, end); /* recurse to find length */
  54.     if (ret == 0)
  55. return 0;
  56.     len += ret;
  57.     buf += ret;
  58. } else { /* definite length */
  59.     if (lenCode & 0x80) {
  60. /* Length of data is in multibyte format */
  61. dataLenLen = lenCode & 0x7f;
  62. switch (dataLenLen) {
  63.   case 1:
  64.     dataLen = buf[0];
  65.     break;
  66.   case 2:
  67.     dataLen = (buf[0]<<8)|buf[1];
  68.     break;
  69.   case 3:
  70.     dataLen = ((unsigned long)buf[0]<<16)|(buf[1]<<8)|buf[2];
  71.     break;
  72.   case 4:
  73.     dataLen = ((unsigned long)buf[0]<<24)|
  74. ((unsigned long)buf[1]<<16)|(buf[2]<<8)|buf[3];
  75.     break;
  76.   default:
  77.     PORT_SetError(SEC_ERROR_BAD_DER);
  78.     return SECFailure;
  79. }
  80.     } else {
  81. /* Length of data is in single byte */
  82. dataLen = lenCode;
  83. dataLenLen = 0;
  84.     }
  85.     /* skip this item */
  86.     buf = buf + dataLenLen + dataLen;
  87.     len = len + dataLenLen + dataLen;
  88. }
  89.     }
  90. }
  91. /*
  92. ** Capture the next thing in the buffer.
  93. ** Returns the length of the header and the length of the contents.
  94. */
  95. static SECStatus
  96. der_capture(unsigned char *buf, unsigned char *end,
  97.     int *header_len_p, uint32 *contents_len_p)
  98. {
  99.     unsigned char *bp;
  100.     unsigned char whole_tag;
  101.     uint32 contents_len;
  102.     int tag_number;
  103.     if ((buf + 2) > end) {
  104. *header_len_p = 0;
  105. *contents_len_p = 0;
  106. if (buf == end)
  107.     return SECSuccess;
  108. return SECFailure;
  109.     }
  110.     bp = buf;
  111.     /* Get tag and verify that it is ok. */
  112.     whole_tag = *bp++;
  113.     tag_number = whole_tag & DER_TAGNUM_MASK;
  114.     /*
  115.      * XXX This code does not (yet) handle the high-tag-number form!
  116.      */
  117.     if (tag_number == DER_HIGH_TAG_NUMBER) {
  118. PORT_SetError(SEC_ERROR_BAD_DER);
  119. return SECFailure;
  120.     }
  121.     if ((whole_tag & DER_CLASS_MASK) == DER_UNIVERSAL) {
  122. /* Check that the universal tag number is one we implement.  */
  123. switch (tag_number) {
  124.   case DER_BOOLEAN:
  125.   case DER_INTEGER:
  126.   case DER_BIT_STRING:
  127.   case DER_OCTET_STRING:
  128.   case DER_NULL:
  129.   case DER_OBJECT_ID:
  130.   case DER_SEQUENCE:
  131.   case DER_SET:
  132.   case DER_PRINTABLE_STRING:
  133.   case DER_T61_STRING:
  134.   case DER_IA5_STRING:
  135.   case DER_VISIBLE_STRING:
  136.   case DER_UTC_TIME:
  137.   case 0: /* end-of-contents tag */
  138.     break;
  139.   default:
  140.     PORT_SetError(SEC_ERROR_BAD_DER);
  141.     return SECFailure;
  142. }
  143.     }
  144.     /*
  145.      * Get first byte of length code (might contain entire length, might not).
  146.      */
  147.     contents_len = *bp++;
  148.     /*
  149.      * If the high bit is set, then the length is in multibyte format,
  150.      * or the thing has an indefinite-length.
  151.      */
  152.     if (contents_len & 0x80) {
  153. int bytes_of_encoded_len;
  154. bytes_of_encoded_len = contents_len & 0x7f;
  155. contents_len = 0;
  156. switch (bytes_of_encoded_len) {
  157.   case 4:
  158.     contents_len |= *bp++;
  159.     contents_len <<= 8;
  160.     /* fallthru */
  161.   case 3:
  162.     contents_len |= *bp++;
  163.     contents_len <<= 8;
  164.     /* fallthru */
  165.   case 2:
  166.     contents_len |= *bp++;
  167.     contents_len <<= 8;
  168.     /* fallthru */
  169.   case 1:
  170.     contents_len |= *bp++;
  171.     break;
  172.   case 0:
  173.     contents_len = der_indefinite_length (bp, end);
  174.     if (contents_len)
  175. break;
  176.     /* fallthru */
  177.   default:
  178.     PORT_SetError(SEC_ERROR_BAD_DER);
  179.     return SECFailure;
  180. }
  181.     }
  182.     if ((bp + contents_len) > end) {
  183. /* Ran past end of buffer */
  184. PORT_SetError(SEC_ERROR_BAD_DER);
  185. return SECFailure;
  186.     }
  187.     *header_len_p = bp - buf;
  188.     *contents_len_p = contents_len;
  189.     return SECSuccess;
  190. }
  191. static unsigned char *
  192. der_decode(PRArenaPool *arena, void *dest, DERTemplate *dtemplate,
  193.    unsigned char *buf, int header_len, uint32 contents_len)
  194. {
  195.     unsigned char *orig_buf, *end;
  196.     unsigned long encode_kind, under_kind;
  197.     PRBool explicit, optional, universal, check_tag;
  198.     SECItem *item;
  199.     SECStatus rv;
  200.     PRBool indefinite_length, explicit_indefinite_length;
  201.     encode_kind = dtemplate->kind;
  202.     explicit = (encode_kind & DER_EXPLICIT) ? PR_TRUE : PR_FALSE;
  203.     optional = (encode_kind & DER_OPTIONAL) ? PR_TRUE : PR_FALSE;
  204.     universal = ((encode_kind & DER_CLASS_MASK) == DER_UNIVERSAL)
  205. ? PR_TRUE : PR_FALSE;
  206.     PORT_Assert (!(explicit && universal)); /* bad templates */
  207.     if (header_len == 0) {
  208. if (optional || (encode_kind & DER_ANY))
  209.     return buf;
  210. PORT_SetError(SEC_ERROR_BAD_DER);
  211. return NULL;
  212.     }
  213.     if (encode_kind & DER_POINTER) {
  214. void *place, **placep;
  215. int offset;
  216. if (dtemplate->sub != NULL) {
  217.     dtemplate = dtemplate->sub;
  218.     under_kind = dtemplate->kind;
  219.     if (universal) {
  220. encode_kind = under_kind;
  221.     }
  222.     place = PORT_ArenaZAlloc(arena, dtemplate->arg);
  223.     offset = dtemplate->offset;
  224. } else {
  225.     if (universal) {
  226. under_kind = encode_kind & ~DER_POINTER;
  227.     } else {
  228. under_kind = dtemplate->arg;
  229.     }
  230.     place = PORT_ArenaZAlloc(arena, sizeof(SECItem));
  231.     offset = 0;
  232. }
  233. if (place == NULL) {
  234.     PORT_SetError(SEC_ERROR_NO_MEMORY);
  235.     return NULL; /* Out of memory */
  236. }
  237. placep = (void **)dest;
  238. *placep = place;
  239. dest = (void *)((char *)place + offset);
  240.     } else if (encode_kind & DER_INLINE) {
  241. PORT_Assert (dtemplate->sub != NULL);
  242. dtemplate = dtemplate->sub;
  243. under_kind = dtemplate->kind;
  244. if (universal) {
  245.     encode_kind = under_kind;
  246. }
  247. dest = (void *)((char *)dest + dtemplate->offset);
  248.     } else if (universal) {
  249. under_kind = encode_kind;
  250.     } else {
  251. under_kind = dtemplate->arg;
  252.     }
  253.     orig_buf = buf;
  254.     end = buf + header_len + contents_len;
  255.     explicit_indefinite_length = PR_FALSE;
  256.     if (explicit) {
  257. /*
  258.  * This tag is expected to match exactly.
  259.  * (The template has all of the bits specified.)
  260.  */
  261. if (*buf != (encode_kind & DER_TAG_MASK)) {
  262.     if (optional)
  263. return buf;
  264.     PORT_SetError(SEC_ERROR_BAD_DER);
  265.     return NULL;
  266. }
  267. if ((header_len == 2) && (*(buf + 1) == 0x80))
  268.     explicit_indefinite_length = PR_TRUE;
  269. buf += header_len;
  270. rv = der_capture (buf, end, &header_len, &contents_len);
  271. if (rv != SECSuccess)
  272.     return NULL;
  273. if (header_len == 0) { /* XXX is this right? */
  274.     PORT_SetError(SEC_ERROR_BAD_DER);
  275.     return NULL;
  276. }
  277. optional = PR_FALSE; /* can no longer be optional */
  278. encode_kind = under_kind;
  279.     }
  280.     check_tag = PR_TRUE;
  281.     if (encode_kind & (DER_DERPTR | DER_ANY | DER_FORCE | DER_SKIP)) {
  282. PORT_Assert ((encode_kind & DER_ANY) || !optional);
  283. encode_kind = encode_kind & (~DER_FORCE);
  284. under_kind = under_kind & (~DER_FORCE);
  285. check_tag = PR_FALSE;
  286.     }
  287.     if (check_tag) {
  288. PRBool wrong;
  289. unsigned char expect_tag, expect_num;
  290. /*
  291.  * This tag is expected to match, but the simple types
  292.  * may or may not have the constructed bit set, so we
  293.  * have to have all this extra logic.
  294.  */
  295. wrong = PR_TRUE;
  296. expect_tag = encode_kind & DER_TAG_MASK;
  297. expect_num = expect_tag & DER_TAGNUM_MASK;
  298. if (expect_num == DER_SET || expect_num == DER_SEQUENCE) {
  299.     if (*buf == (expect_tag | DER_CONSTRUCTED))
  300. wrong = PR_FALSE;
  301. } else {
  302.     if (*buf == expect_tag)
  303. wrong = PR_FALSE;
  304.     else if (*buf == (expect_tag | DER_CONSTRUCTED))
  305. wrong = PR_FALSE;
  306. }
  307. if (wrong) {
  308.     if (optional)
  309. return buf;
  310.     PORT_SetError(SEC_ERROR_BAD_DER);
  311.     return NULL;
  312. }
  313.     }
  314.     if (under_kind & DER_DERPTR) {
  315. item = (SECItem *)dest;
  316. if (under_kind & DER_OUTER) {
  317.     item->data = buf;
  318.     item->len = header_len + contents_len;
  319. } else {
  320.     item->data = buf + header_len;
  321.     item->len = contents_len;
  322. }
  323. return orig_buf;
  324.     }
  325.     if (encode_kind & DER_ANY) {
  326. contents_len += header_len;
  327. header_len = 0;
  328.     }
  329.     if ((header_len == 2) && (*(buf + 1) == 0x80))
  330. indefinite_length = PR_TRUE;
  331.     else
  332. indefinite_length = PR_FALSE;
  333.     buf += header_len;
  334.     if (contents_len == 0)
  335. return buf;
  336.     under_kind &= ~DER_OPTIONAL;
  337.     if (under_kind & DER_INDEFINITE) {
  338. int count, thing_size;
  339. unsigned char *sub_buf;
  340. DERTemplate *tmpt;
  341. void *things, **indp, ***placep;
  342. under_kind &= ~DER_INDEFINITE;
  343. /*
  344.  * Count items.
  345.  */
  346. count = 0;
  347. sub_buf = buf;
  348. while (sub_buf < end) {
  349.     if (indefinite_length && sub_buf[0] == 0 && sub_buf[1] == 0) {
  350. break; 
  351.     }
  352.     rv = der_capture (sub_buf, end, &header_len, &contents_len);
  353.     if (rv != SECSuccess)
  354. return NULL;
  355.     count++;
  356.     sub_buf += header_len + contents_len;
  357. }
  358. /*
  359.  * Allocate an array of pointers to items; extra one is for a NULL.
  360.  */
  361. indp = (void**)PORT_ArenaZAlloc(arena, (count + 1) * sizeof(void *));
  362. if (indp == NULL) {
  363.     PORT_SetError(SEC_ERROR_NO_MEMORY);
  364.     return NULL;
  365. }
  366. /*
  367.  * Prepare.
  368.  */
  369. if (under_kind == DER_SET || under_kind == DER_SEQUENCE) {
  370.     tmpt = dtemplate->sub;
  371.     PORT_Assert (tmpt != NULL);
  372.     thing_size = tmpt->arg;
  373.     PORT_Assert (thing_size != 0);
  374. } else {
  375.     tmpt = NULL;
  376.     thing_size = sizeof(SECItem);
  377. }
  378. /*
  379.  * Allocate the items themselves.
  380.  */
  381. things = PORT_ArenaZAlloc(arena, count * thing_size);
  382. if (things == NULL) {
  383.     PORT_SetError(SEC_ERROR_NO_MEMORY);
  384.     return NULL;
  385. }
  386. placep = (void ***)dest;
  387. *placep = indp;
  388. while (count) {
  389.     /* ignore return value because we already did whole thing above */
  390.     (void) der_capture (buf, end, &header_len, &contents_len);
  391.     if (tmpt != NULL) {
  392. void *sub_thing;
  393. sub_thing = (void *)((char *)things + tmpt->offset);
  394. buf = der_decode (arena, sub_thing, tmpt,
  395.   buf, header_len, contents_len);
  396. if (buf == NULL)
  397.     return NULL;
  398.     } else {
  399. item = (SECItem *)things;
  400. if (under_kind == DER_ANY) {
  401.     contents_len += header_len;
  402.     header_len = 0;
  403. }
  404. buf += header_len;
  405. if (under_kind == DER_BIT_STRING) {
  406.     item->data = buf + 1;
  407.     item->len = ((contents_len - 1) << 3) - *buf;
  408. } else {
  409.     item->data = buf;
  410.     item->len = contents_len;
  411. }
  412. buf += contents_len;
  413.     }
  414.     *indp++ = things;
  415.     things = (void *)((char *)things + thing_size);
  416.     count--;
  417. }
  418. *indp = NULL;
  419. goto der_decode_done;
  420.     }
  421.     switch (under_kind) {
  422.       case DER_SEQUENCE:
  423.       case DER_SET:
  424. {
  425.     DERTemplate *tmpt;
  426.     void *sub_dest;
  427.     for (tmpt = dtemplate + 1; tmpt->kind; tmpt++) {
  428. sub_dest = (void *)((char *)dest + tmpt->offset);
  429. rv = der_capture (buf, end, &header_len, &contents_len);
  430. if (rv != SECSuccess)
  431.     return NULL;
  432. buf = der_decode (arena, sub_dest, tmpt,
  433.   buf, header_len, contents_len);
  434. if (buf == NULL)
  435.     return NULL;
  436.     }
  437. }
  438. break;
  439.       case DER_BIT_STRING:
  440. item = (SECItem *)dest;
  441. item->data = buf + 1;
  442. item->len = ((contents_len - 1) << 3) - *buf;
  443. buf += contents_len;
  444. break;
  445.       case DER_SKIP:
  446. buf += contents_len;
  447. break;
  448.       default:
  449. item = (SECItem *)dest;
  450. item->data = buf;
  451. item->len = contents_len;
  452. buf += contents_len;
  453. break;
  454.     }
  455. der_decode_done:
  456.     if (indefinite_length && buf[0] == 0 && buf[1] == 0) {
  457. buf += 2;
  458.     }
  459.     if (explicit_indefinite_length && buf[0] == 0 && buf[1] == 0) {
  460. buf += 2;
  461.     }
  462.     return buf;
  463. }
  464. SECStatus
  465. DER_Decode(PRArenaPool *arena, void *dest, DERTemplate *dtemplate, SECItem *src)
  466. {
  467.     unsigned char *buf;
  468.     uint32 buf_len, contents_len;
  469.     int header_len;
  470.     SECStatus rv;
  471.     buf = src->data;
  472.     buf_len = src->len;
  473.     rv = der_capture (buf, buf + buf_len, &header_len, &contents_len);
  474.     if (rv != SECSuccess)
  475. return rv;
  476.     dest = (void *)((char *)dest + dtemplate->offset);
  477.     buf = der_decode (arena, dest, dtemplate, buf, header_len, contents_len);
  478.     if (buf == NULL)
  479. return SECFailure;
  480.     return SECSuccess;
  481. }
  482. SECStatus
  483. DER_Lengths(SECItem *item, int *header_len_p, uint32 *contents_len_p)
  484. {
  485.     return(der_capture(item->data, &item->data[item->len], header_len_p,
  486.        contents_len_p));
  487. }