derenc.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. /*
  36.  * Generic templates for individual/simple items.
  37.  */
  38. DERTemplate SECAnyTemplate[] = {
  39.     { DER_ANY,
  40.   0, NULL, sizeof(SECItem) }
  41. };
  42. DERTemplate SECBitStringTemplate[] = {
  43.     { DER_BIT_STRING,
  44.   0, NULL, sizeof(SECItem) }
  45. };
  46. DERTemplate SECBooleanTemplate[] = {
  47.     { DER_BOOLEAN,
  48.   0, NULL, sizeof(SECItem) }
  49. };
  50. DERTemplate SECIA5StringTemplate[] = {
  51.     { DER_IA5_STRING,
  52.   0, NULL, sizeof(SECItem) }
  53. };
  54. DERTemplate SECIntegerTemplate[] = {
  55.     { DER_INTEGER,
  56.   0, NULL, sizeof(SECItem) }
  57. };
  58. DERTemplate SECNullTemplate[] = {
  59.     { DER_NULL,
  60.   0, NULL, sizeof(SECItem) }
  61. };
  62. DERTemplate SECObjectIDTemplate[] = {
  63.     { DER_OBJECT_ID,
  64.   0, NULL, sizeof(SECItem) }
  65. };
  66. DERTemplate SECOctetStringTemplate[] = {
  67.     { DER_OCTET_STRING,
  68.   0, NULL, sizeof(SECItem) }
  69. };
  70. DERTemplate SECPrintableStringTemplate[] = {
  71.     { DER_PRINTABLE_STRING,
  72.   0, NULL, sizeof(SECItem) }
  73. };
  74. DERTemplate SECT61StringTemplate[] = {
  75.     { DER_T61_STRING,
  76.   0, NULL, sizeof(SECItem) }
  77. };
  78. DERTemplate SECUTCTimeTemplate[] = {
  79.     { DER_UTC_TIME,
  80.   0, NULL, sizeof(SECItem) }
  81. };
  82. static int
  83. header_length(DERTemplate *dtemplate, uint32 contents_len)
  84. {
  85.     uint32 len;
  86.     unsigned long encode_kind, under_kind;
  87.     PRBool explicit, optional, universal;
  88.     encode_kind = dtemplate->kind;
  89.     explicit = (encode_kind & DER_EXPLICIT) ? PR_TRUE : PR_FALSE;
  90.     optional = (encode_kind & DER_OPTIONAL) ? PR_TRUE : PR_FALSE;
  91.     universal = ((encode_kind & DER_CLASS_MASK) == DER_UNIVERSAL)
  92. ? PR_TRUE : PR_FALSE;
  93.     PORT_Assert (!(explicit && universal)); /* bad templates */
  94.     if (encode_kind & DER_POINTER) {
  95. if (dtemplate->sub != NULL) {
  96.     under_kind = dtemplate->sub->kind;
  97.     if (universal) {
  98. encode_kind = under_kind;
  99.     }
  100. } else if (universal) {
  101.     under_kind = encode_kind & ~DER_POINTER;
  102. } else {
  103.     under_kind = dtemplate->arg;
  104. }
  105.     } else if (encode_kind & DER_INLINE) {
  106. under_kind = dtemplate->sub->kind;
  107. if (universal) {
  108.     encode_kind = under_kind;
  109. }
  110.     } else if (universal) {
  111. under_kind = encode_kind;
  112.     } else {
  113. under_kind = dtemplate->arg;
  114.     }
  115.     /* This is only used in decoding; it plays no part in encoding.  */
  116.     if (under_kind & DER_DERPTR)
  117. return 0;
  118.     /* No header at all for an "empty" optional.  */
  119.     if ((contents_len == 0) && optional)
  120. return 0;
  121.     /* And no header for a full DER_ANY.  */
  122.     if (encode_kind & DER_ANY)
  123. return 0;
  124.     /*
  125.      * The common case: one octet for identifier and as many octets
  126.      * as necessary to hold the content length.
  127.      */
  128.     len = 1 + DER_LengthLength(contents_len);
  129.     /* Account for the explicit wrapper, if necessary.  */
  130.     if (explicit) {
  131. #if 0 /*
  132.  * Well, I was trying to do something useful, but these
  133.  * assertions are too restrictive on valid templates.
  134.  * I wanted to make sure that the top-level "kind" of
  135.  * a template does not also specify DER_EXPLICIT, which
  136.  * should only modify a component field.  Maybe later
  137.  * I can figure out a better way to detect such a problem,
  138.  * but for now I must remove these checks altogether.
  139.  */
  140. /*
  141.  * This modifier applies only to components of a set or sequence;
  142.  * it should never be used on a set/sequence itself -- confirm.
  143.  */
  144. PORT_Assert (under_kind != DER_SEQUENCE);
  145. PORT_Assert (under_kind != DER_SET);
  146. #endif
  147. len += 1 + DER_LengthLength(len + contents_len);
  148.     }
  149.     return len;
  150. }
  151. static uint32
  152. contents_length(DERTemplate *dtemplate, void *src)
  153. {
  154.     uint32 len;
  155.     unsigned long encode_kind, under_kind;
  156.     PRBool universal;
  157.     PORT_Assert (src != NULL);
  158.     encode_kind = dtemplate->kind;
  159.     universal = ((encode_kind & DER_CLASS_MASK) == DER_UNIVERSAL)
  160. ? PR_TRUE : PR_FALSE;
  161.     encode_kind &= ~DER_OPTIONAL;
  162.     if (encode_kind & DER_POINTER) {
  163. src = *(void **)src;
  164. if (src == NULL) {
  165.     return 0;
  166. }
  167. if (dtemplate->sub != NULL) {
  168.     dtemplate = dtemplate->sub;
  169.     under_kind = dtemplate->kind;
  170.     src = (void *)((char *)src + dtemplate->offset);
  171. } else if (universal) {
  172.     under_kind = encode_kind & ~DER_POINTER;
  173. } else {
  174.     under_kind = dtemplate->arg;
  175. }
  176.     } else if (encode_kind & DER_INLINE) {
  177. PORT_Assert (dtemplate->sub != NULL);
  178. dtemplate = dtemplate->sub;
  179. under_kind = dtemplate->kind;
  180. src = (void *)((char *)src + dtemplate->offset);
  181.     } else if (universal) {
  182. under_kind = encode_kind;
  183.     } else {
  184. under_kind = dtemplate->arg;
  185.     }
  186.     /* Having any of these bits is not expected here...  */
  187.     PORT_Assert ((under_kind & (DER_EXPLICIT | DER_INLINE | DER_OPTIONAL
  188. | DER_POINTER | DER_SKIP)) == 0);
  189.     /* This is only used in decoding; it plays no part in encoding.  */
  190.     if (under_kind & DER_DERPTR)
  191. return 0;
  192.     if (under_kind & DER_INDEFINITE) {
  193. uint32 sub_len;
  194. void **indp;
  195. indp = *(void ***)src;
  196. if (indp == NULL)
  197.     return 0;
  198. len = 0;
  199. under_kind &= ~DER_INDEFINITE;
  200. if (under_kind == DER_SET || under_kind == DER_SEQUENCE) {
  201.     DERTemplate *tmpt;
  202.     void *sub_src;
  203.     tmpt = dtemplate->sub;
  204.     for (; *indp != NULL; indp++) {
  205. sub_src = (void *)((char *)(*indp) + tmpt->offset);
  206. sub_len = contents_length (tmpt, sub_src);
  207. len += sub_len + header_length (tmpt, sub_len);
  208.     }
  209. } else {
  210.     /*
  211.      * XXX Lisa is not sure this code (for handling, for example,
  212.      * DER_INDEFINITE | DER_OCTET_STRING) is right.
  213.      */
  214.     for (; *indp != NULL; indp++) {
  215. SECItem *item;
  216. item = (SECItem *)(*indp);
  217. sub_len = item->len;
  218. if (under_kind == DER_BIT_STRING) {
  219.     sub_len = (sub_len + 7) >> 3;
  220.     /* bit string contents involve an extra octet */
  221.     if (sub_len)
  222. sub_len++;
  223. }
  224. if (under_kind != DER_ANY)
  225.     len += 1 + DER_LengthLength (sub_len);
  226.     }
  227. }
  228. return len;
  229.     }
  230.     switch (under_kind) {
  231.       case DER_SEQUENCE:
  232.       case DER_SET:
  233. {
  234.     DERTemplate *tmpt;
  235.     void *sub_src;
  236.     uint32 sub_len;
  237.     len = 0;
  238.     for (tmpt = dtemplate + 1; tmpt->kind; tmpt++) {
  239. sub_src = (void *)((char *)src + tmpt->offset);
  240. sub_len = contents_length (tmpt, sub_src);
  241. len += sub_len + header_length (tmpt, sub_len);
  242.     }
  243. }
  244. break;
  245.       case DER_BIT_STRING:
  246. len = (((SECItem *)src)->len + 7) >> 3;
  247. /* bit string contents involve an extra octet */
  248. if (len)
  249.     len++;
  250. break;
  251.       default:
  252. len = ((SECItem *)src)->len;
  253. break;
  254.     }
  255.     return len;
  256. }
  257. static unsigned char *
  258. der_encode(unsigned char *buf, DERTemplate *dtemplate, void *src)
  259. {
  260.     int header_len;
  261.     uint32 contents_len;
  262.     unsigned long encode_kind, under_kind;
  263.     PRBool explicit, optional, universal;
  264.     /*
  265.      * First figure out how long the encoding will be.  Do this by
  266.      * traversing the template from top to bottom and accumulating
  267.      * the length of each leaf item.
  268.      */
  269.     contents_len = contents_length (dtemplate, src);
  270.     header_len = header_length (dtemplate, contents_len);
  271.     /*
  272.      * Enough smarts was involved already, so that if both the
  273.      * header and the contents have a length of zero, then we
  274.      * are not doing any encoding for this element.
  275.      */
  276.     if (header_len == 0 && contents_len == 0)
  277. return buf;
  278.     encode_kind = dtemplate->kind;
  279.     explicit = (encode_kind & DER_EXPLICIT) ? PR_TRUE : PR_FALSE;
  280.     optional = (encode_kind & DER_OPTIONAL) ? PR_TRUE : PR_FALSE;
  281.     encode_kind &= ~DER_OPTIONAL;
  282.     universal = ((encode_kind & DER_CLASS_MASK) == DER_UNIVERSAL)
  283. ? PR_TRUE : PR_FALSE;
  284.     if (encode_kind & DER_POINTER) {
  285. if (contents_len) {
  286.     src = *(void **)src;
  287.     PORT_Assert (src != NULL);
  288. }
  289. if (dtemplate->sub != NULL) {
  290.     dtemplate = dtemplate->sub;
  291.     under_kind = dtemplate->kind;
  292.     if (universal) {
  293. encode_kind = under_kind;
  294.     }
  295.     src = (void *)((char *)src + dtemplate->offset);
  296. } else if (universal) {
  297.     under_kind = encode_kind & ~DER_POINTER;
  298. } else {
  299.     under_kind = dtemplate->arg;
  300. }
  301.     } else if (encode_kind & DER_INLINE) {
  302. dtemplate = dtemplate->sub;
  303. under_kind = dtemplate->kind;
  304. if (universal) {
  305.     encode_kind = under_kind;
  306. }
  307. src = (void *)((char *)src + dtemplate->offset);
  308.     } else if (universal) {
  309. under_kind = encode_kind;
  310.     } else {
  311. under_kind = dtemplate->arg;
  312.     }
  313.     if (explicit) {
  314. buf = DER_StoreHeader (buf, encode_kind,
  315.        (1 + DER_LengthLength(contents_len)
  316. + contents_len));
  317. encode_kind = under_kind;
  318.     }
  319.     if ((encode_kind & DER_ANY) == 0) { /* DER_ANY already contains header */
  320. buf = DER_StoreHeader (buf, encode_kind, contents_len);
  321.     }
  322.     /* If no real contents to encode, then we are done.  */
  323.     if (contents_len == 0)
  324. return buf;
  325.     if (under_kind & DER_INDEFINITE) {
  326. void **indp;
  327. indp = *(void ***)src;
  328. PORT_Assert (indp != NULL);
  329. under_kind &= ~DER_INDEFINITE;
  330. if (under_kind == DER_SET || under_kind == DER_SEQUENCE) {
  331.     DERTemplate *tmpt;
  332.     void *sub_src;
  333.     tmpt = dtemplate->sub;
  334.     for (; *indp != NULL; indp++) {
  335. sub_src = (void *)((char *)(*indp) + tmpt->offset);
  336. buf = der_encode (buf, tmpt, sub_src);
  337.     }
  338. } else {
  339.     for (; *indp != NULL; indp++) {
  340. SECItem *item;
  341. int sub_len;
  342. item = (SECItem *)(*indp);
  343. sub_len = item->len;
  344. if (under_kind == DER_BIT_STRING) {
  345.     if (sub_len) {
  346. int rem;
  347. sub_len = (sub_len + 7) >> 3;
  348. buf = DER_StoreHeader (buf, under_kind, sub_len + 1);
  349. rem = (sub_len << 3) - item->len;
  350. *buf++ = rem; /* remaining bits */
  351.     } else {
  352. buf = DER_StoreHeader (buf, under_kind, 0);
  353.     }
  354. } else if (under_kind != DER_ANY) {
  355.     buf = DER_StoreHeader (buf, under_kind, sub_len);
  356. }
  357. PORT_Memcpy (buf, item->data, sub_len);
  358. buf += sub_len;
  359.     }
  360. }
  361. return buf;
  362.     }
  363.     switch (under_kind) {
  364.       case DER_SEQUENCE:
  365.       case DER_SET:
  366. {
  367.     DERTemplate *tmpt;
  368.     void *sub_src;
  369.     for (tmpt = dtemplate + 1; tmpt->kind; tmpt++) {
  370. sub_src = (void *)((char *)src + tmpt->offset);
  371. buf = der_encode (buf, tmpt, sub_src);
  372.     }
  373. }
  374. break;
  375.       case DER_BIT_STRING:
  376. {
  377.     SECItem *item;
  378.     int rem;
  379.     /*
  380.      * The contents length includes our extra octet; subtract
  381.      * it off so we just have the real string length there.
  382.      */
  383.     contents_len--;
  384.     item = (SECItem *)src;
  385.     PORT_Assert (contents_len == ((item->len + 7) >> 3));
  386.     rem = (contents_len << 3) - item->len;
  387.     *buf++ = rem; /* remaining bits */
  388.     PORT_Memcpy (buf, item->data, contents_len);
  389.     buf += contents_len;
  390. }
  391. break;
  392.       default:
  393. {
  394.     SECItem *item;
  395.     item = (SECItem *)src;
  396.     PORT_Assert (contents_len == item->len);
  397.     PORT_Memcpy (buf, item->data, contents_len);
  398.     buf += contents_len;
  399. }
  400. break;
  401.     }
  402.     return buf;
  403. }
  404. SECStatus
  405. DER_Encode(PRArenaPool *arena, SECItem *dest, DERTemplate *dtemplate, void *src)
  406. {
  407.     unsigned int contents_len, header_len;
  408.     src = (void **)((char *)src + dtemplate->offset);
  409.     /*
  410.      * First figure out how long the encoding will be. Do this by
  411.      * traversing the template from top to bottom and accumulating
  412.      * the length of each leaf item.
  413.      */
  414.     contents_len = contents_length (dtemplate, src);
  415.     header_len = header_length (dtemplate, contents_len);
  416.     dest->len = contents_len + header_len;
  417.     /* Allocate storage to hold the encoding */
  418.     dest->data = (unsigned char*) PORT_ArenaAlloc(arena, dest->len);
  419.     if (dest->data == NULL) {
  420. PORT_SetError(SEC_ERROR_NO_MEMORY);
  421. return SECFailure;
  422.     }
  423.     /* Now encode into the buffer */
  424.     (void) der_encode (dest->data, dtemplate, src);
  425.     return SECSuccess;
  426. }