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.

1975 lines
58 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1999 - 1999
  3. Module Name:
  4. ISO7816
  5. Abstract:
  6. The ISCardISO7816 interface provides methods for implementing ISO 7816-4
  7. functionality. With the exception of ISCardISO7816::SetDefaultClassId,
  8. these methods create an APDU command that is encapsulated in a ISCardCmd
  9. object.
  10. The ISO 7816-4 specification defines standard commands available on smart
  11. cards. The specification also defines how a smart card Application
  12. Protocol Data Unit (APDU) command should be constructed and sent to the
  13. smart card for execution. This interface automates the building process.
  14. The following example shows a typical use of the ISCardISO7816 interface.
  15. In this case, the ISCardISO7816 interface is used to build an APDU command.
  16. To submit a transaction to a specific card
  17. 1) Create an ISCardISO7816 and ISCardCmd interface. The ISCardCmd
  18. interface is used to encapsulate the APDU.
  19. 2) Call the appropriate method of the ISCardISO7816 interface, passing the
  20. required parameters and the ISCardCmd interface pointer.
  21. 3) The ISO 7816-4 APDU command will be built and encapsulated in the
  22. ISCardCmd interface.
  23. 4) Release the ISCardISO7816 and ISCardCmd interfaces.
  24. Note
  25. In the method reference pages, if a bit sequence in a table is not defined,
  26. assume that bit sequence is reserved for future use or proprietary to a
  27. specific vendor).
  28. Author:
  29. Doug Barlow (dbarlow) 6/24/1999
  30. Notes:
  31. ?Notes?
  32. --*/
  33. #ifndef WIN32_LEAN_AND_MEAN
  34. #define WIN32_LEAN_AND_MEAN
  35. #endif
  36. #include "stdafx.h"
  37. #include "ISO7816.h"
  38. /////////////////////////////////////////////////////////////////////////////
  39. // CSCardISO7816
  40. /*++
  41. CSCardISO7816::AppendRecord:
  42. The AppendRecord method constructs an APDU command that either appends a
  43. record to the end of a linear-structured elementary file (EF) or writes
  44. record number 1 in an cyclic-structured elementary file.
  45. Arguments:
  46. byRefCtrl [in, defaultvalue(NULL_BYTE)] Identifies the elementary file to
  47. be appended:
  48. Meaning 8 7 6 5 4 3 2 1
  49. Current EF 0 0 0 0 0 0 0 0
  50. Short EF ID x x x x x 0 0 0
  51. Reserved x x x x x x x x
  52. pData [in] Pointer to the data to be appended to the file:
  53. Tn (1 byte)
  54. Ln (1 or 3 bytes)
  55. data (Ln bytes)
  56. ppCmd [in, out] On input, a pointer to an ISCardCmd interface object or
  57. NULL. On return, it is filled with the APDU command constructed by
  58. this operation. If ppCmd was set to NULL, a smart card ISCardCmd
  59. object is internally created and returned via the ppCmd pointer.
  60. Return Value:
  61. The return value is an HRESULT. A value of S_OK indicates the call was
  62. successful.
  63. Remarks:
  64. The encapsulated command can only be performed if the security status of
  65. the smart card satisfies the security attributes of the elementary file
  66. read.
  67. If another elementary file is selected at the time of issuing this command,
  68. it may be processed without identification of the currently selected file.
  69. Elementary files without a record structure cannot be read. The
  70. encapsulated command aborts if applied to an elementary file without a
  71. record structure.
  72. Author:
  73. Doug Barlow (dbarlow) 6/24/1999
  74. --*/
  75. #undef __SUBROUTINE__
  76. #define __SUBROUTINE__ TEXT("CSCardISO7816::AppendRecord")
  77. STDMETHODIMP
  78. CSCardISO7816::AppendRecord(
  79. /* [in] */ BYTE byRefCtrl,
  80. /* [in] */ LPBYTEBUFFER pData,
  81. /* [out][in] */ LPSCARDCMD __RPC_FAR *ppCmd)
  82. {
  83. HRESULT hReturn;
  84. try
  85. {
  86. HRESULT hr;
  87. if (NULL == *ppCmd)
  88. {
  89. *ppCmd = NewSCardCmd();
  90. if (NULL == *ppCmd)
  91. throw (HRESULT)E_OUTOFMEMORY;
  92. }
  93. hr = (*ppCmd)->BuildCmd(
  94. m_bCla, // CLA
  95. 0xe2, // INS
  96. 0, // P1
  97. byRefCtrl, // P2
  98. pData,
  99. NULL);
  100. hReturn = hr;
  101. }
  102. catch (HRESULT hError)
  103. {
  104. hReturn = hError;
  105. }
  106. catch (...)
  107. {
  108. hReturn = E_INVALIDARG;
  109. }
  110. return hReturn;
  111. }
  112. /*++
  113. CSCardISO7816::EraseBinary:
  114. The EraseBinary method constructs an APDU command that sequentially sets
  115. part of the content of an elementary file to its logical erased state,
  116. starting from a given offset.
  117. Arguments:
  118. byP1, byP2 [in] RFU position.
  119. If Then
  120. b8=1 in P1 b7 and b6 of P1 are set to 0 (RFU bits), b5 to b1 of P1 are
  121. a short EF identifier and P2 is the offset of the first
  122. byte to be erased (in data units) from the beginning of the
  123. file.
  124. b8=0 in P1 then P1 || P2 is the offset of the first byte to be erased
  125. (in data units) from the beginning of the file.
  126. If the data field is present, it codes the offset of the first data
  127. unit not to be erased. This offset shall be higher than the one coded
  128. in P1-P2. When the data field is empty, the command erases up to the
  129. end of the file.
  130. pData [in, defaultvalue(NULL)] Pointer to the data that specifies the erase
  131. range; may be NULL.
  132. ppCmd [in, out] On input, a pointer to an ISCardCmd interface object or
  133. NULL. On return, it is filled with the APDU command constructed by
  134. this operation. If ppCmd was set to NULL, a smart card ISCardCmd
  135. object is internally created and returned via the ppCmd pointer.
  136. Return Value:
  137. The return value is an HRESULT. A value of S_OK indicates the call was
  138. successful.
  139. Remarks:
  140. The encapsulated command can only be performed if the security status of
  141. the smart card satisfies the security attributes of the elementary file
  142. being processed.
  143. When the command contains a valid short elementary identifier, it sets the
  144. file as current elementary file.
  145. Elementary files without a transparent structure cannot be erased. The
  146. encapsulated command aborts if applied to an elementary file without a
  147. transparent structure.
  148. Author:
  149. Doug Barlow (dbarlow) 6/24/1999
  150. --*/
  151. #undef __SUBROUTINE__
  152. #define __SUBROUTINE__ TEXT("CSCardISO7816::EraseBinary")
  153. STDMETHODIMP
  154. CSCardISO7816::EraseBinary(
  155. /* [in] */ BYTE byP1,
  156. /* [in] */ BYTE byP2,
  157. /* [in] */ LPBYTEBUFFER pData,
  158. /* [out][in] */ LPSCARDCMD __RPC_FAR *ppCmd)
  159. {
  160. HRESULT hReturn;
  161. try
  162. {
  163. HRESULT hr;
  164. if (NULL == *ppCmd)
  165. {
  166. *ppCmd = NewSCardCmd();
  167. if (NULL == *ppCmd)
  168. throw (HRESULT)E_OUTOFMEMORY;
  169. }
  170. hr = (*ppCmd)->BuildCmd(
  171. m_bCla, // CLA
  172. 0x0e, // INS
  173. byP1, // P1
  174. byP2, // P2
  175. pData,
  176. NULL);
  177. hReturn = hr;
  178. }
  179. catch (HRESULT hError)
  180. {
  181. hReturn = hError;
  182. }
  183. catch (...)
  184. {
  185. hReturn = E_INVALIDARG;
  186. }
  187. return hReturn;
  188. }
  189. /*++
  190. CSCardISO7816::ExternalAuthenticate:
  191. The ExternalAuthenticate method constructs an APDU command that
  192. conditionally updates security status, verifying the identity of the
  193. computer when the smart card does not trust it.
  194. The command uses the result (yes or no) of the computation by the card
  195. (based on a challenge previously issued by the card for example, by the
  196. INS_GET_CHALLENGE command), a key (possibly secret) stored in the card, and
  197. authentication data transmitted by the interface device.
  198. Arguments:
  199. byAlgorithmRef [in, defaultvalue(NULL_BYTE)] Reference of the algorithm in
  200. the card. If this value is zero, this indicates that no information is
  201. given. The reference of the algorithm is known either before issuing
  202. the command or is provided in the data field.
  203. bySecretRef [in, defaultvalue(NULL_BYTE)] Reference of the secret:
  204. Meaning 8 7 6 5 4 3 2 1
  205. No Info 0 0 0 0 0 0 0 0
  206. Global ref 0 - - - - - - -
  207. Specific ref 1 - - - - - - -
  208. RFU - x x - - - - -
  209. Secret - - - x x x x x
  210. No Info = No information is given. The reference of the secret is known
  211. either before issuing the command or is provided in the data field.
  212. Global ref = Global reference data (an MF specific key).
  213. Specific ref = Specific reference data (a DF specific key).
  214. RFU = 00 (other values are RFU).
  215. Secret = Number of the secret.
  216. pChallenge [in, defaultvalue(NULL)] Pointer to the authentication-related
  217. data; may be NULL.
  218. ppCmd [in, out] On input, a pointer to an ISCardCmd interface object or
  219. NULL. On return, it is filled with the APDU command constructed by
  220. this operation. If ppCmd was set to NULL, a smart card ISCardCmd
  221. object is internally created and returned via the ppCmd pointer.
  222. Return Value:
  223. The return value is an HRESULT. A value of S_OK indicates the call was
  224. successful.
  225. Remarks:
  226. For the encapsulated command to be successful, the last challenge obtained
  227. from the card must be valid.
  228. Unsuccessful comparisons may be recorded in the card (for example, to limit
  229. the number of further attempts of the use of the reference data).
  230. Author:
  231. Doug Barlow (dbarlow) 6/24/1999
  232. --*/
  233. #undef __SUBROUTINE__
  234. #define __SUBROUTINE__ TEXT("CSCardISO7816::ExternalAuthenticate")
  235. STDMETHODIMP
  236. CSCardISO7816::ExternalAuthenticate(
  237. /* [in] */ BYTE byAlgorithmRef,
  238. /* [in] */ BYTE bySecretRef,
  239. /* [in] */ LPBYTEBUFFER pChallenge,
  240. /* [out][in] */ LPSCARDCMD __RPC_FAR *ppCmd)
  241. {
  242. HRESULT hReturn;
  243. try
  244. {
  245. HRESULT hr;
  246. if (NULL == *ppCmd)
  247. {
  248. *ppCmd = NewSCardCmd();
  249. if (NULL == *ppCmd)
  250. throw (HRESULT)E_OUTOFMEMORY;
  251. }
  252. hr = (*ppCmd)->BuildCmd(
  253. m_bCla, // CLA
  254. 0x82, // INS
  255. byAlgorithmRef, // P1
  256. bySecretRef, // P2
  257. pChallenge, // data
  258. NULL);
  259. hReturn = hr;
  260. }
  261. catch (HRESULT hError)
  262. {
  263. hReturn = hError;
  264. }
  265. catch (...)
  266. {
  267. hReturn = E_INVALIDARG;
  268. }
  269. return hReturn;
  270. }
  271. /*++
  272. CSCardISO7816::GetChallenge:
  273. The GetChallenge method constructs an APDU command that issue a challenge
  274. (for example, a random number) for use in a security-related procedure.
  275. Arguments:
  276. lBytesExpected [in, defaultvalue(0)] Maximum length of the expected response.
  277. ppCmd [in, out] On input, a pointer to an ISCardCmd interface object or
  278. NULL. On return, it is filled with the APDU command constructed by
  279. this operation. If ppCmd was set to NULL, a smart card ISCardCmd object
  280. is internally created and returned via the ppCmd pointer.
  281. Return Value:
  282. The return value is an HRESULT. A value of S_OK indicates the call was
  283. successful.
  284. Remarks:
  285. The challenge is valid at least for the next command.
  286. Author:
  287. Doug Barlow (dbarlow) 6/24/1999
  288. --*/
  289. #undef __SUBROUTINE__
  290. #define __SUBROUTINE__ TEXT("CSCardISO7816::GetChallenge")
  291. STDMETHODIMP
  292. CSCardISO7816::GetChallenge(
  293. /* [in] */ LONG lBytesExpected,
  294. /* [out][in] */ LPSCARDCMD __RPC_FAR *ppCmd)
  295. {
  296. HRESULT hReturn;
  297. try
  298. {
  299. HRESULT hr;
  300. if (NULL == *ppCmd)
  301. {
  302. *ppCmd = NewSCardCmd();
  303. if (NULL == *ppCmd)
  304. throw (HRESULT)E_OUTOFMEMORY;
  305. }
  306. hr = (*ppCmd)->BuildCmd(
  307. m_bCla, // CLA
  308. 0x84, // INS
  309. 0x00, // P1
  310. 0x00, // P2
  311. NULL,
  312. &lBytesExpected);
  313. hReturn = hr;
  314. }
  315. catch (HRESULT hError)
  316. {
  317. hReturn = hError;
  318. }
  319. catch (...)
  320. {
  321. hReturn = E_INVALIDARG;
  322. }
  323. return hReturn;
  324. }
  325. /*++
  326. CSCardISO7816::GetData:
  327. The GetData method constructs an APDU command that retrieves either a
  328. single primitive data object or a set of data objects (contained in a
  329. constructed data object), depending on the type of file selected.
  330. Arguments:
  331. byP1, byP2 [in] Parameters:
  332. Value Meaning
  333. 0000 - 003F RFU
  334. 0040 - 00FF BER-TLV tag (1 byte) in P2
  335. 0100 - 01FF Application data (proprietary coding)
  336. 0200 - 02FF SIMPLE-TLV tag in P2
  337. 0300 - 03FF RFU
  338. 0400 - 04FF BER-TLV tag (2 bytes) in P1-P2
  339. lBytesToGet [in, defaultvalue(0)] Number of bytes expected in the response.
  340. ppCmd [in, out] On input, a pointer to an ISCardCmd interface object or
  341. NULL. On return, it is filled with the APDU command constructed by
  342. this operation. If ppCmd was set to NULL, a smart card ISCardCmd
  343. object is internally created and returned via the ppCmd pointer.
  344. Return Value:
  345. The return value is an HRESULT. A value of S_OK indicates the call was
  346. successful.
  347. Remarks:
  348. The encapsulated command can only be performed if the security status of
  349. the smart card satisfies the security attributes of the elementary file
  350. being read. Security conditions are dependent on the policy of the card,
  351. and may be manipulated through ExternalAuthenticate, InternalAuthenticate,
  352. ISCardAuth, etc.
  353. To select a file, call SelectFile.
  354. Author:
  355. Doug Barlow (dbarlow) 6/24/1999
  356. --*/
  357. #undef __SUBROUTINE__
  358. #define __SUBROUTINE__ TEXT("CSCardISO7816::GetData")
  359. STDMETHODIMP
  360. CSCardISO7816::GetData(
  361. /* [in] */ BYTE byP1,
  362. /* [in] */ BYTE byP2,
  363. /* [in] */ LONG lBytesToGet,
  364. /* [out][in] */ LPSCARDCMD __RPC_FAR *ppCmd)
  365. {
  366. HRESULT hReturn;
  367. try
  368. {
  369. HRESULT hr;
  370. if (NULL == *ppCmd)
  371. {
  372. *ppCmd = NewSCardCmd();
  373. if (NULL == *ppCmd)
  374. throw (HRESULT)E_OUTOFMEMORY;
  375. }
  376. hr = (*ppCmd)->BuildCmd(
  377. m_bCla, // CLA
  378. 0xca, // INS
  379. byP1, // P1
  380. byP2, // P2
  381. NULL,
  382. &lBytesToGet);
  383. hReturn = hr;
  384. }
  385. catch (HRESULT hError)
  386. {
  387. hReturn = hError;
  388. }
  389. catch (...)
  390. {
  391. hReturn = E_INVALIDARG;
  392. }
  393. return hReturn;
  394. }
  395. /*++
  396. CSCardISO7816::GetResponse:
  397. The GetResponse method constructs an APDU command that transmits APDU
  398. commands (or part of an APDU command) which otherwise could not be
  399. transmitted by the available protocols.
  400. Arguments:
  401. byP1, byP2 [in, defaultvalue(0)] Per the ISO 7816-4, P1 and P2 should be 0
  402. (RFU).
  403. lDataLength [in, defaultvalue(0)] Length of data transmitted.
  404. ppCmd [in, out] On input, a pointer to an ISCardCmd interface object or
  405. NULL. On return, it is filled with the APDU command constructed by
  406. this operation. If ppCmd was set to NULL, a smart card ISCardCmd
  407. object is internally created and returned via the ppCmd pointer.
  408. Return Value:
  409. The return value is an HRESULT. A value of S_OK indicates the call was
  410. successful.
  411. Remarks:
  412. Author:
  413. Doug Barlow (dbarlow) 6/24/1999
  414. --*/
  415. #undef __SUBROUTINE__
  416. #define __SUBROUTINE__ TEXT("CSCardISO7816::GetResponse")
  417. STDMETHODIMP
  418. CSCardISO7816::GetResponse(
  419. /* [in] */ BYTE byP1,
  420. /* [in] */ BYTE byP2,
  421. /* [in] */ LONG lDataLength,
  422. /* [out][in] */ LPSCARDCMD __RPC_FAR *ppCmd)
  423. {
  424. HRESULT hReturn;
  425. try
  426. {
  427. HRESULT hr;
  428. if (NULL == *ppCmd)
  429. {
  430. *ppCmd = NewSCardCmd();
  431. if (NULL == *ppCmd)
  432. throw (HRESULT)E_OUTOFMEMORY;
  433. }
  434. hr = (*ppCmd)->BuildCmd(
  435. m_bCla, // CLA
  436. 0xc0, // INS
  437. 0x00, // P1
  438. 0x00, // P2
  439. NULL,
  440. &lDataLength);
  441. hReturn = hr;
  442. }
  443. catch (HRESULT hError)
  444. {
  445. hReturn = hError;
  446. }
  447. catch (...)
  448. {
  449. hReturn = E_INVALIDARG;
  450. }
  451. return hReturn;
  452. }
  453. /*++
  454. CSCardISO7816::InternalAuthenticate:
  455. The InternalAuthenticate method constructs an APDU command that initiates
  456. the computation of the authentication data by the card using the challenge
  457. data sent from the interface device and a relevant secret (for example, a
  458. key) stored in the card.
  459. When the relevant secret is attached to the MF, the command may be used to
  460. authenticate the card as a whole.
  461. When the relevant secret is attached to another DF, the command may be used
  462. to authenticate that DF.
  463. Arguments:
  464. byAlgorithmRef [in, defaultvalue(NULL_BYTE)] Reference of the algorithm in
  465. the card. If this value is zero, this indicates that no information is
  466. given. The reference of the algorithm is known either before issuing
  467. the command or is provided in the data field.
  468. bySecretRef [in, defaultvalue(NULL_BYTE)] Reference of the secret:
  469. Meaning 8 7 6 5 4 3 2 1
  470. No Info 0 0 0 0 0 0 0 0
  471. Global ref 0 - - - - - - -
  472. Specific ref 1 - - - - - - -
  473. RFU - x x - - - - -
  474. Secret - - - x x x x x
  475. No Info = No information is given.
  476. Global ref = Global reference data (an MF specific key).
  477. Specific ref = Specific reference data (a DF specific key).
  478. RFU = 00 (other values are RFU).
  479. Secret = Number of the secret.
  480. pChallenge [in] Pointer to the authentication-related data (for example,
  481. challenge).
  482. lReplyBytes [in, defaultvalue(0)] Maximum number of bytes expected in
  483. response.
  484. ppCmd [in, out] On input, a pointer to an ISCardCmd interface object or
  485. NULL. On return, it is filled with the APDU command constructed by
  486. this operation. If ppCmd was set to NULL, a smart card ISCardCmd
  487. object is internally created and returned via the ppCmd pointer.
  488. Return Value:
  489. The return value is an HRESULT. A value of S_OK indicates the call was
  490. successful.
  491. Remarks:
  492. The successful execution of the command may be subject to successful
  493. completion of prior commands (for example, VERIFY or SELECT FILE) or
  494. selections (for example, the relevant secret).
  495. If a key and an algorithm are currently selected when issuing the command,
  496. then the command may implicitly use the key and the algorithm.
  497. The number of times the command is issued may be recorded in the card to
  498. limit the number of further attempts of using the relevant secret or the
  499. algorithm.
  500. Author:
  501. Doug Barlow (dbarlow) 6/24/1999
  502. --*/
  503. #undef __SUBROUTINE__
  504. #define __SUBROUTINE__ TEXT("CSCardISO7816::InternalAuthenticate")
  505. STDMETHODIMP
  506. CSCardISO7816::InternalAuthenticate(
  507. /* [in] */ BYTE byAlgorithmRef,
  508. /* [in] */ BYTE bySecretRef,
  509. /* [in] */ LPBYTEBUFFER pChallenge,
  510. /* [in] */ LONG lReplyBytes,
  511. /* [out][in] */ LPSCARDCMD __RPC_FAR *ppCmd)
  512. {
  513. HRESULT hReturn;
  514. try
  515. {
  516. HRESULT hr;
  517. if (NULL == *ppCmd)
  518. {
  519. *ppCmd = NewSCardCmd();
  520. if (NULL == *ppCmd)
  521. throw (HRESULT)E_OUTOFMEMORY;
  522. }
  523. hr = (*ppCmd)->BuildCmd(
  524. m_bCla, // CLA
  525. 0x88, // INS
  526. byAlgorithmRef, // P1
  527. bySecretRef, // P2
  528. pChallenge,
  529. &lReplyBytes);
  530. hReturn = hr;
  531. }
  532. catch (HRESULT hError)
  533. {
  534. hReturn = hError;
  535. }
  536. catch (...)
  537. {
  538. hReturn = E_INVALIDARG;
  539. }
  540. return hReturn;
  541. }
  542. /*++
  543. CSCardISO7816::ManageChannel:
  544. The ManageChannel method constructs an APDU command that opens and closes
  545. logical channels.
  546. The open function opens a new logical channel other than the basic one.
  547. Options are provided for the card to assign a logical channel number, or
  548. for the logical channel number to be supplied to the card.
  549. The close function explicitly closes a logical channel other than the basic
  550. one. After the successful closing, the logical channel shall be available
  551. for re-use.
  552. Arguments:
  553. byChannelState [in, defaultvalue(ISO_CLOSE_LOGICAL_CHANNEL)] Bit b8 of P1
  554. is used to indicate the open function or the close function; if b8 is 0
  555. then MANAGE CHANNEL shall open a logical channel and if b8 is 1 then
  556. MANAGE CHANNEL shall close a logical channel:
  557. P1 = '00' to open
  558. P1 = '80' to close
  559. Other values are RFU
  560. byChannel [in, defaultvalue(ISO_LOGICAL_CHANNEL_0)] For the open function
  561. (P1 = '00'), the bits b1 and b2 of P2 are used to code the logical
  562. channel number in the same manner as in the class byte, the other bits
  563. of P2 are RFU. When b1 and b2 of P2 are NULL, then the card will
  564. assign a logical channel number that will be returned in bits b1 and
  565. b2 of the data field.
  566. When b1 and/or b2 of P2 are not NULL, they code a logical channel
  567. number other than the basic one; then the card will open the externally
  568. assigned logical channel number.
  569. ppCmd [in, out] On input, a pointer to an ISCardCmd interface object or
  570. NULL. On return, it is filled with the APDU command constructed by
  571. this operation. If ppCmd was set to NULL, a smart card ISCardCmd
  572. object is internally created and returned via the ppCmd pointer.
  573. Return Value:
  574. The return value is an HRESULT. A value of S_OK indicates the call was
  575. successful.
  576. Remarks:
  577. When the open function is successfully performed from the basic logical
  578. channel, the MF shall be implicitly selected as the current DF and the
  579. security status of the new logical channel should be the same as the basic
  580. logical channel after ATR. The security status of the new logical channel
  581. should be separate from that of any other logical channel.
  582. When the open function is successfully performed from a logical channel,
  583. which is not the basic one, the current DF of the logical channel that
  584. issued the command will be selected as the current DF. In addition, the
  585. security status for the new logical channel should be the same as the
  586. security status of the logical channel from which the open function was
  587. performed.
  588. After a successful close function, the security status related to this
  589. logical channel is lost.
  590. Author:
  591. Doug Barlow (dbarlow) 6/24/1999
  592. --*/
  593. #undef __SUBROUTINE__
  594. #define __SUBROUTINE__ TEXT("CSCardISO7816::ManageChannel")
  595. STDMETHODIMP
  596. CSCardISO7816::ManageChannel(
  597. /* [in] */ BYTE byChannelState,
  598. /* [in] */ BYTE byChannel,
  599. /* [out][in] */ LPSCARDCMD __RPC_FAR *ppCmd)
  600. {
  601. HRESULT hReturn;
  602. try
  603. {
  604. HRESULT hr;
  605. LONG lLe = 1;
  606. if (NULL == *ppCmd)
  607. {
  608. *ppCmd = NewSCardCmd();
  609. if (NULL == *ppCmd)
  610. throw (HRESULT)E_OUTOFMEMORY;
  611. }
  612. hr = (*ppCmd)->BuildCmd(
  613. m_bCla, // CLA
  614. 0x70, // INS
  615. byChannelState, // P1
  616. byChannel, // P2
  617. NULL,
  618. 0 == (byChannelState | byChannel)
  619. ? &lLe
  620. : NULL);
  621. hReturn = hr;
  622. }
  623. catch (HRESULT hError)
  624. {
  625. hReturn = hError;
  626. }
  627. catch (...)
  628. {
  629. hReturn = E_INVALIDARG;
  630. }
  631. return hReturn;
  632. }
  633. /*++
  634. CSCardISO7816::PutData:
  635. The PutData method constructs an APDU command that stores a single
  636. primitive data object or the set of data objects contained in a constructed
  637. data object, depending on the file selected.
  638. How the objects are stored (writing once and/or updating and/or appending)
  639. depends on the definition or the nature of the data objects.
  640. Arguments:
  641. byP1, byP2 [in] Coding of P1-P2:
  642. Value Meaning
  643. 0000 - 003F RFU
  644. 0040 - 00FF BER-TLV tag (1 byte) in P2
  645. 0100 - 01FF Application data (proprietary coding)
  646. 0200 - 02FF SIMPLE-TLV tag in P2
  647. 0300 - 03FF RFU
  648. 0400 - 04FF BER-TLV tag (2 bytes) in P1-P2
  649. pData [in] Pointer to a byte buffer that contains the parameters and data to be
  650. written.
  651. ppCmd [in, out] On input, a pointer to an ISCardCmd interface object or
  652. NULL. On return, it is filled with the APDU command constructed by
  653. this operation. If ppCmd was set to NULL, a smart card ISCardCmd
  654. object is internally created and returned via the ppCmd pointer.
  655. Return Value:
  656. The return value is an HRESULT. A value of S_OK indicates the call was
  657. successful.
  658. Remarks:
  659. The command can be performed only if the security status satisfies the
  660. security conditions defined by the application within the context for the
  661. function.
  662. Store Application Data
  663. When the value of P1-P2 lies in the range from 0100 to 01FF, the value
  664. of P1-P2 shall be an identifier reserved for card internal tests and
  665. for proprietary services meaningful within a given application context.
  666. Store Data Objects
  667. When the value P1-P2 lies in the range from 0040 to 00FF, the value of
  668. P2 shall be a BER-TLV tag on a single byte. The value of 00FF is
  669. reserved for indicating that the data field carries BER-TLV data
  670. objects.
  671. When the value of P1-P2 lies in the range 0200 to 02FF, the value of P2
  672. shall be a SIMPLE-TLV tag. The value 0200 is RFU. The value 02FF is
  673. reserved for indicating that the data field carries SIMPLE-TLV data
  674. objects.
  675. When the value of P1-P2 lies in the range from 4000 to FFFF, the value
  676. of P1-P2 shall be a BER-TLV tag on two bytes. The values 4000 to FFFF
  677. are RFU.
  678. When a primitive data object is provided, the data field of the command
  679. message shall contain the value of the corresponding primitive data
  680. object.
  681. When a constructed data object is provided, the data field of the
  682. command message shall contain the value of the constructed data object
  683. (that is, data objects including their tag, length, and value).
  684. Author:
  685. Doug Barlow (dbarlow) 6/24/1999
  686. --*/
  687. #undef __SUBROUTINE__
  688. #define __SUBROUTINE__ TEXT("CSCardISO7816::PutData")
  689. STDMETHODIMP
  690. CSCardISO7816::PutData(
  691. /* [in] */ BYTE byP1,
  692. /* [in] */ BYTE byP2,
  693. /* [in] */ LPBYTEBUFFER pData,
  694. /* [out][in] */ LPSCARDCMD __RPC_FAR *ppCmd)
  695. {
  696. HRESULT hReturn;
  697. try
  698. {
  699. HRESULT hr;
  700. if (NULL == *ppCmd)
  701. {
  702. *ppCmd = NewSCardCmd();
  703. if (NULL == *ppCmd)
  704. throw (HRESULT)E_OUTOFMEMORY;
  705. }
  706. hr = (*ppCmd)->BuildCmd(
  707. m_bCla, // CLA
  708. 0xda, // INS
  709. byP1, // P1
  710. byP2, // P2
  711. pData,
  712. NULL);
  713. hReturn = hr;
  714. }
  715. catch (HRESULT hError)
  716. {
  717. hReturn = hError;
  718. }
  719. catch (...)
  720. {
  721. hReturn = E_INVALIDARG;
  722. }
  723. return hReturn;
  724. }
  725. /*++
  726. CSCardISO7816::ReadBinary:
  727. The ReadBinary method constructs an APDU command that acquires a response
  728. message that gives that part of the contents of a transparent-structured
  729. elementary file.
  730. Arguments:
  731. byP1, byP2 [in] The P1-P2 field, offset to the first byte to be read from
  732. the beginning of the file.
  733. If b8=1 in P1, then b7 and b6 of P1 are set to 0 (RFU bits), b5 to b1
  734. of P1 are a short EF identifier and P2 is the offset of the first byte
  735. to be read in data units from the beginning of the file.
  736. If b8=0 in P1, then P1||P2 is the offset of the first byte to be read
  737. in data units from the beginning of the file.
  738. lBytesToRead [in, defaultvalue(0)] Number of bytes to read from the
  739. transparent EF. If the Le field contains only zeroes, then within the
  740. limit of 256 for short length or 65536 for extended length, all the bytes
  741. until the end of the file should be read.
  742. ppCmd [in, out] On input, a pointer to an ISCardCmd interface object or
  743. NULL. On return, it is filled with the APDU command constructed by
  744. this operation. If ppCmd was set to NULL, a smart card ISCardCmd
  745. object is internally created and returned via the ppCmd pointer.
  746. Return Value:
  747. The return value is an HRESULT. A value of S_OK indicates the call was
  748. successful.
  749. Remarks:
  750. The encapsulated command can only be performed if the security status of
  751. the smart card satisfies the security attributes of the elementary file
  752. being processed.
  753. When the command contains a valid short elementary identifier, it sets the
  754. file as current elementary file.
  755. Elementary files without a transparent structure cannot be erased. The
  756. encapsulated command aborts if applied to an elementary file without a
  757. transparent structure.
  758. Author:
  759. Doug Barlow (dbarlow) 6/24/1999
  760. --*/
  761. #undef __SUBROUTINE__
  762. #define __SUBROUTINE__ TEXT("CSCardISO7816::ReadBinary")
  763. STDMETHODIMP
  764. CSCardISO7816::ReadBinary(
  765. /* [in] */ BYTE byP1,
  766. /* [in] */ BYTE byP2,
  767. /* [in] */ LONG lBytesToRead,
  768. /* [out][in] */ LPSCARDCMD __RPC_FAR *ppCmd)
  769. {
  770. HRESULT hReturn;
  771. try
  772. {
  773. HRESULT hr;
  774. if (NULL == *ppCmd)
  775. {
  776. *ppCmd = NewSCardCmd();
  777. if (NULL == *ppCmd)
  778. throw (HRESULT)E_OUTOFMEMORY;
  779. }
  780. hr = (*ppCmd)->BuildCmd(
  781. m_bCla, // CLA
  782. 0xb0, // INS
  783. byP1, // P1
  784. byP2, // P2
  785. NULL,
  786. &lBytesToRead);
  787. hReturn = hr;
  788. }
  789. catch (HRESULT hError)
  790. {
  791. hReturn = hError;
  792. }
  793. catch (...)
  794. {
  795. hReturn = E_INVALIDARG;
  796. }
  797. return hReturn;
  798. }
  799. /*++
  800. CSCardISO7816::ReadRecord:
  801. The ReadRecord method constructs an APDU command that reads either the
  802. contents of the specified record(s) or the beginning part of one record of
  803. an elementary file.
  804. Arguments:
  805. byRecordId [in, defaultvalue(NULL_BYTE)] Record number or ID of the first
  806. record to be read (00 indicates the current record).
  807. byRefCtrl [in] Coding of the reference control:
  808. Meaning 8 7 6 5 4 3 2 1
  809. Current EF 0 0 0 0 0 - - -
  810. Short EF ID x x x x x - - -
  811. RFU 1 1 1 1 1 - - -
  812. Record - - - - - 1 x x
  813. Read Record - - - - - 1 0 0
  814. Up to Last - - - - - 1 0 1
  815. Up to P1 - - - - - 1 1 0
  816. RFU - - - - - 1 1 1
  817. Record ID - - - - - 0 x x
  818. First Occur - - - - - 0 0 0
  819. Last Occur - - - - - 0 0 1
  820. Next Occur - - - - - 0 1 0
  821. Previous - - - - - 0 1 1
  822. Secret - - - x x x x x
  823. Current EF = Currently selected EF.
  824. Short EF ID = Short EF identifier.
  825. Record # = Usage of record number in P1.
  826. Read Record = Read record P1.
  827. Up to Last = Read all records from P1 up to the last.
  828. Up to P1 = Read all records from the last up to P1.
  829. Record ID = Usage of record ID in P1.
  830. First Occur = Read first occurrence.
  831. Last Occur = Read last occurrence.
  832. Next Occur = Read next occurrence.
  833. Previous = Read previous occurrence.
  834. lBytesToRead [in, defaultvalue(0)] Number of bytes to read from the
  835. transparent EF. If the Le field contains only zeroes, then depending
  836. on b3b2b1 of P2 and within the limit of 256 for short length or 65536
  837. for extended length, the command should read completely either the
  838. single requested record or the requested sequence of records.
  839. ppCmd [in, out] On input, a pointer to an ISCardCmd interface object or
  840. NULL. On return, it is filled with the APDU command constructed by
  841. this operation. If ppCmd was set to NULL, a smart card ISCardCmd
  842. object is internally created and returned via the ppCmd pointer.
  843. Return Value:
  844. The return value is an HRESULT. A value of S_OK indicates the call was
  845. successful.
  846. Remarks:
  847. The encapsulated command can only be performed if the security status of
  848. the smart card satisfies the security attributes of the elementary file
  849. being read.
  850. If another elementary file is currently selected at the time of issuing
  851. this command, it may be processed without identification of the currently
  852. selected file.
  853. When the command contains a valid short elementary identifier, it sets the
  854. file as current elementary file.
  855. Elementary files without a record structure cannot be read. The
  856. encapsulated command aborts if applied to an elementary file without a
  857. record structure.
  858. Author:
  859. Doug Barlow (dbarlow) 6/24/1999
  860. --*/
  861. #undef __SUBROUTINE__
  862. #define __SUBROUTINE__ TEXT("CSCardISO7816::ReadRecord")
  863. STDMETHODIMP
  864. CSCardISO7816::ReadRecord(
  865. /* [in] */ BYTE byRecordId,
  866. /* [in] */ BYTE byRefCtrl,
  867. /* [in] */ LONG lBytesToRead,
  868. /* [out][in] */ LPSCARDCMD __RPC_FAR *ppCmd)
  869. {
  870. HRESULT hReturn;
  871. try
  872. {
  873. HRESULT hr;
  874. if (NULL == *ppCmd)
  875. {
  876. *ppCmd = NewSCardCmd();
  877. if (NULL == *ppCmd)
  878. throw (HRESULT)E_OUTOFMEMORY;
  879. }
  880. hr = (*ppCmd)->BuildCmd(
  881. m_bCla, // CLA
  882. 0xb2, // INS
  883. byRecordId, // P1
  884. byRefCtrl, // P2
  885. NULL,
  886. &lBytesToRead);
  887. hReturn = hr;
  888. }
  889. catch (HRESULT hError)
  890. {
  891. hReturn = hError;
  892. }
  893. catch (...)
  894. {
  895. hReturn = E_INVALIDARG;
  896. }
  897. return hReturn;
  898. }
  899. /*++
  900. CSCardISO7816::SelectFile:
  901. The SelectFile method constructs an APDU command that sets a current
  902. elementary file within a logical channel. Subsequent commands may
  903. implicitly refer to the current file through the logical channel.
  904. Selecting a directory (DF) within the card filestore which may be the
  905. root (MF) of the filestore makes it the current DF. After such a
  906. selection, an implicit current elementary file may be referred to through
  907. that logical channel.
  908. Selecting an elementary file sets the selected file and its parent as
  909. current files.
  910. After the answer to reset, the MF is implicitly selected through the basic
  911. logical channel, unless specified differently in the historical bytes or in
  912. the initial data string.
  913. Arguments:
  914. byP1, byP2 [in] Selection control.
  915. P1 (upper byte in word):
  916. Meaning 8 7 6 5 4 3 2 1
  917. Select File ID 0 0 0 0 0 0 x x
  918. EF, DF, or MF 0 0 0 0 0 0 0 0
  919. child DF 0 0 0 0 0 0 0 1
  920. EF under DF 0 0 0 0 0 0 1 0
  921. parent DF of current DF 0 0 0 0 0 0 1 1
  922. Select by DF Name 0 0 0 0 0 1 x x
  923. DFname 0 0 0 0 0 1 0 0
  924. RFU 0 0 0 0 0 1 0 1
  925. RFU 0 0 0 0 0 1 1 0
  926. RFU 0 0 0 0 0 1 1 1
  927. Select by path 0 0 0 0 1 0 x x
  928. from MF 0 0 0 0 1 0 0 0
  929. current DF 0 0 0 0 1 0 0 1
  930. RFU 0 0 0 0 1 0 1 0
  931. RFU 0 0 0 0 1 0 1 1
  932. When P1=00, the card knows either because of a specific coding of
  933. the file ID or because of the context of execution of the command
  934. if the file to select is the MF, a DF, or an EF.
  935. When P1-P2=0000, if a file ID is provided, then it shall be unique
  936. in the following environments:
  937. the immediate children of the current DF
  938. the parent DF
  939. the immediate children of the parent DF
  940. If P1-P2=0000 and if the data field is empty or equal to 3F00, then
  941. select the MF.
  942. When P1=04, the data field is a DF name, possibly right truncated.
  943. When supported, successive such commands with the same data field
  944. shall select DFs whose names match with the data field (that is,
  945. start with the command data field). If the card accepts the
  946. command with an empty data field, then all or a subset of the DFs
  947. can be successively selected.
  948. P2 (lower byte of word):
  949. Meaning 8 7 6 5 4 3 2 1
  950. First occur 0 0 0 0 - - 0 0
  951. Last occur 0 0 0 0 - - 0 1
  952. Next occur 0 0 0 0 - - 1 0
  953. Previous occur 0 0 0 0 - - 1 1
  954. File Control 0 0 0 0 x x - -
  955. Return FCI 0 0 0 0 0 0 - -
  956. Return FCP 0 0 0 0 0 1 - -
  957. Return FMD 0 0 0 0 1 0 - -
  958. pData [in, defaultvalue(NULL)] Data for operation if needed; else, NULL.
  959. Types of data that are passed in this parameter include:
  960. file ID
  961. path from the MF
  962. path from the current DF
  963. DF name
  964. lBytesToRead [in, defaultvalue(0)] Empty (that is, 0) or maximum length of
  965. data expected in response.
  966. ppCmd [in, out] On input, a pointer to an ISCardCmd interface object or
  967. NULL. On return, it is filled with the APDU command constructed by
  968. this operation. If ppCmd was set to NULL, a smart card ISCardCmd
  969. object is internally created and returned via the ppCmd pointer.
  970. Return Value:
  971. The return value is an HRESULT. A value of S_OK indicates the call was
  972. successful.
  973. Remarks:
  974. Unless otherwise specified, the correct execution of the encapsulated
  975. command modifies the security status according to the following rules:
  976. * When the current elementary file is changed, or when there is no
  977. current elementary file, the security status specific to a former
  978. current elementary file is lost.
  979. * When the current filestore directory (DF) is descendant of, or
  980. identical to the former current DF, the security status specific to the
  981. former current DF is lost. The security status common to all common
  982. ancestors of the previous and new current DF is maintained.
  983. Author:
  984. Doug Barlow (dbarlow) 6/24/1999
  985. --*/
  986. #undef __SUBROUTINE__
  987. #define __SUBROUTINE__ TEXT("CSCardISO7816::SelectFile")
  988. STDMETHODIMP
  989. CSCardISO7816::SelectFile(
  990. /* [in] */ BYTE byP1,
  991. /* [in] */ BYTE byP2,
  992. /* [in] */ LPBYTEBUFFER pData,
  993. /* [in] */ LONG lBytesToRead,
  994. /* [out][in] */ LPSCARDCMD __RPC_FAR *ppCmd)
  995. {
  996. HRESULT hReturn;
  997. try
  998. {
  999. HRESULT hr;
  1000. if (NULL == *ppCmd)
  1001. {
  1002. *ppCmd = NewSCardCmd();
  1003. if (NULL == *ppCmd)
  1004. throw (HRESULT)E_OUTOFMEMORY;
  1005. }
  1006. hr = (*ppCmd)->BuildCmd(
  1007. m_bCla, // CLA
  1008. 0xa4, // INS
  1009. byP1, // P1
  1010. byP2, // P2
  1011. pData,
  1012. 0 == lBytesToRead ? NULL : &lBytesToRead);
  1013. hReturn = hr;
  1014. }
  1015. catch (HRESULT hError)
  1016. {
  1017. hReturn = hError;
  1018. }
  1019. catch (...)
  1020. {
  1021. hReturn = E_INVALIDARG;
  1022. }
  1023. return hReturn;
  1024. }
  1025. /*++
  1026. CSCardISO7816::SetDefaultClassId:
  1027. The SetDefaultClassId method assigns a standard class identifier byte that
  1028. will be used in all operations when constructing an ISO 7816-4 command
  1029. APDU. By default, the standard class identifier byte is 0x00.
  1030. Arguments:
  1031. byClass [in] Class ID byte.
  1032. Return Value:
  1033. The return value is an HRESULT. A value of S_OK indicates the call was
  1034. successful.
  1035. Remarks:
  1036. Author:
  1037. Doug Barlow (dbarlow) 6/24/1999
  1038. --*/
  1039. #undef __SUBROUTINE__
  1040. #define __SUBROUTINE__ TEXT("CSCardISO7816::SetDefaultClassId")
  1041. STDMETHODIMP
  1042. CSCardISO7816::SetDefaultClassId(
  1043. /* [in] */ BYTE byClass)
  1044. {
  1045. m_bCla = byClass;
  1046. return S_OK;
  1047. }
  1048. /*++
  1049. CSCardISO7816::UpdateBinary:
  1050. The UpdateBinary method constructs an APDU command that updates the bits
  1051. present in an elementary file with the bits given in the APDU command.
  1052. Arguments:
  1053. byP1, byP2 [in] Offset to the write (update) location into the binary from
  1054. the start of the binary.
  1055. If b8=1 in P1, then b7 and b6 of P1 are set to 0 (RFU bits), b5 to b1
  1056. of P1 are a short EF identifier and P2 is the offset of the first byte
  1057. to be updated in data units from the beginning of the file.
  1058. If b8=0 in P1, then P1 || P2 is the offset of the first byte to be
  1059. updated in data units from the beginning of the file.
  1060. pData [in] Pointer to the string of data units to be updated.
  1061. ppCmd [in, out] On input, a pointer to an ISCardCmd interface object or
  1062. NULL. On return, it is filled with the APDU command constructed by
  1063. this operation. If ppCmd was set to NULL, a smart card ISCardCmd
  1064. object is internally created and returned via the ppCmd pointer.
  1065. Return Value:
  1066. The return value is an HRESULT. A value of S_OK indicates the call was
  1067. successful.
  1068. Remarks:
  1069. The encapsulated command can only be performed if the security status of
  1070. the smart card satisfies the security attributes of the elementary file
  1071. being processed.
  1072. When the command contains a valid short elementary identifier, it sets the
  1073. file as current elementary file.
  1074. Elementary files without a transparent structure cannot be erased. The
  1075. encapsulated command aborts if applied to an elementary file without a
  1076. transparent structure.
  1077. Author:
  1078. Doug Barlow (dbarlow) 6/24/1999
  1079. --*/
  1080. #undef __SUBROUTINE__
  1081. #define __SUBROUTINE__ TEXT("CSCardISO7816::UpdateBinary")
  1082. STDMETHODIMP
  1083. CSCardISO7816::UpdateBinary(
  1084. /* [in] */ BYTE byP1,
  1085. /* [in] */ BYTE byP2,
  1086. /* [in] */ LPBYTEBUFFER pData,
  1087. /* [out][in] */ LPSCARDCMD __RPC_FAR *ppCmd)
  1088. {
  1089. HRESULT hReturn;
  1090. try
  1091. {
  1092. HRESULT hr;
  1093. if (NULL == *ppCmd)
  1094. {
  1095. *ppCmd = NewSCardCmd();
  1096. if (NULL == *ppCmd)
  1097. throw (HRESULT)E_OUTOFMEMORY;
  1098. }
  1099. hr = (*ppCmd)->BuildCmd(
  1100. m_bCla, // CLA
  1101. 0xd6, // INS
  1102. byP1, // P1
  1103. byP2, // P2
  1104. pData,
  1105. NULL);
  1106. hReturn = hr;
  1107. }
  1108. catch (HRESULT hError)
  1109. {
  1110. hReturn = hError;
  1111. }
  1112. catch (...)
  1113. {
  1114. hReturn = E_INVALIDARG;
  1115. }
  1116. return hReturn;
  1117. }
  1118. /*++
  1119. CSCardISO7816::UpdateRecord:
  1120. The UpdateRecord method constructs an APDU command that updates a specific
  1121. record with the bits given in the APDU command.
  1122. Note When using current record addressing, the command sets the record
  1123. pointer on the successfully updated record.
  1124. Arguments:
  1125. byRecordId [in, defaultvalue(NULL_BYTE)] P1 value:
  1126. P1 = 00 designates the current record
  1127. P1 != '00' is the number of the specified record
  1128. byRefCtrl [in, defaultvalue(NULL_BYTE)] Coding of the reference control P2:
  1129. Meaning 8 7 6 5 4 3 2 1
  1130. Current EF 0 0 0 0 0 - - -
  1131. Short EF ID x x x x x - - -
  1132. First Record - - - - - 0 0 0
  1133. Last Record - - - - - 0 0 1
  1134. Next Record - - - - - 0 1 0
  1135. Previous Record - - - - - 0 1 1
  1136. Record # in P1 - - - - - 1 0 0
  1137. pData [in] Pointer to the record to be updated.
  1138. ppCmd [in, out] On input, a pointer to an ISCardCmd interface object or
  1139. NULL. On return, it is filled with the APDU command constructed by
  1140. this operation. If ppCmd was set to NULL, a smart card ISCardCmd
  1141. object is internally created and returned via the ppCmd pointer.
  1142. Return Value:
  1143. The return value is an HRESULT. A value of S_OK indicates the call was
  1144. successful.
  1145. Remarks:
  1146. The encapsulated command can only be performed if the security status of
  1147. the smart card satisfies the security attributes of the elementary file
  1148. being processed.
  1149. When the command contains a valid short elementary identifier, it sets the
  1150. file as current elementary file. If another elementary file is currently
  1151. selected at the time of issuing this command, this command may be processed
  1152. without identification of the currently selected file.
  1153. If the constructed command applies to a linear-fixed or cyclic-structured
  1154. elementary file, it will abort if the record length is different from the
  1155. length of the existing record.
  1156. If the command applies to a linear-variable structured elementary file, it
  1157. may be carried out when the record length is different from the length of
  1158. the existing record.
  1159. The "previous" option of the command (P2=xxxxx011), applied to a cyclic
  1160. file, has the same behavior as a command constructed by AppendRecord.
  1161. Elementary files without a record structure cannot be read. The
  1162. constructed command aborts if applied to an elementary file without record
  1163. structure.
  1164. Author:
  1165. Doug Barlow (dbarlow) 6/24/1999
  1166. --*/
  1167. #undef __SUBROUTINE__
  1168. #define __SUBROUTINE__ TEXT("CSCardISO7816::UpdateRecord")
  1169. STDMETHODIMP
  1170. CSCardISO7816::UpdateRecord(
  1171. /* [in] */ BYTE byRecordId,
  1172. /* [in] */ BYTE byRefCtrl,
  1173. /* [in] */ LPBYTEBUFFER pData,
  1174. /* [out][in] */ LPSCARDCMD __RPC_FAR *ppCmd)
  1175. {
  1176. HRESULT hReturn;
  1177. try
  1178. {
  1179. HRESULT hr;
  1180. if (NULL == *ppCmd)
  1181. {
  1182. *ppCmd = NewSCardCmd();
  1183. if (NULL == *ppCmd)
  1184. throw (HRESULT)E_OUTOFMEMORY;
  1185. }
  1186. hr = (*ppCmd)->BuildCmd(
  1187. m_bCla, // CLA
  1188. 0xdc, // INS
  1189. byRecordId, // P1
  1190. byRefCtrl, // P2
  1191. pData,
  1192. NULL);
  1193. hReturn = hr;
  1194. }
  1195. catch (HRESULT hError)
  1196. {
  1197. hReturn = hError;
  1198. }
  1199. catch (...)
  1200. {
  1201. hReturn = E_INVALIDARG;
  1202. }
  1203. return hReturn;
  1204. }
  1205. /*++
  1206. CSCardISO7816::Verify:
  1207. The Verify method constructs an APDU command that initiates the comparison
  1208. (in the card) of the verification data sent from the interface device with
  1209. the reference data stored in the card (for example, password).
  1210. Arguments:
  1211. byRefCtrl [in, defaultvalue(NULL_BYTE)] Quantifier of the reference data;
  1212. coding of the reference control P2:
  1213. Meaning 8 7 6 5 4 3 2 1
  1214. No Info 0 0 0 0 0 0 0 0
  1215. Global Ref 0 - - - - - - -
  1216. Specific Ref 1 - - - - - - -
  1217. RFU - x x - - - - -
  1218. Ref Data # - - - x x x x x
  1219. An example of Global Ref would be a password.
  1220. An example of Specific Ref is DF specific password.
  1221. P2=00 is reserved to indicate that no particular qualifier is used in
  1222. those cards where the verify command references the secret data
  1223. unambiguously.
  1224. The reference data number may be for example a password number or a
  1225. short EF identifier.
  1226. When the body is empty, the command may be used either to retrieve the
  1227. number 'X' of further allowed retries (SW1-SW2=63CX) or to check
  1228. whether the verification is not required (SW1-SW2=9000).
  1229. pData [in, defaultvalue(NULL)] Pointer to the verification data, or can be
  1230. NULL.
  1231. ppCmd [in, out] On input, a pointer to an ISCardCmd interface object or
  1232. NULL. On return, it is filled with the APDU command constructed by
  1233. this operation. If ppCmd was set to NULL, a smart card ISCardCmd object
  1234. is internally created and returned via the ppCmd pointer.
  1235. Return Value:
  1236. The return value is an HRESULT. A value of S_OK indicates the call was
  1237. successful.
  1238. Remarks:
  1239. The security status may be modified as a result of a comparison.
  1240. Unsuccessful comparisons may be recorded in the card (for example, to limit
  1241. the number of further attempts of the use of the reference data).
  1242. Author:
  1243. Doug Barlow (dbarlow) 6/24/1999
  1244. --*/
  1245. #undef __SUBROUTINE__
  1246. #define __SUBROUTINE__ TEXT("CSCardISO7816::Verify")
  1247. STDMETHODIMP
  1248. CSCardISO7816::Verify(
  1249. /* [in] */ BYTE byRefCtrl,
  1250. /* [in] */ LPBYTEBUFFER pData,
  1251. /* [out][in] */ LPSCARDCMD __RPC_FAR *ppCmd)
  1252. {
  1253. HRESULT hReturn;
  1254. try
  1255. {
  1256. HRESULT hr;
  1257. if (NULL == *ppCmd)
  1258. {
  1259. *ppCmd = NewSCardCmd();
  1260. if (NULL == *ppCmd)
  1261. throw (HRESULT)E_OUTOFMEMORY;
  1262. }
  1263. hr = (*ppCmd)->BuildCmd(
  1264. m_bCla, // CLA
  1265. 0x20, // INS
  1266. 0x00, // P1
  1267. byRefCtrl, // P2
  1268. pData,
  1269. NULL);
  1270. hReturn = hr;
  1271. }
  1272. catch (HRESULT hError)
  1273. {
  1274. hReturn = hError;
  1275. }
  1276. catch (...)
  1277. {
  1278. hReturn = E_INVALIDARG;
  1279. }
  1280. return hReturn;
  1281. }
  1282. /*++
  1283. CSCardISO7816::WriteBinary:
  1284. The WriteBinary method constructs an APDU command that writes binary values
  1285. into an elementary file.
  1286. Depending upon the file attributes, the command performs one of the
  1287. following operations:
  1288. * The logical OR of the bits already present in the card with the bits
  1289. given in the command APDU (logical erased state of the bits of the file
  1290. is 0).
  1291. * The logical AND of the bits already present in the card with the bits
  1292. given in the command APDU (logical erased state of the bits of the file
  1293. is 1).
  1294. * The one-time write in the card of the bits given in the command APDU.
  1295. When no indication is given in the data coding byte, the logical OR
  1296. behavior applies.
  1297. Arguments:
  1298. byP1, byP2 [in] Offset to the write location from the beginning of the
  1299. binary file (EF).
  1300. If b8=1 in P1, then b7 and b6 of P1 are set to 0 (RFU bits), b5 to b1
  1301. of P1 are a short EF identifier and P2 is the offset of the first byte
  1302. to be written in data units from the beginning of the file.
  1303. If b8=0 in P1, then P1||P2 is the offset of the first byte to be
  1304. written in data units from the beginning of the file.
  1305. pData [in] Pointer to the string of data units to be written.
  1306. ppCmd [in, out] On input, a pointer to an ISCardCmd interface object or
  1307. NULL. On return, it is filled with the APDU command constructed by
  1308. this operation. If ppCmd was set to NULL, a smart card ISCardCmd
  1309. object is internally created and returned via the ppCmd pointer.
  1310. Return Value:
  1311. The return value is an HRESULT. A value of S_OK indicates the call was
  1312. successful.
  1313. Remarks:
  1314. The encapsulated command can only be performed if the security status of
  1315. the smart card satisfies the security attributes of the elementary file
  1316. being processed.
  1317. When the command contains a valid short elementary identifier, it sets the
  1318. file as current elementary file.
  1319. Once a write binary operation has been applied to a data unit of a one-time
  1320. write EF, any further write operation referring to this data unit will be
  1321. aborted if the content of the data unit or the logical erased state
  1322. indicator (if any) attached to this data unit is different from the logical
  1323. erased state.
  1324. Elementary files without a transparent structure cannot be written to. The
  1325. encapsulated command aborts if applied to an elementary file without a
  1326. transparent structure.
  1327. Author:
  1328. Doug Barlow (dbarlow) 6/24/1999
  1329. --*/
  1330. #undef __SUBROUTINE__
  1331. #define __SUBROUTINE__ TEXT("CSCardISO7816::WriteBinary")
  1332. STDMETHODIMP
  1333. CSCardISO7816::WriteBinary(
  1334. /* [in] */ BYTE byP1,
  1335. /* [in] */ BYTE byP2,
  1336. /* [in] */ LPBYTEBUFFER pData,
  1337. /* [out][in] */ LPSCARDCMD __RPC_FAR *ppCmd)
  1338. {
  1339. HRESULT hReturn;
  1340. try
  1341. {
  1342. HRESULT hr;
  1343. if (NULL == *ppCmd)
  1344. {
  1345. *ppCmd = NewSCardCmd();
  1346. if (NULL == *ppCmd)
  1347. throw (HRESULT)E_OUTOFMEMORY;
  1348. }
  1349. hr = (*ppCmd)->BuildCmd(
  1350. m_bCla, // CLA
  1351. 0xd0, // INS
  1352. byP1, // P1
  1353. byP2, // P2
  1354. pData,
  1355. NULL);
  1356. hReturn = hr;
  1357. }
  1358. catch (HRESULT hError)
  1359. {
  1360. hReturn = hError;
  1361. }
  1362. catch (...)
  1363. {
  1364. hReturn = E_INVALIDARG;
  1365. }
  1366. return hReturn;
  1367. }
  1368. /*++
  1369. CSCardISO7816::WriteRecord:
  1370. The WriteRecord method constructs an APDU command that initiates one of the
  1371. following operations:
  1372. * The write once of a record.
  1373. * The logical OR of the data bytes of a record already present in the
  1374. card with the data bytes of the record given in the command APDU.
  1375. * The logical AND of the data bytes of a record already present in the
  1376. card with the data bytes of the record given in the command APDU.
  1377. When no indication is given in the data coding byte, the logical OR behavior applies.
  1378. Note: When using current record addressing, the command sets the record
  1379. pointer on the successfully updated record.
  1380. Arguments:
  1381. byRecordId [in, defaultvalue(NULL_BYTE)] Record identification. This is the
  1382. P1 value:
  1383. P1 = '00' designates the current record.
  1384. P1 != '00' is the number of the specified record.
  1385. byRefCtrl [in, defaultvalue(NULL_BYTE)] Coding of the reference control P2:
  1386. Meaning 8 7 6 5 4 3 2 1
  1387. Current EF 0 0 0 0 0 - - -
  1388. Short EF ID x x x x x - - -
  1389. First Record - - - - - 0 0 0
  1390. Last Record - - - - - 0 0 1
  1391. Next Record - - - - - 0 1 0
  1392. Previous Record - - - - - 0 1 1
  1393. Record # in P1 - - - - - 1 0 0
  1394. pData [in] Pointer to the record to be written.
  1395. ppCmd [in, out] On input, a pointer to an ISCardCmd interface object or
  1396. NULL. On return, it is filled with the APDU command constructed by
  1397. this operation. If ppCmd was set to NULL, a smart card ISCardCmd
  1398. object is internally created and returned via the ppCmd pointer.
  1399. Return Value:
  1400. The return value is an HRESULT. A value of S_OK indicates the call was
  1401. successful.
  1402. Remarks:
  1403. The encapsulated command can only be performed if the security status of
  1404. the smart card satisfies the security attributes of the elementary file
  1405. being processed.
  1406. When the command contains a valid short elementary identifier, it sets the
  1407. file as current elementary file. If another elementary file is currently
  1408. selected at the time of issuing this command, this command may be processed
  1409. without identification of the currently selected file.
  1410. If the encapsulated command applies to a linear-fixed or cyclic-structured
  1411. elementary file, it will abort if the record length is different from the
  1412. length of the existing record. If it applies to a linear-variable
  1413. structured elementary file, it may be carried out when the record length is
  1414. different from the length of the existing record.
  1415. If P2=xxxxx011 and the elementary file is cyclic file, this command has the
  1416. same behavior a command constructed using AppendRecord.
  1417. Elementary files without a record structure cannot be written to. The
  1418. constructed command aborts if applied to an elementary file without a
  1419. record structure.
  1420. Author:
  1421. Doug Barlow (dbarlow) 6/24/1999
  1422. --*/
  1423. #undef __SUBROUTINE__
  1424. #define __SUBROUTINE__ TEXT("CSCardISO7816::WriteRecord")
  1425. STDMETHODIMP
  1426. CSCardISO7816::WriteRecord(
  1427. /* [in] */ BYTE byRecordId,
  1428. /* [in] */ BYTE byRefCtrl,
  1429. /* [in] */ LPBYTEBUFFER pData,
  1430. /* [out][in] */ LPSCARDCMD __RPC_FAR *ppCmd)
  1431. {
  1432. HRESULT hReturn;
  1433. try
  1434. {
  1435. HRESULT hr;
  1436. if (NULL == *ppCmd)
  1437. {
  1438. *ppCmd = NewSCardCmd();
  1439. if (NULL == *ppCmd)
  1440. throw (HRESULT)E_OUTOFMEMORY;
  1441. }
  1442. hr = (*ppCmd)->BuildCmd(
  1443. m_bCla, // CLA
  1444. 0xd2, // INS
  1445. byRecordId, // P1
  1446. byRefCtrl, // P2
  1447. pData,
  1448. NULL);
  1449. hReturn = hr;
  1450. }
  1451. catch (HRESULT hError)
  1452. {
  1453. hReturn = hError;
  1454. }
  1455. catch (...)
  1456. {
  1457. hReturn = E_INVALIDARG;
  1458. }
  1459. return hReturn;
  1460. }