Leaked source code of windows server 2003
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.

911 lines
20 KiB

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include <windows.h>
  5. #include <ntsdexts.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include "ber.h"
  10. #define iso_member 0x2a, // iso(1) memberbody(2)
  11. #define us 0x86, 0x48, // us(840)
  12. #define rsadsi 0x86, 0xf7, 0x0d, // rsadsi(113549)
  13. #define pkcs 0x01, // pkcs(1)
  14. #define rsa_ iso_member us rsadsi
  15. #define rsa_len 6
  16. #define rsa_text "iso(2) member-body(2) us(840) rsadsi(113549) "
  17. #define pkcs_1 iso_member us rsadsi pkcs
  18. #define pkcs_len 7
  19. #define pkcs_text "iso(2) member-body(2) us(840) rsadsi(113549) pkcs(1) "
  20. #define joint_iso_ccitt_ds 0x55,
  21. #define attributetype 0x04,
  22. #define attributeType joint_iso_ccitt_ds attributetype
  23. #define attrtype_len 2
  24. typedef struct _ObjectId {
  25. UCHAR Sequence[16];
  26. DWORD SequenceLen;
  27. PSTR Name;
  28. } ObjectId;
  29. ObjectId KnownObjectIds[] = {
  30. { {pkcs_1 1, 1}, pkcs_len + 2, pkcs_text "RSA"},
  31. { {pkcs_1 1, 2}, pkcs_len + 2, pkcs_text "MD2/RSA"},
  32. { {pkcs_1 1, 4}, pkcs_len + 2, pkcs_text "MD5/RSA"},
  33. { {rsa_ 3, 4}, rsa_len + 2, rsa_text "RC4"},
  34. { {attributeType 3}, attrtype_len + 1, "CN="},
  35. { {attributeType 6}, attrtype_len + 1, "C="},
  36. { {attributeType 7}, attrtype_len + 1, "L="},
  37. { {attributeType 8}, attrtype_len + 1, "S="},
  38. { {attributeType 10}, attrtype_len + 1, "O="},
  39. { {attributeType 11}, attrtype_len + 1, "OU="},
  40. };
  41. ObjectId KnownPrefixes[] = {
  42. { {pkcs_1}, pkcs_len, pkcs_text},
  43. { {iso_member us rsadsi}, pkcs_len - 1, "iso(2) member-body(2) us(840) rsadsi(113549) "},
  44. { {iso_member us}, pkcs_len - 4, "iso(2) member-body(2) us(840) "},
  45. { {iso_member}, pkcs_len - 6, "iso(2) member-body(2) " }
  46. };
  47. typedef struct _NameTypes {
  48. PSTR Prefix;
  49. UCHAR Sequence[8];
  50. DWORD SequenceLen;
  51. } NameTypes;
  52. NameTypes KnownNameTypes[] = { {"CN=", {attributeType 3}, attrtype_len + 1},
  53. {"C=", {attributeType 6}, attrtype_len + 1},
  54. {"L=", {attributeType 7}, attrtype_len + 1},
  55. {"S=", {attributeType 8}, attrtype_len + 1},
  56. {"O=", {attributeType 10}, attrtype_len + 1},
  57. {"OU=", {attributeType 11}, attrtype_len + 1}
  58. };
  59. BYTE Buffer[1024];
  60. BOOL BerVerbose = FALSE ;
  61. char maparray[] = "0123456789abcdef";
  62. #define MAX_OID_VALS 32
  63. typedef struct _OID {
  64. unsigned cVal;
  65. unsigned Val[MAX_OID_VALS];
  66. } OID;
  67. typedef enum _OidResult {
  68. OidExact,
  69. OidPartial,
  70. OidMiss,
  71. OidError
  72. } OidResult;
  73. extern PNTSD_EXTENSION_APIS pExtApis;
  74. extern HANDLE hDbgThread;
  75. extern HANDLE hDbgProcess;
  76. #define DebuggerOut (pExtApis->lpOutputRoutine)
  77. #define GetSymbol (pExtApis->lpGetSymbolRoutine)
  78. #define GetExpr (PVOID) (pExtApis->lpGetExpressionRoutine)
  79. #define InitDebugHelp(hProc,hThd,pApis) {hDbgProcess = hProc; hDbgThread = hThd; pExtApis = pApis;}
  80. #define ExitIfCtrlC() if (pExtApis->lpCheckControlCRoutine()) return;
  81. #define BreakIfCtrlC() if (pExtApis->lpCheckControlCRoutine()) break;
  82. #define LINE_SIZE 192
  83. #define INDENT_SIZE 4
  84. #define OID_VERBOSE 0x0002
  85. #define OID_PARTIAL 0x0001
  86. char * DefaultTree =
  87. "1 iso\n"
  88. " 2 memberbody\n"
  89. " 840 us\n"
  90. " 113549 rsadsi\n"
  91. " 1 pkcs\n"
  92. " 1 RSA\n"
  93. " 3 pkcs-3\n"
  94. " 1 dhKeyAgreement\n"
  95. " 2 digestAlgorithm\n"
  96. " 2 MD2\n"
  97. " 4 MD4\n"
  98. " 5 MD5\n"
  99. " 113554 mit\n"
  100. " 1 infosys\n"
  101. " 2 gssapi\n"
  102. " 1 generic\n"
  103. " 1 user_name\n"
  104. " 2 machine_uid_name\n"
  105. " 3 string_uid_name\n"
  106. " 113556 microsoft\n"
  107. " 1 ds\n"
  108. " 3 org\n"
  109. " 6 dod\n"
  110. " 1 internet\n"
  111. " 4 private\n"
  112. " 1 enterprise\n"
  113. " 311 microsoft\n"
  114. " 1 software\n"
  115. " 1 systems\n"
  116. " 2 wins\n"
  117. " 3 dhcp\n"
  118. " 4 apps\n"
  119. " 5 mos\n"
  120. " 7 InternetServer\n"
  121. " 8 ipx\n"
  122. " 9 ripsap\n"
  123. " 2 security\n"
  124. " 1 certificates\n"
  125. " 2 mechanisms\n"
  126. " 9 Negotiator\n"
  127. " 10 NTLM\n"
  128. " 12 SSL\n"
  129. " 5 security\n"
  130. " 3 integrity\n"
  131. " 1 md5-DES-CBC\n"
  132. " 2 sum64-DES-CBC\n"
  133. " 5 mechanisms\n"
  134. " 1 spkm\n"
  135. " 1 spkm-1\n"
  136. " 2 spkm-2\n"
  137. " 10 spkmGssTokens\n"
  138. " 6 nametypes\n"
  139. " 2 gss-host-based-services\n"
  140. " 3 gss-anonymous-name\n"
  141. " 4 gss-api-exported-name\n"
  142. " 14 oiw\n"
  143. " 3 secsig\n"
  144. " 2 algorithm\n"
  145. " 7 DES-CBC\n"
  146. " 10 DES-MAC\n"
  147. " 18 SHA\n"
  148. " 22 id-rsa-key-transport\n"
  149. "2 joint-iso-ccitt\n"
  150. " 5 ds\n"
  151. " 4 attribute-type\n"
  152. " 3 CommonName\n"
  153. " 6 Country/region\n"
  154. " 7 Locality\n"
  155. " 8 State\n"
  156. " 10 Organization\n"
  157. " 11 OrgUnit\n"
  158. ;
  159. typedef struct _TreeFile {
  160. CHAR * Buffer;
  161. CHAR * Line;
  162. CHAR * CurNul;
  163. } TreeFile, * PTreeFile ;
  164. BOOL
  165. TreeFileInit(
  166. PTreeFile pFile,
  167. PSTR pStr)
  168. {
  169. int l;
  170. l = strlen( pStr );
  171. if ( (pStr[l - 1] != '\r') &&
  172. (pStr[l - 1] != '\n') )
  173. {
  174. l++;
  175. }
  176. pFile->Buffer = LocalAlloc( LMEM_FIXED, l );
  177. if ( pFile->Buffer )
  178. {
  179. strcpy( pFile->Buffer, pStr );
  180. pFile->Line = pFile->Buffer ;
  181. pFile->CurNul = NULL ;
  182. }
  183. return (pFile->Buffer != NULL);
  184. }
  185. VOID
  186. TreeFileDelete(
  187. PTreeFile pFile
  188. )
  189. {
  190. LocalFree( pFile->Buffer );
  191. }
  192. PSTR
  193. TreeFileGetLine(
  194. PTreeFile pFile )
  195. {
  196. PSTR Scan;
  197. PSTR Line;
  198. if ( !pFile->Line )
  199. {
  200. return( NULL );
  201. }
  202. if ( pFile->CurNul )
  203. {
  204. *pFile->CurNul = '\n';
  205. }
  206. pFile->CurNul = NULL ;
  207. Scan = pFile->Line ;
  208. while ( *Scan && (*Scan != '\n') && (*Scan != '\r'))
  209. {
  210. Scan++;
  211. }
  212. //
  213. // Okay, get the line to return
  214. //
  215. Line = pFile->Line;
  216. //
  217. // If this is not the end, touch up the pointers:
  218. //
  219. if ( *Scan )
  220. {
  221. *Scan = '\0';
  222. pFile->CurNul = Scan;
  223. Scan += 1;
  224. while ( *Scan && ( (*Scan == '\r' ) || ( *Scan == '\n') ))
  225. {
  226. Scan++ ;
  227. }
  228. //
  229. // If this is the end, reset line
  230. //
  231. if ( *Scan == '\0' )
  232. {
  233. pFile->Line = NULL ;
  234. }
  235. else
  236. {
  237. pFile->Line = Scan;
  238. }
  239. }
  240. else
  241. {
  242. pFile->Line = NULL ;
  243. }
  244. return( Line );
  245. }
  246. VOID
  247. TreeFileRewind(
  248. PTreeFile pFile )
  249. {
  250. if ( pFile->CurNul )
  251. {
  252. *pFile->CurNul = '\n';
  253. }
  254. pFile->CurNul = NULL ;
  255. pFile->Line = pFile->Buffer ;
  256. }
  257. int
  258. tohex(
  259. BYTE b,
  260. PSTR psz)
  261. {
  262. BYTE b1, b2;
  263. b1 = b >> 4;
  264. b2 = b & 0xF;
  265. *psz++ = maparray[b1];
  266. *psz = maparray[b2];
  267. return(3);
  268. }
  269. //+---------------------------------------------------------------------------
  270. //
  271. // Function: DecodeOID
  272. //
  273. // Synopsis: Decodes an OID into a simple structure
  274. //
  275. // Arguments: [pEncoded] --
  276. // [len] --
  277. // [pOID] --
  278. //
  279. // History: 8-07-96 RichardW Stolen directly from DonH
  280. //
  281. // Notes:
  282. //
  283. //----------------------------------------------------------------------------
  284. BOOL
  285. DecodeOID(unsigned char *pEncoded, int len, OID *pOID)
  286. {
  287. unsigned cval;
  288. unsigned val;
  289. int i, j;
  290. if (len <=2) {
  291. return FALSE;
  292. }
  293. // The first two values are encoded in the first octet.
  294. pOID->Val[0] = pEncoded[0] / 40;
  295. pOID->Val[1] = pEncoded[0] % 40;
  296. //DebuggerOut("Encoded value %02x turned into %d and %d\n", pEncoded[0],
  297. // pOID->Val[0], pOID->Val[1] );
  298. cval = 2;
  299. i = 1;
  300. while (i < len) {
  301. j = 0;
  302. val = pEncoded[i] & 0x7f;
  303. while (pEncoded[i] & 0x80) {
  304. val <<= 7;
  305. ++i;
  306. if (++j > 4 || i >= len) {
  307. // Either this value is bigger than we can handle (we
  308. // don't handle values that span more than four octets)
  309. // -or- the last octet in the encoded string has its
  310. // high bit set, indicating that it's not supposed to
  311. // be the last octet. In either case, we're sunk.
  312. return FALSE;
  313. }
  314. val |= pEncoded[i] & 0x7f;
  315. }
  316. //ASSERT(i < len);
  317. pOID->Val[cval] = val;
  318. ++cval;
  319. ++i;
  320. }
  321. pOID->cVal = cval;
  322. return TRUE;
  323. }
  324. PSTR
  325. GetLineWithIndent(
  326. PTreeFile ptf,
  327. DWORD i)
  328. {
  329. PSTR Scan;
  330. DWORD test;
  331. do
  332. {
  333. Scan = TreeFileGetLine( ptf );
  334. if ( Scan && i )
  335. {
  336. if ( i < INDENT_SIZE )
  337. {
  338. test = 0;
  339. }
  340. else
  341. {
  342. test = i - INDENT_SIZE ;
  343. }
  344. if ( Scan[ test ] != ' ' )
  345. {
  346. {
  347. Scan = NULL ;
  348. break;
  349. }
  350. }
  351. }
  352. else
  353. test = 0;
  354. } while ( Scan && (Scan[i] == ' ') );
  355. return( Scan );
  356. }
  357. OidResult
  358. scan_oid_table(
  359. char * Table,
  360. DWORD Flags,
  361. PUCHAR ObjectId,
  362. DWORD Len,
  363. PSTR pszRep,
  364. DWORD MaxRep)
  365. {
  366. CHAR OidPath[ MAX_PATH ];
  367. OID Oid;
  368. DWORD i;
  369. DWORD Indent;
  370. TreeFile tf;
  371. PSTR Scan;
  372. PSTR Tag;
  373. PSTR SubScan;
  374. DWORD Index;
  375. DWORD size;
  376. DWORD TagSize;
  377. if (!DecodeOID( ObjectId, Len, &Oid ))
  378. {
  379. return( OidError );
  380. }
  381. i = 0;
  382. Indent = 0;
  383. if ( !TreeFileInit( &tf, Table ) )
  384. {
  385. DebuggerOut("Unable to load prefix table\n");
  386. return OidError ;
  387. }
  388. Tag = OidPath;
  389. size = 0;
  390. TagSize = 0;
  391. if ( (Flags & OID_VERBOSE) == 0 )
  392. {
  393. while ( i < Oid.cVal )
  394. {
  395. TagSize = _snprintf( Tag, MAX_PATH - size, "%d.",
  396. Oid.Val[i] );
  397. size += TagSize;
  398. Tag += TagSize;
  399. i++;
  400. }
  401. strncpy( pszRep, OidPath, MaxRep );
  402. TreeFileDelete( &tf );
  403. return( OidExact );
  404. }
  405. while ( i < Oid.cVal )
  406. {
  407. do
  408. {
  409. Scan = GetLineWithIndent( &tf, Indent );
  410. if ( Scan )
  411. {
  412. Index = atoi(Scan);
  413. }
  414. else
  415. {
  416. Index = (DWORD) -1;
  417. }
  418. if ( Index == Oid.Val[i] )
  419. {
  420. break;
  421. }
  422. } while ( Scan );
  423. //
  424. // If Scan is NULL, we didn't get a match
  425. //
  426. if ( !Scan )
  427. {
  428. if ( i > 0 )
  429. {
  430. if ( Flags & OID_PARTIAL )
  431. {
  432. while ( i < Oid.cVal )
  433. {
  434. TagSize = _snprintf( Tag, MAX_PATH - size, "%d ",
  435. Oid.Val[i] );
  436. size += TagSize;
  437. Tag += TagSize;
  438. i++;
  439. }
  440. strncpy( pszRep, OidPath, MaxRep );
  441. }
  442. TreeFileDelete( &tf );
  443. return( OidPartial );
  444. }
  445. TreeFileDelete( &tf );
  446. return( OidMiss );
  447. }
  448. //
  449. // Got a hit:
  450. //
  451. SubScan = &Scan[Indent];
  452. while (*SubScan != ' ')
  453. {
  454. SubScan++;
  455. }
  456. SubScan++;
  457. TagSize = _snprintf( Tag, MAX_PATH - size, "%s(%d) ", SubScan, Index );
  458. size += TagSize;
  459. Tag += TagSize ;
  460. Indent += INDENT_SIZE ;
  461. i ++;
  462. }
  463. strncpy( pszRep, OidPath, MaxRep );
  464. TreeFileDelete( &tf );
  465. return( OidExact );
  466. }
  467. decode_to_string(
  468. LPBYTE pBuffer,
  469. DWORD Flags,
  470. DWORD Type,
  471. DWORD Len,
  472. PSTR pszRep,
  473. DWORD RepLen)
  474. {
  475. PSTR pstr;
  476. PSTR lineptr;
  477. DWORD i;
  478. switch (Type)
  479. {
  480. case BER_NULL:
  481. strcpy(pszRep, "<empty>");
  482. break;
  483. case BER_OBJECT_ID:
  484. scan_oid_table( DefaultTree,
  485. OID_PARTIAL | (Flags & DECODE_VERBOSE_OIDS ? OID_VERBOSE : 0 ),
  486. pBuffer, Len, pszRep, RepLen );
  487. break;
  488. case BER_PRINTABLE_STRING:
  489. case BER_TELETEX_STRING:
  490. case BER_GRAPHIC_STRING:
  491. case BER_VISIBLE_STRING:
  492. case BER_GENERAL_STRING:
  493. CopyMemory(pszRep, pBuffer, min(Len, RepLen - 1) );
  494. pszRep[min(Len, RepLen - 1)] = '\0';
  495. break;
  496. default:
  497. pstr = &pszRep[30];
  498. lineptr = pszRep;
  499. for (i = 0; i < min(Len, 8) ; i++ )
  500. {
  501. lineptr += tohex(*pBuffer, lineptr);
  502. if ((*pBuffer >= ' ') && (*pBuffer <= '|'))
  503. {
  504. *pstr++ = *pBuffer;
  505. }
  506. else
  507. {
  508. *pstr++ = '.';
  509. }
  510. pBuffer++;
  511. }
  512. *pstr++ = '\0';
  513. }
  514. return(0);
  515. }
  516. int
  517. ber_decode(
  518. OutputFn Out,
  519. StopFn Stop,
  520. LPBYTE pBuffer,
  521. DWORD Flags,
  522. int Indent,
  523. int Offset,
  524. int TotalLength,
  525. int BarDepth)
  526. {
  527. char * TypeName = NULL;
  528. char msg[32];
  529. char * pstr;
  530. int i;
  531. int Len;
  532. int ByteCount;
  533. int Accumulated;
  534. DWORD Type;
  535. int subsize;
  536. char line[ LINE_SIZE ];
  537. BOOL Nested;
  538. BOOL Leaf;
  539. int NewBarDepth;
  540. char nonuniversal[ LINE_SIZE ];
  541. if ((Stop)())
  542. {
  543. return(0);
  544. }
  545. Type = *pBuffer;
  546. if ( (Type & 0xC0) == 0 )
  547. {
  548. switch ( Type & 0x1F )
  549. {
  550. case BER_BOOL:
  551. TypeName = "Bool";
  552. break;
  553. case BER_INTEGER:
  554. TypeName = "Integer";
  555. break;
  556. case BER_BIT_STRING:
  557. TypeName = "Bit String";
  558. break;
  559. case BER_OCTET_STRING:
  560. TypeName = "Octet String";
  561. if ( Flags & DECODE_NEST_OCTET_STRINGS )
  562. {
  563. TypeName = "Octet String (Expanding)";
  564. Type |= BER_CONSTRUCTED ;
  565. Flags &= ~( DECODE_NEST_OCTET_STRINGS );
  566. }
  567. break;
  568. case BER_NULL:
  569. TypeName = "Null";
  570. break;
  571. case BER_OBJECT_ID:
  572. TypeName = "Object ID";
  573. break;
  574. case BER_OBJECT_DESC:
  575. TypeName = "Object Descriptor";
  576. break;
  577. case BER_SEQUENCE:
  578. TypeName = "Sequence";
  579. break;
  580. case BER_SET:
  581. TypeName = "Set";
  582. break;
  583. case BER_NUMERIC_STRING:
  584. TypeName = "Numeric String";
  585. break;
  586. case BER_PRINTABLE_STRING:
  587. TypeName = "Printable String";
  588. break;
  589. case BER_TELETEX_STRING:
  590. TypeName = "TeleTex String";
  591. break;
  592. case BER_VIDEOTEX_STRING:
  593. TypeName = "VideoTex String";
  594. break;
  595. case BER_VISIBLE_STRING:
  596. TypeName = "Visible String";
  597. break;
  598. case BER_GENERAL_STRING:
  599. TypeName = "General String";
  600. break;
  601. case BER_GRAPHIC_STRING:
  602. TypeName = "Graphic String";
  603. break;
  604. case BER_UTC_TIME:
  605. TypeName = "UTC Time";
  606. break;
  607. default:
  608. TypeName = "Unknown";
  609. break;
  610. }
  611. }
  612. else
  613. {
  614. //
  615. // Not universal
  616. //
  617. switch ( Type & 0xC0 )
  618. {
  619. case BER_UNIVERSAL:
  620. TypeName = "Internal Error!";
  621. break;
  622. case BER_APPLICATION:
  623. sprintf( nonuniversal, "[Application %d]", Type & 0x1F);
  624. TypeName = nonuniversal;
  625. break;
  626. case BER_CONTEXT_SPECIFIC:
  627. sprintf( nonuniversal, "[Context Specific %d]", Type & 0x1F);
  628. TypeName = nonuniversal;
  629. break;
  630. case BER_PRIVATE:
  631. sprintf( nonuniversal, "[Private %d]", Type & 0x1F);
  632. TypeName = nonuniversal ;
  633. break;
  634. }
  635. }
  636. pstr = msg;
  637. for (i = 0; i < Indent ; i++ )
  638. {
  639. if (i < BarDepth)
  640. {
  641. *pstr++ = '\263';
  642. }
  643. else
  644. {
  645. *pstr++ = ' ';
  646. }
  647. *pstr++ = ' ';
  648. }
  649. *pstr++ = '\0';
  650. pBuffer ++;
  651. Len = 0;
  652. if (*pBuffer & 0x80)
  653. {
  654. ByteCount = *pBuffer++ & 0x7f;
  655. for (i = 0; i < ByteCount ; i++ )
  656. {
  657. Len <<= 8;
  658. Len += *pBuffer++;
  659. }
  660. }
  661. else
  662. {
  663. ByteCount = 0;
  664. Len = *pBuffer++;
  665. }
  666. if (Offset + Len + 2 + ByteCount == TotalLength)
  667. {
  668. Leaf = TRUE;
  669. }
  670. else
  671. {
  672. Leaf = FALSE;
  673. }
  674. if (Type & BER_CONSTRUCTED)
  675. {
  676. Nested = TRUE;
  677. }
  678. else
  679. {
  680. Nested = FALSE;
  681. }
  682. (Out)("%s%c\304%c[%x] %s(%d) ", msg,
  683. Leaf ? 192 : 195,
  684. Nested ? 194 : 196,
  685. Type, TypeName, Len);
  686. if ( Type & BER_CONSTRUCTED )
  687. {
  688. (Out)("\n");
  689. Accumulated = 0;
  690. while (Accumulated < Len)
  691. {
  692. if (BarDepth < Indent)
  693. {
  694. NewBarDepth = BarDepth;
  695. }
  696. else
  697. {
  698. NewBarDepth = (Nested && Leaf) ? BarDepth : Indent + 1;
  699. }
  700. subsize = ber_decode(Out, Stop, pBuffer, Flags, Indent + 1,
  701. Accumulated, Len, NewBarDepth);
  702. Accumulated += subsize;
  703. pBuffer += subsize;
  704. }
  705. (Out)("%s%c\n", msg, ((Indent <= BarDepth) && !Leaf) ? 179 : 32);
  706. }
  707. else
  708. {
  709. memset(line, ' ', LINE_SIZE - 1);
  710. line[ LINE_SIZE - 1 ] = '\0';
  711. decode_to_string(pBuffer, Flags, Type, Len, line, LINE_SIZE);
  712. (Out)("%s\n", line);
  713. }
  714. return(Len + 2 + ByteCount);
  715. }
  716. BOOL
  717. NeverStop(void)
  718. {
  719. return(FALSE);
  720. }