VeraCrypt
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/html/Documentation.html1
-rw-r--r--doc/html/EMV Smart Cards.html87
-rw-r--r--doc/html/Keyfiles in VeraCrypt.html19
-rw-r--r--doc/html/Keyfiles.html295
-rw-r--r--src/Common/Dlgcode.c58
-rw-r--r--src/Common/Dlgcode.h1
-rw-r--r--src/Common/EMVToken.cpp121
-rw-r--r--src/Common/EMVToken.h50
-rw-r--r--src/Common/IccDataExtractor.cpp777
-rw-r--r--src/Common/IccDataExtractor.h231
-rw-r--r--src/Common/Keyfiles.c15
-rw-r--r--src/Common/Language.xml8
-rw-r--r--src/Common/SecurityToken.cpp522
-rw-r--r--src/Common/SecurityToken.h126
-rw-r--r--src/Common/TLVParser.cpp179
-rw-r--r--src/Common/TLVParser.h80
-rw-r--r--src/Common/Token.cpp82
-rw-r--r--src/Common/Token.h57
-rw-r--r--src/Core/Core.h19
-rw-r--r--src/Core/CoreBase.cpp18
-rw-r--r--src/Core/CoreBase.h8
-rw-r--r--src/Core/MountOptions.h1
-rw-r--r--src/Core/Unix/CoreServiceProxy.h6
-rw-r--r--src/Core/Unix/CoreUnix.cpp1
-rw-r--r--src/Core/VolumeCreator.cpp2
-rw-r--r--src/Core/VolumeCreator.h1
-rw-r--r--src/ExpandVolume/ExpandVolume.vcxproj16
-rw-r--r--src/ExpandVolume/ExpandVolume.vcxproj.filters24
-rw-r--r--src/ExpandVolume/WinMain.cpp1
-rw-r--r--src/Format/Format.vcxproj20
-rw-r--r--src/Format/Format.vcxproj.filters24
-rw-r--r--src/Format/Tcformat.c4
-rw-r--r--src/Main/CommandLineInterface.cpp16
-rw-r--r--src/Main/CommandLineInterface.h4
-rw-r--r--src/Main/Forms/ChangePasswordDialog.cpp2
-rw-r--r--src/Main/Forms/Forms.cpp13
-rw-r--r--src/Main/Forms/Forms.h1
-rw-r--r--src/Main/Forms/KeyfilesPanel.cpp2
-rw-r--r--src/Main/Forms/MainFrame.cpp3
-rw-r--r--src/Main/Forms/MountOptionsDialog.cpp1
-rw-r--r--src/Main/Forms/PreferencesDialog.cpp1
-rw-r--r--src/Main/Forms/SecurityTokenKeyfilesDialog.cpp53
-rw-r--r--src/Main/Forms/SecurityTokenKeyfilesDialog.h8
-rw-r--r--src/Main/Forms/VolumeCreationWizard.cpp8
-rw-r--r--src/Main/Forms/VolumePasswordPanel.cpp2
-rw-r--r--src/Main/Forms/WaitDialog.cpp9
-rw-r--r--src/Main/GraphicUserInterface.cpp27
-rw-r--r--src/Main/GraphicUserInterface.h4
-rw-r--r--src/Main/TextUserInterface.cpp62
-rw-r--r--src/Main/TextUserInterface.h4
-rw-r--r--src/Main/UserInterface.cpp67
-rw-r--r--src/Main/UserInterface.h2
-rw-r--r--src/Main/UserPreferences.cpp2
-rw-r--r--src/Main/UserPreferences.h2
-rw-r--r--src/Makefile4
-rw-r--r--src/Mount/Mount.c27
-rw-r--r--src/Mount/Mount.rc8
-rw-r--r--src/Mount/Mount.vcxproj16
-rw-r--r--src/Mount/Mount.vcxproj.filters24
-rw-r--r--src/Mount/Resource.h2
-rw-r--r--src/Volume/Keyfile.cpp84
-rw-r--r--src/Volume/Keyfile.h4
-rw-r--r--src/Volume/Volume.cpp9
-rw-r--r--src/Volume/Volume.h4
-rw-r--r--src/Volume/Volume.make4
65 files changed, 2721 insertions, 612 deletions
diff --git a/doc/html/Documentation.html b/doc/html/Documentation.html
index f6a46629..e18feb35 100644
--- a/doc/html/Documentation.html
+++ b/doc/html/Documentation.html
@@ -66,6 +66,7 @@
</li><li><strong><a href="Hot%20Keys.html">Hot keys</a></strong>
</li><li><strong><a href="Keyfiles%20in%20VeraCrypt.html">Keyfiles</a></strong>
</li><li><strong><a href="Security%20Tokens%20%26%20Smart%20Cards.html">Security Tokens &amp; Smart Cards</a></strong>
+</li><li><strong><a href="EMV%20Smart%20Cards.html">EMV Smart Cards</a></strong>
</li><li><strong><a href="Portable%20Mode.html">Portable Mode</a></strong>
</li><li><strong><a href="TrueCrypt%20Support.html">TrueCrypt Support</a></strong>
</li><li><strong><a href="Converting%20TrueCrypt%20volumes%20and%20partitions.html">Converting TrueCrypt Volumes &amp; Partitions</a></strong>
diff --git a/doc/html/EMV Smart Cards.html b/doc/html/EMV Smart Cards.html
new file mode 100644
index 00000000..d9c8716a
--- /dev/null
+++ b/doc/html/EMV Smart Cards.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+ <title>
+ VeraCrypt - Free Open source disk encryption with strong security for the
+ Paranoid
+ </title>
+ <meta
+ name="description"
+ content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."
+ />
+ <meta name="keywords" content="encryption, security" />
+ <link href="styles.css" rel="stylesheet" type="text/css" />
+ </head>
+ <body>
+ <div>
+ <a href="Documentation.html"
+ ><img src="VeraCrypt128x128.png" alt="VeraCrypt"
+ /></a>
+ </div>
+
+ <div id="menu">
+ <ul>
+ <li><a href="Home.html">Home</a></li>
+ <li><a href="/code/">Source Code</a></li>
+ <li><a href="Downloads.html">Downloads</a></li>
+ <li><a class="active" href="Documentation.html">Documentation</a></li>
+ <li><a href="Donation.html">Donate</a></li>
+ <li>
+ <a
+ href="https://sourceforge.net/p/veracrypt/discussion/"
+ target="_blank"
+ >Forums</a
+ >
+ </li>
+ </ul>
+ </div>
+
+ <div>
+ <p>
+ <a href="Documentation.html">Documentation</a>
+ <img src="arrow_right.gif" alt=">>" style="margin-top: 5px" />
+ <a href="EMV%20Smart%20Cards.html">EMV Smart Cards</a>
+ </p>
+ </div>
+
+ <div class="wikidoc">
+ <h1>EMV Smart Cards</h1>
+ <div
+ style="
+ text-align: left;
+ margin-top: 19px;
+ margin-bottom: 19px;
+ padding-top: 0px;
+ padding-bottom: 0px;
+ "
+ >
+ <p>
+ Windows and Linux versions of VeraCrypt offer to use EMV compliant
+ smart cards as a feature. Indeed, the use of PKCS#11 compliant smart
+ cards is dedicated to users with more or less cybersecurity skills.
+ However, in some situations, having such a card strongly reduces the
+ plausible deniability of the user.
+ </p>
+ <p>
+ To overcome this problem, the idea is to allow the use of a type of
+ smart card owned by anyone: EMV compliant smart cards. According to
+ the standard of the same name, these cards spread all over the world
+ are used to carry out banking operations. Using internal data of the
+ user's EMV card as keyfiles will strengthen the security of his volume
+ while keeping his denial plausible.
+ </p>
+ <p>
+ For more technical information, please see the section
+ <em style="text-align: left">EMV Smart Cards</em> in the chapter
+ <a
+ href="Keyfiles%20in%20VeraCrypt.html"
+ style="text-align: left; color: #0080c0; text-decoration: none.html"
+ >
+ <em style="text-align: left">Keyfiles</em></a
+ >.
+ </p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/doc/html/Keyfiles in VeraCrypt.html b/doc/html/Keyfiles in VeraCrypt.html
index ed940d53..eea6939a 100644
--- a/doc/html/Keyfiles in VeraCrypt.html
+++ b/doc/html/Keyfiles in VeraCrypt.html
@@ -114,6 +114,25 @@ To close all opened security token sessions, either select <em style="text-align
Tools</em> &gt; <em style="text-align:left">Close All Security Token Sessions</em> or define and use a hotkey combination (<em style="text-align:left">Settings</em> &gt;
<em style="text-align:left">Hot Keys &gt; Close All Security Token Sessions</em>).</div>
<p>&nbsp;</p>
+<h3 id="SmartCard" style="text-align:left; font-family:Arial,Helvetica,Verdana,sans-serif; font-weight:bold; margin-top:0px; font-size:13px; margin-bottom:4px">
+EMV Smart Cards</h3>
+<div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px">
+Windows and Linux versions of VeraCrypt can use directly as keyfiles data extracted from EMV compliant smart cards, supporting Visa, Mastecard or Maestro applications. As with PKCS-11 compliant smart cards, to use such data as VeraCrypt keyfiles,
+click <em style="text-align:left">Add Token Files</em> (in the keyfile dialog window). The last four digits of the card's Primary Account Number will be displayed, allowing the selection of the card as a keyfile source.
+<div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px">
+The data extracted and concatenated into a single keyfile are as follow : ICC Public Key Certificate, Issuer Public Key Certificate and Card Production Life
+Cycle (CPLC) data. They are respectively identified by the tags '9F46', '90' and '9F7F' in the card's data management system. These two certificates are specific to an application deployed on the EMV card and used for the Dynamic Data Authentication of the card
+during banking transactions. CPLC data are specific to the card and not to any of its applications. They contain information on the production process of the smart card. Therefore both certificates and data are unique and static on any EMV compliant smart card.</div>
+<div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px">
+According to the ISO/IEC 7816 standard on which the EMV standard is based, communication with an EMV smart card is done through structured commands called APDUs, allowing to extract the data from the smart card. These data are encoded in the BER-TLV format,
+defined by the ASN.1 standard, and therefore need to be parsed before being concatenated into a keyfile. No PIN is required to access and retrieve data from the card. To cope with the diversity of smart cards readers on the market, librairies compliant with the Microsoft Personal
+Computer/Smart Card communication standard are used. The Winscard library is used. Natively available on Windows in System32, it then doesn't require any installation on this operating system. However, the libpcsclite1 package has to be installed on Linux.</div>
+<div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px">
+Since the card is read-only, it is not possible to import or delete data. However, data used as keyfiles can be exported locally in any binary file. During the entire cryptographic process of mounting or creating a volume, the certificates and CPLC data are never stored anywhere
+other than in the user's machine RAM. Once the process is complete, these RAM memory areas are rigorously erased.</div>
+<div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px">
+It important to note that this feature is optional and disabled by default. It can be enabled in the <em style="text-align:left">Security Token Preferences</em> parameters by checking the box provided.</div>
+<p>&nbsp;</p>
<h3 style="text-align:left; font-family:Arial,Helvetica,Verdana,sans-serif; font-weight:bold; margin-top:0px; font-size:13px; margin-bottom:4px">
Keyfile Search Path</h3>
<div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px">
diff --git a/doc/html/Keyfiles.html b/doc/html/Keyfiles.html
index db4fb52c..04dd3463 100644
--- a/doc/html/Keyfiles.html
+++ b/doc/html/Keyfiles.html
@@ -1,81 +1,222 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-<meta http-equiv="content-type" content="text/html; charset=utf-8" />
-<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
-<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
-<meta name="keywords" content="encryption, security"/>
-<link href="styles.css" rel="stylesheet" type="text/css" />
-</head>
-<body>
+ <head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+ <title>
+ VeraCrypt - Free Open source disk encryption with strong security for the
+ Paranoid
+ </title>
+ <meta
+ name="description"
+ content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."
+ />
+ <meta name="keywords" content="encryption, security" />
+ <link href="styles.css" rel="stylesheet" type="text/css" />
+ </head>
+ <body>
+ <div>
+ <a href="Documentation.html"
+ ><img src="VeraCrypt128x128.png" alt="VeraCrypt"
+ /></a>
+ </div>
-<div>
-<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
-</div>
+ <div id="menu">
+ <ul>
+ <li><a href="Home.html">Home</a></li>
+ <li><a href="/code/">Source Code</a></li>
+ <li><a href="Downloads.html">Downloads</a></li>
+ <li><a class="active" href="Documentation.html">Documentation</a></li>
+ <li><a href="Donation.html">Donate</a></li>
+ <li>
+ <a
+ href="https://sourceforge.net/p/veracrypt/discussion/"
+ target="_blank"
+ >Forums</a
+ >
+ </li>
+ </ul>
+ </div>
-<div id="menu">
- <ul>
- <li><a href="Home.html">Home</a></li>
- <li><a href="/code/">Source Code</a></li>
- <li><a href="Downloads.html">Downloads</a></li>
- <li><a class="active" href="Documentation.html">Documentation</a></li>
- <li><a href="Donation.html">Donate</a></li>
- <li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
- </ul>
-</div>
+ <div>
+ <p>
+ <a href="Documentation.html">Documentation</a>
+ <img src="arrow_right.gif" alt=">>" style="margin-top: 5px" />
+ <a href="Technical%20Details.html">Technical Details</a>
+ <img src="arrow_right.gif" alt=">>" style="margin-top: 5px" />
+ <a href="Keyfiles.html">Keyfiles</a>
+ </p>
+ </div>
-<div>
-<p>
-<a href="Documentation.html">Documentation</a>
-<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
-<a href="Technical%20Details.html">Technical Details</a>
-<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
-<a href="Keyfiles.html">Keyfiles</a>
-</p></div>
-
-<div class="wikidoc">
-<h1>Keyfiles</h1>
-<div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px">
-<p>VeraCrypt keyfile is a file whose content is combined with a password. The user can use any kind of file as a VeraCrypt keyfile. The user can also generate a keyfile using the built-in keyfile generator, which utilizes the VeraCrypt RNG to generate a file
- with random content (for more information, see the section <a href="Random%20Number%20Generator.html">
-<em>Random Number Generator</em></a>).</p>
-<p>The maximum size of a keyfile is not limited; however, only its first 1,048,576 bytes (1 MiB) are processed (all remaining bytes are ignored due to performance issues connected with processing extremely large files). The user can supply one or more keyfiles
- (the number of keyfiles is not limited).</p>
-<p>Keyfiles can be stored on PKCS-11-compliant [23] security tokens and smart cards protected by multiple PIN codes (which can be entered either using a hardware PIN pad or via the VeraCrypt GUI).</p>
-<p>Keyfiles are processed and applied to a password using the following method:</p>
-<ol>
-<li>Let <em>P</em> be a VeraCrypt volume password supplied by user (may be empty)
-</li><li>Let <em>KP</em> be the keyfile pool </li><li>Let <em>kpl</em> be the size of the keyfile pool <em>KP</em>, in bytes (64, i.e., 512 bits);
-<p>kpl must be a multiple of the output size of a hash function H</p>
-</li><li>Let <em>pl</em> be the length of the password <em>P</em>, in bytes (in the current version: 0 &le;
-<em>pl</em> &le; 64) </li><li>if <em>kpl &gt; pl</em>, append (<em>kpl &ndash; pl</em>) zero bytes to the password
-<em>P</em> (thus <em>pl = kpl</em>) </li><li>Fill the keyfile pool <em>KP</em> with <em>kpl</em> zero bytes. </li><li>For each keyfile perform the following steps:
-<ol type="a">
-<li>Set the position of the keyfile pool cursor to the beginning of the pool </li><li>Initialize the hash function <em>H</em> </li><li>Load all bytes of the keyfile one by one, and for each loaded byte perform the following steps:
-<ol type="i">
-<li>Hash the loaded byte using the hash function <em>H</em> without initializing the hash, to obtain an intermediate hash (state)
-<em>M.</em> Do not finalize the hash (the state is retained for next round). </li><li>Divide the state <em>M</em> into individual bytes.<br>
-For example, if the hash output size is 4 bytes, (<em>T</em><sub>0</sub> || <em>T</em><sub>1</sub> ||
-<em>T</em><sub>2</sub> || <em>T</em><sub>3</sub>) = <em>M</em> </li><li>Write these bytes (obtained in step 7.c.ii) individually to the keyfile pool with the modulo 2<sup>8</sup> addition operation (not by replacing the old values in the pool) at the position of the pool cursor. After a byte is written, the pool cursor position
- is advanced by one byte. When the cursor reaches the end of the pool, its position is set to the beginning of the pool.
-</li></ol>
-</li></ol>
-</li><li>Apply the content of the keyfile pool to the password <em>P</em> using the following method:
-<ol type="a">
-<li>Divide the password <em>P</em> into individual bytes <em>B</em><sub>0</sub>...<em>B</em><sub>pl-1</sub>.<br>
-Note that if the password was shorter than the keyfile pool, then the password was padded with zero bytes to the length of the pool in Step 5 (hence, at this point the length of the password is always greater than or equal to the length of the keyfile pool).
-</li><li>Divide the keyfile pool <em>KP</em> into individual bytes <em>G</em><sub>0</sub>...<em>G</em><sub>kpl-1</sub>
-</li><li>For 0 &le; i &lt; kpl perform: Bi = Bi &oplus; Gi </li><li><em>P</em> = <em>B</em><sub>0</sub> || <em>B</em><sub>1</sub> || ... || <em>B</em><sub>pl-2</sub> ||
-<em>B</em><sub>pl-1</sub> </li></ol>
-</li><li>The password <em>P</em> (after the keyfile pool content has been applied to it) is now passed to the header key derivation function PBKDF2 (PKCS #5 v2), which processes it (along with salt and other data) using a cryptographically secure hash algorithm
- selected by the user (e.g., SHA-512). See the section <a href="Header%20Key%20Derivation.html">
-<em>Header Key Derivation, Salt, and Iteration Count</em></a> for more information.
-</li></ol>
-<p>The role of the hash function <em>H</em> is merely to perform diffusion [2]. CRC-32 is used as the hash function
-<em>H</em>. Note that the output of CRC-32 is subsequently processed using a cryptographically secure hash algorithm: The keyfile pool content (in addition to being hashed using CRC-32) is applied to the password, which is then passed to the header key derivation
- function PBKDF2 (PKCS #5 v2), which processes it (along with salt and other data) using a cryptographically secure hash algorithm selected by the user (e.g., SHA-512). The resultant values are used to form the header key and the secondary header key (XTS mode).</p>
-<p>&nbsp;</p>
-<p><a href="Personal%20Iterations%20Multiplier%20%28PIM%29.html" style="text-align:left; color:#0080c0; text-decoration:none; font-weight:bold.html">Next Section &gt;&gt;</a></p>
-</div>
-</div><div class="ClearBoth"></div></body></html>
+ <div class="wikidoc">
+ <h1>Keyfiles</h1>
+ <div
+ style="
+ text-align: left;
+ margin-top: 19px;
+ margin-bottom: 19px;
+ padding-top: 0px;
+ padding-bottom: 0px;
+ "
+ >
+ <p>
+ VeraCrypt keyfile is a file whose content is combined with a password.
+ The user can use any kind of file as a VeraCrypt keyfile. The user can
+ also generate a keyfile using the built-in keyfile generator, which
+ utilizes the VeraCrypt RNG to generate a file with random content (for
+ more information, see the section
+ <a href="Random%20Number%20Generator.html">
+ <em>Random Number Generator</em></a
+ >).
+ </p>
+ <p>
+ The maximum size of a keyfile is not limited; however, only its first
+ 1,048,576 bytes (1 MiB) are processed (all remaining bytes are ignored
+ due to performance issues connected with processing extremely large
+ files). The user can supply one or more keyfiles (the number of
+ keyfiles is not limited).
+ </p>
+ <p>
+ Keyfiles can be stored on PKCS-11-compliant [23] security tokens and
+ smart cards protected by multiple PIN codes (which can be entered
+ either using a hardware PIN pad or via the VeraCrypt GUI).
+ </p>
+ <p>
+ EMV-compliant smart cards' data can be used as keyfile, see chapter
+ <a
+ href="EMV%20Smart%20Cards.html"
+ style="text-align: left; color: #0080c0; text-decoration: none.html"
+ >
+ <em style="text-align: left">EMV Smart Cards</em></a
+ >.
+ </p>
+ <p>
+ Keyfiles are processed and applied to a password using the following
+ method:
+ </p>
+ <ol>
+ <li>
+ Let <em>P</em> be a VeraCrypt volume password supplied by user (may
+ be empty)
+ </li>
+ <li>Let <em>KP</em> be the keyfile pool</li>
+ <li>
+ Let <em>kpl</em> be the size of the keyfile pool <em>KP</em>, in
+ bytes (64, i.e., 512 bits);
+ <p>
+ kpl must be a multiple of the output size of a hash function H
+ </p>
+ </li>
+ <li>
+ Let <em>pl</em> be the length of the password <em>P</em>, in bytes
+ (in the current version: 0 &le; <em>pl</em> &le; 64)
+ </li>
+ <li>
+ if <em>kpl &gt; pl</em>, append (<em>kpl &ndash; pl</em>) zero bytes
+ to the password <em>P</em> (thus <em>pl = kpl</em>)
+ </li>
+ <li>
+ Fill the keyfile pool <em>KP</em> with <em>kpl</em> zero bytes.
+ </li>
+ <li>
+ For each keyfile perform the following steps:
+ <ol type="a">
+ <li>
+ Set the position of the keyfile pool cursor to the beginning of
+ the pool
+ </li>
+ <li>Initialize the hash function <em>H</em></li>
+ <li>
+ Load all bytes of the keyfile one by one, and for each loaded
+ byte perform the following steps:
+ <ol type="i">
+ <li>
+ Hash the loaded byte using the hash function
+ <em>H</em> without initializing the hash, to obtain an
+ intermediate hash (state) <em>M.</em> Do not finalize the
+ hash (the state is retained for next round).
+ </li>
+ <li>
+ Divide the state <em>M</em> into individual bytes.<br />
+ For example, if the hash output size is 4 bytes, (<em>T</em
+ ><sub>0</sub> || <em>T</em><sub>1</sub> || <em>T</em
+ ><sub>2</sub> || <em>T</em><sub>3</sub>) = <em>M</em>
+ </li>
+ <li>
+ Write these bytes (obtained in step 7.c.ii) individually to
+ the keyfile pool with the modulo 2<sup>8</sup> addition
+ operation (not by replacing the old values in the pool) at
+ the position of the pool cursor. After a byte is written,
+ the pool cursor position is advanced by one byte. When the
+ cursor reaches the end of the pool, its position is set to
+ the beginning of the pool.
+ </li>
+ </ol>
+ </li>
+ </ol>
+ </li>
+ <li>
+ Apply the content of the keyfile pool to the password
+ <em>P</em> using the following method:
+ <ol type="a">
+ <li>
+ Divide the password <em>P</em> into individual bytes <em>B</em
+ ><sub>0</sub>...<em>B</em><sub>pl-1</sub>.<br />
+ Note that if the password was shorter than the keyfile pool,
+ then the password was padded with zero bytes to the length of
+ the pool in Step 5 (hence, at this point the length of the
+ password is always greater than or equal to the length of the
+ keyfile pool).
+ </li>
+ <li>
+ Divide the keyfile pool <em>KP</em> into individual bytes
+ <em>G</em><sub>0</sub>...<em>G</em><sub>kpl-1</sub>
+ </li>
+ <li>For 0 &le; i &lt; kpl perform: Bi = Bi &oplus; Gi</li>
+ <li>
+ <em>P</em> = <em>B</em><sub>0</sub> || <em>B</em><sub>1</sub> ||
+ ... || <em>B</em><sub>pl-2</sub> || <em>B</em><sub>pl-1</sub>
+ </li>
+ </ol>
+ </li>
+ <li>
+ The password <em>P</em> (after the keyfile pool content has been
+ applied to it) is now passed to the header key derivation function
+ PBKDF2 (PKCS #5 v2), which processes it (along with salt and other
+ data) using a cryptographically secure hash algorithm selected by
+ the user (e.g., SHA-512). See the section
+ <a href="Header%20Key%20Derivation.html">
+ <em>Header Key Derivation, Salt, and Iteration Count</em></a
+ >
+ for more information.
+ </li>
+ </ol>
+ <p>
+ The role of the hash function <em>H</em> is merely to perform
+ diffusion [2]. CRC-32 is used as the hash function <em>H</em>. Note
+ that the output of CRC-32 is subsequently processed using a
+ cryptographically secure hash algorithm: The keyfile pool content (in
+ addition to being hashed using CRC-32) is applied to the password,
+ which is then passed to the header key derivation function PBKDF2
+ (PKCS #5 v2), which processes it (along with salt and other data)
+ using a cryptographically secure hash algorithm selected by the user
+ (e.g., SHA-512). The resultant values are used to form the header key
+ and the secondary header key (XTS mode).
+ </p>
+ <p>&nbsp;</p>
+ <p>
+ <a
+ href="Personal%20Iterations%20Multiplier%20%28PIM%29.html"
+ style="
+ text-align: left;
+ color: #0080c0;
+ text-decoration: none;
+ font-weight: bold.html;
+ "
+ >Next Section &gt;&gt;</a
+ >
+ </p>
+ </div>
+ </div>
+ <div class="ClearBoth"></div>
+ </body>
+</html>
diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c
index e1170d84..dfcc3d03 100644
--- a/src/Common/Dlgcode.c
+++ b/src/Common/Dlgcode.c
@@ -207,6 +207,7 @@ BOOL LastMountedVolumeDirty;
BOOL MountVolumesAsSystemFavorite = FALSE;
BOOL FavoriteMountOnArrivalInProgress = FALSE;
BOOL MultipleMountOperationInProgress = FALSE;
+BOOL ActivateEMVOption = FALSE;
volatile BOOL NeedPeriodicDeviceListUpdate = FALSE;
BOOL DisablePeriodicDeviceListUpdate = FALSE;
@@ -12206,11 +12207,11 @@ static BOOL CALLBACK NewSecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPA
WaitCursor();
finally_do ({ NormalCursor(); });
- list <SecurityTokenInfo> tokens;
+ list <shared_ptr<TokenInfo>> tokens;
try
{
- tokens = SecurityToken::GetAvailableTokens();
+ tokens = Token::GetAvailableTokens();
}
catch (Exception &e)
{
@@ -12224,12 +12225,12 @@ static BOOL CALLBACK NewSecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPA
return 1;
}
- foreach (const SecurityTokenInfo &token, tokens)
+ foreach (const shared_ptr<TokenInfo> token, tokens)
{
wstringstream tokenLabel;
- tokenLabel << L"[" << token.SlotId << L"] " << token.Label;
+ tokenLabel << L"[" << token->SlotId << L"] " << token->Label;
- AddComboPair (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN), tokenLabel.str().c_str(), token.SlotId);
+ AddComboPair (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN), tokenLabel.str().c_str(), token->SlotId);
}
ComboBox_SetCurSel (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN), 0);
@@ -12283,7 +12284,7 @@ static BOOL CALLBACK NewSecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPA
}
-static void SecurityTokenKeyfileDlgFillList (HWND hwndDlg, const vector <SecurityTokenKeyfile> &keyfiles)
+static void SecurityTokenKeyfileDlgFillList (HWND hwndDlg, const vector <shared_ptr<TokenKeyfile>> &keyfiles)
{
HWND tokenListControl = GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST);
LVITEMW lvItem;
@@ -12291,18 +12292,18 @@ static void SecurityTokenKeyfileDlgFillList (HWND hwndDlg, const vector <Securit
ListView_DeleteAllItems (tokenListControl);
- foreach (const SecurityTokenKeyfile &keyfile, keyfiles)
+ foreach (const shared_ptr<TokenKeyfile> keyfile, keyfiles)
{
memset (&lvItem, 0, sizeof(lvItem));
lvItem.mask = LVIF_TEXT;
lvItem.iItem = line++;
wstringstream s;
- s << keyfile.SlotId;
+ s << keyfile->Token->SlotId;
ListItemAdd (tokenListControl, lvItem.iItem, (wchar_t *) s.str().c_str());
- ListSubItemSet (tokenListControl, lvItem.iItem, 1, (wchar_t *) keyfile.Token.Label.c_str());
- ListSubItemSet (tokenListControl, lvItem.iItem, 2, (wchar_t *) keyfile.Id.c_str());
+ ListSubItemSet (tokenListControl, lvItem.iItem, 1, (wchar_t *) keyfile->Token->Label.c_str());
+ ListSubItemSet (tokenListControl, lvItem.iItem, 2, (wchar_t *) keyfile->Id.c_str());
}
BOOL selected = (ListView_GetNextItem (GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST), -1, LVIS_SELECTED) != -1);
@@ -12311,10 +12312,10 @@ static void SecurityTokenKeyfileDlgFillList (HWND hwndDlg, const vector <Securit
}
-static list <SecurityTokenKeyfile> SecurityTokenKeyfileDlgGetSelected (HWND hwndDlg, const vector <SecurityTokenKeyfile> &keyfiles)
+static list <shared_ptr<TokenKeyfile>> SecurityTokenKeyfileDlgGetSelected (HWND hwndDlg, const vector <shared_ptr<TokenKeyfile>> &keyfiles)
{
HWND tokenListControl = GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST);
- list <SecurityTokenKeyfile> selectedKeyfiles;
+ list <shared_ptr<TokenKeyfile>> selectedKeyfiles;
int itemId = -1;
while ((itemId = ListView_GetNextItem (tokenListControl, itemId, LVIS_SELECTED)) != -1)
@@ -12328,8 +12329,8 @@ static list <SecurityTokenKeyfile> SecurityTokenKeyfileDlgGetSelected (HWND hwnd
BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
- static list <SecurityTokenKeyfilePath> *selectedTokenKeyfiles;
- static vector <SecurityTokenKeyfile> keyfiles;
+ static list <TokenKeyfilePath> *selectedTokenKeyfiles;
+ static vector <shared_ptr<TokenKeyfile>> keyfiles;
WORD lw = LOWORD (wParam);
@@ -12337,7 +12338,7 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam
{
case WM_INITDIALOG:
{
- selectedTokenKeyfiles = (list <SecurityTokenKeyfilePath> *) lParam;
+ selectedTokenKeyfiles = (list <TokenKeyfilePath> *) lParam;
LVCOLUMNW LvCol;
HWND tokenListControl = GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST);
@@ -12372,7 +12373,7 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam
WaitCursor();
finally_do ({ NormalCursor(); });
- keyfiles = SecurityToken::GetAvailableKeyfiles();
+ keyfiles = Token::GetAvailableKeyfiles(ActivateEMVOption);
}
catch (UserAbort&)
{
@@ -12400,9 +12401,9 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam
{
if (selectedTokenKeyfiles)
{
- foreach (const SecurityTokenKeyfile &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles))
+ foreach (const shared_ptr<TokenKeyfile> &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles))
{
- selectedTokenKeyfiles->push_back (SecurityTokenKeyfilePath (keyfile));
+ selectedTokenKeyfiles->push_back (TokenKeyfilePath (*keyfile));
}
}
@@ -12413,8 +12414,15 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam
if (msg == WM_NOTIFY && ((LPNMHDR) lParam)->code == LVN_ITEMCHANGED)
{
BOOL selected = (ListView_GetNextItem (GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST), -1, LVIS_SELECTED) != -1);
+ BOOL deletable = selected;
+ foreach (const shared_ptr<TokenKeyfile> &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles))
+ {
+ if( ! keyfile->Token->isEditable()){
+ deletable = false;
+ }
+ }
EnableWindow (GetDlgItem (hwndDlg, IDC_EXPORT), selected);
- EnableWindow (GetDlgItem (hwndDlg, IDC_DELETE), selected);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_DELETE), deletable);
return 1;
}
@@ -12461,7 +12469,7 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam
SecurityToken::CreateKeyfile (newParams.SlotId, keyfileDataVector, newParams.Name);
- keyfiles = SecurityToken::GetAvailableKeyfiles();
+ keyfiles = Token::GetAvailableKeyfiles(ActivateEMVOption);
SecurityTokenKeyfileDlgFillList (hwndDlg, keyfiles);
}
catch (Exception &e)
@@ -12489,7 +12497,7 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam
{
try
{
- foreach (const SecurityTokenKeyfile &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles))
+ foreach (const shared_ptr<TokenKeyfile> &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles))
{
wchar_t keyfilePath[TC_MAX_PATH];
@@ -12502,7 +12510,7 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam
vector <byte> keyfileData;
- SecurityToken::GetKeyfileData (keyfile, keyfileData);
+ keyfile->GetKeyfileData (keyfileData);
if (keyfileData.empty())
{
@@ -12538,12 +12546,12 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam
WaitCursor();
finally_do ({ NormalCursor(); });
- foreach (const SecurityTokenKeyfile &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles))
+ foreach (const shared_ptr<TokenKeyfile> keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles))
{
- SecurityToken::DeleteKeyfile (keyfile);
+ SecurityToken::DeleteKeyfile (dynamic_cast<SecurityTokenKeyfile&>(*keyfile.get()));
}
- keyfiles = SecurityToken::GetAvailableKeyfiles();
+ keyfiles = Token::GetAvailableKeyfiles(ActivateEMVOption);
SecurityTokenKeyfileDlgFillList (hwndDlg, keyfiles);
}
catch (Exception &e)
diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h
index 362b2d6d..2004eb2a 100644
--- a/src/Common/Dlgcode.h
+++ b/src/Common/Dlgcode.h
@@ -166,6 +166,7 @@ extern BOOL LastMountedVolumeDirty;
extern BOOL MountVolumesAsSystemFavorite;
extern BOOL FavoriteMountOnArrivalInProgress;
extern BOOL MultipleMountOperationInProgress;
+extern BOOL ActivateEMVOption;
extern volatile BOOL NeedPeriodicDeviceListUpdate;
extern BOOL DisablePeriodicDeviceListUpdate;
diff --git a/src/Common/EMVToken.cpp b/src/Common/EMVToken.cpp
new file mode 100644
index 00000000..aac59a6a
--- /dev/null
+++ b/src/Common/EMVToken.cpp
@@ -0,0 +1,121 @@
+#include "EMVToken.h"
+
+#include "Platform/Finally.h"
+#include "Platform/ForEach.h"
+#include <vector>
+#include <iostream>
+
+
+
+#if !defined(TC_WINDOWS) || defined(TC_PROTOTYPE)
+#include "Platform/SerializerFactory.h"
+#include "Platform/StringConverter.h"
+#include "Platform/SystemException.h"
+#else
+#include "Dictionary.h"
+#include "Language.h"
+#endif
+
+
+using namespace std;
+
+namespace VeraCrypt
+{
+
+ IccDataExtractor EMVToken::extractor;
+
+ EMVTokenInfo::~EMVTokenInfo()
+ {
+ burn(&Label,Label.size());
+ }
+
+ EMVTokenKeyfile::EMVTokenKeyfile(const TokenKeyfilePath& path)
+ {
+ Id = EMV_CARDS_LABEL;
+ Token = shared_ptr<EMVTokenInfo>(new EMVTokenInfo());
+ wstring pathStr = path;
+ unsigned long slotId;
+
+ if (swscanf(pathStr.c_str(), TC_EMV_TOKEN_KEYFILE_URL_PREFIX TC_EMV_TOKEN_KEYFILE_URL_SLOT L"/%lu", &slotId) != 1)
+ throw InvalidEMVPath();
+
+ Token->SlotId = slotId;
+ }
+
+ EMVTokenKeyfile::operator TokenKeyfilePath () const
+ {
+ wstringstream path;
+ path << TC_EMV_TOKEN_KEYFILE_URL_PREFIX TC_EMV_TOKEN_KEYFILE_URL_SLOT L"/" << Token->SlotId;
+ return path.str();
+ }
+
+ void EMVTokenKeyfile::GetKeyfileData(vector <byte>& keyfileData) const
+ {
+ #ifdef TC_WINDOWS
+ EMVToken::extractor.InitLibrary();
+ #endif
+
+ EMVToken::extractor.GetReaders();
+ EMVToken::extractor.GettingAllCerts(Token->SlotId, keyfileData);
+ }
+
+ bool EMVToken::IsKeyfilePathValid(const wstring& emvTokenKeyfilePath)
+ {
+ return emvTokenKeyfilePath.find(TC_EMV_TOKEN_KEYFILE_URL_PREFIX) == 0;
+ }
+
+ vector<EMVTokenKeyfile> EMVToken::GetAvailableKeyfiles(unsigned long int* slotIdFilter, const wstring keyfileIdFilter) {
+ #ifdef TC_WINDOWS
+ EMVToken::extractor.InitLibrary();
+ #endif
+
+ vector <EMVTokenKeyfile> keyfiles;
+ unsigned long int nb = 0;
+
+ nb = EMVToken::extractor.GetReaders();
+
+
+ for(unsigned long int slotId = 0; slotId<nb; slotId++)
+ {
+ EMVTokenInfo token;
+
+ if (slotIdFilter && *slotIdFilter != slotId)
+ continue;
+
+ try{
+ token = GetTokenInfo(slotId);
+ } catch(EMVUnknownCardType) {
+ continue;
+ }catch(PCSCException){
+
+ continue;
+ }
+
+ EMVTokenKeyfile keyfile;
+ keyfile.Token->SlotId = slotId;
+ keyfile.Token = shared_ptr<TokenInfo>(new EMVTokenInfo(token));
+
+ keyfiles.push_back(keyfile);
+
+ if (!keyfileIdFilter.empty())
+ break;
+ }
+
+ return keyfiles;
+
+ }
+
+
+ EMVTokenInfo EMVToken::GetTokenInfo(unsigned long int slotId) {
+ EMVTokenInfo token;
+ token.SlotId = slotId;
+ //card numbers extraction
+ std::string pan;
+ EMVToken::extractor.GettingPAN(slotId, pan);
+ token.Label = L"EMV card **** ";
+ token.Label += wstring (pan.begin(), pan.end());
+ burn(&pan[0],pan.size());
+ return token;
+ }
+
+}
diff --git a/src/Common/EMVToken.h b/src/Common/EMVToken.h
new file mode 100644
index 00000000..1d84ec28
--- /dev/null
+++ b/src/Common/EMVToken.h
@@ -0,0 +1,50 @@
+#ifndef TC_HEADER_Common_EMVToken
+#define TC_HEADER_Common_EMVToken
+
+#define TC_EMV_TOKEN_KEYFILE_URL_PREFIX L"emv://"
+#define TC_EMV_TOKEN_KEYFILE_URL_SLOT L"slot"
+
+#define EMV_CARDS_LABEL L"EMV Certificates"
+
+#include "Platform/PlatformBase.h"
+#if defined (TC_WINDOWS) && !defined (TC_PROTOTYPE)
+# include "Exception.h"
+#else
+# include "Platform/Exception.h"
+#endif
+
+#include "Token.h"
+#include "IccDataExtractor.h"
+
+namespace VeraCrypt {
+
+ struct EMVTokenInfo: TokenInfo
+ {
+ virtual ~EMVTokenInfo();
+ virtual BOOL isEditable() const {return false;}
+ };
+
+ struct EMVTokenKeyfile: TokenKeyfile
+ {
+ EMVTokenKeyfile(){Id = EMV_CARDS_LABEL; Token = shared_ptr<EMVTokenInfo>(new EMVTokenInfo());};
+ EMVTokenKeyfile(const TokenKeyfilePath& path);
+
+ virtual operator TokenKeyfilePath () const;
+ virtual void GetKeyfileData(vector <byte>& keyfileData) const;
+
+ };
+
+ class EMVToken {
+ private:
+ static IccDataExtractor extractor;
+ public:
+ static bool IsKeyfilePathValid(const wstring& emvTokenKeyfilePath);
+ static vector<EMVTokenKeyfile> GetAvailableKeyfiles(unsigned long int* slotIdFilter = nullptr, const wstring keyfileIdFilter = wstring());
+ static EMVTokenInfo GetTokenInfo(unsigned long int slotId);
+
+ friend void EMVTokenKeyfile::GetKeyfileData(vector <byte>& keyfileData) const;
+
+ };
+}
+
+#endif
diff --git a/src/Common/IccDataExtractor.cpp b/src/Common/IccDataExtractor.cpp
new file mode 100644
index 00000000..d98bc360
--- /dev/null
+++ b/src/Common/IccDataExtractor.cpp
@@ -0,0 +1,777 @@
+//
+// Created by bshp on 1/14/23.
+//
+
+#include "IccDataExtractor.h"
+
+#if !defined (TC_WINDOWS) || defined (TC_PROTOTYPE)
+# include "Platform/SerializerFactory.h"
+# include "Platform/StringConverter.h"
+# include "Platform/SystemException.h"
+#else
+# include "Dictionary.h"
+# include "Language.h"
+#endif
+
+#include "Tcdefs.h"
+
+namespace VeraCrypt
+{
+
+
+ #ifdef TC_WINDOWS
+ bool VeraCrypt::IccDataExtractor::Initialized;
+ #endif
+ //using namespace std;
+ const BYTE IccDataExtractor::SELECT_MASTERCARD[] = {00, 0xA4, 0x04, 00, 0x07, 0xA0, 00, 00, 00, 0x04, 0x10, 0x10};
+ const BYTE IccDataExtractor::SELECT_VISA[] = {00, 0xA4, 0x04, 00, 0x07, 0xA0, 00, 00, 00, 0x03, 0x10, 0x10};
+ const BYTE IccDataExtractor::SELECT_AMEX[] = {00, 0xA4, 0x04, 00, 0x07, 0xA0, 00, 00, 00, 00, 0x25, 0x10};
+ const BYTE * IccDataExtractor::SELECT_TYPES[]={SELECT_MASTERCARD, SELECT_VISA, SELECT_AMEX};
+
+ IccDataExtractor::IccDataExtractor(){}
+
+ IccDataExtractor::~IccDataExtractor(){
+ /* Disconnect card if connected */
+ if(hCard){
+ #ifdef TC_WINDOWS
+ WSCardDisconnect(hContext,hCard);
+ #else
+ SCardDisconnect(hContext,hCard);
+ #endif
+ }
+ /* Release memory that has been returned from the resource manager using the SCARD_AUTOALLOCATE length
+ * designator*/
+ if (mszReaders){
+ #ifdef TC_WINDOWS
+ WSCardFreeMemory(hContext, mszReaders);
+ #else
+ SCardFreeMemory(hContext, mszReaders);
+ #endif
+ }
+
+ /* Closing the established resource manager context freeing any resources allocated under that context
+ * including SCARDHANDLE objects and memory allocated using the SCARD_AUTOALLOCATE length designator*/
+ if(hContext){
+ #ifdef TC_WINDOWS
+ WSCardReleaseContext(hContext);
+ #else
+ SCardReleaseContext(hContext);
+ #endif
+ }
+
+ /* Freeing winscard library */
+ #ifdef TC_WINDOWS
+ FreeLibrary(WinscardLibraryHandle);
+ #endif
+ }
+
+ #ifdef TC_WINDOWS
+ void IccDataExtractor::InitLibrary(){
+
+ if(Initialized) return;
+
+ /* Getting the System32 directory */
+ char sysDir[MAX_PATH-20];
+ GetSystemDirectoryA(sysDir, MAX_PATH);
+
+ /* Getting the winscard dll path directory */
+ char winscardPath[MAX_PATH];
+ sprintf_s(winscardPath, "%s\\Winscard.dll", sysDir);
+
+ /* Loading the winscard dll from System32 */
+ WinscardLibraryHandle = LoadLibraryA(winscardPath);
+ throw_sys_if(!WinscardLibraryHandle);
+
+ /* Fetching the functions pointers from the dll */
+ WSCardEstablishContext = (SCardEstablishContextPtr) GetProcAddress(WinscardLibraryHandle,"SCardEstablishContext");
+ if(!WSCardEstablishContext) throw WinscardLibraryNotInitialized();
+
+ WSCardReleaseContext= (SCardReleaseContextPtr) GetProcAddress(WinscardLibraryHandle,"SCardReleaseContext");
+ if(!WSCardReleaseContext) throw WinscardLibraryNotInitialized();
+
+ WSCardConnectA = (SCardConnectAPtr) GetProcAddress(WinscardLibraryHandle,"SCardConnectA");
+ if(!WSCardConnectA) throw WinscardLibraryNotInitialized();
+
+ WSCardDisconnect = (SCardDisconnectPtr) GetProcAddress(WinscardLibraryHandle,"SCardDisconnect");
+ if(!WSCardDisconnect) throw WinscardLibraryNotInitialized();
+
+ WSCardFreeMemory = ( SCardFreeMemoryPtr) GetProcAddress(WinscardLibraryHandle,"SCardFreeMemory");
+ if(!WSCardFreeMemory) throw WinscardLibraryNotInitialized();
+
+ WSCardListReadersA = (SCardListReadersAPtr) GetProcAddress(WinscardLibraryHandle,"SCardListReadersA");
+ if(!WSCardListReadersA) throw WinscardLibraryNotInitialized();
+
+ WSCardTransmit = ( SCardTransmitPtr) GetProcAddress(WinscardLibraryHandle,"SCardTransmit");
+ if(!WSCardTransmit) throw WinscardLibraryNotInitialized();
+
+ Initialized = true;
+
+ }
+ #endif
+
+ /* Establishing the resource manager context (the scope) within which database operations are performed.
+ * The module of the smart card subsystem that manages access to multiple readers and smart cards. The
+ * resource manager identifies and tracks resources, allocates readers and resources across multiple
+ * applications,and supports transaction primitives for accessing services available on a given card.*/
+ int IccDataExtractor::EstablishRSContext(){
+
+ #ifdef TC_WINDOWS
+ LONG returnValue = WSCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+ #else
+ LONG returnValue = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+ #endif
+
+ /* Check if the establishment of the context was unsuccessful */
+ if (returnValue != SCARD_S_SUCCESS)
+ throw PCSCException(returnValue);
+
+ return EXIT_SUCCESS;
+ }
+
+ /* Detecting available readers and filling the reader table */
+ unsigned long IccDataExtractor::GetReaders(){
+
+ #ifdef TC_WINDOWS
+ if(!Initialized)
+ throw WinscardLibraryNotInitialized();
+ #endif
+
+ EstablishRSContext();
+
+ /* Length of the mszReaders buffer in characters. If the buffer length is specified as
+ * SCARD_AUTOALLOCATE, then mszReaders is converted to a pointer to a byte pointer, and
+ * receives the address of a block of memory containing the multi-string structure */
+ DWORD dwReaders = SCARD_AUTOALLOCATE;
+
+ /* Retrieving the available readers list and putting it in mszReaders*/ // Use LPSTR on linux
+ #ifdef TC_WINDOWS
+ LONG returnValue = WSCardListReadersA(hContext, NULL, (LPSTR)&mszReaders, &dwReaders);
+ #else
+ LONG returnValue = SCardListReaders(hContext, NULL, (LPTSTR)&mszReaders, &dwReaders);
+ #endif
+
+ /* If the is no readers, return */
+ if(returnValue == SCARD_E_NO_READERS_AVAILABLE) return 0;
+
+ /* Check if the listing of the connected readers was unsuccessful */
+ if (returnValue != SCARD_S_SUCCESS)
+ throw PCSCException(returnValue);
+
+ nbReaders = 0;
+ LPSTR ReaderPtr = mszReaders;
+
+ /* Getting the total number of readers */
+ while (*ReaderPtr != '\0')
+ {
+ readers.push_back(ReaderPtr);
+ ReaderPtr += strlen((char*)ReaderPtr) + 1;
+ nbReaders++;
+ }
+
+ return nbReaders;
+ }
+
+ /* Connecting to the card in the given reader*/
+ int IccDataExtractor::ConnectCard(unsigned long int reader_nb){
+
+ /* Check if the given reader slot number is possible */
+ if (reader_nb < 0 || reader_nb >= nbReaders)
+ throw InvalidEMVPath();
+
+ dwActiveProtocol = SCARD_PROTOCOL_UNDEFINED;
+
+ #ifdef TC_WINDOWS
+ LONG returnValue = WSCardConnectA(hContext, readers[reader_nb], SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
+ #else
+ LONG returnValue = SCardConnect(hContext, readers[reader_nb], SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
+ #endif
+
+ /* Check is the card connection was unsuccessful */
+ if (returnValue != SCARD_S_SUCCESS)
+ throw PCSCException(returnValue);
+
+ return EXIT_SUCCESS;
+ }
+
+ /* Disconnect the card currently connected*/
+ int IccDataExtractor::DisconnectCard(){
+ #ifdef TC_WINDOWS
+ LONG returnValue = WSCardDisconnect(hCard, SCARD_UNPOWER_CARD);
+ #else
+ LONG returnValue = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);
+ #endif
+
+ /* Check is the card deconnection was unsuccessful */
+ if (returnValue != SCARD_S_SUCCESS)
+ throw PCSCException(returnValue);
+
+ return EXIT_SUCCESS;
+ }
+
+ /* Testing if the card contains the application of the given EMV type (0:Mastercard, 1:Visa, 2:Amex) */
+ bool IccDataExtractor::TestingCardType(const int SELECT_TYPE_NUMBER){
+
+ const BYTE * SELECTED_TYPE = SELECT_TYPES[SELECT_TYPE_NUMBER];
+
+ BYTE pbRecvBuffer[64]; /* Buffer to receive the card response */
+
+ DWORD dwSendLength = SELECT_TYPE_SIZE; /* Set the size of the send buffer */
+ DWORD dwRecvLength = sizeof(pbRecvBuffer); /* Set the size of the reception buffer */
+
+ /* Set up the io request */
+ SCARD_IO_REQUEST ioRequest;
+ ioRequest.dwProtocol = dwActiveProtocol;
+ ioRequest.cbPciLength = sizeof(ioRequest);
+
+ #ifdef TC_WINDOWS
+ LONG returnValue = WSCardTransmit(hCard, &ioRequest, SELECTED_TYPE, dwSendLength, NULL, pbRecvBuffer, &dwRecvLength);
+ #else
+ LONG returnValue = SCardTransmit(hCard, &ioRequest, SELECTED_TYPE, dwSendLength, NULL, pbRecvBuffer, &dwRecvLength);
+ #endif
+
+ /* Check if the transmission was unsuccessful */
+ if (returnValue != SCARD_S_SUCCESS)
+ throw PCSCException(returnValue);
+
+ /* It received a response. Check if it didn't get a recognisable response */
+ if (dwRecvLength < 2)
+ return false;
+
+ /* Check if the command successfully executed (the card is the type passed in the parameter) */
+ if (pbRecvBuffer[0] == 0x61)
+ return true;
+
+ return false;
+ }
+
+ /* Getting the ICC Public Key Certificates and the Issuer Public Key Certificates by parsing the application
+ * (!NEED TO TEST CARD TYPE TO SELECT APPLICATION FIRST!)*/
+ void IccDataExtractor::GetCerts(vector<byte> &CERTS){
+
+ CERTS.clear();
+
+ bool iccFound= false;
+ bool issuerFound= false;
+
+ shared_ptr<TLVNode> node;
+ shared_ptr<TLVNode> ICC_Public_Key_Certificate;
+ shared_ptr<TLVNode> Issuer_PK_Certificate;
+
+ BYTE pbRecvBuffer[64]; /* Buffer to receive the card response */
+ BYTE pbRecvBufferFat[256]; /* Bigger buffer to receive the card response */
+
+ DWORD dwSendLength; /* Size of the send buffer */
+ DWORD dwRecvLength; /* Size of the reception buffer */
+
+ /* Set up the io request */
+ SCARD_IO_REQUEST ioRequest;
+ ioRequest.dwProtocol = dwActiveProtocol;
+ ioRequest.cbPciLength = sizeof(ioRequest);
+
+ LONG returnValue;
+
+ /* Parsing root folders */
+ for (int sfi = 0; sfi < 32; sfi++)
+ {
+ /* Parsing sub folders */
+ for (int rec = 0; rec < 17; rec++)
+ {
+ BYTE SELECT_APDU_FILE[] = {00, 0xB2, static_cast<unsigned char>(rec), static_cast<unsigned char>((sfi << 3) | 4), 0x00};
+
+ dwSendLength = sizeof(SELECT_APDU_FILE);
+ dwRecvLength = sizeof(pbRecvBuffer);
+
+ /* Check if there is data in the folder */
+ #ifdef TC_WINDOWS
+ returnValue = WSCardTransmit(hCard, &ioRequest, SELECT_APDU_FILE, dwSendLength,NULL, pbRecvBuffer, &dwRecvLength);
+ #else
+ returnValue = SCardTransmit(hCard, &ioRequest, SELECT_APDU_FILE, dwSendLength,NULL, pbRecvBuffer, &dwRecvLength);
+ #endif
+
+ /* Check if the transmission was unsuccessful */
+ if (returnValue != SCARD_S_SUCCESS)
+ throw PCSCException(returnValue);
+
+ /* There is no data in the folder */
+ if (pbRecvBuffer[0] != 0x6C)
+ continue;
+
+ /* It set the proper expected length of the data in the APDU */
+ SELECT_APDU_FILE[4] = pbRecvBuffer[1];
+
+ dwRecvLength = sizeof(pbRecvBufferFat);
+
+ /* Get the data from the folder */
+ #ifdef TC_WINDOWS
+ returnValue = WSCardTransmit(hCard, &ioRequest, SELECT_APDU_FILE, dwSendLength, NULL, pbRecvBufferFat, &dwRecvLength);
+ #else
+ returnValue = SCardTransmit(hCard, &ioRequest, SELECT_APDU_FILE, dwSendLength, NULL, pbRecvBufferFat, &dwRecvLength);
+ #endif
+
+ /* Check if the transmission was unsuccessful */
+ if (returnValue != SCARD_S_SUCCESS)
+ throw PCSCException(returnValue);
+
+ /* It received a response. Check if it didn't get a recognisable response */
+ if (dwRecvLength < 2)
+ continue;
+
+ /* Parsing the TLV */
+ try{
+ node = TLVParser::TLV_Parse(pbRecvBufferFat,sizeof(pbRecvBufferFat));
+ }catch(TLVException){
+ continue;
+ }
+
+ /* Finding the ICC_Public_Key_Certificate */
+ try{
+ ICC_Public_Key_Certificate = TLVParser::TLV_Find(node, 0x9F46);
+ }catch(TLVException){
+ continue;
+ }
+ if(ICC_Public_Key_Certificate) {
+ iccFound=true;
+ for (int i = 0; i < ICC_Public_Key_Certificate->Length;i++) {
+ CERTS.push_back(static_cast<byte>(ICC_Public_Key_Certificate->Value[i]));
+ }
+ }
+
+ /* Finding the Issuer_Public_Key_Certificate */
+ try{
+ Issuer_PK_Certificate = TLVParser::TLV_Find(node, 0x90);
+ }catch(TLVException){
+ continue;
+ }
+
+ if(Issuer_PK_Certificate) {
+ issuerFound=true;
+ for (int i = 0; i < Issuer_PK_Certificate->Length;i++) {
+ CERTS.push_back(static_cast<byte>(Issuer_PK_Certificate->Value[i]));
+ }
+ }
+
+ /* Limiting the search to at least one occurrence of both PKs to speed up the process.
+ * There might be more certificates tho */
+ if(iccFound && issuerFound){
+ burn(pbRecvBuffer, sizeof(pbRecvBuffer));
+ burn(pbRecvBufferFat, sizeof(pbRecvBufferFat));
+ return;
+ }
+ }
+ }
+ burn(pbRecvBuffer, sizeof(pbRecvBuffer));
+ burn(pbRecvBufferFat, sizeof(pbRecvBufferFat));
+ throw EMVKeyfileDataNotFound();
+ }
+
+ /* Getting CPCL data from the card*/
+ void IccDataExtractor::GetCPCL(vector<byte> &v){
+
+ BYTE SELECT_APDU_CPCL[] = {0x80,0xCA, 0x9F, 0x7F, 0x00};
+
+ BYTE pbRecvBuffer[64]; /* Buffer to receive the card response */
+ BYTE pbRecvBufferFat[256]; /* Bigger buffer to receive the card response */
+
+ DWORD dwSendLength = sizeof (SELECT_APDU_CPCL); /* Set the size of the send buffer */
+ DWORD dwRecvLength = sizeof(pbRecvBuffer); /* Set the size of the reception buffer */
+
+ /* Set up the io request */
+ SCARD_IO_REQUEST ioRequest;
+ ioRequest.dwProtocol = dwActiveProtocol;
+ ioRequest.cbPciLength = sizeof(ioRequest);
+
+ /* Check if there is the TAG for CPCL Data in the card */
+ #ifdef TC_WINDOWS
+ LONG returnValue = WSCardTransmit(hCard, &ioRequest, SELECT_APDU_CPCL, dwSendLength, NULL, pbRecvBuffer, &dwRecvLength);
+ #else
+ LONG returnValue = SCardTransmit(hCard, &ioRequest, SELECT_APDU_CPCL, dwSendLength, NULL, pbRecvBuffer, &dwRecvLength);
+ #endif
+
+ /* Check if the transmission was unsuccessful */
+ if (returnValue != SCARD_S_SUCCESS)
+ throw PCSCException(returnValue);
+
+ /* Not the correct APDU response code */
+ if (pbRecvBuffer[0] != 0x6C)
+ throw EMVKeyfileDataNotFound();
+
+ /* It set the proper expected length of the data in the APDU */
+ SELECT_APDU_CPCL[4] = pbRecvBuffer[1];
+
+ dwRecvLength = sizeof(pbRecvBufferFat);
+
+ /* Get the CPCL data */
+ #ifdef TC_WINDOWS
+ returnValue = WSCardTransmit(hCard, &ioRequest, SELECT_APDU_CPCL, dwSendLength,NULL, pbRecvBufferFat, &dwRecvLength);
+ #else
+ returnValue = SCardTransmit(hCard, &ioRequest, SELECT_APDU_CPCL, dwSendLength,NULL, pbRecvBufferFat, &dwRecvLength);
+ #endif
+
+ /* Check if the transmission was unsuccessful */
+ if (returnValue != SCARD_S_SUCCESS)
+ throw PCSCException(returnValue);
+
+ /* It received a response. Check if it didn't get a recognisable response */
+ if (dwRecvLength < 2)
+ throw EMVKeyfileDataNotFound();
+
+ /* We add CPCL data and crop the TAG and the data length at the start and the trailer at the end */
+ for (unsigned long i = 3; i < dwRecvLength-2; i++) {
+ v.push_back(static_cast<byte>(pbRecvBufferFat[i]));
+ }
+ burn(pbRecvBuffer, sizeof(pbRecvBuffer));
+ burn(pbRecvBufferFat, sizeof(pbRecvBufferFat));
+
+ }
+
+ /* Getting an ICC Public Key Certificates and an Issuer Public Key Certificates for the first application with the cpcl
+ * data present on the card and finally merge it into one byte array */
+ void IccDataExtractor::GettingAllCerts(int readerNumber, vector<byte> &v){
+
+ #ifdef TC_WINDOWS
+ if(!Initialized)
+ throw WinscardLibraryNotInitialized();
+ #endif
+
+ bool isEMV= false;
+
+ ConnectCard(readerNumber);
+
+ /* Test all the type of applications and get the certificates from the first one found */
+ for(int i=0;i<sizeof(SELECT_TYPES)/sizeof(SELECT_TYPES[0]); i++){
+
+ /* The card does not contain this application (0:Mastercard, 1:Visa, 2:Amex) */
+ if(!TestingCardType(i)) continue;
+ isEMV= true;
+ GetCerts(v);
+ break;
+ }
+
+ /* Need to disconnect reconnect the card to access CPLC data (not located in any application) */
+ DisconnectCard();
+
+ /* Check if the card is not an EMV one */
+ if(!isEMV)
+ throw EMVUnknownCardType();
+
+ ConnectCard(readerNumber);
+
+ GetCPCL(v);
+
+ DisconnectCard();
+ }
+
+ /* Getting the PAN by parsing the application
+ * (!NEED TO TEST CARD TYPE TO SELECT APPLICATION FIRST!)*/
+ void IccDataExtractor::GetPAN(vector<byte> &v) {
+
+ bool PANFound= false;
+ shared_ptr<TLVNode> node;
+ shared_ptr<TLVNode> PAN;
+
+ BYTE pbRecvBuffer[64]; /* Buffer to receive the card response */
+ BYTE pbRecvBufferFat[256]; /* Bigger buffer to receive the card response */
+
+ DWORD dwSendLength; /* Size of the send buffer */
+ DWORD dwRecvLength; /* Size of the reception buffer */
+
+ /* Set up the io request */
+ SCARD_IO_REQUEST ioRequest;
+ ioRequest.dwProtocol = dwActiveProtocol;
+ ioRequest.cbPciLength = sizeof(ioRequest);
+
+ LONG returnValue;
+
+ /* Parsing root folders */
+ for (int sfi = 0; sfi < 32; sfi++)
+ {
+ /* Parsing sub folders */
+ for (int rec = 0; rec < 17; rec++)
+ {
+ BYTE SELECT_APDU_FILE[] = {00, 0xB2, static_cast<unsigned char>(rec), static_cast<unsigned char>((sfi << 3) | 4), 0x00};
+
+ dwSendLength = sizeof(SELECT_APDU_FILE);
+ dwRecvLength = sizeof(pbRecvBuffer);
+
+ /* Check if there is data in the folder */
+ #ifdef TC_WINDOWS
+ returnValue = WSCardTransmit(hCard, &ioRequest, SELECT_APDU_FILE, dwSendLength,NULL, pbRecvBuffer, &dwRecvLength);
+ #else
+ returnValue = SCardTransmit(hCard, &ioRequest, SELECT_APDU_FILE, dwSendLength,NULL, pbRecvBuffer, &dwRecvLength);
+ #endif
+
+ /* Check if the transmission was unsuccessful */
+ if (returnValue != SCARD_S_SUCCESS)
+ throw PCSCException(returnValue);
+
+ /* There is no data in the folder */
+ if (pbRecvBuffer[0] != 0x6C)
+ continue;
+
+ /* It set the proper expected length of the data in the APDU */
+ SELECT_APDU_FILE[4] = pbRecvBuffer[1];
+
+ dwRecvLength = sizeof(pbRecvBufferFat);
+
+ /* Get the data from the folder */
+ #ifdef TC_WINDOWS
+ returnValue = WSCardTransmit(hCard, &ioRequest, SELECT_APDU_FILE, dwSendLength,NULL, pbRecvBufferFat, &dwRecvLength);
+ #else
+ returnValue = SCardTransmit(hCard, &ioRequest, SELECT_APDU_FILE, dwSendLength,NULL, pbRecvBufferFat, &dwRecvLength);
+ #endif
+
+ /* Check if the transmission was unsuccessful */
+ if (returnValue != SCARD_S_SUCCESS)
+ throw PCSCException(returnValue);
+
+ /* It received a response. Check if it didn't get a recognisable response */
+ if (dwRecvLength < 2)
+ continue;
+
+ /* Parsing the TLV */
+ try{
+ node = TLVParser::TLV_Parse(pbRecvBufferFat,sizeof(pbRecvBufferFat));
+ }catch(TLVException){
+ continue;
+ }
+
+ /* Finding the PAN */
+ try{
+ PAN = TLVParser::TLV_Find(node, 0x5A);
+ }catch(TLVException){
+ continue;
+ }
+ if(PAN) {
+ PANFound=true;
+ if (PAN->Length >= 8){
+ for (int i = 6; i < 8;i++) {
+ v.push_back(static_cast<byte>(PAN->Value[i]));
+ }
+ }
+ }
+
+ if(PANFound){
+ burn(pbRecvBuffer, sizeof(pbRecvBuffer));
+ burn(pbRecvBufferFat, sizeof(pbRecvBufferFat));
+ return ;
+ }
+ }
+ }
+ burn(pbRecvBuffer, sizeof(pbRecvBuffer));
+ burn(pbRecvBufferFat, sizeof(pbRecvBufferFat));
+ throw EMVPANNotFound();
+ }
+
+ /* Helper function to transform the PAN received (vector of byte) to a string */
+ template<typename TInputIter>
+ void IccDataExtractor::make_hex_string(TInputIter first, TInputIter last, string& returnValue, bool use_uppercase, bool insert_spaces) {
+ ostringstream ss;
+ ss << hex << std::setfill('0');
+ if (use_uppercase)
+ ss << uppercase;
+ while (first != last)
+ {
+ ss << setw(2) << static_cast<int>(*first++);
+ if (insert_spaces && first != last)
+ ss << " ";
+ }
+
+ returnValue = ss.str();
+ }
+
+ /* Wrapper function to get the PAN of the card*/
+ void IccDataExtractor::GettingPAN(int readerNumber, string& panString) {
+
+ #ifdef TC_WINDOWS
+ if(!Initialized)
+ throw WinscardLibraryNotInitialized();
+ #endif
+
+ vector<byte> PAN;
+
+ bool isEMV= false;
+
+ ConnectCard(readerNumber);
+
+ /* Test all the type of applications and get the PAN from the first one found */
+ for(int i=0;i<sizeof(SELECT_TYPES)/sizeof(SELECT_TYPES[0]); i++){
+
+ /* The card does not contain this application (0:Mastercard, 1:Visa, 2:Amex) */
+ if(!TestingCardType(i)) continue;
+ isEMV=true;
+ GetPAN(PAN);
+ break;
+ }
+
+ DisconnectCard();
+
+ /* Check if the card is not an EMV one */
+ if(!isEMV)
+ throw EMVUnknownCardType();
+
+ make_hex_string(PAN.begin(),PAN.end(),panString);
+
+ burn(&PAN.front(),PAN.size());
+ }
+
+ PCSCException::operator string() const{
+ if (ErrorCode == SCARD_S_SUCCESS)
+ return string();
+
+ static const struct{
+ LONG ErrorCode;
+ const char* ErrorString;
+ } ErrorStrings[] = {
+ #define SC_ERR(CODE) { CODE, #CODE },
+#ifdef TC_WINDOWS
+ SC_ERR(ERROR_BROKEN_PIPE)
+ SC_ERR(SCARD_E_NO_PIN_CACHE)
+ SC_ERR(SCARD_E_PIN_CACHE_EXPIRED)
+ SC_ERR(SCARD_E_READ_ONLY_CARD)
+ SC_ERR(SCARD_W_CACHE_ITEM_NOT_FOUND)
+ SC_ERR(SCARD_W_CACHE_ITEM_STALE)
+ SC_ERR(SCARD_W_CACHE_ITEM_TOO_BIG)
+#endif
+ SC_ERR(SCARD_E_BAD_SEEK)
+ SC_ERR(SCARD_E_CANCELLED)
+ SC_ERR(SCARD_E_CANT_DISPOSE)
+ SC_ERR(SCARD_E_CARD_UNSUPPORTED)
+ SC_ERR(SCARD_E_CERTIFICATE_UNAVAILABLE)
+ SC_ERR(SCARD_E_COMM_DATA_LOST)
+ SC_ERR(SCARD_E_COMM_DATA_LOST)
+ SC_ERR(SCARD_E_DIR_NOT_FOUND)
+ SC_ERR(SCARD_E_DUPLICATE_READER)
+ SC_ERR(SCARD_E_FILE_NOT_FOUND)
+ SC_ERR(SCARD_E_ICC_CREATEORDER)
+ SC_ERR(SCARD_E_ICC_INSTALLATION)
+ SC_ERR(SCARD_E_INSUFFICIENT_BUFFER)
+ SC_ERR(SCARD_E_INVALID_ATR)
+ SC_ERR(SCARD_E_INVALID_CHV)
+ SC_ERR(SCARD_E_INVALID_HANDLE)
+ SC_ERR(SCARD_E_INVALID_PARAMETER)
+ SC_ERR(SCARD_E_INVALID_TARGET)
+ SC_ERR(SCARD_E_INVALID_VALUE)
+ SC_ERR(SCARD_E_NO_ACCESS)
+ SC_ERR(SCARD_E_NO_DIR)
+ SC_ERR(SCARD_E_NO_FILE)
+ SC_ERR(SCARD_E_NO_KEY_CONTAINER)
+ SC_ERR(SCARD_E_NO_MEMORY)
+ SC_ERR(SCARD_E_NO_READERS_AVAILABLE)
+ SC_ERR(SCARD_E_NO_SERVICE)
+ SC_ERR(SCARD_E_NO_SMARTCARD)
+ SC_ERR(SCARD_E_NO_SUCH_CERTIFICATE)
+ SC_ERR(SCARD_E_NOT_READY)
+ SC_ERR(SCARD_E_NOT_TRANSACTED)
+ SC_ERR(SCARD_E_PCI_TOO_SMALL)
+ SC_ERR(SCARD_E_PROTO_MISMATCH)
+ SC_ERR(SCARD_E_READER_UNAVAILABLE)
+ SC_ERR(SCARD_E_READER_UNSUPPORTED)
+ SC_ERR(SCARD_E_SERVER_TOO_BUSY)
+ SC_ERR(SCARD_E_SERVICE_STOPPED)
+ SC_ERR(SCARD_E_SHARING_VIOLATION)
+ SC_ERR(SCARD_E_SYSTEM_CANCELLED)
+ SC_ERR(SCARD_E_TIMEOUT)
+ SC_ERR(SCARD_E_UNEXPECTED)
+ SC_ERR(SCARD_E_UNKNOWN_CARD)
+ SC_ERR(SCARD_E_UNKNOWN_READER)
+ SC_ERR(SCARD_E_UNKNOWN_RES_MNG)
+ SC_ERR(SCARD_E_UNSUPPORTED_FEATURE)
+ SC_ERR(SCARD_E_WRITE_TOO_MANY)
+ SC_ERR(SCARD_F_COMM_ERROR)
+ SC_ERR(SCARD_F_INTERNAL_ERROR)
+ SC_ERR(SCARD_F_UNKNOWN_ERROR)
+ SC_ERR(SCARD_W_CANCELLED_BY_USER)
+ SC_ERR(SCARD_W_CARD_NOT_AUTHENTICATED)
+ SC_ERR(SCARD_W_CHV_BLOCKED)
+ SC_ERR(SCARD_W_EOF)
+ SC_ERR(SCARD_W_REMOVED_CARD)
+ SC_ERR(SCARD_W_RESET_CARD)
+ SC_ERR(SCARD_W_SECURITY_VIOLATION)
+ SC_ERR(SCARD_W_UNPOWERED_CARD)
+ SC_ERR(SCARD_W_UNRESPONSIVE_CARD)
+ SC_ERR(SCARD_W_UNSUPPORTED_CARD)
+ SC_ERR(SCARD_W_WRONG_CHV)
+#undef SC_ERR
+ };
+
+ for (size_t i = 0; i < array_capacity(ErrorStrings); ++i)
+ {
+ if (ErrorStrings[i].ErrorCode == ErrorCode)
+ return ErrorStrings[i].ErrorString;
+ }
+
+ stringstream s;
+ s << "0x" << ErrorCode;
+ return s.str();
+ }
+
+ #ifdef TC_HEADER_Common_Exception
+ void PCSCException::Show(HWND parent) const
+ {
+ string errorString = string(*this);
+
+ if (!errorString.empty())
+ {
+ wstringstream subjectErrorCode;
+ if (SubjectErrorCodeValid)
+ subjectErrorCode << L": " << SubjectErrorCode;
+
+ if (!GetDictionaryValue(errorString.c_str()))
+ {
+ if (errorString.find("SCARD_E_") == 0 || errorString.find("SCARD_F_") == 0 || errorString.find("SCARD_W_") == 0)
+ {
+ errorString = errorString.substr(8);
+ for (size_t i = 0; i < errorString.size(); ++i)
+ {
+ if (errorString[i] == '_')
+ errorString[i] = ' ';
+ }
+ }
+ wchar_t err[8192];
+ StringCbPrintfW(err, sizeof(err), L"%s:\n\n%hs%s", GetString("PCSC_ERROR"), errorString.c_str(), subjectErrorCode.str().c_str());
+ ErrorDirect(err, parent);
+ }
+ else
+ {
+ wstring err = GetString(errorString.c_str());
+
+ if (SubjectErrorCodeValid)
+ err += L"\n\nError code" + subjectErrorCode.str();
+
+ ErrorDirect(err.c_str(), parent);
+ }
+ }
+ }
+ #endif // TC_HEADER_Common_Exception
+
+#ifdef TC_HEADER_Platform_Exception
+
+ void PCSCException::Deserialize(shared_ptr <Stream> stream)
+ {
+ Exception::Deserialize(stream);
+ Serializer sr(stream);
+ uint64 code;
+ sr.Deserialize("ErrorCode", code);
+ sr.Deserialize("SubjectErrorCodeValid", SubjectErrorCodeValid);
+ sr.Deserialize("SubjectErrorCode", SubjectErrorCode);
+ ErrorCode = (LONG)code;
+ }
+
+ void PCSCException::Serialize(shared_ptr <Stream> stream) const
+ {
+ Exception::Serialize(stream);
+ Serializer sr(stream);
+ sr.Serialize("ErrorCode", (uint64)ErrorCode);
+ sr.Serialize("SubjectErrorCodeValid", SubjectErrorCodeValid);
+ sr.Serialize("SubjectErrorCode", SubjectErrorCode);
+ }
+
+# define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE)
+# undef TC_EXCEPTION_NODECL
+# define TC_EXCEPTION_NODECL(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE)
+
+ TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET(PCSCTokenException);
+
+#endif
+
+} \ No newline at end of file
diff --git a/src/Common/IccDataExtractor.h b/src/Common/IccDataExtractor.h
new file mode 100644
index 00000000..777a3555
--- /dev/null
+++ b/src/Common/IccDataExtractor.h
@@ -0,0 +1,231 @@
+//
+// Created by bshp on 1/14/23.
+//
+
+#ifndef NEWEMV_ICCDATAEXTRACTOR_H
+#define NEWEMV_ICCDATAEXTRACTOR_H
+
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sstream>
+#include <vector>
+#include <iomanip>
+#include <memory>
+#include "Platform/PlatformBase.h"
+#include "TLVParser.h"
+
+#ifdef __linux__
+#include <unistd.h>
+#endif
+
+#if defined (TC_WINDOWS) && !defined (TC_PROTOTYPE)
+# include "Exception.h"
+#else
+# include "Platform/Exception.h"
+#endif
+
+#ifdef TC_WINDOWS
+#include <winscard.h>
+#include <windows.h>
+#endif
+#ifdef TC_UNIX
+#undef BOOL
+#include <PCSC/winscard.h>
+using VeraCrypt::byte;
+#define BOOL int
+//#include <unistd.h> //Works without on windows
+#endif
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#ifdef _WIN64
+#define ssize_t __int64
+#else
+#define ssize_t long
+#endif
+
+#define SELECT_TYPE_SIZE 12 /* Size of the SELECT_TYPE APDU */
+
+/* Winscard function pointers definitions for windows import */
+#ifdef TC_WINDOWS
+typedef LONG (WINAPI *SCardEstablishContextPtr)(DWORD dwScope,LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext);
+typedef LONG (WINAPI *SCardReleaseContextPtr)(SCARDCONTEXT hContext);
+typedef LONG (WINAPI *SCardConnectAPtr)(SCARDCONTEXT hContext,LPCSTR szReader,DWORD dwShareMode,DWORD dwPreferredProtocols,LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol);
+typedef LONG (WINAPI *SCardDisconnectPtr)(SCARDHANDLE hCard, DWORD dwDisposition);
+typedef LONG (WINAPI *SCardTransmitPtr)(SCARDHANDLE hCard,LPCSCARD_IO_REQUEST pioSendPci,const BYTE* pbSendBuffer, DWORD cbSendLength,LPSCARD_IO_REQUEST pioRecvPci,BYTE* pbRecvBuffer, LPDWORD pcbRecvLength);
+typedef LONG (WINAPI *SCardListReadersAPtr)(SCARDCONTEXT hContext,LPCSTR mszGroups,LPSTR mszReaders, LPDWORD pcchReaders);
+typedef LONG (WINAPI *SCardFreeMemoryPtr)(SCARDCONTEXT hContext,LPCVOID pvMem);
+#endif
+
+namespace VeraCrypt
+{
+ class IccDataExtractor {
+ private:
+
+ /* Used for loading winscard on windows */
+ #ifdef TC_WINDOWS
+ /* Winscard Library Handle */
+ HMODULE WinscardLibraryHandle;
+
+ /* Winscard function pointers */
+ SCardEstablishContextPtr WSCardEstablishContext;
+ SCardReleaseContextPtr WSCardReleaseContext;
+ SCardConnectAPtr WSCardConnectA;
+ SCardDisconnectPtr WSCardDisconnect;
+ SCardFreeMemoryPtr WSCardFreeMemory;
+ SCardListReadersAPtr WSCardListReadersA;
+ SCardTransmitPtr WSCardTransmit;
+
+ /* Is the winscard library loaded */
+ static bool Initialized;
+ #endif
+
+ /* SELECT_TYPES FOR DIFFERENT AIDs*/
+ const static BYTE SELECT_MASTERCARD[SELECT_TYPE_SIZE];
+ const static BYTE SELECT_VISA[SELECT_TYPE_SIZE];
+ const static BYTE SELECT_AMEX[SELECT_TYPE_SIZE];
+ const static BYTE * SELECT_TYPES[3];
+
+
+ SCARDCONTEXT hContext; /* Handle that identifies the resource manager context.*/
+
+ SCARDHANDLE hCard; /* A handle that identifies the connection to the smart card in the designated reader*/
+
+ std::vector<char*> readers; /* Card reader list */
+
+ unsigned long int nbReaders; /* Number of connected (available) readers */
+
+ LPSTR mszReaders; /* Names of the reader groups defined to the system, as a multi-string. Use a NULL value to
+ * list all readers in the system */
+
+ DWORD dwActiveProtocol; /* A flag that indicates the established active protocol.
+ * SCARD_PROTOCOL_T0: An asynchronous, character-oriented half-duplex transmission protocol.
+ * SCARD_PROTOCOL_T1: An asynchronous, block-oriented half-duplex transmission protocol.*/
+
+
+ /* Establishing the resource manager context (the scope) within which database operations are performed.
+ * The module of the smart card subsystem that manages access to multiple readers and smart cards. The
+ * resource manager identifies and tracks resources, allocates readers and resources across multiple
+ * applications,and supports transaction primitives for accessing services available on a given card.*/
+ int EstablishRSContext();
+
+ /* Connecting to the card in the given reader*/
+ int ConnectCard(unsigned long int reader_nb);
+
+ /* Disconnect the card currently connected*/
+ int DisconnectCard();
+
+ /* Testing if the card contains the application of the given EMV type */
+ bool TestingCardType(const int SELECT_TYPE_NUMBER);
+
+ /* Getting the ICC Public Key Certificates and the Issuer Public Key Certificates by parsing the application
+ * (!NEED TO TEST CARD TYPE TO SELECT APPLICATION FIRST!)*/
+ void GetCerts(vector<byte> &CERTS);
+
+ /* Getting CPCL data from the card and put it into a reference*/
+ void GetCPCL(vector<byte> &v);
+
+ /* Getting the PAN by parsing the application
+ * (!NEED TO TEST CARD TYPE TO SELECT APPLICATION FIRST!)*/
+ void GetPAN(vector<byte> &v);
+
+ /* Helper function to make a string from plain arrays and various standard containers of bytes */
+ template<typename TInputIter>
+ void make_hex_string(TInputIter first, TInputIter last, std::string& panString, bool use_uppercase = true, bool insert_spaces = false);
+
+ public:
+ IccDataExtractor();
+
+ ~IccDataExtractor();
+
+ /* Used to initialize the winscard library on windows to make sure the dll is in System32 */
+ #ifdef TC_WINDOWS
+ void IccDataExtractor::InitLibrary();
+ #endif
+
+ /* Detecting available readers and filling the reader table. Returns
+ * the number of available readers */
+ unsigned long GetReaders();
+
+
+ /* Getting an ICC Public Key Certificates, an Issuer Public Key Certificates and the CPCL data
+ * from the card designated by the reader number. Appending them into a byte vector */
+ void GettingAllCerts(int readerNumber, vector<byte> &v);
+
+ /* Getting the PAN from the card designated by the reader number */
+ void GettingPAN(int readerNumber, string& panString);
+ };
+
+ struct PCSCException: public Exception
+ {
+ PCSCException(LONG errorCode = (LONG) -1): ErrorCode(errorCode), SubjectErrorCodeValid(false), SubjectErrorCode((uint64)-1){}
+ PCSCException(LONG errorCode, uint64 subjectErrorCode): ErrorCode(errorCode), SubjectErrorCodeValid(true), SubjectErrorCode(subjectErrorCode){}
+
+ #ifdef TC_HEADER_Platform_Exception
+ virtual ~PCSCException() throw () { }
+ TC_SERIALIZABLE_EXCEPTION(PCSCException);
+ #else
+
+ void Show(HWND parent) const;
+ #endif
+
+ operator string () const;
+ LONG GetErrorCode() const { return ErrorCode; }
+
+ protected:
+ LONG ErrorCode;
+ bool SubjectErrorCodeValid;
+ uint64 SubjectErrorCode;
+ };
+
+ #ifdef TC_HEADER_Platform_Exception
+
+ #define TC_EXCEPTION(NAME) TC_EXCEPTION_DECL(NAME,Exception)
+
+ #undef TC_EXCEPTION_SET
+ #define TC_EXCEPTION_SET \
+ TC_EXCEPTION_NODECL (PCSCException); \
+ TC_EXCEPTION (WinscardLibraryNotInitialized); \
+ TC_EXCEPTION (InvalidEMVPath); \
+ TC_EXCEPTION (EMVKeyfileDataNotFound); \
+ TC_EXCEPTION (EMVPANNotFound); \
+ TC_EXCEPTION (EMVUnknownCardType);
+ TC_EXCEPTION_SET;
+
+ #undef TC_EXCEPTION
+
+ #else // !TC_HEADER_Platform_Exception
+
+ struct WinscardLibraryNotInitialized: public Exception
+ {
+ void Show(HWND parent) const { Error("WINSCARD_MODULE_INIT_FAILED", parent); }
+ };
+
+ struct InvalidEMVPath: public Exception
+ {
+ void Show(HWND parent) const { Error("INVALID_EMV_PATH", parent); }
+ };
+
+ struct EMVKeyfileDataNotFound: public Exception
+ {
+ void Show(HWND parent) const { Error("EMV_KEYFILE_DATA_NOT_FOUND", parent); }
+ };
+
+ struct EMVPANNotFound: public Exception
+ {
+ void Show(HWND parent) const { Error("EMV_PAN_NOT_FOUND", parent); }
+ };
+
+ struct EMVUnknownCardType: public Exception
+ {
+ void Show(HWND parent) const { Error("EMV_UNKNOWN_CARD_TYPE", parent); }
+ };
+
+ #endif // !TC_HEADER_Platform_Exception
+}
+
+#endif //NEWEMV_ICCDATAEXTRACTOR_H
diff --git a/src/Common/Keyfiles.c b/src/Common/Keyfiles.c
index 174aed92..d2207f5f 100644
--- a/src/Common/Keyfiles.c
+++ b/src/Common/Keyfiles.c
@@ -23,6 +23,7 @@
#include "Dlgcode.h"
#include "Language.h"
#include "SecurityToken.h"
+#include "EMVToken.h"
#include "Common/resource.h"
#include "Platform/Finally.h"
#include "Platform/ForEach.h"
@@ -249,12 +250,12 @@ BOOL KeyFilesApply (HWND hwndDlg, Password *password, KeyFile *firstKeyFile, con
// Determine whether it's a security token path
try
{
- if (SecurityToken::IsKeyfilePathValid (kf->FileName))
+ if (Token::IsKeyfilePathValid (kf->FileName, ActivateEMVOption))
{
// Apply security token keyfile
vector <byte> keyfileData;
- SecurityTokenKeyfilePath secPath (kf->FileName);
- SecurityToken::GetKeyfileData (SecurityTokenKeyfile (secPath), keyfileData);
+ TokenKeyfilePath secPath (kf->FileName);
+ Token::getTokenKeyfile (secPath)->GetKeyfileData (keyfileData);
if (keyfileData.empty())
{
@@ -551,10 +552,10 @@ BOOL CALLBACK KeyFilesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa
if (lw == IDC_TOKEN_FILES_ADD)
{
- list <SecurityTokenKeyfilePath> selectedTokenKeyfiles;
+ list <TokenKeyfilePath> selectedTokenKeyfiles;
if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_KEYFILES), hwndDlg, (DLGPROC) SecurityTokenKeyfileDlgProc, (LPARAM) &selectedTokenKeyfiles) == IDOK)
{
- foreach (const SecurityTokenKeyfilePath &keyPath, selectedTokenKeyfiles)
+ foreach (const TokenKeyfilePath &keyPath, selectedTokenKeyfiles)
{
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
if (kf)
@@ -758,10 +759,10 @@ BOOL KeyfilesPopupMenu (HWND hwndDlg, POINT popupPosition, KeyFilesDlgParam *par
case IDM_KEYFILES_POPUP_ADD_TOKEN_FILES:
{
- list <SecurityTokenKeyfilePath> selectedTokenKeyfiles;
+ list <TokenKeyfilePath> selectedTokenKeyfiles;
if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_KEYFILES), hwndDlg, (DLGPROC) SecurityTokenKeyfileDlgProc, (LPARAM) &selectedTokenKeyfiles) == IDOK)
{
- foreach (const SecurityTokenKeyfilePath &keyPath, selectedTokenKeyfiles)
+ foreach (const TokenKeyfilePath &keyPath, selectedTokenKeyfiles)
{
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
if (kf)
diff --git a/src/Common/Language.xml b/src/Common/Language.xml
index 540f6867..cd996bce 100644
--- a/src/Common/Language.xml
+++ b/src/Common/Language.xml
@@ -113,6 +113,7 @@
<entry lang="en" key="IDC_CACHE">Cache passwords and keyfil&amp;es in memory</entry>
<entry lang="en" key="IDC_CLOSE_BKG_TASK_WHEN_NOVOL">Exit when there are no mounted volumes</entry>
<entry lang="en" key="IDC_CLOSE_TOKEN_SESSION_AFTER_MOUNT">&amp;Close token session (log out) after a volume is successfully mounted</entry>
+ <entry lang="en" key="IDC_ACTIVATE_EMV_OPTION">Activate EMV Option</entry>
<entry lang="en" key="IDC_COPY_EXPANDER">Include VeraCrypt Volume Expander</entry>
<entry lang="en" key="IDC_COPY_WIZARD">Include VeraCrypt Volume Creation Wizard</entry>
<entry lang="en" key="IDC_CREATE">Create</entry>
@@ -295,6 +296,7 @@
<entry lang="en" key="IDT_NEW_PKCS5_PRF">PKCS-5 PRF:</entry>
<entry lang="en" key="IDT_PW_CACHE_OPTIONS">Password Cache</entry>
<entry lang="en" key="IDT_SECURITY_OPTIONS">Security Options</entry>
+ <entry lang="en" key="IDT_EMV_OPTIONS">EMV Options</entry>
<entry lang="en" key="IDT_TASKBAR_ICON">VeraCrypt Background Task</entry>
<entry lang="en" key="IDT_TRAVELER_MOUNT">VeraCrypt volume to mount (relative to traveler disk root):</entry>
<entry lang="en" key="IDT_TRAVEL_INSERTION">Upon insertion of traveler disk: </entry>
@@ -1278,6 +1280,12 @@
<entry lang="en" key="CKR_PIN_INCORRECT">Password for security token is incorrect.</entry>
<entry lang="en" key="CKR_DEVICE_MEMORY">The security token does not have enough memory/space to perform the requested operation.\n\nIf you are attempting to import a keyfile, you should select a smaller file or use a keyfile generated by VeraCrypt (select 'Tools' > 'Keyfile Generator').</entry>
<entry lang="en" key="ALL_TOKEN_SESSIONS_CLOSED">All open security token sessions have been closed.</entry>
+ <entry lang="en" key="WINSCARD_MODULE_INIT_FAILED">Error when loading the winscard library.\n\nPlease make sure the WinSCard.dll is present in your System32 folder.</entry>
+ <entry lang="en" key="INVALID_EMV_PATH">EMV path is invalid.</entry>
+ <entry lang="en" key="EMV_KEYFILE_DATA_NOT_FOUND">Unable to build a keyfile from the EMV card's data.\n\nOne of the following is missing:\n- ICC Public Key Certificate.\n- Issuer Public Key Certificate.\n- CPCL data.</entry>
+ <entry lang="en" key="EMV_PAN_NOT_FOUND">No Primary Account Number (PAN) found in the EMV card.</entry>
+ <entry lang="en" key="EMV_UNKNOWN_CARD_TYPE">The card in the reader is not a supported EMV card.</entry>
+ <entry lang="en" key="SCARD_W_REMOVED_CARD">No card in the reader.\n\nPlease make sure the card is correctly slotted.</entry>
<entry lang="en" key="SELECT_TOKEN_KEYFILES">Select Security Token Keyfiles</entry>
<entry lang="en" key="TOKEN_SLOT_ID">Slot</entry>
<entry lang="en" key="TOKEN_NAME">Token name</entry>
diff --git a/src/Common/SecurityToken.cpp b/src/Common/SecurityToken.cpp
index 8401a0eb..ad8ed33e 100644
--- a/src/Common/SecurityToken.cpp
+++ b/src/Common/SecurityToken.cpp
@@ -36,23 +36,31 @@ using namespace std;
namespace VeraCrypt
{
- SecurityTokenKeyfile::SecurityTokenKeyfile (const SecurityTokenKeyfilePath &path)
+ SecurityTokenKeyfile::SecurityTokenKeyfile(): Handle(CK_INVALID_HANDLE) {
+ SecurityTokenInfo* token = new SecurityTokenInfo();
+ Token = shared_ptr<SecurityTokenInfo>(token);
+ Token->SlotId = CK_UNAVAILABLE_INFORMATION;
+ token->Flags = 0;
+ }
+
+ SecurityTokenKeyfile::SecurityTokenKeyfile(const TokenKeyfilePath& path)
{
+ Token = shared_ptr<SecurityTokenInfo>(new SecurityTokenInfo());
wstring pathStr = path;
unsigned long slotId;
- if (swscanf (pathStr.c_str(), TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX TC_SECURITY_TOKEN_KEYFILE_URL_SLOT L"/%lu", &slotId) != 1)
+ if (swscanf(pathStr.c_str(), TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX TC_SECURITY_TOKEN_KEYFILE_URL_SLOT L"/%lu", &slotId) != 1)
throw InvalidSecurityTokenKeyfilePath();
- SlotId = slotId;
+ Token->SlotId = slotId;
- size_t keyIdPos = pathStr.find (L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/");
+ size_t keyIdPos = pathStr.find(L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/");
if (keyIdPos == wstring::npos)
throw InvalidSecurityTokenKeyfilePath();
- Id = pathStr.substr (keyIdPos + wstring (L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/").size());
+ Id = pathStr.substr(keyIdPos + wstring(L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/").size());
- vector <SecurityTokenKeyfile> keyfiles = SecurityToken::GetAvailableKeyfiles (&SlotId, Id);
+ vector <SecurityTokenKeyfile> keyfiles = SecurityToken::GetAvailableKeyfiles(&Token->SlotId, Id);
if (keyfiles.empty())
throw SecurityTokenKeyfileNotFound();
@@ -60,69 +68,69 @@ namespace VeraCrypt
*this = keyfiles.front();
}
- SecurityTokenKeyfile::operator SecurityTokenKeyfilePath () const
+ SecurityTokenKeyfile::operator TokenKeyfilePath () const
{
wstringstream path;
- path << TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX TC_SECURITY_TOKEN_KEYFILE_URL_SLOT L"/" << SlotId << L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/" << Id;
+ path << TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX TC_SECURITY_TOKEN_KEYFILE_URL_SLOT L"/" << Token->SlotId << L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/" << Id;
return path.str();
}
- void SecurityToken::CheckLibraryStatus ()
+ void SecurityToken::CheckLibraryStatus()
{
if (!Initialized)
throw SecurityTokenLibraryNotInitialized();
}
- void SecurityToken::CloseLibrary ()
+ void SecurityToken::CloseLibrary()
{
if (Initialized)
{
CloseAllSessions();
- Pkcs11Functions->C_Finalize (NULL_PTR);
+ Pkcs11Functions->C_Finalize(NULL_PTR);
#ifdef TC_WINDOWS
- FreeLibrary (Pkcs11LibraryHandle);
+ FreeLibrary(Pkcs11LibraryHandle);
#else
- dlclose (Pkcs11LibraryHandle);
+ dlclose(Pkcs11LibraryHandle);
#endif
Initialized = false;
}
}
- void SecurityToken::CloseAllSessions () throw ()
+ void SecurityToken::CloseAllSessions() throw ()
{
if (!Initialized)
return;
typedef pair <CK_SLOT_ID, Pkcs11Session> SessionMapPair;
- foreach (SessionMapPair p, Sessions)
+ foreach(SessionMapPair p, Sessions)
{
try
{
- CloseSession (p.first);
+ CloseSession(p.first);
}
- catch (...) { }
+ catch (...) {}
}
}
- void SecurityToken::CloseSession (CK_SLOT_ID slotId)
+ void SecurityToken::CloseSession(CK_SLOT_ID slotId)
{
- if (Sessions.find (slotId) == Sessions.end())
- throw ParameterIncorrect (SRC_POS);
+ if (Sessions.find(slotId) == Sessions.end())
+ throw ParameterIncorrect(SRC_POS);
- Pkcs11Functions->C_CloseSession (Sessions[slotId].Handle);
- Sessions.erase (Sessions.find (slotId));
+ Pkcs11Functions->C_CloseSession(Sessions[slotId].Handle);
+ Sessions.erase(Sessions.find(slotId));
}
- void SecurityToken::CreateKeyfile (CK_SLOT_ID slotId, vector <byte> &keyfileData, const string &name)
+ void SecurityToken::CreateKeyfile(CK_SLOT_ID slotId, vector <byte>& keyfileData, const string& name)
{
if (name.empty())
- throw ParameterIncorrect (SRC_POS);
+ throw ParameterIncorrect(SRC_POS);
- LoginUserIfRequired (slotId);
+ LoginUserIfRequired(slotId);
- foreach (const SecurityTokenKeyfile &keyfile, GetAvailableKeyfiles (&slotId))
+ foreach(const SecurityTokenKeyfile & keyfile, GetAvailableKeyfiles(&slotId))
{
if (keyfile.IdUtf8 == name)
throw SecurityTokenKeyfileAlreadyExists();
@@ -133,16 +141,16 @@ namespace VeraCrypt
CK_ATTRIBUTE keyfileTemplate[] =
{
- { CKA_CLASS, &dataClass, sizeof (dataClass) },
- { CKA_TOKEN, &trueVal, sizeof (trueVal) },
- { CKA_PRIVATE, &trueVal, sizeof (trueVal) },
- { CKA_LABEL, (CK_UTF8CHAR *) name.c_str(), (CK_ULONG) name.size() },
- { CKA_VALUE, &keyfileData.front(), (CK_ULONG) keyfileData.size() }
+ { CKA_CLASS, &dataClass, sizeof(dataClass) },
+ { CKA_TOKEN, &trueVal, sizeof(trueVal) },
+ { CKA_PRIVATE, &trueVal, sizeof(trueVal) },
+ { CKA_LABEL, (CK_UTF8CHAR*)name.c_str(), (CK_ULONG)name.size() },
+ { CKA_VALUE, &keyfileData.front(), (CK_ULONG)keyfileData.size() }
};
CK_OBJECT_HANDLE keyfileHandle;
- CK_RV status = Pkcs11Functions->C_CreateObject (Sessions[slotId].Handle, keyfileTemplate, array_capacity (keyfileTemplate), &keyfileHandle);
+ CK_RV status = Pkcs11Functions->C_CreateObject(Sessions[slotId].Handle, keyfileTemplate, array_capacity(keyfileTemplate), &keyfileHandle);
switch (status)
{
@@ -156,36 +164,36 @@ namespace VeraCrypt
}
if (status != CKR_OK)
- throw Pkcs11Exception (status);
+ throw Pkcs11Exception(status);
// Some tokens report success even if the new object was truncated to fit in the available memory
vector <byte> objectData;
- GetObjectAttribute (slotId, keyfileHandle, CKA_VALUE, objectData);
- finally_do_arg (vector <byte> *, &objectData, { if (!finally_arg->empty()) burn (&finally_arg->front(), finally_arg->size()); });
+ GetObjectAttribute(slotId, keyfileHandle, CKA_VALUE, objectData);
+ finally_do_arg(vector <byte> *, &objectData, { if (!finally_arg->empty()) burn(&finally_arg->front(), finally_arg->size()); });
if (objectData.size() != keyfileData.size())
{
- Pkcs11Functions->C_DestroyObject (Sessions[slotId].Handle, keyfileHandle);
- throw Pkcs11Exception (CKR_DEVICE_MEMORY);
+ Pkcs11Functions->C_DestroyObject(Sessions[slotId].Handle, keyfileHandle);
+ throw Pkcs11Exception(CKR_DEVICE_MEMORY);
}
}
- void SecurityToken::DeleteKeyfile (const SecurityTokenKeyfile &keyfile)
+ void SecurityToken::DeleteKeyfile(const SecurityTokenKeyfile& keyfile)
{
- LoginUserIfRequired (keyfile.SlotId);
+ LoginUserIfRequired(keyfile.Token->SlotId);
- CK_RV status = Pkcs11Functions->C_DestroyObject (Sessions[keyfile.SlotId].Handle, keyfile.Handle);
+ CK_RV status = Pkcs11Functions->C_DestroyObject(Sessions[keyfile.Token->SlotId].Handle, keyfile.Handle);
if (status != CKR_OK)
- throw Pkcs11Exception (status);
+ throw Pkcs11Exception(status);
}
- vector <SecurityTokenKeyfile> SecurityToken::GetAvailableKeyfiles (CK_SLOT_ID *slotIdFilter, const wstring keyfileIdFilter)
+ vector <SecurityTokenKeyfile> SecurityToken::GetAvailableKeyfiles(CK_SLOT_ID* slotIdFilter, const wstring keyfileIdFilter)
{
bool unrecognizedTokenPresent = false;
vector <SecurityTokenKeyfile> keyfiles;
- foreach (const CK_SLOT_ID &slotId, GetTokenSlots())
+ foreach(const CK_SLOT_ID & slotId, GetTokenSlots())
{
SecurityTokenInfo token;
@@ -194,14 +202,14 @@ namespace VeraCrypt
try
{
- LoginUserIfRequired (slotId);
- token = GetTokenInfo (slotId);
+ LoginUserIfRequired(slotId);
+ token = GetTokenInfo(slotId);
}
- catch (UserAbort &)
+ catch (UserAbort&)
{
continue;
}
- catch (Pkcs11Exception &e)
+ catch (Pkcs11Exception& e)
{
if (e.GetErrorCode() == CKR_TOKEN_NOT_RECOGNIZED)
{
@@ -212,34 +220,34 @@ namespace VeraCrypt
throw;
}
- foreach (const CK_OBJECT_HANDLE &dataHandle, GetObjects (slotId, CKO_DATA))
+ foreach(const CK_OBJECT_HANDLE & dataHandle, GetObjects(slotId, CKO_DATA))
{
SecurityTokenKeyfile keyfile;
keyfile.Handle = dataHandle;
- keyfile.SlotId = slotId;
- keyfile.Token = token;
+ keyfile.Token->SlotId = slotId;
+ keyfile.Token = shared_ptr<SecurityTokenInfo>(new SecurityTokenInfo(token));
vector <byte> privateAttrib;
- GetObjectAttribute (slotId, dataHandle, CKA_PRIVATE, privateAttrib);
+ GetObjectAttribute(slotId, dataHandle, CKA_PRIVATE, privateAttrib);
- if (privateAttrib.size() == sizeof (CK_BBOOL) && *(CK_BBOOL *) &privateAttrib.front() != CK_TRUE)
+ if (privateAttrib.size() == sizeof(CK_BBOOL) && *(CK_BBOOL*)&privateAttrib.front() != CK_TRUE)
continue;
vector <byte> label;
- GetObjectAttribute (slotId, dataHandle, CKA_LABEL, label);
- label.push_back (0);
+ GetObjectAttribute(slotId, dataHandle, CKA_LABEL, label);
+ label.push_back(0);
- keyfile.IdUtf8 = (char *) &label.front();
+ keyfile.IdUtf8 = (char*)&label.front();
#if defined (TC_WINDOWS) && !defined (TC_PROTOTYPE)
- keyfile.Id = Utf8StringToWide ((const char *) &label.front());
+ keyfile.Id = Utf8StringToWide((const char*)&label.front());
#else
- keyfile.Id = StringConverter::ToWide ((const char *) &label.front());
+ keyfile.Id = StringConverter::ToWide((const char*)&label.front());
#endif
if (keyfile.Id.empty() || (!keyfileIdFilter.empty() && keyfileIdFilter != keyfile.Id))
continue;
- keyfiles.push_back (keyfile);
+ keyfiles.push_back(keyfile);
if (!keyfileIdFilter.empty())
break;
@@ -247,23 +255,23 @@ namespace VeraCrypt
}
if (keyfiles.empty() && unrecognizedTokenPresent)
- throw Pkcs11Exception (CKR_TOKEN_NOT_RECOGNIZED);
+ throw Pkcs11Exception(CKR_TOKEN_NOT_RECOGNIZED);
return keyfiles;
}
- list <SecurityTokenInfo> SecurityToken::GetAvailableTokens ()
+ list <SecurityTokenInfo> SecurityToken::GetAvailableTokens()
{
bool unrecognizedTokenPresent = false;
list <SecurityTokenInfo> tokens;
- foreach (const CK_SLOT_ID &slotId, GetTokenSlots())
+ foreach(const CK_SLOT_ID & slotId, GetTokenSlots())
{
try
{
- tokens.push_back (GetTokenInfo (slotId));
+ tokens.push_back(GetTokenInfo(slotId));
}
- catch (Pkcs11Exception &e)
+ catch (Pkcs11Exception& e)
{
if (e.GetErrorCode() == CKR_TOKEN_NOT_RECOGNIZED)
{
@@ -276,63 +284,63 @@ namespace VeraCrypt
}
if (tokens.empty() && unrecognizedTokenPresent)
- throw Pkcs11Exception (CKR_TOKEN_NOT_RECOGNIZED);
+ throw Pkcs11Exception(CKR_TOKEN_NOT_RECOGNIZED);
return tokens;
}
- SecurityTokenInfo SecurityToken::GetTokenInfo (CK_SLOT_ID slotId)
+ SecurityTokenInfo SecurityToken::GetTokenInfo(CK_SLOT_ID slotId)
{
CK_TOKEN_INFO info;
- CK_RV status = Pkcs11Functions->C_GetTokenInfo (slotId, &info);
+ CK_RV status = Pkcs11Functions->C_GetTokenInfo(slotId, &info);
if (status != CKR_OK)
- throw Pkcs11Exception (status);
+ throw Pkcs11Exception(status);
SecurityTokenInfo token;
token.SlotId = slotId;
token.Flags = info.flags;
- char label[sizeof (info.label) + 1];
- memset (label, 0, sizeof (label));
- memcpy (label, info.label, sizeof (info.label));
+ char label[sizeof(info.label) + 1];
+ memset(label, 0, sizeof(label));
+ memcpy(label, info.label, sizeof(info.label));
token.LabelUtf8 = label;
- size_t lastSpace = token.LabelUtf8.find_last_not_of (' ');
+ size_t lastSpace = token.LabelUtf8.find_last_not_of(' ');
if (lastSpace == string::npos)
token.LabelUtf8.clear();
else
- token.LabelUtf8 = token.LabelUtf8.substr (0, lastSpace + 1);
+ token.LabelUtf8 = token.LabelUtf8.substr(0, lastSpace + 1);
#if defined (TC_WINDOWS) && !defined (TC_PROTOTYPE)
- token.Label = Utf8StringToWide (token.LabelUtf8);
+ token.Label = Utf8StringToWide(token.LabelUtf8);
#else
- token.Label = StringConverter::ToWide (token.LabelUtf8);
+ token.Label = StringConverter::ToWide(token.LabelUtf8);
#endif
return token;
}
- void SecurityToken::GetKeyfileData (const SecurityTokenKeyfile &keyfile, vector <byte> &keyfileData)
+ void SecurityTokenKeyfile::GetKeyfileData(vector <byte>& keyfileData) const
{
- LoginUserIfRequired (keyfile.SlotId);
- GetObjectAttribute (keyfile.SlotId, keyfile.Handle, CKA_VALUE, keyfileData);
+ SecurityToken::LoginUserIfRequired(Token->SlotId);
+ SecurityToken::GetObjectAttribute(Token->SlotId, Handle, CKA_VALUE, keyfileData);
}
- vector <CK_OBJECT_HANDLE> SecurityToken::GetObjects (CK_SLOT_ID slotId, CK_ATTRIBUTE_TYPE objectClass)
+ vector <CK_OBJECT_HANDLE> SecurityToken::GetObjects(CK_SLOT_ID slotId, CK_ATTRIBUTE_TYPE objectClass)
{
- if (Sessions.find (slotId) == Sessions.end())
- throw ParameterIncorrect (SRC_POS);
+ if (Sessions.find(slotId) == Sessions.end())
+ throw ParameterIncorrect(SRC_POS);
CK_ATTRIBUTE findTemplate;
findTemplate.type = CKA_CLASS;
findTemplate.pValue = &objectClass;
- findTemplate.ulValueLen = sizeof (objectClass);
+ findTemplate.ulValueLen = sizeof(objectClass);
- CK_RV status = Pkcs11Functions->C_FindObjectsInit (Sessions[slotId].Handle, &findTemplate, 1);
+ CK_RV status = Pkcs11Functions->C_FindObjectsInit(Sessions[slotId].Handle, &findTemplate, 1);
if (status != CKR_OK)
- throw Pkcs11Exception (status);
+ throw Pkcs11Exception(status);
- finally_do_arg (CK_SLOT_ID, slotId, { Pkcs11Functions->C_FindObjectsFinal (Sessions[finally_arg].Handle); });
+ finally_do_arg(CK_SLOT_ID, slotId, { Pkcs11Functions->C_FindObjectsFinal(Sessions[finally_arg].Handle); });
CK_ULONG objectCount;
vector <CK_OBJECT_HANDLE> objects;
@@ -340,112 +348,112 @@ namespace VeraCrypt
while (true)
{
CK_OBJECT_HANDLE object;
- CK_RV status = Pkcs11Functions->C_FindObjects (Sessions[slotId].Handle, &object, 1, &objectCount);
+ CK_RV status = Pkcs11Functions->C_FindObjects(Sessions[slotId].Handle, &object, 1, &objectCount);
if (status != CKR_OK)
- throw Pkcs11Exception (status);
+ throw Pkcs11Exception(status);
if (objectCount != 1)
break;
- objects.push_back (object);
+ objects.push_back(object);
}
return objects;
}
- void SecurityToken::GetObjectAttribute (CK_SLOT_ID slotId, CK_OBJECT_HANDLE tokenObject, CK_ATTRIBUTE_TYPE attributeType, vector <byte> &attributeValue)
+ void SecurityToken::GetObjectAttribute(CK_SLOT_ID slotId, CK_OBJECT_HANDLE tokenObject, CK_ATTRIBUTE_TYPE attributeType, vector <byte>& attributeValue)
{
attributeValue.clear();
- if (Sessions.find (slotId) == Sessions.end())
- throw ParameterIncorrect (SRC_POS);
+ if (Sessions.find(slotId) == Sessions.end())
+ throw ParameterIncorrect(SRC_POS);
CK_ATTRIBUTE attribute;
attribute.type = attributeType;
attribute.pValue = NULL_PTR;
- CK_RV status = Pkcs11Functions->C_GetAttributeValue (Sessions[slotId].Handle, tokenObject, &attribute, 1);
+ CK_RV status = Pkcs11Functions->C_GetAttributeValue(Sessions[slotId].Handle, tokenObject, &attribute, 1);
if (status != CKR_OK)
- throw Pkcs11Exception (status);
+ throw Pkcs11Exception(status);
if (attribute.ulValueLen == 0)
return;
- attributeValue = vector <byte> (attribute.ulValueLen);
+ attributeValue = vector <byte>(attribute.ulValueLen);
attribute.pValue = &attributeValue.front();
- status = Pkcs11Functions->C_GetAttributeValue (Sessions[slotId].Handle, tokenObject, &attribute, 1);
+ status = Pkcs11Functions->C_GetAttributeValue(Sessions[slotId].Handle, tokenObject, &attribute, 1);
if (status != CKR_OK)
- throw Pkcs11Exception (status);
+ throw Pkcs11Exception(status);
}
- list <CK_SLOT_ID> SecurityToken::GetTokenSlots ()
+ list <CK_SLOT_ID> SecurityToken::GetTokenSlots()
{
CheckLibraryStatus();
list <CK_SLOT_ID> slots;
CK_ULONG slotCount;
- CK_RV status = Pkcs11Functions->C_GetSlotList (TRUE, NULL_PTR, &slotCount);
+ CK_RV status = Pkcs11Functions->C_GetSlotList(TRUE, NULL_PTR, &slotCount);
if (status != CKR_OK)
- throw Pkcs11Exception (status);
+ throw Pkcs11Exception(status);
if (slotCount > 0)
{
- vector <CK_SLOT_ID> slotArray (slotCount);
- status = Pkcs11Functions->C_GetSlotList (TRUE, &slotArray.front(), &slotCount);
+ vector <CK_SLOT_ID> slotArray(slotCount);
+ status = Pkcs11Functions->C_GetSlotList(TRUE, &slotArray.front(), &slotCount);
if (status != CKR_OK)
- throw Pkcs11Exception (status);
+ throw Pkcs11Exception(status);
for (size_t i = 0; i < slotCount; i++)
{
CK_SLOT_INFO slotInfo;
- status = Pkcs11Functions->C_GetSlotInfo (slotArray[i], &slotInfo);
+ status = Pkcs11Functions->C_GetSlotInfo(slotArray[i], &slotInfo);
if (status != CKR_OK || !(slotInfo.flags & CKF_TOKEN_PRESENT))
continue;
- slots.push_back (slotArray[i]);
+ slots.push_back(slotArray[i]);
}
}
return slots;
}
- bool SecurityToken::IsKeyfilePathValid (const wstring &securityTokenKeyfilePath)
+ bool SecurityToken::IsKeyfilePathValid(const wstring& securityTokenKeyfilePath)
{
- return securityTokenKeyfilePath.find (TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX) == 0;
+ return securityTokenKeyfilePath.find(TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX) == 0;
}
- void SecurityToken::Login (CK_SLOT_ID slotId, const char* pin)
+ void SecurityToken::Login(CK_SLOT_ID slotId, const char* pin)
{
- if (Sessions.find (slotId) == Sessions.end())
- OpenSession (slotId);
+ if (Sessions.find(slotId) == Sessions.end())
+ OpenSession(slotId);
else if (Sessions[slotId].UserLoggedIn)
return;
- size_t pinLen = pin? strlen (pin) : 0;
- CK_RV status = Pkcs11Functions->C_Login (Sessions[slotId].Handle, CKU_USER, (CK_CHAR_PTR) pin, (CK_ULONG) pinLen);
+ size_t pinLen = pin ? strlen(pin) : 0;
+ CK_RV status = Pkcs11Functions->C_Login(Sessions[slotId].Handle, CKU_USER, (CK_CHAR_PTR)pin, (CK_ULONG)pinLen);
if (status != CKR_OK)
- throw Pkcs11Exception (status);
+ throw Pkcs11Exception(status);
Sessions[slotId].UserLoggedIn = true;
}
- void SecurityToken::LoginUserIfRequired (CK_SLOT_ID slotId)
+ void SecurityToken::LoginUserIfRequired(CK_SLOT_ID slotId)
{
CheckLibraryStatus();
CK_RV status;
- if (Sessions.find (slotId) == Sessions.end())
+ if (Sessions.find(slotId) == Sessions.end())
{
- OpenSession (slotId);
+ OpenSession(slotId);
}
else
{
CK_SESSION_INFO sessionInfo;
- status = Pkcs11Functions->C_GetSessionInfo (Sessions[slotId].Handle, &sessionInfo);
+ status = Pkcs11Functions->C_GetSessionInfo(Sessions[slotId].Handle, &sessionInfo);
if (status == CKR_OK)
{
@@ -455,14 +463,14 @@ namespace VeraCrypt
{
try
{
- CloseSession (slotId);
+ CloseSession(slotId);
}
- catch (...) { }
- OpenSession (slotId);
+ catch (...) {}
+ OpenSession(slotId);
}
}
- SecurityTokenInfo tokenInfo = GetTokenInfo (slotId);
+ SecurityTokenInfo tokenInfo = GetTokenInfo(slotId);
while (!Sessions[slotId].UserLoggedIn && (tokenInfo.Flags & CKF_LOGIN_REQUIRED))
{
@@ -470,9 +478,9 @@ namespace VeraCrypt
{
if (tokenInfo.Flags & CKF_PROTECTED_AUTHENTICATION_PATH)
{
- status = Pkcs11Functions->C_Login (Sessions[slotId].Handle, CKU_USER, NULL_PTR, 0);
+ status = Pkcs11Functions->C_Login(Sessions[slotId].Handle, CKU_USER, NULL_PTR, 0);
if (status != CKR_OK)
- throw Pkcs11Exception (status);
+ throw Pkcs11Exception(status);
}
else
{
@@ -484,15 +492,15 @@ namespace VeraCrypt
pin = s.str();
}
- finally_do_arg (string*, &pin, { burn ((void *) finally_arg->c_str(), finally_arg->size()); });
+ finally_do_arg(string*, &pin, { burn((void*)finally_arg->c_str(), finally_arg->size()); });
(*PinCallback) (pin);
- Login (slotId, pin.c_str());
+ Login(slotId, pin.c_str());
}
Sessions[slotId].UserLoggedIn = true;
}
- catch (Pkcs11Exception &e)
+ catch (Pkcs11Exception& e)
{
CK_RV error = e.GetErrorCode();
@@ -502,8 +510,8 @@ namespace VeraCrypt
}
else if (error == CKR_PIN_INCORRECT && !(tokenInfo.Flags & CKF_PROTECTED_AUTHENTICATION_PATH))
{
- PinCallback->notifyIncorrectPin ();
- (*WarningCallback) (Pkcs11Exception (CKR_PIN_INCORRECT));
+ PinCallback->notifyIncorrectPin();
+ (*WarningCallback) (Pkcs11Exception(CKR_PIN_INCORRECT));
continue;
}
@@ -513,40 +521,40 @@ namespace VeraCrypt
}
#ifdef TC_WINDOWS
- void SecurityToken::InitLibrary (const wstring &pkcs11LibraryPath, unique_ptr <GetPinFunctor> pinCallback, unique_ptr <SendExceptionFunctor> warningCallback)
+ void SecurityToken::InitLibrary(const wstring& pkcs11LibraryPath, unique_ptr <GetPinFunctor> pinCallback, unique_ptr <SendExceptionFunctor> warningCallback)
#else
- void SecurityToken::InitLibrary (const string &pkcs11LibraryPath, unique_ptr <GetPinFunctor> pinCallback, unique_ptr <SendExceptionFunctor> warningCallback)
+ void SecurityToken::InitLibrary(const string& pkcs11LibraryPath, unique_ptr <GetPinFunctor> pinCallback, unique_ptr <SendExceptionFunctor> warningCallback)
#endif
{
if (Initialized)
CloseLibrary();
#ifdef TC_WINDOWS
- Pkcs11LibraryHandle = LoadLibraryW (pkcs11LibraryPath.c_str());
- throw_sys_if (!Pkcs11LibraryHandle);
+ Pkcs11LibraryHandle = LoadLibraryW(pkcs11LibraryPath.c_str());
+ throw_sys_if(!Pkcs11LibraryHandle);
#else
- Pkcs11LibraryHandle = dlopen (pkcs11LibraryPath.c_str(), RTLD_NOW | RTLD_LOCAL);
- throw_sys_sub_if (!Pkcs11LibraryHandle, dlerror());
+ Pkcs11LibraryHandle = dlopen(pkcs11LibraryPath.c_str(), RTLD_NOW | RTLD_LOCAL);
+ throw_sys_sub_if(!Pkcs11LibraryHandle, dlerror());
#endif
- typedef CK_RV (*C_GetFunctionList_t) (CK_FUNCTION_LIST_PTR_PTR ppFunctionList);
+ typedef CK_RV(*C_GetFunctionList_t) (CK_FUNCTION_LIST_PTR_PTR ppFunctionList);
#ifdef TC_WINDOWS
- C_GetFunctionList_t C_GetFunctionList = (C_GetFunctionList_t) GetProcAddress (Pkcs11LibraryHandle, "C_GetFunctionList");
+ C_GetFunctionList_t C_GetFunctionList = (C_GetFunctionList_t)GetProcAddress(Pkcs11LibraryHandle, "C_GetFunctionList");
#else
- C_GetFunctionList_t C_GetFunctionList = (C_GetFunctionList_t) dlsym (Pkcs11LibraryHandle, "C_GetFunctionList");
+ C_GetFunctionList_t C_GetFunctionList = (C_GetFunctionList_t)dlsym(Pkcs11LibraryHandle, "C_GetFunctionList");
#endif
if (!C_GetFunctionList)
throw SecurityTokenLibraryNotInitialized();
- CK_RV status = C_GetFunctionList (&Pkcs11Functions);
+ CK_RV status = C_GetFunctionList(&Pkcs11Functions);
if (status != CKR_OK)
- throw Pkcs11Exception (status);
+ throw Pkcs11Exception(status);
- status = Pkcs11Functions->C_Initialize (NULL_PTR);
+ status = Pkcs11Functions->C_Initialize(NULL_PTR);
if (status != CKR_OK)
- throw Pkcs11Exception (status);
+ throw Pkcs11Exception(status);
PinCallback = move_ptr(pinCallback);
WarningCallback = move_ptr(warningCallback);
@@ -554,21 +562,21 @@ namespace VeraCrypt
Initialized = true;
}
- void SecurityToken::OpenSession (CK_SLOT_ID slotId)
+ void SecurityToken::OpenSession(CK_SLOT_ID slotId)
{
- if (Sessions.find (slotId) != Sessions.end())
+ if (Sessions.find(slotId) != Sessions.end())
return;
CK_SESSION_HANDLE session;
CK_FLAGS flags = CKF_SERIAL_SESSION;
- if (!(GetTokenInfo (slotId).Flags & CKF_WRITE_PROTECTED))
- flags |= CKF_RW_SESSION;
+ if (!(GetTokenInfo(slotId).Flags & CKF_WRITE_PROTECTED))
+ flags |= CKF_RW_SESSION;
- CK_RV status = Pkcs11Functions->C_OpenSession (slotId, flags, NULL_PTR, NULL_PTR, &session);
+ CK_RV status = Pkcs11Functions->C_OpenSession(slotId, flags, NULL_PTR, NULL_PTR, &session);
if (status != CKR_OK)
- throw Pkcs11Exception (status);
+ throw Pkcs11Exception(status);
Sessions[slotId].Handle = session;
}
@@ -581,103 +589,103 @@ namespace VeraCrypt
static const struct
{
CK_RV ErrorCode;
- const char *ErrorString;
+ const char* ErrorString;
} ErrorStrings[] =
{
# define TC_TOKEN_ERR(CODE) { CODE, #CODE },
- TC_TOKEN_ERR (CKR_CANCEL)
- TC_TOKEN_ERR (CKR_HOST_MEMORY)
- TC_TOKEN_ERR (CKR_SLOT_ID_INVALID)
- TC_TOKEN_ERR (CKR_GENERAL_ERROR)
- TC_TOKEN_ERR (CKR_FUNCTION_FAILED)
- TC_TOKEN_ERR (CKR_ARGUMENTS_BAD)
- TC_TOKEN_ERR (CKR_NO_EVENT)
- TC_TOKEN_ERR (CKR_NEED_TO_CREATE_THREADS)
- TC_TOKEN_ERR (CKR_CANT_LOCK)
- TC_TOKEN_ERR (CKR_ATTRIBUTE_READ_ONLY)
- TC_TOKEN_ERR (CKR_ATTRIBUTE_SENSITIVE)
- TC_TOKEN_ERR (CKR_ATTRIBUTE_TYPE_INVALID)
- TC_TOKEN_ERR (CKR_ATTRIBUTE_VALUE_INVALID)
- TC_TOKEN_ERR (CKR_DATA_INVALID)
- TC_TOKEN_ERR (CKR_DATA_LEN_RANGE)
- TC_TOKEN_ERR (CKR_DEVICE_ERROR)
- TC_TOKEN_ERR (CKR_DEVICE_MEMORY)
- TC_TOKEN_ERR (CKR_DEVICE_REMOVED)
- TC_TOKEN_ERR (CKR_ENCRYPTED_DATA_INVALID)
- TC_TOKEN_ERR (CKR_ENCRYPTED_DATA_LEN_RANGE)
- TC_TOKEN_ERR (CKR_FUNCTION_CANCELED)
- TC_TOKEN_ERR (CKR_FUNCTION_NOT_PARALLEL)
- TC_TOKEN_ERR (CKR_FUNCTION_NOT_SUPPORTED)
- TC_TOKEN_ERR (CKR_KEY_HANDLE_INVALID)
- TC_TOKEN_ERR (CKR_KEY_SIZE_RANGE)
- TC_TOKEN_ERR (CKR_KEY_TYPE_INCONSISTENT)
- TC_TOKEN_ERR (CKR_KEY_NOT_NEEDED)
- TC_TOKEN_ERR (CKR_KEY_CHANGED)
- TC_TOKEN_ERR (CKR_KEY_NEEDED)
- TC_TOKEN_ERR (CKR_KEY_INDIGESTIBLE)
- TC_TOKEN_ERR (CKR_KEY_FUNCTION_NOT_PERMITTED)
- TC_TOKEN_ERR (CKR_KEY_NOT_WRAPPABLE)
- TC_TOKEN_ERR (CKR_KEY_UNEXTRACTABLE)
- TC_TOKEN_ERR (CKR_MECHANISM_INVALID)
- TC_TOKEN_ERR (CKR_MECHANISM_PARAM_INVALID)
- TC_TOKEN_ERR (CKR_OBJECT_HANDLE_INVALID)
- TC_TOKEN_ERR (CKR_OPERATION_ACTIVE)
- TC_TOKEN_ERR (CKR_OPERATION_NOT_INITIALIZED)
- TC_TOKEN_ERR (CKR_PIN_INCORRECT)
- TC_TOKEN_ERR (CKR_PIN_INVALID)
- TC_TOKEN_ERR (CKR_PIN_LEN_RANGE)
- TC_TOKEN_ERR (CKR_PIN_EXPIRED)
- TC_TOKEN_ERR (CKR_PIN_LOCKED)
- TC_TOKEN_ERR (CKR_SESSION_CLOSED)
- TC_TOKEN_ERR (CKR_SESSION_COUNT)
- TC_TOKEN_ERR (CKR_SESSION_HANDLE_INVALID)
- TC_TOKEN_ERR (CKR_SESSION_PARALLEL_NOT_SUPPORTED)
- TC_TOKEN_ERR (CKR_SESSION_READ_ONLY)
- TC_TOKEN_ERR (CKR_SESSION_EXISTS)
- TC_TOKEN_ERR (CKR_SESSION_READ_ONLY_EXISTS)
- TC_TOKEN_ERR (CKR_SESSION_READ_WRITE_SO_EXISTS)
- TC_TOKEN_ERR (CKR_SIGNATURE_INVALID)
- TC_TOKEN_ERR (CKR_SIGNATURE_LEN_RANGE)
- TC_TOKEN_ERR (CKR_TEMPLATE_INCOMPLETE)
- TC_TOKEN_ERR (CKR_TEMPLATE_INCONSISTENT)
- TC_TOKEN_ERR (CKR_TOKEN_NOT_PRESENT)
- TC_TOKEN_ERR (CKR_TOKEN_NOT_RECOGNIZED)
- TC_TOKEN_ERR (CKR_TOKEN_WRITE_PROTECTED)
- TC_TOKEN_ERR (CKR_UNWRAPPING_KEY_HANDLE_INVALID)
- TC_TOKEN_ERR (CKR_UNWRAPPING_KEY_SIZE_RANGE)
- TC_TOKEN_ERR (CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT)
- TC_TOKEN_ERR (CKR_USER_ALREADY_LOGGED_IN)
- TC_TOKEN_ERR (CKR_USER_NOT_LOGGED_IN)
- TC_TOKEN_ERR (CKR_USER_PIN_NOT_INITIALIZED)
- TC_TOKEN_ERR (CKR_USER_TYPE_INVALID)
- TC_TOKEN_ERR (CKR_USER_ANOTHER_ALREADY_LOGGED_IN)
- TC_TOKEN_ERR (CKR_USER_TOO_MANY_TYPES)
- TC_TOKEN_ERR (CKR_WRAPPED_KEY_INVALID)
- TC_TOKEN_ERR (CKR_WRAPPED_KEY_LEN_RANGE)
- TC_TOKEN_ERR (CKR_WRAPPING_KEY_HANDLE_INVALID)
- TC_TOKEN_ERR (CKR_WRAPPING_KEY_SIZE_RANGE)
- TC_TOKEN_ERR (CKR_WRAPPING_KEY_TYPE_INCONSISTENT)
- TC_TOKEN_ERR (CKR_RANDOM_SEED_NOT_SUPPORTED)
- TC_TOKEN_ERR (CKR_RANDOM_NO_RNG)
- TC_TOKEN_ERR (CKR_DOMAIN_PARAMS_INVALID)
- TC_TOKEN_ERR (CKR_BUFFER_TOO_SMALL)
- TC_TOKEN_ERR (CKR_SAVED_STATE_INVALID)
- TC_TOKEN_ERR (CKR_INFORMATION_SENSITIVE)
- TC_TOKEN_ERR (CKR_STATE_UNSAVEABLE)
- TC_TOKEN_ERR (CKR_CRYPTOKI_NOT_INITIALIZED)
- TC_TOKEN_ERR (CKR_CRYPTOKI_ALREADY_INITIALIZED)
- TC_TOKEN_ERR (CKR_MUTEX_BAD)
- TC_TOKEN_ERR (CKR_MUTEX_NOT_LOCKED)
- TC_TOKEN_ERR (CKR_NEW_PIN_MODE)
- TC_TOKEN_ERR (CKR_NEXT_OTP)
- TC_TOKEN_ERR (CKR_FUNCTION_REJECTED)
+ TC_TOKEN_ERR(CKR_CANCEL)
+ TC_TOKEN_ERR(CKR_HOST_MEMORY)
+ TC_TOKEN_ERR(CKR_SLOT_ID_INVALID)
+ TC_TOKEN_ERR(CKR_GENERAL_ERROR)
+ TC_TOKEN_ERR(CKR_FUNCTION_FAILED)
+ TC_TOKEN_ERR(CKR_ARGUMENTS_BAD)
+ TC_TOKEN_ERR(CKR_NO_EVENT)
+ TC_TOKEN_ERR(CKR_NEED_TO_CREATE_THREADS)
+ TC_TOKEN_ERR(CKR_CANT_LOCK)
+ TC_TOKEN_ERR(CKR_ATTRIBUTE_READ_ONLY)
+ TC_TOKEN_ERR(CKR_ATTRIBUTE_SENSITIVE)
+ TC_TOKEN_ERR(CKR_ATTRIBUTE_TYPE_INVALID)
+ TC_TOKEN_ERR(CKR_ATTRIBUTE_VALUE_INVALID)
+ TC_TOKEN_ERR(CKR_DATA_INVALID)
+ TC_TOKEN_ERR(CKR_DATA_LEN_RANGE)
+ TC_TOKEN_ERR(CKR_DEVICE_ERROR)
+ TC_TOKEN_ERR(CKR_DEVICE_MEMORY)
+ TC_TOKEN_ERR(CKR_DEVICE_REMOVED)
+ TC_TOKEN_ERR(CKR_ENCRYPTED_DATA_INVALID)
+ TC_TOKEN_ERR(CKR_ENCRYPTED_DATA_LEN_RANGE)
+ TC_TOKEN_ERR(CKR_FUNCTION_CANCELED)
+ TC_TOKEN_ERR(CKR_FUNCTION_NOT_PARALLEL)
+ TC_TOKEN_ERR(CKR_FUNCTION_NOT_SUPPORTED)
+ TC_TOKEN_ERR(CKR_KEY_HANDLE_INVALID)
+ TC_TOKEN_ERR(CKR_KEY_SIZE_RANGE)
+ TC_TOKEN_ERR(CKR_KEY_TYPE_INCONSISTENT)
+ TC_TOKEN_ERR(CKR_KEY_NOT_NEEDED)
+ TC_TOKEN_ERR(CKR_KEY_CHANGED)
+ TC_TOKEN_ERR(CKR_KEY_NEEDED)
+ TC_TOKEN_ERR(CKR_KEY_INDIGESTIBLE)
+ TC_TOKEN_ERR(CKR_KEY_FUNCTION_NOT_PERMITTED)
+ TC_TOKEN_ERR(CKR_KEY_NOT_WRAPPABLE)
+ TC_TOKEN_ERR(CKR_KEY_UNEXTRACTABLE)
+ TC_TOKEN_ERR(CKR_MECHANISM_INVALID)
+ TC_TOKEN_ERR(CKR_MECHANISM_PARAM_INVALID)
+ TC_TOKEN_ERR(CKR_OBJECT_HANDLE_INVALID)
+ TC_TOKEN_ERR(CKR_OPERATION_ACTIVE)
+ TC_TOKEN_ERR(CKR_OPERATION_NOT_INITIALIZED)
+ TC_TOKEN_ERR(CKR_PIN_INCORRECT)
+ TC_TOKEN_ERR(CKR_PIN_INVALID)
+ TC_TOKEN_ERR(CKR_PIN_LEN_RANGE)
+ TC_TOKEN_ERR(CKR_PIN_EXPIRED)
+ TC_TOKEN_ERR(CKR_PIN_LOCKED)
+ TC_TOKEN_ERR(CKR_SESSION_CLOSED)
+ TC_TOKEN_ERR(CKR_SESSION_COUNT)
+ TC_TOKEN_ERR(CKR_SESSION_HANDLE_INVALID)
+ TC_TOKEN_ERR(CKR_SESSION_PARALLEL_NOT_SUPPORTED)
+ TC_TOKEN_ERR(CKR_SESSION_READ_ONLY)
+ TC_TOKEN_ERR(CKR_SESSION_EXISTS)
+ TC_TOKEN_ERR(CKR_SESSION_READ_ONLY_EXISTS)
+ TC_TOKEN_ERR(CKR_SESSION_READ_WRITE_SO_EXISTS)
+ TC_TOKEN_ERR(CKR_SIGNATURE_INVALID)
+ TC_TOKEN_ERR(CKR_SIGNATURE_LEN_RANGE)
+ TC_TOKEN_ERR(CKR_TEMPLATE_INCOMPLETE)
+ TC_TOKEN_ERR(CKR_TEMPLATE_INCONSISTENT)
+ TC_TOKEN_ERR(CKR_TOKEN_NOT_PRESENT)
+ TC_TOKEN_ERR(CKR_TOKEN_NOT_RECOGNIZED)
+ TC_TOKEN_ERR(CKR_TOKEN_WRITE_PROTECTED)
+ TC_TOKEN_ERR(CKR_UNWRAPPING_KEY_HANDLE_INVALID)
+ TC_TOKEN_ERR(CKR_UNWRAPPING_KEY_SIZE_RANGE)
+ TC_TOKEN_ERR(CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT)
+ TC_TOKEN_ERR(CKR_USER_ALREADY_LOGGED_IN)
+ TC_TOKEN_ERR(CKR_USER_NOT_LOGGED_IN)
+ TC_TOKEN_ERR(CKR_USER_PIN_NOT_INITIALIZED)
+ TC_TOKEN_ERR(CKR_USER_TYPE_INVALID)
+ TC_TOKEN_ERR(CKR_USER_ANOTHER_ALREADY_LOGGED_IN)
+ TC_TOKEN_ERR(CKR_USER_TOO_MANY_TYPES)
+ TC_TOKEN_ERR(CKR_WRAPPED_KEY_INVALID)
+ TC_TOKEN_ERR(CKR_WRAPPED_KEY_LEN_RANGE)
+ TC_TOKEN_ERR(CKR_WRAPPING_KEY_HANDLE_INVALID)
+ TC_TOKEN_ERR(CKR_WRAPPING_KEY_SIZE_RANGE)
+ TC_TOKEN_ERR(CKR_WRAPPING_KEY_TYPE_INCONSISTENT)
+ TC_TOKEN_ERR(CKR_RANDOM_SEED_NOT_SUPPORTED)
+ TC_TOKEN_ERR(CKR_RANDOM_NO_RNG)
+ TC_TOKEN_ERR(CKR_DOMAIN_PARAMS_INVALID)
+ TC_TOKEN_ERR(CKR_BUFFER_TOO_SMALL)
+ TC_TOKEN_ERR(CKR_SAVED_STATE_INVALID)
+ TC_TOKEN_ERR(CKR_INFORMATION_SENSITIVE)
+ TC_TOKEN_ERR(CKR_STATE_UNSAVEABLE)
+ TC_TOKEN_ERR(CKR_CRYPTOKI_NOT_INITIALIZED)
+ TC_TOKEN_ERR(CKR_CRYPTOKI_ALREADY_INITIALIZED)
+ TC_TOKEN_ERR(CKR_MUTEX_BAD)
+ TC_TOKEN_ERR(CKR_MUTEX_NOT_LOCKED)
+ TC_TOKEN_ERR(CKR_NEW_PIN_MODE)
+ TC_TOKEN_ERR(CKR_NEXT_OTP)
+ TC_TOKEN_ERR(CKR_FUNCTION_REJECTED)
#undef TC_TOKEN_ERR
};
- for (size_t i = 0; i < array_capacity (ErrorStrings); ++i)
+ for (size_t i = 0; i < array_capacity(ErrorStrings); ++i)
{
if (ErrorStrings[i].ErrorCode == ErrorCode)
return ErrorStrings[i].ErrorString;
@@ -690,9 +698,9 @@ namespace VeraCrypt
}
#ifdef TC_HEADER_Common_Exception
- void Pkcs11Exception::Show (HWND parent) const
+ void Pkcs11Exception::Show(HWND parent) const
{
- string errorString = string (*this);
+ string errorString = string(*this);
if (!errorString.empty())
{
@@ -700,11 +708,11 @@ namespace VeraCrypt
if (SubjectErrorCodeValid)
subjectErrorCode << L": " << SubjectErrorCode;
- if (!GetDictionaryValue (errorString.c_str()))
+ if (!GetDictionaryValue(errorString.c_str()))
{
- if (errorString.find ("CKR_") == 0)
+ if (errorString.find("CKR_") == 0)
{
- errorString = errorString.substr (4);
+ errorString = errorString.substr(4);
for (size_t i = 0; i < errorString.size(); ++i)
{
if (errorString[i] == '_')
@@ -712,17 +720,17 @@ namespace VeraCrypt
}
}
wchar_t err[8192];
- StringCbPrintfW (err, sizeof(err),L"%s:\n\n%hs%s", GetString ("SECURITY_TOKEN_ERROR"), errorString.c_str(), subjectErrorCode.str().c_str());
- ErrorDirect (err, parent);
+ StringCbPrintfW(err, sizeof(err), L"%s:\n\n%hs%s", GetString("SECURITY_TOKEN_ERROR"), errorString.c_str(), subjectErrorCode.str().c_str());
+ ErrorDirect(err, parent);
}
else
{
- wstring err = GetString (errorString.c_str());
+ wstring err = GetString(errorString.c_str());
if (SubjectErrorCodeValid)
err += L"\n\nError code" + subjectErrorCode.str();
- ErrorDirect (err.c_str(), parent);
+ ErrorDirect(err.c_str(), parent);
}
}
}
@@ -738,36 +746,36 @@ namespace VeraCrypt
#ifdef TC_WINDOWS
HMODULE SecurityToken::Pkcs11LibraryHandle;
#else
- void *SecurityToken::Pkcs11LibraryHandle;
+ void* SecurityToken::Pkcs11LibraryHandle;
#endif
#ifdef TC_HEADER_Platform_Exception
- void Pkcs11Exception::Deserialize (shared_ptr <Stream> stream)
+ void Pkcs11Exception::Deserialize(shared_ptr <Stream> stream)
{
- Exception::Deserialize (stream);
- Serializer sr (stream);
+ Exception::Deserialize(stream);
+ Serializer sr(stream);
uint64 code;
- sr.Deserialize ("ErrorCode", code);
- sr.Deserialize ("SubjectErrorCodeValid", SubjectErrorCodeValid);
- sr.Deserialize ("SubjectErrorCode", SubjectErrorCode);
- ErrorCode = (CK_RV) code;
+ sr.Deserialize("ErrorCode", code);
+ sr.Deserialize("SubjectErrorCodeValid", SubjectErrorCodeValid);
+ sr.Deserialize("SubjectErrorCode", SubjectErrorCode);
+ ErrorCode = (CK_RV)code;
}
- void Pkcs11Exception::Serialize (shared_ptr <Stream> stream) const
+ void Pkcs11Exception::Serialize(shared_ptr <Stream> stream) const
{
- Exception::Serialize (stream);
- Serializer sr (stream);
- sr.Serialize ("ErrorCode", (uint64) ErrorCode);
- sr.Serialize ("SubjectErrorCodeValid", SubjectErrorCodeValid);
- sr.Serialize ("SubjectErrorCode", SubjectErrorCode);
+ Exception::Serialize(stream);
+ Serializer sr(stream);
+ sr.Serialize("ErrorCode", (uint64)ErrorCode);
+ sr.Serialize("SubjectErrorCodeValid", SubjectErrorCodeValid);
+ sr.Serialize("SubjectErrorCode", SubjectErrorCode);
}
# define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE)
# undef TC_EXCEPTION_NODECL
# define TC_EXCEPTION_NODECL(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE)
- TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET (SecurityTokenException);
+ TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET(SecurityTokenException);
#endif
}
diff --git a/src/Common/SecurityToken.h b/src/Common/SecurityToken.h
index 6b228895..0d671dcc 100644
--- a/src/Common/SecurityToken.h
+++ b/src/Common/SecurityToken.h
@@ -53,62 +53,55 @@
#define TC_SECURITY_TOKEN_KEYFILE_URL_SLOT L"slot"
#define TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"file"
+#include "Token.h"
+
namespace VeraCrypt
{
- struct SecurityTokenInfo
+ struct SecurityTokenInfo: TokenInfo
{
- CK_SLOT_ID SlotId;
+ virtual BOOL isEditable() const {return true;}
+
CK_FLAGS Flags;
- wstring Label;
string LabelUtf8;
};
- struct SecurityTokenKeyfilePath
+ struct SecurityTokenKeyfile: TokenKeyfile
{
- SecurityTokenKeyfilePath () { }
- SecurityTokenKeyfilePath (const wstring &path) : Path (path) { }
- operator wstring () const { return Path; }
- wstring Path;
- };
+ SecurityTokenKeyfile();
- struct SecurityTokenKeyfile
- {
- SecurityTokenKeyfile () : Handle(CK_INVALID_HANDLE), SlotId(CK_UNAVAILABLE_INFORMATION) { Token.SlotId = CK_UNAVAILABLE_INFORMATION; Token.Flags = 0; }
- SecurityTokenKeyfile (const SecurityTokenKeyfilePath &path);
+ SecurityTokenKeyfile(const TokenKeyfilePath& path);
+
+ operator TokenKeyfilePath () const;
- operator SecurityTokenKeyfilePath () const;
+ void GetKeyfileData(vector<byte>& keyfileData) const;
CK_OBJECT_HANDLE Handle;
- wstring Id;
- string IdUtf8;
- CK_SLOT_ID SlotId;
- SecurityTokenInfo Token;
};
- struct Pkcs11Exception : public Exception
+ struct Pkcs11Exception: public Exception
{
- Pkcs11Exception (CK_RV errorCode = (CK_RV) -1)
- : ErrorCode (errorCode),
- SubjectErrorCodeValid (false),
- SubjectErrorCode( (uint64) -1)
+ Pkcs11Exception(CK_RV errorCode = (CK_RV)-1)
+ : ErrorCode(errorCode),
+ SubjectErrorCodeValid(false),
+ SubjectErrorCode((uint64)-1)
{
}
- Pkcs11Exception (CK_RV errorCode, uint64 subjectErrorCode)
- : ErrorCode (errorCode),
- SubjectErrorCodeValid (true),
- SubjectErrorCode (subjectErrorCode)
+ Pkcs11Exception(CK_RV errorCode, uint64 subjectErrorCode)
+ : ErrorCode(errorCode),
+ SubjectErrorCodeValid(true),
+ SubjectErrorCode(subjectErrorCode)
{
}
#ifdef TC_HEADER_Platform_Exception
- virtual ~Pkcs11Exception () throw () { }
- TC_SERIALIZABLE_EXCEPTION (Pkcs11Exception);
+ virtual ~Pkcs11Exception() throw () { }
+ TC_SERIALIZABLE_EXCEPTION(Pkcs11Exception);
#else
- void Show (HWND parent) const;
+ void Show(HWND parent) const;
#endif
operator string () const;
- CK_RV GetErrorCode () const { return ErrorCode; }
+ CK_RV GetErrorCode() const { return ErrorCode; }
protected:
CK_RV ErrorCode;
@@ -135,24 +128,24 @@ namespace VeraCrypt
#else // !TC_HEADER_Platform_Exception
- struct SecurityTokenLibraryNotInitialized : public Exception
+ struct SecurityTokenLibraryNotInitialized: public Exception
{
- void Show (HWND parent) const { Error (SecurityTokenLibraryPath[0] == 0 ? "NO_PKCS11_MODULE_SPECIFIED" : "PKCS11_MODULE_INIT_FAILED", parent); }
+ void Show(HWND parent) const { Error(SecurityTokenLibraryPath[0] == 0 ? "NO_PKCS11_MODULE_SPECIFIED" : "PKCS11_MODULE_INIT_FAILED", parent); }
};
- struct InvalidSecurityTokenKeyfilePath : public Exception
+ struct InvalidSecurityTokenKeyfilePath: public Exception
{
- void Show (HWND parent) const { Error ("INVALID_TOKEN_KEYFILE_PATH", parent); }
+ void Show(HWND parent) const { Error("INVALID_TOKEN_KEYFILE_PATH", parent); }
};
- struct SecurityTokenKeyfileAlreadyExists : public Exception
+ struct SecurityTokenKeyfileAlreadyExists: public Exception
{
- void Show (HWND parent) const { Error ("TOKEN_KEYFILE_ALREADY_EXISTS", parent); }
+ void Show(HWND parent) const { Error("TOKEN_KEYFILE_ALREADY_EXISTS", parent); }
};
- struct SecurityTokenKeyfileNotFound : public Exception
+ struct SecurityTokenKeyfileNotFound: public Exception
{
- void Show (HWND parent) const { Error ("TOKEN_KEYFILE_NOT_FOUND", parent); }
+ void Show(HWND parent) const { Error("TOKEN_KEYFILE_NOT_FOUND", parent); }
};
#endif // !TC_HEADER_Platform_Exception
@@ -160,7 +153,7 @@ namespace VeraCrypt
struct Pkcs11Session
{
- Pkcs11Session () : Handle (CK_UNAVAILABLE_INFORMATION), UserLoggedIn (false) { }
+ Pkcs11Session(): Handle(CK_UNAVAILABLE_INFORMATION), UserLoggedIn(false) { }
CK_SESSION_HANDLE Handle;
bool UserLoggedIn;
@@ -168,47 +161,46 @@ namespace VeraCrypt
struct GetPinFunctor
{
- virtual ~GetPinFunctor () { }
- virtual void operator() (string &str) = 0;
- virtual void notifyIncorrectPin () = 0;
+ virtual ~GetPinFunctor() { }
+ virtual void operator() (string& str) = 0;
+ virtual void notifyIncorrectPin() = 0;
};
struct SendExceptionFunctor
{
- virtual ~SendExceptionFunctor () { }
- virtual void operator() (const Exception &e) = 0;
+ virtual ~SendExceptionFunctor() { }
+ virtual void operator() (const Exception& e) = 0;
};
class SecurityToken
{
public:
- static void CloseAllSessions () throw ();
- static void CloseLibrary ();
- static void CreateKeyfile (CK_SLOT_ID slotId, vector <byte> &keyfileData, const string &name);
- static void DeleteKeyfile (const SecurityTokenKeyfile &keyfile);
- static vector <SecurityTokenKeyfile> GetAvailableKeyfiles (CK_SLOT_ID *slotIdFilter = nullptr, const wstring keyfileIdFilter = wstring());
- static void GetKeyfileData (const SecurityTokenKeyfile &keyfile, vector <byte> &keyfileData);
- static list <SecurityTokenInfo> GetAvailableTokens ();
- static SecurityTokenInfo GetTokenInfo (CK_SLOT_ID slotId);
+ static void CloseAllSessions() throw ();
+ static void CloseLibrary();
+ static void CreateKeyfile(CK_SLOT_ID slotId, vector <byte>& keyfileData, const string& name);
+ static void DeleteKeyfile(const SecurityTokenKeyfile& keyfile);
+ static vector <SecurityTokenKeyfile> GetAvailableKeyfiles(CK_SLOT_ID* slotIdFilter = nullptr, const wstring keyfileIdFilter = wstring());
+ static list <SecurityTokenInfo> GetAvailableTokens();
+ static SecurityTokenInfo GetTokenInfo(CK_SLOT_ID slotId);
#ifdef TC_WINDOWS
- static void InitLibrary (const wstring &pkcs11LibraryPath, unique_ptr <GetPinFunctor> pinCallback, unique_ptr <SendExceptionFunctor> warningCallback);
+ static void InitLibrary(const wstring& pkcs11LibraryPath, unique_ptr <GetPinFunctor> pinCallback, unique_ptr <SendExceptionFunctor> warningCallback);
#else
- static void InitLibrary (const string &pkcs11LibraryPath, unique_ptr <GetPinFunctor> pinCallback, unique_ptr <SendExceptionFunctor> warningCallback);
+ static void InitLibrary(const string& pkcs11LibraryPath, unique_ptr <GetPinFunctor> pinCallback, unique_ptr <SendExceptionFunctor> warningCallback);
#endif
- static bool IsInitialized () { return Initialized; }
- static bool IsKeyfilePathValid (const wstring &securityTokenKeyfilePath);
+ static bool IsInitialized() { return Initialized; }
+ static bool IsKeyfilePathValid(const wstring& securityTokenKeyfilePath);
static const size_t MaxPasswordLength = 128;
protected:
- static void CloseSession (CK_SLOT_ID slotId);
- static vector <CK_OBJECT_HANDLE> GetObjects (CK_SLOT_ID slotId, CK_ATTRIBUTE_TYPE objectClass);
- static void GetObjectAttribute (CK_SLOT_ID slotId, CK_OBJECT_HANDLE tokenObject, CK_ATTRIBUTE_TYPE attributeType, vector <byte> &attributeValue);
- static list <CK_SLOT_ID> GetTokenSlots ();
- static void Login (CK_SLOT_ID slotId, const char* pin);
- static void LoginUserIfRequired (CK_SLOT_ID slotId);
- static void OpenSession (CK_SLOT_ID slotId);
- static void CheckLibraryStatus ();
+ static void CloseSession(CK_SLOT_ID slotId);
+ static vector <CK_OBJECT_HANDLE> GetObjects(CK_SLOT_ID slotId, CK_ATTRIBUTE_TYPE objectClass);
+ static void GetObjectAttribute(CK_SLOT_ID slotId, CK_OBJECT_HANDLE tokenObject, CK_ATTRIBUTE_TYPE attributeType, vector <byte>& attributeValue);
+ static list <CK_SLOT_ID> GetTokenSlots();
+ static void Login(CK_SLOT_ID slotId, const char* pin);
+ static void LoginUserIfRequired(CK_SLOT_ID slotId);
+ static void OpenSession(CK_SLOT_ID slotId);
+ static void CheckLibraryStatus();
static bool Initialized;
static unique_ptr <GetPinFunctor> PinCallback;
@@ -216,10 +208,12 @@ namespace VeraCrypt
#ifdef TC_WINDOWS
static HMODULE Pkcs11LibraryHandle;
#else
- static void *Pkcs11LibraryHandle;
+ static void* Pkcs11LibraryHandle;
#endif
static map <CK_SLOT_ID, Pkcs11Session> Sessions;
static unique_ptr <SendExceptionFunctor> WarningCallback;
+
+ friend void SecurityTokenKeyfile::GetKeyfileData(vector <byte>& keyfileData) const;
};
}
diff --git a/src/Common/TLVParser.cpp b/src/Common/TLVParser.cpp
new file mode 100644
index 00000000..bda9dec0
--- /dev/null
+++ b/src/Common/TLVParser.cpp
@@ -0,0 +1,179 @@
+#include "TLVParser.h"
+#include <string.h>
+
+using namespace std;
+
+/* TLV node structure creation */
+shared_ptr<TLVNode> TLVParser::TLV_CreateNode()
+{
+ shared_ptr<TLVNode> node= shared_ptr<TLVNode>(new TLVNode);
+ memset(node.get(),0,sizeof(*node));
+ return node;
+}
+
+/* Check if the bit is correct */
+uint16_t TLVParser::CheckBit(unsigned char value, int bit){
+ unsigned char bitvalue[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
+
+ if((bit >= 1)&&(bit <= 8)){
+ if(value & bitvalue[bit-1]) {
+ return (1);
+ }
+ else {
+ return (0);
+ }
+ }
+ else{
+ throw TLVException("FILE:"+string(__FILE__)+"LINE: "+to_string(static_cast<long long>((__LINE__)))+" fonction parameter incorrect! bit=["+to_string(static_cast<long long>(bit)));
+ return(2);
+ }
+}
+
+/* Parsing one TLV node */
+shared_ptr<TLVNode> TLVParser::TLV_Parse_One(unsigned char* buf,int size){
+ int index = 0;
+ int i;
+ unsigned char tag1,tag2,tagsize;
+ unsigned char len,lensize;
+ unsigned char* value;
+ shared_ptr<TLVNode> node = TLV_CreateNode();
+
+ tag1 = tag2 = 0;
+ tagsize = 1;
+ tag1 = buf[index++];
+ if((tag1 & 0x1f) == 0x1f){
+ tagsize++;
+ tag2 = buf[index++];
+ //tag2 b8 must be 0!
+ }
+ if(tagsize == 1) {
+ node->Tag = tag1;
+ }
+ else {
+ node->Tag = (tag1 << 8) + tag2;
+ }
+ node->TagSize = tagsize;
+
+ //SubFlag
+ node->SubFlag = CheckBit(tag1,6);
+
+ //L zone
+ len = 0;
+ lensize = 1;
+ len = buf[index++];
+ if(CheckBit(len,8) == 0){
+ node->Length = len;
+ }
+ else{
+ lensize = len & 0x7f;
+ len = 0;
+ for(i=0;i<lensize;i++){
+ len += (uint16_t)buf[index++] << (i*8);
+ }
+ lensize++;
+ }
+ node->Length = len;
+ node->LengthSize = lensize;
+
+ //V zone
+ value = new unsigned char[len];
+ std::copy(buf+index,buf+index+len,value);
+ node->Value = value;
+ index += len;
+
+ if(index < size){
+ node->MoreFlag = 1;
+ }
+ else if(index == size){
+ node->MoreFlag = 0;
+ }
+ else{
+ throw TLVException("Parse Error! index="+to_string(static_cast<long long>(index))+"size="+to_string(static_cast<long long>(size)));
+ }
+
+ return node;
+}
+
+/* Parsing all sub-nodes (in width not in depth) of a given parent node */
+int TLVParser::TLV_Parse_SubNodes(shared_ptr<TLVNode> parent){
+ int sublen = 0;
+ int i;
+
+ //No sub-nodes
+ if(parent->SubFlag == 0)
+ return 0;
+
+ for(i=0;i<parent->SubCount;i++)
+ {
+ sublen += (parent->Sub[i]->TagSize + parent->Sub[i]->Length + parent->Sub[i]->LengthSize);
+ }
+
+ if(sublen < parent->Length)
+ {
+ shared_ptr<TLVNode> subnode = TLV_Parse_One(parent->Value+sublen,parent->Length-sublen);
+ parent->Sub[parent->SubCount++] = subnode;
+ return subnode->MoreFlag;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/* Recursive function to parse all nodes starting from a root parent node */
+void TLVParser::TLV_Parse_Sub(shared_ptr<TLVNode> parent)
+{
+ int i;
+ if(parent->SubFlag != 0)
+ {
+ //Parse all sub nodes.
+ while(TLV_Parse_SubNodes(parent) != 0);
+
+ for(i=0;i<parent->SubCount;i++)
+ {
+ if(parent->Sub[i]->SubFlag != 0)
+ {
+ TLV_Parse_Sub(parent->Sub[i]);
+ }
+ }
+ }
+ return;
+}
+
+/* Parsing TLV from a buffer and constructing TLV structure */
+shared_ptr<TLVNode> TLVParser::TLV_Parse(unsigned char* buf,int size)
+{
+ shared_ptr<TLVNode> node = TLV_Parse_One(buf,size);
+ TLV_Parse_Sub(node);
+
+ return node;
+}
+
+/* Finding a TLV node with a particular tag */
+shared_ptr<TLVNode> TLVParser::TLV_Find(shared_ptr<TLVNode> node,uint16_t tag){
+ int i;
+ shared_ptr<TLVNode> tmpnode;
+ if(node->Tag == tag)
+ {
+ return node;
+ }
+ for(i=0;i<node->SubCount;i++)
+ {
+ tmpnode = NULL;
+ tmpnode = TLV_Find(node->Sub[i],tag);
+ if(tmpnode != NULL){
+ return tmpnode;
+ }
+ }
+ if(node->Next)
+ {
+ tmpnode = NULL;
+ tmpnode = TLV_Find(node->Next,tag);
+ if(tmpnode != NULL){
+ return tmpnode;
+ }
+ }
+
+ return nullptr;
+}
+
diff --git a/src/Common/TLVParser.h b/src/Common/TLVParser.h
new file mode 100644
index 00000000..e25e429f
--- /dev/null
+++ b/src/Common/TLVParser.h
@@ -0,0 +1,80 @@
+//
+// Created by bshp on 1/20/23.
+//
+
+#ifndef ICC_EXTRACTOR_TLVPARSER_H
+#define ICC_EXTRACTOR_TLVPARSER_H
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <algorithm>
+#include <string>
+#include <memory>
+#include "iostream"
+#include "Tcdefs.h"
+using namespace std;
+struct TLVNode{
+ uint16_t Tag; /* T */
+ uint16_t Length; /* L */
+ unsigned char* Value; /* V */
+ unsigned char TagSize;
+ unsigned char LengthSize;
+ uint16_t MoreFlag; /* Used In Sub */
+ uint16_t SubFlag; /* Does it have sub-nodes? */
+ uint16_t SubCount;
+ shared_ptr<TLVNode> Sub[256];
+ shared_ptr<TLVNode> Next;
+
+ ~TLVNode() {
+ burn(Value, Length);
+ delete Value;
+ }
+};
+
+class TLVParser{
+private :
+
+ /* TLV node structure creation */
+ static shared_ptr<TLVNode> TLV_CreateNode();
+
+ /* Check if the bit is correct */
+ static uint16_t CheckBit(unsigned char value, int bit);
+
+ /* Parsing one TLV node */
+ static shared_ptr<TLVNode> TLV_Parse_One(unsigned char* buf,int size);
+
+ /* Parsing all TLV nodes */
+ static int TLV_Parse_SubNodes(shared_ptr<TLVNode> parent);
+
+ /* Parsing all sub-nodes (in width not in depth) of a given parent node */
+ static int TLV_Parse_All(shared_ptr<TLVNode> parent);
+
+ /* Recursive function to parse all nodes starting from a root parent node */
+ static void TLV_Parse_Sub(shared_ptr<TLVNode> parent);
+
+public:
+
+ /* Parsing TLV from a buffer and constructing TLV structure */
+ static shared_ptr<TLVNode> TLV_Parse(unsigned char* buf,int size);
+
+ /* Finding a TLV node with a particular tag */
+ static shared_ptr<TLVNode> TLV_Find(shared_ptr<TLVNode> node,uint16_t tag);
+};
+
+/* The definition of the exception class related to the TLV parsing */
+class TLVException
+{
+public:
+ TLVException(std::string errormessage): m_errormessage(errormessage){}
+
+ /* Get the error message */
+ inline std::string ErrorMessage() const
+ {
+ return m_errormessage;
+ }
+
+protected:
+ std::string m_errormessage;
+};
+
+#endif //ICC_EXTRACTOR_TLVPARSER_H
diff --git a/src/Common/Token.cpp b/src/Common/Token.cpp
new file mode 100644
index 00000000..5da677de
--- /dev/null
+++ b/src/Common/Token.cpp
@@ -0,0 +1,82 @@
+#include "Token.h"
+#include "Platform/Finally.h"
+#include "Platform/ForEach.h"
+
+#if !defined(TC_WINDOWS) || defined(TC_PROTOTYPE)
+#include "Platform/SerializerFactory.h"
+#include "Platform/StringConverter.h"
+#include "Platform/SystemException.h"
+#else
+#include "Dictionary.h"
+#include "Language.h"
+#endif
+
+#include <vector>
+#include <algorithm>
+#include <memory>
+
+#include "SecurityToken.h"
+#include "EMVToken.h"
+#include "iostream"
+
+using namespace std;
+
+namespace VeraCrypt
+{
+ vector<shared_ptr<TokenKeyfile>> Token::GetAvailableKeyfiles(bool EMVOption) {
+ vector<shared_ptr<TokenKeyfile>> availableKeyfiles;
+ bool securityTokenLibraryInitialized = true;
+
+ try{
+ foreach (SecurityTokenKeyfile k, SecurityToken::GetAvailableKeyfiles()) {
+ availableKeyfiles.push_back(shared_ptr<TokenKeyfile>(new SecurityTokenKeyfile(k)));
+ }
+ } catch (SecurityTokenLibraryNotInitialized){
+ securityTokenLibraryInitialized = false;
+ }
+
+ if(EMVOption){
+ foreach (EMVTokenKeyfile k, EMVToken::GetAvailableKeyfiles()) {
+ availableKeyfiles.push_back(shared_ptr<TokenKeyfile>(new EMVTokenKeyfile(k)));
+ }
+ }
+
+ if(availableKeyfiles.size() == 0 && ! securityTokenLibraryInitialized){
+ throw SecurityTokenLibraryNotInitialized();
+ }
+
+ return availableKeyfiles;
+ }
+
+ bool Token::IsKeyfilePathValid(const wstring& tokenKeyfilePath, bool EMVOption)
+ {
+ if(EMVOption){
+ return SecurityToken::IsKeyfilePathValid(tokenKeyfilePath) || EMVToken::IsKeyfilePathValid(tokenKeyfilePath);
+ }
+ return SecurityToken::IsKeyfilePathValid(tokenKeyfilePath);
+ }
+
+ list <shared_ptr<TokenInfo>> Token::GetAvailableTokens()
+ {
+ list <shared_ptr<TokenInfo>> availableTokens;
+ foreach(SecurityTokenInfo securityToken, SecurityToken::GetAvailableTokens()){
+ availableTokens.push_back(shared_ptr<TokenInfo>(new SecurityTokenInfo(std::move(securityToken))));
+ }
+
+ return availableTokens ;
+ }
+
+ shared_ptr<TokenKeyfile> Token::getTokenKeyfile(const TokenKeyfilePath path){
+ shared_ptr<TokenKeyfile> tokenKeyfile;
+
+ if(SecurityToken::IsKeyfilePathValid(path)){
+ tokenKeyfile = shared_ptr<TokenKeyfile>(new SecurityTokenKeyfile(path));
+ } else {
+ if(EMVToken::IsKeyfilePathValid(path)){
+ tokenKeyfile = shared_ptr<TokenKeyfile>(new EMVTokenKeyfile(path));
+ }
+ }
+
+ return tokenKeyfile;
+ }
+} \ No newline at end of file
diff --git a/src/Common/Token.h b/src/Common/Token.h
new file mode 100644
index 00000000..28c6a489
--- /dev/null
+++ b/src/Common/Token.h
@@ -0,0 +1,57 @@
+#ifndef TC_HEADER_Common_Token
+#define TC_HEADER_Common_Token
+
+#include "Platform/PlatformBase.h"
+
+#if defined (TC_WINDOWS) && !defined (TC_PROTOTYPE)
+# include "Exception.h"
+#else
+
+# include "Platform/Exception.h"
+
+#endif
+
+#include <string>
+
+#define UNAVAILABLE_SLOT ~0UL
+
+namespace VeraCrypt {
+
+ struct TokenKeyfilePath {
+ TokenKeyfilePath(const wstring& path): Path(path) { }
+ operator wstring () const { return Path; }
+
+ wstring Path; //Complete path
+
+ };
+ struct TokenInfo {
+ TokenInfo() {}
+ virtual ~TokenInfo() {}
+
+ virtual BOOL isEditable() const=0;
+
+ unsigned long int SlotId;
+ wstring Label; //Card name
+ };
+
+ struct TokenKeyfile {
+ virtual operator TokenKeyfilePath () const = 0;
+ virtual void GetKeyfileData(vector <byte>& keyfileData) const = 0;
+
+ string IdUtf8; // Was used in SecurityToken to compare with the file name from a PKCS11 card, remove from token ?
+ shared_ptr<TokenInfo> Token;
+ wstring Id;
+ };
+
+ class Token {
+ public:
+ static vector<shared_ptr<TokenKeyfile>> GetAvailableKeyfiles(bool EMVOption);
+ static bool IsKeyfilePathValid(const wstring& tokenKeyfilePath, bool EMVOption);
+ static list <shared_ptr<TokenInfo>> GetAvailableTokens(); // List available token to write
+ static shared_ptr<TokenKeyfile> getTokenKeyfile(const TokenKeyfilePath path);
+ };
+
+};
+
+
+#endif //TC_HEADER_Common_Token
diff --git a/src/Core/Core.h b/src/Core/Core.h
index 3a2235a5..d2a4c593 100644
--- a/src/Core/Core.h
+++ b/src/Core/Core.h
@@ -82,9 +82,10 @@ namespace VeraCrypt
shared_ptr <KeyfileList> m_newKeyfiles;
shared_ptr <Pkcs5Kdf> m_newPkcs5Kdf;
int m_wipeCount;
- ChangePasswordThreadRoutine(shared_ptr <VolumePath> volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> newPassword, int newPim, shared_ptr <KeyfileList> newKeyfiles, shared_ptr <Pkcs5Kdf> newPkcs5Kdf, int wipeCount) : m_volumePath(volumePath), m_preserveTimestamps(preserveTimestamps), m_password(password), m_pim(pim), m_kdf(kdf), m_truecryptMode(truecryptMode), m_keyfiles(keyfiles), m_newPassword(newPassword), m_newPim(newPim), m_newKeyfiles(newKeyfiles), m_newPkcs5Kdf(newPkcs5Kdf), m_wipeCount(wipeCount) {}
+ bool m_emvoption;
+ ChangePasswordThreadRoutine(shared_ptr <VolumePath> volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> newPassword, int newPim, shared_ptr <KeyfileList> newKeyfiles, shared_ptr <Pkcs5Kdf> newPkcs5Kdf, int wipeCount, bool EMVOption) : m_volumePath(volumePath), m_preserveTimestamps(preserveTimestamps), m_password(password), m_pim(pim), m_kdf(kdf), m_truecryptMode(truecryptMode), m_keyfiles(keyfiles), m_newPassword(newPassword), m_newPim(newPim), m_newKeyfiles(newKeyfiles), m_newPkcs5Kdf(newPkcs5Kdf), m_wipeCount(wipeCount), m_emvoption(EMVOption) {}
virtual ~ChangePasswordThreadRoutine() { }
- virtual void ExecutionCode(void) { Core->ChangePassword(m_volumePath, m_preserveTimestamps, m_password, m_pim, m_kdf, m_truecryptMode, m_keyfiles, m_newPassword, m_newPim, m_newKeyfiles, m_newPkcs5Kdf, m_wipeCount); }
+ virtual void ExecutionCode(void) { Core->ChangePassword(m_volumePath, m_preserveTimestamps, m_password, m_pim, m_kdf, m_truecryptMode, m_keyfiles, m_newPassword, m_newPim, m_newKeyfiles, m_emvoption, m_newPkcs5Kdf, m_wipeCount); }
};
class OpenVolumeThreadRoutine : public WaitThreadRoutine
@@ -107,15 +108,16 @@ namespace VeraCrypt
bool m_useBackupHeaders;
bool m_partitionInSystemEncryptionScope;
shared_ptr <Volume> m_pVolume;
+ bool m_emvoption;
- OpenVolumeThreadRoutine(shared_ptr <VolumePath> volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr<Pkcs5Kdf> Kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr <VolumePassword> protectionPassword = shared_ptr <VolumePassword> (), int protectionPim = 0, shared_ptr<Pkcs5Kdf> protectionKdf = shared_ptr<Pkcs5Kdf> (), shared_ptr <KeyfileList> protectionKeyfiles = shared_ptr <KeyfileList> (), bool sharedAccessAllowed = false, VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false):
+ OpenVolumeThreadRoutine(shared_ptr <VolumePath> volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr<Pkcs5Kdf> Kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, bool EMVOption, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr <VolumePassword> protectionPassword = shared_ptr <VolumePassword> (), int protectionPim = 0, shared_ptr<Pkcs5Kdf> protectionKdf = shared_ptr<Pkcs5Kdf> (), shared_ptr <KeyfileList> protectionKeyfiles = shared_ptr <KeyfileList> (), bool sharedAccessAllowed = false, VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false):
m_volumePath(volumePath), m_preserveTimestamps(preserveTimestamps), m_password(password), m_pim(pim), m_Kdf(Kdf), m_truecryptMode(truecryptMode), m_keyfiles(keyfiles),
m_protection(protection), m_protectionPassword(protectionPassword), m_protectionPim(protectionPim), m_protectionKdf(protectionKdf), m_protectionKeyfiles(protectionKeyfiles), m_sharedAccessAllowed(sharedAccessAllowed), m_volumeType(volumeType),m_useBackupHeaders(useBackupHeaders),
- m_partitionInSystemEncryptionScope(partitionInSystemEncryptionScope) {}
+ m_partitionInSystemEncryptionScope(partitionInSystemEncryptionScope), m_emvoption(EMVOption) {}
~OpenVolumeThreadRoutine() {}
- virtual void ExecutionCode(void) { m_pVolume = Core->OpenVolume(m_volumePath,m_preserveTimestamps,m_password,m_pim,m_Kdf,m_truecryptMode,m_keyfiles, m_protection,m_protectionPassword,m_protectionPim,m_protectionKdf, m_protectionKeyfiles,m_sharedAccessAllowed,m_volumeType,m_useBackupHeaders, m_partitionInSystemEncryptionScope); }
+ virtual void ExecutionCode(void) { m_pVolume = Core->OpenVolume(m_volumePath,m_preserveTimestamps,m_password,m_pim,m_Kdf,m_truecryptMode,m_keyfiles, m_emvoption, m_protection,m_protectionPassword,m_protectionPim,m_protectionKdf, m_protectionKeyfiles,m_sharedAccessAllowed,m_volumeType,m_useBackupHeaders, m_partitionInSystemEncryptionScope); }
};
@@ -127,10 +129,11 @@ namespace VeraCrypt
shared_ptr <VolumePassword> m_password;
int m_pim;
shared_ptr <KeyfileList> m_keyfiles;
- ReEncryptHeaderThreadRoutine(const BufferPtr &newHeaderBuffer, shared_ptr <VolumeHeader> header, shared_ptr <VolumePassword> password, int pim, shared_ptr <KeyfileList> keyfiles)
- : m_newHeaderBuffer(newHeaderBuffer), m_header(header), m_password(password), m_pim(pim), m_keyfiles(keyfiles) {}
+ bool m_emvoption;
+ ReEncryptHeaderThreadRoutine(const BufferPtr &newHeaderBuffer, shared_ptr <VolumeHeader> header, shared_ptr <VolumePassword> password, int pim, shared_ptr <KeyfileList> keyfiles, bool EMVOption)
+ : m_newHeaderBuffer(newHeaderBuffer), m_header(header), m_password(password), m_pim(pim), m_keyfiles(keyfiles), m_emvoption(EMVOption) {}
virtual ~ReEncryptHeaderThreadRoutine() { }
- virtual void ExecutionCode(void) { Core->ReEncryptVolumeHeaderWithNewSalt (m_newHeaderBuffer, m_header, m_password, m_pim, m_keyfiles); }
+ virtual void ExecutionCode(void) { Core->ReEncryptVolumeHeaderWithNewSalt (m_newHeaderBuffer, m_header, m_password, m_pim, m_keyfiles, m_emvoption); }
};
class DecryptThreadRoutine : public WaitThreadRoutine
diff --git a/src/Core/CoreBase.cpp b/src/Core/CoreBase.cpp
index 29bfb74d..ce6e0c20 100644
--- a/src/Core/CoreBase.cpp
+++ b/src/Core/CoreBase.cpp
@@ -30,7 +30,7 @@ namespace VeraCrypt
{
}
- void CoreBase::ChangePassword (shared_ptr <Volume> openVolume, shared_ptr <VolumePassword> newPassword, int newPim, shared_ptr <KeyfileList> newKeyfiles, shared_ptr <Pkcs5Kdf> newPkcs5Kdf, int wipeCount) const
+ void CoreBase::ChangePassword (shared_ptr <Volume> openVolume, shared_ptr <VolumePassword> newPassword, int newPim, shared_ptr <KeyfileList> newKeyfiles, bool EMVOption, shared_ptr <Pkcs5Kdf> newPkcs5Kdf, int wipeCount) const
{
if ((!newPassword || newPassword->Size() < 1) && (!newKeyfiles || newKeyfiles->empty()))
throw PasswordEmpty (SRC_POS);
@@ -58,7 +58,7 @@ namespace VeraCrypt
SecureBuffer newSalt (openVolume->GetSaltSize());
SecureBuffer newHeaderKey (VolumeHeader::GetLargestSerializedKeySize());
- shared_ptr <VolumePassword> password (Keyfile::ApplyListToPassword (newKeyfiles, newPassword));
+ shared_ptr <VolumePassword> password (Keyfile::ApplyListToPassword (newKeyfiles, newPassword, EMVOption));
bool backupHeader = false;
while (true)
@@ -83,10 +83,10 @@ namespace VeraCrypt
}
}
- void CoreBase::ChangePassword (shared_ptr <VolumePath> volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> newPassword, int newPim, shared_ptr <KeyfileList> newKeyfiles, shared_ptr <Pkcs5Kdf> newPkcs5Kdf, int wipeCount) const
+ void CoreBase::ChangePassword (shared_ptr <VolumePath> volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> newPassword, int newPim, shared_ptr <KeyfileList> newKeyfiles, bool EMVOption, shared_ptr <Pkcs5Kdf> newPkcs5Kdf, int wipeCount) const
{
- shared_ptr <Volume> volume = OpenVolume (volumePath, preserveTimestamps, password, pim, kdf, truecryptMode, keyfiles);
- ChangePassword (volume, newPassword, newPim, newKeyfiles, newPkcs5Kdf, wipeCount);
+ shared_ptr <Volume> volume = OpenVolume (volumePath, preserveTimestamps, password, pim, kdf, truecryptMode, keyfiles, EMVOption);
+ ChangePassword (volume, newPassword, newPim, newKeyfiles, EMVOption, newPkcs5Kdf, wipeCount);
}
void CoreBase::CoalesceSlotNumberAndMountPoint (MountOptions &options) const
@@ -261,10 +261,10 @@ namespace VeraCrypt
return false;
}
- shared_ptr <Volume> CoreBase::OpenVolume (shared_ptr <VolumePath> volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr<Pkcs5Kdf> kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, VolumeProtection::Enum protection, shared_ptr <VolumePassword> protectionPassword, int protectionPim, shared_ptr<Pkcs5Kdf> protectionKdf, shared_ptr <KeyfileList> protectionKeyfiles, bool sharedAccessAllowed, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope) const
+ shared_ptr <Volume> CoreBase::OpenVolume (shared_ptr <VolumePath> volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr<Pkcs5Kdf> kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, bool EMVOption, VolumeProtection::Enum protection, shared_ptr <VolumePassword> protectionPassword, int protectionPim, shared_ptr<Pkcs5Kdf> protectionKdf, shared_ptr <KeyfileList> protectionKeyfiles, bool sharedAccessAllowed, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope) const
{
make_shared_auto (Volume, volume);
- volume->Open (*volumePath, preserveTimestamps, password, pim, kdf, truecryptMode, keyfiles, protection, protectionPassword, protectionPim, protectionKdf, protectionKeyfiles, sharedAccessAllowed, volumeType, useBackupHeaders, partitionInSystemEncryptionScope);
+ volume->Open (*volumePath, preserveTimestamps, password, pim, kdf, truecryptMode, keyfiles, EMVOption, protection, protectionPassword, protectionPim, protectionKdf, protectionKeyfiles, sharedAccessAllowed, volumeType, useBackupHeaders, partitionInSystemEncryptionScope);
return volume;
}
@@ -279,7 +279,7 @@ namespace VeraCrypt
encryptionAlgorithm->GetMode()->SetKey (modeKey);
}
- void CoreBase::ReEncryptVolumeHeaderWithNewSalt (const BufferPtr &newHeaderBuffer, shared_ptr <VolumeHeader> header, shared_ptr <VolumePassword> password, int pim, shared_ptr <KeyfileList> keyfiles) const
+ void CoreBase::ReEncryptVolumeHeaderWithNewSalt (const BufferPtr &newHeaderBuffer, shared_ptr <VolumeHeader> header, shared_ptr <VolumePassword> password, int pim, shared_ptr <KeyfileList> keyfiles, bool EMVOption) const
{
shared_ptr <Pkcs5Kdf> pkcs5Kdf = header->GetPkcs5Kdf();
@@ -288,7 +288,7 @@ namespace VeraCrypt
SecureBuffer newSalt (header->GetSaltSize());
SecureBuffer newHeaderKey (VolumeHeader::GetLargestSerializedKeySize());
- shared_ptr <VolumePassword> passwordKey (Keyfile::ApplyListToPassword (keyfiles, password));
+ shared_ptr <VolumePassword> passwordKey (Keyfile::ApplyListToPassword (keyfiles, password, EMVOption));
RandomNumberGenerator::GetData (newSalt);
pkcs5Kdf->DeriveKey (newHeaderKey, *passwordKey, pim, newSalt);
diff --git a/src/Core/CoreBase.h b/src/Core/CoreBase.h
index 8f41ddd8..8df644c3 100644
--- a/src/Core/CoreBase.h
+++ b/src/Core/CoreBase.h
@@ -33,8 +33,8 @@ namespace VeraCrypt
public:
virtual ~CoreBase ();
- virtual void ChangePassword (shared_ptr <Volume> openVolume, shared_ptr <VolumePassword> newPassword, int newPim, shared_ptr <KeyfileList> newKeyfiles, shared_ptr <Pkcs5Kdf> newPkcs5Kdf = shared_ptr <Pkcs5Kdf> (), int wipeCount = PRAND_HEADER_WIPE_PASSES) const;
- virtual void ChangePassword (shared_ptr <VolumePath> volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> newPassword, int newPim, shared_ptr <KeyfileList> newKeyfiles, shared_ptr <Pkcs5Kdf> newPkcs5Kdf = shared_ptr <Pkcs5Kdf> (), int wipeCount = PRAND_HEADER_WIPE_PASSES) const;
+ virtual void ChangePassword (shared_ptr <Volume> openVolume, shared_ptr <VolumePassword> newPassword, int newPim, shared_ptr <KeyfileList> newKeyfiles, bool EMVOption, shared_ptr <Pkcs5Kdf> newPkcs5Kdf = shared_ptr <Pkcs5Kdf> (), int wipeCount = PRAND_HEADER_WIPE_PASSES) const;
+ virtual void ChangePassword (shared_ptr <VolumePath> volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> newPassword, int newPim, shared_ptr <KeyfileList> newKeyfiles, bool EMVOption, shared_ptr <Pkcs5Kdf> newPkcs5Kdf = shared_ptr <Pkcs5Kdf> (), int wipeCount = PRAND_HEADER_WIPE_PASSES) const;
virtual void CheckFilesystem (shared_ptr <VolumeInfo> mountedVolume, bool repair = false) const = 0;
virtual void CoalesceSlotNumberAndMountPoint (MountOptions &options) const;
virtual void CreateKeyfile (const FilePath &keyfilePath) const;
@@ -69,9 +69,9 @@ namespace VeraCrypt
virtual bool IsVolumeMounted (const VolumePath &volumePath) const;
virtual VolumeSlotNumber MountPointToSlotNumber (const DirectoryPath &mountPoint) const = 0;
virtual shared_ptr <VolumeInfo> MountVolume (MountOptions &options) = 0;
- virtual shared_ptr <Volume> OpenVolume (shared_ptr <VolumePath> volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr<Pkcs5Kdf> Kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr <VolumePassword> protectionPassword = shared_ptr <VolumePassword> (), int protectionPim = 0, shared_ptr<Pkcs5Kdf> protectionKdf = shared_ptr<Pkcs5Kdf> (), shared_ptr <KeyfileList> protectionKeyfiles = shared_ptr <KeyfileList> (), bool sharedAccessAllowed = false, VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false) const;
+ virtual shared_ptr <Volume> OpenVolume (shared_ptr <VolumePath> volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr<Pkcs5Kdf> Kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, bool EMVOption, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr <VolumePassword> protectionPassword = shared_ptr <VolumePassword> (), int protectionPim = 0, shared_ptr<Pkcs5Kdf> protectionKdf = shared_ptr<Pkcs5Kdf> (), shared_ptr <KeyfileList> protectionKeyfiles = shared_ptr <KeyfileList> (), bool sharedAccessAllowed = false, VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false) const;
virtual void RandomizeEncryptionAlgorithmKey (shared_ptr <EncryptionAlgorithm> encryptionAlgorithm) const;
- virtual void ReEncryptVolumeHeaderWithNewSalt (const BufferPtr &newHeaderBuffer, shared_ptr <VolumeHeader> header, shared_ptr <VolumePassword> password, int pim, shared_ptr <KeyfileList> keyfiles) const;
+ virtual void ReEncryptVolumeHeaderWithNewSalt (const BufferPtr &newHeaderBuffer, shared_ptr <VolumeHeader> header, shared_ptr <VolumePassword> password, int pim, shared_ptr <KeyfileList> keyfiles, bool EMVOption) const;
virtual void SetAdminPasswordCallback (shared_ptr <GetStringFunctor> functor) { }
virtual void SetApplicationExecutablePath (const FilePath &path) { ApplicationExecutablePath = path; }
virtual void SetFileOwner (const FilesystemPath &path, const UserId &owner) const = 0;
diff --git a/src/Core/MountOptions.h b/src/Core/MountOptions.h
index 83a8bffc..6daecadd 100644
--- a/src/Core/MountOptions.h
+++ b/src/Core/MountOptions.h
@@ -73,6 +73,7 @@ namespace VeraCrypt
VolumeSlotNumber SlotNumber;
bool UseBackupHeaders;
bool TrueCryptMode;
+ bool EMVOption;
protected:
void CopyFrom (const MountOptions &other);
diff --git a/src/Core/Unix/CoreServiceProxy.h b/src/Core/Unix/CoreServiceProxy.h
index f5bbae3d..63b208a8 100644
--- a/src/Core/Unix/CoreServiceProxy.h
+++ b/src/Core/Unix/CoreServiceProxy.h
@@ -98,11 +98,11 @@ namespace VeraCrypt
{
MountOptions newOptions = options;
- newOptions.Password = Keyfile::ApplyListToPassword (options.Keyfiles, options.Password);
+ newOptions.Password = Keyfile::ApplyListToPassword (options.Keyfiles, options.Password, options.EMVOption);
if (newOptions.Keyfiles)
newOptions.Keyfiles->clear();
- newOptions.ProtectionPassword = Keyfile::ApplyListToPassword (options.ProtectionKeyfiles, options.ProtectionPassword);
+ newOptions.ProtectionPassword = Keyfile::ApplyListToPassword (options.ProtectionKeyfiles, options.ProtectionPassword, options.EMVOption);
if (newOptions.ProtectionKeyfiles)
newOptions.ProtectionKeyfiles->clear();
@@ -126,7 +126,7 @@ namespace VeraCrypt
if (options.CachePassword
&& ((options.Password && !options.Password->IsEmpty()) || (options.Keyfiles && !options.Keyfiles->empty())))
{
- VolumePasswordCache::Store (*Keyfile::ApplyListToPassword (options.Keyfiles, options.Password));
+ VolumePasswordCache::Store (*Keyfile::ApplyListToPassword (options.Keyfiles, options.Password, options.EMVOption));
}
}
diff --git a/src/Core/Unix/CoreUnix.cpp b/src/Core/Unix/CoreUnix.cpp
index 56382c18..3b495e5f 100644
--- a/src/Core/Unix/CoreUnix.cpp
+++ b/src/Core/Unix/CoreUnix.cpp
@@ -548,6 +548,7 @@ namespace VeraCrypt
options.Kdf,
options.TrueCryptMode,
options.Keyfiles,
+ options.EMVOption,
options.Protection,
options.ProtectionPassword,
options.ProtectionPim,
diff --git a/src/Core/VolumeCreator.cpp b/src/Core/VolumeCreator.cpp
index 1cc45b27..8a4baeed 100644
--- a/src/Core/VolumeCreator.cpp
+++ b/src/Core/VolumeCreator.cpp
@@ -307,7 +307,7 @@ namespace VeraCrypt
// Header key
HeaderKey.Allocate (VolumeHeader::GetLargestSerializedKeySize());
- PasswordKey = Keyfile::ApplyListToPassword (options->Keyfiles, options->Password);
+ PasswordKey = Keyfile::ApplyListToPassword (options->Keyfiles, options->Password, options->EMVOption);
options->VolumeHeaderKdf->DeriveKey (HeaderKey, *PasswordKey, options->Pim, salt);
headerOptions.HeaderKey = HeaderKey;
diff --git a/src/Core/VolumeCreator.h b/src/Core/VolumeCreator.h
index 3e051bc7..dc742911 100644
--- a/src/Core/VolumeCreator.h
+++ b/src/Core/VolumeCreator.h
@@ -38,6 +38,7 @@ namespace VeraCrypt
shared_ptr <Pkcs5Kdf> VolumeHeaderKdf;
shared_ptr <EncryptionAlgorithm> EA;
bool Quick;
+ bool EMVOption;
struct FilesystemType
{
diff --git a/src/ExpandVolume/ExpandVolume.vcxproj b/src/ExpandVolume/ExpandVolume.vcxproj
index c4f8ce09..c182afe5 100644
--- a/src/ExpandVolume/ExpandVolume.vcxproj
+++ b/src/ExpandVolume/ExpandVolume.vcxproj
@@ -245,7 +245,7 @@ copy Debug\VeraCryptExpander.exe "..\Debug\Setup Files" &gt;NUL:
<DisableSpecificWarnings>4311;4131;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
- <AdditionalDependencies>..\Crypto\x64\Debug\crypto.lib;..\Common\x64\Debug\Zip.lib;..\Common\x64\Debug\lzma.lib;mpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>..\Crypto\x64\Debug\crypto.lib;..\Common\x64\Debug\Zip.lib;..\Common\x64\Debug\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)VeraCryptExpander.exe</OutputFile>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<DelayLoadDLLs>mpr.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
@@ -336,7 +336,7 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCryptExpander-x64.exe" &gt;NUL:
<DisableSpecificWarnings>4311;4131;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
- <AdditionalDependencies>..\Crypto\Release\crypto.lib;..\Common\Release\Zip.lib;..\Common\Release\lzma.lib;mpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>..\Crypto\Release\crypto.lib;..\Common\Release\Zip.lib;..\Common\Release\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)VeraCryptExpander.exe</OutputFile>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<DelayLoadDLLs>mpr.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
@@ -428,7 +428,7 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCryptExpander-x64.exe" &gt;NUL:
<DisableSpecificWarnings>4311;4131;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
- <AdditionalDependencies>..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)VeraCryptExpander.exe</OutputFile>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<DelayLoadDLLs>mpr.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
@@ -476,7 +476,7 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCryptExpander-x64.exe" &gt;NUL:
<DisableSpecificWarnings>4311;4131;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
- <AdditionalDependencies>..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)VeraCryptExpander.exe</OutputFile>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<DelayLoadDLLs>mpr.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
@@ -575,6 +575,10 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCryptExpander-x64.exe" &gt;NUL:
</ProjectReference>
</ItemGroup>
<ItemGroup>
+ <ClCompile Include="..\Common\EMVToken.cpp" />
+ <ClCompile Include="..\Common\IccDataExtractor.cpp" />
+ <ClCompile Include="..\Common\TLVParser.cpp" />
+ <ClCompile Include="..\Common\Token.cpp" />
<ClCompile Include="..\Setup\SelfExtract.c" />
<ClCompile Include="DlgExpandVolume.cpp" />
<ClCompile Include="ExpandVolume.c" />
@@ -655,6 +659,10 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCryptExpander-x64.exe" &gt;NUL:
</ClCompile>
</ItemGroup>
<ItemGroup>
+ <ClInclude Include="..\Common\EMVToken.h" />
+ <ClInclude Include="..\Common\IccDataExtractor.h" />
+ <ClInclude Include="..\Common\TLVParser.h" />
+ <ClInclude Include="..\Common\Token.h" />
<ClInclude Include="..\Common\Wipe.h" />
<ClInclude Include="..\Common\Apidrvr.h" />
<ClInclude Include="..\Common\BaseCom.h" />
diff --git a/src/ExpandVolume/ExpandVolume.vcxproj.filters b/src/ExpandVolume/ExpandVolume.vcxproj.filters
index 007757ff..3997d07f 100644
--- a/src/ExpandVolume/ExpandVolume.vcxproj.filters
+++ b/src/ExpandVolume/ExpandVolume.vcxproj.filters
@@ -126,6 +126,18 @@
<ClCompile Include="..\Setup\SelfExtract.c">
<Filter>Source Files\Setup</Filter>
</ClCompile>
+ <ClCompile Include="..\Common\EMVToken.cpp">
+ <Filter>Source Files\Common</Filter>
+ </ClCompile>
+ <ClCompile Include="..\Common\Token.cpp">
+ <Filter>Source Files\Common</Filter>
+ </ClCompile>
+ <ClCompile Include="..\Common\IccDataExtractor.cpp">
+ <Filter>Source Files\Common</Filter>
+ </ClCompile>
+ <ClCompile Include="..\Common\TLVParser.cpp">
+ <Filter>Source Files\Common</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\Common\Wipe.h">
@@ -230,6 +242,18 @@
<ClInclude Include="..\Common\Xts.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\Common\EMVToken.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\Common\Token.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\Common\IccDataExtractor.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\Common\TLVParser.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<Midl Include="..\Mount\MainCom.idl">
diff --git a/src/ExpandVolume/WinMain.cpp b/src/ExpandVolume/WinMain.cpp
index 42f1c28d..57e58b4f 100644
--- a/src/ExpandVolume/WinMain.cpp
+++ b/src/ExpandVolume/WinMain.cpp
@@ -321,6 +321,7 @@ void LoadSettings (HWND hwndDlg)
mountOptions = defaultMountOptions;
CloseSecurityTokenSessionsAfterMount = ConfigReadInt ("CloseSecurityTokenSessionsAfterMount", 0);
+ ActivateEMVOption = ConfigReadInt ("ActivateEMVOption", 0);
{
char szTmp[TC_MAX_PATH] = {0};
diff --git a/src/Format/Format.vcxproj b/src/Format/Format.vcxproj
index e377c1e0..9f5abbc0 100644
--- a/src/Format/Format.vcxproj
+++ b/src/Format/Format.vcxproj
@@ -218,7 +218,7 @@ copy Debug\VeraCryptFormat.exe "..\Debug\Setup Files\VeraCrypt Format.exe" &gt;N
<DisableSpecificWarnings>4057;4100;4127;4201;4204;4701;4706;4131;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
- <AdditionalDependencies>..\Crypto\x64\Debug\crypto.lib;..\Common\x64\Debug\Zip.lib;..\Common\x64\Debug\lzma.lib;mpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>..\Crypto\x64\Debug\crypto.lib;..\Common\x64\Debug\Zip.lib;..\Common\x64\Debug\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)VeraCryptFormat.exe</OutputFile>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<DelayLoadDLLs>mpr.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
@@ -301,7 +301,7 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt Format-x64.exe" &gt;NUL:
<DisableSpecificWarnings>4057;4100;4127;4201;4204;4701;4706;4131;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
- <AdditionalDependencies>..\Crypto\Release\crypto.lib;..\Common\Release\Zip.lib;..\Common\Release\lzma.lib;mpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>..\Crypto\Release\crypto.lib;..\Common\Release\Zip.lib;..\Common\Release\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)VeraCryptFormat.exe</OutputFile>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<DelayLoadDLLs>mpr.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
@@ -385,7 +385,7 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt Format-x64.exe" &gt;NUL:
<DisableSpecificWarnings>4057;4100;4127;4201;4204;4701;4706;4131;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
- <AdditionalDependencies>..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)VeraCryptFormat.exe</OutputFile>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<DelayLoadDLLs>mpr.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
@@ -429,7 +429,7 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt Format-x64.exe" &gt;NUL:
<DisableSpecificWarnings>4057;4100;4127;4201;4204;4701;4706;4131;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
- <AdditionalDependencies>..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)VeraCryptFormat.exe</OutputFile>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<DelayLoadDLLs>mpr.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
@@ -497,6 +497,10 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt Format-x64.exe" &gt;NUL:
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
+ <ClCompile Include="..\Common\EMVToken.cpp" />
+ <ClCompile Include="..\Common\IccDataExtractor.cpp" />
+ <ClCompile Include="..\Common\TLVParser.cpp" />
+ <ClCompile Include="..\Common\Token.cpp" />
<ClCompile Include="FormatCom.cpp" />
<ClCompile Include="InPlace.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
@@ -582,11 +586,15 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt Format-x64.exe" &gt;NUL:
<ClInclude Include="..\Common\Crypto.h" />
<ClInclude Include="..\Common\Dictionary.h" />
<ClInclude Include="..\Common\Dlgcode.h" />
+ <ClInclude Include="..\Common\EMVToken.h" />
<ClInclude Include="..\Common\EncryptionThreadPool.h" />
<ClInclude Include="..\Common\Endian.h" />
<ClInclude Include="..\Common\Exception.h" />
<ClInclude Include="..\Common\Fat.h" />
<ClInclude Include="..\Common\Format.h" />
+ <ClInclude Include="..\Common\IccDataExtractor.h" />
+ <ClInclude Include="..\Common\TLVParser.h" />
+ <ClInclude Include="..\Common\Token.h" />
<ClInclude Include="FormatCom.h" />
<ClInclude Include="..\Common\GfMul.h" />
<ClInclude Include="InPlace.h" />
@@ -644,7 +652,9 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt Format-x64.exe" &gt;NUL:
<None Include="..\Boot\Windows\Release_Twofish\BootSector.bin" />
<None Include="..\Boot\Windows\Release_AES\BootSector.bin" />
<None Include="..\Boot\Windows\Release\Decompressor.com" />
- <None Include="..\Common\Language.xml" />
+ <None Include="..\Common\Language.xml">
+ <SubType>Designer</SubType>
+ </None>
<None Include="..\Resources\Texts\License.rtf" />
<None Include="..\Common\Textual_logo_288dpi.bmp" />
<None Include="..\Common\Textual_logo_96dpi.bmp" />
diff --git a/src/Format/Format.vcxproj.filters b/src/Format/Format.vcxproj.filters
index 4f0e81eb..e6615982 100644
--- a/src/Format/Format.vcxproj.filters
+++ b/src/Format/Format.vcxproj.filters
@@ -108,6 +108,18 @@
<ClCompile Include="..\Common\Xts.c">
<Filter>Source Files\Common</Filter>
</ClCompile>
+ <ClCompile Include="..\Common\EMVToken.cpp">
+ <Filter>Source Files\Common</Filter>
+ </ClCompile>
+ <ClCompile Include="..\Common\Token.cpp">
+ <Filter>Source Files\Common</Filter>
+ </ClCompile>
+ <ClCompile Include="..\Common\IccDataExtractor.cpp">
+ <Filter>Source Files\Common</Filter>
+ </ClCompile>
+ <ClCompile Include="..\Common\TLVParser.cpp">
+ <Filter>Source Files\Common</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<Midl Include="FormatCom.idl">
@@ -208,6 +220,18 @@
<ClInclude Include="..\Common\Xts.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\Common\EMVToken.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\Common\Token.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\Common\IccDataExtractor.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\Common\TLVParser.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\Boot\Windows\Release_Serpent_SHA2\BootSector.bin">
diff --git a/src/Format/Tcformat.c b/src/Format/Tcformat.c
index 9c8648a8..1e605c4d 100644
--- a/src/Format/Tcformat.c
+++ b/src/Format/Tcformat.c
@@ -802,6 +802,8 @@ static void LoadSettingsAndCheckModified (HWND hwndDlg, BOOL bOnlyCheckModified,
ConfigReadCompareInt ("UseLegacyMaxPasswordLength", FALSE, &bUseLegacyMaxPasswordLength, bOnlyCheckModified, pbSettingsModified);
+ ConfigReadCompareInt ("ActivateEMVOption", 0, &ActivateEMVOption, bOnlyCheckModified, pbSettingsModified);
+
{
char szTmp[MAX_PATH] = {0};
WideCharToMultiByte (CP_UTF8, 0, SecurityTokenLibraryPath, -1, szTmp, MAX_PATH, NULL, NULL);
@@ -9589,7 +9591,7 @@ void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine)
case OptionTokenPin:
{
- wchar_t szTmp[SecurityToken::MaxPasswordLength + 1] = {0};
+ wchar_t szTmp[SecurityToken::MaxPasswordLength + 1] = {0}; // TODO Use Token
if (GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, szTmp, ARRAYSIZE (szTmp)) == HAS_ARGUMENT)
{
if (0 == WideCharToMultiByte (CP_UTF8, 0, szTmp, -1, CmdTokenPin, TC_MAX_PATH, nullptr, nullptr))
diff --git a/src/Main/CommandLineInterface.cpp b/src/Main/CommandLineInterface.cpp
index 865f69dd..dabfcad6 100644
--- a/src/Main/CommandLineInterface.cpp
+++ b/src/Main/CommandLineInterface.cpp
@@ -67,7 +67,9 @@ namespace VeraCrypt
parser.AddSwitch (L"", L"import-token-keyfiles", _("Import keyfiles to security token"));
parser.AddOption (L"k", L"keyfiles", _("Keyfiles"));
parser.AddSwitch (L"l", L"list", _("List mounted volumes"));
- parser.AddSwitch (L"", L"list-token-keyfiles", _("List security token keyfiles"));
+ parser.AddSwitch (L"", L"list-token-keyfiles", _("List token keyfiles"));
+ parser.AddSwitch (L"", L"list-securitytoken-keyfiles", _("List security token keyfiles"));
+ parser.AddSwitch (L"", L"list-emvtoken-keyfiles", _("List emv token keyfiles"));
parser.AddSwitch (L"", L"load-preferences", _("Load user preferences"));
parser.AddSwitch (L"", L"mount", _("Mount volume interactively"));
parser.AddOption (L"m", L"mount-options", _("VeraCrypt volume mount options"));
@@ -238,8 +240,18 @@ namespace VeraCrypt
if (parser.Found (L"list-token-keyfiles"))
{
CheckCommandSingle();
- ArgCommand = CommandId::ListSecurityTokenKeyfiles;
+ ArgCommand = CommandId::ListTokenKeyfiles;
}
+ if (parser.Found (L"list-securitytoken-keyfiles"))
+ {
+ CheckCommandSingle();
+ ArgCommand = CommandId::ListSecurityTokenKeyfiles;
+ }
+ if (parser.Found (L"list-emvtoken-keyfiles"))
+ {
+ CheckCommandSingle();
+ ArgCommand = CommandId::ListEMVTokenKeyfiles;
+ }
if (parser.Found (L"mount"))
{
diff --git a/src/Main/CommandLineInterface.h b/src/Main/CommandLineInterface.h
index 23693330..21fb5c89 100644
--- a/src/Main/CommandLineInterface.h
+++ b/src/Main/CommandLineInterface.h
@@ -42,7 +42,9 @@ namespace VeraCrypt
ExportSecurityTokenKeyfile,
Help,
ImportSecurityTokenKeyfiles,
- ListSecurityTokenKeyfiles,
+ ListTokenKeyfiles,
+ ListSecurityTokenKeyfiles,
+ ListEMVTokenKeyfiles,
ListVolumes,
MountVolume,
RestoreHeaders,
diff --git a/src/Main/Forms/ChangePasswordDialog.cpp b/src/Main/Forms/ChangePasswordDialog.cpp
index 585d14a5..0992cf3b 100644
--- a/src/Main/Forms/ChangePasswordDialog.cpp
+++ b/src/Main/Forms/ChangePasswordDialog.cpp
@@ -204,7 +204,7 @@ namespace VeraCrypt
wxBusyCursor busy;
ChangePasswordThreadRoutine routine(Path, Gui->GetPreferences().DefaultMountOptions.PreserveTimestamps,
CurrentPasswordPanel->GetPassword(), CurrentPasswordPanel->GetVolumePim(), CurrentPasswordPanel->GetPkcs5Kdf(bUnsupportedKdf), CurrentPasswordPanel->GetTrueCryptMode(),CurrentPasswordPanel->GetKeyfiles(),
- newPassword, newPim, newKeyfiles, NewPasswordPanel->GetPkcs5Kdf(bUnsupportedKdf), NewPasswordPanel->GetHeaderWipeCount());
+ newPassword, newPim, newKeyfiles, NewPasswordPanel->GetPkcs5Kdf(bUnsupportedKdf), NewPasswordPanel->GetHeaderWipeCount(), Gui->GetPreferences().ActivateEMVOption);
Gui->ExecuteWaitThreadRoutine (this, &routine);
}
diff --git a/src/Main/Forms/Forms.cpp b/src/Main/Forms/Forms.cpp
index b601839e..8667a741 100644
--- a/src/Main/Forms/Forms.cpp
+++ b/src/Main/Forms/Forms.cpp
@@ -2204,11 +2204,18 @@ PreferencesDialogBase::PreferencesDialogBase( wxWindow* parent, wxWindowID id, c
CloseSecurityTokenSessionsAfterMountCheckBox = new wxCheckBox( sbSizer37->GetStaticBox(), wxID_ANY, _("IDC_CLOSE_TOKEN_SESSION_AFTER_MOUNT"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizer37->Add( CloseSecurityTokenSessionsAfterMountCheckBox, 0, wxALL, 5 );
-
+
bSizer128->Add( sbSizer37, 0, wxEXPAND|wxALL, 5 );
-
-
+
+ wxStaticBoxSizer* sbSizer38;
+ sbSizer38 = new wxStaticBoxSizer( new wxStaticBox( SecurityTokensPage, wxID_ANY, _("IDT_EMV_OPTIONS") ), wxVERTICAL );
+
+ ActivateEMVOptionCheckBox = new wxCheckBox( sbSizer38->GetStaticBox(), wxID_ANY, _("IDC_ACTIVATE_EMV_OPTION"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizer38->Add( ActivateEMVOptionCheckBox, 0, wxALL, 5 );
+
+ bSizer128->Add( sbSizer38, 0, wxEXPAND|wxALL, 5 );
+
bSizer127->Add( bSizer128, 1, wxEXPAND|wxALL, 5 );
diff --git a/src/Main/Forms/Forms.h b/src/Main/Forms/Forms.h
index 245087de..904e96dd 100644
--- a/src/Main/Forms/Forms.h
+++ b/src/Main/Forms/Forms.h
@@ -593,6 +593,7 @@ namespace VeraCrypt
wxTextCtrl* Pkcs11ModulePathTextCtrl;
wxButton* SelectPkcs11ModuleButton;
wxCheckBox* CloseSecurityTokenSessionsAfterMountCheckBox;
+ wxCheckBox* ActivateEMVOptionCheckBox;
wxListCtrl* HotkeyListCtrl;
wxTextCtrl* HotkeyTextCtrl;
wxButton* AssignHotkeyButton;
diff --git a/src/Main/Forms/KeyfilesPanel.cpp b/src/Main/Forms/KeyfilesPanel.cpp
index c1f26d86..e3d086fc 100644
--- a/src/Main/Forms/KeyfilesPanel.cpp
+++ b/src/Main/Forms/KeyfilesPanel.cpp
@@ -115,7 +115,7 @@ namespace VeraCrypt
SecurityTokenKeyfilesDialog dialog (this);
if (dialog.ShowModal() == wxID_OK)
{
- foreach (const SecurityTokenKeyfilePath &path, dialog.GetSelectedSecurityTokenKeyfilePaths())
+ foreach (const TokenKeyfilePath &path, dialog.GetSelectedSecurityTokenKeyfilePaths())
{
vector <wstring> fields;
fields.push_back (path);
diff --git a/src/Main/Forms/MainFrame.cpp b/src/Main/Forms/MainFrame.cpp
index ab42ac06..b52682ce 100644
--- a/src/Main/Forms/MainFrame.cpp
+++ b/src/Main/Forms/MainFrame.cpp
@@ -683,7 +683,7 @@ namespace VeraCrypt
{
mountOptions.Pim = CmdLine->ArgPim;
}
-
+ mountOptions.EMVOption = GetPreferences().ActivateEMVOption;
Gui->MountAllFavoriteVolumes (mountOptions);
}
catch (exception &e)
@@ -718,6 +718,7 @@ namespace VeraCrypt
{
mountOptions.Pim = CmdLine->ArgPim;
}
+ mountOptions.EMVOption = GetPreferences().ActivateEMVOption;
try
{
diff --git a/src/Main/Forms/MountOptionsDialog.cpp b/src/Main/Forms/MountOptionsDialog.cpp
index 04410922..28a9919c 100644
--- a/src/Main/Forms/MountOptionsDialog.cpp
+++ b/src/Main/Forms/MountOptionsDialog.cpp
@@ -193,6 +193,7 @@ namespace VeraCrypt
Options.MountPoint = make_shared <DirectoryPath> (mountPoint);
Options.FilesystemOptions = FilesystemOptionsTextCtrl->GetValue();
+ Options.EMVOption = Gui->GetPreferences().ActivateEMVOption;
EndModal (wxID_OK);
}
diff --git a/src/Main/Forms/PreferencesDialog.cpp b/src/Main/Forms/PreferencesDialog.cpp
index 2815c9b5..6caae325 100644
--- a/src/Main/Forms/PreferencesDialog.cpp
+++ b/src/Main/Forms/PreferencesDialog.cpp
@@ -96,6 +96,7 @@ namespace VeraCrypt
// Security tokens
Pkcs11ModulePathTextCtrl->SetValue (wstring (Preferences.SecurityTokenModule));
TC_CHECK_BOX_VALIDATOR (CloseSecurityTokenSessionsAfterMount);
+ TC_CHECK_BOX_VALIDATOR (ActivateEMVOption);
// System integration
TC_CHECK_BOX_VALIDATOR (StartOnLogon);
diff --git a/src/Main/Forms/SecurityTokenKeyfilesDialog.cpp b/src/Main/Forms/SecurityTokenKeyfilesDialog.cpp
index c4492599..2c5896a7 100644
--- a/src/Main/Forms/SecurityTokenKeyfilesDialog.cpp
+++ b/src/Main/Forms/SecurityTokenKeyfilesDialog.cpp
@@ -12,7 +12,6 @@
#include "System.h"
#include "Main/GraphicUserInterface.h"
-#include "Common/SecurityToken.h"
#include "NewSecurityTokenKeyfileDialog.h"
#include "SecurityTokenKeyfilesDialog.h"
@@ -54,18 +53,18 @@ namespace VeraCrypt
wxBusyCursor busy;
SecurityTokenKeyfileListCtrl->DeleteAllItems();
- SecurityTokenKeyfileList = SecurityToken::GetAvailableKeyfiles();
+ SecurityTokenKeyfileList = Token::GetAvailableKeyfiles(Gui->GetPreferences().ActivateEMVOption);
size_t i = 0;
- foreach (const SecurityTokenKeyfile &key, SecurityTokenKeyfileList)
+ foreach (const shared_ptr<TokenKeyfile> key, SecurityTokenKeyfileList)
{
vector <wstring> fields (SecurityTokenKeyfileListCtrl->GetColumnCount());
- fields[ColumnSecurityTokenSlotId] = StringConverter::ToWide ((uint64) key.SlotId);
- fields[ColumnSecurityTokenLabel] = key.Token.Label;
- fields[ColumnSecurityTokenKeyfileLabel] = key.Id;
+ fields[ColumnSecurityTokenSlotId] = StringConverter::ToWide ((uint64) key->Token->SlotId);
+ fields[ColumnSecurityTokenLabel] = key->Token->Label;
+ fields[ColumnSecurityTokenKeyfileLabel] = key->Id;
- Gui->AppendToListCtrl (SecurityTokenKeyfileListCtrl, fields, 0, &SecurityTokenKeyfileList[i++]);
+ Gui->AppendToListCtrl (SecurityTokenKeyfileListCtrl, fields, 0, key.get());
}
}
@@ -97,7 +96,7 @@ namespace VeraCrypt
{
foreach (long item, Gui->GetListCtrlSelectedItems (SecurityTokenKeyfileListCtrl))
{
- SecurityTokenKeyfile *keyfile = reinterpret_cast <SecurityTokenKeyfile *> (SecurityTokenKeyfileListCtrl->GetItemData (item));
+ TokenKeyfile *keyfile = reinterpret_cast <TokenKeyfile *> (SecurityTokenKeyfileListCtrl->GetItemData (item));
FilePathList files = Gui->SelectFiles (this, wxEmptyString, true);
@@ -106,7 +105,7 @@ namespace VeraCrypt
wxBusyCursor busy;
vector <byte> keyfileData;
- SecurityToken::GetKeyfileData (*keyfile, keyfileData);
+ keyfile->GetKeyfileData (keyfileData);
BufferPtr keyfileDataBuf (&keyfileData.front(), keyfileData.size());
finally_do_arg (BufferPtr, keyfileDataBuf, { finally_arg.Erase(); });
@@ -178,24 +177,34 @@ namespace VeraCrypt
}
}
- void SecurityTokenKeyfilesDialog::OnListItemSelected (wxListEvent& event)
- {
- if (event.GetItem().GetData() != (wxUIntPtr) nullptr)
- {
- DeleteButton->Enable();
- ExportButton->Enable();
- OKButton->Enable();
- }
- }
+ void SecurityTokenKeyfilesDialog::OnListItemSelected(wxListEvent &event) {
+ if (event.GetItem().GetData() != (wxUIntPtr) nullptr) {
+ BOOL deletable = true;
+ foreach(long
+ item, Gui->GetListCtrlSelectedItems(SecurityTokenKeyfileListCtrl))
+ {
+ TokenKeyfile *keyfile = reinterpret_cast <TokenKeyfile *> (SecurityTokenKeyfileListCtrl->GetItemData(
+ item));
+ if (!keyfile->Token->isEditable()) {
+ deletable = false;
+ }
+ }
+ if (deletable) {
+ DeleteButton->Enable();
+ }
+ ExportButton->Enable();
+ OKButton->Enable();
+ }
+ }
void SecurityTokenKeyfilesDialog::OnOKButtonClick ()
{
foreach (long item, Gui->GetListCtrlSelectedItems (SecurityTokenKeyfileListCtrl))
- {
- SecurityTokenKeyfile *key = reinterpret_cast <SecurityTokenKeyfile *> (SecurityTokenKeyfileListCtrl->GetItemData (item));
- SelectedSecurityTokenKeyfilePaths.push_back (*key);
- }
+ {
+ TokenKeyfile *key = reinterpret_cast <TokenKeyfile *> (SecurityTokenKeyfileListCtrl->GetItemData(item));
+ SelectedSecurityTokenKeyfilePaths.push_back(*key);
+ }
EndModal (wxID_OK);
}
}
diff --git a/src/Main/Forms/SecurityTokenKeyfilesDialog.h b/src/Main/Forms/SecurityTokenKeyfilesDialog.h
index 8ba7fa9d..92119e1e 100644
--- a/src/Main/Forms/SecurityTokenKeyfilesDialog.h
+++ b/src/Main/Forms/SecurityTokenKeyfilesDialog.h
@@ -14,7 +14,9 @@
#define TC_HEADER_Main_Forms_SecurityTokenKeyfilesDialog
#include "Forms.h"
+#include "Common/Token.h"
#include "Common/SecurityToken.h"
+#include "Common/EMVToken.h"
#include "Main/Main.h"
namespace VeraCrypt
@@ -23,7 +25,7 @@ namespace VeraCrypt
{
public:
SecurityTokenKeyfilesDialog (wxWindow* parent, bool selectionMode = true);
- list <SecurityTokenKeyfilePath> GetSelectedSecurityTokenKeyfilePaths() const { return SelectedSecurityTokenKeyfilePaths; }
+ list <TokenKeyfilePath> GetSelectedSecurityTokenKeyfilePaths() const { return SelectedSecurityTokenKeyfilePaths; }
protected:
enum
@@ -43,8 +45,8 @@ namespace VeraCrypt
void OnOKButtonClick ();
void OnOKButtonClick (wxCommandEvent& event) { OnOKButtonClick(); }
- vector <SecurityTokenKeyfile> SecurityTokenKeyfileList;
- list <SecurityTokenKeyfilePath> SelectedSecurityTokenKeyfilePaths;
+ vector <shared_ptr<TokenKeyfile>> SecurityTokenKeyfileList;
+ list <TokenKeyfilePath> SelectedSecurityTokenKeyfilePaths;
};
}
diff --git a/src/Main/Forms/VolumeCreationWizard.cpp b/src/Main/Forms/VolumeCreationWizard.cpp
index dbb01974..0487455f 100644
--- a/src/Main/Forms/VolumeCreationWizard.cpp
+++ b/src/Main/Forms/VolumeCreationWizard.cpp
@@ -795,7 +795,7 @@ namespace VeraCrypt
shared_ptr <VolumePassword> hiddenPassword;
try
{
- hiddenPassword = Keyfile::ApplyListToPassword (Keyfiles, Password);
+ hiddenPassword = Keyfile::ApplyListToPassword (Keyfiles, Password, Gui->GetPreferences().ActivateEMVOption);
}
catch (...)
{
@@ -846,7 +846,7 @@ namespace VeraCrypt
shared_ptr <VolumePassword> hiddenPassword;
try
{
- hiddenPassword = Keyfile::ApplyListToPassword (Keyfiles, Password);
+ hiddenPassword = Keyfile::ApplyListToPassword (Keyfiles, Password, Gui->GetPreferences().ActivateEMVOption);
}
catch (...)
{
@@ -1032,6 +1032,8 @@ namespace VeraCrypt
options->Size = VolumeSize;
options->Type = OuterVolume ? VolumeType::Normal : SelectedVolumeType;
options->VolumeHeaderKdf = Pkcs5Kdf::GetAlgorithm (*SelectedHash, false);
+ options->EMVOption = Gui->GetPreferences().ActivateEMVOption;
+
Creator.reset (new VolumeCreator);
VolumeCreatorThreadRoutine routine(options, Creator);
@@ -1160,7 +1162,7 @@ namespace VeraCrypt
// remember Outer password and keyfiles in order to be able to compare it with those of Hidden volume
try
{
- OuterPassword = Keyfile::ApplyListToPassword (Keyfiles, Password);
+ OuterPassword = Keyfile::ApplyListToPassword (Keyfiles, Password, Gui->GetPreferences().ActivateEMVOption);
}
catch (...)
{
diff --git a/src/Main/Forms/VolumePasswordPanel.cpp b/src/Main/Forms/VolumePasswordPanel.cpp
index 3b624340..5bd98daa 100644
--- a/src/Main/Forms/VolumePasswordPanel.cpp
+++ b/src/Main/Forms/VolumePasswordPanel.cpp
@@ -383,7 +383,7 @@ namespace VeraCrypt
SecurityTokenKeyfilesDialog dialog (this);
if (dialog.ShowModal() == wxID_OK)
{
- foreach (const SecurityTokenKeyfilePath &path, dialog.GetSelectedSecurityTokenKeyfilePaths())
+ foreach (const TokenKeyfilePath &path, dialog.GetSelectedSecurityTokenKeyfilePaths())
{
Keyfiles->push_back (make_shared <Keyfile> (wstring (path)));
}
diff --git a/src/Main/Forms/WaitDialog.cpp b/src/Main/Forms/WaitDialog.cpp
index 795d7763..c2e0be96 100644
--- a/src/Main/Forms/WaitDialog.cpp
+++ b/src/Main/Forms/WaitDialog.cpp
@@ -10,6 +10,7 @@
#include "Volume/EncryptionModeXTS.h"
#include "Main/GraphicUserInterface.h"
#include "Common/SecurityToken.h"
+#include "Common/IccDataExtractor.h"
#include "WaitDialog.h"
namespace VeraCrypt
@@ -101,6 +102,14 @@ namespace VeraCrypt
VC_CONVERT_EXCEPTION (CipherException);
VC_CONVERT_EXCEPTION (VolumeException);
VC_CONVERT_EXCEPTION (PasswordException);
+
+ VC_CONVERT_EXCEPTION (PCSCException);
+ VC_CONVERT_EXCEPTION (WinscardLibraryNotInitialized);
+ VC_CONVERT_EXCEPTION (InvalidEMVPath);
+ VC_CONVERT_EXCEPTION (EMVKeyfileDataNotFound);
+ VC_CONVERT_EXCEPTION (EMVPANNotFound);
+ VC_CONVERT_EXCEPTION (EMVUnknownCardType);
+
throw *ex;
}
}
diff --git a/src/Main/GraphicUserInterface.cpp b/src/Main/GraphicUserInterface.cpp
index ba5c4e50..c76f1886 100644
--- a/src/Main/GraphicUserInterface.cpp
+++ b/src/Main/GraphicUserInterface.cpp
@@ -193,6 +193,7 @@ namespace VeraCrypt
options->Kdf,
false,
options->Keyfiles,
+ options->EMVOption,
options->Protection,
options->ProtectionPassword,
options->ProtectionPim,
@@ -221,6 +222,7 @@ namespace VeraCrypt
options->Kdf,
false,
options->Keyfiles,
+ options->EMVOption,
options->Protection,
options->ProtectionPassword,
options->ProtectionPim,
@@ -315,7 +317,7 @@ namespace VeraCrypt
// Re-encrypt volume header
SecureBuffer newHeaderBuffer (normalVolume->GetLayout()->GetHeaderSize());
- ReEncryptHeaderThreadRoutine routine(newHeaderBuffer, normalVolume->GetHeader(), normalVolumeMountOptions.Password, normalVolumeMountOptions.Pim, normalVolumeMountOptions.Keyfiles);
+ ReEncryptHeaderThreadRoutine routine(newHeaderBuffer, normalVolume->GetHeader(), normalVolumeMountOptions.Password, normalVolumeMountOptions.Pim, normalVolumeMountOptions.Keyfiles, normalVolumeMountOptions.EMVOption);
ExecuteWaitThreadRoutine (parent, &routine);
@@ -324,7 +326,7 @@ namespace VeraCrypt
if (hiddenVolume)
{
// Re-encrypt hidden volume header
- ReEncryptHeaderThreadRoutine hiddenRoutine(newHeaderBuffer, hiddenVolume->GetHeader(), hiddenVolumeMountOptions.Password, hiddenVolumeMountOptions.Pim, hiddenVolumeMountOptions.Keyfiles);
+ ReEncryptHeaderThreadRoutine hiddenRoutine(newHeaderBuffer, hiddenVolume->GetHeader(), hiddenVolumeMountOptions.Password, hiddenVolumeMountOptions.Pim, hiddenVolumeMountOptions.Keyfiles, hiddenVolumeMountOptions.EMVOption);
ExecuteWaitThreadRoutine (parent, &hiddenRoutine);
}
@@ -677,11 +679,21 @@ namespace VeraCrypt
return true;
}
- void GraphicUserInterface::ListSecurityTokenKeyfiles () const
+ void GraphicUserInterface::ListTokenKeyfiles () const
{
SecurityTokenKeyfilesDialog dialog (nullptr);
dialog.ShowModal();
}
+ void GraphicUserInterface::ListSecurityTokenKeyfiles () const
+ {
+ SecurityTokenKeyfilesDialog dialog (nullptr);
+ dialog.ShowModal();
+ }
+ void GraphicUserInterface::ListEMVTokenKeyfiles () const
+ {
+ SecurityTokenKeyfilesDialog dialog (nullptr);
+ dialog.ShowModal();
+ }
#ifdef TC_MACOSX
void GraphicUserInterface::MacOpenFiles (const wxArrayString &fileNames)
@@ -1456,6 +1468,7 @@ namespace VeraCrypt
options.Kdf,
options.TrueCryptMode,
options.Keyfiles,
+ options.EMVOption,
options.Protection,
options.ProtectionPassword,
options.ProtectionPim,
@@ -1488,7 +1501,7 @@ namespace VeraCrypt
// Re-encrypt volume header
wxBusyCursor busy;
SecureBuffer newHeaderBuffer (volume->GetLayout()->GetHeaderSize());
- ReEncryptHeaderThreadRoutine routine(newHeaderBuffer, volume->GetHeader(), options.Password, options.Pim, options.Keyfiles);
+ ReEncryptHeaderThreadRoutine routine(newHeaderBuffer, volume->GetHeader(), options.Password, options.Pim, options.Keyfiles, options.EMVOption);
ExecuteWaitThreadRoutine (parent, &routine);
@@ -1569,7 +1582,7 @@ namespace VeraCrypt
backupFile.ReadAt (headerBuffer, layout->GetType() == VolumeType::Hidden ? layout->GetHeaderSize() : 0);
// Decrypt header
- shared_ptr <VolumePassword> passwordKey = Keyfile::ApplyListToPassword (options.Keyfiles, options.Password);
+ shared_ptr <VolumePassword> passwordKey = Keyfile::ApplyListToPassword (options.Keyfiles, options.Password, options.EMVOption);
Pkcs5KdfList keyDerivationFunctions = layout->GetSupportedKeyDerivationFunctions(options.TrueCryptMode);
EncryptionAlgorithmList encryptionAlgorithms = layout->GetSupportedEncryptionAlgorithms();
EncryptionModeList encryptionModes = layout->GetSupportedEncryptionModes();
@@ -1603,7 +1616,7 @@ namespace VeraCrypt
// Re-encrypt volume header
wxBusyCursor busy;
SecureBuffer newHeaderBuffer (decryptedLayout->GetHeaderSize());
- ReEncryptHeaderThreadRoutine routine(newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Pim, options.Keyfiles);
+ ReEncryptHeaderThreadRoutine routine(newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Pim, options.Keyfiles, options.EMVOption);
ExecuteWaitThreadRoutine (parent, &routine);
@@ -1619,7 +1632,7 @@ namespace VeraCrypt
if (decryptedLayout->HasBackupHeader())
{
// Re-encrypt backup volume header
- ReEncryptHeaderThreadRoutine backupRoutine(newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Pim, options.Keyfiles);
+ ReEncryptHeaderThreadRoutine backupRoutine(newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Pim, options.Keyfiles, options.EMVOption);
ExecuteWaitThreadRoutine (parent, &backupRoutine);
diff --git a/src/Main/GraphicUserInterface.h b/src/Main/GraphicUserInterface.h
index 06ea6772..e50c6386 100644
--- a/src/Main/GraphicUserInterface.h
+++ b/src/Main/GraphicUserInterface.h
@@ -63,7 +63,9 @@ namespace VeraCrypt
virtual void InsertToListCtrl (wxListCtrl *listCtrl, long itemIndex, const vector <wstring> &itemFields, int imageIndex = -1, void *itemDataPtr = nullptr) const;
virtual bool IsInBackgroundMode () const { return BackgroundMode; }
virtual bool IsTheOnlyTopLevelWindow (const wxWindow *window) const;
- virtual void ListSecurityTokenKeyfiles () const;
+ virtual void ListTokenKeyfiles () const;
+ virtual void ListSecurityTokenKeyfiles () const;
+ virtual void ListEMVTokenKeyfiles () const;
virtual VolumeInfoList MountAllDeviceHostedVolumes (MountOptions &options) const;
virtual shared_ptr <VolumeInfo> MountVolume (MountOptions &options) const;
virtual void MoveListCtrlItem (wxListCtrl *listCtrl, long itemIndex, long newItemIndex) const;
diff --git a/src/Main/TextUserInterface.cpp b/src/Main/TextUserInterface.cpp
index ec3ed531..f4f73d7f 100644
--- a/src/Main/TextUserInterface.cpp
+++ b/src/Main/TextUserInterface.cpp
@@ -21,7 +21,9 @@
#endif
#include <wx/platinfo.h>
+#include "Common/Token.h"
#include "Common/SecurityToken.h"
+#include "Common/EMVToken.h"
#include "Core/RandomNumberGenerator.h"
#include "Application.h"
#include "TextUserInterface.h"
@@ -312,6 +314,7 @@ namespace VeraCrypt
kdf,
false,
options->Keyfiles,
+ true,
options->Protection,
options->ProtectionPassword,
options->ProtectionPim,
@@ -337,6 +340,7 @@ namespace VeraCrypt
kdf,
false,
options->Keyfiles,
+ true,
options->Protection,
options->ProtectionPassword,
options->ProtectionPim,
@@ -407,14 +411,14 @@ namespace VeraCrypt
// Re-encrypt volume header
SecureBuffer newHeaderBuffer (normalVolume->GetLayout()->GetHeaderSize());
- Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, normalVolume->GetHeader(), normalVolumeMountOptions.Password, normalVolumeMountOptions.Pim, normalVolumeMountOptions.Keyfiles);
+ Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, normalVolume->GetHeader(), normalVolumeMountOptions.Password, normalVolumeMountOptions.Pim, normalVolumeMountOptions.Keyfiles, true);
backupFile.Write (newHeaderBuffer);
if (hiddenVolume)
{
// Re-encrypt hidden volume header
- Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, hiddenVolume->GetHeader(), hiddenVolumeMountOptions.Password, hiddenVolumeMountOptions.Pim, hiddenVolumeMountOptions.Keyfiles);
+ Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, hiddenVolume->GetHeader(), hiddenVolumeMountOptions.Password, hiddenVolumeMountOptions.Pim, hiddenVolumeMountOptions.Keyfiles, true);
}
else
{
@@ -482,7 +486,7 @@ namespace VeraCrypt
try
{
keyfiles.reset (new KeyfileList);
- volume = Core->OpenVolume (volumePath, Preferences.DefaultMountOptions.PreserveTimestamps, password, pim, kdf, truecryptMode, keyfiles);
+ volume = Core->OpenVolume (volumePath, Preferences.DefaultMountOptions.PreserveTimestamps, password, pim, kdf, truecryptMode, keyfiles, true);
}
catch (PasswordException&)
{
@@ -492,7 +496,7 @@ namespace VeraCrypt
}
if (!volume.get())
- volume = Core->OpenVolume (volumePath, Preferences.DefaultMountOptions.PreserveTimestamps, password, pim, kdf, truecryptMode, keyfiles);
+ volume = Core->OpenVolume (volumePath, Preferences.DefaultMountOptions.PreserveTimestamps, password, pim, kdf, truecryptMode, keyfiles, true);
}
catch (PasswordException &e)
{
@@ -527,7 +531,7 @@ namespace VeraCrypt
RandomNumberGenerator::SetEnrichedByUserStatus (false);
UserEnrichRandomPool();
- Core->ChangePassword (volume, newPassword, newPim, newKeyfiles,
+ Core->ChangePassword (volume, newPassword, newPim, newKeyfiles, true,
newHash ? Pkcs5Kdf::GetAlgorithm (*newHash, false) : shared_ptr <Pkcs5Kdf>());
ShowInfo ("PASSWORD_CHANGED");
@@ -911,6 +915,7 @@ namespace VeraCrypt
wxLongLong startTime = wxGetLocalTimeMillis();
VolumeCreator creator;
+ options->EMVOption = true;
creator.CreateVolume (options);
bool volumeCreated = false;
@@ -1024,7 +1029,7 @@ namespace VeraCrypt
foreach_ref (const Keyfile &keyfile, *keyfiles)
{
- SecurityToken::DeleteKeyfile (SecurityTokenKeyfilePath (FilePath (keyfile)));
+ SecurityToken::DeleteKeyfile (TokenKeyfilePath (FilePath (keyfile)));
}
}
@@ -1055,10 +1060,10 @@ namespace VeraCrypt
if (keyfilePath.empty())
throw UserAbort (SRC_POS);
- SecurityTokenKeyfile tokenKeyfile (keyfilePath);
+ shared_ptr<TokenKeyfile> tokenKeyfile = Token::getTokenKeyfile(keyfilePath);
vector <byte> keyfileData;
- SecurityToken::GetKeyfileData (tokenKeyfile, keyfileData);
+ tokenKeyfile->GetKeyfileData (keyfileData);
BufferPtr keyfileDataBuf (&keyfileData.front(), keyfileData.size());
finally_do_arg (BufferPtr, keyfileDataBuf, { finally_arg.Erase(); });
@@ -1100,7 +1105,7 @@ namespace VeraCrypt
void TextUserInterface::ImportSecurityTokenKeyfiles () const
{
- list <SecurityTokenInfo> tokens = SecurityToken::GetAvailableTokens();
+ list <shared_ptr<TokenInfo>> tokens = Token::GetAvailableTokens();
if (tokens.empty())
throw_err (LangString ["NO_TOKENS_FOUND"]);
@@ -1109,19 +1114,19 @@ namespace VeraCrypt
if (tokens.size() == 1)
{
- slotId = tokens.front().SlotId;
+ slotId = tokens.front()->SlotId;
}
else
{
- foreach (const SecurityTokenInfo &token, tokens)
+ foreach (const shared_ptr<TokenInfo> &token, tokens)
{
wstringstream tokenLabel;
- tokenLabel << L"[" << token.SlotId << L"] " << LangString["TOKEN_SLOT_ID"].c_str() << L" " << token.SlotId << L" " << token.Label;
+ tokenLabel << L"[" << token->SlotId << L"] " << LangString["TOKEN_SLOT_ID"].c_str() << L" " << token->SlotId << L" " << token->Label;
ShowInfo (tokenLabel.str());
}
- slotId = (CK_SLOT_ID) AskSelection (tokens.back().SlotId, tokens.front().SlotId);
+ slotId = (CK_SLOT_ID) AskSelection (tokens.back()->SlotId, tokens.front()->SlotId);
}
shared_ptr <KeyfileList> keyfiles;
@@ -1225,14 +1230,30 @@ namespace VeraCrypt
}
}
- void TextUserInterface::ListSecurityTokenKeyfiles () const
+ void TextUserInterface::ListTokenKeyfiles () const
{
- foreach (const SecurityTokenKeyfile &keyfile, SecurityToken::GetAvailableKeyfiles())
+ foreach (const shared_ptr<TokenKeyfile> keyfile, Token::GetAvailableKeyfiles(true))
{
- ShowString (wstring (SecurityTokenKeyfilePath (keyfile)));
+ ShowString (wstring (TokenKeyfilePath (*keyfile)));
ShowString (L"\n");
}
}
+ void TextUserInterface::ListSecurityTokenKeyfiles () const
+ {
+ foreach (const TokenKeyfile &keyfile, SecurityToken::GetAvailableKeyfiles())
+ {
+ ShowString (wstring (TokenKeyfilePath (keyfile)));
+ ShowString (L"\n");
+ }
+ }
+ void TextUserInterface::ListEMVTokenKeyfiles () const
+ {
+ foreach (const TokenKeyfile &keyfile, EMVToken::GetAvailableKeyfiles())
+ {
+ ShowString (wstring (TokenKeyfilePath (keyfile)));
+ ShowString (L"\n");
+ }
+ }
VolumeInfoList TextUserInterface::MountAllDeviceHostedVolumes (MountOptions &options) const
{
@@ -1523,6 +1544,7 @@ namespace VeraCrypt
kdf,
false,
options.Keyfiles,
+ true,
options.Protection,
options.ProtectionPassword,
options.ProtectionPim,
@@ -1550,7 +1572,7 @@ namespace VeraCrypt
// Re-encrypt volume header
SecureBuffer newHeaderBuffer (volume->GetLayout()->GetHeaderSize());
- Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, volume->GetHeader(), options.Password, options.Pim, options.Keyfiles);
+ Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, volume->GetHeader(), options.Password, options.Pim, options.Keyfiles, true);
// Write volume header
int headerOffset = volume->GetLayout()->GetHeaderOffset();
@@ -1627,7 +1649,7 @@ namespace VeraCrypt
backupFile.ReadAt (headerBuffer, layout->GetType() == VolumeType::Hidden ? layout->GetHeaderSize() : 0);
// Decrypt header
- shared_ptr <VolumePassword> passwordKey = Keyfile::ApplyListToPassword (options.Keyfiles, options.Password);
+ shared_ptr <VolumePassword> passwordKey = Keyfile::ApplyListToPassword (options.Keyfiles, options.Password, true);
if (layout->GetHeader()->Decrypt (headerBuffer, *passwordKey, options.Pim, kdf, false, layout->GetSupportedKeyDerivationFunctions(false), layout->GetSupportedEncryptionAlgorithms(), layout->GetSupportedEncryptionModes()))
{
decryptedLayout = layout;
@@ -1652,7 +1674,7 @@ namespace VeraCrypt
// Re-encrypt volume header
SecureBuffer newHeaderBuffer (decryptedLayout->GetHeaderSize());
- Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Pim, options.Keyfiles);
+ Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Pim, options.Keyfiles, true);
// Write volume header
int headerOffset = decryptedLayout->GetHeaderOffset();
@@ -1666,7 +1688,7 @@ namespace VeraCrypt
if (decryptedLayout->HasBackupHeader())
{
// Re-encrypt backup volume header
- Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Pim, options.Keyfiles);
+ Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Pim, options.Keyfiles, true);
// Write backup volume header
headerOffset = decryptedLayout->GetBackupHeaderOffset();
diff --git a/src/Main/TextUserInterface.h b/src/Main/TextUserInterface.h
index 14eb2c0e..5e64aac7 100644
--- a/src/Main/TextUserInterface.h
+++ b/src/Main/TextUserInterface.h
@@ -51,7 +51,9 @@ namespace VeraCrypt
virtual bool Initialize (int &argc, wxChar **argv) { return wxAppBase::Initialize(argc, argv); }
#endif
virtual void InitSecurityTokenLibrary () const;
- virtual void ListSecurityTokenKeyfiles () const;
+ virtual void ListTokenKeyfiles () const;
+ virtual void ListSecurityTokenKeyfiles () const;
+ virtual void ListEMVTokenKeyfiles () const;
virtual VolumeInfoList MountAllDeviceHostedVolumes (MountOptions &options) const;
virtual shared_ptr <VolumeInfo> MountVolume (MountOptions &options) const;
virtual bool OnInit ();
diff --git a/src/Main/UserInterface.cpp b/src/Main/UserInterface.cpp
index 1a237bbe..132ad0e0 100644
--- a/src/Main/UserInterface.cpp
+++ b/src/Main/UserInterface.cpp
@@ -24,6 +24,7 @@
#include "Platform/SystemInfo.h"
#include "Platform/SystemException.h"
#include "Common/SecurityToken.h"
+#include "Common/IccDataExtractor.h"
#include "Volume/EncryptionTest.h"
#include "Application.h"
#include "FavoriteVolume.h"
@@ -436,6 +437,27 @@ namespace VeraCrypt
return LangString["SECURITY_TOKEN_ERROR"] + L":\n\n" + StringConverter::ToWide (errorString);
}
+
+ // PCSC Exception
+ if (dynamic_cast <const PCSCException *> (&ex))
+ {
+ string errorString = string (dynamic_cast <const PCSCException &> (ex));
+
+ if (LangString.Exists (errorString))
+ return LangString[errorString];
+
+ if (errorString.find("SCARD_E_") == 0 || errorString.find("SCARD_F_") == 0 || errorString.find("SCARD_W_") == 0)
+ {
+ errorString = errorString.substr(8);
+ for (size_t i = 0; i < errorString.size(); ++i)
+ {
+ if (errorString[i] == '_')
+ errorString[i] = ' ';
+ }
+ }
+ return LangString["PCSC_ERROR"] + L":\n\n" + StringConverter::ToWide (errorString);
+ }
+
// Other library exceptions
return ExceptionTypeToString (typeid (ex));
}
@@ -479,6 +501,12 @@ namespace VeraCrypt
EX2MSG (StringFormatterException, LangString["LINUX_EX2MSG_STRINGFORMATTEREXCEPTION"]);
EX2MSG (TemporaryDirectoryFailure, LangString["LINUX_EX2MSG_TEMPORARYDIRECTORYFAILURE"]);
EX2MSG (UnportablePassword, LangString["UNSUPPORTED_CHARS_IN_PWD"]);
+
+ EX2MSG (WinscardLibraryNotInitialized, LangString["WINSCARD_MODULE_INIT_FAILED"]);
+ EX2MSG (InvalidEMVPath, LangString["INVALID_EMV_PATH"]);
+ EX2MSG (EMVKeyfileDataNotFound, LangString["EMV_KEYFILE_DATA_NOT_FOUND"]);
+ EX2MSG (EMVPANNotFound, LangString["EMV_PAN_NOT_FOUND"]);
+ EX2MSG (EMVUnknownCardType, LangString["EMV_UNKNOWN_CARD_TYPE"]);
#if defined (TC_LINUX)
EX2MSG (TerminalNotFound, LangString["LINUX_EX2MSG_TERMINALNOTFOUND"]);
@@ -1122,7 +1150,7 @@ namespace VeraCrypt
" Delete keyfiles from security tokens. See also command --list-token-keyfiles.\n"
"\n"
"--export-token-keyfile\n"
- " Export a keyfile from a security token. See also command --list-token-keyfiles.\n"
+ " Export a keyfile from a token keyfile. See also command --list-token-keyfiles.\n"
"\n"
"--import-token-keyfiles\n"
" Import keyfiles to a security token. See also option --token-lib.\n"
@@ -1134,9 +1162,15 @@ namespace VeraCrypt
" output option (-v). See below for description of MOUNTED_VOLUME.\n"
"\n"
"--list-token-keyfiles\n"
- " Display a list of all available security token keyfiles. See also command\n"
+ " Display a list of all available token keyfiles. See also command\n"
" --import-token-keyfiles.\n"
- "\n"
+ "\n""--list-securitytoken-keyfiles\n"
+ " Display a list of all available security token keyfiles. See also command\n"
+ " --import-token-keyfiles.\n"
+ "\n"
+ "\n""--list-emvtoken-keyfiles\n"
+ " Display a list of all available emv token keyfiles. See also command\n"
+ "\n"
"--mount[=VOLUME_PATH]\n"
" Mount a volume. Volume path and other options are requested from the user\n"
" if not specified on command line.\n"
@@ -1199,9 +1233,12 @@ namespace VeraCrypt
" used (non-recursively). Multiple keyfiles must be separated by comma.\n"
" Use double comma (,,) to specify a comma contained in keyfile's name.\n"
" Keyfile stored on a security token must be specified as\n"
- " token://slot/SLOT_NUMBER/file/FILENAME. An empty keyfile (-k \"\") disables\n"
+ " token://slot/SLOT_NUMBER/file/FILENAME for a security token keyfile\n"
+ " and emv://slot/SLOT_NUMBER for an EMV token keyfile.\n"
+ " An empty keyfile (-k \"\") disables\n"
" interactive requests for keyfiles. See also options --import-token-keyfiles,\n"
- " --list-token-keyfiles, --new-keyfiles, --protection-keyfiles.\n"
+ " --list-token-keyfiles, --list-securitytoken-keyfiles, --list-emvtoken-keyfiles,\n"
+ " --new-keyfiles, --protection-keyfiles.\n"
"\n"
"--load-preferences\n"
" Load user preferences.\n"
@@ -1364,10 +1401,18 @@ namespace VeraCrypt
ImportSecurityTokenKeyfiles();
return true;
- case CommandId::ListSecurityTokenKeyfiles:
- ListSecurityTokenKeyfiles();
+ case CommandId::ListTokenKeyfiles:
+ ListTokenKeyfiles();
return true;
+ case CommandId::ListSecurityTokenKeyfiles:
+ ListSecurityTokenKeyfiles();
+ return true;
+
+ case CommandId::ListEMVTokenKeyfiles:
+ ListEMVTokenKeyfiles();
+ return true;
+
case CommandId::ListVolumes:
if (Preferences.Verbose)
DisplayVolumeProperties (cmdLine.ArgVolumes);
@@ -1648,6 +1693,14 @@ namespace VeraCrypt
VC_CONVERT_EXCEPTION (CipherException);
VC_CONVERT_EXCEPTION (VolumeException);
VC_CONVERT_EXCEPTION (PasswordException);
+
+ VC_CONVERT_EXCEPTION (PCSCException);
+ VC_CONVERT_EXCEPTION (WinscardLibraryNotInitialized);
+ VC_CONVERT_EXCEPTION (InvalidEMVPath);
+ VC_CONVERT_EXCEPTION (EMVKeyfileDataNotFound);
+ VC_CONVERT_EXCEPTION (EMVPANNotFound);
+ VC_CONVERT_EXCEPTION (EMVUnknownCardType);
+
throw *ex;
}
}
diff --git a/src/Main/UserInterface.h b/src/Main/UserInterface.h
index 8c8cca7b..4b628235 100644
--- a/src/Main/UserInterface.h
+++ b/src/Main/UserInterface.h
@@ -56,7 +56,9 @@ namespace VeraCrypt
virtual void Init ();
virtual void InitSecurityTokenLibrary () const = 0;
virtual void ListMountedVolumes (const VolumeInfoList &volumes) const;
+ virtual void ListTokenKeyfiles () const = 0;
virtual void ListSecurityTokenKeyfiles () const = 0;
+ virtual void ListEMVTokenKeyfiles () const = 0;
virtual shared_ptr <VolumeInfo> MountVolume (MountOptions &options) const;
virtual shared_ptr <VolumeInfo> MountVolumeThread (MountOptions &options) const { return Core->MountVolume (options);}
virtual VolumeInfoList MountAllDeviceHostedVolumes (MountOptions &options) const;
diff --git a/src/Main/UserPreferences.cpp b/src/Main/UserPreferences.cpp
index db54b4a4..d5b37bab 100644
--- a/src/Main/UserPreferences.cpp
+++ b/src/Main/UserPreferences.cpp
@@ -79,6 +79,7 @@ namespace VeraCrypt
TC_CONFIG_SET (CloseBackgroundTaskOnNoVolumes);
TC_CONFIG_SET (CloseExplorerWindowsOnDismount);
TC_CONFIG_SET (CloseSecurityTokenSessionsAfterMount);
+ TC_CONFIG_SET (ActivateEMVOption);
TC_CONFIG_SET (DisableKernelEncryptionModeWarning);
TC_CONFIG_SET (DismountOnInactivity);
TC_CONFIG_SET (DismountOnLogOff);
@@ -197,6 +198,7 @@ namespace VeraCrypt
TC_CONFIG_ADD (CloseBackgroundTaskOnNoVolumes);
TC_CONFIG_ADD (CloseExplorerWindowsOnDismount);
TC_CONFIG_ADD (CloseSecurityTokenSessionsAfterMount);
+ TC_CONFIG_ADD (ActivateEMVOption);
TC_CONFIG_ADD (DisableKernelEncryptionModeWarning);
TC_CONFIG_ADD (DismountOnInactivity);
TC_CONFIG_ADD (DismountOnLogOff);
diff --git a/src/Main/UserPreferences.h b/src/Main/UserPreferences.h
index 96faf8a2..bc9cc0c7 100644
--- a/src/Main/UserPreferences.h
+++ b/src/Main/UserPreferences.h
@@ -31,6 +31,7 @@ namespace VeraCrypt
CloseBackgroundTaskOnNoVolumes (true),
CloseExplorerWindowsOnDismount (true),
CloseSecurityTokenSessionsAfterMount (false),
+ ActivateEMVOption (false),
DisableKernelEncryptionModeWarning (false),
DismountOnInactivity (false),
DismountOnLogOff (true),
@@ -72,6 +73,7 @@ namespace VeraCrypt
bool CloseBackgroundTaskOnNoVolumes;
bool CloseExplorerWindowsOnDismount;
bool CloseSecurityTokenSessionsAfterMount;
+ bool ActivateEMVOption;
bool DisableKernelEncryptionModeWarning;
bool DismountOnInactivity;
bool DismountOnLogOff;
diff --git a/src/Makefile b/src/Makefile
index 98b3dd1a..53e460b6 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -190,6 +190,10 @@ ifeq "$(shell uname -s)" "Linux"
PLATFORM := Linux
C_CXX_FLAGS += -DTC_UNIX -DTC_LINUX
+ # TODO: Prpoper implementation in the makefile
+ C_CXX_FLAGS += -I/usr/include/PCSC/ -lpcsclite
+ LFLAGS += -I/usr/include/PCSC/ -lpcsclite
+
# GNU GCC version 11 and higher compile with -std=gnu++17 by default
# which breaks "byte" definitions in Crypto++ library. So set
diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c
index 5a7e40fe..a7552411 100644
--- a/src/Mount/Mount.c
+++ b/src/Mount/Mount.c
@@ -954,6 +954,7 @@ void LoadSettingsAndCheckModified (HWND hwndDlg, BOOL bOnlyCheckModified, BOOL*
}
ConfigReadCompareInt ("CloseSecurityTokenSessionsAfterMount", 0, &CloseSecurityTokenSessionsAfterMount, bOnlyCheckModified, pbSettingsModified);
+ ConfigReadCompareInt ("ActivateEMVOption", 0, &ActivateEMVOption, bOnlyCheckModified, pbSettingsModified);
if (IsHiddenOSRunning())
ConfigReadCompareInt ("HiddenSystemLeakProtNotifStatus", TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_NONE, &HiddenSysLeakProtectionNotificationStatus, bOnlyCheckModified, pbSettingsModified);
@@ -1126,6 +1127,7 @@ void SaveSettings (HWND hwndDlg)
}
ConfigWriteInt ("CloseSecurityTokenSessionsAfterMount", CloseSecurityTokenSessionsAfterMount);
+ ConfigWriteInt ("ActivateEMVOption", ActivateEMVOption);
// Hotkeys
ConfigWriteInt ("HotkeyModAutoMountDevices", Hotkeys[HK_AUTOMOUNT_DEVICES].vKeyModifiers);
@@ -5401,7 +5403,7 @@ ret:
bCacheInDriver = bCacheInDriverDefault;
if (status && CloseSecurityTokenSessionsAfterMount && !MultipleMountOperationInProgress)
- SecurityToken::CloseAllSessions();
+ SecurityToken::CloseAllSessions(); // TODO Use Token
return status;
}
@@ -5903,7 +5905,7 @@ static BOOL MountAllDevicesThreadCode (HWND hwndDlg, BOOL bPasswordPrompt)
}
if (status && CloseSecurityTokenSessionsAfterMount)
- SecurityToken::CloseAllSessions();
+ SecurityToken::CloseAllSessions(); // TODO Use Token
ret:
MultipleMountOperationInProgress = FALSE;
@@ -7653,7 +7655,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
if (bWipeCacheOnAutoDismount)
{
DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL);
- SecurityToken::CloseAllSessions();
+ SecurityToken::CloseAllSessions(); // TODO Use Token
}
DismountAll (hwndDlg, bForceAutoDismount, TRUE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY);
@@ -7692,7 +7694,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
if (bWipeCacheOnAutoDismount)
{
DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL);
- SecurityToken::CloseAllSessions();
+ SecurityToken::CloseAllSessions(); // TODO Use Token
}
DismountAll (hwndDlg, bForceAutoDismount, TRUE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY);
@@ -7749,7 +7751,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
if (bWipeCacheOnAutoDismount)
{
DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL);
- SecurityToken::CloseAllSessions();
+ SecurityToken::CloseAllSessions(); // TODO Use Token
}
DismountAll (hwndDlg, bForceAutoDismount, FALSE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY);
@@ -8648,7 +8650,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
WaitCursor();
finally_do ({ NormalCursor(); });
- SecurityToken::CloseAllSessions();
+ SecurityToken::CloseAllSessions(); // TODO Use Token
}
InfoBalloon (NULL, "ALL_TOKEN_SESSIONS_CLOSED", hwndDlg);
@@ -9637,7 +9639,7 @@ void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine)
case OptionTokenPin:
{
- wchar_t szTmp[SecurityToken::MaxPasswordLength + 1] = {0};
+ wchar_t szTmp[SecurityToken::MaxPasswordLength + 1] = {0}; // TODO Use Token
if (GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, szTmp, ARRAYSIZE (szTmp)) == HAS_ARGUMENT)
{
if (0 == WideCharToMultiByte (CP_UTF8, 0, szTmp, -1, CmdTokenPin, TC_MAX_PATH, nullptr, nullptr))
@@ -10303,7 +10305,7 @@ void DismountIdleVolumes ()
if (bWipeCacheOnAutoDismount)
{
DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL);
- SecurityToken::CloseAllSessions();
+ SecurityToken::CloseAllSessions(); // TODO Use Token
}
}
}
@@ -10632,7 +10634,7 @@ BOOL MountFavoriteVolumes (HWND hwnd, BOOL systemFavorites, BOOL logOnMount, BOO
burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode));
if (bRet && CloseSecurityTokenSessionsAfterMount)
- SecurityToken::CloseAllSessions();
+ SecurityToken::CloseAllSessions(); // TODO Use Token
return bRet;
}
@@ -10810,7 +10812,7 @@ static void HandleHotKey (HWND hwndDlg, WPARAM wParam)
break;
case HK_CLOSE_SECURITY_TOKEN_SESSIONS:
- SecurityToken::CloseAllSessions();
+ SecurityToken::CloseAllSessions(); // TODO Use Token
InfoBalloon (NULL, "ALL_TOKEN_SESSIONS_CLOSED", hwndDlg);
@@ -11879,6 +11881,7 @@ static BOOL CALLBACK SecurityTokenPreferencesDlgProc (HWND hwndDlg, UINT msg, WP
LocalizeDialog (hwndDlg, "IDD_TOKEN_PREFERENCES");
SetDlgItemText (hwndDlg, IDC_PKCS11_MODULE, SecurityTokenLibraryPath);
CheckDlgButton (hwndDlg, IDC_CLOSE_TOKEN_SESSION_AFTER_MOUNT, CloseSecurityTokenSessionsAfterMount ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton (hwndDlg, IDC_ACTIVATE_EMV_OPTION, ActivateEMVOption ? BST_CHECKED : BST_UNCHECKED);
SetWindowTextW (GetDlgItem (hwndDlg, IDT_PKCS11_LIB_HELP), GetString("PKCS11_LIB_LOCATION_HELP"));
@@ -11901,7 +11904,7 @@ static BOOL CALLBACK SecurityTokenPreferencesDlgProc (HWND hwndDlg, UINT msg, WP
{
try
{
- SecurityToken::CloseLibrary();
+ SecurityToken::CloseLibrary(); // TODO Use Token
}
catch (...) { }
@@ -11921,7 +11924,7 @@ static BOOL CALLBACK SecurityTokenPreferencesDlgProc (HWND hwndDlg, UINT msg, WP
}
CloseSecurityTokenSessionsAfterMount = (IsDlgButtonChecked (hwndDlg, IDC_CLOSE_TOKEN_SESSION_AFTER_MOUNT) == BST_CHECKED);
-
+ ActivateEMVOption = (IsDlgButtonChecked (hwndDlg, IDC_ACTIVATE_EMV_OPTION) == BST_CHECKED);
WaitCursor ();
SaveSettings (hwndDlg);
NormalCursor ();
diff --git a/src/Mount/Mount.rc b/src/Mount/Mount.rc
index a524d9f0..d6d766c5 100644
--- a/src/Mount/Mount.rc
+++ b/src/Mount/Mount.rc
@@ -270,7 +270,7 @@ BEGIN
GROUPBOX "Shortcut",IDT_ASSIGN_HOTKEY,7,127,375,53
END
-IDD_TOKEN_PREFERENCES DIALOGEX 0, 0, 316, 199
+IDD_TOKEN_PREFERENCES DIALOGEX 0, 0, 316, 229
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "VeraCrypt - Security Token Preferences"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
@@ -280,10 +280,12 @@ BEGIN
PUSHBUTTON "Auto-&Detect Library",IDC_AUTO_DETECT_PKCS11_MODULE,16,41,112,14
CONTROL "&Close token session (log out) after a volume is successfully mounted",IDC_CLOSE_TOKEN_SESSION_AFTER_MOUNT,
"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,16,154,284,9
- DEFPUSHBUTTON "OK",IDOK,205,178,50,14
- PUSHBUTTON "Cancel",IDCANCEL,259,178,50,14
+ CONTROL "&Activate EMV Option",IDC_ACTIVATE_EMV_OPTION,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,16,185,284,9
+ DEFPUSHBUTTON "OK",IDOK,205,208,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,259,208,50,14
GROUPBOX "PKCS #11 Library Path",IDT_PKCS11_LIB_PATH,7,7,302,129
GROUPBOX "Security Options",IDT_SECURITY_OPTIONS,7,140,302,30
+ GROUPBOX "EMV Options",IDT_EMV_OPTIONS,7,172,302,30
LTEXT "",IDT_PKCS11_LIB_HELP,16,63,286,65
END
diff --git a/src/Mount/Mount.vcxproj b/src/Mount/Mount.vcxproj
index 1c55193a..5aeb6722 100644
--- a/src/Mount/Mount.vcxproj
+++ b/src/Mount/Mount.vcxproj
@@ -236,7 +236,7 @@ copy Debug\VeraCrypt.exe "..\Debug\Setup Files" &gt;NUL:
<DisableSpecificWarnings>4057;4100;4127;4201;4701;4706;4131;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
- <AdditionalDependencies>..\Crypto\x64\Debug\crypto.lib;..\Common\x64\Debug\Zip.lib;..\Common\x64\Debug\lzma.lib;mpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>..\Crypto\x64\Debug\crypto.lib;..\Common\x64\Debug\Zip.lib;..\Common\x64\Debug\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)VeraCrypt.exe</OutputFile>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<DelayLoadDLLs>mpr.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
@@ -325,7 +325,7 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt-x64.exe" &gt;NUL:
<DisableSpecificWarnings>4057;4100;4127;4201;4701;4706;4131;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
- <AdditionalDependencies>..\Crypto\Release\crypto.lib;..\Common\Release\Zip.lib;..\Common\Release\lzma.lib;mpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>..\Crypto\Release\crypto.lib;..\Common\Release\Zip.lib;..\Common\Release\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)VeraCrypt.exe</OutputFile>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<DelayLoadDLLs>mpr.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
@@ -415,7 +415,7 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt-x64.exe" &gt;NUL:
<DisableSpecificWarnings>4057;4100;4127;4201;4701;4706;4131;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
- <AdditionalDependencies>..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)VeraCrypt.exe</OutputFile>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<DelayLoadDLLs>mpr.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
@@ -462,7 +462,7 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt-x64.exe" &gt;NUL:
<DisableSpecificWarnings>4057;4100;4127;4201;4701;4706;4131;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
- <AdditionalDependencies>..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)VeraCrypt.exe</OutputFile>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<DelayLoadDLLs>mpr.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
@@ -533,6 +533,10 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt-x64.exe" &gt;NUL:
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
+ <ClCompile Include="..\Common\EMVToken.cpp" />
+ <ClCompile Include="..\Common\IccDataExtractor.cpp" />
+ <ClCompile Include="..\Common\TLVParser.cpp" />
+ <ClCompile Include="..\Common\Token.cpp" />
<ClCompile Include="..\Setup\SelfExtract.c" />
<ClCompile Include="Favorites.cpp" />
<ClCompile Include="Hotkeys.c" />
@@ -602,6 +606,10 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt-x64.exe" &gt;NUL:
<Midl Include="MainCom.idl" />
</ItemGroup>
<ItemGroup>
+ <ClInclude Include="..\Common\EMVToken.h" />
+ <ClInclude Include="..\Common\IccDataExtractor.h" />
+ <ClInclude Include="..\Common\TLVParser.h" />
+ <ClInclude Include="..\Common\Token.h" />
<ClInclude Include="..\Common\Wipe.h" />
<ClInclude Include="..\Common\Apidrvr.h" />
<ClInclude Include="..\Common\BaseCom.h" />
diff --git a/src/Mount/Mount.vcxproj.filters b/src/Mount/Mount.vcxproj.filters
index e1dfd652..033a76ff 100644
--- a/src/Mount/Mount.vcxproj.filters
+++ b/src/Mount/Mount.vcxproj.filters
@@ -108,6 +108,18 @@
<ClCompile Include="..\Setup\SelfExtract.c">
<Filter>Source Files\Setup</Filter>
</ClCompile>
+ <ClCompile Include="..\Common\EMVToken.cpp">
+ <Filter>Source Files\Common</Filter>
+ </ClCompile>
+ <ClCompile Include="..\Common\Token.cpp">
+ <Filter>Source Files\Common</Filter>
+ </ClCompile>
+ <ClCompile Include="..\Common\IccDataExtractor.cpp">
+ <Filter>Source Files\Common</Filter>
+ </ClCompile>
+ <ClCompile Include="..\Common\TLVParser.cpp">
+ <Filter>Source Files\Common</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<Midl Include="MainCom.idl">
@@ -211,6 +223,18 @@
<ClInclude Include="..\Common\Xts.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\Common\EMVToken.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\Common\Token.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\Common\IccDataExtractor.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\Common\TLVParser.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\Boot\Windows\Rescue_Serpent_SHA2\BootSector.bin">
diff --git a/src/Mount/Resource.h b/src/Mount/Resource.h
index f7b3ff05..69f99080 100644
--- a/src/Mount/Resource.h
+++ b/src/Mount/Resource.h
@@ -199,6 +199,8 @@
#define IDC_FORCE_NEXT_BOOT_VERACRYPT 1176
#define IDC_FORCE_VERACRYPT_BOOT_ENTRY 1177
#define IDC_FORCE_VERACRYPT_FIRST_BOOT_ENTRY 1178
+#define IDC_ACTIVATE_EMV_OPTION 1179
+#define IDT_EMV_OPTIONS 1180
#define IDM_HELP 40001
#define IDM_ABOUT 40002
#define IDM_UNMOUNT_VOLUME 40003
diff --git a/src/Volume/Keyfile.cpp b/src/Volume/Keyfile.cpp
index d171458c..9527fd11 100644
--- a/src/Volume/Keyfile.cpp
+++ b/src/Volume/Keyfile.cpp
@@ -12,13 +12,13 @@
#include "Platform/Serializer.h"
#include "Common/SecurityToken.h"
+#include "Common/EMVToken.h"
#include "Crc32.h"
#include "Keyfile.h"
#include "VolumeException.h"
-
namespace VeraCrypt
{
- void Keyfile::Apply (const BufferPtr &pool) const
+ void Keyfile::Apply (const BufferPtr &pool, bool EMVOption) const
{
if (Path.IsDirectory())
throw ParameterIncorrect (SRC_POS);
@@ -32,61 +32,57 @@ namespace VeraCrypt
SecureBuffer keyfileBuf (File::GetOptimalReadSize());
- if (SecurityToken::IsKeyfilePathValid (Path))
- {
- // Apply keyfile generated by a security token
- vector <byte> keyfileData;
- SecurityToken::GetKeyfileData (SecurityTokenKeyfile (wstring (Path)), keyfileData);
+ std::wcout << wstring (Path) << std::endl;
+ if (Token::IsKeyfilePathValid (Path, EMVOption)) {
+ // Apply keyfile generated by a security token
+ vector <byte> keyfileData;
+ Token::getTokenKeyfile(wstring(Path))->GetKeyfileData(keyfileData);
- if (keyfileData.size() < MinProcessedLength)
- throw InsufficientData (SRC_POS, Path);
+ if (keyfileData.size() < MinProcessedLength)
+ throw InsufficientData(SRC_POS, Path);
- for (size_t i = 0; i < keyfileData.size(); i++)
- {
- uint32 crc = crc32.Process (keyfileData[i]);
+ for (size_t i = 0; i < keyfileData.size(); i++) {
+ uint32 crc = crc32.Process(keyfileData[i]);
- pool[poolPos++] += (byte) (crc >> 24);
- pool[poolPos++] += (byte) (crc >> 16);
- pool[poolPos++] += (byte) (crc >> 8);
- pool[poolPos++] += (byte) crc;
+ pool[poolPos++] += (byte)(crc >> 24);
+ pool[poolPos++] += (byte)(crc >> 16);
+ pool[poolPos++] += (byte)(crc >> 8);
+ pool[poolPos++] += (byte) crc;
- if (poolPos >= pool.Size())
- poolPos = 0;
-
- if (++totalLength >= MaxProcessedLength)
- break;
- }
+ if (poolPos >= pool.Size())
+ poolPos = 0;
- burn (&keyfileData.front(), keyfileData.size());
- goto done;
- }
+ if (++totalLength >= MaxProcessedLength)
+ break;
+ }
- file.Open (Path, File::OpenRead, File::ShareRead);
- while ((readLength = file.Read (keyfileBuf)) > 0)
- {
- for (size_t i = 0; i < readLength; i++)
- {
- uint32 crc = crc32.Process (keyfileBuf[i]);
+ burn(&keyfileData.front(), keyfileData.size());
+ goto done;
+ }
- pool[poolPos++] += (byte) (crc >> 24);
- pool[poolPos++] += (byte) (crc >> 16);
- pool[poolPos++] += (byte) (crc >> 8);
- pool[poolPos++] += (byte) crc;
+ file.Open (Path, File::OpenRead, File::ShareRead);
- if (poolPos >= pool.Size())
- poolPos = 0;
+ while ((readLength = file.Read (keyfileBuf)) > 0) {
+ for (size_t i = 0; i < readLength; i++) {
+ uint32 crc = crc32.Process(keyfileBuf[i]);
+ pool[poolPos++] += (byte)(crc >> 24);
+ pool[poolPos++] += (byte)(crc >> 16);
+ pool[poolPos++] += (byte)(crc >> 8);
+ pool[poolPos++] += (byte) crc;
+ if (poolPos >= pool.Size())
+ poolPos = 0;
+ if (++totalLength >= MaxProcessedLength)
+ goto done;
+ }
+ }
+ done:
- if (++totalLength >= MaxProcessedLength)
- goto done;
- }
- }
-done:
if (totalLength < MinProcessedLength)
throw InsufficientData (SRC_POS, Path);
}
- shared_ptr <VolumePassword> Keyfile::ApplyListToPassword (shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> password)
+ shared_ptr <VolumePassword> Keyfile::ApplyListToPassword (shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> password, bool EMVOption)
{
if (!password)
password.reset (new VolumePassword);
@@ -143,7 +139,7 @@ done:
// Apply all keyfiles
foreach_ref (const Keyfile &k, keyfilesExp)
{
- k.Apply (keyfilePool);
+ k.Apply (keyfilePool, EMVOption);
}
newPassword->Set (keyfilePool);
diff --git a/src/Volume/Keyfile.h b/src/Volume/Keyfile.h
index 04674178..bf0a524b 100644
--- a/src/Volume/Keyfile.h
+++ b/src/Volume/Keyfile.h
@@ -29,7 +29,7 @@ namespace VeraCrypt
virtual ~Keyfile () { };
operator FilesystemPath () const { return Path; }
- static shared_ptr <VolumePassword> ApplyListToPassword (shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> password);
+ static shared_ptr <VolumePassword> ApplyListToPassword (shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> password, bool EMVOption = false);
static shared_ptr <KeyfileList> DeserializeList (shared_ptr <Stream> stream, const string &name);
static void SerializeList (shared_ptr <Stream> stream, const string &name, shared_ptr <KeyfileList> keyfiles);
static bool WasHiddenFilePresentInKeyfilePath() { bool r = HiddenFileWasPresentInKeyfilePath; HiddenFileWasPresentInKeyfilePath = false; return r; }
@@ -38,7 +38,7 @@ namespace VeraCrypt
static const size_t MaxProcessedLength = 1024 * 1024;
protected:
- void Apply (const BufferPtr &pool) const;
+ void Apply (const BufferPtr &pool, bool EMVOption) const;
static bool HiddenFileWasPresentInKeyfilePath;
diff --git a/src/Volume/Volume.cpp b/src/Volume/Volume.cpp
index c4a21b3e..6fb906b6 100644
--- a/src/Volume/Volume.cpp
+++ b/src/Volume/Volume.cpp
@@ -71,7 +71,7 @@ namespace VeraCrypt
return EA->GetMode();
}
- void Volume::Open (const VolumePath &volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, VolumeProtection::Enum protection, shared_ptr <VolumePassword> protectionPassword, int protectionPim, shared_ptr <Pkcs5Kdf> protectionKdf, shared_ptr <KeyfileList> protectionKeyfiles, bool sharedAccessAllowed, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope)
+ void Volume::Open (const VolumePath &volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, bool EMVOption, VolumeProtection::Enum protection, shared_ptr <VolumePassword> protectionPassword, int protectionPim, shared_ptr <Pkcs5Kdf> protectionKdf, shared_ptr <KeyfileList> protectionKeyfiles, bool sharedAccessAllowed, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope)
{
make_shared_auto (File, file);
@@ -102,10 +102,10 @@ namespace VeraCrypt
throw;
}
- return Open (file, password, pim, kdf, truecryptMode, keyfiles, protection, protectionPassword, protectionPim, protectionKdf,protectionKeyfiles, volumeType, useBackupHeaders, partitionInSystemEncryptionScope);
+ return Open (file, password, pim, kdf, truecryptMode, keyfiles, EMVOption, protection, protectionPassword, protectionPim, protectionKdf,protectionKeyfiles, volumeType, useBackupHeaders, partitionInSystemEncryptionScope);
}
- void Volume::Open (shared_ptr <File> volumeFile, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, VolumeProtection::Enum protection, shared_ptr <VolumePassword> protectionPassword, int protectionPim, shared_ptr <Pkcs5Kdf> protectionKdf,shared_ptr <KeyfileList> protectionKeyfiles, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope)
+ void Volume::Open (shared_ptr <File> volumeFile, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, bool EMVOption, VolumeProtection::Enum protection, shared_ptr <VolumePassword> protectionPassword, int protectionPim, shared_ptr <Pkcs5Kdf> protectionKdf,shared_ptr <KeyfileList> protectionKeyfiles, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope)
{
if (!volumeFile)
throw ParameterIncorrect (SRC_POS);
@@ -121,7 +121,7 @@ namespace VeraCrypt
try
{
VolumeHostSize = VolumeFile->Length();
- shared_ptr <VolumePassword> passwordKey = Keyfile::ApplyListToPassword (keyfiles, password);
+ shared_ptr <VolumePassword> passwordKey = Keyfile::ApplyListToPassword (keyfiles, password, EMVOption);
bool skipLayoutV1Normal = false;
@@ -249,6 +249,7 @@ namespace VeraCrypt
protectedVolume.Open (VolumeFile,
protectionPassword, protectionPim, protectionKdf, truecryptMode, protectionKeyfiles,
+ EMVOption,
VolumeProtection::ReadOnly,
shared_ptr <VolumePassword> (), 0, shared_ptr <Pkcs5Kdf> (),shared_ptr <KeyfileList> (),
VolumeType::Hidden,
diff --git a/src/Volume/Volume.h b/src/Volume/Volume.h
index a743a161..85fdbe41 100644
--- a/src/Volume/Volume.h
+++ b/src/Volume/Volume.h
@@ -123,8 +123,8 @@ namespace VeraCrypt
uint64 GetVolumeCreationTime () const { return Header->GetVolumeCreationTime(); }
bool IsHiddenVolumeProtectionTriggered () const { return HiddenVolumeProtectionTriggered; }
bool IsInSystemEncryptionScope () const { return SystemEncryption; }
- void Open (const VolumePath &volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr <VolumePassword> protectionPassword = shared_ptr <VolumePassword> (), int protectionPim = 0, shared_ptr <Pkcs5Kdf> protectionKdf = shared_ptr <Pkcs5Kdf> (),shared_ptr <KeyfileList> protectionKeyfiles = shared_ptr <KeyfileList> (), bool sharedAccessAllowed = false, VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false);
- void Open (shared_ptr <File> volumeFile, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr <VolumePassword> protectionPassword = shared_ptr <VolumePassword> (), int protectionPim = 0, shared_ptr <Pkcs5Kdf> protectionKdf = shared_ptr <Pkcs5Kdf> (), shared_ptr <KeyfileList> protectionKeyfiles = shared_ptr <KeyfileList> (), VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false);
+ void Open (const VolumePath &volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, bool EMVOption, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr <VolumePassword> protectionPassword = shared_ptr <VolumePassword> (), int protectionPim = 0, shared_ptr <Pkcs5Kdf> protectionKdf = shared_ptr <Pkcs5Kdf> (),shared_ptr <KeyfileList> protectionKeyfiles = shared_ptr <KeyfileList> (), bool sharedAccessAllowed = false, VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false);
+ void Open (shared_ptr <File> volumeFile, shared_ptr <VolumePassword> password, int pim, shared_ptr <Pkcs5Kdf> kdf, bool truecryptMode, shared_ptr <KeyfileList> keyfiles, bool EMVOption, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr <VolumePassword> protectionPassword = shared_ptr <VolumePassword> (), int protectionPim = 0, shared_ptr <Pkcs5Kdf> protectionKdf = shared_ptr <Pkcs5Kdf> (), shared_ptr <KeyfileList> protectionKeyfiles = shared_ptr <KeyfileList> (), VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false);
void ReadSectors (const BufferPtr &buffer, uint64 byteOffset);
void ReEncryptHeader (bool backupHeader, const ConstBufferPtr &newSalt, const ConstBufferPtr &newHeaderKey, shared_ptr <Pkcs5Kdf> newPkcs5Kdf);
void WriteSectors (const ConstBufferPtr &buffer, uint64 byteOffset);
diff --git a/src/Volume/Volume.make b/src/Volume/Volume.make
index 91f40fb7..03e06eaa 100644
--- a/src/Volume/Volume.make
+++ b/src/Volume/Volume.make
@@ -96,11 +96,15 @@ OBJS += ../Crypto/kuznyechik_simd.o
OBJSNOOPT += ../Crypto/jitterentropy-base.o0
+OBJS += ../Common/Token.o
OBJS += ../Common/Crc.o
+OBJS += ../Common/TLVParser.o
+OBJS += ../Common/EMVToken.o
OBJS += ../Common/Endian.o
OBJS += ../Common/GfMul.o
OBJS += ../Common/Pkcs5.o
OBJS += ../Common/SecurityToken.o
+OBJS += ../Common/IccDataExtractor.o
VolumeLibrary: Volume.a