ASN1.C
上传用户:sunrenlu
上传日期:2022-06-13
资源大小:1419k
文件大小:39k
源码类别:

操作系统开发

开发平台:

DOS

  1. /* Beholder RMON ethernet network monitor,Copyright (C) 1993 DNPAP group */
  2. /* See file COPYING 'GNU General Public Licence' for copyright details   */
  3. /************************************************************************
  4. ** MODULE INFORMATION*
  5. **********************
  6. **     FILE     NAME:       asn1.c
  7. **     SYSTEM   NAME:       ASN1 Basic Encoding
  8. **     ORIGINAL AUTHOR(S):  Dirk Wisse
  9. **     VERSION  NUMBER:     1
  10. **     CREATION DATE:       1990/11/22
  11. **
  12. ** DESCRIPTION: ASN1 Basic Encoding Rules.
  13. **              Encoding takes place from end to begin. A normal
  14. **              procedure for definite encoding is:
  15. **
  16. **              Asn1Opn (Asn1, Buf, sizeof (Buf), ASN_ENC);
  17. **              Asn1EocEnc (Asn1, &EndOfSeq);
  18. **              Asn1IntEnc (Asn1, &EndOfInt, 3);
  19. **              Asn1HdrEnc (Asn1, EndOfInt, ASN_UNI, ASN_PRI, ASN_INT);
  20. **              Asn1OtsEnc (Asn1, &EndOfOts, "String", 6);
  21. **              Asn1HdrEnc (Asn1, EndOfOts, ASN_UNI, ASN_PRI, ASN_OTS);
  22. **              Asn1HdrEnc (Asn1, EndOfSeq, ASN_UNI, ASN_CON, ASN_SEQ);
  23. **              Asn1Cls (Asn1, &BufBeg, &BufLen);
  24. **
  25. **              To decode this we must do:
  26. **
  27. **              Asn1Opn (Asn1, BufBeg, BufLen, ASN_DEC);
  28. **              Asn1HdrDec (Asn1, &EndOfSeq, Cls, Con, Tag);
  29. **              Asn1HdrDec (Asn1, &EndOfOts, Cls, Con, Tag);
  30. **              Asn1OtsDec (Asn1, EndOfOts, String, sizeof (String), Length);
  31. **              Asn1HdrDec (Asn1, &EndOfInt, Cls, Con, Tag);
  32. **              Asn1IntDec (Asn1, EndOfInt, &Integer);
  33. **              Asn1EocDec (Asn1, EndOfSeq);
  34. **              Asn1Cls (Asn1, &BufBeg, &BufLen);
  35. **              
  36. **              For indefinite encoding EndOfSeq and &EndOfSeq in the
  37. **              example above should be replaced by NULL.
  38. **              For indefinite decoding nothing has to be changed.
  39. **              This can be very useful if you want to decode both
  40. **              definite and indefinite encodings.
  41. **
  42. *************************************************************************
  43. ** CHANGES INFORMATION **
  44. *************************
  45. ** REVISION:    $Revision$
  46. ** WORKFILE:    $Workfile$
  47. ** LOGINFO:     $Log$
  48. *************************************************************************/
  49. #include "dnpap.h"
  50. #include "asn1.h"
  51. /**************************************************************
  52. ** NAME:        Asn1Opn                                   [API]
  53. ** SYNOPSIS:    void Asn1Opn
  54. **                  (
  55. **                      ASN1_SCK    *Asn1,
  56. **                      BYTE        *Buf,
  57. **                      unsigned    Len,
  58. **                      unsigned    Mde
  59. **                  )
  60. ** DESCRIPTION: Opens an ASN1 socket.
  61. **              Parameters:
  62. **              Asn1: Pointer to ASN1 socket.
  63. **              Buf: Character buffer for encoding.
  64. **              Len: Length of character buffer.
  65. **              Mde: Encoding, Decoding (ASN_ENC, ASN_DEC).
  66. **              Encoding starts at the end of the buffer, and
  67. **              proceeds to the beginning.
  68. ** RETURNS:     void
  69. **************************************************************/
  70. void Asn1Opn(ASN1_SCK *Asn1, BYTE *Buf, unsigned Len, unsigned Mde)
  71. {
  72.     Asn1->Begin = Buf;
  73.     Asn1->End = Buf + Len;
  74.     Asn1->Pointer = (Mde == ASN1_ENC) ? Buf + Len : Buf;
  75. }
  76. /**************************************************************
  77. ** NAME:        Asn1Cls                                   [API]
  78. ** SYNOPSIS:    void Asn1Cls
  79. **                  (
  80. **                      ASN1_SCK    *Asn1,
  81. **                      BYTE        **Buf,
  82. **                      unsigned    *Len
  83. **                  )
  84. ** DESCRIPTION: Closes an ASN1 socket.
  85. **              Parameters:
  86. **              Asn1: Pointer to ASN1 socket.
  87. **              Buf: Pointer to beginning of encoding.
  88. **              Len: Length of encoding.
  89. ** RETURNS:     void
  90. **************************************************************/
  91. void Asn1Cls(ASN1_SCK *Asn1, BYTE **Buf, unsigned *Len)
  92. {
  93.     *Buf = Asn1->Pointer;
  94.     *Len = Asn1->End - Asn1->Pointer;
  95. }
  96. /**************************************************************
  97. ** NAME:        Asn1OctEnc
  98. ** SYNOPSIS:    BOOLEAN Asn1OctEnc
  99. **                  (
  100. **                      ASN1_SCK        *Asn1,
  101. **                      BYTE            Chr
  102. **                  )
  103. ** DESCRIPTION: Encodes an octet.
  104. ** RETURNS:     BOOLEAN success.
  105. **************************************************************/
  106. BOOLEAN Asn1OctEnc(ASN1_SCK *Asn1, BYTE Chr)
  107. {
  108.     if (Asn1->Pointer <= Asn1->Begin)
  109.         return FALSE;
  110.     *--(Asn1->Pointer) = Chr;
  111.     return TRUE;
  112. }
  113. /**************************************************************
  114. ** NAME:        Asn1OctDec
  115. ** SYNOPSIS:    BOOLEAN Asn1OctDec
  116. **                  (
  117. **                      ASN1_SCK        *Asn1,
  118. **                      BYTE            *Chr
  119. **                  )
  120. ** DESCRIPTION: Decodes an octet.
  121. ** RETURNS:     BOOLEAN success.
  122. **************************************************************/
  123. BOOLEAN Asn1OctDec(ASN1_SCK *Asn1, BYTE *Chr)
  124. {
  125.     if (Asn1->Pointer >= Asn1->End)
  126.         return FALSE;
  127.     *Chr = *(Asn1->Pointer)++;
  128.     return TRUE;
  129. }
  130. /**************************************************************
  131. ** NAME:        Asn1TagEnc
  132. ** SYNOPSIS:    BOOLEAN Asn1TagEnc
  133. **                  (
  134. **                      ASN1_SCK         *Asn1,
  135. **                      unsigned        Tag
  136. **                  )
  137. ** DESCRIPTION: Encodes a tag.
  138. ** RETURNS:     BOOLEAN success.
  139. **************************************************************/
  140. BOOLEAN Asn1TagEnc(ASN1_SCK *Asn1, unsigned Tag)
  141. {
  142.     BYTE        Chr;
  143.     Chr = (BYTE) (Tag & 0x7F);
  144.     Tag >>= 7;
  145.     if (!Asn1OctEnc (Asn1, Chr))
  146.         return FALSE;
  147.     while (Tag > 0)
  148.     {
  149.         Chr = (BYTE) (Tag | 0x80);
  150.         Tag >>= 7;
  151.         if (!Asn1OctEnc (Asn1, Chr))
  152.             return FALSE;
  153.     }
  154.     return TRUE;
  155. }
  156. /**************************************************************
  157. ** NAME:        Asn1TagDec
  158. ** SYNOPSIS:    BOOLEAN Asn1TagDec
  159. **                  (
  160. **                      ASN1_SCK         *Asn1,
  161. **                      unsigned        *Tag
  162. **                  )
  163. ** DESCRIPTION: Decodes a tag.
  164. ** RETURNS:     BOOLEAN success.
  165. **************************************************************/
  166. BOOLEAN Asn1TagDec(ASN1_SCK *Asn1, unsigned *Tag)
  167. {
  168.     BYTE        Chr;
  169.     *Tag = 0;
  170.     do
  171.     {
  172.         if (!Asn1OctDec (Asn1, &Chr))
  173.             return FALSE;
  174.         *Tag <<= 7;
  175.         *Tag |= Chr & 0x7F;
  176.     }
  177.     while ((Chr & 0x80) == 0x80);
  178.     return TRUE;
  179. }
  180. /**************************************************************
  181. ** NAME:        Asn1IdrEnc
  182. ** SYNOPSIS:    BOOLEAN Asn1IdrEnc
  183. **                  (
  184. **                      ASN1_SCK     *Asn1,
  185. **                      unsigned    Cls,
  186. **                      unsigned    Con,
  187. **                      unsigned    Tag
  188. **                  )
  189. ** DESCRIPTION: Encodes an identifier.
  190. ** RETURNS:     BOOLEAN success.
  191. **************************************************************/
  192. BOOLEAN Asn1IdrEnc(ASN1_SCK *Asn1, unsigned Cls, unsigned Con,
  193.         unsigned Tag)
  194. {
  195.     BYTE        Chr;
  196.     if (Tag >= 0x1F)
  197.     {
  198.         if (!Asn1TagEnc (Asn1, Tag))
  199.             return FALSE;
  200.         Tag = 0x1F;
  201.     }
  202.     Chr = (BYTE) ((Cls << 6) | (Con << 5) | (Tag));
  203.     if (!Asn1OctEnc (Asn1, Chr))
  204.         return FALSE;
  205.     return TRUE;
  206. }
  207. /**************************************************************
  208. ** NAME:        Asn1IdrDec
  209. ** SYNOPSIS:    BOOLEAN Asn1IdrDec
  210. **                  (
  211. **                      ASN1_SCK     *Asn1,
  212. **                      unsigned    *Cls,
  213. **                      unsigned    *Con,
  214. **                      unsigned    *Tag
  215. **                  )
  216. ** DESCRIPTION: Decodes an identifier.
  217. ** RETURNS:     BOOLEAN success.
  218. **************************************************************/
  219. BOOLEAN Asn1IdrDec(ASN1_SCK *Asn1, unsigned *Cls, unsigned *Con,
  220.         unsigned *Tag)
  221. {
  222.     BYTE        Chr;
  223.     if (!Asn1OctDec (Asn1, &Chr))
  224.         return FALSE;
  225.     *Cls = (Chr & 0xC0) >> 6;
  226.     *Con = (Chr & 0x20) >> 5;
  227.     *Tag = (Chr & 0x1F);
  228.     if (*Tag == 0x1F)
  229.     {
  230.         if (!Asn1TagDec (Asn1, Tag))
  231.             return FALSE;
  232.     }
  233.     return TRUE;
  234. }
  235. /**************************************************************
  236. ** NAME:        Asn1LenEnc
  237. ** SYNOPSIS:    BOOLEAN Asn1LenEnc
  238. **                  (
  239. **                      ASN1_SCK     *Asn1,
  240. **                      unsigned    Def,
  241. **                      unsigned    Len
  242. **                  )
  243. ** DESCRIPTION: Encodes a definite or indefinite length.
  244. ** RETURNS:     BOOLEAN success.
  245. **************************************************************/
  246. BOOLEAN Asn1LenEnc(ASN1_SCK *Asn1, unsigned Def, unsigned Len)
  247. {
  248.     BYTE        Chr,Cnt;
  249.     if (!Def)
  250.         Chr = 0x80;
  251.     else
  252.     {
  253.         if (Len < 0x80)
  254.             Chr = (BYTE) Len;
  255.         else
  256.         {
  257.             Cnt = 0;
  258.             while (Len > 0)
  259.             {
  260.                 Chr = (BYTE) Len;
  261.                 Len >>= 8;
  262.                 if (!Asn1OctEnc (Asn1, Chr))
  263.                     return FALSE;
  264.                 Cnt++;
  265.             }
  266.             Chr = (BYTE) (Cnt | 0x80);
  267.         }
  268.     }
  269.     if (!Asn1OctEnc (Asn1, Chr))
  270.         return FALSE;
  271.     return TRUE;
  272. }
  273. /**************************************************************
  274. ** NAME:        Asn1LenDec
  275. ** SYNOPSIS:    BOOLEAN Asn1LenDec
  276. **                  (
  277. **                      ASN1_SCK     *Asn1,
  278. **                      unsigned    Def,
  279. **                      unsigned    Len
  280. **                  )
  281. ** DESCRIPTION: Decodes a definite or indefinite length.
  282. ** RETURNS:     BOOLEAN success.
  283. **************************************************************/
  284. BOOLEAN Asn1LenDec(ASN1_SCK *Asn1, unsigned *Def, unsigned *Len)
  285. {
  286.     BYTE        Chr,Cnt;
  287.     if (!Asn1OctDec (Asn1, &Chr))
  288.         return FALSE;
  289.     if (Chr == 0x80)
  290.         *Def = 0;
  291.     else
  292.     {
  293.         *Def = 1;
  294.         if (Chr < 0x80)
  295.             *Len = Chr;
  296.         else
  297.         {
  298.             Cnt = (BYTE) (Chr & 0x7F);
  299.             *Len = 0;
  300.             while (Cnt > 0)
  301.             {
  302.                 if (!Asn1OctDec (Asn1, &Chr))
  303.                     return FALSE;
  304.                 *Len <<= 8;
  305.                 *Len |= Chr;
  306.                 Cnt--;
  307.             }
  308.         }
  309.     }
  310.     return TRUE;
  311. }
  312. /**************************************************************
  313. ** NAME:        Asn1HdrEnc                                [API]
  314. ** SYNOPSIS:    BOOLEAN Asn1HdrEnc
  315. **                  (
  316. **                      ASN1_SCK    *Asn1,
  317. **                      BYTE        *Eoc,
  318. **                      unsigned    Cls,
  319. **                      unsigned    Con,
  320. **                      unsigned    Tag
  321. **                  )
  322. ** DESCRIPTION: Encodes an ASN1 header.
  323. **              Parameters:
  324. **              Asn1: Pointer to ASN1 socket.
  325. **              Eoc: Pointer to end of encoding or NULL if
  326. **                   indefinite.
  327. **              Cls: Class (see asn1.h)
  328. **              Con: Primitive, Constructed (ASN_PRI, ASN_CON)
  329. **              Tag: Tag (see asn1.h)
  330. ** RETURNS:     BOOLEAN success.
  331. **************************************************************/
  332. BOOLEAN Asn1HdrEnc(ASN1_SCK *Asn1, BYTE *Eoc, unsigned Cls,
  333.         unsigned Con, unsigned Tag)
  334. {
  335.     unsigned
  336.         Def,
  337.         Len;
  338.     if (Eoc == 0)
  339.     {
  340.         Def = 0;
  341.         Len = 0;
  342.     }
  343.     else
  344.     {
  345.         Def = 1;
  346.         Len = Eoc - Asn1->Pointer;
  347.     }
  348.     if (!Asn1LenEnc (Asn1, Def, Len))
  349.         return FALSE;
  350.     if (!Asn1IdrEnc (Asn1, Cls, Con, Tag))
  351.         return FALSE;
  352.     return TRUE;
  353. }
  354. /**************************************************************
  355. ** NAME:        Asn1HdrDec                                [API]
  356. ** SYNOPSIS:    BOOLEAN Asn1HdrDec
  357. **                  (
  358. **                      ASN1_SCK    *Asn1,
  359. **                      BYTE        **Eoc,
  360. **                      unsigned    *Cls,
  361. **                      unsigned    *Con,
  362. **                      unsigned    *Tag
  363. **                  )
  364. ** DESCRIPTION: Decodes an ASN1 header.
  365. **              Parameters:
  366. **              Asn1: Pointer to ASN1 socket.
  367. **              Eoc: Pointer to end of encoding or 0 if
  368. **                   indefinite.
  369. **              Cls: Class (see asn1.h)
  370. **              Con: Primitive, Constructed (ASN_PRI, ASN_CON)
  371. **              Tag: Tag (see asn1.h)
  372. ** RETURNS:     BOOLEAN success.
  373. **************************************************************/
  374. BOOLEAN Asn1HdrDec(ASN1_SCK *Asn1, BYTE **Eoc, unsigned *Cls,
  375.         unsigned *Con, unsigned *Tag)
  376. {
  377.     unsigned
  378.         Def,
  379.         Len;
  380.     if (!Asn1IdrDec (Asn1, Cls, Con, Tag))
  381.         return FALSE;
  382.     if (!Asn1LenDec (Asn1, &Def, &Len))
  383.         return FALSE;
  384.     if (Def)
  385.         *Eoc = Asn1->Pointer + Len;
  386.     else
  387.         *Eoc = 0;
  388.     return TRUE;
  389. }
  390. /**************************************************************
  391. ** NAME:        Asn1Eoc                                   [API]
  392. ** SYNOPSIS:    BOOLEAN Asn1Eoc
  393. **                  (
  394. **                      ASN1_SCK    *Asn1,
  395. **                      BYTE        *Eoc
  396. **                  )
  397. ** DESCRIPTION: Checks if decoding is at End Of Contents.
  398. **              Parameters:
  399. **              Asn1: Pointer to ASN1 socket.
  400. **              Eoc: Pointer to end of encoding or 0 if
  401. **                   indefinite.
  402. ** RETURNS:     BOOLEAN success.
  403. **************************************************************/
  404. BOOLEAN Asn1Eoc
  405.     (
  406.         ASN1_SCK *Asn1,
  407.         BYTE     *Eoc
  408.     )
  409. {
  410.     if (Eoc == 0)
  411.         return (Asn1->Pointer [0] == 0x00 && Asn1->Pointer [1] == 0x00);
  412.     else
  413.         return (Asn1->Pointer >= Eoc);
  414. }
  415. /**************************************************************
  416. ** NAME:        Asn1EocEnc                                [API]
  417. ** SYNOPSIS:    BOOLEAN Asn1EocEnc
  418. **                  (
  419. **                      ASN1_SCK    *Asn1,
  420. **                      BYTE        **Eoc
  421. **                  )
  422. ** DESCRIPTION: Encodes End Of Contents.
  423. **              Parameters:
  424. **              Asn1: Pointer to ASN1 socket.
  425. **              Eoc: Pointer to end of encoding or 0 if
  426. **                   indefinite.
  427. **              If Eoc is 0 it encodes an ASN1 End Of
  428. **              Contents (0x00 0x00), so it produces an
  429. **              indefinite length encoding. If Eoc points to
  430. **              a character pointer, Eoc is filled with the
  431. **              pointer to the last encoded octet. This pointer
  432. **              can be used in the next Asn1HdrEnc to determine
  433. **              the length of the encoding. This produces a
  434. **              definite length encoding.
  435. ** RETURNS:     BOOLEAN success.
  436. **************************************************************/
  437. BOOLEAN Asn1EocEnc
  438.     (
  439.         ASN1_SCK *Asn1,
  440.         BYTE     **Eoc
  441.     )        
  442. {
  443.     if (Eoc == 0)
  444.     {
  445.         if (!Asn1OctEnc (Asn1, 0x00))
  446.             return FALSE;
  447.         if (!Asn1OctEnc (Asn1, 0x00))
  448.             return FALSE;
  449.         return TRUE;
  450.     }
  451.     else
  452.     {
  453.         *Eoc = Asn1->Pointer;
  454.         return TRUE;
  455.     }
  456. }
  457. /**************************************************************
  458. ** NAME:        Asn1EocDec                                [API]
  459. ** SYNOPSIS:    BOOLEAN Asn1EocDec
  460. **                  (
  461. **                      ASN1_SCK    *Asn1,
  462. **                      BYTE        *Eoc
  463. **                  )
  464. ** DESCRIPTION: Decodes End Of Contents.
  465. **              Parameters:
  466. **              Asn1: Pointer to ASN1 socket.
  467. **              Eoc: Pointer to end of encoding or 0 if
  468. **                   indefinite.
  469. **              If Eoc is 0 it decodes an ASN1 End Of
  470. **              Contents (0x00 0x00), so it has to be an
  471. **              indefinite length encoding. If Eoc is a
  472. **              character pointer, it probably was filled by
  473. **              Asn1HdrDec, and should point to the octet
  474. **              after the last of the encoding. It is checked
  475. **              if this pointer points to the octet to be
  476. **              decoded. This only takes place in decoding a
  477. **              definite length encoding.
  478. ** RETURNS:     BOOLEAN success.
  479. **************************************************************/
  480. BOOLEAN Asn1EocDec
  481.     (
  482.         ASN1_SCK *Asn1,
  483.         BYTE     *Eoc
  484.     )
  485. {
  486.     BYTE        Chr;
  487.     if (Eoc == 0)
  488.     {
  489.         if (!Asn1OctDec (Asn1, &Chr))
  490.             return FALSE;
  491.         if (Chr != 0x00)
  492.             return FALSE;
  493.         if (!Asn1OctDec (Asn1, &Chr))
  494.             return FALSE;
  495.         if (Chr != 0x00)
  496.             return FALSE;
  497.         return TRUE;
  498.     }
  499.     else
  500.     {
  501.         if (Asn1->Pointer != Eoc)
  502.             return FALSE;
  503.         return TRUE;
  504.     }
  505. }
  506. /**************************************************************
  507. ** NAME:        Asn1NulEnc                                [API]
  508. ** SYNOPSIS:    BOOLEAN Asn1NulEnc
  509. **                  (
  510. **                      ASN1_SCK    *Asn1,
  511. **                      BYTE        **Eoc
  512. **                  )
  513. ** DESCRIPTION: Encodes Null.
  514. **              Parameters:
  515. **              Asn1: Pointer to ASN1 socket.
  516. **              Eoc: Pointer to end of encoding.
  517. **              Encodes nothing but can be used to fill Eoc.
  518. ** RETURNS:     BOOLEAN success.
  519. **************************************************************/
  520. BOOLEAN Asn1NulEnc
  521.     (
  522.         ASN1_SCK *Asn1,
  523.         BYTE     **Eoc
  524.     )
  525. {
  526.     *Eoc = Asn1->Pointer;
  527.     return TRUE;
  528. }
  529. /**************************************************************
  530. ** NAME:        Asn1NulDec                                [API]
  531. ** SYNOPSIS:    BOOLEAN Asn1NulDec
  532. **                  (
  533. **                      ASN1_SCK    *Asn1,
  534. **                      BYTE        *Eoc
  535. **                  )
  536. ** DESCRIPTION: Decodes Null.
  537. **              Parameters:
  538. **              Asn1: Pointer to ASN1 socket.
  539. **              Eoc: Pointer to end of encoding or 0 if
  540. **                   indefinite.
  541. **              Decodes anything up to Eoc.
  542. ** RETURNS:     BOOLEAN success.
  543. **************************************************************/
  544. BOOLEAN Asn1NulDec
  545.     (
  546.         ASN1_SCK *Asn1,
  547.         BYTE    *Eoc
  548.     )
  549. {
  550.     Asn1->Pointer = Eoc;
  551.     return TRUE;
  552. }
  553. /**************************************************************
  554. ** NAME:        Asn1BolEnc                                [API]
  555. ** SYNOPSIS:    BOOLEAN Asn1BolEnc
  556. **                  (
  557. **                      ASN1_SCK    *Asn1,
  558. **                      BYTE        **Eoc,
  559. **                      BOOLEAN     Bol
  560. **                  )
  561. ** DESCRIPTION: Encodes Boolean.
  562. **              Parameters:
  563. **              Asn1: Pointer to ASN1 socket.
  564. **              Eoc: Pointer to end of encoding.
  565. **              Bol: FALSE, TRUE (0, !0).
  566. ** RETURNS:     BOOLEAN success.
  567. **************************************************************/
  568. BOOLEAN Asn1BolEnc
  569.     (
  570.         ASN1_SCK *Asn1,
  571.         BYTE    **Eoc,
  572.         BOOLEAN     Bol
  573.     )
  574. {
  575.     BYTE        Chr;
  576.     *Eoc = Asn1->Pointer;
  577.     Chr = (BYTE) (Bol ? 0xFF : 0x00);
  578.     if (!Asn1OctEnc (Asn1, Chr))
  579.         return FALSE;
  580.     return TRUE;
  581. }
  582. /**************************************************************
  583. ** NAME:        Asn1BolDec                                [API]
  584. ** SYNOPSIS:    BOOLEAN Asn1BolDec
  585. **                  (
  586. **                      ASN1_SCK    *Asn1,
  587. **                      BYTE        *Eoc
  588. **                      BOOLEAN     *Bol
  589. **                  )
  590. ** DESCRIPTION: Decodes Boolean.
  591. **              Parameters:
  592. **              Asn1: Pointer to ASN1 socket.
  593. **              Eoc: Pointer to end of encoding or 0 if
  594. **                   indefinite.
  595. **              Bol: False, True (0, !0).
  596. ** RETURNS:     BOOLEAN success.
  597. **************************************************************/
  598. BOOLEAN Asn1BolDec
  599.     (
  600.         ASN1_SCK *Asn1,
  601.         BYTE    *Eoc,
  602.         BOOLEAN     *Bol
  603.     )
  604. {
  605.     BYTE        Chr;
  606.     if (!Asn1OctDec (Asn1, &Chr))
  607.         return FALSE;
  608.     *Bol = Chr ? 1 : 0;
  609.     if (Asn1->Pointer != Eoc)
  610.         return FALSE;
  611.     return TRUE;
  612. }
  613. /**************************************************************
  614. ** NAME:        Asn1IntEnc                                [API]
  615. ** SYNOPSIS:    BOOLEAN Asn1IntEnc
  616. **                  (
  617. **                      ASN1_SCK    *Asn1,
  618. **                      BYTE        **Eoc,
  619. **                      int         Int
  620. **                  )
  621. ** DESCRIPTION: Encodes Integer.
  622. **              Parameters:
  623. **              Asn1: Pointer to ASN1 socket.
  624. **              Eoc: Pointer to end of encoding.
  625. **              Int: Integer.
  626. ** RETURNS:     BOOLEAN success.
  627. **************************************************************/
  628. BOOLEAN Asn1IntEnc
  629.     (
  630.         ASN1_SCK *Asn1,
  631.         BYTE    **Eoc,
  632.         int     Int
  633.     )
  634. {
  635.     BYTE        Chr,Sgn;
  636.     int
  637.         Lim;
  638.     *Eoc = Asn1->Pointer;
  639.     if (Int < 0)
  640.     {
  641.         Lim = -1;
  642.         Sgn = 0x80;
  643.     }
  644.     else
  645.     {
  646.         Lim = 0;
  647.         Sgn = 0x00;
  648.     }
  649.     do
  650.     {
  651.         Chr = (BYTE) Int;
  652.         Int >>= 8;
  653.         if (!Asn1OctEnc (Asn1, Chr))
  654.             return FALSE;
  655.     }
  656.     while ((Int != Lim) || (BYTE) (Chr & 0x80) != Sgn);
  657.     return TRUE;
  658. }
  659. /**************************************************************
  660. ** NAME:        Asn1IntDec                                [API]
  661. ** SYNOPSIS:    BOOLEAN Asn1IntDec
  662. **                  (
  663. **                      ASN1_SCK    *Asn1,
  664. **                      BYTE        *Eoc
  665. **                      int         *Int
  666. **                  )
  667. ** DESCRIPTION: Decodes Integer.
  668. **              Parameters:
  669. **              Asn1: Pointer to ASN1 socket.
  670. **              Eoc: Pointer to end of encoding or 0 if
  671. **                   indefinite.
  672. **              Int: Integer.
  673. ** RETURNS:     BOOLEAN success.
  674. **************************************************************/
  675. BOOLEAN Asn1IntDec
  676.     (
  677.         ASN1_SCK *Asn1,
  678.         BYTE     *Eoc,
  679.         int     *Int
  680.     )
  681. {
  682.     BYTE
  683.         Chr;
  684.     unsigned
  685.         Len;
  686.     if (!Asn1OctDec (Asn1, &Chr))
  687.         return FALSE;
  688.     *Int = (int) Chr;
  689.     Len = 1;
  690.     while (Asn1->Pointer < Eoc)
  691.     {
  692.         if (++Len > sizeof (int))
  693.             return FALSE;
  694.         if (!Asn1OctDec (Asn1, &Chr))
  695.             return FALSE;
  696.         *Int <<= 8;
  697.         *Int |= Chr;
  698.     }
  699.     return TRUE;
  700. }
  701. /**************************************************************
  702. ** NAME:        Asn1IntEncLng                             [API]
  703. ** SYNOPSIS:    BOOLEAN Asn1IntEncLng
  704. **                  (
  705. **                      ASN1_SCK    *Asn1,
  706. **                      BYTE        **Eoc,
  707. **                      long        Int
  708. **                  )
  709. ** DESCRIPTION: Encodes Long Integer.
  710. **              Parameters:
  711. **              Asn1: Pointer to ASN1 socket.
  712. **              Eoc: Pointer to end of encoding.
  713. **              Int: Integer.
  714. ** RETURNS:     BOOLEAN success.
  715. **************************************************************/
  716. BOOLEAN Asn1IntEncLng
  717.     (
  718.         ASN1_SCK *Asn1,
  719.         BYTE     **Eoc,
  720.         long    Int
  721.     )
  722. {
  723.     BYTE
  724.         Chr,
  725.         Sgn;
  726.     long
  727.         Lim;
  728.     *Eoc = Asn1->Pointer;
  729.     if (Int < 0)
  730.     {
  731.         Lim = -1;
  732.         Sgn = 0x80;
  733.     }
  734.     else
  735.     {
  736.         Lim = 0;
  737.         Sgn = 0x00;
  738.     }
  739.     do
  740.     {
  741.         Chr = (BYTE) Int;
  742.         Int >>= 8;
  743.         if (!Asn1OctEnc (Asn1, Chr))
  744.             return FALSE;
  745.     }
  746.     while ((Int != Lim) || (BYTE) (Chr & 0x80) != Sgn);
  747.     return TRUE;
  748. }
  749. /**************************************************************
  750. ** NAME:        Asn1IntDecLng                             [API]
  751. ** SYNOPSIS:    BOOLEAN Asn1IntDecLng
  752. **                  (
  753. **                      ASN1_SCK    *Asn1,
  754. **                      BYTE        *Eoc,
  755. **                      long        *Int
  756. **                  )
  757. ** DESCRIPTION: Decodes Long Integer.
  758. **              Parameters:
  759. **              Asn1: Pointer to ASN1 socket.
  760. **              Eoc: Pointer to end of encoding or 0 if
  761. **                   indefinite.
  762. **              Int: Integer.
  763. ** RETURNS:     BOOLEAN success.
  764. **************************************************************/
  765. BOOLEAN Asn1IntDecLng
  766.     (
  767.         ASN1_SCK *Asn1,
  768.         BYTE    *Eoc,
  769.         long    *Int
  770.     )
  771. {
  772.     BYTE
  773.         Chr;
  774.     unsigned
  775.         Len;
  776.     if (!Asn1OctDec (Asn1, &Chr))
  777.         return FALSE;
  778.     *Int = (signed char) Chr;
  779.     Len = 1;
  780.     while (Asn1->Pointer < Eoc)
  781.     {
  782.         if (++Len > sizeof (long))
  783.             return FALSE;
  784.         if (!Asn1OctDec (Asn1, &Chr))
  785.             return FALSE;
  786.         *Int <<= 8;
  787.         *Int |= Chr;
  788.     }
  789.     return TRUE;
  790. }
  791. /**************************************************************
  792. ** NAME:        Asn1IntEncUns                             [API]
  793. ** SYNOPSIS:    BOOLEAN Asn1IntEncUns
  794. **                  (
  795. **                      ASN1_SCK    *Asn1,
  796. **                      BYTE        **Eoc,
  797. **                      unsigned    Int
  798. **                  )
  799. ** DESCRIPTION: Encodes Unsigned Integer.
  800. **              Parameters:
  801. **              Asn1: Pointer to ASN1 socket.
  802. **              Eoc: Pointer to end of encoding.
  803. **              Int: Integer.
  804. ** RETURNS:     BOOLEAN success.
  805. **************************************************************/
  806. BOOLEAN Asn1IntEncUns
  807.     (
  808.         ASN1_SCK     *Asn1,
  809.         BYTE        **Eoc,
  810.         unsigned    Int
  811.     )
  812. {
  813.     BYTE
  814.         Chr;
  815.     *Eoc = Asn1->Pointer;
  816.     do
  817.     {
  818.         Chr = (BYTE) Int;
  819.         Int >>= 8;
  820.         if (!Asn1OctEnc (Asn1, Chr))
  821.             return FALSE;
  822.     }
  823.     while ((Int != 0) || (Chr & 0x80) != 0x00);
  824.     return TRUE;
  825. }
  826. /**************************************************************
  827. ** NAME:        Asn1IntDecUns                             [API]
  828. ** SYNOPSIS:    BOOLEAN An1IntDecUns
  829. **                  (
  830. **                      ASN1_SCK    *Asn1,
  831. **                      BYTE        *Eoc,
  832. **                      unsigned    *Int
  833. **                  )
  834. ** DESCRIPTION: Decodes Unsigned Integer.
  835. **              Parameters:
  836. **              Asn1: Pointer to ASN1 socket.
  837. **              Eoc: Pointer to end of encoding or 0 if
  838. **                   indefinite.
  839. **              Int: Integer.
  840. ** RETURNS:     BOOLEAN success.
  841. **************************************************************/
  842. BOOLEAN Asn1IntDecUns
  843.     (
  844.         ASN1_SCK     *Asn1,
  845.         BYTE        *Eoc,
  846.         unsigned    *Int
  847.     )
  848. {
  849.     BYTE
  850.         Chr;
  851.     unsigned
  852.         Len;
  853.     if (!Asn1OctDec (Asn1, &Chr))
  854.         return FALSE;
  855.     *Int = Chr;
  856.     if (Chr == 0)
  857.         Len = 0;
  858.     else
  859.         Len = 1;
  860.     while (Asn1->Pointer < Eoc)
  861.     {
  862.         if (++Len > sizeof (int))
  863.             return FALSE;
  864.         if (!Asn1OctDec (Asn1, &Chr))
  865.             return FALSE;
  866.         *Int <<= 8;
  867.         *Int |= Chr;
  868.     }
  869.     return TRUE;
  870. }
  871. /**************************************************************
  872. ** NAME:        Asn1IntEncLngUns                          [API]
  873. ** SYNOPSIS:    BOOLEAN Asn1IntEncLngUns
  874. **                  (
  875. **                      ASN1_SCK        *Asn1,
  876. **                      BYTE            **Eoc,
  877. **                      long unsigned   Int
  878. **                  )
  879. ** DESCRIPTION: Encodes Long Unsigned Integer.
  880. **              Parameters:
  881. **              Asn1: Pointer to ASN1 socket.
  882. **              Eoc: Pointer to end of encoding.
  883. **              Int: Integer.
  884. ** RETURNS:     BOOLEAN success.
  885. **************************************************************/
  886. BOOLEAN Asn1IntEncLngUns
  887.     (
  888.         ASN1_SCK         *Asn1,
  889.         BYTE            **Eoc,
  890.         unsigned long   Int
  891.     )
  892. {
  893.     BYTE
  894.         Chr;
  895.     *Eoc = Asn1->Pointer;
  896.     do
  897.     {
  898.         Chr = (BYTE) Int;
  899.         Int >>= 8;
  900.         if (!Asn1OctEnc (Asn1, Chr))
  901.             return FALSE;
  902.     }
  903.     while ((Int != 0) || (Chr & 0x80) != 0x00);
  904.     return TRUE;
  905. }
  906. /**************************************************************
  907. ** NAME:        Asn1IntDecLngUns                          [API]
  908. ** SYNOPSIS:    BOOLEAN Asn1IntDecLngUns
  909. **                  (
  910. **                      ASN1_SCK        *Asn1,
  911. **                      BYTE            *Eoc,
  912. **                      long unsigned   *Int
  913. **                  )
  914. ** DESCRIPTION: Decodes Long Unsigned Integer.
  915. **              Parameters:
  916. **              Asn1: Pointer to ASN1 socket.
  917. **              Eoc: Pointer to end of encoding or 0 if
  918. **                   indefinite.
  919. **              Int: Integer.
  920. ** RETURNS:     BOOLEAN success.
  921. **************************************************************/
  922. BOOLEAN Asn1IntDecLngUns
  923.     (
  924.         ASN1_SCK         *Asn1,
  925.         BYTE            *Eoc,
  926.         unsigned long   *Int
  927.     )
  928. {
  929.     BYTE
  930.         Chr;
  931.     unsigned
  932.         Len;
  933.     if (!Asn1OctDec (Asn1, &Chr))
  934.         return FALSE;
  935.     *Int = Chr;
  936.     if (Chr == 0)
  937.         Len = 0;
  938.     else
  939.         Len = 1;
  940.     while (Asn1->Pointer < Eoc)
  941.     {
  942.         if (++Len > sizeof (long))
  943.             return FALSE;
  944.         if (!Asn1OctDec (Asn1, &Chr))
  945.             return FALSE;
  946.         *Int <<= 8;
  947.         *Int |= Chr;
  948.     }
  949.     return TRUE;
  950. }
  951. /**************************************************************
  952. ** NAME:        Asn1BtsEnc                                [API]
  953. ** SYNOPSIS:    BOOLEAN Asn1BtsEnc
  954. **                  (
  955. **                      ASN1_SCK    *Asn1,
  956. **                      BYTE        **Eoc,
  957. **                      BYTE        *Bts,
  958. **                      unsigned    BtsLen,
  959. **                      BYTE        BtsUnu
  960. **                  )
  961. ** DESCRIPTION: Encodes Bit String.
  962. **              Parameters:
  963. **              Asn1: Pointer to ASN1 socket.
  964. **              Eoc: Pointer to end of encoding.
  965. **              Bts: Pointer to begin of Bit String.
  966. **              BtsLen: Length of Bit String in characters.
  967. **              BtsUnu: Number of unused bits in last character.
  968. ** RETURNS:     BOOLEAN success.
  969. **************************************************************/
  970. BOOLEAN Asn1BtsEnc
  971.     (
  972.         ASN1_SCK      *Asn1,
  973.         BYTE         **Eoc,
  974.         BYTE         *Bts,
  975.         unsigned     BtsLen,
  976.         BYTE   BtsUnu
  977.     )
  978. {
  979.     *Eoc = Asn1->Pointer;
  980.     Bts += BtsLen;
  981.     while (BtsLen-- > 0)
  982.     {
  983.         if (!Asn1OctEnc (Asn1, *--Bts))
  984.             return FALSE;
  985.     }
  986.     if (!Asn1OctEnc (Asn1, BtsUnu))
  987.         return FALSE;
  988.     return TRUE;
  989. }
  990. /**************************************************************
  991. ** NAME:        Asn1BtsDec                                [API]
  992. ** SYNOPSIS:    BOOLEAN Asn1BtsDec
  993. **                  (
  994. **                      ASN1_SCK      *Asn1,
  995. **                      BYTE         *Eoc,
  996. **                      BYTE         *Bts,
  997. **                      unsigned     BtsSze,
  998. **                      unsigned     *BtsLen,
  999. **                      BYTE   *BtsUnu
  1000. **                  )
  1001. ** DESCRIPTION: Decodes Bit String.
  1002. **              Parameters:
  1003. **              Asn1: Pointer to ASN1 socket.
  1004. **              Eoc: Pointer to end of encoding or 0 if
  1005. **                   indefinite.
  1006. **              Bts: Pointer to begin of Bit String.
  1007. **              BtsSze: Size of Bit String in characters.
  1008. **              BtsLen: Length of Bit String in characters.
  1009. **              BtsUnu: Number of unused bits in last character.
  1010. ** RETURNS:     BOOLEAN success.
  1011. **************************************************************/
  1012. BOOLEAN Asn1BtsDec
  1013.     (
  1014.         ASN1_SCK      *Asn1,
  1015.         BYTE         *Eoc,
  1016.         BYTE     *Bts,
  1017.         unsigned     BtsSze,
  1018.         unsigned     *BtsLen,
  1019.         BYTE   *BtsUnu
  1020.     )
  1021. {
  1022.     if (!Asn1OctDec (Asn1, BtsUnu))
  1023.         return FALSE;
  1024.     *BtsLen = 0;
  1025.     while (Asn1->Pointer < Eoc)
  1026.     {
  1027.         if (++(*BtsLen) > BtsSze)
  1028.             return FALSE;
  1029.         if (!Asn1OctDec (Asn1, (BYTE *)Bts++))
  1030.             return FALSE;
  1031.     }
  1032.     return TRUE;
  1033. }
  1034. /**************************************************************
  1035. ** NAME:        Asn1OtsEnc                                [API]
  1036. ** SYNOPSIS:    BOOLEAN Asn1OtsEnc
  1037. **                  (
  1038. **                      ASN1_SCK    *Asn1,
  1039. **                      BYTE        **Eoc,
  1040. **                      BYTE        *Ots,
  1041. **                      unsigned    OtsLen
  1042. **                  )
  1043. ** DESCRIPTION: Encodes Octet String.
  1044. **              Parameters:
  1045. **              Asn1: Pointer to ASN1 socket.
  1046. **              Eoc: Pointer to end of encoding.
  1047. **              Ots: Pointer to begin of Octet String.
  1048. **              OtsLen: Length of Octet String in characters.
  1049. ** RETURNS:     BOOLEAN success.
  1050. **************************************************************/
  1051. BOOLEAN Asn1OtsEnc
  1052.     (
  1053.         ASN1_SCK     *Asn1,
  1054.         BYTE        **Eoc,
  1055.         BYTE        *Ots,
  1056.         unsigned    OtsLen
  1057.     )
  1058. {
  1059.     *Eoc = Asn1->Pointer;
  1060.     Ots += OtsLen;
  1061.     while (OtsLen-- > 0)
  1062.     {
  1063.         if (!Asn1OctEnc (Asn1, *--Ots))
  1064.             return FALSE;
  1065.     }
  1066.     return TRUE;
  1067. }
  1068. /**************************************************************
  1069. ** NAME:        Asn1OtsDec                                [API]
  1070. ** SYNOPSIS:    BOOLEAN Asn1OtsDec
  1071. **                  (
  1072. **                      ASN1_SCK    *Asn1,
  1073. **                      BYTE        *Eoc,
  1074. **                      BYTE        *Ots,
  1075. **                      unsigned    OtsSze,
  1076. **                      unsigned    *OtsLen
  1077. **                  )
  1078. ** DESCRIPTION: Decodes Octet String.
  1079. **              Parameters:
  1080. **              Asn1: Pointer to ASN1 socket.
  1081. **              Eoc: Pointer to end of encoding or 0 if
  1082. **                   indefinite.
  1083. **              Ots: Pointer to begin of Octet String.
  1084. **              OtsSze: Size of Octet String in characters.
  1085. **              OtsLen: Length of Octet String in characters.
  1086. ** RETURNS:     BOOLEAN success.
  1087. **************************************************************/
  1088. BOOLEAN Asn1OtsDec
  1089.     (
  1090.         ASN1_SCK     *Asn1,
  1091.         BYTE        *Eoc,
  1092.         BYTE        *Ots,
  1093.         unsigned    OtsSze,
  1094.         unsigned    *OtsLen
  1095.     )
  1096. {
  1097.     *OtsLen = 0;
  1098.     while (Asn1->Pointer < Eoc)
  1099.     {
  1100.         if (++(*OtsLen) > OtsSze)
  1101.             return FALSE;
  1102.         if (!Asn1OctDec (Asn1, (BYTE *)Ots++))
  1103.             return FALSE;
  1104.     }
  1105.     return TRUE;
  1106. }
  1107. /**************************************************************
  1108. ** NAME:        Asn1SbiEnc
  1109. ** SYNOPSIS:    BOOLEAN Asn1SbiEnc
  1110. **                  (
  1111. **                      ASN1_SCK        *Asn1,
  1112. **                      unsigned long   Sbi
  1113. **                  )
  1114. ** DESCRIPTION: Encodes Sub Identifier.
  1115. **              Parameters:
  1116. **              Asn1: Pointer to ASN1 socket.
  1117. **              Sbi: Sub Identifier.
  1118. ** RETURNS:     BOOLEAN success.
  1119. **************************************************************/
  1120. BOOLEAN Asn1SbiEnc
  1121.     (
  1122.         ASN1_SCK      *Asn1,
  1123.         unsigned long Sbi
  1124.     )
  1125. {
  1126.     BYTE
  1127.         Chr;
  1128.     Chr = (BYTE) (Sbi & 0x7F);
  1129.     Sbi >>= 7;
  1130.     if (!Asn1OctEnc (Asn1, Chr))
  1131.         return FALSE;
  1132.     while (Sbi > 0)
  1133.     {
  1134.         Chr = (BYTE) (Sbi | 0x80);
  1135.         Sbi >>= 7;
  1136.         if (!Asn1OctEnc (Asn1, Chr))
  1137.             return FALSE;
  1138.     }
  1139.     return TRUE;
  1140. }
  1141. /**************************************************************
  1142. ** NAME:        Asn1SbiDec
  1143. ** SYNOPSIS:    BOOLEAN Asn1SbiDec
  1144. **                  (
  1145. **                      ASN1_SCK        *Asn1,
  1146. **                      unsigned long   *Sbi
  1147. **                  )
  1148. ** DESCRIPTION: Encodes Sub Identifier.
  1149. **              Parameters:
  1150. **              Asn1: Pointer to ASN1 socket.
  1151. **              Sbi: Sub Identifier.
  1152. ** RETURNS:     BOOLEAN success.
  1153. **************************************************************/
  1154. BOOLEAN Asn1SbiDec
  1155.     (
  1156.         ASN1_SCK      *Asn1,
  1157.         unsigned long *Sbi
  1158.     )
  1159. {
  1160.     BYTE
  1161.         Chr;
  1162.     *Sbi = 0;
  1163.     do
  1164.     {
  1165.         if (!Asn1OctDec (Asn1, &Chr))
  1166.             return FALSE;
  1167.         *Sbi <<= 7;
  1168.         *Sbi |= Chr & 0x7F;
  1169.     }
  1170.     while ((Chr & 0x80) == 0x80);
  1171.     return TRUE;
  1172. }
  1173. /**************************************************************
  1174. ** NAME:        Asn1OjiEnc                                [API]
  1175. ** SYNOPSIS:    BOOLEAN Asn1OjiEnc
  1176. **                  (
  1177. **                      ASN1_SCK        *Asn1,
  1178. **                      char            **Eoc,
  1179. **                      unsigned long   *Oji,
  1180. **                      unsigned        OjiLen
  1181. **                  )
  1182. ** DESCRIPTION: Encodes Obect Identifier.
  1183. **              Parameters:
  1184. **              Asn1: Pointer to ASN1 socket.
  1185. **              Eoc: Pointer to end of encoding.
  1186. **              Oji: Pointer to begin of Object Identifier.
  1187. **              OjiLen: Length of Object Identifier in unsigneds.
  1188. ** RETURNS:     BOOLEAN success.
  1189. **************************************************************/
  1190. BOOLEAN Asn1OjiEnc
  1191.     (
  1192.         ASN1_SCK        *Asn1,
  1193.         BYTE            **Eoc,
  1194.         unsigned long   *Oji,
  1195.         unsigned        OjiLen
  1196.     )
  1197. {
  1198.     unsigned long
  1199.         Sbi;
  1200.     *Eoc = Asn1->Pointer;
  1201.     if (OjiLen < 2)
  1202.         return FALSE;
  1203.     Sbi = Oji [1] + Oji [0] * 40;
  1204.     Oji += OjiLen;
  1205.     while (OjiLen-- > 2)
  1206.     {
  1207.         if (!Asn1SbiEnc (Asn1, *--Oji))
  1208.             return FALSE;
  1209.     }
  1210.     if (!Asn1SbiEnc (Asn1, Sbi))
  1211.         return FALSE;
  1212.     return TRUE;
  1213. }
  1214. /**************************************************************
  1215. ** NAME:        Asn1OjiDec                                [API]
  1216. ** SYNOPSIS:    BOOLEAN Asn1OjiDec
  1217. **                  (
  1218. **                      ASN1_SCK        *Asn1,
  1219. **                      char            *Eoc,
  1220. **                      unsigned long   *Oji,
  1221. **                      unsigned        OjiSze,
  1222. **                      unsigned        *OjiLen
  1223. **                  )
  1224. ** DESCRIPTION: Decodes Obect Identifier.
  1225. **              Parameters:
  1226. **              Asn1: Pointer to ASN1 socket.
  1227. **              Eoc: Pointer to end of encoding or 0 if
  1228. **                   indefinite.
  1229. **              Oji: Pointer to begin of Object Identifier.
  1230. **              OjiSze: Size of Obect Identifier in unsigneds
  1231. **              OjiLen: Length of Object Identifier in unsigneds.
  1232. ** RETURNS:     BOOLEAN success.
  1233. **************************************************************/
  1234. BOOLEAN Asn1OjiDec
  1235.     (
  1236.         ASN1_SCK      *Asn1,
  1237.         BYTE          *Eoc,
  1238.         unsigned long *Oji,
  1239.         unsigned      OjiSze,
  1240.         unsigned      *OjiLen
  1241.     )
  1242. {
  1243.     unsigned long
  1244.         Sbi;
  1245.     if (OjiSze < 2)
  1246.         return FALSE;
  1247.     if (!Asn1SbiDec (Asn1, &Sbi))
  1248.         return FALSE;
  1249.     if (Sbi < 40)
  1250.     {
  1251.         Oji [0] = 0;
  1252.         Oji [1] = Sbi;
  1253.     }
  1254.     else if (Sbi < 80)
  1255.     {
  1256.         Oji [0] = 1;
  1257.         Oji [1] = Sbi - 40;
  1258.     }
  1259.     else
  1260.     {
  1261.         Oji [0] = 2;
  1262.         Oji [1] = Sbi - 80;
  1263.     }
  1264.     *OjiLen = 2;
  1265.     Oji += 2;
  1266.     while (Asn1->Pointer < Eoc)
  1267.     {
  1268.         if (++(*OjiLen) > OjiSze)
  1269.             return FALSE;
  1270.         if (!Asn1SbiDec (Asn1, Oji++))
  1271.             return FALSE;
  1272.     }
  1273.     return TRUE;
  1274. }