Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1671 lines
41 KiB

  1. /*-----------------------------------------------------------------------------
  2. * Copyright (C) Microsoft Corporation, 1995 - 1996.
  3. * All rights reserved.
  4. *
  5. * This file is part of the Microsoft Private Communication Technology
  6. * reference implementation, version 1.0
  7. *
  8. * The Private Communication Technology reference implementation, version 1.0
  9. * ("PCTRef"), is being provided by Microsoft to encourage the development and
  10. * enhancement of an open standard for secure general-purpose business and
  11. * personal communications on open networks. Microsoft is distributing PCTRef
  12. * at no charge irrespective of whether you use PCTRef for non-commercial or
  13. * commercial use.
  14. *
  15. * Microsoft expressly disclaims any warranty for PCTRef and all derivatives of
  16. * it. PCTRef and any related documentation is provided "as is" without
  17. * warranty of any kind, either express or implied, including, without
  18. * limitation, the implied warranties or merchantability, fitness for a
  19. * particular purpose, or noninfringement. Microsoft shall have no obligation
  20. * to provide maintenance, support, upgrades or new releases to you or to anyone
  21. * receiving from you PCTRef or your modifications. The entire risk arising out
  22. * of use or performance of PCTRef remains with you.
  23. *
  24. * Please see the file LICENSE.txt,
  25. * or http://pct.microsoft.com/pct/pctlicen.txt
  26. * for more information on licensing.
  27. *
  28. * Please see http://pct.microsoft.com/pct/pct.htm for The Private
  29. * Communication Technology Specification version 1.0 ("PCT Specification")
  30. *
  31. * 1/23/96
  32. *----------------------------------------------------------------------------*/
  33. #include <windows.h>
  34. #define SP_ASSERT(a)
  35. #define DebugLog(a)
  36. #define SP_LOG_RESULT(a) (a)
  37. #include "ber.h"
  38. #include "encode.h"
  39. /************************************************************/
  40. /* EncodeLength ASN1 encodes a length field. The parameter */
  41. /* dwLen is the length to be encoded, it is a DWORD and */
  42. /* therefore may be no larger than 2^32. The pbEncoded */
  43. /* parameter is the encoded result, and memory must be */
  44. /* allocated for it by the caller. The Writeflag parameter */
  45. /* indicates if the result is to be written to the pbEncoded*/
  46. /* parameter. The function returns a -1 if it fails and */
  47. /* otherwise returns the number of total bytes in the */
  48. /* encoded length. */
  49. /************************************************************/
  50. typedef struct __Algorithms {
  51. DWORD Id;
  52. UCHAR Sequence[16];
  53. DWORD SequenceLen;
  54. } _Algorithms;
  55. typedef struct __CryptAlgs {
  56. DWORD Id;
  57. DWORD idHash;
  58. UCHAR Sequence[16];
  59. DWORD SequenceLen;
  60. } _CryptAlgs;
  61. #define iso_member 0x2a, /* iso(1) memberbody(2) */
  62. #define us 0x86, 0x48, /* us(840) */
  63. #define rsadsi 0x86, 0xf7, 0x0d, /* rsadsi(113549) */
  64. #define pkcs iso_member us rsadsi 0x01, /* pkcs */
  65. #define pkcs_len 7
  66. #define rsa_dsi iso_member us rsadsi
  67. #define rsa_dsi_len 6
  68. #define joint_iso_ccitt_ds 0x55,
  69. #define attributetype 0x04,
  70. #define attributeType joint_iso_ccitt_ds attributetype
  71. #define attrtype_len 2
  72. #if 0
  73. _Algorithms KnownSigAlgs[] = {
  74. {PCT_SIG_RSA_MD2, {pkcs 1, 1}, pkcs_len + 2},
  75. {PCT_SIG_RSA_MD2, {pkcs 1, 2}, pkcs_len + 2},
  76. {PCT_SIG_RSA_MD5, {pkcs 1, 4}, pkcs_len + 2}
  77. };
  78. _Algorithms KnownKeyExchAlgs[] = {{PCT_EXCH_RSA_PKCS1, {pkcs 1, 1}, pkcs_len + 2},
  79. {PCT_EXCH_RSA_PKCS1, {pkcs 1, 2}, pkcs_len + 2},
  80. {PCT_EXCH_RSA_PKCS1, {pkcs 1, 4}, pkcs_len + 2}
  81. };
  82. _CryptAlgs KnownCryptAlgs[] = {
  83. {PCT_CIPHER_RC4 | PCT_ENC_BITS_128 | PCT_MAC_BITS_128, PCT_HASH_MD5, {rsa_dsi 3, 4}, rsa_dsi_len + 2}
  84. };
  85. #endif
  86. typedef struct _NameTypes {
  87. PSTR Prefix;
  88. UCHAR Sequence[12];
  89. DWORD SequenceLen;
  90. } NameTypes;
  91. // DO NOT change the order in this table !
  92. NameTypes KnownNameTypes[] = { {"CN=", {attributeType 3}, attrtype_len + 1},
  93. {"C=", {attributeType 6}, attrtype_len + 1},
  94. {"L=", {attributeType 7}, attrtype_len + 1},
  95. {"S=", {attributeType 8}, attrtype_len + 1},
  96. {"O=", {attributeType 10}, attrtype_len + 1},
  97. {"OU=", {attributeType 11}, attrtype_len + 1},
  98. {"Email=", {pkcs 9, 1}, pkcs_len + 2},
  99. {"Name=", {pkcs 9, 2}, pkcs_len + 2},
  100. {"Addr=", {pkcs 9, 8}, pkcs_len + 2}
  101. };
  102. /************************************************************/
  103. /* DecodeLength decodes an ASN1 encoded length field. The */
  104. /* pbEncoded parameter is the encoded length. pdwLen is */
  105. /* used to return the length therefore the length may be no */
  106. /* larger than 2^32. The function returns a -1 if it fails */
  107. /* and otherwise returns the number of total bytes in the */
  108. /* encoded length. */
  109. /************************************************************/
  110. long
  111. DecodeLength(
  112. DWORD * pdwLen,
  113. BYTE * pbEncoded,
  114. DWORD cEncoded)
  115. {
  116. long index = 0;
  117. BYTE count;
  118. SP_ASSERT(pdwLen != NULL);
  119. SP_ASSERT(pbEncoded != NULL);
  120. if(cEncoded < 1) {
  121. DebugLog((DEB_TRACE, "cEncode overflow %d\n", cEncoded));
  122. return(SP_LOG_RESULT(-1));
  123. }
  124. /* determine what the length of the length field is */
  125. if ((count = pbEncoded[0]) > 0x80)
  126. {
  127. /* if there is more than one byte in the length field then */
  128. /* the lower seven bits tells us the number of bytes */
  129. count = count ^ 0x80;
  130. /* this function only allows the length field to be 3 bytes */
  131. /* if the field is longer then the function fails */
  132. if (count > 2)
  133. {
  134. DebugLog((DEB_WARN, "Length field reported to be over 3 bytes\n"));
  135. return(SP_LOG_RESULT(-1));
  136. }
  137. if(count > cEncoded) {
  138. DebugLog((DEB_TRACE, "cEncode overflow %d\n", cEncoded));
  139. return(SP_LOG_RESULT(-1));
  140. }
  141. *pdwLen = 0;
  142. /* go through the bytes of the length field */
  143. for (index = 1; index <= count; index++)
  144. {
  145. *pdwLen = (*pdwLen << 8) + (DWORD) (pbEncoded[index]);
  146. }
  147. }
  148. /* the length field is just one byte long */
  149. else
  150. {
  151. *pdwLen = (DWORD) (pbEncoded[0]);
  152. index = 1;
  153. }
  154. /* return how many bytes there were in the length field */
  155. return index;
  156. }
  157. #if 0
  158. /************************************************************/
  159. /* DecodeSigAlgid decodes an ASN1 encoded algorithm identifier.*/
  160. /* pbEncoded parameter is the encoded identifier. pAlgid is */
  161. /* the parameter used to return the ALG_ID type algorithm */
  162. /* identifier. The Writeflag parameter tells the function */
  163. /* whether to write to pAlgid or not, if TRUE write wlse */
  164. /* don't. The function returns a -1 if it fails and */
  165. /* otherwise returns the number of total bytes in the */
  166. /* encoded algorithm identifier. */
  167. /************************************************************/
  168. long
  169. DecodeSigAlgid(
  170. DWORD * pAlgid,
  171. BYTE * pbEncoded,
  172. DWORD cEncoded,
  173. BOOL Writeflag)
  174. {
  175. DWORD i;
  176. DWORD len;
  177. SP_ASSERT(pbEncoded != NULL);
  178. SP_ASSERT(pAlgid != NULL);
  179. SP_ASSERT((!Writeflag) || (pAlgid != NULL));
  180. if(cEncoded < 2)
  181. {
  182. return(SP_LOG_RESULT(-1));
  183. }
  184. if (*pbEncoded++ != OBJECT_ID_TAG)
  185. {
  186. return(SP_LOG_RESULT(-1));
  187. }
  188. len = *pbEncoded++;
  189. if(cEncoded < 2 + len) return(SP_LOG_RESULT(-1));
  190. for (i = 0; i < sizeof(KnownSigAlgs) / sizeof(_Algorithms) ; i++ )
  191. {
  192. if (KnownSigAlgs[i].SequenceLen == len)
  193. {
  194. if (memcmp(pbEncoded, KnownSigAlgs[i].Sequence, len) == 0)
  195. {
  196. if (Writeflag)
  197. {
  198. *pAlgid = KnownSigAlgs[i].Id;
  199. }
  200. return(len + 2);
  201. }
  202. }
  203. }
  204. return(SP_LOG_RESULT(-1));
  205. }
  206. /************************************************************/
  207. /* DecodeSigAlgid decodes an ASN1 encoded algorithm identifier.*/
  208. /* pbEncoded parameter is the encoded identifier. pAlgid is */
  209. /* the parameter used to return the ALG_ID type algorithm */
  210. /* identifier. The Writeflag parameter tells the function */
  211. /* whether to write to pAlgid or not, if TRUE write wlse */
  212. /* don't. The function returns a -1 if it fails and */
  213. /* otherwise returns the number of total bytes in the */
  214. /* encoded algorithm identifier. */
  215. /************************************************************/
  216. long
  217. DecodeCryptAlgid(
  218. DWORD * pAlgid,
  219. DWORD * pHashid,
  220. BYTE * pbEncoded,
  221. DWORD cEncoded,
  222. BOOL Writeflag)
  223. {
  224. DWORD i;
  225. DWORD len;
  226. SP_ASSERT(pbEncoded != NULL);
  227. SP_ASSERT(pAlgid != NULL);
  228. SP_ASSERT((!Writeflag) || (pAlgid != NULL));
  229. if(cEncoded < 2) return(SP_LOG_RESULT(-1));
  230. if (*pbEncoded++ != OBJECT_ID_TAG)
  231. {
  232. return(SP_LOG_RESULT(-1));
  233. }
  234. len = *pbEncoded++;
  235. if(cEncoded < 2 + len)
  236. {
  237. return(SP_LOG_RESULT(-1));
  238. }
  239. for (i = 0; i < sizeof(KnownCryptAlgs) / sizeof(_Algorithms) ; i++ )
  240. {
  241. if (KnownCryptAlgs[i].SequenceLen == len)
  242. {
  243. if (memcmp(pbEncoded, KnownCryptAlgs[i].Sequence, len) == 0)
  244. {
  245. if (Writeflag)
  246. {
  247. *pAlgid = KnownCryptAlgs[i].Id;
  248. *pHashid = KnownCryptAlgs[i].idHash;
  249. }
  250. return(len + 2);
  251. }
  252. }
  253. }
  254. return(SP_LOG_RESULT(-1));
  255. }
  256. /************************************************************/
  257. /* DecodeKeyExchId decodes an ASN1 encoded algorithm identifier.*/
  258. /* pbEncoded parameter is the encoded identifier. pAlgid is */
  259. /* the parameter used to return the ALG_ID type algorithm */
  260. /* identifier. The Writeflag parameter tells the function */
  261. /* whether to write to pAlgid or not, if TRUE write wlse */
  262. /* don't. The function returns a -1 if it fails and */
  263. /* otherwise returns the number of total bytes in the */
  264. /* encoded algorithm identifier. */
  265. /************************************************************/
  266. long
  267. DecodeKeyExchAlgid(
  268. DWORD * pKeyId,
  269. BYTE * pbEncoded,
  270. DWORD cEncoded,
  271. BOOL Writeflag)
  272. {
  273. DWORD i;
  274. DWORD len;
  275. SP_ASSERT(pbEncoded != NULL);
  276. SP_ASSERT((!Writeflag) || (pKeyId != NULL));
  277. if(cEncoded < 2)
  278. {
  279. return(SP_LOG_RESULT(-1));
  280. }
  281. if (*pbEncoded++ != OBJECT_ID_TAG)
  282. {
  283. return(SP_LOG_RESULT(-1));
  284. }
  285. len = *pbEncoded++;
  286. if(cEncoded < 2 + len)
  287. {
  288. return(SP_LOG_RESULT(-1));
  289. }
  290. for (i = 0; i < sizeof(KnownCryptAlgs) / sizeof(_Algorithms) ; i++ )
  291. {
  292. if (KnownKeyExchAlgs[i].SequenceLen == len)
  293. {
  294. if (memcmp(pbEncoded, KnownKeyExchAlgs[i].Sequence, len) == 0)
  295. {
  296. if (Writeflag)
  297. {
  298. *pKeyId = KnownKeyExchAlgs[i].Id;
  299. }
  300. return(len + 2);
  301. }
  302. }
  303. }
  304. return(SP_LOG_RESULT(-1));
  305. }
  306. #endif
  307. /************************************************************/
  308. /* DecodeHeader decodes an ASN1 encoded sequence type header.*/
  309. /* pbEncoded parameter is the encoded header. pdwLen is */
  310. /* the parameter used to return the length of the encoded */
  311. /* sequence. The function returns a -1 if it fails and */
  312. /* otherwise returns the number of total bytes in the */
  313. /* encoded header, not including the content. */
  314. /************************************************************/
  315. long
  316. DecodeHeader(
  317. DWORD * pdwLen,
  318. BYTE * pbEncoded,
  319. DWORD cEncoded)
  320. {
  321. long len;
  322. SP_ASSERT(pdwLen != NULL);
  323. SP_ASSERT(pbEncoded != NULL);
  324. if(cEncoded < 1)
  325. {
  326. DebugLog((DEB_TRACE, "Buffer Overflow\n"));
  327. return(SP_LOG_RESULT(-1));
  328. }
  329. /* make sure this is a sequence type */
  330. if (pbEncoded[0] != SEQUENCE_TAG)
  331. {
  332. DebugLog((DEB_WARN, "Sequence Tag not found, %x instead\n", pbEncoded[0]));
  333. return(SP_LOG_RESULT(-1));
  334. }
  335. /* decode the length */
  336. if ((len = DecodeLength (pdwLen, pbEncoded + 1, cEncoded-1)) == -1)
  337. {
  338. DebugLog((DEB_TRACE, "Bad Length Decode\n"));
  339. return(SP_LOG_RESULT(-1));
  340. }
  341. return (len + 1);
  342. }
  343. /************************************************************/
  344. /* DecodeSetOfHeader decodes an ASN1 encoded set of type */
  345. /* header. pbEncoded parameter is the encoded header. pdwLen*/
  346. /* is the parameter used to return the length of the encoded*/
  347. /* set of. The function returns a -1 if it fails and */
  348. /* otherwise returns the number of total bytes in the */
  349. /* encoded header, not including the content. */
  350. /************************************************************/
  351. long
  352. DecodeSetOfHeader(
  353. DWORD * pdwLen,
  354. BYTE * pbEncoded,
  355. DWORD cEncoded)
  356. {
  357. long len;
  358. SP_ASSERT(pdwLen != NULL);
  359. SP_ASSERT(pbEncoded != NULL);
  360. if(cEncoded < 1)
  361. {
  362. return(SP_LOG_RESULT(-1));
  363. }
  364. /* make sure this is a sequence type */
  365. if (*pbEncoded != SET_OF_TAG)
  366. {
  367. return(SP_LOG_RESULT(-1));
  368. }
  369. /* decode the length */
  370. if ((len = DecodeLength (pdwLen, pbEncoded + 1, cEncoded-1)) == -1)
  371. return(-1);
  372. return (len + 1);
  373. }
  374. long
  375. DecodeSetHeader(
  376. DWORD * pdwLen,
  377. BYTE * pbEncoded,
  378. DWORD cEncoded)
  379. {
  380. long len;
  381. SP_ASSERT(pdwLen != NULL);
  382. SP_ASSERT(pbEncoded != NULL);
  383. if(cEncoded < 1)
  384. {
  385. return(SP_LOG_RESULT(-1));
  386. }
  387. if (*pbEncoded != BER_SET)
  388. {
  389. return(SP_LOG_RESULT(-1));
  390. }
  391. if((len = DecodeLength(pdwLen, pbEncoded + 1, cEncoded-1)) == -1)
  392. {
  393. return(-1);
  394. }
  395. return(len + 1);
  396. }
  397. /****************************************************************/
  398. /* DecodeInteger decodes an ASN1 encoded integer. The encoded */
  399. /* integer is passed into the function with the pbEncoded */
  400. /* parameter. The pbInt parameter is used to pass back the */
  401. /* integer as an array of bytes, and dwLen is the number of */
  402. /* in the array. The least significant byte of the integer */
  403. /* is the zeroth byte of the array. The Writeflag indicates */
  404. /* indicates if the result is to be written to the pbInt */
  405. /* parameter. The function returns a -1 if it fails and */
  406. /* otherwise returns the number of total bytes in the encoded */
  407. /* integer. */
  408. /* This implementation will only deal with positive integers. */
  409. /****************************************************************/
  410. long
  411. DecodeInteger(
  412. BYTE * pbInt,
  413. DWORD cbBuff,
  414. DWORD * pdwLen,
  415. BYTE * pbEncoded,
  416. DWORD cEncoded,
  417. BOOL Writeflag)
  418. {
  419. long count;
  420. long i;
  421. SP_ASSERT(pdwLen != NULL);
  422. SP_ASSERT(pbEncoded != NULL);
  423. SP_ASSERT((!Writeflag) || (pbInt != NULL));
  424. if(cEncoded < 1)
  425. {
  426. return(SP_LOG_RESULT(-1));
  427. }
  428. /* make sure this is tagged as an integer */
  429. if (pbEncoded[0] != INTEGER_TAG)
  430. {
  431. return(SP_LOG_RESULT(-1));
  432. }
  433. count = 1;
  434. /* decode the length field */
  435. if ((i = DecodeLength (pdwLen, pbEncoded + 1, cEncoded-count)) == -1)
  436. {
  437. return(-1);
  438. }
  439. count += i;
  440. if(cEncoded < count+*pdwLen)
  441. {
  442. return(SP_LOG_RESULT(-1));
  443. }
  444. /* write the integer out if suppose to */
  445. if (Writeflag)
  446. {
  447. if (pbEncoded[count] == 0)
  448. {
  449. count++;
  450. (*pdwLen)--;
  451. }
  452. if(*pdwLen > cbBuff) return -1;
  453. i = (*pdwLen) - 1;
  454. while (i >= 0)
  455. {
  456. pbInt[i--] = pbEncoded[count++];
  457. }
  458. }
  459. else
  460. {
  461. count += (long) *pdwLen;
  462. }
  463. /* return the length of the encoded integer */
  464. return (count);
  465. }
  466. /****************************************************************/
  467. /* DecodeString decodes an ASN1 encoded a character string. The*/
  468. /* encoded string is passed into the function with the pbEncoded*/
  469. /* parameter. The pbStr is used to pass the decoded string back*/
  470. /* to the caller, and pdwLen is the number of characters in the */
  471. /* decoded array. The Writeflag indicates if the result is to */
  472. /* be written to the pbStr parameter. The function returns a */
  473. /* -1 if it fails and otherwise returns the number of bytes in */
  474. /* the encoded string. */
  475. /****************************************************************/
  476. long
  477. DecodeString(
  478. BYTE * pbStr,
  479. DWORD * pdwLen,
  480. BYTE * pbEncoded,
  481. DWORD cEncoded,
  482. BOOL Writeflag)
  483. {
  484. long index;
  485. SP_ASSERT(pdwLen != NULL);
  486. SP_ASSERT(pbEncoded != NULL);
  487. SP_ASSERT((!Writeflag) || (pbStr != NULL));
  488. if(cEncoded < 1)
  489. {
  490. return(SP_LOG_RESULT(-1));
  491. }
  492. if ((*pbEncoded != BER_PRINTABLE_STRING) &&
  493. (*pbEncoded != BER_TELETEX_STRING) &&
  494. (*pbEncoded != BER_GRAPHIC_STRING) &&
  495. (*pbEncoded != BER_IA5STRING))
  496. {
  497. return(SP_LOG_RESULT(-1));
  498. }
  499. /* determine how long the string is */
  500. if ((index = DecodeLength (pdwLen, pbEncoded + 1, cEncoded-1)) == -1)
  501. {
  502. return(-1);
  503. }
  504. index++;
  505. if(cEncoded < index + *pdwLen)
  506. {
  507. return(SP_LOG_RESULT(-1));
  508. }
  509. if (Writeflag)
  510. {
  511. CopyMemory(pbStr, pbEncoded + index, *pdwLen);
  512. }
  513. return (index + *pdwLen);
  514. }
  515. /****************************************************************/
  516. /* DecodeOctetString decodes an ASN1 encoded a octet string. The*/
  517. /* encoded string is passed into the function with the pbEncoded*/
  518. /* parameter. The pbStr is used to pass the decoded string back*/
  519. /* to the caller, and pdwLen is the number of characters in the */
  520. /* decoded array. The Writeflag indicates if the result is to */
  521. /* be written to the pbStr parameter. The function returns a */
  522. /* -1 if it fails and otherwise returns the number of bytes in */
  523. /* the encoded string. */
  524. /****************************************************************/
  525. long
  526. DecodeOctetString(
  527. BYTE * pbStr,
  528. DWORD * pdwLen,
  529. BYTE * pbEncoded,
  530. DWORD cEncoded,
  531. BOOL Writeflag)
  532. {
  533. long index;
  534. SP_ASSERT(pdwLen != NULL);
  535. SP_ASSERT(pbEncoded != NULL);
  536. SP_ASSERT((!Writeflag) || (pbStr != NULL));
  537. if(cEncoded < 1)
  538. {
  539. DebugLog((DEB_TRACE, "cEncoded Overflow:%d\n", cEncoded));
  540. return(SP_LOG_RESULT(-1));
  541. }
  542. if (pbEncoded[0] != OCTET_STRING_TAG)
  543. {
  544. DebugLog((DEB_TRACE, "Invalid Tag, expected OCTET_STRING, got %d\n", pbEncoded[0]));
  545. return(SP_LOG_RESULT(-1));
  546. }
  547. /* determine how long the string is */
  548. if ((index = DecodeLength (pdwLen, pbEncoded + 1, cEncoded-1)) == -1)
  549. {
  550. return(-1);
  551. }
  552. index++;
  553. if(cEncoded < index+*pdwLen)
  554. {
  555. return(SP_LOG_RESULT(-1));
  556. }
  557. if (Writeflag)
  558. {
  559. CopyMemory(pbStr, pbEncoded + index, *pdwLen);
  560. }
  561. return (index + *pdwLen);
  562. }
  563. /****************************************************************/
  564. /* DecodeBitString decodes an ASN1 encoded a bit string. The */
  565. /* encoded string is passed into the function with the pbEncoded*/
  566. /* parameter. The pbStr is used to pass the decoded string back*/
  567. /* to the caller, and pdwLen is the number of characters in the */
  568. /* decoded array. The Writeflag indicates if the result is to */
  569. /* be written to the pbStr parameter. The function returns a */
  570. /* -1 if it fails and otherwise returns the number of bytes in */
  571. /* the encoded string. The DER are used in the decoding. */
  572. /****************************************************************/
  573. long
  574. DecodeBitString(
  575. BYTE * pbStr,
  576. DWORD * pdwLen,
  577. BYTE * pbEncoded,
  578. DWORD cEncoded,
  579. BOOL Writeflag)
  580. {
  581. long index;
  582. SP_ASSERT(pdwLen != NULL);
  583. SP_ASSERT(pbEncoded != NULL);
  584. SP_ASSERT((!Writeflag) || (pbStr != NULL));
  585. if(cEncoded < 1)
  586. {
  587. return(SP_LOG_RESULT(-1));
  588. }
  589. if (pbEncoded[0] != BIT_STRING_TAG)
  590. {
  591. return(SP_LOG_RESULT(-1));
  592. }
  593. /* determine how long the string is */
  594. if ((index = DecodeLength (pdwLen, pbEncoded + 1, cEncoded-1)) == -1)
  595. {
  596. return(-1);
  597. }
  598. /* move the index up two bytes, one for the tag and one for the byte after */
  599. /* the length which tells the number of unused bits in the last byte, that */
  600. /* byte is always zero in this implementation, so it is ignored */
  601. index += 2;
  602. /* subtract one from the length of the bit string (in bytes) since, */
  603. /* to account for the byte after the length */
  604. (*pdwLen)--;
  605. if(cEncoded < index + *pdwLen)
  606. {
  607. return(SP_LOG_RESULT(-1));
  608. }
  609. if (Writeflag)
  610. {
  611. CopyMemory(pbStr, pbEncoded + index, *pdwLen);
  612. }
  613. return (index + *pdwLen);
  614. }
  615. #if 0
  616. #ifdef SECURITY_LINUX
  617. /****************************************************************/
  618. /* DecodeUTCTime decodes an ASN1 encoded Universal time type. */
  619. /* time type. The Time parameter is the time passed into the */
  620. /* function as a time_t type. The encoded result is passed back*/
  621. /* in the pbEncoded parameter. The Writeflag indicates if the */
  622. /* result is to be written to the pbEncoded parameter. The */
  623. /* function returns a -1 if it fails and otherwise returns the */
  624. /* number of total bytes in the encoded universal time. */
  625. /****************************************************************/
  626. long
  627. DecodeUTCTime(time_t *pTime, BYTE *pbEncoded, DWORD cEncoded, BOOL Writeflag)
  628. {
  629. long count;
  630. struct tm tmTime;
  631. DWORD dwLen;
  632. SP_ASSERT(pbEncoded != NULL);
  633. SP_ASSERT((!Writeflag) || (pTime != NULL));
  634. if(cEncoded < 1)
  635. {
  636. return(SP_LOG_RESULT(-1));
  637. }
  638. /* check to make sure this is a universal time type */
  639. if (pbEncoded[0] != UTCTIME_TAG)
  640. {
  641. return(SP_LOG_RESULT(-1));
  642. }
  643. /* decode the length */
  644. if ((count = DecodeLength (&dwLen, pbEncoded + 1, cEncoded-1)) == -1)
  645. {
  646. return -1;
  647. }
  648. count++;
  649. dwLen += count;
  650. if(cEncoded < dwLen)
  651. {
  652. return(SP_LOG_RESULT(-1));
  653. }
  654. if (Writeflag)
  655. {
  656. /* extract the year */
  657. tmTime.tm_year = (int)((pbEncoded[count] - 0x30) * 0xA
  658. + (pbEncoded[count + 1] - 0x30));
  659. count += 2;
  660. /* extract the month */
  661. tmTime.tm_mon = (int)((pbEncoded[count] - 0x30) * 0xA
  662. + (pbEncoded[count + 1] - 0x30));
  663. count += 2;
  664. /* extract the day */
  665. tmTime.tm_mday = (int)((pbEncoded[count] - 0x30) * 0xA
  666. + (pbEncoded[count + 1] - 0x30));
  667. count += 2;
  668. /* extract the hour */
  669. tmTime.tm_hour = (int)((pbEncoded[count] - 0x30) * 0xA
  670. + (pbEncoded[count + 1] - 0x30));
  671. count += 2;
  672. /* extract the minutes */
  673. tmTime.tm_min = (int)((pbEncoded[count] - 0x30) * 0xA
  674. + (pbEncoded[count + 1] - 0x30));
  675. count += 2;
  676. /* extract the seconds */
  677. tmTime.tm_sec = (int)((pbEncoded[count] - 0x30) * 0xA
  678. + (pbEncoded[count + 1] - 0x30));
  679. count += 2;
  680. /* make sure there is a Z at the end */
  681. if (pbEncoded[count] != 'Z')
  682. {
  683. return(SP_LOG_RESULT(-1));
  684. }
  685. *pTime = mktime (&tmTime);
  686. }
  687. return (long)dwLen;
  688. }
  689. #else /* SECURITY_LINUX */
  690. long
  691. DecodeFileTime(
  692. FILETIME * pTime,
  693. BYTE * pbEncoded,
  694. DWORD cEncoded,
  695. BOOL WriteFlag)
  696. {
  697. LONGLONG ft;
  698. LONGLONG delta;
  699. SYSTEMTIME st;
  700. long count;
  701. DWORD dwLen, dwTotalLen;
  702. BOOL fUTC;
  703. int Offset;
  704. SP_ASSERT(pTime != NULL);
  705. SP_ASSERT(pbEncoded != NULL);
  706. SP_ASSERT((!WriteFlag) || (pTime != NULL));
  707. if(cEncoded < 1)
  708. {
  709. return(SP_LOG_RESULT(-1));
  710. }
  711. /* check to make sure this is a universal time type */
  712. if (pbEncoded[0] != UTCTIME_TAG)
  713. {
  714. return(SP_LOG_RESULT(-1));
  715. }
  716. /* decode the length */
  717. if ((count = DecodeLength (&dwLen, pbEncoded + 1, cEncoded-1)) == -1)
  718. {
  719. return(-1);
  720. }
  721. count++;
  722. dwTotalLen = dwLen + count;
  723. if(cEncoded < dwLen)
  724. {
  725. return(SP_LOG_RESULT(-1));
  726. }
  727. pbEncoded += count;
  728. if (WriteFlag)
  729. {
  730. st.wYear = (WORD) ((pbEncoded[0] - '0') * 10) +
  731. (pbEncoded[1] - '0');
  732. if (st.wYear < 90)
  733. {
  734. st.wYear += 2000;
  735. }
  736. else
  737. {
  738. st.wYear += 1900;
  739. }
  740. pbEncoded += 2;
  741. dwLen -= 2;
  742. st.wMonth = (WORD) ((pbEncoded[0] - '0') * 10) +
  743. (pbEncoded[1] - '0');
  744. pbEncoded += 2;
  745. dwLen -= 2;
  746. st.wDay = (WORD) ((pbEncoded[0] - '0') * 10) +
  747. (pbEncoded[1] - '0');
  748. pbEncoded += 2;
  749. dwLen -= 2;
  750. st.wHour = (WORD) ((pbEncoded[0] - '0') * 10) +
  751. (pbEncoded[1] - '0');
  752. pbEncoded += 2;
  753. dwLen -= 2;
  754. st.wMinute = (WORD) ((pbEncoded[0] - '0') * 10) +
  755. (pbEncoded[1] - '0');
  756. pbEncoded += 2;
  757. dwLen -= 2;
  758. fUTC = FALSE;
  759. Offset = 0;
  760. st.wSecond = 0;
  761. if (dwLen)
  762. {
  763. //
  764. // Ok, still more to go:
  765. //
  766. if (*pbEncoded == 'Z')
  767. {
  768. DebugLog((DEB_TRACE, "FileTime: no seconds, Z term\n"));
  769. //
  770. // Ok, it is UTC.
  771. //
  772. dwLen++;
  773. pbEncoded++;
  774. }
  775. else
  776. {
  777. if ((*pbEncoded == '+') ||
  778. (*pbEncoded == '-') )
  779. {
  780. DebugLog((DEB_TRACE, "FileTime: no seconds, offset\n"));
  781. //
  782. // Yuck! Offset encoded!
  783. //
  784. if (dwLen != 5)
  785. {
  786. return( -1 );
  787. }
  788. Offset = (int) ((pbEncoded[1] - '0') * 10) +
  789. (pbEncoded[2] - '0');
  790. Offset *= 60;
  791. Offset += (int) ((pbEncoded[3] - '0') * 10) +
  792. (pbEncoded[4] - '0');
  793. if (pbEncoded[0] == '-')
  794. {
  795. Offset *= -1;
  796. }
  797. }
  798. else
  799. {
  800. st.wSecond = (WORD) ((pbEncoded[0] - '0') * 10) +
  801. (pbEncoded[1] - '0');
  802. if (dwLen == 3)
  803. {
  804. if (pbEncoded[2] != 'Z')
  805. {
  806. return( -1 );
  807. }
  808. }
  809. else if (dwLen > 3)
  810. {
  811. Offset = (int) ((pbEncoded[3] - '0') * 10) +
  812. (pbEncoded[4] - '0');
  813. Offset *= 60;
  814. Offset += (int) ((pbEncoded[5] - '0') * 10) +
  815. (pbEncoded[6] - '0');
  816. if (pbEncoded[2] == '-')
  817. {
  818. Offset *= -1;
  819. }
  820. }
  821. }
  822. }
  823. }
  824. st.wMilliseconds = 0;
  825. SystemTimeToFileTime(&st, (FILETIME *) &ft);
  826. if (Offset != 0)
  827. {
  828. delta = (LONGLONG) Offset * 10000000;
  829. ft += delta;
  830. }
  831. *pTime = *((FILETIME *) &ft);
  832. }
  833. return(dwTotalLen);
  834. }
  835. #endif / * SECURITY_LINUX */
  836. #endif
  837. /****************************************************************/
  838. /* DecodeName decodes an ASN1 encoded Name type. The encoded */
  839. /* name is passed into the function with the pbEncoded parameter*/
  840. /* The pbName parameter is used to pass the name back to the */
  841. /* caller and pdwLen is the length of the name in bytes. */
  842. /* The Writeflag indicates if the result is to be written to */
  843. /* the pbName parameter. The function returns a -1 if it */
  844. /* fails and otherwise returns the number of total bytes in the */
  845. /* encoded name. */
  846. /****************************************************************/
  847. long
  848. DecodeName(
  849. BYTE * pbName,
  850. DWORD * pdwLen,
  851. BYTE * pbEncoded,
  852. DWORD cEncoded,
  853. BOOL Writeflag)
  854. {
  855. long index;
  856. DWORD dwLen;
  857. SP_ASSERT(pdwLen != NULL);
  858. SP_ASSERT(pbEncoded != NULL);
  859. SP_ASSERT((!Writeflag) || (pbName != NULL));
  860. /* decode the sequence header */
  861. if ((index = DecodeHeader (&dwLen, pbEncoded, cEncoded)) == -1)
  862. {
  863. return(-1);
  864. }
  865. /* decode the set of header */
  866. if ((index += DecodeSetOfHeader (&dwLen, pbEncoded + index, cEncoded-index)) < index)
  867. {
  868. return(-1);
  869. }
  870. /* decode the sequence header */
  871. if ((index += DecodeHeader (&dwLen, pbEncoded + index, cEncoded-index)) < index)
  872. {
  873. return(-1);
  874. }
  875. /* decode the attribute type, in this implementation it is fake */
  876. index += 3; /* 3 because this is the length of the fake OBJECT IDENTIFIER */
  877. /* decode the string which is the name */
  878. if ((index += DecodeString (pbName, pdwLen, pbEncoded + index, cEncoded-index, Writeflag)) < index)
  879. {
  880. return(-1);
  881. }
  882. return index;
  883. }
  884. long
  885. DecodeNull(
  886. BYTE * pbEncoded, DWORD cEncoded)
  887. {
  888. SP_ASSERT(pbEncoded != NULL);
  889. if(cEncoded < 2) return(SP_LOG_RESULT(-1));
  890. if (*pbEncoded != NULL_TAG)
  891. {
  892. return(SP_LOG_RESULT(-1));
  893. }
  894. return(2);
  895. }
  896. long
  897. IisDecodeNameType(
  898. int * piPrefix,
  899. BYTE * pbEncoded,
  900. DWORD cEncoded)
  901. {
  902. DWORD i;
  903. DWORD len;
  904. SP_ASSERT(piPrefix != NULL);
  905. SP_ASSERT(pbEncoded != NULL);
  906. if(cEncoded < 1)
  907. {
  908. return(SP_LOG_RESULT(-1));
  909. }
  910. if (*pbEncoded != OBJECT_ID_TAG)
  911. {
  912. return(SP_LOG_RESULT(-1));
  913. }
  914. pbEncoded++;
  915. len = *pbEncoded++;
  916. if(cEncoded < len+2)
  917. {
  918. return(SP_LOG_RESULT(-1));
  919. }
  920. for (i = 0; i < sizeof(KnownNameTypes) / sizeof(NameTypes) ; i++ )
  921. {
  922. if (KnownNameTypes[i].SequenceLen == len)
  923. {
  924. if (memcmp(pbEncoded, KnownNameTypes[i].Sequence, len) == 0)
  925. {
  926. *piPrefix = i;
  927. return(len + 2);
  928. }
  929. }
  930. }
  931. *piPrefix = -1;
  932. return len + 2;
  933. }
  934. long
  935. IisDecodeRDN(
  936. PSTR *pValue,
  937. PSTR pBuf,
  938. DWORD * pdwComponentLength,
  939. BYTE * pbEncoded,
  940. DWORD cEncoded
  941. )
  942. {
  943. long index;
  944. DWORD dwLen;
  945. long CompLen = 0;
  946. long Processed;
  947. long RdnLen;
  948. BOOL fTmpWrite;
  949. PSTR pName;
  950. int iPrefixType;
  951. index = DecodeSetHeader(&RdnLen, pbEncoded, cEncoded);
  952. if (index == -1)
  953. {
  954. return(-1);
  955. }
  956. Processed = RdnLen + index;
  957. pbEncoded += index;
  958. if (0 != RdnLen)
  959. for (;;)
  960. {
  961. index = DecodeHeader(&dwLen, pbEncoded, RdnLen);
  962. if (index < 0)
  963. return(-1);
  964. RdnLen -= index;
  965. pbEncoded += index;
  966. index = IisDecodeNameType(&iPrefixType, pbEncoded, RdnLen);
  967. if (index < 0)
  968. {
  969. return(-1);
  970. }
  971. RdnLen -= index;
  972. pbEncoded += index;
  973. switch ( iPrefixType )
  974. {
  975. case 0: // CN
  976. pValue[3] = pBuf;
  977. fTmpWrite = TRUE;
  978. break;
  979. case 1: // C
  980. pValue[2] = pBuf;
  981. fTmpWrite = TRUE;
  982. break;
  983. case 4: // O
  984. pValue[0] = pBuf;
  985. fTmpWrite = TRUE;
  986. break;
  987. case 5: // OU
  988. pValue[1] = pBuf;
  989. fTmpWrite = TRUE;
  990. break;
  991. default:
  992. pName = NULL;
  993. fTmpWrite = FALSE;
  994. }
  995. index = DecodeString((PUCHAR)pBuf, &dwLen, pbEncoded, RdnLen, fTmpWrite);
  996. if (index < 0)
  997. {
  998. return(-1);
  999. }
  1000. pBuf[dwLen] = '\0';
  1001. CompLen += dwLen + 1;
  1002. pBuf += dwLen + 1;
  1003. RdnLen -= index;
  1004. pbEncoded += index;
  1005. if (0 < RdnLen)
  1006. {
  1007. }
  1008. else
  1009. {
  1010. break;
  1011. }
  1012. }
  1013. *pdwComponentLength = CompLen;
  1014. return Processed;
  1015. }
  1016. long
  1017. IisDecodeDN(
  1018. PSTR pValue[],
  1019. PSTR pBuf,
  1020. BYTE * pbEncoded,
  1021. DWORD cEncoded
  1022. )
  1023. {
  1024. long index;
  1025. DWORD dwLen;
  1026. long TotalNameLength;
  1027. DWORD ComponentLength;
  1028. DWORD NameLength;
  1029. long EncodedNameLength;
  1030. index = DecodeHeader(&dwLen, pbEncoded, cEncoded);
  1031. if (index == -1)
  1032. {
  1033. return(-1);
  1034. }
  1035. EncodedNameLength = index + dwLen;
  1036. TotalNameLength = dwLen;
  1037. NameLength = 0;
  1038. while (TotalNameLength > 0)
  1039. {
  1040. pbEncoded += index;
  1041. index = IisDecodeRDN( pValue,
  1042. pBuf + NameLength,
  1043. &ComponentLength,
  1044. pbEncoded,
  1045. cEncoded - index
  1046. );
  1047. if (index == -1)
  1048. return(-1);
  1049. // if (WriteFlag)
  1050. // pName += ComponentLength;
  1051. TotalNameLength -= index;
  1052. NameLength += ComponentLength;
  1053. #if 0
  1054. if ((TotalNameLength > 0) && (0 < ComponentLength))
  1055. {
  1056. if (WriteFlag)
  1057. {
  1058. *pName++ = ',';
  1059. *pName++ = ' ';
  1060. }
  1061. NameLength += 2;
  1062. }
  1063. else if ((TotalNameLength <= 0)
  1064. && (0 == ComponentLength)
  1065. && (0 < NameLength))
  1066. {
  1067. //
  1068. // The last RDN didn't produce any output, so we need to
  1069. // roll back that ", " we put on previously.
  1070. //
  1071. if (WriteFlag)
  1072. pName -= 2;
  1073. NameLength -= 2;
  1074. }
  1075. #endif
  1076. }
  1077. //*pdwLen = NameLength;
  1078. return(EncodedNameLength);
  1079. }
  1080. #if 0
  1081. long
  1082. DecodeSigAlg(
  1083. DWORD * pAlgId,
  1084. PBYTE pbEncoded,
  1085. DWORD cEncoded,
  1086. BOOL WriteFlag)
  1087. {
  1088. long Result;
  1089. DWORD dwLen;
  1090. long index;
  1091. index = DecodeHeader( &dwLen, pbEncoded, cEncoded);
  1092. if (index == -1)
  1093. {
  1094. return(-1);
  1095. }
  1096. Result = DecodeSigAlgid( pAlgId,
  1097. pbEncoded+index,
  1098. cEncoded - index,
  1099. WriteFlag );
  1100. if (Result == -1)
  1101. {
  1102. return(-1);
  1103. }
  1104. index += Result;
  1105. Result = DecodeNull(pbEncoded + index, cEncoded - index);
  1106. if (Result == -1)
  1107. {
  1108. return(-1);
  1109. }
  1110. return(index + Result);
  1111. }
  1112. long
  1113. DecodeCryptAlg(
  1114. DWORD * pAlgId,
  1115. DWORD * pHashid,
  1116. PBYTE pbEncoded,
  1117. DWORD cEncoded,
  1118. BOOL WriteFlag)
  1119. {
  1120. long Result;
  1121. DWORD dwLen;
  1122. long index;
  1123. index = DecodeHeader( &dwLen, pbEncoded, cEncoded);
  1124. if (index == -1)
  1125. {
  1126. return(-1);
  1127. }
  1128. Result = DecodeCryptAlgid(pAlgId, pHashid,
  1129. pbEncoded+index,
  1130. cEncoded - index,
  1131. WriteFlag );
  1132. if (Result == -1)
  1133. {
  1134. return(-1);
  1135. }
  1136. index += Result;
  1137. Result = DecodeNull(pbEncoded + index, cEncoded - index);
  1138. if (Result == -1)
  1139. {
  1140. return(-1);
  1141. }
  1142. return(index + Result);
  1143. }
  1144. long
  1145. DecodeKeyType(
  1146. DWORD * pKeyType,
  1147. PBYTE pbEncoded,
  1148. DWORD cEncoded,
  1149. BOOL WriteFlag)
  1150. {
  1151. long Result;
  1152. DWORD dwLen;
  1153. long index;
  1154. index = DecodeHeader( &dwLen, pbEncoded, cEncoded);
  1155. if (index == -1)
  1156. {
  1157. return(-1);
  1158. }
  1159. Result = DecodeKeyExchAlgid(pKeyType,
  1160. pbEncoded+index,
  1161. cEncoded - index,
  1162. WriteFlag );
  1163. if (Result == -1)
  1164. {
  1165. return(-1);
  1166. }
  1167. index += Result;
  1168. Result = DecodeNull(pbEncoded + index, cEncoded - index);
  1169. if (Result == -1)
  1170. {
  1171. return(-1);
  1172. }
  1173. return(index + Result);
  1174. }
  1175. #endif
  1176. #if 0
  1177. long
  1178. DecryptOctetString(
  1179. DWORD * pdwLen,
  1180. BYTE * pbEncoded,
  1181. DWORD cEncoded,
  1182. BOOL Writeflag,
  1183. PSTR pszPassword)
  1184. {
  1185. long index, Result;
  1186. CipherSpec CryptId;
  1187. HashSpec HashId;
  1188. SPBuffer Input, Output;
  1189. PCryptoSystem pCipher;
  1190. PCheckSumFunction pHash;
  1191. if(cEncoded < 1)
  1192. {
  1193. return(SP_LOG_RESULT(-1));
  1194. }
  1195. /* Figure out what crypto alg and pasword has we are using. */
  1196. index = DecodeCryptAlg( &CryptId, &HashId, pbEncoded, cEncoded, TRUE );
  1197. if (index == -1)
  1198. {
  1199. return(-1);
  1200. }
  1201. pCipher = CipherFromSpec(CryptId);
  1202. if(pCipher == NULL)
  1203. {
  1204. return(SP_LOG_RESULT(-1));
  1205. }
  1206. pHash = HashFromSpec(HashId);
  1207. if(pHash == NULL)
  1208. {
  1209. return(SP_LOG_RESULT(-1));
  1210. }
  1211. if (*(pbEncoded + index) != OCTET_STRING_TAG)
  1212. {
  1213. return ( -1 );
  1214. }
  1215. index++;
  1216. /* determine how long the string is */
  1217. if ((Result = DecodeLength (pdwLen, pbEncoded + index, cEncoded-index)) == -1)
  1218. if (Result == -1)
  1219. {
  1220. return(-1);
  1221. }
  1222. index += Result;
  1223. if(cEncoded < (index + *pdwLen))
  1224. {
  1225. return(SP_LOG_RESULT(-1));
  1226. }
  1227. if (Writeflag)
  1228. {
  1229. HashBuf SumBuff, Buff;
  1230. PStateBuffer pState;
  1231. PCheckSumBuffer Sum = (PCheckSumBuffer)SumBuff;
  1232. pHash->Initialize(Sum,0);
  1233. pHash->Sum(Sum, lstrlen(pszPassword), (PUCHAR)pszPassword);
  1234. pHash->Finalize(Sum, Buff);
  1235. Input.pvBuffer = Output.pvBuffer = pbEncoded+index;
  1236. Input.cbBuffer = Output.cbBuffer = *pdwLen;
  1237. Input.cbData = Output.cbData = *pdwLen;
  1238. pCipher->Initialize(Buff, pHash->cbCheckSum, &pState);
  1239. pCipher->Decrypt(pState, &Input, &Output);
  1240. pCipher->Discard(&pState);
  1241. }
  1242. return (index);
  1243. }
  1244. long
  1245. DecodePrivateKeyFile(
  1246. PctPrivateKey * * ppKey,
  1247. PBYTE pbEncoded,
  1248. DWORD cEncoded,
  1249. PSTR Password )
  1250. {
  1251. DWORD dwLen;
  1252. long Result;
  1253. long index;
  1254. DWORD KeyId;
  1255. DWORD Version;
  1256. KeyExchangeSystem *pSys = NULL;
  1257. index = 0;
  1258. SP_BEGIN("DecodePrivateKeyFile");
  1259. Result = DecodeHeader( &dwLen, pbEncoded , cEncoded);
  1260. if (Result == -1)
  1261. {
  1262. SP_RETURN(-1);
  1263. }
  1264. index += Result;
  1265. Result = DecodeOctetString( NULL, &dwLen, pbEncoded+ index, cEncoded-index, FALSE );
  1266. if (Result == -1)
  1267. {
  1268. SP_RETURN(-1);
  1269. }
  1270. index += Result;
  1271. Result = DecodeHeader( &dwLen, pbEncoded +index, cEncoded-index);
  1272. if (Result == -1)
  1273. {
  1274. SP_RETURN(-1);
  1275. }
  1276. index += Result;
  1277. /* Now, the next item should be an octet string, which is encrypted */
  1278. /* with the password above. So, we need to skip into it, decrypt it, */
  1279. /* then treat it as a constructed type: */
  1280. Result = DecryptOctetString(&dwLen,
  1281. pbEncoded+index,
  1282. cEncoded-index,
  1283. TRUE,
  1284. Password);
  1285. if (Result == -1)
  1286. {
  1287. SP_RETURN(-1);
  1288. }
  1289. index += Result;
  1290. /* The moment of truth */
  1291. Result = DecodeHeader( &dwLen, pbEncoded+index, cEncoded-index );
  1292. if (Result == -1)
  1293. {
  1294. SP_RETURN(-1);
  1295. }
  1296. index += Result;
  1297. Version = 0;
  1298. Result = DecodeInteger( (PUCHAR) &Version, sizeof(Version), &dwLen, pbEncoded+index, cEncoded-index, FALSE );
  1299. if ((Result < 0) || ( dwLen > 4 ) )
  1300. {
  1301. SP_RETURN(SP_LOG_RESULT(-1));
  1302. }
  1303. Result = DecodeInteger( (PUCHAR) &Version, sizeof(Version), &dwLen, pbEncoded+index, cEncoded-index, TRUE );
  1304. if (Result == -1 || Version != 0)
  1305. {
  1306. SP_RETURN(SP_LOG_RESULT(-1));
  1307. }
  1308. index += Result;
  1309. Result = DecodeKeyType( &KeyId, pbEncoded+index, cEncoded-index, TRUE );
  1310. if (Result == -1)
  1311. {
  1312. SP_RETURN(-1);
  1313. }
  1314. index += Result;
  1315. /* This is now the serialized rsa key. */
  1316. if (*(pbEncoded+index) != OCTET_STRING_TAG)
  1317. {
  1318. SP_RETURN(SP_LOG_RESULT(-1));
  1319. }
  1320. index ++;
  1321. Result = DecodeLength( &dwLen, pbEncoded+index, cEncoded-index );
  1322. if (Result == -1)
  1323. {
  1324. SP_RETURN(-1);
  1325. }
  1326. if(index + dwLen > cEncoded)
  1327. {
  1328. SP_RETURN(SP_LOG_RESULT(-1));
  1329. }
  1330. index += Result;
  1331. /* The sequence is the key... */
  1332. pSys = KeyExchangeFromSpec(KeyId);
  1333. if(pSys == NULL)
  1334. {
  1335. SP_RETURN(SP_LOG_RESULT(-1));
  1336. }
  1337. index += pSys->DecodePrivate(pbEncoded+index, cEncoded-index, ppKey);
  1338. SP_RETURN(index);
  1339. }
  1340. #endif